拆分数据流Stream为基类和内存数据流MemoryStream,编译通过,未测试
This commit is contained in:
parent
98d1df4cfa
commit
0c6ee45297
|
@ -47,7 +47,7 @@ void Message::SetError(byte errorCode, const char* msg)
|
|||
|
||||
bool Message::Clone(const Message& msg)
|
||||
{
|
||||
Stream ms;
|
||||
MemoryStream ms;
|
||||
msg.Write(ms);
|
||||
|
||||
ms.SetPosition(0);
|
||||
|
|
|
@ -18,7 +18,7 @@ void MessageBase::WriteMessage(Message& msg)
|
|||
{
|
||||
// 如果是令牌消息,这里就要自己小心了
|
||||
//Stream ms(msg.Data, 256);
|
||||
Stream ms;
|
||||
MemoryStream ms;
|
||||
|
||||
Write(ms);
|
||||
|
||||
|
|
181
Stream.cpp
181
Stream.cpp
|
@ -1,87 +1,55 @@
|
|||
#include "Stream.h"
|
||||
|
||||
Stream::Stream(uint len)
|
||||
{
|
||||
if(len <= ArrayLength(_Arr))
|
||||
{
|
||||
len = ArrayLength(_Arr);
|
||||
_Buffer = _Arr;
|
||||
_needFree = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
_Buffer = new byte[len];
|
||||
assert_ptr(_Buffer);
|
||||
_needFree = true;
|
||||
}
|
||||
|
||||
_Capacity = len;
|
||||
_Position = 0;
|
||||
Length = len;
|
||||
_canWrite = true;
|
||||
Little = true;
|
||||
}
|
||||
|
||||
// 使用缓冲区初始化数据流。注意,此时指针位于0,而内容长度为缓冲区长度
|
||||
Stream::Stream(byte* buf, uint len)
|
||||
{
|
||||
assert_ptr(buf);
|
||||
//assert_param2(len > 0, "不能用0长度缓冲区来初始化数据流");
|
||||
|
||||
_Buffer = buf;
|
||||
_Capacity = len;
|
||||
_Position = 0;
|
||||
_needFree = false;
|
||||
_canWrite = true;
|
||||
Length = len;
|
||||
Little = true;
|
||||
Init(buf, len);
|
||||
}
|
||||
|
||||
Stream::Stream(const byte* buf, uint len)
|
||||
{
|
||||
assert_ptr(buf);
|
||||
Init((byte*)buf, len);
|
||||
|
||||
_Buffer = (byte*)buf;
|
||||
_Capacity = len;
|
||||
_Position = 0;
|
||||
_needFree = false;
|
||||
_canWrite = false;
|
||||
Length = len;
|
||||
Little = true;
|
||||
CanWrite = false;
|
||||
}
|
||||
|
||||
// 使用字节数组初始化数据流。注意,此时指针位于0,而内容长度为缓冲区长度
|
||||
Stream::Stream(ByteArray& bs)
|
||||
{
|
||||
_Buffer = bs.GetBuffer();
|
||||
_Capacity = bs.Length();
|
||||
_Position = 0;
|
||||
_needFree = false;
|
||||
_canWrite = true;
|
||||
Length = bs.Length();
|
||||
Little = true;
|
||||
Init(bs.GetBuffer(), bs.Length());
|
||||
}
|
||||
|
||||
Stream::Stream(const ByteArray& bs)
|
||||
{
|
||||
_Buffer = bs.GetBuffer();
|
||||
_Capacity = bs.Length();
|
||||
Init((byte*)bs.GetBuffer(), bs.Length());
|
||||
|
||||
CanWrite = false;
|
||||
}
|
||||
|
||||
void Stream::Init(byte* buf, uint len)
|
||||
{
|
||||
assert_ptr(buf);
|
||||
|
||||
_Buffer = buf;
|
||||
_Capacity = len;
|
||||
_Position = 0;
|
||||
_needFree = false;
|
||||
_canWrite = false;
|
||||
Length = bs.Length();
|
||||
CanWrite = true;
|
||||
Length = len;
|
||||
Little = true;
|
||||
}
|
||||
|
||||
// 销毁数据流
|
||||
Stream::~Stream()
|
||||
bool Stream::CheckRemain(uint count)
|
||||
{
|
||||
assert_ptr(this);
|
||||
if(_needFree)
|
||||
uint remain = _Capacity - _Position;
|
||||
// 容量不够,需要扩容
|
||||
if(count > remain)
|
||||
{
|
||||
if(_Buffer != _Arr) delete[] _Buffer;
|
||||
_Buffer = NULL;
|
||||
debug_printf("数据流 0x%08X 剩余容量 %d 不足 %d ,无法扩容!\r\n", this, remain, count);
|
||||
assert_param(false);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// 数据流容量
|
||||
|
@ -175,13 +143,12 @@ bool Stream::Write(const byte* buf, uint offset, uint count)
|
|||
{
|
||||
assert_param2(buf, "向数据流写入数据需要有效的缓冲区");
|
||||
|
||||
if(!_canWrite) return false;
|
||||
if(!CanWrite) return false;
|
||||
if(!CheckRemain(count)) return false;
|
||||
|
||||
memcpy(Current(), buf + offset, count);
|
||||
|
||||
_Position += count;
|
||||
//Length += count;
|
||||
// 内容长度不是累加,而是根据位置而扩大
|
||||
if(_Position > Length) Length = _Position;
|
||||
|
||||
|
@ -191,7 +158,7 @@ bool Stream::Write(const byte* buf, uint offset, uint count)
|
|||
// 写入7位压缩编码整数
|
||||
uint Stream::WriteEncodeInt(uint value)
|
||||
{
|
||||
if(!_canWrite) return false;
|
||||
if(!CanWrite) return false;
|
||||
|
||||
byte temp;
|
||||
for( int i = 0 ; i < 4 ; i++ )
|
||||
|
@ -212,7 +179,7 @@ uint Stream::WriteEncodeInt(uint value)
|
|||
// 写入字符串,先写入压缩编码整数表示的长度
|
||||
uint Stream::Write(const string str)
|
||||
{
|
||||
if(!_canWrite) return false;
|
||||
if(!CanWrite) return false;
|
||||
|
||||
int len = 0;
|
||||
if(str)
|
||||
|
@ -252,37 +219,6 @@ int Stream::Peek() const
|
|||
return *Current();
|
||||
}
|
||||
|
||||
bool Stream::CheckRemain(uint count)
|
||||
{
|
||||
uint remain = _Capacity - _Position;
|
||||
// 容量不够,需要扩容
|
||||
if(count > remain)
|
||||
{
|
||||
if(!_needFree && _Buffer != _Arr)
|
||||
{
|
||||
debug_printf("数据流 0x%08X 剩余容量 %d 不足 %d ,而外部缓冲区无法扩容!\r\n", this, remain, count);
|
||||
//assert_param(false);
|
||||
return false;
|
||||
}
|
||||
|
||||
// 原始容量成倍扩容
|
||||
uint total = _Position + count;
|
||||
uint size = _Capacity;
|
||||
while(size < total) size <<= 1;
|
||||
|
||||
// 申请新的空间,并复制数据
|
||||
byte* bufNew = new byte[size];
|
||||
if(_Position > 0) memcpy(bufNew, _Buffer, _Position);
|
||||
|
||||
if(_Buffer != _Arr) delete[] _Buffer;
|
||||
|
||||
_Buffer = bufNew;
|
||||
_Capacity = size;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// 从数据流读取变长数据到字节数组。以压缩整数开头表示长度
|
||||
uint Stream::ReadArray(ByteArray& bs)
|
||||
{
|
||||
|
@ -366,8 +302,6 @@ byte Stream::ReadByte()
|
|||
|
||||
ushort Stream::ReadUInt16()
|
||||
{
|
||||
//byte* p = ReadBytes(2);
|
||||
//ushort v = *(ushort*)p;
|
||||
ushort v;
|
||||
if(!Read((byte*)&v, 0, 2)) return 0;
|
||||
if(!Little) v = __REV16(v);
|
||||
|
@ -376,8 +310,6 @@ ushort Stream::ReadUInt16()
|
|||
|
||||
uint Stream::ReadUInt32()
|
||||
{
|
||||
//byte* p = ReadBytes(4);
|
||||
//uint v = *(uint*)p;
|
||||
uint v;
|
||||
if(!Read((byte*)&v, 0, 4)) return 0;
|
||||
if(!Little) v = __REV(v);
|
||||
|
@ -386,8 +318,6 @@ uint Stream::ReadUInt32()
|
|||
|
||||
ulong Stream::ReadUInt64()
|
||||
{
|
||||
//byte* p = ReadBytes(8);
|
||||
//ulong v = *(ulong*)p;
|
||||
ulong v;
|
||||
if(!Read((byte*)&v, 0, 8)) return 0;
|
||||
if(!Little) v = __REV(v >> 32) | ((ulong)__REV(v & 0xFFFFFFFF) << 32);
|
||||
|
@ -420,3 +350,56 @@ bool Stream::Write(ulong value)
|
|||
return Write((byte*)&value, 0, 8);
|
||||
}
|
||||
|
||||
MemoryStream::MemoryStream(uint len) : Stream(_Arr, ArrayLength(_Arr))
|
||||
{
|
||||
_needFree = false;
|
||||
if(len > ArrayLength(_Arr))
|
||||
{
|
||||
byte* buf = new byte[len];
|
||||
Init(buf, len);
|
||||
_needFree = true;
|
||||
}
|
||||
}
|
||||
|
||||
// 销毁数据流
|
||||
MemoryStream::~MemoryStream()
|
||||
{
|
||||
assert_ptr(this);
|
||||
if(_needFree)
|
||||
{
|
||||
if(_Buffer != _Arr) delete[] _Buffer;
|
||||
_Buffer = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
bool MemoryStream::CheckRemain(uint count)
|
||||
{
|
||||
uint remain = _Capacity - _Position;
|
||||
// 容量不够,需要扩容
|
||||
if(count > remain)
|
||||
{
|
||||
if(!_needFree && _Buffer != _Arr)
|
||||
{
|
||||
debug_printf("数据流 0x%08X 剩余容量 %d 不足 %d ,而外部缓冲区无法扩容!\r\n", this, remain, count);
|
||||
//assert_param(false);
|
||||
return false;
|
||||
}
|
||||
|
||||
// 原始容量成倍扩容
|
||||
uint total = _Position + count;
|
||||
uint size = _Capacity;
|
||||
while(size < total) size <<= 1;
|
||||
|
||||
// 申请新的空间,并复制数据
|
||||
byte* bufNew = new byte[size];
|
||||
if(_Position > 0) memcpy(bufNew, _Buffer, _Position);
|
||||
|
||||
if(_Buffer != _Arr) delete[] _Buffer;
|
||||
|
||||
_Buffer = bufNew;
|
||||
_Capacity = size;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
73
Stream.h
73
Stream.h
|
@ -4,40 +4,34 @@
|
|||
#include <stddef.h>
|
||||
#include "Sys.h"
|
||||
|
||||
// 内存数据流
|
||||
// 数据流
|
||||
// 数据流内有一个缓冲区,游标位置,数据长度。实际有效数据仅占用缓冲区中间部分,头尾都可能有剩余
|
||||
class Stream
|
||||
{
|
||||
private:
|
||||
protected:
|
||||
byte* _Buffer; // 数据缓冲区。扩容后会重新分配缓冲区
|
||||
uint _Capacity; // 缓冲区容量
|
||||
uint _Position; // 游标位置
|
||||
|
||||
byte _Arr[64]; // 内部缓冲区。较小内存需要时,直接使用栈分配,提高性能。
|
||||
|
||||
bool _needFree; // 是否自动释放
|
||||
bool _canWrite; // 是否可写
|
||||
void Init(byte* buf, uint len);
|
||||
virtual bool CheckRemain(uint count);
|
||||
public:
|
||||
bool Little; // 默认小字节序。仅影响数据读写操作
|
||||
uint Length; // 数据长度
|
||||
bool Little; // 默认小字节序。仅影响数据读写操作
|
||||
bool CanWrite; // 是否可写
|
||||
|
||||
// 分配指定大小的数据流
|
||||
Stream(uint len = 0);
|
||||
// 使用缓冲区初始化数据流。注意,此时指针位于0,而内容长度为缓冲区长度
|
||||
Stream(byte* buf, uint len);
|
||||
Stream(const byte* buf, uint len);
|
||||
// 使用字节数组初始化数据流。注意,此时指针位于0,而内容长度为缓冲区长度
|
||||
Stream(ByteArray& bs);
|
||||
Stream(const ByteArray& bs);
|
||||
// 销毁数据流
|
||||
~Stream();
|
||||
|
||||
// 数据流容量
|
||||
uint Capacity() const;
|
||||
void SetCapacity(uint len);
|
||||
// 当前位置
|
||||
uint Position() const;
|
||||
void SetCapacity(uint len);
|
||||
|
||||
// 设置位置
|
||||
bool SetPosition(int p);
|
||||
// 余下的有效数据流长度。0表示已经到达终点
|
||||
|
@ -102,52 +96,27 @@ public:
|
|||
return pt;
|
||||
}
|
||||
|
||||
/*// 常用读写整数方法
|
||||
template<typename T>
|
||||
T Read()
|
||||
{
|
||||
byte* p = Current();
|
||||
if(!Seek(sizeof(T))) return 0;
|
||||
|
||||
// 检查地址对齐
|
||||
if((uint)p % sizeof(T) == 0)
|
||||
return *(T*)p;
|
||||
|
||||
T obj;
|
||||
memcpy(&obj, p, sizeof(T));
|
||||
|
||||
return obj;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
bool Write(T value)
|
||||
{
|
||||
if(!_canWrite) return false;
|
||||
if(!CheckRemain(sizeof(T))) return false;
|
||||
|
||||
byte* p = Current();
|
||||
|
||||
// 检查地址对齐
|
||||
if((uint)p % sizeof(T) == 0)
|
||||
*(T*)p = value;
|
||||
else
|
||||
memcpy(p, &value, sizeof(T));
|
||||
|
||||
// 移动游标
|
||||
_Position += sizeof(T);
|
||||
if(_Position > Length) Length = _Position;
|
||||
|
||||
return true;
|
||||
}*/
|
||||
|
||||
// 读取指定长度的数据并返回首字节指针,移动数据流位置
|
||||
byte* ReadBytes(int count = -1);
|
||||
|
||||
// 读取一个字节,不移动游标。如果没有可用数据,则返回-1
|
||||
int Peek() const;
|
||||
};
|
||||
|
||||
// 内存数据流。预分配空间,自动扩容
|
||||
class MemoryStream : public Stream
|
||||
{
|
||||
private:
|
||||
bool CheckRemain(uint count);
|
||||
byte _Arr[0x40]; // 内部缓冲区。较小内存需要时,直接使用栈分配,提高性能。
|
||||
bool _needFree; // 是否自动释放
|
||||
|
||||
virtual bool CheckRemain(uint count);
|
||||
|
||||
public:
|
||||
// 分配指定大小的数据流
|
||||
MemoryStream(uint len = 0);
|
||||
// 销毁数据流
|
||||
~MemoryStream();
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -402,7 +402,7 @@ bool Gateway::SendDeviceInfo(const Device* dv)
|
|||
rs.Code = 0x25;
|
||||
// 担心rs.Data内部默认缓冲区不够大,这里直接使用数据流。必须小心,ms生命结束以后,它的缓冲区也将无法使用
|
||||
//Stream ms(rs.Data, rs.Length);
|
||||
Stream ms;
|
||||
MemoryStream ms;
|
||||
|
||||
dv->Write(ms);
|
||||
|
||||
|
|
Loading…
Reference in New Issue