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

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. #include "hxtypes.h"
  36. #include "hxresult.h"
  37. #include "hxcom.h"
  38. #include "ihxpckts.h"
  39. #include "chxpckts.h"
  40. #include "hxbuffer.h"
  41. #include "hxcppflags.h"
  42. #include "hxheap.h"
  43. #ifdef _DEBUG
  44. #undef HX_THIS_FILE
  45. static const char HX_THIS_FILE[] = __FILE__;
  46. #endif
  47. /////////////////////////////////////////
  48. // XXX - We can't use pnheap to debug mory leaks...
  49. // because of defining our own new and delete operations.
  50. //
  51. //  #include "hxheap.h"
  52. //  
  53. //  #ifdef _DEBUG
  54. //  #undef HX_THIS_FILE
  55. //  static const char HX_THIS_FILE[] = __FILE__;
  56. //  #endif
  57. /////////////////////////////////////////
  58. #ifdef PAULM_HXBUFFERSPACE
  59. extern UINT32* volatile g_pCHXBufferTotalData;
  60. void
  61. MoreBufferData(UINT32 ul)
  62. {
  63.     if (!g_pCHXBufferTotalData)
  64.     {
  65.         return;
  66.     }
  67.     (*g_pCHXBufferTotalData) += ul;
  68. }
  69. void
  70. LessBufferData(UINT32 ul)
  71. {
  72.     if (!g_pCHXBufferTotalData)
  73.     {
  74.         return;
  75.     }
  76.     if (ul > (*g_pCHXBufferTotalData))
  77.     {
  78.         (*g_pCHXBufferTotalData) = 0;
  79.     }
  80.     else
  81.     {   
  82.         (*g_pCHXBufferTotalData) -= ul;
  83.     }
  84. }
  85. UINT32
  86. GetBufferDataSize()
  87. {
  88.     if (!g_pCHXBufferTotalData)
  89.         return 0;
  90.     return (*g_pCHXBufferTotalData);
  91. }
  92. #endif
  93. CHXBuffer::CHXBuffer()
  94.     : m_lRefCount(0)
  95.     , m_bJustPointToExistingData(FALSE)
  96.     , m_ulAllocLength(0)
  97. {
  98.     m_BigData.m_pData = NULL;
  99.     m_BigData.m_ulLength = 0;
  100.     m_BigData.m_FreeWithMallocInterfaceIfAvail = TRUE;
  101.     m_ShortData[MaxPnbufShortDataLen] = 0;
  102. }
  103. CHXBuffer::CHXBuffer(UCHAR* pData, UINT32 ulLength, BOOL bOwnBuffer)
  104.     : m_lRefCount(0)
  105.     , m_ulAllocLength(ulLength)
  106. {
  107.     m_BigData.m_pData = pData;
  108.     m_BigData.m_ulLength = ulLength;
  109.     m_BigData.m_FreeWithMallocInterfaceIfAvail = FALSE;
  110.     m_ShortData[MaxPnbufShortDataLen] = BigDataTag;
  111.     // This constructor does not actually allocate memory, so we may want
  112.     // to use it in a way that does not deallocate memory when it is deleted.
  113.     m_bJustPointToExistingData = !bOwnBuffer;
  114. }
  115. CHXBuffer::~CHXBuffer()
  116. {
  117.     // If this buffer just points to data/memory that is actually 'owned' by
  118.     // another buffer, our destructor must not de-allocate that memory.
  119.     if( m_bJustPointToExistingData == TRUE )
  120.     {
  121. return;
  122.     }
  123.     if (!IsShort() && m_BigData.m_pData)
  124.     {
  125. #ifdef PAULM_HXBUFFERSPACE
  126.         LessBufferData(m_ulAllocLength);
  127. #endif
  128.         Deallocate(m_BigData.m_pData);
  129.         m_ulAllocLength = 0;
  130.     }
  131. }
  132. bool CHXBuffer::IsShort() const
  133. {
  134.     return m_ShortData[MaxPnbufShortDataLen] != BigDataTag;
  135. }
  136. #if !defined(HELIX_CONFIG_NOSTATICS)
  137. // static member initalization...
  138. IMalloc* CHXBuffer::m_zMallocInterface = NULL;
  139. #endif
  140. BOOL CHXBuffer::FreeWithMallocInterface() const
  141. {
  142. #if !defined(HELIX_CONFIG_NOSTATICS)
  143.     return !IsShort() && 
  144.         m_BigData.m_FreeWithMallocInterfaceIfAvail && 
  145.         m_zMallocInterface != NULL;
  146. #else
  147.     return FALSE;
  148. #endif
  149. }
  150. void CHXBuffer::SetAllocator(IMalloc* pMalloc)
  151. {
  152. #if !defined(HELIX_CONFIG_NOSTATICS)
  153.     if (pMalloc)
  154.     {
  155.         HX_RELEASE(m_zMallocInterface);
  156.         m_zMallocInterface = pMalloc;
  157.         m_zMallocInterface->AddRef();
  158.     }
  159. #endif
  160. }
  161. void CHXBuffer::ReleaseAllocator()
  162. {
  163. #if !defined(HELIX_CONFIG_NOSTATICS)
  164.     HX_RELEASE(m_zMallocInterface);
  165. #endif
  166. }
  167. /////////////////////////////////////////////////////////////////////////
  168. // Method:
  169. // IUnknown::QueryInterface
  170. // Purpose:
  171. // Implement this to export the interfaces supported by your 
  172. // object.
  173. //
  174. STDMETHODIMP CHXBuffer::QueryInterface(REFIID riid, void** ppvObj)
  175. {
  176.     if (IsEqualIID(riid, IID_IUnknown))
  177.     {
  178.             AddRef();
  179.             *ppvObj = this;
  180.             return HXR_OK;
  181.     }
  182.     else if (IsEqualIID(riid, IID_IHXBuffer))
  183.     {
  184.             AddRef();
  185.             *ppvObj = (IHXBuffer*)this;
  186.             return HXR_OK;
  187.     }
  188.     *ppvObj = NULL;
  189.     return HXR_NOINTERFACE;
  190. }
  191. /////////////////////////////////////////////////////////////////////////
  192. // Method:
  193. // IUnknown::AddRef
  194. // Purpose:
  195. // Everyone usually implements this the same... feel free to use
  196. // this implementation.
  197. //
  198. STDMETHODIMP_(ULONG32) CHXBuffer::AddRef()
  199. {
  200.     return InterlockedIncrement(&m_lRefCount);
  201. }
  202. /////////////////////////////////////////////////////////////////////////
  203. // Method:
  204. // IUnknown::Release
  205. // Purpose:
  206. // Everyone usually implements this the same... feel free to use
  207. // this implementation.
  208. //
  209. STDMETHODIMP_(ULONG32) CHXBuffer::Release()
  210. {
  211.     if (InterlockedDecrement(&m_lRefCount) > 0)
  212.     {
  213.         return m_lRefCount;
  214.     }
  215.     delete this;
  216.     return 0;
  217. }
  218. /*
  219.  * IHXBuffer methods
  220.  */
  221. /************************************************************************
  222.  * Method:
  223.  * IHXBuffer::Get
  224.  * Purpose:
  225.  * TBD
  226.  */
  227. STDMETHODIMP CHXBuffer::Get
  228. (
  229.     REF(UCHAR*) pData, 
  230.     REF(ULONG32) ulLength
  231. )
  232. {
  233.     // Whenever a COM object is returned out of an
  234.     // interface, it should be AddRef()'d. But this is
  235.     // not a COM object, it is only a buffer...
  236.     if (IsShort())
  237.     {
  238.         pData    = m_ShortData;
  239.         ulLength = m_ShortData[MaxPnbufShortDataLen];
  240.     }
  241.     else
  242.     {
  243.         pData    = m_BigData.m_pData;
  244.         ulLength = m_BigData.m_ulLength;
  245.     }
  246.     return HXR_OK;
  247. }
  248. /************************************************************************
  249.  * Method:
  250.  * IHXBuffer::Set
  251.  * Purpose:
  252.  * TBD
  253.  */
  254. STDMETHODIMP CHXBuffer::Set
  255. (
  256.     const UCHAR* pData, 
  257.     ULONG32 ulLength
  258. )
  259. {
  260.     HX_RESULT res = SetSize(ulLength, FALSE); // don't copy data
  261.     if (FAILED(res)) return res;
  262.     HX_ASSERT(GetSize() == ulLength);
  263.     memcpy(GetBuffer(), pData, (ulLength <= GetSize() ? ulLength : GetSize())); /* Flawfinder: ignore */
  264.     return HXR_OK;
  265. }
  266. /************************************************************************
  267.  * Method:
  268.  * SetSize
  269.  * Purpose:
  270.  * TBD
  271.  */
  272. HX_RESULT CHXBuffer::SetSize(ULONG32 ulLength, BOOL copyExistingData)
  273. {
  274.     /* We allow changing the packet info when it is owned
  275.      * by atmost one user.
  276.      */
  277.     if (m_lRefCount > 1)
  278.     {
  279.         return HXR_UNEXPECTED;
  280.     }
  281.     if (ulLength <= GetSize())
  282.     {
  283.         if (IsShort()) 
  284.         {
  285.             m_ShortData[MaxPnbufShortDataLen] = (UCHAR)ulLength;
  286.         }
  287.         else
  288.         {
  289.             m_BigData.m_ulLength = ulLength;
  290.         }
  291.         return HXR_OK;
  292.     }
  293.     if (ulLength <= MaxPnbufShortDataLen)
  294.     {
  295.         if (IsShort())
  296.         {
  297.             // New size short, old size short
  298.             // Nothing to do
  299.         }
  300.         else
  301.         {
  302.             // New size short, old size big
  303.             UCHAR temp[MaxPnbufShortDataLen];
  304.             memcpy(temp, m_BigData.m_pData, ulLength); /* Flawfinder: ignore */
  305.             Deallocate(m_BigData.m_pData);
  306.             m_ulAllocLength = 0;
  307.             memcpy(m_ShortData, temp, ulLength); /* Flawfinder: ignore */
  308.         }
  309.         m_ShortData[MaxPnbufShortDataLen] = (UCHAR)ulLength;
  310.     }
  311.     else
  312.     {
  313.         if (IsShort())
  314.         {
  315.             // New size big, old size short
  316.             UCHAR* pNewData = Allocate(ulLength);
  317.             m_ulAllocLength = ulLength;
  318.             // Allocate new data
  319.             // Treat alloc error
  320.             if (!pNewData)
  321.             {
  322.                 return HXR_OUTOFMEMORY;
  323.             }
  324.             // copy memory
  325.             if (copyExistingData) 
  326.             {
  327.                 memcpy(pNewData, m_ShortData, m_ShortData[MaxPnbufShortDataLen]); /* Flawfinder: ignore */
  328.             }
  329.             // Assign data
  330.             m_BigData.m_pData = pNewData;
  331.             // Force length
  332.             m_BigData.m_ulLength = ulLength;
  333.             // Init extra field
  334.             m_BigData.m_FreeWithMallocInterfaceIfAvail = TRUE;
  335.             // Mark data as big
  336.             m_ShortData[MaxPnbufShortDataLen] = BigDataTag;
  337.         }
  338.         else
  339.         {
  340.             if( ulLength <= m_ulAllocLength )
  341.             {
  342.                m_BigData.m_ulLength = ulLength;
  343.                m_BigData.m_FreeWithMallocInterfaceIfAvail = TRUE;
  344.                return HXR_OK;
  345.             }
  346.             // New size big, old size big
  347.             // Reallocate the data
  348.             UCHAR* pTemp = copyExistingData 
  349.                 ? Reallocate(m_BigData.m_pData, m_BigData.m_ulLength, ulLength) 
  350.                 : Allocate(ulLength);
  351.             // Treat alloc error
  352.             if (!pTemp)
  353.             {
  354.                 return HXR_OUTOFMEMORY;
  355.             }
  356.             m_ulAllocLength = ulLength;
  357.             // Deallocate old memory
  358.             if (!copyExistingData) 
  359.             {
  360.                 Deallocate(m_BigData.m_pData);
  361.             }
  362.             // Assign data
  363.             m_BigData.m_pData = pTemp;
  364.             // Force length
  365.             m_BigData.m_ulLength = ulLength;
  366.             // Set flag
  367.             m_BigData.m_FreeWithMallocInterfaceIfAvail = TRUE;
  368.         }
  369.     }
  370.     
  371.     return HXR_OK;
  372. }
  373. /************************************************************************
  374.  * Method:
  375.  * IHXBuffer::SetSize
  376.  * Purpose:
  377.  * TBD
  378.  */
  379. UCHAR* CHXBuffer::Allocate(UINT32 size) const
  380. {
  381. #if !defined(HELIX_CONFIG_NOSTATICS)
  382.     if (m_zMallocInterface)
  383.     {
  384.         return (UCHAR*) m_zMallocInterface->Alloc(size);
  385.     }
  386.     else
  387. #endif
  388.     {
  389. #ifdef HX_CPP_MALLOC_SUPPORTED
  390.         return (UCHAR*)malloc(size);
  391. #else
  392.         return new UCHAR[size];
  393. #endif
  394.     }
  395. }
  396. /************************************************************************
  397.  * Method:
  398.  * IHXBuffer::SetSize
  399.  * Purpose:
  400.  * TBD
  401.  */
  402. UCHAR* CHXBuffer::Reallocate(UCHAR* p, UINT32 oldSize, UINT32 newSize) const
  403. {
  404. #if !defined(HELIX_CONFIG_NOSTATICS)
  405.     if (m_zMallocInterface)
  406.     {
  407.         UCHAR* pNewData = (UCHAR*)m_zMallocInterface->Alloc(newSize);
  408.         if (!pNewData) return 0;
  409.         // copy memory
  410.         memcpy(pNewData, p, min(oldSize, newSize)); /* Flawfinder: ignore */
  411.         m_zMallocInterface->Free(p);
  412.         return pNewData;
  413.     }
  414.     else
  415. #endif
  416.     {
  417. #ifdef HX_CPP_MALLOC_SUPPORTED
  418.         return (UCHAR*)realloc(p, newSize);
  419. #else
  420.         UCHAR* pNewData = new UCHAR[newSize];
  421.         if (pNewData)
  422.         {
  423.             memcpy(pNewData, p, min(oldSize, newSize)); /* Flawfinder: ignore */
  424.             delete[] p;
  425.         }
  426.         return pNewData;
  427. #endif
  428.     }
  429. }
  430. /************************************************************************
  431.  * Method:
  432.  * IHXBuffer::SetSize
  433.  * Purpose:
  434.  * TBD
  435.  */
  436. void CHXBuffer::Deallocate(UCHAR* p) const
  437. {
  438. #if !defined(HELIX_CONFIG_NOSTATICS)
  439.     if (FreeWithMallocInterface())
  440.     {
  441.         m_zMallocInterface->Free(p);
  442.     }
  443.     else
  444. #endif
  445.     {
  446. #ifdef HX_CPP_MALLOC_SUPPORTED
  447.         free(p);
  448. #else
  449.         delete[] p;
  450. #endif
  451.     }
  452. }
  453. /************************************************************************
  454.  * Method:
  455.  * IHXBuffer::SetSize
  456.  * Purpose:
  457.  * TBD
  458.  */
  459. STDMETHODIMP CHXBuffer::SetSize(ULONG32 ulLength)
  460. {
  461.     return SetSize(ulLength, TRUE);
  462. }
  463. /************************************************************************
  464.  * Method:
  465.  * IHXBuffer::GetSize
  466.  * Purpose:
  467.  * TBD
  468.  */
  469. STDMETHODIMP_(ULONG32) CHXBuffer::GetSize()
  470. {
  471.     return IsShort() ? m_ShortData[MaxPnbufShortDataLen] : m_BigData.m_ulLength;
  472. }
  473. /************************************************************************
  474.  * Method:
  475.  * IHXBuffer::GetBuffer
  476.  * Purpose:
  477.  * TBD
  478.  */
  479. STDMETHODIMP_(UCHAR*) CHXBuffer::GetBuffer()
  480. {
  481.     // Whenever a COM object is returned out of an
  482.     // interface, it should be AddRef()'d. But this is
  483.     // not a COM object, it is only a buffer...
  484.     return IsShort() ? m_ShortData : m_BigData.m_pData;
  485. }
  486. HX_RESULT 
  487. CHXBuffer::FromCharArray
  488. (
  489.     const char* szIn, 
  490.     IHXBuffer** ppbufOut
  491. )
  492. {
  493.     if (!szIn)
  494.     {
  495.         *ppbufOut = NULL;
  496.         return HXR_FAIL;
  497.     }
  498.     return FromCharArray(szIn, strlen(szIn)+1, ppbufOut);
  499. }
  500. HX_RESULT 
  501. CHXBuffer::FromCharArray
  502. (
  503.     const char* szIn, 
  504.     UINT32 ulLength, 
  505.     IHXBuffer** ppbufOut
  506. )
  507. {
  508.     if (!szIn)
  509.     {
  510.         *ppbufOut = NULL;
  511.         return HXR_FAIL;
  512.     }
  513.     (*ppbufOut) = new CHXBuffer;
  514.     if((*ppbufOut))
  515.     {
  516.         (*ppbufOut)->AddRef();
  517.         (*ppbufOut)->Set((const unsigned char*)szIn, ulLength);
  518.         return HXR_OK;
  519.     }
  520.     return HXR_OUTOFMEMORY;
  521. }