Corrade::Utility::Json class new in Git master

JSON parser.

Tokenizes a JSON file together with optional parsing of selected token subtrees. Supports files over 4 GB and parsing of numeric values into 32-bit floating-point, 32-bit and 52-/53-bit unsigned and signed integer types in addition to the general 64-bit floating-point representation.

To optimize for parsing performance and minimal memory usage, the parsed tokens are contained in a single contiguous allocation and form an immutable view on the input JSON string. As the intended usage is sequential processing of chosen parts of the file, there's no time spent building any acceleration structures for fast lookup of keys and array indices — if that's desired, users are encouraged to build them on top of the parsed output.

The JsonWriter class provides a write-only counterpart for saving a JSON file.

Usage

The following snippet opens a very minimal glTF file, parses it including unescaping strings and converting numbers to floats, and accesses the known properties:

{
  "asset": {
    "version": "2.0"
  },
  "nodes": [
    ,
    {
      "name": "Fox",
      "mesh": 5
    }
  ]
}
Containers::Optional<Utility::Json> gltf =
    Utility::Json::fromFile("scene.gltf",
        Utility::Json::Option::ParseLiterals|
        Utility::Json::Option::ParseFloats|
        Utility::Json::Option::ParseStrings);
if(!gltf)
    Utility::Fatal{} << "Whoops!";

const Utility::JsonToken& gltfNode = gltf->root()["nodes"][i];
Utility::Debug{}
    << "Node" << i << "is named" << gltfNode["name"].asString()
    << "and has a mesh" << gltfNode["mesh"].asFloat();

The above — apart from handling a parsing failure — assumes that the node i we're looking for exists in the file and contains the properties we want. But that might not always be the case and so it could assert if we'd ask for something that's not there. This is how it would look with JsonToken::find() used instead of JsonToken::operator[]():

const Utility::JsonToken *gltfNodes, *gltfNode;
if(!(gltfNodes = gltf->root().find("nodes")) || !(gltfNode = gltfNodes->find(i)))
    Utility::Fatal{} << "Node" << i << "is not in the file";

if(const Utility::JsonToken* gltfName = gltfNode->find("name"))
    Utility::Debug{} << "Node" << i << "is named" << gltfName->asString();

if(const Utility::JsonToken* gltfMesh = gltfNode->find("mesh"))
    Utility::Debug{} << "Node" << i << "has a mesh" << gltfMesh->asFloat();

Selective parsing

As shown above, the Option values passed to fromFile() or fromString() cause the file to get fully parsed upfront including number conversion and string unescaping. While that's a convenient behavior that makes sense when consuming the whole file, doing all that might be unnecessary when you only need to access a small portion of a large file. In the following snippet, all literals and string keys get parsed upfront so objects and arrays can be searched, but then we parse only contents of the particular node using parseStrings() and parseFloats():

Containers::Optional<Utility::Json> gltf = Utility::Json::fromFile("scene.gltf",
    Utility::Json::Option::ParseLiterals|
    Utility::Json::Option::ParseStringKeys);

const Utility::JsonToken* gltfNode = ;
if(!gltfNode || !gltf->parseStrings(*gltfNode) || !gltf->parseFloats(*gltfNode))
    Utility::Fatal{} << "Invalid node" << i;

This way we also have a greater control over parsed numeric types. Instead of parsing everything as a float using Option::ParseFloats or parseFloats(), we can parse values that are meant to be integers using parseUnsignedInts(), parseInts() etc., enforcing a desired numeric type on a particular subset of the document. Which means, if the mesh ID in the following snippet has a fractional part or is negative, we get an error:

if(const Utility::JsonToken* gltfMesh = gltfNode->find("mesh")) {
    if(!gltf->parseUnsignedInts(*gltfMesh))
        Utility::Fatal{} << "Invalid node" << i << "mesh reference";

    Utility::Debug{} << "Node" << i << "has a mesh" << gltfMesh->asUnsignedInt();
}

Finally, while a JSON number is defined to be of a double type, often the full precision is not needed and so we parsed everything as floats. If the precision indeed is important, you can switch to Option::ParseDoubles / parseDoubles() instead where needed.

Checked selective parsing

At this point, the code can handle variations in valid glTF files, but isn't immune from files that don't follow the spec — for example where the root element is not an object, or a name isn't a string. Those would still cause the find() and as*() APIs to assert.

If we omit all Parse* Options in fromString() / fromFile(), the instance will behave as if nothing was parsed yet. Thus any call to JsonToken::operator[](), JsonToken::asString(), JsonToken::asFloat() etc. will assert unless given token was explicitly previously checked and parsed using parseObject(), parseArray(), parseString(), parseFloat() etc. That ensures there are no accidental hardcoded assumptions about the layout of the file:

Containers::Optional<Utility::Json> gltf = Utility::Json::fromFile("scene.gltf");

if(!gltf->parseObject(gltf->root()))
    Utility::Fatal{} << "Can't parse glTF root";

const Utility::JsonToken* gltfNodes = gltf->root().find("nodes");
if(!gltfNodes || !gltf->parseArray(*gltfNodes))
    Utility::Fatal{} << "Missing or invalid nodes array";

const Utility::JsonToken* gltfNode = gltfNodes->find(i);
if(!gltfNode || !gltf->parseObject(*gltfNode))
    Utility::Fatal{} << "Missing or invalid node" << i;

