cachobj.cpp
上传用户:zhongxx05
上传日期:2007-06-06
资源大小:33641k
文件大小:15k
源码类别:

Symbian

开发平台:

C/C++

  1. /* ***** BEGIN LICENSE BLOCK ***** 
  2.  * Version: RCSL 1.0/RPSL 1.0 
  3.  *  
  4.  * Portions Copyright (c) 1995-2002 RealNetworks, Inc. All Rights Reserved. 
  5.  *      
  6.  * The contents of this file, and the files included with this file, are 
  7.  * subject to the current version of the RealNetworks Public Source License 
  8.  * Version 1.0 (the "RPSL") available at 
  9.  * http://www.helixcommunity.org/content/rpsl unless you have licensed 
  10.  * the file under the RealNetworks Community Source License Version 1.0 
  11.  * (the "RCSL") available at http://www.helixcommunity.org/content/rcsl, 
  12.  * in which case the RCSL will apply. You may also obtain the license terms 
  13.  * directly from RealNetworks.  You may not use this file except in 
  14.  * compliance with the RPSL or, if you have a valid RCSL with RealNetworks 
  15.  * applicable to this file, the RCSL.  Please see the applicable RPSL or 
  16.  * RCSL for the rights, obligations and limitations governing use of the 
  17.  * contents of the file.  
  18.  *  
  19.  * This file is part of the Helix DNA Technology. RealNetworks is the 
  20.  * developer of the Original Code and owns the copyrights in the portions 
  21.  * it created. 
  22.  *  
  23.  * This file, and the files included with this file, is distributed and made 
  24.  * available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 
  25.  * EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS ALL SUCH WARRANTIES, 
  26.  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS 
  27.  * FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 
  28.  * 
  29.  * Technology Compatibility Kit Test Suite(s) Location: 
  30.  *    http://www.helixcommunity.org/content/tck 
  31.  * 
  32.  * Contributor(s): 
  33.  *  
  34.  * ***** END LICENSE BLOCK ***** */ 
  35. /****************************************************************************
  36.  * 
  37.  *  cachobj.cpp
  38.  *
  39.  *  Purpose:
  40.  * To cache objects in a temporary storage for later retrieval
  41.  * Can be created off of IHXCommonClassFactory.
  42.  * Currently supported only on the client side.
  43.  *
  44.  */
  45. #include "hxcom.h"
  46. #include "hxtypes.h"
  47. #include "hxresult.h"
  48. #include "hxguid.h"
  49. #include "timeval.h"
  50. #include "basepkt.h"
  51. #include "hxbuffer.h"
  52. #include "timebuff.h"
  53. #include "hxcache.h"
  54. #include "ihxpckts.h"
  55. #include "hxtbuf.h"
  56. #include "chunkres.h"
  57. #include "cachobj.h"
  58. #include "hxheap.h"
  59. #ifdef _DEBUG
  60. #undef HX_THIS_FILE
  61. static const char HX_THIS_FILE[] = __FILE__;
  62. #endif
  63. // HXFIFOCache...
  64. HXFIFOCache::HXFIFOCache() :
  65.       m_lRefCount(0)
  66.     , m_pChunkyRes(NULL)
  67.     , m_ulCurrentReadPosition(0)
  68.     , m_ulCurrentWritePosition(0)
  69. {
  70. }
  71. HXFIFOCache::~HXFIFOCache()
  72. {
  73.     Flush();
  74. }
  75. /*
  76.  * IUnknown methods
  77.  */
  78. /////////////////////////////////////////////////////////////////////////
  79. // Method:
  80. // IUnknown::QueryInterface
  81. // Purpose:
  82. // Implement this to export the interfaces supported by your 
  83. // object.
  84. //
  85. STDMETHODIMP HXFIFOCache::QueryInterface(REFIID riid, void** ppvObj)
  86. {
  87. QInterfaceList qiList[] =
  88. {
  89. { GET_IIDHANDLE(IID_IUnknown), this },
  90. { GET_IIDHANDLE(IID_IHXFIFOCache), (IHXFIFOCache*) this },
  91. };
  92.     return QIFind(qiList, QILISTSIZE(qiList), riid, ppvObj);   
  93. }
  94. /////////////////////////////////////////////////////////////////////////
  95. // Method:
  96. // IUnknown::AddRef
  97. // Purpose:
  98. // Everyone usually implements this the same... feel free to use
  99. // this implementation.
  100. //
  101. STDMETHODIMP_(ULONG32) HXFIFOCache::AddRef()
  102. {
  103.     return InterlockedIncrement(&m_lRefCount);
  104. }
  105. /////////////////////////////////////////////////////////////////////////
  106. // Method:
  107. // IUnknown::Release
  108. // Purpose:
  109. // Everyone usually implements this the same... feel free to use
  110. // this implementation.
  111. //
  112. STDMETHODIMP_(ULONG32) HXFIFOCache::Release()
  113. {
  114.     if (InterlockedDecrement(&m_lRefCount) > 0)
  115.     {
  116. return m_lRefCount;
  117.     }
  118.     delete this;
  119.     return 0;
  120. }
  121. /************************************************************************
  122.  * Method:
  123.  * IHXFIFOCache::Cache
  124.  * Purpose:
  125.  *     To cache objects in a temporary storage for later retrieval
  126.  *
  127.  *     Currently supported objects:
  128.  * IHXBuffer
  129.  * IHXValues
  130.  * IHXPacket
  131. // $Private:
  132.  * IHXTimeStampedBuffer
  133. // $EndPrivate.
  134.  *
  135.  */
  136. STDMETHODIMP HXFIFOCache::Cache(IUnknown*     pObject)
  137. {
  138.     HX_RESULT     theErr = HXR_UNEXPECTED;
  139.     IHXClientPacket*     pClientPacket = NULL;
  140.     IHXTimeStampedBuffer*  pTimeStampBuffer = NULL;
  141.     IHXBuffer*     pBuffer = NULL;
  142.     IHXPacket*     pPacket = NULL;
  143.     IHXValues*     pValues = NULL;
  144.     if (!m_pChunkyRes)
  145.     {
  146. m_pChunkyRes = new CChunkyRes;
  147.     }
  148.     if (pObject->QueryInterface(IID_IHXClientPacket, (void**) &pClientPacket) == HXR_OK)
  149.     {
  150. theErr = CacheClientPacket(pClientPacket);
  151. pClientPacket->Release();
  152.     }
  153.     else if (pObject->QueryInterface(IID_IHXTimeStampedBuffer, (void**) &pTimeStampBuffer) == HXR_OK)
  154.     {
  155. theErr = CacheTimestampBuffer(pTimeStampBuffer);
  156. pTimeStampBuffer->Release();
  157.     }
  158.     else if (pObject->QueryInterface(IID_IHXBuffer, (void**) &pBuffer) == HXR_OK)
  159.     {
  160. theErr = CacheBuffer(pBuffer);
  161. pBuffer->Release();
  162.     }
  163.     else if (pObject->QueryInterface(IID_IHXPacket, (void**) &pPacket) == HXR_OK)
  164.     {
  165. theErr = CachePacket(pPacket);
  166. pPacket->Release();
  167.     }
  168.     else if (pObject->QueryInterface(IID_IHXValues, (void**) &pValues) == HXR_OK)
  169.     {
  170. theErr = CacheValues(pValues);
  171. pValues->Release();
  172.     }
  173.     return theErr;
  174. }
  175. /************************************************************************
  176.  * Method:
  177.  *     IHXFIFOCache::Retrieve
  178.  * Purpose:
  179.  *
  180.  *
  181.  */
  182. STDMETHODIMP HXFIFOCache::Retrieve(REF(IUnknown*)  pObject)
  183. {
  184.     HX_RESULT theErr = HXR_OK;
  185.     UINT32 ulBytesRead = 0;
  186.     UINT32 ulBytesToRead = 0;
  187.     char* pData = NULL;
  188.     char* pCursor = NULL;
  189.     CHXBuffer* pBuffer = NULL;
  190.     ChunkyCacheLayout* pChunkyCacheLayout = NULL;
  191.     if (!m_pChunkyRes)
  192.     {
  193. theErr = HXR_UNEXPECTED;
  194. goto cleanup;
  195.     }
  196.     pObject = NULL;
  197.     
  198.     pChunkyCacheLayout = new ChunkyCacheLayout;
  199.     ulBytesToRead = sizeof(ChunkyCacheLayout);
  200.     // read Chunk Header Info
  201.     m_pChunkyRes->GetData(m_ulCurrentReadPosition,
  202.   (char*)pChunkyCacheLayout,
  203.   ulBytesToRead,
  204.   &ulBytesRead);
  205.     m_ulCurrentReadPosition += ulBytesRead;
  206.     if (ulBytesRead)
  207.     {
  208. HX_ASSERT(ulBytesToRead == ulBytesRead);
  209. ulBytesToRead = pChunkyCacheLayout->size - ulBytesRead;
  210. pData = new char[ulBytesToRead];
  211. // read the Chunk Data
  212. m_pChunkyRes->GetData(m_ulCurrentReadPosition,
  213.       (char*)pData,
  214.       ulBytesToRead,
  215.       &ulBytesRead);
  216. HX_ASSERT(ulBytesToRead == ulBytesRead);
  217. m_ulCurrentReadPosition += ulBytesRead;
  218. pCursor = pData;
  219. if (::IsEqualGUID(IID_IHXClientPacket, pChunkyCacheLayout->guid)) 
  220. {          
  221.     ClientPacket::UnPack((IHXClientPacket*&)pObject, pCursor, ulBytesRead);
  222. }
  223. else if (::IsEqualGUID(IID_IHXPacket, pChunkyCacheLayout->guid))
  224. {
  225.     CHXPacket::UnPack((IHXPacket*&)pObject, pCursor, ulBytesRead);
  226. }
  227. else if (::IsEqualGUID(IID_IHXTimeStampedBuffer, pChunkyCacheLayout->guid))
  228. {
  229.     CHXTimeStampedBuffer::UnPack((IHXTimeStampedBuffer*&)pObject, pCursor, ulBytesRead);
  230. }
  231. else if (::IsEqualGUID(IID_IHXBuffer, pChunkyCacheLayout->guid))
  232. {
  233.     pBuffer = new CHXBuffer();
  234.     pBuffer->Set((const UCHAR*)pCursor, ulBytesRead);
  235.     pBuffer->QueryInterface(IID_IHXBuffer, (void**)&pObject);
  236. }
  237. else
  238. {
  239.     theErr = HXR_NOTIMPL;
  240. }
  241.     }
  242. cleanup:
  243.     HX_DELETE(pChunkyCacheLayout);
  244.     HX_VECTOR_DELETE(pData);
  245.     
  246.     return theErr;
  247. }
  248. /************************************************************************
  249.  * Method:
  250.  *     IHXFIFOCache::Flush
  251.  * Purpose:
  252.  *
  253.  *
  254.  */
  255. STDMETHODIMP HXFIFOCache::Flush(void)
  256. {
  257.     m_ulCurrentReadPosition = 0;
  258.     m_ulCurrentWritePosition = 0;
  259.     HX_DELETE(m_pChunkyRes);
  260.     return HXR_OK;
  261. }
  262. HX_RESULT 
  263. HXFIFOCache::CacheClientPacket(IHXClientPacket* pClientPacket)
  264. {
  265.     HX_RESULT theErr = HXR_OK;
  266.     BOOL bContiguousDataPointer = FALSE;
  267.     UINT32 ulBytesWrote = 0;
  268.     UINT32 ulBytesToWrite = 0;
  269.     char* pData = NULL;
  270.     char* pCursor = NULL;
  271. #if !defined(HELIX_FEATURE_FULLGUID)
  272.     GUID tmp = IID_IHXClientPacket;
  273. #endif
  274.     if (!pClientPacket)
  275.     {
  276. theErr = HXR_FAILED;
  277. goto cleanup;
  278.     }
  279.     // caculate the size of client packet
  280.     ClientPacket::Pack(pClientPacket, NULL, ulBytesToWrite);
  281.     ulBytesToWrite += sizeof(ChunkyCacheLayout);
  282.     // check whether we have cont. memory chunk of the size needed
  283.     if (HXR_OK == m_pChunkyRes->GetContiguousDataPointer(m_ulCurrentWritePosition,
  284.  pData,
  285.  ulBytesToWrite) && pData)
  286.     {
  287. bContiguousDataPointer = TRUE;
  288. pCursor = pData;
  289.     }
  290.     // otherwise we allocated our own
  291.     else
  292.     {
  293. pData = new char[ulBytesToWrite];
  294. pCursor = pData;
  295.     }
  296.     // total chunk bytes
  297.     *pCursor++ = (BYTE)ulBytesToWrite; *pCursor++ = (BYTE)(ulBytesToWrite >> 8);
  298.     ulBytesWrote += 2;
  299.     // GUID
  300. #if !defined(HELIX_FEATURE_FULLGUID)
  301.     memcpy(pCursor, (char*)&tmp, sizeof(GUID)); /* Flawfinder: ignore */
  302. #else
  303.     memcpy(pCursor, (char*)&IID_IHXClientPacket, sizeof(GUID)); /* Flawfinder: ignore */
  304. #endif
  305.     pCursor += sizeof(GUID);
  306.     ulBytesWrote += sizeof(GUID);
  307.     // pack data
  308.     ClientPacket::Pack(pClientPacket, pCursor, ulBytesWrote);
  309.     if (!bContiguousDataPointer)
  310.     {
  311. // let the memory manager take care of the contingency
  312. theErr = m_pChunkyRes->SetData(m_ulCurrentWritePosition, pData, ulBytesWrote);
  313.     }
  314.     HX_ASSERT(ulBytesToWrite == ulBytesWrote);
  315.     // advance the write cursor
  316.     m_ulCurrentWritePosition += ulBytesToWrite;
  317. cleanup:
  318.     if (!bContiguousDataPointer)
  319.     {
  320. HX_VECTOR_DELETE(pData);
  321.     }
  322.     return theErr;
  323. }
  324. HX_RESULT 
  325. HXFIFOCache::CacheTimestampBuffer(IHXTimeStampedBuffer* pTimeStampBuffer)
  326. {
  327.     HX_RESULT theErr = HXR_OK;
  328.     BOOL bContiguousDataPointer = FALSE;
  329.     UINT32 ulBytesWrote = 0;
  330.     UINT32 ulBytesToWrite = 0;
  331.     char* pData = NULL;
  332.     char* pCursor = NULL;
  333. #if !defined(HELIX_FEATURE_FULLGUID)
  334.     GUID tmp = IID_IHXBuffer;
  335. #endif
  336.     if (!pTimeStampBuffer)
  337.     {
  338. theErr = HXR_FAILED;
  339. goto cleanup;
  340.     }
  341.     // caculate the size of buffer
  342.     CHXTimeStampedBuffer::Pack(pTimeStampBuffer, NULL, 0, ulBytesToWrite);
  343.     ulBytesToWrite += sizeof(ChunkyCacheLayout);
  344.     // check whether we have cont. memory chunk of the size needed
  345.     if (HXR_OK == m_pChunkyRes->GetContiguousDataPointer(m_ulCurrentWritePosition,
  346.  pData,
  347.  ulBytesToWrite) && pData)
  348.     {
  349. bContiguousDataPointer = TRUE;
  350. pCursor = pData;
  351.     }
  352.     // otherwise we allocated our own
  353.     else
  354.     {
  355. pData = new char[ulBytesToWrite];
  356. pCursor = pData;
  357.     }
  358.     // total chunk bytes
  359.     *pCursor++ = (BYTE)ulBytesToWrite; *pCursor++ = (BYTE)(ulBytesToWrite >> 8);
  360.     ulBytesWrote += 2;
  361.     // GUID
  362. #if !defined(HELIX_FEATURE_FULLGUID)
  363.     memcpy(pCursor, (char*)&tmp, sizeof(GUID)); /* Flawfinder: ignore */
  364. #else
  365.     memcpy(pCursor, (char*)&IID_IHXBuffer, sizeof(GUID)); /* Flawfinder: ignore */
  366. #endif
  367.     pCursor += sizeof(GUID);
  368.     ulBytesWrote += sizeof(GUID);
  369.     // pack data
  370.     CHXTimeStampedBuffer::Pack(pTimeStampBuffer, pCursor,
  371.                                ulBytesToWrite - ulBytesWrote, ulBytesWrote);
  372.     if (!bContiguousDataPointer)
  373.     {
  374. // let the memory manager take care of the contingency
  375. theErr = m_pChunkyRes->SetData(m_ulCurrentWritePosition, pData, ulBytesWrote);
  376.     }
  377.     HX_ASSERT(ulBytesToWrite == ulBytesWrote);
  378.     // advance the write cursor
  379.     m_ulCurrentWritePosition += ulBytesToWrite;
  380. cleanup:
  381.     if (!bContiguousDataPointer)
  382.     {
  383. HX_VECTOR_DELETE(pData);
  384.     }
  385.     return theErr;
  386. }
  387. HX_RESULT 
  388. HXFIFOCache::CacheBuffer(IHXBuffer* pBuffer)
  389. {
  390.     HX_RESULT theErr = HXR_OK;
  391.     BOOL bContiguousDataPointer = FALSE;
  392.     UINT32 ulBytesWrote = 0;
  393.     UINT32 ulBytesToWrite = 0;
  394.     char* pData = NULL;
  395.     char* pCursor = NULL;
  396. #if !defined(HELIX_FEATURE_FULLGUID)
  397.     GUID tmp = IID_IHXBuffer;
  398. #endif
  399.     if (!pBuffer)
  400.     {
  401. theErr = HXR_FAILED;
  402. goto cleanup;
  403.     }
  404.     // caculate the size of client packet
  405.     ulBytesToWrite = pBuffer->GetSize();
  406.     ulBytesToWrite += sizeof(ChunkyCacheLayout);
  407.     // check whether we have cont. memory chunk of the size needed
  408.     if (HXR_OK == m_pChunkyRes->GetContiguousDataPointer(m_ulCurrentWritePosition,
  409.  pData,
  410.  ulBytesToWrite) && pData)
  411.     {
  412. bContiguousDataPointer = TRUE;
  413. pCursor = pData;
  414.     }
  415.     // otherwise we allocated our own
  416.     else
  417.     {
  418. pData = new char[ulBytesToWrite];
  419. pCursor = pData;
  420.     }
  421.     // total chunk bytes
  422.     *pCursor++ = (BYTE)ulBytesToWrite; *pCursor++ = (BYTE)(ulBytesToWrite >> 8);
  423.     ulBytesWrote += 2;
  424.     // GUID
  425. #if !defined(HELIX_FEATURE_FULLGUID)
  426.     memcpy(pCursor, (char*)&tmp, sizeof(GUID)); /* Flawfinder: ignore */
  427. #else
  428.     memcpy(pCursor, (char*)&IID_IHXBuffer, sizeof(GUID)); /* Flawfinder: ignore */
  429. #endif
  430.     pCursor += sizeof(GUID);
  431.     ulBytesWrote += sizeof(GUID);
  432.     // pack data
  433.     memcpy(pCursor, (char*)pBuffer->GetBuffer(), pBuffer->GetSize()); /* Flawfinder: ignore */
  434.     if (!bContiguousDataPointer)
  435.     {
  436. // let the memory manager take care of the contingency
  437. theErr = m_pChunkyRes->SetData(m_ulCurrentWritePosition, pData, ulBytesWrote);
  438.     }
  439.     HX_ASSERT(ulBytesToWrite == ulBytesWrote);
  440.     // advance the write cursor
  441.     m_ulCurrentWritePosition += ulBytesToWrite;
  442. cleanup:
  443.     if (!bContiguousDataPointer)
  444.     {
  445. HX_VECTOR_DELETE(pData);
  446.     }
  447.     return theErr;
  448. }
  449. HX_RESULT 
  450. HXFIFOCache::CachePacket(IHXPacket* pPacket)
  451. {
  452.     HX_RESULT theErr = HXR_OK;
  453.     BOOL bContiguousDataPointer = FALSE;
  454.     UINT32 ulBytesWrote = 0;
  455.     UINT32 ulBytesToWrite = 0;
  456.     char* pData = NULL;
  457.     char* pCursor = NULL;
  458. #if !defined(HELIX_FEATURE_FULLGUID)
  459.     GUID tmp = IID_IHXPacket;
  460. #endif
  461.     if (!pPacket)
  462.     {
  463. theErr = HXR_FAILED;
  464. goto cleanup;
  465.     }
  466.     // caculate the size of client packet
  467.     CHXPacket::Pack(pPacket, NULL, ulBytesToWrite);
  468.     ulBytesToWrite += sizeof(ChunkyCacheLayout);
  469.     // check whether we have cont. memory chunk of the size needed
  470.     if (HXR_OK == m_pChunkyRes->GetContiguousDataPointer(m_ulCurrentWritePosition,
  471.  pData,
  472.  ulBytesToWrite) && pData)
  473.     {
  474. bContiguousDataPointer = TRUE;
  475. pCursor = pData;
  476.     }
  477.     // otherwise we allocated our own
  478.     else
  479.     {
  480. pData = new char[ulBytesToWrite];
  481. pCursor = pData;
  482.     }
  483.     // total chunk bytes
  484.     *pCursor++ = (BYTE)ulBytesToWrite; *pCursor++ = (BYTE)(ulBytesToWrite >> 8);
  485.     ulBytesWrote += 2;
  486.     // GUID
  487. #if !defined(HELIX_FEATURE_FULLGUID)
  488.     memcpy(pCursor, (char*)&tmp, sizeof(GUID)); /* Flawfinder: ignore */
  489. #else
  490.     memcpy(pCursor, (char*)&IID_IHXPacket, sizeof(GUID)); /* Flawfinder: ignore */
  491. #endif
  492.     pCursor += sizeof(GUID);
  493.     ulBytesWrote += sizeof(GUID);
  494.     // pack data
  495.     CHXPacket::Pack(pPacket, pCursor, ulBytesWrote);
  496.     if (!bContiguousDataPointer)
  497.     {
  498. // let the memory manager take care of the contingency
  499. theErr = m_pChunkyRes->SetData(m_ulCurrentWritePosition, pData, ulBytesWrote);
  500.     }
  501.     HX_ASSERT(ulBytesToWrite == ulBytesWrote);
  502.     // advance the write cursor
  503.     m_ulCurrentWritePosition += ulBytesToWrite;
  504. cleanup:
  505.     if (!bContiguousDataPointer)
  506.     {
  507. HX_VECTOR_DELETE(pData);
  508.     }
  509.     return theErr;
  510. }
  511. HX_RESULT 
  512. HXFIFOCache::CacheValues(IHXValues* pValues)
  513. {
  514.     // TBD
  515.     HX_RESULT theErr = HXR_NOTIMPL;
  516.     return theErr;
  517. }