1

zjson

introduce

From node.js to c++, I especially miss the fun of using json in js. I have also used some libraries in C++, but the interface usage provided is not a habit, it is annoying to lock, and there are too many interface functions, which are not intuitive. I have referred to many libraries, such as: rapidjson, cJson, CJsonObject, drleq-cppjson, json11, etc., inspired by the data structure of cJson, I decided to use C++ to manually create one. Finally, because data storage needs to be indistinguishable by type, and it is necessary to know its type, std::variant and std::any, which are only supported by C++17, are selected. In the end, the C++ version is fixed at c++17. The library is designed as a single header file and does not depend on any library other than the C++ standard library.

Project name description

The first letter z of my name in Pinyin plus josn is the name of this project, zjson, which has no other meaning. I'm going to write a series of related projects starting with z, naming it is a hassle, so here's the simplistic approach.

Design ideas

Simple interface functions, simple usage methods, flexible data structures, and support chain operations as much as possible. Using template technology, there are only two methods for adding values to Json objects, AddValueBase and AddValueJson. A linked list structure (a tribute to cJSON) is used to store Json objects. Please see my data structure design below. The header and the following nodes use the same structure, which makes it possible to perform index operations ([]). chain operation.

project progress

The project is currently half completed. You can create a new Json object, add data, extract the corresponding value or sub-object by key (Object type) or index (Array type), and generate a JSON string.
The memory leak test has been done, the destructor can run correctly, and there is no significant increase in memory for millions of levels of generation and destruction.
task list:

  • [x] Constructor, copy constructor, destructor
  • [x] AddValueBase (add value type to Json object), AddValueJson (add object type to Json object)
  • [x] operator=, operator[]
  • [x] toString (generates json string)
  • [x] value type conversions such as toInt, toDouble, toFalse
  • [x] Node type judgment such as isError, isNull, isArray, etc.
  • [ ] parse, generate a Json object from a json string; the corresponding constructor
  • [ ] Extend Json - Extend Object
  • [ ] Remove[All] key - removes data, since Json objects allow duplicate keys
  • [ ] findAll - find all, since Json objects allow duplicate keys
  • [ ] std::move semantics

data structure

Json node type definition

(Internal use, the data type is only used inside the Json class)

 enum Type {
    Error,                //错误,查找无果,这是一个无效Json对象
    False,                //Json值类型 - false
    True,                 //Json值类型 - true
    Null,                 //Json值类型 - null
    Number,               //Json值类型 - 数字,库中以double类型存储
    String,               //Json值类型 - 字符串
    Object,               //Json类对象类型 - 这是Object嵌套,对象型中只有child需要关注
    Array                 //Json类对象类型 - 这是Array嵌套,对象型中只有child需要关注
};

Json node definition

 class Json {
    Json* brother;       //与cJSON中的next对应,值类型才有效,指向并列的数据,但有可能是值类型,也有可能是对象类型
    Json* child;         //孩子节点,对象类型才有效
    Type type;           //节点类型
    std::variant <int, bool, double, string> data;   //节点数据
    string name;         //节点的key
}

Interface Description

The public object type, json only supports Object and Array two kinds of objects, corresponding to the internal type (public type).

 enum class JsonType
{
    Object = 6,
    Array = 7
};

Interface list

  • Json(JsonType type = JsonType::Object) //Default constructor, generates Json objects of Object or Array type
  • Json(const Json& origin) //copy constructor
  • Json& operator = (const Json& origin) //assignment operation
  • Json operator[](const int& index) //Json array object element query
  • Json operator[](const string& key) //Json Object object is queried by key
  • bool AddValueJson(Json& obj) //Add sub-Json class object type, only for Array
  • bool AddValueJson(string name, Json& obj) //Add sub-Json class object type, when obj is Array, name will be ignored
  • template<typename T> bool AddValueBase(T value) //Add value object type, only for Array
  • template<typename T> bool AddValueBase(string name, T value) //Add value object type, when this is Array, name will be ignored
  • string toString() //Json object is serialized to string
  • bool isError() //Invalid Json object determination
  • bool isNull() //null value determination
  • bool isObject() //Object object determination
  • bool isArray() //Array object determination
  • bool isNumber() //Number value determination, use double type to store number value in Json
  • bool isTrue() //true value judgment
  • bool isFalse() //false value determination
  • int toInt() //The value object is converted to int
  • float toFloat() //The value object is converted to float
  • double toDouble() //The value object is converted to double
  • bool toBool() //The value object is converted to bool

programming example

Simple usage example

 Json ajson(JsonType::Object);                   //新建Object对象,输入参数可以省略
    std::string data = "kevin";                     
    ajson.AddValueBase("fail", false);              //增加false值对象
    ajson.AddValueBase("name", data);               //增加字符串值对象
    ajson.AddValueBase("school-en", "the 85th.");   
    ajson.AddValueBase("age", 10);                  //增加number值对象,此处为整数
    ajson.AddValueBase("scores", 95.98);            //增加number值对象,此处为浮点数,还支持long,long long
    ajson.AddValueBase("nullkey", nullptr);         //增加null值对象,需要送入nullptr, NULL会被认为是整数0

    Json sub;                                       //新建Object对象
    sub.AddValueBase("math", 99);                 
    ajson.AddValueJson("subJson", sub);             //为ajson增加子Json类型对象,完成嵌套需要

    Json subArray(JsonType::Array);                 //新建Array对象,输入参数不可省略
    subArray.AddValueBase("I'm the first one.");    //增加Array对象的字符串值子对象
    subArray.AddValueBase("two", 2);                //增加Array对象的number值子对象,第一个参数会被忽略
    
    Json sub2;                            
    sub2.AddValueBase("sb2", 222);

    subArray.AddValueJson("subObj", sub2);          //为Array对象增加Object类子对象,完成嵌套需求
    
    ajson.AddValueJson("array", subArray);          //为ajson增加Array对象,且这个Array对象本身就是一个嵌套结构

    std::cout << "ajson's string is : " << ajson.toString() << std::endl;    //输出ajson对象序列化后的字符串, 结果见下方

    string name = ajson["name"].toString();         //提取key为name的字符串值,结果为:kevin
    int oper = ajson["sb2"].toInt();                //提取嵌套深层结构中的key为sb2的整数值,结果为:222
    Json operArr = ajson["array"];                  //提取key为array的数组对象
    string first = ajson["array"][0].toString();    //提取key为array的数组对象的序号为0的值,结果为:I'm the first one.

The result of ajson serialization is:

 {
    "fail": false,
    "name": "kevin",
    "school-en": "the 85th.",
    "age": 10,
    "scores": 95.98,
    "nullkey": null,
    "subJson": {
        "math": 99
    },
    "array": [
        "I'm the first one.",
        2,
        {
            "sb2": 222
        }
    ]
}

For details, please refer to demo.cpp or test cases in the tests directory

project address

 https://gitee.com/zhoutk/zjson
或
https://github.com/zhoutk/zjson

run method

The project compiles and runs normally under vs2019, gcc7.5, and clang12.0.

 git clone https://github.com/zhoutk/zjson
cd zjson
cmake -Bbuild .

---windows
cd build && cmake --build .

---linux & mac
cd build && make

run zjson or ctest

Related items

There will be a series of projects released, related to network services, so stay tuned...


zhoutk
2.6k 声望1.2k 粉丝

自由程序员,技术路线c,delphi,c++,c#,java,php,node.js,python,golang,typescript;超喜欢react.js的设计思路,全栈开发成为我的终极目标。开发机器macbook pro,或装ubuntu、fedora的机器,编程用vim...