Skip to content

zhoutk/zjson

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

203 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

ZJSON    中文介绍

JSONTestSuite C++17 header-only license: MIT

Conformance verified against the full JSONTestSuite test_parsing/ corpus — 95/95 y_ (must-accept) and 188/188 n_ (must-reject) cases pass in strict mode. See docs/jsontestsuite_results.txt.

The bundled JSON_checker mini-suite is also covered by automated regression tests: 36/36 corpus files under thirds/JSON-c/test/ pass with the original suite semantics (top-level object/array and 19-level nesting limit).

Recent API additions include toString(indent) pretty-printing, semantic ==/!=, begin/end/cbegin/cend iteration with structured bindings, duplicate-key ParseOptions, JSON Pointer via at("/a/b/0"), JSON Merge Patch / JSON Patch via mergePatch(...) and applyPatch(..., err), ADL-based to_json / from_json hooks, plus internal slab allocation and arena-backed parsed string storage.

The current Windows/MSVC Release benchmark report comparing zjson with nlohmann/json, RapidJSON, and simdjson is available in docs/性能测试报告.md.

Introduce

From node.Js back to c++. I especially miss the pleasure of using json in javascript, so try to diy one. I used many libraries, such as: rapidjson, cJson, CJsonObject, drleq cppjson, json11, etc. Zjson's data structure is greatly inspired by cJOSN. The parsing part refers to json11, thanks! Finally, because data storage needs not only to distinguish values, but also to know their types. I choose std:: variant and std:: any which supported by C++17. Finally, the C++ version is fixed at C++17. This library is designed as a single header file, not relying on any other lib than the C++ standard library.

Design ideas

Simple interface functions, simple use methods, flexible data structures, and support chain operations as much as possible. Realizing the simplest design using template technology. Adding a child object of Json only needs one function -- addSubitem, which automatically identifies whether it is a value or a child Json object. The Json object is stored in a linked list structure (refers to cJSON). Please see my data structure design as follows. The header and the following nodes use the same structure, which enables chained operations during index operations ([]).

Project progress

At present, the project has completed most of functions. Please refer to the task list for details.

task list:

  • constructor(Object & Array)
  • constructor(values)
  • JSON serializable constructor
  • copy constructor
  • initializer_list constructor
  • destructor
  • operator=
  • operator[]
  • contains
  • getValueType
  • getAndRemove
  • getAllKeys
  • addSubitem(add subitems & add items to array rapidly)
  • toString(generate josn string)
  • toInt、toDouble、toFalse
  • toVector
  • isError、isNull、isArray
  • parse - from Json string to Json object
  • Extend - Json
  • concat - Json
  • push_front - Json
  • push_back - Json
  • insert - Json
  • clear
  • std::move
  • Remove key
  • Remove intger
  • pop pop_back pop_front
  • removeFirst removeLast remove(for array)
  • slice
  • takes take
  • performance test and comparison harness
  • algorithm non recursion
  • slab allocator and parsed string arena

Data structure

Json node type

For internal use, the data type is only used inside the Json class

enum Type {
    Error,                //error or a invalid Json
    False,                //Json value type - false
    True,                 //Json value type - true
    Null,                 //Json value type - null
    Number,               //Json value type - numerial
    String,               //Json value type - string
    Object,               //Json object type
    Array                 //Json object type
};

Json node define

class Json {
    Json* brother;       //like cJSON's next
    Json* child;         //chile node, for object type
    Type type;           //node type
    std::variant <int, bool, double, string> data;   //node's data
    string name;         //node's key
}

Interface

Object type, only support Object and Array.

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

Api list

  • Json(JsonType type = JsonType::Object)      //constructor default, can generate Object or Array
  • template<typename T> Json(T value, string key="")        //value constructor
  • Json(const Json& origin)              //move constructor
  • Json(Json&& rhs)              //copy constructor
  • Json(string jsonStr)               //deserialized constructor
  • explicit Json(std::initializer_list<std::pair<const std::string, Json>> values)     //initializer_list Object constructor
  • Json& operator = (const Json& origin)       
  • Json& operator = (Json&& origin)       
  • Json operator[](const int& index)        
  • Json operator[](const string& key)         
  • template<typename T> bool addSubitem(T value)      
  • template<typename T> bool addSubitem(string name, T value) //add a subitem
  • string toString()                 
  • bool isError()                 
  • bool isNull()                  
  • bool isObject()                 
  • bool isArray()                 
  • bool isNumber()                 
  • bool isTrue()                  
  • bool isFalse()                 
  • int toInt()                    
  • float toFloat()                  
  • double toDouble()               
  • bool toBool()                  
  • vector<Json> toVector()             
  • bool extend(Json value)            
  • bool concat(Json value)            //for array object
  • bool push_front(Json value)            //for array object
  • bool push_back(Json value)            //for array object
  • bool insert(int index, Json value)           //for array object
  • void clear()            //clear child
  • void remove(const string &key)          
  • bool contains(const string& key)            
  • string getValueType()           //return value's type in string
  • Json getAndRemove(const string& key)           
  • std::vectorstd::string getAllKeys()           