if(const Utility::JsonToken* gltfName = gltfNode->find("name")) {
    if(Containers::Optional<Containers::StringView> s = gltf->parseString(*gltfName))
        Utility::Debug{} << "Node" << i << "is named" << *s;
    else
        Utility::Fatal{} << "Invalid node" << i << "name";
}

if(const Utility::JsonToken* gltfMesh = gltfNode->find("mesh")) {
    if(Containers::Optional<unsigned> n = gltf->parseUnsignedInt(*gltfMesh))
        Utility::Debug{} << "Node" << i << "has a mesh" << *n;
    else
        Utility::Fatal{} << "Invalid node" << i << "mesh reference";
}

A possibly non-obvious side-effect of using various parse*() APIs instead of checking JsonToken::type() yourself is that if they fail, they will print a detailed error message about what exactly failed and where — including file, line and column info.

Iterating objects and arrays

So far, we only accessed object and array elements by a concrete key or an index. Because the internal representation is optimized for linear consumption rather than lookup by keys or values, those are $ \mathcal{O}(n) $ operations. If the whole file is being consumed, a more efficient way may be iterating over object and array contents using JsonToken::asObject() and asArray() and building your own representation from these instead:

struct Node {
    Containers::StringView name;
    unsigned mesh;
};
Containers::Array<Node> nodes;

for(Utility::JsonArrayItem gltfNode: gltfNodes->asArray()) {
    Utility::Debug{} << "Parsing node" << gltfNode.index();

    Node node;
    for(Utility::JsonObjectItem gltfNodeProperty: gltfNode.value().asObject()) {
        if(gltfNodeProperty.key() == "name")
            node.name = gltfNodeProperty.value().asString();
        else if(gltfNodeProperty.key() == "mesh")
            node.mesh = gltfNodeProperty.value().asFloat();
        
    }

    arrayAppend(nodes, node);
}

Both JsonObjectItem and JsonArrayItem is implicitly convertible to a JsonToken reference, giving back either the object key (of which the value is JsonToken::firstChild()) or array value.

Containers::Array<Containers::Reference<const Utility::JsonToken>> gltfNodeMap;
for(const Utility::JsonToken& gltfNode: gltfNodes->asArray())
    arrayAppend(gltfNodeMap, gltfNode);

Direct access to arrays

Besides high-level array iteration, there's also a set of functions for accessing homogeneous arrays. Coming back to the glTF format, for example a node translation vector and child indices:

{
  "translation": [1.5, -0.5, 2.3],
  "children": [2, 3, 4, 17, 399]
}

We'll check, parse and access the first property with parseFloatArray() and the other with parseUnsignedIntArray() — those will check that it's indeed an array and that it contains either all floats or all unsigned integers. If everything passes, we get back a Containers::StridedArrayView, pointing to parsed data stored inside the token elements, or we get an error message and Containers::NullOpt if not. A view to the parsed array can be also retrieved later using JsonToken::asFloatArray() and others, assuming the parsed type matches.

Containers::Optional<Containers::StridedArrayView1D<const float>> translation;
if(const Utility::JsonToken* gltfNodeTranslation = gltfNode.find("translation"))
    if(!(translation = gltf->parseFloatArray(*gltfNodeTranslation, 3)))
        Utility::Fatal{} << "Node translation is not a 3-component float vector";

Containers::Optional<Containers::StridedArrayView1D<const unsigned>> children;
if(const Utility::JsonToken* gltfNodeChildren = gltfNode.find("children"))
    if(!(children = gltf->parseUnsignedIntArray(*gltfNodeChildren)))
        Utility::Fatal{} << "Node children is not an index list";

// use the translation and children arrays …

This feature isn't limited to just numeric arrays — for booleans there's parseBitArray() returning a Containers::StridedBitArrayView1D and for strings there's parseStringArray() returning a Containers::StringIterable. Both again point to data stored elsewhere without unnecessary copies.

Tokenization and parsing process

The class expects exactly one top-level JSON value, be it an object, array, literal, number or a string.

The tokenization process is largely inspired by jsmn — the file gets processed to a flat list of JsonToken instances, where each literal, number, string (or a string object key), object and array is one token, ordered in a depth-first manner. Whitespace is skipped and not present in the parsed token list. JsonToken::data() is a view on the input string that defines the token, with the range containing also all nested tokens for objects and arrays. JsonToken::type() is then implicitly inferred from the first byte of the token, but no further parsing or validation of actual token values is done during the initial tokenization.

This allows the application to reduce the initial processing time and memory footprint. Token parsing is a subsequent step, parsing the string range of a token as a literal, converting it to a number or interpreting string escape sequences. This step can then fail on its own, for example when an invalid literal value is encountered, when a Unicode escape is out of range or when a parsed integer doesn't fit into the output type size.

Token hierarchy is defined as the following — object tokens have string keys as children, string keys have object values as children, arrays have array values as children and values themselves have no children. As implied by the depth-first ordering, the first child token (if any) is ordered right after its parent token, and together with JsonToken::childCount(), which is the count of all nested tokens, it's either possible to dive into the child token tree using JsonToken::firstChild() or JsonToken::children() or skip after the child token tree using JsonToken::next().

Internal representation

