📄 chxfgbuf.cpp
字号:
} if(phxbufBuffy) { phxbufBuffy->Get(pData, ulLength); pData = pData+ulFirstStartIndex; 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 + -