!!!核心数组Array降为非模版,新增模版数组TArray,网关C测试通过。
这次修改影响整个系统每一个细节,各个地方要及时跟进
This commit is contained in:
parent
3d27b28a0e
commit
c26f493650
|
@ -45,7 +45,7 @@ private:
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
Array<Area, 0x08> Areas;
|
TArray<Area, 0x08> Areas;
|
||||||
|
|
||||||
bool OnHook(uint offset, uint size, int mode);
|
bool OnHook(uint offset, uint size, int mode);
|
||||||
};
|
};
|
||||||
|
|
2
Task.cpp
2
Task.cpp
|
@ -148,7 +148,7 @@ void TaskScheduler::Set(IArray<Task>* tasks)
|
||||||
// 创建任务,返回任务编号。dueTime首次调度时间ms,-1表示事件型任务,period调度间隔ms,-1表示仅处理一次
|
// 创建任务,返回任务编号。dueTime首次调度时间ms,-1表示事件型任务,period调度间隔ms,-1表示仅处理一次
|
||||||
uint TaskScheduler::Add(Action func, void* param, int dueTime, int period, string name)
|
uint TaskScheduler::Add(Action func, void* param, int dueTime, int period, string name)
|
||||||
{
|
{
|
||||||
if(!_Tasks) _Tasks = new Array<Task, 0x10>();
|
if(!_Tasks) _Tasks = new TArray<Task, 0x10>();
|
||||||
|
|
||||||
Task* task = NULL;
|
Task* task = NULL;
|
||||||
IArray<Task>& ts = *_Tasks;
|
IArray<Task>& ts = *_Tasks;
|
||||||
|
|
|
@ -27,7 +27,7 @@ public:
|
||||||
};
|
};
|
||||||
|
|
||||||
// Socket列表
|
// Socket列表
|
||||||
class SocketList : public Array<TinySocket*>
|
class SocketList : public TArray<TinySocket*>
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
TinySocket* FindByType(ushort type);
|
TinySocket* FindByType(ushort type);
|
||||||
|
|
|
@ -35,7 +35,7 @@ public:
|
||||||
MessageHandler Received;
|
MessageHandler Received;
|
||||||
void* Param;
|
void* Param;
|
||||||
|
|
||||||
Array<Device*> Devices;
|
TArray<Device*> Devices;
|
||||||
Device* FindDevice(byte id);
|
Device* FindDevice(byte id);
|
||||||
Device* FindDevice(const ByteArray& hardid);
|
Device* FindDevice(const ByteArray& hardid);
|
||||||
bool DeleteDevice(byte id);
|
bool DeleteDevice(byte id);
|
||||||
|
|
|
@ -459,7 +459,8 @@ void TokenController::ShowStat()
|
||||||
{
|
{
|
||||||
char cs[128];
|
char cs[128];
|
||||||
String str(cs, ArrayLength(cs));
|
String str(cs, ArrayLength(cs));
|
||||||
Stat->ToStr(str.Clear());
|
str.Clear();
|
||||||
|
Stat->ToStr(str);
|
||||||
str.Show(true);
|
str.Show(true);
|
||||||
|
|
||||||
Stat->Clear();
|
Stat->Clear();
|
||||||
|
|
269
Type.cpp
269
Type.cpp
|
@ -55,9 +55,264 @@ void Object::Show(bool newLine) const
|
||||||
Name.Set(name);
|
Name.Set(name);
|
||||||
}*/
|
}*/
|
||||||
|
|
||||||
|
/******************************** TArray ********************************/
|
||||||
|
// 数组长度
|
||||||
|
int Array::Length() const { return _Length; }
|
||||||
|
// 数组最大容量。初始化时决定,后面不允许改变
|
||||||
|
int Array::Capacity() const { return _Capacity; }
|
||||||
|
// 缓冲区
|
||||||
|
void* Array::GetBuffer() const { return _Arr; }
|
||||||
|
|
||||||
|
int memlen(const void* data)
|
||||||
|
{
|
||||||
|
// 自动计算长度,\0结尾,单字节大小时才允许
|
||||||
|
int len = 0;
|
||||||
|
byte* p =(byte*)data;
|
||||||
|
while(*p++) len++;
|
||||||
|
return len;
|
||||||
|
}
|
||||||
|
|
||||||
|
Array::Array(void* data, int len)
|
||||||
|
{
|
||||||
|
_Size = 1;
|
||||||
|
|
||||||
|
if(!len) len = memlen(data);
|
||||||
|
|
||||||
|
_Arr = data;
|
||||||
|
_Length = len;
|
||||||
|
_Capacity = len;
|
||||||
|
_needFree = false;
|
||||||
|
_canWrite = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
Array::Array(const void* data, int len)
|
||||||
|
{
|
||||||
|
_Size = 1;
|
||||||
|
|
||||||
|
if(!len) len = memlen(data);
|
||||||
|
|
||||||
|
_Arr = (void*)data;
|
||||||
|
_Length = len;
|
||||||
|
_Capacity = len;
|
||||||
|
_needFree = false;
|
||||||
|
_canWrite = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 析构。释放资源
|
||||||
|
Array::~Array()
|
||||||
|
{
|
||||||
|
if(_needFree && _Arr) delete _Arr;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 重载等号运算符,使用另一个固定数组来初始化
|
||||||
|
Array& Array::operator=(const Array& arr)
|
||||||
|
{
|
||||||
|
// 不要自己拷贝给自己
|
||||||
|
if(&arr == this) return *this;
|
||||||
|
|
||||||
|
_Length = 0;
|
||||||
|
|
||||||
|
Copy(arr);
|
||||||
|
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 设置数组长度。容量足够则缩小Length,否则扩容以确保数组容量足够大避免多次分配内存
|
||||||
|
bool Array::SetLength(int length, bool bak)
|
||||||
|
{
|
||||||
|
if(length <= _Capacity)
|
||||||
|
{
|
||||||
|
_Length = length;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if(!CheckCapacity(length, bak ? _Length : 0)) return false;
|
||||||
|
|
||||||
|
// 扩大长度
|
||||||
|
if(length > _Length) _Length = length;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 设置数组元素为指定值,自动扩容
|
||||||
|
bool Array::SetItem(const void* data, int index, int count)
|
||||||
|
{
|
||||||
|
assert_param2(_canWrite, "禁止修改数组数据");
|
||||||
|
// count<=0 表示设置全部元素
|
||||||
|
if(count <= 0) count = _Length - index;
|
||||||
|
assert_param2(count > 0, "TArray::Set的个数必须大于0");
|
||||||
|
|
||||||
|
// 检查长度是否足够
|
||||||
|
int len2 = index + count;
|
||||||
|
CheckCapacity(len2, index);
|
||||||
|
|
||||||
|
byte* buf = (byte*)GetBuffer();
|
||||||
|
// 如果元素类型大小为1,那么可以直接调用内存设置函数
|
||||||
|
if(_Size == 1)
|
||||||
|
memset(&buf[index], *(byte*)data, count);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
while(count-- > 0)
|
||||||
|
{
|
||||||
|
memcpy(buf, data, _Size);
|
||||||
|
buf += _Size;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 扩大长度
|
||||||
|
if(len2 > _Length) _Length = len2;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 设置数组。直接使用指针,不拷贝数据
|
||||||
|
bool Array::Set(void* data, int len)
|
||||||
|
{
|
||||||
|
if(!Set((const void*)data, len)) return false;
|
||||||
|
|
||||||
|
_canWrite = true;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 设置数组。直接使用指针,不拷贝数据
|
||||||
|
bool Array::Set(const void* data, int len)
|
||||||
|
{
|
||||||
|
if(!len) len = memlen(data);
|
||||||
|
|
||||||
|
// 销毁旧的
|
||||||
|
if(_needFree && _Arr && _Arr != data) delete _Arr;
|
||||||
|
|
||||||
|
_Arr = (void*)data;
|
||||||
|
_Length = len;
|
||||||
|
_Capacity = len;
|
||||||
|
_needFree = false;
|
||||||
|
_canWrite = false;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 复制数组。深度克隆,拷贝数据,自动扩容
|
||||||
|
int Array::Copy(const void* data, int len, int index)
|
||||||
|
{
|
||||||
|
assert_param2(_canWrite, "禁止修改数组数据");
|
||||||
|
if(!len) len = memlen(data);
|
||||||
|
|
||||||
|
// 检查长度是否足够
|
||||||
|
int len2 = index + len;
|
||||||
|
CheckCapacity(len2, index);
|
||||||
|
|
||||||
|
// 拷贝数据
|
||||||
|
memcpy((byte*)_Arr + _Size * index, data, _Size * len);
|
||||||
|
|
||||||
|
// 扩大长度
|
||||||
|
if(len2 > _Length) _Length = len2;
|
||||||
|
|
||||||
|
return len;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 把当前数组复制到目标缓冲区。未指定长度len时复制全部
|
||||||
|
int Array::CopyTo(void* data, int len, int index) const
|
||||||
|
{
|
||||||
|
// 数据长度可能不足
|
||||||
|
if(_Length - index < len || len == 0) len = _Length - index;
|
||||||
|
if(len <= 0) return 0;
|
||||||
|
|
||||||
|
// 拷贝数据
|
||||||
|
memcpy(data, (byte*)_Arr + _Size * index, _Size * len);
|
||||||
|
|
||||||
|
return len;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 清空已存储数据。
|
||||||
|
void Array::Clear()
|
||||||
|
{
|
||||||
|
assert_param2(_canWrite, "禁止修改数组数据");
|
||||||
|
memset(_Arr, 0, _Size * _Length);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 复制数组。深度克隆,拷贝数据
|
||||||
|
int Array::Copy(const Array& arr, int index)
|
||||||
|
{
|
||||||
|
assert_param2(_canWrite, "禁止修改数组数据");
|
||||||
|
if(&arr == this) return 0;
|
||||||
|
if(arr.Length() == 0) return 0;
|
||||||
|
|
||||||
|
return Copy(arr._Arr, arr.Length(), index);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 设置指定位置的值,不足时自动扩容
|
||||||
|
void Array::SetItemAt(int i, const void* item)
|
||||||
|
{
|
||||||
|
assert_param2(_canWrite, "禁止修改数组数据");
|
||||||
|
// 检查长度,不足时扩容
|
||||||
|
CheckCapacity(i + 1, _Length);
|
||||||
|
|
||||||
|
if(i >= _Length) _Length = i + 1;
|
||||||
|
|
||||||
|
//_Arr[i] = item;
|
||||||
|
memcpy((byte*)_Arr + _Size * i, item, _Size);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 检查容量。如果不足则扩大,并备份指定长度的数据
|
||||||
|
bool Array::CheckCapacity(int len, int bak)
|
||||||
|
{
|
||||||
|
// 是否超出容量
|
||||||
|
if(len <= _Capacity) return true;
|
||||||
|
|
||||||
|
// 自动计算合适的容量
|
||||||
|
int k = 0x40;
|
||||||
|
while(k < len) k <<= 1;
|
||||||
|
|
||||||
|
void* p = Alloc(k);
|
||||||
|
if(!p) return false;
|
||||||
|
|
||||||
|
// 是否需要备份数据
|
||||||
|
if(bak > _Length) bak = _Length;
|
||||||
|
if(bak > 0 && _Arr) memcpy(p, _Arr, bak);
|
||||||
|
|
||||||
|
if(_needFree && _Arr && _Arr != p) delete _Arr;
|
||||||
|
|
||||||
|
_Capacity = k;
|
||||||
|
_Arr = p;
|
||||||
|
_needFree = true;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void* Array::Alloc(int len) { return new byte[_Size * len];}
|
||||||
|
|
||||||
|
bool operator==(const Array& bs1, const Array& bs2)
|
||||||
|
{
|
||||||
|
if(bs1.Length() != bs2.Length()) return false;
|
||||||
|
|
||||||
|
/*for(int i=0; i<bs1.Length(); i++)
|
||||||
|
{
|
||||||
|
if(bs1[i] != bs2[i]) return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;*/
|
||||||
|
|
||||||
|
return memcmp(bs1._Arr, bs2._Arr, bs1.Length() * bs1._Size) == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool operator!=(const Array& bs1, const Array& bs2)
|
||||||
|
{
|
||||||
|
if(bs1.Length() != bs2.Length()) return true;
|
||||||
|
|
||||||
|
/*for(int i=0; i<bs1.Length(); i++)
|
||||||
|
{
|
||||||
|
if(bs1[i] != bs2[i]) return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;*/
|
||||||
|
|
||||||
|
return memcmp(bs1._Arr, bs2._Arr, bs1.Length() * bs1._Size) != 0;
|
||||||
|
}
|
||||||
|
|
||||||
/******************************** ByteArray ********************************/
|
/******************************** ByteArray ********************************/
|
||||||
|
|
||||||
ByteArray::ByteArray(const void* data, int length, bool copy) : Array(0)
|
ByteArray::ByteArray(const void* data, int length, bool copy) : TArray(0)
|
||||||
{
|
{
|
||||||
if(copy)
|
if(copy)
|
||||||
Copy(data, length);
|
Copy(data, length);
|
||||||
|
@ -65,7 +320,7 @@ ByteArray::ByteArray(const void* data, int length, bool copy) : Array(0)
|
||||||
Set(data, length);
|
Set(data, length);
|
||||||
}
|
}
|
||||||
|
|
||||||
ByteArray::ByteArray(void* data, int length, bool copy) : Array(0)
|
ByteArray::ByteArray(void* data, int length, bool copy) : TArray(0)
|
||||||
{
|
{
|
||||||
if(copy)
|
if(copy)
|
||||||
Copy(data, length);
|
Copy(data, length);
|
||||||
|
@ -74,14 +329,14 @@ ByteArray::ByteArray(void* data, int length, bool copy) : Array(0)
|
||||||
}
|
}
|
||||||
|
|
||||||
// 字符串转为字节数组
|
// 字符串转为字节数组
|
||||||
ByteArray::ByteArray(String& str) : Array(0)
|
ByteArray::ByteArray(String& str) : TArray(0)
|
||||||
{
|
{
|
||||||
char* p = str.GetBuffer();
|
char* p = str.GetBuffer();
|
||||||
Set((byte*)p, str.Length());
|
Set((byte*)p, str.Length());
|
||||||
}
|
}
|
||||||
|
|
||||||
// 不允许修改,拷贝
|
// 不允许修改,拷贝
|
||||||
ByteArray::ByteArray(const String& str) : Array(0)
|
ByteArray::ByteArray(const String& str) : TArray(0)
|
||||||
{
|
{
|
||||||
const char* p = str.GetBuffer();
|
const char* p = str.GetBuffer();
|
||||||
//Copy((const byte*)p, str.Length());
|
//Copy((const byte*)p, str.Length());
|
||||||
|
@ -253,13 +508,11 @@ String String::ToString() const
|
||||||
}
|
}
|
||||||
|
|
||||||
// 清空已存储数据。长度放大到最大容量
|
// 清空已存储数据。长度放大到最大容量
|
||||||
String& String::Clear()
|
void String::Clear()
|
||||||
{
|
{
|
||||||
Array::Clear();
|
TArray::Clear();
|
||||||
|
|
||||||
_Length = 0;
|
_Length = 0;
|
||||||
|
|
||||||
return *this;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
String& String::Append(char ch)
|
String& String::Append(char ch)
|
||||||
|
|
346
Type.h
346
Type.h
|
@ -88,6 +88,57 @@ public:
|
||||||
virtual T& operator[](int i) const = 0;
|
virtual T& operator[](int i) const = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class Array : public Object
|
||||||
|
{
|
||||||
|
protected:
|
||||||
|
void* _Arr; // 数据指针
|
||||||
|
int _Length; // 元素个数。非字节数
|
||||||
|
uint _Capacity; // 最大个数。非字节数
|
||||||
|
bool _needFree; // 是否需要释放
|
||||||
|
bool _canWrite; // 是否可写
|
||||||
|
ushort _Size; // 单个元素大小。字节
|
||||||
|
|
||||||
|
public:
|
||||||
|
// 数组长度
|
||||||
|
int Length() const;
|
||||||
|
// 数组最大容量。初始化时决定,后面不允许改变
|
||||||
|
int Capacity() const;
|
||||||
|
// 缓冲区
|
||||||
|
void* GetBuffer() const;
|
||||||
|
|
||||||
|
Array(void* data, int len = 0);
|
||||||
|
Array(const void* data, int len = 0);
|
||||||
|
// 重载等号运算符,使用另一个固定数组来初始化
|
||||||
|
Array& operator=(const Array& arr);
|
||||||
|
virtual ~Array();
|
||||||
|
|
||||||
|
// 设置数组长度。容量足够则缩小Length,否则扩容以确保数组容量足够大避免多次分配内存
|
||||||
|
bool SetLength(int length, bool bak = false);
|
||||||
|
// 设置数组元素为指定值,自动扩容
|
||||||
|
bool SetItem(const void* data, int index = 0, int count = 0);
|
||||||
|
// 设置数组。直接使用指针,不拷贝数据
|
||||||
|
bool Set(void* data, int len = 0);
|
||||||
|
// 设置数组。直接使用指针,不拷贝数据
|
||||||
|
bool Set(const void* data, int len = 0);
|
||||||
|
// 复制数组。深度克隆,拷贝数据,自动扩容
|
||||||
|
int Copy(const void* data, int len = 0, int index = 0);
|
||||||
|
// 把当前数组复制到目标缓冲区。未指定长度len时复制全部
|
||||||
|
int CopyTo(void* data, int len = 0, int index = 0) const;
|
||||||
|
// 清空已存储数据。
|
||||||
|
virtual void Clear();
|
||||||
|
// 复制数组。深度克隆,拷贝数据
|
||||||
|
int Copy(const Array& arr, int index = 0);
|
||||||
|
// 设置指定位置的值,不足时自动扩容
|
||||||
|
virtual void SetItemAt(int i, const void* item);
|
||||||
|
|
||||||
|
friend bool operator==(const Array& bs1, const Array& bs2);
|
||||||
|
friend bool operator!=(const Array& bs1, const Array& bs2);
|
||||||
|
protected:
|
||||||
|
// 检查容量。如果不足则扩大,并备份指定长度的数据
|
||||||
|
bool CheckCapacity(int len, int bak = 0);
|
||||||
|
virtual void* Alloc(int len);
|
||||||
|
};
|
||||||
|
|
||||||
// 数组
|
// 数组
|
||||||
/*
|
/*
|
||||||
数组是指针和长度的封装。
|
数组是指针和长度的封装。
|
||||||
|
@ -107,260 +158,57 @@ public:
|
||||||
外=>外 仅复制指针
|
外=>外 仅复制指针
|
||||||
*/
|
*/
|
||||||
template<typename T, int ArraySize = 0x40>
|
template<typename T, int ArraySize = 0x40>
|
||||||
class Array : public Object, public IArray<T>
|
class TArray : public Array, public IArray<T>
|
||||||
{
|
{
|
||||||
protected:
|
protected:
|
||||||
T* _Arr; // 数据指针
|
|
||||||
int _Length; // 数组长度
|
|
||||||
uint _Capacity; // 数组最大容量
|
|
||||||
bool _needFree; // 是否需要释放
|
|
||||||
bool _canWrite; // 是否可写
|
|
||||||
|
|
||||||
T Arr[ArraySize]; // 内部缓冲区
|
T Arr[ArraySize]; // 内部缓冲区
|
||||||
|
|
||||||
// 检查容量。如果不足则扩大,并备份指定长度的数据
|
virtual void* Alloc(int len) { return new T[len]; }
|
||||||
void CheckCapacity(int len, int bak = 0)
|
|
||||||
{
|
|
||||||
// 是否超出容量
|
|
||||||
if(len <= _Capacity) return;
|
|
||||||
|
|
||||||
// 自动计算合适的容量
|
|
||||||
int k = 0x40;
|
|
||||||
while(k < len) k <<= 1;
|
|
||||||
|
|
||||||
T* p = new T[k];
|
|
||||||
|
|
||||||
// 是否需要备份数据
|
|
||||||
if(bak > _Length) bak = _Length;
|
|
||||||
if(bak > 0 && _Arr) memcpy(p, _Arr, bak);
|
|
||||||
|
|
||||||
if(_needFree && _Arr) delete _Arr;
|
|
||||||
|
|
||||||
_Capacity = k;
|
|
||||||
_Arr = p;
|
|
||||||
_needFree = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
// 数组长度
|
// 数组长度
|
||||||
virtual int Length() const { return _Length; }
|
virtual int Length() const { return _Length; }
|
||||||
// 数组最大容量。初始化时决定,后面不允许改变
|
|
||||||
int Capacity() const { return _Capacity; }
|
|
||||||
// 缓冲区
|
// 缓冲区
|
||||||
T* GetBuffer() const { return _Arr; }
|
T* GetBuffer() const { return (T*)_Arr; }
|
||||||
|
|
||||||
// 初始化指定长度的数组。默认使用内部缓冲区
|
// 初始化指定长度的数组。默认使用内部缓冲区
|
||||||
Array(int length = ArraySize)
|
TArray(int length = ArraySize) : Array(Arr, ArrayLength(Arr))
|
||||||
{
|
{
|
||||||
assert_param2(length <= 0x400, "禁止分配超过1k的数组");
|
assert_param2(length <= 0x400, "禁止分配超过1k的数组");
|
||||||
if(length < 0) length = ArrayLength(Arr);
|
if(length < 0) length = ArrayLength(Arr);
|
||||||
|
|
||||||
_Length = length;
|
_Length = length;
|
||||||
if(length <= ArrayLength(Arr))
|
if(length > ArrayLength(Arr))
|
||||||
{
|
|
||||||
_Arr = Arr;
|
|
||||||
_Capacity = ArrayLength(Arr);
|
|
||||||
_needFree = false;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
_Arr = new T[length];
|
_Arr = new T[length];
|
||||||
_Capacity = length;
|
_Capacity = length;
|
||||||
_needFree = true;
|
_needFree = true;
|
||||||
}
|
}
|
||||||
_canWrite = true;
|
|
||||||
|
_Size = sizeof(T);
|
||||||
}
|
}
|
||||||
|
|
||||||
Array(const Array& arr)
|
// 让父类的所有Set函数在这里可见
|
||||||
{
|
using Array::Set;
|
||||||
_Length = arr.Length();
|
|
||||||
_canWrite = true;
|
|
||||||
|
|
||||||
Copy(arr);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 析构。释放资源
|
|
||||||
virtual ~Array()
|
|
||||||
{
|
|
||||||
if(_needFree && _Arr) delete _Arr;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 重载等号运算符,使用另一个固定数组来初始化
|
|
||||||
Array& operator=(const Array& arr)
|
|
||||||
{
|
|
||||||
// 不要自己拷贝给自己
|
|
||||||
if(&arr == this) return *this;
|
|
||||||
|
|
||||||
_Length = 0;
|
|
||||||
|
|
||||||
Copy(arr);
|
|
||||||
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 设置数组长度。容量足够则缩小Length,否则扩容以确保数组容量足够大避免多次分配内存
|
|
||||||
bool SetLength(int length, bool bak = false)
|
|
||||||
{
|
|
||||||
if(length <= _Capacity)
|
|
||||||
{
|
|
||||||
_Length = length;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
CheckCapacity(length, bak ? _Length : 0);
|
|
||||||
|
|
||||||
// 扩大长度
|
|
||||||
if(length > _Length) _Length = length;
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 设置数组元素为指定值,自动扩容
|
// 设置数组元素为指定值,自动扩容
|
||||||
bool Set(const T& item, int index = 0, int count = 0)
|
bool Set(const T& item, int index = 0, int count = 0)
|
||||||
{
|
{
|
||||||
assert_param2(_canWrite, "禁止修改数组数据");
|
return SetItem(&item, index, count);
|
||||||
// count<=0 表示设置全部元素
|
|
||||||
if(count <= 0) count = _Length - index;
|
|
||||||
assert_param2(count > 0, "Array::Set的个数必须大于0");
|
|
||||||
|
|
||||||
// 检查长度是否足够
|
|
||||||
int len2 = index + count;
|
|
||||||
CheckCapacity(len2, index);
|
|
||||||
|
|
||||||
// 如果元素类型大小为1,那么可以直接调用内存设置函数
|
|
||||||
if(sizeof(T) == 1)
|
|
||||||
memset(_Arr + index, item, sizeof(T) * count);
|
|
||||||
else
|
|
||||||
while(count-- > 0) _Arr[index++] = item;
|
|
||||||
|
|
||||||
// 扩大长度
|
|
||||||
if(len2 > _Length) _Length = len2;
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 设置数组。直接使用指针,不拷贝数据
|
|
||||||
bool Set(void* data, int len = 0)
|
|
||||||
{
|
|
||||||
if(!Set((const void*)data, len)) return false;
|
|
||||||
|
|
||||||
_canWrite = true;
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 设置数组。直接使用指针,不拷贝数据
|
|
||||||
bool Set(const void* data, int len = 0)
|
|
||||||
{
|
|
||||||
int max = len;
|
|
||||||
if(!data)
|
|
||||||
{
|
|
||||||
data = Arr;
|
|
||||||
max = ArrayLength(Arr);
|
|
||||||
}
|
|
||||||
// 自动计算长度,\0结尾
|
|
||||||
else if(!len)
|
|
||||||
{
|
|
||||||
byte* p =(byte*)data;
|
|
||||||
while(*p++) len++;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 销毁旧的
|
|
||||||
if(_needFree && _Arr) delete _Arr;
|
|
||||||
|
|
||||||
_Arr = (T*)data;
|
|
||||||
_Length = len;
|
|
||||||
_Capacity = max;
|
|
||||||
_needFree = false;
|
|
||||||
_canWrite = false;
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 复制数组。深度克隆,拷贝数据
|
|
||||||
int Copy(const Array& arr, int index = 0)
|
|
||||||
{
|
|
||||||
assert_param2(_canWrite, "禁止修改数组数据");
|
|
||||||
if(&arr == this) return 0;
|
|
||||||
if(arr.Length() == 0) return 0;
|
|
||||||
|
|
||||||
return Copy(arr._Arr, arr.Length(), index);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 复制数组。深度克隆,拷贝数据,自动扩容
|
|
||||||
int Copy(const void* data, int len = 0, int index = 0)
|
|
||||||
{
|
|
||||||
assert_param2(_canWrite, "禁止修改数组数据");
|
|
||||||
// 自动计算长度,\0结尾
|
|
||||||
if(!len)
|
|
||||||
{
|
|
||||||
byte* p =(byte*)data;
|
|
||||||
while(*p++) len++;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 检查长度是否足够
|
|
||||||
int len2 = index + len;
|
|
||||||
CheckCapacity(len2, index);
|
|
||||||
|
|
||||||
// 拷贝数据
|
|
||||||
memcpy(_Arr + index, data, sizeof(T) * len);
|
|
||||||
|
|
||||||
// 扩大长度
|
|
||||||
if(len2 > _Length) _Length = len2;
|
|
||||||
|
|
||||||
return len;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 把当前数组复制到目标缓冲区。未指定长度len时复制全部
|
|
||||||
int CopyTo(void* data, int len = 0, int index = 0) const
|
|
||||||
{
|
|
||||||
// 数据长度可能不足
|
|
||||||
if(_Length - index < len || len == 0) len = _Length - index;
|
|
||||||
if(len <= 0) return 0;
|
|
||||||
|
|
||||||
// 拷贝数据
|
|
||||||
memcpy(data, _Arr + index, sizeof(T) * len);
|
|
||||||
|
|
||||||
return len;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 清空已存储数据。
|
|
||||||
virtual Array& Clear()
|
|
||||||
{
|
|
||||||
assert_param2(_canWrite, "禁止修改数组数据");
|
|
||||||
memset(_Arr, 0, sizeof(T) * _Length);
|
|
||||||
|
|
||||||
return *this;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 设置指定位置的值,不足时自动扩容
|
// 设置指定位置的值,不足时自动扩容
|
||||||
virtual void SetAt(int i, const T& item)
|
virtual void SetAt(int i, const T& item)
|
||||||
{
|
{
|
||||||
assert_param2(_canWrite, "禁止修改数组数据");
|
SetItemAt(i, &item);
|
||||||
// 检查长度,不足时扩容
|
|
||||||
CheckCapacity(i + 1, _Length);
|
|
||||||
|
|
||||||
if(i >= _Length) _Length = i + 1;
|
|
||||||
|
|
||||||
_Arr[i] = item;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 加入一个数据到末尾
|
// 加入一个数据到末尾
|
||||||
virtual int Push(T& item)
|
virtual int Push(T& item)
|
||||||
{
|
{
|
||||||
assert_param2(_canWrite, "禁止修改数组数据");
|
SetItemAt(_Length, &item);
|
||||||
|
|
||||||
int i = _Length;
|
return _Length;
|
||||||
// 检查长度,不足时扩容
|
|
||||||
CheckCapacity(i + 1, _Length);
|
|
||||||
|
|
||||||
_Length++;
|
|
||||||
|
|
||||||
_Arr[i] = item;
|
|
||||||
|
|
||||||
return i;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 末尾加入一个空数据,并返回引用,允许外部修改
|
// 末尾加入一个空数据,并返回引用,允许外部修改
|
||||||
|
@ -374,7 +222,8 @@ public:
|
||||||
|
|
||||||
_Length++;
|
_Length++;
|
||||||
|
|
||||||
return _Arr[i];
|
T* buf = (T*)_Arr;
|
||||||
|
return buf[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
// 弹出最后一个数组元素,长度减一
|
// 弹出最后一个数组元素,长度减一
|
||||||
|
@ -382,15 +231,17 @@ public:
|
||||||
{
|
{
|
||||||
assert_param2(_canWrite, "禁止修改数组数据");
|
assert_param2(_canWrite, "禁止修改数组数据");
|
||||||
|
|
||||||
return _Arr[--_Length];
|
T* buf = (T*)_Arr;
|
||||||
|
return buf[--_Length];
|
||||||
}
|
}
|
||||||
|
|
||||||
// 查找元素
|
// 查找元素
|
||||||
virtual int FindIndex(const T item)
|
virtual int FindIndex(const T item)
|
||||||
{
|
{
|
||||||
|
T* buf = (T*)_Arr;
|
||||||
for(int i=0; i<Length(); i++)
|
for(int i=0; i<Length(); i++)
|
||||||
{
|
{
|
||||||
if(_Arr[i] == item) return i;
|
if(buf[i] == item) return i;
|
||||||
}
|
}
|
||||||
|
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -401,44 +252,21 @@ public:
|
||||||
{
|
{
|
||||||
assert_param2(_Arr && i >= 0 && i < _Length, "数组下标越界");
|
assert_param2(_Arr && i >= 0 && i < _Length, "数组下标越界");
|
||||||
|
|
||||||
return _Arr[i];
|
T* buf = (T*)_Arr;
|
||||||
}
|
return buf[i];
|
||||||
|
|
||||||
friend bool operator==(const Array& bs1, const Array& bs2)
|
|
||||||
{
|
|
||||||
if(bs1.Length() != bs2.Length()) return false;
|
|
||||||
|
|
||||||
for(int i=0; i<bs1.Length(); i++)
|
|
||||||
{
|
|
||||||
if(bs1[i] != bs2[i]) return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
friend bool operator!=(const Array& bs1, const Array& bs2)
|
|
||||||
{
|
|
||||||
if(bs1.Length() != bs2.Length()) return true;
|
|
||||||
|
|
||||||
for(int i=0; i<bs1.Length(); i++)
|
|
||||||
{
|
|
||||||
if(bs1[i] != bs2[i]) return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// 字节数组
|
// 字节数组
|
||||||
class ByteArray : public Array<byte>
|
class ByteArray : public TArray<byte>
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
ByteArray(int length = 0) : Array(length) { }
|
ByteArray(int length = 0) : TArray(length) { }
|
||||||
ByteArray(byte item, int length) : Array(length) { Set(item, 0, length); }
|
ByteArray(byte item, int length) : TArray(length) { Set(item, 0, length); }
|
||||||
// 因为使用外部指针,这里初始化时没必要分配内存造成浪费
|
// 因为使用外部指针,这里初始化时没必要分配内存造成浪费
|
||||||
ByteArray(const void* data, int length, bool copy = false);
|
ByteArray(const void* data, int length, bool copy = false);
|
||||||
ByteArray(void* data, int length, bool copy = false);
|
ByteArray(void* data, int length, bool copy = false);
|
||||||
ByteArray(const ByteArray& arr) : Array(arr.Length()) { Copy(arr); }
|
ByteArray(const ByteArray& arr) : TArray(arr.Length()) { Copy(arr); }
|
||||||
ByteArray(String& str); // 直接引用数据缓冲区
|
ByteArray(String& str); // 直接引用数据缓冲区
|
||||||
ByteArray(const String& str); // 不允许修改,拷贝
|
ByteArray(const String& str); // 不允许修改,拷贝
|
||||||
|
|
||||||
|
@ -474,25 +302,25 @@ public:
|
||||||
};
|
};
|
||||||
|
|
||||||
// 字符串
|
// 字符串
|
||||||
class String : public Array<char>
|
class String : public TArray<char>
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
|
|
||||||
public:
|
public:
|
||||||
// 字符串默认0长度,容量0x40
|
// 字符串默认0长度,容量0x40
|
||||||
String(int length = 0) : Array(length) { }
|
String(int length = 0) : TArray(length) { }
|
||||||
String(char item, int count) : Array(count) { Set(item, 0, count); }
|
String(char item, int count) : TArray(count) { Set(item, 0, count); }
|
||||||
// 因为使用外部指针,这里初始化时没必要分配内存造成浪费
|
// 因为使用外部指针,这里初始化时没必要分配内存造成浪费
|
||||||
String(void* str, int len = 0) : Array(0) { Set(str, len); }
|
String(void* str, int len = 0) : TArray(0) { Set(str, len); }
|
||||||
String(const void* str, int len = 0) : Array(0) { Set(str, len); }
|
String(const void* str, int len = 0) : TArray(0) { Set(str, len); }
|
||||||
String(const String& str) : Array(str.Length()) { Copy(str); }
|
String(const String& str) : TArray(str.Length()) { Copy(str); }
|
||||||
|
|
||||||
// 输出对象的字符串表示方式
|
// 输出对象的字符串表示方式
|
||||||
virtual String& ToStr(String& str) const;
|
virtual String& ToStr(String& str) const;
|
||||||
// 输出对象的字符串表示方式
|
// 输出对象的字符串表示方式
|
||||||
virtual String ToString() const;
|
virtual String ToString() const;
|
||||||
// 清空已存储数据。长度放大到最大容量
|
// 清空已存储数据。长度放大到最大容量
|
||||||
virtual String& Clear();
|
virtual void Clear();
|
||||||
|
|
||||||
String& Append(char ch);
|
String& Append(char ch);
|
||||||
String& Append(const char* str, int len = 0);
|
String& Append(const char* str, int len = 0);
|
||||||
|
@ -581,7 +409,7 @@ public:
|
||||||
return _Arr[i];
|
return _Arr[i];
|
||||||
}
|
}
|
||||||
// 列表转为指针,注意安全
|
// 列表转为指针,注意安全
|
||||||
//T* operator=(Array arr) { return arr.Arr; }
|
//T* operator=(TArray arr) { return arr.Arr; }
|
||||||
};
|
};
|
||||||
|
|
||||||
// 固定大小的指针数组。
|
// 固定大小的指针数组。
|
||||||
|
@ -749,10 +577,10 @@ public:
|
||||||
/*// 变长列表模版
|
/*// 变长列表模版
|
||||||
// T一般是指针,列表内部有一个数组用于存放指针
|
// T一般是指针,列表内部有一个数组用于存放指针
|
||||||
template<typename T>
|
template<typename T>
|
||||||
class List : public Array<T*>
|
class List : public TArray<T*>
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
List(int size = 0) : Array(size) { _Length = 0; }
|
List(int size = 0) : TArray(size) { _Length = 0; }
|
||||||
List(T* items, uint count) { Set(items, count); }
|
List(T* items, uint count) { Set(items, count); }
|
||||||
|
|
||||||
// 添加单个元素
|
// 添加单个元素
|
||||||
|
|
Loading…
Reference in New Issue