整合List到Type,增加Array.FindIndex

This commit is contained in:
nnhy 2015-10-29 03:35:35 +00:00
parent 7a5f259ea3
commit c1544f64e1
13 changed files with 859 additions and 30 deletions

View File

@ -2,7 +2,6 @@
#define __Controller_H__
#include "Sys.h"
#include "List.h"
#include "Net\ITransport.h"
#include "Message.h"

View File

@ -38,6 +38,11 @@ private:
Area();
bool Contain(uint offset, uint size);
friend bool operator==(const Area& a1, const Area& a2)
{
return a1.Offset == a2.Offset && a1.Size == a2.Size;
}
};
Array<Area, 0x08> Areas;

3
Sys.h
View File

@ -119,9 +119,6 @@ public:
extern TSys Sys; //创建一个全局的Sys对象 会在main函数之前执行构造函数
// 内存管理
#include "Memory.h"
//#include "Time.h"
#include "Interrupt.h"

3
Task.h
View File

@ -2,7 +2,6 @@
#define __Task_H__
#include "Sys.h"
#include "List.h"
class TaskScheduler;
@ -46,6 +45,8 @@ public:
// 显示状态
void ShowStatus();
friend bool operator==(const Task& t1, const Task& t2) { return &t1 == &t2; }
// 全局任务调度器
static TaskScheduler* Scheduler();
static Task* Get(int taskid);

View File

@ -2,7 +2,6 @@
#define __Thread_H__
#include "Sys.h"
#include "List.h"
class Thread;

View File

@ -2,7 +2,6 @@
#define _TinyIP_ICMP_H_
#include "Sys.h"
#include "List.h"
#include "Stream.h"
#include "TinyIP.h"

View File

@ -34,7 +34,7 @@ void TinyIP::Init()
Mask = 0x00FFFFFF;
DHCPServer = Gateway = DNSServer = IP = 0;
Sockets.SetCapacity(0x10);
//Sockets.SetCapacity(0x10);
Arp = NULL;
}
@ -162,7 +162,7 @@ void TinyIP::Process(Stream& ms)
// 各处理器有可能改变数据流游标,这里备份一下
uint p = ms.Position();
// 考虑到可能有通用端口处理器,也可能有专用端口处理器(一般在后面),这里偷懒使用倒序处理
uint count = Sockets.Count();
uint count = Sockets.Length();
for(int i=count-1; i>=0; i--)
{
TinySocket* socket = Sockets[i];
@ -417,6 +417,19 @@ TinySocket::TinySocket(TinyIP* tip, IP_TYPE type)
// 除了ARP以外加入到列表
if(type != IP_NONE) tip->Sockets.Add(this);
/*if(type != IP_NONE)
{
for(int i=0; i<tip->Sockets.Length(); i++)
{
if(tip->Sockets[i] == NULL)
{
tip->Sockets[i] = this;
break;
}
}
}*/
//int idx = tip->Sockets.FindIndex(NULL);
//if(idx >= 0) tip->Sockets[idx] = this;
}
TinySocket::~TinySocket()
@ -426,12 +439,21 @@ TinySocket::~TinySocket()
Enable = false;
// 从TinyIP中删除当前Socket
Tip->Sockets.Remove(this);
/*for(int i=0; i<Tip->Sockets.Length(); i++)
{
if(Tip->Sockets[i] == this)
{
Tip->Sockets[i] = NULL;
break;
}
}*/
//int idx = Tip->Sockets.FindIndex(this);
//if(idx >= 0) Tip->Sockets[idx] = NULL;
}
TinySocket* SocketList::FindByType(ushort type)
{
uint count = Count();
for(int i=count-1; i>=0; i--)
for(int i=Length()-1; i>=0; i--)
{
TinySocket* socket = (*this)[i];
if(socket)
@ -443,3 +465,18 @@ TinySocket* SocketList::FindByType(ushort type)
return NULL;
}
void SocketList::Add(const TinySocket* socket)
{
int idx = FindIndex(NULL);
// 如果找不到空位,则加在最后
if(idx < 0) idx = Length();
SetAt(idx, (TinySocket*)socket);
}
void SocketList::Remove(const TinySocket* socket)
{
int idx = FindIndex((TinySocket*)socket);
if(idx >= 0) (*this)[idx] = NULL;
}

View File

@ -4,7 +4,6 @@
// 模块开发使用说明见后
#include "Sys.h"
#include "List.h"
#include "Stream.h"
#include "Net\ITransport.h"
#include "Net\Net.h"
@ -28,10 +27,12 @@ public:
};
// Socket列表
class SocketList : public List<TinySocket*>
class SocketList : public Array<TinySocket*>
{
public:
TinySocket* FindByType(ushort type);
void Add(const TinySocket* socket);
void Remove(const TinySocket* socket);
};
// 精简以太网协议。封装以太网帧以及IP协议不包含其它协议实现仅提供底层支持。

