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

Symbian

开发平台:

Visual C++

  1. /* ***** BEGIN LICENSE BLOCK *****
  2.  * Source last modified: $Id: cachobj.cpp,v 1.7.20.3 2004/07/09 01:48:15 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. /****************************************************************************
  50.  * 
  51.  *  cachobj.cpp
  52.  *
  53.  *  Purpose:
  54.  * To cache objects in a temporary storage for later retrieval
  55.  * Can be created off of IHXCommonClassFactory.
  56.  * Currently supported only on the client side.
  57.  *
  58.  */
  59. #include "hxcom.h"
  60. #include "hxtypes.h"
  61. #include "hxresult.h"
  62. #include "hxguid.h"
  63. #include "timeval.h"
  64. #include "basepkt.h"
  65. #include "hxbuffer.h"
  66. #include "timebuff.h"
  67. #include "hxcache.h"
  68. #include "ihxpckts.h"
  69. #include "hxtbuf.h"
  70. #include "chunkres.h"
  71. #include "cachobj.h"
  72. #include "hxheap.h"
  73. #ifdef _DEBUG
  74. #undef HX_THIS_FILE
  75. static const char HX_THIS_FILE[] = __FILE__;
  76. #endif
  77. // HXFIFOCache...
  78. HXFIFOCache::HXFIFOCache() :
  79.       m_lRefCount(0)
  80.     , m_pChunkyRes(NULL)
  81.     , m_ulCurrentReadPosition(0)
  82.     , m_ulCurrentWritePosition(0)
  83. {
  84. }
  85. HXFIFOCache::~HXFIFOCache()
  86. {
  87.     Flush();
  88. }
  89. /*
  90.  * IUnknown methods
  91.  */
  92. /////////////////////////////////////////////////////////////////////////
  93. // Method:
  94. // IUnknown::QueryInterface
  95. // Purpose:
  96. // Implement this to export the interfaces supported by your 
  97. // object.
  98. //
  99. STDMETHODIMP HXFIFOCache::QueryInterface(REFIID riid, void** ppvObj)
  100. {
  101. QInterfaceList qiList[] =
  102. {
  103. { GET_IIDHANDLE(IID_IUnknown), this },
  104. { GET_IIDHANDLE(IID_IHXFIFOCache), (IHXFIFOCache*) this },
  105. };
  106.     return QIFind(qiList, QILISTSIZE(qiList), riid, ppvObj);   
  107. }
  108. /////////////////////////////////////////////////////////////////////////
  109. // Method:
  110. // IUnknown::AddRef
  111. // Purpose:
  112. // Everyone usually implements this the same... feel free to use
  113. // this implementation.
  114. //
  115. STDMETHODIMP_(ULONG32) HXFIFOCache::AddRef()
  116. {
  117.     return InterlockedIncrement(&m_lRefCount);
  118. }
  119. /////////////////////////////////////////////////////////////////////////
  120. // Method:
  121. // IUnknown::Release
  122. // Purpose:
  123. // Everyone usually implements this the same... feel free to use
  124. // this implementation.
  125. //
  126. STDMETHODIMP_(ULONG32) HXFIFOCache::Release()
  127. {
  128.     if (InterlockedDecrement(&m_lRefCount) > 0)
  129.     {
  130. return m_lRefCount;
  131.     }
  132.     delete this;
  133.     return 0;
  134. }
  135. /************************************************************************
  136.  * Method:
  137.  * IHXFIFOCache::Cache
  138.  * Purpose:
  139.  *     To cache objects in a temporary storage for later retrieval
  140.  *
  141.  *     Currently supported objects:
  142.  * IHXBuffer
  143.  * IHXValues
  144.  * IHXPacket
  145. // $Private:
  146.  * IHXTimeStampedBuffer
  147. // $EndPrivate.
  148.  *
  149.  */
  150. STDMETHODIMP HXFIFOCache::Cache(IUnknown*     pObject)
  151. {
  152.     HX_RESULT     theErr = HXR_UNEXPECTED;
  153.     IHXClientPacket*     pClientPacket = NULL;
  154.     IHXTimeStampedBuffer*  pTimeStampBuffer = NULL;
  155.     IHXBuffer*     pBuffer = NULL;
  156.     IHXPacket*     pPacket = NULL;
  157.     IHXValues*     pValues = NULL;
  158.     if (!m_pChunkyRes)
  159.     {
  160. m_pChunkyRes = new CChunkyRes;
  161.     }
  162.     if (pObject->QueryInterface(IID_IHXClientPacket, (void**) &pClientPacket) == HXR_OK)
  163.     {
  164. theErr = CacheClientPacket(pClientPacket);
  165. pClientPacket->Release();
  166.     }
  167.     else if (pObject->QueryInterface(IID_IHXTimeStampedBuffer, (void**) &pTimeStampBuffer) == HXR_OK)
  168.     {
  169. theErr = CacheTimestampBuffer(pTimeStampBuffer);
  170. pTimeStampBuffer->Release();
  171.     }
  172.     else if (pObject->QueryInterface(IID_IHXBuffer, (void**) &pBuffer) == HXR_OK)
  173.     {
  174. theErr = CacheBuffer(pBuffer);
  175. pBuffer->Release();
  176.     }
  177.     else if (pObject->QueryInterface(IID_IHXPacket, (void**) &pPacket) == HXR_OK)
  178.     {
  179. theErr = CachePacket(pPacket);
  180. pPacket->Release();
  181.     }
  182.     else if (pObject->QueryInterface(IID_IHXValues, (void**) &pValues) == HXR_OK)
  183.     {
  184. theErr = CacheValues(pValues);
  185. pValues->Release();
  186.     }
  187.     return theErr;
  188. }
  189. /************************************************************************
  190.  * Method:
  191.  *     IHXFIFOCache::Retrieve
  192.  * Purpose:
  193.  *
  194.  *
  195.  */
  196. STDMETHODIMP HXFIFOCache::Retrieve(REF(IUnknown*)  pObject)
  197. {
  198.     HX_RESULT theErr = HXR_OK;
  199.     UINT32 ulBytesRead = 0;
  200.     UINT32 ulBytesToRead = 0;
  201.     char* pData = NULL;
  202.     char* pCursor = NULL;
  203.     CHXBuffer* pBuffer = NULL;
  204.     ChunkyCacheLayout* pChunkyCacheLayout = NULL;
  205.     if (!m_pChunkyRes)
  206.     {
  207. theErr = HXR_UNEXPECTED;
  208. goto cleanup;
  209.     }
  210.     pObject = NULL;
  211.     
  212.     pChunkyCacheLayout = new ChunkyCacheLayout;
  213.     ulBytesToRead = sizeof(ChunkyCacheLayout);
  214.     // read Chunk Header Info
  215.     m_pChunkyRes->GetData(m_ulCurrentReadPosition,
  216.   (char*)pChunkyCacheLayout,
  217.   ulBytesToRead,
  218.   &ulBytesRead);
  219.     m_ulCurrentReadPosition += ulBytesRead;
  220.     if (ulBytesRead)
  221.     {
  222. HX_ASSERT(ulBytesToRead == ulBytesRead);
  223. ulBytesToRead = pChunkyCacheLayout->size - ulBytesRead;
  224. pData = new char[ulBytesToRead];
  225. // read the Chunk Data
  226. m_pChunkyRes->GetData(m_ulCurrentReadPosition,
  227.       (char*)pData,
  228.       ulBytesToRead,
  229.       &ulBytesRead);
  230. HX_ASSERT(ulBytesToRead == ulBytesRead);
  231. m_ulCurrentReadPosition += ulBytesRead;
  232. pCursor = pData;
  233. if (::IsEqualGUID(IID_IHXClientPacket, pChunkyCacheLayout->guid)) 
  234. {          
  235.     ClientPacket::UnPack((IHXClientPacket*&)pObject, pCursor, ulBytesRead);
  236. }
  237. else if (::IsEqualGUID(IID_IHXPacket, pChunkyCacheLayout->guid))
  238. {
  239.     CHXPacket::UnPack((IHXPacket*&)pObject, pCursor, ulBytesRead);
  240. }
  241. else if (::IsEqualGUID(IID_IHXTimeStampedBuffer, pChunkyCacheLayout->guid))
  242. {
  243.     CHXTimeStampedBuffer::UnPack((IHXTimeStampedBuffer*&)pObject, pCursor, ulBytesRead);
  244. }
  245. else if (::IsEqualGUID(IID_IHXBuffer, pChunkyCacheLayout->guid))
  246. {
  247.     pBuffer = new CHXBuffer();
  248.     pBuffer->Set((const UCHAR*)pCursor, ulBytesRead);
  249.     pBuffer->QueryInterface(IID_IHXBuffer, (void**)&pObject);
  250. }
  251. else
  252. {
  253.     theErr = HXR_NOTIMPL;
  254. }
  255.     }
  256. cleanup:
  257.     HX_DELETE(pChunkyCacheLayout);
  258.     HX_VECTOR_DELETE(pData);
  259.     
  260.     return theErr;
  261. }
  262. /************************************************************************
  263.  * Method:
  264.  *     IHXFIFOCache::Flush
  265.  * Purpose:
  266.  *
  267.  *
  268.  */
  269. STDMETHODIMP HXFIFOCache::Flush(void)
  270. {
  271.     m_ulCurrentReadPosition = 0;
  272.     m_ulCurrentWritePosition = 0;
  273.     HX_DELETE(m_pChunkyRes);
  274.     return HXR_OK;
  275. }
  276. HX_RESULT 
  277. HXFIFOCache::CacheClientPacket(IHXClientPacket* pClientPacket)
  278. {
  279.     HX_RESULT theErr = HXR_OK;
  280.     BOOL bContiguousDataPointer = FALSE;
  281.     UINT32 ulBytesWrote = 0;
  282.     UINT32 ulBytesToWrite = 0;
  283.     char* pData = NULL;
  284.     char* pCursor = NULL;
  285. #if !defined(HELIX_FEATURE_FULLGUID)
  286.     GUID tmp = IID_IHXClientPacket;
  287. #endif
  288.     if (!pClientPacket)
  289.     {
  290. theErr = HXR_FAILED;
  291. goto cleanup;
  292.     }
  293.     // caculate the size of client packet
  294.     ClientPacket::Pack(pClientPacket, NULL, ulBytesToWrite);
  295.     ulBytesToWrite += sizeof(ChunkyCacheLayout);
  296.     // check whether we have cont. memory chunk of the size needed
  297.     if (HXR_OK == m_pChunkyRes->GetContiguousDataPointer(m_ulCurrentWritePosition,
  298.  pData,
  299.  ulBytesToWrite) && pData)
  300.     {
  301. bContiguousDataPointer = TRUE;
  302. pCursor = pData;
  303.     }
  304.     // otherwise we allocated our own
  305.     else
  306.     {
  307. pData = new char[ulBytesToWrite];
  308. pCursor = pData;
  309.     }
  310.     // total chunk bytes
  311.     *pCursor++ = (BYTE)ulBytesToWrite; *pCursor++ = (BYTE)(ulBytesToWrite >> 8);
  312.     ulBytesWrote += 2;
  313.     // GUID
  314. #if !defined(HELIX_FEATURE_FULLGUID)
  315.     memcpy(pCursor, (char*)&tmp, sizeof(GUID)); /* Flawfinder: ignore */
  316. #else
  317.     memcpy(pCursor, (char*)&IID_IHXClientPacket, sizeof(GUID)); /* Flawfinder: ignore */
  318. #endif
  319.     pCursor += sizeof(GUID);
  320.     ulBytesWrote += sizeof(GUID);
  321.     // pack data
  322.     ClientPacket::Pack(pClientPacket, pCursor, ulBytesWrote);
  323.     if (!bContiguousDataPointer)
  324.     {
  325. // let the memory manager take care of the contingency
  326. theErr = m_pChunkyRes->SetData(m_ulCurrentWritePosition, pData, ulBytesWrote);
  327.     }
  328.     HX_ASSERT(ulBytesToWrite == ulBytesWrote);
  329.     // advance the write cursor
  330.     m_ulCurrentWritePosition += ulBytesToWrite;
  331. cleanup:
  332.     if (!bContiguousDataPointer)
  333.     {
  334. HX_VECTOR_DELETE(pData);
  335.     }
  336.     return theErr;
  337. }
  338. HX_RESULT 
  339. HXFIFOCache::CacheTimestampBuffer(IHXTimeStampedBuffer* pTimeStampBuffer)
  340. {
  341.     HX_RESULT theErr = HXR_OK;
  342.     BOOL bContiguousDataPointer = FALSE;
  343.     UINT32 ulBytesWrote = 0;
  344.     UINT32 ulBytesToWrite = 0;
  345.     char* pData = NULL;
  346.     char* pCursor = NULL;
  347. #if !defined(HELIX_FEATURE_FULLGUID)
  348.     GUID tmp = IID_IHXBuffer;
  349. #endif
  350.     if (!pTimeStampBuffer)
  351.     {
  352. theErr = HXR_FAILED;
  353. goto cleanup;
  354.     }
  355.     // caculate the size of buffer
  356.     CHXTimeStampedBuffer::Pack(pTimeStampBuffer, NULL, 0, ulBytesToWrite);
  357.     ulBytesToWrite += sizeof(ChunkyCacheLayout);
  358.     // check whether we have cont. memory chunk of the size needed
  359.     if (HXR_OK == m_pChunkyRes->GetContiguousDataPointer(m_ulCurrentWritePosition,
  360.  pData,
  361.  ulBytesToWrite) && pData)
  362.     {
  363. bContiguousDataPointer = TRUE;
  364. pCursor = pData;
  365.     }
  366.     // otherwise we allocated our own
  367.     else
  368.     {
  369. pData = new char[ulBytesToWrite];
  370. pCursor = pData;
  371.     }
  372.     // total chunk bytes
  373.     *pCursor++ = (BYTE)ulBytesToWrite; *pCursor++ = (BYTE)(ulBytesToWrite >> 8);
  374.     ulBytesWrote += 2;
  375.     // GUID
  376. #if !defined(HELIX_FEATURE_FULLGUID)
  377.     memcpy(pCursor, (char*)&tmp, sizeof(GUID)); /* Flawfinder: ignore */
  378. #else
  379.     memcpy(pCursor, (char*)&IID_IHXBuffer, sizeof(GUID)); /* Flawfinder: ignore */
  380. #endif
  381.     pCursor += sizeof(GUID);
  382.     ulBytesWrote += sizeof(GUID);
  383.     // pack data
  384.     CHXTimeStampedBuffer::Pack(pTimeStampBuffer, pCursor,
  385.                                ulBytesToWrite - ulBytesWrote, ulBytesWrote);
  386.     if (!bContiguousDataPointer)
  387.     {
  388. // let the memory manager take care of the contingency
  389. theErr = m_pChunkyRes->SetData(m_ulCurrentWritePosition, pData, ulBytesWrote);
  390.     }
  391.     HX_ASSERT(ulBytesToWrite == ulBytesWrote);
  392.     // advance the write cursor
  393.     m_ulCurrentWritePosition += ulBytesToWrite;
  394. cleanup:
  395.     if (!bContiguousDataPointer)
  396.     {
  397. HX_VECTOR_DELETE(pData);
  398.     }
  399.     return theErr;
  400. }
  401. HX_RESULT 
  402. HXFIFOCache::CacheBuffer(IHXBuffer* pBuffer)
  403. {
  404.     HX_RESULT theErr = HXR_OK;
  405.     BOOL bContiguousDataPointer = FALSE;
  406.     UINT32 ulBytesWrote = 0;
  407.     UINT32 ulBytesToWrite = 0;
  408.     char* pData = NULL;
  409.     char* pCursor = NULL;
  410. #if !defined(HELIX_FEATURE_FULLGUID)
  411.     GUID tmp = IID_IHXBuffer;
  412. #endif
  413.     if (!pBuffer)
  414.     {
  415. theErr = HXR_FAILED;
  416. goto cleanup;
  417.     }
  418.     // caculate the size of client packet
  419.     ulBytesToWrite = pBuffer->GetSize();
  420.     ulBytesToWrite += sizeof(ChunkyCacheLayout);
  421.     // check whether we have cont. memory chunk of the size needed
  422.     if (HXR_OK == m_pChunkyRes->GetContiguousDataPointer(m_ulCurrentWritePosition,
  423.  pData,
  424.  ulBytesToWrite) && pData)
  425.     {
  426. bContiguousDataPointer = TRUE;
  427. pCursor = pData;
  428.     }
  429.     // otherwise we allocated our own
  430.     else
  431.     {
  432. pData = new char[ulBytesToWrite];
  433. pCursor = pData;
  434.     }
  435.     // total chunk bytes
  436.     *pCursor++ = (BYTE)ulBytesToWrite; *pCursor++ = (BYTE)(ulBytesToWrite >> 8);
  437.     ulBytesWrote += 2;
  438.     // GUID
  439. #if !defined(HELIX_FEATURE_FULLGUID)
  440.     memcpy(pCursor, (char*)&tmp, sizeof(GUID)); /* Flawfinder: ignore */
  441. #else
  442.     memcpy(pCursor, (char*)&IID_IHXBuffer, sizeof(GUID)); /* Flawfinder: ignore */
  443. #endif
  444.     pCursor += sizeof(GUID);
  445.     ulBytesWrote += sizeof(GUID);
  446.     // pack data
  447.     memcpy(pCursor, (char*)pBuffer->GetBuffer(), pBuffer->GetSize()); /* Flawfinder: ignore */
  448.     if (!bContiguousDataPointer)
  449.     {
  450. // let the memory manager take care of the contingency
  451. theErr = m_pChunkyRes->SetData(m_ulCurrentWritePosition, pData, ulBytesWrote);
  452.     }
  453.     HX_ASSERT(ulBytesToWrite == ulBytesWrote);
  454.     // advance the write cursor
  455.     m_ulCurrentWritePosition += ulBytesToWrite;
  456. cleanup:
  457.     if (!bContiguousDataPointer)
  458.     {
  459. HX_VECTOR_DELETE(pData);
  460.     }
  461.     return theErr;
  462. }
  463. HX_RESULT 
  464. HXFIFOCache::CachePacket(IHXPacket* pPacket)
  465. {
  466.     HX_RESULT theErr = HXR_OK;
  467.     BOOL bContiguousDataPointer = FALSE;
  468.     UINT32 ulBytesWrote = 0;
  469.     UINT32 ulBytesToWrite = 0;
  470.     char* pData = NULL;
  471.     char* pCursor = NULL;
  472. #if !defined(HELIX_FEATURE_FULLGUID)
  473.     GUID tmp = IID_IHXPacket;
  474. #endif
  475.     if (!pPacket)
  476.     {
  477. theErr = HXR_FAILED;
  478. goto cleanup;
  479.     }
  480.     // caculate the size of client packet
  481.     CHXPacket::Pack(pPacket, NULL, ulBytesToWrite);
  482.     ulBytesToWrite += sizeof(ChunkyCacheLayout);
  483.     // check whether we have cont. memory chunk of the size needed
  484.     if (HXR_OK == m_pChunkyRes->GetContiguousDataPointer(m_ulCurrentWritePosition,
  485.  pData,
  486.  ulBytesToWrite) && pData)
  487.     {
  488. bContiguousDataPointer = TRUE;
  489. pCursor = pData;
  490.     }
  491.     // otherwise we allocated our own
  492.     else
  493.     {
  494. pData = new char[ulBytesToWrite];
  495. pCursor = pData;
  496.     }
  497.     // total chunk bytes
  498.     *pCursor++ = (BYTE)ulBytesToWrite; *pCursor++ = (BYTE)(ulBytesToWrite >> 8);
  499.     ulBytesWrote += 2;
  500.     // GUID
  501. #if !defined(HELIX_FEATURE_FULLGUID)
  502.     memcpy(pCursor, (char*)&tmp, sizeof(GUID)); /* Flawfinder: ignore */
  503. #else
  504.     memcpy(pCursor, (char*)&IID_IHXPacket, sizeof(GUID)); /* Flawfinder: ignore */
  505. #endif
  506.     pCursor += sizeof(GUID);
  507.     ulBytesWrote += sizeof(GUID);
  508.     // pack data
  509.     CHXPacket::Pack(pPacket, pCursor, ulBytesWrote);
  510.     if (!bContiguousDataPointer)
  511.     {
  512. // let the memory manager take care of the contingency
  513. theErr = m_pChunkyRes->SetData(m_ulCurrentWritePosition, pData, ulBytesWrote);
  514.     }
  515.     HX_ASSERT(ulBytesToWrite == ulBytesWrote);
  516.     // advance the write cursor
  517.     m_ulCurrentWritePosition += ulBytesToWrite;
  518. cleanup:
  519.     if (!bContiguousDataPointer)
  520.     {
  521. HX_VECTOR_DELETE(pData);
  522.     }
  523.     return theErr;
  524. }
  525. HX_RESULT 
  526. HXFIFOCache::CacheValues(IHXValues* pValues)
  527. {
  528.     // TBD
  529.     HX_RESULT theErr = HXR_NOTIMPL;
  530.     return theErr;
  531. }