#ifndef _CELL_STREAM_HPP_
#define _CELL_STREAM_HPP_
#include <cstdint>
class CELLStream
{
public:
//創建數據塊 (寫消息)
CELLStream(int nSize = 1024)
{
_nSize = nSize;
_pBuff = new char[_nSize];
_bDelete = true;
}
//已有數據塊解析(讀消息)
CELLStream(char* pData, int nSize = 1024, bool bDelete = false)
{
_nSize = nSize;
_pBuff = pData;
_bDelete = bDelete;
}
~CELLStream()
{
if (_pBuff)
{
delete[] _pBuff;
_pBuff = nullptr;
}
}
//read
private:
template<typename T>
bool Read(T& n, bool isOffset = true)
{
//計算讀取數據的字節長度
auto nLen = sizeof(T);
//判斷能不能讀
if ( _nReadPos + nLen <= _nSize)
{
memcpy(&n, _pBuff + _nReadPos, nLen);
//計算已讀數據位置
if(isOffset)
_nReadPos += nLen;
return true;
}
return false;
}
public:
/*bool canRead()
{
return false;
}*/
template<typename T>
bool onlyRead(T& n = 0)
{
return Read(n, false);
}
int8_t ReadInt8(int8_t def = 0)
{
Read<int8_t>(def);
return def;
}
int16_t ReadInt16(int16_t def = 0)
{
Read<int16_t>(def);
return def;
}
int32_t ReadInt32(int32_t def = 0)
{
Read<int32_t>(def);
return def;
}
float ReadFloat(float def = 0)
{
Read<float>(def);
return def;
}
double ReadDouble(double def = 0)
{
Read<double>(def);
return def;
}
template<typename T>
bool ReadArrary(T* pData, uint32_t len)
{
//讀取數組的元素個數
/*
防止讀取數組的個數的時候能讀取數據的長度,但是裏面真實數據不能讀出來,所以爲了確保緩衝區不被破壞 暫時不偏移讀取位置的光標<_nReadPos>
*/
int32_t len1 = 0;
Read<int32_t>(len1, false);
//判斷緩衝區數據能否放下
if (len1 < len)
{
//計算讀取數據的數據大小
auto nLen = sizeof(T)*len1;
//s
if (_nReadPos + nLen + sizeof(int32_t) <= _nSize)
{
_nReadPos += sizeof(int32_t);
memcpy(pData, _pBuff + _nReadPos, nLen);
_nReadPos += nLen;
return len1;
}
}
return len1;
}
private:
//write
template<typename T>
bool Write(T& n)
{
//寫入數據的大小長度
size_t nLen = sizeof(T);
//判斷能不能寫入
if ( _nWritePos + nLen <= _nSize )
{
//將要寫入的數據 拷貝到緩衝區尾部
memcpy(_pBuff + _nWritePos, &n, nLen);
//計算已寫數據位置
_nWritePos += nLen;
return true;
}
return false;
}
public:
bool WriteInt8(int8_t n)
{
return Write<int8_t>(n);
}
bool WriteInt16(int16_t n)
{
return Write<int16_t>(n);
}
bool WriteInt32(int32_t n)
{
return Write<int32_t>(n);
}
bool WriteFloat(float n)
{
return Write<float>(n);
}
bool WriteDouble(double n)
{
return Write<double>(n);
}
/*
數組寫入
*/
template<typename T>
bool WriteArray(T* pData, uint32_t len)
{
//計算寫入數據的大小
//由於寫入數據的大小 讀取的時候不知道讀取的長度 故加個寫入數據大小長度一個字節頭
auto nLen = sizeof(T)* len;
//判斷能不能寫入
if (_nWritePos + nLen + sizeof(uint32_t) <= _nSize)
{
//先寫入數組的長度
WriteInt32(len);
//將要寫入的數據 拷貝到緩衝區尾部
memcpy(_pBuff + _nWritePos, pData, nLen);
//計算數據尾部位置
_nWritePos += nLen;
return true;
}
return false;
}
protected:
private:
//數據緩衝區
char* _pBuff = nullptr;
//緩衝區總空間大小,字節長度
int _nSize = 0;
//寫入數據的尾部位置,已寫入數據長度
int _nWritePos = 0;
//已讀數據的尾部位置,已讀取的數據的長度
int _nReadPos = 0;
//_pBuff是外部傳入的數據塊是否應該被釋放
bool _bDelete = true;
};
#endif