Skip to content

Latest commit

 

History

History
271 lines (205 loc) · 8.76 KB

json_parser.md

File metadata and controls

271 lines (205 loc) · 8.76 KB

jsoncons::json_parser

#include <jsoncons/json_parser.hpp>

typedef basic_json_parser<char> json_parser

json_parser is an incremental json parser. It can be fed its input in chunks, and does not require an entire file to be loaded in memory at one time.

A buffer of text is supplied to the parser with a call to update(buffer). If a subsequent call to parse_some reaches the end of the buffer in the middle of parsing, say after digesting the sequence 'f', 'a', 'l', member function stopped() will return false and source_exhausted() will return true. Additional JSON text can be supplied to the parser, parse_some called again, and parsing will resume from where it left off.

A typical application will repeatedly call the parse_some function until stopped() returns true. A stopped state indicates that a content visitor function returned false, an error occured, or a complete JSON text has been consumed. If the latter, done() will return true.

As an alternative to repeatedly calling parse_some() until stopped() returns true, when source_exhausted() is true and there is no more input, finish_parse may be called.

check_done can be called to check if the input has any unconsumed non-whitespace characters, which would normally be considered an error.

json_parser is used by the push parser basic_json_reader, and by the pull parser basic_json_cursor.

json_parser is noncopyable and nonmoveable.

Constructors

json_parser(); (1)

json_parser(const json_decode_options& options); (2)

json_parser(std::function<bool(json_errc,const ser_context&)> err_handler); (3)

json_parser(const json_decode_options& options, 
            std::function<bool(json_errc,const ser_context&)> err_handler); (4)

(1) Constructs a json_parser that uses default basic_json_options and a default err_handler.

(2) Constructs a json_parser that uses the specified basic_json_options and a default err_handler.

(3) Constructs a json_parser that uses default basic_json_options and a specified err_handler.

(4) Constructs a json_parser that uses the specified basic_json_options and a specified err_handler.

Note: It is the programmer's responsibility to ensure that a basic_json_parser does not outlive any string passed in the constuctor.

Member functions

void update(const string_view_type& sv)
void update(const char* data, std::size_t length)

Update the parser with a chunk of JSON

bool done() const

Returns true when the parser has consumed a complete JSON text, false otherwise

bool stopped() const

Returns true if the parser is stopped, false otherwise. The parser may enter a stopped state as a result of a visitor function returning false, an error occurred, or after having consumed a complete JSON text.

bool finished() const

Returns true if the parser is finished parsing, false otherwise.

bool source_exhausted() const

Returns true if the input in the source buffer has been exhausted, false otherwise

void parse_some(json_visitor& visitor)

Parses the source until a complete json text has been consumed or the source has been exhausted. Parse events are sent to the supplied visitor. Throws a ser_error if parsing fails.

void parse_some(json_visitor<CharT>& visitor,
                std::error_code& ec)

Parses the source until a complete json text has been consumed or the source has been exhausted. Parse events are sent to the supplied visitor. Sets ec to a json_errc if parsing fails.

void finish_parse(json_visitor<CharT>& visitor)

Called after source_exhausted() is true and there is no more input. Repeatedly calls parse_some(visitor) until finished() returns true Throws a ser_error if parsing fails.

void finish_parse(json_visitor<CharT>& visitor,
               std::error_code& ec)

Called after source_exhausted() is true and there is no more input. Repeatedly calls parse_some(visitor) until finished() returns true Sets ec to a json_errc if parsing fails.

void skip_bom()

Reads the next JSON text from the stream and reports JSON events to a basic_json_visitor, such as a json_decoder. Throws a ser_error if parsing fails.

void check_done()

Throws if there are any unconsumed non-whitespace characters in the input. Throws a ser_error if parsing fails.

void check_done(std::error_code& ec)

Sets ec to a json_errc if parsing fails.

void reset() const

