!!!核心数组Array降为非模版,新增模版数组TArray,网关C测试通过。

这次修改影响整个系统每一个细节,各个地方要及时跟进
This commit is contained in:
nnhy 2015-10-30 04:36:18 +00:00
parent 3d27b28a0e
commit c26f493650
7 changed files with 354 additions and 272 deletions

View File

@ -45,7 +45,7 @@ private:
}
};
Array<Area, 0x08> Areas;
TArray<Area, 0x08> Areas;
bool OnHook(uint offset, uint size, int mode);
};

View File

@ -148,7 +148,7 @@ void TaskScheduler::Set(IArray<Task>* tasks)
// 创建任务返回任务编号。dueTime首次调度时间ms-1表示事件型任务period调度间隔ms-1表示仅处理一次
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;
IArray<Task>& ts = *_Tasks;

View File

@ -27,7 +27,7 @@ public:
};
// Socket列表
class SocketList : public Array<TinySocket*>
class SocketList : public TArray<TinySocket*>
{
public:
TinySocket* FindByType(ushort type);

View File

@ -35,7 +35,7 @@ public:
MessageHandler Received;
void* Param;
Array<Device*> Devices;
TArray<Device*> Devices;
Device* FindDevice(byte id);
Device* FindDevice(const ByteArray& hardid);
bool DeleteDevice(byte id);

View File

@ -459,7 +459,8 @@ void TokenController::ShowStat()
{
char cs[128];
String str(cs, ArrayLength(cs));
Stat->ToStr(str.Clear());
str.Clear();
Stat->ToStr(str);
str.Show(true);
Stat->Clear();

269
Type.cpp
View File

@ -55,9 +55,264 @@ void Object::Show(bool newLine) const
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(const void* data, int length, bool copy) : Array(0)
ByteArray::ByteArray(const void* data, int length, bool copy) : TArray(0)
{
if(copy)
Copy(data, length);
@ -65,7 +320,7 @@ ByteArray::ByteArray(const void* data, int length, bool copy) : Array(0)
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)
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();
Set((byte*)p, str.Length());
}
// 不允许修改,拷贝
ByteArray::ByteArray(const String& str) : Array(0)
ByteArray::ByteArray(const String& str) : TArray(0)
{
const char* p = str.GetBuffer();
//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;
return *this;
}
String& String::Append(char ch)

344
Type.h
View File

@ -88,6 +88,57 @@ public:
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>
class Array : public Object, public IArray<T>
class TArray : public Array, public IArray<T>
{
protected:
T* _Arr; // 数据指针
int _Length; // 数组长度
uint _Capacity; // 数组最大容量
bool _needFree; // 是否需要释放
bool _canWrite; // 是否可写
T Arr[ArraySize]; // 内部缓冲区
// 检查容量。如果不足则扩大,并备份指定长度的数据
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;
}
virtual void* Alloc(int len) { return new T[len]; }
public:
// 数组长度
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的数组");
if(length < 0) length = ArrayLength(Arr);
_Length = length;
if(length <= ArrayLength(Arr))
{
_Arr = Arr;
_Capacity = ArrayLength(Arr);
_needFree = false;
}
else
if(length > ArrayLength(Arr))
{
_Arr = new T[length];
_Capacity = length;
_needFree = true;
}
_canWrite = true;
_Size = sizeof(T);
}
Array(const Array& arr)
{
_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;
}
}
// 让父类的所有Set函数在这里可见
using Array::Set;
// 设置数组元素为指定值,自动扩容
bool Set(const T& item, int index = 0, int count = 0)
{
assert_param2(_canWrite, "禁止修改数组数据");
// 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;
return SetItem(&item, index, count);
}
// 设置指定位置的值,不足时自动扩容
virtual void SetAt(int i, const T& item)
{
assert_param2(_canWrite, "禁止修改数组数据");
// 检查长度,不足时扩容
CheckCapacity(i + 1, _Length);
if(i >= _Length) _Length = i + 1;
_Arr[i] = item;
SetItemAt(i, &item);
}
// 加入一个数据到末尾
virtual int Push(T& item)
{
assert_param2(_canWrite, "禁止修改数组数据");
SetItemAt(_Length, &item);
int i = _Length;
// 检查长度,不足时扩容
CheckCapacity(i + 1, _Length);
_Length++;
_Arr[i] = item;
return i;
return _Length;
}
// 末尾加入一个空数据,并返回引用,允许外部修改
@ -374,7 +222,8 @@ public:
_Length++;
return _Arr[i];
T* buf = (T*)_Arr;
return buf[i];
}
// 弹出最后一个数组元素,长度减一
@ -382,15 +231,17 @@ public:
{
assert_param2(_canWrite, "禁止修改数组数据");
return _Arr[--_Length];
T* buf = (T*)_Arr;
return buf[--_Length];
}
// 查找元素
virtual int FindIndex(const T item)
{
T* buf = (T*)_Arr;
for(int i=0; i<Length(); i++)
{
if(_Arr[i] == item) return i;
if(buf[i] == item) return i;
}
return -1;
@ -401,44 +252,21 @@ public:
{
assert_param2(_Arr && i >= 0 && i < _Length, "数组下标越界");
return _Arr[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;
T* buf = (T*)_Arr;
return buf[i];
}
};
// 字节数组
class ByteArray : public Array<byte>
class ByteArray : public TArray<byte>
{
public:
ByteArray(int length = 0) : Array(length) { }
ByteArray(byte item, int length) : Array(length) { Set(item, 0, length); }
ByteArray(int length = 0) : TArray(length) { }
ByteArray(byte item, int length) : TArray(length) { Set(item, 0, length); }
// 因为使用外部指针,这里初始化时没必要分配内存造成浪费
ByteArray(const 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(const String& str); // 不允许修改,拷贝
@ -474,25 +302,25 @@ public:
};
// 字符串
class String : public Array<char>
class String : public TArray<char>
{
private:
public:
// 字符串默认0长度容量0x40
String(int length = 0) : Array(length) { }
String(char item, int count) : Array(count) { Set(item, 0, count); }
String(int length = 0) : TArray(length) { }
String(char item, int count) : TArray(count) { Set(item, 0, count); }
// 因为使用外部指针,这里初始化时没必要分配内存造成浪费
String(void* str, int len = 0) : Array(0) { Set(str, len); }
String(const void* str, int len = 0) : Array(0) { Set(str, len); }
String(const String& str) : Array(str.Length()) { Copy(str); }
String(void* str, int len = 0) : TArray(0) { Set(str, len); }
String(const void* str, int len = 0) : TArray(0) { Set(str, len); }
String(const String& str) : TArray(str.Length()) { Copy(str); }
// 输出对象的字符串表示方式
virtual String& ToStr(String& str) const;
// 输出对象的字符串表示方式
virtual String ToString() const;
// 清空已存储数据。长度放大到最大容量
virtual String& Clear();
virtual void Clear();
String& Append(char ch);
String& Append(const char* str, int len = 0);
@ -581,7 +409,7 @@ public:
return _Arr[i];
}
// 列表转为指针,注意安全
//T* operator=(Array arr) { return arr.Arr; }
//T* operator=(TArray arr) { return arr.Arr; }
};
// 固定大小的指针数组。
@ -749,10 +577,10 @@ public:
/*// 变长列表模版
// T一般是指针列表内部有一个数组用于存放指针
template<typename T>
class List : public Array<T*>
class List : public TArray<T*>
{
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); }
// 添加单个元素