ZJSON 中文介绍
Conformance verified against the full
JSONTestSuitetest_parsing/corpus — 95/95y_(must-accept) and 188/188n_(must-reject) cases pass in strict mode. Seedocs/jsontestsuite_results.txt.The bundled
JSON_checkermini-suite is also covered by automated regression tests: 36/36 corpus files underthirds/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.
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.
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 ([]).
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
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
};
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
}
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()
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.
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 |
| 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 |
https://gitee.com/zhoutk/zjson
or
https://github.com/zhoutk/zjson
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
zorm (General Encapsulation of Relational Database)
https://gitee.com/zhoutk/zorm
or
https://github.com/zhoutk/zorm