项目名称

该项目是我在学习现代c++编程时所写的一个用于序列化对象为json和反序列化json为指定对象的c++库。该库的特点就是轻量,便捷,灵活。

功能特性

  • 功能 1:序列化基本数据类型(nullptr_tbool整数double)、内定类型(StrDictList)为json,支持json美化。
  • 功能 2:反序列化json文本为指定对象。
  • 功能 3:提供支持有限的自定义类型序列化和反序列化接口,需要自己去实现这两个方法。

注意:默认并不支持 c + + 原生容器的序列化合反序列化,需要自己实现这两个方法。 \textcolor{BrickRed}{注意:默认并不支持c++原生容器的序列化合反序列化,需要自己实现这两个方法。} 注意:默认并不支持c++原生容器的序列化合反序列化,需要自己实现这两个方法。

安装指南

# 克隆项目
git clone https://github.com/LonelyWindy/cjson.git

然后将cjson.hfile_view.h放到你的项目中。

注意:请使用 C + + 20 及以上标准! \textcolor{BrickRed}{注意:请使用C++20及以上标准!} 注意:请使用C++20及以上标准!

内定数据类型

Str

增强的std::string,使用方法在原来的基础上,新增格式化字符串方法 f o r m a t \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许可证。

Logo

更多推荐