{"id":16693725,"url":"https://github.com/cculianu/univalue","last_synced_at":"2025-03-17T00:33:30.784Z","repository":{"id":137477700,"uuid":"381099579","full_name":"cculianu/univalue","owner":"cculianu","description":"An easy-to-use and competitively fast JSON parsing library for C++17, forked from Bitcoin Cash Node's own UniValue library.","archived":false,"fork":false,"pushed_at":"2024-07-02T13:30:57.000Z","size":12765,"stargazers_count":30,"open_issues_count":0,"forks_count":2,"subscribers_count":4,"default_branch":"master","last_synced_at":"2025-03-16T06:41:15.224Z","etag":null,"topics":["cpp","json","library","parser","serialization"],"latest_commit_sha":null,"homepage":"","language":"C++","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/cculianu.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"COPYING","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2021-06-28T16:42:30.000Z","updated_at":"2025-03-09T17:03:49.000Z","dependencies_parsed_at":"2024-10-27T11:49:43.048Z","dependency_job_id":"9647add6-a317-4245-bcd8-644529ba4e2a","html_url":"https://github.com/cculianu/univalue","commit_stats":null,"previous_names":[],"tags_count":4,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cculianu%2Funivalue","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cculianu%2Funivalue/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cculianu%2Funivalue/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cculianu%2Funivalue/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/cculianu","download_url":"https://codeload.github.com/cculianu/univalue/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":243955668,"owners_count":20374371,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["cpp","json","library","parser","serialization"],"created_at":"2024-10-12T16:32:10.691Z","updated_at":"2025-03-17T00:33:28.717Z","avatar_url":"https://github.com/cculianu.png","language":"C++","funding_links":[],"categories":[],"sub_categories":[],"readme":"# UniValue JSON Library for C++17 (and above)\n\nAn easy-to-use and competitively fast JSON parsing library for C++17, forked from Bitcoin Cash Node's own UniValue library.\n\nSupports parsing and serializing, as well as modeling a JSON document.  The central class is `UniValue`, a universal value class, with JSON encoding and decoding methods. `UniValue` is an abstract data type that may be a null, boolean, string, number, array container, or a key/value dictionary container, nested to an arbitrary depth. This class implements  the JSON standard, [RFC 8259](https://tools.ietf.org/html/rfc8259).\n\n## Quick 'n Dirty Example Usage\n\nThe below is taken from [basic_example.cpp](examples/basic_example.cpp).\n\n### Building an Object\n```c++\n// An example of how to build an object\nUniValue uv;\nauto \u0026obj = uv.setObject(); // this clears the uv instance and sets it to type VOBJ, returning a reference to the underlying Object\nobj.emplace_back(\"this is a JSON object\", \"it's pretty neat\");\nobj.emplace_back(\"akey\", 3.14);\nobj.emplace_back(\"theanswer\", 42);\nobj.emplace_back(\"thequestion\", false);\nobj.emplace_back(\"alist\", UniValue::Array{{ 1, 2, 3, 4, \"hahaha\" }});\n\n// the below stringifies or serializes the constructed object\nstd::cout \u003c\u003c UniValue::stringify(uv, 4 /* pretty indent 4 spaces */) \u003c\u003c std::endl;\n\n/*\n   Program output for above is:\n   {\n       \"this is a JSON object\": \"it's pretty neat\",\n       \"akey\": 3.14,\n       \"theanswer\": 42,\n       \"thequestion\": false,\n       \"alist\": [\n           1,\n           2,\n           3,\n           4,\n           \"hahaha\"\n       ]\n   }\n*/\n```\n\n### Parsing / Processing an Object\n\n```c++\n// An example of how to parse an object and examine it\nconst std::string json{\n    \"{\"\n    \"    \\\"this is a JSON object\\\": \\\"it's pretty neat\\\" ,\"\n    \"    \\\"akey\\\": 3.14,\"\n    \"    \\\"theanswer\\\": 42,\"\n    \"    \\\"thequestion\\\": false,\"\n    \"    \\\"alist\\\": [1,2,3,4,\\\"hahaha\\\"]\"\n    \"}\"\n};\nUniValue uv;\nconst bool ok = uv.read(json);\nassert(ok); // parse of valid json\nassert(uv.isObject()); // uv.isObject() is true\nconst auto \u0026obj = uv.get_obj(); // this would throw std::runtime_error if !uv.isObject()\nfor (const auto \u0026 [key, value] : obj) {\n    if (key == \"theanswer\")\n        std::cout \u003c\u003c \"the answer is: \" \u003c\u003c value.get_int64() \u003c\u003c std::endl; // throws if the value is not numeric\n    else if (key == \"thequestion\")\n        std::cout \u003c\u003c \"the question is: \" \u003c\u003c value.get_bool() \u003c\u003c std::endl; // throws if value is not boolean\n    else if (key == \"alist\" \u0026\u0026 value.isArray()) {\n        std::cout \u003c\u003c \"the list: \" \u003c\u003c std::flush;\n        int i = 0;\n        for (const auto \u0026 item : value.get_array())\n            std::cout \u003c\u003c (i++ ? \", \" : \"\") \u003c\u003c item.getValStr(); // getValStr() returns the contents of either a numeric or a string\n        std::cout \u003c\u003c std::endl;\n    }\n}\n/*\n   Program output for above is:\n\n   the answer is: 42\n   the question is: 0\n   the list: 1, 2, 3, 4, hahaha\n*/\n```\n\n## Summary of Differences from other JSON Libraries\n\n- Faster than many implementations.  For example, faster than [nlohmann](https://github.com/nlohmann/json) for both parsing and for stringification (roughly 2x faster in many cases).\n  - Install `nlohmann::json` and use the `bench` build target to convince yourself of this.\n  - Example bench on my 2019 MacBook Pro:\n```\nRunning test on \"../bench/semanticscholar-corpus.json\" ...\nRead 8593351 bytes in 6.723 msec\n\n--- UniValue lib ---\nParsing and re-serializing 10 times ...\nElapsed (msec) - 967.757\nParse (msec) - median: 48.598, avg: 49.845, best: 46.742, worst: 57.972\nSerialize (msec) - median: 32.081, avg: 32.789, best: 31.280, worst: 40.098\n\n--- nlohmann::json lib ---\nParsing and re-serializing 10 times ...\nElapsed (msec) - 1860.147\nParse (msec) - median: 91.739, avg: 96.404, best: 89.113, worst: 128.864\nSerialize (msec) - median: 45.042, avg: 45.768, best: 44.437, worst: 51.345\n```\n- Easier to use, perhaps?\n  - The entire implementation is wrapped by a single class, called `UniValue` which captures any JSON data item, as well as the whole document, with a single abstraction. Compare this to some of the other fast libraries out there (which shall remain nameless here), some of which are arguably more difficult to use.\n- \"Faithful\" representation of input JSON.\n  - Stores the read JSON faithfully without \"reinterpreting\" anything.  For example if the input document had a JSON numeric `1.000000`, this library will re-serialize it verbatim as `1.000000` rather than `1.0` or `1`.\n   - The reason for this: when this library parses JSON numerics, they are internally stored as string fragments (validation is applied, however, to ensure that invalid numerics cannot make it in).\n   - JSON numerics are actually really parsed to ints or doubles \"on-demand\" only when the caller actually asks for a number via a getter method.\n- Does not use `std::map` or other map-like structures for JSON objects.  JSON objects are implemented as a `std::vector` of `std::pair`s.\n   - This has the benefit of fast inserts when building or parsing the JSON object. (No need to balance r-b trees, etc).\n   - Inserts preserve the order of insert (which can be an advantage  or a disadvantage, depending on what matters to you; they are sort of like Python 3.7+ dicts in that regard).\n   - Inserts do not check for dupes -- you can have the same key appear twice in the object (something which the JSON specification allows for but discourages).\n   - Lookups are O(N), though -- but it is felt that for most usages of a C++ app manipulating JSON, this is an acceptable tradeoff.\n     - In practice many applications merely either parse JSON and iterate over keys, or build the object up once to be sent out on the network or saved to disk immediately -- in such usecases the `std::vector` approach for JSON objects is faster \u0026 simpler.\n- Nesting limits:\n  - Unlimited for serializing/stringification\n  - **512** for parsing (as a simple DoS measure)\n    - This can be changed by modifying a compile-time constant in [`univalue_read.cpp`](https://github.com/cculianu/univalue/blob/master/lib/univalue_read.cpp#L31).\n\n## Background\n\nUniValue was originally created by [Jeff Garzik](https://github.com/jgarzik/univalue/) and is used in node software for many bitcoin-based cryptocurrencies.\n\n**BCHN UniValue** was a fork of UniValue designed and maintained for use in [Bitcoin Cash Node (BCHN)](https://bitcoincashnode.org/).\n\n**This library** is a fork of the above implementation, optimized and maintained by me, [Calin A. Culianu](mailto:calin.culianu@gmail.com)\n\nUnlike the [Bitcoin Core fork](https://github.com/bitcoin-core/univalue/), this UniValue library contains major improvements to *code quality* and *performance*. This library's UniValue API differs slightly from its ancestor projects.\n\n#### How this library differs from its ancestor UniValue libaries:\n\n- Optimizations made to parsing (about 1.7x faster than the BCHN library, and several times faster than the Bitcoin Core library)\n- Optimizations made to memory consumption (each UniValue nested instance eats only 32 bytes of memory, as opposed to 80 or more bytes in the other implementations)\n- Various small nits and improvements to code quality\n\n## License\n\nThis library is released under the terms of the MIT license. See [COPYING](COPYING) for more information or see \u003chttps://opensource.org/licenses/MIT\u003e.\n\n## Build Instructions\n\n- `mkdir build \u0026\u0026 cd build`\n- `cmake -GNinja ..`\n- `ninja all check`\n\nThe above will build and run the unit tests, as well as build the shared library. Alternatively, you can just **put the source files** from the [`lib/`](lib) and [`include/`](include) folders into your project.  \n\nThis library requires C++17 or above.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcculianu%2Funivalue","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcculianu%2Funivalue","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcculianu%2Funivalue/lists"}