|
пре 3 месеци | |
---|---|---|
.. | ||
example | пре 3 месеци | |
gtest | пре 3 месеци | |
thirdparty | пре 3 месеци | |
.gitignore | пре 3 месеци | |
LICENSE | пре 3 месеци | |
README.md | пре 3 месеци | |
config.h | пре 3 месеци | |
extend.h | пре 3 месеци | |
json.h | пре 3 месеци | |
json_data.h | пре 3 месеци | |
json_decoder.h | пре 3 месеци | |
json_encoder.h | пре 3 месеци | |
l1l2_expand.h | пре 3 месеци | |
numeric.h | пре 3 месеци | |
rapidjson_custom.h | пре 3 месеци | |
traits.h | пре 3 месеци | |
util.h | пре 3 месеци | |
xdecoder.h | пре 3 месеци | |
xencoder.h | пре 3 месеци | |
xml.h | пре 3 месеци | |
xml_decoder.h | пре 3 месеци | |
xml_encoder.h | пре 3 месеци | |
xpack.h | пре 3 месеци | |
xpack.pri | пре 3 месеци | |
xtype.h | пре 3 месеци |
using namespace std;
struct User {
int id;
string name;
XPACK(O(id, name)); // 添加宏定义XPACK在结构体定义结尾
};
int main(int argc, char *argv[]) {
User u;
string data = "{\"id\":12345, \"name\":\"xpack\"}";
xpack::json::decode(data, u); // json转结构体
cout<<u.id<<';'<<u.name<<endl;
string json = xpack::json::encode(u); // 结构体转json
cout<<json<<endl;
return 0;
}
容器支持
----
目前支持下列容器(std)
- vector
- set
- list
- map<string, T>
- map<integer, T> // 仅JSON,XML不支持
- unordered_map<string, T> (需要C++11支持)
- shared_ptr (需要C++11支持)
FLAG
----
宏XPACK里面,需要用字母将变量包含起来,比如XPACK(O(a,b)),XPACK可以包含多个字母,每个字母可以包含多个变量。目前支持的字母有:
- X。格式是X(F(flag1, flag2...), member1, member2,...) F里面包含各种FLAG,目前支持的有:
- 0 没有任何FLAG
- OE omitempty,encode的时候,如果变量是0或者空字符串或者false,则不生成对应的key信息
- M mandatory,decode的时候,如果这个字段不存在,则抛出异常,用于一些id字段。
- ATTR attribute,xml encode的时候,把值放到attribute里面。
- O。等价于X(F(0), ...) 没有任何FLAG。
- M。等价于X(F(M),...) 表示这些字段是必须存在的。
- A。[别名](#别名),A(member1, alias1, member2, alias2...),用于变量和key名不一样的情况
- AF。带FLAG的[别名](#别名),AF(F(flag1, flag2,...), member1, alias1, member2, alias2...)
- B。[位域](#位域),B(F(flag1, flag2, ...), member1, member2, ...) **位域不支持别名**
- I。[继承](#继承),I(baseclass1, baseclass2....),里面放父类
- E。[枚举](#枚举):
- 如果编译器支持C++11,不需要用E,枚举可以放X/O/M/A里面。
- 否则枚举只能放E里面,不支持别名
别名
----
- 用于变量名和key名不一致的场景
- 格式是A(变量,别名....)或者AF(F(flags), 变量,别名....),别名的格式是"x t:n"的格式
- x表示全局别名,t表示类型(目前支持json、xml、bson),n表示类型下的别名
- 全局别名可以没有,比如"json:_id"是合法的
- 类型别名可以没有,比如"_id"是合法的
- 有类型别名优先用类型别名,否则用全局别名,都没有,则用变量名
``` C++
#include <iostream>
#include "xpack/json.h"
using namespace std;
struct Test {
long uid;
string name;
XPACK(A(uid, "id"), O(name)); // "uid"的别名是"id"
};
int main(int argc, char *argv[]) {
Test t;
string json="{\"id\":123, \"name\":\"Pony\"}";
xpack::json::decode(json, t);
cout<<t.uid<<endl;
return 0;
}
#include <iostream>
#include "xpack/json.h"
using namespace std;
struct Test {
short ver:8;
short len:8;
string name;
XPACK(B(F(0), ver, len), O(name));
};
int main(int argc, char *argv[]) {
Test t;
string json="{\"ver\":4, \"len\":20, \"name\":\"IPv4\"}";
xpack::json::decode(json, t);
cout<<t.ver<<endl;
cout<<t.len<<endl;
return 0;
}
#include <iostream>
#include "xpack/json.h"
using namespace std;
struct P1 {
string mail;
XPACK(O(mail));
};
struct P2 {
long version;
XPACK(O(version));
};
struct Test:public P1, public P2 {
long uid;
string name;
XPACK(I(P1, P2), O(uid, name));
};
int main(int argc, char *argv[]) {
Test t;
string json="{\"mail\":\"pony@xpack.com\", \"version\":2019, \"id\":123, \"name\":\"Pony\"}";
xpack::json::decode(json, t);
cout<<t.mail<<endl;
cout<<t.version<<endl;
return 0;
}
#include <iostream>
#include "xpack/json.h"
using namespace std;
enum Enum {
X = 0,
Y = 1,
Z = 2,
};
struct Test {
string name;
Enum e;
XPACK(O(name), E(F(0), e));
};
int main(int argc, char *argv[]) {
Test t;
string json="{\"name\":\"IPv4\", \"e\":1}";
xpack::json::decode(json, t);
cout<<t.name<<endl;
cout<<t.e<<endl;
return 0;
}
应用场景:部分类型可能不想按结构体变量逐个编码,比如定义了一个时间结构体:
struct Time {
long ts; //unix timestamp
};
并不希望编码成{"ts":1218196800} 这种格式,而是希望编码成"2008-08-08 20:00:00"这种格式,这个时候就可以用自定义编解码实现。
template<> struct is_xpack_xtype {static bool const value = true;};
// implement decode template bool xpack_xtype_decode(OBJ &obj, const char*key, CString &val, const Extend *ext) {
std::string str;
obj.decode(key, str, ext);
if (str.empty()) {
return false;
}
// TODO 把str转到val里面去
return true;
}
// implement encode template bool xpack_xtype_encode(OBJ &obj, const char*key, const CString &val, const Extend *ext) {
std::string str;
// TODO 把val转到str里面去
return obj.encode(key, str, ext);
}
}
数组
----
- decode的时候如果元素个数超过数组的长度,会截断
- char数组按有\0结束符处理
```C++
#include <iostream>
#include "xpack/json.h"
using namespace std;
struct Test {
char name[64];
char email[64];
XPACK(O(name, email));
};
int main(int argc, char *argv[]) {
Test t;
string json="{\"name\":\"Pony\", \"email\":\"pony@xpack.com\"}";
xpack::json::decode(json, t);
cout<<t.name<<endl;
cout<<t.email<<endl;
return 0;
}
operator [](size_t index)
用来取数组的第index个元素(从0开始)operator [](const char *key)
用来根据key取Object类型的元素#include <sys/time.h>
#include <iostream>
#include "xpack/json.h"
using namespace std;
/*
struct timeval {
time_t tv_sec;
suseconds_t tv_usec;
};
*/
// timeval is thirdparty struct
XPACK_OUT(timeval, O(tv_sec, tv_usec));
struct T {
int a;
string b;
timeval t;
XPACK(O(a, b, t));
};
int main(int argc, char *argv[]) {
T t;
T r;
t.a = 123;
t.b = "xpack";
t.t.tv_sec = 888;
t.t.tv_usec = 999;
string s = xpack::json::encode(t);
cout<<s<<endl;
xpack::json::decode(s, r);
cout<<r.a<<','<<r.b<<','<<r.t.tv_sec<<','<<r.t.tv_usec<<endl;
return 0;
}
数组默认会用"x"作为标签,比如"ids":[1,2,3],对应的xml是:
<ids>
<x>1</x>
<x>2</x>
<x>3</x>
</ids>
xml
<ids>
<id>1</id>
<id>2</id>
<id>3</id>
</ids>