Files
mir_server/Gateway/srvlib/include/luabase/clvariant.h

553 lines
9.8 KiB
C
Raw Normal View History

2025-01-09 17:45:40 +08:00
#ifndef _CL_VARIANT_H_
#define _CL_VARIANT_H_
/************************************************************************
* C/C++<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϊ<EFBFBD>ű<EFBFBD><EFBFBD><EFBFBD>ı<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
* <EFBFBD><EFBFBD><EFBFBD><EFBFBD>֧<EFBFBD><EFBFBD>double<EFBFBD><EFBFBD>char*<EFBFBD><EFBFBD><EFBFBD>Լ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ƶij<EFBFBD>Աֵ
************************************************************************/
#include "bzhash.h"
class CLVariant
{
public:
/** <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> **/
typedef enum tagVarType
{
vNil = 0, //<2F><>ֵ
vNumber = 1,//<2F><><EFBFBD><EFBFBD>ֵ
vStr = 2,//<2F>ַ<EFBFBD><D6B7><EFBFBD>ֵ
vStruct = 3,//<2F>ṹֵ
} VARTYPE;
public:
/** <20><><EFBFBD><EFBFBD>ת<EFBFBD><D7AA><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> **/
inline operator int64_t() const
{
if (type_ == vNumber)
return (int64_t)data_.n;
if (type_ == vStr)
{
char* e;
double d = strtod(data_.s.str, &e);
if (!e || !*e)
return (int64_t)d;
}
return 0;
}
inline operator double() const
{
if (type_ == vNumber)
return data_.n;
if (type_ == vStr)
{
char* e;
double d = strtod(data_.s.str, &e);
if (!e || !*e)
return d;
}
return 0;
}
inline operator const char* () const
{
if (type_ == vStr)
{
return data_.s.str;
}
return NULL;
}
inline operator const CLVariant** () const
{
if (type_ == vStruct)
return (const CLVariant**)data_.a.list;
return NULL;
}
public:
/** <20>Ƚ<EFBFBD><C8BD>ж<EFBFBD><D0B6><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> **/
inline bool operator == (const CLVariant& var)
{
switch (type_)
{
case vNumber:
if (var.type_ == vNumber)
{
return data_.n == var.data_.n;
}
else if (var.type_ == vStr)
{
char* e = NULL;
double d = strtod(var.data_.s.str, &e);
if (!e || !*e)
return data_.n == d;
}
break;
case vStr:
if (var.type_ == vNumber)
{
char* e = NULL;
double d = strtod(data_.s.str, &e);
if (!e || !*e)
return d == var.data_.n;
}
else if (var.type_ == vStr)
{
return (data_.s.len == var.data_.s.len) && !strcmp(data_.s.str, var.data_.s.str);
}
break;
}
return false;
}
inline bool operator < (const CLVariant& var)
{
switch (type_)
{
case vNumber:
if (var.type_ == vNumber)
{
return data_.n < var.data_.n;
}
else if (var.type_ == vStr)//<2F><>ʱ<EFBFBD><CAB1>Ҫ<EFBFBD><D2AA><EFBFBD>н<EFBFBD><D0BD><EFBFBD><EFBFBD><EFBFBD>ת<EFBFBD><D7AA>Ϊ<EFBFBD>ַ<EFBFBD><D6B7><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>strcmp<6D>Ƚϣ<C8BD><CFA3><EFBFBD>Ϊ<EFBFBD><CEAA><EFBFBD><EFBFBD>><3E><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʱ<EFBFBD><CAB1><EFBFBD><EFBFBD>lua<75><EFBFBD>ڶ<EFBFBD><DAB6><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϊ<EFBFBD><CEAA>һ<EFBFBD><D2BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
{
char* e = NULL;
double d = strtod(var.data_.s.str, &e);
if (!e || !*e)
return data_.n < d;
}
break;
case vStr:
if (var.type_ == vNumber)
{
char* e = NULL;
double d = strtod(data_.s.str, &e);
if (!e || !*e)
return d < var.data_.n;
}
else if (var.type_ == vStr)
return (data_.s.len < var.data_.s.len) || strcmp(data_.s.str, var.data_.s.str) < 0;
break;
}
return false;
}
inline bool operator > (const CLVariant& var)
{
return !operator <= (var);
}
inline bool operator <= (const CLVariant& var)
{
switch (type_)
{
case vNumber:
if (var.type_ == vNumber)
{
return data_.n <= var.data_.n;
}
else if (var.type_ == vStr)//<2F><>ʱ<EFBFBD><CAB1>Ҫ<EFBFBD><D2AA><EFBFBD>н<EFBFBD><D0BD><EFBFBD><EFBFBD><EFBFBD>ת<EFBFBD><D7AA>Ϊ<EFBFBD>ַ<EFBFBD><D6B7><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>strcmp<6D>Ƚϣ<C8BD><CFA3><EFBFBD>Ϊ<EFBFBD><CEAA><EFBFBD><EFBFBD>>=<3D><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʱ<EFBFBD><CAB1><EFBFBD><EFBFBD>lua<75><EFBFBD>ڶ<EFBFBD><DAB6><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϊ<EFBFBD><CEAA>һ<EFBFBD><D2BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
{
char* e = NULL;
double d = strtod(var.data_.s.str, &e);
if (!e || !*e)
return data_.n <= d;
}
break;
case vStr:
if (var.type_ == vNumber)
{
char* e = NULL;
double d = strtod(data_.s.str, &e);
if (!e || !*e)
return d <= var.data_.n;
}
else if (var.type_ == vStr)
return (data_.s.len </*<2A><><EFBFBD><EFBFBD><EFB2BB><EFBFBD><EFBFBD><=*/ var.data_.s.len) ||
(data_.s.len == var.data_.s.len && strcmp(data_.s.str, var.data_.s.str) <= 0);
break;
}
return false;
}
inline bool operator >= (const CLVariant& var)
{
return !operator < (var);
}
public:
/** <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> **/
inline CLVariant& operator = (double val)
{
if (type_ != vNumber && type_ != vNil)
clear();
type_ = vNumber;
data_.n = val;
return *this;
}
inline CLVariant& operator = (const char* val)
{
if (type_ == vStr && data_.s.str && !strcmp(data_.s.str, val))
return *this;
clear();
type_ = vStr;
data_.s.len = (unsigned int)strlen(val);
data_.s.str = (char*)malloc(data_.s.len + 1);
memcpy(data_.s.str, val, data_.s.len + 1);
return *this;
}
inline CLVariant& operator = (const CLVariant& val)
{
if (&val == this)
return *this;
if (val.type_ == vNumber)
{
operator = (val.data_.n);
}
else if (val.type_ == vStr)
{
if (type_ == vStr && data_.s.len == val.data_.s.len && data_.s.str
&& val.data_.s.str && !strcmp(data_.s.str, val.data_.s.str))
{
return *this;
}
clear();
type_ = vStr;
data_.s.str = (char*)malloc(val.data_.s.len + 1);
memcpy(data_.s.str, val.data_.s.str, val.data_.s.len + 1);
}
else if (val.type_ == vStruct)
{
clear();
type_ = vStruct;
data_.a.list = (CLVariant**)calloc(val.data_.a.len, sizeof(*data_.a.list));
data_.a.len = val.data_.a.len;
for (int i = 0; i < (int)val.data_.a.len; ++i)
{
data_.a.list[i] = new CLVariant(*val.data_.a.list[i]);
}
}
return *this;
}
public:
/** ȡ<><C8A1>Աֵ<D4B1>Լ<EFBFBD><D4BC><EFBFBD><EFBFBD>ó<EFBFBD>Աֵ<D4B1>ĺ<EFBFBD><C4BA><EFBFBD><EFBFBD><EFBFBD> **/
//ͨ<><CDA8><EFBFBD><EFBFBD><EFBFBD>ƻ<EFBFBD>ȡ<EFBFBD><C8A1>Աֵ
inline CLVariant* get(const char* name)
{
if (type_ != vStruct || !name)
return NULL;
unsigned int h1 = bzhashstr(name, 1);
unsigned int h2 = bzhashstr(name, 2);
int64_t namecode = MAKEINT64(h1, h2);
return get(namecode);
}
//ͨ<><CDA8><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ƻ<EFBFBD><C6BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ȡ<EFBFBD><C8A1>Աֵ
inline CLVariant* get(int64_t namecode)
{
if (type_ != vStruct)
return NULL;
CLVariant* pVar = NULL;
if (data_.a.len && data_.a.list)
{
int low = 0;
int high = data_.a.len - 1;
while (low <= high)
{
int mid = ((unsigned int)(low + high)) >> 1;
const CLVariant* mid_item = data_.a.list[mid];
if (mid_item->name_id_ < namecode)
low = mid + 1;
else if (mid_item->name_id_ > namecode)
high = mid - 1;
else
return data_.a.list[mid]; // key found
}
}
return pVar;
}
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Աֵ<D4B1><D6B5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ա<EFBFBD>Ѿ<EFBFBD><D1BE><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʲôҲ<C3B4><D2B2><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>򴴽<EFBFBD><F2B4B4BD><EFBFBD>һ<EFBFBD><D2BB>ֵΪvNil<69>ij<EFBFBD>Ա
inline CLVariant& set(const char* name)
{
if (type_ != vStruct)
clear();
type_ = vStruct;
unsigned int h1 = bzhashstr(name, 1);
unsigned int h2 = bzhashstr(name, 2);
int64_t namecode = MAKEINT64(h1, h2);
CLVariant* var = get(namecode);
if (!var)
{
var = new CLVariant();
var->name_id_ = namecode;
int low = 0;
int high = data_.a.len - 1;
while (low <= high)
{
int mid = ((unsigned)(low + high)) >> 1;
const CLVariant* mid_item = data_.a.list[mid];
if (mid_item->name_id_ < var->name_id_)
low = mid + 1;
else
high = mid - 1;
}
int index = low;
data_.a.list = (CLVariant**)realloc(data_.a.list, sizeof(*data_.a.list) * (data_.a.len + 1));
if (index < (int)data_.a.len)
{
memmove(data_.a.list + index + 1, data_.a.list + index, sizeof(CLVariant*) * (data_.a.len - index));
}
data_.a.list[index] = var;
data_.a.len++;
}
return *var;
}
//<2F><><EFBFBD><EFBFBD>һ<EFBFBD><D2BB><EFBFBD><EFBFBD>Ա<EFBFBD><D4B1>doubleֵ<65><D6B5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Աֵ<D4B1><D6B5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Զ<EFBFBD><D4B6><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Աֵ<D4B1><D6B5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ı<EFBFBD><C4B1><EFBFBD>Աֵ<D4B1><D6B5><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
inline const CLVariant& set(const char* name, double val)
{
CLVariant& Var = set(name);
Var.operator = (val);
return Var;
}
//<2F><><EFBFBD><EFBFBD>һ<EFBFBD><D2BB><EFBFBD><EFBFBD>Ա<EFBFBD><D4B1><EFBFBD>ַ<EFBFBD><D6B7><EFBFBD>ֵ<EFBFBD><D6B5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Աֵ<D4B1><D6B5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Զ<EFBFBD><D4B6><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Աֵ<D4B1><D6B5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ı<EFBFBD><C4B1><EFBFBD>Աֵ<D4B1><D6B5><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
inline const CLVariant& set(const char* name, const char* val)
{
CLVariant& Var = set(name);
Var.operator = (val);
return Var;
}
//<2F><><EFBFBD><EFBFBD>Ϊ<EFBFBD><CEAA><EFBFBD><EFBFBD><EFBFBD>ݽṹ<DDBD><E1B9B9>
inline const void setToEmptyStruct()
{
clear();
type_ = vStruct;
}
public:
//<2F><>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
inline int type()
{
return type_;
}
/* <20><>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD><EFBFBD>ij<EFBFBD><C4B3><EFBFBD>
* <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֵ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϊ<EFBFBD><EFBFBD><EFBFBD>ֵ<EFBFBD>ʱ<EFBFBD>򣬷<EFBFBD><EFBFBD><EFBFBD>ֵΪ1<EFBFBD><EFBFBD>
* <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֵ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϊ<EFBFBD>ַ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʱ<EFBFBD>򣬷<EFBFBD><EFBFBD><EFBFBD>ֵΪ<EFBFBD>ַ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ȣ<EFBFBD>
* <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֵ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϊ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݵ<EFBFBD>ʱ<EFBFBD>򣬷<EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><EFBFBD><EFBFBD>ӳ<EFBFBD>Ա<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
* <EFBFBD><EFBFBD><EFBFBD><EFBFBD>0<EFBFBD><EFBFBD>ʾ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>û<EFBFBD><EFBFBD>ֵ
*/
inline size_t len()
{
if (type_ == vStr)
return data_.s.len;
if (type_ == vStruct)
return data_.a.len;
if (type_ == vNumber)
return 1;
return 0;
}
//<2F><><EFBFBD>ձ<EFBFBD><D5B1><EFBFBD><EFBFBD><EFBFBD>ֵ
inline void clear()
{
if (type_ == vStr)
{
free(data_.s.str);
data_.s.str = NULL;
data_.s.len = 0;
}
else if (type_ == vStruct)
{
if (data_.a.len)
{
for (int i = data_.a.len - 1; i > -1; --i)
{
delete data_.a.list[i];
}
}
free(data_.a.list);
data_.a.list = NULL;
data_.a.len = 0;
}
else if (type_ == vNumber)
{
data_.n = 0;
}
type_ = vNil;
}
//<2F><>ȡ<EFBFBD><C8A1>vStr<74><72><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ų<EFBFBD>vNilֵ<6C>ij<EFBFBD>Ա<EFBFBD><D4B1><EFBFBD><EFBFBD>
inline size_t packedlen()
{
if (vStruct != type_ || data_.a.len == 0)
{
return 0;
}
size_t result = 0;
for (int i = data_.a.len - 1; i > -1; --i)
{
if (data_.a.list[i]->type_ != vNil)
result++;
}
return result;
}
/*
* Comments: <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>м<EFBFBD><EFBFBD>ر<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
* Param const char * ptr: <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ָ<EFBFBD><EFBFBD>
* Param size_t size: <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
* Param size_t *pCount: <EFBFBD><EFBFBD><EFBFBD>ڱ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>˶<EFBFBD><EFBFBD>ٸ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
* @Return size_t: <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ؼ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>˱<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ڴ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>λ<EFBFBD><EFBFBD>
*/
const char* loadFromMemory(const char* ptr, size_t& size, size_t* pCount = NULL);
/*
* Comments: <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ڴ<EFBFBD><EFBFBD><EFBFBD>
* Param char * ptr: <EFBFBD>ڴ<EFBFBD><EFBFBD><EFBFBD>ָ<EFBFBD><EFBFBD>
* Param size_t size: <EFBFBD>ڴ<EFBFBD><EFBFBD>ȣ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֵΪ0<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>д<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݣ<EFBFBD><EFBFBD>ҷ<EFBFBD><EFBFBD><EFBFBD>д<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ڴ<EFBFBD><EFBFBD>ֽڳ<EFBFBD><EFBFBD><EFBFBD>
memory:<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϊ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֵ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʾ<EFBFBD>ڴ<EFBFBD><EFBFBD>Ƿ<EFBFBD><EFBFBD>
*/
size_t saveToMemory(char* ptr, size_t size, bool& memory);
inline int compareName(CLVariant* v2)
{
if (name_id_ < v2->name_id_)
{
return -1;
}
else if (name_id_ > v2->name_id_)
{
return 1;
}
else
{
return 0;
}
}
private:
inline void zd()
{
type_ = vNil;
name_id_ = 0;
data_.s.len = 0;
data_.n = 0;
}
public:
CLVariant()
{
zd();
}
CLVariant(double val)
{
zd();
type_ = vNumber;
data_.n = val;
}
CLVariant(const char* val)
{
zd();
this->operator = (val);
}
CLVariant(const CLVariant& val)
{
zd();
this->operator = (val);
}
~CLVariant()
{
clear();
}
private:
unsigned int type_; //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
int64_t name_id_; //<2F><>ϣ<EFBFBD><CFA3><EFBFBD><EFBFBD>
union
{
//<2F><><EFBFBD><EFBFBD>ֵ
double n;
//<2F>ַ<EFBFBD><D6B7><EFBFBD>ֵ
struct
{
char* str;
unsigned int len;
} s;
//<2F><><EFBFBD><EFBFBD>ֵ
struct
{
CLVariant** list;
unsigned int len;
} a;
} data_;
};
#endif