jsoncons 0.1.0

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