JSON

Interfaces for manipulating, validating and conversating data in JSON format.

JSON Serialization and Deserialization

JSON data object abstraction, and interfaces for JSON serialization and deserialization.

This module provides a set of interfaces for interacting with raw JSON data, and converting that data into data objects, and vice versa.

The top level function sneaker::json::parse() takes a JSON blob in string format and returns the parsed JSON object, which is an instance of sneaker::json::JSON.

Internally, instances of sneaker::json::JSON depends on several internal types to encapsulate JSON data of various formats. For example, std::vector is used to capture JSON arrays and std::map is used to encapsulate JSON objects, and so on.

This module is largely based on some of the concepts and implementations borrowed from the open source project “json11” from Dropbox, with minor changes and fixes. Please refer to https://github.com/dropbox/json11 for more information.

Here is an example of parsing a JSON blob into its corresponding data object.

#include <sneaker/json/json.h>
#include <cassert>
#include <iostream>
#include <string>

using namespace sneaker::json;

const std::string str = "{"
  "\"k1\": \"v1\","
  "\"k2\": -42,"
  "\"k3\": [\"a\", 123, true, false, null]"
"}";

auto json = sneaker::json::parse(str);

assert(std::string("\"v1\"") == json["k1"].dump());
assert(std::string("-42") == json["k2"].dump());
assert(std::string("[\"a\", 123, true, false, null]") == json["k3"].dump());

assert(std::string("v1") == json["k1"].string_value());
assert(-42 == json["k2"].number_value());
assert(std::string("a") == json["k3"][0].string_value());
assert(123 == json["k3"][1].number_value());
assert(true == json["k3"][2].bool_value());
assert(false == json["k3"][3].bool_value());

// Conversely, here is an example of serializing a JSON data object:

JSON json = JSON::object {
  { "key1", "value1" },
  { "key2", 123.456 },
  { "key3", false },
  { "key4", JSON::array { 1, "a", true, nullptr } },
};

std::cout << json.dump() << std::endl;

Header file: sneaker/json/json.h

sneaker::json::parse(const std::string &in)

Top level function for parsing a JSON blob and returns the deserialized JSON data object.
class sneaker::json::invalid_json_error

Error thrown when parsing an invalid JSON blob.
class sneaker::json::JSON

type JSON::Type

The type of the JSON object. Values are NUL, NUMBER, BOOL, STRING, ARRAY and OBJECT.

type JSON::string

The underflying JSON string type.

type JSON::array

The underlying JSON array type.

type JSON::object

The underlying JSON object type.

JSON()

Default constructor.

JSON(null)

Constructor.

JSON(double)

Constructor.

JSON(int)

Constructor.

JSON(const string&)

Constructor.

JSON(string&&)

Constructor.

JSON(const char *)

Constructor.

JSON(const array&)

Constructor.

JSON(array&&)

Constructor.

JSON(const object&)

Constructor.

JSON(object&&)

Constructor.

template<class T, class = decltype(&T::to_json)>
JSON(const T &t)

Implicit constructor: anything with a to_json() function.

template<class M, typename std::enable_if<
std::is_constructible<std::string, typename M::key_type>::value &&
std::is_constructible<JSON, typename M::mapped_type>::value, int>::type = 0
>
JSON(const M &m)

Implicit constructor: map-like objects (std::map, std::unordered_map, etc).

template<class V, typename std::enable_if<
std::is_constructible<JSON, typename V::value_type>::value, int>::type = 0
>
JSON(const V &v)

Implicit constructor: vector-like objects (std::list, std::vector, std::set, etc).

Type type() const

Gets the type of the JSON object.

bool is_null()

Determines if this instance represents a JSON null value.

bool is_number()

Determines if this instance represents a JSON numeric value.

bool is_bool()

Determines if this instance represents a JSON boolean value.

bool is_string()

Determines if this instance represents a JSON string value.

bool is_array()

Determines if this instance represents a JSON array value.

bool is_object()

Determines if this instance represents a JSON object value.

double number_value() const

Gets the encapsulating floating numeric value of this JSON object.

int64_t int_value() const

Gets the encapsulating integer numeric value of this JSON object.

bool bool_value() const

Gets the encapsulating boolean value of this JSON object.

const string &string_value() const

Gets the encapsulating string value of this JSON object.

const array &array_items() const

Gets the encapsulating array value of this JSON object.

const object &object_items() const

Gets the encapsulating object value of this JSON object.

const JSON &operator[](size_t i) const

JSON array type element accessor.

const JSON &operator[](const std::string &key) const

JSON object type element accessor.

bool operator==(const JSON &other) const

Equality operator.

bool operator<(const JSON &other) const

Less Than equality operator.

bool operator!=(const JSON &other) const

Inequality operator.

bool operator<=(const JSON &other) const

Less Than or Equal equality operator.

bool operator>(const JSON &other) const

Greater Than equality operator.

bool operator>=(const JSON &other) const

Greater Than or Equal equality operator.

void dump(std::string &out) const

Serializes the JSON data object and dumps the result into the provided string.

std::string dump() const

Serializes the JSON data object and returns the result string.

JSON Schema Validation

Interface for validating JSON blobs using JSON schemas.

The validation mechanisms are implemented based on the JSON Schema Validation specification. More information can be found at:

http://json-schema.org/documentation.html

The implementation is strictly based on the latest specification found at http://json-schema.org/latest/json-schema-validation.html. All features specified in the specification are supported.

Example:

#include <sneaker/json/json.h>
#include <sneaker/json/json_schema.h>
#include <string>

using namespace sneaker::json;

const std::string json_str = "{"
  "\"name\": \"Tomiko Van\","
  "\"age\": 28,"
  "\"interests\": ["
    "music",
    "swimming,"
    "reading"
  "],"
  "\"married\": false,"
  "\"languages\": {"
    "\"Japanese\": \"fluent\","
    "\"Chinese\": \"beginner\","
    "\"English\": \"fluent\""
  "}"
"}";

const std::string schema_str = "{"
  "\"type\": \"object\","
  "\"properties\": {"
    "\"name\": {"
      "\"type\": \"string\","
      "\"maxLength\": 50"
    "},"
    "\"age\": {"
      "\"type\": \"number\","
      "\"minimum\": 0,"
      "\"maximum\": 120"
    "},"
    "\"married\": {"
      "\"type\": \"boolean\""
    "},"
    "\"interests\": {"
      "\"type\": \"array\","
      "\"uniqueItems\": ["
        "\"music\","
        "\"dancing\","
        "\"swimming\","
        "\"reading\""
      "]"
    "},"
    "\"languages\": {"
      "\"type\": \"object\""
    "}"
  "}"
"}";

JSON json = sneaker::json::parse(json_str);
JSON schema = sneaker::json::parse(schema_str);

sneaker::json::json_schema::validate(json, schema);
class sneaker::json::json_validation_error

Error thrown when parsing an JSON schema validation fails.
sneaker::json::json_schema::validate(const JSON&, const JSON&)

Interface for validating a JSON blob with a specified JSON schema. The first argument is the JSON blob to be validated, and the second argument is the JSON schema. The JSON schema passed in must be valid, as no validation is performed on the schema object itself, and an invalid schema will cause undefined behaviors during validation.

If validation is successful, nothing happens. Otherwise an instance of json_validation_error is thrown.