📄 chxfgbuf.h
字号:
/* ***** 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 ***** */
#ifndef _HXFGBUF_H_
#define _HXFGBUF_H_
/*
* IHXFragmentedBuffer
* STDMETHOD(GetEnumerator)(REF(IEnumHXFragmentedBuffer *));
* STDMETHOD(Prepend)(IHXBuffer *pBufferFrom, UINT32 ulStartFrom, UINT32 ulLengthFrom);
* STDMETHOD(Append)(IHXBuffer *pBufferFrom, UINT32 ulStartFrom, UINT32 ulLengthFrom);
* STDMETHOD(Insert)(IHXBuffer *pBufferFrom, UINT32 ulStartFrom, UINT32 ulLengthFrom, UINT32 ulStartTo);
* STDMETHOD(Replace)(IHXBuffer *pBufferFrom, UINT32 ulStartFrom, UINT32 ulLengthFrom, UINT32 ulStartTo);
* STDMETHOD(Get)(UINT32 ulStartFrom, UINT32 ulLengthFrom, REF(UCHAR*) pData, REF(UINT32) ulLength);
* STDMETHOD_(UCHAR*, GetBuffer)(UINT32 ulStartFrom, UINT32 ulLengthFrom);
*
* IEnumHXFragmentedBuffer
* STDMETHOD(Reset)();
* STDMETHOD(Next)(UINT32 ulRequested, IHXBuffer *[]arrpbufReturned, REF(UINT32) ulReturned);
* STDMETHOD(Skip)(UINT32 ulNumToSkip);
* STDMETHOD(Clone)(REF(IEnumHXFragmentedBuffer *)ppefbufClone);
*/
#include "hxtypes.h"
#include "unkimp.h"
#include "ihxfgbuf.h"
#include "hxbuffer.h"
#include "arrenum.h"
DECLARE_INTERFACE_ARRAY_ENUMERATOR(IHXBuffer, IHXEnumFragmentedBuffer);
/*
* This class is to allow fragment(s) to be
* inserted into the middle of existing buffers
* without re-copying the bytes.
*
* Before:
* ...
* IHXBuffer[100]
* ...
*
* After:
* ...
* (_CBufferFragment(0,20))IHXBuffer[20]----\
* (New)IHXBuffer[43] -->IHXBuffer[100]
* (_CBufferFragment(21,80)IHXBuffer[80]----/
* ...
*
* XXX Optimize by overriding the new operator.
*
* The local implementation should maintain a
* static array of BufferFragment arrays
* (BufferFragment[n][32]), and return the next
* free one.
* When all BFs are in use, the first dimension
* should be re-alloced to twice it's size
* (BufferFragment*[n*2]). The existing pointers
* are then copied into it. A new block
* of memory to cover the second dimension of
* each of the new locations in the first dimension
* is alloced, (BufferFragment[n*32])
* then its contents are distrubuted to the first
* array.
*
* This has several benefits:
* - not copying the data around when growing.
* - Balancing allocs with wasted space.
* - Not allocing for every new object.
* - Fixed second dimension keeps management simple.
*/
class _CBufferFragment
: public IHXBuffer
, public CUnknownIMP
{
DECLARE_UNKNOWN(_CBufferFragment)
public:
_CBufferFragment()
: m_pData(NULL)
, m_ulStart(0)
, m_ulLength(0)
{}
~_CBufferFragment()
{HX_RELEASE(m_pData); m_ulStart=0; m_ulLength=0;}
_CBufferFragment* _SetBuffer(IHXBuffer* pData, UINT32 ulStart, UINT32 ulLength);
STDMETHOD(Set)(const UCHAR* pData, UINT32 ulLength);
STDMETHOD(Get)(REF(UCHAR*) pData, REF(UINT32) ulLength);
STDMETHOD(SetSize)(UINT32 ulLength);
STDMETHOD_(UINT32, GetSize)();
STDMETHOD_(UCHAR*, GetBuffer)();
private:
IHXBuffer* m_pData;
UINT32 m_ulStart, m_ulLength;
};
class CHXFragmentedBuffer
: public IHXFragmentedBuffer
, public IHXBuffer
, public CUnknownIMP
{
DECLARE_UNKNOWN(CHXFragmentedBuffer)
private:
class _CFragment;
class _CFragmentList;
friend class _CFragment;
friend class _CFragmentList;
/* This class implements the listnodes of fragments
*/
class _CFragment
{
public:
inline _CFragment* Prev(){return m_pPrev;}
inline _CFragment* Next(){return m_pNext;}
_CFragment* SetData(IHXBuffer* pData);
_CFragment* SetData(IHXBuffer* pData, UINT32 ulStartFrom, UINT32 ulLengthFrom);
inline IHXBuffer* GetData(){return m_pData;}
_CFragment* Insert(_CFragment* pNewPrev);
_CFragment* Append(_CFragment* pNewNext);
_CFragment* Remove();
_CFragment():m_pData(NULL),m_pPrev(NULL),m_pNext(NULL){}
~_CFragment()
{
HX_RELEASE(m_pData);
if(m_pNext)
{
m_pNext->_SetPrev(m_pPrev);
}
if(m_pPrev)
{
m_pPrev->_SetNext(m_pNext);
}
}
private:
inline void _SetPrev(_CFragment* pfrgNew){m_pPrev = pfrgNew;}
inline void _SetNext(_CFragment* pfrgNew){m_pNext = pfrgNew;}
IHXBuffer* m_pData;
_CFragment* m_pPrev;
_CFragment* m_pNext;
};
/* This class maintains the First and Last pointers
* for a list of fragments
*/
class _CFragmentList
{
public:
_CFragmentList()
: m_pfrgListStart(NULL)
, m_pfrgListEnd(NULL)
, m_ulTotal(0)
{}
~_CFragmentList()
{
m_pfrgListEnd = NULL;
while(m_pfrgListStart)
{
m_pfrgListStart=m_pfrgListStart->Remove();
}
}
inline _CFragment* First(){return m_pfrgListStart;}
inline _CFragment* Last(){return m_pfrgListEnd;}
void Remove(_CFragment* pfrgObsolete);
void Insert(_CFragment* pfrgNew, _CFragment* pfrgRelative = NULL);
void Append(_CFragment* pfrgNew, _CFragment* pfrgRelative = NULL);
inline UINT32 GetTotal(){return m_ulTotal;}
private:
_CFragment* m_pfrgListStart;
_CFragment* m_pfrgListEnd;
UINT32 m_ulTotal;
};
public:
CHXFragmentedBuffer()
{}
~CHXFragmentedBuffer(){}
/* IHXFragmentedBuffer Methods
*/
STDMETHOD(GetEnumerator)
(
THIS_
IHXEnumFragmentedBuffer** ppefbNewEnum
);
STDMETHOD(Prepend)
(
THIS_
IHXBuffer* pBufferFrom,
ULONG32 ulStartFrom,
ULONG32 ulLengthFrom
);
STDMETHOD(Append)
(
THIS_
IHXBuffer* pBufferFrom,
ULONG32 ulStartFrom,
ULONG32 ulLengthFrom
);
STDMETHOD(Insert)
(
THIS_
IHXBuffer* pBufferFrom,
ULONG32 ulStartFrom,
ULONG32 ulLengthFrom,
ULONG32 ulStartTo
);
STDMETHOD(Replace)
(
THIS_
IHXBuffer* pBufferFrom,
ULONG32 ulStartFrom,
ULONG32 ulLengthFrom,
ULONG32 ulStartTo
);
STDMETHOD(Get)
(
THIS_
ULONG32 ulStartFrom,
ULONG32 ulLengthFrom,
REF(UCHAR*) pData,
REF(ULONG32) ulLength
);
STDMETHOD_(UCHAR*, GetBuffer)
(
THIS_
ULONG32 ulStartFrom,
ULONG32 ulLengthFrom
);
/* IHXBuffer Methods
*/
STDMETHOD(Set)(const UCHAR* pData, ULONG32 ulLength);
STDMETHOD(Get)(REF(UCHAR*) pData, REF(ULONG32) ulLength);
STDMETHOD(SetSize)(ULONG32 ulLength);
STDMETHOD_(ULONG32, GetSize)();
STDMETHOD_(UCHAR*, GetBuffer)();
private:
STDMETHOD(_FindFragment)(UINT32 ulFindIndex, REF(_CFragment*) pfrgCurrent, REF(UINT32) ulCurrentSize, REF(UINT32) ulCurrentStart);
void _RecursiveBufferCopy
(
UCHAR* pucDestBuffer,
IHXBuffer* pbufSource,
UINT32 ulStartIndex,
UINT32 ulSize
);
_CFragmentList m_frglstThis;
};
#endif //!_HXFGBUF_H_
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -