remote_logger.cpp
上传用户:dangjiwu
上传日期:2013-07-19
资源大小:42019k
文件大小:10k
源码类别:

Symbian

开发平台:

Visual C++

  1. /* ***** BEGIN LICENSE BLOCK *****
  2.  * Source last modified: $Id: remote_logger.cpp,v 1.2.8.1 2004/07/09 02:09:03 hubbe Exp $
  3.  * 
  4.  * Portions Copyright (c) 1995-2004 RealNetworks, Inc. All Rights Reserved.
  5.  * 
  6.  * The contents of this file, and the files included with this file,
  7.  * are subject to the current version of the RealNetworks Public
  8.  * Source License (the "RPSL") available at
  9.  * http://www.helixcommunity.org/content/rpsl unless you have licensed
  10.  * the file under the current version of the RealNetworks Community
  11.  * Source License (the "RCSL") available at
  12.  * http://www.helixcommunity.org/content/rcsl, in which case the RCSL
  13.  * will apply. You may also obtain the license terms directly from
  14.  * RealNetworks.  You may not use this file except in compliance with
  15.  * the RPSL or, if you have a valid RCSL with RealNetworks applicable
  16.  * to this file, the RCSL.  Please see the applicable RPSL or RCSL for
  17.  * the rights, obligations and limitations governing use of the
  18.  * contents of the file.
  19.  * 
  20.  * Alternatively, the contents of this file may be used under the
  21.  * terms of the GNU General Public License Version 2 or later (the
  22.  * "GPL") in which case the provisions of the GPL are applicable
  23.  * instead of those above. If you wish to allow use of your version of
  24.  * this file only under the terms of the GPL, and not to allow others
  25.  * to use your version of this file under the terms of either the RPSL
  26.  * or RCSL, indicate your decision by deleting the provisions above
  27.  * and replace them with the notice and other provisions required by
  28.  * the GPL. If you do not delete the provisions above, a recipient may
  29.  * use your version of this file under the terms of any one of the
  30.  * RPSL, the RCSL or the GPL.
  31.  * 
  32.  * This file is part of the Helix DNA Technology. RealNetworks is the
  33.  * developer of the Original Code and owns the copyrights in the
  34.  * portions it created.
  35.  * 
  36.  * This file, and the files included with this file, is distributed
  37.  * and made available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY
  38.  * KIND, EITHER EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS
  39.  * ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES
  40.  * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET
  41.  * ENJOYMENT OR NON-INFRINGEMENT.
  42.  * 
  43.  * Technology Compatibility Kit Test Suite(s) Location:
  44.  *    http://www.helixcommunity.org/content/tck
  45.  * 
  46.  * Contributor(s):
  47.  * 
  48.  * ***** END LICENSE BLOCK ***** */
  49. #include "remote_logger.h"
  50. class HXLogMesg
  51. {
  52. public:
  53.     HXLogMesg(HXLogMesgType type,
  54.       IHXBuffer* pPayload);
  55.     ~HXLogMesg();
  56.     
  57.     HXLogMesgType Type() const;
  58.     IHXBuffer* Payload();
  59. private:
  60.     HXLogMesgType m_type;
  61.     IHXBuffer* m_pPayload;
  62. };
  63. HXLogMesg::HXLogMesg(HXLogMesgType type,
  64.      IHXBuffer* pPayload) :
  65.     m_type(type),
  66.     m_pPayload(pPayload)
  67. {
  68.     if (m_pPayload)
  69.     {
  70. m_pPayload->AddRef();
  71.     }
  72. }
  73. HXLogMesg::~HXLogMesg()
  74. {
  75.     HX_RELEASE(m_pPayload);
  76. }
  77.     
  78. HXLogMesgType HXLogMesg::Type() const
  79. {
  80.     return m_type;
  81. }
  82. IHXBuffer* HXLogMesg::Payload()
  83. {
  84.     IHXBuffer* pRet = m_pPayload;
  85.     if (pRet)
  86.     {
  87. pRet->AddRef();
  88.     }
  89.     return pRet;
  90. }
  91. HXRemoteLogger::HXRemoteLogger() :
  92.     m_lRefCount(0),
  93.     m_pCCF(0),
  94.     m_pNetSvc(0),
  95.     m_pSocket(0),
  96.     m_pRemoteHost(0),
  97.     m_remotePort(0),
  98.     m_state(HXLogClosed),
  99.     m_seq(0)
  100. {}
  101. HXRemoteLogger::~HXRemoteLogger()
  102. {
  103.     Close();
  104. }
  105. HX_RESULT HXRemoteLogger::Init(IUnknown* pContext, 
  106.        const char* pRemoteHost,
  107.        UINT16 nRemotePort,
  108.        const char* pLogFilename)
  109. {
  110.     HX_RESULT res = HXR_FAILED;
  111.     if (pContext && pLogFilename && (strlen(pLogFilename) > 0))
  112.     {
  113. Close();
  114. pContext->QueryInterface(IID_IHXCommonClassFactory, (void**)&m_pCCF);
  115. pContext->QueryInterface(IID_IHXNetworkServices, (void**)&m_pNetSvc);
  116. m_pRemoteHost = CopyBuffer(pRemoteHost, strlen(pRemoteHost) + 1);
  117. m_remotePort = nRemotePort;
  118. IHXBuffer* pFilename = CopyBuffer(pLogFilename, 
  119.   strlen(pLogFilename) + 1);
  120. if (m_pCCF && m_pNetSvc && m_pRemoteHost && pFilename)
  121. {
  122.     // Enqueue Log open message to be sent when 
  123.     // we are connected
  124.     QueueMesg(HXLogOpen, pFilename);
  125.     res = HXR_OK;
  126. }
  127. HX_RELEASE(pFilename);
  128.     }
  129.     return res;
  130. }
  131. void HXRemoteLogger::Log( const char* pLogStr)
  132. {
  133.     BOOL bEnqueueMesg = FALSE;
  134.     switch(m_state) {
  135.     case HXLogClosed:
  136.     {
  137. // Try to connect
  138. if (m_pNetSvc &&
  139.     (HXR_OK == m_pNetSvc->CreateTCPSocket(&m_pSocket)) &&
  140.     m_pSocket &&
  141.     (HXR_OK == m_pSocket->Init(this)) &&
  142.     m_pRemoteHost &&
  143.     (HXR_OK == m_pSocket->Connect((const char*)m_pRemoteHost->GetBuffer(),
  144.   m_remotePort)))
  145. {
  146.     m_state = HXLogConnecting;
  147.     bEnqueueMesg = TRUE;
  148. }
  149. else
  150. {
  151.     OnError();
  152. }
  153.     } break;
  154.     case HXLogConnecting:
  155.     {
  156. // We are in the process of connecting
  157. // Just enqueue the message
  158. bEnqueueMesg = TRUE;
  159.     } break;
  160.     case HXLogConnected:
  161.     {
  162. IHXBuffer* pPayload = CopyBuffer(pLogStr, strlen(pLogStr));
  163. if (pPayload &&
  164.     (HXR_OK != SendMesg(HXLogEntry, pPayload)))
  165. {
  166.     OnError();
  167. }
  168. HX_RELEASE(pPayload);
  169.     }
  170.     default:
  171. // Ignore the string
  172. break;
  173.     };
  174.     if (bEnqueueMesg)
  175.     {
  176. IHXBuffer* pPayload = CopyBuffer(pLogStr, strlen(pLogStr));
  177. if (pPayload)
  178. {
  179.     QueueMesg(HXLogEntry, pPayload);
  180. }
  181. HX_RELEASE(pPayload);
  182.     }
  183. }
  184. void HXRemoteLogger::Close()
  185. {
  186.     HX_RELEASE(m_pSocket);
  187.     HX_RELEASE(m_pNetSvc);
  188.     HX_RELEASE(m_pCCF);
  189.     HX_RELEASE(m_pRemoteHost);
  190.     m_seq = 0;
  191.     ClearMesgQueue();
  192. }
  193.     /*
  194.      *  IUnknown methods
  195.      */
  196. STDMETHODIMP HXRemoteLogger::QueryInterface(THIS_
  197.     REFIID riid,
  198.     void** ppvObj)
  199. {
  200.     if (IsEqualIID(riid, IID_IHXTCPResponse))
  201.     {
  202.         AddRef();
  203.         *ppvObj = (IHXTCPResponse*)this;
  204.         return HXR_OK;
  205.     }
  206.     else if (IsEqualIID(riid, IID_IUnknown))
  207.     {
  208.         AddRef();
  209.         *ppvObj = this;
  210.         return HXR_OK;
  211.     }
  212.     *ppvObj = NULL;
  213.     return HXR_NOINTERFACE;
  214. }
  215. STDMETHODIMP_(ULONG32) HXRemoteLogger::AddRef(THIS)
  216. {
  217.     return InterlockedIncrement(&m_lRefCount);
  218. }
  219. STDMETHODIMP_(ULONG32) HXRemoteLogger::Release(THIS)
  220. {
  221.     if (InterlockedDecrement(&m_lRefCount) > 0)
  222.     {
  223.         return m_lRefCount;
  224.     }
  225.     delete this;
  226.     return 0;
  227. }
  228.     /*
  229.      * IHXTCPResponse methods
  230.      */
  231.     /************************************************************************
  232.      * Method:
  233.      *     IHXTCPResponse::ConnectDone
  234.      * Purpose:
  235.      *     A Connect operation has been completed or an error has occurred.
  236.      */
  237. STDMETHODIMP HXRemoteLogger::ConnectDone(THIS_
  238.  HX_RESULT status)
  239. {
  240.     if (HXR_OK == status)
  241.     {
  242. m_state = HXLogConnected;
  243. SendQueuedMesgs();
  244.     }
  245.     else
  246.     {
  247. OnError();
  248.     }
  249.     return HXR_OK;
  250. }
  251.     /************************************************************************
  252.      * Method:
  253.      *     IHXTCPResponse::ReadDone
  254.      * Purpose:
  255.      *     A Read operation has been completed or an error has occurred.
  256.      *     The data is returned in the IHXBuffer.
  257.      */
  258. STDMETHODIMP HXRemoteLogger::ReadDone(THIS_
  259.       HX_RESULT status,
  260.       IHXBuffer* pBuffer)
  261. {
  262.     if (status != HXR_OK)
  263.     {
  264. OnError();
  265.     }
  266.     return HXR_OK;
  267. }
  268.     /************************************************************************
  269.      * Method:
  270.      *     IHXTCPResponse::WriteReady
  271.      * Purpose:
  272.      *     This is the response method for WantWrite.
  273.      *     If HX_RESULT is ok, then the TCP channel is ok to Write to.
  274.      */
  275. STDMETHODIMP HXRemoteLogger::WriteReady(THIS_
  276. HX_RESULT status)
  277. {
  278.     if (status != HXR_OK)
  279.     {
  280. OnError();
  281.     }
  282.     return HXR_OK;
  283. }
  284.     /************************************************************************
  285.      * Method:
  286.      *     IHXTCPResponse::Closed
  287.      * Purpose:
  288.      *     This method is called to inform you that the TCP channel has
  289.      *     been closed by the peer or closed due to error.
  290.      */
  291. STDMETHODIMP HXRemoteLogger::Closed(THIS_
  292.     HX_RESULT status)
  293. {
  294.     HX_RELEASE(m_pSocket);
  295.     m_state = HXLogClosed;
  296.     return HXR_OK;
  297. }
  298. IHXBuffer* HXRemoteLogger::CopyBuffer(const char* pStr,
  299.       UINT32 ulLength) const
  300. {
  301.     IHXBuffer* pRet = 0;
  302.     if (m_pCCF && pStr &&
  303. (HXR_OK == m_pCCF->CreateInstance(CLSID_IHXBuffer, (void**)(&pRet))))
  304.     {
  305. if (HXR_OK != pRet->Set((const UCHAR*)pStr, ulLength))
  306. {
  307.     HX_RELEASE(pRet);
  308. }
  309.     }
  310.     return pRet;
  311. }
  312. void HXRemoteLogger::ClearMesgQueue()
  313. {
  314.     while(!m_mesgList.IsEmpty())
  315.     {
  316. HXLogMesg* pMesg = (HXLogMesg*)m_mesgList.RemoveHead();
  317. HX_DELETE(pMesg);
  318.     }
  319.     m_state = HXLogClosed;
  320. }
  321. void HXRemoteLogger::OnError()
  322. {
  323.     HX_RELEASE(m_pSocket);
  324.     m_state = HXLogError;
  325.     ClearMesgQueue();
  326. }
  327. HX_RESULT HXRemoteLogger::QueueMesg(HXLogMesgType type, IHXBuffer* pPayload)
  328. {
  329.     HX_RESULT res = HXR_FAILED;
  330.     HXLogMesg* pMesg = new HXLogMesg(type, pPayload);
  331.     if (pMesg)
  332.     {
  333. m_mesgList.AddTail(pMesg);
  334. res = HXR_OK;
  335.     }
  336.     return res;
  337. }
  338. void HXRemoteLogger::SendQueuedMesgs()
  339. {
  340.     while(!m_mesgList.IsEmpty())
  341.     {
  342. HXLogMesg* pMesg = (HXLogMesg*)m_mesgList.RemoveHead();
  343. HXLogMesgType type = pMesg->Type();
  344. IHXBuffer* pPayload = pMesg->Payload();
  345. HX_DELETE(pMesg);
  346. if (HXR_OK != SendMesg(type, pPayload))
  347. {
  348.     OnError();
  349. }
  350. HX_RELEASE(pPayload);
  351.     }
  352. }
  353. void HXRemoteLogger::PackUInt32(UCHAR* pBuf, UINT32 ulVal) const
  354. {
  355.     pBuf[0] = (UCHAR)((ulVal >> 24) & 0xff);
  356.     pBuf[1] = (UCHAR)((ulVal >> 16) & 0xff);
  357.     pBuf[2] = (UCHAR)((ulVal >> 8) & 0xff);
  358.     pBuf[3] = (UCHAR)((ulVal) & 0xff);
  359. }
  360. HX_RESULT HXRemoteLogger::SendMesg(HXLogMesgType type, IHXBuffer* pPayload)
  361. {
  362.     HX_RESULT res = HXR_FAILED;
  363.     
  364.     IHXBuffer* pHdr = 0;
  365.     if ((m_state == HXLogConnected) &&
  366. pPayload && m_pCCF && m_pSocket &&
  367. (HXR_OK == m_pCCF->CreateInstance(CLSID_IHXBuffer, (void**)&pHdr)) &&
  368. (HXR_OK == pHdr->SetSize(16)))
  369.     {
  370. UCHAR* pHdrBuf = pHdr->GetBuffer();
  371. PackUInt32(pHdrBuf, 0xff4d48ff);
  372. PackUInt32(pHdrBuf + 4, (UINT32)type);
  373. PackUInt32(pHdrBuf + 8, m_seq);
  374. PackUInt32(pHdrBuf + 12, pPayload->GetSize());
  375. if ((HXR_OK == m_pSocket->Write(pHdr)) &&
  376.     (HXR_OK == m_pSocket->Write(pPayload)))
  377. {
  378.     res = HXR_OK;
  379. }
  380.     }
  381.     HX_RELEASE(pHdr);
  382.     return res;
  383. }