📄 smartbuffer.cpp
字号:
// SmartBuffer - Buffer for handy network packets arrangement
// Implementation file
//
// (c) Lev Naumov, CAMEL Laboratory
// E-mail: camellab@mail.ru
// For more information see http://camel.ifmo.ru or
// http://www.codeproject.com/internet/ctp.asp
/////////////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "SmartBuffer.h"
SmartBuffer::SmartBuffer(unsigned int datasize, bool autodel, unsigned int headsize, unsigned int maxdatasize)
{
// Store key values
m_uDataSize=datasize;
m_bAutoDel=autodel;
m_uHeadSize=headsize;
m_uMaxDataSize=maxdatasize;
// Allocate buffer
m_pBuffer=new char[m_uBufferSize=GetNeededBufferSize(m_uDataSize,m_uHeadSize,m_uMaxDataSize)];
// Set current pointer to the begining
m_pCurPtr=m_pBuffer+m_uHeadSize;
}
SmartBuffer::SmartBuffer(LPCTSTR fname, unsigned int datasize, bool autodel, unsigned int headsize, unsigned int maxdatasize)
{
CStdioFile file(fname,CFile::modeRead|CFile::typeBinary);
// Store key values
unsigned int fsize=file.GetLength();
m_uDataSize=fsize+datasize;
m_bAutoDel=autodel;
m_uHeadSize=headsize;
m_uMaxDataSize=maxdatasize;
// Allocate buffer
m_pBuffer=new char[m_uBufferSize=GetNeededBufferSize(m_uDataSize,m_uHeadSize,m_uMaxDataSize)];
// Set current pointer and temporary pointer to the begining
m_pCurPtr=m_pBuffer+m_uHeadSize;
char* ptr=m_pBuffer;
// Skip space for prefile data
while (datasize>m_uMaxDataSize) {
datasize-=m_uMaxDataSize;
ptr+=m_uHeadSize+m_uMaxDataSize;
}
// Copy file's content
ptr+=m_uHeadSize+datasize;
unsigned int read=0;
do {
read=file.Read(ptr,min(m_uMaxDataSize-datasize,fsize));
ptr+=m_uHeadSize+read;
fsize-=read;
if (datasize) datasize=0;
} while (fsize>0);
file.Close();
}
void SmartBuffer::SetDataSize(unsigned int datasize)
{
m_uDataSize=datasize;
// Arrange new buffer
unsigned int buffersize;
char* buffer=new char[buffersize=GetNeededBufferSize(m_uDataSize,m_uHeadSize,m_uMaxDataSize)];
memcpy(buffer,m_pBuffer,min(m_uBufferSize,buffersize));
// Move current pointer to equivalent place in new buffer
m_pCurPtr+=buffer-m_pBuffer;
if (m_pCurPtr>buffer+buffersize) m_pCurPtr=buffer+buffersize;
// Delete old buffer
delete[] m_pBuffer;
m_pBuffer=buffer;
}
bool SmartBuffer::PutHead(void* src, unsigned int i)
{
char* ptr=GetHeadPtr(i);
if (!ptr) return false;
memcpy(ptr,src,m_uHeadSize);
return true;
}
void SmartBuffer::DestToPtr(int dest, char*& ptr, unsigned int* prtnsize)
{
if (dest<0) {
ptr=m_pCurPtr;
if ((unsigned int)(ptr-m_pBuffer)%(m_uHeadSize+m_uMaxDataSize)<m_uHeadSize) ptr=(ptr-m_pBuffer)/(m_uHeadSize+m_uMaxDataSize)*(m_uHeadSize+m_uMaxDataSize)+m_uHeadSize+m_pBuffer;
if (prtnsize) *prtnsize=m_uMaxDataSize+m_uHeadSize-(ptr-m_pBuffer)%(m_uHeadSize+m_uMaxDataSize);
} else {
ptr=(dest/m_uMaxDataSize)*(m_uHeadSize+m_uMaxDataSize)+dest%m_uMaxDataSize+m_uHeadSize+m_pBuffer;
if (prtnsize) *prtnsize=m_uMaxDataSize-dest%m_uMaxDataSize;
}
}
bool SmartBuffer::PutData(void* src, unsigned int size, bool movecur, int dest)
{
// Calculating pointer and size of single portion
char* ptr=NULL;
unsigned int prtnsize=0;
DestToPtr(dest,ptr,&prtnsize);
bool res=true;
while (size>0) {
// Is starting point out of buffer
if (ptr>=m_pBuffer+m_uBufferSize) return false;
// Is possible portion bigger then the rest of data
if (size<prtnsize) prtnsize=size;
// Is rest of buffer smaller then possible portion
if ((unsigned int)(ptr+prtnsize-m_pBuffer)>m_uBufferSize) {
prtnsize=m_pBuffer+m_uBufferSize-ptr-1;
res=false;
}
// Copy data
memcpy(ptr,src,prtnsize);
size-=prtnsize;
ptr+=prtnsize;
prtnsize=m_uMaxDataSize;
if ((unsigned int)(ptr-m_pBuffer)%(m_uHeadSize+m_uMaxDataSize)==0) ptr+=m_uHeadSize;
if (!res) break;
}
if (movecur) m_pCurPtr=ptr;
return res;
}
bool SmartBuffer::PutDataByte(unsigned char bt, bool movecur, int dest)
{
// Calculating pointer
char* ptr=NULL;
DestToPtr(dest,ptr,NULL);
// Put byte
if (ptr<m_pBuffer+m_uBufferSize) {
*ptr=bt;
if (movecur) m_pCurPtr=ptr+1;
return true;
} else return false;
}
bool SmartBuffer::PutDataFile(LPCTSTR fname, bool movecur, int dest)
{
// Calculating pointer and size of single portion
char* ptr=NULL;
unsigned int prtnsize=0;
DestToPtr(dest,ptr,&prtnsize);
CStdioFile file(fname,CFile::modeRead|CFile::typeBinary);
unsigned int fsize=file.GetLength();
// Copy file's content
unsigned int read=0;
bool res=true;
do {
// Is starting point out of buffer
if (ptr>=m_pBuffer+m_uBufferSize) return false;
// Is rest of buffer smaller then possible portion
if ((unsigned int)(ptr+prtnsize-m_pBuffer)>m_uBufferSize) {
prtnsize=m_pBuffer+m_uBufferSize-ptr-1;
res=false;
}
// Copy data
read=file.Read(ptr,min(prtnsize,fsize));
ptr+=read;
fsize-=read;
prtnsize=m_uMaxDataSize;
if ((unsigned int)(ptr-m_pBuffer)%(m_uHeadSize+m_uMaxDataSize)==0) ptr+=m_uHeadSize;
} while (fsize>0);
file.Close();
if (movecur) m_pCurPtr=ptr;
return res;
}
void SmartBuffer::Trim()
{
// If m_pCurPtr is erroreous or points to fine end of buffer
if ((int)(m_pBuffer+m_uBufferSize-m_pCurPtr)<=0) return;
// New values of m_uBufferSize and m_uDataSize
m_uBufferSize=(unsigned int)(m_pCurPtr-m_pBuffer);
m_uDataSize=m_uBufferSize/(m_uHeadSize+m_uMaxDataSize)*m_uMaxDataSize+((m_uBufferSize%(m_uHeadSize+m_uMaxDataSize)<m_uHeadSize)?0:(m_uBufferSize%(m_uHeadSize+m_uMaxDataSize)-m_uHeadSize));
// Current pointer will point just after buffer's end
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -