SmartOS/Core/Buffer.h

130 lines
4.8 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#ifndef _Buffer_H_
#define _Buffer_H_
#include "Type.h"
/*
数据区设计原则:
1固定数据区封装 Buffer => Object
2变长数据区封装 Array => Buffer
3自带初始缓冲区封装 ByteArray/String => Array
赋值运算符原则:
1赋值运算拷贝长度和数据核心语义为拷贝一份数据区
2左值长度大于等于右值时左值长度变小
3左值长度小于右值时左值尝试SetLength扩容
4如果扩容失败调试版断言失败发行版左值长度保持不变
*/
// 内存数据区。包装指针和长度
// 参考C#的Byte[],主要实现对象与指针的相互转化、赋值、拷贝、设置、截取、比较等操作。
// 内部指针指向的内存和长度,都由外部传入,内部不会自动分配。
// 所有的进出拷贝都是针对内部指针和最大长度不会自动扩容除非子类继承扩展SetLength。
// 拷贝的原则是尽力而为,有多少可用空间就拷贝多少长度。
class Buffer : public Object
{
public:
// 打包一个指针和长度指定的数据区
Buffer(void* ptr, int len);
// 禁用拷贝构造函数
Buffer(const Buffer& buf) = delete;
// 对象mov操作指针和长度归我清空对方
Buffer(Buffer&& rval);
// 从另一个对象拷贝数据和长度,长度不足且扩容失败时报错
Buffer& operator = (const Buffer& rhs);
// 从指针拷贝,使用我的长度
Buffer& operator = (const void* ptr);
// 对象mov操作指针和长度归我清空对方
Buffer& operator = (Buffer&& rval);
// 拿出指针供外部使用
inline byte* GetBuffer() { return (byte*)_Arr; }
inline const byte* GetBuffer() const { return (byte*)_Arr; }
inline int Length() const { return _Length; }
// 设置数组长度。只能缩小不能扩大,子类可以扩展以实现自动扩容
virtual bool SetLength(int len);
//virtual void SetBuffer(void* ptr, int len);
// 设置指定位置的值,长度不足时自动扩容
bool SetAt(int index, byte value);
// 重载索引运算符[],返回指定元素的第一个字节
byte operator[](int i) const;
// 支持 buf[i] = 0x36 的语法
byte& operator[](int i);
// 原始拷贝、清零,不检查边界
static void Copy(void* dest, const void* src, int len);
static void Zero(void* dest, int len);
// 拷贝数据,默认-1长度表示当前长度
virtual int Copy(int destIndex, const void* src, int len);
// 把数据复制到目标缓冲区,默认-1长度表示当前长度
virtual int CopyTo(int srcIndex, void* dest, int len) const;
// 拷贝数据,默认-1长度表示两者最小长度
virtual int Copy(int destIndex, const Buffer& src, int srcIndex, int len);
// 从另一个对象拷贝数据和长度,长度不足且扩容失败时报错
int Copy(const Buffer& src, int destIndex = 0);
// 用指定字节设置初始化一个区域
int Set(byte item, int index, int len);
void Clear(byte item = 0);
// 截取一个子缓冲区,默认-1长度表示剩余全部
//### 这里逻辑可以考虑修改为当len大于内部长度时直接用内部长度而不报错方便应用层免去比较长度的啰嗦
Buffer Sub(int index, int len);
const Buffer Sub(int index, int len) const;
// 显示十六进制数据,指定分隔字符和换行长度
String& ToHex(String& str, char sep = 0, int newLine = 0) const;
// 显示十六进制数据,指定分隔字符和换行长度
String ToHex(char sep = 0, int newLine = 0) const;
ushort ToUInt16() const;
uint ToUInt32() const;
UInt64 ToUInt64() const;
void Write(ushort value, int index = 0);
void Write(short value, int index = 0);
void Write(uint value, int index = 0);
void Write(int value, int index = 0);
void Write(UInt64 value, int index = 0);
// 输出对象的字符串表示方式
virtual String& ToStr(String& str) const;
// 包装为字符串对象
String AsString() const;
explicit operator bool() const { return _Length > 0; }
bool operator !() const { return _Length == 0; }
int CompareTo(const Buffer& bs) const;
int CompareTo(const void* ptr, int len = -1) const;
friend bool operator == (const Buffer& bs1, const Buffer& bs2);
friend bool operator == (const Buffer& bs1, const void* ptr);
friend bool operator != (const Buffer& bs1, const Buffer& bs2);
friend bool operator != (const Buffer& bs1, const void* ptr);
#if DEBUG
static void Test();
#endif
protected:
char* _Arr; // 数据指针
int _Length; // 长度
void move(Buffer& rval);
};
// 带引用计数的缓冲区
class BufferRef : public Buffer
{
public:
int Ref = 1; // 引用计数
// 打包一个指针和长度指定的数据区
void Set(void* ptr, int len);
};
#endif