398 lines
7.4 KiB
C++
398 lines
7.4 KiB
C++
#ifndef BLOCK_LIST_BUFFER__H_
|
|
#define BLOCK_LIST_BUFFER__H_
|
|
|
|
#ifdef _WIN32
|
|
#pragma once
|
|
#endif
|
|
|
|
|
|
struct _TBinaryBlock
|
|
{
|
|
char * pData;
|
|
char * pDataOffset;
|
|
int nSize;
|
|
};
|
|
typedef struct _TBinaryBlock TBinaryBlock;
|
|
|
|
|
|
class HBlockListBuffer : public HObject
|
|
{
|
|
public:
|
|
HBlockListBuffer(int nBlockSize)
|
|
{
|
|
m_nBlockSize = nBlockSize;
|
|
m_nTotalSize = 0; //...
|
|
}
|
|
|
|
~HBlockListBuffer()
|
|
{
|
|
RemoveAll();
|
|
}
|
|
|
|
inline size_t GetCount() { return listBinaryBlock.size(); }
|
|
|
|
inline int GetTotalSize()
|
|
{
|
|
int nTotalSize = 0;
|
|
for (std::list<TBinaryBlock>::iterator iter = listBinaryBlock.begin();
|
|
iter != listBinaryBlock.end(); iter++)
|
|
{
|
|
if (iter->nSize > 0)
|
|
nTotalSize += iter->nSize;
|
|
}
|
|
|
|
return nTotalSize;
|
|
}
|
|
|
|
inline bool Enqueue(const char * pData, int nSize)
|
|
{
|
|
if (nSize <= 0) //... command, -1 = end mark
|
|
{
|
|
TBinaryBlock blockNew;
|
|
blockNew.nSize = nSize;
|
|
listBinaryBlock.push_back(blockNew);
|
|
return true;
|
|
}
|
|
|
|
if (listBinaryBlock.empty() == false)
|
|
{
|
|
#if 1
|
|
std::list<TBinaryBlock>::iterator iter = listBinaryBlock.end();
|
|
iter--;
|
|
|
|
if (iter->nSize <= 0)
|
|
return false;
|
|
|
|
int nRemainBufer = m_nBlockSize - iter->nSize - (iter->pDataOffset - iter->pData);
|
|
if (nRemainBufer > nSize)
|
|
{
|
|
memcpy(iter->pDataOffset + iter->nSize, pData, nSize);
|
|
iter->nSize += nSize;
|
|
return true;
|
|
}
|
|
else
|
|
{
|
|
if (nRemainBufer > 0)
|
|
{
|
|
memcpy(iter->pDataOffset + iter->nSize, pData, nRemainBufer);
|
|
iter->nSize += nRemainBufer;
|
|
pData += nRemainBufer;
|
|
nSize -= nRemainBufer;
|
|
}
|
|
}
|
|
#endif
|
|
}
|
|
|
|
while (nSize > 0)
|
|
{
|
|
TBinaryBlock blockNew;
|
|
blockNew.pData = (char *)malloc(m_nBlockSize);
|
|
blockNew.pDataOffset = blockNew.pData;
|
|
|
|
if (nSize <= m_nBlockSize)
|
|
{
|
|
memcpy(blockNew.pDataOffset, pData, nSize);
|
|
blockNew.nSize = nSize;
|
|
nSize = 0;
|
|
}
|
|
else
|
|
{
|
|
memcpy(blockNew.pDataOffset, pData, m_nBlockSize);
|
|
blockNew.nSize = m_nBlockSize;
|
|
pData += m_nBlockSize;
|
|
nSize -= m_nBlockSize;
|
|
}
|
|
|
|
listBinaryBlock.push_back(blockNew);
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
inline bool Dequeue(char * pDst, int nCount)
|
|
{
|
|
if (nCount > GetTotalSize())
|
|
return false;
|
|
|
|
int nRemainSize = nCount;
|
|
|
|
std::list<TBinaryBlock>::iterator iter = listBinaryBlock.begin();
|
|
while (iter != listBinaryBlock.end())
|
|
{
|
|
if (iter->nSize < 0)
|
|
return false;
|
|
|
|
if (nRemainSize < nCount)
|
|
{
|
|
if (iter->nSize < nRemainSize)
|
|
{
|
|
memcpy(pDst, iter->pDataOffset, iter->nSize);
|
|
pDst += iter->nSize;
|
|
nRemainSize -= iter->nSize;
|
|
free(iter->pData);
|
|
iter = listBinaryBlock.erase(iter);
|
|
}
|
|
else
|
|
{
|
|
memcpy(pDst, iter->pDataOffset, nRemainSize);
|
|
|
|
if (iter->nSize == nRemainSize)
|
|
{
|
|
free(iter->pData);
|
|
listBinaryBlock.erase(iter);
|
|
}
|
|
else
|
|
{
|
|
iter->pDataOffset += nRemainSize;
|
|
iter->nSize -= nRemainSize;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
}
|
|
else if (iter->nSize > 0)
|
|
{
|
|
if (iter->nSize < nCount)
|
|
{
|
|
memcpy(pDst, iter->pDataOffset, iter->nSize);
|
|
pDst += iter->nSize;
|
|
nRemainSize -= iter->nSize;
|
|
free(iter->pData);
|
|
iter = listBinaryBlock.erase(iter);
|
|
}
|
|
else
|
|
{
|
|
memcpy(pDst, iter->pDataOffset, nCount);
|
|
|
|
if (iter->nSize == nCount)
|
|
{
|
|
free(iter->pData);
|
|
listBinaryBlock.erase(iter);
|
|
}
|
|
else
|
|
{
|
|
iter->pDataOffset += nCount;
|
|
iter->nSize -= nCount;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
bool DequeueAll(char * pDst)
|
|
{
|
|
std::list<TBinaryBlock>::iterator iter = listBinaryBlock.begin();
|
|
while (iter != listBinaryBlock.end())
|
|
{
|
|
if (iter->nSize <= 0) //...
|
|
return false;
|
|
|
|
memcpy(pDst, iter->pDataOffset, iter->nSize);
|
|
pDst += iter->nSize;
|
|
free(iter->pData);
|
|
iter = listBinaryBlock.erase(iter);
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
inline bool GetFront(char ** ppData, int * pnSize)
|
|
{
|
|
std::list<TBinaryBlock>::iterator iter = listBinaryBlock.begin();
|
|
if (iter == listBinaryBlock.end())
|
|
return false;
|
|
|
|
if (iter->nSize > 0)
|
|
*ppData = iter->pDataOffset;
|
|
|
|
*pnSize = iter->nSize;
|
|
|
|
return true;
|
|
}
|
|
|
|
inline void PopFront()
|
|
{
|
|
std::list<TBinaryBlock>::iterator iter = listBinaryBlock.begin();
|
|
if (iter == listBinaryBlock.end())
|
|
return;
|
|
|
|
if (iter->nSize > 0)
|
|
free(iter->pData);
|
|
listBinaryBlock.erase(iter);
|
|
}
|
|
|
|
inline bool ReduceFront(int nSize)
|
|
{
|
|
if (nSize > m_nBlockSize)
|
|
return false;
|
|
|
|
std::list<TBinaryBlock>::iterator iter = listBinaryBlock.begin();
|
|
if (iter == listBinaryBlock.end())
|
|
return false;
|
|
|
|
if (iter->nSize <= 0)
|
|
{
|
|
return false;
|
|
}
|
|
else if (nSize > iter->nSize)
|
|
{
|
|
return false;
|
|
}
|
|
else if (nSize == iter->nSize)
|
|
{
|
|
free(iter->pData);
|
|
listBinaryBlock.erase(iter);
|
|
return true;
|
|
}
|
|
|
|
iter->pDataOffset += nSize;
|
|
iter->nSize -= nSize;
|
|
return true;
|
|
}
|
|
|
|
inline void RemoveAll()
|
|
{
|
|
for (std::list<TBinaryBlock>::iterator iter = listBinaryBlock.begin();
|
|
iter != listBinaryBlock.end(); iter++)
|
|
{
|
|
if (iter->nSize > 0)
|
|
free(iter->pData);
|
|
}
|
|
listBinaryBlock.clear();
|
|
}
|
|
|
|
HDynamicArray<char> ChangeAndClear(int * pnSize, int nExtra)
|
|
{
|
|
*pnSize = GetTotalSize();
|
|
if (*pnSize <= 0)
|
|
return (char *)NULL;
|
|
|
|
char * pBuffer = (char *)malloc(*pnSize + nExtra);
|
|
char * pOffset = pBuffer;
|
|
|
|
for (std::list<TBinaryBlock>::iterator iter = listBinaryBlock.begin();
|
|
iter != listBinaryBlock.end(); iter++)
|
|
{
|
|
if (iter->nSize > 0) //...
|
|
{
|
|
memcpy(pOffset, iter->pDataOffset, iter->nSize);
|
|
pOffset += iter->nSize;
|
|
}
|
|
|
|
free(iter->pData);
|
|
}
|
|
listBinaryBlock.clear();
|
|
|
|
return pBuffer;
|
|
}
|
|
|
|
inline bool Copy(char * pDst, int nStartPos, int nCount)
|
|
{
|
|
int nRemainSize = nCount;
|
|
int i = 0;
|
|
for (std::list<TBinaryBlock>::iterator iter = listBinaryBlock.begin();
|
|
iter != listBinaryBlock.end(); iter++)
|
|
{
|
|
if (iter->nSize < 0)
|
|
return false;
|
|
|
|
i += iter->nSize;
|
|
|
|
if (nRemainSize < nCount)
|
|
{
|
|
if (iter->nSize < nRemainSize)
|
|
{
|
|
memcpy(pDst, iter->pDataOffset, iter->nSize);
|
|
pDst += iter->nSize;
|
|
nRemainSize -= iter->nSize;
|
|
}
|
|
else
|
|
{
|
|
memcpy(pDst, iter->pDataOffset, nRemainSize);
|
|
return true;
|
|
}
|
|
}
|
|
else if (i > nStartPos) //...
|
|
{
|
|
int nBlockRemain = i - nStartPos;
|
|
int nBlockStartIndex = iter->nSize - nBlockRemain;
|
|
|
|
if (nBlockRemain < nCount)
|
|
{
|
|
memcpy(pDst, iter->pDataOffset + nBlockStartIndex, nBlockRemain);
|
|
pDst += nBlockRemain;
|
|
nRemainSize -= nBlockRemain;
|
|
}
|
|
else
|
|
{
|
|
memcpy(pDst, iter->pDataOffset + nBlockStartIndex, nCount);
|
|
return true;
|
|
}
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
int SearchChr(int nStartPos, char ch)
|
|
{
|
|
int i = 0, j;
|
|
for (std::list<TBinaryBlock>::iterator iter = listBinaryBlock.begin();
|
|
iter != listBinaryBlock.end(); iter++)
|
|
{
|
|
if (iter->nSize < 0)
|
|
return -1;
|
|
|
|
if (i + iter->nSize > nStartPos)
|
|
{
|
|
for (j = 0; j < iter->nSize; j++)
|
|
{
|
|
if (i >= nStartPos && iter->pDataOffset[j] == ch)
|
|
return i;
|
|
|
|
i++;
|
|
}
|
|
}
|
|
else
|
|
i += iter->nSize;
|
|
}
|
|
|
|
return -1;
|
|
}
|
|
|
|
|
|
#ifdef _DEBUG
|
|
void Print()
|
|
{
|
|
printf("Print, count = %d\n", listBinaryBlock.size());
|
|
|
|
int i = 0;
|
|
for (std::list<TBinaryBlock>::iterator iter = listBinaryBlock.begin();
|
|
iter != listBinaryBlock.end(); iter++)
|
|
{
|
|
printf("%d, ", i++);
|
|
|
|
if (iter->nSize > 0)
|
|
{
|
|
for (int j = 0; j < iter->nSize; j++)
|
|
putchar(iter->pDataOffset[j]);
|
|
}
|
|
|
|
putchar('\n');
|
|
}
|
|
}
|
|
|
|
#endif
|
|
|
|
protected:
|
|
std::list<TBinaryBlock> listBinaryBlock;
|
|
int m_nBlockSize;
|
|
int m_nTotalSize;
|
|
};
|
|
|
|
#endif // BLOCK_LIST_BUFFER__H_
|