diff --git a/include/nlohmann/detail/input/json_sax.hpp b/include/nlohmann/detail/input/json_sax.hpp index 06227e70..e2b8baad 100644 --- a/include/nlohmann/detail/input/json_sax.hpp +++ b/include/nlohmann/detail/input/json_sax.hpp @@ -275,5 +275,79 @@ class json_sax_dom_parser : public json_sax const bool allow_exceptions = true; }; +template +class json_sax_acceptor : public json_sax +{ + public: + using number_integer_t = typename BasicJsonType::number_integer_t; + using number_unsigned_t = typename BasicJsonType::number_unsigned_t; + using number_float_t = typename BasicJsonType::number_float_t; + + bool null() override + { + return true; + } + + bool boolean(bool) override + { + return true; + } + + bool number_integer(number_integer_t) override + { + return true; + } + + bool number_unsigned(number_unsigned_t) override + { + return true; + } + + bool number_float(number_float_t, const std::string&) override + { + return true; + } + + bool string(std::string&&) override + { + return true; + } + + bool start_object(std::size_t) override + { + return true; + } + + bool key(std::string&&) override + { + return true; + } + + bool end_object() override + { + return true; + } + + bool start_array(std::size_t) override + { + return true; + } + + bool end_array() override + { + return true; + } + + bool binary(const std::vector&) override + { + return true; + } + + bool parse_error(std::size_t, const std::string&, const std::string&) override + { + return false; + } +}; + } diff --git a/include/nlohmann/detail/input/parser.hpp b/include/nlohmann/detail/input/parser.hpp index 23fac952..5c0c2e94 100644 --- a/include/nlohmann/detail/input/parser.hpp +++ b/include/nlohmann/detail/input/parser.hpp @@ -137,7 +137,9 @@ class parser */ bool accept(const bool strict = true) { - if (not accept_internal()) + json_sax_acceptor sax_acceptor; + + if (not sax_parse_internal(&sax_acceptor)) { return false; } @@ -436,119 +438,6 @@ class parser } } - /*! - @brief the actual acceptor - - @invariant 1. The last token is not yet processed. Therefore, the caller - of this function must make sure a token has been read. - 2. When this function returns, the last token is processed. - That is, the last read character was already considered. - - This invariant makes sure that no token needs to be "unput". - */ - bool accept_internal() - { - switch (last_token) - { - case token_type::begin_object: - { - // read next token - get_token(); - - // closing } -> we are done - if (last_token == token_type::end_object) - { - return true; - } - - // parse values - while (true) - { - // parse key - if (last_token != token_type::value_string) - { - return false; - } - - // parse separator (:) - get_token(); - if (last_token != token_type::name_separator) - { - return false; - } - - // parse value - get_token(); - if (not accept_internal()) - { - return false; - } - - // comma -> next value - get_token(); - if (last_token == token_type::value_separator) - { - get_token(); - continue; - } - - // closing } - return (last_token == token_type::end_object); - } - } - - case token_type::begin_array: - { - // read next token - get_token(); - - // closing ] -> we are done - if (last_token == token_type::end_array) - { - return true; - } - - // parse values - while (true) - { - // parse value - if (not accept_internal()) - { - return false; - } - - // comma -> next value - get_token(); - if (last_token == token_type::value_separator) - { - get_token(); - continue; - } - - // closing ] - return (last_token == token_type::end_array); - } - } - - case token_type::value_float: - { - // reject infinity or NAN - return std::isfinite(m_lexer.get_number_float()); - } - - case token_type::literal_false: - case token_type::literal_null: - case token_type::literal_true: - case token_type::value_integer: - case token_type::value_string: - case token_type::value_unsigned: - return true; - - default: // the last token was unexpected - return false; - } - } - bool sax_parse_internal(json_sax_t* sax) { switch (last_token) diff --git a/single_include/nlohmann/json.hpp b/single_include/nlohmann/json.hpp index 9fc301e2..ff992269 100644 --- a/single_include/nlohmann/json.hpp +++ b/single_include/nlohmann/json.hpp @@ -3409,6 +3409,80 @@ class json_sax_dom_parser : public json_sax const bool allow_exceptions = true; }; +template +class json_sax_acceptor : public json_sax +{ + public: + using number_integer_t = typename BasicJsonType::number_integer_t; + using number_unsigned_t = typename BasicJsonType::number_unsigned_t; + using number_float_t = typename BasicJsonType::number_float_t; + + bool null() override + { + return true; + } + + bool boolean(bool) override + { + return true; + } + + bool number_integer(number_integer_t) override + { + return true; + } + + bool number_unsigned(number_unsigned_t) override + { + return true; + } + + bool number_float(number_float_t, const std::string&) override + { + return true; + } + + bool string(std::string&&) override + { + return true; + } + + bool start_object(std::size_t) override + { + return true; + } + + bool key(std::string&&) override + { + return true; + } + + bool end_object() override + { + return true; + } + + bool start_array(std::size_t) override + { + return true; + } + + bool end_array() override + { + return true; + } + + bool binary(const std::vector&) override + { + return true; + } + + bool parse_error(std::size_t, const std::string&, const std::string&) override + { + return false; + } +}; + } @@ -3540,7 +3614,9 @@ class parser */ bool accept(const bool strict = true) { - if (not accept_internal()) + json_sax_acceptor sax_acceptor; + + if (not sax_parse_internal(&sax_acceptor)) { return false; } @@ -3839,119 +3915,6 @@ class parser } } - /*! - @brief the actual acceptor - - @invariant 1. The last token is not yet processed. Therefore, the caller - of this function must make sure a token has been read. - 2. When this function returns, the last token is processed. - That is, the last read character was already considered. - - This invariant makes sure that no token needs to be "unput". - */ - bool accept_internal() - { - switch (last_token) - { - case token_type::begin_object: - { - // read next token - get_token(); - - // closing } -> we are done - if (last_token == token_type::end_object) - { - return true; - } - - // parse values - while (true) - { - // parse key - if (last_token != token_type::value_string) - { - return false; - } - - // parse separator (:) - get_token(); - if (last_token != token_type::name_separator) - { - return false; - } - - // parse value - get_token(); - if (not accept_internal()) - { - return false; - } - - // comma -> next value - get_token(); - if (last_token == token_type::value_separator) - { - get_token(); - continue; - } - - // closing } - return (last_token == token_type::end_object); - } - } - - case token_type::begin_array: - { - // read next token - get_token(); - - // closing ] -> we are done - if (last_token == token_type::end_array) - { - return true; - } - - // parse values - while (true) - { - // parse value - if (not accept_internal()) - { - return false; - } - - // comma -> next value - get_token(); - if (last_token == token_type::value_separator) - { - get_token(); - continue; - } - - // closing ] - return (last_token == token_type::end_array); - } - } - - case token_type::value_float: - { - // reject infinity or NAN - return std::isfinite(m_lexer.get_number_float()); - } - - case token_type::literal_false: - case token_type::literal_null: - case token_type::literal_true: - case token_type::value_integer: - case token_type::value_string: - case token_type::value_unsigned: - return true; - - default: // the last token was unexpected - return false; - } - } - bool sax_parse_internal(json_sax_t* sax) { switch (last_token)