Skip to content

Commit

Permalink
json_parser incremental parsing
Browse files Browse the repository at this point in the history
  • Loading branch information
danielaparker committed Nov 11, 2024
1 parent f124869 commit 40f64d0
Show file tree
Hide file tree
Showing 4 changed files with 56 additions and 50 deletions.
50 changes: 3 additions & 47 deletions include/jsoncons/json_parser.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,28 +29,6 @@

namespace jsoncons {

template <typename CharT>
class basic_json_parser_input
{
public:
using char_type = CharT;

virtual void update(const char_type* data, std::size_t length) = 0;
};

template <typename CharT>
class chunk_reader
{
public:
using char_type = CharT;

virtual ~chunk_reader() = default;
virtual bool read_chunk(basic_json_parser_input<char_type>&, std::error_code&)
{
return false;
}
};

enum class json_parse_state : uint8_t
{
root,
Expand All @@ -75,32 +53,13 @@ enum class json_parse_state : uint8_t
};

template <typename CharT,typename TempAllocator = std::allocator<char>>
class basic_json_parser : public ser_context, public virtual basic_json_parser_input<CharT>
class basic_json_parser : public ser_context, public virtual basic_parser_input<CharT>
{
public:
using char_type = CharT;
using string_view_type = typename basic_json_visitor<CharT>::string_view_type;
using chunk_reader_type = std::function<bool(basic_json_parser_input<char_type>& input, std::error_code& ec)>;
using chunk_reader_type = std::function<bool(basic_parser_input<char_type>& input, std::error_code& ec)>;
private:
class chunk_reader_adaptor : public chunk_reader<char_type>
{
chunk_reader_type read_chunk_;

public:
chunk_reader_adaptor()
: read_chunk_([](basic_json_parser_input<char_type>&, std::error_code&){return false;})
{
}
chunk_reader_adaptor(chunk_reader_type read_chunk)
: read_chunk_(read_chunk)
{
}

bool read_chunk(basic_json_parser_input<char_type>& input, std::error_code& ec)
{
return read_chunk_(input, ec);
}
};

struct string_maps_to_double
{
Expand Down Expand Up @@ -142,7 +101,7 @@ class basic_json_parser : public ser_context, public virtual basic_json_parser_i
std::vector<json_parse_state,parse_state_allocator_type> state_stack_;
std::vector<std::pair<std::basic_string<char_type>,double>> string_double_map_;

chunk_reader_adaptor chk_rdr_;
chunk_reader_adaptor<char_type> chk_rdr_;
chunk_reader<char_type>* chunk_rdr_;

// Noncopyable and nonmoveable
Expand Down Expand Up @@ -2830,9 +2789,6 @@ class basic_json_parser : public ser_context, public virtual basic_json_parser_i

using json_parser = basic_json_parser<char>;
using wjson_parser = basic_json_parser<wchar_t>;

using json_parser_input = basic_json_parser_input<char>;
using wjson_parser_input = basic_json_parser_input<wchar_t>;
}

#endif
Expand Down
2 changes: 1 addition & 1 deletion include/jsoncons/json_reader.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -269,7 +269,7 @@ namespace jsoncons {
{
}

bool read_chunk(basic_json_parser_input<char_type>&, std::error_code& ec) final
bool read_chunk(basic_parser_input<char_type>&, std::error_code& ec) final
{
//std::cout << "UPDATE BUFFER\n";
bool success = false;
Expand Down
51 changes: 51 additions & 0 deletions include/jsoncons/source.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
#include <exception>
#include <iterator>
#include <type_traits> // std::enable_if
#include <functional>
#include <jsoncons/config/jsoncons_config.hpp>
#include <jsoncons/byte_string.hpp> // jsoncons::byte_traits
#include <jsoncons/extension_traits.hpp>
Expand Down Expand Up @@ -788,6 +789,56 @@ namespace jsoncons {
constexpr std::size_t source_reader<Source>::max_buffer_length;
#endif

template <typename CharT>
class basic_parser_input
{
public:
using char_type = CharT;

virtual ~basic_parser_input() = default;
virtual void update(const char_type* data, std::size_t length) = 0;
};

template <typename CharT>
class chunk_reader
{
public:
using char_type = CharT;

virtual ~chunk_reader() = default;
virtual bool read_chunk(basic_parser_input<char_type>&, std::error_code&)
{
return false;
}
};

template <typename CharT>
class chunk_reader_adaptor : public chunk_reader<CharT>
{
using char_type = CharT;
using chunk_reader_type = std::function<bool(basic_parser_input<char_type>& input, std::error_code& ec)>;

chunk_reader_type read_chunk_;

public:
chunk_reader_adaptor()
: read_chunk_([](basic_parser_input<char_type>&, std::error_code&){return false;})
{
}
chunk_reader_adaptor(chunk_reader_type read_chunk)
: read_chunk_(read_chunk)
{
}

bool read_chunk(basic_parser_input<char_type>& input, std::error_code& ec)
{
return read_chunk_(input, ec);
}
};

using parser_input = basic_parser_input<char>;
using wparser_input = basic_parser_input<wchar_t>;

} // namespace jsoncons

#endif
3 changes: 1 addition & 2 deletions test/corelib/src/json_parser_tests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -238,7 +238,7 @@ TEST_CASE("test_incremental_parsing")
std::vector<std::string> chunks = {"[fal", "se]"};
std::size_t index = 0;

auto read_chunk = [&](jsoncons::json_parser_input& input, std::error_code& /*ec*/) -> bool
auto read_chunk = [&](jsoncons::parser_input& input, std::error_code& /*ec*/) -> bool
{
if (index < chunks.size())
{
Expand All @@ -260,7 +260,6 @@ TEST_CASE("test_incremental_parsing")
parser.parse_some(decoder);
CHECK_FALSE(parser.done());
CHECK(parser.source_exhausted());
parser.parse_some(decoder);
parser.finish_parse(decoder);
CHECK(parser.done());

Expand Down

0 comments on commit 40f64d0

Please sign in to comment.