jsoncons 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
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,1942 @@
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_CBOR_CBOR_PARSER_HPP
8
+ #define JSONCONS_CBOR_CBOR_PARSER_HPP
9
+
10
+ #include <string>
11
+ #include <vector>
12
+ #include <memory>
13
+ #include <utility> // std::move
14
+ #include <bitset> // std::bitset
15
+ #include <jsoncons/json.hpp>
16
+ #include <jsoncons/source.hpp>
17
+ #include <jsoncons/json_visitor.hpp>
18
+ #include <jsoncons/config/jsoncons_config.hpp>
19
+ #include <jsoncons_ext/cbor/cbor_error.hpp>
20
+ #include <jsoncons_ext/cbor/cbor_detail.hpp>
21
+ #include <jsoncons_ext/cbor/cbor_options.hpp>
22
+ #include <jsoncons/json_visitor2.hpp>
23
+
24
+ namespace jsoncons { namespace cbor {
25
+
26
+ enum class parse_mode {root,accept,array,indefinite_array,map_key,map_value,indefinite_map_key,indefinite_map_value,multi_dim};
27
+
28
+ struct mapped_string
29
+ {
30
+ jsoncons::cbor::detail::cbor_major_type type;
31
+ std::string s;
32
+ std::vector<uint8_t> bytes;
33
+
34
+ mapped_string(const std::string& s)
35
+ : type(jsoncons::cbor::detail::cbor_major_type::text_string), s(s)
36
+ {
37
+ }
38
+
39
+ mapped_string(std::string&& s)
40
+ : type(jsoncons::cbor::detail::cbor_major_type::text_string), s(std::move(s))
41
+ {
42
+ }
43
+
44
+ mapped_string(const std::vector<uint8_t>& bytes)
45
+ : type(jsoncons::cbor::detail::cbor_major_type::byte_string), bytes(bytes)
46
+ {
47
+ }
48
+
49
+ mapped_string(std::vector<uint8_t>&& bytes)
50
+ : type(jsoncons::cbor::detail::cbor_major_type::byte_string), bytes(std::move(bytes))
51
+ {
52
+ }
53
+
54
+ mapped_string(const mapped_string&) = default;
55
+
56
+ mapped_string(mapped_string&&) = default;
57
+
58
+ mapped_string& operator=(const mapped_string&) = default;
59
+
60
+ mapped_string& operator=(mapped_string&&) = default;
61
+ };
62
+
63
+ struct parse_state
64
+ {
65
+ parse_mode mode;
66
+ std::size_t length;
67
+ std::size_t index;
68
+ bool pop_stringref_map_stack;
69
+
70
+ parse_state(parse_mode mode, std::size_t length, bool pop_stringref_map_stack = false) noexcept
71
+ : mode(mode), length(length), index(0), pop_stringref_map_stack(pop_stringref_map_stack)
72
+ {
73
+ }
74
+
75
+ parse_state(const parse_state&) = default;
76
+ parse_state(parse_state&&) = default;
77
+ };
78
+
79
+ template <class Source,class Allocator=std::allocator<char>>
80
+ class basic_cbor_parser : public ser_context
81
+ {
82
+ using char_type = char;
83
+ using char_traits_type = std::char_traits<char>;
84
+ using allocator_type = Allocator;
85
+ using char_allocator_type = typename std::allocator_traits<allocator_type>:: template rebind_alloc<char_type>;
86
+ using byte_allocator_type = typename std::allocator_traits<allocator_type>:: template rebind_alloc<uint8_t>;
87
+ using tag_allocator_type = typename std::allocator_traits<allocator_type>:: template rebind_alloc<uint64_t>;
88
+ using parse_state_allocator_type = typename std::allocator_traits<allocator_type>:: template rebind_alloc<parse_state>;
89
+ using stringref_map = std::vector<mapped_string>;
90
+ using stringref_map_allocator_type = typename std::allocator_traits<allocator_type>:: template rebind_alloc<stringref_map>;
91
+
92
+ using string_type = std::basic_string<char_type,char_traits_type,char_allocator_type>;
93
+
94
+ enum {stringref_tag, // 25
95
+ stringref_namespace_tag, // 256
96
+ item_tag,
97
+ num_of_tags};
98
+
99
+ std::bitset<num_of_tags> other_tags_;
100
+
101
+ allocator_type alloc_;
102
+ Source source_;
103
+ cbor_decode_options options_;
104
+
105
+ bool more_;
106
+ bool done_;
107
+ string_type text_buffer_;
108
+ std::vector<uint8_t,byte_allocator_type> bytes_buffer_;
109
+ uint64_t item_tag_;
110
+ std::vector<parse_state,parse_state_allocator_type> state_stack_;
111
+ std::vector<uint8_t,byte_allocator_type> typed_array_;
112
+ std::vector<std::size_t> shape_;
113
+ std::size_t index_; // TODO: Never used!
114
+ std::vector<stringref_map,stringref_map_allocator_type> stringref_map_stack_;
115
+ int nesting_depth_;
116
+
117
+ struct read_byte_string_from_buffer
118
+ {
119
+ byte_string_view bytes;
120
+
121
+ read_byte_string_from_buffer(const byte_string_view& b)
122
+ : bytes(b)
123
+ {
124
+ }
125
+ template <class Container>
126
+ void operator()(Container& c, std::error_code&)
127
+ {
128
+ c.clear();
129
+ c.reserve(bytes.size());
130
+ for (auto b : bytes)
131
+ {
132
+ c.push_back(b);
133
+ }
134
+ }
135
+ };
136
+
137
+ struct read_byte_string_from_source
138
+ {
139
+ basic_cbor_parser<Source,Allocator>* source;
140
+
141
+ read_byte_string_from_source(basic_cbor_parser<Source,Allocator>* source)
142
+ : source(source)
143
+ {
144
+ }
145
+ template <class Container>
146
+ void operator()(Container& c, std::error_code& ec)
147
+ {
148
+ source->read_byte_string(c,ec);
149
+ }
150
+ };
151
+
152
+ public:
153
+ template <class Sourceable>
154
+ basic_cbor_parser(Sourceable&& source,
155
+ const cbor_decode_options& options = cbor_decode_options(),
156
+ const Allocator alloc = Allocator())
157
+ : alloc_(alloc),
158
+ source_(std::forward<Sourceable>(source)),
159
+ options_(options),
160
+ more_(true),
161
+ done_(false),
162
+ text_buffer_(alloc),
163
+ bytes_buffer_(alloc),
164
+ item_tag_(0),
165
+ state_stack_(alloc),
166
+ typed_array_(alloc),
167
+ index_(0),
168
+ stringref_map_stack_(alloc),
169
+ nesting_depth_(0)
170
+ {
171
+ state_stack_.emplace_back(parse_mode::root,0);
172
+ }
173
+
174
+ void restart()
175
+ {
176
+ more_ = true;
177
+ }
178
+
179
+ void reset()
180
+ {
181
+ more_ = true;
182
+ done_ = false;
183
+ text_buffer_.clear();
184
+ bytes_buffer_.clear();
185
+ item_tag_ = 0;
186
+ state_stack_.clear();
187
+ state_stack_.emplace_back(parse_mode::root,0);
188
+ typed_array_.clear();
189
+ stringref_map_stack_.clear();
190
+ nesting_depth_ = 0;
191
+ }
192
+
193
+ template <class Sourceable>
194
+ void reset(Sourceable&& source)
195
+ {
196
+ source_ = std::forward<Sourceable>(source);
197
+ reset();
198
+ }
199
+
200
+ bool done() const
201
+ {
202
+ return done_;
203
+ }
204
+
205
+ bool stopped() const
206
+ {
207
+ return !more_;
208
+ }
209
+
210
+ std::size_t line() const override
211
+ {
212
+ return 0;
213
+ }
214
+
215
+ std::size_t column() const override
216
+ {
217
+ return source_.position();
218
+ }
219
+
220
+ void parse(json_visitor2& visitor, std::error_code& ec)
221
+ {
222
+ while (!done_ && more_)
223
+ {
224
+ switch (state_stack_.back().mode)
225
+ {
226
+ case parse_mode::multi_dim:
227
+ {
228
+ if (state_stack_.back().index == 0)
229
+ {
230
+ ++state_stack_.back().index;
231
+ read_item(visitor, ec);
232
+ }
233
+ else
234
+ {
235
+ produce_end_multi_dim(visitor, ec);
236
+ }
237
+ break;
238
+ }
239
+ case parse_mode::array:
240
+ {
241
+ if (state_stack_.back().index < state_stack_.back().length)
242
+ {
243
+ ++state_stack_.back().index;
244
+ read_item(visitor, ec);
245
+ }
246
+ else
247
+ {
248
+ end_array(visitor, ec);
249
+ }
250
+ break;
251
+ }
252
+ case parse_mode::indefinite_array:
253
+ {
254
+ auto c = source_.peek();
255
+ if (c.eof)
256
+ {
257
+ ec = cbor_errc::unexpected_eof;
258
+ more_ = false;
259
+ return;
260
+ }
261
+ if (c.value == 0xff)
262
+ {
263
+ source_.ignore(1);
264
+ end_array(visitor, ec);
265
+ }
266
+ else
267
+ {
268
+ read_item(visitor, ec);
269
+ }
270
+ break;
271
+ }
272
+ case parse_mode::map_key:
273
+ {
274
+ if (state_stack_.back().index < state_stack_.back().length)
275
+ {
276
+ ++state_stack_.back().index;
277
+ state_stack_.back().mode = parse_mode::map_value;
278
+ read_item(visitor, ec);
279
+ }
280
+ else
281
+ {
282
+ end_object(visitor, ec);
283
+ }
284
+ break;
285
+ }
286
+ case parse_mode::map_value:
287
+ {
288
+ state_stack_.back().mode = parse_mode::map_key;
289
+ read_item(visitor, ec);
290
+ break;
291
+ }
292
+ case parse_mode::indefinite_map_key:
293
+ {
294
+ auto c = source_.peek();
295
+ if (c.eof)
296
+ {
297
+ ec = cbor_errc::unexpected_eof;
298
+ more_ = false;
299
+ return;
300
+ }
301
+ if (c.value == 0xff)
302
+ {
303
+ source_.ignore(1);
304
+ end_object(visitor, ec);
305
+ }
306
+ else
307
+ {
308
+ state_stack_.back().mode = parse_mode::indefinite_map_value;
309
+ read_item(visitor, ec);
310
+ }
311
+ break;
312
+ }
313
+ case parse_mode::indefinite_map_value:
314
+ {
315
+ state_stack_.back().mode = parse_mode::indefinite_map_key;
316
+ read_item(visitor, ec);
317
+ break;
318
+ }
319
+ case parse_mode::root:
320
+ {
321
+ state_stack_.back().mode = parse_mode::accept;
322
+ read_item(visitor, ec);
323
+ break;
324
+ }
325
+ case parse_mode::accept:
326
+ {
327
+ JSONCONS_ASSERT(state_stack_.size() == 1);
328
+ state_stack_.clear();
329
+ more_ = false;
330
+ done_ = true;
331
+ visitor.flush();
332
+ break;
333
+ }
334
+ }
335
+ }
336
+ }
337
+ private:
338
+ void read_item(json_visitor2& visitor, std::error_code& ec)
339
+ {
340
+ read_tags(ec);
341
+ if (!more_)
342
+ {
343
+ return;
344
+ }
345
+ auto c = source_.peek();
346
+ if (c.eof)
347
+ {
348
+ ec = cbor_errc::unexpected_eof;
349
+ more_ = false;
350
+ return;
351
+ }
352
+ jsoncons::cbor::detail::cbor_major_type major_type = get_major_type(c.value);
353
+ uint8_t info = get_additional_information_value(c.value);
354
+
355
+ switch (major_type)
356
+ {
357
+ case jsoncons::cbor::detail::cbor_major_type::unsigned_integer:
358
+ {
359
+ uint64_t val = get_uint64_value(ec);
360
+ if (ec)
361
+ {
362
+ return;
363
+ }
364
+ if (!stringref_map_stack_.empty() && other_tags_[stringref_tag])
365
+ {
366
+ other_tags_[stringref_tag] = false;
367
+ if (val >= stringref_map_stack_.back().size())
368
+ {
369
+ ec = cbor_errc::stringref_too_large;
370
+ more_ = false;
371
+ return;
372
+ }
373
+ stringref_map::size_type index = (stringref_map::size_type)val;
374
+ if (index != val)
375
+ {
376
+ ec = cbor_errc::number_too_large;
377
+ more_ = false;
378
+ return;
379
+ }
380
+ auto& str = stringref_map_stack_.back().at(index);
381
+ switch (str.type)
382
+ {
383
+ case jsoncons::cbor::detail::cbor_major_type::text_string:
384
+ {
385
+ handle_string(visitor, jsoncons::basic_string_view<char>(str.s.data(),str.s.length()),ec);
386
+ if (ec)
387
+ {
388
+ return;
389
+ }
390
+ break;
391
+ }
392
+ case jsoncons::cbor::detail::cbor_major_type::byte_string:
393
+ {
394
+ read_byte_string_from_buffer read(byte_string_view(str.bytes));
395
+ write_byte_string(read, visitor, ec);
396
+ if (ec)
397
+ {
398
+ return;
399
+ }
400
+ break;
401
+ }
402
+ default:
403
+ JSONCONS_UNREACHABLE();
404
+ break;
405
+ }
406
+ }
407
+ else
408
+ {
409
+ semantic_tag tag = semantic_tag::none;
410
+ if (other_tags_[item_tag])
411
+ {
412
+ if (item_tag_ == 1)
413
+ {
414
+ tag = semantic_tag::epoch_second;
415
+ }
416
+ other_tags_[item_tag] = false;
417
+ }
418
+ more_ = visitor.uint64_value(val, tag, *this, ec);
419
+ }
420
+ break;
421
+ }
422
+ case jsoncons::cbor::detail::cbor_major_type::negative_integer:
423
+ {
424
+ int64_t val = get_int64_value(ec);
425
+ if (ec)
426
+ {
427
+ return;
428
+ }
429
+ semantic_tag tag = semantic_tag::none;
430
+ if (other_tags_[item_tag])
431
+ {
432
+ if (item_tag_ == 1)
433
+ {
434
+ tag = semantic_tag::epoch_second;
435
+ }
436
+ other_tags_[item_tag] = false;
437
+ }
438
+ more_ = visitor.int64_value(val, tag, *this, ec);
439
+ break;
440
+ }
441
+ case jsoncons::cbor::detail::cbor_major_type::byte_string:
442
+ {
443
+ read_byte_string_from_source read(this);
444
+ write_byte_string(read, visitor, ec);
445
+ if (ec)
446
+ {
447
+ return;
448
+ }
449
+ break;
450
+ }
451
+ case jsoncons::cbor::detail::cbor_major_type::text_string:
452
+ {
453
+ text_buffer_.clear();
454
+ read_text_string(text_buffer_, ec);
455
+ if (ec)
456
+ {
457
+ return;
458
+ }
459
+ auto result = unicode_traits::validate(text_buffer_.data(),text_buffer_.size());
460
+ if (result.ec != unicode_traits::conv_errc())
461
+ {
462
+ ec = cbor_errc::invalid_utf8_text_string;
463
+ more_ = false;
464
+ return;
465
+ }
466
+ handle_string(visitor, jsoncons::basic_string_view<char>(text_buffer_.data(),text_buffer_.length()),ec);
467
+ if (ec)
468
+ {
469
+ return;
470
+ }
471
+ break;
472
+ }
473
+ case jsoncons::cbor::detail::cbor_major_type::semantic_tag:
474
+ {
475
+ JSONCONS_UNREACHABLE();
476
+ break;
477
+ }
478
+ case jsoncons::cbor::detail::cbor_major_type::simple:
479
+ {
480
+ switch (info)
481
+ {
482
+ case 0x14:
483
+ more_ = visitor.bool_value(false, semantic_tag::none, *this, ec);
484
+ source_.ignore(1);
485
+ break;
486
+ case 0x15:
487
+ more_ = visitor.bool_value(true, semantic_tag::none, *this, ec);
488
+ source_.ignore(1);
489
+ break;
490
+ case 0x16:
491
+ more_ = visitor.null_value(semantic_tag::none, *this, ec);
492
+ source_.ignore(1);
493
+ break;
494
+ case 0x17:
495
+ more_ = visitor.null_value(semantic_tag::undefined, *this, ec);
496
+ source_.ignore(1);
497
+ break;
498
+ case 0x19: // Half-Precision Float (two-byte IEEE 754)
499
+ {
500
+ uint64_t val = get_uint64_value(ec);
501
+ if (ec)
502
+ {
503
+ return;
504
+ }
505
+ more_ = visitor.half_value(static_cast<uint16_t>(val), semantic_tag::none, *this, ec);
506
+ break;
507
+ }
508
+ case 0x1a: // Single-Precision Float (four-byte IEEE 754)
509
+ case 0x1b: // Double-Precision Float (eight-byte IEEE 754)
510
+ {
511
+ double val = get_double(ec);
512
+ if (ec)
513
+ {
514
+ return;
515
+ }
516
+ semantic_tag tag = semantic_tag::none;
517
+ if (other_tags_[item_tag])
518
+ {
519
+ if (item_tag_ == 1)
520
+ {
521
+ tag = semantic_tag::epoch_second;
522
+ }
523
+ other_tags_[item_tag] = false;
524
+ }
525
+ more_ = visitor.double_value(val, tag, *this, ec);
526
+ break;
527
+ }
528
+ default:
529
+ {
530
+ ec = cbor_errc::unknown_type;
531
+ more_ = false;
532
+ return;
533
+ }
534
+ }
535
+ break;
536
+ }
537
+ case jsoncons::cbor::detail::cbor_major_type::array:
538
+ {
539
+ if (other_tags_[item_tag])
540
+ {
541
+ switch (item_tag_)
542
+ {
543
+ case 0x04:
544
+ text_buffer_.clear();
545
+ read_decimal_fraction(text_buffer_, ec);
546
+ if (ec)
547
+ {
548
+ return;
549
+ }
550
+ more_ = visitor.string_value(text_buffer_, semantic_tag::bigdec, *this, ec);
551
+ break;
552
+ case 0x05:
553
+ text_buffer_.clear();
554
+ read_bigfloat(text_buffer_, ec);
555
+ if (ec)
556
+ {
557
+ return;
558
+ }
559
+ more_ = visitor.string_value(text_buffer_, semantic_tag::bigfloat, *this, ec);
560
+ break;
561
+ case 40: // row major storage
562
+ produce_begin_multi_dim(visitor, semantic_tag::multi_dim_row_major, ec);
563
+ break;
564
+ case 1040: // column major storage
565
+ produce_begin_multi_dim(visitor, semantic_tag::multi_dim_column_major, ec);
566
+ break;
567
+ default:
568
+ begin_array(visitor, info, ec);
569
+ break;
570
+ }
571
+ other_tags_[item_tag] = false;
572
+ }
573
+ else
574
+ {
575
+ begin_array(visitor, info, ec);
576
+ }
577
+ break;
578
+ }
579
+ case jsoncons::cbor::detail::cbor_major_type::map:
580
+ {
581
+ begin_object(visitor, info, ec);
582
+ break;
583
+ }
584
+ default:
585
+ break;
586
+ }
587
+ other_tags_[item_tag] = false;
588
+ }
589
+
590
+ void begin_array(json_visitor2& visitor, uint8_t info, std::error_code& ec)
591
+ {
592
+ if (JSONCONS_UNLIKELY(++nesting_depth_ > options_.max_nesting_depth()))
593
+ {
594
+ ec = cbor_errc::max_nesting_depth_exceeded;
595
+ more_ = false;
596
+ return;
597
+ }
598
+ semantic_tag tag = semantic_tag::none;
599
+ bool pop_stringref_map_stack = false;
600
+ if (other_tags_[stringref_namespace_tag])
601
+ {
602
+ stringref_map_stack_.emplace_back(alloc_);
603
+ other_tags_[stringref_namespace_tag] = false;
604
+ pop_stringref_map_stack = true;
605
+ }
606
+ switch (info)
607
+ {
608
+ case jsoncons::cbor::detail::additional_info::indefinite_length:
609
+ {
610
+ state_stack_.emplace_back(parse_mode::indefinite_array,0,pop_stringref_map_stack);
611
+ more_ = visitor.begin_array(tag, *this, ec);
612
+ source_.ignore(1);
613
+ break;
614
+ }
615
+ default: // definite length
616
+ {
617
+ std::size_t len = get_size(ec);
618
+ if (!more_)
619
+ {
620
+ return;
621
+ }
622
+ state_stack_.emplace_back(parse_mode::array,len,pop_stringref_map_stack);
623
+ more_ = visitor.begin_array(len, tag, *this, ec);
624
+ break;
625
+ }
626
+ }
627
+ }
628
+
629
+ void end_array(json_visitor2& visitor, std::error_code& ec)
630
+ {
631
+ --nesting_depth_;
632
+
633
+ more_ = visitor.end_array(*this, ec);
634
+ if (state_stack_.back().pop_stringref_map_stack)
635
+ {
636
+ stringref_map_stack_.pop_back();
637
+ }
638
+ state_stack_.pop_back();
639
+ }
640
+
641
+ void begin_object(json_visitor2& visitor, uint8_t info, std::error_code& ec)
642
+ {
643
+ if (JSONCONS_UNLIKELY(++nesting_depth_ > options_.max_nesting_depth()))
644
+ {
645
+ ec = cbor_errc::max_nesting_depth_exceeded;
646
+ more_ = false;
647
+ return;
648
+ }
649
+ bool pop_stringref_map_stack = false;
650
+ if (other_tags_[stringref_namespace_tag])
651
+ {
652
+ stringref_map_stack_.emplace_back(alloc_);
653
+ other_tags_[stringref_namespace_tag] = false;
654
+ pop_stringref_map_stack = true;
655
+ }
656
+ switch (info)
657
+ {
658
+ case jsoncons::cbor::detail::additional_info::indefinite_length:
659
+ {
660
+ state_stack_.emplace_back(parse_mode::indefinite_map_key,0,pop_stringref_map_stack);
661
+ more_ = visitor.begin_object(semantic_tag::none, *this, ec);
662
+ source_.ignore(1);
663
+ break;
664
+ }
665
+ default: // definite_length
666
+ {
667
+ std::size_t len = get_size(ec);
668
+ if (!more_)
669
+ {
670
+ return;
671
+ }
672
+ state_stack_.emplace_back(parse_mode::map_key,len,pop_stringref_map_stack);
673
+ more_ = visitor.begin_object(len, semantic_tag::none, *this, ec);
674
+ break;
675
+ }
676
+ }
677
+ }
678
+
679
+ void end_object(json_visitor2& visitor, std::error_code& ec)
680
+ {
681
+ --nesting_depth_;
682
+ more_ = visitor.end_object(*this, ec);
683
+ if (state_stack_.back().pop_stringref_map_stack)
684
+ {
685
+ stringref_map_stack_.pop_back();
686
+ }
687
+ state_stack_.pop_back();
688
+ }
689
+
690
+ void read_text_string(string_type& s, std::error_code& ec)
691
+ {
692
+ auto c = source_.peek();
693
+ if (c.eof)
694
+ {
695
+ ec = cbor_errc::unexpected_eof;
696
+ more_ = false;
697
+ return;
698
+ }
699
+ jsoncons::cbor::detail::cbor_major_type major_type = get_major_type(c.value);
700
+ uint8_t info = get_additional_information_value(c.value);
701
+
702
+ JSONCONS_ASSERT(major_type == jsoncons::cbor::detail::cbor_major_type::text_string);
703
+ auto func = [&s](Source& source, std::size_t length, std::error_code& ec) -> bool
704
+ {
705
+ if (source_reader<Source>::read(source, s, length) != length)
706
+ {
707
+ ec = cbor_errc::unexpected_eof;
708
+ return false;
709
+ }
710
+ return true;
711
+ };
712
+ iterate_string_chunks(func, major_type, ec);
713
+ if (!stringref_map_stack_.empty() &&
714
+ info != jsoncons::cbor::detail::additional_info::indefinite_length &&
715
+ s.length() >= jsoncons::cbor::detail::min_length_for_stringref(stringref_map_stack_.back().size()))
716
+ {
717
+ stringref_map_stack_.back().emplace_back(s);
718
+ }
719
+ }
720
+
721
+ std::size_t get_size(std::error_code& ec)
722
+ {
723
+ uint64_t u = get_uint64_value(ec);
724
+ if (!more_)
725
+ {
726
+ return 0;
727
+ }
728
+ std::size_t len = static_cast<std::size_t>(u);
729
+ if (len != u)
730
+ {
731
+ ec = cbor_errc::number_too_large;
732
+ more_ = false;
733
+ }
734
+ return len;
735
+ }
736
+
737
+ bool read_byte_string(std::vector<uint8_t,byte_allocator_type>& v, std::error_code& ec)
738
+ {
739
+ bool more = true;
740
+ v.clear();
741
+ auto c = source_.peek();
742
+ if (c.eof)
743
+ {
744
+ ec = cbor_errc::unexpected_eof;
745
+ more = false;
746
+ return more;
747
+ }
748
+ jsoncons::cbor::detail::cbor_major_type major_type = get_major_type(c.value);
749
+ uint8_t info = get_additional_information_value(c.value);
750
+
751
+ JSONCONS_ASSERT(major_type == jsoncons::cbor::detail::cbor_major_type::byte_string);
752
+
753
+ switch(info)
754
+ {
755
+ case jsoncons::cbor::detail::additional_info::indefinite_length:
756
+ {
757
+ auto func = [&v,&more](Source& source, std::size_t length, std::error_code& ec) -> bool
758
+ {
759
+ if (source_reader<Source>::read(source, v, length) != length)
760
+ {
761
+ ec = cbor_errc::unexpected_eof;
762
+ more = false;
763
+ return more;
764
+ }
765
+ return true;
766
+ };
767
+ iterate_string_chunks(func, major_type, ec);
768
+ break;
769
+ }
770
+ default:
771
+ {
772
+ std::size_t length = get_size(ec);
773
+ if (ec)
774
+ {
775
+ more = false;
776
+ return more;
777
+ }
778
+ if (source_reader<Source>::read(source_, v, length) != length)
779
+ {
780
+ ec = cbor_errc::unexpected_eof;
781
+ more = false;
782
+ return more;
783
+ }
784
+ if (!stringref_map_stack_.empty() &&
785
+ v.size() >= jsoncons::cbor::detail::min_length_for_stringref(stringref_map_stack_.back().size()))
786
+ {
787
+ stringref_map_stack_.back().emplace_back(v);
788
+ }
789
+ break;
790
+ }
791
+ }
792
+ return more;
793
+ }
794
+
795
+ template <class Function>
796
+ void iterate_string_chunks(Function& func, jsoncons::cbor::detail::cbor_major_type type, std::error_code& ec)
797
+ {
798
+ int nesting_level = 0;
799
+
800
+ bool done = false;
801
+ while (!done)
802
+ {
803
+ auto c = source_.peek();
804
+ if (c.eof)
805
+ {
806
+ ec = cbor_errc::unexpected_eof;
807
+ more_ = false;
808
+ return;
809
+ }
810
+ if (nesting_level > 0 && c.value == 0xff)
811
+ {
812
+ --nesting_level;
813
+ if (nesting_level == 0)
814
+ {
815
+ done = true;
816
+ }
817
+ source_.ignore(1);
818
+ continue;
819
+ }
820
+
821
+ jsoncons::cbor::detail::cbor_major_type major_type = get_major_type(c.value);
822
+ if (major_type != type)
823
+ {
824
+ ec = cbor_errc::illegal_chunked_string;
825
+ more_ = false;
826
+ return;
827
+ }
828
+ uint8_t info = get_additional_information_value(c.value);
829
+
830
+ switch (info)
831
+ {
832
+ case jsoncons::cbor::detail::additional_info::indefinite_length:
833
+ {
834
+ ++nesting_level;
835
+ source_.ignore(1);
836
+ break;
837
+ }
838
+ default: // definite length
839
+ {
840
+ std::size_t length = get_size(ec);
841
+ if (!more_)
842
+ {
843
+ return;
844
+ }
845
+ more_ = func(source_, length, ec);
846
+ if (!more_)
847
+ {
848
+ return;
849
+ }
850
+ if (nesting_level == 0)
851
+ {
852
+ done = true;
853
+ }
854
+ break;
855
+ }
856
+ }
857
+ }
858
+ }
859
+
860
+ uint64_t get_uint64_value(std::error_code& ec)
861
+ {
862
+ uint64_t val = 0;
863
+
864
+ uint8_t initial_b;
865
+ if (source_.read(&initial_b, 1) == 0)
866
+ {
867
+ ec = cbor_errc::unexpected_eof;
868
+ more_ = false;
869
+ return 0;
870
+ }
871
+ uint8_t info = get_additional_information_value(initial_b);
872
+ switch (info)
873
+ {
874
+ case JSONCONS_CBOR_0x00_0x17: // Integer 0x00..0x17 (0..23)
875
+ {
876
+ val = info;
877
+ break;
878
+ }
879
+
880
+ case 0x18: // Unsigned integer (one-byte uint8_t follows)
881
+ {
882
+ uint8_t b;
883
+ if (source_.read(&b, 1) == 0)
884
+ {
885
+ ec = cbor_errc::unexpected_eof;
886
+ more_ = false;
887
+ return val;
888
+ }
889
+ val = b;
890
+ break;
891
+ }
892
+
893
+ case 0x19: // Unsigned integer (two-byte uint16_t follows)
894
+ {
895
+ uint8_t buf[sizeof(uint16_t)];
896
+ source_.read(buf, sizeof(uint16_t));
897
+ val = binary::big_to_native<uint16_t>(buf, sizeof(buf));
898
+ break;
899
+ }
900
+
901
+ case 0x1a: // Unsigned integer (four-byte uint32_t follows)
902
+ {
903
+ uint8_t buf[sizeof(uint32_t)];
904
+ source_.read(buf, sizeof(uint32_t));
905
+ val = binary::big_to_native<uint32_t>(buf, sizeof(buf));
906
+ break;
907
+ }
908
+
909
+ case 0x1b: // Unsigned integer (eight-byte uint64_t follows)
910
+ {
911
+ uint8_t buf[sizeof(uint64_t)];
912
+ source_.read(buf, sizeof(uint64_t));
913
+ val = binary::big_to_native<uint64_t>(buf, sizeof(buf));
914
+ break;
915
+ }
916
+ default:
917
+ break;
918
+ }
919
+ return val;
920
+ }
921
+
922
+ int64_t get_int64_value(std::error_code& ec)
923
+ {
924
+ int64_t val = 0;
925
+
926
+ auto ch = source_.peek();
927
+ if (ch.eof)
928
+ {
929
+ ec = cbor_errc::unexpected_eof;
930
+ more_ = false;
931
+ return val;
932
+ }
933
+
934
+ jsoncons::cbor::detail::cbor_major_type major_type = get_major_type(ch.value);
935
+ uint8_t info = get_additional_information_value(ch.value);
936
+ switch (major_type)
937
+ {
938
+ case jsoncons::cbor::detail::cbor_major_type::negative_integer:
939
+ source_.ignore(1);
940
+ switch (info)
941
+ {
942
+ case JSONCONS_CBOR_0x00_0x17: // 0x00..0x17 (0..23)
943
+ {
944
+ val = static_cast<int8_t>(- 1 - info);
945
+ break;
946
+ }
947
+ case 0x18: // Negative integer (one-byte uint8_t follows)
948
+ {
949
+ uint8_t b;
950
+ if (source_.read(&b, 1) == 0)
951
+ {
952
+ ec = cbor_errc::unexpected_eof;
953
+ more_ = false;
954
+ return val;
955
+ }
956
+ val = static_cast<int64_t>(-1) - static_cast<int64_t>(b);
957
+ break;
958
+ }
959
+
960
+ case 0x19: // Negative integer -1-n (two-byte uint16_t follows)
961
+ {
962
+ uint8_t buf[sizeof(uint16_t)];
963
+ if (source_.read(buf, sizeof(uint16_t)) != sizeof(uint16_t))
964
+ {
965
+ ec = cbor_errc::unexpected_eof;
966
+ more_ = false;
967
+ return val;
968
+ }
969
+ auto x = binary::big_to_native<uint16_t>(buf, sizeof(buf));
970
+ val = static_cast<int64_t>(-1)- x;
971
+ break;
972
+ }
973
+
974
+ case 0x1a: // Negative integer -1-n (four-byte uint32_t follows)
975
+ {
976
+ uint8_t buf[sizeof(uint32_t)];
977
+ if (source_.read(buf, sizeof(uint32_t)) != sizeof(uint32_t))
978
+ {
979
+ ec = cbor_errc::unexpected_eof;
980
+ more_ = false;
981
+ return val;
982
+ }
983
+ auto x = binary::big_to_native<uint32_t>(buf, sizeof(buf));
984
+ val = static_cast<int64_t>(-1)- x;
985
+ break;
986
+ }
987
+
988
+ case 0x1b: // Negative integer -1-n (eight-byte uint64_t follows)
989
+ {
990
+ uint8_t buf[sizeof(uint64_t)];
991
+ if (source_.read(buf, sizeof(uint64_t)) != sizeof(uint64_t))
992
+ {
993
+ ec = cbor_errc::unexpected_eof;
994
+ more_ = false;
995
+ return val;
996
+ }
997
+ auto x = binary::big_to_native<uint64_t>(buf, sizeof(buf));
998
+ val = static_cast<int64_t>(-1)- static_cast<int64_t>(x);
999
+ break;
1000
+ }
1001
+ }
1002
+ break;
1003
+
1004
+ case jsoncons::cbor::detail::cbor_major_type::unsigned_integer:
1005
+ {
1006
+ uint64_t x = get_uint64_value(ec);
1007
+ if (ec)
1008
+ {
1009
+ return 0;
1010
+ }
1011
+ if (x <= static_cast<uint64_t>((std::numeric_limits<int64_t>::max)()))
1012
+ {
1013
+ val = x;
1014
+ }
1015
+ else
1016
+ {
1017
+ // error;
1018
+ }
1019
+
1020
+ break;
1021
+ }
1022
+ break;
1023
+ default:
1024
+ break;
1025
+ }
1026
+
1027
+ return val;
1028
+ }
1029
+
1030
+ double get_double(std::error_code& ec)
1031
+ {
1032
+ double val = 0;
1033
+
1034
+ uint8_t b;
1035
+ if (source_.read(&b, 1) == 0)
1036
+ {
1037
+ ec = cbor_errc::unexpected_eof;
1038
+ more_ = false;
1039
+ return 0;
1040
+ }
1041
+ uint8_t info = get_additional_information_value(b);
1042
+ switch (info)
1043
+ {
1044
+ case 0x1a: // Single-Precision Float (four-byte IEEE 754)
1045
+ {
1046
+ uint8_t buf[sizeof(float)];
1047
+ if (source_.read(buf, sizeof(float)) !=sizeof(float))
1048
+ {
1049
+ ec = cbor_errc::unexpected_eof;
1050
+ more_ = false;
1051
+ return 0;
1052
+ }
1053
+ val = binary::big_to_native<float>(buf, sizeof(buf));
1054
+ break;
1055
+ }
1056
+
1057
+ case 0x1b: // Double-Precision Float (eight-byte IEEE 754)
1058
+ {
1059
+ uint8_t buf[sizeof(double)];
1060
+ if (source_.read(buf, sizeof(double)) != sizeof(double))
1061
+ {
1062
+ ec = cbor_errc::unexpected_eof;
1063
+ more_ = false;
1064
+ return 0;
1065
+ }
1066
+ val = binary::big_to_native<double>(buf, sizeof(buf));
1067
+ break;
1068
+ }
1069
+ default:
1070
+ break;
1071
+ }
1072
+
1073
+ return val;
1074
+ }
1075
+
1076
+ void read_decimal_fraction(string_type& result, std::error_code& ec)
1077
+ {
1078
+ std::size_t size = get_size(ec);
1079
+ if (!more_)
1080
+ {
1081
+ return;
1082
+ }
1083
+ if (size != 2)
1084
+ {
1085
+ ec = cbor_errc::invalid_decimal_fraction;
1086
+ more_ = false;
1087
+ return;
1088
+ }
1089
+
1090
+ auto c = source_.peek();
1091
+ if (c.eof)
1092
+ {
1093
+ ec = cbor_errc::unexpected_eof;
1094
+ more_ = false;
1095
+ return;
1096
+ }
1097
+ int64_t exponent = 0;
1098
+ switch (get_major_type(c.value))
1099
+ {
1100
+ case jsoncons::cbor::detail::cbor_major_type::unsigned_integer:
1101
+ {
1102
+ exponent = get_uint64_value(ec);
1103
+ if (ec)
1104
+ {
1105
+ return;
1106
+ }
1107
+ break;
1108
+ }
1109
+ case jsoncons::cbor::detail::cbor_major_type::negative_integer:
1110
+ {
1111
+ exponent = get_int64_value(ec);
1112
+ if (ec)
1113
+ {
1114
+ return;
1115
+ }
1116
+ break;
1117
+ }
1118
+ default:
1119
+ {
1120
+ ec = cbor_errc::invalid_decimal_fraction;
1121
+ more_ = false;
1122
+ return;
1123
+ }
1124
+ }
1125
+
1126
+ string_type s;
1127
+
1128
+ c = source_.peek();
1129
+ if (c.eof)
1130
+ {
1131
+ ec = cbor_errc::unexpected_eof;
1132
+ more_ = false;
1133
+ return;
1134
+ }
1135
+
1136
+ switch (get_major_type(c.value))
1137
+ {
1138
+ case jsoncons::cbor::detail::cbor_major_type::unsigned_integer:
1139
+ {
1140
+ uint64_t val = get_uint64_value(ec);
1141
+ if (ec)
1142
+ {
1143
+ return;
1144
+ }
1145
+ jsoncons::detail::from_integer(val, s);
1146
+ break;
1147
+ }
1148
+ case jsoncons::cbor::detail::cbor_major_type::negative_integer:
1149
+ {
1150
+ int64_t val = get_int64_value(ec);
1151
+ if (ec)
1152
+ {
1153
+ return;
1154
+ }
1155
+ jsoncons::detail::from_integer(val, s);
1156
+ break;
1157
+ }
1158
+ case jsoncons::cbor::detail::cbor_major_type::semantic_tag:
1159
+ {
1160
+ uint8_t b;
1161
+ if (source_.read(&b, 1) == 0)
1162
+ {
1163
+ ec = cbor_errc::unexpected_eof;
1164
+ more_ = false;
1165
+ return;
1166
+ }
1167
+ uint8_t tag = get_additional_information_value(b);
1168
+ c = source_.peek();
1169
+ if (c.eof)
1170
+ {
1171
+ ec = cbor_errc::unexpected_eof;
1172
+ more_ = false;
1173
+ return;
1174
+ }
1175
+
1176
+ if (get_major_type(c.value) == jsoncons::cbor::detail::cbor_major_type::byte_string)
1177
+ {
1178
+ bytes_buffer_.clear();
1179
+ read_byte_string(bytes_buffer_, ec);
1180
+ if (ec)
1181
+ {
1182
+ more_ = false;
1183
+ return;
1184
+ }
1185
+ if (tag == 2)
1186
+ {
1187
+ bigint n = bigint::from_bytes_be(1, bytes_buffer_.data(), bytes_buffer_.size());
1188
+ n.write_string(s);
1189
+ }
1190
+ else if (tag == 3)
1191
+ {
1192
+ bigint n = bigint::from_bytes_be(1, bytes_buffer_.data(), bytes_buffer_.size());
1193
+ n = -1 - n;
1194
+ n.write_string(s);
1195
+ }
1196
+ }
1197
+ break;
1198
+ }
1199
+ default:
1200
+ {
1201
+ ec = cbor_errc::invalid_decimal_fraction;
1202
+ more_ = false;
1203
+ return;
1204
+ }
1205
+ }
1206
+
1207
+ if (s.size() >= static_cast<std::size_t>((std::numeric_limits<int32_t>::max)()) ||
1208
+ exponent >= (std::numeric_limits<int32_t>::max)() ||
1209
+ exponent <= (std::numeric_limits<int32_t>::min)())
1210
+ {
1211
+ ec = cbor_errc::invalid_decimal_fraction;
1212
+ more_ = false;
1213
+ return;
1214
+ }
1215
+ else if (s.size() > 0)
1216
+ {
1217
+ if (s[0] == '-')
1218
+ {
1219
+ result.push_back('-');
1220
+ jsoncons::detail::prettify_string(s.c_str()+1, s.size()-1, (int)exponent, -4, 17, result);
1221
+ }
1222
+ else
1223
+ {
1224
+ jsoncons::detail::prettify_string(s.c_str(), s.size(), (int)exponent, -4, 17, result);
1225
+ }
1226
+ }
1227
+ else
1228
+ {
1229
+ ec = cbor_errc::invalid_decimal_fraction;
1230
+ more_ = false;
1231
+ return;
1232
+ }
1233
+ }
1234
+
1235
+ void read_bigfloat(string_type& s, std::error_code& ec)
1236
+ {
1237
+ std::size_t size = get_size(ec);
1238
+ if (!more_)
1239
+ {
1240
+ return;
1241
+ }
1242
+ if (size != 2)
1243
+ {
1244
+ ec = cbor_errc::invalid_bigfloat;
1245
+ more_ = false;
1246
+ return;
1247
+ }
1248
+
1249
+ auto c = source_.peek();
1250
+ if (c.eof)
1251
+ {
1252
+ ec = cbor_errc::unexpected_eof;
1253
+ more_ = false;
1254
+ return;
1255
+ }
1256
+ int64_t exponent = 0;
1257
+ switch (get_major_type(c.value))
1258
+ {
1259
+ case jsoncons::cbor::detail::cbor_major_type::unsigned_integer:
1260
+ {
1261
+ exponent = get_uint64_value(ec);
1262
+ if (ec)
1263
+ {
1264
+ return;
1265
+ }
1266
+ break;
1267
+ }
1268
+ case jsoncons::cbor::detail::cbor_major_type::negative_integer:
1269
+ {
1270
+ exponent = get_int64_value(ec);
1271
+ if (ec)
1272
+ {
1273
+ return;
1274
+ }
1275
+ break;
1276
+ }
1277
+ default:
1278
+ {
1279
+ ec = cbor_errc::invalid_bigfloat;
1280
+ more_ = false;
1281
+ return;
1282
+ }
1283
+ }
1284
+
1285
+ c = source_.peek();
1286
+ if (c.eof)
1287
+ {
1288
+ ec = cbor_errc::unexpected_eof;
1289
+ more_ = false;
1290
+ return;
1291
+ }
1292
+ switch (get_major_type(c.value))
1293
+ {
1294
+ case jsoncons::cbor::detail::cbor_major_type::unsigned_integer:
1295
+ {
1296
+ uint64_t val = get_uint64_value(ec);
1297
+ if (ec)
1298
+ {
1299
+ return;
1300
+ }
1301
+ s.push_back('0');
1302
+ s.push_back('x');
1303
+ jsoncons::detail::integer_to_string_hex(val, s);
1304
+ break;
1305
+ }
1306
+ case jsoncons::cbor::detail::cbor_major_type::negative_integer:
1307
+ {
1308
+ int64_t val = get_int64_value(ec);
1309
+ if (ec)
1310
+ {
1311
+ return;
1312
+ }
1313
+ s.push_back('-');
1314
+ s.push_back('0');
1315
+ s.push_back('x');
1316
+ jsoncons::detail::integer_to_string_hex(static_cast<uint64_t>(-val), s);
1317
+ break;
1318
+ }
1319
+ case jsoncons::cbor::detail::cbor_major_type::semantic_tag:
1320
+ {
1321
+ uint8_t b;
1322
+ if (source_.read(&b, 1) == 0)
1323
+ {
1324
+ ec = cbor_errc::unexpected_eof;
1325
+ more_ = false;
1326
+ return;
1327
+ }
1328
+ uint8_t tag = get_additional_information_value(b);
1329
+
1330
+ c = source_.peek();
1331
+ if (c.eof)
1332
+ {
1333
+ ec = cbor_errc::unexpected_eof;
1334
+ more_ = false;
1335
+ return;
1336
+ }
1337
+
1338
+ if (get_major_type(c.value) == jsoncons::cbor::detail::cbor_major_type::byte_string)
1339
+ {
1340
+ bytes_buffer_.clear();
1341
+ more_ = read_byte_string(bytes_buffer_, ec);
1342
+ if (!more_)
1343
+ {
1344
+ return;
1345
+ }
1346
+ if (tag == 2)
1347
+ {
1348
+ s.push_back('0');
1349
+ s.push_back('x');
1350
+ bigint n = bigint::from_bytes_be(1, bytes_buffer_.data(), bytes_buffer_.size());
1351
+ n.write_string_hex(s);
1352
+ }
1353
+ else if (tag == 3)
1354
+ {
1355
+ s.push_back('-');
1356
+ s.push_back('0');
1357
+ bigint n = bigint::from_bytes_be(1, bytes_buffer_.data(), bytes_buffer_.size());
1358
+ n = -1 - n;
1359
+ n.write_string_hex(s);
1360
+ s[2] = 'x'; // overwrite minus
1361
+ }
1362
+ }
1363
+ break;
1364
+ }
1365
+ default:
1366
+ {
1367
+ ec = cbor_errc::invalid_bigfloat;
1368
+ more_ = false;
1369
+ return;
1370
+ }
1371
+ }
1372
+
1373
+ s.push_back('p');
1374
+ if (exponent >=0)
1375
+ {
1376
+ jsoncons::detail::integer_to_string_hex(static_cast<uint64_t>(exponent), s);
1377
+ }
1378
+ else
1379
+ {
1380
+ s.push_back('-');
1381
+ jsoncons::detail::integer_to_string_hex(static_cast<uint64_t>(-exponent), s);
1382
+ }
1383
+ }
1384
+
1385
+ static jsoncons::cbor::detail::cbor_major_type get_major_type(uint8_t type)
1386
+ {
1387
+ static constexpr uint8_t major_type_shift = 0x05;
1388
+ uint8_t value = type >> major_type_shift;
1389
+ return static_cast<jsoncons::cbor::detail::cbor_major_type>(value);
1390
+ }
1391
+
1392
+ static uint8_t get_additional_information_value(uint8_t type)
1393
+ {
1394
+ static constexpr uint8_t additional_information_mask = (1U << 5) - 1;
1395
+ uint8_t value = type & additional_information_mask;
1396
+ return value;
1397
+ }
1398
+
1399
+ void read_tags(std::error_code& ec)
1400
+ {
1401
+ auto c = source_.peek();
1402
+ if (c.eof)
1403
+ {
1404
+ ec = cbor_errc::unexpected_eof;
1405
+ more_ = false;
1406
+ return;
1407
+ }
1408
+ jsoncons::cbor::detail::cbor_major_type major_type = get_major_type(c.value);
1409
+
1410
+ while (major_type == jsoncons::cbor::detail::cbor_major_type::semantic_tag)
1411
+ {
1412
+ uint64_t val = get_uint64_value(ec);
1413
+ if (!more_)
1414
+ {
1415
+ return;
1416
+ }
1417
+ switch(val)
1418
+ {
1419
+ case 25: // stringref
1420
+ other_tags_[stringref_tag] = true;
1421
+ break;
1422
+ case 256: // stringref-namespace
1423
+ other_tags_[stringref_namespace_tag] = true;
1424
+ break;
1425
+ default:
1426
+ other_tags_[item_tag] = true;
1427
+ item_tag_ = val;
1428
+ break;
1429
+ }
1430
+ c = source_.peek();
1431
+ if (c.eof)
1432
+ {
1433
+ ec = cbor_errc::unexpected_eof;
1434
+ more_ = false;
1435
+ return;
1436
+ }
1437
+ major_type = get_major_type(c.value);
1438
+ }
1439
+ }
1440
+
1441
+ void handle_string(json_visitor2& visitor, const jsoncons::basic_string_view<char>& v, std::error_code& ec)
1442
+ {
1443
+ semantic_tag tag = semantic_tag::none;
1444
+ if (other_tags_[item_tag])
1445
+ {
1446
+ switch (item_tag_)
1447
+ {
1448
+ case 0:
1449
+ tag = semantic_tag::datetime;
1450
+ break;
1451
+ case 32:
1452
+ tag = semantic_tag::uri;
1453
+ break;
1454
+ case 33:
1455
+ tag = semantic_tag::base64url;
1456
+ break;
1457
+ case 34:
1458
+ tag = semantic_tag::base64;
1459
+ break;
1460
+ default:
1461
+ break;
1462
+ }
1463
+ other_tags_[item_tag] = false;
1464
+ }
1465
+ more_ = visitor.string_value(v, tag, *this, ec);
1466
+ }
1467
+
1468
+ static jsoncons::endian get_typed_array_endianness(const uint8_t tag)
1469
+ {
1470
+ return ((tag & detail::cbor_array_tags_e_mask) >> detail::cbor_array_tags_e_shift) == 0 ? jsoncons::endian::big : jsoncons::endian::little;
1471
+ }
1472
+
1473
+ static std::size_t get_typed_array_bytes_per_element(const uint8_t tag)
1474
+ {
1475
+ const uint8_t f = (tag & detail::cbor_array_tags_f_mask) >> detail::cbor_array_tags_f_shift;
1476
+ const uint8_t ll = (tag & detail::cbor_array_tags_ll_mask) >> detail::cbor_array_tags_ll_shift;
1477
+
1478
+ return std::size_t(1) << (f + ll);
1479
+ }
1480
+
1481
+ template <typename Read>
1482
+ void write_byte_string(Read read, json_visitor2& visitor, std::error_code& ec)
1483
+ {
1484
+ if (other_tags_[item_tag])
1485
+ {
1486
+ switch (item_tag_)
1487
+ {
1488
+ case 0x2:
1489
+ {
1490
+ bytes_buffer_.clear();
1491
+ read(bytes_buffer_,ec);
1492
+ if (ec)
1493
+ {
1494
+ more_ = false;
1495
+ return;
1496
+ }
1497
+ bigint n = bigint::from_bytes_be(1, bytes_buffer_.data(), bytes_buffer_.size());
1498
+ text_buffer_.clear();
1499
+ n.write_string(text_buffer_);
1500
+ more_ = visitor.string_value(text_buffer_, semantic_tag::bigint, *this, ec);
1501
+ break;
1502
+ }
1503
+ case 0x3:
1504
+ {
1505
+ bytes_buffer_.clear();
1506
+ read(bytes_buffer_,ec);
1507
+ if (ec)
1508
+ {
1509
+ more_ = false;
1510
+ return;
1511
+ }
1512
+ bigint n = bigint::from_bytes_be(1, bytes_buffer_.data(), bytes_buffer_.size());
1513
+ n = -1 - n;
1514
+ text_buffer_.clear();
1515
+ n.write_string(text_buffer_);
1516
+ more_ = visitor.string_value(text_buffer_, semantic_tag::bigint, *this, ec);
1517
+ break;
1518
+ }
1519
+ case 0x15:
1520
+ {
1521
+ read(bytes_buffer_,ec);
1522
+ if (ec)
1523
+ {
1524
+ more_ = false;
1525
+ return;
1526
+ }
1527
+ more_ = visitor.byte_string_value(bytes_buffer_, semantic_tag::base64url, *this, ec);
1528
+ break;
1529
+ }
1530
+ case 0x16:
1531
+ {
1532
+ read(bytes_buffer_,ec);
1533
+ if (ec)
1534
+ {
1535
+ more_ = false;
1536
+ return;
1537
+ }
1538
+ more_ = visitor.byte_string_value(bytes_buffer_, semantic_tag::base64, *this, ec);
1539
+ break;
1540
+ }
1541
+ case 0x17:
1542
+ {
1543
+ read(bytes_buffer_,ec);
1544
+ if (ec)
1545
+ {
1546
+ more_ = false;
1547
+ return;
1548
+ }
1549
+ more_ = visitor.byte_string_value(bytes_buffer_, semantic_tag::base16, *this, ec);
1550
+ break;
1551
+ }
1552
+ case 0x40:
1553
+ {
1554
+ typed_array_.clear();
1555
+ read(typed_array_,ec);
1556
+ if (ec)
1557
+ {
1558
+ more_ = false;
1559
+ return;
1560
+ }
1561
+ uint8_t* data = reinterpret_cast<uint8_t*>(typed_array_.data());
1562
+ std::size_t size = typed_array_.size();
1563
+ more_ = visitor.typed_array(jsoncons::span<const uint8_t>(data,size), semantic_tag::none, *this, ec);
1564
+ break;
1565
+ }
1566
+ case 0x44:
1567
+ {
1568
+ typed_array_.clear();
1569
+ read(typed_array_,ec);
1570
+ if (ec)
1571
+ {
1572
+ more_ = false;
1573
+ return;
1574
+ }
1575
+ uint8_t* data = reinterpret_cast<uint8_t*>(typed_array_.data());
1576
+ std::size_t size = typed_array_.size();
1577
+ more_ = visitor.typed_array(jsoncons::span<const uint8_t>(data,size), semantic_tag::clamped, *this, ec);
1578
+ break;
1579
+ }
1580
+ case 0x41:
1581
+ case 0x45:
1582
+ {
1583
+ typed_array_.clear();
1584
+ read(typed_array_,ec);
1585
+ if (ec)
1586
+ {
1587
+ more_ = false;
1588
+ return;
1589
+ }
1590
+ const uint8_t tag = (uint8_t)item_tag_;
1591
+ jsoncons::endian e = get_typed_array_endianness(tag);
1592
+ const size_t bytes_per_elem = get_typed_array_bytes_per_element(tag);
1593
+
1594
+ uint16_t* data = reinterpret_cast<uint16_t*>(typed_array_.data());
1595
+ std::size_t size = typed_array_.size()/bytes_per_elem;
1596
+
1597
+ if (e != jsoncons::endian::native)
1598
+ {
1599
+ for (std::size_t i = 0; i < size; ++i)
1600
+ {
1601
+ data[i] = binary::byte_swap<uint16_t>(data[i]);
1602
+ }
1603
+ }
1604
+ more_ = visitor.typed_array(jsoncons::span<const uint16_t>(data,size), semantic_tag::none, *this, ec);
1605
+ break;
1606
+ }
1607
+ case 0x42:
1608
+ case 0x46:
1609
+ {
1610
+ typed_array_.clear();
1611
+ read(typed_array_,ec);
1612
+ if (ec)
1613
+ {
1614
+ more_ = false;
1615
+ return;
1616
+ }
1617
+ const uint8_t tag = (uint8_t)item_tag_;
1618
+ jsoncons::endian e = get_typed_array_endianness(tag);
1619
+ const size_t bytes_per_elem = get_typed_array_bytes_per_element(tag);
1620
+
1621
+ uint32_t* data = reinterpret_cast<uint32_t*>(typed_array_.data());
1622
+ std::size_t size = typed_array_.size()/bytes_per_elem;
1623
+ if (e != jsoncons::endian::native)
1624
+ {
1625
+ for (std::size_t i = 0; i < size; ++i)
1626
+ {
1627
+ data[i] = binary::byte_swap<uint32_t>(data[i]);
1628
+ }
1629
+ }
1630
+ more_ = visitor.typed_array(jsoncons::span<const uint32_t>(data,size), semantic_tag::none, *this, ec);
1631
+ break;
1632
+ }
1633
+ case 0x43:
1634
+ case 0x47:
1635
+ {
1636
+ typed_array_.clear();
1637
+ read(typed_array_,ec);
1638
+ if (ec)
1639
+ {
1640
+ more_ = false;
1641
+ return;
1642
+ }
1643
+ const uint8_t tag = (uint8_t)item_tag_;
1644
+ jsoncons::endian e = get_typed_array_endianness(tag);
1645
+ const size_t bytes_per_elem = get_typed_array_bytes_per_element(tag);
1646
+
1647
+ uint64_t* data = reinterpret_cast<uint64_t*>(typed_array_.data());
1648
+ std::size_t size = typed_array_.size()/bytes_per_elem;
1649
+ if (e != jsoncons::endian::native)
1650
+ {
1651
+ for (std::size_t i = 0; i < size; ++i)
1652
+ {
1653
+ data[i] = binary::byte_swap<uint64_t>(data[i]);
1654
+ }
1655
+ }
1656
+ more_ = visitor.typed_array(jsoncons::span<const uint64_t>(data,size), semantic_tag::none, *this, ec);
1657
+ break;
1658
+ }
1659
+ case 0x48:
1660
+ {
1661
+ typed_array_.clear();
1662
+ read(typed_array_,ec);
1663
+ if (ec)
1664
+ {
1665
+ more_ = false;
1666
+ return;
1667
+ }
1668
+ int8_t* data = reinterpret_cast<int8_t*>(typed_array_.data());
1669
+ std::size_t size = typed_array_.size();
1670
+ more_ = visitor.typed_array(jsoncons::span<const int8_t>(data,size), semantic_tag::none, *this, ec);
1671
+ break;
1672
+ }
1673
+ case 0x49:
1674
+ case 0x4d:
1675
+ {
1676
+ typed_array_.clear();
1677
+ read(typed_array_,ec);
1678
+ if (ec)
1679
+ {
1680
+ more_ = false;
1681
+ return;
1682
+ }
1683
+ const uint8_t tag = (uint8_t)item_tag_;
1684
+ jsoncons::endian e = get_typed_array_endianness(tag);
1685
+ const size_t bytes_per_elem = get_typed_array_bytes_per_element(tag);
1686
+
1687
+ int16_t* data = reinterpret_cast<int16_t*>(typed_array_.data());
1688
+ std::size_t size = typed_array_.size()/bytes_per_elem;
1689
+ if (e != jsoncons::endian::native)
1690
+ {
1691
+ for (std::size_t i = 0; i < size; ++i)
1692
+ {
1693
+ data[i] = binary::byte_swap<int16_t>(data[i]);
1694
+ }
1695
+ }
1696
+ more_ = visitor.typed_array(jsoncons::span<const int16_t>(data,size), semantic_tag::none, *this, ec);
1697
+ break;
1698
+ }
1699
+ case 0x4a:
1700
+ case 0x4e:
1701
+ {
1702
+ typed_array_.clear();
1703
+ read(typed_array_,ec);
1704
+ if (ec)
1705
+ {
1706
+ more_ = false;
1707
+ return;
1708
+ }
1709
+ const uint8_t tag = (uint8_t)item_tag_;
1710
+ jsoncons::endian e = get_typed_array_endianness(tag);
1711
+ const size_t bytes_per_elem = get_typed_array_bytes_per_element(tag);
1712
+
1713
+ int32_t* data = reinterpret_cast<int32_t*>(typed_array_.data());
1714
+ std::size_t size = typed_array_.size()/bytes_per_elem;
1715
+ if (e != jsoncons::endian::native)
1716
+ {
1717
+ for (std::size_t i = 0; i < size; ++i)
1718
+ {
1719
+ data[i] = binary::byte_swap<int32_t>(data[i]);
1720
+ }
1721
+ }
1722
+ more_ = visitor.typed_array(jsoncons::span<const int32_t>(data,size), semantic_tag::none, *this, ec);
1723
+ break;
1724
+ }
1725
+ case 0x4b:
1726
+ case 0x4f:
1727
+ {
1728
+ typed_array_.clear();
1729
+ read(typed_array_,ec);
1730
+ if (ec)
1731
+ {
1732
+ more_ = false;
1733
+ return;
1734
+ }
1735
+ const uint8_t tag = (uint8_t)item_tag_;
1736
+ jsoncons::endian e = get_typed_array_endianness(tag);
1737
+ const size_t bytes_per_elem = get_typed_array_bytes_per_element(tag);
1738
+
1739
+ int64_t* data = reinterpret_cast<int64_t*>(typed_array_.data());
1740
+ std::size_t size = typed_array_.size()/bytes_per_elem;
1741
+ if (e != jsoncons::endian::native)
1742
+ {
1743
+ for (std::size_t i = 0; i < size; ++i)
1744
+ {
1745
+ data[i] = binary::byte_swap<int64_t>(data[i]);
1746
+ }
1747
+ }
1748
+ more_ = visitor.typed_array(jsoncons::span<const int64_t>(data,size), semantic_tag::none, *this, ec);
1749
+ break;
1750
+ }
1751
+ case 0x50:
1752
+ case 0x54:
1753
+ {
1754
+ typed_array_.clear();
1755
+ read(typed_array_,ec);
1756
+ if (ec)
1757
+ {
1758
+ more_ = false;
1759
+ return;
1760
+ }
1761
+ const uint8_t tag = (uint8_t)item_tag_;
1762
+ jsoncons::endian e = get_typed_array_endianness(tag);
1763
+ const size_t bytes_per_elem = get_typed_array_bytes_per_element(tag);
1764
+
1765
+ uint16_t* data = reinterpret_cast<uint16_t*>(typed_array_.data());
1766
+ std::size_t size = typed_array_.size()/bytes_per_elem;
1767
+ if (e != jsoncons::endian::native)
1768
+ {
1769
+ for (std::size_t i = 0; i < size; ++i)
1770
+ {
1771
+ data[i] = binary::byte_swap<uint16_t>(data[i]);
1772
+ }
1773
+ }
1774
+ more_ = visitor.typed_array(half_arg, jsoncons::span<const uint16_t>(data,size), semantic_tag::none, *this, ec);
1775
+ break;
1776
+ }
1777
+ case 0x51:
1778
+ case 0x55:
1779
+ {
1780
+ typed_array_.clear();
1781
+ read(typed_array_,ec);
1782
+ if (ec)
1783
+ {
1784
+ more_ = false;
1785
+ return;
1786
+ }
1787
+ const uint8_t tag = (uint8_t)item_tag_;
1788
+ jsoncons::endian e = get_typed_array_endianness(tag);
1789
+ const size_t bytes_per_elem = get_typed_array_bytes_per_element(tag);
1790
+
1791
+ float* data = reinterpret_cast<float*>(typed_array_.data());
1792
+ std::size_t size = typed_array_.size()/bytes_per_elem;
1793
+ if (e != jsoncons::endian::native)
1794
+ {
1795
+ for (std::size_t i = 0; i < size; ++i)
1796
+ {
1797
+ data[i] = binary::byte_swap<float>(data[i]);
1798
+ }
1799
+ }
1800
+ more_ = visitor.typed_array(jsoncons::span<const float>(data,size), semantic_tag::none, *this, ec);
1801
+ break;
1802
+ }
1803
+ case 0x52:
1804
+ case 0x56:
1805
+ {
1806
+ typed_array_.clear();
1807
+ read(typed_array_,ec);
1808
+ if (ec)
1809
+ {
1810
+ more_ = false;
1811
+ return;
1812
+ }
1813
+ const uint8_t tag = (uint8_t)item_tag_;
1814
+ jsoncons::endian e = get_typed_array_endianness(tag);
1815
+ const size_t bytes_per_elem = get_typed_array_bytes_per_element(tag);
1816
+
1817
+ double* data = reinterpret_cast<double*>(typed_array_.data());
1818
+ std::size_t size = typed_array_.size()/bytes_per_elem;
1819
+
1820
+ if (e != jsoncons::endian::native)
1821
+ {
1822
+ for (std::size_t i = 0; i < size; ++i)
1823
+ {
1824
+ data[i] = binary::byte_swap<double>(data[i]);
1825
+ }
1826
+ }
1827
+ more_ = visitor.typed_array(jsoncons::span<const double>(data,size), semantic_tag::none, *this, ec);
1828
+ break;
1829
+ }
1830
+ default:
1831
+ {
1832
+ read(bytes_buffer_,ec);
1833
+ if (ec)
1834
+ {
1835
+ more_ = false;
1836
+ return;
1837
+ }
1838
+ more_ = visitor.byte_string_value(bytes_buffer_, item_tag_, *this, ec);
1839
+ break;
1840
+ }
1841
+ }
1842
+ other_tags_[item_tag] = false;
1843
+ }
1844
+ else
1845
+ {
1846
+ read(bytes_buffer_,ec);
1847
+ if (ec)
1848
+ {
1849
+ return;
1850
+ }
1851
+ more_ = visitor.byte_string_value(bytes_buffer_, semantic_tag::none, *this, ec);
1852
+ }
1853
+ }
1854
+
1855
+ void produce_begin_multi_dim(json_visitor2& visitor,
1856
+ semantic_tag tag,
1857
+ std::error_code& ec)
1858
+ {
1859
+ uint8_t b;
1860
+ if (source_.read(&b, 1) == 0)
1861
+ {
1862
+ ec = cbor_errc::unexpected_eof;
1863
+ more_ = false;
1864
+ return;
1865
+ }
1866
+ jsoncons::cbor::detail::cbor_major_type major_type = get_major_type(b);
1867
+ JSONCONS_ASSERT(major_type == jsoncons::cbor::detail::cbor_major_type::array);
1868
+ uint8_t info = get_additional_information_value(b);
1869
+
1870
+ read_shape(info, ec);
1871
+ if (ec)
1872
+ {
1873
+ return;
1874
+ }
1875
+
1876
+ state_stack_.emplace_back(parse_mode::multi_dim, 0);
1877
+ more_ = visitor.begin_multi_dim(shape_, tag, *this, ec);
1878
+ }
1879
+
1880
+ void produce_end_multi_dim(json_visitor2& visitor, std::error_code& ec)
1881
+ {
1882
+ more_ = visitor.end_multi_dim(*this, ec);
1883
+ state_stack_.pop_back();
1884
+ }
1885
+
1886
+ void read_shape(uint8_t info, std::error_code& ec)
1887
+ {
1888
+ shape_.clear();
1889
+ switch (info)
1890
+ {
1891
+ case jsoncons::cbor::detail::additional_info::indefinite_length:
1892
+ {
1893
+ while (true)
1894
+ {
1895
+ auto c = source_.peek();
1896
+ if (c.eof)
1897
+ {
1898
+ ec = cbor_errc::unexpected_eof;
1899
+ more_ = false;
1900
+ return;
1901
+ }
1902
+ if (c.value == 0xff)
1903
+ {
1904
+ source_.ignore(1);
1905
+ }
1906
+ else
1907
+ {
1908
+ std::size_t dim = get_size(ec);
1909
+ if (!more_)
1910
+ {
1911
+ return;
1912
+ }
1913
+ shape_.push_back(dim);
1914
+ }
1915
+ }
1916
+ break;
1917
+ }
1918
+ default:
1919
+ {
1920
+ std::size_t size = get_size(ec);
1921
+ if (!more_)
1922
+ {
1923
+ return;
1924
+ }
1925
+ for (std::size_t i = 0; more_ && i < size; ++i)
1926
+ {
1927
+ std::size_t dim = get_size(ec);
1928
+ if (!more_)
1929
+ {
1930
+ return;
1931
+ }
1932
+ shape_.push_back(dim);
1933
+ }
1934
+ break;
1935
+ }
1936
+ }
1937
+ }
1938
+ };
1939
+
1940
+ }}
1941
+
1942
+ #endif