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,820 @@
|
|
|
1
|
+
// Copyright 2013 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_BYTE_STRING_HPP
|
|
8
|
+
#define JSONCONS_BYTE_STRING_HPP
|
|
9
|
+
|
|
10
|
+
#include <sstream>
|
|
11
|
+
#include <vector>
|
|
12
|
+
#include <ostream>
|
|
13
|
+
#include <cmath>
|
|
14
|
+
#include <cstring> // std::memcmp
|
|
15
|
+
#include <memory> // std::allocator
|
|
16
|
+
#include <iterator>
|
|
17
|
+
#include <exception>
|
|
18
|
+
#include <iomanip> // std::setw
|
|
19
|
+
#include <initializer_list>
|
|
20
|
+
#include <utility> // std::move
|
|
21
|
+
#include <jsoncons/config/jsoncons_config.hpp>
|
|
22
|
+
#include <jsoncons/json_exception.hpp>
|
|
23
|
+
#include <jsoncons/conv_error.hpp>
|
|
24
|
+
#include <jsoncons/traits_extension.hpp>
|
|
25
|
+
|
|
26
|
+
namespace jsoncons {
|
|
27
|
+
|
|
28
|
+
// Algorithms
|
|
29
|
+
|
|
30
|
+
namespace detail {
|
|
31
|
+
|
|
32
|
+
template <class InputIt, class Container>
|
|
33
|
+
typename std::enable_if<std::is_same<typename std::iterator_traits<InputIt>::value_type,uint8_t>::value,size_t>::type
|
|
34
|
+
encode_base64_generic(InputIt first, InputIt last, const char alphabet[65], Container& result)
|
|
35
|
+
{
|
|
36
|
+
std::size_t count = 0;
|
|
37
|
+
unsigned char a3[3];
|
|
38
|
+
unsigned char a4[4];
|
|
39
|
+
unsigned char fill = alphabet[64];
|
|
40
|
+
int i = 0;
|
|
41
|
+
int j = 0;
|
|
42
|
+
|
|
43
|
+
while (first != last)
|
|
44
|
+
{
|
|
45
|
+
a3[i++] = *first++;
|
|
46
|
+
if (i == 3)
|
|
47
|
+
{
|
|
48
|
+
a4[0] = (a3[0] & 0xfc) >> 2;
|
|
49
|
+
a4[1] = ((a3[0] & 0x03) << 4) + ((a3[1] & 0xf0) >> 4);
|
|
50
|
+
a4[2] = ((a3[1] & 0x0f) << 2) + ((a3[2] & 0xc0) >> 6);
|
|
51
|
+
a4[3] = a3[2] & 0x3f;
|
|
52
|
+
|
|
53
|
+
for (i = 0; i < 4; i++)
|
|
54
|
+
{
|
|
55
|
+
result.push_back(alphabet[a4[i]]);
|
|
56
|
+
++count;
|
|
57
|
+
}
|
|
58
|
+
i = 0;
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
if (i > 0)
|
|
63
|
+
{
|
|
64
|
+
for (j = i; j < 3; ++j)
|
|
65
|
+
{
|
|
66
|
+
a3[j] = 0;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
a4[0] = (a3[0] & 0xfc) >> 2;
|
|
70
|
+
a4[1] = ((a3[0] & 0x03) << 4) + ((a3[1] & 0xf0) >> 4);
|
|
71
|
+
a4[2] = ((a3[1] & 0x0f) << 2) + ((a3[2] & 0xc0) >> 6);
|
|
72
|
+
|
|
73
|
+
for (j = 0; j < i + 1; ++j)
|
|
74
|
+
{
|
|
75
|
+
result.push_back(alphabet[a4[j]]);
|
|
76
|
+
++count;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
if (fill != 0)
|
|
80
|
+
{
|
|
81
|
+
while (i++ < 3)
|
|
82
|
+
{
|
|
83
|
+
result.push_back(fill);
|
|
84
|
+
++count;
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
return count;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
template <class InputIt, class F, class Container>
|
|
93
|
+
typename std::enable_if<traits_extension::is_back_insertable_byte_container<Container>::value,decode_result<InputIt>>::type
|
|
94
|
+
decode_base64_generic(InputIt first, InputIt last,
|
|
95
|
+
const uint8_t reverse_alphabet[256],
|
|
96
|
+
F f,
|
|
97
|
+
Container& result)
|
|
98
|
+
{
|
|
99
|
+
uint8_t a4[4], a3[3];
|
|
100
|
+
uint8_t i = 0;
|
|
101
|
+
uint8_t j = 0;
|
|
102
|
+
|
|
103
|
+
while (first != last && *first != '=')
|
|
104
|
+
{
|
|
105
|
+
if (!f(*first))
|
|
106
|
+
{
|
|
107
|
+
return decode_result<InputIt>{first, conv_errc::conversion_failed};
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
a4[i++] = *first++;
|
|
111
|
+
if (i == 4)
|
|
112
|
+
{
|
|
113
|
+
for (i = 0; i < 4; ++i)
|
|
114
|
+
{
|
|
115
|
+
a4[i] = reverse_alphabet[a4[i]];
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
a3[0] = (a4[0] << 2) + ((a4[1] & 0x30) >> 4);
|
|
119
|
+
a3[1] = ((a4[1] & 0xf) << 4) + ((a4[2] & 0x3c) >> 2);
|
|
120
|
+
a3[2] = ((a4[2] & 0x3) << 6) + a4[3];
|
|
121
|
+
|
|
122
|
+
for (i = 0; i < 3; i++)
|
|
123
|
+
{
|
|
124
|
+
result.push_back(a3[i]);
|
|
125
|
+
}
|
|
126
|
+
i = 0;
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
if (i > 0)
|
|
131
|
+
{
|
|
132
|
+
for (j = 0; j < i; ++j)
|
|
133
|
+
{
|
|
134
|
+
a4[j] = reverse_alphabet[a4[j]];
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
a3[0] = (a4[0] << 2) + ((a4[1] & 0x30) >> 4);
|
|
138
|
+
a3[1] = ((a4[1] & 0xf) << 4) + ((a4[2] & 0x3c) >> 2);
|
|
139
|
+
|
|
140
|
+
for (j = 0; j < i - 1; ++j)
|
|
141
|
+
{
|
|
142
|
+
result.push_back(a3[j]);
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
return decode_result<InputIt>{last, conv_errc::success};
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
} // namespace detail
|
|
149
|
+
|
|
150
|
+
template <class InputIt, class Container>
|
|
151
|
+
typename std::enable_if<std::is_same<typename std::iterator_traits<InputIt>::value_type,uint8_t>::value,size_t>::type
|
|
152
|
+
encode_base16(InputIt first, InputIt last, Container& result)
|
|
153
|
+
{
|
|
154
|
+
static constexpr char characters[] = "0123456789ABCDEF";
|
|
155
|
+
|
|
156
|
+
for (auto it = first; it != last; ++it)
|
|
157
|
+
{
|
|
158
|
+
uint8_t c = *it;
|
|
159
|
+
result.push_back(characters[c >> 4]);
|
|
160
|
+
result.push_back(characters[c & 0xf]);
|
|
161
|
+
}
|
|
162
|
+
return (last-first)*2;
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
template <class InputIt, class Container>
|
|
166
|
+
typename std::enable_if<std::is_same<typename std::iterator_traits<InputIt>::value_type,uint8_t>::value,size_t>::type
|
|
167
|
+
encode_base64url(InputIt first, InputIt last, Container& result)
|
|
168
|
+
{
|
|
169
|
+
static constexpr char alphabet[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
|
|
170
|
+
"abcdefghijklmnopqrstuvwxyz"
|
|
171
|
+
"0123456789-_"
|
|
172
|
+
"\0";
|
|
173
|
+
return detail::encode_base64_generic(first, last, alphabet, result);
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
template <class InputIt, class Container>
|
|
177
|
+
typename std::enable_if<std::is_same<typename std::iterator_traits<InputIt>::value_type,uint8_t>::value,size_t>::type
|
|
178
|
+
encode_base64(InputIt first, InputIt last, Container& result)
|
|
179
|
+
{
|
|
180
|
+
static constexpr char alphabet[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
|
|
181
|
+
"abcdefghijklmnopqrstuvwxyz"
|
|
182
|
+
"0123456789+/"
|
|
183
|
+
"=";
|
|
184
|
+
return detail::encode_base64_generic(first, last, alphabet, result);
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
template <class Char>
|
|
188
|
+
bool is_base64(Char c)
|
|
189
|
+
{
|
|
190
|
+
return (c >= 0 && c < 128) && (isalnum((int)c) || c == '+' || c == '/');
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
template <class Char>
|
|
194
|
+
bool is_base64url(Char c)
|
|
195
|
+
{
|
|
196
|
+
return (c >= 0 && c < 128) && (isalnum((int)c) || c == '-' || c == '_');
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
inline
|
|
200
|
+
static bool is_base64url(int c)
|
|
201
|
+
{
|
|
202
|
+
return isalnum(c) || c == '-' || c == '_';
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
// decode
|
|
206
|
+
|
|
207
|
+
template <class InputIt, class Container>
|
|
208
|
+
typename std::enable_if<traits_extension::is_back_insertable_byte_container<Container>::value,decode_result<InputIt>>::type
|
|
209
|
+
decode_base64url(InputIt first, InputIt last, Container& result)
|
|
210
|
+
{
|
|
211
|
+
static constexpr uint8_t reverse_alphabet[256] = {
|
|
212
|
+
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
|
213
|
+
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
|
214
|
+
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 62, 0xff, 0xff,
|
|
215
|
+
52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
|
216
|
+
0xff, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
|
|
217
|
+
15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 0xff, 0xff, 0xff, 0xff, 63,
|
|
218
|
+
0xff, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
|
|
219
|
+
41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 0xff, 0xff, 0xff, 0xff, 0xff,
|
|
220
|
+
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
|
221
|
+
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
|
222
|
+
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
|
223
|
+
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
|
224
|
+
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
|
225
|
+
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
|
226
|
+
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
|
227
|
+
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
|
|
228
|
+
};
|
|
229
|
+
auto retval = jsoncons::detail::decode_base64_generic(first, last, reverse_alphabet,
|
|
230
|
+
is_base64url<typename std::iterator_traits<InputIt>::value_type>,
|
|
231
|
+
result);
|
|
232
|
+
return retval.ec == conv_errc::success ? retval : decode_result<InputIt>{retval.it, conv_errc::not_base64url};
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
template <class InputIt, class Container>
|
|
236
|
+
typename std::enable_if<traits_extension::is_back_insertable_byte_container<Container>::value,decode_result<InputIt>>::type
|
|
237
|
+
decode_base64(InputIt first, InputIt last, Container& result)
|
|
238
|
+
{
|
|
239
|
+
static constexpr uint8_t reverse_alphabet[256] = {
|
|
240
|
+
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
|
241
|
+
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
|
242
|
+
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 62, 0xff, 0xff, 0xff, 63,
|
|
243
|
+
52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
|
244
|
+
0xff, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
|
|
245
|
+
15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 0xff, 0xff, 0xff, 0xff, 0xff,
|
|
246
|
+
0xff, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
|
|
247
|
+
41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 0xff, 0xff, 0xff, 0xff, 0xff,
|
|
248
|
+
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
|
249
|
+
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
|
250
|
+
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
|
251
|
+
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
|
252
|
+
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
|
253
|
+
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
|
254
|
+
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
|
255
|
+
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
|
|
256
|
+
};
|
|
257
|
+
auto retval = jsoncons::detail::decode_base64_generic(first, last, reverse_alphabet,
|
|
258
|
+
is_base64<typename std::iterator_traits<InputIt>::value_type>,
|
|
259
|
+
result);
|
|
260
|
+
return retval.ec == conv_errc::success ? retval : decode_result<InputIt>{retval.it, conv_errc::not_base64};
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
template <class InputIt,class Container>
|
|
264
|
+
typename std::enable_if<traits_extension::is_back_insertable_byte_container<Container>::value,decode_result<InputIt>>::type
|
|
265
|
+
decode_base16(InputIt first, InputIt last, Container& result)
|
|
266
|
+
{
|
|
267
|
+
std::size_t len = std::distance(first,last);
|
|
268
|
+
if (len & 1)
|
|
269
|
+
{
|
|
270
|
+
return decode_result<InputIt>{first, conv_errc::not_base16};
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
InputIt it = first;
|
|
274
|
+
while (it != last)
|
|
275
|
+
{
|
|
276
|
+
uint8_t val;
|
|
277
|
+
auto a = *it++;
|
|
278
|
+
if (a >= '0' && a <= '9')
|
|
279
|
+
{
|
|
280
|
+
val = (a - '0') << 4;
|
|
281
|
+
}
|
|
282
|
+
else if ((a | 0x20) >= 'a' && (a | 0x20) <= 'f')
|
|
283
|
+
{
|
|
284
|
+
val = ((a | 0x20) - 'a' + 10) << 4;
|
|
285
|
+
}
|
|
286
|
+
else
|
|
287
|
+
{
|
|
288
|
+
return decode_result<InputIt>{first, conv_errc::not_base16};
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
auto b = *it++;
|
|
292
|
+
if (b >= '0' && b <= '9')
|
|
293
|
+
{
|
|
294
|
+
val |= (b - '0');
|
|
295
|
+
}
|
|
296
|
+
else if ((b | 0x20) >= 'a' && (b | 0x20) <= 'f')
|
|
297
|
+
{
|
|
298
|
+
val |= ((b | 0x20) - 'a' + 10);
|
|
299
|
+
}
|
|
300
|
+
else
|
|
301
|
+
{
|
|
302
|
+
return decode_result<InputIt>{first, conv_errc::not_base16};
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
result.push_back(val);
|
|
306
|
+
}
|
|
307
|
+
return decode_result<InputIt>{last, conv_errc::success};
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
struct byte_traits
|
|
311
|
+
{
|
|
312
|
+
using char_type = uint8_t;
|
|
313
|
+
|
|
314
|
+
static constexpr int eof()
|
|
315
|
+
{
|
|
316
|
+
return std::char_traits<char>::eof();
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
static int compare(const char_type* s1, const char_type* s2, std::size_t count) noexcept
|
|
320
|
+
{
|
|
321
|
+
return std::memcmp(s1,s2,count);
|
|
322
|
+
}
|
|
323
|
+
};
|
|
324
|
+
|
|
325
|
+
// basic_byte_string
|
|
326
|
+
|
|
327
|
+
template <class Allocator>
|
|
328
|
+
class basic_byte_string;
|
|
329
|
+
|
|
330
|
+
// byte_string_view
|
|
331
|
+
class byte_string_view
|
|
332
|
+
{
|
|
333
|
+
const uint8_t* data_;
|
|
334
|
+
std::size_t size_;
|
|
335
|
+
public:
|
|
336
|
+
using traits_type = byte_traits;
|
|
337
|
+
|
|
338
|
+
using const_iterator = const uint8_t*;
|
|
339
|
+
using iterator = const_iterator;
|
|
340
|
+
using size_type = std::size_t;
|
|
341
|
+
using value_type = uint8_t;
|
|
342
|
+
using reference = uint8_t&;
|
|
343
|
+
using const_reference = const uint8_t&;
|
|
344
|
+
using difference_type = std::ptrdiff_t;
|
|
345
|
+
using pointer = uint8_t*;
|
|
346
|
+
using const_pointer = const uint8_t*;
|
|
347
|
+
|
|
348
|
+
constexpr byte_string_view() noexcept
|
|
349
|
+
: data_(nullptr), size_(0)
|
|
350
|
+
{
|
|
351
|
+
}
|
|
352
|
+
|
|
353
|
+
constexpr byte_string_view(const uint8_t* data, std::size_t length) noexcept
|
|
354
|
+
: data_(data), size_(length)
|
|
355
|
+
{
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
template <class Container>
|
|
359
|
+
constexpr explicit byte_string_view(const Container& cont,
|
|
360
|
+
typename std::enable_if<traits_extension::is_byte_sequence<Container>::value,int>::type = 0)
|
|
361
|
+
: data_(reinterpret_cast<const uint8_t*>(cont.data())), size_(cont.size())
|
|
362
|
+
{
|
|
363
|
+
}
|
|
364
|
+
|
|
365
|
+
template <class Allocator>
|
|
366
|
+
constexpr byte_string_view(const basic_byte_string<Allocator>& bytes);
|
|
367
|
+
|
|
368
|
+
constexpr byte_string_view(const byte_string_view&) noexcept = default;
|
|
369
|
+
|
|
370
|
+
JSONCONS_CPP14_CONSTEXPR byte_string_view(byte_string_view&& other) noexcept
|
|
371
|
+
: data_(nullptr), size_(0)
|
|
372
|
+
{
|
|
373
|
+
const_pointer temp_data = data_;
|
|
374
|
+
data_ = other.data_;
|
|
375
|
+
other.data_ = temp_data;
|
|
376
|
+
|
|
377
|
+
size_type temp_size = size_;
|
|
378
|
+
size_ = other.size_;
|
|
379
|
+
other.size_ = temp_size;
|
|
380
|
+
}
|
|
381
|
+
|
|
382
|
+
byte_string_view& operator=(const byte_string_view&) = default;
|
|
383
|
+
|
|
384
|
+
byte_string_view& operator=(byte_string_view&& other) noexcept
|
|
385
|
+
{
|
|
386
|
+
std::swap(data_, other.data_);
|
|
387
|
+
std::swap(size_, other.size_);
|
|
388
|
+
return *this;
|
|
389
|
+
}
|
|
390
|
+
|
|
391
|
+
constexpr const uint8_t* data() const noexcept
|
|
392
|
+
{
|
|
393
|
+
return data_;
|
|
394
|
+
}
|
|
395
|
+
#if !defined(JSONCONS_NO_DEPRECATED)
|
|
396
|
+
JSONCONS_DEPRECATED_MSG("Instead, use size()")
|
|
397
|
+
std::size_t length() const
|
|
398
|
+
{
|
|
399
|
+
return size_;
|
|
400
|
+
}
|
|
401
|
+
#endif
|
|
402
|
+
constexpr size_t size() const noexcept
|
|
403
|
+
{
|
|
404
|
+
return size_;
|
|
405
|
+
}
|
|
406
|
+
|
|
407
|
+
// iterator support
|
|
408
|
+
constexpr const_iterator begin() const noexcept
|
|
409
|
+
{
|
|
410
|
+
return data_;
|
|
411
|
+
}
|
|
412
|
+
constexpr const_iterator end() const noexcept
|
|
413
|
+
{
|
|
414
|
+
return data_ + size_;
|
|
415
|
+
}
|
|
416
|
+
constexpr const_iterator cbegin() const noexcept
|
|
417
|
+
{
|
|
418
|
+
return data_;
|
|
419
|
+
}
|
|
420
|
+
constexpr const_iterator cend() const noexcept
|
|
421
|
+
{
|
|
422
|
+
return data_ + size_;
|
|
423
|
+
}
|
|
424
|
+
|
|
425
|
+
constexpr uint8_t operator[](size_type pos) const
|
|
426
|
+
{
|
|
427
|
+
return data_[pos];
|
|
428
|
+
}
|
|
429
|
+
|
|
430
|
+
JSONCONS_CPP14_CONSTEXPR byte_string_view substr(size_type pos) const
|
|
431
|
+
{
|
|
432
|
+
if (pos > size_)
|
|
433
|
+
{
|
|
434
|
+
JSONCONS_THROW(std::out_of_range("pos exceeds size"));
|
|
435
|
+
}
|
|
436
|
+
std::size_t n = size_ - pos;
|
|
437
|
+
return byte_string_view(data_ + pos, n);
|
|
438
|
+
}
|
|
439
|
+
|
|
440
|
+
byte_string_view substr(size_type pos, size_type n) const
|
|
441
|
+
{
|
|
442
|
+
if (pos > size_)
|
|
443
|
+
{
|
|
444
|
+
JSONCONS_THROW(std::out_of_range("pos exceeds size"));
|
|
445
|
+
}
|
|
446
|
+
if (pos + n > size_)
|
|
447
|
+
{
|
|
448
|
+
n = size_ - pos;
|
|
449
|
+
}
|
|
450
|
+
return byte_string_view(data_ + pos, n);
|
|
451
|
+
}
|
|
452
|
+
|
|
453
|
+
int compare(const byte_string_view& s) const noexcept
|
|
454
|
+
{
|
|
455
|
+
const int rc = traits_type::compare(data_, s.data(), (std::min)(size_, s.size()));
|
|
456
|
+
return rc != 0 ? rc : (size_ == s.size() ? 0 : size_ < s.size() ? -1 : 1);
|
|
457
|
+
}
|
|
458
|
+
|
|
459
|
+
template <class Allocator>
|
|
460
|
+
int compare(const basic_byte_string<Allocator>& s) const noexcept
|
|
461
|
+
{
|
|
462
|
+
const int rc = traits_type::compare(data_, s.data(), (std::min)(size_, s.size()));
|
|
463
|
+
return rc != 0 ? rc : (size_ == s.size() ? 0 : size_ < s.size() ? -1 : 1);
|
|
464
|
+
}
|
|
465
|
+
|
|
466
|
+
template <class CharT>
|
|
467
|
+
friend std::basic_ostream<CharT>& operator<<(std::basic_ostream<CharT>& os, const byte_string_view& bstr)
|
|
468
|
+
{
|
|
469
|
+
std::basic_ostringstream<CharT> ss;
|
|
470
|
+
ss.flags(std::ios::hex);
|
|
471
|
+
ss.fill('0');
|
|
472
|
+
|
|
473
|
+
bool first = true;
|
|
474
|
+
for (auto b : bstr)
|
|
475
|
+
{
|
|
476
|
+
if (first)
|
|
477
|
+
{
|
|
478
|
+
first = false;
|
|
479
|
+
}
|
|
480
|
+
else
|
|
481
|
+
{
|
|
482
|
+
ss << ',';
|
|
483
|
+
}
|
|
484
|
+
ss << std::setw(2) << static_cast<int>(b);
|
|
485
|
+
}
|
|
486
|
+
os << ss.str();
|
|
487
|
+
return os;
|
|
488
|
+
}
|
|
489
|
+
};
|
|
490
|
+
|
|
491
|
+
// basic_byte_string
|
|
492
|
+
template <class Allocator = std::allocator<uint8_t>>
|
|
493
|
+
class basic_byte_string
|
|
494
|
+
{
|
|
495
|
+
using byte_allocator_type = typename std::allocator_traits<Allocator>:: template rebind_alloc<uint8_t>;
|
|
496
|
+
std::vector<uint8_t,byte_allocator_type> data_;
|
|
497
|
+
public:
|
|
498
|
+
using traits_type = byte_traits;
|
|
499
|
+
using allocator_type = byte_allocator_type;
|
|
500
|
+
|
|
501
|
+
using value_type = typename std::vector<uint8_t,byte_allocator_type>::value_type;
|
|
502
|
+
using size_type = typename std::vector<uint8_t,byte_allocator_type>::size_type;
|
|
503
|
+
using difference_type = typename std::vector<uint8_t,byte_allocator_type>::difference_type;
|
|
504
|
+
using reference = typename std::vector<uint8_t,byte_allocator_type>::reference;
|
|
505
|
+
using const_reference = typename std::vector<uint8_t,byte_allocator_type>::const_reference;
|
|
506
|
+
using pointer = typename std::vector<uint8_t,byte_allocator_type>::pointer;
|
|
507
|
+
using const_pointer = typename std::vector<uint8_t,byte_allocator_type>::const_pointer;
|
|
508
|
+
using iterator = typename std::vector<uint8_t,byte_allocator_type>::iterator;
|
|
509
|
+
using const_iterator = typename std::vector<uint8_t,byte_allocator_type>::const_iterator;
|
|
510
|
+
|
|
511
|
+
basic_byte_string() = default;
|
|
512
|
+
|
|
513
|
+
explicit basic_byte_string(const Allocator& alloc)
|
|
514
|
+
: data_(alloc)
|
|
515
|
+
{
|
|
516
|
+
}
|
|
517
|
+
|
|
518
|
+
basic_byte_string(std::initializer_list<uint8_t> init)
|
|
519
|
+
: data_(std::move(init))
|
|
520
|
+
{
|
|
521
|
+
}
|
|
522
|
+
|
|
523
|
+
basic_byte_string(std::initializer_list<uint8_t> init, const Allocator& alloc)
|
|
524
|
+
: data_(std::move(init), alloc)
|
|
525
|
+
{
|
|
526
|
+
}
|
|
527
|
+
|
|
528
|
+
explicit basic_byte_string(const byte_string_view& v)
|
|
529
|
+
: data_(v.begin(),v.end())
|
|
530
|
+
{
|
|
531
|
+
}
|
|
532
|
+
|
|
533
|
+
basic_byte_string(const basic_byte_string<Allocator>& v)
|
|
534
|
+
: data_(v.data_)
|
|
535
|
+
{
|
|
536
|
+
}
|
|
537
|
+
|
|
538
|
+
basic_byte_string(basic_byte_string<Allocator>&& v) noexcept
|
|
539
|
+
: data_(std::move(v.data_))
|
|
540
|
+
{
|
|
541
|
+
}
|
|
542
|
+
|
|
543
|
+
basic_byte_string(const byte_string_view& v, const Allocator& alloc)
|
|
544
|
+
: data_(v.begin(),v.end(),alloc)
|
|
545
|
+
{
|
|
546
|
+
}
|
|
547
|
+
|
|
548
|
+
basic_byte_string(const uint8_t* data, std::size_t length, const Allocator& alloc = Allocator())
|
|
549
|
+
: data_(data, data+length,alloc)
|
|
550
|
+
{
|
|
551
|
+
}
|
|
552
|
+
|
|
553
|
+
Allocator get_allocator() const
|
|
554
|
+
{
|
|
555
|
+
return data_.get_allocator();
|
|
556
|
+
}
|
|
557
|
+
|
|
558
|
+
basic_byte_string& operator=(const basic_byte_string& s) = default;
|
|
559
|
+
|
|
560
|
+
basic_byte_string& operator=(basic_byte_string&& other) noexcept
|
|
561
|
+
{
|
|
562
|
+
data_.swap(other.data_);
|
|
563
|
+
return *this;
|
|
564
|
+
}
|
|
565
|
+
|
|
566
|
+
void reserve(std::size_t new_cap)
|
|
567
|
+
{
|
|
568
|
+
data_.reserve(new_cap);
|
|
569
|
+
}
|
|
570
|
+
|
|
571
|
+
void push_back(uint8_t b)
|
|
572
|
+
{
|
|
573
|
+
data_.push_back(b);
|
|
574
|
+
}
|
|
575
|
+
|
|
576
|
+
void assign(const uint8_t* s, std::size_t count)
|
|
577
|
+
{
|
|
578
|
+
data_.clear();
|
|
579
|
+
data_.insert(s, s+count);
|
|
580
|
+
}
|
|
581
|
+
|
|
582
|
+
void append(const uint8_t* s, std::size_t count)
|
|
583
|
+
{
|
|
584
|
+
data_.insert(s, s+count);
|
|
585
|
+
}
|
|
586
|
+
|
|
587
|
+
void clear()
|
|
588
|
+
{
|
|
589
|
+
data_.clear();
|
|
590
|
+
}
|
|
591
|
+
|
|
592
|
+
uint8_t operator[](size_type pos) const
|
|
593
|
+
{
|
|
594
|
+
return data_[pos];
|
|
595
|
+
}
|
|
596
|
+
|
|
597
|
+
// iterator support
|
|
598
|
+
iterator begin() noexcept
|
|
599
|
+
{
|
|
600
|
+
return data_.begin();
|
|
601
|
+
}
|
|
602
|
+
iterator end() noexcept
|
|
603
|
+
{
|
|
604
|
+
return data_.end();
|
|
605
|
+
}
|
|
606
|
+
|
|
607
|
+
const_iterator begin() const noexcept
|
|
608
|
+
{
|
|
609
|
+
return data_.begin();
|
|
610
|
+
}
|
|
611
|
+
const_iterator end() const noexcept
|
|
612
|
+
{
|
|
613
|
+
return data_.end();
|
|
614
|
+
}
|
|
615
|
+
|
|
616
|
+
uint8_t* data()
|
|
617
|
+
{
|
|
618
|
+
return data_.data();
|
|
619
|
+
}
|
|
620
|
+
|
|
621
|
+
const uint8_t* data() const
|
|
622
|
+
{
|
|
623
|
+
return data_.data();
|
|
624
|
+
}
|
|
625
|
+
|
|
626
|
+
std::size_t size() const
|
|
627
|
+
{
|
|
628
|
+
return data_.size();
|
|
629
|
+
}
|
|
630
|
+
|
|
631
|
+
#if !defined(JSONCONS_NO_DEPRECATED)
|
|
632
|
+
JSONCONS_DEPRECATED_MSG("Instead, use size()")
|
|
633
|
+
std::size_t length() const
|
|
634
|
+
{
|
|
635
|
+
return data_.size();
|
|
636
|
+
}
|
|
637
|
+
#endif
|
|
638
|
+
|
|
639
|
+
int compare(const byte_string_view& s) const noexcept
|
|
640
|
+
{
|
|
641
|
+
const int rc = traits_type::compare(data(), s.data(), (std::min)(size(), s.size()));
|
|
642
|
+
return rc != 0 ? rc : (size() == s.size() ? 0 : size() < s.size() ? -1 : 1);
|
|
643
|
+
}
|
|
644
|
+
|
|
645
|
+
int compare(const basic_byte_string& s) const noexcept
|
|
646
|
+
{
|
|
647
|
+
const int rc = traits_type::compare(data(), s.data(), (std::min)(size(), s.size()));
|
|
648
|
+
return rc != 0 ? rc : (size() == s.size() ? 0 : size() < s.size() ? -1 : 1);
|
|
649
|
+
}
|
|
650
|
+
|
|
651
|
+
template <class CharT>
|
|
652
|
+
friend std::basic_ostream<CharT>& operator<<(std::basic_ostream<CharT>& os, const basic_byte_string& o)
|
|
653
|
+
{
|
|
654
|
+
os << byte_string_view(o);
|
|
655
|
+
return os;
|
|
656
|
+
}
|
|
657
|
+
};
|
|
658
|
+
|
|
659
|
+
template <class Allocator>
|
|
660
|
+
constexpr byte_string_view::byte_string_view(const basic_byte_string<Allocator>& bytes)
|
|
661
|
+
: data_(bytes.data()), size_(bytes.size())
|
|
662
|
+
{
|
|
663
|
+
}
|
|
664
|
+
|
|
665
|
+
// ==
|
|
666
|
+
inline
|
|
667
|
+
bool operator==(const byte_string_view& lhs, const byte_string_view& rhs) noexcept
|
|
668
|
+
{
|
|
669
|
+
return lhs.compare(rhs) == 0;
|
|
670
|
+
}
|
|
671
|
+
template<class Allocator>
|
|
672
|
+
bool operator==(const byte_string_view& lhs, const basic_byte_string<Allocator>& rhs) noexcept
|
|
673
|
+
{
|
|
674
|
+
return lhs.compare(rhs) == 0;
|
|
675
|
+
}
|
|
676
|
+
template<class Allocator>
|
|
677
|
+
bool operator==(const basic_byte_string<Allocator>& lhs, const byte_string_view& rhs) noexcept
|
|
678
|
+
{
|
|
679
|
+
return rhs.compare(lhs) == 0;
|
|
680
|
+
}
|
|
681
|
+
template<class Allocator>
|
|
682
|
+
bool operator==(const basic_byte_string<Allocator>& lhs, const basic_byte_string<Allocator>& rhs) noexcept
|
|
683
|
+
{
|
|
684
|
+
return rhs.compare(lhs) == 0;
|
|
685
|
+
}
|
|
686
|
+
|
|
687
|
+
// !=
|
|
688
|
+
|
|
689
|
+
inline
|
|
690
|
+
bool operator!=(const byte_string_view& lhs, const byte_string_view& rhs) noexcept
|
|
691
|
+
{
|
|
692
|
+
return lhs.compare(rhs) != 0;
|
|
693
|
+
}
|
|
694
|
+
template<class Allocator>
|
|
695
|
+
bool operator!=(const byte_string_view& lhs, const basic_byte_string<Allocator>& rhs) noexcept
|
|
696
|
+
{
|
|
697
|
+
return lhs.compare(rhs) != 0;
|
|
698
|
+
}
|
|
699
|
+
template<class Allocator>
|
|
700
|
+
bool operator!=(const basic_byte_string<Allocator>& lhs, const byte_string_view& rhs) noexcept
|
|
701
|
+
{
|
|
702
|
+
return rhs.compare(lhs) != 0;
|
|
703
|
+
}
|
|
704
|
+
template<class Allocator>
|
|
705
|
+
bool operator!=(const basic_byte_string<Allocator>& lhs, const basic_byte_string<Allocator>& rhs) noexcept
|
|
706
|
+
{
|
|
707
|
+
return rhs.compare(lhs) != 0;
|
|
708
|
+
}
|
|
709
|
+
|
|
710
|
+
// <=
|
|
711
|
+
|
|
712
|
+
inline
|
|
713
|
+
bool operator<=(const byte_string_view& lhs, const byte_string_view& rhs) noexcept
|
|
714
|
+
{
|
|
715
|
+
return lhs.compare(rhs) <= 0;
|
|
716
|
+
}
|
|
717
|
+
template<class Allocator>
|
|
718
|
+
bool operator<=(const byte_string_view& lhs, const basic_byte_string<Allocator>& rhs) noexcept
|
|
719
|
+
{
|
|
720
|
+
return lhs.compare(rhs) <= 0;
|
|
721
|
+
}
|
|
722
|
+
template<class Allocator>
|
|
723
|
+
bool operator<=(const basic_byte_string<Allocator>& lhs, const byte_string_view& rhs) noexcept
|
|
724
|
+
{
|
|
725
|
+
return rhs.compare(lhs) >= 0;
|
|
726
|
+
}
|
|
727
|
+
template<class Allocator>
|
|
728
|
+
bool operator<=(const basic_byte_string<Allocator>& lhs, const basic_byte_string<Allocator>& rhs) noexcept
|
|
729
|
+
{
|
|
730
|
+
return rhs.compare(lhs) >= 0;
|
|
731
|
+
}
|
|
732
|
+
|
|
733
|
+
// <
|
|
734
|
+
|
|
735
|
+
inline
|
|
736
|
+
bool operator<(const byte_string_view& lhs, const byte_string_view& rhs) noexcept
|
|
737
|
+
{
|
|
738
|
+
return lhs.compare(rhs) < 0;
|
|
739
|
+
}
|
|
740
|
+
template<class Allocator>
|
|
741
|
+
bool operator<(const byte_string_view& lhs, const basic_byte_string<Allocator>& rhs) noexcept
|
|
742
|
+
{
|
|
743
|
+
return lhs.compare(rhs) < 0;
|
|
744
|
+
}
|
|
745
|
+
template<class Allocator>
|
|
746
|
+
bool operator<(const basic_byte_string<Allocator>& lhs, const byte_string_view& rhs) noexcept
|
|
747
|
+
{
|
|
748
|
+
return rhs.compare(lhs) > 0;
|
|
749
|
+
}
|
|
750
|
+
template<class Allocator>
|
|
751
|
+
bool operator<(const basic_byte_string<Allocator>& lhs, const basic_byte_string<Allocator>& rhs) noexcept
|
|
752
|
+
{
|
|
753
|
+
return rhs.compare(lhs) > 0;
|
|
754
|
+
}
|
|
755
|
+
|
|
756
|
+
// >=
|
|
757
|
+
|
|
758
|
+
inline
|
|
759
|
+
bool operator>=(const byte_string_view& lhs, const byte_string_view& rhs) noexcept
|
|
760
|
+
{
|
|
761
|
+
return lhs.compare(rhs) >= 0;
|
|
762
|
+
}
|
|
763
|
+
template<class Allocator>
|
|
764
|
+
bool operator>=(const byte_string_view& lhs, const basic_byte_string<Allocator>& rhs) noexcept
|
|
765
|
+
{
|
|
766
|
+
return lhs.compare(rhs) >= 0;
|
|
767
|
+
}
|
|
768
|
+
template<class Allocator>
|
|
769
|
+
bool operator>=(const basic_byte_string<Allocator>& lhs, const byte_string_view& rhs) noexcept
|
|
770
|
+
{
|
|
771
|
+
return rhs.compare(lhs) <= 0;
|
|
772
|
+
}
|
|
773
|
+
template<class Allocator>
|
|
774
|
+
bool operator>=(const basic_byte_string<Allocator>& lhs, const basic_byte_string<Allocator>& rhs) noexcept
|
|
775
|
+
{
|
|
776
|
+
return rhs.compare(lhs) <= 0;
|
|
777
|
+
}
|
|
778
|
+
|
|
779
|
+
// >
|
|
780
|
+
|
|
781
|
+
inline
|
|
782
|
+
bool operator>(const byte_string_view& lhs, const byte_string_view& rhs) noexcept
|
|
783
|
+
{
|
|
784
|
+
return lhs.compare(rhs) > 0;
|
|
785
|
+
}
|
|
786
|
+
template<class Allocator>
|
|
787
|
+
bool operator>(const byte_string_view& lhs, const basic_byte_string<Allocator>& rhs) noexcept
|
|
788
|
+
{
|
|
789
|
+
return lhs.compare(rhs) > 0;
|
|
790
|
+
}
|
|
791
|
+
template<class Allocator>
|
|
792
|
+
bool operator>(const basic_byte_string<Allocator>& lhs, const byte_string_view& rhs) noexcept
|
|
793
|
+
{
|
|
794
|
+
return rhs.compare(lhs) < 0;
|
|
795
|
+
}
|
|
796
|
+
template<class Allocator>
|
|
797
|
+
bool operator>(const basic_byte_string<Allocator>& lhs, const basic_byte_string<Allocator>& rhs) noexcept
|
|
798
|
+
{
|
|
799
|
+
return rhs.compare(lhs) < 0;
|
|
800
|
+
}
|
|
801
|
+
|
|
802
|
+
using byte_string = basic_byte_string<std::allocator<uint8_t>>;
|
|
803
|
+
|
|
804
|
+
namespace traits_extension {
|
|
805
|
+
|
|
806
|
+
template <typename T>
|
|
807
|
+
struct is_basic_byte_string
|
|
808
|
+
: std::false_type
|
|
809
|
+
{};
|
|
810
|
+
|
|
811
|
+
template <typename Allocator>
|
|
812
|
+
struct is_basic_byte_string<basic_byte_string<Allocator>>
|
|
813
|
+
: std::true_type
|
|
814
|
+
{};
|
|
815
|
+
|
|
816
|
+
} // namespace traits_extension
|
|
817
|
+
|
|
818
|
+
} // namespace jsoncons
|
|
819
|
+
|
|
820
|
+
#endif
|