If the string passed to fromString() is Containers::StringViewFlag::Global, it's just referenced without an internal copy, and all token data will point to it as well. Otherwise, or if fromFile() is used, a local copy is made, and tokens point to the copy instead.

A JsonToken is 16 bytes on 32-bit systems and 24 bytes on 64-bit systems, containing view pointer, size and child count. When a literal or numeric value is parsed, it's stored inside. Simply put, the representation exploits the fact that a token either has children or is a value, but never both. For strings the general assumption is that most of them (and especially object keys) don't contain any escape characters and thus can be returned as views on the input string. Strings containing escape characters are allocated separately, either upfront if Option::ParseStrings is set (or if Option::ParseStringKeys is set and object keys contain escaped values), or on-demand if parseStrings() / parseStringKeys() / parseString() is used.

Public types

enum class Option { ParseLiterals = 1 << 0, ParseDoubles = 1 << 1, ParseFloats = 1 << 2, ParseStringKeys = 1 << 3, ParseStrings = ParseStringKeys|(1 << 4) }
Parsing option.
using Options = Containers::EnumSet<Option>
Parsing options.

Public static functions

static auto fromString(Containers::StringView string, Options options = {}, Containers::StringView filename = {}, std::size_t lineOffset = 0, std::size_t columnOffset = 0) -> Containers::Optional<Json>
Parse a JSON string.
static auto fromString(Containers::StringView string, Containers::StringView filename, std::size_t lineOffset = 0, std::size_t columnOffset = 0) -> Containers::Optional<Json>
static auto fromFile(Containers::StringView filename, Options options = {}) -> Containers::Optional<Json>
Parse a JSON file.

Constructors, destructors, conversion operators

Json(const Json&) deleted
Copying is not allowed.
Json(Json&&) noexcept
Move constructor.

Public functions

auto operator=(const Json&) -> Json& deleted
Copying is not allowed.
auto operator=(Json&&) -> Json& noexcept
Move assignment.
auto tokens() const -> Containers::ArrayView<const JsonToken>
Parsed JSON tokens.
auto root() const -> const JsonToken&
Root JSON token.
auto parseLiterals(const JsonToken& token) -> bool
Parse objects, arrays, null, true and false values in given token tree.
auto parseDoubles(const JsonToken& token) -> bool
Parse numbers in given token tree as 64-bit floating-point values.
auto parseFloats(const JsonToken& token) -> bool
Parse numbers in given token tree as 32-bit floating-point values.
auto parseUnsignedInts(const JsonToken& token) -> bool
Parse numbers in given token tree as unsigned 32-bit integer values.
auto parseInts(const JsonToken& token) -> bool
Parse numbers in given token tree as signed 32-bit integer values.
auto parseUnsignedLongs(const JsonToken& token) -> bool
Parse numbers in given token tree as unsigned 52-bit integer values.
auto parseLongs(const JsonToken& token) -> bool
Parse numbers in given token tree as signed 53-bit integer values.
auto parseSizes(const JsonToken& token) -> bool
Parse numbers in given token tree as size values.
auto parseStringKeys(const JsonToken& token) -> bool
Parse string keys in given token tree.
auto parseStrings(const JsonToken& token) -> bool
Parse strings in given token tree.
auto parseObject(const JsonToken& token) -> Containers::Optional<JsonObjectView>
Check and parse an object token.
auto parseArray(const JsonToken& token) -> Containers::Optional<JsonArrayView>
Check and parse an array token.
auto parseNull(const JsonToken& token) -> Containers::Optional<std::nullptr_t>
Check and parse a null token.
auto parseBool(const JsonToken& token) -> Containers::Optional<bool>
Check and parse a boolean token.
auto parseDouble(const JsonToken& token) -> Containers::Optional<double>
Check and parse a 64-bit floating-point token.
auto parseFloat(const JsonToken& token) -> Containers::Optional<float>
Check and parse a 32-bit floating-point token.
auto parseUnsignedInt(const JsonToken& token) -> Containers::Optional<std::uint32_t>
Check and parse an unsigned 32-bit integer token.
auto parseInt(const JsonToken& token) -> Containers::Optional<std::int32_t>
Check and parse a signed 32-bit integer token.
auto parseUnsignedLong(const JsonToken& token) -> Containers::Optional<std::uint64_t>
Check and parse an unsigned 52-bit integer token.
auto parseLong(const JsonToken& token) -> Containers::Optional<std::int64_t>
Check and parse a signed 53-bit integer token.
auto parseSize(const JsonToken& token) -> Containers::Optional<std::size_t>
Check and parse a size token.
auto parseString(const JsonToken& token) -> Containers::Optional<Containers::StringView>
Check and parse a string token.
auto parseBitArray(const JsonToken& token, std::size_t expectedSize = 0) -> Containers::Optional<Containers::StridedBitArrayView1D>
Check and parse a bit array.
auto parseBoolArray(const JsonToken& token, std::size_t expectedSize = 0) -> Containers::Optional<Containers::StridedArrayView1D<const bool>> deprecated in Git master
Check and parse a boolean array.
auto parseDoubleArray(const JsonToken& token, std::size_t expectedSize = 0) -> Containers::Optional<Containers::StridedArrayView1D<const double>>
Check and parse a 64-bit floating-point array.
auto parseFloatArray(const JsonToken& token, std::size_t expectedSize = 0) -> Containers::Optional<Containers::StridedArrayView1D<const float>>
Check and parse a 32-bit floating-point array.
auto parseUnsignedIntArray(const JsonToken& token, std::size_t expectedSize = 0) -> Containers::Optional<Containers::StridedArrayView1D<const std::uint32_t>>
Check and parse an unsigned 32-bit integer array.
auto parseIntArray(const JsonToken& token, std::size_t expectedSize = 0) -> Containers::Optional<Containers::StridedArrayView1D<const std::int32_t>>
Check and parse a signed 32-bit integer array.
auto parseUnsignedLongArray(const JsonToken& token, std::size_t expectedSize = 0) -> Containers::Optional<Containers::StridedArrayView1D<const std::uint64_t>>
Check and parse an unsigned 52-bit integer array.
auto parseLongArray(const JsonToken& token, std::size_t expectedSize = 0) -> Containers::Optional<Containers::StridedArrayView1D<const std::int64_t>>
Check and parse a signed 52-bit integer array.
auto parseSizeArray(const JsonToken& token, std::size_t expectedSize = 0) -> Containers::Optional<Containers::StridedArrayView1D<const std::size_t>>
Check and parse a size array.
auto parseStringArray(const JsonToken& token, std::size_t expectedSize = 0) -> Containers::Optional<Containers::StringIterable>
Check and parse a string array.

