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,579 @@
|
|
|
1
|
+
// Copyright 2017 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_JSONPATCH_JSONPATCH_HPP
|
|
8
|
+
#define JSONCONS_JSONPATCH_JSONPATCH_HPP
|
|
9
|
+
|
|
10
|
+
#include <string>
|
|
11
|
+
#include <vector>
|
|
12
|
+
#include <memory>
|
|
13
|
+
#include <algorithm> // std::min
|
|
14
|
+
#include <utility> // std::move
|
|
15
|
+
#include <jsoncons/json.hpp>
|
|
16
|
+
#include <jsoncons_ext/jsonpointer/jsonpointer.hpp>
|
|
17
|
+
#include <jsoncons_ext/jsonpatch/jsonpatch_error.hpp>
|
|
18
|
+
|
|
19
|
+
namespace jsoncons { namespace jsonpatch {
|
|
20
|
+
|
|
21
|
+
namespace detail {
|
|
22
|
+
|
|
23
|
+
template <class CharT>
|
|
24
|
+
struct jsonpatch_names
|
|
25
|
+
{
|
|
26
|
+
static std::basic_string<CharT> test_name()
|
|
27
|
+
{
|
|
28
|
+
static std::basic_string<CharT> name{'t','e','s','t'};
|
|
29
|
+
return name;
|
|
30
|
+
}
|
|
31
|
+
static std::basic_string<CharT> add_name()
|
|
32
|
+
{
|
|
33
|
+
static std::basic_string<CharT> name{'a','d','d'};
|
|
34
|
+
return name;
|
|
35
|
+
}
|
|
36
|
+
static std::basic_string<CharT> remove_name()
|
|
37
|
+
{
|
|
38
|
+
static std::basic_string<CharT> name{'r','e','m','o','v','e'};
|
|
39
|
+
return name;
|
|
40
|
+
}
|
|
41
|
+
static std::basic_string<CharT> replace_name()
|
|
42
|
+
{
|
|
43
|
+
static std::basic_string<CharT> name{'r','e','p','l','a','c','e'};
|
|
44
|
+
return name;
|
|
45
|
+
}
|
|
46
|
+
static std::basic_string<CharT> move_name()
|
|
47
|
+
{
|
|
48
|
+
static std::basic_string<CharT> name{'m','o','v','e'};
|
|
49
|
+
return name;
|
|
50
|
+
}
|
|
51
|
+
static std::basic_string<CharT> copy_name()
|
|
52
|
+
{
|
|
53
|
+
static std::basic_string<CharT> name{'c','o','p','y'};
|
|
54
|
+
return name;
|
|
55
|
+
}
|
|
56
|
+
static std::basic_string<CharT> op_name()
|
|
57
|
+
{
|
|
58
|
+
static std::basic_string<CharT> name{'o','p'};
|
|
59
|
+
return name;
|
|
60
|
+
}
|
|
61
|
+
static std::basic_string<CharT> path_name()
|
|
62
|
+
{
|
|
63
|
+
static std::basic_string<CharT> name{'p','a','t','h'};
|
|
64
|
+
return name;
|
|
65
|
+
}
|
|
66
|
+
static std::basic_string<CharT> from_name()
|
|
67
|
+
{
|
|
68
|
+
static std::basic_string<CharT> name{'f','r','o','m'};
|
|
69
|
+
return name;
|
|
70
|
+
}
|
|
71
|
+
static std::basic_string<CharT> value_name()
|
|
72
|
+
{
|
|
73
|
+
static std::basic_string<CharT> name{'v','a','l','u','e'};
|
|
74
|
+
return name;
|
|
75
|
+
}
|
|
76
|
+
static std::basic_string<CharT> dash_name()
|
|
77
|
+
{
|
|
78
|
+
static std::basic_string<CharT> name{'-'};
|
|
79
|
+
return name;
|
|
80
|
+
}
|
|
81
|
+
};
|
|
82
|
+
|
|
83
|
+
template<class Json>
|
|
84
|
+
jsonpointer::basic_json_pointer<typename Json::char_type> definite_path(const Json& root, jsonpointer::basic_json_pointer<typename Json::char_type>& location)
|
|
85
|
+
{
|
|
86
|
+
using char_type = typename Json::char_type;
|
|
87
|
+
using string_type = std::basic_string<char_type>;
|
|
88
|
+
|
|
89
|
+
auto rit = location.rbegin();
|
|
90
|
+
if (rit == location.rend())
|
|
91
|
+
{
|
|
92
|
+
return location;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
if (*rit != jsonpatch_names<char_type>::dash_name())
|
|
96
|
+
{
|
|
97
|
+
return location;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
std::vector<string_type> tokens;
|
|
101
|
+
for (auto it = location.begin(); it != location.rbegin().base()-1; ++it)
|
|
102
|
+
{
|
|
103
|
+
tokens.push_back(*it);
|
|
104
|
+
}
|
|
105
|
+
jsonpointer::basic_json_pointer<char_type> pointer(tokens);
|
|
106
|
+
|
|
107
|
+
std::error_code ec;
|
|
108
|
+
|
|
109
|
+
Json val = jsonpointer::get(root, pointer, ec);
|
|
110
|
+
if (ec || !val.is_array())
|
|
111
|
+
{
|
|
112
|
+
return location;
|
|
113
|
+
}
|
|
114
|
+
string_type last_token;
|
|
115
|
+
jsoncons::detail::from_integer(val.size(), last_token);
|
|
116
|
+
tokens.emplace_back(std::move(last_token));
|
|
117
|
+
|
|
118
|
+
return jsonpointer::basic_json_pointer<char_type>(std::move(tokens));
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
enum class op_type {add,remove,replace};
|
|
122
|
+
enum class state_type {begin,abort,commit};
|
|
123
|
+
|
|
124
|
+
template <class Json>
|
|
125
|
+
struct operation_unwinder
|
|
126
|
+
{
|
|
127
|
+
using char_type = typename Json::char_type;
|
|
128
|
+
using string_type = std::basic_string<char_type>;
|
|
129
|
+
using json_pointer_type = jsonpointer::basic_json_pointer<char_type>;
|
|
130
|
+
|
|
131
|
+
struct entry
|
|
132
|
+
{
|
|
133
|
+
op_type op;
|
|
134
|
+
json_pointer_type path;
|
|
135
|
+
Json value;
|
|
136
|
+
|
|
137
|
+
entry(op_type op, const json_pointer_type& path, const Json& value)
|
|
138
|
+
: op(op), path(path), value(value)
|
|
139
|
+
{
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
entry(const entry&) = default;
|
|
143
|
+
|
|
144
|
+
entry(entry&&) = default;
|
|
145
|
+
|
|
146
|
+
entry& operator=(const entry&) = default;
|
|
147
|
+
|
|
148
|
+
entry& operator=(entry&&) = default;
|
|
149
|
+
};
|
|
150
|
+
|
|
151
|
+
Json& target;
|
|
152
|
+
state_type state;
|
|
153
|
+
std::vector<entry> stack;
|
|
154
|
+
|
|
155
|
+
operation_unwinder(Json& j)
|
|
156
|
+
: target(j), state(state_type::begin)
|
|
157
|
+
{
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
~operation_unwinder() noexcept
|
|
161
|
+
{
|
|
162
|
+
std::error_code ec;
|
|
163
|
+
if (state != state_type::commit)
|
|
164
|
+
{
|
|
165
|
+
for (auto it = stack.rbegin(); it != stack.rend(); ++it)
|
|
166
|
+
{
|
|
167
|
+
if (it->op == op_type::add)
|
|
168
|
+
{
|
|
169
|
+
jsonpointer::add(target,it->path,it->value,ec);
|
|
170
|
+
if (ec)
|
|
171
|
+
{
|
|
172
|
+
//std::cout << "add: " << it->path << std::endl;
|
|
173
|
+
break;
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
else if (it->op == op_type::remove)
|
|
177
|
+
{
|
|
178
|
+
jsonpointer::remove(target,it->path,ec);
|
|
179
|
+
if (ec)
|
|
180
|
+
{
|
|
181
|
+
//std::cout << "remove: " << it->path << std::endl;
|
|
182
|
+
break;
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
else if (it->op == op_type::replace)
|
|
186
|
+
{
|
|
187
|
+
jsonpointer::replace(target,it->path,it->value,ec);
|
|
188
|
+
if (ec)
|
|
189
|
+
{
|
|
190
|
+
//std::cout << "replace: " << it->path << std::endl;
|
|
191
|
+
break;
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
};
|
|
198
|
+
|
|
199
|
+
template <class Json>
|
|
200
|
+
Json from_diff(const Json& source, const Json& target, const typename Json::string_view_type& path)
|
|
201
|
+
{
|
|
202
|
+
using char_type = typename Json::char_type;
|
|
203
|
+
|
|
204
|
+
Json result = typename Json::array();
|
|
205
|
+
|
|
206
|
+
if (source == target)
|
|
207
|
+
{
|
|
208
|
+
return result;
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
if (source.is_array() && target.is_array())
|
|
212
|
+
{
|
|
213
|
+
std::size_t common = (std::min)(source.size(),target.size());
|
|
214
|
+
for (std::size_t i = 0; i < common; ++i)
|
|
215
|
+
{
|
|
216
|
+
std::basic_string<char_type> ss(path);
|
|
217
|
+
ss.push_back('/');
|
|
218
|
+
jsoncons::detail::from_integer(i,ss);
|
|
219
|
+
auto temp_diff = from_diff(source[i],target[i],ss);
|
|
220
|
+
result.insert(result.array_range().end(),temp_diff.array_range().begin(),temp_diff.array_range().end());
|
|
221
|
+
}
|
|
222
|
+
// Element in source, not in target - remove
|
|
223
|
+
for (std::size_t i = source.size(); i-- > target.size();)
|
|
224
|
+
{
|
|
225
|
+
std::basic_string<char_type> ss(path);
|
|
226
|
+
ss.push_back('/');
|
|
227
|
+
jsoncons::detail::from_integer(i,ss);
|
|
228
|
+
Json val(json_object_arg);
|
|
229
|
+
val.insert_or_assign(jsonpatch_names<char_type>::op_name(), jsonpatch_names<char_type>::remove_name());
|
|
230
|
+
val.insert_or_assign(jsonpatch_names<char_type>::path_name(), ss);
|
|
231
|
+
result.push_back(std::move(val));
|
|
232
|
+
}
|
|
233
|
+
// Element in target, not in source - add,
|
|
234
|
+
// Fix contributed by Alexander rog13
|
|
235
|
+
for (std::size_t i = source.size(); i < target.size(); ++i)
|
|
236
|
+
{
|
|
237
|
+
const auto& a = target[i];
|
|
238
|
+
std::basic_string<char_type> ss(path);
|
|
239
|
+
ss.push_back('/');
|
|
240
|
+
jsoncons::detail::from_integer(i,ss);
|
|
241
|
+
Json val(json_object_arg);
|
|
242
|
+
val.insert_or_assign(jsonpatch_names<char_type>::op_name(), jsonpatch_names<char_type>::add_name());
|
|
243
|
+
val.insert_or_assign(jsonpatch_names<char_type>::path_name(), ss);
|
|
244
|
+
val.insert_or_assign(jsonpatch_names<char_type>::value_name(), a);
|
|
245
|
+
result.push_back(std::move(val));
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
else if (source.is_object() && target.is_object())
|
|
249
|
+
{
|
|
250
|
+
for (const auto& a : source.object_range())
|
|
251
|
+
{
|
|
252
|
+
std::basic_string<char_type> ss(path);
|
|
253
|
+
ss.push_back('/');
|
|
254
|
+
jsonpointer::escape(a.key(),ss);
|
|
255
|
+
auto it = target.find(a.key());
|
|
256
|
+
if (it != target.object_range().end())
|
|
257
|
+
{
|
|
258
|
+
auto temp_diff = from_diff(a.value(),it->value(),ss);
|
|
259
|
+
result.insert(result.array_range().end(),temp_diff.array_range().begin(),temp_diff.array_range().end());
|
|
260
|
+
}
|
|
261
|
+
else
|
|
262
|
+
{
|
|
263
|
+
Json val(json_object_arg);
|
|
264
|
+
val.insert_or_assign(jsonpatch_names<char_type>::op_name(), jsonpatch_names<char_type>::remove_name());
|
|
265
|
+
val.insert_or_assign(jsonpatch_names<char_type>::path_name(), ss);
|
|
266
|
+
result.push_back(std::move(val));
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
for (const auto& a : target.object_range())
|
|
270
|
+
{
|
|
271
|
+
auto it = source.find(a.key());
|
|
272
|
+
if (it == source.object_range().end())
|
|
273
|
+
{
|
|
274
|
+
std::basic_string<char_type> ss(path);
|
|
275
|
+
ss.push_back('/');
|
|
276
|
+
jsonpointer::escape(a.key(),ss);
|
|
277
|
+
Json val(json_object_arg);
|
|
278
|
+
val.insert_or_assign(jsonpatch_names<char_type>::op_name(), jsonpatch_names<char_type>::add_name());
|
|
279
|
+
val.insert_or_assign(jsonpatch_names<char_type>::path_name(), ss);
|
|
280
|
+
val.insert_or_assign(jsonpatch_names<char_type>::value_name(), a.value());
|
|
281
|
+
result.push_back(std::move(val));
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
else
|
|
286
|
+
{
|
|
287
|
+
Json val(json_object_arg);
|
|
288
|
+
val.insert_or_assign(jsonpatch_names<char_type>::op_name(), jsonpatch_names<char_type>::replace_name());
|
|
289
|
+
val.insert_or_assign(jsonpatch_names<char_type>::path_name(), path);
|
|
290
|
+
val.insert_or_assign(jsonpatch_names<char_type>::value_name(), target);
|
|
291
|
+
result.push_back(std::move(val));
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
return result;
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
template <class Json>
|
|
299
|
+
void apply_patch(Json& target, const Json& patch, std::error_code& ec)
|
|
300
|
+
{
|
|
301
|
+
using char_type = typename Json::char_type;
|
|
302
|
+
using string_type = std::basic_string<char_type>;
|
|
303
|
+
using json_pointer_type = jsonpointer::basic_json_pointer<char_type>;
|
|
304
|
+
|
|
305
|
+
jsoncons::jsonpatch::detail::operation_unwinder<Json> unwinder(target);
|
|
306
|
+
std::error_code local_ec;
|
|
307
|
+
|
|
308
|
+
// Validate
|
|
309
|
+
|
|
310
|
+
for (const auto& operation : patch.array_range())
|
|
311
|
+
{
|
|
312
|
+
unwinder.state =jsoncons::jsonpatch::detail::state_type::begin;
|
|
313
|
+
|
|
314
|
+
auto it_op = operation.find(detail::jsonpatch_names<char_type>::op_name());
|
|
315
|
+
if (it_op == operation.object_range().end())
|
|
316
|
+
{
|
|
317
|
+
ec = jsonpatch_errc::invalid_patch;
|
|
318
|
+
unwinder.state =jsoncons::jsonpatch::detail::state_type::abort;
|
|
319
|
+
return;
|
|
320
|
+
}
|
|
321
|
+
string_type op = it_op->value().template as<string_type>();
|
|
322
|
+
|
|
323
|
+
auto it_path = operation.find(detail::jsonpatch_names<char_type>::path_name());
|
|
324
|
+
if (it_path == operation.object_range().end())
|
|
325
|
+
{
|
|
326
|
+
ec = jsonpatch_errc::invalid_patch;
|
|
327
|
+
unwinder.state =jsoncons::jsonpatch::detail::state_type::abort;
|
|
328
|
+
return;
|
|
329
|
+
}
|
|
330
|
+
string_type path = it_path->value().template as<string_type>();
|
|
331
|
+
auto location = json_pointer_type::parse(path, local_ec);
|
|
332
|
+
if (local_ec)
|
|
333
|
+
{
|
|
334
|
+
ec = jsonpatch_errc::invalid_patch;
|
|
335
|
+
unwinder.state =jsoncons::jsonpatch::detail::state_type::abort;
|
|
336
|
+
return;
|
|
337
|
+
}
|
|
338
|
+
|
|
339
|
+
if (op ==jsoncons::jsonpatch::detail::jsonpatch_names<char_type>::test_name())
|
|
340
|
+
{
|
|
341
|
+
Json val = jsonpointer::get(target,location,local_ec);
|
|
342
|
+
if (local_ec)
|
|
343
|
+
{
|
|
344
|
+
ec = jsonpatch_errc::test_failed;
|
|
345
|
+
unwinder.state =jsoncons::jsonpatch::detail::state_type::abort;
|
|
346
|
+
return;
|
|
347
|
+
}
|
|
348
|
+
auto it_value = operation.find(detail::jsonpatch_names<char_type>::value_name());
|
|
349
|
+
if (it_value == operation.object_range().end())
|
|
350
|
+
{
|
|
351
|
+
ec = jsonpatch_errc::invalid_patch;
|
|
352
|
+
unwinder.state =jsoncons::jsonpatch::detail::state_type::abort;
|
|
353
|
+
return;
|
|
354
|
+
}
|
|
355
|
+
if (val != it_value->value())
|
|
356
|
+
{
|
|
357
|
+
ec = jsonpatch_errc::test_failed;
|
|
358
|
+
unwinder.state =jsoncons::jsonpatch::detail::state_type::abort;
|
|
359
|
+
return;
|
|
360
|
+
}
|
|
361
|
+
}
|
|
362
|
+
else if (op ==jsoncons::jsonpatch::detail::jsonpatch_names<char_type>::add_name())
|
|
363
|
+
{
|
|
364
|
+
auto it_value = operation.find(detail::jsonpatch_names<char_type>::value_name());
|
|
365
|
+
if (it_value == operation.object_range().end())
|
|
366
|
+
{
|
|
367
|
+
ec = jsonpatch_errc::invalid_patch;
|
|
368
|
+
unwinder.state =jsoncons::jsonpatch::detail::state_type::abort;
|
|
369
|
+
return;
|
|
370
|
+
}
|
|
371
|
+
Json val = it_value->value();
|
|
372
|
+
auto npath = jsonpatch::detail::definite_path(target,location);
|
|
373
|
+
|
|
374
|
+
std::error_code insert_ec;
|
|
375
|
+
jsonpointer::add_if_absent(target,npath,val,insert_ec); // try insert without replace
|
|
376
|
+
if (insert_ec) // try a replace
|
|
377
|
+
{
|
|
378
|
+
std::error_code select_ec;
|
|
379
|
+
Json orig_val = jsonpointer::get(target,npath,select_ec);
|
|
380
|
+
if (select_ec) // shouldn't happen
|
|
381
|
+
{
|
|
382
|
+
ec = jsonpatch_errc::add_failed;
|
|
383
|
+
unwinder.state =jsoncons::jsonpatch::detail::state_type::abort;
|
|
384
|
+
return;
|
|
385
|
+
}
|
|
386
|
+
std::error_code replace_ec;
|
|
387
|
+
jsonpointer::replace(target,npath,val,replace_ec);
|
|
388
|
+
if (replace_ec)
|
|
389
|
+
{
|
|
390
|
+
ec = jsonpatch_errc::add_failed;
|
|
391
|
+
unwinder.state =jsoncons::jsonpatch::detail::state_type::abort;
|
|
392
|
+
return;
|
|
393
|
+
}
|
|
394
|
+
unwinder.stack.emplace_back(detail::op_type::replace,npath,orig_val);
|
|
395
|
+
}
|
|
396
|
+
else // insert without replace succeeded
|
|
397
|
+
{
|
|
398
|
+
unwinder.stack.emplace_back(detail::op_type::remove,npath,Json::null());
|
|
399
|
+
}
|
|
400
|
+
}
|
|
401
|
+
else if (op ==jsoncons::jsonpatch::detail::jsonpatch_names<char_type>::remove_name())
|
|
402
|
+
{
|
|
403
|
+
Json val = jsonpointer::get(target,location,local_ec);
|
|
404
|
+
if (local_ec)
|
|
405
|
+
{
|
|
406
|
+
ec = jsonpatch_errc::remove_failed;
|
|
407
|
+
unwinder.state =jsoncons::jsonpatch::detail::state_type::abort;
|
|
408
|
+
return;
|
|
409
|
+
}
|
|
410
|
+
jsonpointer::remove(target,location,local_ec);
|
|
411
|
+
if (local_ec)
|
|
412
|
+
{
|
|
413
|
+
ec = jsonpatch_errc::remove_failed;
|
|
414
|
+
unwinder.state =jsoncons::jsonpatch::detail::state_type::abort;
|
|
415
|
+
return;
|
|
416
|
+
}
|
|
417
|
+
unwinder.stack.emplace_back(detail::op_type::add, location, val);
|
|
418
|
+
}
|
|
419
|
+
else if (op ==jsoncons::jsonpatch::detail::jsonpatch_names<char_type>::replace_name())
|
|
420
|
+
{
|
|
421
|
+
Json val = jsonpointer::get(target,location,local_ec);
|
|
422
|
+
if (local_ec)
|
|
423
|
+
{
|
|
424
|
+
ec = jsonpatch_errc::replace_failed;
|
|
425
|
+
unwinder.state =jsoncons::jsonpatch::detail::state_type::abort;
|
|
426
|
+
return;
|
|
427
|
+
}
|
|
428
|
+
auto it_value = operation.find(detail::jsonpatch_names<char_type>::value_name());
|
|
429
|
+
if (it_value == operation.object_range().end())
|
|
430
|
+
{
|
|
431
|
+
ec = jsonpatch_errc::invalid_patch;
|
|
432
|
+
unwinder.state =jsoncons::jsonpatch::detail::state_type::abort;
|
|
433
|
+
return;
|
|
434
|
+
}
|
|
435
|
+
jsonpointer::replace(target, location, it_value->value(), local_ec);
|
|
436
|
+
if (local_ec)
|
|
437
|
+
{
|
|
438
|
+
ec = jsonpatch_errc::replace_failed;
|
|
439
|
+
unwinder.state =jsoncons::jsonpatch::detail::state_type::abort;
|
|
440
|
+
return;
|
|
441
|
+
}
|
|
442
|
+
unwinder.stack.emplace_back(detail::op_type::replace,location,val);
|
|
443
|
+
}
|
|
444
|
+
else if (op ==jsoncons::jsonpatch::detail::jsonpatch_names<char_type>::move_name())
|
|
445
|
+
{
|
|
446
|
+
auto it_from = operation.find(detail::jsonpatch_names<char_type>::from_name());
|
|
447
|
+
if (it_from == operation.object_range().end())
|
|
448
|
+
{
|
|
449
|
+
ec = jsonpatch_errc::invalid_patch;
|
|
450
|
+
unwinder.state =jsoncons::jsonpatch::detail::state_type::abort;
|
|
451
|
+
return;
|
|
452
|
+
}
|
|
453
|
+
string_type from = it_from->value().as_string();
|
|
454
|
+
auto from_pointer = json_pointer_type::parse(from, local_ec);
|
|
455
|
+
if (local_ec)
|
|
456
|
+
{
|
|
457
|
+
ec = jsonpatch_errc::move_failed;
|
|
458
|
+
unwinder.state = jsoncons::jsonpatch::detail::state_type::abort;
|
|
459
|
+
return;
|
|
460
|
+
}
|
|
461
|
+
|
|
462
|
+
Json val = jsonpointer::get(target, from_pointer, local_ec);
|
|
463
|
+
if (local_ec)
|
|
464
|
+
{
|
|
465
|
+
ec = jsonpatch_errc::move_failed;
|
|
466
|
+
unwinder.state =jsoncons::jsonpatch::detail::state_type::abort;
|
|
467
|
+
return;
|
|
468
|
+
}
|
|
469
|
+
jsonpointer::remove(target, from_pointer, local_ec);
|
|
470
|
+
if (local_ec)
|
|
471
|
+
{
|
|
472
|
+
ec = jsonpatch_errc::move_failed;
|
|
473
|
+
unwinder.state =jsoncons::jsonpatch::detail::state_type::abort;
|
|
474
|
+
return;
|
|
475
|
+
}
|
|
476
|
+
unwinder.stack.emplace_back(detail::op_type::add, from_pointer, val);
|
|
477
|
+
// add
|
|
478
|
+
std::error_code insert_ec;
|
|
479
|
+
auto npath = jsonpatch::detail::definite_path(target,location);
|
|
480
|
+
jsonpointer::add_if_absent(target,npath,val,insert_ec); // try insert without replace
|
|
481
|
+
if (insert_ec) // try a replace
|
|
482
|
+
{
|
|
483
|
+
std::error_code select_ec;
|
|
484
|
+
Json orig_val = jsonpointer::get(target,npath,select_ec);
|
|
485
|
+
if (select_ec) // shouldn't happen
|
|
486
|
+
{
|
|
487
|
+
ec = jsonpatch_errc::copy_failed;
|
|
488
|
+
unwinder.state =jsoncons::jsonpatch::detail::state_type::abort;
|
|
489
|
+
return;
|
|
490
|
+
}
|
|
491
|
+
std::error_code replace_ec;
|
|
492
|
+
jsonpointer::replace(target, npath, val, replace_ec);
|
|
493
|
+
if (replace_ec)
|
|
494
|
+
{
|
|
495
|
+
ec = jsonpatch_errc::copy_failed;
|
|
496
|
+
unwinder.state =jsoncons::jsonpatch::detail::state_type::abort;
|
|
497
|
+
return;
|
|
498
|
+
}
|
|
499
|
+
unwinder.stack.emplace_back(jsoncons::jsonpatch::detail::op_type::replace,npath,orig_val);
|
|
500
|
+
}
|
|
501
|
+
else
|
|
502
|
+
{
|
|
503
|
+
unwinder.stack.emplace_back(detail::op_type::remove,npath,Json::null());
|
|
504
|
+
}
|
|
505
|
+
}
|
|
506
|
+
else if (op ==jsoncons::jsonpatch::detail::jsonpatch_names<char_type>::copy_name())
|
|
507
|
+
{
|
|
508
|
+
auto it_from = operation.find(detail::jsonpatch_names<char_type>::from_name());
|
|
509
|
+
if (it_from == operation.object_range().end())
|
|
510
|
+
{
|
|
511
|
+
ec = jsonpatch_errc::invalid_patch;
|
|
512
|
+
unwinder.state =jsoncons::jsonpatch::detail::state_type::abort;
|
|
513
|
+
return;
|
|
514
|
+
}
|
|
515
|
+
string_type from = it_from->value().as_string();
|
|
516
|
+
Json val = jsonpointer::get(target,from,local_ec);
|
|
517
|
+
if (local_ec)
|
|
518
|
+
{
|
|
519
|
+
ec = jsonpatch_errc::copy_failed;
|
|
520
|
+
unwinder.state =jsoncons::jsonpatch::detail::state_type::abort;
|
|
521
|
+
return;
|
|
522
|
+
}
|
|
523
|
+
// add
|
|
524
|
+
auto npath = jsonpatch::detail::definite_path(target,location);
|
|
525
|
+
std::error_code insert_ec;
|
|
526
|
+
jsonpointer::add_if_absent(target,npath,val,insert_ec); // try insert without replace
|
|
527
|
+
if (insert_ec) // Failed, try a replace
|
|
528
|
+
{
|
|
529
|
+
std::error_code select_ec;
|
|
530
|
+
Json orig_val = jsonpointer::get(target,npath, select_ec);
|
|
531
|
+
if (select_ec) // shouldn't happen
|
|
532
|
+
{
|
|
533
|
+
ec = jsonpatch_errc::copy_failed;
|
|
534
|
+
unwinder.state =jsoncons::jsonpatch::detail::state_type::abort;
|
|
535
|
+
return;
|
|
536
|
+
}
|
|
537
|
+
std::error_code replace_ec;
|
|
538
|
+
jsonpointer::replace(target, npath, val,replace_ec);
|
|
539
|
+
if (replace_ec)
|
|
540
|
+
{
|
|
541
|
+
ec = jsonpatch_errc::copy_failed;
|
|
542
|
+
unwinder.state =jsoncons::jsonpatch::detail::state_type::abort;
|
|
543
|
+
return;
|
|
544
|
+
}
|
|
545
|
+
unwinder.stack.emplace_back(jsoncons::jsonpatch::detail::op_type::replace,npath,orig_val);
|
|
546
|
+
}
|
|
547
|
+
else
|
|
548
|
+
{
|
|
549
|
+
unwinder.stack.emplace_back(detail::op_type::remove,npath,Json::null());
|
|
550
|
+
}
|
|
551
|
+
}
|
|
552
|
+
}
|
|
553
|
+
if (unwinder.state ==jsoncons::jsonpatch::detail::state_type::begin)
|
|
554
|
+
{
|
|
555
|
+
unwinder.state =jsoncons::jsonpatch::detail::state_type::commit;
|
|
556
|
+
}
|
|
557
|
+
}
|
|
558
|
+
|
|
559
|
+
template <class Json>
|
|
560
|
+
Json from_diff(const Json& source, const Json& target)
|
|
561
|
+
{
|
|
562
|
+
std::basic_string<typename Json::char_type> path;
|
|
563
|
+
return jsoncons::jsonpatch::detail::from_diff(source, target, path);
|
|
564
|
+
}
|
|
565
|
+
|
|
566
|
+
template <class Json>
|
|
567
|
+
void apply_patch(Json& target, const Json& patch)
|
|
568
|
+
{
|
|
569
|
+
std::error_code ec;
|
|
570
|
+
apply_patch(target, patch, ec);
|
|
571
|
+
if (ec)
|
|
572
|
+
{
|
|
573
|
+
JSONCONS_THROW(jsonpatch_error(ec));
|
|
574
|
+
}
|
|
575
|
+
}
|
|
576
|
+
|
|
577
|
+
}}
|
|
578
|
+
|
|
579
|
+
#endif
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
/// Copyright 2017 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_JSONPATCH_JSONPATCH_ERROR_HPP
|
|
8
|
+
#define JSONCONS_JSONPATCH_JSONPATCH_ERROR_HPP
|
|
9
|
+
|
|
10
|
+
#include <jsoncons/json_exception.hpp>
|
|
11
|
+
#include <system_error>
|
|
12
|
+
|
|
13
|
+
namespace jsoncons { namespace jsonpatch {
|
|
14
|
+
|
|
15
|
+
enum class jsonpatch_errc
|
|
16
|
+
{
|
|
17
|
+
success = 0,
|
|
18
|
+
invalid_patch = 1,
|
|
19
|
+
test_failed,
|
|
20
|
+
add_failed,
|
|
21
|
+
remove_failed,
|
|
22
|
+
replace_failed,
|
|
23
|
+
move_failed,
|
|
24
|
+
copy_failed
|
|
25
|
+
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
class jsonpatch_error_category_impl
|
|
29
|
+
: public std::error_category
|
|
30
|
+
{
|
|
31
|
+
public:
|
|
32
|
+
const char* name() const noexcept override
|
|
33
|
+
{
|
|
34
|
+
return "jsoncons/jsonpatch";
|
|
35
|
+
}
|
|
36
|
+
std::string message(int ev) const override
|
|
37
|
+
{
|
|
38
|
+
switch (static_cast<jsonpatch_errc>(ev))
|
|
39
|
+
{
|
|
40
|
+
case jsonpatch_errc::invalid_patch:
|
|
41
|
+
return "Invalid JSON Patch document";
|
|
42
|
+
case jsonpatch_errc::test_failed:
|
|
43
|
+
return "JSON Patch test operation failed";
|
|
44
|
+
case jsonpatch_errc::add_failed:
|
|
45
|
+
return "JSON Patch add operation failed";
|
|
46
|
+
case jsonpatch_errc::remove_failed:
|
|
47
|
+
return "JSON Patch remove operation failed";
|
|
48
|
+
case jsonpatch_errc::replace_failed:
|
|
49
|
+
return "JSON Patch replace operation failed";
|
|
50
|
+
case jsonpatch_errc::move_failed:
|
|
51
|
+
return "JSON Patch move operation failed";
|
|
52
|
+
case jsonpatch_errc::copy_failed:
|
|
53
|
+
return "JSON Patch copy operation failed";
|
|
54
|
+
default:
|
|
55
|
+
return "Unknown JSON Patch error";
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
};
|
|
59
|
+
|
|
60
|
+
inline
|
|
61
|
+
const std::error_category& jsonpatch_error_category()
|
|
62
|
+
{
|
|
63
|
+
static jsonpatch_error_category_impl instance;
|
|
64
|
+
return instance;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
inline
|
|
68
|
+
std::error_code make_error_code(jsonpatch_errc result)
|
|
69
|
+
{
|
|
70
|
+
return std::error_code(static_cast<int>(result),jsonpatch_error_category());
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
} // jsonpatch
|
|
74
|
+
} // jsoncons
|
|
75
|
+
|
|
76
|
+
namespace std {
|
|
77
|
+
template<>
|
|
78
|
+
struct is_error_code_enum<jsoncons::jsonpatch::jsonpatch_errc> : public true_type
|
|
79
|
+
{
|
|
80
|
+
};
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
namespace jsoncons { namespace jsonpatch {
|
|
84
|
+
|
|
85
|
+
// allow to disable exceptions
|
|
86
|
+
#if !defined(JSONCONS_NO_EXCEPTIONS)
|
|
87
|
+
#define JSONCONS_THROW(exception) throw exception
|
|
88
|
+
#define JSONCONS_RETHROW throw
|
|
89
|
+
#define JSONCONS_TRY try
|
|
90
|
+
#define JSONCONS_CATCH(exception) catch(exception)
|
|
91
|
+
#else
|
|
92
|
+
#define JSONCONS_THROW(exception) std::terminate()
|
|
93
|
+
#define JSONCONS_RETHROW std::terminate()
|
|
94
|
+
#define JSONCONS_TRY if (true)
|
|
95
|
+
#define JSONCONS_CATCH(exception) if (false)
|
|
96
|
+
#endif
|
|
97
|
+
|
|
98
|
+
class jsonpatch_error : public std::system_error, public virtual json_exception
|
|
99
|
+
{
|
|
100
|
+
public:
|
|
101
|
+
jsonpatch_error(const std::error_code& ec)
|
|
102
|
+
: std::system_error(ec)
|
|
103
|
+
{
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
jsonpatch_error(const jsonpatch_error& other) = default;
|
|
107
|
+
|
|
108
|
+
jsonpatch_error(jsonpatch_error&& other) = default;
|
|
109
|
+
|
|
110
|
+
jsonpatch_error& operator=(const jsonpatch_error& e) = default;
|
|
111
|
+
jsonpatch_error& operator=(jsonpatch_error&& e) = default;
|
|
112
|
+
|
|
113
|
+
const char* what() const noexcept override
|
|
114
|
+
{
|
|
115
|
+
return std::system_error::what();
|
|
116
|
+
}
|
|
117
|
+
};
|
|
118
|
+
} // jsonpatch
|
|
119
|
+
} // jsoncons
|
|
120
|
+
|
|
121
|
+
#endif
|