Files
mir_server/sdk/srvlib/include/DataPacket.hpp

309 lines
8.9 KiB
C++
Raw Normal View History

2025-01-09 17:45:40 +08:00
#pragma once
/************************************************************************
MemoryStream相同
CBufferAllocator进行的使
ANSI字符串以及UNICODE16字符串
[2][65536][0]
************************************************************************/
#include "ObjectCounter.h"
#include "DataPacketReader.hpp"
class CDataPacket : public CDataPacketReader, public Counter<CDataPacket>
{
public:
/* 写入二进制数据
* lpBuffer
* dwSize
*/
inline void writeBuf(LPCVOID lpBuffer, size_t dwSize)
{
size_t dwMemSize = m_pMemoryEnd - m_pOffset;
if ( dwMemSize < dwSize )
{
setSize(m_pMemoryEnd - m_pMemory + dwSize);
}
memcpy(m_pOffset, lpBuffer, dwSize);
m_pOffset += dwSize;
//如果读写指针超过长度指针的位置,则调整长度指针为读写指针的位置
if ( m_pOffset > m_pDataEnd )
m_pDataEnd = m_pOffset;
}
/* 写入原子类型数据
* bool,char,short,int,__int64,float,double,void*
*/
template <typename T>
inline void writeAtom(T data)
{
size_t dwMemSize = m_pMemoryEnd - m_pOffset;
if ( dwMemSize < sizeof(data) )
{
setSize(m_pMemoryEnd - m_pMemory + sizeof(data));
}
*(T*)m_pOffset = data;
m_pOffset += sizeof(data);
//如果读写指针超过长度指针的位置,则调整长度指针为读写指针的位置
if ( m_pOffset > m_pDataEnd )
m_pDataEnd = m_pOffset;
}
inline void writeString(const char *str, size_t len = -1)
{
rawWriteStringLen<unsigned short>(str, len);
}
/* 写入UNICODE16字符串数据字符串长度必须在65536以内超过65535的部分将不会被写入
*
* len -1str的长度
*/
inline void writeWideString(const wchar_t *str, size_t len = -1)
{
rawWriteWideStringLen<unsigned short>(str, len);
}
public:
/* 设置数据包的数据长度
*
*
*/
inline void setLength(size_t newLength)
{
if ( newLength > (size_t)(m_pMemoryEnd - m_pMemory) )
setSize(newLength);
m_pDataEnd = m_pMemory + newLength;
//如果调整数据长度后偏移位置超出长度位置,则调整偏移位置为长度位置
if ( m_pOffset > m_pDataEnd )
m_pOffset = m_pDataEnd;
}
/* 设置数据包当前读写位置字节偏移量,
* setLength一样进行内存块的扩展操作
*/
inline size_t setPosition(size_t newPos)
{
size_t dwMemSize = m_pMemoryEnd - m_pMemory;
if ( newPos > dwMemSize )
setSize(newPos);
m_pOffset = m_pMemory + newPos;
//如果读写指针超过长度指针的位置,则调整长度指针为读写指针的位置
if ( m_pOffset > m_pDataEnd )
m_pDataEnd = m_pOffset;
return newPos;
}
/* 基于当前读写指针偏移位置调整偏移量
* nOffsetToAdjust
*
* 便
*/
inline size_t adjustOffset(INT64 nOffsetToAdjust)
{
m_pOffset += nOffsetToAdjust;
if ( m_pOffset < m_pMemory )
m_pOffset = m_pMemory;
else if ( m_pOffset > m_pMemoryEnd )
setSize(m_pOffset - m_pMemory);
if ( m_pOffset > m_pDataEnd )
m_pDataEnd = m_pOffset;
return m_pOffset - m_pMemory;
}
/*
*
*/
inline size_t reserve(size_t nSize)
{
size_t Result = m_pMemoryEnd - m_pMemory;
if ( Result < nSize )
setSize(nSize);
return Result;
}
/*
*
*/
inline size_t getAvaliableCapacity()
{
return m_pMemoryEnd - m_pOffset;
}
//获取当前占有的内存的物理长度
inline size_t getMemorySize()
{
return m_pMemoryEnd - m_pMemory;
}
public:
/*
* Comment: _DPPACK_MEM_CHK_的情况下
* @Return void:
*/
inline void _Assert()
{
#ifdef _DPPACK_MEM_CHK_
DbgAssert(!m_pMemoryEnd || *(PINT)m_pMemoryEnd == 0xCCDDCCEE);
#endif
}
/*
*
*/
inline CDataPacket& operator = (const CDataPacket& an)
{
//禁止引用赋值!
#ifdef WIN32
Assert(false);
#else
return *this;
#endif
}
public:
/* 写入原子数据的运算符重载 */
template <typename T>
inline CDataPacket& operator << (T val)
{
if ( sizeof(val) <= sizeof(INT_PTR) )
writeAtom<T>(val);
else writeBuf(&val, sizeof(val));
return *this;
}
inline CDataPacket& operator << (const char* val)
{
writeString(val, strlen(val));
return *this;
}
inline CDataPacket& operator << (char* val)
{
writeString(val, strlen(val));
return *this;
}
inline CDataPacket& operator << (const wchar_t* val)
{
#ifdef WIN32
writeWideString(val, wcslen(val));
#endif
return *this;
}
inline CDataPacket& operator << (wchar_t* val)
{
#ifdef WIN32
writeWideString(val, wcslen(val));
#endif
return *this;
}
public:
typedef CDataPacketReader Inherited;
CDataPacket()
:Inherited()
{
m_pAllocator = NULL;
}
CDataPacket(const CDataPacket &another)
{
//为了防止将引用赋值给一个对象,此处禁止从另一个对象中构造
#ifdef WIN32
Assert(FALSE);
#else
//return *this;
#endif
}
CDataPacket(LPCVOID lpDataPtr, size_t dwSize)
:Inherited(lpDataPtr, dwSize)
{
m_pDataEnd = m_pMemory;
m_pAllocator = NULL;
}
CDataPacket(CBufferAllocator *pAllocator)
:Inherited()
{
m_pAllocator = pAllocator;
}
~CDataPacket()
{
if ( m_pMemory && m_pAllocator )
{
m_pAllocator->FreeBuffer(m_pMemory);
m_pMemory = m_pMemoryEnd = m_pOffset = m_pDataEnd = NULL;
}
}
// 设置分配器
inline void setAllocator(CBufferAllocator *pAllocator) { m_pAllocator = pAllocator; }
protected:
/* 重新设定数据包内存空间大小 */
void setSize(size_t dwNewSize)
{
char *pOldMemory = m_pMemory;
//内存长度按CDataPacket::MemoryAlginmentSize字节对齐
//数据长度增加4字节用于增加0终止以便进行字符串的结尾调试
dwNewSize = (dwNewSize + MemoryAlginmentSize) & (~(MemoryAlginmentSize - 1));
#ifdef _DPPACK_MEM_CHK_
char *pMemory = (char*)m_pAllocator->AllocBuffer(dwNewSize + sizeof(INT));
#else
char *pMemory = (char*)m_pAllocator->AllocBuffer(dwNewSize);
#endif
size_t dwOffset = m_pOffset - m_pMemory;
size_t dwLength = m_pDataEnd - m_pMemory;
if ( dwLength > 0 )
{
memcpy(pMemory, m_pMemory, __min(dwNewSize, dwLength));
}
//重设数据指针
m_pMemory = pMemory;
m_pMemoryEnd = m_pMemory + dwNewSize;
#ifdef _DPPACK_MEM_CHK_
*(PINT)m_pMemoryEnd = 0xCCDDCCEE;
#endif
m_pOffset = m_pMemory + dwOffset;
m_pDataEnd = m_pMemory + dwLength;
//销毁原有数据内存
if ( pOldMemory )
{
_Assert();
m_pAllocator->FreeBuffer(pOldMemory);
}
}
/* 写入ANSI短字符串以及字符串数据
* [2][65536][0]65535
* sizeof(TL)
* <TL> unsigned charunsigned short
* len -1str的长度
*/
template <typename TL>
void rawWriteStringLen(const char* str, size_t len)
{
if ( len == -1 )
len = str?(TL)strlen(str):0;
writeAtom<TL>((TL)len);//写入长度
writeBuf(str, len * sizeof(*str));
writeAtom<char>(0);//写入终止字符
}
/* 写入UNICODE16短字符串以及字符串数据
* rawWriteLengthString相同
*/
template <typename TL>
void rawWriteWideStringLen(const wchar_t* str, size_t len)
{
#ifdef WIN32
if ( len == -1 )
len = str?(TL)wcslen(str):0;
writeAtom<TL>((TL)len);//写入长度
writeBuf(str, len * sizeof(*str));
writeAtom<wchar_t>(0);//写入终止字符
#endif
}
protected:
CBufferAllocator *m_pAllocator; //内存申请器
private:
static const size_t MemoryAlginmentSize = 256; //数据包内存长度对齐边界
};