Ai
2 Star 11 Fork 2

寻根/jsonreflect

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
文件
克隆/下载
reflect.cpp 5.45 KB
一键复制 编辑 原始数据 按行查看 历史
寻根 提交于 2020-04-30 21:41 +08:00 . modified: reflect.cpp
#ifndef XG_REFLECT_CPP
#define XG_REFLECT_CPP
///////////////////////////////////////////////////////////////////
#include "Reflect.h"
Object::~Object()
{
}
string Object::toString() const
{
char buffer[16];
sprintf(buffer, "%p", this);
return buffer;
}
const char* Object::getClassName() const
{
#ifdef _MSC_VER
return typeid(*this).name() + 6;
#else
const char* str = typeid(*this).name();
while (*str >= '0' && *str <= '9') str++;
return str;
#endif
}
class ReflectAttrMap
{
friend class ReflectHelper;
public:
class Item
{
public:
const char* type;
const char* name;
Item() : type(NULL), name(NULL)
{
}
};
class Data : public SpinMutex
{
public:
int ofs;
int end;
ReflectKey key;
mutable Item arr[10000];
vector<ReflectItem> vec;
public:
Data(const Data& obj)
{
ofs = obj.ofs;
end = obj.end;
key = obj.key;
}
Data(ReflectKey _key = 0) : ofs(-1), end(-1), key(_key)
{
}
public:
vector<ReflectItem> getArrList()
{
if (end >= ofs) return vec;
lock();
vector<ReflectItem> res;
for (int i = 0; i <= ofs; i++)
{
const Item& item = arr[i];
if (item.name) res.push_back(ReflectItem(i, item.type, item.name));
}
vec = res;
end = ofs;
unlock();
return res;
}
void add(int offset, const char* type, const char* name)
{
if (ofs >= offset) return;
if (strcmp(type, "int") && strcmp(type, "bool") && strcmp(type, "float") && strcmp(type, "double") && strcmp(type, "string")) type = "object";
assert(offset < ARR_LEN(arr));
Item& item = arr[offset];
lock();
ofs = offset;
item.type = type;
item.name = name;
unlock();
}
};
protected:
SpinMutex mtx;
vector<Data> arr[10000];
vector<ReflectItem> getAttrList(ReflectKey key)
{
vector<Data>& vec = arr[(key >> 3) % ARR_LEN(arr)];
for (Data& item : vec) if (key == item.key) return item.getArrList();
return vector<ReflectItem>();
}
void add(Object* self, void* data, const char* type, const char* name)
{
ReflectKey key = ReflectHelper::GetKey(self);
vector<Data>& vec = arr[(key >> 3) % ARR_LEN(arr)];
for (Data& item : vec)
{
if (key == item.key)
{
item.add((char*)(data) - (char*)(self), type, name);
return;
}
}
{
SpinLocker lk(mtx);
for (Data& item : vec)
{
if (key == item.key)
{
item.add((char*)(data) - (char*)(self), type, name);
return;
}
}
vec.push_back(Data(key));
vec.back().add((char*)(data) - (char*)(self), type, name);
}
}
void add(Object* self, Object* data, const char* type, const char* name)
{
ReflectKey key = ReflectHelper::GetKey(data);
vector<Data>& vec = arr[(key >> 3) % ARR_LEN(arr)];
if (vec.size() > 0) add(self, (void*)(data), type, name);
}
};
string ReflectItem::get(const void* obj) const
{
char* dest = (char*)(obj) + offset;
if (type == NULL || strcmp(type, "object") == 0) return "";
if (strcmp(type, "int") == 0) return to_string(*(int*)(dest));
if (strcmp(type, "bool") == 0) return *(bool*)(dest) ? "true" : "false";
if (strcmp(type, "float") == 0) return to_string(*(float*)(dest));
if (strcmp(type, "double") == 0) return to_string(*(double*)(dest));
return *(string*)(dest);
}
bool ReflectItem::set(void* obj, int val) const
{
char* dest = (char*)(obj) + offset;
if (type == NULL || strcmp(type, "object") == 0) return false;
if (strcmp(type, "int") == 0)
{
*(int*)(dest) = val;
}
else if (strcmp(type, "bool") == 0)
{
*(bool*)(dest) = val ? true : false;
}
else if (strcmp(type, "float") == 0)
{
*(float*)(dest) = val;
}
else if (strcmp(type, "double") == 0)
{
*(double*)(dest) = val;
}
else
{
*(string*)(dest) = to_string(val);
}
return true;
}
bool ReflectItem::set(void* obj, double val) const
{
char* dest = (char*)(obj) + offset;
if (type == NULL || strcmp(type, "object") == 0) return false;
if (strcmp(type, "int") == 0)
{
*(int*)(dest) = val;
}
else if (strcmp(type, "bool") == 0)
{
*(bool*)(dest) = val < -0.000001 || val > 0.000001;
}
else if (strcmp(type, "float") == 0)
{
*(float*)(dest) = val;
}
else if (strcmp(type, "double") == 0)
{
*(double*)(dest) = val;
}
else
{
*(string*)(dest) = to_string(val);
}
return true;
}
bool ReflectItem::set(void* obj, const char* val) const
{
char* dest = (char*)(obj) + offset;
if (val == NULL || type == NULL || strcmp(type, "object") == 0) return false;
if (strcmp(type, "string") == 0)
{
*(string*)(dest) = val;
}
else
{
if (*val == 0) return true;
if (strcmp(type, "int") == 0)
{
*(int*)(dest) = atoi(val);
}
else if (strcmp(type, "bool") == 0)
{
*(bool*)(dest) = strcasecmp(val, "true") == 0;
}
else if (strcmp(type, "float") == 0)
{
*(float*)(dest) = atof(val);
}
else
{
*(double*)(dest) = atof(val);
}
}
return true;
}
static ReflectAttrMap attrmap;
string ReflectHelper::GetAttrString(ReflectKey key)
{
string res;
string gap = ",";
vector<ReflectItem> vec = attrmap.getAttrList(key);
if (vec.empty()) return res;
for (auto& item : vec) res += gap + item.getName();
return res.substr(gap.length());
}
vector<ReflectItem> ReflectHelper::GetAttrList(ReflectKey key)
{
return attrmap.getAttrList(key);
}
ReflectHelper::ReflectHelper(Object* self, void* data, const char* type, const char* name)
{
attrmap.add(self, data, type, name);
}
ReflectHelper::ReflectHelper(Object* self, Object* data, const char* type, const char* name)
{
attrmap.add(self, data, type, name);
}
///////////////////////////////////////////////////////////////////
#endif
Loading...
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
C++
1
https://gitee.com/xungen/jsonreflect.git
git@gitee.com:xungen/jsonreflect.git
xungen
jsonreflect
jsonreflect
master

搜索帮助