xpack
====
* 用于在C++结构体和json/xml之间互相转换, bson在[xbson](https://github.com/xyz347/xbson)中支持。
* 只有头文件, 无需编译库文件,所以也没有Makefile。
* 具体可以参考example的例子
------
* [基本用法](#基本用法)
* [容器支持](#容器支持)
* [FLAG](#flag)
* [别名](#别名)
* [位域](#位域)
* [继承](#继承)
* [枚举](#枚举)
* [自定义编解码](#自定义编解码)
* [union](#union)
* [不定类型](#不定类型)
* [数组](#数组)
* [第三方类和结构体](#第三方类和结构体)
* [格式化缩进](#格式化缩进)
* [XML数组](#xml数组)
* [Qt支持](#qt支持)
* [重要说明](#重要说明)
基本用法
----
- 结构体后面用XPACK宏包含各个变量,XPACK内还需要一个字母,不同字母的意义请参考[FLAG](#flag)
- 用xpack::json::encode把结构体转json
- 用xpack::json::decode把json转结构体
```C++
#include <iostream>
#include "xpack/json.h" // Json包含这个头文件,xml则包含xpack/xml.h
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信息
- EN empty as null, 用于json的encode,OE是直接不生成empty的字段,EN则是生成一个null
- M mandatory,decode的时候,如果这个字段不存在,则抛出异常,用于一些id字段。
- ATTR attribute,xml encode的时候,把值放到attribute里面。
- C。格式是C(customcodec, F(flag1,flags...), member1, member2,...)用于自定义编解码函数,详情请参考[自定义编解码](#自定义编解码)
- 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;
}
```
位域
----
- 使用"B"来包含位域变量,**位域不支持别名**
``` C++
#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;
}
```
继承
----
- 使用"I"来包含父类。需要用到父类的变量就包含,用不到可以不包含。
- 父类的父类也需要包含,比如class Base; class Base1:public Base; class Base2:public Base1;那么在Base2中需要I(Base1, Base)
- 父类也需要定义XPACK/XPACK_OUT宏。
```C++
#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;
}
```
枚举
----
- 如果编译器支持C++11,则枚举和普通变量名一样,放X/O/M/A里面皆可。
- 否则需要放到E里面,格式是E(F(...), member1, member2, ...)
```C++
#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;
}
```
自定义编解码
----
应用场景
- 有些基础类型想用自定义方式编码,比如用字符串的方式来编码整数/浮点数
- 部分类型可能不想按结构体变量逐个编码,比如定义了一个时间结构体:
```C++
struct Time {
long ts; //unix timestamp
};
```
并不希望编码成{"ts":1218196800} 这种格式,而是希望编码成"2008-08-08 20:00:00"这种格式。
这里有两种方式:
- 使用xtype,可以参考[例子](example/xtype.cpp)
- 用C来包含需要自定义编解码的变量(下面简称C方法),可以参考[例子](example/custom.cpp)
两种方法本质上都是自己去实现encode/decode,但是有以下区别:
- xtype是类型级别的,也就是一旦某个类型用xtype封装之后,那么自定义的encode/decode就对这个类型生效。xtype无法作用于基本类型(int/string等)
- C方法能支持基本类型(int/string等)和非基本类型,但是仅作用于用C包含的变量,比如int a;int b; O(a), C(custome_int, F(0), b);那么a还是用默认的编解码,b才是用自定义的编解码。
1. xtype优先于XPACK宏,也就是定义了xtype的,会优先使用xtype的encode/decode
2. C方法优先于xtype,也就是用C包含的变量,一定会用C里面指定的编解码方法。
用这两个特性,可以实现一些比较灵活的编解码控制,比如这个[例子](example/xtype_advance.cpp)实现了一个根据变量情况来编码的功能,如果Sub.type==1则encode seq1,否则encode seq2. `__x_pack_decode`和`__x_pack_encode`是XPACK宏给结构体添加的decode/encode函数,自定义编解码函数可以通过这些函数调用xpack默认的编解码功能。
union
----
可以使用[自定义编解码](#自定义编解码)来处理联合体,可以参考[范例](example/union1.cpp)
数组
----
- decode的时候如果元素个数超过数组的长度,会截断
- char数组按有\0结束符处理
```C++
#include <iostream>
#include "xpack/json.h"
using na
没有合适的资源?快使用搜索试试~ 我知道了~
资源推荐
资源详情
资源评论
收起资源包目录
xpack-master.zip (86个子文件)
xpack-master
config.h 710B
json.h 2KB
example
char_array.cpp 1009B
bitfield.cpp 1021B
xpack_out.cpp 1KB
alias.cpp 961B
sharedptr.cpp 2KB
json_decoder.cpp 2KB
my_encoder.cpp 3KB
makefile 363B
json-data.cpp 2KB
xtype_advance.cpp 2KB
msvc.make 322B
enum.cpp 1KB
custom.cpp 2KB
build_json.cpp 1KB
base.cpp 2KB
xtype.cpp 3KB
inherit.cpp 1KB
union1.cpp 3KB
xml_encoder.h 10KB
gtest
test.cpp 19KB
makefile 454B
gtest_stub.h 4KB
msvc.make 286B
xdecoder.h 12KB
util.h 5KB
numeric.h 2KB
json_data.h 9KB
json_decoder.h 11KB
LICENSE 11KB
traits.h 3KB
json_encoder.h 8KB
xpack.h 9KB
thirdparty
rapidxml
rapidxml_print.hpp 16KB
license.txt 3KB
rapidxml_iterators.hpp 4KB
rapidxml_utils.hpp 3KB
manual.html 111KB
rapidxml.hpp 118KB
rapidjson
document.h 115KB
reader.h 91KB
cursorstreamwrapper.h 2KB
prettywriter.h 10KB
allocators.h 10KB
internal
strtod.h 9KB
itoa.h 10KB
pow10.h 4KB
strfunc.h 2KB
regex.h 25KB
diyfp.h 12KB
ieee754.h 3KB
meta.h 6KB
dtoa.h 8KB
biginteger.h 9KB
swap.h 1KB
stack.h 7KB
schema.h 101KB
fwd.h 4KB
ostreamwrapper.h 2KB
encodedstream.h 10KB
error
en.h 4KB
error.h 6KB
encodings.h 29KB
filereadstream.h 3KB
memorybuffer.h 3KB
msinttypes
stdint.h 9KB
inttypes.h 8KB
istreamwrapper.h 4KB
writer.h 26KB
pointer.h 59KB
rapidjson.h 23KB
stream.h 7KB
memorystream.h 3KB
stringbuffer.h 4KB
filewritestream.h 3KB
xml_decoder.h 10KB
.gitignore 27B
xml.h 2KB
rapidjson_custom.h 499B
xencoder.h 9KB
README.md 11KB
xtype.h 1KB
xpack.pri 68B
extend.h 5KB
l1l2_expand.h 52KB
共 86 条
- 1
资源评论
HWWXQ442119958
- 粉丝: 0
- 资源: 73
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
最新资源
- 无风险利率数据1990-2020
- 年Beta数据1991-2019年
- 新疆105个区县财政收支一般公共预算科学技术支出税收收入2000-2023
- Unity3D((2018-2019)版本游戏源码(2018,2019)(泡泡龙)
- 基于matlab实现的针对旋转机械采集到得振动信号进行消燥处理.rar
- 基于matlab实现的针对红外弱小目标检测难点,采用高通和双边滤波实现弱小目标的检测 .rar
- 基于 YOLOv8 和 LPRNet 的车牌识别系统
- 11-18年润灵环球责任数据
- Unity3D((2018-2019)版本游戏源码(2018,2019)2D螺旋球无限旋转休闲益智游戏
- 2005-2020年中国全球投资追踪数据
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功