jsoncons 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/ext/jsoncons/extconf.rb +43 -0
- data/ext/jsoncons/jsoncons.cpp +161 -0
- data/ext/jsoncons/jsoncons.h +10 -0
- data/jsoncons.gemspec +44 -0
- data/lib/jsoncons/jsoncons/examples/input/address-book.json +13 -0
- data/lib/jsoncons/jsoncons/examples/input/books.json +28 -0
- data/lib/jsoncons/jsoncons/examples/input/countries.json +7 -0
- data/lib/jsoncons/jsoncons/examples/input/employees.json +30 -0
- data/lib/jsoncons/jsoncons/examples/input/jsonschema/name.json +15 -0
- data/lib/jsoncons/jsoncons/examples/input/multiple-json-objects.json +3 -0
- data/lib/jsoncons/jsoncons/examples/input/sales.csv +6 -0
- data/lib/jsoncons/jsoncons/examples/input/store.json +28 -0
- data/lib/jsoncons/jsoncons/examples/input/tasks.csv +6 -0
- data/lib/jsoncons/jsoncons/include/jsoncons/allocator_holder.hpp +38 -0
- data/lib/jsoncons/jsoncons/include/jsoncons/basic_json.hpp +5905 -0
- data/lib/jsoncons/jsoncons/include/jsoncons/bigint.hpp +1611 -0
- data/lib/jsoncons/jsoncons/include/jsoncons/byte_string.hpp +820 -0
- data/lib/jsoncons/jsoncons/include/jsoncons/config/binary_config.hpp +226 -0
- data/lib/jsoncons/jsoncons/include/jsoncons/config/compiler_support.hpp +375 -0
- data/lib/jsoncons/jsoncons/include/jsoncons/config/jsoncons_config.hpp +309 -0
- data/lib/jsoncons/jsoncons/include/jsoncons/config/version.hpp +40 -0
- data/lib/jsoncons/jsoncons/include/jsoncons/conv_error.hpp +218 -0
- data/lib/jsoncons/jsoncons/include/jsoncons/decode_json.hpp +209 -0
- data/lib/jsoncons/jsoncons/include/jsoncons/decode_traits.hpp +651 -0
- data/lib/jsoncons/jsoncons/include/jsoncons/detail/endian.hpp +44 -0
- data/lib/jsoncons/jsoncons/include/jsoncons/detail/grisu3.hpp +312 -0
- data/lib/jsoncons/jsoncons/include/jsoncons/detail/optional.hpp +483 -0
- data/lib/jsoncons/jsoncons/include/jsoncons/detail/parse_number.hpp +1133 -0
- data/lib/jsoncons/jsoncons/include/jsoncons/detail/span.hpp +188 -0
- data/lib/jsoncons/jsoncons/include/jsoncons/detail/string_view.hpp +537 -0
- data/lib/jsoncons/jsoncons/include/jsoncons/detail/string_wrapper.hpp +370 -0
- data/lib/jsoncons/jsoncons/include/jsoncons/detail/write_number.hpp +567 -0
- data/lib/jsoncons/jsoncons/include/jsoncons/encode_json.hpp +315 -0
- data/lib/jsoncons/jsoncons/include/jsoncons/encode_traits.hpp +378 -0
- data/lib/jsoncons/jsoncons/include/jsoncons/json.hpp +18 -0
- data/lib/jsoncons/jsoncons/include/jsoncons/json_array.hpp +324 -0
- data/lib/jsoncons/jsoncons/include/jsoncons/json_content_handler.hpp +12 -0
- data/lib/jsoncons/jsoncons/include/jsoncons/json_cursor.hpp +448 -0
- data/lib/jsoncons/jsoncons/include/jsoncons/json_decoder.hpp +420 -0
- data/lib/jsoncons/jsoncons/include/jsoncons/json_encoder.hpp +1587 -0
- data/lib/jsoncons/jsoncons/include/jsoncons/json_error.hpp +156 -0
- data/lib/jsoncons/jsoncons/include/jsoncons/json_exception.hpp +241 -0
- data/lib/jsoncons/jsoncons/include/jsoncons/json_filter.hpp +653 -0
- data/lib/jsoncons/jsoncons/include/jsoncons/json_fwd.hpp +23 -0
- data/lib/jsoncons/jsoncons/include/jsoncons/json_object.hpp +1772 -0
- data/lib/jsoncons/jsoncons/include/jsoncons/json_options.hpp +862 -0
- data/lib/jsoncons/jsoncons/include/jsoncons/json_parser.hpp +2900 -0
- data/lib/jsoncons/jsoncons/include/jsoncons/json_reader.hpp +731 -0
- data/lib/jsoncons/jsoncons/include/jsoncons/json_traits_macros.hpp +1072 -0
- data/lib/jsoncons/jsoncons/include/jsoncons/json_traits_macros_deprecated.hpp +144 -0
- data/lib/jsoncons/jsoncons/include/jsoncons/json_type.hpp +206 -0
- data/lib/jsoncons/jsoncons/include/jsoncons/json_type_traits.hpp +1830 -0
- data/lib/jsoncons/jsoncons/include/jsoncons/json_visitor.hpp +1560 -0
- data/lib/jsoncons/jsoncons/include/jsoncons/json_visitor2.hpp +2079 -0
- data/lib/jsoncons/jsoncons/include/jsoncons/pretty_print.hpp +89 -0
- data/lib/jsoncons/jsoncons/include/jsoncons/ser_context.hpp +62 -0
- data/lib/jsoncons/jsoncons/include/jsoncons/sink.hpp +289 -0
- data/lib/jsoncons/jsoncons/include/jsoncons/source.hpp +777 -0
- data/lib/jsoncons/jsoncons/include/jsoncons/source_adaptor.hpp +148 -0
- data/lib/jsoncons/jsoncons/include/jsoncons/staj2_cursor.hpp +1189 -0
- data/lib/jsoncons/jsoncons/include/jsoncons/staj_cursor.hpp +1254 -0
- data/lib/jsoncons/jsoncons/include/jsoncons/staj_iterator.hpp +449 -0
- data/lib/jsoncons/jsoncons/include/jsoncons/tag_type.hpp +245 -0
- data/lib/jsoncons/jsoncons/include/jsoncons/text_source_adaptor.hpp +144 -0
- data/lib/jsoncons/jsoncons/include/jsoncons/traits_extension.hpp +884 -0
- data/lib/jsoncons/jsoncons/include/jsoncons/typed_array_view.hpp +250 -0
- data/lib/jsoncons/jsoncons/include/jsoncons/unicode_traits.hpp +1330 -0
- data/lib/jsoncons/jsoncons/include/jsoncons/uri.hpp +635 -0
- data/lib/jsoncons/jsoncons/include/jsoncons/value_converter.hpp +340 -0
- data/lib/jsoncons/jsoncons/include/jsoncons_ext/bson/bson.hpp +23 -0
- data/lib/jsoncons/jsoncons/include/jsoncons_ext/bson/bson_cursor.hpp +320 -0
- data/lib/jsoncons/jsoncons/include/jsoncons_ext/bson/bson_decimal128.hpp +865 -0
- data/lib/jsoncons/jsoncons/include/jsoncons_ext/bson/bson_encoder.hpp +585 -0
- data/lib/jsoncons/jsoncons/include/jsoncons_ext/bson/bson_error.hpp +103 -0
- data/lib/jsoncons/jsoncons/include/jsoncons_ext/bson/bson_oid.hpp +245 -0
- data/lib/jsoncons/jsoncons/include/jsoncons_ext/bson/bson_options.hpp +75 -0
- data/lib/jsoncons/jsoncons/include/jsoncons_ext/bson/bson_parser.hpp +645 -0
- data/lib/jsoncons/jsoncons/include/jsoncons_ext/bson/bson_reader.hpp +92 -0
- data/lib/jsoncons/jsoncons/include/jsoncons_ext/bson/bson_type.hpp +44 -0
- data/lib/jsoncons/jsoncons/include/jsoncons_ext/bson/decode_bson.hpp +201 -0
- data/lib/jsoncons/jsoncons/include/jsoncons_ext/bson/encode_bson.hpp +144 -0
- data/lib/jsoncons/jsoncons/include/jsoncons_ext/cbor/cbor.hpp +26 -0
- data/lib/jsoncons/jsoncons/include/jsoncons_ext/cbor/cbor_cursor.hpp +351 -0
- data/lib/jsoncons/jsoncons/include/jsoncons_ext/cbor/cbor_cursor2.hpp +265 -0
- data/lib/jsoncons/jsoncons/include/jsoncons_ext/cbor/cbor_detail.hpp +93 -0
- data/lib/jsoncons/jsoncons/include/jsoncons_ext/cbor/cbor_encoder.hpp +1766 -0
- data/lib/jsoncons/jsoncons/include/jsoncons_ext/cbor/cbor_error.hpp +105 -0
- data/lib/jsoncons/jsoncons/include/jsoncons_ext/cbor/cbor_options.hpp +113 -0
- data/lib/jsoncons/jsoncons/include/jsoncons_ext/cbor/cbor_parser.hpp +1942 -0
- data/lib/jsoncons/jsoncons/include/jsoncons_ext/cbor/cbor_reader.hpp +116 -0
- data/lib/jsoncons/jsoncons/include/jsoncons_ext/cbor/decode_cbor.hpp +203 -0
- data/lib/jsoncons/jsoncons/include/jsoncons_ext/cbor/encode_cbor.hpp +151 -0
- data/lib/jsoncons/jsoncons/include/jsoncons_ext/csv/csv.hpp +17 -0
- data/lib/jsoncons/jsoncons/include/jsoncons_ext/csv/csv_cursor.hpp +358 -0
- data/lib/jsoncons/jsoncons/include/jsoncons_ext/csv/csv_encoder.hpp +954 -0
- data/lib/jsoncons/jsoncons/include/jsoncons_ext/csv/csv_error.hpp +85 -0
- data/lib/jsoncons/jsoncons/include/jsoncons_ext/csv/csv_options.hpp +973 -0
- data/lib/jsoncons/jsoncons/include/jsoncons_ext/csv/csv_parser.hpp +2099 -0
- data/lib/jsoncons/jsoncons/include/jsoncons_ext/csv/csv_reader.hpp +348 -0
- data/lib/jsoncons/jsoncons/include/jsoncons_ext/csv/csv_serializer.hpp +12 -0
- data/lib/jsoncons/jsoncons/include/jsoncons_ext/csv/decode_csv.hpp +208 -0
- data/lib/jsoncons/jsoncons/include/jsoncons_ext/csv/encode_csv.hpp +122 -0
- data/lib/jsoncons/jsoncons/include/jsoncons_ext/jmespath/jmespath.hpp +5215 -0
- data/lib/jsoncons/jsoncons/include/jsoncons_ext/jmespath/jmespath_error.hpp +215 -0
- data/lib/jsoncons/jsoncons/include/jsoncons_ext/jsonpatch/jsonpatch.hpp +579 -0
- data/lib/jsoncons/jsoncons/include/jsoncons_ext/jsonpatch/jsonpatch_error.hpp +121 -0
- data/lib/jsoncons/jsoncons/include/jsoncons_ext/jsonpath/expression.hpp +3329 -0
- data/lib/jsoncons/jsoncons/include/jsoncons_ext/jsonpath/flatten.hpp +432 -0
- data/lib/jsoncons/jsoncons/include/jsoncons_ext/jsonpath/json_location.hpp +445 -0
- data/lib/jsoncons/jsoncons/include/jsoncons_ext/jsonpath/json_query.hpp +115 -0
- data/lib/jsoncons/jsoncons/include/jsoncons_ext/jsonpath/jsonpath.hpp +13 -0
- data/lib/jsoncons/jsoncons/include/jsoncons_ext/jsonpath/jsonpath_error.hpp +240 -0
- data/lib/jsoncons/jsoncons/include/jsoncons_ext/jsonpath/jsonpath_expression.hpp +2612 -0
- data/lib/jsoncons/jsoncons/include/jsoncons_ext/jsonpath/jsonpath_selector.hpp +1322 -0
- data/lib/jsoncons/jsoncons/include/jsoncons_ext/jsonpointer/jsonpointer.hpp +1577 -0
- data/lib/jsoncons/jsoncons/include/jsoncons_ext/jsonpointer/jsonpointer_error.hpp +119 -0
- data/lib/jsoncons/jsoncons/include/jsoncons_ext/jsonschema/format_validator.hpp +968 -0
- data/lib/jsoncons/jsoncons/include/jsoncons_ext/jsonschema/json_validator.hpp +120 -0
- data/lib/jsoncons/jsoncons/include/jsoncons_ext/jsonschema/jsonschema.hpp +13 -0
- data/lib/jsoncons/jsoncons/include/jsoncons_ext/jsonschema/jsonschema_error.hpp +105 -0
- data/lib/jsoncons/jsoncons/include/jsoncons_ext/jsonschema/jsonschema_version.hpp +18 -0
- data/lib/jsoncons/jsoncons/include/jsoncons_ext/jsonschema/keyword_validator.hpp +1745 -0
- data/lib/jsoncons/jsoncons/include/jsoncons_ext/jsonschema/keyword_validator_factory.hpp +556 -0
- data/lib/jsoncons/jsoncons/include/jsoncons_ext/jsonschema/schema_draft7.hpp +198 -0
- data/lib/jsoncons/jsoncons/include/jsoncons_ext/jsonschema/schema_location.hpp +200 -0
- data/lib/jsoncons/jsoncons/include/jsoncons_ext/jsonschema/schema_version.hpp +35 -0
- data/lib/jsoncons/jsoncons/include/jsoncons_ext/jsonschema/subschema.hpp +144 -0
- data/lib/jsoncons/jsoncons/include/jsoncons_ext/mergepatch/mergepatch.hpp +103 -0
- data/lib/jsoncons/jsoncons/include/jsoncons_ext/msgpack/decode_msgpack.hpp +202 -0
- data/lib/jsoncons/jsoncons/include/jsoncons_ext/msgpack/encode_msgpack.hpp +142 -0
- data/lib/jsoncons/jsoncons/include/jsoncons_ext/msgpack/msgpack.hpp +24 -0
- data/lib/jsoncons/jsoncons/include/jsoncons_ext/msgpack/msgpack_cursor.hpp +343 -0
- data/lib/jsoncons/jsoncons/include/jsoncons_ext/msgpack/msgpack_cursor2.hpp +259 -0
- data/lib/jsoncons/jsoncons/include/jsoncons_ext/msgpack/msgpack_encoder.hpp +753 -0
- data/lib/jsoncons/jsoncons/include/jsoncons_ext/msgpack/msgpack_error.hpp +94 -0
- data/lib/jsoncons/jsoncons/include/jsoncons_ext/msgpack/msgpack_options.hpp +74 -0
- data/lib/jsoncons/jsoncons/include/jsoncons_ext/msgpack/msgpack_parser.hpp +748 -0
- data/lib/jsoncons/jsoncons/include/jsoncons_ext/msgpack/msgpack_reader.hpp +116 -0
- data/lib/jsoncons/jsoncons/include/jsoncons_ext/msgpack/msgpack_type.hpp +63 -0
- data/lib/jsoncons/jsoncons/include/jsoncons_ext/ubjson/decode_ubjson.hpp +201 -0
- data/lib/jsoncons/jsoncons/include/jsoncons_ext/ubjson/encode_ubjson.hpp +142 -0
- data/lib/jsoncons/jsoncons/include/jsoncons_ext/ubjson/ubjson.hpp +23 -0
- data/lib/jsoncons/jsoncons/include/jsoncons_ext/ubjson/ubjson_cursor.hpp +307 -0
- data/lib/jsoncons/jsoncons/include/jsoncons_ext/ubjson/ubjson_encoder.hpp +502 -0
- data/lib/jsoncons/jsoncons/include/jsoncons_ext/ubjson/ubjson_error.hpp +100 -0
- data/lib/jsoncons/jsoncons/include/jsoncons_ext/ubjson/ubjson_options.hpp +87 -0
- data/lib/jsoncons/jsoncons/include/jsoncons_ext/ubjson/ubjson_parser.hpp +880 -0
- data/lib/jsoncons/jsoncons/include/jsoncons_ext/ubjson/ubjson_reader.hpp +92 -0
- data/lib/jsoncons/jsoncons/include/jsoncons_ext/ubjson/ubjson_type.hpp +43 -0
- data/lib/jsoncons/version.rb +5 -0
- data/lib/jsoncons.rb +33 -0
- data/test/jsoncons_test.rb +108 -0
- data/test/test_helper.rb +7 -0
- metadata +268 -0
|
@@ -0,0 +1,1322 @@
|
|
|
1
|
+
// Copyright 2021 Daniel Parker
|
|
2
|
+
// Distributed under the Boost license, Version 1.0.
|
|
3
|
+
// (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
|
4
|
+
|
|
5
|
+
// See https://github.com/danielaparker/jsoncons for latest version
|
|
6
|
+
|
|
7
|
+
#ifndef JSONCONS_JSONPATH_JSONPATH_SELECTOR_HPP
|
|
8
|
+
#define JSONCONS_JSONPATH_JSONPATH_SELECTOR_HPP
|
|
9
|
+
|
|
10
|
+
#include <string>
|
|
11
|
+
#include <vector>
|
|
12
|
+
#include <memory>
|
|
13
|
+
#include <type_traits> // std::is_const
|
|
14
|
+
#include <limits> // std::numeric_limits
|
|
15
|
+
#include <utility> // std::move
|
|
16
|
+
#include <regex>
|
|
17
|
+
#include <jsoncons/json.hpp>
|
|
18
|
+
#include <jsoncons_ext/jsonpath/jsonpath_error.hpp>
|
|
19
|
+
#include <jsoncons_ext/jsonpath/expression.hpp>
|
|
20
|
+
|
|
21
|
+
namespace jsoncons {
|
|
22
|
+
namespace jsonpath {
|
|
23
|
+
namespace detail {
|
|
24
|
+
|
|
25
|
+
struct slice
|
|
26
|
+
{
|
|
27
|
+
jsoncons::optional<int64_t> start_;
|
|
28
|
+
jsoncons::optional<int64_t> stop_;
|
|
29
|
+
int64_t step_;
|
|
30
|
+
|
|
31
|
+
slice()
|
|
32
|
+
: start_(), stop_(), step_(1)
|
|
33
|
+
{
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
slice(const jsoncons::optional<int64_t>& start, const jsoncons::optional<int64_t>& end, int64_t step)
|
|
37
|
+
: start_(start), stop_(end), step_(step)
|
|
38
|
+
{
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
slice(const slice& other)
|
|
42
|
+
: start_(other.start_), stop_(other.stop_), step_(other.step_)
|
|
43
|
+
{
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
slice& operator=(const slice& rhs)
|
|
47
|
+
{
|
|
48
|
+
if (this != &rhs)
|
|
49
|
+
{
|
|
50
|
+
if (rhs.start_)
|
|
51
|
+
{
|
|
52
|
+
start_ = rhs.start_;
|
|
53
|
+
}
|
|
54
|
+
else
|
|
55
|
+
{
|
|
56
|
+
start_.reset();
|
|
57
|
+
}
|
|
58
|
+
if (rhs.stop_)
|
|
59
|
+
{
|
|
60
|
+
stop_ = rhs.stop_;
|
|
61
|
+
}
|
|
62
|
+
else
|
|
63
|
+
{
|
|
64
|
+
stop_.reset();
|
|
65
|
+
}
|
|
66
|
+
step_ = rhs.step_;
|
|
67
|
+
}
|
|
68
|
+
return *this;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
int64_t get_start(std::size_t size) const
|
|
72
|
+
{
|
|
73
|
+
if (start_)
|
|
74
|
+
{
|
|
75
|
+
auto len = *start_ >= 0 ? *start_ : (static_cast<int64_t>(size) + *start_);
|
|
76
|
+
return len <= static_cast<int64_t>(size) ? len : static_cast<int64_t>(size);
|
|
77
|
+
}
|
|
78
|
+
else
|
|
79
|
+
{
|
|
80
|
+
if (step_ >= 0)
|
|
81
|
+
{
|
|
82
|
+
return 0;
|
|
83
|
+
}
|
|
84
|
+
else
|
|
85
|
+
{
|
|
86
|
+
return static_cast<int64_t>(size);
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
int64_t get_stop(std::size_t size) const
|
|
92
|
+
{
|
|
93
|
+
if (stop_)
|
|
94
|
+
{
|
|
95
|
+
auto len = *stop_ >= 0 ? *stop_ : (static_cast<int64_t>(size) + *stop_);
|
|
96
|
+
return len <= static_cast<int64_t>(size) ? len : static_cast<int64_t>(size);
|
|
97
|
+
}
|
|
98
|
+
else
|
|
99
|
+
{
|
|
100
|
+
return step_ >= 0 ? static_cast<int64_t>(size) : -1;
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
int64_t step() const
|
|
105
|
+
{
|
|
106
|
+
return step_; // Allow negative
|
|
107
|
+
}
|
|
108
|
+
};
|
|
109
|
+
|
|
110
|
+
template <class Json,class JsonReference>
|
|
111
|
+
class json_array_receiver : public node_receiver<Json,JsonReference>
|
|
112
|
+
{
|
|
113
|
+
public:
|
|
114
|
+
using reference = JsonReference;
|
|
115
|
+
using char_type = typename Json::char_type;
|
|
116
|
+
using json_location_node_type = json_location_node<char_type>;
|
|
117
|
+
|
|
118
|
+
Json* val;
|
|
119
|
+
|
|
120
|
+
json_array_receiver(Json* ptr)
|
|
121
|
+
: val(ptr)
|
|
122
|
+
{
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
void add(const json_location_node_type&, reference value) override
|
|
126
|
+
{
|
|
127
|
+
val->emplace_back(value);
|
|
128
|
+
}
|
|
129
|
+
};
|
|
130
|
+
|
|
131
|
+
template <class Json,class JsonReference>
|
|
132
|
+
struct path_generator
|
|
133
|
+
{
|
|
134
|
+
using char_type = typename Json::char_type;
|
|
135
|
+
using json_location_node_type = json_location_node<char_type>;
|
|
136
|
+
using string_type = std::basic_string<char_type>;
|
|
137
|
+
|
|
138
|
+
static const json_location_node_type& generate(dynamic_resources<Json,JsonReference>& resources,
|
|
139
|
+
const json_location_node_type& last,
|
|
140
|
+
std::size_t index,
|
|
141
|
+
result_options options)
|
|
142
|
+
{
|
|
143
|
+
const result_options require_path = result_options::path | result_options::nodups | result_options::sort;
|
|
144
|
+
if ((options & require_path) != result_options())
|
|
145
|
+
{
|
|
146
|
+
return *resources.create_path_node(&last, index);
|
|
147
|
+
}
|
|
148
|
+
else
|
|
149
|
+
{
|
|
150
|
+
return last;
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
static const json_location_node_type& generate(dynamic_resources<Json,JsonReference>& resources,
|
|
155
|
+
const json_location_node_type& last,
|
|
156
|
+
const string_type& identifier,
|
|
157
|
+
result_options options)
|
|
158
|
+
{
|
|
159
|
+
const result_options require_path = result_options::path | result_options::nodups | result_options::sort;
|
|
160
|
+
if ((options & require_path) != result_options())
|
|
161
|
+
{
|
|
162
|
+
return *resources.create_path_node(&last, identifier);
|
|
163
|
+
}
|
|
164
|
+
else
|
|
165
|
+
{
|
|
166
|
+
return last;
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
};
|
|
170
|
+
|
|
171
|
+
template <class Json,class JsonReference>
|
|
172
|
+
class base_selector : public jsonpath_selector<Json,JsonReference>
|
|
173
|
+
{
|
|
174
|
+
using supertype = jsonpath_selector<Json,JsonReference>;
|
|
175
|
+
|
|
176
|
+
supertype* tail_;
|
|
177
|
+
public:
|
|
178
|
+
using value_type = typename supertype::value_type;
|
|
179
|
+
using reference = typename supertype::reference;
|
|
180
|
+
using pointer = typename supertype::pointer;
|
|
181
|
+
using path_value_pair_type = typename supertype::path_value_pair_type;
|
|
182
|
+
using json_location_node_type = typename supertype::json_location_node_type;
|
|
183
|
+
using json_location_type = typename supertype::json_location_type;
|
|
184
|
+
using node_receiver_type = typename supertype::node_receiver_type;
|
|
185
|
+
using selector_type = typename supertype::selector_type;
|
|
186
|
+
|
|
187
|
+
base_selector()
|
|
188
|
+
: supertype(true, 11), tail_(nullptr)
|
|
189
|
+
{
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
base_selector(bool is_path, std::size_t precedence_level)
|
|
193
|
+
: supertype(is_path, precedence_level), tail_(nullptr)
|
|
194
|
+
{
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
void append_selector(selector_type* expr) override
|
|
198
|
+
{
|
|
199
|
+
if (!tail_)
|
|
200
|
+
{
|
|
201
|
+
tail_ = expr;
|
|
202
|
+
}
|
|
203
|
+
else
|
|
204
|
+
{
|
|
205
|
+
tail_->append_selector(expr);
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
void tail_select(dynamic_resources<Json,JsonReference>& resources,
|
|
210
|
+
reference root,
|
|
211
|
+
const json_location_node_type& last,
|
|
212
|
+
reference current,
|
|
213
|
+
node_receiver_type& receiver,
|
|
214
|
+
result_options options) const
|
|
215
|
+
{
|
|
216
|
+
if (!tail_)
|
|
217
|
+
{
|
|
218
|
+
receiver.add(last, current);
|
|
219
|
+
}
|
|
220
|
+
else
|
|
221
|
+
{
|
|
222
|
+
tail_->select(resources, root, last, current, receiver, options);
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
reference evaluate_tail(dynamic_resources<Json,JsonReference>& resources,
|
|
227
|
+
reference root,
|
|
228
|
+
const json_location_node_type& last,
|
|
229
|
+
reference current,
|
|
230
|
+
result_options options,
|
|
231
|
+
std::error_code& ec) const
|
|
232
|
+
{
|
|
233
|
+
if (!tail_)
|
|
234
|
+
{
|
|
235
|
+
return current;
|
|
236
|
+
}
|
|
237
|
+
else
|
|
238
|
+
{
|
|
239
|
+
return tail_->evaluate(resources, root, last, current, options, ec);
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
std::string to_string(int level = 0) const override
|
|
244
|
+
{
|
|
245
|
+
std::string s;
|
|
246
|
+
if (level > 0)
|
|
247
|
+
{
|
|
248
|
+
s.append("\n");
|
|
249
|
+
s.append(level*2, ' ');
|
|
250
|
+
}
|
|
251
|
+
if (tail_)
|
|
252
|
+
{
|
|
253
|
+
s.append(tail_->to_string(level));
|
|
254
|
+
}
|
|
255
|
+
return s;
|
|
256
|
+
}
|
|
257
|
+
};
|
|
258
|
+
|
|
259
|
+
template <class Json,class JsonReference>
|
|
260
|
+
class identifier_selector final : public base_selector<Json,JsonReference>
|
|
261
|
+
{
|
|
262
|
+
using supertype = base_selector<Json,JsonReference>;
|
|
263
|
+
using path_generator_type = path_generator<Json,JsonReference>;
|
|
264
|
+
public:
|
|
265
|
+
using value_type = typename supertype::value_type;
|
|
266
|
+
using reference = typename supertype::reference;
|
|
267
|
+
using pointer = typename supertype::pointer;
|
|
268
|
+
using path_value_pair_type = typename supertype::path_value_pair_type;
|
|
269
|
+
using json_location_node_type = typename supertype::json_location_node_type;
|
|
270
|
+
using char_type = typename Json::char_type;
|
|
271
|
+
using string_type = std::basic_string<char_type>;
|
|
272
|
+
using string_view_type = basic_string_view<char_type>;
|
|
273
|
+
using node_receiver_type = typename supertype::node_receiver_type;
|
|
274
|
+
private:
|
|
275
|
+
string_type identifier_;
|
|
276
|
+
public:
|
|
277
|
+
|
|
278
|
+
identifier_selector(const string_view_type& identifier)
|
|
279
|
+
: base_selector<Json,JsonReference>(), identifier_(identifier)
|
|
280
|
+
{
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
void select(dynamic_resources<Json,JsonReference>& resources,
|
|
284
|
+
reference root,
|
|
285
|
+
const json_location_node_type& last,
|
|
286
|
+
reference current,
|
|
287
|
+
node_receiver_type& receiver,
|
|
288
|
+
result_options options) const override
|
|
289
|
+
{
|
|
290
|
+
//std::string buf;
|
|
291
|
+
//buf.append("identifier selector: ");
|
|
292
|
+
//unicode_traits::convert(identifier_.data(),identifier_.size(),buf);
|
|
293
|
+
|
|
294
|
+
static const char_type length_name[] = {'l', 'e', 'n', 'g', 't', 'h', 0};
|
|
295
|
+
|
|
296
|
+
if (current.is_object())
|
|
297
|
+
{
|
|
298
|
+
auto it = current.find(identifier_);
|
|
299
|
+
if (it != current.object_range().end())
|
|
300
|
+
{
|
|
301
|
+
this->tail_select(resources, root,
|
|
302
|
+
path_generator_type::generate(resources, last, identifier_, options),
|
|
303
|
+
it->value(), receiver, options);
|
|
304
|
+
}
|
|
305
|
+
}
|
|
306
|
+
else if (current.is_array())
|
|
307
|
+
{
|
|
308
|
+
int64_t n{0};
|
|
309
|
+
auto r = jsoncons::detail::to_integer_decimal(identifier_.data(), identifier_.size(), n);
|
|
310
|
+
if (r)
|
|
311
|
+
{
|
|
312
|
+
std::size_t index = (n >= 0) ? static_cast<std::size_t>(n) : static_cast<std::size_t>(static_cast<int64_t>(current.size()) + n);
|
|
313
|
+
if (index < current.size())
|
|
314
|
+
{
|
|
315
|
+
this->tail_select(resources, root,
|
|
316
|
+
path_generator_type::generate(resources, last, index, options),
|
|
317
|
+
current[index], receiver, options);
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
else if (identifier_ == length_name && current.size() > 0)
|
|
321
|
+
{
|
|
322
|
+
pointer ptr = resources.create_json(current.size());
|
|
323
|
+
this->tail_select(resources, root,
|
|
324
|
+
path_generator_type::generate(resources, last, identifier_, options),
|
|
325
|
+
*ptr,
|
|
326
|
+
receiver, options);
|
|
327
|
+
}
|
|
328
|
+
}
|
|
329
|
+
else if (current.is_string() && identifier_ == length_name)
|
|
330
|
+
{
|
|
331
|
+
string_view_type sv = current.as_string_view();
|
|
332
|
+
std::size_t count = unicode_traits::count_codepoints(sv.data(), sv.size());
|
|
333
|
+
pointer ptr = resources.create_json(count);
|
|
334
|
+
this->tail_select(resources, root,
|
|
335
|
+
path_generator_type::generate(resources, last, identifier_, options),
|
|
336
|
+
*ptr, receiver, options);
|
|
337
|
+
}
|
|
338
|
+
//std::cout << "end identifier_selector\n";
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
reference evaluate(dynamic_resources<Json,JsonReference>& resources,
|
|
342
|
+
reference root,
|
|
343
|
+
const json_location_node_type& last,
|
|
344
|
+
reference current,
|
|
345
|
+
result_options options,
|
|
346
|
+
std::error_code& ec) const override
|
|
347
|
+
{
|
|
348
|
+
static const char_type length_name[] = {'l', 'e', 'n', 'g', 't', 'h', 0};
|
|
349
|
+
|
|
350
|
+
if (current.is_object())
|
|
351
|
+
{
|
|
352
|
+
auto it = current.find(identifier_);
|
|
353
|
+
if (it != current.object_range().end())
|
|
354
|
+
{
|
|
355
|
+
return this->evaluate_tail(resources, root,
|
|
356
|
+
path_generator_type::generate(resources, last, identifier_, options),
|
|
357
|
+
it->value(), options, ec);
|
|
358
|
+
}
|
|
359
|
+
else
|
|
360
|
+
{
|
|
361
|
+
return resources.null_value();
|
|
362
|
+
}
|
|
363
|
+
}
|
|
364
|
+
else if (current.is_array())
|
|
365
|
+
{
|
|
366
|
+
int64_t n{0};
|
|
367
|
+
auto r = jsoncons::detail::to_integer_decimal(identifier_.data(), identifier_.size(), n);
|
|
368
|
+
if (r)
|
|
369
|
+
{
|
|
370
|
+
std::size_t index = (n >= 0) ? static_cast<std::size_t>(n) : static_cast<std::size_t>(static_cast<int64_t>(current.size()) + n);
|
|
371
|
+
if (index < current.size())
|
|
372
|
+
{
|
|
373
|
+
return this->evaluate_tail(resources, root,
|
|
374
|
+
path_generator_type::generate(resources, last, index, options),
|
|
375
|
+
current[index], options, ec);
|
|
376
|
+
}
|
|
377
|
+
else
|
|
378
|
+
{
|
|
379
|
+
return resources.null_value();
|
|
380
|
+
}
|
|
381
|
+
}
|
|
382
|
+
else if (identifier_ == length_name && current.size() > 0)
|
|
383
|
+
{
|
|
384
|
+
pointer ptr = resources.create_json(current.size());
|
|
385
|
+
return this->evaluate_tail(resources, root,
|
|
386
|
+
path_generator_type::generate(resources, last, identifier_, options),
|
|
387
|
+
*ptr,
|
|
388
|
+
options, ec);
|
|
389
|
+
}
|
|
390
|
+
else
|
|
391
|
+
{
|
|
392
|
+
return resources.null_value();
|
|
393
|
+
}
|
|
394
|
+
}
|
|
395
|
+
else if (current.is_string() && identifier_ == length_name)
|
|
396
|
+
{
|
|
397
|
+
string_view_type sv = current.as_string_view();
|
|
398
|
+
std::size_t count = unicode_traits::count_codepoints(sv.data(), sv.size());
|
|
399
|
+
pointer ptr = resources.create_json(count);
|
|
400
|
+
return this->evaluate_tail(resources, root,
|
|
401
|
+
path_generator_type::generate(resources, last, identifier_, options),
|
|
402
|
+
*ptr, options, ec);
|
|
403
|
+
}
|
|
404
|
+
else
|
|
405
|
+
{
|
|
406
|
+
return resources.null_value();
|
|
407
|
+
}
|
|
408
|
+
}
|
|
409
|
+
|
|
410
|
+
std::string to_string(int level = 0) const override
|
|
411
|
+
{
|
|
412
|
+
std::string s;
|
|
413
|
+
if (level > 0)
|
|
414
|
+
{
|
|
415
|
+
s.append("\n");
|
|
416
|
+
s.append(level*2, ' ');
|
|
417
|
+
}
|
|
418
|
+
s.append("identifier selector ");
|
|
419
|
+
unicode_traits::convert(identifier_.data(),identifier_.size(),s);
|
|
420
|
+
s.append(base_selector<Json,JsonReference>::to_string(level+1));
|
|
421
|
+
//s.append("\n");
|
|
422
|
+
|
|
423
|
+
return s;
|
|
424
|
+
}
|
|
425
|
+
};
|
|
426
|
+
|
|
427
|
+
template <class Json,class JsonReference>
|
|
428
|
+
class root_selector final : public base_selector<Json,JsonReference>
|
|
429
|
+
{
|
|
430
|
+
using supertype = base_selector<Json,JsonReference>;
|
|
431
|
+
using path_generator_type = path_generator<Json,JsonReference>;
|
|
432
|
+
|
|
433
|
+
std::size_t id_;
|
|
434
|
+
public:
|
|
435
|
+
using value_type = typename supertype::value_type;
|
|
436
|
+
using reference = typename supertype::reference;
|
|
437
|
+
using pointer = typename supertype::pointer;
|
|
438
|
+
using path_value_pair_type = typename supertype::path_value_pair_type;
|
|
439
|
+
using json_location_node_type = typename supertype::json_location_node_type;
|
|
440
|
+
using node_receiver_type = typename supertype::node_receiver_type;
|
|
441
|
+
|
|
442
|
+
root_selector(std::size_t id)
|
|
443
|
+
: base_selector<Json,JsonReference>(), id_(id)
|
|
444
|
+
{
|
|
445
|
+
}
|
|
446
|
+
|
|
447
|
+
void select(dynamic_resources<Json,JsonReference>& resources,
|
|
448
|
+
reference root,
|
|
449
|
+
const json_location_node_type& last,
|
|
450
|
+
reference,
|
|
451
|
+
node_receiver_type& receiver,
|
|
452
|
+
result_options options) const override
|
|
453
|
+
{
|
|
454
|
+
this->tail_select(resources, root, last, root, receiver, options);
|
|
455
|
+
}
|
|
456
|
+
|
|
457
|
+
reference evaluate(dynamic_resources<Json,JsonReference>& resources,
|
|
458
|
+
reference root,
|
|
459
|
+
const json_location_node_type& last,
|
|
460
|
+
reference,
|
|
461
|
+
result_options options,
|
|
462
|
+
std::error_code& ec) const override
|
|
463
|
+
{
|
|
464
|
+
if (resources.is_cached(id_))
|
|
465
|
+
{
|
|
466
|
+
return resources.retrieve_from_cache(id_);
|
|
467
|
+
}
|
|
468
|
+
else
|
|
469
|
+
{
|
|
470
|
+
auto& ref = this->evaluate_tail(resources, root, last, root, options, ec);
|
|
471
|
+
if (!ec)
|
|
472
|
+
{
|
|
473
|
+
resources.add_to_cache(id_, ref);
|
|
474
|
+
}
|
|
475
|
+
|
|
476
|
+
return ref;
|
|
477
|
+
}
|
|
478
|
+
}
|
|
479
|
+
|
|
480
|
+
std::string to_string(int level = 0) const override
|
|
481
|
+
{
|
|
482
|
+
std::string s;
|
|
483
|
+
if (level > 0)
|
|
484
|
+
{
|
|
485
|
+
s.append("\n");
|
|
486
|
+
s.append(level*2, ' ');
|
|
487
|
+
}
|
|
488
|
+
s.append("root_selector ");
|
|
489
|
+
s.append(base_selector<Json,JsonReference>::to_string(level+1));
|
|
490
|
+
|
|
491
|
+
return s;
|
|
492
|
+
}
|
|
493
|
+
};
|
|
494
|
+
|
|
495
|
+
template <class Json,class JsonReference>
|
|
496
|
+
class current_node_selector final : public base_selector<Json,JsonReference>
|
|
497
|
+
{
|
|
498
|
+
using supertype = base_selector<Json,JsonReference>;
|
|
499
|
+
|
|
500
|
+
public:
|
|
501
|
+
using value_type = typename supertype::value_type;
|
|
502
|
+
using reference = typename supertype::reference;
|
|
503
|
+
using pointer = typename supertype::pointer;
|
|
504
|
+
using path_value_pair_type = typename supertype::path_value_pair_type;
|
|
505
|
+
using json_location_node_type = typename supertype::json_location_node_type;
|
|
506
|
+
using path_generator_type = path_generator<Json,JsonReference>;
|
|
507
|
+
using node_receiver_type = typename supertype::node_receiver_type;
|
|
508
|
+
|
|
509
|
+
current_node_selector()
|
|
510
|
+
{
|
|
511
|
+
}
|
|
512
|
+
|
|
513
|
+
void select(dynamic_resources<Json,JsonReference>& resources,
|
|
514
|
+
reference root,
|
|
515
|
+
const json_location_node_type& last,
|
|
516
|
+
reference current,
|
|
517
|
+
node_receiver_type& receiver,
|
|
518
|
+
result_options options) const override
|
|
519
|
+
{
|
|
520
|
+
this->tail_select(resources,
|
|
521
|
+
root, last, current, receiver, options);
|
|
522
|
+
}
|
|
523
|
+
|
|
524
|
+
reference evaluate(dynamic_resources<Json,JsonReference>& resources,
|
|
525
|
+
reference root,
|
|
526
|
+
const json_location_node_type& last,
|
|
527
|
+
reference current,
|
|
528
|
+
result_options options,
|
|
529
|
+
std::error_code& ec) const override
|
|
530
|
+
{
|
|
531
|
+
//std::cout << "current_node_selector: " << current << "\n";
|
|
532
|
+
return this->evaluate_tail(resources,
|
|
533
|
+
root, last, current, options, ec);
|
|
534
|
+
}
|
|
535
|
+
|
|
536
|
+
std::string to_string(int level = 0) const override
|
|
537
|
+
{
|
|
538
|
+
std::string s;
|
|
539
|
+
if (level > 0)
|
|
540
|
+
{
|
|
541
|
+
s.append("\n");
|
|
542
|
+
s.append(level*2, ' ');
|
|
543
|
+
}
|
|
544
|
+
s.append("current_node_selector");
|
|
545
|
+
s.append(base_selector<Json,JsonReference>::to_string(level+1));
|
|
546
|
+
|
|
547
|
+
return s;
|
|
548
|
+
}
|
|
549
|
+
};
|
|
550
|
+
|
|
551
|
+
template <class Json,class JsonReference>
|
|
552
|
+
class parent_node_selector final : public base_selector<Json,JsonReference>
|
|
553
|
+
{
|
|
554
|
+
using supertype = base_selector<Json,JsonReference>;
|
|
555
|
+
|
|
556
|
+
int ancestor_depth_;
|
|
557
|
+
|
|
558
|
+
public:
|
|
559
|
+
using value_type = typename supertype::value_type;
|
|
560
|
+
using reference = typename supertype::reference;
|
|
561
|
+
using pointer = typename supertype::pointer;
|
|
562
|
+
using path_value_pair_type = typename supertype::path_value_pair_type;
|
|
563
|
+
using json_location_node_type = typename supertype::json_location_node_type;
|
|
564
|
+
using json_location_type = typename supertype::json_location_type;
|
|
565
|
+
using path_generator_type = path_generator<Json,JsonReference>;
|
|
566
|
+
using node_receiver_type = typename supertype::node_receiver_type;
|
|
567
|
+
|
|
568
|
+
parent_node_selector(int ancestor_depth)
|
|
569
|
+
{
|
|
570
|
+
ancestor_depth_ = ancestor_depth;
|
|
571
|
+
}
|
|
572
|
+
|
|
573
|
+
void select(dynamic_resources<Json,JsonReference>& resources,
|
|
574
|
+
reference root,
|
|
575
|
+
const json_location_node_type& last,
|
|
576
|
+
reference,
|
|
577
|
+
node_receiver_type& receiver,
|
|
578
|
+
result_options options) const override
|
|
579
|
+
{
|
|
580
|
+
const json_location_node_type* ancestor = std::addressof(last);
|
|
581
|
+
int index = 0;
|
|
582
|
+
while (ancestor != nullptr && index < ancestor_depth_)
|
|
583
|
+
{
|
|
584
|
+
ancestor = ancestor->parent();
|
|
585
|
+
++index;
|
|
586
|
+
}
|
|
587
|
+
|
|
588
|
+
if (ancestor != nullptr)
|
|
589
|
+
{
|
|
590
|
+
json_location_type path(*ancestor);
|
|
591
|
+
pointer ptr = jsoncons::jsonpath::select(root,path);
|
|
592
|
+
if (ptr != nullptr)
|
|
593
|
+
{
|
|
594
|
+
this->tail_select(resources, root, path.last(), *ptr, receiver, options);
|
|
595
|
+
}
|
|
596
|
+
}
|
|
597
|
+
}
|
|
598
|
+
|
|
599
|
+
reference evaluate(dynamic_resources<Json,JsonReference>& resources,
|
|
600
|
+
reference root,
|
|
601
|
+
const json_location_node_type& last,
|
|
602
|
+
reference,
|
|
603
|
+
result_options options,
|
|
604
|
+
std::error_code& ec) const override
|
|
605
|
+
{
|
|
606
|
+
const json_location_node_type* ancestor = std::addressof(last);
|
|
607
|
+
int index = 0;
|
|
608
|
+
while (ancestor != nullptr && index < ancestor_depth_)
|
|
609
|
+
{
|
|
610
|
+
ancestor = ancestor->parent();
|
|
611
|
+
++index;
|
|
612
|
+
}
|
|
613
|
+
|
|
614
|
+
if (ancestor != nullptr)
|
|
615
|
+
{
|
|
616
|
+
json_location_type path(*ancestor);
|
|
617
|
+
pointer ptr = jsoncons::jsonpath::select(root,path);
|
|
618
|
+
if (ptr != nullptr)
|
|
619
|
+
{
|
|
620
|
+
return this->evaluate_tail(resources, root, path.last(), *ptr, options, ec);
|
|
621
|
+
}
|
|
622
|
+
else
|
|
623
|
+
{
|
|
624
|
+
return resources.null_value();
|
|
625
|
+
}
|
|
626
|
+
}
|
|
627
|
+
else
|
|
628
|
+
{
|
|
629
|
+
return resources.null_value();
|
|
630
|
+
}
|
|
631
|
+
}
|
|
632
|
+
|
|
633
|
+
std::string to_string(int level = 0) const override
|
|
634
|
+
{
|
|
635
|
+
std::string s;
|
|
636
|
+
if (level > 0)
|
|
637
|
+
{
|
|
638
|
+
s.append("\n");
|
|
639
|
+
s.append(level*2, ' ');
|
|
640
|
+
}
|
|
641
|
+
s.append("parent_node_selector");
|
|
642
|
+
s.append(base_selector<Json,JsonReference>::to_string(level+1));
|
|
643
|
+
|
|
644
|
+
return s;
|
|
645
|
+
}
|
|
646
|
+
};
|
|
647
|
+
|
|
648
|
+
template <class Json,class JsonReference>
|
|
649
|
+
class index_selector final : public base_selector<Json,JsonReference>
|
|
650
|
+
{
|
|
651
|
+
using supertype = base_selector<Json,JsonReference>;
|
|
652
|
+
|
|
653
|
+
int64_t index_;
|
|
654
|
+
public:
|
|
655
|
+
using value_type = typename supertype::value_type;
|
|
656
|
+
using reference = typename supertype::reference;
|
|
657
|
+
using pointer = typename supertype::pointer;
|
|
658
|
+
using path_value_pair_type = typename supertype::path_value_pair_type;
|
|
659
|
+
using json_location_node_type = typename supertype::json_location_node_type;
|
|
660
|
+
using path_generator_type = path_generator<Json,JsonReference>;
|
|
661
|
+
using node_receiver_type = typename supertype::node_receiver_type;
|
|
662
|
+
|
|
663
|
+
index_selector(int64_t index)
|
|
664
|
+
: base_selector<Json,JsonReference>(), index_(index)
|
|
665
|
+
{
|
|
666
|
+
}
|
|
667
|
+
|
|
668
|
+
void select(dynamic_resources<Json,JsonReference>& resources,
|
|
669
|
+
reference root,
|
|
670
|
+
const json_location_node_type& last,
|
|
671
|
+
reference current,
|
|
672
|
+
node_receiver_type& receiver,
|
|
673
|
+
result_options options) const override
|
|
674
|
+
{
|
|
675
|
+
if (current.is_array())
|
|
676
|
+
{
|
|
677
|
+
int64_t slen = static_cast<int64_t>(current.size());
|
|
678
|
+
if (index_ >= 0 && index_ < slen)
|
|
679
|
+
{
|
|
680
|
+
std::size_t i = static_cast<std::size_t>(index_);
|
|
681
|
+
this->tail_select(resources, root,
|
|
682
|
+
path_generator_type::generate(resources, last, i, options),
|
|
683
|
+
current.at(i), receiver, options);
|
|
684
|
+
}
|
|
685
|
+
else
|
|
686
|
+
{
|
|
687
|
+
int64_t index = slen + index_;
|
|
688
|
+
if (index >= 0 && index < slen)
|
|
689
|
+
{
|
|
690
|
+
std::size_t i = static_cast<std::size_t>(index);
|
|
691
|
+
this->tail_select(resources, root,
|
|
692
|
+
path_generator_type::generate(resources, last, i, options),
|
|
693
|
+
current.at(i), receiver, options);
|
|
694
|
+
}
|
|
695
|
+
}
|
|
696
|
+
}
|
|
697
|
+
}
|
|
698
|
+
|
|
699
|
+
reference evaluate(dynamic_resources<Json,JsonReference>& resources,
|
|
700
|
+
reference root,
|
|
701
|
+
const json_location_node_type& last,
|
|
702
|
+
reference current,
|
|
703
|
+
result_options options,
|
|
704
|
+
std::error_code& ec) const override
|
|
705
|
+
{
|
|
706
|
+
if (current.is_array())
|
|
707
|
+
{
|
|
708
|
+
int64_t slen = static_cast<int64_t>(current.size());
|
|
709
|
+
if (index_ >= 0 && index_ < slen)
|
|
710
|
+
{
|
|
711
|
+
std::size_t i = static_cast<std::size_t>(index_);
|
|
712
|
+
return this->evaluate_tail(resources, root,
|
|
713
|
+
path_generator_type::generate(resources, last, i, options),
|
|
714
|
+
current.at(i), options, ec);
|
|
715
|
+
}
|
|
716
|
+
else
|
|
717
|
+
{
|
|
718
|
+
int64_t index = slen + index_;
|
|
719
|
+
if (index >= 0 && index < slen)
|
|
720
|
+
{
|
|
721
|
+
std::size_t i = static_cast<std::size_t>(index);
|
|
722
|
+
return this->evaluate_tail(resources, root,
|
|
723
|
+
path_generator_type::generate(resources, last, i, options),
|
|
724
|
+
current.at(i), options, ec);
|
|
725
|
+
}
|
|
726
|
+
else
|
|
727
|
+
{
|
|
728
|
+
return resources.null_value();
|
|
729
|
+
}
|
|
730
|
+
}
|
|
731
|
+
}
|
|
732
|
+
else
|
|
733
|
+
{
|
|
734
|
+
return resources.null_value();
|
|
735
|
+
}
|
|
736
|
+
}
|
|
737
|
+
};
|
|
738
|
+
|
|
739
|
+
template <class Json,class JsonReference>
|
|
740
|
+
class wildcard_selector final : public base_selector<Json,JsonReference>
|
|
741
|
+
{
|
|
742
|
+
using supertype = base_selector<Json,JsonReference>;
|
|
743
|
+
|
|
744
|
+
public:
|
|
745
|
+
using value_type = typename supertype::value_type;
|
|
746
|
+
using reference = typename supertype::reference;
|
|
747
|
+
using pointer = typename supertype::pointer;
|
|
748
|
+
using path_value_pair_type = typename supertype::path_value_pair_type;
|
|
749
|
+
using json_location_node_type = typename supertype::json_location_node_type;
|
|
750
|
+
using path_generator_type = path_generator<Json,JsonReference>;
|
|
751
|
+
using node_receiver_type = typename supertype::node_receiver_type;
|
|
752
|
+
|
|
753
|
+
wildcard_selector()
|
|
754
|
+
: base_selector<Json,JsonReference>()
|
|
755
|
+
{
|
|
756
|
+
}
|
|
757
|
+
|
|
758
|
+
void select(dynamic_resources<Json,JsonReference>& resources,
|
|
759
|
+
reference root,
|
|
760
|
+
const json_location_node_type& last,
|
|
761
|
+
reference current,
|
|
762
|
+
node_receiver_type& receiver,
|
|
763
|
+
result_options options) const override
|
|
764
|
+
{
|
|
765
|
+
if (current.is_array())
|
|
766
|
+
{
|
|
767
|
+
for (std::size_t i = 0; i < current.size(); ++i)
|
|
768
|
+
{
|
|
769
|
+
this->tail_select(resources, root,
|
|
770
|
+
path_generator_type::generate(resources, last, i, options), current[i],
|
|
771
|
+
receiver, options);
|
|
772
|
+
}
|
|
773
|
+
}
|
|
774
|
+
else if (current.is_object())
|
|
775
|
+
{
|
|
776
|
+
for (auto& member : current.object_range())
|
|
777
|
+
{
|
|
778
|
+
this->tail_select(resources, root,
|
|
779
|
+
path_generator_type::generate(resources, last, member.key(), options),
|
|
780
|
+
member.value(), receiver, options);
|
|
781
|
+
}
|
|
782
|
+
}
|
|
783
|
+
//std::cout << "end wildcard_selector\n";
|
|
784
|
+
}
|
|
785
|
+
|
|
786
|
+
reference evaluate(dynamic_resources<Json,JsonReference>& resources,
|
|
787
|
+
reference root,
|
|
788
|
+
const json_location_node_type& last,
|
|
789
|
+
reference current,
|
|
790
|
+
result_options options,
|
|
791
|
+
std::error_code&) const override
|
|
792
|
+
{
|
|
793
|
+
auto jptr = resources.create_json(json_array_arg);
|
|
794
|
+
json_array_receiver<Json,JsonReference> receiver(jptr);
|
|
795
|
+
select(resources, root, last, current, receiver, options);
|
|
796
|
+
return *jptr;
|
|
797
|
+
}
|
|
798
|
+
|
|
799
|
+
std::string to_string(int level = 0) const override
|
|
800
|
+
{
|
|
801
|
+
std::string s;
|
|
802
|
+
if (level > 0)
|
|
803
|
+
{
|
|
804
|
+
s.append("\n");
|
|
805
|
+
s.append(level*2, ' ');
|
|
806
|
+
}
|
|
807
|
+
s.append("wildcard selector");
|
|
808
|
+
s.append(base_selector<Json,JsonReference>::to_string(level));
|
|
809
|
+
|
|
810
|
+
return s;
|
|
811
|
+
}
|
|
812
|
+
};
|
|
813
|
+
|
|
814
|
+
template <class Json,class JsonReference>
|
|
815
|
+
class recursive_selector final : public base_selector<Json,JsonReference>
|
|
816
|
+
{
|
|
817
|
+
using supertype = base_selector<Json,JsonReference>;
|
|
818
|
+
|
|
819
|
+
public:
|
|
820
|
+
using value_type = typename supertype::value_type;
|
|
821
|
+
using reference = typename supertype::reference;
|
|
822
|
+
using pointer = typename supertype::pointer;
|
|
823
|
+
using path_value_pair_type = typename supertype::path_value_pair_type;
|
|
824
|
+
using json_location_node_type = typename supertype::json_location_node_type;
|
|
825
|
+
using path_generator_type = path_generator<Json,JsonReference>;
|
|
826
|
+
using node_receiver_type = typename supertype::node_receiver_type;
|
|
827
|
+
|
|
828
|
+
recursive_selector()
|
|
829
|
+
: base_selector<Json,JsonReference>()
|
|
830
|
+
{
|
|
831
|
+
}
|
|
832
|
+
|
|
833
|
+
void select(dynamic_resources<Json,JsonReference>& resources,
|
|
834
|
+
reference root,
|
|
835
|
+
const json_location_node_type& last,
|
|
836
|
+
reference current,
|
|
837
|
+
node_receiver_type& receiver,
|
|
838
|
+
result_options options) const override
|
|
839
|
+
{
|
|
840
|
+
if (current.is_array())
|
|
841
|
+
{
|
|
842
|
+
this->tail_select(resources, root, last, current, receiver, options);
|
|
843
|
+
for (std::size_t i = 0; i < current.size(); ++i)
|
|
844
|
+
{
|
|
845
|
+
select(resources, root,
|
|
846
|
+
path_generator_type::generate(resources, last, i, options), current[i], receiver, options);
|
|
847
|
+
}
|
|
848
|
+
}
|
|
849
|
+
else if (current.is_object())
|
|
850
|
+
{
|
|
851
|
+
this->tail_select(resources, root, last, current, receiver, options);
|
|
852
|
+
for (auto& item : current.object_range())
|
|
853
|
+
{
|
|
854
|
+
select(resources, root,
|
|
855
|
+
path_generator_type::generate(resources, last, item.key(), options), item.value(), receiver, options);
|
|
856
|
+
}
|
|
857
|
+
}
|
|
858
|
+
//std::cout << "end wildcard_selector\n";
|
|
859
|
+
}
|
|
860
|
+
|
|
861
|
+
reference evaluate(dynamic_resources<Json,JsonReference>& resources,
|
|
862
|
+
reference root,
|
|
863
|
+
const json_location_node_type& last,
|
|
864
|
+
reference current,
|
|
865
|
+
result_options options,
|
|
866
|
+
std::error_code&) const override
|
|
867
|
+
{
|
|
868
|
+
auto jptr = resources.create_json(json_array_arg);
|
|
869
|
+
json_array_receiver<Json,JsonReference> receiver(jptr);
|
|
870
|
+
select(resources, root, last, current, receiver, options);
|
|
871
|
+
return *jptr;
|
|
872
|
+
}
|
|
873
|
+
|
|
874
|
+
std::string to_string(int level = 0) const override
|
|
875
|
+
{
|
|
876
|
+
std::string s;
|
|
877
|
+
if (level > 0)
|
|
878
|
+
{
|
|
879
|
+
s.append("\n");
|
|
880
|
+
s.append(level*2, ' ');
|
|
881
|
+
}
|
|
882
|
+
s.append("wildcard selector");
|
|
883
|
+
s.append(base_selector<Json,JsonReference>::to_string(level));
|
|
884
|
+
|
|
885
|
+
return s;
|
|
886
|
+
}
|
|
887
|
+
};
|
|
888
|
+
|
|
889
|
+
template <class Json,class JsonReference>
|
|
890
|
+
class union_selector final : public jsonpath_selector<Json,JsonReference>
|
|
891
|
+
{
|
|
892
|
+
using supertype = jsonpath_selector<Json,JsonReference>;
|
|
893
|
+
public:
|
|
894
|
+
using value_type = typename supertype::value_type;
|
|
895
|
+
using reference = typename supertype::reference;
|
|
896
|
+
using pointer = typename supertype::pointer;
|
|
897
|
+
using path_value_pair_type = typename supertype::path_value_pair_type;
|
|
898
|
+
using json_location_node_type = typename supertype::json_location_node_type;
|
|
899
|
+
using json_location_type = typename supertype::json_location_type;
|
|
900
|
+
using path_expression_type = path_expression<Json, JsonReference>;
|
|
901
|
+
using path_generator_type = path_generator<Json,JsonReference>;
|
|
902
|
+
using node_receiver_type = typename supertype::node_receiver_type;
|
|
903
|
+
using selector_type = typename supertype::selector_type;
|
|
904
|
+
private:
|
|
905
|
+
std::vector<selector_type*> selectors_;
|
|
906
|
+
selector_type* tail_;
|
|
907
|
+
public:
|
|
908
|
+
union_selector(std::vector<selector_type*>&& selectors)
|
|
909
|
+
: supertype(true, 11), selectors_(std::move(selectors)), tail_(nullptr)
|
|
910
|
+
{
|
|
911
|
+
}
|
|
912
|
+
|
|
913
|
+
void append_selector(selector_type* tail) override
|
|
914
|
+
{
|
|
915
|
+
if (tail_ == nullptr)
|
|
916
|
+
{
|
|
917
|
+
tail_ = tail;
|
|
918
|
+
for (auto& selector : selectors_)
|
|
919
|
+
{
|
|
920
|
+
selector->append_selector(tail);
|
|
921
|
+
}
|
|
922
|
+
}
|
|
923
|
+
else
|
|
924
|
+
{
|
|
925
|
+
tail_->append_selector(tail);
|
|
926
|
+
}
|
|
927
|
+
}
|
|
928
|
+
|
|
929
|
+
void select(dynamic_resources<Json,JsonReference>& resources,
|
|
930
|
+
reference root,
|
|
931
|
+
const json_location_node_type& last,
|
|
932
|
+
reference current,
|
|
933
|
+
node_receiver_type& receiver,
|
|
934
|
+
result_options options) const override
|
|
935
|
+
{
|
|
936
|
+
for (auto& selector : selectors_)
|
|
937
|
+
{
|
|
938
|
+
selector->select(resources, root, last, current, receiver, options);
|
|
939
|
+
}
|
|
940
|
+
}
|
|
941
|
+
|
|
942
|
+
reference evaluate(dynamic_resources<Json,JsonReference>& resources,
|
|
943
|
+
reference root,
|
|
944
|
+
const json_location_node_type& last,
|
|
945
|
+
reference current,
|
|
946
|
+
result_options options,
|
|
947
|
+
std::error_code&) const override
|
|
948
|
+
{
|
|
949
|
+
auto jptr = resources.create_json(json_array_arg);
|
|
950
|
+
json_array_receiver<Json,JsonReference> receiver(jptr);
|
|
951
|
+
select(resources,root,last,current,receiver,options);
|
|
952
|
+
return *jptr;
|
|
953
|
+
}
|
|
954
|
+
|
|
955
|
+
std::string to_string(int level = 0) const override
|
|
956
|
+
{
|
|
957
|
+
std::string s;
|
|
958
|
+
if (level > 0)
|
|
959
|
+
{
|
|
960
|
+
s.append("\n");
|
|
961
|
+
s.append(level*2, ' ');
|
|
962
|
+
}
|
|
963
|
+
s.append("union selector ");
|
|
964
|
+
for (auto& selector : selectors_)
|
|
965
|
+
{
|
|
966
|
+
s.append(selector->to_string(level+1));
|
|
967
|
+
//s.push_back('\n');
|
|
968
|
+
}
|
|
969
|
+
|
|
970
|
+
return s;
|
|
971
|
+
}
|
|
972
|
+
};
|
|
973
|
+
|
|
974
|
+
template <class Json,class JsonReference>
|
|
975
|
+
class filter_selector final : public base_selector<Json,JsonReference>
|
|
976
|
+
{
|
|
977
|
+
using supertype = base_selector<Json,JsonReference>;
|
|
978
|
+
|
|
979
|
+
expression<Json,JsonReference> expr_;
|
|
980
|
+
|
|
981
|
+
public:
|
|
982
|
+
using value_type = typename supertype::value_type;
|
|
983
|
+
using reference = typename supertype::reference;
|
|
984
|
+
using pointer = typename supertype::pointer;
|
|
985
|
+
using path_value_pair_type = typename supertype::path_value_pair_type;
|
|
986
|
+
using json_location_node_type = typename supertype::json_location_node_type;
|
|
987
|
+
using path_generator_type = path_generator<Json,JsonReference>;
|
|
988
|
+
using node_receiver_type = typename supertype::node_receiver_type;
|
|
989
|
+
|
|
990
|
+
filter_selector(expression<Json,JsonReference>&& expr)
|
|
991
|
+
: base_selector<Json,JsonReference>(), expr_(std::move(expr))
|
|
992
|
+
{
|
|
993
|
+
}
|
|
994
|
+
|
|
995
|
+
void select(dynamic_resources<Json,JsonReference>& resources,
|
|
996
|
+
reference root,
|
|
997
|
+
const json_location_node_type& last,
|
|
998
|
+
reference current,
|
|
999
|
+
node_receiver_type& receiver,
|
|
1000
|
+
result_options options) const override
|
|
1001
|
+
{
|
|
1002
|
+
if (current.is_array())
|
|
1003
|
+
{
|
|
1004
|
+
for (std::size_t i = 0; i < current.size(); ++i)
|
|
1005
|
+
{
|
|
1006
|
+
std::error_code ec;
|
|
1007
|
+
value_type r = expr_.evaluate(resources, root, current[i], options, ec);
|
|
1008
|
+
bool t = ec ? false : detail::is_true(r);
|
|
1009
|
+
if (t)
|
|
1010
|
+
{
|
|
1011
|
+
this->tail_select(resources, root,
|
|
1012
|
+
path_generator_type::generate(resources, last, i, options),
|
|
1013
|
+
current[i], receiver, options);
|
|
1014
|
+
}
|
|
1015
|
+
}
|
|
1016
|
+
}
|
|
1017
|
+
else if (current.is_object())
|
|
1018
|
+
{
|
|
1019
|
+
for (auto& member : current.object_range())
|
|
1020
|
+
{
|
|
1021
|
+
std::error_code ec;
|
|
1022
|
+
value_type r = expr_.evaluate(resources, root, member.value(), options, ec);
|
|
1023
|
+
bool t = ec ? false : detail::is_true(r);
|
|
1024
|
+
if (t)
|
|
1025
|
+
{
|
|
1026
|
+
this->tail_select(resources, root,
|
|
1027
|
+
path_generator_type::generate(resources, last, member.key(), options),
|
|
1028
|
+
member.value(), receiver, options);
|
|
1029
|
+
}
|
|
1030
|
+
}
|
|
1031
|
+
}
|
|
1032
|
+
}
|
|
1033
|
+
|
|
1034
|
+
reference evaluate(dynamic_resources<Json,JsonReference>& resources,
|
|
1035
|
+
reference root,
|
|
1036
|
+
const json_location_node_type& last,
|
|
1037
|
+
reference current,
|
|
1038
|
+
result_options options,
|
|
1039
|
+
std::error_code&) const override
|
|
1040
|
+
{
|
|
1041
|
+
auto jptr = resources.create_json(json_array_arg);
|
|
1042
|
+
json_array_receiver<Json,JsonReference> receiver(jptr);
|
|
1043
|
+
select(resources, root, last, current, receiver, options);
|
|
1044
|
+
return *jptr;
|
|
1045
|
+
}
|
|
1046
|
+
|
|
1047
|
+
std::string to_string(int level = 0) const override
|
|
1048
|
+
{
|
|
1049
|
+
std::string s;
|
|
1050
|
+
if (level > 0)
|
|
1051
|
+
{
|
|
1052
|
+
s.append("\n");
|
|
1053
|
+
s.append(level*2, ' ');
|
|
1054
|
+
}
|
|
1055
|
+
s.append("filter selector ");
|
|
1056
|
+
s.append(expr_.to_string(level+1));
|
|
1057
|
+
|
|
1058
|
+
return s;
|
|
1059
|
+
}
|
|
1060
|
+
};
|
|
1061
|
+
|
|
1062
|
+
template <class Json,class JsonReference>
|
|
1063
|
+
class index_expression_selector final : public base_selector<Json,JsonReference>
|
|
1064
|
+
{
|
|
1065
|
+
using supertype = base_selector<Json,JsonReference>;
|
|
1066
|
+
|
|
1067
|
+
expression<Json,JsonReference> expr_;
|
|
1068
|
+
|
|
1069
|
+
public:
|
|
1070
|
+
using value_type = typename supertype::value_type;
|
|
1071
|
+
using reference = typename supertype::reference;
|
|
1072
|
+
using pointer = typename supertype::pointer;
|
|
1073
|
+
using path_value_pair_type = typename supertype::path_value_pair_type;
|
|
1074
|
+
using json_location_node_type = typename supertype::json_location_node_type;
|
|
1075
|
+
using path_generator_type = path_generator<Json,JsonReference>;
|
|
1076
|
+
using node_receiver_type = typename supertype::node_receiver_type;
|
|
1077
|
+
|
|
1078
|
+
index_expression_selector(expression<Json,JsonReference>&& expr)
|
|
1079
|
+
: base_selector<Json,JsonReference>(), expr_(std::move(expr))
|
|
1080
|
+
{
|
|
1081
|
+
}
|
|
1082
|
+
|
|
1083
|
+
void select(dynamic_resources<Json,JsonReference>& resources,
|
|
1084
|
+
reference root,
|
|
1085
|
+
const json_location_node_type& last,
|
|
1086
|
+
reference current,
|
|
1087
|
+
node_receiver_type& receiver,
|
|
1088
|
+
result_options options) const override
|
|
1089
|
+
{
|
|
1090
|
+
std::error_code ec;
|
|
1091
|
+
value_type j = expr_.evaluate(resources, root, current, options, ec);
|
|
1092
|
+
|
|
1093
|
+
if (!ec)
|
|
1094
|
+
{
|
|
1095
|
+
if (j.template is<std::size_t>() && current.is_array())
|
|
1096
|
+
{
|
|
1097
|
+
std::size_t start = j.template as<std::size_t>();
|
|
1098
|
+
this->tail_select(resources, root,
|
|
1099
|
+
path_generator_type::generate(resources, last, start, options),
|
|
1100
|
+
current.at(start), receiver, options);
|
|
1101
|
+
}
|
|
1102
|
+
else if (j.is_string() && current.is_object())
|
|
1103
|
+
{
|
|
1104
|
+
this->tail_select(resources, root,
|
|
1105
|
+
path_generator_type::generate(resources, last, j.as_string(), options),
|
|
1106
|
+
current.at(j.as_string_view()), receiver, options);
|
|
1107
|
+
}
|
|
1108
|
+
}
|
|
1109
|
+
}
|
|
1110
|
+
|
|
1111
|
+
reference evaluate(dynamic_resources<Json,JsonReference>& resources,
|
|
1112
|
+
reference root,
|
|
1113
|
+
const json_location_node_type& last,
|
|
1114
|
+
reference current,
|
|
1115
|
+
result_options options,
|
|
1116
|
+
std::error_code& ec) const override
|
|
1117
|
+
{
|
|
1118
|
+
//std::cout << "index_expression_selector current: " << current << "\n";
|
|
1119
|
+
|
|
1120
|
+
value_type j = expr_.evaluate(resources, root, current, options, ec);
|
|
1121
|
+
|
|
1122
|
+
if (!ec)
|
|
1123
|
+
{
|
|
1124
|
+
if (j.template is<std::size_t>() && current.is_array())
|
|
1125
|
+
{
|
|
1126
|
+
std::size_t start = j.template as<std::size_t>();
|
|
1127
|
+
return this->evaluate_tail(resources, root, last, current.at(start), options, ec);
|
|
1128
|
+
}
|
|
1129
|
+
else if (j.is_string() && current.is_object())
|
|
1130
|
+
{
|
|
1131
|
+
return this->evaluate_tail(resources, root, last, current.at(j.as_string_view()), options, ec);
|
|
1132
|
+
}
|
|
1133
|
+
else
|
|
1134
|
+
{
|
|
1135
|
+
return resources.null_value();
|
|
1136
|
+
}
|
|
1137
|
+
}
|
|
1138
|
+
else
|
|
1139
|
+
{
|
|
1140
|
+
return resources.null_value();
|
|
1141
|
+
}
|
|
1142
|
+
}
|
|
1143
|
+
|
|
1144
|
+
std::string to_string(int level = 0) const override
|
|
1145
|
+
{
|
|
1146
|
+
std::string s;
|
|
1147
|
+
if (level > 0)
|
|
1148
|
+
{
|
|
1149
|
+
s.append("\n");
|
|
1150
|
+
s.append(level*2, ' ');
|
|
1151
|
+
}
|
|
1152
|
+
s.append("bracket expression selector ");
|
|
1153
|
+
s.append(expr_.to_string(level+1));
|
|
1154
|
+
s.append(base_selector<Json,JsonReference>::to_string(level+1));
|
|
1155
|
+
|
|
1156
|
+
return s;
|
|
1157
|
+
}
|
|
1158
|
+
};
|
|
1159
|
+
|
|
1160
|
+
template <class Json,class JsonReference>
|
|
1161
|
+
class slice_selector final : public base_selector<Json,JsonReference>
|
|
1162
|
+
{
|
|
1163
|
+
using supertype = base_selector<Json,JsonReference>;
|
|
1164
|
+
using path_generator_type = path_generator<Json, JsonReference>;
|
|
1165
|
+
|
|
1166
|
+
slice slice_;
|
|
1167
|
+
public:
|
|
1168
|
+
using value_type = typename supertype::value_type;
|
|
1169
|
+
using reference = typename supertype::reference;
|
|
1170
|
+
using pointer = typename supertype::pointer;
|
|
1171
|
+
using path_value_pair_type = typename supertype::path_value_pair_type;
|
|
1172
|
+
using json_location_node_type = typename supertype::json_location_node_type;
|
|
1173
|
+
using node_receiver_type = typename supertype::node_receiver_type;
|
|
1174
|
+
|
|
1175
|
+
slice_selector(const slice& slic)
|
|
1176
|
+
: base_selector<Json,JsonReference>(), slice_(slic)
|
|
1177
|
+
{
|
|
1178
|
+
}
|
|
1179
|
+
|
|
1180
|
+
void select(dynamic_resources<Json,JsonReference>& resources,
|
|
1181
|
+
reference root,
|
|
1182
|
+
const json_location_node_type& last,
|
|
1183
|
+
reference current,
|
|
1184
|
+
node_receiver_type& receiver,
|
|
1185
|
+
result_options options) const override
|
|
1186
|
+
{
|
|
1187
|
+
if (current.is_array())
|
|
1188
|
+
{
|
|
1189
|
+
auto start = slice_.get_start(current.size());
|
|
1190
|
+
auto end = slice_.get_stop(current.size());
|
|
1191
|
+
auto step = slice_.step();
|
|
1192
|
+
|
|
1193
|
+
if (step > 0)
|
|
1194
|
+
{
|
|
1195
|
+
if (start < 0)
|
|
1196
|
+
{
|
|
1197
|
+
start = 0;
|
|
1198
|
+
}
|
|
1199
|
+
if (end > static_cast<int64_t>(current.size()))
|
|
1200
|
+
{
|
|
1201
|
+
end = current.size();
|
|
1202
|
+
}
|
|
1203
|
+
for (int64_t i = start; i < end; i += step)
|
|
1204
|
+
{
|
|
1205
|
+
std::size_t j = static_cast<std::size_t>(i);
|
|
1206
|
+
this->tail_select(resources, root,
|
|
1207
|
+
path_generator_type::generate(resources, last, j, options),
|
|
1208
|
+
current[j], receiver, options);
|
|
1209
|
+
}
|
|
1210
|
+
}
|
|
1211
|
+
else if (step < 0)
|
|
1212
|
+
{
|
|
1213
|
+
if (start >= static_cast<int64_t>(current.size()))
|
|
1214
|
+
{
|
|
1215
|
+
start = static_cast<int64_t>(current.size()) - 1;
|
|
1216
|
+
}
|
|
1217
|
+
if (end < -1)
|
|
1218
|
+
{
|
|
1219
|
+
end = -1;
|
|
1220
|
+
}
|
|
1221
|
+
for (int64_t i = start; i > end; i += step)
|
|
1222
|
+
{
|
|
1223
|
+
std::size_t j = static_cast<std::size_t>(i);
|
|
1224
|
+
if (j < current.size())
|
|
1225
|
+
{
|
|
1226
|
+
this->tail_select(resources, root,
|
|
1227
|
+
path_generator_type::generate(resources, last,j,options), current[j], receiver, options);
|
|
1228
|
+
}
|
|
1229
|
+
}
|
|
1230
|
+
}
|
|
1231
|
+
}
|
|
1232
|
+
}
|
|
1233
|
+
|
|
1234
|
+
reference evaluate(dynamic_resources<Json,JsonReference>& resources,
|
|
1235
|
+
reference root,
|
|
1236
|
+
const json_location_node_type& last,
|
|
1237
|
+
reference current,
|
|
1238
|
+
result_options options,
|
|
1239
|
+
std::error_code&) const override
|
|
1240
|
+
{
|
|
1241
|
+
auto jptr = resources.create_json(json_array_arg);
|
|
1242
|
+
json_array_receiver<Json,JsonReference> accum(jptr);
|
|
1243
|
+
select(resources, root, last, current, accum, options);
|
|
1244
|
+
return *jptr;
|
|
1245
|
+
}
|
|
1246
|
+
};
|
|
1247
|
+
|
|
1248
|
+
template <class Json,class JsonReference>
|
|
1249
|
+
class function_selector final : public base_selector<Json,JsonReference>
|
|
1250
|
+
{
|
|
1251
|
+
using supertype = base_selector<Json,JsonReference>;
|
|
1252
|
+
|
|
1253
|
+
expression<Json,JsonReference> expr_;
|
|
1254
|
+
|
|
1255
|
+
public:
|
|
1256
|
+
using value_type = typename supertype::value_type;
|
|
1257
|
+
using reference = typename supertype::reference;
|
|
1258
|
+
using pointer = typename supertype::pointer;
|
|
1259
|
+
using path_value_pair_type = typename supertype::path_value_pair_type;
|
|
1260
|
+
using json_location_node_type = typename supertype::json_location_node_type;
|
|
1261
|
+
using path_generator_type = path_generator<Json,JsonReference>;
|
|
1262
|
+
using node_receiver_type = typename supertype::node_receiver_type;
|
|
1263
|
+
|
|
1264
|
+
function_selector(expression<Json,JsonReference>&& expr)
|
|
1265
|
+
: base_selector<Json,JsonReference>(), expr_(std::move(expr))
|
|
1266
|
+
{
|
|
1267
|
+
}
|
|
1268
|
+
|
|
1269
|
+
void select(dynamic_resources<Json,JsonReference>& resources,
|
|
1270
|
+
reference root,
|
|
1271
|
+
const json_location_node_type& last,
|
|
1272
|
+
reference current,
|
|
1273
|
+
node_receiver_type& receiver,
|
|
1274
|
+
result_options options) const override
|
|
1275
|
+
{
|
|
1276
|
+
std::error_code ec;
|
|
1277
|
+
value_type ref = expr_.evaluate(resources, root, current, options, ec);
|
|
1278
|
+
if (!ec)
|
|
1279
|
+
{
|
|
1280
|
+
this->tail_select(resources, root, last, *resources.create_json(std::move(ref)), receiver, options);
|
|
1281
|
+
}
|
|
1282
|
+
}
|
|
1283
|
+
|
|
1284
|
+
reference evaluate(dynamic_resources<Json,JsonReference>& resources,
|
|
1285
|
+
reference root,
|
|
1286
|
+
const json_location_node_type& last,
|
|
1287
|
+
reference current,
|
|
1288
|
+
result_options options,
|
|
1289
|
+
std::error_code& ec) const override
|
|
1290
|
+
{
|
|
1291
|
+
value_type ref = expr_.evaluate(resources, root, current, options, ec);
|
|
1292
|
+
if (!ec)
|
|
1293
|
+
{
|
|
1294
|
+
return this->evaluate_tail(resources, root, last, *resources.create_json(std::move(ref)),
|
|
1295
|
+
options, ec);
|
|
1296
|
+
}
|
|
1297
|
+
else
|
|
1298
|
+
{
|
|
1299
|
+
return resources.null_value();
|
|
1300
|
+
}
|
|
1301
|
+
}
|
|
1302
|
+
|
|
1303
|
+
std::string to_string(int level = 0) const override
|
|
1304
|
+
{
|
|
1305
|
+
std::string s;
|
|
1306
|
+
if (level > 0)
|
|
1307
|
+
{
|
|
1308
|
+
s.append("\n");
|
|
1309
|
+
s.append(level*2, ' ');
|
|
1310
|
+
}
|
|
1311
|
+
s.append("function_selector ");
|
|
1312
|
+
s.append(expr_.to_string(level+1));
|
|
1313
|
+
|
|
1314
|
+
return s;
|
|
1315
|
+
}
|
|
1316
|
+
};
|
|
1317
|
+
|
|
1318
|
+
} // namespace detail
|
|
1319
|
+
} // namespace jsonpath
|
|
1320
|
+
} // namespace jsoncons
|
|
1321
|
+
|
|
1322
|
+
#endif
|