/src/jsoncons/include/jsoncons_ext/msgpack/msgpack_parser.hpp
Line | Count | Source |
1 | | // Copyright 2013-2025 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_EXT_MSGPACK_MSGPACK_PARSER_HPP |
8 | | #define JSONCONS_EXT_MSGPACK_MSGPACK_PARSER_HPP |
9 | | |
10 | | #include <cstddef> |
11 | | #include <cstdint> |
12 | | #include <memory> |
13 | | #include <string> |
14 | | #include <system_error> |
15 | | #include <utility> // std::move |
16 | | #include <vector> |
17 | | |
18 | | #include <jsoncons/config/compiler_support.hpp> |
19 | | #include <jsoncons/config/jsoncons_config.hpp> |
20 | | #include <jsoncons/item_event_visitor.hpp> |
21 | | #include <jsoncons/json_type.hpp> |
22 | | #include <jsoncons/semantic_tag.hpp> |
23 | | #include <jsoncons/ser_util.hpp> |
24 | | #include <jsoncons/source.hpp> |
25 | | #include <jsoncons/utility/bigint.hpp> |
26 | | #include <jsoncons/utility/binary.hpp> |
27 | | #include <jsoncons/utility/byte_string.hpp> |
28 | | #include <jsoncons/utility/unicode_traits.hpp> |
29 | | |
30 | | #include <jsoncons_ext/msgpack/msgpack_error.hpp> |
31 | | #include <jsoncons_ext/msgpack/msgpack_options.hpp> |
32 | | #include <jsoncons_ext/msgpack/msgpack_type.hpp> |
33 | | |
34 | | namespace jsoncons { |
35 | | namespace msgpack { |
36 | | |
37 | | enum class parse_mode {root,accept,array,map_key,map_value}; |
38 | | |
39 | | struct parse_state |
40 | | { |
41 | | parse_mode mode; |
42 | | std::size_t length{0}; |
43 | | std::size_t index{0}; |
44 | | |
45 | | parse_state(parse_mode mode, std::size_t length) noexcept |
46 | 13.6M | : mode(mode), length(length) |
47 | 13.6M | { |
48 | 13.6M | } |
49 | | |
50 | | parse_state(const parse_state&) = default; |
51 | | parse_state(parse_state&&) = default; |
52 | | |
53 | | ~parse_state() = default; |
54 | | }; |
55 | | |
56 | | template <typename Source,typename Allocator=std::allocator<char>> |
57 | | class basic_msgpack_parser : public ser_context |
58 | | { |
59 | | using char_type = char; |
60 | | using char_traits_type = std::char_traits<char>; |
61 | | using temp_allocator_type = Allocator; |
62 | | using char_allocator_type = typename std::allocator_traits<temp_allocator_type>:: template rebind_alloc<char_type>; |
63 | | using byte_allocator_type = typename std::allocator_traits<temp_allocator_type>:: template rebind_alloc<uint8_t>; |
64 | | using int64_allocator_type = typename std::allocator_traits<temp_allocator_type>:: template rebind_alloc<int64_t>; |
65 | | using parse_state_allocator_type = typename std::allocator_traits<temp_allocator_type>:: template rebind_alloc<parse_state>; |
66 | | |
67 | | static constexpr int64_t nanos_in_second = 1000000000; |
68 | | |
69 | | bool more_{true}; |
70 | | bool done_{false}; |
71 | | int nesting_depth_{0}; |
72 | | bool cursor_mode_{false}; |
73 | | int mark_level_{0}; |
74 | | |
75 | | Source source_; |
76 | | msgpack_decode_options options_; |
77 | | std::basic_string<char,std::char_traits<char>,char_allocator_type> text_buffer_; |
78 | | std::vector<uint8_t,byte_allocator_type> bytes_buffer_; |
79 | | std::vector<parse_state,parse_state_allocator_type> state_stack_; |
80 | | |
81 | | public: |
82 | | template <typename Sourceable> |
83 | | basic_msgpack_parser(Sourceable&& source, |
84 | | const msgpack_decode_options& options = msgpack_decode_options(), |
85 | | const Allocator& alloc = Allocator()) |
86 | 17.2k | : source_(std::forward<Sourceable>(source)), |
87 | 17.2k | options_(options), |
88 | 17.2k | text_buffer_(alloc), |
89 | 17.2k | bytes_buffer_(alloc), |
90 | 17.2k | state_stack_(alloc) |
91 | 17.2k | { |
92 | 17.2k | state_stack_.emplace_back(parse_mode::root,0); |
93 | 17.2k | } jsoncons::msgpack::basic_msgpack_parser<jsoncons::stream_source<unsigned char, std::__1::allocator<unsigned char> >, std::__1::allocator<char> >::basic_msgpack_parser<std::__1::basic_istringstream<char, std::__1::char_traits<char>, std::__1::allocator<char> >&>(std::__1::basic_istringstream<char, std::__1::char_traits<char>, std::__1::allocator<char> >&, jsoncons::msgpack::msgpack_decode_options const&, std::__1::allocator<char> const&) Line | Count | Source | 86 | 10.6k | : source_(std::forward<Sourceable>(source)), | 87 | 10.6k | options_(options), | 88 | 10.6k | text_buffer_(alloc), | 89 | 10.6k | bytes_buffer_(alloc), | 90 | 10.6k | state_stack_(alloc) | 91 | 10.6k | { | 92 | 10.6k | state_stack_.emplace_back(parse_mode::root,0); | 93 | 10.6k | } |
jsoncons::msgpack::basic_msgpack_parser<jsoncons::stream_source<unsigned char, std::__1::allocator<unsigned char> >, std::__1::allocator<char> >::basic_msgpack_parser<std::__1::basic_istream<char, std::__1::char_traits<char> >&>(std::__1::basic_istream<char, std::__1::char_traits<char> >&, jsoncons::msgpack::msgpack_decode_options const&, std::__1::allocator<char> const&) Line | Count | Source | 86 | 6.67k | : source_(std::forward<Sourceable>(source)), | 87 | 6.67k | options_(options), | 88 | 6.67k | text_buffer_(alloc), | 89 | 6.67k | bytes_buffer_(alloc), | 90 | 6.67k | state_stack_(alloc) | 91 | 6.67k | { | 92 | 6.67k | state_stack_.emplace_back(parse_mode::root,0); | 93 | 6.67k | } |
|
94 | | |
95 | | void restart() |
96 | | { |
97 | | more_ = true; |
98 | | } |
99 | | |
100 | | void reset() |
101 | 17.2k | { |
102 | 17.2k | more_ = true; |
103 | 17.2k | done_ = false; |
104 | 17.2k | text_buffer_.clear(); |
105 | 17.2k | bytes_buffer_.clear(); |
106 | 17.2k | state_stack_.clear(); |
107 | 17.2k | state_stack_.emplace_back(parse_mode::root,0); |
108 | 17.2k | nesting_depth_ = 0; |
109 | 17.2k | } |
110 | | |
111 | | template <typename Sourceable> |
112 | | void reset(Sourceable&& source) |
113 | | { |
114 | | source_ = std::forward<Sourceable>(source); |
115 | | reset(); |
116 | | } |
117 | | |
118 | | void cursor_mode(bool value) |
119 | | { |
120 | | cursor_mode_ = value; |
121 | | } |
122 | | |
123 | | int level() const |
124 | | { |
125 | | return static_cast<int>(state_stack_.size()); |
126 | | } |
127 | | |
128 | | int mark_level() const |
129 | | { |
130 | | return mark_level_; |
131 | | } |
132 | | |
133 | | void mark_level(int value) |
134 | | { |
135 | | mark_level_ = value; |
136 | | } |
137 | | |
138 | | bool done() const |
139 | | { |
140 | | return done_; |
141 | | } |
142 | | |
143 | | bool stopped() const |
144 | | { |
145 | | return !more_; |
146 | | } |
147 | | |
148 | | std::size_t line() const override |
149 | 4.31k | { |
150 | 4.31k | return 0; |
151 | 4.31k | } |
152 | | |
153 | | std::size_t column() const override |
154 | 4.31k | { |
155 | 4.31k | return source_.position(); |
156 | 4.31k | } |
157 | | |
158 | | void parse(item_event_visitor& visitor, std::error_code& ec) |
159 | 17.2k | { |
160 | 141M | while (!done_ && more_) |
161 | 141M | { |
162 | 141M | switch (state_stack_.back().mode) |
163 | 141M | { |
164 | 97.5M | case parse_mode::array: |
165 | 97.5M | { |
166 | 97.5M | if (state_stack_.back().index < state_stack_.back().length) |
167 | 89.5M | { |
168 | 89.5M | ++state_stack_.back().index; |
169 | 89.5M | read_item(visitor, ec); |
170 | 89.5M | if (JSONCONS_UNLIKELY(ec)) |
171 | 3.55k | { |
172 | 3.55k | return; |
173 | 3.55k | } |
174 | 89.5M | } |
175 | 7.90M | else |
176 | 7.90M | { |
177 | 7.90M | end_array(visitor, ec); |
178 | 7.90M | } |
179 | 97.5M | break; |
180 | 97.5M | } |
181 | 97.5M | case parse_mode::map_key: |
182 | 25.0M | { |
183 | 25.0M | if (state_stack_.back().index < state_stack_.back().length) |
184 | 19.4M | { |
185 | 19.4M | ++state_stack_.back().index; |
186 | 19.4M | state_stack_.back().mode = parse_mode::map_value; |
187 | 19.4M | read_item(visitor, ec); |
188 | 19.4M | if (JSONCONS_UNLIKELY(ec)) |
189 | 2.19k | { |
190 | 2.19k | return; |
191 | 2.19k | } |
192 | 19.4M | } |
193 | 5.60M | else |
194 | 5.60M | { |
195 | 5.60M | end_object(visitor, ec); |
196 | 5.60M | } |
197 | 25.0M | break; |
198 | 25.0M | } |
199 | 25.0M | case parse_mode::map_value: |
200 | 19.3M | { |
201 | 19.3M | state_stack_.back().mode = parse_mode::map_key; |
202 | 19.3M | read_item(visitor, ec); |
203 | 19.3M | if (JSONCONS_UNLIKELY(ec)) |
204 | 5.70k | { |
205 | 5.70k | return; |
206 | 5.70k | } |
207 | 19.3M | break; |
208 | 19.3M | } |
209 | 19.3M | case parse_mode::root: |
210 | 17.2k | { |
211 | 17.2k | state_stack_.back().mode = parse_mode::accept; |
212 | 17.2k | read_item(visitor, ec); |
213 | 17.2k | if (JSONCONS_UNLIKELY(ec)) |
214 | 1.12k | { |
215 | 1.12k | return; |
216 | 1.12k | } |
217 | 16.1k | break; |
218 | 17.2k | } |
219 | 16.1k | case parse_mode::accept: |
220 | 4.70k | { |
221 | 4.70k | JSONCONS_ASSERT(state_stack_.size() == 1); |
222 | 4.70k | state_stack_.clear(); |
223 | 4.70k | more_ = false; |
224 | 4.70k | done_ = true; |
225 | 4.70k | visitor.flush(); |
226 | 4.70k | break; |
227 | 4.70k | } |
228 | 141M | } |
229 | 141M | } |
230 | 17.2k | } |
231 | | private: |
232 | | |
233 | | void read_item(item_event_visitor& visitor, std::error_code& ec) |
234 | 128M | { |
235 | 128M | if (source_.is_error()) |
236 | 0 | { |
237 | 0 | ec = msgpack_errc::source_error; |
238 | 0 | more_ = false; |
239 | 0 | return; |
240 | 0 | } |
241 | | |
242 | 128M | uint8_t type; |
243 | 128M | if (source_.read(&type, 1) == 0) |
244 | 10.1k | { |
245 | 10.1k | ec = msgpack_errc::unexpected_eof; |
246 | 10.1k | more_ = false; |
247 | 10.1k | return; |
248 | 10.1k | } |
249 | | |
250 | 128M | if (type <= 0xbf) |
251 | 63.4M | { |
252 | 63.4M | if (type <= 0x7f) |
253 | 44.5M | { |
254 | | // positive fixint |
255 | 44.5M | visitor.uint64_value(type, semantic_tag::none, *this, ec); |
256 | 44.5M | more_ = !cursor_mode_; |
257 | 44.5M | } |
258 | 18.9M | else if (type <= 0x8f) |
259 | 5.64M | { |
260 | 5.64M | begin_object(visitor,type,ec); // fixmap |
261 | 5.64M | } |
262 | 13.3M | else if (type <= 0x9f) |
263 | 7.98M | { |
264 | 7.98M | begin_array(visitor,type,ec); // fixarray |
265 | 7.98M | } |
266 | 5.32M | else |
267 | 5.32M | { |
268 | | // fixstr |
269 | 5.32M | const size_t len = type & 0x1f; |
270 | | |
271 | 5.32M | text_buffer_.clear(); |
272 | | |
273 | 5.32M | if (source_reader<Source>::read(source_,text_buffer_,len) != static_cast<std::size_t>(len)) |
274 | 78 | { |
275 | 78 | ec = msgpack_errc::unexpected_eof; |
276 | 78 | more_ = false; |
277 | 78 | return; |
278 | 78 | } |
279 | | |
280 | 5.32M | auto result = unicode_traits::validate(text_buffer_.data(),text_buffer_.size()); |
281 | 5.32M | if (result.ec != unicode_traits::conv_errc()) |
282 | 275 | { |
283 | 275 | ec = msgpack_errc::invalid_utf8_text_string; |
284 | 275 | more_ = false; |
285 | 275 | return; |
286 | 275 | } |
287 | 5.32M | visitor.string_value(jsoncons::basic_string_view<char>(text_buffer_.data(),text_buffer_.length()), semantic_tag::none, *this, ec); |
288 | 5.32M | more_ = !cursor_mode_; |
289 | 5.32M | } |
290 | 63.4M | } |
291 | 64.9M | else if (type >= 0xe0) |
292 | 7.75M | { |
293 | | // negative fixint |
294 | 7.75M | visitor.int64_value(static_cast<int8_t>(type), semantic_tag::none, *this, ec); |
295 | 7.75M | more_ = !cursor_mode_; |
296 | 7.75M | } |
297 | 57.1M | else |
298 | 57.1M | { |
299 | 57.1M | switch (type) |
300 | 57.1M | { |
301 | 2.58M | case jsoncons::msgpack::msgpack_type::nil_type: |
302 | 2.58M | { |
303 | 2.58M | visitor.null_value(semantic_tag::none, *this, ec); |
304 | 2.58M | more_ = !cursor_mode_; |
305 | 2.58M | break; |
306 | 0 | } |
307 | 8.13M | case jsoncons::msgpack::msgpack_type::true_type: |
308 | 8.13M | { |
309 | 8.13M | visitor.bool_value(true, semantic_tag::none, *this, ec); |
310 | 8.13M | more_ = !cursor_mode_; |
311 | 8.13M | break; |
312 | 0 | } |
313 | 45.4M | case jsoncons::msgpack::msgpack_type::false_type: |
314 | 45.4M | { |
315 | 45.4M | visitor.bool_value(false, semantic_tag::none, *this, ec); |
316 | 45.4M | more_ = !cursor_mode_; |
317 | 45.4M | break; |
318 | 0 | } |
319 | 204k | case jsoncons::msgpack::msgpack_type::float32_type: |
320 | 204k | { |
321 | 204k | uint8_t buf[sizeof(float)]; |
322 | 204k | if (source_.read(buf, sizeof(float)) != sizeof(float)) |
323 | 40 | { |
324 | 40 | ec = msgpack_errc::unexpected_eof; |
325 | 40 | more_ = false; |
326 | 40 | return; |
327 | 40 | } |
328 | 204k | float val = binary::big_to_native<float>(buf, sizeof(buf)); |
329 | 204k | visitor.double_value(val, semantic_tag::none, *this, ec); |
330 | 204k | more_ = !cursor_mode_; |
331 | 204k | break; |
332 | 204k | } |
333 | | |
334 | 29.4k | case jsoncons::msgpack::msgpack_type::float64_type: |
335 | 29.4k | { |
336 | 29.4k | uint8_t buf[sizeof(double)]; |
337 | 29.4k | if (source_.read(buf, sizeof(double)) != sizeof(double)) |
338 | 26 | { |
339 | 26 | ec = msgpack_errc::unexpected_eof; |
340 | 26 | more_ = false; |
341 | 26 | return; |
342 | 26 | } |
343 | 29.4k | double val = binary::big_to_native<double>(buf, sizeof(buf)); |
344 | 29.4k | visitor.double_value(val, semantic_tag::none, *this, ec); |
345 | 29.4k | more_ = !cursor_mode_; |
346 | 29.4k | break; |
347 | 29.4k | } |
348 | | |
349 | 45.8k | case jsoncons::msgpack::msgpack_type::uint8_type: |
350 | 45.8k | { |
351 | 45.8k | uint8_t b; |
352 | 45.8k | if (source_.read(&b, 1) == 0) |
353 | 5 | { |
354 | 5 | ec = msgpack_errc::unexpected_eof; |
355 | 5 | more_ = false; |
356 | 5 | return; |
357 | 5 | } |
358 | 45.8k | visitor.uint64_value(b, semantic_tag::none, *this, ec); |
359 | 45.8k | more_ = !cursor_mode_; |
360 | 45.8k | break; |
361 | 45.8k | } |
362 | | |
363 | 3.29k | case jsoncons::msgpack::msgpack_type::uint16_type: |
364 | 3.29k | { |
365 | 3.29k | uint8_t buf[sizeof(uint16_t)]; |
366 | 3.29k | if (source_.read(buf, sizeof(uint16_t)) !=sizeof(uint16_t)) |
367 | 6 | { |
368 | 6 | ec = msgpack_errc::unexpected_eof; |
369 | 6 | more_ = false; |
370 | 6 | return; |
371 | 6 | } |
372 | 3.29k | uint16_t val = binary::big_to_native<uint16_t>(buf, sizeof(buf)); |
373 | 3.29k | visitor.uint64_value(val, semantic_tag::none, *this, ec); |
374 | 3.29k | more_ = !cursor_mode_; |
375 | 3.29k | break; |
376 | 3.29k | } |
377 | | |
378 | 19.9k | case jsoncons::msgpack::msgpack_type::uint32_type: |
379 | 19.9k | { |
380 | 19.9k | uint8_t buf[sizeof(uint32_t)]; |
381 | 19.9k | if (source_.read(buf, sizeof(uint32_t)) != sizeof(uint32_t)) |
382 | 11 | { |
383 | 11 | ec = msgpack_errc::unexpected_eof; |
384 | 11 | more_ = false; |
385 | 11 | return; |
386 | 11 | } |
387 | 19.9k | uint32_t val = binary::big_to_native<uint32_t>(buf, sizeof(buf)); |
388 | 19.9k | visitor.uint64_value(val, semantic_tag::none, *this, ec); |
389 | 19.9k | more_ = !cursor_mode_; |
390 | 19.9k | break; |
391 | 19.9k | } |
392 | | |
393 | 4.69k | case jsoncons::msgpack::msgpack_type::uint64_type: |
394 | 4.69k | { |
395 | 4.69k | uint8_t buf[sizeof(uint64_t)]; |
396 | 4.69k | if (source_.read(buf, sizeof(uint64_t)) != sizeof(uint64_t)) |
397 | 16 | { |
398 | 16 | ec = msgpack_errc::unexpected_eof; |
399 | 16 | more_ = false; |
400 | 16 | return; |
401 | 16 | } |
402 | 4.68k | uint64_t val = binary::big_to_native<uint64_t>(buf, sizeof(buf)); |
403 | 4.68k | visitor.uint64_value(val, semantic_tag::none, *this, ec); |
404 | 4.68k | more_ = !cursor_mode_; |
405 | 4.68k | break; |
406 | 4.69k | } |
407 | | |
408 | 127k | case jsoncons::msgpack::msgpack_type::int8_type: |
409 | 127k | { |
410 | 127k | uint8_t buf[sizeof(int8_t)]; |
411 | 127k | if (source_.read(buf, sizeof(int8_t)) != sizeof(int8_t)) |
412 | 4 | { |
413 | 4 | ec = msgpack_errc::unexpected_eof; |
414 | 4 | more_ = false; |
415 | 4 | return; |
416 | 4 | } |
417 | 127k | int8_t val = binary::big_to_native<int8_t>(buf, sizeof(buf)); |
418 | 127k | visitor.int64_value(val, semantic_tag::none, *this, ec); |
419 | 127k | more_ = !cursor_mode_; |
420 | 127k | break; |
421 | 127k | } |
422 | | |
423 | 22.5k | case jsoncons::msgpack::msgpack_type::int16_type: |
424 | 22.5k | { |
425 | 22.5k | uint8_t buf[sizeof(int16_t)]; |
426 | 22.5k | if (source_.read(buf, sizeof(int16_t)) != sizeof(int16_t)) |
427 | 7 | { |
428 | 7 | ec = msgpack_errc::unexpected_eof; |
429 | 7 | more_ = false; |
430 | 7 | return; |
431 | 7 | } |
432 | 22.5k | int16_t val = binary::big_to_native<int16_t>(buf, sizeof(buf)); |
433 | 22.5k | visitor.int64_value(val, semantic_tag::none, *this, ec); |
434 | 22.5k | more_ = !cursor_mode_; |
435 | 22.5k | break; |
436 | 22.5k | } |
437 | | |
438 | 21.8k | case jsoncons::msgpack::msgpack_type::int32_type: |
439 | 21.8k | { |
440 | 21.8k | uint8_t buf[sizeof(int32_t)]; |
441 | 21.8k | if (source_.read(buf, sizeof(int32_t)) != sizeof(int32_t)) |
442 | 14 | { |
443 | 14 | ec = msgpack_errc::unexpected_eof; |
444 | 14 | more_ = false; |
445 | 14 | return; |
446 | 14 | } |
447 | 21.8k | int32_t val = binary::big_to_native<int32_t>(buf, sizeof(buf)); |
448 | 21.8k | visitor.int64_value(val, semantic_tag::none, *this, ec); |
449 | 21.8k | more_ = !cursor_mode_; |
450 | 21.8k | break; |
451 | 21.8k | } |
452 | | |
453 | 19.0k | case jsoncons::msgpack::msgpack_type::int64_type: |
454 | 19.0k | { |
455 | 19.0k | uint8_t buf[sizeof(int64_t)]; |
456 | 19.0k | if (source_.read(buf, sizeof(int64_t)) != sizeof(int64_t)) |
457 | 35 | { |
458 | 35 | ec = msgpack_errc::unexpected_eof; |
459 | 35 | more_ = false; |
460 | 35 | return; |
461 | 35 | } |
462 | 18.9k | int64_t val = binary::big_to_native<int64_t>(buf, sizeof(buf)); |
463 | 18.9k | visitor.int64_value(val, semantic_tag::none, *this, ec); |
464 | 18.9k | more_ = !cursor_mode_; |
465 | 18.9k | break; |
466 | 19.0k | } |
467 | | |
468 | 2.49k | case jsoncons::msgpack::msgpack_type::str8_type: |
469 | 3.80k | case jsoncons::msgpack::msgpack_type::str16_type: |
470 | 4.88k | case jsoncons::msgpack::msgpack_type::str32_type: |
471 | 4.88k | { |
472 | 4.88k | std::size_t len = get_size(type, ec); |
473 | 4.88k | if (!more_) |
474 | 71 | { |
475 | 71 | return; |
476 | 71 | } |
477 | | |
478 | 4.81k | text_buffer_.clear(); |
479 | 4.81k | if (source_reader<Source>::read(source_,text_buffer_,len) != static_cast<std::size_t>(len)) |
480 | 315 | { |
481 | 315 | ec = msgpack_errc::unexpected_eof; |
482 | 315 | more_ = false; |
483 | 315 | return; |
484 | 315 | } |
485 | | |
486 | 4.49k | auto result = unicode_traits::validate(text_buffer_.data(),text_buffer_.size()); |
487 | 4.49k | if (result.ec != unicode_traits::conv_errc()) |
488 | 53 | { |
489 | 53 | ec = msgpack_errc::invalid_utf8_text_string; |
490 | 53 | more_ = false; |
491 | 53 | return; |
492 | 53 | } |
493 | 4.44k | visitor.string_value(jsoncons::basic_string_view<char>(text_buffer_.data(),text_buffer_.length()), semantic_tag::none, *this, ec); |
494 | 4.44k | more_ = !cursor_mode_; |
495 | 4.44k | break; |
496 | 4.49k | } |
497 | | |
498 | 92.3k | case jsoncons::msgpack::msgpack_type::bin8_type: |
499 | 97.9k | case jsoncons::msgpack::msgpack_type::bin16_type: |
500 | 98.9k | case jsoncons::msgpack::msgpack_type::bin32_type: |
501 | 98.9k | { |
502 | 98.9k | std::size_t len = get_size(type,ec); |
503 | 98.9k | if (!more_) |
504 | 80 | { |
505 | 80 | return; |
506 | 80 | } |
507 | 98.9k | bytes_buffer_.clear(); |
508 | 98.9k | if (source_reader<Source>::read(source_,bytes_buffer_,len) != static_cast<std::size_t>(len)) |
509 | 468 | { |
510 | 468 | ec = msgpack_errc::unexpected_eof; |
511 | 468 | more_ = false; |
512 | 468 | return; |
513 | 468 | } |
514 | | |
515 | 98.4k | visitor.byte_string_value(byte_string_view(bytes_buffer_.data(),bytes_buffer_.size()), |
516 | 98.4k | semantic_tag::none, |
517 | 98.4k | *this, |
518 | 98.4k | ec); |
519 | 98.4k | more_ = !cursor_mode_; |
520 | 98.4k | break; |
521 | 98.9k | } |
522 | 31.8k | case jsoncons::msgpack::msgpack_type::fixext1_type: |
523 | 201k | case jsoncons::msgpack::msgpack_type::fixext2_type: |
524 | 206k | case jsoncons::msgpack::msgpack_type::fixext4_type: |
525 | 271k | case jsoncons::msgpack::msgpack_type::fixext8_type: |
526 | 280k | case jsoncons::msgpack::msgpack_type::fixext16_type: |
527 | 316k | case jsoncons::msgpack::msgpack_type::ext8_type: |
528 | 318k | case jsoncons::msgpack::msgpack_type::ext16_type: |
529 | 320k | case jsoncons::msgpack::msgpack_type::ext32_type: |
530 | 320k | { |
531 | 320k | std::size_t len = get_size(type,ec); |
532 | 320k | if (!more_) |
533 | 75 | { |
534 | 75 | return; |
535 | 75 | } |
536 | | |
537 | | // type |
538 | 319k | uint8_t buf[sizeof(int8_t)]; |
539 | 319k | if (source_.read(buf, sizeof(int8_t)) != sizeof(int8_t)) |
540 | 141 | { |
541 | 141 | ec = msgpack_errc::unexpected_eof; |
542 | 141 | more_ = false; |
543 | 141 | return; |
544 | 141 | } |
545 | | |
546 | 319k | int8_t ext_type = binary::big_to_native<int8_t>(buf, sizeof(buf)); |
547 | | |
548 | 319k | bool is_timestamp = false; |
549 | 319k | if (ext_type == -1) |
550 | 91.9k | { |
551 | 91.9k | is_timestamp = true;; |
552 | 91.9k | } |
553 | | |
554 | | // payload |
555 | 319k | if (is_timestamp && len == 4) |
556 | 2.53k | { |
557 | 2.53k | uint8_t buf32[sizeof(uint32_t)]; |
558 | 2.53k | if (source_.read(buf32, sizeof(uint32_t)) != sizeof(uint32_t)) |
559 | 9 | { |
560 | 9 | ec = msgpack_errc::unexpected_eof; |
561 | 9 | more_ = false; |
562 | 9 | return; |
563 | 9 | } |
564 | 2.52k | uint32_t val = binary::big_to_native<uint32_t>(buf32, sizeof(buf32)); |
565 | 2.52k | visitor.uint64_value(val, semantic_tag::epoch_second, *this, ec); |
566 | 2.52k | more_ = !cursor_mode_; |
567 | 2.52k | } |
568 | 317k | else if (is_timestamp && len == 8) |
569 | 59.8k | { |
570 | 59.8k | uint8_t buf64[sizeof(uint64_t)]; |
571 | 59.8k | if (source_.read(buf64, sizeof(uint64_t)) != sizeof(uint64_t)) |
572 | 22 | { |
573 | 22 | ec = msgpack_errc::unexpected_eof; |
574 | 22 | more_ = false; |
575 | 22 | return; |
576 | 22 | } |
577 | 59.8k | uint64_t data64 = binary::big_to_native<uint64_t>(buf64, sizeof(buf64)); |
578 | 59.8k | uint64_t sec = data64 & 0x00000003ffffffffL; |
579 | 59.8k | uint64_t nsec = data64 >> 34; |
580 | | |
581 | 59.8k | bigint nano(sec); |
582 | 59.8k | nano *= uint64_t(nanos_in_second); |
583 | 59.8k | nano += nsec; |
584 | 59.8k | text_buffer_.clear(); |
585 | 59.8k | nano.write_string(text_buffer_); |
586 | 59.8k | visitor.string_value(text_buffer_, semantic_tag::epoch_nano, *this, ec); |
587 | 59.8k | more_ = !cursor_mode_; |
588 | 59.8k | if (!more_) return; |
589 | 59.8k | } |
590 | 257k | else if (is_timestamp && len == 12) |
591 | 27.1k | { |
592 | 27.1k | uint8_t buf1[sizeof(uint32_t)]; |
593 | 27.1k | if (source_.read(buf1, sizeof(uint32_t)) != sizeof(uint32_t)) |
594 | 10 | { |
595 | 10 | ec = msgpack_errc::unexpected_eof; |
596 | 10 | more_ = false; |
597 | 10 | return; |
598 | 10 | } |
599 | 27.1k | uint32_t nsec = binary::big_to_native<uint32_t>(buf1, sizeof(buf1)); |
600 | | |
601 | 27.1k | uint8_t buf2[sizeof(int64_t)]; |
602 | 27.1k | if (source_.read(buf2, sizeof(int64_t)) != sizeof(int64_t)) |
603 | 13 | { |
604 | 13 | ec = msgpack_errc::unexpected_eof; |
605 | 13 | more_ = false; |
606 | 13 | return; |
607 | 13 | } |
608 | 27.1k | int64_t sec = binary::big_to_native<int64_t>(buf2, sizeof(buf2)); |
609 | | |
610 | 27.1k | bigint nano(sec); |
611 | | |
612 | 27.1k | nano *= uint64_t(nanos_in_second); |
613 | | |
614 | 27.1k | if (nano < 0) |
615 | 7.64k | { |
616 | 7.64k | nano -= nsec; |
617 | 7.64k | } |
618 | 19.5k | else |
619 | 19.5k | { |
620 | 19.5k | nano += nsec; |
621 | 19.5k | } |
622 | | |
623 | 27.1k | text_buffer_.clear(); |
624 | 27.1k | nano.write_string(text_buffer_); |
625 | 27.1k | visitor.string_value(text_buffer_, semantic_tag::epoch_nano, *this, ec); |
626 | 27.1k | more_ = !cursor_mode_; |
627 | 27.1k | if (!more_) return; |
628 | 27.1k | } |
629 | 230k | else |
630 | 230k | { |
631 | 230k | bytes_buffer_.clear(); |
632 | 230k | if (source_reader<Source>::read(source_,bytes_buffer_,len) != static_cast<std::size_t>(len)) |
633 | 438 | { |
634 | 438 | ec = msgpack_errc::unexpected_eof; |
635 | 438 | more_ = false; |
636 | 438 | return; |
637 | 438 | } |
638 | | |
639 | 229k | visitor.byte_string_value(byte_string_view(bytes_buffer_.data(),bytes_buffer_.size()), |
640 | 229k | static_cast<uint8_t>(ext_type), |
641 | 229k | *this, |
642 | 229k | ec); |
643 | 229k | more_ = !cursor_mode_; |
644 | 229k | } |
645 | 319k | break; |
646 | 319k | } |
647 | | |
648 | 319k | case jsoncons::msgpack::msgpack_type::array16_type: |
649 | 13.6k | case jsoncons::msgpack::msgpack_type::array32_type: |
650 | 13.6k | { |
651 | 13.6k | begin_array(visitor,type,ec); |
652 | 13.6k | break; |
653 | 9.24k | } |
654 | | |
655 | 13.8k | case jsoncons::msgpack::msgpack_type::map16_type : |
656 | 16.8k | case jsoncons::msgpack::msgpack_type::map32_type : |
657 | 16.8k | { |
658 | 16.8k | begin_object(visitor, type, ec); |
659 | 16.8k | break; |
660 | 13.8k | } |
661 | | |
662 | 46 | default: |
663 | 46 | { |
664 | 46 | ec = msgpack_errc::unknown_type; |
665 | 46 | more_ = false; |
666 | 46 | return; |
667 | 13.8k | } |
668 | 57.1M | } |
669 | 57.1M | } |
670 | 128M | } |
671 | | |
672 | | void begin_array(item_event_visitor& visitor, uint8_t type, std::error_code& ec) |
673 | 7.99M | { |
674 | 7.99M | if (JSONCONS_UNLIKELY(++nesting_depth_ > options_.max_nesting_depth())) |
675 | 8 | { |
676 | 8 | ec = msgpack_errc::max_nesting_depth_exceeded; |
677 | 8 | more_ = false; |
678 | 8 | return; |
679 | 8 | } |
680 | 7.99M | std::size_t length = get_size(type, ec); |
681 | 7.99M | if (!more_) |
682 | 52 | { |
683 | 52 | return; |
684 | 52 | } |
685 | 7.99M | state_stack_.emplace_back(parse_mode::array,length); |
686 | 7.99M | visitor.begin_array(length, semantic_tag::none, *this, ec); |
687 | 7.99M | more_ = !cursor_mode_; |
688 | 7.99M | } |
689 | | |
690 | | void end_array(item_event_visitor& visitor, std::error_code& ec) |
691 | 7.90M | { |
692 | 7.90M | --nesting_depth_; |
693 | | |
694 | 7.90M | visitor.end_array(*this, ec); |
695 | 7.90M | more_ = !cursor_mode_; |
696 | 7.90M | state_stack_.pop_back(); |
697 | 7.90M | } |
698 | | |
699 | | void begin_object(item_event_visitor& visitor, uint8_t type, std::error_code& ec) |
700 | 5.65M | { |
701 | 5.65M | if (JSONCONS_UNLIKELY(++nesting_depth_ > options_.max_nesting_depth())) |
702 | 5 | { |
703 | 5 | ec = msgpack_errc::max_nesting_depth_exceeded; |
704 | 5 | more_ = false; |
705 | 5 | return; |
706 | 5 | } |
707 | 5.65M | std::size_t length = get_size(type, ec); |
708 | 5.65M | if (!more_) |
709 | 55 | { |
710 | 55 | return; |
711 | 55 | } |
712 | 5.65M | state_stack_.emplace_back(parse_mode::map_key,length); |
713 | 5.65M | visitor.begin_object(length, semantic_tag::none, *this, ec); |
714 | 5.65M | more_ = !cursor_mode_; |
715 | 5.65M | } |
716 | | |
717 | | void end_object(item_event_visitor& visitor, std::error_code& ec) |
718 | 5.60M | { |
719 | 5.60M | --nesting_depth_; |
720 | 5.60M | visitor.end_object(*this, ec); |
721 | 5.60M | more_ = !cursor_mode_; |
722 | 5.60M | state_stack_.pop_back(); |
723 | 5.60M | } |
724 | | |
725 | | std::size_t get_size(uint8_t type, std::error_code& ec) |
726 | 14.0M | { |
727 | 14.0M | switch (type) |
728 | 14.0M | { |
729 | 2.49k | case jsoncons::msgpack::msgpack_type::str8_type: |
730 | 94.8k | case jsoncons::msgpack::msgpack_type::bin8_type: |
731 | 131k | case jsoncons::msgpack::msgpack_type::ext8_type: |
732 | 131k | { |
733 | 131k | uint8_t buf[sizeof(int8_t)]; |
734 | 131k | if (source_.read(buf, sizeof(int8_t)) != sizeof(int8_t)) |
735 | 73 | { |
736 | 73 | ec = msgpack_errc::unexpected_eof; |
737 | 73 | more_ = false; |
738 | 73 | return 0; |
739 | 73 | } |
740 | 131k | uint8_t len = binary::big_to_native<uint8_t>(buf, sizeof(buf)); |
741 | 131k | return static_cast<std::size_t>(len); |
742 | 131k | } |
743 | | |
744 | 1.31k | case jsoncons::msgpack::msgpack_type::str16_type: |
745 | 6.88k | case jsoncons::msgpack::msgpack_type::bin16_type: |
746 | 8.41k | case jsoncons::msgpack::msgpack_type::ext16_type: |
747 | 17.6k | case jsoncons::msgpack::msgpack_type::array16_type: |
748 | 31.5k | case jsoncons::msgpack::msgpack_type::map16_type: |
749 | 31.5k | { |
750 | 31.5k | uint8_t buf[sizeof(int16_t)]; |
751 | 31.5k | if (source_.read(buf, sizeof(int16_t)) != sizeof(int16_t)) |
752 | 131 | { |
753 | 131 | ec = msgpack_errc::unexpected_eof; |
754 | 131 | more_ = false; |
755 | 131 | return 0; |
756 | 131 | } |
757 | 31.4k | uint16_t len = binary::big_to_native<uint16_t>(buf, sizeof(buf)); |
758 | 31.4k | return static_cast<std::size_t>(len); |
759 | 31.5k | } |
760 | | |
761 | 1.07k | case jsoncons::msgpack::msgpack_type::str32_type: |
762 | 2.16k | case jsoncons::msgpack::msgpack_type::bin32_type: |
763 | 4.05k | case jsoncons::msgpack::msgpack_type::ext32_type: |
764 | 8.50k | case jsoncons::msgpack::msgpack_type::array32_type: |
765 | 11.4k | case jsoncons::msgpack::msgpack_type::map32_type : |
766 | 11.4k | { |
767 | 11.4k | uint8_t buf[sizeof(int32_t)]; |
768 | 11.4k | if (source_.read(buf, sizeof(int32_t)) != sizeof(int32_t)) |
769 | 129 | { |
770 | 129 | ec = msgpack_errc::unexpected_eof; |
771 | 129 | more_ = false; |
772 | 129 | return 0; |
773 | 129 | } |
774 | 11.3k | uint32_t len = binary::big_to_native<uint32_t>(buf, sizeof(buf)); |
775 | 11.3k | return static_cast<std::size_t>(len); |
776 | 11.4k | } |
777 | 31.8k | case jsoncons::msgpack::msgpack_type::fixext1_type: |
778 | 31.8k | return 1; |
779 | 169k | case jsoncons::msgpack::msgpack_type::fixext2_type: |
780 | 169k | return 2; |
781 | 5.63k | case jsoncons::msgpack::msgpack_type::fixext4_type: |
782 | 5.63k | return 4; |
783 | 64.8k | case jsoncons::msgpack::msgpack_type::fixext8_type: |
784 | 64.8k | return 8; |
785 | 8.44k | case jsoncons::msgpack::msgpack_type::fixext16_type: |
786 | 8.44k | return 16; |
787 | 13.6M | default: |
788 | 13.6M | if ((type > 0x8f && type <= 0x9f) // fixarray |
789 | 5.64M | || (type > 0x7f && type <= 0x8f) // fixmap |
790 | 13.6M | ) |
791 | 13.6M | { |
792 | 13.6M | return type & 0x0f; |
793 | 13.6M | } |
794 | 0 | else |
795 | 0 | { |
796 | 0 | ec = msgpack_errc::unknown_type; |
797 | 0 | more_ = false; |
798 | 0 | return 0; |
799 | 0 | } |
800 | 0 | break; |
801 | 14.0M | } |
802 | 14.0M | } |
803 | | }; |
804 | | |
805 | | } // namespace msgpack |
806 | | } // namespace jsoncons |
807 | | |
808 | | #endif // JSONCONS_EXT_MSGPACK_MSGPACK_PARSER_HPP |