summaryrefslogtreecommitdiff
path: root/vendor/jsoncons-0.99.2/jsoncons/json_parser.hpp
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/jsoncons-0.99.2/jsoncons/json_parser.hpp')
-rw-r--r--vendor/jsoncons-0.99.2/jsoncons/json_parser.hpp1587
1 files changed, 0 insertions, 1587 deletions
diff --git a/vendor/jsoncons-0.99.2/jsoncons/json_parser.hpp b/vendor/jsoncons-0.99.2/jsoncons/json_parser.hpp
deleted file mode 100644
index 8a06c2e7..00000000
--- a/vendor/jsoncons-0.99.2/jsoncons/json_parser.hpp
+++ /dev/null
@@ -1,1587 +0,0 @@
-// Copyright 2015 Daniel Parker
-// Distributed under the Boost license, Version 1.0.
-// (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
-
-// See https://github.com/danielaparker/jsoncons for latest version
-
-#ifndef JSONCONS_JSON_PARSER_HPP
-#define JSONCONS_JSON_PARSER_HPP
-
-#include <memory>
-#include <string>
-#include <sstream>
-#include <vector>
-#include <istream>
-#include <cstdlib>
-#include <stdexcept>
-#include <system_error>
-#include "jsoncons/jsoncons.hpp"
-#include "jsoncons/json_input_handler.hpp"
-#include "jsoncons/parse_error_handler.hpp"
-#include "jsoncons/json_error_category.hpp"
-
-namespace jsoncons {
-
-enum class states
-{
- root,
- start,
- slash,
- slash_slash,
- slash_star,
- slash_star_star,
- expect_comma_or_end,
- object,
- expect_member_name_or_end,
- expect_member_name,
- expect_colon,
- expect_value_or_end,
- expect_value,
- array,
- string,
- member_name,
- escape,
- u1,
- u2,
- u3,
- u4,
- expect_surrogate_pair1,
- expect_surrogate_pair2,
- u6,
- u7,
- u8,
- u9,
- minus,
- zero,
- integer,
- fraction,
- exp1,
- exp2,
- exp3,
- n,
- t,
- f,
- cr,
- lf,
- done
-};
-
-template<typename CharT>
-class basic_json_parser : private basic_parsing_context<CharT>
-{
- static const int default_initial_stack_capacity_ = 100;
-
- std::vector<states> stack_;
- basic_json_input_handler<CharT> *handler_;
- basic_parse_error_handler<CharT> *err_handler_;
- size_t column_;
- size_t line_;
- uint32_t cp_;
- uint32_t cp2_;
- std::basic_string<CharT> string_buffer_;
- std::basic_string<char> number_buffer_;
- bool is_negative_;
- size_t index_;
- int initial_stack_capacity_;
- int nesting_depth_;
- int max_depth_;
- float_reader float_reader_;
- const CharT* begin_input_;
- const CharT* end_input_;
- const CharT* p_;
- uint8_t precision_;
- std::pair<const CharT*,size_t> literal_;
- size_t literal_index_;
-
-public:
- basic_json_parser(basic_json_input_handler<CharT>& handler)
- : handler_(std::addressof(handler)),
- err_handler_(std::addressof(basic_default_parse_error_handler<CharT>::instance())),
- column_(0),
- line_(0),
- cp_(0),
- is_negative_(false),
- index_(0),
- initial_stack_capacity_(default_initial_stack_capacity_)
- {
- max_depth_ = std::numeric_limits<int>::max JSONCONS_NO_MACRO_EXP();
- }
-
- basic_json_parser(basic_json_input_handler<CharT>& handler,
- basic_parse_error_handler<CharT>& err_handler)
- : handler_(std::addressof(handler)),
- err_handler_(std::addressof(err_handler)),
- column_(0),
- line_(0),
- cp_(0),
- is_negative_(false),
- index_(0),
- initial_stack_capacity_(default_initial_stack_capacity_)
-
- {
- max_depth_ = std::numeric_limits<int>::max JSONCONS_NO_MACRO_EXP();
- }
-
- const basic_parsing_context<CharT>& parsing_context() const
- {
- return *this;
- }
-
- ~basic_json_parser()
- {
- }
-
- size_t max_nesting_depth() const
- {
- return static_cast<size_t>(max_depth_);
- }
-
- void max_nesting_depth(size_t max_nesting_depth)
- {
- max_depth_ = static_cast<int>(std::min(max_nesting_depth,static_cast<size_t>(std::numeric_limits<int>::max JSONCONS_NO_MACRO_EXP())));
- }
-
- states parent() const
- {
- return stack_[stack_.size()-2];
- }
-
- bool done() const
- {
- return stack_.back() == states::done;
- }
-
- void do_space()
- {
- while ((p_ + 1) < end_input_ && (*(p_ + 1) == ' ' || *(p_ + 1) == '\t'))
- {
- ++p_;
- ++column_;
- }
- }
-
- void do_begin_object()
- {
- if (++nesting_depth_ >= max_depth_)
- {
- err_handler_->error(std::error_code(json_parser_errc::max_depth_exceeded, json_error_category()), *this);
- }
- stack_.back() = states::object;
- stack_.push_back(states::expect_member_name_or_end);
- handler_->begin_object(*this);
- }
-
- void do_end_object()
- {
- --nesting_depth_;
- JSONCONS_ASSERT(!stack_.empty())
- stack_.pop_back();
- if (stack_.back() == states::object)
- {
- handler_->end_object(*this);
- }
- else if (stack_.back() == states::array)
- {
- err_handler_->fatal_error(std::error_code(json_parser_errc::expected_comma_or_right_bracket, json_error_category()), *this);
- }
- else
- {
- err_handler_->fatal_error(std::error_code(json_parser_errc::unexpected_right_brace, json_error_category()), *this);
- }
-
- JSONCONS_ASSERT(stack_.size() >= 2);
- if (parent() == states::root)
- {
- stack_.back() = states::done;
- handler_->end_json();
- }
- else
- {
- stack_.back() = states::expect_comma_or_end;
- }
- }
-
- void do_begin_array()
- {
- if (++nesting_depth_ >= max_depth_)
- {
- err_handler_->error(std::error_code(json_parser_errc::max_depth_exceeded, json_error_category()), *this);
- }
- stack_.back() = states::array;
- stack_.push_back(states::expect_value_or_end);
- handler_->begin_array(*this);
- }
-
- void do_end_array()
- {
- --nesting_depth_;
- JSONCONS_ASSERT(!stack_.empty())
- stack_.pop_back();
- if (stack_.back() == states::array)
- {
- handler_->end_array(*this);
- }
- else if (stack_.back() == states::object)
- {
- err_handler_->fatal_error(std::error_code(json_parser_errc::expected_comma_or_right_brace, json_error_category()), *this);
- }
- else
- {
- err_handler_->fatal_error(std::error_code(json_parser_errc::unexpected_right_bracket, json_error_category()), *this);
- }
- JSONCONS_ASSERT(stack_.size() >= 2);
- if (parent() == states::root)
- {
- stack_.back() = states::done;
- handler_->end_json();
- }
- else
- {
- stack_.back() = states::expect_comma_or_end;
- }
- }
-
- void begin_parse()
- {
- stack_.clear();
- stack_.reserve(initial_stack_capacity_);
- stack_.push_back(states::root);
- stack_.push_back(states::start);
- line_ = 1;
- column_ = 1;
- nesting_depth_ = 0;
- }
-
- void check_done(const CharT* input, size_t start, size_t length)
- {
- index_ = start;
- for (; index_ < length; ++index_)
- {
- CharT curr_char_ = input[index_];
- switch (curr_char_)
- {
- case '\n':
- case '\r':
- case '\t':
- case ' ':
- break;
- default:
- err_handler_->error(std::error_code(json_parser_errc::extra_character, json_error_category()), *this);
- break;
- }
- }
- }
-
- void parse_string()
- {
- const CharT* sb = p_;
- bool done = false;
- while (!done && p_ < end_input_)
- {
- switch (*p_)
- {
- case 0x00:case 0x01:case 0x02:case 0x03:case 0x04:case 0x05:case 0x06:case 0x07:case 0x08:case 0x0b:
- case 0x0c:case 0x0e:case 0x0f:case 0x10:case 0x11:case 0x12:case 0x13:case 0x14:case 0x15:case 0x16:
- case 0x17:case 0x18:case 0x19:case 0x1a:case 0x1b:case 0x1c:case 0x1d:case 0x1e:case 0x1f:
- string_buffer_.append(sb,p_-sb);
- column_ += (p_ - sb + 1);
- err_handler_->error(std::error_code(json_parser_errc::illegal_control_character, json_error_category()), *this);
- // recovery - skip
- done = true;
- ++p_;
- break;
- case '\r':
- {
- column_ += (p_ - sb + 1);
- err_handler_->error(std::error_code(json_parser_errc::illegal_character_in_string, json_error_category()), *this);
- // recovery - keep
- string_buffer_.append(sb, p_ - sb + 1);
- stack_.push_back(states::cr);
- done = true;
- ++p_;
- }
- break;
- case '\n':
- {
- column_ += (p_ - sb + 1);
- err_handler_->error(std::error_code(json_parser_errc::illegal_character_in_string, json_error_category()), *this);
- // recovery - keep
- string_buffer_.append(sb, p_ - sb + 1);
- stack_.push_back(states::lf);
- done = true;
- ++p_;
- }
- break;
- case '\t':
- {
- column_ += (p_ - sb + 1);
- err_handler_->error(std::error_code(json_parser_errc::illegal_character_in_string, json_error_category()), *this);
- // recovery - keep
- string_buffer_.append(sb, p_ - sb + 1);
- done = true;
- ++p_;
- }
- break;
- case '\\':
- string_buffer_.append(sb,p_-sb);
- column_ += (p_ - sb + 1);
- stack_.back() = states::escape;
- done = true;
- ++p_;
- break;
- case '\"':
- if (string_buffer_.length() == 0)
- {
- end_string_value(sb,p_-sb);
- }
- else
- {
- string_buffer_.append(sb,p_-sb);
- end_string_value(string_buffer_.data(),string_buffer_.length());
- string_buffer_.clear();
- }
- column_ += (p_ - sb + 1);
- done = true;
- ++p_;
- break;
- default:
- ++p_;
- break;
- }
- }
- if (!done)
- {
- string_buffer_.append(sb,p_-sb);
- column_ += (p_ - sb + 1);
- }
- }
-
- void parse(const CharT* const input, size_t start, size_t length)
- {
- begin_input_ = input + start;
- end_input_ = input + length;
- p_ = begin_input_;
-
- index_ = start;
- while ((p_ < end_input_) && (stack_.back() != states::done))
- {
- switch (*p_)
- {
- case 0x00:case 0x01:case 0x02:case 0x03:case 0x04:case 0x05:case 0x06:case 0x07:case 0x08:case 0x0b:
- case 0x0c:case 0x0e:case 0x0f:case 0x10:case 0x11:case 0x12:case 0x13:case 0x14:case 0x15:case 0x16:
- case 0x17:case 0x18:case 0x19:case 0x1a:case 0x1b:case 0x1c:case 0x1d:case 0x1e:case 0x1f:
- err_handler_->error(std::error_code(json_parser_errc::illegal_control_character, json_error_category()), *this);
- break;
- default:
- break;
- }
-
- switch (stack_.back())
- {
- case states::cr:
- ++line_;
- column_ = 1;
- switch (*p_)
- {
- case '\n':
- JSONCONS_ASSERT(!stack_.empty())
- stack_.pop_back();
- ++p_;
- break;
- default:
- JSONCONS_ASSERT(!stack_.empty())
- stack_.pop_back();
- break;
- }
- break;
- case states::lf:
- ++line_;
- column_ = 1;
- JSONCONS_ASSERT(!stack_.empty())
- stack_.pop_back();
- break;
- case states::start:
- {
- switch (*p_)
- {
- case '\r':
- stack_.push_back(states::cr);
- break;
- case '\n':
- stack_.push_back(states::lf);
- break;
- case ' ':case '\t':
- do_space();
- break;
- case '/':
- stack_.push_back(states::slash);
- break;
- case '{':
- handler_->begin_json();
- do_begin_object();
- break;
- case '[':
- handler_->begin_json();
- do_begin_array();
- break;
- case '\"':
- handler_->begin_json();
- stack_.back() = states::string;
- break;
- case '-':
- handler_->begin_json();
- is_negative_ = true;
- stack_.back() = states::minus;
- break;
- case '0':
- handler_->begin_json();
- number_buffer_.push_back(static_cast<char>(*p_));
- stack_.back() = states::zero;
- break;
- case '1':case '2':case '3':case '4':case '5':case '6':case '7':case '8': case '9':
- handler_->begin_json();
- number_buffer_.push_back(static_cast<char>(*p_));
- stack_.back() = states::integer;
- break;
- case 'f':
- handler_->begin_json();
- stack_.back() = states::f;
- literal_ = json_literals<CharT>::false_literal();
- literal_index_ = 1;
- break;
- case 'n':
- handler_->begin_json();
- stack_.back() = states::n;
- literal_ = json_literals<CharT>::null_literal();
- literal_index_ = 1;
- break;
- case 't':
- handler_->begin_json();
- stack_.back() = states::t;
- literal_ = json_literals<CharT>::true_literal();
- literal_index_ = 1;
- break;
- case '}':
- err_handler_->fatal_error(std::error_code(json_parser_errc::unexpected_right_brace, json_error_category()), *this);
- break;
- case ']':
- err_handler_->fatal_error(std::error_code(json_parser_errc::unexpected_right_bracket, json_error_category()), *this);
- break;
- default:
- err_handler_->fatal_error(std::error_code(json_parser_errc::invalid_json_text, json_error_category()), *this);
- break;
- }
- }
- ++p_;
- ++column_;
- break;
-
- case states::expect_comma_or_end:
- {
- switch (*p_)
- {
- case '\r':
- stack_.push_back(states::cr);
- break;
- case '\n':
- stack_.push_back(states::lf);
- break;
- case ' ':case '\t':
- do_space();
- break;
- case '/':
- stack_.push_back(states::slash);
- break;
- case '}':
- do_end_object();
- break;
- case ']':
- do_end_array();
- break;
- case ',':
- begin_member_or_element();
- break;
- default:
- JSONCONS_ASSERT(stack_.size() >= 2);
- if (parent() == states::array)
- {
- err_handler_->error(std::error_code(json_parser_errc::expected_comma_or_right_bracket, json_error_category()), *this);
- }
- else if (parent() == states::object)
- {
- err_handler_->error(std::error_code(json_parser_errc::expected_comma_or_right_brace, json_error_category()), *this);
- }
- break;
- }
- }
- ++p_;
- ++column_;
- break;
- case states::expect_member_name_or_end:
- {
- switch (*p_)
- {
- case '\r':
- stack_.push_back(states::cr);
- break;
- case '\n':
- stack_.push_back(states::lf);
- break;
- case ' ':case '\t':
- do_space();
- break;
- case '/':
- stack_.push_back(states::slash);
- break;
- case '}':
- do_end_object();
- break;
- case '\"':
- stack_.back() = states::member_name;
- stack_.push_back(states::string);
- break;
- case '\'':
- err_handler_->error(std::error_code(json_parser_errc::single_quote, json_error_category()), *this);
- break;
- default:
- err_handler_->error(std::error_code(json_parser_errc::expected_name, json_error_category()), *this);
- break;
- }
- }
- ++p_;
- ++column_;
- break;
- case states::expect_member_name:
- {
- switch (*p_)
- {
- case '\r':
- stack_.push_back(states::cr);
- break;
- case '\n':
- stack_.push_back(states::lf);
- break;
- case ' ':case '\t':
- do_space();
- break;
- case '/':
- stack_.push_back(states::slash);
- break;
- case '\"':
- //stack_.back() = states::string;
- stack_.back() = states::member_name;
- stack_.push_back(states::string);
- break;
- case '}':
- --nesting_depth_;
- err_handler_->error(std::error_code(json_parser_errc::extra_comma, json_error_category()), *this);
- break;
- case '\'':
- err_handler_->error(std::error_code(json_parser_errc::single_quote, json_error_category()), *this);
- break;
- default:
- err_handler_->error(std::error_code(json_parser_errc::expected_name, json_error_category()), *this);
- break;
- }
- }
- ++p_;
- ++column_;
- break;
- case states::expect_colon:
- {
- switch (*p_)
- {
- case '\r':
- stack_.push_back(states::cr);
- break;
- case '\n':
- stack_.push_back(states::lf);
- break;
- case ' ':case '\t':
- do_space();
- break;
- case '/':
- stack_.push_back(states::slash);
- break;
- case ':':
- stack_.back() = states::expect_value;
- break;
- default:
- err_handler_->error(std::error_code(json_parser_errc::expected_colon, json_error_category()), *this);
- break;
- }
- }
- ++p_;
- ++column_;
- break;
- case states::expect_value:
- {
- switch (*p_)
- {
- case '\r':
- stack_.push_back(states::cr);
- break;
- case '\n':
- stack_.push_back(states::lf);
- break;
- case ' ':case '\t':
- do_space();
- break;
- case '/':
- stack_.push_back(states::slash);
- break;
- case '{':
- do_begin_object();
- break;
- case '[':
- do_begin_array();
- break;
- case '\"':
- stack_.back() = states::string;
- break;
- case '-':
- is_negative_ = true;
- stack_.back() = states::minus;
- break;
- case '0':
- number_buffer_.push_back(static_cast<char>(*p_));
- stack_.back() = states::zero;
- break;
- case '1':case '2':case '3':case '4':case '5':case '6':case '7':case '8': case '9':
- number_buffer_.push_back(static_cast<char>(*p_));
- stack_.back() = states::integer;
- break;
- case 'f':
- stack_.back() = states::f;
- literal_ = json_literals<CharT>::false_literal();
- literal_index_ = 1;
- break;
- case 'n':
- stack_.back() = states::n;
- literal_ = json_literals<CharT>::null_literal();
- literal_index_ = 1;
- break;
- case 't':
- stack_.back() = states::t;
- literal_ = json_literals<CharT>::true_literal();
- literal_index_ = 1;
- break;
- case ']':
- JSONCONS_ASSERT(stack_.size() >= 2);
- if (parent() == states::array)
- {
- err_handler_->error(std::error_code(json_parser_errc::extra_comma, json_error_category()), *this);
- }
- else
- {
- err_handler_->error(std::error_code(json_parser_errc::expected_value, json_error_category()), *this);
- }
- break;
- case '\'':
- err_handler_->error(std::error_code(json_parser_errc::single_quote, json_error_category()), *this);
- break;
- default:
- err_handler_->error(std::error_code(json_parser_errc::expected_value, json_error_category()), *this);
- break;
- }
- }
- ++p_;
- ++column_;
- break;
- case states::expect_value_or_end:
- {
- switch (*p_)
- {
- case '\r':
- stack_.push_back(states::cr);
- break;
- case '\n':
- stack_.push_back(states::lf);
- break;
- case ' ':case '\t':
- do_space();
- break;
- case '/':
- stack_.push_back(states::slash);
- break;
- case '{':
- do_begin_object();
- break;
- case '[':
- do_begin_array();
- break;
- case ']':
- do_end_array();
- break;
- case '\"':
- stack_.back() = states::string;
- break;
- case '-':
- is_negative_ = true;
- stack_.back() = states::minus;
- break;
- case '0':
- number_buffer_.push_back(static_cast<char>(*p_));
- stack_.back() = states::zero;
- break;
- case '1':case '2':case '3':case '4':case '5':case '6':case '7':case '8': case '9':
- number_buffer_.push_back(static_cast<char>(*p_));
- stack_.back() = states::integer;
- break;
- case 'f':
- stack_.back() = states::f;
- literal_ = json_literals<CharT>::false_literal();
- literal_index_ = 1;
- break;
- case 'n':
- stack_.back() = states::n;
- literal_ = json_literals<CharT>::null_literal();
- literal_index_ = 1;
- break;
- case 't':
- stack_.back() = states::t;
- literal_ = json_literals<CharT>::true_literal();
- literal_index_ = 1;
- break;
- case '\'':
- err_handler_->error(std::error_code(json_parser_errc::single_quote, json_error_category()), *this);
- break;
- default:
- err_handler_->error(std::error_code(json_parser_errc::expected_value, json_error_category()), *this);
- break;
- }
- }
- ++p_;
- ++column_;
- break;
- case states::string:
- parse_string();
- break;
- case states::escape:
- {
- escape_next_char(*p_);
- }
- ++p_;
- ++column_;
- break;
- case states::u1:
- {
- append_codepoint(*p_);
- stack_.back() = states::u2;
- }
- ++p_;
- ++column_;
- break;
- case states::u2:
- {
- append_codepoint(*p_);
- stack_.back() = states::u3;
- }
- ++p_;
- ++column_;
- break;
- case states::u3:
- {
- append_codepoint(*p_);
- stack_.back() = states::u4;
- }
- ++p_;
- ++column_;
- break;
- case states::u4:
- {
- append_codepoint(*p_);
- if (cp_ >= min_lead_surrogate && cp_ <= max_lead_surrogate)
- {
- stack_.back() = states::expect_surrogate_pair1;
- }
- else
- {
- json_char_traits<CharT, sizeof(CharT)>::append_codepoint_to_string(cp_, string_buffer_);
- stack_.back() = states::string;
- }
- }
- ++p_;
- ++column_;
- break;
- case states::expect_surrogate_pair1:
- {
- switch (*p_)
- {
- case '\\':
- cp2_ = 0;
- stack_.back() = states::expect_surrogate_pair2;
- break;
- default:
- err_handler_->error(std::error_code(json_parser_errc::expected_codepoint_surrogate_pair, json_error_category()), *this);
- break;
- }
- }
- ++p_;
- ++column_;
- break;
- case states::expect_surrogate_pair2:
- {
- switch (*p_)
- {
- case 'u':
- stack_.back() = states::u6;
- break;
- default:
- err_handler_->error(std::error_code(json_parser_errc::expected_codepoint_surrogate_pair, json_error_category()), *this);
- break;
- }
- }
- ++p_;
- ++column_;
- break;
- case states::u6:
- {
- append_second_codepoint(*p_);
- stack_.back() = states::u7;
- }
- ++p_;
- ++column_;
- break;
- case states::u7:
- {
- append_second_codepoint(*p_);
- stack_.back() = states::u8;
- }
- ++p_;
- ++column_;
- break;
- case states::u8:
- {
- append_second_codepoint(*p_);
- stack_.back() = states::u9;
- }
- ++p_;
- ++column_;
- break;
- case states::u9:
- {
- append_second_codepoint(*p_);
- uint32_t cp = 0x10000 + ((cp_ & 0x3FF) << 10) + (cp2_ & 0x3FF);
- json_char_traits<CharT, sizeof(CharT)>::append_codepoint_to_string(cp, string_buffer_);
- stack_.back() = states::string;
- }
- ++p_;
- ++column_;
- break;
- case states::minus:
- {
- switch (*p_)
- {
- case '0':
- number_buffer_.push_back(static_cast<char>(*p_));
- stack_.back() = states::zero;
- break;
- case '1':case '2':case '3':case '4':case '5':case '6':case '7':case '8': case '9':
- number_buffer_.push_back(static_cast<char>(*p_));
- stack_.back() = states::integer;
- break;
- default:
- err_handler_->error(std::error_code(json_parser_errc::expected_value, json_error_category()), *this);
- break;
- }
- }
- ++p_;
- ++column_;
- break;
- case states::zero:
- {
- switch (*p_)
- {
- case '\r':
- end_integer_value();
- stack_.push_back(states::cr);
- break;
- case '\n':
- end_integer_value();
- stack_.push_back(states::lf);
- break;
- case ' ':case '\t':
- end_integer_value();
- do_space();
- break;
- case '/':
- end_integer_value();
- stack_.push_back(states::slash);
- break;
- case '}':
- end_integer_value();
- do_end_object();
- break;
- case ']':
- end_integer_value();
- do_end_array();
- break;
- case '.':
- precision_ = static_cast<uint8_t>(number_buffer_.length());
- number_buffer_.push_back(static_cast<char>(*p_));
- stack_.back() = states::fraction;
- break;
- case ',':
- end_integer_value();
- begin_member_or_element();
- break;
- case '0': case '1':case '2':case '3':case '4':case '5':case '6':case '7':case '8': case '9':
- err_handler_->error(std::error_code(json_parser_errc::leading_zero, json_error_category()), *this);
- break;
- default:
- err_handler_->error(std::error_code(json_parser_errc::invalid_number, json_error_category()), *this);
- break;
- }
- }
- ++p_;
- ++column_;
- break;
- case states::integer:
- {
- switch (*p_)
- {
- case '\r':
- end_integer_value();
- stack_.push_back(states::cr);
- break;
- case '\n':
- end_integer_value();
- stack_.push_back(states::lf);
- break;
- case ' ':case '\t':
- end_integer_value();
- do_space();
- break;
- case '/':
- end_integer_value();
- stack_.push_back(states::slash);
- break;
- case '}':
- end_integer_value();
- do_end_object();
- break;
- case ']':
- end_integer_value();
- do_end_array();
- break;
- case '0':
- case '1':case '2':case '3':case '4':case '5':case '6':case '7':case '8': case '9':
- number_buffer_.push_back(static_cast<char>(*p_));
- stack_.back() = states::integer;
- break;
- case '.':
- precision_ = static_cast<uint8_t>(number_buffer_.length());
- number_buffer_.push_back(static_cast<char>(*p_));
- stack_.back() = states::fraction;
- break;
- case ',':
- end_integer_value();
- begin_member_or_element();
- break;
- case 'e':case 'E':
- number_buffer_.push_back(static_cast<char>(*p_));
- stack_.back() = states::exp1;
- break;
- default:
- err_handler_->error(std::error_code(json_parser_errc::invalid_number, json_error_category()), *this);
- break;
- }
- }
- ++p_;
- ++column_;
- break;
- case states::fraction:
- {
- switch (*p_)
- {
- case '\r':
- end_fraction_value();
- stack_.push_back(states::cr);
- break;
- case '\n':
- end_fraction_value();
- stack_.push_back(states::lf);
- break;
- case ' ':case '\t':
- end_fraction_value();
- do_space();
- break;
- case '/':
- end_fraction_value();
- stack_.push_back(states::slash);
- break;
- case '}':
- end_fraction_value();
- do_end_object();
- break;
- case ']':
- end_fraction_value();
- do_end_array();
- break;
- case '0':
- case '1':case '2':case '3':case '4':case '5':case '6':case '7':case '8': case '9':
- ++precision_;
- number_buffer_.push_back(static_cast<char>(*p_));
- stack_.back() = states::fraction;
- break;
- case ',':
- end_fraction_value();
- begin_member_or_element();
- break;
- case 'e':case 'E':
- number_buffer_.push_back(static_cast<char>(*p_));
- stack_.back() = states::exp1;
- break;
- default:
- err_handler_->error(std::error_code(json_parser_errc::invalid_number, json_error_category()), *this);
- break;
- }
- }
- ++p_;
- ++column_;
- break;
- case states::exp1:
- {
- switch (*p_)
- {
- case '+':
- stack_.back() = states::exp2;
- break;
- case '-':
- number_buffer_.push_back(static_cast<char>(*p_));
- stack_.back() = states::exp2;
- break;
- case '0':
- case '1':case '2':case '3':case '4':case '5':case '6':case '7':case '8': case '9':
- number_buffer_.push_back(static_cast<char>(*p_));
- stack_.back() = states::exp3;
- break;
- default:
- err_handler_->error(std::error_code(json_parser_errc::expected_value, json_error_category()), *this);
- break;
- }
- }
- ++p_;
- ++column_;
- break;
- case states::exp2:
- {
- switch (*p_)
- {
- case '0':
- case '1':case '2':case '3':case '4':case '5':case '6':case '7':case '8': case '9':
- number_buffer_.push_back(static_cast<char>(*p_));
- stack_.back() = states::exp3;
- break;
- default:
- err_handler_->error(std::error_code(json_parser_errc::expected_value, json_error_category()), *this);
- break;
- }
- }
- ++p_;
- ++column_;
- break;
- case states::exp3:
- {
- switch (*p_)
- {
- case '\r':
- end_fraction_value();
- stack_.push_back(states::cr);
- break;
- case '\n':
- end_fraction_value();
- stack_.push_back(states::lf);
- break;
- case ' ':case '\t':
- end_fraction_value();
- do_space();
- break;
- case '/':
- end_fraction_value();
- stack_.push_back(states::slash);
- break;
- case '}':
- end_fraction_value();
- do_end_object();
- break;
- case ']':
- end_fraction_value();
- do_end_array();
- break;
- case ',':
- end_fraction_value();
- begin_member_or_element();
- break;
- case '0':
- case '1':case '2':case '3':case '4':case '5':case '6':case '7':case '8': case '9':
- number_buffer_.push_back(static_cast<char>(*p_));
- stack_.back() = states::exp3;
- break;
- default:
- err_handler_->error(std::error_code(json_parser_errc::invalid_number, json_error_category()), *this);
- break;
- }
- }
- ++p_;
- ++column_;
- break;
- case states::t:
- while (p_ < end_input_ && literal_index_ < literal_.second)
- {
- if (*p_ != literal_.first[literal_index_])
- {
- err_handler_->error(std::error_code(json_parser_errc::invalid_value, json_error_category()), *this);
- }
- ++p_;
- ++literal_index_;
- ++column_;
- }
- if (literal_index_ == literal_.second)
- {
- handler_->value(true, *this);
- JSONCONS_ASSERT(stack_.size() >= 2);
- if (parent() == states::root)
- {
- stack_.back() = states::done;
- handler_->end_json();
- }
- else
- {
- stack_.back() = states::expect_comma_or_end;
- }
- }
- break;
- case states::f:
- while (p_ < end_input_ && literal_index_ < literal_.second)
- {
- if (*p_ != literal_.first[literal_index_])
- {
- err_handler_->error(std::error_code(json_parser_errc::invalid_value, json_error_category()), *this);
- }
- ++p_;
- ++literal_index_;
- ++column_;
- }
- if (literal_index_ == literal_.second)
- {
- handler_->value(false, *this);
- JSONCONS_ASSERT(stack_.size() >= 2);
- if (parent() == states::root)
- {
- stack_.back() = states::done;
- handler_->end_json();
- }
- else
- {
- stack_.back() = states::expect_comma_or_end;
- }
- }
- break;
- case states::n:
- while (p_ < end_input_ && literal_index_ < literal_.second)
- {
- if (*p_ != literal_.first[literal_index_])
- {
- err_handler_->error(std::error_code(json_parser_errc::invalid_value, json_error_category()), *this);
- }
- ++p_;
- ++literal_index_;
- ++column_;
- }
- if (literal_index_ == literal_.second)
- {
- handler_->value(null_type(), *this);
- JSONCONS_ASSERT(stack_.size() >= 2);
- if (parent() == states::root)
- {
- stack_.back() = states::done;
- handler_->end_json();
- }
- else
- {
- stack_.back() = states::expect_comma_or_end;
- }
- }
- break;
- case states::slash:
- {
- switch (*p_)
- {
- case '*':
- stack_.back() = states::slash_star;
- break;
- case '/':
- stack_.back() = states::slash_slash;
- break;
- default:
- err_handler_->error(std::error_code(json_parser_errc::invalid_json_text, json_error_category()), *this);
- break;
- }
- }
- ++p_;
- ++column_;
- break;
- case states::slash_star:
- {
- switch (*p_)
- {
- case '\r':
- stack_.push_back(states::cr);
- break;
- case '\n':
- stack_.push_back(states::lf);
- break;
- case '*':
- stack_.back() = states::slash_star_star;
- break;
- }
- }
- ++p_;
- ++column_;
- break;
- case states::slash_slash:
- {
- switch (*p_)
- {
- case '\r':
- stack_.pop_back();
- break;
- case '\n':
- stack_.pop_back();
- break;
- default:
- ++p_;
- ++column_;
- }
- }
- break;
- case states::slash_star_star:
- {
- switch (*p_)
- {
- case '/':
- JSONCONS_ASSERT(!stack_.empty())
- stack_.pop_back();
- break;
- default:
- stack_.back() = states::slash_star;
- break;
- }
- }
- ++p_;
- ++column_;
- break;
- default:
- JSONCONS_THROW_EXCEPTION(std::runtime_error,"Bad parser state");
- break;
- }
- }
- index_ += (p_-begin_input_);
- }
-
- void end_parse()
- {
- JSONCONS_ASSERT(stack_.size() >= 2);
- if (parent() == states::root)
- {
- switch (stack_.back())
- {
- case states::zero:
- case states::integer:
- end_integer_value();
- break;
- case states::fraction:
- case states::exp3:
- end_fraction_value();
- break;
- default:
- break;
- }
- }
- if (stack_.back() == states::lf || stack_.back() == states::cr)
- {
- stack_.pop_back();
- }
- if (!(stack_.back() == states::done || stack_.back() == states::start))
- {
- err_handler_->error(std::error_code(json_parser_errc::unexpected_eof, json_error_category()), *this);
- }
- }
-
- states state() const
- {
- return stack_.back();
- }
-
- size_t index() const
- {
- return index_;
- }
-private:
- void end_fraction_value()
- {
- try
- {
- double d = float_reader_.read(number_buffer_.data(), precision_);
- if (is_negative_)
- d = -d;
- handler_->value(d, static_cast<uint8_t>(precision_), *this);
- }
- catch (...)
- {
- err_handler_->error(std::error_code(json_parser_errc::invalid_number, json_error_category()), *this);
- handler_->value(null_type(), *this); // recovery
- }
- number_buffer_.clear();
- is_negative_ = false;
-
- JSONCONS_ASSERT(stack_.size() >= 2);
- switch (parent())
- {
- case states::array:
- case states::object:
- stack_.back() = states::expect_comma_or_end;
- break;
- case states::root:
- stack_.back() = states::done;
- handler_->end_json();
- break;
- default:
- err_handler_->error(std::error_code(json_parser_errc::invalid_json_text, json_error_category()), *this);
- break;
- }
- }
-
- void end_integer_value()
- {
- if (is_negative_)
- {
- try
- {
- int64_t d = string_to_integer(is_negative_, number_buffer_.data(), number_buffer_.length());
- handler_->value(d, *this);
- }
- catch (const std::exception&)
- {
- try
- {
- double d = float_reader_.read(number_buffer_.data(), number_buffer_.length());
- handler_->value(-d, static_cast<uint8_t>(number_buffer_.length()), *this);
- }
- catch (...)
- {
- err_handler_->error(std::error_code(json_parser_errc::invalid_number, json_error_category()), *this);
- handler_->value(null_type(), *this);
- }
- }
- }
- else
- {
- try
- {
- uint64_t d = string_to_uinteger(number_buffer_.data(), number_buffer_.length());
- handler_->value(d, *this);
- }
- catch (const std::exception&)
- {
- try
- {
- double d = float_reader_.read(number_buffer_.data(),number_buffer_.length());
- handler_->value(d, static_cast<uint8_t>(number_buffer_.length()), *this);
- }
- catch (...)
- {
- err_handler_->error(std::error_code(json_parser_errc::invalid_number, json_error_category()), *this);
- handler_->value(null_type(), *this);
- }
- }
- }
-
- JSONCONS_ASSERT(stack_.size() >= 2);
- switch (parent())
- {
- case states::array:
- case states::object:
- stack_.back() = states::expect_comma_or_end;
- break;
- case states::root:
- stack_.back() = states::done;
- handler_->end_json();
- break;
- default:
- err_handler_->error(std::error_code(json_parser_errc::invalid_json_text, json_error_category()), *this);
- break;
- }
- number_buffer_.clear();
- is_negative_ = false;
- }
-
- void append_codepoint(int c)
- {
- switch (c)
- {
- case '0': case '1':case '2':case '3':case '4':case '5':case '6':case '7':case '8': case '9':
- case 'a':case 'b':case 'c':case 'd':case 'e':case 'f':
- case 'A':case 'B':case 'C':case 'D':case 'E':case 'F':
- cp_ = append_to_codepoint(cp_, c);
- break;
- default:
- err_handler_->error(std::error_code(json_parser_errc::expected_value, json_error_category()), *this);
- break;
- }
- }
-
- void append_second_codepoint(int c)
- {
- switch (c)
- {
- case '0':
- case '1':case '2':case '3':case '4':case '5':case '6':case '7':case '8': case '9':
- case 'a':case 'b':case 'c':case 'd':case 'e':case 'f':
- case 'A':case 'B':case 'C':case 'D':case 'E':case 'F':
- cp2_ = append_to_codepoint(cp2_, c);
- break;
- default:
- err_handler_->error(std::error_code(json_parser_errc::expected_value, json_error_category()), *this);
- break;
- }
- }
-
- void escape_next_char(int next_input)
- {
- switch (next_input)
- {
- case '\"':
- string_buffer_.push_back('\"');
- stack_.back() = states::string;
- break;
- case '\\':
- string_buffer_.push_back('\\');
- stack_.back() = states::string;
- break;
- case '/':
- string_buffer_.push_back('/');
- stack_.back() = states::string;
- break;
- case 'b':
- string_buffer_.push_back('\b');
- stack_.back() = states::string;
- break;
- case 'f':
- string_buffer_.push_back('\f');
- stack_.back() = states::string;
- break;
- case 'n':
- string_buffer_.push_back('\n');
- stack_.back() = states::string;
- break;
- case 'r':
- string_buffer_.push_back('\r');
- stack_.back() = states::string;
- break;
- case 't':
- string_buffer_.push_back('\t');
- stack_.back() = states::string;
- break;
- case 'u':
- cp_ = 0;
- stack_.back() = states::u1;
- break;
- default:
- err_handler_->error(std::error_code(json_parser_errc::illegal_escaped_character, json_error_category()), *this);
- break;
- }
- }
-
- void end_string_value(const CharT* s, size_t length)
- {
- JSONCONS_ASSERT(stack_.size() >= 2);
- switch (parent())
- {
- case states::member_name:
- handler_->name(s, length, *this);
- stack_.pop_back();
- stack_.back() = states::expect_colon;
- break;
- case states::object:
- case states::array:
- handler_->value(s, length, *this);
- stack_.back() = states::expect_comma_or_end;
- break;
- case states::root:
- handler_->value(s, length, *this);
- stack_.back() = states::done;
- handler_->end_json();
- break;
- default:
- err_handler_->error(std::error_code(json_parser_errc::invalid_json_text, json_error_category()), *this);
- break;
- }
- }
-
- void begin_member_or_element()
- {
- JSONCONS_ASSERT(stack_.size() >= 2);
- switch (parent())
- {
- case states::object:
- stack_.back() = states::expect_member_name;
- break;
- case states::array:
- stack_.back() = states::expect_value;
- break;
- case states::root:
- break;
- default:
- err_handler_->error(std::error_code(json_parser_errc::invalid_json_text, json_error_category()), *this);
- break;
- }
- }
-
- uint32_t append_to_codepoint(uint32_t cp, int c)
- {
- cp *= 16;
- if (c >= '0' && c <= '9')
- {
- cp += c - '0';
- }
- else if (c >= 'a' && c <= 'f')
- {
- cp += c - 'a' + 10;
- }
- else if (c >= 'A' && c <= 'F')
- {
- cp += c - 'A' + 10;
- }
- else
- {
- err_handler_->error(std::error_code(json_parser_errc::invalid_hex_escape_sequence, json_error_category()), *this);
- }
- return cp;
- }
-
- size_t do_line_number() const override
- {
- return line_;
- }
-
- size_t do_column_number() const override
- {
- return column_;
- }
-
- CharT do_current_char() const override
- {
- return p_ < end_input_? *p_ : 0;
- }
-};
-
-typedef basic_json_parser<char> json_parser;
-typedef basic_json_parser<wchar_t> wjson_parser;
-
-}
-
-#endif
-