Skip to content
/ cxon Public

Simple, extensible and fast C++11 serialization library with JSON as a default serialization format.

License

Notifications You must be signed in to change notification settings

oknenavin/cxon

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

CXON library

Library Version
Language Format Format
License

Build Build Build
Codecov Coverity


  • CXON is a C++ serialization interface
  • CXON implements JSON (UTF-8 encoded) as a serialization format (an example of a text-based data format)
  • CXON implements CBOR as a serialization format (example of a binary data format)
  • CXON is easy to extend for different formats and types with zero-overhead
  • CXON is a C++11 compliant, self contained and compact header-only library

Although CXON is a serialization library, its goal is to actually compete with JSON/CBOR/etc. libraries like Boost.JSON/RapidJSON/etc. and its main advantage is, that no intermediate type is needed to represent the data - any C++ type that matches it semantically can be used.

Example
#include "cxon/json.hxx"
#include "cxon/lib/std/vector.hxx" // for <vector>
#include <cassert>

int main() {
    std::vector<int> cxx; // or std::array, std::list, std::set, etc.
        // the input is a JSON array, semantically a list of integers
        auto result = cxon::from_bytes(cxx,  "[1, 2, 3]");
    assert(result);
    // the data is loaded successfully, no additional semantic validation is needed, so
    assert(cxx == (std::vector<int> {1, 2, 3}));
}

Successful deserialization means that the input is syntactically and semantically correct.

Other such libraries represent arbitrary data with polymorphic type (called DOM, value, etc.), and successful parsing of the input data means only that it is syntactically correct.

Example
// pseudo code
value_type json = json_lib::parse("[1, 2, 3]");
assert(json.has_parsing_errors()); // check for syntax errors
// check the semantics, expected is a list of integers
assert(json.is_array()); // check the type
auto& array = json.get_array();
assert( // check the values
    array.size() > ... &&
    array[0].is_integer() &&
    array[1].is_integer() &&
    array[2].is_integer() &&
    ...
);
// the input is semantically correct, but
// the values still need special attention
int x0 = array[0].get_integer(); // it's an int, but not quite
...

To help with this, some of the libraries provide utilities to convert the value type to a C++ type - e.g. Boost.JSON provides value_from / value_to.
For completeness, CXON also provides polymorphic types (called node) for the supported formats that match the functionality provided by these libraries.

The performance is often important and is emphasized by many libraries and in this respect, CXON is close to the alternatives.
Many libraries emphasize the floating-point serialization and deserialization performance. CXON uses <charconv> by default (with a fallback implementation for C++11), but can be configured to use boost::charconv by defining CXON_USE_BOOST_CHARCONV.
Note here, that libraries based on polymorphic types have validation and use overhead that should be taken into account.

The memory management is often important. CXON does not allocate in general, it's up to the types provided.
In the example above, the memory management will be handled completely by std::vector and its allocator (whatever it is).
The polymorphic types provided by CXON are also AllocatorAware compliant.

CXON is non-throwing, provided that the serializers involved do not throw.


Contents


Overview

CXON defines and implements an interface similar toC++17's <charconv>.
CXON extends <charconv>'s interface with:

  • traits template parameter (support for different serialization formats, see Format traits)
  • trailing named parameters of arbitrary types (passing of parameters to specific type serializers, see Named parameters
  • input and output iterators for I/O (allowing streams, containers and arrays, see Interface)

The traits can be stateful or stateless allowing arbitrary complex formats.
Named parameters can be compile time or runtime giving flexibility for the implementations.

More about the interface can be found in the MANUAL.

CXON supports good part of C++'s fundamental, compound and standard library types out of the box.
CXON can be extended for arbitrary types, using intrusive and non-intrusive methods.

More details can be found in the MANUAL.


Formats

The implementation strictly complies with RFC8259 / ECMA-404.
CXON/JSON also provides a polymorphic type cxon::json::node, which can represent arbitrary JSON data.

The implementation complies with RFC7049.
CXON/CBOR also provides a polymorphic type cxon::cbor::node, which can represent arbitrary CBOR data.

CXCF is a simple configuration format derived from JSON.


Performance

  • CXON deserialization using the default (<charconv>) floating-point conversion.
    read/native
    read/native

  • CXON serialization using the default (<charconv>) floating-point conversion.
    write/native (default)
    write/native (default)

  • CXON binary size and compilation times.
    space (default)
    space (default)

Information about the benchmarks and additional benchmark results can be found here.

Given the benchmark results and assuming that the libraries CXON is compared to are reasonably well written, it can be said that CXON satisfies the zero-overhead principle.


Compilation

CXON requires C++11 compliant compiler, tested with g++ >= 5, clang++ >= 4.0 and msvc++ >= 19.16 (see the builds).

CXON is using <charconv> for numeric conversions if available.
If not (ex. pre-C++17) a fallback implementation (based on strto* and sprintf) will be used.
If CXON_USE_BOOST_CHARCONV is defined, boost::charconv will be used. This will provide a good performance boost for C++11/14 and some earlier implementations of <charconv>.


Installation

CXON is a header-only library - copy the headers you need, or use the provided makefile to install it on POSIX systems:

$ sudo make install

or run the test suites with:

$ make check

Contributing

Any kind of contribution (feedback, suggestions, code, tests, documentation, etc.) is welcome.
Contact via GitHub (create an issue even it's just a question or comment) or via mail.


Distributed under the MIT license. See LICENSE for more information.
GitHub