Enum documentation

enum class Corrade::Utility::Json::Option

Parsing option.

Enumerators
ParseLiterals

Parse objects, arrays, null, true and false values. Causes all JsonToken instances of JsonToken::Type::Object, Array, Null and Bool to have JsonToken::isParsed() set and be accessible through JsonToken::asObject(), asArray(), operator[](std::size_t) const, find(std::size_t) const, asNull() and asBool().

Invalid values will cause fromString() / fromFile() to print an error and return Containers::NullOpt. This operation can be also performed selectively later using parseLiterals(), or directly for particular tokens using parseObject(), parseArray(), parseNull() or parseBool().

Note that using JsonToken::operator[](Containers::StringView) const, JsonToken::find(Containers::StringView) const or accessing JsonObjectItem::key() requires object keys to be parsed as well — either with parseStringKeys(), Option::ParseStringKeys during the initial call or with parseObject() that parses both an object and its keys.

ParseDoubles

Parse all numbers as 64-bit floating-point values. Causes all JsonToken instances of JsonToken::Type::Number to become JsonToken::ParsedType::Double and be accessible through JsonToken::asDouble(). If both Option::ParseDoubles and Option::ParseFloats is specified, Option::ParseDoubles gets a precedence.

Invalid values will cause fromString() / fromFile() to exit with a parse error. This operation can be also performed selectively later using parseDoubles(), or directly for particular tokens using parseDouble().

While this option is guaranteed to preserve the full precision of JSON numeric literals, often you may need only 32-bit precision — use Option::ParseFloats in that case instead. It's also possible to selectively parse certain values as integers using parseUnsignedInts(), parseInts(), parseUnsignedLongs(), parseLongs() or parseSizes(), then the parsing will also check that the value is an (unsigned) integer and can be represented in given type size. There's no corresponding Option for those, as JSON files rarely contain just integer numbers alone. If you indeed have an integer-only file, call those directly on root().

ParseFloats

Parse all numbers as 32-bit floating-point values. Causes all JsonToken instances of JsonToken::Type::Number to become JsonToken::ParsedType::Float and be accessible through JsonToken::asFloat(). If both Option::ParseDoubles and Option::ParseFloats is specified, Option::ParseDoubles gets a precedence.

Invalid values will cause fromString() / fromFile() to exit with a parse error. This operation can be also performed selectively later using parseFloats(), or directly for particular tokens using parseFloat().

While 32-bit float precision is often enough, sometimes you might want to preserve the full precision of JSON numeric literals — use Option::ParseDoubles in that case instead. It's also possible to selectively parse certain values as integers using parseUnsignedInts(), parseInts(), parseUnsignedLongs(), parseLongs() or parseSizes(), then the parsing will also check that the value is an (unsigned) integer and can be represented in given type size. There's no corresponding Option for those, as JSON files rarely contain just integer numbers alone. If you indeed have an integer-only file, call those directly on root().

ParseStringKeys

Parse object key strings by processing all escape sequences and caching the parsed result (or marking the original string as parsed in-place, if it has no escape sequences). Causes JsonToken instances of JsonToken::Type::String that are children of a JsonToken::Type::Object to have JsonToken::isParsed() set and be accessible through JsonToken::asString(). String values (as opposed to keys) are left untouched, thus this is useful if you need to perform a key-based search, but don't need to have also all other strings unescaped.

Invalid values will cause fromString() / fromFile() to exit with a parse error. This operation can be also performed selectively later using parseStringKeys(), or directly for particular tokens using parseString().

ParseStrings

Parse string values by processing all escape sequences and caching the parsed result (or marking the original string as parsed in-place, if it has no escape sequences). Causes all JsonToken instances of JsonToken::Type::String to have JsonToken::isParsed() set and be accessible through JsonToken::asString(). Implies Option::ParseStringKeys.

Invalid values will cause fromString() / fromFile() to exit with a parse error. This operation can be also performed selectively later using parseStrings(), or directly for particular tokens using parseString().

Typedef documentation

typedef Containers::EnumSet<Option> Corrade::Utility::Json::Options

Parsing options.

Function documentation

static Containers::Optional<Json> Corrade::Utility::Json::fromString(Containers::StringView string, Options options = {}, Containers::StringView filename = {}, std::size_t lineOffset = 0, std::size_t columnOffset = 0)

Parse a JSON string.

Parameters
string JSON string to parse
options Parsing options
filename Filename to use for error reporting. If not set, <in> is printed in error messages.
lineOffset Initial line offset in the file for error reporting
columnOffset Initial column offset in the file for error reporting

By default performs only tokenization, not parsing any literals. Use options to enable parsing of particular token types as well. If a tokenization or parsing error happens, prints a message to Error and returns Containers::NullOpt.

If the string is Containers::StringViewFlag::Global, the parsed tokens will reference it, returning also global string literals. Otherwise a copy is made internally.

The filename, lineOffset and columnOffset parameters have no effect on actual parsing and are used only to enhance error messages. Line offset is added to the reported line always but column offset is used only if the happens on the first line of the JSON string, errors on subsequent lines are reported without the initial column offset.

static Containers::Optional<Json> Corrade::Utility::Json::fromString(Containers::StringView string, Containers::StringView filename, std::size_t lineOffset = 0, std::size_t columnOffset = 0)

This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts.

static Containers::Optional<Json> Corrade::Utility::Json::fromFile(Containers::StringView filename, Options options = {})

Parse a JSON file.

By default performs only tokenization, not parsing any literals. Use options to enable parsing of particular token types as well. If the file can't be read, or a tokenization or parsing error happens, prints a message to Error and returns Containers::NullOpt.

Containers::ArrayView<const JsonToken> Corrade::Utility::Json::tokens() const

Parsed JSON tokens.

The first token is the root token (also accessible via root()) and is always present, the rest is ordered in a depth-first manner as described in Tokenization and parsing process.

const JsonToken& Corrade::Utility::Json::root() const

Root JSON token.

Always present. Tts JsonToken::children() (if any) contain the whole document ordered in a depth-first manner as described in Tokenization and parsing process.

bool Corrade::Utility::Json::parseLiterals(const JsonToken& token)

Parse objects, arrays, null, true and false values in given token tree.

Causes all JsonToken instances of JsonToken::Type::Object, Array, Null and Bool to have JsonToken::isParsed() set and be accessible through JsonToken::asObject(), asArray(), operator[](std::size_t) const, find(std::size_t) const, asNull() and asBool(). Tokens of other types and tokens that are already parsed are skipped. If an invalid value is encountered, prints a message to Error and returns false. Expects that token references a token owned by this instance.

Passing root() as token has the same effect as Option::ParseLiterals specified during the initial fromString() or fromFile() call. Checking a single token for an object, array, null or boolean type and parsing it as can be done using parseObject(), parseArray(), parseNull() or parseBool().

Note that using JsonToken::operator[](Containers::StringView) const, JsonToken::find(Containers::StringView) const or accessing JsonObjectItem::key() requires object keys to be parsed as well — either with parseStringKeys(), Option::ParseStringKeys during the initial call or with parseObject() that parses both an object and its keys.

bool Corrade::Utility::Json::parseDoubles(const JsonToken& token)

Parse numbers in given token tree as 64-bit floating-point values.

Causes all JsonToken instances of JsonToken::Type::Number in token and its children to become JsonToken::ParsedType::Double and be accessible through JsonToken::asDouble(). Non-numeric tokens and numeric tokens that are already parsed as doubles are skipped, numeric tokens parsed as other types are reparsed. If an invalid value is encountered, prints a message to Error and returns false. Expects that token references a token owned by this instance.

Passing root() as token has the same effect as Option::ParseDoubles specified during the initial fromString() or fromFile() call. Checking a single token for a numeric type and parsing it as a doouble can be done using parseDouble().

bool Corrade::Utility::Json::parseFloats(const JsonToken& token)

Parse numbers in given token tree as 32-bit floating-point values.

Causes all JsonToken instances of JsonToken::Type::Number in token and its children to become JsonToken::ParsedType::Float and be accessible through JsonToken::asFloat(). Non-numeric tokens and numeric tokens that are already parsed as floats are skipped, numeric tokens parsed as other types are reparsed. If an invalid value is encountered, prints a message to Error and returns false. Expects that token references a token owned by this instance.

Passing root() as token has the same effect as Option::ParseFloats specified during the initial fromString() or fromFile() call. Checking a single token for a numeric type and parsing it as a float can be done using parseFloat().

bool Corrade::Utility::Json::parseUnsignedInts(const JsonToken& token)

Parse numbers in given token tree as unsigned 32-bit integer values.

Causes all JsonToken instances of JsonToken::Type::Number in token and its children to become JsonToken::ParsedType::UnsignedInt and be accessible through JsonToken::asUnsignedInt(). Non-numeric tokens and numeric tokens that are already parsed as unsigned int are skipped, numeric tokens parsed as other types are reparsed. If an invalid value, a literal with a fractional or exponent part or a negative value is encountered or a value doesn't fit into a 32-bit representation, prints a message to Error and returns false. Expects that token references a token owned by this instance.

Checking a single token for a numeric type and parsing it as an unsigned int can be done using parseUnsignedInt().

bool Corrade::Utility::Json::parseInts(const JsonToken& token)

Parse numbers in given token tree as signed 32-bit integer values.

Causes all JsonToken instances of JsonToken::Type::Number in token and its children to become JsonToken::ParsedType::Int and be accessible through JsonToken::asInt(). Non-numeric tokens and numeric tokens that are already parsed as int are skipped, numeric tokens parsed as other types are reparsed. If an invalid value, a literal with a fractional or exponent part is encountered or a value doesn't fit into a 32-bit representation, prints a message to Error and returns false. Expects that token references a token owned by this instance.

Checking a single token for a numeric type and parsing it as an int can be done using parseUnsignedInt().

bool Corrade::Utility::Json::parseUnsignedLongs(const JsonToken& token)

Parse numbers in given token tree as unsigned 52-bit integer values.

Causes all JsonToken instances of JsonToken::Type::Number in token and its children to become JsonToken::ParsedType::UnsignedLong and be accessible through JsonToken::asUnsignedLong(). Non-numeric tokens and numeric tokens that are already parsed as unsigned long are skipped, numeric tokens parsed as other types are reparsed. If an invalid value, a literal with a fractional or exponent part or a negative value is encountered or a value doesn't fit into 52 bits (which is the representable unsigned integer range in a JSON), prints a message to Error and returns false. Expects that token references a token owned by this instance.

Checking a single token for a numeric type and parsing it as an unsigned long can be done using parseUnsignedInt().

bool Corrade::Utility::Json::parseLongs(const JsonToken& token)

Parse numbers in given token tree as signed 53-bit integer values.

Causes all JsonToken instances of JsonToken::Type::Number in token and its children to become JsonToken::ParsedType::Long and be accessible through JsonToken::asLong(). Non-numeric tokens and numeric tokens that are already parsed as long are skipped, numeric tokens parsed as other types are reparsed. If an invalid value, a literal with a fractional or exponent part is encountered or a value doesn't fit into 53 bits (which is the representable signed integer range in a JSON), prints a message to Error and returns false. Expects that token references a token owned by this instance.

Checking a single token for a numeric type and parsing it as a long can be done using parseLong().

bool Corrade::Utility::Json::parseSizes(const JsonToken& token)

Parse numbers in given token tree as size values.

Convenience function that calls into parseUnsignedInts() on 32-bit targets and into parseUnsignedLongs() on 64-bit. Besides being available under the concrete types as documented in these functions, JsonToken instances of JsonToken::Type::Number in token and its children will alias to JsonToken::ParsedType::Size and be also accessible through JsonToken::asSize().

Checking a single token for a numeric type and parsing it as a size can be done using parseSize().

bool Corrade::Utility::Json::parseStringKeys(const JsonToken& token)

Parse string keys in given token tree.

Causes all JsonToken instances of JsonToken::Type::String that are children of a JsonToken::Type::Object in token and its children to have JsonToken::isParsed() set and be accessible through JsonToken::asString(). The operation is a subset of parseStringKeys(). Non-string tokens, string tokens that are not object keys and string tokens that are already parsed are skipped. If an invalid value is encountered, prints a message to Error and returns false. Expects that token references a token owned by this instance.

Passing root() as token has the same effect as Option::ParseStringKeys specified during the initial fromString() or fromFile() call. Checking a single token for a string type and parsing it can be done using parseString().

bool Corrade::Utility::Json::parseStrings(const JsonToken& token)

Parse strings in given token tree.

Causes all JsonToken instances of JsonToken::Type::String in token and its children to have JsonToken::isParsed() set and be accessible through JsonToken::asString(). The operation is a superset of parseStringKeys(). Non-string tokens and string tokens that are already parsed are skipped. If an invalid value is encountered, prints a message to Error and returns false. Expects that token references a token owned by this instance.

Passing root() as token has the same effect as Option::ParseStrings specified during the initial fromString() or fromFile() call. Checking a single token for a string type and parsing it can be done using parseString().

Containers::Optional<JsonObjectView> Corrade::Utility::Json::parseObject(const JsonToken& token)

Check and parse an object token.

If token is not a JsonToken::Type::Object or does not have valid string values in its keys, prints a message to Error and returns Containers::NullOpt. If JsonToken::isParsed() is already set on the object and all its keys, returns the object view directly, otherwise caches the parsed results first. Expects that token references a token owned by this instance.

Containers::Optional<JsonArrayView> Corrade::Utility::Json::parseArray(const JsonToken& token)

Check and parse an array token.

If token is not a JsonToken::Type::Array, prints a message to Error and returns false. If JsonToken::isParsed() is already set on the array, returns the array view directly, otherwise marks it as parsed first. Expects that token references a token owned by this instance.

Containers::Optional<std::nullptr_t> Corrade::Utility::Json::parseNull(const JsonToken& token)

Check and parse a null token.

If token is not a JsonToken::Type::Null or is not a valid null value, prints a message to Error and returns Containers::NullOpt. If JsonToken::isParsed() is already set, returns the cached value, otherwise caches the parsed result. Expects that token references a token owned by this instance.

Containers::Optional<bool> Corrade::Utility::Json::parseBool(const JsonToken& token)

Check and parse a boolean token.

If token is not a JsonToken::Type::Bool or is not a valid boolean value, prints a message to Error and returns Containers::NullOpt. If JsonToken::isParsed() is already set, returns the cached value, otherwise caches the parsed result. Expects that token references a token owned by this instance.

Containers::Optional<double> Corrade::Utility::Json::parseDouble(const JsonToken& token)

Check and parse a 64-bit floating-point token.

If token is not a JsonToken::Type::Number or is not a valid numeric value, prints a message to Error and returns Containers::NullOpt. If the token is already parsed as JsonToken::ParsedType::Double, returns the cached value, otherwise caches the parsed result. Expects that token references a token owned by this instance.

Containers::Optional<float> Corrade::Utility::Json::parseFloat(const JsonToken& token)

Check and parse a 32-bit floating-point token.

If token is not a JsonToken::Type::Number or is not a valid numeric value, prints a message to Error and returns Containers::NullOpt. Precision that doesn't fit into the 32-bit floating-point representation is truncated, use parseDouble() to get the full precision. If the token is already parsed as JsonToken::ParsedType::Float, returns the cached value, otherwise caches the parsed result. Expects that token references a token owned by this instance.

Containers::Optional<std::uint32_t> Corrade::Utility::Json::parseUnsignedInt(const JsonToken& token)

Check and parse an unsigned 32-bit integer token.

If token is not a JsonToken::Type::Number, is not a valid numeric value, has a fractional or exponent part, is negative or doesn't fit into a 32-bit representation, prints a message to Error and returns Containers::NullOpt. If the token is already parsed as JsonToken::ParsedType::UnsignedInt, returns the cached value, otherwise caches the parsed result. Expects that token references a token owned by this instance.

Containers::Optional<std::int32_t> Corrade::Utility::Json::parseInt(const JsonToken& token)

Check and parse a signed 32-bit integer token.

If token is not a JsonToken::Type::Number, is not a valid numeric value, has a fractional or exponent part or doesn't fit into a 32-bit representation, prints a message to Error and returns Containers::NullOpt. If the token is already parsed as JsonToken::ParsedType::Int, returns the cached value, otherwise caches the parsed result. Expects that token references a token owned by this instance.

Containers::Optional<std::uint64_t> Corrade::Utility::Json::parseUnsignedLong(const JsonToken& token)

Check and parse an unsigned 52-bit integer token.

If token is not a JsonToken::Type::Number, is not a valid numeric value, has a fractional or exponent part, is negative or doesn't fit into 52 bits (which is the representable unsigned integer range in a JSON), prints a message to Error and returns Containers::NullOpt. If the token is already parsed as JsonToken::ParsedType::UnsignedLong, returns the cached value, otherwise caches the parsed result. Expects that token references a token owned by this instance.

Containers::Optional<std::int64_t> Corrade::Utility::Json::parseLong(const JsonToken& token)

Check and parse a signed 53-bit integer token.

If token is not a JsonToken::Type::Number, is not a valid nnumeric value, has a fractional or exponent part or doesn't fit into 53 bits (which is the representable signed integer range in a JSON), prints a message to Error and returns Containers::NullOpt. If the token is already parsed as JsonToken::ParsedType::Long, returns the cached value, otherwise caches the parsed result. Expects that token references a token owned by this instance.

Containers::Optional<std::size_t> Corrade::Utility::Json::parseSize(const JsonToken& token)

Check and parse a size token.

Convenience function that calls into parseUnsignedInt() on 32-bit targets and into parseUnsignedLong() on 64-bit. If the token is already parsed as JsonToken::ParsedType::Size, returns the cached value, otherwise caches the parsed result. Expects that token references a token owned by this instance.

Containers::Optional<Containers::StringView> Corrade::Utility::Json::parseString(const JsonToken& token)

Check and parse a string token.

If token is not a JsonToken::Type::String or is not a valid string value, prints a message to Error and returns Containers::NullOpt. If JsonToken::isParsed() is already set, returns the cached value, otherwise caches the parsed result. Expects that token references a token owned by this instance. If fromString() was called with a global literal and the string didn't contain any escape sequences, the returned view has Containers::StringViewFlag::Global set. If not, the view points to data owned by this instance.

Containers::Optional<Containers::StridedBitArrayView1D> Corrade::Utility::Json::parseBitArray(const JsonToken& token, std::size_t expectedSize = 0)

Check and parse a bit array.

If token is not a JsonToken::Type::Array, doesn't contain just JsonToken::Type::Bool tokens, the tokens are not valid boolean values, or expectedSize is not 0 and the array has different size, prints a message to Error and returns Containers::NullOpt. If JsonToken::isParsed() is already set for the array and all tokens inside, returns the cached values, otherwise caches the parsed results. Expects that token references a token owned by this instance, the returned view points to data owned by this instance.

Containers::Optional<Containers::StridedArrayView1D<const bool>> Corrade::Utility::Json::parseBoolArray(const JsonToken& token, std::size_t expectedSize = 0)

Check and parse a boolean array.

Containers::Optional<Containers::StridedArrayView1D<const double>> Corrade::Utility::Json::parseDoubleArray(const JsonToken& token, std::size_t expectedSize = 0)

Check and parse a 64-bit floating-point array.

If token is not a JsonToken::Type::Array, doesn't contain just JsonToken::Type::Number tokens, the tokens are not valid numeric values, or expectedSize is not 0 and the array has different size, prints a message to Error and returns Containers::NullOpt. If JsonToken::isParsed() is already set for the array and all tokens inside are already parsed as JsonToken::ParsedType::Double, returns the cached values, otherwise caches the parsed results. Expects that token references a token owned by this instance, the returned view points to data owned by this instance.

Containers::Optional<Containers::StridedArrayView1D<const float>> Corrade::Utility::Json::parseFloatArray(const JsonToken& token, std::size_t expectedSize = 0)

Check and parse a 32-bit floating-point array.

If token is not a JsonToken::Type::Array, doesn't contain just JsonToken::Type::Number tokens, the tokens are not valid numeric values, or expectedSize is not 0 and the array has different size, prints a message to Error and returns Containers::NullOpt. Precision that doesn't fit into the 32-bit floating-point representation is truncated, use parseDoubleArray() to get the full precision. If JsonToken::isParsed() is already set for the array and all tokens inside are already parsed as JsonToken::ParsedType::Float, returns the cached values, otherwise caches the parsed results. Expects that token references a token owned by this instance, the returned view points to data owned by this instance.

Containers::Optional<Containers::StridedArrayView1D<const std::uint32_t>> Corrade::Utility::Json::parseUnsignedIntArray(const JsonToken& token, std::size_t expectedSize = 0)

Check and parse an unsigned 32-bit integer array.

If token is not a JsonToken::Type::Array, doesn't contain just JsonToken::Type::Number tokens, the tokens are not valid numeric values, have a fractional or exponent part, are negative or don't fit into a 32-bit representation, or expectedSize is not 0 and the array has different size, prints a message to Error and returns Containers::NullOpt. If JsonToken::isParsed() is already set for the array and all tokens inside are already parsed as JsonToken::ParsedType::UnsignedInt, returns the cached values, otherwise caches the parsed results. Expects that token references a token owned by this instance, the returned view points to data owned by this instance.

Containers::Optional<Containers::StridedArrayView1D<const std::int32_t>> Corrade::Utility::Json::parseIntArray(const JsonToken& token, std::size_t expectedSize = 0)

Check and parse a signed 32-bit integer array.

If token is not a JsonToken::Type::Array, doesn't contain just JsonToken::Type::Number tokens, the tokens are not valid numeric values, have a fractional or exponent part or don't fit into a 32-bit representation, or expectedSize is not 0 and the array has different size, prints a message to Error and returns Containers::NullOpt. If JsonToken::isParsed() is already set for the array and all tokens inside are already parsed as JsonToken::ParsedType::Int, returns the cached values, otherwise caches the parsed results. Expects that token references a token owned by this instance, the returned view points to data owned by this instance.

Containers::Optional<Containers::StridedArrayView1D<const std::uint64_t>> Corrade::Utility::Json::parseUnsignedLongArray(const JsonToken& token, std::size_t expectedSize = 0)

Check and parse an unsigned 52-bit integer array.

If token is not a JsonToken::Type::Array, doesn't contain just JsonToken::Type::Number tokens, the tokens are not valid numeric values, have a fractional or exponent part, are negative or don't fit into 52 bits (which is the representable unsigned integer range in a JSON), or expectedSize is not 0 and the array has different size, prints a message to Error and returns Containers::NullOpt. If JsonToken::isParsed() is already set for the array and all tokens inside are already parsed as JsonToken::ParsedType::UnsignedLong, returns the cached values, otherwise caches the parsed results. Expects that token references a token owned by this instance, the returned view points to data owned by this instance.

Containers::Optional<Containers::StridedArrayView1D<const std::int64_t>> Corrade::Utility::Json::parseLongArray(const JsonToken& token, std::size_t expectedSize = 0)

Check and parse a signed 52-bit integer array.

If token is not a JsonToken::Type::Array, doesn't contain just JsonToken::Type::Number tokens, the tokens are not valid numeric values, have a fractional or exponent part or don't fit into 53 bits (which is the representable signed integer range in a JSON), or expectedSize is not 0 and the array has different size, prints a message to Error and returns Containers::NullOpt. If JsonToken::isParsed() is already set for the array and all tokens are already parsed as JsonToken::ParsedType::Long, returns the cached values, otherwise caches the parsed results. Expects that token references a token owned by this instance, the returned view points to data owned by this instance.

Containers::Optional<Containers::StridedArrayView1D<const std::size_t>> Corrade::Utility::Json::parseSizeArray(const JsonToken& token, std::size_t expectedSize = 0)

Check and parse a size array.

Convenience function that calls into parseUnsignedIntArray() on 32-bit targets and into parseUnsignedLongArray() on 64-bit.

Containers::Optional<Containers::StringIterable> Corrade::Utility::Json::parseStringArray(const JsonToken& token, std::size_t expectedSize = 0)

Check and parse a string array.

If token is not a JsonToken::Type::Array, doesn't contain just JsonToken::Type::String tokens, the tokens are not valid numeric values, or expectedSize is not 0 and the array has different size, prints a message to Error and returns Containers::NullOpt. If JsonToken::isParsed() is already set for the array and all tokens inside, returns the cached values, otherwise caches the parsed results. Expects that token references a token owned by this instance. If fromString() was called with a global literal and the string didn't contain any escape sequences, the returned views have Containers::StringViewFlag::Global set. If not, the views point to data owned by this instance.