hxbuffer.cpp
上传用户:zhongxx05
上传日期:2007-06-06
资源大小:33641k
文件大小:14k
- /* ***** BEGIN LICENSE BLOCK *****
- * Version: RCSL 1.0/RPSL 1.0
- *
- * Portions Copyright (c) 1995-2002 RealNetworks, Inc. All Rights Reserved.
- *
- * The contents of this file, and the files included with this file, are
- * subject to the current version of the RealNetworks Public Source License
- * Version 1.0 (the "RPSL") available at
- * http://www.helixcommunity.org/content/rpsl unless you have licensed
- * the file under the RealNetworks Community Source License Version 1.0
- * (the "RCSL") available at http://www.helixcommunity.org/content/rcsl,
- * in which case the RCSL will apply. You may also obtain the license terms
- * directly from RealNetworks. You may not use this file except in
- * compliance with the RPSL or, if you have a valid RCSL with RealNetworks
- * applicable to this file, the RCSL. Please see the applicable RPSL or
- * RCSL for the rights, obligations and limitations governing use of the
- * contents of the file.
- *
- * This file is part of the Helix DNA Technology. RealNetworks is the
- * developer of the Original Code and owns the copyrights in the portions
- * it created.
- *
- * This file, and the files included with this file, is distributed and made
- * available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS
- * FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- *
- * Technology Compatibility Kit Test Suite(s) Location:
- * http://www.helixcommunity.org/content/tck
- *
- * Contributor(s):
- *
- * ***** END LICENSE BLOCK ***** */
- #include "hxtypes.h"
- #include "hxresult.h"
- #include "hxcom.h"
- #include "ihxpckts.h"
- #include "chxpckts.h"
- #include "hxbuffer.h"
- #include "hxcppflags.h"
- #include "hxheap.h"
- #ifdef _DEBUG
- #undef HX_THIS_FILE
- static const char HX_THIS_FILE[] = __FILE__;
- #endif
- /////////////////////////////////////////
- // XXX - We can't use pnheap to debug mory leaks...
- // because of defining our own new and delete operations.
- //
- // #include "hxheap.h"
- //
- // #ifdef _DEBUG
- // #undef HX_THIS_FILE
- // static const char HX_THIS_FILE[] = __FILE__;
- // #endif
- /////////////////////////////////////////
- #ifdef PAULM_HXBUFFERSPACE
- extern UINT32* volatile g_pCHXBufferTotalData;
- void
- MoreBufferData(UINT32 ul)
- {
- if (!g_pCHXBufferTotalData)
- {
- return;
- }
- (*g_pCHXBufferTotalData) += ul;
- }
- void
- LessBufferData(UINT32 ul)
- {
- if (!g_pCHXBufferTotalData)
- {
- return;
- }
- if (ul > (*g_pCHXBufferTotalData))
- {
- (*g_pCHXBufferTotalData) = 0;
- }
- else
- {
- (*g_pCHXBufferTotalData) -= ul;
- }
- }
- UINT32
- GetBufferDataSize()
- {
- if (!g_pCHXBufferTotalData)
- return 0;
- return (*g_pCHXBufferTotalData);
- }
- #endif
- CHXBuffer::CHXBuffer()
- : m_lRefCount(0)
- , m_bJustPointToExistingData(FALSE)
- , m_ulAllocLength(0)
- {
- m_BigData.m_pData = NULL;
- m_BigData.m_ulLength = 0;
- m_BigData.m_FreeWithMallocInterfaceIfAvail = TRUE;
- m_ShortData[MaxPnbufShortDataLen] = 0;
- }
- CHXBuffer::CHXBuffer(UCHAR* pData, UINT32 ulLength, BOOL bOwnBuffer)
- : m_lRefCount(0)
- , m_ulAllocLength(ulLength)
- {
- m_BigData.m_pData = pData;
- m_BigData.m_ulLength = ulLength;
- m_BigData.m_FreeWithMallocInterfaceIfAvail = FALSE;
- m_ShortData[MaxPnbufShortDataLen] = BigDataTag;
- // This constructor does not actually allocate memory, so we may want
- // to use it in a way that does not deallocate memory when it is deleted.
- m_bJustPointToExistingData = !bOwnBuffer;
- }
- CHXBuffer::~CHXBuffer()
- {
- // If this buffer just points to data/memory that is actually 'owned' by
- // another buffer, our destructor must not de-allocate that memory.
- if( m_bJustPointToExistingData == TRUE )
- {
- return;
- }
- if (!IsShort() && m_BigData.m_pData)
- {
- #ifdef PAULM_HXBUFFERSPACE
- LessBufferData(m_ulAllocLength);
- #endif
- Deallocate(m_BigData.m_pData);
- m_ulAllocLength = 0;
- }
- }
- bool CHXBuffer::IsShort() const
- {
- return m_ShortData[MaxPnbufShortDataLen] != BigDataTag;
- }
- #if !defined(HELIX_CONFIG_NOSTATICS)
- // static member initalization...
- IMalloc* CHXBuffer::m_zMallocInterface = NULL;
- #endif
- BOOL CHXBuffer::FreeWithMallocInterface() const
- {
- #if !defined(HELIX_CONFIG_NOSTATICS)
- return !IsShort() &&
- m_BigData.m_FreeWithMallocInterfaceIfAvail &&
- m_zMallocInterface != NULL;
- #else
- return FALSE;
- #endif
- }
- void CHXBuffer::SetAllocator(IMalloc* pMalloc)
- {
- #if !defined(HELIX_CONFIG_NOSTATICS)
- if (pMalloc)
- {
- HX_RELEASE(m_zMallocInterface);
- m_zMallocInterface = pMalloc;
- m_zMallocInterface->AddRef();
- }
- #endif
- }
- void CHXBuffer::ReleaseAllocator()
- {
- #if !defined(HELIX_CONFIG_NOSTATICS)
- HX_RELEASE(m_zMallocInterface);
- #endif
- }
- /////////////////////////////////////////////////////////////////////////
- // Method:
- // IUnknown::QueryInterface
- // Purpose:
- // Implement this to export the interfaces supported by your
- // object.
- //
- STDMETHODIMP CHXBuffer::QueryInterface(REFIID riid, void** ppvObj)
- {
- if (IsEqualIID(riid, IID_IUnknown))
- {
- AddRef();
- *ppvObj = this;
- return HXR_OK;
- }
- else if (IsEqualIID(riid, IID_IHXBuffer))
- {
- AddRef();
- *ppvObj = (IHXBuffer*)this;
- return HXR_OK;
- }
- *ppvObj = NULL;
- return HXR_NOINTERFACE;
- }
- /////////////////////////////////////////////////////////////////////////
- // Method:
- // IUnknown::AddRef
- // Purpose:
- // Everyone usually implements this the same... feel free to use
- // this implementation.
- //
- STDMETHODIMP_(ULONG32) CHXBuffer::AddRef()
- {
- return InterlockedIncrement(&m_lRefCount);
- }
- /////////////////////////////////////////////////////////////////////////
- // Method:
- // IUnknown::Release
- // Purpose:
- // Everyone usually implements this the same... feel free to use
- // this implementation.
- //
- STDMETHODIMP_(ULONG32) CHXBuffer::Release()
- {
- if (InterlockedDecrement(&m_lRefCount) > 0)
- {
- return m_lRefCount;
- }
- delete this;
- return 0;
- }
- /*
- * IHXBuffer methods
- */
- /************************************************************************
- * Method:
- * IHXBuffer::Get
- * Purpose:
- * TBD
- */
- STDMETHODIMP CHXBuffer::Get
- (
- REF(UCHAR*) pData,
- REF(ULONG32) ulLength
- )
- {
- // Whenever a COM object is returned out of an
- // interface, it should be AddRef()'d. But this is
- // not a COM object, it is only a buffer...
- if (IsShort())
- {
- pData = m_ShortData;
- ulLength = m_ShortData[MaxPnbufShortDataLen];
- }
- else
- {
- pData = m_BigData.m_pData;
- ulLength = m_BigData.m_ulLength;
- }
- return HXR_OK;
- }
- /************************************************************************
- * Method:
- * IHXBuffer::Set
- * Purpose:
- * TBD
- */
- STDMETHODIMP CHXBuffer::Set
- (
- const UCHAR* pData,
- ULONG32 ulLength
- )
- {
- HX_RESULT res = SetSize(ulLength, FALSE); // don't copy data
- if (FAILED(res)) return res;
- HX_ASSERT(GetSize() == ulLength);
- memcpy(GetBuffer(), pData, (ulLength <= GetSize() ? ulLength : GetSize())); /* Flawfinder: ignore */
- return HXR_OK;
- }
- /************************************************************************
- * Method:
- * SetSize
- * Purpose:
- * TBD
- */
- HX_RESULT CHXBuffer::SetSize(ULONG32 ulLength, BOOL copyExistingData)
- {
- /* We allow changing the packet info when it is owned
- * by atmost one user.
- */
- if (m_lRefCount > 1)
- {
- return HXR_UNEXPECTED;
- }
- if (ulLength <= GetSize())
- {
- if (IsShort())
- {
- m_ShortData[MaxPnbufShortDataLen] = (UCHAR)ulLength;
- }
- else
- {
- m_BigData.m_ulLength = ulLength;
- }
- return HXR_OK;
- }
- if (ulLength <= MaxPnbufShortDataLen)
- {
- if (IsShort())
- {
- // New size short, old size short
- // Nothing to do
- }
- else
- {
- // New size short, old size big
- UCHAR temp[MaxPnbufShortDataLen];
- memcpy(temp, m_BigData.m_pData, ulLength); /* Flawfinder: ignore */
- Deallocate(m_BigData.m_pData);
- m_ulAllocLength = 0;
- memcpy(m_ShortData, temp, ulLength); /* Flawfinder: ignore */
- }
- m_ShortData[MaxPnbufShortDataLen] = (UCHAR)ulLength;
- }
- else
- {
- if (IsShort())
- {
- // New size big, old size short
- UCHAR* pNewData = Allocate(ulLength);
- m_ulAllocLength = ulLength;
- // Allocate new data
- // Treat alloc error
- if (!pNewData)
- {
- return HXR_OUTOFMEMORY;
- }
- // copy memory
- if (copyExistingData)
- {
- memcpy(pNewData, m_ShortData, m_ShortData[MaxPnbufShortDataLen]); /* Flawfinder: ignore */
- }
- // Assign data
- m_BigData.m_pData = pNewData;
- // Force length
- m_BigData.m_ulLength = ulLength;
- // Init extra field
- m_BigData.m_FreeWithMallocInterfaceIfAvail = TRUE;
- // Mark data as big
- m_ShortData[MaxPnbufShortDataLen] = BigDataTag;
- }
- else
- {
- if( ulLength <= m_ulAllocLength )
- {
- m_BigData.m_ulLength = ulLength;
- m_BigData.m_FreeWithMallocInterfaceIfAvail = TRUE;
- return HXR_OK;
- }
- // New size big, old size big
- // Reallocate the data
- UCHAR* pTemp = copyExistingData
- ? Reallocate(m_BigData.m_pData, m_BigData.m_ulLength, ulLength)
- : Allocate(ulLength);
- // Treat alloc error
- if (!pTemp)
- {
- return HXR_OUTOFMEMORY;
- }
- m_ulAllocLength = ulLength;
- // Deallocate old memory
- if (!copyExistingData)
- {
- Deallocate(m_BigData.m_pData);
- }
- // Assign data
- m_BigData.m_pData = pTemp;
- // Force length
- m_BigData.m_ulLength = ulLength;
- // Set flag
- m_BigData.m_FreeWithMallocInterfaceIfAvail = TRUE;
- }
- }
-
- return HXR_OK;
- }
- /************************************************************************
- * Method:
- * IHXBuffer::SetSize
- * Purpose:
- * TBD
- */
- UCHAR* CHXBuffer::Allocate(UINT32 size) const
- {
- #if !defined(HELIX_CONFIG_NOSTATICS)
- if (m_zMallocInterface)
- {
- return (UCHAR*) m_zMallocInterface->Alloc(size);
- }
- else
- #endif
- {
- #ifdef HX_CPP_MALLOC_SUPPORTED
- return (UCHAR*)malloc(size);
- #else
- return new UCHAR[size];
- #endif
- }
- }
- /************************************************************************
- * Method:
- * IHXBuffer::SetSize
- * Purpose:
- * TBD
- */
- UCHAR* CHXBuffer::Reallocate(UCHAR* p, UINT32 oldSize, UINT32 newSize) const
- {
- #if !defined(HELIX_CONFIG_NOSTATICS)
- if (m_zMallocInterface)
- {
- UCHAR* pNewData = (UCHAR*)m_zMallocInterface->Alloc(newSize);
- if (!pNewData) return 0;
- // copy memory
- memcpy(pNewData, p, min(oldSize, newSize)); /* Flawfinder: ignore */
- m_zMallocInterface->Free(p);
- return pNewData;
- }
- else
- #endif
- {
- #ifdef HX_CPP_MALLOC_SUPPORTED
- return (UCHAR*)realloc(p, newSize);
- #else
- UCHAR* pNewData = new UCHAR[newSize];
- if (pNewData)
- {
- memcpy(pNewData, p, min(oldSize, newSize)); /* Flawfinder: ignore */
- delete[] p;
- }
- return pNewData;
- #endif
- }
- }
- /************************************************************************
- * Method:
- * IHXBuffer::SetSize
- * Purpose:
- * TBD
- */
- void CHXBuffer::Deallocate(UCHAR* p) const
- {
- #if !defined(HELIX_CONFIG_NOSTATICS)
- if (FreeWithMallocInterface())
- {
- m_zMallocInterface->Free(p);
- }
- else
- #endif
- {
- #ifdef HX_CPP_MALLOC_SUPPORTED
- free(p);
- #else
- delete[] p;
- #endif
- }
- }
- /************************************************************************
- * Method:
- * IHXBuffer::SetSize
- * Purpose:
- * TBD
- */
- STDMETHODIMP CHXBuffer::SetSize(ULONG32 ulLength)
- {
- return SetSize(ulLength, TRUE);
- }
- /************************************************************************
- * Method:
- * IHXBuffer::GetSize
- * Purpose:
- * TBD
- */
- STDMETHODIMP_(ULONG32) CHXBuffer::GetSize()
- {
- return IsShort() ? m_ShortData[MaxPnbufShortDataLen] : m_BigData.m_ulLength;
- }
- /************************************************************************
- * Method:
- * IHXBuffer::GetBuffer
- * Purpose:
- * TBD
- */
- STDMETHODIMP_(UCHAR*) CHXBuffer::GetBuffer()
- {
- // Whenever a COM object is returned out of an
- // interface, it should be AddRef()'d. But this is
- // not a COM object, it is only a buffer...
- return IsShort() ? m_ShortData : m_BigData.m_pData;
- }
- HX_RESULT
- CHXBuffer::FromCharArray
- (
- const char* szIn,
- IHXBuffer** ppbufOut
- )
- {
- if (!szIn)
- {
- *ppbufOut = NULL;
- return HXR_FAIL;
- }
- return FromCharArray(szIn, strlen(szIn)+1, ppbufOut);
- }
- HX_RESULT
- CHXBuffer::FromCharArray
- (
- const char* szIn,
- UINT32 ulLength,
- IHXBuffer** ppbufOut
- )
- {
- if (!szIn)
- {
- *ppbufOut = NULL;
- return HXR_FAIL;
- }
- (*ppbufOut) = new CHXBuffer;
- if((*ppbufOut))
- {
- (*ppbufOut)->AddRef();
- (*ppbufOut)->Set((const unsigned char*)szIn, ulLength);
- return HXR_OK;
- }
- return HXR_OUTOFMEMORY;
- }