diff options
Diffstat (limited to 'vendor/jsoncons-0.99.2/jsoncons_ext/jsonpath/json_query.hpp')
-rw-r--r-- | vendor/jsoncons-0.99.2/jsoncons_ext/jsonpath/json_query.hpp | 921 |
1 files changed, 0 insertions, 921 deletions
diff --git a/vendor/jsoncons-0.99.2/jsoncons_ext/jsonpath/json_query.hpp b/vendor/jsoncons-0.99.2/jsoncons_ext/jsonpath/json_query.hpp deleted file mode 100644 index 7e530abd..00000000 --- a/vendor/jsoncons-0.99.2/jsoncons_ext/jsonpath/json_query.hpp +++ /dev/null @@ -1,921 +0,0 @@ -// Copyright 2013 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_JSONPATH_JSONQUERY_HPP -#define JSONCONS_JSONPATH_JSONQUERY_HPP - -#include <string> -#include <sstream> -#include <vector> -#include <istream> -#include <cstdlib> -#include <memory> -#include "jsoncons/json.hpp" -#include "jsonpath_filter.hpp" -#include "jsonpath_error_category.hpp" - -namespace jsoncons { namespace jsonpath { - - template<typename CharT> - bool try_string_to_index(const CharT *s, size_t length, size_t* value) - { - static const size_t max_value = std::numeric_limits<size_t>::max JSONCONS_NO_MACRO_EXP(); - static const size_t max_value_div_10 = max_value / 10; - - size_t n = 0; - for (size_t i = 0; i < length; ++i) - { - CharT c = s[i]; - switch (c) - { - case '0':case '1':case '2':case '3':case '4':case '5':case '6':case '7':case '8':case '9': - { - size_t x = c - '0'; - if (n > max_value_div_10) - { - return false; - } - n = n * 10; - if (n > max_value - x) - { - return false; - } - - n += x; - } - break; - default: - return false; - break; - } - } - *value = n; - return true; - } - - template <typename CharT> - struct json_jsonpath_traits - { - }; - - template <> - struct json_jsonpath_traits<char> - { - static const std::string length_literal() {return "length";}; - }; - - template <> - struct json_jsonpath_traits<wchar_t> // assume utf16 - { - static const std::wstring length_literal() {return L"length";}; - }; - -// here - -template<class JsonT> -JsonT json_query(const JsonT& root, const typename JsonT::char_type* path, size_t length) -{ - jsonpath_evaluator<JsonT> evaluator; - evaluator.evaluate(root,path,length); - return evaluator.get_values(); -} - -template<class JsonT> -JsonT json_query(const JsonT& root, const typename JsonT::string_type& path) -{ - return json_query(root,path.data(),path.length()); -} - -template<class JsonT> -JsonT json_query(const JsonT& root, const typename JsonT::char_type* path) -{ - return json_query(root,path,std::char_traits<typename JsonT::char_type>::length(path)); -} - -enum class states -{ - start, - cr, - lf, - expect_separator, - expect_unquoted_name, - unquoted_name, - single_quoted_name, - double_quoted_name, - left_bracket, - left_bracket_start, - left_bracket_end, - left_bracket_end2, - left_bracket_step, - left_bracket_step2, - expect_right_bracket, - dot -}; - -template<class JsonT> -class jsonpath_evaluator : private basic_parsing_context<typename JsonT::char_type> -{ -private: - typedef typename JsonT::char_type char_type; - typedef typename JsonT::string_type string_type; - typedef const JsonT* cjson_ptr; - typedef std::vector<cjson_ptr> node_set; - - basic_parse_error_handler<char_type> *err_handler_; - states state_; - string_type buffer_; - size_t start_; - size_t end_; - size_t step_; - bool positive_start_; - bool positive_end_; - bool positive_step_; - bool end_undefined_; - std::vector<node_set> stack_; - bool recursive_descent_; - std::vector<cjson_ptr> nodes_; - std::vector<std::shared_ptr<JsonT>> temp_; - size_t line_; - size_t column_; - const char_type* begin_input_; - const char_type* end_input_; - const char_type* p_; - states pre_line_break_state_; - - void transfer_nodes() - { - stack_.push_back(nodes_); - nodes_.clear(); - } - -public: - jsonpath_evaluator() - : err_handler_(std::addressof(basic_default_parse_error_handler<char_type>::instance())) - { - } - - JsonT get_values() const - { - JsonT result = JsonT::make_array(); - - if (stack_.size() > 0) - { - for (size_t i = 0; i < stack_.back().size(); ++i) - { - cjson_ptr p = stack_.back()[i]; - result.add(*p); - } - } - return result; - } - - void evaluate(const JsonT& root, const string_type& path) - { - evaluate(root,path.data(),path.length()); - } - void evaluate(const JsonT& root, const char_type* path) - { - evaluate(root,path,std::char_traits<char_type>::length(path)); - } - - void evaluate(const JsonT& root, const char_type* path, size_t length) - { - begin_input_ = path; - end_input_ = path + length; - p_ = begin_input_; - - line_ = 1; - column_ = 1; - state_ = states::start; - buffer_.clear(); - start_ = 0; - end_ = 0; - step_ = 1; - recursive_descent_ = false; - positive_start_ = true; - positive_end_ = true; - positive_step_ = true; - end_undefined_ = false; - - while (p_ < end_input_) - { - switch (state_) - { - case states::cr: - ++line_; - column_ = 1; - switch (*p_) - { - case '\n': - state_ = pre_line_break_state_; - ++p_; - ++column_; - break; - default: - state_ = pre_line_break_state_; - break; - } - break; - case states::lf: - ++line_; - column_ = 1; - state_ = pre_line_break_state_; - break; - case states::start: - switch (*p_) - { - case '\r': - pre_line_break_state_ = state_; - state_ = states::cr; - break; - case '\n': - pre_line_break_state_ = state_; - state_ = states::lf; - break; - case ' ':case '\t': - ++p_; - ++column_; - break; - case '$': - case '@': - { - node_set v; - v.push_back(std::addressof(root)); - stack_.push_back(v); - state_ = states::expect_separator; - } - break; - default: - err_handler_->fatal_error(std::error_code(jsonpath_parser_errc::expected_root, jsonpath_error_category()), *this); - break; - }; - ++p_; - ++column_; - break; - case states::dot: - switch (*p_) - { - case '.': - recursive_descent_ = true; - ++p_; - ++column_; - state_ = states::expect_unquoted_name; - break; - default: - state_ = states::expect_unquoted_name; - break; - } - break; - case states::expect_unquoted_name: - switch (*p_) - { - case '\r': - pre_line_break_state_ = state_; - state_ = states::cr; - break; - case '\n': - pre_line_break_state_ = state_; - state_ = states::lf; - break; - case '.': - err_handler_->fatal_error(std::error_code(jsonpath_parser_errc::expected_name, jsonpath_error_category()), *this); - ++p_; - ++column_; - break; - case '*': - end_all(); - transfer_nodes(); - state_ = states::expect_separator; - ++p_; - ++column_; - break; - default: - state_ = states::unquoted_name; - break; - } - break; - case states::expect_separator: - switch (*p_) - { - case '\r': - pre_line_break_state_ = state_; - state_ = states::cr; - break; - case '\n': - pre_line_break_state_ = state_; - state_ = states::lf; - break; - case ' ':case '\t': - ++p_; - ++column_; - break; - case '.': - state_ = states::dot; - break; - case '[': - state_ = states::left_bracket; - break; - default: - err_handler_->fatal_error(std::error_code(jsonpath_parser_errc::expected_separator, jsonpath_error_category()), *this); - break; - }; - ++p_; - ++column_; - break; - case states::expect_right_bracket: - switch (*p_) - { - case '\r': - pre_line_break_state_ = state_; - state_ = states::cr; - break; - case '\n': - pre_line_break_state_ = state_; - state_ = states::lf; - break; - case ',': - state_ = states::left_bracket; - break; - case ']': - transfer_nodes(); - state_ = states::expect_separator; - break; - case ' ':case '\t': - break; - default: - err_handler_->fatal_error(std::error_code(jsonpath_parser_errc::expected_right_bracket, jsonpath_error_category()), *this); - break; - } - ++p_; - ++column_; - break; - case states::left_bracket_step: - switch (*p_) - { - case '\r': - pre_line_break_state_ = state_; - state_ = states::cr; - break; - case '\n': - pre_line_break_state_ = state_; - state_ = states::lf; - break; - case '-': - positive_step_ = false; - state_ = states::left_bracket_step2; - break; - case '0':case '1':case '2':case '3':case '4':case '5':case '6':case '7':case '8':case '9': - step_ = static_cast<size_t>(*p_-'0'); - state_ = states::left_bracket_step2; - break; - case ']': - end_array_slice(); - transfer_nodes(); - state_ = states::expect_separator; - break; - } - ++p_; - ++column_; - break; - case states::left_bracket_step2: - switch (*p_) - { - case '\r': - pre_line_break_state_ = state_; - state_ = states::cr; - break; - case '\n': - pre_line_break_state_ = state_; - state_ = states::lf; - break; - case '0':case '1':case '2':case '3':case '4':case '5':case '6':case '7':case '8':case '9': - step_ = step_*10 + static_cast<size_t>(*p_-'0'); - break; - case ']': - end_array_slice(); - transfer_nodes(); - state_ = states::expect_separator; - break; - } - ++p_; - ++column_; - break; - case states::left_bracket_end: - switch (*p_) - { - case '\r': - pre_line_break_state_ = state_; - state_ = states::cr; - break; - case '\n': - pre_line_break_state_ = state_; - state_ = states::lf; - break; - case '-': - positive_end_ = false; - state_ = states::left_bracket_end2; - break; - case ':': - step_ = 0; - state_ = states::left_bracket_step; - break; - case '0':case '1':case '2':case '3':case '4':case '5':case '6':case '7':case '8':case '9': - end_undefined_ = false; - end_ = static_cast<size_t>(*p_-'0'); - state_ = states::left_bracket_end2; - break; - case ']': - end_array_slice(); - transfer_nodes(); - state_ = states::expect_separator; - break; - } - ++p_; - ++column_; - break; - case states::left_bracket_end2: - switch (*p_) - { - case '\r': - pre_line_break_state_ = state_; - state_ = states::cr; - break; - case '\n': - pre_line_break_state_ = state_; - state_ = states::lf; - break; - case ':': - step_ = 0; - state_ = states::left_bracket_step; - break; - case '0':case '1':case '2':case '3':case '4':case '5':case '6':case '7':case '8':case '9': - end_undefined_ = false; - end_ = end_*10 + static_cast<size_t>(*p_-'0'); - break; - case ']': - end_array_slice(); - transfer_nodes(); - state_ = states::expect_separator; - break; - } - ++p_; - ++column_; - break; - case states::left_bracket_start: - switch (*p_) - { - case '\r': - pre_line_break_state_ = state_; - state_ = states::cr; - break; - case '\n': - pre_line_break_state_ = state_; - state_ = states::lf; - break; - case ':': - step_ = 1; - end_undefined_ = true; - state_ = states::left_bracket_end; - break; - case ',': - find_elements(); - break; - case '0':case '1':case '2':case '3':case '4':case '5':case '6':case '7':case '8':case '9': - start_ = start_*10 + static_cast<size_t>(*p_-'0'); - break; - case ']': - find_elements(); - transfer_nodes(); - state_ = states::expect_separator; - break; - } - ++p_; - ++column_; - break; - case states::left_bracket: - switch (*p_) - { - case '\r': - pre_line_break_state_ = state_; - state_ = states::cr; - break; - case '\n': - pre_line_break_state_ = state_; - state_ = states::lf; - break; - case ' ':case '\t': - ++p_; - ++column_; - break; - case '(': - { - if (stack_.back().size() == 1) - { - jsonpath_filter_parser<JsonT> parser(&p_,&line_,&column_); - parser.parse(p_,end_input_); - auto index = parser.eval(*(stack_.back()[0])); - if (index.template is<size_t>()) - { - start_ = index. template as<size_t>(); - find_elements(); - } - else if (index.is_string()) - { - find(index.as_string()); - } - } - else - { - ++p_; - ++column_; - } - } - break; - case '?': - { - jsonpath_filter_parser<JsonT> parser(&p_,&line_,&column_); - parser.parse(p_,end_input_); - nodes_.clear(); - for (size_t j = 0; j < stack_.back().size(); ++j) - { - accept(*(stack_.back()[j]),parser); - } - } - break; - - case ':': - step_ = 1; - end_undefined_ = true; - state_ = states::left_bracket_end; - ++p_; - ++column_; - break; - case ',': - find_elements(); - ++p_; - ++column_; - break; - case '-': - positive_start_ = false; - state_ = states::left_bracket_start; - ++p_; - ++column_; - break; - case '0':case '1':case '2':case '3':case '4':case '5':case '6':case '7':case '8':case '9': - start_ = static_cast<size_t>(*p_-'0'); - state_ = states::left_bracket_start; - ++p_; - ++column_; - break; - case ']': - //find_elements(); - transfer_nodes(); - state_ = states::expect_separator; - ++p_; - ++column_; - break; - case '*': - end_all(); - //transfer_nodes(); - state_ = states::expect_right_bracket; - ++p_; - ++column_; - break; - case '\'': - state_ = states::single_quoted_name; - ++p_; - ++column_; - break; - case '\"': - state_ = states::double_quoted_name; - ++p_; - ++column_; - break; - default: - ++p_; - ++column_; - break; - } - break; - case states::unquoted_name: - switch (*p_) - { - case '\r': - pre_line_break_state_ = state_; - state_ = states::cr; - break; - case '\n': - pre_line_break_state_ = state_; - state_ = states::lf; - break; - case '[': - find(buffer_); - buffer_.clear(); - transfer_nodes(); - start_ = 0; - state_ = states::left_bracket; - break; - case '.': - find(buffer_); - buffer_.clear(); - transfer_nodes(); - state_ = states::dot; - break; - case ' ':case '\t': - break; - default: - buffer_.push_back(*p_); - break; - }; - ++p_; - ++column_; - break; - case states::single_quoted_name: - switch (*p_) - { - case '\'': - find(buffer_); - buffer_.clear(); - state_ = states::expect_right_bracket; - break; - case '\\': - buffer_.push_back(*p_); - if (p_+1 < end_input_) - { - ++p_; - ++column_; - buffer_.push_back(*p_); - } - break; - default: - buffer_.push_back(*p_); - break; - }; - ++p_; - ++column_; - break; - case states::double_quoted_name: - switch (*p_) - { - case '\"': - find(buffer_); - buffer_.clear(); - state_ = states::expect_right_bracket; - break; - case '\\': - buffer_.push_back(*p_); - if (p_+1 < end_input_) - { - ++p_; - ++column_; - buffer_.push_back(*p_); - } - break; - default: - buffer_.push_back(*p_); - break; - }; - ++p_; - ++column_; - break; - default: - ++p_; - ++column_; - break; - } - } - switch (state_) - { - case states::unquoted_name: - { - find(buffer_); - buffer_.clear(); - transfer_nodes(); - } - break; - default: - break; - } - } - - void accept(const JsonT& val, - jsonpath_filter_parser<JsonT>& filter) - { - if (val.is_object()) - { - if (recursive_descent_ && val.is_object()) - { - for (auto it = val.members().begin(); it != val.members().end(); ++it) - { - accept(it->value(),filter); - } - } - if (filter.exists(val)) - { - nodes_.push_back(std::addressof(val)); - } - } - else if (val.is_array()) - { - for (auto it = val.elements().begin(); it != val.elements().end(); ++it) - { - accept(*it,filter); - } - } - } - - - - void end_all() - { - for (size_t i = 0; i < stack_.back().size(); ++i) - { - cjson_ptr p = stack_.back()[i]; - if (p->is_array()) - { - for (auto it = p->elements().begin(); it != p->elements().end(); ++it) - { - nodes_.push_back(std::addressof(*it)); - } - } - else if (p->is_object()) - { - for (auto it = p->members().begin(); it != p->members().end(); ++it) - { - nodes_.push_back(std::addressof(it->value())); - } - } - - } - start_ = 0; - } - - void find_elements() - { - for (size_t i = 0; i < stack_.back().size(); ++i) - { - cjson_ptr p = stack_.back()[i]; - if (p->is_array() && start_ < p->size()) - { - nodes_.push_back(std::addressof((*p)[start_])); - } - } - start_ = 0; - } - - void end_array_slice() - { - if (positive_step_) - { - end_array_slice1(); - } - else - { - end_array_slice2(); - } - start_ = 0; - end_ = 0; - step_ = 1; - positive_start_ = positive_end_ = positive_step_ = true; - end_undefined_ = true; - } - - void end_array_slice1() - { - for (size_t i = 0; i < stack_.back().size(); ++i) - { - cjson_ptr p = stack_.back()[i]; - if (p->is_array()) - { - size_t start = positive_start_ ? start_ : p->size() - start_; - size_t end; - if (!end_undefined_) - { - end = positive_end_ ? end_ : p->size() - end_; - } - else - { - end = p->size(); - } - for (size_t j = start; j < end; j += step_) - { - if (p->is_array() && j < p->size()) - { - nodes_.push_back(std::addressof((*p)[j])); - } - } - } - } - } - - void end_array_slice2() - { - for (size_t i = 0; i < stack_.back().size(); ++i) - { - cjson_ptr p = stack_.back()[i]; - size_t start = positive_start_ ? start_ : p->size() - start_; - size_t end; - if (!end_undefined_) - { - end = positive_end_ ? end_ : p->size() - end_; - } - else - { - end = p->size(); - } - - size_t j = end + step_ - 1; - while (j > (start+step_-1)) - { - j -= step_; - if (p->is_array() && j < p->size()) - { - nodes_.push_back(std::addressof((*p)[j])); - } - } - } - } - - void find(const string_type& name) - { - if (name.length() > 0) - { - for (size_t i = 0; i < stack_.back().size(); ++i) - { - find1(*(stack_.back()[i]), name); - } - recursive_descent_ = false; - } - } - - void find1(const JsonT& context_val, const string_type& name) - { - if (context_val.is_object()) - { - if (context_val.count(name) > 0) - { - nodes_.push_back(std::addressof(context_val.at(name))); - } - if (recursive_descent_) - { - for (auto it = context_val.members().begin(); it != context_val.members().end(); ++it) - { - if (it->value().is_object() || it->value().is_array()) - { - find1(it->value(), name); - } - } - } - } - else if (context_val.is_array()) - { - size_t index = 0; - if (try_string_to_index(name.data(),name.size(),&index)) - { - if (index < context_val.size()) - { - nodes_.push_back(std::addressof(context_val[index])); - } - } - else if (name == json_jsonpath_traits<char_type>::length_literal() && context_val.size() > 0) - { - auto q = std::make_shared<JsonT>(context_val.size()); - temp_.push_back(q); - nodes_.push_back(q.get()); - } - if (recursive_descent_) - { - for (auto it = context_val.elements().begin(); it != context_val.elements().end(); ++it) - { - if (it->is_object() || it->is_array()) - { - find1(*it, name); - } - } - } - } - } - - size_t do_line_number() const override - { - return line_; - } - - size_t do_column_number() const override - { - return column_; - } - - char_type do_current_char() const override - { - return 0; //p_ < end_input_? *p_ : 0; - } - -}; - -}} - -#endif |