轻量版C++json库,支持自定义类型
文章目录
- 项目名称
- 功能特性
- 安装指南
- 内定数据类型
- Str
- List
- Dict
- 接口
- 序列化为json字符串
- 反序列化json字符串为对象
- 注册自己的序列化和反序列化方法
- 例子
- List的序列化和反序列化
- Dict的序列化和反序列化
- 嵌套List序列化和反序列化
- 嵌套Dict序列化和反序列化
- List和Dict混合序列化和反序列化1
- List和Dict混合序列化和反序列化2
- 自定义类型序列化和反序列化
- 贡献指南
- 许可证
项目名称
该项目是我在学习现代c++编程时所写的一个用于序列化对象为json和反序列化json为指定对象的c++库。该库的特点就是轻量,便捷,灵活。
功能特性
- 功能 1:序列化基本数据类型(
nullptr_t
、bool
、整数
、double
)、内定类型(Str
、Dict
和List
)为json,支持json美化。 - 功能 2:反序列化json文本为指定对象。
- 功能 3:提供支持有限的自定义类型序列化和反序列化接口,需要自己去实现这两个方法。
注意:默认并不支持c++原生容器的序列化合反序列化,需要自己实现这两个方法。\textcolor{BrickRed}{注意:默认并不支持c++原生容器的序列化合反序列化,需要自己实现这两个方法。}注意:默认并不支持c++原生容器的序列化合反序列化,需要自己实现这两个方法。
安装指南
# 克隆项目
git clone https://github.com/LonelyWindy/cjson.git
然后将cjson.h和file_view.h放到你的项目中。
注意:请使用C++20及以上标准!\textcolor{BrickRed}{注意:请使用C++20及以上标准!}注意:请使用C++20及以上标准!
内定数据类型
Str
增强的std::string
,使用方法在原来的基础上,新增格式化字符串方法format\textcolor{cornflowerblue}{format}format:
auto str = cjson::Str();
str.format("%s %d %.2f\n", "cvk", 18, 168.5);
std::cout << str << std::endl;// cvk 18 168.50
List
增强的std::vector
,可以存储任何类型的元素,并支持任何元素的查找和比较:
auto l = cjson::List("Cxk", 18, 168.5, -894, true, nullptr);
auto d = cjson::Dict();
d["48"] = 1564;
d[-8] = "5ef46";
l.append(d);std::cout << l <<std::endl;
std::cout<< l.index(true) << std::endl;
std::cout<< l.index(d) << std::endl;// ["Cxk",18,168.500000,-894,true,null]
// 4
Dict
增强的std::map
,可以存储任何类型的元素,并支持任何元素的查找和比较:
auto d = cjson::Dict();
d[15] = "xdwdf";
auto l = cjson::List("fewf",84,-4);
d[-59] = l;
d["ef"] = cjson::Dict();
d["ef"].as_dict()["878"] = -5486;
d["ef"].as_dict()[0.15415] = "ewfeewf";std::cout << d <<std::endl; // {"-59":["fewf",84,-4],"15":"xdwdf","ef":{"0.154150":"ewfeewf","878":-5486}}
接口
序列化为json字符串
std::string dumps(const std::any& object, int indent = 0
)
- object,任意对象,如果是自己定义对象需要自己实现序列化合反序列化方法。
- indent,json字符串缩进,默认为0,表示不美化。常用值2和4。
反序列化json字符串为对象
JValue loads(file_view::StreamView&& json, size_t* end_pos = nullptr
);
-
json,json字符串或者json文件路径。如果需要传入json文件路径需要显示调用StreamView的构造函数,并指定file_mode参数为true。
-
end_pos,反序列化结束位置,json字符串中的下标或者json文件偏移。可空。
注册自己的序列化和反序列化方法
using ObjDumper = std::function<std::string(const std::any& obj, int indent, int current_indent, bool first)>;
using JInterpreter = std::function <JValue(file_view::StreamView& json, size_t current_pos, size_t& end_pos)>;void register_json_interpreter(ObjDumper dumper, JInterpreter interpreter
);
- dumper,将对象序列化为json字符串的方法。
- interpreter,将json字符串反序列化为对象的方法。
例子
List的序列化和反序列化
auto l = cjson::List("fesd", 156, -8879, true, -748.4854, 'F');
auto json = cjson::dumps(l,4);
std::cout << json << std::endl;
auto new_l = cjson::loads(json);
std::cout << new_l.as_list() << std::endl;
输出:
["fesd",156,-8879,true,-748.485400,70
]
["fesd",156,-8879,true,-748.485400,70]
Dict的序列化和反序列化
auto d = cjson::Dict();
d["fe"] = "defr5y5";
d["45t45"] = 156;
d[454] = -156056;
d[-54] = 545.07;
auto json = cjson::dumps(d,4);
std::cout << json << std::endl;
auto new_d = cjson::loads(json);
std::cout << new_d.as_dict() << std::endl;
输出:
{"fe": "defr5y5","45t45": 156,"454": -156056,"-54": 545.070000
}
{"fe":"defr5y5","45t45":156,"454":-156056,"-54":545.070000}
嵌套List序列化和反序列化
auto l1 = cjson::List("fesd", 156, -8879, false, -748.4854, 'F');
auto l2 = cjson::List("{fesd}", "s\ta44\r5\a5y\n", -56.454, 0x45489, nullptr, 'F4t\t');
auto l3 = cjson::List();
l3.append(l1);
l3.append("dt4t");
l3.append(l2);
l3.append(cjson::List());
auto json = cjson::dumps(l3,4);
std::cout << json << std::endl;
auto new_d = cjson::loads(json);
std::cout << new_d.as_list() << std::endl;
输出:
[["fesd",156,-8879,false,-748.485400,70],"dt4t",["{fesd}","s\ta44\r5\u00075y\n",-56.454000,283785,null,1177842697],[]
]
[["fesd",156,-8879,false,-748.485400,70],"dt4t",["{fesd}","s\ta44\r5\u00075y\n",-56.454000,283785,null,1177842697],[]]
嵌套Dict序列化和反序列化
auto d = cjson::Dict();
d["fe"] = "defr5y5";
d["45t45"] = 156;
d[454] = -156056;
d[-54] = cjson::Dict();
d[55] = cjson::Dict();
d[55].as_dict()[56] = "efgerg";
d[55].as_dict()[-56] = 0.41564;
d[55].as_dict()[0.415] = -464;auto d2 = cjson::Dict();
d2["5tg\r"] = "{g5y\t6}";
d2[0.458] = 548.154;d["\n"] = d2;auto json = cjson::dumps(d,4);
std::cout << json << std::endl;
auto new_d = cjson::loads(json);
std::cout << new_d.as_dict() << std::endl;
输出:
{"fe": "defr5y5","\n": {"5tg\r": "{g5y\t6}","0.458000": 548.154000},"45t45": 156,"454": -156056,"-54": {},"55": {"56": "efgerg","-56": 0.415640,"0.415000": -464}
}
{"fe":"defr5y5","45t45":156,"\n":{"5tg\r":"{g5y\t6}","0.458000":548.154000},"454":-156056,"-54":{},"55":{"56":"efgerg","-56":0.415640,"0.415000":-464}}
List和Dict混合序列化和反序列化1
auto d = cjson::Dict();
auto l2 = cjson::List("{fesd}", "s\ta44\r5\a5y\n", -56.454, 0x45489, nullptr, 'F4t\t', false, true);
d.insert(45, l2);
auto l1 = cjson::List("fesd", 156, -8879, false, -748.4854, 'F');
l1.append(d);
auto json = cjson::dumps(l1, 4);
std::cout << json << std::endl;
auto new_d = cjson::loads(json);
std::cout << new_d.as_list() << std::endl;
输出:
["fesd",156,-8879,false,-748.485400,70,{"45": ["{fesd}","s\ta44\r5\u00075y\n",-56.454000,283785,null,1177842697,false,true]}
]
["fesd",156,-8879,false,-748.485400,70,{"45":["{fesd}","s\ta44\r5\u00075y\n",-56.454000,283785,null,1177842697,false,true]}]
List和Dict混合序列化和反序列化2
auto d = cjson::Dict();
auto l2 = cjson::List("{fesd}", "s\ta44\r5\a5y\n", -56.454, 0x45489, nullptr, 'F4t\t', false, true);
d.insert(45, l2);
auto l1 = cjson::List("fesd", 156, -8879, false, -748.4854, 'F');
l1.append(d);
d[87.15] = l1;
auto json = cjson::dumps(d, 4);
std::cout << json << std::endl;
auto new_d = cjson::loads(json);
std::cout << new_d.as_dict() << std::endl;
输出:
{"45": ["{fesd}","s\ta44\r5\u00075y\n",-56.454000,283785,null,1177842697,false,true],"87.150000": ["fesd",156,-8879,false,-748.485400,70,{"45": ["{fesd}","s\ta44\r5\u00075y\n",-56.454000,283785,null,1177842697,false,true]}]
}
{"45":["{fesd}","s\ta44\r5\u00075y\n",-56.454000,283785,null,1177842697,false,true],"87.150000":["fesd",156,-8879,false,-748.485400,70,{"45":["{fesd}","s\ta44\r5\u00075y\n",-56.454000,283785,null,1177842697,false,true]}]}
自定义类型序列化和反序列化
class Custom
{
private:int32_t age_ = 0;bool female_ = false;std::string name_;cjson::List likes_;
public:Custom() = default;Custom(int32_t age, bool female, const std::string& name, const cjson::List& likes): age_(age), female_(female), name_(name), likes_(likes){ }int32_t get_age() const { return age_; }bool get_gender() const { return female_; }const std::string& get_name() const { return name_; }const cjson::List& get_likes() const { return likes_; }void set_age(const int32_t age) { age_ = age; }void set_gender(const bool female) { female_ = female; }void set_name(const std::string& name) { name_ = name; }void set_likes(const cjson::List& likes) { likes_ = likes; }
};void test_custom()
{Custom c(32, false, "Cxk", { "Sing","Dump","Rap" });auto json = cjson::dumps(c, 4);std::cout << json << std::endl;auto obj = cjson::loads(json);if (obj.any_value_.type() == typeid(Custom)){std::cout << "Suc\n";std::cout << cjson::dumps(obj.as_other<Custom>(), 4) << std::endl;}else{std::cout << "Fail\n";}}int main()
{cjson::register_json_interpreter<Custom>(dump_custom, load_custom);test_custom();
}
输出:
<age: 32,gender: male,name: Cxk,likes: ["Sing","Dump","Rap"]
>
Suc
<age: 32,gender: male,name: Cxk,likes: ["Sing","Dump","Rap"]
>
贡献指南
欢迎提交 Issue !
许可证
本项目采用GPL-3.0 license许可证。