An easy-to-use and competitively fast JSON parsing library for C++17, forked from Bitcoin Cash Node's own UniValue library.

Overview

UniValue JSON Library for C++17 (and above)

An easy-to-use and competitively fast JSON parsing library for C++17, forked from Bitcoin Cash Node's own UniValue library.

Supports 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.

Quick 'n Dirty Example Usage

The below is taken from basic_example.cpp.

Building an Object

// An example of how to build an object
UniValue uv;
auto &obj = uv.setObject(); // this clears the uv instance and sets it to type VOBJ, returning a reference to the underlying Object
obj.emplace_back("this is a JSON object", "it's pretty neat");
obj.emplace_back("akey", 3.14);
obj.emplace_back("theanswer", 42);
obj.emplace_back("thequestion", false);
obj.emplace_back("alist", UniValue::Array{{ 1, 2, 3, 4, "hahaha" }});

// the below stringifies or serializes the constructed object
std::cout << UniValue::stringify(uv, 4 /* pretty indent 4 spaces */) << std::endl;

/*
   Program output for above is:
   {
       "this is a JSON object": "it's pretty neat",
       "akey": 3.14,
       "theanswer": 42,
       "thequestion": false,
       "alist": [
           1,
           2,
           3,
           4,
           "hahaha"
       ]
   }
*/

Parsing / Processing an Object

// An example of how to parse an object and examine it
const std::string json{
    "{"
    "    \"this is a JSON object\": \"it's pretty neat\" ,"
    "    \"akey\": 3.14,"
    "    \"theanswer\": 42,"
    "    \"thequestion\": false,"
    "    \"alist\": [1,2,3,4,\"hahaha\"]"
    "}"
};
UniValue uv;
const bool ok = uv.read(json);
assert(ok); // parse of valid json
assert(uv.isObject()); // uv.isObject() is true
const auto &obj = uv.get_obj(); // this would throw std::runtime_error if !uv.isObject()
for (const auto & [key, value] : obj) {
    if (key == "theanswer")
        std::cout << "the answer is: " << value.get_int64() << std::endl; // throws if the value is not numeric
    else if (key == "thequestion")
        std::cout << "the question is: " << value.get_bool() << std::endl; // throws if value is not boolean
    else if (key == "alist" && value.isArray()) {
        std::cout << "the list: " << std::flush;
        int i = 0;
        for (const auto & item : value.get_array())
            std::cout << (i++ ? ", " : "") << item.getValStr(); // getValStr() returns the contents of either a numeric or a string
        std::cout << std::endl;
    }
}
/*
   Program output for above is:

   the answer is: 42
   the question is: 0
   the list: 1, 2, 3, 4, hahaha
*/

Summary of Differences from other JSON Libraries

  • Faster than many implementations. For example, faster than nlohmann for both parsing and for stringification (roughly 2x faster in many cases).
  • Easier to use, perhaps?
    • 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.
  • "Faithful" representation of input JSON.
    • 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.
    • 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).
    • 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.
  • Does not use std::map or other map-like structures for JSON objects. JSON objects are implemented as a std::vector of std::pairs.
    • This has the benefit of fast inserts when building or parsing the JSON object. (No need to balance r-b trees, etc).
    • 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).
    • 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).
    • Lookups are O(N), though -- but it is felt that for most usages of a C++ app manipulating JSON, this is an acceptable tradeoff.
      • 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 & simpler.
  • Nesting limits:
    • Unlimited for serializing/stringification
    • 512 for parsing (as a simple DoS measure)

Background

UniValue was originally created by Jeff Garzik and is used in node software for many bitcoin-based cryptocurrencies.

BCHN UniValue was a fork of UniValue designed and maintained for use in Bitcoin Cash Node (BCHN).

This library is a fork of the above implementation, optimized and maintained by me, Calin A. Culianu

Unlike the Bitcoin Core fork, this UniValue library contains major improvements to code quality and performance. This library's UniValue API differs slightly from its ancestor projects.

How this library differs from its ancestor UniValue libaries:

  • Optimizations made to parsing (about 1.7x faster than the BCHN library, and several times faster than the Bitcoin Core library)
  • 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)
  • Various small nits and improvements to code quality

License

This library is released under the terms of the MIT license. See COPYING for more information or see https://opensource.org/licenses/MIT.

Build Instructions

  • mkdir build && cd build
  • cmake -GNinja ..
  • ninja all check

The 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/ and include/ folders into your project.

This library requires C++17 or above.

Releases(v2.2.0)
  • v2.2.0(Aug 31, 2021)

    What's new:

    • Added unsigned getters get_uint64() and get_uint(), which allow for retrieving values over a larger positive range, and also throw for you if the stored value is negative.
    • Updated the unit test to handle more corner cases
    • The CMake project now embeds an SONAME into the lib (on platforms that support this), to allow ABI/compatibility versioning of the library.
    • Some internal code refactoring.
    Source code(tar.gz)
    Source code(zip)
  • v2.1.0(Aug 29, 2021)

    What's new:

    • Added a bench target to the project. If using ninja, you can do ninja bench to run the benchmark.
      • This target optionally also finds and uses nlohmann::json (if installed) to compare this library to that library.
      • If curious, see univalue_bench.cpp for the implementation.
    • Renamed the static function UniValue::Version() (for querying library version) to UniValue::version(), which is more consistent with the other names in this class.
    • Added an optional 3rd argument to stringify, reserve, which allows the caller to hint to the function how much space to preallocate for the returned string.
    • Misc tiny fixups to univalue.h
    Source code(tar.gz)
    Source code(zip)
  • v2.0.1(Jun 30, 2021)

    What's new:

    • Added std::initializer_list constructor for both UniValue::Array and UniValue::Object types, for convenience.
    • Added a basic example: examples/basic_example.cpp.
    • Added the static method UniValue::Version() to have the library report its own compiled-in version information.
    • Added two new unit tests.
    Source code(tar.gz)
    Source code(zip)
  • v2.0(Jun 29, 2021)