Resets the state of the parser to its initial state. In this state stopped() returns false and done() returns false.

void restart() const

Resets the stopped state of the parser to false, allowing parsing to continue.

Examples

Incremental parsing

int main()
{
    json_parser parser;
    jsoncons::json_decoder<json> decoder;
    try
    {
        parser.update("10");
        parser.parse_some(decoder);
        std::cout << "(1) done: " << std::boolalpha << parser.done() << ", source_exhausted: " << parser.source_exhausted() << "\n\n";

        parser.update(".5");
        parser.parse_some(decoder); // This is the end, but the parser can't tell
        std::cout << "(2) done: " << std::boolalpha << parser.done() << ", source_exhausted: " << parser.source_exhausted() << "\n\n";

        parser.finish_parse(decoder); // Indicates that this is the end
        std::cout << "(3) done: " << std::boolalpha << parser.done() << ", source_exhausted: " << parser.source_exhausted() << "\n\n";

        parser.check_done(); // Checks if there are any unconsumed 
                             // non-whitespace characters in the input
        std::cout << "(4) done: " << std::boolalpha << parser.done() << ", source_exhausted: " << parser.source_exhausted() << "\n\n";

        json j = decoder.get_result();
        std::cout << "(5) " << j << "\n";
    }
    catch (const ser_error& e)
    {
        std::cout << e.what() << std::endl;
    }
}

Output:

(1) done: false, source_exhausted: true

(2) done: false, source_exhausted: true

(3) done: true, source_exhausted: true

(4) done: true, source_exhausted: true

(5) 10.5

Incremental parsing with unconsumed non-whitespace characters

int main()
{
    json_parser parser;
    jsoncons::json_decoder<json> decoder;
    try
    {
        parser.update("[10");
        parser.parse_some(decoder);
        std::cout << "(1) done: " << std::boolalpha << parser.done() << ", source_exhausted: " << parser.source_exhausted() << "\n\n";

        parser.update(".5]{}");
        parser.parse_some(decoder); // The parser reaches the end at ']'
        std::cout << "(2) done: " << std::boolalpha << parser.done() << ", source_exhausted: " << parser.source_exhausted() << "\n\n";

        parser.finish_parse(decoder); // Indicates that this is the end
        std::cout << "(3) done: " << std::boolalpha << parser.done() << ", source_exhausted: " << parser.source_exhausted() << "\n\n";

        parser.check_done(); // Checks if there are any unconsumed 
                             // non-whitespace characters in the input
                             (there are)
    }
    catch (const ser_error& e)
    {
        std::cout << "(4) " << e.what() << std::endl;
    }
}

Output:

(1) done: false, source_exhausted: true

(2) done: true, source_exhausted: false

(3) done: true, source_exhausted: false

(4) Unexpected non-whitespace character after JSON text at line 1 and column 7

nan, inf, and -inf substitition

int main()
{
    std::string s = R"(
        {
           "A" : "NaN",
           "B" : "Infinity",
           "C" : "-Infinity"
        }
    )";

    json_options options; // Implements json_decode_options
    options.nan_to_str("NaN")
           .inf_to_str("Infinity");

    json_parser parser(options);
    jsoncons::json_decoder<json> decoder;
    try
    {
        parser.update(s);
        parser.parse_some(decoder);
        parser.finish_parse(decoder);
        parser.check_done();
    }
    catch (const ser_error& e)
    {
        std::cout << e.what() << std::endl;
    }

    json j = decoder.get_result(); // performs move
    if (j["A"].is<double>())
    {
        std::cout << "A: " << j["A"].as<double>() << std::endl;
    }
    if (j["B"].is<double>())
    {
        std::cout << "B: " << j["B"].as<double>() << std::endl;
    }
    if (j["C"].is<double>())
    {
        std::cout << "C: " << j["C"].as<double>() << std::endl;
    }
}

Output:

A: nan
B: inf
C: -inf