|
// SmartBuffer - Buffer for handy network packets arrangement
// Declaration 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
/////////////////////////////////////////////////////////////////////////////
class SmartBuffer
{
public:
// Constructor. Parameters:
// +) datasize - amount of data to be used;
// +) autodel - if true then this buffer will be freed automatically by
// protocol's implementation after it will be sent and confirmed if
// needed. So, working with such buffer, you will have to create it with
// operator new, but do not to delete it. If this parameter equals false
// you will have to do new and delete manually
// +) headsize - size of header of each packet;
// +) maxdatasize - maximum size of data in single packet (without header)
SmartBuffer(unsigned int datasize=0, bool autodel=true, unsigned int headsize=25, unsigned int maxdatasize=65400);
// Constructor. Parameters:
// +) fname - name of file to be stored in internal buffer as data;
// +) datasize - amount of data to be stroed just before the file;
// +) autodel - if true then this buffer will be freed automatically by
// protocol's implementation after it will be sent and confirmed if
// needed. So, working with such buffer, you will have to create it with
// operator new, but do not to delete it. If this parameter equals false
// you will have to do new and delete manually
// +) headsize - size of header of each packet;
// +) maxdatasize - maximum size of data in single packet (without header)
SmartBuffer(LPCTSTR fname, unsigned int datasize=0, bool autodel=true, unsigned int headsize=25, unsigned int maxdatasize=65400);
// Destructor
virtual ~SmartBuffer() {delete[] m_pBuffer;};
// Access to key values
// Header size
inline unsigned int GetHeadSize() {return m_uHeadSize;};
// Data size
inline unsigned int GetDataSize() {return m_uDataSize;};
void SetDataSize(unsigned int datasize);
// Maximum data size for single packet
inline unsigned int GetMaxDataSize() {return m_uMaxDataSize;};
// Allocated buffer size
inline unsigned int GetBufferSize() {return m_uBufferSize;};
// Auto deleting
inline bool GetAutoDel() {return m_bAutoDel;}
inline void SetAutoDel(bool autodel) {m_bAutoDel=autodel;}
// Access to key pointers
// Returns begining of the buffer
inline char* GetBufferBegin() {return m_pBuffer;};
// Returns current pointer
inline void* GetCurPtr() {return m_pCurPtr;};
// Sets current pointer to pointer to data of i-th packet (i from zero to
// GetPacketsCount()-1). Result false if index i is out of bounds
inline bool CurPtrToDataPtr(unsigned int i) {char* res=GetDataPtr(i); if (res) {m_pCurPtr=res; return true;} else return false;};
// Sets current pointer to the begining of data
inline void CurPtrToDataBegin() {m_pCurPtr=m_pBuffer+m_uHeadSize;};
// Access to packets
// Returns amount of packets
inline unsigned int GetPacketsCount() {return m_uBufferSize/(m_uHeadSize+m_uMaxDataSize)+((m_uBufferSize%(m_uHeadSize+m_uMaxDataSize))?1:0);};
// Returns pointer to header of i-th packet (i from zero to
// GetPacketsCount()-1). Result is zero if index i is out of bounds
inline char* GetHeadPtr(unsigned int i) {char* res=i*(m_uHeadSize+m_uMaxDataSize)+m_pBuffer; if (res>m_pBuffer+m_uBufferSize) return NULL; else return res;};
// Returns pointer to data of i-th packet (i from zero to
// GetPacketsCount()-1). Result is zero if index i is out of bounds
inline char* GetDataPtr(unsigned int i) {char* res=GetHeadPtr(i); if (res) return res+m_uHeadSize; else return NULL;};
// Returns size of i-th packet (i from zero to GetPacketsCount()-1),
// including header. Only last packet's size can differ from header's size
// plus maximum data size. Result is zero if index i is out of bounds
inline unsigned int GetPacketSize(unsigned int i) {if (i<(m_uBufferSize)/(m_uHeadSize+m_uMaxDataSize)) return m_uHeadSize+m_uMaxDataSize; else if (i==(m_uBufferSize)/(m_uHeadSize+m_uMaxDataSize)) return (m_uBufferSize)%(m_uHeadSize+m_uMaxDataSize); else return 0;};
// Data and header access routines
// Put data of size GetHeadSize() from src to the are of i-th header.
// Returns true if data was copied successfully to the existing header etc
// and false otherwise
bool PutHead(void* src, unsigned int i);
// Put byte of data bt to internal buffer from current pointer (if dest is
// negative) or from dest-th byte.. Current pointer will be moved to the
// end of put data (skipping headers) if movecur equals true. Returns true
// if data was copied successfully
bool PutDataByte(unsigned char bt, bool movecur=true, int dest=-1);
// Put data of size size from src to internal buffer from current pointer
// (if dest is negative) or from dest-th byte. Current pointer will be
// moved to the end of put data (skipping headers) if movecur equals true.
// Returns true if data was copied successfully, without truncation etc and
// false otherwise
bool PutData(void* src, unsigned int size, bool movecur=true, int dest=-1);
// Put string to internal buffer from current pointer (if dest is negative)
// or from dest-th byte. Current pointer will be moved to the end of put
// data (skipping headers) if movecur equals true. Returns true if data was
// copied successfully, without truncation etc and false otherwise
inline bool PutDataString(char* str, bool movecur=true, int dest=-1) {return PutData(str,strlen(str)+1,movecur,dest);};
// Put data from file fname to internal buffer from current pointer
// (if dest is negative) or from dest-th byte. Current pointer will be
// moved to the end of put data (skipping headers) if movecur equals true.
// Returns true if data was copied successfully, without truncation etc and
// false otherwise
bool PutDataFile(LPCTSTR fname, bool movecur=true, int dest=-1);
// Trim the buffer, by cutting the content, excluding the part of buffer
// from current pointer to the end. It is strongly to perform this
// operation only after all buffer's modifications
void Trim();
protected:
// Calculates needed buffer size
inline unsigned int GetNeededBufferSize(unsigned int datasize, unsigned int headsize, unsigned int maxdatasize) {return datasize?(datasize/maxdatasize*(headsize+maxdatasize)+((datasize%maxdatasize>0)?(datasize%maxdatasize+headsize):0)):headsize;};
// Calculate pointer by dest (if negative - then by m_pCurPtr). Result
// pointer will be put to ptr. If prtnsize is not NULL then portion size
// will be also calculated and put to variable, pointed by prtnsize
inline void DestToPtr(int dest, char*& ptr, unsigned int* prtnsize);
// Data members
bool m_bAutoDel; // Detele it automatically or not
unsigned int m_uHeadSize; // Size of header
unsigned int m_uDataSize; // Size of data
unsigned int m_uMaxDataSize; // Maximum size of data in single packet
unsigned int m_uBufferSize; // Size of allocated internal buffer
char* m_pBuffer; // Pointer to internal buffer
char* m_pCurPtr; // Current pointer
};
|
By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.
If a file you wish to view isn't highlighted, and is a text file (not binary), please
let us know and we'll add colourisation support for it.
Lev Naumov.
MSc in Computer Science. Graduated from Computer Technologies Department of Saint-Petersburg State University of Information Technologies, Mechanics and Optics.
Worked as C/C++ and Java programmer. Now - the research worker in "CAMEL Laboratory" and PhD student in Computer Technologies Department of Saint-Petersburg State University of Information Technologies, Mechanics and Optics.
Has scientific achievements in field of physics, automata theory, cellular automata theory, cluster computing. There are some publications.