Files
mir_server/sdk/srvlib/include/CLVariant.h

689 lines
16 KiB
C
Raw Normal View History

2025-01-09 17:45:40 +08:00
#pragma once
/************************************************************************
C/C++
doublechar*
************************************************************************/
#include "_osdef.h"
#include "ObjectCounter.h"
class CCLVariant : public Counter<CCLVariant>
{
public:
/** 定义变量类型 **/
typedef enum tagVarType
{
vNil = 0, //无值
vNumber = 1,//数字值
vStr = 2,//字符串值
vStruct = 3,//结构值
}VARTYPE;
public:
inline operator __int64 () const
{
if (m_btType == vNumber)
return (__int64)m_Data.n;
if (m_btType == vStr)
{
char *e;
double d = strtod(m_Data.s.str, &e);
if (!e || !*e)
return (__int64)d;
}
return 0;
}
inline operator double () const
{
if (m_btType == vNumber)
return m_Data.n;
if (m_btType == vStr)
{
char *e;
double d = strtod(m_Data.s.str, &e);
if (!e || !*e)
return d;
}
return 0;
}
inline operator const char* () const
{
if (m_btType == vStr)
{
return m_Data.s.str;
}
return NULL;
}
inline operator const CCLVariant** () const
{
if (m_btType == vStruct)
return (const CCLVariant**)m_Data.a.list;
return NULL;
}
public:
/** 比较判断运算符函数集 **/
inline bool operator == (const CCLVariant &var)
{
char *e;
double d;
switch(m_btType)
{
case vNumber:
if (var.m_btType == vNumber)
{
return m_Data.n == var.m_Data.n;
}
else if (var.m_btType == vStr)
{
d = strtod(var.m_Data.s.str, &e);
if (!e || !*e)
return m_Data.n == d;
}
break;
case vStr:
if (var.m_btType == vNumber)
{
d = strtod(m_Data.s.str, &e);
if (!e || !*e)
return d == var.m_Data.n;
}
else if (var.m_btType == vStr)
return (m_Data.s.len == var.m_Data.s.len) && !strcmp(m_Data.s.str, var.m_Data.s.str);
break;
}
return false;
}
inline bool operator < (const CCLVariant &var)
{
char *e;
double d;
switch(m_btType)
{
case vNumber:
if (var.m_btType == vNumber)
{
return m_Data.n < var.m_Data.n;
}
else if (var.m_btType == vStr)//此时不要进行将数字转换为字符而进行strcmp比较因为进行>运算的时候lua会将第二个参数传递为第一个参数
{
d = strtod(var.m_Data.s.str, &e);
if (!e || !*e)
return m_Data.n < d;
}
break;
case vStr:
if (var.m_btType == vNumber)
{
d = strtod(m_Data.s.str, &e);
if (!e || !*e)
return d < var.m_Data.n;
}
else if (var.m_btType == vStr)
return (m_Data.s.len < var.m_Data.s.len) || strcmp(m_Data.s.str, var.m_Data.s.str) < 0;
break;
}
return false;
}
inline bool operator > (const CCLVariant &var)
{
return !operator <= (var);
}
inline bool operator <= (const CCLVariant &var)
{
char *e;
double d;
switch(m_btType)
{
case vNumber:
if (var.m_btType == vNumber)
{
return m_Data.n <= var.m_Data.n;
}
else if (var.m_btType == vStr)//此时不要进行将数字转换为字符而进行strcmp比较因为进行>=运算的时候lua会将第二个参数传递为第一个参数
{
d = strtod(var.m_Data.s.str, &e);
if (!e || !*e)
return m_Data.n <= d;
}
break;
case vStr:
if (var.m_btType == vNumber)
{
d = strtod(m_Data.s.str, &e);
if (!e || !*e)
return d <= var.m_Data.n;
}
else if (var.m_btType == vStr)
return (m_Data.s.len </*这里不能用<=*/ var.m_Data.s.len) || (m_Data.s.len == var.m_Data.s.len && strcmp(m_Data.s.str, var.m_Data.s.str) <= 0);
break;
}
return false;
}
inline bool operator >= (const CCLVariant &var)
{
return !operator < (var);
}
public:
/** 复制运算符函数集 **/
inline CCLVariant& operator = (double val)
{
if (m_btType != vNumber && m_btType != vNil)
clear();
m_btType = vNumber;
m_Data.n = val;
return *this;
}
inline CCLVariant& operator = (const char* val)
{
if (m_btType == vStr && m_Data.s.str && !strcmp(m_Data.s.str, val))
return *this;
clear();
m_btType = vStr;
m_Data.s.len = (unsigned int)strlen(val);
m_Data.s.str = (char*)malloc(m_Data.s.len + 1);
memcpy(m_Data.s.str, val, m_Data.s.len + 1);
return *this;
}
inline CCLVariant& operator = (const CCLVariant& val)
{
if (&val == this)
return *this;
if (val.m_btType == vNumber)
{
operator = (val.m_Data.n);
}
else if (val.m_btType == vStr)
{
if (m_btType == vStr && m_Data.s.len == val.m_Data.s.len && m_Data.s.str
&& val.m_Data.s.str && !strcmp(m_Data.s.str, val.m_Data.s.str))
{
return *this;
}
clear();
m_btType = vStr;
m_Data.s.str = (char*)malloc(val.m_Data.s.len + 1);
memcpy(m_Data.s.str, val.m_Data.s.str, val.m_Data.s.len + 1);
}
else if (val.m_btType == vStruct)
{
clear();
m_btType = vStruct;
m_Data.a.list = (CCLVariant**)calloc(val.m_Data.a.len, sizeof(*m_Data.a.list));
for (INT_PTR i=0; i<(INT_PTR)val.m_Data.a.len; ++i)
{
m_Data.a.list[i] = new CCLVariant(*val.m_Data.a.list[i]);
}
}
return *this;
}
public:
inline CCLVariant* ipair(int idx)
{
if (m_btType != vStruct)
return NULL;
CCLVariant *pVar;
if(idx <= m_Data.a.len && idx >= 0)
{
pVar = m_Data.a.list[idx];
return pVar;
}
return NULL;
}
/** 取成员值以及设置成员值的函数集 **/
//通过名称获取成员值
inline CCLVariant* get(const char* sName)
{
if (m_btType != vStruct || !sName)
return NULL;
DWORD dwName = hashstr(sName);
return get(dwName);
}
//通过数字名称或索引获取成员值
inline CCLVariant* get(DWORD dwName)
{
if (m_btType != vStruct)
return NULL;
CCLVariant *pVar;
if(m_Data.a.len )
{
for (INT_PTR i=m_Data.a.len-1; i>-1; --i)
{
pVar = m_Data.a.list[i];
if (pVar->m_dwName == dwName)
{
return pVar;
}
}
}
return NULL;
}
//创建成员值如果成员已经存在则什么也不做否则创建按一个值为vNil的成员
inline CCLVariant& set(const char* sName)
{
if (m_btType != vStruct)
clear();
m_btType = vStruct;
DWORD dwName = hashstr(sName);
CCLVariant *pVar = get(dwName);
if (!pVar)
{
pVar = new CCLVariant();
pVar->m_dwName = dwName;
m_Data.a.list = (CCLVariant**)realloc(m_Data.a.list, sizeof(*m_Data.a.list) * (m_Data.a.len+1));
m_Data.a.list[m_Data.a.len] = pVar;
m_Data.a.len++;
}
return *pVar;
}
//设置一个成员的double值如果成员值不存在则会自动创建如果成员值存在则会改变成员值的类型
inline const CCLVariant& set(const char* sName, double val)
{
CCLVariant &Var = set(sName);
Var.operator = (val);
return Var;
}
//设置一个成员的字符串值,如果成员值不存在则会自动创建,如果成员值存在则会改变成员值的类型
inline const CCLVariant& set(const char* sName, const char* val)
{
CCLVariant &Var = set(sName);
Var.operator = (val);
return Var;
}
//设置为空数据结构体
inline const void setToEmptyStruct()
{
clear();
m_btType = vStruct;
}
public:
//字符串hash函数
inline static unsigned int hashstr(const char* str)
{
return hashlstr(str, strlen(str));
}
//字符串hash函数需要提供长度
inline static unsigned int hashlstr(const char* str, size_t len)
{
unsigned int h = (unsigned int)len;
size_t step = (len>>5)+1; /* if string is too long, don't hash all its chars */
size_t l1;
for (l1=len; l1>=step; l1-=step) /* compute hash */
h = h ^ ((h<<5)+(h>>2)+(unsigned char)str[l1-1]);
return h;
}
public:
//获取变量的类型
inline int type()
{
return m_btType;
}
/* 获取变量的长度
* 1
*
*
* 0
*/
inline size_t len()
{
if (m_btType == vStr)
return m_Data.s.len;
if (m_btType == vStruct)
return m_Data.a.len;
if (m_btType == vNumber)
return 1;
return 0;
}
//清空变量的值
inline void clear()
{
if (m_btType == vStr)
{
free(m_Data.s.str);
m_Data.s.str = NULL;
m_Data.s.len = 0;
}
else if (m_btType == vStruct)
{
if(m_Data.a.len)
{
for (INT_PTR i=m_Data.a.len-1; i>-1; --i)
{
delete m_Data.a.list[i];
}
}
free(m_Data.a.list);
m_Data.a.list = NULL;
m_Data.a.len = 0;
}
else if (m_btType == vNumber)
{
m_Data.n = 0;
}
m_btType = vNil;
}
//获取在vStr类型中排除vNil值的成员数量
inline size_t packedlen()
{
if (vStruct != m_btType || m_Data.a.len ==0 )
{
return 0;
}
size_t result = 0;
for (INT_PTR i=m_Data.a.len-1; i>-1; --i)
{
if (m_Data.a.list[i]->m_btType != vNil)
result++;
}
return result;
}
/*
* Comments:
* Param const char * ptr:
* Param size_t size:
* Param size_t *pCount:
* @Return size_t:
*/
inline const char* loadFromMemory(const char* ptr, size_t size, size_t *pCount = NULL)
{
//内存长度小于5字节不能读取
if (size < 5)
{
if (pCount) *pCount = 0;
return ptr;
}
clear();
//读取类型
m_btType = *(unsigned char*)ptr;
ptr += sizeof(unsigned char);
size -= sizeof(unsigned char);
//读取名称
m_dwName = *(unsigned int *)ptr;
ptr += sizeof(unsigned int);
size -= sizeof(unsigned int);
//依据类型读取数据
switch(m_btType)
{
case vNumber:
if (size >= sizeof(m_Data.n))
{
m_Data.n = *(double*)ptr;
ptr += sizeof(double);
size -= sizeof(double);
}
else m_btType = vNil;
break;
case vStr:
if (size >= sizeof(unsigned int))
{
unsigned int len = *(unsigned int*)ptr;
ptr += sizeof(unsigned int);
size -= sizeof(unsigned int);
if (len > 0 && size >= len + 1)
{
operator = ((const char*)ptr);
ptr += len + 1;
size -= len + 1;
}
}
else m_btType = vNil;
break;
case vStruct:
if (size >= sizeof(unsigned int))
{
unsigned int len = *(unsigned int*)ptr;
ptr += sizeof(unsigned int);
size -= sizeof(unsigned int);
if (len > 0 && size >= 5)
{
m_Data.a.list = (CCLVariant**)calloc(len, sizeof(*m_Data.a.list));
for (INT_PTR i=0; i<(INT_PTR)len; ++i)
{
size_t n = 0;
m_Data.a.list[i] = new CCLVariant();
ptr = m_Data.a.list[i]->loadFromMemory(ptr, size, &n);
if (n <= 0)
break;
m_Data.a.len++;
if (pCount) *pCount += n;
}
}
}
else m_btType = vNil;
break;
}
//增加读取的变量数据量
if (pCount && m_btType != vNil)
*pCount += 1;//不能用*pCount++,意义不一样的,*pCount++表示 *(pCount++)。
return ptr;
}
/*
* Comments:
* @Return size_t:
*/
inline size_t getStoreMemory()
{
size_t reqSize = 0;
//计算存储所需的空间
switch(m_btType)
{
case vNil:
reqSize =0; //nil值没有值但是数据的长度里还是包含了类型以及名字
break;
case vNumber:
reqSize = 1 + sizeof(m_dwName) + sizeof(m_Data.n);
break;
case vStr:
reqSize = 1 + sizeof(m_dwName) + sizeof(m_Data.s.len) + ((m_Data.s.len > 0) ? m_Data.s.len + 1 : 0);
break;
case vStruct:
reqSize = 1 + sizeof(m_dwName) + sizeof(m_Data.a.len);
if (m_Data.a.len >0)//仅当参数size为0时用于计算保存变量所需的内存字节长度
{
for (INT_PTR i=m_Data.a.len-1;i>-1; --i)
{
reqSize += m_Data.a.list[i]->getStoreMemory();
}
}
break;
}
return reqSize;
}
/*
* Comments:
* Param char * ptr:
* Param size_t size: 0
@ Param CCLVariant **pNextSaveVar:
saveToStream函数来保存数据
* @Return size_t:
*
* & &
*
* char *buff = NULL;
* size_t bufsize = 0;
* size_t totalsize = 0;
* CCLVariant *pContinueVar = &var;
* do
* {
* bufsize += 1024;
* buff = realloc(buff, buffsize);
* totalsize += pContinueVar->saveToMemory(&buff[totalsize], bufsize - totalsize, &pContinueVar);
* }
* while (pContinueVar);
*
*/
inline size_t saveToMemory(char *ptr, size_t size, CCLVariant **pNextSaveVar)
{
size_t reqSize = getStoreMemory(); //获取存储需要的内存的量
size_t saveSize =0; //这个变量写进去多少的内存
//计算存储所需的空间
//没有任何数据可以写入
if (reqSize <= 0)
{
*pNextSaveVar = NULL;
return 0;
}
else if (size > 0)
{
//仅在剩余内存空间满足所需空间长度的时候才书写内容
if (size >= reqSize)
{
if (pNextSaveVar) *pNextSaveVar = NULL;
if(m_btType == vNil) //如果是空的话
{
return saveSize;
}
//写入类型
*(unsigned char*)ptr = (unsigned char)m_btType;
ptr += sizeof(unsigned char);
size -= sizeof(unsigned char);
saveSize += sizeof(unsigned char);
//写入名称
*(unsigned int*)ptr = m_dwName;
ptr += sizeof(unsigned int);
size -= sizeof(unsigned int);
saveSize += sizeof(unsigned int);
//写入数据
switch(m_btType)
{
case vNumber:
//写入值
*(double*)ptr = m_Data.n;
ptr += sizeof(double);
size -= sizeof(double);
saveSize += sizeof(double);
break;
case vStr:
//写入字符串长度
*(unsigned int*)ptr = m_Data.s.len;
ptr += sizeof(unsigned int);
size -= sizeof(unsigned int);
saveSize += sizeof(unsigned int);
//写入字符串内容
if (m_Data.s.len > 0)
{
memcpy(ptr, m_Data.s.str, m_Data.s.len + 1);
ptr += m_Data.s.len + 1;
size -= m_Data.s.len + 1;
saveSize += m_Data.s.len + 1;
}
break;
case vStruct:
//写入成员数量
{
*(unsigned int*)ptr =(unsigned int)packedlen() ;
ptr += sizeof(unsigned int);
size -= sizeof(unsigned int);
saveSize += sizeof(unsigned int);
//循环写入成员内容
if(m_Data.a.len >0)
{
for (INT_PTR i=m_Data.a.len-1;i>-1; --i)
{
size_t nb = m_Data.a.list[i]->saveToMemory(ptr, size, pNextSaveVar);
//没有写入数据则终止不能判断写入长度是否大于0因为nil值不会写入
if(nb >0)
{
saveSize += nb;
ptr += nb;
size -= nb;
}
if (pNextSaveVar && *pNextSaveVar)
break;
}
}
}
break;
}
}
else
{
if (pNextSaveVar) *pNextSaveVar = this;
saveSize = 0;//没有写入任何数据
}
}
return saveSize;
}
private:
inline void zd()
{
m_btType = vNil;
m_dwName = 0;
m_Data.s.len = 0;
m_Data.n = 0;
}
protected:
unsigned int m_btType; //数据类型
unsigned int m_dwName; //哈希名称
union
{
//整数值
double n;
//字符串值
struct
{
char *str;
unsigned int len;
}s;
//数组值
struct
{
CCLVariant** list;
unsigned int len;
}a;
} m_Data;
public:
CCLVariant()
{
zd();
}
CCLVariant(double val)
{
zd();
m_btType = vNumber;
m_Data.n = val;
}
CCLVariant(const char* val)
{
zd();
this->operator = (val);
}
CCLVariant(const CCLVariant& val)
{
zd();
this->operator = (val);
}
~CCLVariant()
{
clear();
}
};