Examples

    Json subObject{{"math", 99},{"str", "a string."}};   
    Json mulitListObj{{"fkey", false},{"strkey","ffffff"},{"num2", 9.98}, {"okey", subObject}};
    Json subArray(JsonType::Array);                 
    subArray.add({12,13,14,15});            

    Json ajson(JsonType::Object);                
    std::string data = "kevin";                     
    ajson.add("fail", false);             
    ajson.add("name", data);              
    ajson.add("school-en", "the 85th.");   
    ajson.add("age", 10);                  
    ajson.add("scores", 95.98);            
    ajson.add("nullkey", nullptr);         

    Json sub;                                  
    sub.add("math", 99);                 
    ajson.addValueJson("subJson", sub);           

    Json subArray(JsonType::Array);              
    subArray.add("I'm the first one.");   
    subArray.add("two", 2);               
    
    Json sub2;                            
    sub2.add("sb2", 222);

    subArray.addValueJson("subObj", sub2);         
    
    ajson.addValueJson("array", subArray);         

    std::cout << "ajson's string is : " << ajson.toString() << std::endl;   

    string name = ajson["name"].toString();        
    int oper = ajson["sb2"].toInt();               
    Json operArr = ajson["array"];                 
    string first = ajson["array"][0].toString();   

result of mulitListObj:

{
    "fkey": false,
    "strkey": "ffffff",
    "num2": 9.98,
    "okey": {
        "math": 99,
        "str": "a string."
    }
}

result of ajson:

{
    "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
        }
    ]
}

Detailed description, please move to demo.cpp or unit test in tests catalogue.

Implementation-Defined Behavior

The following table documents zjson's behavior on inputs where the JSON specification (RFC 8259) does not mandate a particular outcome, or where common implementations differ. These correspond to the i_* (implementation-defined) category in the JSONTestSuite.

Behavior zjson Notes
Duplicate object keys Configurable; default keep-last ParseOptions::DuplicateKeyPolicy supports KeepFirst, KeepLast, and Reject
Number precision IEEE 754 double Parsed via strtod; integers that fit in int use atoi fast path
Very large numbers ±Infinity strtod result; no error
Very small numbers 0.0 or denormal strtod result; no error
Maximum nesting depth 100 levels Configurable via max_depth; deeper input is rejected
UTF-8 BOM (U+FEFF) Not consumed BOM bytes cause a parse error (not treated as whitespace)
Comments (// and /* */) Accepted in extension mode ParseJson() allows comments; ParseJsonStrict() rejects them
Trailing commas Rejected [1,] and {"a":1,} produce parse errors
Leading zeros Rejected 012, -01 produce parse errors
NaN / Infinity literals Rejected Not valid JSON values
Single-quoted strings Rejected Only double-quoted strings are accepted
Unquoted object keys Rejected Keys must be double-quoted strings
Lone surrogates in \uXXXX Encoded as-is into UTF-8 Not rejected in extension mode; use ParseJsonStrictUtf8() for byte-level validation
UTF-8 byte validation Off by default Enable via ParseJsonStrictUtf8() to reject invalid byte sequences
Maximum string length Limited by std::string / memory No explicit limit
Null bytes in strings Accepted via \u0000 Raw 0x00 bytes in the input stream cause string termination issues on C-string APIs

Parsing Modes

API Comments UTF-8 validation Use case
ParseJson(input, err) Allowed Off General use with extensions
ParseJsonStrict(input, err) Rejected Off Strict RFC 8259 structure
ParseJsonStrictUtf8(input, err) Rejected On Full RFC 8259 + UTF-8 compliance

Project site

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

run guidance

The project is built in vs2019, gcc7.5, clang12.0 success.

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

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

---linux & mac
cd build && make

run ctest --test-dir out/build/x64-release --output-on-failure

Associated projects

zorm (General Encapsulation of Relational Database)

https://gitee.com/zhoutk/zorm
or
https://github.com/zhoutk/zorm

About

A json lib use c++17, simplest interface, fully implement JSON standard, a single head file, full unit test.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors