jsoncons 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (155) hide show
  1. checksums.yaml +7 -0
  2. data/ext/jsoncons/extconf.rb +43 -0
  3. data/ext/jsoncons/jsoncons.cpp +161 -0
  4. data/ext/jsoncons/jsoncons.h +10 -0
  5. data/jsoncons.gemspec +44 -0
  6. data/lib/jsoncons/jsoncons/examples/input/address-book.json +13 -0
  7. data/lib/jsoncons/jsoncons/examples/input/books.json +28 -0
  8. data/lib/jsoncons/jsoncons/examples/input/countries.json +7 -0
  9. data/lib/jsoncons/jsoncons/examples/input/employees.json +30 -0
  10. data/lib/jsoncons/jsoncons/examples/input/jsonschema/name.json +15 -0
  11. data/lib/jsoncons/jsoncons/examples/input/multiple-json-objects.json +3 -0
  12. data/lib/jsoncons/jsoncons/examples/input/sales.csv +6 -0
  13. data/lib/jsoncons/jsoncons/examples/input/store.json +28 -0
  14. data/lib/jsoncons/jsoncons/examples/input/tasks.csv +6 -0
  15. data/lib/jsoncons/jsoncons/include/jsoncons/allocator_holder.hpp +38 -0
  16. data/lib/jsoncons/jsoncons/include/jsoncons/basic_json.hpp +5905 -0
  17. data/lib/jsoncons/jsoncons/include/jsoncons/bigint.hpp +1611 -0
  18. data/lib/jsoncons/jsoncons/include/jsoncons/byte_string.hpp +820 -0
  19. data/lib/jsoncons/jsoncons/include/jsoncons/config/binary_config.hpp +226 -0
  20. data/lib/jsoncons/jsoncons/include/jsoncons/config/compiler_support.hpp +375 -0
  21. data/lib/jsoncons/jsoncons/include/jsoncons/config/jsoncons_config.hpp +309 -0
  22. data/lib/jsoncons/jsoncons/include/jsoncons/config/version.hpp +40 -0
  23. data/lib/jsoncons/jsoncons/include/jsoncons/conv_error.hpp +218 -0
  24. data/lib/jsoncons/jsoncons/include/jsoncons/decode_json.hpp +209 -0
  25. data/lib/jsoncons/jsoncons/include/jsoncons/decode_traits.hpp +651 -0
  26. data/lib/jsoncons/jsoncons/include/jsoncons/detail/endian.hpp +44 -0
  27. data/lib/jsoncons/jsoncons/include/jsoncons/detail/grisu3.hpp +312 -0
  28. data/lib/jsoncons/jsoncons/include/jsoncons/detail/optional.hpp +483 -0
  29. data/lib/jsoncons/jsoncons/include/jsoncons/detail/parse_number.hpp +1133 -0
  30. data/lib/jsoncons/jsoncons/include/jsoncons/detail/span.hpp +188 -0
  31. data/lib/jsoncons/jsoncons/include/jsoncons/detail/string_view.hpp +537 -0
  32. data/lib/jsoncons/jsoncons/include/jsoncons/detail/string_wrapper.hpp +370 -0
  33. data/lib/jsoncons/jsoncons/include/jsoncons/detail/write_number.hpp +567 -0
  34. data/lib/jsoncons/jsoncons/include/jsoncons/encode_json.hpp +315 -0
  35. data/lib/jsoncons/jsoncons/include/jsoncons/encode_traits.hpp +378 -0
  36. data/lib/jsoncons/jsoncons/include/jsoncons/json.hpp +18 -0
  37. data/lib/jsoncons/jsoncons/include/jsoncons/json_array.hpp +324 -0
  38. data/lib/jsoncons/jsoncons/include/jsoncons/json_content_handler.hpp +12 -0
  39. data/lib/jsoncons/jsoncons/include/jsoncons/json_cursor.hpp +448 -0
  40. data/lib/jsoncons/jsoncons/include/jsoncons/json_decoder.hpp +420 -0
  41. data/lib/jsoncons/jsoncons/include/jsoncons/json_encoder.hpp +1587 -0
  42. data/lib/jsoncons/jsoncons/include/jsoncons/json_error.hpp +156 -0
  43. data/lib/jsoncons/jsoncons/include/jsoncons/json_exception.hpp +241 -0
  44. data/lib/jsoncons/jsoncons/include/jsoncons/json_filter.hpp +653 -0
  45. data/lib/jsoncons/jsoncons/include/jsoncons/json_fwd.hpp +23 -0
  46. data/lib/jsoncons/jsoncons/include/jsoncons/json_object.hpp +1772 -0
  47. data/lib/jsoncons/jsoncons/include/jsoncons/json_options.hpp +862 -0
  48. data/lib/jsoncons/jsoncons/include/jsoncons/json_parser.hpp +2900 -0
  49. data/lib/jsoncons/jsoncons/include/jsoncons/json_reader.hpp +731 -0
  50. data/lib/jsoncons/jsoncons/include/jsoncons/json_traits_macros.hpp +1072 -0
  51. data/lib/jsoncons/jsoncons/include/jsoncons/json_traits_macros_deprecated.hpp +144 -0
  52. data/lib/jsoncons/jsoncons/include/jsoncons/json_type.hpp +206 -0
  53. data/lib/jsoncons/jsoncons/include/jsoncons/json_type_traits.hpp +1830 -0
  54. data/lib/jsoncons/jsoncons/include/jsoncons/json_visitor.hpp +1560 -0
  55. data/lib/jsoncons/jsoncons/include/jsoncons/json_visitor2.hpp +2079 -0
  56. data/lib/jsoncons/jsoncons/include/jsoncons/pretty_print.hpp +89 -0
  57. data/lib/jsoncons/jsoncons/include/jsoncons/ser_context.hpp +62 -0
  58. data/lib/jsoncons/jsoncons/include/jsoncons/sink.hpp +289 -0
  59. data/lib/jsoncons/jsoncons/include/jsoncons/source.hpp +777 -0
  60. data/lib/jsoncons/jsoncons/include/jsoncons/source_adaptor.hpp +148 -0
  61. data/lib/jsoncons/jsoncons/include/jsoncons/staj2_cursor.hpp +1189 -0
  62. data/lib/jsoncons/jsoncons/include/jsoncons/staj_cursor.hpp +1254 -0
  63. data/lib/jsoncons/jsoncons/include/jsoncons/staj_iterator.hpp +449 -0
  64. data/lib/jsoncons/jsoncons/include/jsoncons/tag_type.hpp +245 -0
  65. data/lib/jsoncons/jsoncons/include/jsoncons/text_source_adaptor.hpp +144 -0
  66. data/lib/jsoncons/jsoncons/include/jsoncons/traits_extension.hpp +884 -0
  67. data/lib/jsoncons/jsoncons/include/jsoncons/typed_array_view.hpp +250 -0
  68. data/lib/jsoncons/jsoncons/include/jsoncons/unicode_traits.hpp +1330 -0
  69. data/lib/jsoncons/jsoncons/include/jsoncons/uri.hpp +635 -0
  70. data/lib/jsoncons/jsoncons/include/jsoncons/value_converter.hpp +340 -0
  71. data/lib/jsoncons/jsoncons/include/jsoncons_ext/bson/bson.hpp +23 -0
  72. data/lib/jsoncons/jsoncons/include/jsoncons_ext/bson/bson_cursor.hpp +320 -0
  73. data/lib/jsoncons/jsoncons/include/jsoncons_ext/bson/bson_decimal128.hpp +865 -0
  74. data/lib/jsoncons/jsoncons/include/jsoncons_ext/bson/bson_encoder.hpp +585 -0
  75. data/lib/jsoncons/jsoncons/include/jsoncons_ext/bson/bson_error.hpp +103 -0
  76. data/lib/jsoncons/jsoncons/include/jsoncons_ext/bson/bson_oid.hpp +245 -0
  77. data/lib/jsoncons/jsoncons/include/jsoncons_ext/bson/bson_options.hpp +75 -0
  78. data/lib/jsoncons/jsoncons/include/jsoncons_ext/bson/bson_parser.hpp +645 -0
  79. data/lib/jsoncons/jsoncons/include/jsoncons_ext/bson/bson_reader.hpp +92 -0
  80. data/lib/jsoncons/jsoncons/include/jsoncons_ext/bson/bson_type.hpp +44 -0
  81. data/lib/jsoncons/jsoncons/include/jsoncons_ext/bson/decode_bson.hpp +201 -0
  82. data/lib/jsoncons/jsoncons/include/jsoncons_ext/bson/encode_bson.hpp +144 -0
  83. data/lib/jsoncons/jsoncons/include/jsoncons_ext/cbor/cbor.hpp +26 -0
  84. data/lib/jsoncons/jsoncons/include/jsoncons_ext/cbor/cbor_cursor.hpp +351 -0
  85. data/lib/jsoncons/jsoncons/include/jsoncons_ext/cbor/cbor_cursor2.hpp +265 -0
  86. data/lib/jsoncons/jsoncons/include/jsoncons_ext/cbor/cbor_detail.hpp +93 -0
  87. data/lib/jsoncons/jsoncons/include/jsoncons_ext/cbor/cbor_encoder.hpp +1766 -0
  88. data/lib/jsoncons/jsoncons/include/jsoncons_ext/cbor/cbor_error.hpp +105 -0
  89. data/lib/jsoncons/jsoncons/include/jsoncons_ext/cbor/cbor_options.hpp +113 -0
  90. data/lib/jsoncons/jsoncons/include/jsoncons_ext/cbor/cbor_parser.hpp +1942 -0
  91. data/lib/jsoncons/jsoncons/include/jsoncons_ext/cbor/cbor_reader.hpp +116 -0
  92. data/lib/jsoncons/jsoncons/include/jsoncons_ext/cbor/decode_cbor.hpp +203 -0
  93. data/lib/jsoncons/jsoncons/include/jsoncons_ext/cbor/encode_cbor.hpp +151 -0
  94. data/lib/jsoncons/jsoncons/include/jsoncons_ext/csv/csv.hpp +17 -0
  95. data/lib/jsoncons/jsoncons/include/jsoncons_ext/csv/csv_cursor.hpp +358 -0
  96. data/lib/jsoncons/jsoncons/include/jsoncons_ext/csv/csv_encoder.hpp +954 -0
  97. data/lib/jsoncons/jsoncons/include/jsoncons_ext/csv/csv_error.hpp +85 -0
  98. data/lib/jsoncons/jsoncons/include/jsoncons_ext/csv/csv_options.hpp +973 -0
  99. data/lib/jsoncons/jsoncons/include/jsoncons_ext/csv/csv_parser.hpp +2099 -0
  100. data/lib/jsoncons/jsoncons/include/jsoncons_ext/csv/csv_reader.hpp +348 -0
  101. data/lib/jsoncons/jsoncons/include/jsoncons_ext/csv/csv_serializer.hpp +12 -0
  102. data/lib/jsoncons/jsoncons/include/jsoncons_ext/csv/decode_csv.hpp +208 -0
  103. data/lib/jsoncons/jsoncons/include/jsoncons_ext/csv/encode_csv.hpp +122 -0
  104. data/lib/jsoncons/jsoncons/include/jsoncons_ext/jmespath/jmespath.hpp +5215 -0
  105. data/lib/jsoncons/jsoncons/include/jsoncons_ext/jmespath/jmespath_error.hpp +215 -0
  106. data/lib/jsoncons/jsoncons/include/jsoncons_ext/jsonpatch/jsonpatch.hpp +579 -0
  107. data/lib/jsoncons/jsoncons/include/jsoncons_ext/jsonpatch/jsonpatch_error.hpp +121 -0
  108. data/lib/jsoncons/jsoncons/include/jsoncons_ext/jsonpath/expression.hpp +3329 -0
  109. data/lib/jsoncons/jsoncons/include/jsoncons_ext/jsonpath/flatten.hpp +432 -0
  110. data/lib/jsoncons/jsoncons/include/jsoncons_ext/jsonpath/json_location.hpp +445 -0
  111. data/lib/jsoncons/jsoncons/include/jsoncons_ext/jsonpath/json_query.hpp +115 -0
  112. data/lib/jsoncons/jsoncons/include/jsoncons_ext/jsonpath/jsonpath.hpp +13 -0
  113. data/lib/jsoncons/jsoncons/include/jsoncons_ext/jsonpath/jsonpath_error.hpp +240 -0
  114. data/lib/jsoncons/jsoncons/include/jsoncons_ext/jsonpath/jsonpath_expression.hpp +2612 -0
  115. data/lib/jsoncons/jsoncons/include/jsoncons_ext/jsonpath/jsonpath_selector.hpp +1322 -0
  116. data/lib/jsoncons/jsoncons/include/jsoncons_ext/jsonpointer/jsonpointer.hpp +1577 -0
  117. data/lib/jsoncons/jsoncons/include/jsoncons_ext/jsonpointer/jsonpointer_error.hpp +119 -0
  118. data/lib/jsoncons/jsoncons/include/jsoncons_ext/jsonschema/format_validator.hpp +968 -0
  119. data/lib/jsoncons/jsoncons/include/jsoncons_ext/jsonschema/json_validator.hpp +120 -0
  120. data/lib/jsoncons/jsoncons/include/jsoncons_ext/jsonschema/jsonschema.hpp +13 -0
  121. data/lib/jsoncons/jsoncons/include/jsoncons_ext/jsonschema/jsonschema_error.hpp +105 -0
  122. data/lib/jsoncons/jsoncons/include/jsoncons_ext/jsonschema/jsonschema_version.hpp +18 -0
  123. data/lib/jsoncons/jsoncons/include/jsoncons_ext/jsonschema/keyword_validator.hpp +1745 -0
  124. data/lib/jsoncons/jsoncons/include/jsoncons_ext/jsonschema/keyword_validator_factory.hpp +556 -0
  125. data/lib/jsoncons/jsoncons/include/jsoncons_ext/jsonschema/schema_draft7.hpp +198 -0
  126. data/lib/jsoncons/jsoncons/include/jsoncons_ext/jsonschema/schema_location.hpp +200 -0
  127. data/lib/jsoncons/jsoncons/include/jsoncons_ext/jsonschema/schema_version.hpp +35 -0
  128. data/lib/jsoncons/jsoncons/include/jsoncons_ext/jsonschema/subschema.hpp +144 -0
  129. data/lib/jsoncons/jsoncons/include/jsoncons_ext/mergepatch/mergepatch.hpp +103 -0
  130. data/lib/jsoncons/jsoncons/include/jsoncons_ext/msgpack/decode_msgpack.hpp +202 -0
  131. data/lib/jsoncons/jsoncons/include/jsoncons_ext/msgpack/encode_msgpack.hpp +142 -0
  132. data/lib/jsoncons/jsoncons/include/jsoncons_ext/msgpack/msgpack.hpp +24 -0
  133. data/lib/jsoncons/jsoncons/include/jsoncons_ext/msgpack/msgpack_cursor.hpp +343 -0
  134. data/lib/jsoncons/jsoncons/include/jsoncons_ext/msgpack/msgpack_cursor2.hpp +259 -0
  135. data/lib/jsoncons/jsoncons/include/jsoncons_ext/msgpack/msgpack_encoder.hpp +753 -0
  136. data/lib/jsoncons/jsoncons/include/jsoncons_ext/msgpack/msgpack_error.hpp +94 -0
  137. data/lib/jsoncons/jsoncons/include/jsoncons_ext/msgpack/msgpack_options.hpp +74 -0
  138. data/lib/jsoncons/jsoncons/include/jsoncons_ext/msgpack/msgpack_parser.hpp +748 -0
  139. data/lib/jsoncons/jsoncons/include/jsoncons_ext/msgpack/msgpack_reader.hpp +116 -0
  140. data/lib/jsoncons/jsoncons/include/jsoncons_ext/msgpack/msgpack_type.hpp +63 -0
  141. data/lib/jsoncons/jsoncons/include/jsoncons_ext/ubjson/decode_ubjson.hpp +201 -0
  142. data/lib/jsoncons/jsoncons/include/jsoncons_ext/ubjson/encode_ubjson.hpp +142 -0
  143. data/lib/jsoncons/jsoncons/include/jsoncons_ext/ubjson/ubjson.hpp +23 -0
  144. data/lib/jsoncons/jsoncons/include/jsoncons_ext/ubjson/ubjson_cursor.hpp +307 -0
  145. data/lib/jsoncons/jsoncons/include/jsoncons_ext/ubjson/ubjson_encoder.hpp +502 -0
  146. data/lib/jsoncons/jsoncons/include/jsoncons_ext/ubjson/ubjson_error.hpp +100 -0
  147. data/lib/jsoncons/jsoncons/include/jsoncons_ext/ubjson/ubjson_options.hpp +87 -0
  148. data/lib/jsoncons/jsoncons/include/jsoncons_ext/ubjson/ubjson_parser.hpp +880 -0
  149. data/lib/jsoncons/jsoncons/include/jsoncons_ext/ubjson/ubjson_reader.hpp +92 -0
  150. data/lib/jsoncons/jsoncons/include/jsoncons_ext/ubjson/ubjson_type.hpp +43 -0
  151. data/lib/jsoncons/version.rb +5 -0
  152. data/lib/jsoncons.rb +33 -0
  153. data/test/jsoncons_test.rb +108 -0
  154. data/test/test_helper.rb +7 -0
  155. 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