📄 chxfgbuf.cpp
字号:
ulLength = ulLengthFrom;
}
HX_RELEASE(phxbufBuffy);
return HXR_OK;
}
void
CHXFragmentedBuffer::_RecursiveBufferCopy
(
UCHAR* pucDestBuffer,
IHXBuffer* pbufSource,
UINT32 ulStartIndex,
UINT32 ulSize
)
{
IHXFragmentedBuffer* pfgbufCurrent = NULL;
/* Optimized by directly enumerating nested
* fragmented buffers.
* (instead of "pfrgCurrent->GetData()->GetBuffer()")
*/
if (!(pbufSource->QueryInterface(IID_IHXFragmentedBuffer, (void**)&pfgbufCurrent)) || pfgbufCurrent)
{
IHXEnumFragmentedBuffer* pefbCurrent = NULL;
IHXBuffer* pbufCurrent = NULL;
UINT32 ulSizeCurrent=0;
UINT32 ulCopied=0;
UINT32 ulTotal=0;
pfgbufCurrent->GetEnumerator(&pefbCurrent);
pefbCurrent->Reset();
while(!(pefbCurrent->Next(1, &pbufCurrent, NULL)) && ulSize>0)
{
ulSizeCurrent = pbufCurrent->GetSize();
if ((ulTotal+ulSizeCurrent) < ulStartIndex)
{
ulTotal += ulSizeCurrent;
}
else
{
_RecursiveBufferCopy
(
pucDestBuffer+ulCopied,
pbufCurrent,
ulStartIndex-ulTotal,
min(ulSize, ulSizeCurrent)
);
ulSize -= ulSizeCurrent;
ulCopied += ulSizeCurrent;
ulStartIndex = 0;
ulTotal=0;
}
HX_RELEASE(pbufCurrent);
}
HX_RELEASE(pefbCurrent);
HX_RELEASE(pfgbufCurrent);
}
else
{
memcpy /* Flawfinder: ignore */
(
pucDestBuffer,
pbufSource->GetBuffer()+ulStartIndex,
HX_SAFESIZE_T(ulSize-ulStartIndex)
);
}
}
STDMETHODIMP_(UCHAR*)
CHXFragmentedBuffer::GetBuffer(UINT32 ulStartFrom, UINT32 ulLengthFrom)
{
UCHAR* pData;
UINT32 ulLength;
/* Gather from start to start+length
*/
Get(ulStartFrom, ulLengthFrom, pData, ulLength);
return pData;
}
/* IHXBuffer Methods
*/
/* XXX I am not doing memcopies into existing space as I cannot guarantee write access.
* An acceptable Optimization is to try to memcopy, and fragment only if that fails.
*/
STDMETHODIMP
CHXFragmentedBuffer::Set(const UCHAR* pData, ULONG32 ulLength)
{
/* Need to make an empty Buffer sizeof ulLength
*/
IHXBuffer* phxbufTemp = (IHXBuffer*)(new CHXBuffer());
phxbufTemp->AddRef();
phxbufTemp->SetSize(ulLength);
phxbufTemp->Set(pData, ulLength);
Replace(phxbufTemp, 0, ulLength, 0);
HX_RELEASE(phxbufTemp);
return HXR_OK;
}
STDMETHODIMP
CHXFragmentedBuffer::Get(REF(UCHAR*) pData, REF(ULONG32) ulLength)
{
return Get(0,UINT32(-1), pData, ulLength);
}
/* adds/removes fragment(s) to the end to set the size to the requested length
*/
STDMETHODIMP
CHXFragmentedBuffer::SetSize(ULONG32 ulLength)
{
UINT32 ulSize;
ulSize = GetSize();
if (ulLength > ulSize)
{
/* The existing buffers are not big enough
* Need to make an empty Buffer sizeof ulLength-GetSize()
*/
IHXBuffer* phxbufTemp = (IHXBuffer*)(new CHXBuffer());
_CFragment* pfrgNew;
phxbufTemp->AddRef();
phxbufTemp->SetSize(ulLength-ulSize);
pfrgNew = new _CFragment();
pfrgNew->SetData(phxbufTemp);
m_frglstThis.Append(pfrgNew);
HX_RELEASE(phxbufTemp);
}
else if (ulLength < ulSize)
{
_CFragment* pfrgFirst;
_CFragment* pfrgCurrent;
_CFragment* pfrgTmp;
UINT32 ulTotalFirst=0, ulSizeFirst=0;
/* Find First affected fragment
*/
_FindFragment(ulLength, pfrgFirst, ulSizeFirst, ulTotalFirst);
if(pfrgFirst)
{
IHXBuffer* phxbufBuffy;
pfrgCurrent = pfrgFirst->Next();
phxbufBuffy = pfrgFirst->GetData();
phxbufBuffy->AddRef();
if(ulLength-ulTotalFirst > 0)
{
/* Reset existing fragment to contain first part of phxbufBuffy
*/
pfrgFirst->SetData(phxbufBuffy, 0, ulLength-ulTotalFirst);
}
else
{
m_frglstThis.Remove(pfrgFirst);
}
HX_RELEASE(phxbufBuffy);
/* Remove the truncated items.
*/
while(pfrgCurrent)
{
pfrgTmp = pfrgCurrent;
pfrgCurrent = pfrgCurrent->Next();
m_frglstThis.Remove(pfrgTmp);
}
}
}
return HXR_OK;
}
/* returns the sum of all the fragments sizes
*/
STDMETHODIMP_(ULONG32)
CHXFragmentedBuffer::GetSize()
{
_CFragment* pfrgCurrent;
UINT32 ulTotal = 0;
pfrgCurrent = m_frglstThis.First();
while (pfrgCurrent)
{
ulTotal += pfrgCurrent->GetData()->GetSize();
pfrgCurrent = pfrgCurrent->Next();
}
return ulTotal;
}
STDMETHODIMP_(UCHAR*)
CHXFragmentedBuffer::GetBuffer()
{
return GetBuffer(0,UINT32(-1));
}
CHXFragmentedBuffer::_CFragment*
CHXFragmentedBuffer::_CFragment::SetData(IHXBuffer* pData)
{
HX_RELEASE(m_pData);
m_pData=pData;
m_pData->AddRef();
return this;
}
CHXFragmentedBuffer::_CFragment*
CHXFragmentedBuffer::_CFragment::SetData(IHXBuffer* pData, UINT32 ulStartFrom, UINT32 ulLengthFrom)
{
HX_RELEASE(m_pData);
if(!ulStartFrom && ulLengthFrom >= pData->GetSize())
{
/* Use whole Buffer
*/
m_pData=pData;
m_pData->AddRef();
}
else
{
/* Use Part of Buffer
*/
(
_CBufferFragment::CreateObject()
)
->_SetBuffer
(
pData,
ulStartFrom,
ulLengthFrom
)
->QueryInterface
(
IID_IHXBuffer,
(void**)&m_pData
);
}
return this;
}
CHXFragmentedBuffer::_CFragment*
CHXFragmentedBuffer::_CFragment::Insert(_CFragment* pNewPrev)
{
if(pNewPrev == m_pPrev)
{
return this;
}
if(m_pPrev)
{
m_pPrev->_SetNext(pNewPrev);
}
if(pNewPrev)
{
pNewPrev->_SetNext(this);
pNewPrev->_SetPrev(m_pPrev);
}
_SetPrev(pNewPrev);
return pNewPrev;
}
CHXFragmentedBuffer::_CFragment*
CHXFragmentedBuffer::_CFragment::Append(_CFragment* pNewNext)
{
if(pNewNext == m_pNext)
{
return this;
}
if(m_pNext)
{
m_pNext->_SetPrev(pNewNext);
}
if(pNewNext)
{
pNewNext->_SetPrev(this);
pNewNext->_SetNext(m_pNext);
}
_SetNext(pNewNext);
return pNewNext;
}
CHXFragmentedBuffer::_CFragment*
CHXFragmentedBuffer::_CFragment::Remove()
{
_CFragment* pfrgRet;
if(m_pNext)
{
pfrgRet = m_pNext;
}
else
{
pfrgRet = m_pPrev;
}
delete this;
return pfrgRet;
}
void
CHXFragmentedBuffer::_CFragmentList::Remove(_CFragment* pfrgObsolete)
{
if(pfrgObsolete)
{
if (pfrgObsolete == m_pfrgListEnd)
{
m_pfrgListEnd = pfrgObsolete->Prev();
}
if (pfrgObsolete == m_pfrgListStart)
{
m_pfrgListStart = pfrgObsolete->Next();
}
pfrgObsolete->Remove();
--m_ulTotal;
}
}
void
CHXFragmentedBuffer::_CFragmentList::Insert(_CFragment* pfrgNew, _CFragment* pfrgRelative)
{
if (!pfrgNew)
{
return;
}
if(pfrgRelative)
{
pfrgRelative->Insert(pfrgNew);
if (pfrgRelative == m_pfrgListStart)
{
m_pfrgListStart = pfrgNew;
}
}
else if (m_pfrgListStart)
{
m_pfrgListStart->Insert(pfrgNew);
m_pfrgListStart = pfrgNew;
}
else
{
m_pfrgListStart = m_pfrgListEnd = pfrgNew;
}
++m_ulTotal;
}
void
CHXFragmentedBuffer::_CFragmentList::Append(_CFragment* pfrgNew, _CFragment* pfrgRelative)
{
if (!pfrgNew)
{
return;
}
if(pfrgRelative)
{
pfrgRelative->Append(pfrgNew);
if (pfrgRelative == m_pfrgListEnd)
{
m_pfrgListEnd = pfrgNew;
}
}
else if (m_pfrgListEnd)
{
m_pfrgListEnd->Append(pfrgNew);
m_pfrgListEnd = pfrgNew;
}
else
{
m_pfrgListStart = m_pfrgListEnd = pfrgNew;
}
++m_ulTotal;
}
_CBufferFragment*
_CBufferFragment::_SetBuffer(IHXBuffer* pData, UINT32 ulStart, UINT32 ulLength)
{
HX_RELEASE(m_pData);
m_pData = pData;
if(m_pData)
{
m_pData->AddRef();
m_ulStart=ulStart;
if(m_pData->GetSize()-ulStart < ulLength)
{
m_ulLength=m_pData->GetSize()-ulStart;
}
else
{
m_ulLength=ulLength;
}
}
else
{
m_ulStart=0;
m_ulLength=0;
}
return this;
}
STDMETHODIMP
_CBufferFragment::Set(const UCHAR* pData, UINT32 ulLength)
{
if(!m_pData)
{
return HXR_UNEXPECTED;
}
return m_pData->Set(pData+m_ulStart, ulLength);
}
STDMETHODIMP
_CBufferFragment::Get(REF(UCHAR*) pData, REF(UINT32) ulLength)
{
if(!m_pData)
{
return HXR_UNEXPECTED;
}
if(ulLength > m_ulLength)
{
return HXR_INVALID_PARAMETER;
}
pData = GetBuffer();
ulLength = GetSize();
return HXR_OK;
}
STDMETHODIMP
_CBufferFragment::SetSize(UINT32 ulLength)
{
HX_RESULT hxrRet = HXR_FAIL;
if(!m_pData)
{
/* Make New Buffer
*/
m_pData = (IHXBuffer*)(new CHXBuffer());
m_pData->AddRef();
m_ulStart = 0;
}
hxrRet = m_pData->SetSize(ulLength+m_ulStart);
m_ulLength = ulLength;
return hxrRet;
}
STDMETHODIMP_(UINT32)
_CBufferFragment::GetSize()
{
if(!m_pData)
{
return 0;
}
return min(m_pData->GetSize()-m_ulStart, m_ulLength);
}
STDMETHODIMP_(UCHAR*)
_CBufferFragment::GetBuffer()
{
if(!m_pData)
{
return NULL;
}
return m_pData->GetBuffer()?m_pData->GetBuffer()+m_ulStart:NULL;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -