nosjob  JsonParser


The JsonParser class provides a pull-style parser for JSON data. It parses JSON text (ASCII or UTF8/16) into either an Object or Array structure (JSON supports both types of root elements).

It is very simple to use:

Atom root = JsonParser().parse( std::cin );

The parse() function can also take an iterator range to read input from. On error it throws a JsonParser::ParseError which contains information about the error, including the location within the JSON input. On success it returns either an Object or Array, depending on what the root object is in the JSON input. We can process the results with:

if( Object::isObject(root) ) {
    Object obj( Object::cast(root) );
else {
    Array ar( Array::cast(root) );

From there, the data can be fished out however the user likes.

The parser is based on Jean Gressman's JSON parser, a push-style parser implemented in C. (Of all of the C/C++ JSON parsers i looked at, Jean's was the only one i liked in terms of design and usage.) The plan is to also provide a push parser for this project, and re-implement JsonParser on top of it. The primary advantage of push parsers is that they allow one to incrementally process JSON without necessarily holding all the collected data in memory at once. The down-side is that they are, in general, more difficult to use, and the client-side hooks for the parser tend to very grammar-specific. (Or they are used to build up the contents of a pull-parser, as is the case with JsonParser.)

Generating data for the parser is just as simple:

Object obj;
... populate obj ...
atomToJSON( obj, std::cout );

atomToJSON() can also send its output to an arbitrary output iterator instead of a stream.

By default atomToJSON() does not use any indentation in the output. To make it more human-readable, pass a number (type=uint8_t) as the last argument to atomToJSON(). If the number is 0, indentation is disabled. If it is 1 then 1 TAB character is used for each level of indentation. If the number is greater than 1, that many spaces are used for each level of indentation. e.g. passing 6 would use 6 spaces for each level of indentation.