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.
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