213 lines
3.7 KiB
C++
213 lines
3.7 KiB
C++
// Buffer.cpp: implementation of the CBuffer class.
|
||
//
|
||
//////////////////////////////////////////////////////////////////////
|
||
#include "Buffer.h"
|
||
#include "math.h"
|
||
|
||
#ifdef _DEBUG
|
||
#undef THIS_FILE
|
||
static char THIS_FILE[]=__FILE__;
|
||
#define new DEBUG_NEW
|
||
#endif
|
||
|
||
CBuffer::CBuffer()
|
||
{
|
||
// Initial size
|
||
m_nSize = 0;
|
||
|
||
m_pPtr = m_pBase = NULL;
|
||
}
|
||
|
||
CBuffer::~CBuffer()
|
||
{
|
||
if (m_pBase)
|
||
VirtualFree(m_pBase, 0, MEM_RELEASE);
|
||
}
|
||
|
||
|
||
BOOL CBuffer::Write(PBYTE pData, UINT nSize)
|
||
{
|
||
if (ReAllocateBuffer(nSize + GetBufferLen()) == -1)
|
||
{
|
||
return false;
|
||
}
|
||
|
||
CopyMemory(m_pPtr,pData,nSize);
|
||
|
||
// Advance Pointer
|
||
m_pPtr+=nSize;
|
||
return nSize;
|
||
}
|
||
|
||
|
||
void *mymemmove(void *dst, const void *src, size_t count)
|
||
{
|
||
void *ret = dst;
|
||
if (dst <= src || (char *)dst >= ((char *)src + count))
|
||
{
|
||
// Non-Overlapping Buffers
|
||
// copy from lower addresses to higher addresses
|
||
while (count--)
|
||
{
|
||
*(char*)dst = *(char*)src;
|
||
dst = (char*)dst + 1;
|
||
src = (char*)src + 1;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
// Overlapping Buffers
|
||
// copy from higher addresses to lower addresses
|
||
dst = (char*)dst + count - 1;
|
||
src = (char*)src + count - 1;
|
||
|
||
while (count--)
|
||
{
|
||
*(char*)dst = *(char*)src;
|
||
dst = (char*)dst - 1;
|
||
src = (char*)src - 1;
|
||
}
|
||
}
|
||
|
||
return ret;
|
||
}
|
||
|
||
UINT CBuffer::Read(PBYTE pData, UINT nSize)
|
||
{
|
||
// Trying to byte off more than ya can chew - eh?
|
||
if (nSize > GetMemSize())
|
||
{
|
||
return 0;
|
||
}
|
||
|
||
// all that we have
|
||
if (nSize > GetBufferLen())
|
||
nSize = GetBufferLen();
|
||
|
||
|
||
if (nSize)
|
||
{
|
||
// Copy over required amount and its not up to us
|
||
// to terminate the buffer - got that!!!
|
||
CopyMemory(pData,m_pBase,nSize);
|
||
|
||
// Slide the buffer back - like sinking the data
|
||
mymemmove(m_pBase,m_pBase+nSize,GetMemSize() - nSize);
|
||
|
||
m_pPtr -= nSize;
|
||
}
|
||
|
||
DeAllocateBuffer(GetBufferLen());
|
||
|
||
return nSize;
|
||
}
|
||
|
||
UINT CBuffer::GetMemSize()
|
||
{
|
||
return m_nSize;
|
||
}
|
||
|
||
UINT CBuffer::GetBufferLen()
|
||
{
|
||
if (m_pBase == NULL)
|
||
return 0;
|
||
|
||
int nSize =
|
||
m_pPtr - m_pBase;
|
||
return nSize;
|
||
}
|
||
double my_ceil(double x)
|
||
{
|
||
double y=x;
|
||
if( (*( ( (int *) &y)+1) & 0x80000000) != 0)//<2F><><EFBFBD><EFBFBD>if(x<0)
|
||
return (float)((int)x);
|
||
else //<2F><><EFBFBD>۷Ǹ<DBB7><C7B8><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||
{
|
||
if(x == 0)
|
||
return (float)((int)x);
|
||
else
|
||
return (float)((int)x) + 1;
|
||
}
|
||
}
|
||
UINT CBuffer::ReAllocateBuffer(UINT nRequestedSize)
|
||
{
|
||
|
||
if (nRequestedSize < GetMemSize())
|
||
return 0;
|
||
|
||
// Allocate new size
|
||
UINT nNewSize = (UINT) my_ceil(nRequestedSize / 1024.0) * 1024 ;
|
||
|
||
// New Copy Data Over
|
||
PBYTE pNewBuffer = (PBYTE) VirtualAlloc(NULL,nNewSize,MEM_COMMIT,PAGE_READWRITE);
|
||
if (pNewBuffer == NULL)
|
||
return -1;
|
||
|
||
UINT nBufferLen = GetBufferLen();
|
||
if(nBufferLen > 0)
|
||
CopyMemory(pNewBuffer,m_pBase,nBufferLen);
|
||
|
||
if (m_pBase)
|
||
VirtualFree(m_pBase,0,MEM_RELEASE);
|
||
|
||
|
||
// Hand over the pointer
|
||
m_pBase = pNewBuffer;
|
||
|
||
// Realign position pointer
|
||
m_pPtr = m_pBase + nBufferLen;
|
||
|
||
m_nSize = nNewSize;
|
||
|
||
return m_nSize;
|
||
}
|
||
|
||
UINT CBuffer::DeAllocateBuffer(UINT nRequestedSize)
|
||
{
|
||
if (nRequestedSize < GetBufferLen())
|
||
return 0;
|
||
|
||
// Allocate new size
|
||
UINT nNewSize = (UINT) my_ceil(nRequestedSize / 1024.0) * 1024;
|
||
|
||
if (nNewSize < GetMemSize())
|
||
return 0;
|
||
|
||
// New Copy Data Over
|
||
PBYTE pNewBuffer = (PBYTE) VirtualAlloc(NULL,nNewSize,MEM_COMMIT,PAGE_READWRITE);
|
||
if(pNewBuffer == NULL)
|
||
return -1;
|
||
|
||
UINT nBufferLen = GetBufferLen();
|
||
if(nBufferLen > 0)
|
||
CopyMemory(pNewBuffer,m_pBase,nBufferLen);
|
||
|
||
VirtualFree(m_pBase,0,MEM_RELEASE);
|
||
|
||
// Hand over the pointer
|
||
m_pBase = pNewBuffer;
|
||
|
||
// Realign position pointer
|
||
m_pPtr = m_pBase + nBufferLen;
|
||
|
||
m_nSize = nNewSize;
|
||
|
||
return m_nSize;
|
||
}
|
||
|
||
void CBuffer::ClearBuffer()
|
||
{
|
||
// Force the buffer to be empty
|
||
if (m_pBase)
|
||
VirtualFree(m_pBase,0,MEM_RELEASE);
|
||
|
||
m_pPtr = m_pBase = NULL;
|
||
m_nSize = 0;
|
||
}
|
||
|
||
|
||
PBYTE CBuffer::GetBuffer(UINT nPos)
|
||
{
|
||
return m_pBase+nPos;
|
||
}
|