jsoncons 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/ext/jsoncons/extconf.rb +43 -0
- data/ext/jsoncons/jsoncons.cpp +161 -0
- data/ext/jsoncons/jsoncons.h +10 -0
- data/jsoncons.gemspec +44 -0
- data/lib/jsoncons/jsoncons/examples/input/address-book.json +13 -0
- data/lib/jsoncons/jsoncons/examples/input/books.json +28 -0
- data/lib/jsoncons/jsoncons/examples/input/countries.json +7 -0
- data/lib/jsoncons/jsoncons/examples/input/employees.json +30 -0
- data/lib/jsoncons/jsoncons/examples/input/jsonschema/name.json +15 -0
- data/lib/jsoncons/jsoncons/examples/input/multiple-json-objects.json +3 -0
- data/lib/jsoncons/jsoncons/examples/input/sales.csv +6 -0
- data/lib/jsoncons/jsoncons/examples/input/store.json +28 -0
- data/lib/jsoncons/jsoncons/examples/input/tasks.csv +6 -0
- data/lib/jsoncons/jsoncons/include/jsoncons/allocator_holder.hpp +38 -0
- data/lib/jsoncons/jsoncons/include/jsoncons/basic_json.hpp +5905 -0
- data/lib/jsoncons/jsoncons/include/jsoncons/bigint.hpp +1611 -0
- data/lib/jsoncons/jsoncons/include/jsoncons/byte_string.hpp +820 -0
- data/lib/jsoncons/jsoncons/include/jsoncons/config/binary_config.hpp +226 -0
- data/lib/jsoncons/jsoncons/include/jsoncons/config/compiler_support.hpp +375 -0
- data/lib/jsoncons/jsoncons/include/jsoncons/config/jsoncons_config.hpp +309 -0
- data/lib/jsoncons/jsoncons/include/jsoncons/config/version.hpp +40 -0
- data/lib/jsoncons/jsoncons/include/jsoncons/conv_error.hpp +218 -0
- data/lib/jsoncons/jsoncons/include/jsoncons/decode_json.hpp +209 -0
- data/lib/jsoncons/jsoncons/include/jsoncons/decode_traits.hpp +651 -0
- data/lib/jsoncons/jsoncons/include/jsoncons/detail/endian.hpp +44 -0
- data/lib/jsoncons/jsoncons/include/jsoncons/detail/grisu3.hpp +312 -0
- data/lib/jsoncons/jsoncons/include/jsoncons/detail/optional.hpp +483 -0
- data/lib/jsoncons/jsoncons/include/jsoncons/detail/parse_number.hpp +1133 -0
- data/lib/jsoncons/jsoncons/include/jsoncons/detail/span.hpp +188 -0
- data/lib/jsoncons/jsoncons/include/jsoncons/detail/string_view.hpp +537 -0
- data/lib/jsoncons/jsoncons/include/jsoncons/detail/string_wrapper.hpp +370 -0
- data/lib/jsoncons/jsoncons/include/jsoncons/detail/write_number.hpp +567 -0
- data/lib/jsoncons/jsoncons/include/jsoncons/encode_json.hpp +315 -0
- data/lib/jsoncons/jsoncons/include/jsoncons/encode_traits.hpp +378 -0
- data/lib/jsoncons/jsoncons/include/jsoncons/json.hpp +18 -0
- data/lib/jsoncons/jsoncons/include/jsoncons/json_array.hpp +324 -0
- data/lib/jsoncons/jsoncons/include/jsoncons/json_content_handler.hpp +12 -0
- data/lib/jsoncons/jsoncons/include/jsoncons/json_cursor.hpp +448 -0
- data/lib/jsoncons/jsoncons/include/jsoncons/json_decoder.hpp +420 -0
- data/lib/jsoncons/jsoncons/include/jsoncons/json_encoder.hpp +1587 -0
- data/lib/jsoncons/jsoncons/include/jsoncons/json_error.hpp +156 -0
- data/lib/jsoncons/jsoncons/include/jsoncons/json_exception.hpp +241 -0
- data/lib/jsoncons/jsoncons/include/jsoncons/json_filter.hpp +653 -0
- data/lib/jsoncons/jsoncons/include/jsoncons/json_fwd.hpp +23 -0
- data/lib/jsoncons/jsoncons/include/jsoncons/json_object.hpp +1772 -0
- data/lib/jsoncons/jsoncons/include/jsoncons/json_options.hpp +862 -0
- data/lib/jsoncons/jsoncons/include/jsoncons/json_parser.hpp +2900 -0
- data/lib/jsoncons/jsoncons/include/jsoncons/json_reader.hpp +731 -0
- data/lib/jsoncons/jsoncons/include/jsoncons/json_traits_macros.hpp +1072 -0
- data/lib/jsoncons/jsoncons/include/jsoncons/json_traits_macros_deprecated.hpp +144 -0
- data/lib/jsoncons/jsoncons/include/jsoncons/json_type.hpp +206 -0
- data/lib/jsoncons/jsoncons/include/jsoncons/json_type_traits.hpp +1830 -0
- data/lib/jsoncons/jsoncons/include/jsoncons/json_visitor.hpp +1560 -0
- data/lib/jsoncons/jsoncons/include/jsoncons/json_visitor2.hpp +2079 -0
- data/lib/jsoncons/jsoncons/include/jsoncons/pretty_print.hpp +89 -0
- data/lib/jsoncons/jsoncons/include/jsoncons/ser_context.hpp +62 -0
- data/lib/jsoncons/jsoncons/include/jsoncons/sink.hpp +289 -0
- data/lib/jsoncons/jsoncons/include/jsoncons/source.hpp +777 -0
- data/lib/jsoncons/jsoncons/include/jsoncons/source_adaptor.hpp +148 -0
- data/lib/jsoncons/jsoncons/include/jsoncons/staj2_cursor.hpp +1189 -0
- data/lib/jsoncons/jsoncons/include/jsoncons/staj_cursor.hpp +1254 -0
- data/lib/jsoncons/jsoncons/include/jsoncons/staj_iterator.hpp +449 -0
- data/lib/jsoncons/jsoncons/include/jsoncons/tag_type.hpp +245 -0
- data/lib/jsoncons/jsoncons/include/jsoncons/text_source_adaptor.hpp +144 -0
- data/lib/jsoncons/jsoncons/include/jsoncons/traits_extension.hpp +884 -0
- data/lib/jsoncons/jsoncons/include/jsoncons/typed_array_view.hpp +250 -0
- data/lib/jsoncons/jsoncons/include/jsoncons/unicode_traits.hpp +1330 -0
- data/lib/jsoncons/jsoncons/include/jsoncons/uri.hpp +635 -0
- data/lib/jsoncons/jsoncons/include/jsoncons/value_converter.hpp +340 -0
- data/lib/jsoncons/jsoncons/include/jsoncons_ext/bson/bson.hpp +23 -0
- data/lib/jsoncons/jsoncons/include/jsoncons_ext/bson/bson_cursor.hpp +320 -0
- data/lib/jsoncons/jsoncons/include/jsoncons_ext/bson/bson_decimal128.hpp +865 -0
- data/lib/jsoncons/jsoncons/include/jsoncons_ext/bson/bson_encoder.hpp +585 -0
- data/lib/jsoncons/jsoncons/include/jsoncons_ext/bson/bson_error.hpp +103 -0
- data/lib/jsoncons/jsoncons/include/jsoncons_ext/bson/bson_oid.hpp +245 -0
- data/lib/jsoncons/jsoncons/include/jsoncons_ext/bson/bson_options.hpp +75 -0
- data/lib/jsoncons/jsoncons/include/jsoncons_ext/bson/bson_parser.hpp +645 -0
- data/lib/jsoncons/jsoncons/include/jsoncons_ext/bson/bson_reader.hpp +92 -0
- data/lib/jsoncons/jsoncons/include/jsoncons_ext/bson/bson_type.hpp +44 -0
- data/lib/jsoncons/jsoncons/include/jsoncons_ext/bson/decode_bson.hpp +201 -0
- data/lib/jsoncons/jsoncons/include/jsoncons_ext/bson/encode_bson.hpp +144 -0
- data/lib/jsoncons/jsoncons/include/jsoncons_ext/cbor/cbor.hpp +26 -0
- data/lib/jsoncons/jsoncons/include/jsoncons_ext/cbor/cbor_cursor.hpp +351 -0
- data/lib/jsoncons/jsoncons/include/jsoncons_ext/cbor/cbor_cursor2.hpp +265 -0
- data/lib/jsoncons/jsoncons/include/jsoncons_ext/cbor/cbor_detail.hpp +93 -0
- data/lib/jsoncons/jsoncons/include/jsoncons_ext/cbor/cbor_encoder.hpp +1766 -0
- data/lib/jsoncons/jsoncons/include/jsoncons_ext/cbor/cbor_error.hpp +105 -0
- data/lib/jsoncons/jsoncons/include/jsoncons_ext/cbor/cbor_options.hpp +113 -0
- data/lib/jsoncons/jsoncons/include/jsoncons_ext/cbor/cbor_parser.hpp +1942 -0
- data/lib/jsoncons/jsoncons/include/jsoncons_ext/cbor/cbor_reader.hpp +116 -0
- data/lib/jsoncons/jsoncons/include/jsoncons_ext/cbor/decode_cbor.hpp +203 -0
- data/lib/jsoncons/jsoncons/include/jsoncons_ext/cbor/encode_cbor.hpp +151 -0
- data/lib/jsoncons/jsoncons/include/jsoncons_ext/csv/csv.hpp +17 -0
- data/lib/jsoncons/jsoncons/include/jsoncons_ext/csv/csv_cursor.hpp +358 -0
- data/lib/jsoncons/jsoncons/include/jsoncons_ext/csv/csv_encoder.hpp +954 -0
- data/lib/jsoncons/jsoncons/include/jsoncons_ext/csv/csv_error.hpp +85 -0
- data/lib/jsoncons/jsoncons/include/jsoncons_ext/csv/csv_options.hpp +973 -0
- data/lib/jsoncons/jsoncons/include/jsoncons_ext/csv/csv_parser.hpp +2099 -0
- data/lib/jsoncons/jsoncons/include/jsoncons_ext/csv/csv_reader.hpp +348 -0
- data/lib/jsoncons/jsoncons/include/jsoncons_ext/csv/csv_serializer.hpp +12 -0
- data/lib/jsoncons/jsoncons/include/jsoncons_ext/csv/decode_csv.hpp +208 -0
- data/lib/jsoncons/jsoncons/include/jsoncons_ext/csv/encode_csv.hpp +122 -0
- data/lib/jsoncons/jsoncons/include/jsoncons_ext/jmespath/jmespath.hpp +5215 -0
- data/lib/jsoncons/jsoncons/include/jsoncons_ext/jmespath/jmespath_error.hpp +215 -0
- data/lib/jsoncons/jsoncons/include/jsoncons_ext/jsonpatch/jsonpatch.hpp +579 -0
- data/lib/jsoncons/jsoncons/include/jsoncons_ext/jsonpatch/jsonpatch_error.hpp +121 -0
- data/lib/jsoncons/jsoncons/include/jsoncons_ext/jsonpath/expression.hpp +3329 -0
- data/lib/jsoncons/jsoncons/include/jsoncons_ext/jsonpath/flatten.hpp +432 -0
- data/lib/jsoncons/jsoncons/include/jsoncons_ext/jsonpath/json_location.hpp +445 -0
- data/lib/jsoncons/jsoncons/include/jsoncons_ext/jsonpath/json_query.hpp +115 -0
- data/lib/jsoncons/jsoncons/include/jsoncons_ext/jsonpath/jsonpath.hpp +13 -0
- data/lib/jsoncons/jsoncons/include/jsoncons_ext/jsonpath/jsonpath_error.hpp +240 -0
- data/lib/jsoncons/jsoncons/include/jsoncons_ext/jsonpath/jsonpath_expression.hpp +2612 -0
- data/lib/jsoncons/jsoncons/include/jsoncons_ext/jsonpath/jsonpath_selector.hpp +1322 -0
- data/lib/jsoncons/jsoncons/include/jsoncons_ext/jsonpointer/jsonpointer.hpp +1577 -0
- data/lib/jsoncons/jsoncons/include/jsoncons_ext/jsonpointer/jsonpointer_error.hpp +119 -0
- data/lib/jsoncons/jsoncons/include/jsoncons_ext/jsonschema/format_validator.hpp +968 -0
- data/lib/jsoncons/jsoncons/include/jsoncons_ext/jsonschema/json_validator.hpp +120 -0
- data/lib/jsoncons/jsoncons/include/jsoncons_ext/jsonschema/jsonschema.hpp +13 -0
- data/lib/jsoncons/jsoncons/include/jsoncons_ext/jsonschema/jsonschema_error.hpp +105 -0
- data/lib/jsoncons/jsoncons/include/jsoncons_ext/jsonschema/jsonschema_version.hpp +18 -0
- data/lib/jsoncons/jsoncons/include/jsoncons_ext/jsonschema/keyword_validator.hpp +1745 -0
- data/lib/jsoncons/jsoncons/include/jsoncons_ext/jsonschema/keyword_validator_factory.hpp +556 -0
- data/lib/jsoncons/jsoncons/include/jsoncons_ext/jsonschema/schema_draft7.hpp +198 -0
- data/lib/jsoncons/jsoncons/include/jsoncons_ext/jsonschema/schema_location.hpp +200 -0
- data/lib/jsoncons/jsoncons/include/jsoncons_ext/jsonschema/schema_version.hpp +35 -0
- data/lib/jsoncons/jsoncons/include/jsoncons_ext/jsonschema/subschema.hpp +144 -0
- data/lib/jsoncons/jsoncons/include/jsoncons_ext/mergepatch/mergepatch.hpp +103 -0
- data/lib/jsoncons/jsoncons/include/jsoncons_ext/msgpack/decode_msgpack.hpp +202 -0
- data/lib/jsoncons/jsoncons/include/jsoncons_ext/msgpack/encode_msgpack.hpp +142 -0
- data/lib/jsoncons/jsoncons/include/jsoncons_ext/msgpack/msgpack.hpp +24 -0
- data/lib/jsoncons/jsoncons/include/jsoncons_ext/msgpack/msgpack_cursor.hpp +343 -0
- data/lib/jsoncons/jsoncons/include/jsoncons_ext/msgpack/msgpack_cursor2.hpp +259 -0
- data/lib/jsoncons/jsoncons/include/jsoncons_ext/msgpack/msgpack_encoder.hpp +753 -0
- data/lib/jsoncons/jsoncons/include/jsoncons_ext/msgpack/msgpack_error.hpp +94 -0
- data/lib/jsoncons/jsoncons/include/jsoncons_ext/msgpack/msgpack_options.hpp +74 -0
- data/lib/jsoncons/jsoncons/include/jsoncons_ext/msgpack/msgpack_parser.hpp +748 -0
- data/lib/jsoncons/jsoncons/include/jsoncons_ext/msgpack/msgpack_reader.hpp +116 -0
- data/lib/jsoncons/jsoncons/include/jsoncons_ext/msgpack/msgpack_type.hpp +63 -0
- data/lib/jsoncons/jsoncons/include/jsoncons_ext/ubjson/decode_ubjson.hpp +201 -0
- data/lib/jsoncons/jsoncons/include/jsoncons_ext/ubjson/encode_ubjson.hpp +142 -0
- data/lib/jsoncons/jsoncons/include/jsoncons_ext/ubjson/ubjson.hpp +23 -0
- data/lib/jsoncons/jsoncons/include/jsoncons_ext/ubjson/ubjson_cursor.hpp +307 -0
- data/lib/jsoncons/jsoncons/include/jsoncons_ext/ubjson/ubjson_encoder.hpp +502 -0
- data/lib/jsoncons/jsoncons/include/jsoncons_ext/ubjson/ubjson_error.hpp +100 -0
- data/lib/jsoncons/jsoncons/include/jsoncons_ext/ubjson/ubjson_options.hpp +87 -0
- data/lib/jsoncons/jsoncons/include/jsoncons_ext/ubjson/ubjson_parser.hpp +880 -0
- data/lib/jsoncons/jsoncons/include/jsoncons_ext/ubjson/ubjson_reader.hpp +92 -0
- data/lib/jsoncons/jsoncons/include/jsoncons_ext/ubjson/ubjson_type.hpp +43 -0
- data/lib/jsoncons/version.rb +5 -0
- data/lib/jsoncons.rb +33 -0
- data/test/jsoncons_test.rb +108 -0
- data/test/test_helper.rb +7 -0
- metadata +268 -0
|
@@ -0,0 +1,3329 @@
|
|
|
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_EXPRESSION_HPP
|
|
8
|
+
#define JSONCONS_JSONPATH_EXPRESSION_HPP
|
|
9
|
+
|
|
10
|
+
#include <string> // std::basic_string
|
|
11
|
+
#include <vector> // std::vector
|
|
12
|
+
#include <unordered_map> // std::unordered_map
|
|
13
|
+
#include <unordered_set> // std::unordered_set
|
|
14
|
+
#include <limits> // std::numeric_limits
|
|
15
|
+
#include <set> // std::set
|
|
16
|
+
#include <utility> // std::move
|
|
17
|
+
#if defined(JSONCONS_HAS_STD_REGEX)
|
|
18
|
+
#include <regex>
|
|
19
|
+
#endif
|
|
20
|
+
#include <jsoncons/json_type.hpp>
|
|
21
|
+
#include <jsoncons_ext/jsonpath/json_location.hpp>
|
|
22
|
+
#include <jsoncons_ext/jsonpath/jsonpath_error.hpp>
|
|
23
|
+
|
|
24
|
+
namespace jsoncons {
|
|
25
|
+
namespace jsonpath {
|
|
26
|
+
|
|
27
|
+
struct reference_arg_t
|
|
28
|
+
{
|
|
29
|
+
explicit reference_arg_t() = default;
|
|
30
|
+
};
|
|
31
|
+
constexpr reference_arg_t reference_arg{};
|
|
32
|
+
|
|
33
|
+
struct const_reference_arg_t
|
|
34
|
+
{
|
|
35
|
+
explicit const_reference_arg_t() = default;
|
|
36
|
+
};
|
|
37
|
+
constexpr const_reference_arg_t const_reference_arg{};
|
|
38
|
+
|
|
39
|
+
struct literal_arg_t
|
|
40
|
+
{
|
|
41
|
+
explicit literal_arg_t() = default;
|
|
42
|
+
};
|
|
43
|
+
constexpr literal_arg_t literal_arg{};
|
|
44
|
+
|
|
45
|
+
struct end_of_expression_arg_t
|
|
46
|
+
{
|
|
47
|
+
explicit end_of_expression_arg_t() = default;
|
|
48
|
+
};
|
|
49
|
+
constexpr end_of_expression_arg_t end_of_expression_arg{};
|
|
50
|
+
|
|
51
|
+
struct separator_arg_t
|
|
52
|
+
{
|
|
53
|
+
explicit separator_arg_t() = default;
|
|
54
|
+
};
|
|
55
|
+
constexpr separator_arg_t separator_arg{};
|
|
56
|
+
|
|
57
|
+
struct lparen_arg_t
|
|
58
|
+
{
|
|
59
|
+
explicit lparen_arg_t() = default;
|
|
60
|
+
};
|
|
61
|
+
constexpr lparen_arg_t lparen_arg{};
|
|
62
|
+
|
|
63
|
+
struct rparen_arg_t
|
|
64
|
+
{
|
|
65
|
+
explicit rparen_arg_t() = default;
|
|
66
|
+
};
|
|
67
|
+
constexpr rparen_arg_t rparen_arg{};
|
|
68
|
+
|
|
69
|
+
struct begin_union_arg_t
|
|
70
|
+
{
|
|
71
|
+
explicit begin_union_arg_t() = default;
|
|
72
|
+
};
|
|
73
|
+
constexpr begin_union_arg_t begin_union_arg{};
|
|
74
|
+
|
|
75
|
+
struct end_union_arg_t
|
|
76
|
+
{
|
|
77
|
+
explicit end_union_arg_t() = default;
|
|
78
|
+
};
|
|
79
|
+
constexpr end_union_arg_t end_union_arg{};
|
|
80
|
+
|
|
81
|
+
struct begin_filter_arg_t
|
|
82
|
+
{
|
|
83
|
+
explicit begin_filter_arg_t() = default;
|
|
84
|
+
};
|
|
85
|
+
constexpr begin_filter_arg_t begin_filter_arg{};
|
|
86
|
+
|
|
87
|
+
struct end_filter_arg_t
|
|
88
|
+
{
|
|
89
|
+
explicit end_filter_arg_t() = default;
|
|
90
|
+
};
|
|
91
|
+
constexpr end_filter_arg_t end_filter_arg{};
|
|
92
|
+
|
|
93
|
+
struct begin_expression_arg_t
|
|
94
|
+
{
|
|
95
|
+
explicit begin_expression_arg_t() = default;
|
|
96
|
+
};
|
|
97
|
+
constexpr begin_expression_arg_t begin_expression_arg{};
|
|
98
|
+
|
|
99
|
+
struct end_index_expression_arg_t
|
|
100
|
+
{
|
|
101
|
+
explicit end_index_expression_arg_t() = default;
|
|
102
|
+
};
|
|
103
|
+
constexpr end_index_expression_arg_t end_index_expression_arg{};
|
|
104
|
+
|
|
105
|
+
struct end_argument_expression_arg_t
|
|
106
|
+
{
|
|
107
|
+
explicit end_argument_expression_arg_t() = default;
|
|
108
|
+
};
|
|
109
|
+
constexpr end_argument_expression_arg_t end_argument_expression_arg{};
|
|
110
|
+
|
|
111
|
+
struct current_node_arg_t
|
|
112
|
+
{
|
|
113
|
+
explicit current_node_arg_t() = default;
|
|
114
|
+
};
|
|
115
|
+
constexpr current_node_arg_t current_node_arg{};
|
|
116
|
+
|
|
117
|
+
struct root_node_arg_t
|
|
118
|
+
{
|
|
119
|
+
explicit root_node_arg_t() = default;
|
|
120
|
+
};
|
|
121
|
+
constexpr root_node_arg_t root_node_arg{};
|
|
122
|
+
|
|
123
|
+
struct end_function_arg_t
|
|
124
|
+
{
|
|
125
|
+
explicit end_function_arg_t() = default;
|
|
126
|
+
};
|
|
127
|
+
constexpr end_function_arg_t end_function_arg{};
|
|
128
|
+
|
|
129
|
+
struct argument_arg_t
|
|
130
|
+
{
|
|
131
|
+
explicit argument_arg_t() = default;
|
|
132
|
+
};
|
|
133
|
+
constexpr argument_arg_t argument_arg{};
|
|
134
|
+
|
|
135
|
+
enum class result_options {value=0, nodups=1, sort=2, path=4};
|
|
136
|
+
|
|
137
|
+
using result_type = result_options;
|
|
138
|
+
|
|
139
|
+
inline result_options operator~(result_options a)
|
|
140
|
+
{
|
|
141
|
+
return static_cast<result_options>(~static_cast<unsigned int>(a));
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
inline result_options operator&(result_options a, result_options b)
|
|
145
|
+
{
|
|
146
|
+
return static_cast<result_options>(static_cast<unsigned int>(a) & static_cast<unsigned int>(b));
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
inline result_options operator^(result_options a, result_options b)
|
|
150
|
+
{
|
|
151
|
+
return static_cast<result_options>(static_cast<unsigned int>(a) ^ static_cast<unsigned int>(b));
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
inline result_options operator|(result_options a, result_options b)
|
|
155
|
+
{
|
|
156
|
+
return static_cast<result_options>(static_cast<unsigned int>(a) | static_cast<unsigned int>(b));
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
inline result_options operator&=(result_options& a, result_options b)
|
|
160
|
+
{
|
|
161
|
+
a = a & b;
|
|
162
|
+
return a;
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
inline result_options operator^=(result_options& a, result_options b)
|
|
166
|
+
{
|
|
167
|
+
a = a ^ b;
|
|
168
|
+
return a;
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
inline result_options operator|=(result_options& a, result_options b)
|
|
172
|
+
{
|
|
173
|
+
a = a | b;
|
|
174
|
+
return a;
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
template <class Json>
|
|
178
|
+
class parameter;
|
|
179
|
+
|
|
180
|
+
template <class Json,class JsonReference>
|
|
181
|
+
class value_or_pointer
|
|
182
|
+
{
|
|
183
|
+
public:
|
|
184
|
+
friend class parameter<Json>;
|
|
185
|
+
using value_type = Json;
|
|
186
|
+
using reference = JsonReference;
|
|
187
|
+
using pointer = typename std::conditional<std::is_const<typename std::remove_reference<reference>::type>::value,typename Json::const_pointer,typename Json::pointer>::type;
|
|
188
|
+
private:
|
|
189
|
+
bool is_value_;
|
|
190
|
+
union
|
|
191
|
+
{
|
|
192
|
+
value_type val_;
|
|
193
|
+
pointer ptr_;
|
|
194
|
+
};
|
|
195
|
+
public:
|
|
196
|
+
value_or_pointer(value_type&& val)
|
|
197
|
+
: is_value_(true), val_(std::move(val))
|
|
198
|
+
{
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
value_or_pointer(pointer ptr)
|
|
202
|
+
: is_value_(false), ptr_(std::move(ptr))
|
|
203
|
+
{
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
value_or_pointer(value_or_pointer&& other) noexcept
|
|
207
|
+
: is_value_(other.is_value_)
|
|
208
|
+
{
|
|
209
|
+
if (is_value_)
|
|
210
|
+
{
|
|
211
|
+
new(&val_)value_type(std::move(other.val_));
|
|
212
|
+
}
|
|
213
|
+
else
|
|
214
|
+
{
|
|
215
|
+
ptr_ = other.ptr_;
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
~value_or_pointer() noexcept
|
|
220
|
+
{
|
|
221
|
+
if (is_value_)
|
|
222
|
+
{
|
|
223
|
+
val_.~value_type();
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
value_or_pointer& operator=(value_or_pointer&& other) noexcept
|
|
228
|
+
{
|
|
229
|
+
if (is_value_)
|
|
230
|
+
{
|
|
231
|
+
val_.~value_type();
|
|
232
|
+
}
|
|
233
|
+
is_value_ = other.is_value_;
|
|
234
|
+
|
|
235
|
+
if (is_value_)
|
|
236
|
+
{
|
|
237
|
+
new(&val_)value_type(std::move(other.val_));
|
|
238
|
+
}
|
|
239
|
+
else
|
|
240
|
+
{
|
|
241
|
+
ptr_ = other.ptr_;
|
|
242
|
+
}
|
|
243
|
+
return *this;
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
reference value()
|
|
247
|
+
{
|
|
248
|
+
return is_value_ ? val_ : *ptr_;
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
pointer ptr()
|
|
252
|
+
{
|
|
253
|
+
return is_value_ ? &val_ : ptr_;
|
|
254
|
+
}
|
|
255
|
+
};
|
|
256
|
+
|
|
257
|
+
template <class Json>
|
|
258
|
+
class parameter
|
|
259
|
+
{
|
|
260
|
+
using value_type = Json;
|
|
261
|
+
using reference = const Json&;
|
|
262
|
+
using pointer = const Json*;
|
|
263
|
+
private:
|
|
264
|
+
value_or_pointer<Json,reference> data_;
|
|
265
|
+
public:
|
|
266
|
+
template <class JsonReference>
|
|
267
|
+
parameter(value_or_pointer<Json,JsonReference>&& data) noexcept
|
|
268
|
+
: data_(nullptr)
|
|
269
|
+
{
|
|
270
|
+
data_.is_value_ = data.is_value_;
|
|
271
|
+
if (data.is_value_)
|
|
272
|
+
{
|
|
273
|
+
data_.val_ = std::move(data.val_);
|
|
274
|
+
}
|
|
275
|
+
else
|
|
276
|
+
{
|
|
277
|
+
data_.ptr_ = data.ptr_;
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
parameter(parameter&& other) noexcept = default;
|
|
282
|
+
|
|
283
|
+
parameter& operator=(parameter&& other) noexcept = default;
|
|
284
|
+
|
|
285
|
+
const Json& value() const
|
|
286
|
+
{
|
|
287
|
+
return data_.is_value_ ? data_.val_ : *data_.ptr_;
|
|
288
|
+
}
|
|
289
|
+
};
|
|
290
|
+
|
|
291
|
+
template <class Json>
|
|
292
|
+
class custom_function
|
|
293
|
+
{
|
|
294
|
+
public:
|
|
295
|
+
using value_type = Json;
|
|
296
|
+
using char_type = typename Json::char_type;
|
|
297
|
+
using parameter_type = parameter<Json>;
|
|
298
|
+
using function_type = std::function<value_type(jsoncons::span<const parameter_type>, std::error_code& ec)>;
|
|
299
|
+
using string_type = std::basic_string<char_type>;
|
|
300
|
+
|
|
301
|
+
string_type function_name_;
|
|
302
|
+
optional<std::size_t> arity_;
|
|
303
|
+
function_type f_;
|
|
304
|
+
|
|
305
|
+
custom_function(const string_type& function_name,
|
|
306
|
+
const optional<std::size_t>& arity,
|
|
307
|
+
const function_type& f)
|
|
308
|
+
: function_name_(function_name),
|
|
309
|
+
arity_(arity),
|
|
310
|
+
f_(f)
|
|
311
|
+
{
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
custom_function(string_type&& function_name,
|
|
315
|
+
optional<std::size_t>&& arity,
|
|
316
|
+
function_type&& f)
|
|
317
|
+
: function_name_(std::move(function_name)),
|
|
318
|
+
arity_(std::move(arity)),
|
|
319
|
+
f_(std::move(f))
|
|
320
|
+
{
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
custom_function(const custom_function&) = default;
|
|
324
|
+
|
|
325
|
+
custom_function(custom_function&&) = default;
|
|
326
|
+
|
|
327
|
+
const string_type& name() const
|
|
328
|
+
{
|
|
329
|
+
return function_name_;
|
|
330
|
+
}
|
|
331
|
+
|
|
332
|
+
optional<std::size_t> arity() const
|
|
333
|
+
{
|
|
334
|
+
return arity_;
|
|
335
|
+
}
|
|
336
|
+
|
|
337
|
+
const function_type& function() const
|
|
338
|
+
{
|
|
339
|
+
return f_;
|
|
340
|
+
}
|
|
341
|
+
};
|
|
342
|
+
|
|
343
|
+
template <class Json>
|
|
344
|
+
class custom_functions
|
|
345
|
+
{
|
|
346
|
+
using char_type = typename Json::char_type;
|
|
347
|
+
using string_type = std::basic_string<char_type>;
|
|
348
|
+
using value_type = Json;
|
|
349
|
+
using parameter_type = parameter<Json>;
|
|
350
|
+
using function_type = std::function<value_type(jsoncons::span<const parameter_type>, std::error_code& ec)>;
|
|
351
|
+
using const_iterator = typename std::vector<custom_function<Json>>::const_iterator;
|
|
352
|
+
|
|
353
|
+
std::vector<custom_function<Json>> functions_;
|
|
354
|
+
public:
|
|
355
|
+
void register_function(const string_type& name,
|
|
356
|
+
jsoncons::optional<std::size_t> arity,
|
|
357
|
+
const function_type& f)
|
|
358
|
+
{
|
|
359
|
+
functions_.emplace_back(name, arity, f);
|
|
360
|
+
}
|
|
361
|
+
|
|
362
|
+
const_iterator begin() const
|
|
363
|
+
{
|
|
364
|
+
return functions_.begin();
|
|
365
|
+
}
|
|
366
|
+
|
|
367
|
+
const_iterator end() const
|
|
368
|
+
{
|
|
369
|
+
return functions_.end();
|
|
370
|
+
}
|
|
371
|
+
};
|
|
372
|
+
|
|
373
|
+
namespace detail {
|
|
374
|
+
|
|
375
|
+
template <class Json,class JsonReference>
|
|
376
|
+
class dynamic_resources;
|
|
377
|
+
|
|
378
|
+
template <class Json,class JsonReference>
|
|
379
|
+
struct unary_operator
|
|
380
|
+
{
|
|
381
|
+
std::size_t precedence_level_;
|
|
382
|
+
bool is_right_associative_;
|
|
383
|
+
|
|
384
|
+
unary_operator(std::size_t precedence_level,
|
|
385
|
+
bool is_right_associative)
|
|
386
|
+
: precedence_level_(precedence_level),
|
|
387
|
+
is_right_associative_(is_right_associative)
|
|
388
|
+
{
|
|
389
|
+
}
|
|
390
|
+
|
|
391
|
+
virtual ~unary_operator() = default;
|
|
392
|
+
|
|
393
|
+
std::size_t precedence_level() const
|
|
394
|
+
{
|
|
395
|
+
return precedence_level_;
|
|
396
|
+
}
|
|
397
|
+
bool is_right_associative() const
|
|
398
|
+
{
|
|
399
|
+
return is_right_associative_;
|
|
400
|
+
}
|
|
401
|
+
|
|
402
|
+
virtual Json evaluate(JsonReference,
|
|
403
|
+
std::error_code&) const = 0;
|
|
404
|
+
};
|
|
405
|
+
|
|
406
|
+
template <class Json>
|
|
407
|
+
bool is_false(const Json& val)
|
|
408
|
+
{
|
|
409
|
+
return ((val.is_array() && val.empty()) ||
|
|
410
|
+
(val.is_object() && val.empty()) ||
|
|
411
|
+
(val.is_string() && val.as_string_view().empty()) ||
|
|
412
|
+
(val.is_bool() && !val.as_bool()) ||
|
|
413
|
+
val.is_null());
|
|
414
|
+
}
|
|
415
|
+
|
|
416
|
+
template <class Json>
|
|
417
|
+
bool is_true(const Json& val)
|
|
418
|
+
{
|
|
419
|
+
return !is_false(val);
|
|
420
|
+
}
|
|
421
|
+
|
|
422
|
+
template <class Json,class JsonReference>
|
|
423
|
+
class unary_not_operator final : public unary_operator<Json,JsonReference>
|
|
424
|
+
{
|
|
425
|
+
public:
|
|
426
|
+
unary_not_operator()
|
|
427
|
+
: unary_operator<Json,JsonReference>(1, true)
|
|
428
|
+
{}
|
|
429
|
+
|
|
430
|
+
Json evaluate(JsonReference val,
|
|
431
|
+
std::error_code&) const override
|
|
432
|
+
{
|
|
433
|
+
return is_false(val) ? Json(true) : Json(false);
|
|
434
|
+
}
|
|
435
|
+
};
|
|
436
|
+
|
|
437
|
+
template <class Json,class JsonReference>
|
|
438
|
+
class unary_minus_operator final : public unary_operator<Json,JsonReference>
|
|
439
|
+
{
|
|
440
|
+
public:
|
|
441
|
+
unary_minus_operator()
|
|
442
|
+
: unary_operator<Json,JsonReference>(1, true)
|
|
443
|
+
{}
|
|
444
|
+
|
|
445
|
+
Json evaluate(JsonReference val,
|
|
446
|
+
std::error_code&) const override
|
|
447
|
+
{
|
|
448
|
+
if (val.is_int64())
|
|
449
|
+
{
|
|
450
|
+
return Json(-val.template as<int64_t>());
|
|
451
|
+
}
|
|
452
|
+
else if (val.is_double())
|
|
453
|
+
{
|
|
454
|
+
return Json(-val.as_double());
|
|
455
|
+
}
|
|
456
|
+
else
|
|
457
|
+
{
|
|
458
|
+
return Json::null();
|
|
459
|
+
}
|
|
460
|
+
}
|
|
461
|
+
};
|
|
462
|
+
|
|
463
|
+
template <class Json,class JsonReference>
|
|
464
|
+
class regex_operator final : public unary_operator<Json,JsonReference>
|
|
465
|
+
{
|
|
466
|
+
using char_type = typename Json::char_type;
|
|
467
|
+
using string_type = std::basic_string<char_type>;
|
|
468
|
+
std::basic_regex<char_type> pattern_;
|
|
469
|
+
public:
|
|
470
|
+
regex_operator(std::basic_regex<char_type>&& pattern)
|
|
471
|
+
: unary_operator<Json,JsonReference>(2, true),
|
|
472
|
+
pattern_(std::move(pattern))
|
|
473
|
+
{
|
|
474
|
+
}
|
|
475
|
+
|
|
476
|
+
regex_operator(regex_operator&&) = default;
|
|
477
|
+
regex_operator& operator=(regex_operator&&) = default;
|
|
478
|
+
|
|
479
|
+
Json evaluate(JsonReference val,
|
|
480
|
+
std::error_code&) const override
|
|
481
|
+
{
|
|
482
|
+
if (!val.is_string())
|
|
483
|
+
{
|
|
484
|
+
return Json::null();
|
|
485
|
+
}
|
|
486
|
+
return std::regex_search(val.as_string(), pattern_) ? Json(true) : Json(false);
|
|
487
|
+
}
|
|
488
|
+
};
|
|
489
|
+
|
|
490
|
+
template <class Json,class JsonReference>
|
|
491
|
+
struct binary_operator
|
|
492
|
+
{
|
|
493
|
+
std::size_t precedence_level_;
|
|
494
|
+
bool is_right_associative_;
|
|
495
|
+
|
|
496
|
+
binary_operator(std::size_t precedence_level,
|
|
497
|
+
bool is_right_associative = false)
|
|
498
|
+
: precedence_level_(precedence_level),
|
|
499
|
+
is_right_associative_(is_right_associative)
|
|
500
|
+
{
|
|
501
|
+
}
|
|
502
|
+
|
|
503
|
+
std::size_t precedence_level() const
|
|
504
|
+
{
|
|
505
|
+
return precedence_level_;
|
|
506
|
+
}
|
|
507
|
+
bool is_right_associative() const
|
|
508
|
+
{
|
|
509
|
+
return is_right_associative_;
|
|
510
|
+
}
|
|
511
|
+
|
|
512
|
+
virtual Json evaluate(JsonReference,
|
|
513
|
+
JsonReference,
|
|
514
|
+
|
|
515
|
+
std::error_code&) const = 0;
|
|
516
|
+
|
|
517
|
+
virtual std::string to_string(int = 0) const
|
|
518
|
+
{
|
|
519
|
+
return "binary operator";
|
|
520
|
+
}
|
|
521
|
+
|
|
522
|
+
protected:
|
|
523
|
+
~binary_operator() = default;
|
|
524
|
+
};
|
|
525
|
+
|
|
526
|
+
// Implementations
|
|
527
|
+
|
|
528
|
+
template <class Json,class JsonReference>
|
|
529
|
+
class or_operator final : public binary_operator<Json,JsonReference>
|
|
530
|
+
{
|
|
531
|
+
public:
|
|
532
|
+
or_operator()
|
|
533
|
+
: binary_operator<Json,JsonReference>(9)
|
|
534
|
+
{
|
|
535
|
+
}
|
|
536
|
+
|
|
537
|
+
Json evaluate(JsonReference lhs, JsonReference rhs, std::error_code&) const override
|
|
538
|
+
{
|
|
539
|
+
if (lhs.is_null() && rhs.is_null())
|
|
540
|
+
{
|
|
541
|
+
return Json::null();
|
|
542
|
+
}
|
|
543
|
+
if (!is_false(lhs))
|
|
544
|
+
{
|
|
545
|
+
return lhs;
|
|
546
|
+
}
|
|
547
|
+
else
|
|
548
|
+
{
|
|
549
|
+
return rhs;
|
|
550
|
+
}
|
|
551
|
+
}
|
|
552
|
+
std::string to_string(int level = 0) const override
|
|
553
|
+
{
|
|
554
|
+
std::string s;
|
|
555
|
+
if (level > 0)
|
|
556
|
+
{
|
|
557
|
+
//s.append("\n");
|
|
558
|
+
s.append(level*2, ' ');
|
|
559
|
+
}
|
|
560
|
+
s.append("or operator");
|
|
561
|
+
return s;
|
|
562
|
+
}
|
|
563
|
+
};
|
|
564
|
+
|
|
565
|
+
template <class Json,class JsonReference>
|
|
566
|
+
class and_operator final : public binary_operator<Json,JsonReference>
|
|
567
|
+
{
|
|
568
|
+
public:
|
|
569
|
+
and_operator()
|
|
570
|
+
: binary_operator<Json,JsonReference>(8)
|
|
571
|
+
{
|
|
572
|
+
}
|
|
573
|
+
|
|
574
|
+
Json evaluate(JsonReference lhs, JsonReference rhs, std::error_code&) const override
|
|
575
|
+
{
|
|
576
|
+
if (is_true(lhs))
|
|
577
|
+
{
|
|
578
|
+
return rhs;
|
|
579
|
+
}
|
|
580
|
+
else
|
|
581
|
+
{
|
|
582
|
+
return lhs;
|
|
583
|
+
}
|
|
584
|
+
}
|
|
585
|
+
|
|
586
|
+
std::string to_string(int level = 0) const override
|
|
587
|
+
{
|
|
588
|
+
std::string s;
|
|
589
|
+
if (level > 0)
|
|
590
|
+
{
|
|
591
|
+
s.append("\n");
|
|
592
|
+
s.append(level*2, ' ');
|
|
593
|
+
}
|
|
594
|
+
s.append("and operator");
|
|
595
|
+
return s;
|
|
596
|
+
}
|
|
597
|
+
};
|
|
598
|
+
|
|
599
|
+
template <class Json,class JsonReference>
|
|
600
|
+
class eq_operator final : public binary_operator<Json,JsonReference>
|
|
601
|
+
{
|
|
602
|
+
public:
|
|
603
|
+
eq_operator()
|
|
604
|
+
: binary_operator<Json,JsonReference>(6)
|
|
605
|
+
{
|
|
606
|
+
}
|
|
607
|
+
|
|
608
|
+
Json evaluate(JsonReference lhs, JsonReference rhs, std::error_code&) const override
|
|
609
|
+
{
|
|
610
|
+
return lhs == rhs ? Json(true) : Json(false);
|
|
611
|
+
}
|
|
612
|
+
|
|
613
|
+
std::string to_string(int level = 0) const override
|
|
614
|
+
{
|
|
615
|
+
std::string s;
|
|
616
|
+
if (level > 0)
|
|
617
|
+
{
|
|
618
|
+
s.append("\n");
|
|
619
|
+
s.append(level*2, ' ');
|
|
620
|
+
}
|
|
621
|
+
s.append("equal operator");
|
|
622
|
+
return s;
|
|
623
|
+
}
|
|
624
|
+
};
|
|
625
|
+
|
|
626
|
+
template <class Json,class JsonReference>
|
|
627
|
+
class ne_operator final : public binary_operator<Json,JsonReference>
|
|
628
|
+
{
|
|
629
|
+
public:
|
|
630
|
+
ne_operator()
|
|
631
|
+
: binary_operator<Json,JsonReference>(6)
|
|
632
|
+
{
|
|
633
|
+
}
|
|
634
|
+
|
|
635
|
+
Json evaluate(JsonReference lhs, JsonReference rhs, std::error_code&) const override
|
|
636
|
+
{
|
|
637
|
+
return lhs != rhs ? Json(true) : Json(false);
|
|
638
|
+
}
|
|
639
|
+
|
|
640
|
+
std::string to_string(int level = 0) const override
|
|
641
|
+
{
|
|
642
|
+
std::string s;
|
|
643
|
+
if (level > 0)
|
|
644
|
+
{
|
|
645
|
+
s.append("\n");
|
|
646
|
+
s.append(level*2, ' ');
|
|
647
|
+
}
|
|
648
|
+
s.append("not equal operator");
|
|
649
|
+
return s;
|
|
650
|
+
}
|
|
651
|
+
};
|
|
652
|
+
|
|
653
|
+
template <class Json,class JsonReference>
|
|
654
|
+
class lt_operator final : public binary_operator<Json,JsonReference>
|
|
655
|
+
{
|
|
656
|
+
public:
|
|
657
|
+
lt_operator()
|
|
658
|
+
: binary_operator<Json,JsonReference>(5)
|
|
659
|
+
{
|
|
660
|
+
}
|
|
661
|
+
|
|
662
|
+
Json evaluate(JsonReference lhs, JsonReference rhs, std::error_code&) const override
|
|
663
|
+
{
|
|
664
|
+
if (lhs.is_number() && rhs.is_number())
|
|
665
|
+
{
|
|
666
|
+
return lhs < rhs ? Json(true) : Json(false);
|
|
667
|
+
}
|
|
668
|
+
else if (lhs.is_string() && rhs.is_string())
|
|
669
|
+
{
|
|
670
|
+
return lhs < rhs ? Json(true) : Json(false);
|
|
671
|
+
}
|
|
672
|
+
return Json::null();
|
|
673
|
+
}
|
|
674
|
+
|
|
675
|
+
std::string to_string(int level = 0) const override
|
|
676
|
+
{
|
|
677
|
+
std::string s;
|
|
678
|
+
if (level > 0)
|
|
679
|
+
{
|
|
680
|
+
s.append("\n");
|
|
681
|
+
s.append(level*2, ' ');
|
|
682
|
+
}
|
|
683
|
+
s.append("less than operator");
|
|
684
|
+
return s;
|
|
685
|
+
}
|
|
686
|
+
};
|
|
687
|
+
|
|
688
|
+
template <class Json,class JsonReference>
|
|
689
|
+
class lte_operator final : public binary_operator<Json,JsonReference>
|
|
690
|
+
{
|
|
691
|
+
public:
|
|
692
|
+
lte_operator()
|
|
693
|
+
: binary_operator<Json,JsonReference>(5)
|
|
694
|
+
{
|
|
695
|
+
}
|
|
696
|
+
|
|
697
|
+
Json evaluate(JsonReference lhs, JsonReference rhs, std::error_code&) const override
|
|
698
|
+
{
|
|
699
|
+
if (lhs.is_number() && rhs.is_number())
|
|
700
|
+
{
|
|
701
|
+
return lhs <= rhs ? Json(true) : Json(false);
|
|
702
|
+
}
|
|
703
|
+
else if (lhs.is_string() && rhs.is_string())
|
|
704
|
+
{
|
|
705
|
+
return lhs <= rhs ? Json(true) : Json(false);
|
|
706
|
+
}
|
|
707
|
+
return Json::null();
|
|
708
|
+
}
|
|
709
|
+
|
|
710
|
+
std::string to_string(int level = 0) const override
|
|
711
|
+
{
|
|
712
|
+
std::string s;
|
|
713
|
+
if (level > 0)
|
|
714
|
+
{
|
|
715
|
+
s.append("\n");
|
|
716
|
+
s.append(level*2, ' ');
|
|
717
|
+
}
|
|
718
|
+
s.append("less than or equal operator");
|
|
719
|
+
return s;
|
|
720
|
+
}
|
|
721
|
+
};
|
|
722
|
+
|
|
723
|
+
template <class Json,class JsonReference>
|
|
724
|
+
class gt_operator final : public binary_operator<Json,JsonReference>
|
|
725
|
+
{
|
|
726
|
+
public:
|
|
727
|
+
gt_operator()
|
|
728
|
+
: binary_operator<Json,JsonReference>(5)
|
|
729
|
+
{
|
|
730
|
+
}
|
|
731
|
+
|
|
732
|
+
Json evaluate(JsonReference lhs, JsonReference rhs, std::error_code&) const override
|
|
733
|
+
{
|
|
734
|
+
//std::cout << "operator> lhs: " << lhs << ", rhs: " << rhs << "\n";
|
|
735
|
+
|
|
736
|
+
if (lhs.is_number() && rhs.is_number())
|
|
737
|
+
{
|
|
738
|
+
return lhs > rhs ? Json(true) : Json(false);
|
|
739
|
+
}
|
|
740
|
+
else if (lhs.is_string() && rhs.is_string())
|
|
741
|
+
{
|
|
742
|
+
return lhs > rhs ? Json(true) : Json(false);
|
|
743
|
+
}
|
|
744
|
+
return Json::null();
|
|
745
|
+
}
|
|
746
|
+
|
|
747
|
+
std::string to_string(int level = 0) const override
|
|
748
|
+
{
|
|
749
|
+
std::string s;
|
|
750
|
+
if (level > 0)
|
|
751
|
+
{
|
|
752
|
+
s.append("\n");
|
|
753
|
+
s.append(level*2, ' ');
|
|
754
|
+
}
|
|
755
|
+
s.append("greater than operator");
|
|
756
|
+
return s;
|
|
757
|
+
}
|
|
758
|
+
};
|
|
759
|
+
|
|
760
|
+
template <class Json,class JsonReference>
|
|
761
|
+
class gte_operator final : public binary_operator<Json,JsonReference>
|
|
762
|
+
{
|
|
763
|
+
public:
|
|
764
|
+
gte_operator()
|
|
765
|
+
: binary_operator<Json,JsonReference>(5)
|
|
766
|
+
{
|
|
767
|
+
}
|
|
768
|
+
|
|
769
|
+
Json evaluate(JsonReference lhs, JsonReference rhs, std::error_code&) const override
|
|
770
|
+
{
|
|
771
|
+
if (lhs.is_number() && rhs.is_number())
|
|
772
|
+
{
|
|
773
|
+
return lhs >= rhs ? Json(true) : Json(false);
|
|
774
|
+
}
|
|
775
|
+
else if (lhs.is_string() && rhs.is_string())
|
|
776
|
+
{
|
|
777
|
+
return lhs >= rhs ? Json(true) : Json(false);
|
|
778
|
+
}
|
|
779
|
+
return Json::null();
|
|
780
|
+
}
|
|
781
|
+
|
|
782
|
+
std::string to_string(int level = 0) const override
|
|
783
|
+
{
|
|
784
|
+
std::string s;
|
|
785
|
+
if (level > 0)
|
|
786
|
+
{
|
|
787
|
+
s.append("\n");
|
|
788
|
+
s.append(level*2, ' ');
|
|
789
|
+
}
|
|
790
|
+
s.append("greater than or equal operator");
|
|
791
|
+
return s;
|
|
792
|
+
}
|
|
793
|
+
};
|
|
794
|
+
|
|
795
|
+
template <class Json,class JsonReference>
|
|
796
|
+
class plus_operator final : public binary_operator<Json,JsonReference>
|
|
797
|
+
{
|
|
798
|
+
public:
|
|
799
|
+
plus_operator()
|
|
800
|
+
: binary_operator<Json,JsonReference>(4)
|
|
801
|
+
{
|
|
802
|
+
}
|
|
803
|
+
|
|
804
|
+
Json evaluate(JsonReference lhs, JsonReference rhs, std::error_code&) const override
|
|
805
|
+
{
|
|
806
|
+
if (!(lhs.is_number() && rhs.is_number()))
|
|
807
|
+
{
|
|
808
|
+
return Json::null();
|
|
809
|
+
}
|
|
810
|
+
else if (lhs.is_int64() && rhs.is_int64())
|
|
811
|
+
{
|
|
812
|
+
return Json(((lhs.template as<int64_t>() + rhs.template as<int64_t>())));
|
|
813
|
+
}
|
|
814
|
+
else if (lhs.is_uint64() && rhs.is_uint64())
|
|
815
|
+
{
|
|
816
|
+
return Json((lhs.template as<uint64_t>() + rhs.template as<uint64_t>()));
|
|
817
|
+
}
|
|
818
|
+
else
|
|
819
|
+
{
|
|
820
|
+
return Json((lhs.as_double() + rhs.as_double()));
|
|
821
|
+
}
|
|
822
|
+
}
|
|
823
|
+
|
|
824
|
+
std::string to_string(int level = 0) const override
|
|
825
|
+
{
|
|
826
|
+
std::string s;
|
|
827
|
+
if (level > 0)
|
|
828
|
+
{
|
|
829
|
+
s.append("\n");
|
|
830
|
+
s.append(level*2, ' ');
|
|
831
|
+
}
|
|
832
|
+
s.append("plus operator");
|
|
833
|
+
return s;
|
|
834
|
+
}
|
|
835
|
+
};
|
|
836
|
+
|
|
837
|
+
template <class Json,class JsonReference>
|
|
838
|
+
class minus_operator final : public binary_operator<Json,JsonReference>
|
|
839
|
+
{
|
|
840
|
+
public:
|
|
841
|
+
minus_operator()
|
|
842
|
+
: binary_operator<Json,JsonReference>(4)
|
|
843
|
+
{
|
|
844
|
+
}
|
|
845
|
+
|
|
846
|
+
Json evaluate(JsonReference lhs, JsonReference rhs, std::error_code&) const override
|
|
847
|
+
{
|
|
848
|
+
if (!(lhs.is_number() && rhs.is_number()))
|
|
849
|
+
{
|
|
850
|
+
return Json::null();
|
|
851
|
+
}
|
|
852
|
+
else if (lhs.is_int64() && rhs.is_int64())
|
|
853
|
+
{
|
|
854
|
+
return Json(((lhs.template as<int64_t>() - rhs.template as<int64_t>())));
|
|
855
|
+
}
|
|
856
|
+
else if (lhs.is_uint64() && rhs.is_uint64())
|
|
857
|
+
{
|
|
858
|
+
return Json((lhs.template as<uint64_t>() - rhs.template as<uint64_t>()));
|
|
859
|
+
}
|
|
860
|
+
else
|
|
861
|
+
{
|
|
862
|
+
return Json((lhs.as_double() - rhs.as_double()));
|
|
863
|
+
}
|
|
864
|
+
}
|
|
865
|
+
|
|
866
|
+
std::string to_string(int level = 0) const override
|
|
867
|
+
{
|
|
868
|
+
std::string s;
|
|
869
|
+
if (level > 0)
|
|
870
|
+
{
|
|
871
|
+
s.append("\n");
|
|
872
|
+
s.append(level*2, ' ');
|
|
873
|
+
}
|
|
874
|
+
s.append("minus operator");
|
|
875
|
+
return s;
|
|
876
|
+
}
|
|
877
|
+
};
|
|
878
|
+
|
|
879
|
+
template <class Json,class JsonReference>
|
|
880
|
+
class mult_operator final : public binary_operator<Json,JsonReference>
|
|
881
|
+
{
|
|
882
|
+
public:
|
|
883
|
+
mult_operator()
|
|
884
|
+
: binary_operator<Json,JsonReference>(3)
|
|
885
|
+
{
|
|
886
|
+
}
|
|
887
|
+
|
|
888
|
+
Json evaluate(JsonReference lhs, JsonReference rhs, std::error_code&) const override
|
|
889
|
+
{
|
|
890
|
+
if (!(lhs.is_number() && rhs.is_number()))
|
|
891
|
+
{
|
|
892
|
+
return Json::null();
|
|
893
|
+
}
|
|
894
|
+
else if (lhs.is_int64() && rhs.is_int64())
|
|
895
|
+
{
|
|
896
|
+
return Json(((lhs.template as<int64_t>() * rhs.template as<int64_t>())));
|
|
897
|
+
}
|
|
898
|
+
else if (lhs.is_uint64() && rhs.is_uint64())
|
|
899
|
+
{
|
|
900
|
+
return Json((lhs.template as<uint64_t>() * rhs.template as<uint64_t>()));
|
|
901
|
+
}
|
|
902
|
+
else
|
|
903
|
+
{
|
|
904
|
+
return Json((lhs.as_double() * rhs.as_double()));
|
|
905
|
+
}
|
|
906
|
+
}
|
|
907
|
+
|
|
908
|
+
std::string to_string(int level = 0) const override
|
|
909
|
+
{
|
|
910
|
+
std::string s;
|
|
911
|
+
if (level > 0)
|
|
912
|
+
{
|
|
913
|
+
s.append("\n");
|
|
914
|
+
s.append(level*2, ' ');
|
|
915
|
+
}
|
|
916
|
+
s.append("multiply operator");
|
|
917
|
+
return s;
|
|
918
|
+
}
|
|
919
|
+
};
|
|
920
|
+
|
|
921
|
+
template <class Json,class JsonReference>
|
|
922
|
+
class div_operator final : public binary_operator<Json,JsonReference>
|
|
923
|
+
{
|
|
924
|
+
public:
|
|
925
|
+
div_operator()
|
|
926
|
+
: binary_operator<Json,JsonReference>(3)
|
|
927
|
+
{
|
|
928
|
+
}
|
|
929
|
+
|
|
930
|
+
Json evaluate(JsonReference lhs, JsonReference rhs, std::error_code&) const override
|
|
931
|
+
{
|
|
932
|
+
//std::cout << "operator/ lhs: " << lhs << ", rhs: " << rhs << "\n";
|
|
933
|
+
|
|
934
|
+
if (!(lhs.is_number() && rhs.is_number()))
|
|
935
|
+
{
|
|
936
|
+
return Json::null();
|
|
937
|
+
}
|
|
938
|
+
else if (lhs.is_int64() && rhs.is_int64())
|
|
939
|
+
{
|
|
940
|
+
return Json(((lhs.template as<int64_t>() / rhs.template as<int64_t>())));
|
|
941
|
+
}
|
|
942
|
+
else if (lhs.is_uint64() && rhs.is_uint64())
|
|
943
|
+
{
|
|
944
|
+
return Json((lhs.template as<uint64_t>() / rhs.template as<uint64_t>()));
|
|
945
|
+
}
|
|
946
|
+
else
|
|
947
|
+
{
|
|
948
|
+
return Json((lhs.as_double() / rhs.as_double()));
|
|
949
|
+
}
|
|
950
|
+
}
|
|
951
|
+
|
|
952
|
+
std::string to_string(int level = 0) const override
|
|
953
|
+
{
|
|
954
|
+
std::string s;
|
|
955
|
+
if (level > 0)
|
|
956
|
+
{
|
|
957
|
+
s.append("\n");
|
|
958
|
+
s.append(level*2, ' ');
|
|
959
|
+
}
|
|
960
|
+
s.append("divide operator");
|
|
961
|
+
return s;
|
|
962
|
+
}
|
|
963
|
+
};
|
|
964
|
+
|
|
965
|
+
template <class Json,class JsonReference>
|
|
966
|
+
class modulus_operator final : public binary_operator<Json,JsonReference>
|
|
967
|
+
{
|
|
968
|
+
public:
|
|
969
|
+
modulus_operator()
|
|
970
|
+
: binary_operator<Json,JsonReference>(3)
|
|
971
|
+
{
|
|
972
|
+
}
|
|
973
|
+
|
|
974
|
+
Json evaluate(JsonReference lhs, JsonReference rhs, std::error_code&) const override
|
|
975
|
+
{
|
|
976
|
+
//std::cout << "operator/ lhs: " << lhs << ", rhs: " << rhs << "\n";
|
|
977
|
+
|
|
978
|
+
if (!(lhs.is_number() && rhs.is_number()))
|
|
979
|
+
{
|
|
980
|
+
return Json::null();
|
|
981
|
+
}
|
|
982
|
+
else if (lhs.is_int64() && rhs.is_int64())
|
|
983
|
+
{
|
|
984
|
+
return Json(((lhs.template as<int64_t>() % rhs.template as<int64_t>())));
|
|
985
|
+
}
|
|
986
|
+
else if (lhs.is_uint64() && rhs.is_uint64())
|
|
987
|
+
{
|
|
988
|
+
return Json((lhs.template as<uint64_t>() % rhs.template as<uint64_t>()));
|
|
989
|
+
}
|
|
990
|
+
else
|
|
991
|
+
{
|
|
992
|
+
return Json(fmod(lhs.as_double(), rhs.as_double()));
|
|
993
|
+
}
|
|
994
|
+
}
|
|
995
|
+
|
|
996
|
+
std::string to_string(int level = 0) const override
|
|
997
|
+
{
|
|
998
|
+
std::string s;
|
|
999
|
+
if (level > 0)
|
|
1000
|
+
{
|
|
1001
|
+
s.append("\n");
|
|
1002
|
+
s.append(level*2, ' ');
|
|
1003
|
+
}
|
|
1004
|
+
s.append("modulus operator");
|
|
1005
|
+
return s;
|
|
1006
|
+
}
|
|
1007
|
+
};
|
|
1008
|
+
|
|
1009
|
+
// function_base
|
|
1010
|
+
template <class Json>
|
|
1011
|
+
class function_base
|
|
1012
|
+
{
|
|
1013
|
+
jsoncons::optional<std::size_t> arg_count_;
|
|
1014
|
+
public:
|
|
1015
|
+
using value_type = Json;
|
|
1016
|
+
using parameter_type = parameter<Json>;
|
|
1017
|
+
|
|
1018
|
+
function_base(jsoncons::optional<std::size_t> arg_count)
|
|
1019
|
+
: arg_count_(arg_count)
|
|
1020
|
+
{
|
|
1021
|
+
}
|
|
1022
|
+
|
|
1023
|
+
virtual ~function_base() noexcept = default;
|
|
1024
|
+
|
|
1025
|
+
jsoncons::optional<std::size_t> arity() const
|
|
1026
|
+
{
|
|
1027
|
+
return arg_count_;
|
|
1028
|
+
}
|
|
1029
|
+
|
|
1030
|
+
virtual value_type evaluate(const std::vector<parameter_type>& args,
|
|
1031
|
+
std::error_code& ec) const = 0;
|
|
1032
|
+
|
|
1033
|
+
virtual std::string to_string(int level = 0) const
|
|
1034
|
+
{
|
|
1035
|
+
std::string s;
|
|
1036
|
+
if (level > 0)
|
|
1037
|
+
{
|
|
1038
|
+
s.append("\n");
|
|
1039
|
+
s.append(level*2, ' ');
|
|
1040
|
+
}
|
|
1041
|
+
s.append("function");
|
|
1042
|
+
return s;
|
|
1043
|
+
}
|
|
1044
|
+
};
|
|
1045
|
+
|
|
1046
|
+
template <class Json>
|
|
1047
|
+
class decorator_function : public function_base<Json>
|
|
1048
|
+
{
|
|
1049
|
+
public:
|
|
1050
|
+
using value_type = Json;
|
|
1051
|
+
using parameter_type = parameter<Json>;
|
|
1052
|
+
using string_view_type = typename Json::string_view_type;
|
|
1053
|
+
using function_type = std::function<value_type(jsoncons::span<const parameter_type>, std::error_code& ec)>;
|
|
1054
|
+
private:
|
|
1055
|
+
function_type f_;
|
|
1056
|
+
public:
|
|
1057
|
+
decorator_function(jsoncons::optional<std::size_t> arity,
|
|
1058
|
+
const function_type& f)
|
|
1059
|
+
: function_base<Json>(arity), f_(f)
|
|
1060
|
+
{
|
|
1061
|
+
}
|
|
1062
|
+
|
|
1063
|
+
value_type evaluate(const std::vector<parameter_type>& args,
|
|
1064
|
+
std::error_code& ec) const override
|
|
1065
|
+
{
|
|
1066
|
+
return f_(args, ec);
|
|
1067
|
+
}
|
|
1068
|
+
};
|
|
1069
|
+
|
|
1070
|
+
template <class Json>
|
|
1071
|
+
class contains_function : public function_base<Json>
|
|
1072
|
+
{
|
|
1073
|
+
public:
|
|
1074
|
+
using value_type = Json;
|
|
1075
|
+
using parameter_type = parameter<Json>;
|
|
1076
|
+
using string_view_type = typename Json::string_view_type;
|
|
1077
|
+
|
|
1078
|
+
contains_function()
|
|
1079
|
+
: function_base<Json>(2)
|
|
1080
|
+
{
|
|
1081
|
+
}
|
|
1082
|
+
|
|
1083
|
+
value_type evaluate(const std::vector<parameter_type>& args,
|
|
1084
|
+
std::error_code& ec) const override
|
|
1085
|
+
{
|
|
1086
|
+
if (args.size() != *this->arity())
|
|
1087
|
+
{
|
|
1088
|
+
ec = jsonpath_errc::invalid_arity;
|
|
1089
|
+
return value_type::null();
|
|
1090
|
+
}
|
|
1091
|
+
|
|
1092
|
+
auto arg0= args[0].value();
|
|
1093
|
+
auto arg1= args[1].value();
|
|
1094
|
+
|
|
1095
|
+
switch (arg0.type())
|
|
1096
|
+
{
|
|
1097
|
+
case json_type::array_value:
|
|
1098
|
+
for (auto& j : arg0.array_range())
|
|
1099
|
+
{
|
|
1100
|
+
if (j == arg1)
|
|
1101
|
+
{
|
|
1102
|
+
return value_type(true);
|
|
1103
|
+
}
|
|
1104
|
+
}
|
|
1105
|
+
return value_type(false);
|
|
1106
|
+
case json_type::string_value:
|
|
1107
|
+
{
|
|
1108
|
+
if (!arg1.is_string())
|
|
1109
|
+
{
|
|
1110
|
+
ec = jsonpath_errc::invalid_type;
|
|
1111
|
+
return value_type::null();
|
|
1112
|
+
}
|
|
1113
|
+
auto sv0 = arg0.template as<string_view_type>();
|
|
1114
|
+
auto sv1 = arg1.template as<string_view_type>();
|
|
1115
|
+
return sv0.find(sv1) != string_view_type::npos ? value_type(true) : value_type(false);
|
|
1116
|
+
}
|
|
1117
|
+
default:
|
|
1118
|
+
{
|
|
1119
|
+
ec = jsonpath_errc::invalid_type;
|
|
1120
|
+
return value_type::null();
|
|
1121
|
+
}
|
|
1122
|
+
}
|
|
1123
|
+
}
|
|
1124
|
+
|
|
1125
|
+
std::string to_string(int level = 0) const override
|
|
1126
|
+
{
|
|
1127
|
+
std::string s;
|
|
1128
|
+
if (level > 0)
|
|
1129
|
+
{
|
|
1130
|
+
s.append("\n");
|
|
1131
|
+
s.append(level*2, ' ');
|
|
1132
|
+
}
|
|
1133
|
+
s.append("contains function");
|
|
1134
|
+
return s;
|
|
1135
|
+
}
|
|
1136
|
+
};
|
|
1137
|
+
|
|
1138
|
+
template <class Json>
|
|
1139
|
+
class ends_with_function : public function_base<Json>
|
|
1140
|
+
{
|
|
1141
|
+
public:
|
|
1142
|
+
using value_type = Json;
|
|
1143
|
+
using parameter_type = parameter<Json>;
|
|
1144
|
+
using string_view_type = typename Json::string_view_type;
|
|
1145
|
+
|
|
1146
|
+
ends_with_function()
|
|
1147
|
+
: function_base<Json>(2)
|
|
1148
|
+
{
|
|
1149
|
+
}
|
|
1150
|
+
|
|
1151
|
+
value_type evaluate(const std::vector<parameter_type>& args,
|
|
1152
|
+
std::error_code& ec) const override
|
|
1153
|
+
{
|
|
1154
|
+
if (args.size() != *this->arity())
|
|
1155
|
+
{
|
|
1156
|
+
ec = jsonpath_errc::invalid_arity;
|
|
1157
|
+
return value_type::null();
|
|
1158
|
+
}
|
|
1159
|
+
|
|
1160
|
+
auto arg0= args[0].value();
|
|
1161
|
+
if (!arg0.is_string())
|
|
1162
|
+
{
|
|
1163
|
+
ec = jsonpath_errc::invalid_type;
|
|
1164
|
+
return value_type::null();
|
|
1165
|
+
}
|
|
1166
|
+
|
|
1167
|
+
auto arg1= args[1].value();
|
|
1168
|
+
if (!arg1.is_string())
|
|
1169
|
+
{
|
|
1170
|
+
ec = jsonpath_errc::invalid_type;
|
|
1171
|
+
return value_type::null();
|
|
1172
|
+
}
|
|
1173
|
+
|
|
1174
|
+
auto sv0 = arg0.template as<string_view_type>();
|
|
1175
|
+
auto sv1 = arg1.template as<string_view_type>();
|
|
1176
|
+
|
|
1177
|
+
if (sv1.length() <= sv0.length() && sv1 == sv0.substr(sv0.length() - sv1.length()))
|
|
1178
|
+
{
|
|
1179
|
+
return value_type(true);
|
|
1180
|
+
}
|
|
1181
|
+
else
|
|
1182
|
+
{
|
|
1183
|
+
return value_type(false);
|
|
1184
|
+
}
|
|
1185
|
+
}
|
|
1186
|
+
|
|
1187
|
+
std::string to_string(int level = 0) const override
|
|
1188
|
+
{
|
|
1189
|
+
std::string s;
|
|
1190
|
+
if (level > 0)
|
|
1191
|
+
{
|
|
1192
|
+
s.append("\n");
|
|
1193
|
+
s.append(level*2, ' ');
|
|
1194
|
+
}
|
|
1195
|
+
s.append("ends_with function");
|
|
1196
|
+
return s;
|
|
1197
|
+
}
|
|
1198
|
+
};
|
|
1199
|
+
|
|
1200
|
+
template <class Json>
|
|
1201
|
+
class starts_with_function : public function_base<Json>
|
|
1202
|
+
{
|
|
1203
|
+
public:
|
|
1204
|
+
using value_type = Json;
|
|
1205
|
+
using parameter_type = parameter<Json>;
|
|
1206
|
+
using string_view_type = typename Json::string_view_type;
|
|
1207
|
+
|
|
1208
|
+
starts_with_function()
|
|
1209
|
+
: function_base<Json>(2)
|
|
1210
|
+
{
|
|
1211
|
+
}
|
|
1212
|
+
|
|
1213
|
+
value_type evaluate(const std::vector<parameter_type>& args,
|
|
1214
|
+
std::error_code& ec) const override
|
|
1215
|
+
{
|
|
1216
|
+
if (args.size() != *this->arity())
|
|
1217
|
+
{
|
|
1218
|
+
ec = jsonpath_errc::invalid_arity;
|
|
1219
|
+
return value_type::null();
|
|
1220
|
+
}
|
|
1221
|
+
|
|
1222
|
+
auto arg0= args[0].value();
|
|
1223
|
+
if (!arg0.is_string())
|
|
1224
|
+
{
|
|
1225
|
+
ec = jsonpath_errc::invalid_type;
|
|
1226
|
+
return value_type::null();
|
|
1227
|
+
}
|
|
1228
|
+
|
|
1229
|
+
auto arg1= args[1].value();
|
|
1230
|
+
if (!arg1.is_string())
|
|
1231
|
+
{
|
|
1232
|
+
ec = jsonpath_errc::invalid_type;
|
|
1233
|
+
return value_type::null();
|
|
1234
|
+
}
|
|
1235
|
+
|
|
1236
|
+
auto sv0 = arg0.template as<string_view_type>();
|
|
1237
|
+
auto sv1 = arg1.template as<string_view_type>();
|
|
1238
|
+
|
|
1239
|
+
if (sv1.length() <= sv0.length() && sv1 == sv0.substr(0, sv1.length()))
|
|
1240
|
+
{
|
|
1241
|
+
return value_type(true);
|
|
1242
|
+
}
|
|
1243
|
+
else
|
|
1244
|
+
{
|
|
1245
|
+
return value_type(false);
|
|
1246
|
+
}
|
|
1247
|
+
}
|
|
1248
|
+
|
|
1249
|
+
std::string to_string(int level = 0) const override
|
|
1250
|
+
{
|
|
1251
|
+
std::string s;
|
|
1252
|
+
if (level > 0)
|
|
1253
|
+
{
|
|
1254
|
+
s.append("\n");
|
|
1255
|
+
s.append(level*2, ' ');
|
|
1256
|
+
}
|
|
1257
|
+
s.append("starts_with function");
|
|
1258
|
+
return s;
|
|
1259
|
+
}
|
|
1260
|
+
};
|
|
1261
|
+
|
|
1262
|
+
template <class Json>
|
|
1263
|
+
class sum_function : public function_base<Json>
|
|
1264
|
+
{
|
|
1265
|
+
public:
|
|
1266
|
+
using value_type = Json;
|
|
1267
|
+
using parameter_type = parameter<Json>;
|
|
1268
|
+
|
|
1269
|
+
sum_function()
|
|
1270
|
+
: function_base<Json>(1)
|
|
1271
|
+
{
|
|
1272
|
+
}
|
|
1273
|
+
|
|
1274
|
+
value_type evaluate(const std::vector<parameter_type>& args,
|
|
1275
|
+
std::error_code& ec) const override
|
|
1276
|
+
{
|
|
1277
|
+
if (args.size() != *this->arity())
|
|
1278
|
+
{
|
|
1279
|
+
ec = jsonpath_errc::invalid_arity;
|
|
1280
|
+
return value_type::null();
|
|
1281
|
+
}
|
|
1282
|
+
|
|
1283
|
+
auto arg0= args[0].value();
|
|
1284
|
+
if (!arg0.is_array())
|
|
1285
|
+
{
|
|
1286
|
+
//std::cout << "arg: " << arg0 << "\n";
|
|
1287
|
+
ec = jsonpath_errc::invalid_type;
|
|
1288
|
+
return value_type::null();
|
|
1289
|
+
}
|
|
1290
|
+
//std::cout << "sum function arg: " << arg0 << "\n";
|
|
1291
|
+
|
|
1292
|
+
double sum = 0;
|
|
1293
|
+
for (auto& j : arg0.array_range())
|
|
1294
|
+
{
|
|
1295
|
+
if (!j.is_number())
|
|
1296
|
+
{
|
|
1297
|
+
ec = jsonpath_errc::invalid_type;
|
|
1298
|
+
return value_type::null();
|
|
1299
|
+
}
|
|
1300
|
+
sum += j.template as<double>();
|
|
1301
|
+
}
|
|
1302
|
+
|
|
1303
|
+
return value_type(sum);
|
|
1304
|
+
}
|
|
1305
|
+
|
|
1306
|
+
std::string to_string(int level = 0) const override
|
|
1307
|
+
{
|
|
1308
|
+
std::string s;
|
|
1309
|
+
if (level > 0)
|
|
1310
|
+
{
|
|
1311
|
+
s.append("\n");
|
|
1312
|
+
s.append(level*2, ' ');
|
|
1313
|
+
}
|
|
1314
|
+
s.append("sum function");
|
|
1315
|
+
return s;
|
|
1316
|
+
}
|
|
1317
|
+
};
|
|
1318
|
+
|
|
1319
|
+
#if defined(JSONCONS_HAS_STD_REGEX)
|
|
1320
|
+
|
|
1321
|
+
template <class Json>
|
|
1322
|
+
class tokenize_function : public function_base<Json>
|
|
1323
|
+
{
|
|
1324
|
+
public:
|
|
1325
|
+
using value_type = Json;
|
|
1326
|
+
using parameter_type = parameter<Json>;
|
|
1327
|
+
using char_type = typename Json::char_type;
|
|
1328
|
+
using string_type = std::basic_string<char_type>;
|
|
1329
|
+
|
|
1330
|
+
tokenize_function()
|
|
1331
|
+
: function_base<Json>(2)
|
|
1332
|
+
{
|
|
1333
|
+
}
|
|
1334
|
+
|
|
1335
|
+
value_type evaluate(const std::vector<parameter_type>& args,
|
|
1336
|
+
std::error_code& ec) const override
|
|
1337
|
+
{
|
|
1338
|
+
if (args.size() != *this->arity())
|
|
1339
|
+
{
|
|
1340
|
+
ec = jsonpath_errc::invalid_arity;
|
|
1341
|
+
return value_type::null();
|
|
1342
|
+
}
|
|
1343
|
+
|
|
1344
|
+
if (!args[0].value().is_string() || !args[1].value().is_string())
|
|
1345
|
+
{
|
|
1346
|
+
//std::cout << "arg: " << arg0 << "\n";
|
|
1347
|
+
ec = jsonpath_errc::invalid_type;
|
|
1348
|
+
return value_type::null();
|
|
1349
|
+
}
|
|
1350
|
+
auto arg0 = args[0].value().template as<string_type>();
|
|
1351
|
+
auto arg1 = args[1].value().template as<string_type>();
|
|
1352
|
+
|
|
1353
|
+
std::regex::flag_type options = std::regex_constants::ECMAScript;
|
|
1354
|
+
std::basic_regex<char_type> pieces_regex(arg1, options);
|
|
1355
|
+
|
|
1356
|
+
std::regex_token_iterator<typename string_type::const_iterator> rit ( arg0.begin(), arg0.end(), pieces_regex, -1);
|
|
1357
|
+
std::regex_token_iterator<typename string_type::const_iterator> rend;
|
|
1358
|
+
|
|
1359
|
+
value_type j(json_array_arg);
|
|
1360
|
+
while (rit != rend)
|
|
1361
|
+
{
|
|
1362
|
+
j.emplace_back(rit->str());
|
|
1363
|
+
++rit;
|
|
1364
|
+
}
|
|
1365
|
+
return j;
|
|
1366
|
+
}
|
|
1367
|
+
|
|
1368
|
+
std::string to_string(int level = 0) const override
|
|
1369
|
+
{
|
|
1370
|
+
std::string s;
|
|
1371
|
+
if (level > 0)
|
|
1372
|
+
{
|
|
1373
|
+
s.append("\n");
|
|
1374
|
+
s.append(level*2, ' ');
|
|
1375
|
+
}
|
|
1376
|
+
s.append("tokenize function");
|
|
1377
|
+
return s;
|
|
1378
|
+
}
|
|
1379
|
+
};
|
|
1380
|
+
|
|
1381
|
+
#endif // defined(JSONCONS_HAS_STD_REGEX)
|
|
1382
|
+
|
|
1383
|
+
template <class Json>
|
|
1384
|
+
class ceil_function : public function_base<Json>
|
|
1385
|
+
{
|
|
1386
|
+
public:
|
|
1387
|
+
using value_type = Json;
|
|
1388
|
+
using parameter_type = parameter<Json>;
|
|
1389
|
+
|
|
1390
|
+
ceil_function()
|
|
1391
|
+
: function_base<Json>(1)
|
|
1392
|
+
{
|
|
1393
|
+
}
|
|
1394
|
+
|
|
1395
|
+
value_type evaluate(const std::vector<parameter_type>& args,
|
|
1396
|
+
std::error_code& ec) const override
|
|
1397
|
+
{
|
|
1398
|
+
if (args.size() != *this->arity())
|
|
1399
|
+
{
|
|
1400
|
+
ec = jsonpath_errc::invalid_arity;
|
|
1401
|
+
return value_type::null();
|
|
1402
|
+
}
|
|
1403
|
+
|
|
1404
|
+
auto arg0= args[0].value();
|
|
1405
|
+
switch (arg0.type())
|
|
1406
|
+
{
|
|
1407
|
+
case json_type::uint64_value:
|
|
1408
|
+
case json_type::int64_value:
|
|
1409
|
+
{
|
|
1410
|
+
return value_type(arg0.template as<double>());
|
|
1411
|
+
}
|
|
1412
|
+
case json_type::double_value:
|
|
1413
|
+
{
|
|
1414
|
+
return value_type(std::ceil(arg0.template as<double>()));
|
|
1415
|
+
}
|
|
1416
|
+
default:
|
|
1417
|
+
ec = jsonpath_errc::invalid_type;
|
|
1418
|
+
return value_type::null();
|
|
1419
|
+
}
|
|
1420
|
+
}
|
|
1421
|
+
|
|
1422
|
+
std::string to_string(int level = 0) const override
|
|
1423
|
+
{
|
|
1424
|
+
std::string s;
|
|
1425
|
+
if (level > 0)
|
|
1426
|
+
{
|
|
1427
|
+
s.append("\n");
|
|
1428
|
+
s.append(level*2, ' ');
|
|
1429
|
+
}
|
|
1430
|
+
s.append("ceil function");
|
|
1431
|
+
return s;
|
|
1432
|
+
}
|
|
1433
|
+
};
|
|
1434
|
+
|
|
1435
|
+
template <class Json>
|
|
1436
|
+
class floor_function : public function_base<Json>
|
|
1437
|
+
{
|
|
1438
|
+
public:
|
|
1439
|
+
using value_type = Json;
|
|
1440
|
+
using parameter_type = parameter<Json>;
|
|
1441
|
+
|
|
1442
|
+
floor_function()
|
|
1443
|
+
: function_base<Json>(1)
|
|
1444
|
+
{
|
|
1445
|
+
}
|
|
1446
|
+
|
|
1447
|
+
value_type evaluate(const std::vector<parameter_type>& args,
|
|
1448
|
+
std::error_code& ec) const override
|
|
1449
|
+
{
|
|
1450
|
+
if (args.size() != *this->arity())
|
|
1451
|
+
{
|
|
1452
|
+
ec = jsonpath_errc::invalid_arity;
|
|
1453
|
+
return value_type::null();
|
|
1454
|
+
}
|
|
1455
|
+
|
|
1456
|
+
auto arg0= args[0].value();
|
|
1457
|
+
switch (arg0.type())
|
|
1458
|
+
{
|
|
1459
|
+
case json_type::uint64_value:
|
|
1460
|
+
case json_type::int64_value:
|
|
1461
|
+
{
|
|
1462
|
+
return value_type(arg0.template as<double>());
|
|
1463
|
+
}
|
|
1464
|
+
case json_type::double_value:
|
|
1465
|
+
{
|
|
1466
|
+
return value_type(std::floor(arg0.template as<double>()));
|
|
1467
|
+
}
|
|
1468
|
+
default:
|
|
1469
|
+
ec = jsonpath_errc::invalid_type;
|
|
1470
|
+
return value_type::null();
|
|
1471
|
+
}
|
|
1472
|
+
}
|
|
1473
|
+
|
|
1474
|
+
std::string to_string(int level = 0) const override
|
|
1475
|
+
{
|
|
1476
|
+
std::string s;
|
|
1477
|
+
if (level > 0)
|
|
1478
|
+
{
|
|
1479
|
+
s.append("\n");
|
|
1480
|
+
s.append(level*2, ' ');
|
|
1481
|
+
}
|
|
1482
|
+
s.append("floor function");
|
|
1483
|
+
return s;
|
|
1484
|
+
}
|
|
1485
|
+
};
|
|
1486
|
+
|
|
1487
|
+
template <class Json>
|
|
1488
|
+
class to_number_function : public function_base<Json>
|
|
1489
|
+
{
|
|
1490
|
+
public:
|
|
1491
|
+
using value_type = Json;
|
|
1492
|
+
using parameter_type = parameter<Json>;
|
|
1493
|
+
|
|
1494
|
+
to_number_function()
|
|
1495
|
+
: function_base<Json>(1)
|
|
1496
|
+
{
|
|
1497
|
+
}
|
|
1498
|
+
|
|
1499
|
+
value_type evaluate(const std::vector<parameter_type>& args,
|
|
1500
|
+
std::error_code& ec) const override
|
|
1501
|
+
{
|
|
1502
|
+
if (args.size() != *this->arity())
|
|
1503
|
+
{
|
|
1504
|
+
ec = jsonpath_errc::invalid_arity;
|
|
1505
|
+
return value_type::null();
|
|
1506
|
+
}
|
|
1507
|
+
|
|
1508
|
+
auto arg0= args[0].value();
|
|
1509
|
+
switch (arg0.type())
|
|
1510
|
+
{
|
|
1511
|
+
case json_type::int64_value:
|
|
1512
|
+
case json_type::uint64_value:
|
|
1513
|
+
case json_type::double_value:
|
|
1514
|
+
return arg0;
|
|
1515
|
+
case json_type::string_value:
|
|
1516
|
+
{
|
|
1517
|
+
auto sv = arg0.as_string_view();
|
|
1518
|
+
uint64_t un{0};
|
|
1519
|
+
auto result1 = jsoncons::detail::to_integer(sv.data(), sv.length(), un);
|
|
1520
|
+
if (result1)
|
|
1521
|
+
{
|
|
1522
|
+
return value_type(un);
|
|
1523
|
+
}
|
|
1524
|
+
int64_t sn{0};
|
|
1525
|
+
auto result2 = jsoncons::detail::to_integer(sv.data(), sv.length(), sn);
|
|
1526
|
+
if (result2)
|
|
1527
|
+
{
|
|
1528
|
+
return value_type(sn);
|
|
1529
|
+
}
|
|
1530
|
+
jsoncons::detail::chars_to to_double;
|
|
1531
|
+
try
|
|
1532
|
+
{
|
|
1533
|
+
auto s = arg0.as_string();
|
|
1534
|
+
double d = to_double(s.c_str(), s.length());
|
|
1535
|
+
return value_type(d);
|
|
1536
|
+
}
|
|
1537
|
+
catch (const std::exception&)
|
|
1538
|
+
{
|
|
1539
|
+
return value_type::null();
|
|
1540
|
+
}
|
|
1541
|
+
}
|
|
1542
|
+
default:
|
|
1543
|
+
ec = jsonpath_errc::invalid_type;
|
|
1544
|
+
return value_type::null();
|
|
1545
|
+
}
|
|
1546
|
+
}
|
|
1547
|
+
|
|
1548
|
+
std::string to_string(int level = 0) const override
|
|
1549
|
+
{
|
|
1550
|
+
std::string s;
|
|
1551
|
+
if (level > 0)
|
|
1552
|
+
{
|
|
1553
|
+
s.append("\n");
|
|
1554
|
+
s.append(level*2, ' ');
|
|
1555
|
+
}
|
|
1556
|
+
s.append("to_number function");
|
|
1557
|
+
return s;
|
|
1558
|
+
}
|
|
1559
|
+
};
|
|
1560
|
+
|
|
1561
|
+
template <class Json>
|
|
1562
|
+
class prod_function : public function_base<Json>
|
|
1563
|
+
{
|
|
1564
|
+
public:
|
|
1565
|
+
using value_type = Json;
|
|
1566
|
+
using parameter_type = parameter<Json>;
|
|
1567
|
+
|
|
1568
|
+
prod_function()
|
|
1569
|
+
: function_base<Json>(1)
|
|
1570
|
+
{
|
|
1571
|
+
}
|
|
1572
|
+
|
|
1573
|
+
value_type evaluate(const std::vector<parameter_type>& args,
|
|
1574
|
+
std::error_code& ec) const override
|
|
1575
|
+
{
|
|
1576
|
+
if (args.size() != *this->arity())
|
|
1577
|
+
{
|
|
1578
|
+
ec = jsonpath_errc::invalid_arity;
|
|
1579
|
+
return value_type::null();
|
|
1580
|
+
}
|
|
1581
|
+
|
|
1582
|
+
auto arg0= args[0].value();
|
|
1583
|
+
if (!arg0.is_array() || arg0.empty())
|
|
1584
|
+
{
|
|
1585
|
+
//std::cout << "arg: " << arg0 << "\n";
|
|
1586
|
+
ec = jsonpath_errc::invalid_type;
|
|
1587
|
+
return value_type::null();
|
|
1588
|
+
}
|
|
1589
|
+
double prod = 1;
|
|
1590
|
+
for (auto& j : arg0.array_range())
|
|
1591
|
+
{
|
|
1592
|
+
if (!j.is_number())
|
|
1593
|
+
{
|
|
1594
|
+
ec = jsonpath_errc::invalid_type;
|
|
1595
|
+
return value_type::null();
|
|
1596
|
+
}
|
|
1597
|
+
prod *= j.template as<double>();
|
|
1598
|
+
}
|
|
1599
|
+
|
|
1600
|
+
return value_type(prod);
|
|
1601
|
+
}
|
|
1602
|
+
|
|
1603
|
+
std::string to_string(int level = 0) const override
|
|
1604
|
+
{
|
|
1605
|
+
std::string s;
|
|
1606
|
+
if (level > 0)
|
|
1607
|
+
{
|
|
1608
|
+
s.append("\n");
|
|
1609
|
+
s.append(level*2, ' ');
|
|
1610
|
+
}
|
|
1611
|
+
s.append("prod function");
|
|
1612
|
+
return s;
|
|
1613
|
+
}
|
|
1614
|
+
};
|
|
1615
|
+
|
|
1616
|
+
template <class Json>
|
|
1617
|
+
class avg_function : public function_base<Json>
|
|
1618
|
+
{
|
|
1619
|
+
public:
|
|
1620
|
+
using value_type = Json;
|
|
1621
|
+
using parameter_type = parameter<Json>;
|
|
1622
|
+
|
|
1623
|
+
avg_function()
|
|
1624
|
+
: function_base<Json>(1)
|
|
1625
|
+
{
|
|
1626
|
+
}
|
|
1627
|
+
|
|
1628
|
+
value_type evaluate(const std::vector<parameter_type>& args,
|
|
1629
|
+
std::error_code& ec) const override
|
|
1630
|
+
{
|
|
1631
|
+
if (args.size() != *this->arity())
|
|
1632
|
+
{
|
|
1633
|
+
ec = jsonpath_errc::invalid_arity;
|
|
1634
|
+
return value_type::null();
|
|
1635
|
+
}
|
|
1636
|
+
|
|
1637
|
+
auto arg0= args[0].value();
|
|
1638
|
+
if (!arg0.is_array())
|
|
1639
|
+
{
|
|
1640
|
+
ec = jsonpath_errc::invalid_type;
|
|
1641
|
+
return value_type::null();
|
|
1642
|
+
}
|
|
1643
|
+
if (arg0.empty())
|
|
1644
|
+
{
|
|
1645
|
+
return value_type::null();
|
|
1646
|
+
}
|
|
1647
|
+
double sum = 0;
|
|
1648
|
+
for (auto& j : arg0.array_range())
|
|
1649
|
+
{
|
|
1650
|
+
if (!j.is_number())
|
|
1651
|
+
{
|
|
1652
|
+
ec = jsonpath_errc::invalid_type;
|
|
1653
|
+
return value_type::null();
|
|
1654
|
+
}
|
|
1655
|
+
sum += j.template as<double>();
|
|
1656
|
+
}
|
|
1657
|
+
|
|
1658
|
+
return value_type(sum / static_cast<double>(arg0.size()));
|
|
1659
|
+
}
|
|
1660
|
+
|
|
1661
|
+
std::string to_string(int level = 0) const override
|
|
1662
|
+
{
|
|
1663
|
+
std::string s;
|
|
1664
|
+
if (level > 0)
|
|
1665
|
+
{
|
|
1666
|
+
s.append("\n");
|
|
1667
|
+
s.append(level*2, ' ');
|
|
1668
|
+
}
|
|
1669
|
+
s.append("to_string function");
|
|
1670
|
+
return s;
|
|
1671
|
+
}
|
|
1672
|
+
};
|
|
1673
|
+
|
|
1674
|
+
template <class Json>
|
|
1675
|
+
class min_function : public function_base<Json>
|
|
1676
|
+
{
|
|
1677
|
+
public:
|
|
1678
|
+
using value_type = Json;
|
|
1679
|
+
using parameter_type = parameter<Json>;
|
|
1680
|
+
|
|
1681
|
+
min_function()
|
|
1682
|
+
: function_base<Json>(1)
|
|
1683
|
+
{
|
|
1684
|
+
}
|
|
1685
|
+
|
|
1686
|
+
value_type evaluate(const std::vector<parameter_type>& args,
|
|
1687
|
+
std::error_code& ec) const override
|
|
1688
|
+
{
|
|
1689
|
+
if (args.size() != *this->arity())
|
|
1690
|
+
{
|
|
1691
|
+
ec = jsonpath_errc::invalid_arity;
|
|
1692
|
+
return value_type::null();
|
|
1693
|
+
}
|
|
1694
|
+
|
|
1695
|
+
auto arg0= args[0].value();
|
|
1696
|
+
if (!arg0.is_array())
|
|
1697
|
+
{
|
|
1698
|
+
//std::cout << "arg: " << arg0 << "\n";
|
|
1699
|
+
ec = jsonpath_errc::invalid_type;
|
|
1700
|
+
return value_type::null();
|
|
1701
|
+
}
|
|
1702
|
+
if (arg0.empty())
|
|
1703
|
+
{
|
|
1704
|
+
return value_type::null();
|
|
1705
|
+
}
|
|
1706
|
+
bool is_number = arg0.at(0).is_number();
|
|
1707
|
+
bool is_string = arg0.at(0).is_string();
|
|
1708
|
+
if (!is_number && !is_string)
|
|
1709
|
+
{
|
|
1710
|
+
ec = jsonpath_errc::invalid_type;
|
|
1711
|
+
return value_type::null();
|
|
1712
|
+
}
|
|
1713
|
+
|
|
1714
|
+
std::size_t index = 0;
|
|
1715
|
+
for (std::size_t i = 1; i < arg0.size(); ++i)
|
|
1716
|
+
{
|
|
1717
|
+
if (!(arg0.at(i).is_number() == is_number && arg0.at(i).is_string() == is_string))
|
|
1718
|
+
{
|
|
1719
|
+
ec = jsonpath_errc::invalid_type;
|
|
1720
|
+
return value_type::null();
|
|
1721
|
+
}
|
|
1722
|
+
if (arg0.at(i) < arg0.at(index))
|
|
1723
|
+
{
|
|
1724
|
+
index = i;
|
|
1725
|
+
}
|
|
1726
|
+
}
|
|
1727
|
+
|
|
1728
|
+
return arg0.at(index);
|
|
1729
|
+
}
|
|
1730
|
+
|
|
1731
|
+
std::string to_string(int level = 0) const override
|
|
1732
|
+
{
|
|
1733
|
+
std::string s;
|
|
1734
|
+
if (level > 0)
|
|
1735
|
+
{
|
|
1736
|
+
s.append("\n");
|
|
1737
|
+
s.append(level*2, ' ');
|
|
1738
|
+
}
|
|
1739
|
+
s.append("min function");
|
|
1740
|
+
return s;
|
|
1741
|
+
}
|
|
1742
|
+
};
|
|
1743
|
+
|
|
1744
|
+
template <class Json>
|
|
1745
|
+
class max_function : public function_base<Json>
|
|
1746
|
+
{
|
|
1747
|
+
public:
|
|
1748
|
+
using value_type = Json;
|
|
1749
|
+
using parameter_type = parameter<Json>;
|
|
1750
|
+
|
|
1751
|
+
max_function()
|
|
1752
|
+
: function_base<Json>(1)
|
|
1753
|
+
{
|
|
1754
|
+
}
|
|
1755
|
+
|
|
1756
|
+
value_type evaluate(const std::vector<parameter_type>& args,
|
|
1757
|
+
std::error_code& ec) const override
|
|
1758
|
+
{
|
|
1759
|
+
if (args.size() != *this->arity())
|
|
1760
|
+
{
|
|
1761
|
+
ec = jsonpath_errc::invalid_arity;
|
|
1762
|
+
return value_type::null();
|
|
1763
|
+
}
|
|
1764
|
+
|
|
1765
|
+
auto arg0= args[0].value();
|
|
1766
|
+
if (!arg0.is_array())
|
|
1767
|
+
{
|
|
1768
|
+
//std::cout << "arg: " << arg0 << "\n";
|
|
1769
|
+
ec = jsonpath_errc::invalid_type;
|
|
1770
|
+
return value_type::null();
|
|
1771
|
+
}
|
|
1772
|
+
if (arg0.empty())
|
|
1773
|
+
{
|
|
1774
|
+
return value_type::null();
|
|
1775
|
+
}
|
|
1776
|
+
|
|
1777
|
+
bool is_number = arg0.at(0).is_number();
|
|
1778
|
+
bool is_string = arg0.at(0).is_string();
|
|
1779
|
+
if (!is_number && !is_string)
|
|
1780
|
+
{
|
|
1781
|
+
ec = jsonpath_errc::invalid_type;
|
|
1782
|
+
return value_type::null();
|
|
1783
|
+
}
|
|
1784
|
+
|
|
1785
|
+
std::size_t index = 0;
|
|
1786
|
+
for (std::size_t i = 1; i < arg0.size(); ++i)
|
|
1787
|
+
{
|
|
1788
|
+
if (!(arg0.at(i).is_number() == is_number && arg0.at(i).is_string() == is_string))
|
|
1789
|
+
{
|
|
1790
|
+
ec = jsonpath_errc::invalid_type;
|
|
1791
|
+
return value_type::null();
|
|
1792
|
+
}
|
|
1793
|
+
if (arg0.at(i) > arg0.at(index))
|
|
1794
|
+
{
|
|
1795
|
+
index = i;
|
|
1796
|
+
}
|
|
1797
|
+
}
|
|
1798
|
+
|
|
1799
|
+
return arg0.at(index);
|
|
1800
|
+
}
|
|
1801
|
+
|
|
1802
|
+
std::string to_string(int level = 0) const override
|
|
1803
|
+
{
|
|
1804
|
+
std::string s;
|
|
1805
|
+
if (level > 0)
|
|
1806
|
+
{
|
|
1807
|
+
s.append("\n");
|
|
1808
|
+
s.append(level*2, ' ');
|
|
1809
|
+
}
|
|
1810
|
+
s.append("max function");
|
|
1811
|
+
return s;
|
|
1812
|
+
}
|
|
1813
|
+
};
|
|
1814
|
+
|
|
1815
|
+
template <class Json>
|
|
1816
|
+
class abs_function : public function_base<Json>
|
|
1817
|
+
{
|
|
1818
|
+
public:
|
|
1819
|
+
using value_type = Json;
|
|
1820
|
+
using parameter_type = parameter<Json>;
|
|
1821
|
+
|
|
1822
|
+
abs_function()
|
|
1823
|
+
: function_base<Json>(1)
|
|
1824
|
+
{
|
|
1825
|
+
}
|
|
1826
|
+
|
|
1827
|
+
value_type evaluate(const std::vector<parameter_type>& args,
|
|
1828
|
+
std::error_code& ec) const override
|
|
1829
|
+
{
|
|
1830
|
+
if (args.size() != *this->arity())
|
|
1831
|
+
{
|
|
1832
|
+
ec = jsonpath_errc::invalid_arity;
|
|
1833
|
+
return value_type::null();
|
|
1834
|
+
}
|
|
1835
|
+
|
|
1836
|
+
auto arg0= args[0].value();
|
|
1837
|
+
switch (arg0.type())
|
|
1838
|
+
{
|
|
1839
|
+
case json_type::uint64_value:
|
|
1840
|
+
return arg0;
|
|
1841
|
+
case json_type::int64_value:
|
|
1842
|
+
{
|
|
1843
|
+
return arg0.template as<int64_t>() >= 0 ? arg0 : value_type(std::abs(arg0.template as<int64_t>()));
|
|
1844
|
+
}
|
|
1845
|
+
case json_type::double_value:
|
|
1846
|
+
{
|
|
1847
|
+
return arg0.template as<double>() >= 0 ? arg0 : value_type(std::abs(arg0.template as<double>()));
|
|
1848
|
+
}
|
|
1849
|
+
default:
|
|
1850
|
+
{
|
|
1851
|
+
ec = jsonpath_errc::invalid_type;
|
|
1852
|
+
return value_type::null();
|
|
1853
|
+
}
|
|
1854
|
+
}
|
|
1855
|
+
}
|
|
1856
|
+
|
|
1857
|
+
std::string to_string(int level = 0) const override
|
|
1858
|
+
{
|
|
1859
|
+
std::string s;
|
|
1860
|
+
if (level > 0)
|
|
1861
|
+
{
|
|
1862
|
+
s.append("\n");
|
|
1863
|
+
s.append(level*2, ' ');
|
|
1864
|
+
}
|
|
1865
|
+
s.append("abs function");
|
|
1866
|
+
return s;
|
|
1867
|
+
}
|
|
1868
|
+
};
|
|
1869
|
+
|
|
1870
|
+
template <class Json>
|
|
1871
|
+
class length_function : public function_base<Json>
|
|
1872
|
+
{
|
|
1873
|
+
public:
|
|
1874
|
+
using value_type = Json;
|
|
1875
|
+
using string_view_type = typename Json::string_view_type;
|
|
1876
|
+
using parameter_type = parameter<Json>;
|
|
1877
|
+
|
|
1878
|
+
length_function()
|
|
1879
|
+
: function_base<Json>(1)
|
|
1880
|
+
{
|
|
1881
|
+
}
|
|
1882
|
+
|
|
1883
|
+
value_type evaluate(const std::vector<parameter_type>& args,
|
|
1884
|
+
std::error_code& ec) const override
|
|
1885
|
+
{
|
|
1886
|
+
if (args.size() != *this->arity())
|
|
1887
|
+
{
|
|
1888
|
+
ec = jsonpath_errc::invalid_arity;
|
|
1889
|
+
return value_type::null();
|
|
1890
|
+
}
|
|
1891
|
+
|
|
1892
|
+
auto arg0= args[0].value();
|
|
1893
|
+
//std::cout << "length function arg: " << arg0 << "\n";
|
|
1894
|
+
|
|
1895
|
+
switch (arg0.type())
|
|
1896
|
+
{
|
|
1897
|
+
case json_type::object_value:
|
|
1898
|
+
case json_type::array_value:
|
|
1899
|
+
return value_type(arg0.size());
|
|
1900
|
+
case json_type::string_value:
|
|
1901
|
+
{
|
|
1902
|
+
auto sv0 = arg0.template as<string_view_type>();
|
|
1903
|
+
auto length = unicode_traits::count_codepoints(sv0.data(), sv0.size());
|
|
1904
|
+
return value_type(length);
|
|
1905
|
+
}
|
|
1906
|
+
default:
|
|
1907
|
+
{
|
|
1908
|
+
ec = jsonpath_errc::invalid_type;
|
|
1909
|
+
return value_type::null();
|
|
1910
|
+
}
|
|
1911
|
+
}
|
|
1912
|
+
}
|
|
1913
|
+
|
|
1914
|
+
std::string to_string(int level = 0) const override
|
|
1915
|
+
{
|
|
1916
|
+
std::string s;
|
|
1917
|
+
if (level > 0)
|
|
1918
|
+
{
|
|
1919
|
+
s.append("\n");
|
|
1920
|
+
s.append(level*2, ' ');
|
|
1921
|
+
}
|
|
1922
|
+
s.append("length function");
|
|
1923
|
+
return s;
|
|
1924
|
+
}
|
|
1925
|
+
};
|
|
1926
|
+
|
|
1927
|
+
template <class Json>
|
|
1928
|
+
class keys_function : public function_base<Json>
|
|
1929
|
+
{
|
|
1930
|
+
public:
|
|
1931
|
+
using value_type = Json;
|
|
1932
|
+
using parameter_type = parameter<Json>;
|
|
1933
|
+
using string_view_type = typename Json::string_view_type;
|
|
1934
|
+
|
|
1935
|
+
keys_function()
|
|
1936
|
+
: function_base<Json>(1)
|
|
1937
|
+
{
|
|
1938
|
+
}
|
|
1939
|
+
|
|
1940
|
+
value_type evaluate(const std::vector<parameter_type>& args,
|
|
1941
|
+
std::error_code& ec) const override
|
|
1942
|
+
{
|
|
1943
|
+
if (args.size() != *this->arity())
|
|
1944
|
+
{
|
|
1945
|
+
ec = jsonpath_errc::invalid_arity;
|
|
1946
|
+
return value_type::null();
|
|
1947
|
+
}
|
|
1948
|
+
|
|
1949
|
+
auto arg0= args[0].value();
|
|
1950
|
+
if (!arg0.is_object())
|
|
1951
|
+
{
|
|
1952
|
+
ec = jsonpath_errc::invalid_type;
|
|
1953
|
+
return value_type::null();
|
|
1954
|
+
}
|
|
1955
|
+
|
|
1956
|
+
value_type result(json_array_arg);
|
|
1957
|
+
result.reserve(args.size());
|
|
1958
|
+
|
|
1959
|
+
for (auto& item : arg0.object_range())
|
|
1960
|
+
{
|
|
1961
|
+
result.emplace_back(item.key());
|
|
1962
|
+
}
|
|
1963
|
+
return result;
|
|
1964
|
+
}
|
|
1965
|
+
|
|
1966
|
+
std::string to_string(int level = 0) const override
|
|
1967
|
+
{
|
|
1968
|
+
std::string s;
|
|
1969
|
+
if (level > 0)
|
|
1970
|
+
{
|
|
1971
|
+
s.append("\n");
|
|
1972
|
+
s.append(level*2, ' ');
|
|
1973
|
+
}
|
|
1974
|
+
s.append("keys function");
|
|
1975
|
+
return s;
|
|
1976
|
+
}
|
|
1977
|
+
};
|
|
1978
|
+
|
|
1979
|
+
enum class jsonpath_token_kind
|
|
1980
|
+
{
|
|
1981
|
+
root_node,
|
|
1982
|
+
current_node,
|
|
1983
|
+
expression,
|
|
1984
|
+
lparen,
|
|
1985
|
+
rparen,
|
|
1986
|
+
begin_union,
|
|
1987
|
+
end_union,
|
|
1988
|
+
begin_filter,
|
|
1989
|
+
end_filter,
|
|
1990
|
+
begin_expression,
|
|
1991
|
+
end_index_expression,
|
|
1992
|
+
end_argument_expression,
|
|
1993
|
+
separator,
|
|
1994
|
+
literal,
|
|
1995
|
+
selector,
|
|
1996
|
+
function,
|
|
1997
|
+
end_function,
|
|
1998
|
+
argument,
|
|
1999
|
+
unary_operator,
|
|
2000
|
+
binary_operator
|
|
2001
|
+
};
|
|
2002
|
+
|
|
2003
|
+
inline
|
|
2004
|
+
std::string to_string(jsonpath_token_kind kind)
|
|
2005
|
+
{
|
|
2006
|
+
switch (kind)
|
|
2007
|
+
{
|
|
2008
|
+
case jsonpath_token_kind::root_node:
|
|
2009
|
+
return "root_node";
|
|
2010
|
+
case jsonpath_token_kind::current_node:
|
|
2011
|
+
return "current_node";
|
|
2012
|
+
case jsonpath_token_kind::lparen:
|
|
2013
|
+
return "lparen";
|
|
2014
|
+
case jsonpath_token_kind::rparen:
|
|
2015
|
+
return "rparen";
|
|
2016
|
+
case jsonpath_token_kind::begin_union:
|
|
2017
|
+
return "begin_union";
|
|
2018
|
+
case jsonpath_token_kind::end_union:
|
|
2019
|
+
return "end_union";
|
|
2020
|
+
case jsonpath_token_kind::begin_filter:
|
|
2021
|
+
return "begin_filter";
|
|
2022
|
+
case jsonpath_token_kind::end_filter:
|
|
2023
|
+
return "end_filter";
|
|
2024
|
+
case jsonpath_token_kind::begin_expression:
|
|
2025
|
+
return "begin_expression";
|
|
2026
|
+
case jsonpath_token_kind::end_index_expression:
|
|
2027
|
+
return "end_index_expression";
|
|
2028
|
+
case jsonpath_token_kind::end_argument_expression:
|
|
2029
|
+
return "end_argument_expression";
|
|
2030
|
+
case jsonpath_token_kind::separator:
|
|
2031
|
+
return "separator";
|
|
2032
|
+
case jsonpath_token_kind::literal:
|
|
2033
|
+
return "literal";
|
|
2034
|
+
case jsonpath_token_kind::selector:
|
|
2035
|
+
return "selector";
|
|
2036
|
+
case jsonpath_token_kind::function:
|
|
2037
|
+
return "function";
|
|
2038
|
+
case jsonpath_token_kind::end_function:
|
|
2039
|
+
return "end_function";
|
|
2040
|
+
case jsonpath_token_kind::argument:
|
|
2041
|
+
return "argument";
|
|
2042
|
+
case jsonpath_token_kind::unary_operator:
|
|
2043
|
+
return "unary_operator";
|
|
2044
|
+
case jsonpath_token_kind::binary_operator:
|
|
2045
|
+
return "binary_operator";
|
|
2046
|
+
default:
|
|
2047
|
+
return "";
|
|
2048
|
+
}
|
|
2049
|
+
}
|
|
2050
|
+
|
|
2051
|
+
template <class Json,class JsonReference>
|
|
2052
|
+
struct path_value_pair
|
|
2053
|
+
{
|
|
2054
|
+
using char_type = typename Json::char_type;
|
|
2055
|
+
using string_type = std::basic_string<char_type,std::char_traits<char_type>>;
|
|
2056
|
+
using value_type = Json;
|
|
2057
|
+
using reference = JsonReference;
|
|
2058
|
+
using value_pointer = typename std::conditional<std::is_const<typename std::remove_reference<JsonReference>::type>::value,typename Json::const_pointer,typename Json::pointer>::type;
|
|
2059
|
+
using json_location_node_type = json_location_node<char_type>;
|
|
2060
|
+
using json_location_type = json_location<char_type>;
|
|
2061
|
+
using path_pointer = const json_location_node_type*;
|
|
2062
|
+
|
|
2063
|
+
json_location_type path_;
|
|
2064
|
+
value_pointer value_ptr_;
|
|
2065
|
+
|
|
2066
|
+
path_value_pair(const json_location_type& path, reference value) noexcept
|
|
2067
|
+
: path_(path), value_ptr_(std::addressof(value))
|
|
2068
|
+
{
|
|
2069
|
+
}
|
|
2070
|
+
|
|
2071
|
+
path_value_pair(json_location_type&& path, value_pointer valp) noexcept
|
|
2072
|
+
: path_(std::move(path)), value_ptr_(valp)
|
|
2073
|
+
{
|
|
2074
|
+
}
|
|
2075
|
+
|
|
2076
|
+
path_value_pair(const path_value_pair&) = default;
|
|
2077
|
+
path_value_pair(path_value_pair&& other) = default;
|
|
2078
|
+
path_value_pair& operator=(const path_value_pair&) = default;
|
|
2079
|
+
path_value_pair& operator=(path_value_pair&& other) = default;
|
|
2080
|
+
|
|
2081
|
+
json_location_type path() const
|
|
2082
|
+
{
|
|
2083
|
+
return path_;
|
|
2084
|
+
}
|
|
2085
|
+
|
|
2086
|
+
reference value()
|
|
2087
|
+
{
|
|
2088
|
+
return *value_ptr_;
|
|
2089
|
+
}
|
|
2090
|
+
};
|
|
2091
|
+
|
|
2092
|
+
template <class Json,class JsonReference>
|
|
2093
|
+
struct path_value_pair_less
|
|
2094
|
+
{
|
|
2095
|
+
bool operator()(const path_value_pair<Json,JsonReference>& lhs,
|
|
2096
|
+
const path_value_pair<Json,JsonReference>& rhs) const noexcept
|
|
2097
|
+
{
|
|
2098
|
+
return lhs.path() < rhs.path();
|
|
2099
|
+
}
|
|
2100
|
+
};
|
|
2101
|
+
|
|
2102
|
+
template <class Json,class JsonReference>
|
|
2103
|
+
struct path_value_pair_equal
|
|
2104
|
+
{
|
|
2105
|
+
bool operator()(const path_value_pair<Json,JsonReference>& lhs,
|
|
2106
|
+
const path_value_pair<Json,JsonReference>& rhs) const noexcept
|
|
2107
|
+
{
|
|
2108
|
+
return lhs.path() == rhs.path();
|
|
2109
|
+
}
|
|
2110
|
+
};
|
|
2111
|
+
|
|
2112
|
+
template <class Json,class JsonReference>
|
|
2113
|
+
struct path_component_value_pair
|
|
2114
|
+
{
|
|
2115
|
+
using char_type = typename Json::char_type;
|
|
2116
|
+
using string_type = std::basic_string<char_type,std::char_traits<char_type>>;
|
|
2117
|
+
using value_type = Json;
|
|
2118
|
+
using reference = JsonReference;
|
|
2119
|
+
using value_pointer = typename std::conditional<std::is_const<typename std::remove_reference<JsonReference>::type>::value,typename Json::const_pointer,typename Json::pointer>::type;
|
|
2120
|
+
using json_location_node_type = json_location_node<char_type>;
|
|
2121
|
+
using json_location_type = json_location<char_type>;
|
|
2122
|
+
using path_pointer = const json_location_node_type*;
|
|
2123
|
+
private:
|
|
2124
|
+
const json_location_node_type* last_ptr_;
|
|
2125
|
+
value_pointer value_ptr_;
|
|
2126
|
+
public:
|
|
2127
|
+
path_component_value_pair(const json_location_node_type& last, reference value) noexcept
|
|
2128
|
+
: last_ptr_(std::addressof(last)), value_ptr_(std::addressof(value))
|
|
2129
|
+
{
|
|
2130
|
+
}
|
|
2131
|
+
|
|
2132
|
+
const json_location_node_type& last() const
|
|
2133
|
+
{
|
|
2134
|
+
return *last_ptr_;
|
|
2135
|
+
}
|
|
2136
|
+
|
|
2137
|
+
reference value() const
|
|
2138
|
+
{
|
|
2139
|
+
return *value_ptr_;
|
|
2140
|
+
}
|
|
2141
|
+
};
|
|
2142
|
+
|
|
2143
|
+
template <class Json,class JsonReference>
|
|
2144
|
+
class node_receiver
|
|
2145
|
+
{
|
|
2146
|
+
public:
|
|
2147
|
+
using char_type = typename Json::char_type;
|
|
2148
|
+
using reference = JsonReference;
|
|
2149
|
+
using json_location_node_type = json_location_node<char_type>;
|
|
2150
|
+
|
|
2151
|
+
virtual ~node_receiver() noexcept = default;
|
|
2152
|
+
|
|
2153
|
+
virtual void add(const json_location_node_type& path_tail,
|
|
2154
|
+
reference value) = 0;
|
|
2155
|
+
};
|
|
2156
|
+
|
|
2157
|
+
template <class Json,class JsonReference>
|
|
2158
|
+
class path_value_receiver : public node_receiver<Json,JsonReference>
|
|
2159
|
+
{
|
|
2160
|
+
public:
|
|
2161
|
+
using reference = JsonReference;
|
|
2162
|
+
using char_type = typename Json::char_type;
|
|
2163
|
+
using json_location_node_type = json_location_node<char_type>;
|
|
2164
|
+
using json_location_type = json_location<char_type>;
|
|
2165
|
+
using path_value_pair_type = path_value_pair<Json,JsonReference>;
|
|
2166
|
+
|
|
2167
|
+
std::vector<path_value_pair_type> nodes;
|
|
2168
|
+
|
|
2169
|
+
void add(const json_location_node_type& path_tail,
|
|
2170
|
+
reference value) override
|
|
2171
|
+
{
|
|
2172
|
+
nodes.emplace_back(json_location_type(path_tail), std::addressof(value));
|
|
2173
|
+
}
|
|
2174
|
+
};
|
|
2175
|
+
|
|
2176
|
+
template <class Json,class JsonReference>
|
|
2177
|
+
class path_stem_value_receiver : public node_receiver<Json,JsonReference>
|
|
2178
|
+
{
|
|
2179
|
+
public:
|
|
2180
|
+
using reference = JsonReference;
|
|
2181
|
+
using char_type = typename Json::char_type;
|
|
2182
|
+
using json_location_node_type = json_location_node<char_type>;
|
|
2183
|
+
using path_stem_value_pair_type = path_component_value_pair<Json,JsonReference>;
|
|
2184
|
+
|
|
2185
|
+
std::vector<path_stem_value_pair_type> nodes;
|
|
2186
|
+
|
|
2187
|
+
void add(const json_location_node_type& path_tail,
|
|
2188
|
+
reference value) override
|
|
2189
|
+
{
|
|
2190
|
+
nodes.emplace_back(path_tail, value);
|
|
2191
|
+
}
|
|
2192
|
+
};
|
|
2193
|
+
|
|
2194
|
+
template <class Json, class JsonReference>
|
|
2195
|
+
class dynamic_resources
|
|
2196
|
+
{
|
|
2197
|
+
using reference = JsonReference;
|
|
2198
|
+
using pointer = typename std::conditional<std::is_const<typename std::remove_reference<reference>::type>::value,typename Json::const_pointer,typename Json::pointer>::type;
|
|
2199
|
+
using json_location_node_type = json_location_node<typename Json::char_type>;
|
|
2200
|
+
using path_stem_value_pair_type = path_component_value_pair<Json,JsonReference>;
|
|
2201
|
+
std::vector<std::unique_ptr<Json>> temp_json_values_;
|
|
2202
|
+
std::vector<std::unique_ptr<json_location_node_type>> temp_path_node_values_;
|
|
2203
|
+
std::unordered_map<std::size_t,pointer> cache_;
|
|
2204
|
+
public:
|
|
2205
|
+
bool is_cached(std::size_t id) const
|
|
2206
|
+
{
|
|
2207
|
+
return cache_.find(id) != cache_.end();
|
|
2208
|
+
}
|
|
2209
|
+
void add_to_cache(std::size_t id, reference val)
|
|
2210
|
+
{
|
|
2211
|
+
cache_.emplace(id, std::addressof(val));
|
|
2212
|
+
}
|
|
2213
|
+
reference retrieve_from_cache(std::size_t id)
|
|
2214
|
+
{
|
|
2215
|
+
return *cache_[id];
|
|
2216
|
+
}
|
|
2217
|
+
|
|
2218
|
+
reference null_value()
|
|
2219
|
+
{
|
|
2220
|
+
static Json j{ null_type{} };
|
|
2221
|
+
return j;
|
|
2222
|
+
}
|
|
2223
|
+
|
|
2224
|
+
template <typename... Args>
|
|
2225
|
+
Json* create_json(Args&& ... args)
|
|
2226
|
+
{
|
|
2227
|
+
auto temp = jsoncons::make_unique<Json>(std::forward<Args>(args)...);
|
|
2228
|
+
Json* ptr = temp.get();
|
|
2229
|
+
temp_json_values_.emplace_back(std::move(temp));
|
|
2230
|
+
return ptr;
|
|
2231
|
+
}
|
|
2232
|
+
|
|
2233
|
+
const json_location_node_type& root_path_node() const
|
|
2234
|
+
{
|
|
2235
|
+
static json_location_node_type root('$');
|
|
2236
|
+
return root;
|
|
2237
|
+
}
|
|
2238
|
+
|
|
2239
|
+
const json_location_node_type& current_path_node() const
|
|
2240
|
+
{
|
|
2241
|
+
static json_location_node_type root('@');
|
|
2242
|
+
return root;
|
|
2243
|
+
}
|
|
2244
|
+
|
|
2245
|
+
template <typename... Args>
|
|
2246
|
+
const json_location_node_type* create_path_node(Args&& ... args)
|
|
2247
|
+
{
|
|
2248
|
+
auto temp = jsoncons::make_unique<json_location_node_type>(std::forward<Args>(args)...);
|
|
2249
|
+
json_location_node_type* ptr = temp.get();
|
|
2250
|
+
temp_path_node_values_.emplace_back(std::move(temp));
|
|
2251
|
+
return ptr;
|
|
2252
|
+
}
|
|
2253
|
+
};
|
|
2254
|
+
|
|
2255
|
+
template <class Json,class JsonReference>
|
|
2256
|
+
struct node_less
|
|
2257
|
+
{
|
|
2258
|
+
bool operator()(const path_value_pair<Json,JsonReference>& a, const path_value_pair<Json,JsonReference>& b) const
|
|
2259
|
+
{
|
|
2260
|
+
return *(a.ptr) < *(b.ptr);
|
|
2261
|
+
}
|
|
2262
|
+
};
|
|
2263
|
+
|
|
2264
|
+
template <class Json,class JsonReference>
|
|
2265
|
+
class jsonpath_selector
|
|
2266
|
+
{
|
|
2267
|
+
bool is_path_;
|
|
2268
|
+
std::size_t precedence_level_;
|
|
2269
|
+
|
|
2270
|
+
public:
|
|
2271
|
+
using char_type = typename Json::char_type;
|
|
2272
|
+
using string_type = std::basic_string<char_type,std::char_traits<char_type>>;
|
|
2273
|
+
using string_view_type = jsoncons::basic_string_view<char_type, std::char_traits<char_type>>;
|
|
2274
|
+
using value_type = Json;
|
|
2275
|
+
using reference = JsonReference;
|
|
2276
|
+
using pointer = typename std::conditional<std::is_const<typename std::remove_reference<JsonReference>::type>::value,typename Json::const_pointer,typename Json::pointer>::type;
|
|
2277
|
+
using path_value_pair_type = path_value_pair<Json,JsonReference>;
|
|
2278
|
+
using json_location_node_type = json_location_node<char_type>;
|
|
2279
|
+
using json_location_type = json_location<char_type>;
|
|
2280
|
+
using node_receiver_type = node_receiver<Json,JsonReference>;
|
|
2281
|
+
using selector_type = jsonpath_selector<Json,JsonReference>;
|
|
2282
|
+
|
|
2283
|
+
jsonpath_selector(bool is_path,
|
|
2284
|
+
std::size_t precedence_level = 0)
|
|
2285
|
+
: is_path_(is_path),
|
|
2286
|
+
precedence_level_(precedence_level)
|
|
2287
|
+
{
|
|
2288
|
+
}
|
|
2289
|
+
|
|
2290
|
+
virtual ~jsonpath_selector() noexcept = default;
|
|
2291
|
+
|
|
2292
|
+
bool is_path() const
|
|
2293
|
+
{
|
|
2294
|
+
return is_path_;
|
|
2295
|
+
}
|
|
2296
|
+
|
|
2297
|
+
std::size_t precedence_level() const
|
|
2298
|
+
{
|
|
2299
|
+
return precedence_level_;
|
|
2300
|
+
}
|
|
2301
|
+
|
|
2302
|
+
bool is_right_associative() const
|
|
2303
|
+
{
|
|
2304
|
+
return true;
|
|
2305
|
+
}
|
|
2306
|
+
|
|
2307
|
+
virtual void select(dynamic_resources<Json,JsonReference>& resources,
|
|
2308
|
+
reference root,
|
|
2309
|
+
const json_location_node_type& path_tail,
|
|
2310
|
+
reference val,
|
|
2311
|
+
node_receiver_type& receiver,
|
|
2312
|
+
result_options options) const = 0;
|
|
2313
|
+
|
|
2314
|
+
virtual reference evaluate(dynamic_resources<Json,JsonReference>& resources,
|
|
2315
|
+
reference root,
|
|
2316
|
+
const json_location_node_type& path_tail,
|
|
2317
|
+
reference current,
|
|
2318
|
+
result_options options,
|
|
2319
|
+
std::error_code& ec) const = 0;
|
|
2320
|
+
|
|
2321
|
+
virtual void append_selector(jsonpath_selector*)
|
|
2322
|
+
{
|
|
2323
|
+
}
|
|
2324
|
+
|
|
2325
|
+
virtual std::string to_string(int = 0) const
|
|
2326
|
+
{
|
|
2327
|
+
return std::string();
|
|
2328
|
+
}
|
|
2329
|
+
};
|
|
2330
|
+
|
|
2331
|
+
template <class Json, class JsonReference>
|
|
2332
|
+
struct static_resources
|
|
2333
|
+
{
|
|
2334
|
+
using char_type = typename Json::char_type;
|
|
2335
|
+
using string_type = std::basic_string<char_type>;
|
|
2336
|
+
using value_type = Json;
|
|
2337
|
+
using reference = JsonReference;
|
|
2338
|
+
using function_base_type = function_base<Json>;
|
|
2339
|
+
using selector_type = jsonpath_selector<Json,JsonReference>;
|
|
2340
|
+
|
|
2341
|
+
std::vector<std::unique_ptr<selector_type>> selectors_;
|
|
2342
|
+
std::vector<std::unique_ptr<Json>> temp_json_values_;
|
|
2343
|
+
std::vector<std::unique_ptr<unary_operator<Json,JsonReference>>> unary_operators_;
|
|
2344
|
+
std::unordered_map<string_type,std::unique_ptr<function_base_type>> custom_functions_;
|
|
2345
|
+
|
|
2346
|
+
static_resources()
|
|
2347
|
+
{
|
|
2348
|
+
}
|
|
2349
|
+
|
|
2350
|
+
static_resources(const custom_functions<Json>& functions)
|
|
2351
|
+
{
|
|
2352
|
+
for (const auto& item : functions)
|
|
2353
|
+
{
|
|
2354
|
+
custom_functions_.emplace(item.name(),
|
|
2355
|
+
jsoncons::make_unique<decorator_function<Json>>(item.arity(),item.function()));
|
|
2356
|
+
}
|
|
2357
|
+
}
|
|
2358
|
+
|
|
2359
|
+
static_resources(const static_resources&) = default;
|
|
2360
|
+
|
|
2361
|
+
static_resources(static_resources&& other) noexcept
|
|
2362
|
+
: selectors_(std::move(other.selectors_)),
|
|
2363
|
+
temp_json_values_(std::move(other.temp_json_values_)),
|
|
2364
|
+
unary_operators_(std::move(other.unary_operators_)),
|
|
2365
|
+
custom_functions_(std::move(other.custom_functions_))
|
|
2366
|
+
{
|
|
2367
|
+
}
|
|
2368
|
+
|
|
2369
|
+
const function_base_type* get_function(const string_type& name, std::error_code& ec) const
|
|
2370
|
+
{
|
|
2371
|
+
static abs_function<Json> abs_func;
|
|
2372
|
+
static contains_function<Json> contains_func;
|
|
2373
|
+
static starts_with_function<Json> starts_with_func;
|
|
2374
|
+
static ends_with_function<Json> ends_with_func;
|
|
2375
|
+
static ceil_function<Json> ceil_func;
|
|
2376
|
+
static floor_function<Json> floor_func;
|
|
2377
|
+
static to_number_function<Json> to_number_func;
|
|
2378
|
+
static sum_function<Json> sum_func;
|
|
2379
|
+
static prod_function<Json> prod_func;
|
|
2380
|
+
static avg_function<Json> avg_func;
|
|
2381
|
+
static min_function<Json> min_func;
|
|
2382
|
+
static max_function<Json> max_func;
|
|
2383
|
+
static length_function<Json> length_func;
|
|
2384
|
+
static keys_function<Json> keys_func;
|
|
2385
|
+
#if defined(JSONCONS_HAS_STD_REGEX)
|
|
2386
|
+
static tokenize_function<Json> tokenize_func;
|
|
2387
|
+
#endif
|
|
2388
|
+
|
|
2389
|
+
static std::unordered_map<string_type,const function_base_type*> functions =
|
|
2390
|
+
{
|
|
2391
|
+
{string_type{'a','b','s'}, &abs_func},
|
|
2392
|
+
{string_type{'c','o','n','t','a','i','n','s'}, &contains_func},
|
|
2393
|
+
{string_type{'s','t','a','r','t','s','_','w','i','t','h'}, &starts_with_func},
|
|
2394
|
+
{string_type{'e','n','d','s','_','w','i','t','h'}, &ends_with_func},
|
|
2395
|
+
{string_type{'c','e','i','l'}, &ceil_func},
|
|
2396
|
+
{string_type{'f','l','o','o','r'}, &floor_func},
|
|
2397
|
+
{string_type{'t','o','_','n','u','m','b','e','r'}, &to_number_func},
|
|
2398
|
+
{string_type{'s','u','m'}, &sum_func},
|
|
2399
|
+
{string_type{'p','r','o', 'd'}, &prod_func},
|
|
2400
|
+
{string_type{'a','v','g'}, &avg_func},
|
|
2401
|
+
{string_type{'m','i','n'}, &min_func},
|
|
2402
|
+
{string_type{'m','a','x'}, &max_func},
|
|
2403
|
+
{string_type{'l','e','n','g','t','h'}, &length_func},
|
|
2404
|
+
{string_type{'k','e','y','s'}, &keys_func},
|
|
2405
|
+
#if defined(JSONCONS_HAS_STD_REGEX)
|
|
2406
|
+
{string_type{'t','o','k','e','n','i','z','e'}, &tokenize_func},
|
|
2407
|
+
#endif
|
|
2408
|
+
{string_type{'c','o','u','n','t'}, &length_func}
|
|
2409
|
+
};
|
|
2410
|
+
|
|
2411
|
+
auto it = functions.find(name);
|
|
2412
|
+
if (it == functions.end())
|
|
2413
|
+
{
|
|
2414
|
+
auto it2 = custom_functions_.find(name);
|
|
2415
|
+
if (it2 == custom_functions_.end())
|
|
2416
|
+
{
|
|
2417
|
+
ec = jsonpath_errc::unknown_function;
|
|
2418
|
+
return nullptr;
|
|
2419
|
+
}
|
|
2420
|
+
else
|
|
2421
|
+
{
|
|
2422
|
+
return it2->second.get();
|
|
2423
|
+
}
|
|
2424
|
+
}
|
|
2425
|
+
else
|
|
2426
|
+
{
|
|
2427
|
+
return it->second;
|
|
2428
|
+
}
|
|
2429
|
+
}
|
|
2430
|
+
|
|
2431
|
+
const unary_operator<Json,JsonReference>* get_unary_not() const
|
|
2432
|
+
{
|
|
2433
|
+
static unary_not_operator<Json,JsonReference> oper;
|
|
2434
|
+
return &oper;
|
|
2435
|
+
}
|
|
2436
|
+
|
|
2437
|
+
const unary_operator<Json,JsonReference>* get_unary_minus() const
|
|
2438
|
+
{
|
|
2439
|
+
static unary_minus_operator<Json,JsonReference> oper;
|
|
2440
|
+
return &oper;
|
|
2441
|
+
}
|
|
2442
|
+
|
|
2443
|
+
const unary_operator<Json,JsonReference>* get_regex_operator(std::basic_regex<char_type>&& pattern)
|
|
2444
|
+
{
|
|
2445
|
+
unary_operators_.push_back(jsoncons::make_unique<regex_operator<Json,JsonReference>>(std::move(pattern)));
|
|
2446
|
+
return unary_operators_.back().get();
|
|
2447
|
+
}
|
|
2448
|
+
|
|
2449
|
+
const binary_operator<Json,JsonReference>* get_or_operator() const
|
|
2450
|
+
{
|
|
2451
|
+
static or_operator<Json,JsonReference> oper;
|
|
2452
|
+
|
|
2453
|
+
return &oper;
|
|
2454
|
+
}
|
|
2455
|
+
|
|
2456
|
+
const binary_operator<Json,JsonReference>* get_and_operator() const
|
|
2457
|
+
{
|
|
2458
|
+
static and_operator<Json,JsonReference> oper;
|
|
2459
|
+
|
|
2460
|
+
return &oper;
|
|
2461
|
+
}
|
|
2462
|
+
|
|
2463
|
+
const binary_operator<Json,JsonReference>* get_eq_operator() const
|
|
2464
|
+
{
|
|
2465
|
+
static eq_operator<Json,JsonReference> oper;
|
|
2466
|
+
return &oper;
|
|
2467
|
+
}
|
|
2468
|
+
|
|
2469
|
+
const binary_operator<Json,JsonReference>* get_ne_operator() const
|
|
2470
|
+
{
|
|
2471
|
+
static ne_operator<Json,JsonReference> oper;
|
|
2472
|
+
return &oper;
|
|
2473
|
+
}
|
|
2474
|
+
|
|
2475
|
+
const binary_operator<Json,JsonReference>* get_lt_operator() const
|
|
2476
|
+
{
|
|
2477
|
+
static lt_operator<Json,JsonReference> oper;
|
|
2478
|
+
return &oper;
|
|
2479
|
+
}
|
|
2480
|
+
|
|
2481
|
+
const binary_operator<Json,JsonReference>* get_lte_operator() const
|
|
2482
|
+
{
|
|
2483
|
+
static lte_operator<Json,JsonReference> oper;
|
|
2484
|
+
return &oper;
|
|
2485
|
+
}
|
|
2486
|
+
|
|
2487
|
+
const binary_operator<Json,JsonReference>* get_gt_operator() const
|
|
2488
|
+
{
|
|
2489
|
+
static gt_operator<Json,JsonReference> oper;
|
|
2490
|
+
return &oper;
|
|
2491
|
+
}
|
|
2492
|
+
|
|
2493
|
+
const binary_operator<Json,JsonReference>* get_gte_operator() const
|
|
2494
|
+
{
|
|
2495
|
+
static gte_operator<Json,JsonReference> oper;
|
|
2496
|
+
return &oper;
|
|
2497
|
+
}
|
|
2498
|
+
|
|
2499
|
+
const binary_operator<Json,JsonReference>* get_plus_operator() const
|
|
2500
|
+
{
|
|
2501
|
+
static plus_operator<Json,JsonReference> oper;
|
|
2502
|
+
return &oper;
|
|
2503
|
+
}
|
|
2504
|
+
|
|
2505
|
+
const binary_operator<Json,JsonReference>* get_minus_operator() const
|
|
2506
|
+
{
|
|
2507
|
+
static minus_operator<Json,JsonReference> oper;
|
|
2508
|
+
return &oper;
|
|
2509
|
+
}
|
|
2510
|
+
|
|
2511
|
+
const binary_operator<Json,JsonReference>* get_mult_operator() const
|
|
2512
|
+
{
|
|
2513
|
+
static mult_operator<Json,JsonReference> oper;
|
|
2514
|
+
return &oper;
|
|
2515
|
+
}
|
|
2516
|
+
|
|
2517
|
+
const binary_operator<Json,JsonReference>* get_div_operator() const
|
|
2518
|
+
{
|
|
2519
|
+
static div_operator<Json,JsonReference> oper;
|
|
2520
|
+
return &oper;
|
|
2521
|
+
}
|
|
2522
|
+
|
|
2523
|
+
const binary_operator<Json,JsonReference>* get_modulus_operator() const
|
|
2524
|
+
{
|
|
2525
|
+
static modulus_operator<Json,JsonReference> oper;
|
|
2526
|
+
return &oper;
|
|
2527
|
+
}
|
|
2528
|
+
|
|
2529
|
+
template <typename T>
|
|
2530
|
+
selector_type* new_selector(T&& val)
|
|
2531
|
+
{
|
|
2532
|
+
selectors_.emplace_back(jsoncons::make_unique<T>(std::forward<T>(val)));
|
|
2533
|
+
return selectors_.back().get();
|
|
2534
|
+
}
|
|
2535
|
+
|
|
2536
|
+
template <typename... Args>
|
|
2537
|
+
Json* create_json(Args&& ... args)
|
|
2538
|
+
{
|
|
2539
|
+
auto temp = jsoncons::make_unique<Json>(std::forward<Args>(args)...);
|
|
2540
|
+
Json* ptr = temp.get();
|
|
2541
|
+
temp_json_values_.emplace_back(std::move(temp));
|
|
2542
|
+
return ptr;
|
|
2543
|
+
}
|
|
2544
|
+
};
|
|
2545
|
+
|
|
2546
|
+
template <class Json, class JsonReference>
|
|
2547
|
+
class expression_base
|
|
2548
|
+
{
|
|
2549
|
+
public:
|
|
2550
|
+
using char_type = typename Json::char_type;
|
|
2551
|
+
using string_type = std::basic_string<char_type,std::char_traits<char_type>>;
|
|
2552
|
+
using string_view_type = jsoncons::basic_string_view<char_type, std::char_traits<char_type>>;
|
|
2553
|
+
using value_type = Json;
|
|
2554
|
+
using reference = JsonReference;
|
|
2555
|
+
using pointer = typename std::conditional<std::is_const<typename std::remove_reference<JsonReference>::type>::value,typename Json::const_pointer,typename Json::pointer>::type;
|
|
2556
|
+
using path_value_pair_type = path_value_pair<Json,JsonReference>;
|
|
2557
|
+
using json_location_node_type = json_location_node<char_type>;
|
|
2558
|
+
|
|
2559
|
+
virtual ~expression_base() noexcept = default;
|
|
2560
|
+
|
|
2561
|
+
virtual value_type evaluate(dynamic_resources<Json,JsonReference>& resources,
|
|
2562
|
+
reference root,
|
|
2563
|
+
//const json_location_node_type& path,
|
|
2564
|
+
reference val,
|
|
2565
|
+
result_options options,
|
|
2566
|
+
std::error_code& ec) const = 0;
|
|
2567
|
+
|
|
2568
|
+
virtual std::string to_string(int level = 0) const = 0;
|
|
2569
|
+
};
|
|
2570
|
+
|
|
2571
|
+
template <class Json,class JsonReference>
|
|
2572
|
+
class token
|
|
2573
|
+
{
|
|
2574
|
+
public:
|
|
2575
|
+
using selector_type = jsonpath_selector<Json,JsonReference>;
|
|
2576
|
+
using expression_base_type = expression_base<Json,JsonReference>;
|
|
2577
|
+
|
|
2578
|
+
jsonpath_token_kind token_kind_;
|
|
2579
|
+
|
|
2580
|
+
union
|
|
2581
|
+
{
|
|
2582
|
+
selector_type* selector_;
|
|
2583
|
+
std::unique_ptr<expression_base_type> expression_;
|
|
2584
|
+
const unary_operator<Json,JsonReference>* unary_operator_;
|
|
2585
|
+
const binary_operator<Json,JsonReference>* binary_operator_;
|
|
2586
|
+
const function_base<Json>* function_;
|
|
2587
|
+
Json value_;
|
|
2588
|
+
};
|
|
2589
|
+
public:
|
|
2590
|
+
|
|
2591
|
+
token(const unary_operator<Json,JsonReference>* expr) noexcept
|
|
2592
|
+
: token_kind_(jsonpath_token_kind::unary_operator),
|
|
2593
|
+
unary_operator_(expr)
|
|
2594
|
+
{
|
|
2595
|
+
}
|
|
2596
|
+
|
|
2597
|
+
token(const binary_operator<Json,JsonReference>* expr) noexcept
|
|
2598
|
+
: token_kind_(jsonpath_token_kind::binary_operator),
|
|
2599
|
+
binary_operator_(expr)
|
|
2600
|
+
{
|
|
2601
|
+
}
|
|
2602
|
+
|
|
2603
|
+
token(current_node_arg_t) noexcept
|
|
2604
|
+
: token_kind_(jsonpath_token_kind::current_node)
|
|
2605
|
+
{
|
|
2606
|
+
}
|
|
2607
|
+
|
|
2608
|
+
token(root_node_arg_t) noexcept
|
|
2609
|
+
: token_kind_(jsonpath_token_kind::root_node)
|
|
2610
|
+
{
|
|
2611
|
+
}
|
|
2612
|
+
|
|
2613
|
+
token(end_function_arg_t) noexcept
|
|
2614
|
+
: token_kind_(jsonpath_token_kind::end_function)
|
|
2615
|
+
{
|
|
2616
|
+
}
|
|
2617
|
+
|
|
2618
|
+
token(separator_arg_t) noexcept
|
|
2619
|
+
: token_kind_(jsonpath_token_kind::separator)
|
|
2620
|
+
{
|
|
2621
|
+
}
|
|
2622
|
+
|
|
2623
|
+
token(lparen_arg_t) noexcept
|
|
2624
|
+
: token_kind_(jsonpath_token_kind::lparen)
|
|
2625
|
+
{
|
|
2626
|
+
}
|
|
2627
|
+
|
|
2628
|
+
token(rparen_arg_t) noexcept
|
|
2629
|
+
: token_kind_(jsonpath_token_kind::rparen)
|
|
2630
|
+
{
|
|
2631
|
+
}
|
|
2632
|
+
|
|
2633
|
+
token(begin_union_arg_t) noexcept
|
|
2634
|
+
: token_kind_(jsonpath_token_kind::begin_union)
|
|
2635
|
+
{
|
|
2636
|
+
}
|
|
2637
|
+
|
|
2638
|
+
token(end_union_arg_t) noexcept
|
|
2639
|
+
: token_kind_(jsonpath_token_kind::end_union)
|
|
2640
|
+
{
|
|
2641
|
+
}
|
|
2642
|
+
|
|
2643
|
+
token(begin_filter_arg_t) noexcept
|
|
2644
|
+
: token_kind_(jsonpath_token_kind::begin_filter)
|
|
2645
|
+
{
|
|
2646
|
+
}
|
|
2647
|
+
|
|
2648
|
+
token(end_filter_arg_t) noexcept
|
|
2649
|
+
: token_kind_(jsonpath_token_kind::end_filter)
|
|
2650
|
+
{
|
|
2651
|
+
}
|
|
2652
|
+
|
|
2653
|
+
token(begin_expression_arg_t) noexcept
|
|
2654
|
+
: token_kind_(jsonpath_token_kind::begin_expression)
|
|
2655
|
+
{
|
|
2656
|
+
}
|
|
2657
|
+
|
|
2658
|
+
token(end_index_expression_arg_t) noexcept
|
|
2659
|
+
: token_kind_(jsonpath_token_kind::end_index_expression)
|
|
2660
|
+
{
|
|
2661
|
+
}
|
|
2662
|
+
|
|
2663
|
+
token(end_argument_expression_arg_t) noexcept
|
|
2664
|
+
: token_kind_(jsonpath_token_kind::end_argument_expression)
|
|
2665
|
+
{
|
|
2666
|
+
}
|
|
2667
|
+
|
|
2668
|
+
token(selector_type* selector)
|
|
2669
|
+
: token_kind_(jsonpath_token_kind::selector), selector_(selector)
|
|
2670
|
+
{
|
|
2671
|
+
}
|
|
2672
|
+
|
|
2673
|
+
token(std::unique_ptr<expression_base_type>&& expr)
|
|
2674
|
+
: token_kind_(jsonpath_token_kind::expression)
|
|
2675
|
+
{
|
|
2676
|
+
new (&expression_) std::unique_ptr<expression_base_type>(std::move(expr));
|
|
2677
|
+
}
|
|
2678
|
+
|
|
2679
|
+
token(const function_base<Json>* function) noexcept
|
|
2680
|
+
: token_kind_(jsonpath_token_kind::function),
|
|
2681
|
+
function_(function)
|
|
2682
|
+
{
|
|
2683
|
+
}
|
|
2684
|
+
|
|
2685
|
+
token(argument_arg_t) noexcept
|
|
2686
|
+
: token_kind_(jsonpath_token_kind::argument)
|
|
2687
|
+
{
|
|
2688
|
+
}
|
|
2689
|
+
|
|
2690
|
+
token(literal_arg_t, Json&& value) noexcept
|
|
2691
|
+
: token_kind_(jsonpath_token_kind::literal), value_(std::move(value))
|
|
2692
|
+
{
|
|
2693
|
+
}
|
|
2694
|
+
|
|
2695
|
+
token(token&& other) noexcept
|
|
2696
|
+
{
|
|
2697
|
+
construct(std::forward<token>(other));
|
|
2698
|
+
}
|
|
2699
|
+
|
|
2700
|
+
const Json& get_value(const_reference_arg_t, dynamic_resources<Json,JsonReference>&) const
|
|
2701
|
+
{
|
|
2702
|
+
return value_;
|
|
2703
|
+
}
|
|
2704
|
+
|
|
2705
|
+
Json& get_value(reference_arg_t, dynamic_resources<Json,JsonReference>& resources) const
|
|
2706
|
+
{
|
|
2707
|
+
return *resources.create_json(value_);
|
|
2708
|
+
}
|
|
2709
|
+
|
|
2710
|
+
token& operator=(token&& other)
|
|
2711
|
+
{
|
|
2712
|
+
if (&other != this)
|
|
2713
|
+
{
|
|
2714
|
+
if (token_kind_ == other.token_kind_)
|
|
2715
|
+
{
|
|
2716
|
+
switch (token_kind_)
|
|
2717
|
+
{
|
|
2718
|
+
case jsonpath_token_kind::selector:
|
|
2719
|
+
selector_ = other.selector_;
|
|
2720
|
+
break;
|
|
2721
|
+
case jsonpath_token_kind::expression:
|
|
2722
|
+
expression_ = std::move(other.expression_);
|
|
2723
|
+
break;
|
|
2724
|
+
case jsonpath_token_kind::unary_operator:
|
|
2725
|
+
unary_operator_ = other.unary_operator_;
|
|
2726
|
+
break;
|
|
2727
|
+
case jsonpath_token_kind::binary_operator:
|
|
2728
|
+
binary_operator_ = other.binary_operator_;
|
|
2729
|
+
break;
|
|
2730
|
+
case jsonpath_token_kind::function:
|
|
2731
|
+
function_ = other.function_;
|
|
2732
|
+
break;
|
|
2733
|
+
case jsonpath_token_kind::literal:
|
|
2734
|
+
value_ = std::move(other.value_);
|
|
2735
|
+
break;
|
|
2736
|
+
default:
|
|
2737
|
+
break;
|
|
2738
|
+
}
|
|
2739
|
+
}
|
|
2740
|
+
else
|
|
2741
|
+
{
|
|
2742
|
+
destroy();
|
|
2743
|
+
construct(std::forward<token>(other));
|
|
2744
|
+
}
|
|
2745
|
+
}
|
|
2746
|
+
return *this;
|
|
2747
|
+
}
|
|
2748
|
+
|
|
2749
|
+
~token() noexcept
|
|
2750
|
+
{
|
|
2751
|
+
destroy();
|
|
2752
|
+
}
|
|
2753
|
+
|
|
2754
|
+
jsonpath_token_kind token_kind() const
|
|
2755
|
+
{
|
|
2756
|
+
return token_kind_;
|
|
2757
|
+
}
|
|
2758
|
+
|
|
2759
|
+
bool is_lparen() const
|
|
2760
|
+
{
|
|
2761
|
+
return token_kind_ == jsonpath_token_kind::lparen;
|
|
2762
|
+
}
|
|
2763
|
+
|
|
2764
|
+
bool is_rparen() const
|
|
2765
|
+
{
|
|
2766
|
+
return token_kind_ == jsonpath_token_kind::rparen;
|
|
2767
|
+
}
|
|
2768
|
+
|
|
2769
|
+
bool is_current_node() const
|
|
2770
|
+
{
|
|
2771
|
+
return token_kind_ == jsonpath_token_kind::current_node;
|
|
2772
|
+
}
|
|
2773
|
+
|
|
2774
|
+
bool is_path() const
|
|
2775
|
+
{
|
|
2776
|
+
return token_kind_ == jsonpath_token_kind::selector && selector_->is_path();
|
|
2777
|
+
}
|
|
2778
|
+
|
|
2779
|
+
bool is_operator() const
|
|
2780
|
+
{
|
|
2781
|
+
return token_kind_ == jsonpath_token_kind::unary_operator ||
|
|
2782
|
+
token_kind_ == jsonpath_token_kind::binary_operator;
|
|
2783
|
+
}
|
|
2784
|
+
|
|
2785
|
+
std::size_t precedence_level() const
|
|
2786
|
+
{
|
|
2787
|
+
switch(token_kind_)
|
|
2788
|
+
{
|
|
2789
|
+
case jsonpath_token_kind::selector:
|
|
2790
|
+
return selector_->precedence_level();
|
|
2791
|
+
case jsonpath_token_kind::unary_operator:
|
|
2792
|
+
return unary_operator_->precedence_level();
|
|
2793
|
+
case jsonpath_token_kind::binary_operator:
|
|
2794
|
+
return binary_operator_->precedence_level();
|
|
2795
|
+
default:
|
|
2796
|
+
return 0;
|
|
2797
|
+
}
|
|
2798
|
+
}
|
|
2799
|
+
|
|
2800
|
+
jsoncons::optional<std::size_t> arity() const
|
|
2801
|
+
{
|
|
2802
|
+
return token_kind_ == jsonpath_token_kind::function ? function_->arity() : jsoncons::optional<std::size_t>();
|
|
2803
|
+
}
|
|
2804
|
+
|
|
2805
|
+
bool is_right_associative() const
|
|
2806
|
+
{
|
|
2807
|
+
switch(token_kind_)
|
|
2808
|
+
{
|
|
2809
|
+
case jsonpath_token_kind::selector:
|
|
2810
|
+
return selector_->is_right_associative();
|
|
2811
|
+
case jsonpath_token_kind::unary_operator:
|
|
2812
|
+
return unary_operator_->is_right_associative();
|
|
2813
|
+
case jsonpath_token_kind::binary_operator:
|
|
2814
|
+
return binary_operator_->is_right_associative();
|
|
2815
|
+
default:
|
|
2816
|
+
return false;
|
|
2817
|
+
}
|
|
2818
|
+
}
|
|
2819
|
+
|
|
2820
|
+
void construct(token&& other)
|
|
2821
|
+
{
|
|
2822
|
+
token_kind_ = other.token_kind_;
|
|
2823
|
+
switch (token_kind_)
|
|
2824
|
+
{
|
|
2825
|
+
case jsonpath_token_kind::selector:
|
|
2826
|
+
selector_ = other.selector_;
|
|
2827
|
+
break;
|
|
2828
|
+
case jsonpath_token_kind::expression:
|
|
2829
|
+
new (&expression_) std::unique_ptr<expression_base_type>(std::move(other.expression_));
|
|
2830
|
+
break;
|
|
2831
|
+
case jsonpath_token_kind::unary_operator:
|
|
2832
|
+
unary_operator_ = other.unary_operator_;
|
|
2833
|
+
break;
|
|
2834
|
+
case jsonpath_token_kind::binary_operator:
|
|
2835
|
+
binary_operator_ = other.binary_operator_;
|
|
2836
|
+
break;
|
|
2837
|
+
case jsonpath_token_kind::function:
|
|
2838
|
+
function_ = other.function_;
|
|
2839
|
+
break;
|
|
2840
|
+
case jsonpath_token_kind::literal:
|
|
2841
|
+
new (&value_) Json(std::move(other.value_));
|
|
2842
|
+
break;
|
|
2843
|
+
default:
|
|
2844
|
+
break;
|
|
2845
|
+
}
|
|
2846
|
+
}
|
|
2847
|
+
|
|
2848
|
+
void destroy() noexcept
|
|
2849
|
+
{
|
|
2850
|
+
switch(token_kind_)
|
|
2851
|
+
{
|
|
2852
|
+
case jsonpath_token_kind::expression:
|
|
2853
|
+
expression_.~unique_ptr();
|
|
2854
|
+
break;
|
|
2855
|
+
case jsonpath_token_kind::literal:
|
|
2856
|
+
value_.~Json();
|
|
2857
|
+
break;
|
|
2858
|
+
default:
|
|
2859
|
+
break;
|
|
2860
|
+
}
|
|
2861
|
+
}
|
|
2862
|
+
|
|
2863
|
+
std::string to_string(int level = 0) const
|
|
2864
|
+
{
|
|
2865
|
+
std::string s;
|
|
2866
|
+
switch (token_kind_)
|
|
2867
|
+
{
|
|
2868
|
+
case jsonpath_token_kind::root_node:
|
|
2869
|
+
if (level > 0)
|
|
2870
|
+
{
|
|
2871
|
+
s.append("\n");
|
|
2872
|
+
s.append(level*2, ' ');
|
|
2873
|
+
}
|
|
2874
|
+
s.append("root node");
|
|
2875
|
+
break;
|
|
2876
|
+
case jsonpath_token_kind::current_node:
|
|
2877
|
+
if (level > 0)
|
|
2878
|
+
{
|
|
2879
|
+
s.append("\n");
|
|
2880
|
+
s.append(level*2, ' ');
|
|
2881
|
+
}
|
|
2882
|
+
s.append("current node");
|
|
2883
|
+
break;
|
|
2884
|
+
case jsonpath_token_kind::argument:
|
|
2885
|
+
if (level > 0)
|
|
2886
|
+
{
|
|
2887
|
+
s.append("\n");
|
|
2888
|
+
s.append(level*2, ' ');
|
|
2889
|
+
}
|
|
2890
|
+
s.append("argument");
|
|
2891
|
+
break;
|
|
2892
|
+
case jsonpath_token_kind::selector:
|
|
2893
|
+
s.append(selector_->to_string(level));
|
|
2894
|
+
break;
|
|
2895
|
+
case jsonpath_token_kind::expression:
|
|
2896
|
+
s.append(expression_->to_string(level));
|
|
2897
|
+
break;
|
|
2898
|
+
case jsonpath_token_kind::literal:
|
|
2899
|
+
{
|
|
2900
|
+
if (level > 0)
|
|
2901
|
+
{
|
|
2902
|
+
s.append("\n");
|
|
2903
|
+
s.append(level*2, ' ');
|
|
2904
|
+
}
|
|
2905
|
+
auto sbuf = value_.to_string();
|
|
2906
|
+
unicode_traits::convert(sbuf.data(), sbuf.size(), s);
|
|
2907
|
+
break;
|
|
2908
|
+
}
|
|
2909
|
+
case jsonpath_token_kind::binary_operator:
|
|
2910
|
+
s.append(binary_operator_->to_string(level));
|
|
2911
|
+
break;
|
|
2912
|
+
case jsonpath_token_kind::function:
|
|
2913
|
+
s.append(function_->to_string(level));
|
|
2914
|
+
break;
|
|
2915
|
+
default:
|
|
2916
|
+
if (level > 0)
|
|
2917
|
+
{
|
|
2918
|
+
s.append("\n");
|
|
2919
|
+
s.append(level*2, ' ');
|
|
2920
|
+
}
|
|
2921
|
+
s.append("token kind: ");
|
|
2922
|
+
s.append(jsoncons::jsonpath::detail::to_string(token_kind_));
|
|
2923
|
+
break;
|
|
2924
|
+
}
|
|
2925
|
+
//s.append("\n");
|
|
2926
|
+
return s;
|
|
2927
|
+
}
|
|
2928
|
+
};
|
|
2929
|
+
|
|
2930
|
+
template <class Callback, class Json,class JsonReference>
|
|
2931
|
+
class callback_receiver : public node_receiver<Json,JsonReference>
|
|
2932
|
+
{
|
|
2933
|
+
Callback& callback_;
|
|
2934
|
+
public:
|
|
2935
|
+
using reference = JsonReference;
|
|
2936
|
+
using char_type = typename Json::char_type;
|
|
2937
|
+
using json_location_node_type = json_location_node<char_type>;
|
|
2938
|
+
using json_location_type = json_location<char_type>;
|
|
2939
|
+
|
|
2940
|
+
callback_receiver(Callback& callback)
|
|
2941
|
+
: callback_(callback)
|
|
2942
|
+
{
|
|
2943
|
+
}
|
|
2944
|
+
|
|
2945
|
+
void add(const json_location_node_type& path_tail,
|
|
2946
|
+
reference value) override
|
|
2947
|
+
{
|
|
2948
|
+
callback_(json_location_type(path_tail), value);
|
|
2949
|
+
}
|
|
2950
|
+
};
|
|
2951
|
+
|
|
2952
|
+
template <class Json,class JsonReference>
|
|
2953
|
+
class path_expression
|
|
2954
|
+
{
|
|
2955
|
+
public:
|
|
2956
|
+
using char_type = typename Json::char_type;
|
|
2957
|
+
using string_type = std::basic_string<char_type,std::char_traits<char_type>>;
|
|
2958
|
+
using string_view_type = typename Json::string_view_type;
|
|
2959
|
+
using path_value_pair_type = path_value_pair<Json,JsonReference>;
|
|
2960
|
+
using path_value_pair_less_type = path_value_pair_less<Json,JsonReference>;
|
|
2961
|
+
using path_value_pair_equal_type = path_value_pair_equal<Json,JsonReference>;
|
|
2962
|
+
using value_type = Json;
|
|
2963
|
+
using reference = typename path_value_pair_type::reference;
|
|
2964
|
+
using pointer = typename path_value_pair_type::value_pointer;
|
|
2965
|
+
using token_type = token<Json,JsonReference>;
|
|
2966
|
+
using reference_arg_type = typename std::conditional<std::is_const<typename std::remove_reference<JsonReference>::type>::value,
|
|
2967
|
+
const_reference_arg_t,reference_arg_t>::type;
|
|
2968
|
+
using json_location_node_type = json_location_node<char_type>;
|
|
2969
|
+
using json_location_type = json_location<char_type>;
|
|
2970
|
+
using selector_type = jsonpath_selector<Json,JsonReference>;
|
|
2971
|
+
private:
|
|
2972
|
+
selector_type* selector_;
|
|
2973
|
+
result_options required_options_;
|
|
2974
|
+
public:
|
|
2975
|
+
|
|
2976
|
+
path_expression()
|
|
2977
|
+
: required_options_()
|
|
2978
|
+
{
|
|
2979
|
+
}
|
|
2980
|
+
|
|
2981
|
+
path_expression(path_expression&& expr) = default;
|
|
2982
|
+
|
|
2983
|
+
path_expression(selector_type* selector, bool paths_required)
|
|
2984
|
+
: selector_(selector), required_options_()
|
|
2985
|
+
{
|
|
2986
|
+
if (paths_required)
|
|
2987
|
+
{
|
|
2988
|
+
required_options_ |= result_options::path;
|
|
2989
|
+
}
|
|
2990
|
+
}
|
|
2991
|
+
|
|
2992
|
+
path_expression& operator=(path_expression&& expr) = default;
|
|
2993
|
+
|
|
2994
|
+
Json evaluate(dynamic_resources<Json,JsonReference>& resources,
|
|
2995
|
+
reference root,
|
|
2996
|
+
const json_location_node_type& path,
|
|
2997
|
+
reference instance,
|
|
2998
|
+
result_options options) const
|
|
2999
|
+
{
|
|
3000
|
+
Json result(json_array_arg);
|
|
3001
|
+
|
|
3002
|
+
if ((options & result_options::path) == result_options::path)
|
|
3003
|
+
{
|
|
3004
|
+
auto callback = [&result](const json_location_type& path, reference)
|
|
3005
|
+
{
|
|
3006
|
+
result.emplace_back(path.to_string());
|
|
3007
|
+
};
|
|
3008
|
+
evaluate(resources, root, path, instance, callback, options);
|
|
3009
|
+
}
|
|
3010
|
+
else
|
|
3011
|
+
{
|
|
3012
|
+
auto callback = [&result](const json_location_type&, reference val)
|
|
3013
|
+
{
|
|
3014
|
+
result.push_back(val);
|
|
3015
|
+
};
|
|
3016
|
+
evaluate(resources, root, path, instance, callback, options);
|
|
3017
|
+
}
|
|
3018
|
+
|
|
3019
|
+
return result;
|
|
3020
|
+
}
|
|
3021
|
+
|
|
3022
|
+
template <class Callback>
|
|
3023
|
+
typename std::enable_if<traits_extension::is_binary_function_object<Callback,const json_location_type&,reference>::value,void>::type
|
|
3024
|
+
evaluate(dynamic_resources<Json,JsonReference>& resources,
|
|
3025
|
+
reference root,
|
|
3026
|
+
const json_location_node_type& path,
|
|
3027
|
+
reference current,
|
|
3028
|
+
Callback callback,
|
|
3029
|
+
result_options options) const
|
|
3030
|
+
{
|
|
3031
|
+
std::error_code ec;
|
|
3032
|
+
|
|
3033
|
+
options |= required_options_;
|
|
3034
|
+
|
|
3035
|
+
const result_options require_more = result_options::nodups | result_options::sort;
|
|
3036
|
+
|
|
3037
|
+
if ((options & require_more) != result_options())
|
|
3038
|
+
{
|
|
3039
|
+
path_value_receiver<Json,JsonReference> receiver;
|
|
3040
|
+
selector_->select(resources, root, path, current, receiver, options);
|
|
3041
|
+
|
|
3042
|
+
if (receiver.nodes.size() > 1 && (options & result_options::sort) == result_options::sort)
|
|
3043
|
+
{
|
|
3044
|
+
std::sort(receiver.nodes.begin(), receiver.nodes.end(), path_value_pair_less_type());
|
|
3045
|
+
}
|
|
3046
|
+
|
|
3047
|
+
if (receiver.nodes.size() > 1 && (options & result_options::nodups) == result_options::nodups)
|
|
3048
|
+
{
|
|
3049
|
+
if ((options & result_options::sort) == result_options::sort)
|
|
3050
|
+
{
|
|
3051
|
+
auto last = std::unique(receiver.nodes.begin(),receiver.nodes.end(),path_value_pair_equal_type());
|
|
3052
|
+
receiver.nodes.erase(last,receiver.nodes.end());
|
|
3053
|
+
for (auto& node : receiver.nodes)
|
|
3054
|
+
{
|
|
3055
|
+
callback(node.path(), node.value());
|
|
3056
|
+
}
|
|
3057
|
+
}
|
|
3058
|
+
else
|
|
3059
|
+
{
|
|
3060
|
+
std::vector<path_value_pair_type> index(receiver.nodes);
|
|
3061
|
+
std::sort(index.begin(), index.end(), path_value_pair_less_type());
|
|
3062
|
+
auto last = std::unique(index.begin(),index.end(),path_value_pair_equal_type());
|
|
3063
|
+
index.erase(last,index.end());
|
|
3064
|
+
|
|
3065
|
+
std::vector<path_value_pair_type> temp2;
|
|
3066
|
+
temp2.reserve(index.size());
|
|
3067
|
+
for (auto&& node : receiver.nodes)
|
|
3068
|
+
{
|
|
3069
|
+
auto it = std::lower_bound(index.begin(),index.end(),node, path_value_pair_less_type());
|
|
3070
|
+
if (it != index.end() && it->path() == node.path())
|
|
3071
|
+
{
|
|
3072
|
+
temp2.emplace_back(std::move(node));
|
|
3073
|
+
index.erase(it);
|
|
3074
|
+
}
|
|
3075
|
+
}
|
|
3076
|
+
for (auto& node : temp2)
|
|
3077
|
+
{
|
|
3078
|
+
callback(node.path(), node.value());
|
|
3079
|
+
}
|
|
3080
|
+
}
|
|
3081
|
+
}
|
|
3082
|
+
else
|
|
3083
|
+
{
|
|
3084
|
+
for (auto& node : receiver.nodes)
|
|
3085
|
+
{
|
|
3086
|
+
callback(node.path(), node.value());
|
|
3087
|
+
}
|
|
3088
|
+
}
|
|
3089
|
+
}
|
|
3090
|
+
else
|
|
3091
|
+
{
|
|
3092
|
+
callback_receiver<Callback,Json,JsonReference> receiver(callback);
|
|
3093
|
+
selector_->select(resources, root, path, current, receiver, options);
|
|
3094
|
+
}
|
|
3095
|
+
}
|
|
3096
|
+
|
|
3097
|
+
std::string to_string(int level) const
|
|
3098
|
+
{
|
|
3099
|
+
std::string s;
|
|
3100
|
+
if (level > 0)
|
|
3101
|
+
{
|
|
3102
|
+
s.append("\n");
|
|
3103
|
+
s.append(level*2, ' ');
|
|
3104
|
+
}
|
|
3105
|
+
s.append("expression ");
|
|
3106
|
+
s.append(selector_->to_string(level+1));
|
|
3107
|
+
|
|
3108
|
+
return s;
|
|
3109
|
+
|
|
3110
|
+
}
|
|
3111
|
+
};
|
|
3112
|
+
|
|
3113
|
+
template <class Json,class JsonReference>
|
|
3114
|
+
class expression : public expression_base<Json,JsonReference>
|
|
3115
|
+
{
|
|
3116
|
+
public:
|
|
3117
|
+
using path_value_pair_type = path_value_pair<Json,JsonReference>;
|
|
3118
|
+
using value_type = Json;
|
|
3119
|
+
using reference = typename path_value_pair_type::reference;
|
|
3120
|
+
using pointer = typename path_value_pair_type::value_pointer;
|
|
3121
|
+
using const_pointer = const value_type*;
|
|
3122
|
+
using char_type = typename Json::char_type;
|
|
3123
|
+
using string_type = std::basic_string<char_type,std::char_traits<char_type>>;
|
|
3124
|
+
using string_view_type = typename Json::string_view_type;
|
|
3125
|
+
using path_value_pair_less_type = path_value_pair_less<Json,reference>;
|
|
3126
|
+
using path_value_pair_equal_type = path_value_pair_equal<Json,reference>;
|
|
3127
|
+
using parameter_type = parameter<Json>;
|
|
3128
|
+
using token_type = token<Json,reference>;
|
|
3129
|
+
using reference_arg_type = typename std::conditional<std::is_const<typename std::remove_reference<reference>::type>::value,
|
|
3130
|
+
const_reference_arg_t,reference_arg_t>::type;
|
|
3131
|
+
using json_location_node_type = json_location_node<char_type>;
|
|
3132
|
+
using stack_item_type = value_or_pointer<Json,JsonReference>;
|
|
3133
|
+
private:
|
|
3134
|
+
std::vector<token_type> token_list_;
|
|
3135
|
+
public:
|
|
3136
|
+
|
|
3137
|
+
expression()
|
|
3138
|
+
{
|
|
3139
|
+
}
|
|
3140
|
+
|
|
3141
|
+
expression(expression&& expr)
|
|
3142
|
+
: token_list_(std::move(expr.token_list_))
|
|
3143
|
+
{
|
|
3144
|
+
}
|
|
3145
|
+
|
|
3146
|
+
expression(std::vector<token_type>&& token_stack)
|
|
3147
|
+
: token_list_(std::move(token_stack))
|
|
3148
|
+
{
|
|
3149
|
+
}
|
|
3150
|
+
|
|
3151
|
+
expression& operator=(expression&& expr) = default;
|
|
3152
|
+
|
|
3153
|
+
value_type evaluate(dynamic_resources<Json,reference>& resources,
|
|
3154
|
+
reference root,
|
|
3155
|
+
reference current,
|
|
3156
|
+
result_options options,
|
|
3157
|
+
std::error_code& ec) const override
|
|
3158
|
+
{
|
|
3159
|
+
std::vector<stack_item_type> stack;
|
|
3160
|
+
std::vector<parameter_type> arg_stack;
|
|
3161
|
+
|
|
3162
|
+
//std::cout << "EVALUATE TOKENS\n";
|
|
3163
|
+
//for (auto& tok : token_list_)
|
|
3164
|
+
//{
|
|
3165
|
+
// std::cout << tok.to_string() << "\n";
|
|
3166
|
+
//}
|
|
3167
|
+
//std::cout << "\n";
|
|
3168
|
+
|
|
3169
|
+
if (!token_list_.empty())
|
|
3170
|
+
{
|
|
3171
|
+
for (auto& tok : token_list_)
|
|
3172
|
+
{
|
|
3173
|
+
//std::cout << "Token: " << tok.to_string() << "\n";
|
|
3174
|
+
switch (tok.token_kind())
|
|
3175
|
+
{
|
|
3176
|
+
case jsonpath_token_kind::literal:
|
|
3177
|
+
{
|
|
3178
|
+
stack.emplace_back(std::addressof(tok.get_value(reference_arg_type(), resources)));
|
|
3179
|
+
break;
|
|
3180
|
+
}
|
|
3181
|
+
case jsonpath_token_kind::unary_operator:
|
|
3182
|
+
{
|
|
3183
|
+
JSONCONS_ASSERT(stack.size() >= 1);
|
|
3184
|
+
auto item = std::move(stack.back());
|
|
3185
|
+
stack.pop_back();
|
|
3186
|
+
|
|
3187
|
+
auto val = tok.unary_operator_->evaluate(item.value(), ec);
|
|
3188
|
+
stack.emplace_back(std::move(val));
|
|
3189
|
+
break;
|
|
3190
|
+
}
|
|
3191
|
+
case jsonpath_token_kind::binary_operator:
|
|
3192
|
+
{
|
|
3193
|
+
//std::cout << "binary operator: " << stack.size() << "\n";
|
|
3194
|
+
JSONCONS_ASSERT(stack.size() >= 2);
|
|
3195
|
+
auto rhs = std::move(stack.back());
|
|
3196
|
+
//std::cout << "rhs: " << *rhs << "\n";
|
|
3197
|
+
stack.pop_back();
|
|
3198
|
+
auto lhs = std::move(stack.back());
|
|
3199
|
+
//std::cout << "lhs: " << *lhs << "\n";
|
|
3200
|
+
stack.pop_back();
|
|
3201
|
+
|
|
3202
|
+
auto val = tok.binary_operator_->evaluate(lhs.value(), rhs.value(), ec);
|
|
3203
|
+
//std::cout << "Evaluate binary expression: " << r << "\n";
|
|
3204
|
+
stack.emplace_back(std::move(val));
|
|
3205
|
+
break;
|
|
3206
|
+
}
|
|
3207
|
+
case jsonpath_token_kind::root_node:
|
|
3208
|
+
//std::cout << "root: " << root << "\n";
|
|
3209
|
+
stack.emplace_back(std::addressof(root));
|
|
3210
|
+
break;
|
|
3211
|
+
case jsonpath_token_kind::current_node:
|
|
3212
|
+
//std::cout << "current: " << current << "\n";
|
|
3213
|
+
stack.emplace_back(std::addressof(current));
|
|
3214
|
+
break;
|
|
3215
|
+
case jsonpath_token_kind::argument:
|
|
3216
|
+
JSONCONS_ASSERT(!stack.empty());
|
|
3217
|
+
//std::cout << "argument stack items " << stack.size() << "\n";
|
|
3218
|
+
//for (auto& item : stack)
|
|
3219
|
+
//{
|
|
3220
|
+
// std::cout << *item.to_pointer(resources) << "\n";
|
|
3221
|
+
//}
|
|
3222
|
+
//std::cout << "\n";
|
|
3223
|
+
arg_stack.emplace_back(std::move(stack.back()));
|
|
3224
|
+
//for (auto& item : arg_stack)
|
|
3225
|
+
//{
|
|
3226
|
+
// std::cout << *item << "\n";
|
|
3227
|
+
//}
|
|
3228
|
+
//std::cout << "\n";
|
|
3229
|
+
stack.pop_back();
|
|
3230
|
+
break;
|
|
3231
|
+
case jsonpath_token_kind::function:
|
|
3232
|
+
{
|
|
3233
|
+
if (tok.function_->arity() && *(tok.function_->arity()) != arg_stack.size())
|
|
3234
|
+
{
|
|
3235
|
+
ec = jsonpath_errc::invalid_arity;
|
|
3236
|
+
return Json::null();
|
|
3237
|
+
}
|
|
3238
|
+
//std::cout << "function arg stack:\n";
|
|
3239
|
+
//for (auto& item : arg_stack)
|
|
3240
|
+
//{
|
|
3241
|
+
// std::cout << *item << "\n";
|
|
3242
|
+
//}
|
|
3243
|
+
//std::cout << "\n";
|
|
3244
|
+
|
|
3245
|
+
value_type val = tok.function_->evaluate(arg_stack, ec);
|
|
3246
|
+
if (ec)
|
|
3247
|
+
{
|
|
3248
|
+
return Json::null();
|
|
3249
|
+
}
|
|
3250
|
+
//std::cout << "function result: " << val << "\n";
|
|
3251
|
+
arg_stack.clear();
|
|
3252
|
+
stack.emplace_back(std::move(val));
|
|
3253
|
+
break;
|
|
3254
|
+
}
|
|
3255
|
+
case jsonpath_token_kind::expression:
|
|
3256
|
+
{
|
|
3257
|
+
value_type val = tok.expression_->evaluate(resources, root, current, options, ec);
|
|
3258
|
+
stack.emplace_back(std::move(val));
|
|
3259
|
+
break;
|
|
3260
|
+
}
|
|
3261
|
+
case jsonpath_token_kind::selector:
|
|
3262
|
+
{
|
|
3263
|
+
JSONCONS_ASSERT(!stack.empty());
|
|
3264
|
+
auto item = std::move(stack.back());
|
|
3265
|
+
//for (auto& item : stack)
|
|
3266
|
+
//{
|
|
3267
|
+
//std::cout << "selector stack input:\n";
|
|
3268
|
+
//switch (item.tag)
|
|
3269
|
+
//{
|
|
3270
|
+
// case node_set_tag::single:
|
|
3271
|
+
// std::cout << "single: " << *(item.node.ptr) << "\n";
|
|
3272
|
+
// break;
|
|
3273
|
+
// case node_set_tag::multi:
|
|
3274
|
+
// for (auto& node : stack.back().ptr().nodes)
|
|
3275
|
+
// {
|
|
3276
|
+
// std::cout << "multi: " << *node.ptr << "\n";
|
|
3277
|
+
// }
|
|
3278
|
+
// break;
|
|
3279
|
+
// default:
|
|
3280
|
+
// break;
|
|
3281
|
+
//}
|
|
3282
|
+
//std::cout << "\n";
|
|
3283
|
+
//}
|
|
3284
|
+
//std::cout << "selector item: " << *ptr << "\n";
|
|
3285
|
+
|
|
3286
|
+
reference val = tok.selector_->evaluate(resources, root, resources.current_path_node(), item.value(), options, ec);
|
|
3287
|
+
|
|
3288
|
+
stack.pop_back();
|
|
3289
|
+
stack.emplace_back(stack_item_type(std::addressof(val)));
|
|
3290
|
+
break;
|
|
3291
|
+
}
|
|
3292
|
+
default:
|
|
3293
|
+
break;
|
|
3294
|
+
}
|
|
3295
|
+
}
|
|
3296
|
+
}
|
|
3297
|
+
|
|
3298
|
+
//if (stack.size() != 1)
|
|
3299
|
+
//{
|
|
3300
|
+
// std::cout << "Stack size: " << stack.size() << "\n";
|
|
3301
|
+
//}
|
|
3302
|
+
return stack.empty() ? Json::null() : stack.back().value();
|
|
3303
|
+
}
|
|
3304
|
+
|
|
3305
|
+
std::string to_string(int level) const override
|
|
3306
|
+
{
|
|
3307
|
+
std::string s;
|
|
3308
|
+
if (level > 0)
|
|
3309
|
+
{
|
|
3310
|
+
s.append("\n");
|
|
3311
|
+
s.append(level*2, ' ');
|
|
3312
|
+
}
|
|
3313
|
+
s.append("expression ");
|
|
3314
|
+
for (const auto& item : token_list_)
|
|
3315
|
+
{
|
|
3316
|
+
s.append(item.to_string(level+1));
|
|
3317
|
+
}
|
|
3318
|
+
|
|
3319
|
+
return s;
|
|
3320
|
+
|
|
3321
|
+
}
|
|
3322
|
+
private:
|
|
3323
|
+
};
|
|
3324
|
+
|
|
3325
|
+
} // namespace detail
|
|
3326
|
+
} // namespace jsonpath
|
|
3327
|
+
} // namespace jsoncons
|
|
3328
|
+
|
|
3329
|
+
#endif // JSONCONS_JSONPATH_JSONPATH_EXPRESSION_HPP
|