Owner
Calin Culianu
aka NilacTheGrim aka Void Pointer
Calin Culianu
https://github.com/json-c/json-c is the official code repository for json-c. See the wiki for release tarballs for download. API docs at http://json-c.github.io/json-c/

\mainpage json-c Overview and Build Status Building on Unix Prerequisites Build commands CMake options Testing Building with vcpkg Linking to libjson-

json-c 2.5k Aug 2, 2022
A convenience C++ wrapper library for JSON-Glib providing friendly syntactic sugar for parsing JSON

This library is a wrapper for the json-glib library that aims to provide the user with a trivial alternative API to the API provided by the base json-

Rob J Meijer 16 May 10, 2022
Fast JSON serialization and parsing in C++

DAW JSON Link v2 Content Intro Default Mapping of Types API Documentation - Member mapping classes and methods Cookbook Get cooking and putting it all

Darrell Wright 305 Aug 5, 2022
A fast streaming JSON parsing library in C.

********************************************************************** This is YAJL 2. For the legacy version of YAJL see https

Lloyd Hilaiel 2.1k Jul 30, 2022
Very fast Python JSON parsing library

cysimdjson Fast JSON parsing library for Python, 7-12 times faster than standard Python JSON parser. It is Python bindings for the simdjson using Cyth

TeskaLabs 215 Aug 5, 2022
json_struct is a single header only C++ library for parsing JSON directly to C++ structs and vice versa

Structurize your JSON json_struct is a single header only library that parses JSON to C++ structs/classes and serializing structs/classes to JSON. It

Jørgen Lind 238 Aug 6, 2022
Easy-to-use helpers for TDLib JSON.

easy-tg Easy-to-use helpers for TDLib JSON. Not completely tested yet. Dependencies tdlib json-c Functions Automatically handles authorization state c

Yuuta Liang 1 Oct 18, 2021
A simple class for parsing JSON data into a QVariant hierarchy and vice versa.

The qt-json project is a simple collection of functions for parsing and serializing JSON data to and from QVariant hierarchies. NOTE: Qt5 introduced a

null 300 Jul 23, 2022
Jvar - JS inspired Variants and JSON parsing for C++

jvar jvar tries to capture some of the expressiveness of JavaScript and bring it into C++ In particular, it implements a Variant type which is similar

Yasser Asmi 23 Jun 15, 2022
A simple class for parsing JSON data into a QVariant hierarchy and vice versa.

The qt-json project is a simple collection of functions for parsing and serializing JSON data to and from QVariant hierarchies. NOTE: Qt5 introduced a

null 300 Jul 23, 2022
jstruct is an automatic C code generation tool for generating JSON parsing and stringifying code.

jstruct is an automatic C code generation tool for generating JSON parsing and stringifying code. The C code generated by this tool needs to depend on the cJSON library for execution.

acoinfo 27 Apr 18, 2022
Parsing gigabytes of JSON per second

simdjson : Parsing gigabytes of JSON per second JSON is everywhere on the Internet. Servers spend a *lot* of time parsing it. We need a fresh approach

null 15.9k Aug 1, 2022
Parsing gigabytes of JSON per second

simdjson : Parsing gigabytes of JSON per second JSON is everywhere on the Internet. Servers spend a *lot* of time parsing it. We need a fresh approach

null 15.9k Jul 29, 2022
This is a JSON C++ library. It can write and read JSON files with ease and speed.

Json Box JSON (JavaScript Object Notation) is a lightweight data-interchange format. Json Box is a C++ library used to read and write JSON with ease a

Anhero inc. 108 Jul 7, 2022
json-cpp is a C++11 JSON serialization library.

JSON parser and generator for C++ Version 0.1 alpha json-cpp is a C++11 JSON serialization library. Example #include <json-cpp.hpp> struct Foo {

Anatoly Scheglov 4 Dec 31, 2019
json-build is a zero-allocation JSON serializer compatible with C89

json-build is a zero-allocation JSON serializer compatible with C89. It is inspired by jsmn, a minimalistic JSON tokenizer.

Lucas Müller 27 Jul 26, 2022
a JSON parser and printer library in C. easy to integrate with any model.

libjson - simple and efficient json parser and printer in C Introduction libjson is a simple library without any dependancies to parse and pretty prin

Vincent Hanquez 262 Aug 6, 2022
A Simple Nastran to JSON mesh reader which makes it easy to exchange data

Nastran to Json Converter A simple code that helps convert Nastran meshes to a JSON file format that is more suitable for the current day and age. Cur

Vijai Kumar S 5 Sep 23, 2021
A Haskell library for fast decoding of JSON documents using the simdjson C++ library

hermes A Haskell interface over the simdjson C++ library for decoding JSON documents. Hermes, messenger of the gods, was the maternal great-grandfathe

Josh Miller 36 Jun 29, 2022