View File

@ -2,7 +2,6 @@
#define __TinyMessage_H__
#include "Sys.h"
#include "List.h"
#include "Net\ITransport.h"
#include "Stream.h"

View File

@ -196,7 +196,7 @@ bool TinyServer::OnJoin(const TinyMessage& msg)
// 节点注册
dv->RegTime = now;
Devices.Add(dv);
Devices.Push(dv);
SaveDevices();
}
@ -482,7 +482,7 @@ Device* TinyServer::FindDevice(byte id)
{
if(id == 0) return NULL;
for(int i=0; i<Devices.Count(); i++)
for(int i=0; i<Devices.Length(); i++)
{
if(id == Devices[i]->Address) return Devices[i];
}
@ -494,7 +494,7 @@ Device* TinyServer::FindDevice(const ByteArray& hardid)
{
if(hardid.Length() == 0) return NULL;
for(int i=0; i<Devices.Count(); i++)
for(int i=0; i<Devices.Length(); i++)
{
if(hardid == Devices[i]->HardID) return Devices[i];
}
@ -507,7 +507,9 @@ bool TinyServer::DeleteDevice(byte id)
Device* dv = FindDevice(id);
if(dv && dv->Address == id)
{
Devices.Remove(dv);
//Devices.Remove(dv);
int idx = Devices.FindIndex(dv);
if(idx >= 0) Devices[idx] = NULL;
delete dv;
return true;
}
@ -537,7 +539,9 @@ int TinyServer::LoadDevices()
if(!dv) dv = new Device();
dv->Read(ms);
Devices.Add(dv);
//Devices.Add(dv);
int idx = Devices.FindIndex(NULL);
if(idx >= 0) Devices[idx] = dv;
}
debug_printf("TinyServer::LoadDevices 从 0x%08X 加载 %d 个设备!\r\n", addr, i);
@ -556,7 +560,7 @@ void TinyServer::SaveDevices()
Stream ms(buf, ArrayLength(buf));
// 设备个数
int count = Devices.Count();
int count = Devices.Length();
ms.Write((byte)count);
for(int i = 0; i<count; i++)
{

View File

@ -35,15 +35,15 @@ public:
MessageHandler Received;
void* Param;
List<Device*> Devices;
Array<Device*> Devices;
Device* FindDevice(byte id);
Device* FindDevice(const ByteArray& hardid);
bool DeleteDevice(byte id);
int LoadDevices();
void SaveDevices();
void ClearDevices();
bool LoadConfig();
void SaveConfig();
void ClearConfig();
@ -59,7 +59,7 @@ public:
// 组网
bool OnJoin(const TinyMessage& msg);
bool ResetPassword(byte id);
bool OnDisjoin(const TinyMessage& msg);

View File

@ -59,7 +59,7 @@ void Gateway::Start()
Server->Start();
// 添加网关这一条设备信息
if(Server->Devices.Count() == 0)
if(Server->Devices.Length() == 0)
{
Device* dv = new Device();
dv->Address = Server->Cfg->Address;
@ -69,7 +69,7 @@ void Gateway::Start()
dv->LastTime = Time.Current();
dv->Name = Sys.Name;
Server->Devices.Add(dv);
Server->Devices.Push(dv);
Server->SaveDevices();
}
@ -218,7 +218,7 @@ bool Gateway::OnRemote(const TokenMessage& msg)
rs.Code = 0x21;
OnGetDeviceList(rs);
// 遍历发送所有设备信息
for(int i=0; i<Server->Devices.Count(); i++)
for(int i=0; i<Server->Devices.Length(); i++)
SendDeviceInfo(Server->Devices[i]);
}
break;
@ -334,7 +334,7 @@ bool Gateway::OnGetDeviceList(const Message& msg)
TokenMessage rs;
rs.Code = msg.Code;
if(Server->Devices.Count() == 0)
if(Server->Devices.Length() == 0)
{
rs.Data[0] = 0;
rs.Length = 1;
@ -342,12 +342,12 @@ bool Gateway::OnGetDeviceList(const Message& msg)
else
{
int i = 0;
for(i=0; i<Server->Devices.Count(); i++)
for(i=0; i<Server->Devices.Length(); i++)
rs.Data[i] = Server->Devices[i]->Address;
rs.Length = i;
}
debug_printf("获取设备列表 共%d个\r\n", Server->Devices.Count());
debug_printf("获取设备列表 共%d个\r\n", Server->Devices.Length());
return Client->Reply(rs);
}

788
Type.h
View File

@ -385,6 +385,17 @@ public:
return _Arr[--_Length];
}
// 查找元素
virtual int FindIndex(const T item)
{
for(int i=0; i<Length(); i++)
{
if(_Arr[i] == item) return i;
}
return -1;
}
// 重载索引运算符[],让它可以像数组一样使用下标索引。
virtual T& operator[](int i) const
{
@ -511,4 +522,781 @@ public:
String operator+(const char* str, const Object& obj);
String operator+(const Object& obj, const char* str);
// 从数组创建列表
#define MakeList(T, arr) List<T>(&arr[0], sizeof(arr)/sizeof(arr[0]))
// 数组
class JArray
{
private:
void** _Arr;
int _Count;
int _Capacity;
public:
// 有效元素个数
int Count() const { return _Count; }
// 最大元素个数
int Capacity() const { return _Capacity; }
JArray(int capacity = 0x10)
{
_Capacity = capacity;
_Count = 0;
_Arr = new void*[capacity];
ArrayZero2(_Arr, capacity);
}
~JArray()
{
if(_Arr) delete _Arr;
_Arr = NULL;
}
// 压入一个元素
int Push(void* item)
{
assert_param(_Count < _Capacity);
// 找到空闲位放置
int idx = _Count++;
_Arr[idx] = item;
return idx;
}
// 弹出一个元素
const void* Pop()
{
assert_param(_Count > 0);
return _Arr[--_Count];
}
// 重载索引运算符[],让它可以像数组一样使用下标索引。
void* operator[](int i)
{
assert_param(i >= 0 && i < _Count);
return _Arr[i];
}
// 列表转为指针,注意安全
//T* operator=(Array arr) { return arr.Arr; }
};
// 固定大小的指针数组。
/*
便
*/
template<typename T, int ArraySize>
class FixedArray
{
private:
uint _Count;
T* Arr[ArraySize];
public:
// 默认初始化。大小和数组元素全部清零
FixedArray()
{
_Count = 0;
ArrayZero(Arr);
}
// 使用另一个固定数组来初始化
FixedArray(FixedArray& arr)
{
_Count = arr._Count;
ArrayCopy(Arr, arr.Arr);
}
// 重载等号运算符,使用另一个固定数组来初始化
FixedArray& operator=(FixedArray& arr)
{
_Count = arr._Count;
ArrayCopy(Arr, arr.Arr);
return *this;
}
~FixedArray() { DeleteAll(); }
// 实际元素个数
uint Count() const { return _Count; }
// 数组总长度
uint Length() const { return ArraySize; }
// 压入一个元素。返回元素所存储的索引
int Add(T* item)
{
assert_ptr(item);
//assert_param(_Count < ArraySize);
if(_Count >= ArraySize) return -1;
// 找到空闲位放置
int i = 0;
for(; i < ArraySize && Arr[i]; i++);
// 检查是否还有空位
if(i >= ArraySize) return -1;
Arr[i] = item;
_Count++;
return i;
}
// 弹出最后一个元素
T* Pop()
{
if(_Count == 0) return NULL;
// 找到最后一个元素
int i = ArraySize - 1;
for(; i >=0 && !Arr[i]; i--);
T* item = Arr[i];
_Count--;
Arr[i] = NULL;
return item;
}
// 删除元素
bool Remove(T* item)
{
int idx = Find(item);
if(idx < 0) return false;
RemoveAt(idx);
return true;
}
// 删除指定位置的元素
void RemoveAt(int idx)
{
assert_param(idx >= 0 && idx < ArraySize);
_Count--;
Arr[idx] = NULL;
}
// 清空数组。个数设0所有元素清零
FixedArray& Clear()
{
_Count = 0;
ArrayZero(Arr);
return *this;
}
// 释放所有指针指向的内存
FixedArray& DeleteAll()
{
for(int i=0; i < ArraySize; i++)
{
if(Arr[i]) delete Arr[i];
}
return *this;
}
// 查找元素
int Find(T* item)
{
assert_ptr(item);
int i = 0;
for(; i < ArraySize && Arr[i] != item; i++);
if(i >= ArraySize) return -1;
return i;
}
// 移到下一个元素累加参数如果没有下一个元素则返回false。
bool MoveNext(int& idx)
{
//assert_ptr(idx);
// 从idx开始找到第一个非空节点。注意存储不一定连续
int i = idx + 1;
for(; i < ArraySize && !Arr[i]; i++);
if(i >= ArraySize) return false;
idx = i;
return true;
}
// 重载索引运算符[],让它可以像数组一样使用下标索引。
/*T*& operator[](int i)
{
assert_param(i >= 0 && i < ArraySize);
return Arr[i];
}*/
// 不能允许[]作为左值否则外部直接设置数据以后Count并没有改变
T* operator[](int i)
{
assert_param(i >= 0 && i < ArraySize);
return Arr[i];
}
};
// 变长列表模版
// T一般是指针列表内部有一个数组用于存放指针
template<typename T>
class List
{
private:
uint _Count;// 拥有实际元素个数
uint _total;// 可容纳元素总数
T* _Arr; // 存储数据的数组
void ChangeSize(int newSize)
{
if(_total == newSize) return;
T* arr2 = new T[newSize];
if(_Arr)
{
// 如果新数组较小,则直接复制;如果新数组较大,则先复制,再清空余下部分
if(newSize < _Count)
{
// 此时有数据丢失
memcpy(arr2, _Arr, newSize * sizeof(T));
_Count = newSize;
}
else
{
memcpy(arr2, _Arr, _Count * sizeof(T));
memset(&arr2[_Count], 0, (newSize - _Count) * sizeof(T));
}
delete[] _Arr;
}
else
ArrayZero2(arr2, newSize);
_Arr = arr2;
_total = newSize;
}
void CheckSize()
{
// 如果数组空间已用完,则两倍扩容
if(_Count >= _total) ChangeSize(_Count > 0 ? _Count * 2 : 4);
}
public:
List(int size = 0)
{
_Count = 0;
_total = size;
_Arr = NULL;
if(size)
{
_Arr = new T[size];
ArrayZero2(_Arr, size);
}
}
List(T* items, uint count)
{
_Arr = new T[count];
_Count = 0;
_total = count;
for(int i=0; i<count; i++)
{
_Arr[_Count++] = *items++;
}
}
~List() { if(_Arr) delete[] _Arr; _Arr = NULL; }
// 重载等号运算符,使用另一个列表来初始化
List& operator=(List& list)
{
Clear();
for(int i=0; i<list.Count(); i++)
Add(list[i]);
return *this;
}
// 添加单个元素
virtual void Add(const T& item)
{
// 检查大小
CheckSize();
_Arr[_Count++] = item;
}
// 添加多个元素
void Add(T* items, int count)
{
int size = _Count + count;
if(size >= _total) ChangeSize(_Count > 0 ? _Count * 2 : 4);
for(int i=0; i<count; i++)
{
_Arr[_Count++] = *items++;
}
}
// 查找元素
int Find(const T& item)
{
for(int i=0; i<_Count; i++)
{
if(_Arr[i] == item) return i;
}
return -1;
}
virtual bool Contains(const T& item)
{
return Find(item) > -1;
}
// 删除指定位置元素
void RemoveAt(int index)
{
if(_Count <= 0 || index >= _Count) return;
// 复制元素
if(index < _Count - 1) memcpy(&_Arr[index], &_Arr[index + 1], (_Count - index - 1) * sizeof(T));
_Count--;
}
// 删除指定元素
virtual void Remove(const T& item)
{
int index = Find(item);
if(index >= 0) RemoveAt(index);
}
// 释放所有指针指向的内存
List& DeleteAll()
{
for(int i=0; i < _Count; i++)
{
if(_Arr[i]) delete _Arr[i];
}
return *this;
}
virtual void Clear()
{
_Count = 0;
}
virtual void CopyTo(T* arr)
{
assert_ptr(arr);
if(!_Count) return;
memcpy(arr, _Arr, _Count * sizeof(T));
}
// 返回内部指针
const T* ToArray() { return _Arr; }
// 有效元素个数
virtual int Count() const { return _Count; }
// 设置新的容量,如果容量比元素个数小,则会丢失数据
void SetCapacity(int capacity) { ChangeSize(capacity); }
// 重载索引运算符[],让它可以像数组一样使用下标索引。
T operator[](int i)
{
assert_param(i >= 0 && i < _Count);
// 有可能多线程冲突
//if(i < 0 || i >= _Count) return NULL;
return _Arr[i];
}
};
// 双向链表
template <class T> class LinkedList;
// 双向链表节点。实体类继承该类
template <class T> class LinkedNode
{
// 友元类。允许链表类控制本类私有成员
friend class LinkedList<T>;
public:
T* Prev; // 上一个节点
T* Next; // 下一个节点
void Initialize()
{
Next = NULL;
Prev = NULL;
}
// 从链表中删除。需要修改前后节点的指针指向,但当前节点仍然指向之前的前后节点
void RemoveFromList()
{
if(Prev) Prev->Next = Next;
if(Next) Next->Prev = Prev;
}
// 完全脱离链表。不再指向其它节点
void Unlink()
{
if(Prev) Prev->Next = Next;
if(Next) Next->Prev = Prev;
Next = NULL;
Prev = NULL;
}
// 把当前节点附加到另一个节点之后
void LinkAfter(T* node)
{
node->Next = (T*)this;
Prev = node;
// 不能清空Next因为可能是两个链表的合并
//Next = NULL;
}
// 最后一个节点
T* Last()
{
T* node = (T*)this;
while(node->Next) node = node->Next;
return node;
}
// 附加到当前节点后面
void Append(T* node)
{
Next = node;
node->Prev = (T*)this;
//node->Next = NULL;
}
};
// 双向链表
template <class T>
class LinkedList
{
public:
// 链表节点。实体类不需要继承该内部类
class Node
{
public:
T Item; // 元素
Node* Prev; // 前一节点
Node* Next; // 下一节点
Node()
{
Prev = NULL;
Next = NULL;
}
// 从队列中脱离
void RemoveFromList()
{
// 双保险,只有在前后节点指向当前节点时,才修改它们的值
if(Prev && Prev->Next == this) Prev->Next = Next;
if(Next && Next->Prev == this) Next->Prev = Prev;
}
// 附加到当前节点后面
void Append(Node* node)
{
Next = node;
node->Prev = this;
}
};
private:
Node* _Head; // 链表头部
Node* _Tail; // 链表尾部
int _Count; // 元素个数
void Init()
{
_Head = NULL;
_Tail = NULL;
_Count = 0;
}
void Remove(Node* node)
{
// 脱离队列
node->RemoveFromList();
// 特殊处理头尾
if(node == _Head) _Head = node->Next;
if(node == _Tail) _Tail = node->Prev;
delete node;
_Count--;
}
public:
LinkedList()
{
Init();
}
// 计算链表节点数
virtual int Count() const { return _Count; }
// 将某项添加到集合
virtual void Add(const T& item)
{
Node* node = new Node();
node->Item = item;
if(_Tail)
_Tail->Append(node);
else
_Head = _Tail = node;
_Count++;
}
// 从集合中移除特定对象的第一个匹配项
virtual void Remove(const T& item)
{
if(!_Count) return;
Node* node;
for(node = _Head; node; node = node->Next)
{
if(node->Item == item) break;
}
if(node) Remove(node);
}
// 确定集合是否包含特定值
virtual bool Contains(const T& item)
{
if(!_Count) return false;
Node* node;
for(node = _Head; node; node = node->Next)
{
if(node->Item == item) return true;
}
return false;
}
// 从集合中移除所有项。注意,该方法不会释放元素指针
virtual void Clear()
{
if(!_Count) return;
Node* node;
for(node = _Head; node;)
{
// 先备份,待会删除可能影响指针
Node* next = node->Next;
delete node;
node = next;
}
Init();
}
// 将集合元素复制到数组中
virtual void CopyTo(T* arr)
{
assert_ptr(arr);
if(!_Count) return;
Node* node;
for(node = _Head; node; node = node->Next)
{
*arr++ = node->Item;
}
}
T& First() { return _Head->Item; }
T& Last() { return _Tail->Item; }
// 释放第一个有效节点
T& ExtractFirst()
{
if(!_Count) return NULL;
Node* node = _Head;
_Head = _Head->Next;
// 可能只有一个节点
if(!_Head)
_Tail = NULL;
else
_Head->Prev = NULL;
T& item = node->Item;
delete node;
_Count--;
return item;
}
// 释放最后一个有效节点
T& ExtractLast()
{
if(!_Count) return NULL;
Node* node = _Tail;
_Tail = _Tail->Prev;
// 可能只有一个节点
if(!_Tail)
_Head = NULL;
else
_Tail->Next = NULL;
T& item = node->Item;
delete node;
_Count--;
return item;
}
};
void* operator new(uint size);
void* operator new[](uint size);
void operator delete(void* p);
void operator delete [] (void* p);
//#define DEBUG_NEW new(__FILE__, __LINE__)
//#define new DEBUG_NEW
//#endif
// 自动释放的智能指针
class SmartPtr
{
private:
// 内部包装。指针的多个智能指针SmartPtr对象共用该内部包装
class WrapPtr
{
public:
void* Ptr; // 目标指针
uint Count; // 引用计数
WrapPtr(void* ptr) { Ptr = ptr; Count = 1; }
~WrapPtr() { delete Ptr; }
};
WrapPtr* _ptr;
public:
// 为某个指针封装
SmartPtr(void* ptr)
{
assert_ptr(ptr);
_ptr = new WrapPtr(ptr);
}
// 拷贝智能指针。仅拷贝内部包装,然后引用计数加一
SmartPtr(const SmartPtr& ptr)
{
assert_ptr(ptr._ptr);
assert_ptr(ptr._ptr->Ptr);
_ptr = ptr._ptr;
_ptr->Count++;
}
~SmartPtr()
{
// 释放智能指针时,指针引用计数减一
_ptr->Count--;
// 如果指针引用计数为0则释放指针
if(!_ptr->Count)
{
delete _ptr;
_ptr = NULL;
}
}
void* ToPtr() { return _ptr->Ptr; }
};
// 经典的C++自动指针
// 超出对象作用域时自动销毁被管理指针
template<class T>
class auto_ptr
{
private:
T* _ptr;
public:
// 普通指针构造自动指针,隐式转换
// 构造函数的explicit关键词有效阻止从一个“裸”指针隐式转换成auto_ptr类型
explicit auto_ptr(T* p = 0) : _ptr(p) { }
// 拷贝构造函数,解除原来自动指针的管理权
auto_ptr(auto_ptr& ap) : _ptr(ap.release()) { }
// 析构时销毁被管理指针
~auto_ptr()
{
// 因为C++保证删除一个空指针是安全的,所以我们没有必要判断空
/*if(_ptr)
{
delete _ptr;
_ptr = NULL;
}*/
delete _ptr;
}
// 自动指针拷贝,解除原来自动指针的管理权
auto_ptr& operator=(T* p)
{
_ptr = p;
return *this;
}
// 自动指针拷贝,解除原来自动指针的管理权
auto_ptr& operator=(auto_ptr& ap)
{
reset(ap.release());
return *this;
}
// 获取原始指针
T* get() const { return _ptr; }
// 重载*和->运算符
T& operator*() const { assert_param(_ptr); return *_ptr; }
T* operator->() const { return _ptr; }
// 接触指针的管理权
T* release()
{
T* p = _ptr;
_ptr = 0;
return p;
}
// 销毁原指针,管理新指针
void reset(T* p = 0)
{
if(_ptr != p)
{
//if(_ptr) delete _ptr;
// 因为C++保证删除一个空指针是安全的,所以我们没有必要判断空
delete _ptr;
_ptr = p;
}
}
};
#endif