Skip to content

Latest commit

 

History

History
313 lines (239 loc) · 9.89 KB

basic_json_parser.md

File metadata and controls

313 lines (239 loc) · 9.89 KB

jsoncons::basic_json_parser

#include <jsoncons/json_parser.hpp>

template< 
    typename CharT,
    typename TempAllocator = std::allocator<char>
> class basic_json_parser;

A basic_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.

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

basic_json_parser is noncopyable and nonmoveable.

Aliases for common character types are provided:

Type Definition
json_parser jsoncons::basic_json_parser<char,std::allocator<char>>
wjson_parser jsoncons::basic_json_parser<wchar_t,std::allocator<char>>

Member types

Type Definition
char_type CharT
temp_allocator_type TempAllocator

Constructors

basic_json_parser(const TempAllocator& temp_alloc = TempAllocator());                     (1)

basic_json_parser(const basic_json_decode_options<CharT>& options, 
    const TempAllocator& temp_alloc = TempAllocator());                                   (2)

basic_json_parser(std::function<bool(json_errc,const ser_context&)> err_handler, 
    const TempAllocator& temp_alloc = TempAllocator());                                   (3)   (deprecated since 0.171.0)

basic_json_parser(const basic_json_decode_options<CharT>& options, 
    std::function<bool(json_errc,const ser_context&)> err_handler,                        (4)   (deprecated since 0.171.0) 
    const TempAllocator& temp_alloc = TempAllocator());                       

basic_json_parser(
    std::function<bool(basic_parser_input<CharT>& input, std::error_code& ec)> chunk_rdr, 
    const TempAllocator& temp_alloc = TempAllocator());                                   (5)   (since 0.179.0)

basic_json_parser(
    std::function<bool(basic_parser_input<CharT>& input, std::error_code& ec)> chunk_rdr, 
    const basic_json_decode_options<CharT>& options,
    const TempAllocator& temp_alloc = TempAllocator());                                   (6)   (since 0.179.0)

(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.

Member functions

void update(const string_view_type& sv)              
void update(const CharT* data, std::size_t length)             (deprecated in 0.179.0)

Update the parser with a chunk of JSON

void set_buffer(const CharT* data, std::size_t length) final   (since 0.179.0)

Initializes the buffer to parse from with a chunk of JSON text

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

nan, inf, and -inf substitition

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

    auto options = json_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

Incremental parsing (until 0.179.0)

#include <jsoncons/json.hpp>
#include <iostream>

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

        parser.update("se,");
        parser.parse_some(decoder);
        std::cout << "(2) done: " << std::boolalpha << parser.done() << ", source_exhausted: " << parser.source_exhausted() << "\n\n";

        parser.update("9");
        parser.parse_some(decoder);
        std::cout << "(3) done: " << std::boolalpha << parser.done() << ", source_exhausted: " << parser.source_exhausted() << "\n\n";

        parser.update("0]");
        parser.parse_some(decoder);
        std::cout << "(4) done: " << std::boolalpha << parser.done() << ", source_exhausted: " << parser.source_exhausted() << "\n\n";

        parser.finish_parse(decoder);
        std::cout << "(5) done: " << std::boolalpha << parser.done() << ", source_exhausted: " << parser.source_exhausted() << "\n\n";

        parser.check_done();
        std::cout << "(6) done: " << std::boolalpha << parser.done() << ", source_exhausted: " << parser.source_exhausted() << "\n\n";

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

Output:

(1) done: false, source_exhausted: true

(2) done: false, source_exhausted: true

(3) done: false, source_exhausted: true

(4) done: false, source_exhausted: true

(5) done: true, source_exhausted: true

(6) done: true, source_exhausted: true

(7) [false,90]

Incremental parsing (since 0.179.0)

#include <jsoncons/json.hpp>
#include <iostream>

int main()
{
    std::vector<std::string> chunks = {"[fal", "se,", "9", "0]"};
    std::size_t index = 0;

    auto read_chunk = [&](jsoncons::parser_input& input, std::error_code& /*ec*/) -> bool
    {
        if (index < chunks.size())
        {
            input.set_buffer(chunks[index].data(), chunks[index].size());
            ++index;
            return true;
        }
        else
        {
            return false;
        }
    };

    jsoncons::json_decoder<jsoncons::json> decoder;
    jsoncons::json_parser parser{read_chunk};

    parser.reset();
    try
    {
        parser.parse_some(decoder);
        std::cout << "(1) done: " << std::boolalpha << parser.done() << ", source_exhausted: " << parser.source_exhausted() << "\n\n";
        parser.finish_parse(decoder);
        std::cout << "(2) done: " << std::boolalpha << parser.done() << ", source_exhausted: " << parser.source_exhausted() << "\n\n";
        parser.check_done();
        std::cout << "(3) done: " << std::boolalpha << parser.done() << ", source_exhausted: " << parser.source_exhausted() << "\n\n";

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

Output:

(1) done: false, source_exhausted: true

(2) done: true, source_exhausted: true

(3) done: true, source_exhausted: true

(4) [false,90]