Coverage Report

Created: 2026-08-18 06:21

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/jsoncons/include/jsoncons_ext/msgpack/msgpack_parser.hpp
Line
Count
Source
1
// Copyright 2013-2026 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/generic_visitor.hpp>
21
#include <jsoncons/json_type.hpp>
22
#include <jsoncons/semantic_tag.hpp>
23
#include <jsoncons/ser_utils.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
10.0M
        : mode(mode), length(length)
47
10.0M
    {
48
10.0M
    }
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
    int max_nesting_depth_;
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
18.3k
       : source_(std::forward<Sourceable>(source)),
87
18.3k
         max_nesting_depth_(options.max_nesting_depth()),
88
18.3k
         text_buffer_(alloc),
89
18.3k
         bytes_buffer_(alloc),
90
18.3k
         state_stack_(alloc)
91
18.3k
    {
92
18.3k
        state_stack_.emplace_back(parse_mode::root,0);
93
18.3k
    }
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
11.1k
       : source_(std::forward<Sourceable>(source)),
87
11.1k
         max_nesting_depth_(options.max_nesting_depth()),
88
11.1k
         text_buffer_(alloc),
89
11.1k
         bytes_buffer_(alloc),
90
11.1k
         state_stack_(alloc)
91
11.1k
    {
92
11.1k
        state_stack_.emplace_back(parse_mode::root,0);
93
11.1k
    }
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
7.23k
       : source_(std::forward<Sourceable>(source)),
87
7.23k
         max_nesting_depth_(options.max_nesting_depth()),
88
7.23k
         text_buffer_(alloc),
89
7.23k
         bytes_buffer_(alloc),
90
7.23k
         state_stack_(alloc)
91
7.23k
    {
92
7.23k
        state_stack_.emplace_back(parse_mode::root,0);
93
7.23k
    }
94
95
    void restart()
96
    {
97
        more_ = true;
98
    }
99
100
    void reset()
101
18.3k
    {
102
18.3k
        more_ = true;
103
18.3k
        done_ = false;
104
18.3k
        text_buffer_.clear();
105
18.3k
        bytes_buffer_.clear();
106
18.3k
        state_stack_.clear();
107
18.3k
        state_stack_.emplace_back(parse_mode::root,0);
108
18.3k
        nesting_depth_ = 0;
109
18.3k
    }
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 final
149
4.77k
    {
150
4.77k
        return 0;
151
4.77k
    }
152
153
    std::size_t column() const final
154
4.77k
    {
155
4.77k
        return source_.position();
156
4.77k
    }
157
158
    void parse(generic_visitor& visitor, std::error_code& ec)
159
18.3k
    {
160
175M
        while (!done_ && more_)
161
175M
        {
162
175M
            switch (state_stack_.back().mode)
163
175M
            {
164
113M
                case parse_mode::array:
165
113M
                {
166
113M
                    if (state_stack_.back().index < state_stack_.back().length)
167
106M
                    {
168
106M
                        ++state_stack_.back().index;
169
106M
                        read_item(visitor, ec);
170
106M
                        if (JSONCONS_UNLIKELY(ec))
171
3.88k
                        {
172
3.88k
                            return;
173
3.88k
                        }
174
106M
                    }
175
7.08M
                    else
176
7.08M
                    {
177
7.08M
                        end_array(visitor, ec);
178
7.08M
                    }
179
113M
                    break;
180
113M
                }
181
113M
                case parse_mode::map_key:
182
32.3M
                {
183
32.3M
                    if (state_stack_.back().index < state_stack_.back().length)
184
29.5M
                    {
185
29.5M
                        ++state_stack_.back().index;
186
29.5M
                        state_stack_.back().mode = parse_mode::map_value;
187
29.5M
                        read_item(visitor, ec);
188
29.5M
                        if (JSONCONS_UNLIKELY(ec))
189
2.49k
                        {
190
2.49k
                            return;
191
2.49k
                        }
192
29.5M
                    }
193
2.80M
                    else
194
2.80M
                    {
195
2.80M
                        end_object(visitor, ec);
196
2.80M
                    }
197
32.3M
                    break;
198
32.3M
                }
199
32.3M
                case parse_mode::map_value:
200
29.4M
                {
201
29.4M
                    state_stack_.back().mode = parse_mode::map_key;
202
29.4M
                    read_item(visitor, ec);
203
29.4M
                    if (JSONCONS_UNLIKELY(ec))
204
5.73k
                    {
205
5.73k
                        return;
206
5.73k
                    }
207
29.4M
                    break;
208
29.4M
                }
209
29.4M
                case parse_mode::root:
210
18.3k
                {
211
18.3k
                    state_stack_.back().mode = parse_mode::accept;
212
18.3k
                    read_item(visitor, ec);
213
18.3k
                    if (JSONCONS_UNLIKELY(ec))
214
1.30k
                    {
215
1.30k
                        return;
216
1.30k
                    }
217
17.0k
                    break;
218
18.3k
                }
219
17.0k
                case parse_mode::accept:
220
4.95k
                {
221
4.95k
                    JSONCONS_ASSERT(state_stack_.size() == 1);
222
4.95k
                    state_stack_.clear();
223
4.95k
                    more_ = false;
224
4.95k
                    done_ = true;
225
4.95k
                    visitor.flush();
226
4.95k
                    break;
227
4.95k
                }
228
175M
            }
229
175M
        }
230
18.3k
    }
231
private:
232
233
    void read_item(generic_visitor& visitor, std::error_code& ec)
234
165M
    {
235
165M
        if (source_.is_error())
236
0
        {
237
0
            ec = msgpack_errc::source_error;
238
0
            more_ = false;
239
0
            return;
240
0
        }   
241
242
165M
        uint8_t type;
243
165M
        if (source_.read(&type, 1) == 0)
244
10.4k
        {
245
10.4k
            ec = msgpack_errc::unexpected_eof;
246
10.4k
            more_ = false;
247
10.4k
            return;
248
10.4k
        }
249
250
165M
        if (type <= 0xbf)
251
79.2M
        {
252
79.2M
            if (type <= 0x7f) 
253
61.3M
            {
254
                // positive fixint
255
61.3M
                visitor.uint64_value(type, semantic_tag::none, *this, ec);
256
61.3M
                more_ = !cursor_mode_;
257
61.3M
            }
258
17.8M
            else if (type <= 0x8f) 
259
2.85M
            {
260
2.85M
                begin_object(visitor,type,ec); // fixmap
261
2.85M
            }
262
15.0M
            else if (type <= 0x9f) 
263
7.15M
            {
264
7.15M
                begin_array(visitor,type,ec); // fixarray
265
7.15M
            }
266
7.86M
            else 
267
7.86M
            {
268
                // fixstr
269
7.86M
                const size_t len = type & 0x1f;
270
271
7.86M
                auto data = source_.read_span(len, bytes_buffer_);
272
7.86M
                if (data.size() != static_cast<std::size_t>(len))
273
150
                {
274
150
                    ec = msgpack_errc::unexpected_eof;
275
150
                    more_ = false;
276
150
                    return;
277
150
                }
278
279
7.86M
                auto result = unicode_traits::validate(data.data(), data.size());
280
7.86M
                if (result.ec != unicode_traits::unicode_errc())
281
495
                {
282
495
                    ec = msgpack_errc::invalid_utf8_text_string;
283
495
                    more_ = false;
284
495
                    return;
285
495
                }
286
7.86M
                visitor.string_value(jsoncons::string_view(reinterpret_cast<const char*>(data.data()),data.size()), 
287
7.86M
                    semantic_tag::none, *this, ec);
288
7.86M
                more_ = !cursor_mode_;
289
7.86M
            }
290
79.2M
        }
291
85.9M
        else if (type >= 0xe0) 
292
14.6M
        {
293
            // negative fixint
294
14.6M
            visitor.int64_value(static_cast<int8_t>(type), semantic_tag::none, *this, ec);
295
14.6M
            more_ = !cursor_mode_;
296
14.6M
        }
297
71.2M
        else
298
71.2M
        {
299
71.2M
            switch (type)
300
71.2M
            {
301
2.79M
                case jsoncons::msgpack::msgpack_type::nil_type: 
302
2.79M
                {
303
2.79M
                    visitor.null_value(semantic_tag::none, *this, ec);
304
2.79M
                    more_ = !cursor_mode_;
305
2.79M
                    break;
306
0
                }
307
8.44M
                case jsoncons::msgpack::msgpack_type::true_type:
308
8.44M
                {
309
8.44M
                    visitor.bool_value(true, semantic_tag::none, *this, ec);
310
8.44M
                    more_ = !cursor_mode_;
311
8.44M
                    break;
312
0
                }
313
55.0M
                case jsoncons::msgpack::msgpack_type::false_type:
314
55.0M
                {
315
55.0M
                    visitor.bool_value(false, semantic_tag::none, *this, ec);
316
55.0M
                    more_ = !cursor_mode_;
317
55.0M
                    break;
318
0
                }
319
292k
                case jsoncons::msgpack::msgpack_type::float32_type: 
320
292k
                {
321
292k
                    uint8_t buf[sizeof(float)];
322
292k
                    if (source_.read(buf, sizeof(float)) != sizeof(float))
323
59
                    {
324
59
                        ec = msgpack_errc::unexpected_eof;
325
59
                        more_ = false;
326
59
                        return;
327
59
                    }
328
292k
                    float val = binary::big_to_native<float>(buf, sizeof(buf));
329
292k
                    visitor.double_value(val, semantic_tag::none, *this, ec);
330
292k
                    more_ = !cursor_mode_;
331
292k
                    break;
332
292k
                }
333
334
85.7k
                case jsoncons::msgpack::msgpack_type::float64_type: 
335
85.7k
                {
336
85.7k
                    uint8_t buf[sizeof(double)];
337
85.7k
                    if (source_.read(buf, sizeof(double)) != sizeof(double))
338
31
                    {
339
31
                        ec = msgpack_errc::unexpected_eof;
340
31
                        more_ = false;
341
31
                        return;
342
31
                    }
343
85.6k
                    double val = binary::big_to_native<double>(buf, sizeof(buf));
344
85.6k
                    visitor.double_value(val, semantic_tag::none, *this, ec);
345
85.6k
                    more_ = !cursor_mode_;
346
85.6k
                    break;
347
85.7k
                }
348
349
26.2k
                case jsoncons::msgpack::msgpack_type::uint8_type: 
350
26.2k
                {
351
26.2k
                    uint8_t b;
352
26.2k
                    if (source_.read(&b, 1) == 0)
353
6
                    {
354
6
                        ec = msgpack_errc::unexpected_eof;
355
6
                        more_ = false;
356
6
                        return;
357
6
                    }
358
26.2k
                    visitor.uint64_value(b, semantic_tag::none, *this, ec);
359
26.2k
                    more_ = !cursor_mode_;
360
26.2k
                    break;
361
26.2k
                }
362
363
209k
                case jsoncons::msgpack::msgpack_type::uint16_type: 
364
209k
                {
365
209k
                    uint8_t buf[sizeof(uint16_t)];
366
209k
                    if (source_.read(buf, sizeof(uint16_t)) !=sizeof(uint16_t)) 
367
9
                    {
368
9
                        ec = msgpack_errc::unexpected_eof;
369
9
                        more_ = false;
370
9
                        return;
371
9
                    }
372
209k
                    uint16_t val = binary::big_to_native<uint16_t>(buf, sizeof(buf));
373
209k
                    visitor.uint64_value(val, semantic_tag::none, *this, ec);
374
209k
                    more_ = !cursor_mode_;
375
209k
                    break;
376
209k
                }
377
378
91.5k
                case jsoncons::msgpack::msgpack_type::uint32_type: 
379
91.5k
                {
380
91.5k
                    uint8_t buf[sizeof(uint32_t)];
381
91.5k
                    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
91.5k
                    uint32_t val = binary::big_to_native<uint32_t>(buf, sizeof(buf));
388
91.5k
                    visitor.uint64_value(val, semantic_tag::none, *this, ec);
389
91.5k
                    more_ = !cursor_mode_;
390
91.5k
                    break;
391
91.5k
                }
392
393
11.8k
                case jsoncons::msgpack::msgpack_type::uint64_type: 
394
11.8k
                {
395
11.8k
                    uint8_t buf[sizeof(uint64_t)];
396
11.8k
                    if (source_.read(buf, sizeof(uint64_t)) != sizeof(uint64_t))
397
21
                    {
398
21
                        ec = msgpack_errc::unexpected_eof;
399
21
                        more_ = false;
400
21
                        return;
401
21
                    }
402
11.8k
                    uint64_t val = binary::big_to_native<uint64_t>(buf, sizeof(buf));
403
11.8k
                    visitor.uint64_value(val, semantic_tag::none, *this, ec);
404
11.8k
                    more_ = !cursor_mode_;
405
11.8k
                    break;
406
11.8k
                }
407
408
404k
                case jsoncons::msgpack::msgpack_type::int8_type: 
409
404k
                {
410
404k
                    uint8_t buf[sizeof(int8_t)];
411
404k
                    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
404k
                    int8_t val = binary::big_to_native<int8_t>(buf, sizeof(buf));
418
404k
                    visitor.int64_value(val, semantic_tag::none, *this, ec);
419
404k
                    more_ = !cursor_mode_;
420
404k
                    break;
421
404k
                }
422
423
152k
                case jsoncons::msgpack::msgpack_type::int16_type: 
424
152k
                {
425
152k
                    uint8_t buf[sizeof(int16_t)];
426
152k
                    if (source_.read(buf, sizeof(int16_t)) != sizeof(int16_t))
427
8
                    {
428
8
                        ec = msgpack_errc::unexpected_eof;
429
8
                        more_ = false;
430
8
                        return;
431
8
                    }
432
152k
                    int16_t val = binary::big_to_native<int16_t>(buf, sizeof(buf));
433
152k
                    visitor.int64_value(val, semantic_tag::none, *this, ec);
434
152k
                    more_ = !cursor_mode_;
435
152k
                    break;
436
152k
                }
437
438
25.8k
                case jsoncons::msgpack::msgpack_type::int32_type: 
439
25.8k
                {
440
25.8k
                    uint8_t buf[sizeof(int32_t)];
441
25.8k
                    if (source_.read(buf, sizeof(int32_t)) != sizeof(int32_t))
442
10
                    {
443
10
                        ec = msgpack_errc::unexpected_eof;
444
10
                        more_ = false;
445
10
                        return;
446
10
                    }
447
25.8k
                    int32_t val = binary::big_to_native<int32_t>(buf, sizeof(buf));
448
25.8k
                    visitor.int64_value(val, semantic_tag::none, *this, ec);
449
25.8k
                    more_ = !cursor_mode_;
450
25.8k
                    break;
451
25.8k
                }
452
453
26.7k
                case jsoncons::msgpack::msgpack_type::int64_type: 
454
26.7k
                {
455
26.7k
                    uint8_t buf[sizeof(int64_t)];
456
26.7k
                    if (source_.read(buf, sizeof(int64_t)) != sizeof(int64_t))
457
28
                    {
458
28
                        ec = msgpack_errc::unexpected_eof;
459
28
                        more_ = false;
460
28
                        return;
461
28
                    }
462
26.7k
                    int64_t val = binary::big_to_native<int64_t>(buf, sizeof(buf));
463
26.7k
                    visitor.int64_value(val, semantic_tag::none, *this, ec);
464
26.7k
                    more_ = !cursor_mode_;
465
26.7k
                    break;
466
26.7k
                }
467
468
2.59k
                case jsoncons::msgpack::msgpack_type::str8_type: 
469
4.62k
                case jsoncons::msgpack::msgpack_type::str16_type: 
470
6.40k
                case jsoncons::msgpack::msgpack_type::str32_type: 
471
6.40k
                {
472
6.40k
                    std::size_t len = get_size(type, ec);
473
6.40k
                    if (!more_)
474
77
                    {
475
77
                        return;
476
77
                    }
477
478
6.32k
                    auto data = source_.read_span(len, bytes_buffer_);
479
6.32k
                    if (data.size() != static_cast<std::size_t>(len))
480
352
                    {
481
352
                        ec = msgpack_errc::unexpected_eof;
482
352
                        more_ = false;
483
352
                        return;
484
352
                    }
485
486
5.97k
                    auto result = unicode_traits::validate(data.data(), data.size());
487
5.97k
                    if (result.ec != unicode_traits::unicode_errc())
488
140
                    {
489
140
                        ec = msgpack_errc::invalid_utf8_text_string;
490
140
                        more_ = false;
491
140
                        return;
492
140
                    }
493
5.83k
                    visitor.string_value(jsoncons::string_view(reinterpret_cast<const char*>(data.data()),data.size()), 
494
5.83k
                        semantic_tag::none, *this, ec);
495
5.83k
                    more_ = !cursor_mode_;
496
5.83k
                    break;
497
5.97k
                }
498
499
328k
                case jsoncons::msgpack::msgpack_type::bin8_type: 
500
336k
                case jsoncons::msgpack::msgpack_type::bin16_type: 
501
338k
                case jsoncons::msgpack::msgpack_type::bin32_type: 
502
338k
                {
503
338k
                    std::size_t len = get_size(type,ec);
504
338k
                    if (!more_)
505
83
                    {
506
83
                        return;
507
83
                    }
508
337k
                    auto data = source_.read_span(len, bytes_buffer_);
509
337k
                    if (JSONCONS_UNLIKELY(data.size() != static_cast<std::size_t>(len)))
510
436
                    {
511
436
                        ec = msgpack_errc::unexpected_eof;
512
436
                        more_ = false;
513
436
                        return;
514
436
                    }
515
516
337k
                    visitor.byte_string_value(byte_string_view(data.data(),data.size()), 
517
337k
                        semantic_tag::none, 
518
337k
                        *this,
519
337k
                        ec);
520
337k
                    more_ = !cursor_mode_;
521
337k
                    break;
522
337k
                }
523
1.22M
                case jsoncons::msgpack::msgpack_type::fixext1_type: 
524
2.74M
                case jsoncons::msgpack::msgpack_type::fixext2_type: 
525
2.84M
                case jsoncons::msgpack::msgpack_type::fixext4_type: 
526
2.97M
                case jsoncons::msgpack::msgpack_type::fixext8_type: 
527
3.10M
                case jsoncons::msgpack::msgpack_type::fixext16_type: 
528
3.21M
                case jsoncons::msgpack::msgpack_type::ext8_type: 
529
3.22M
                case jsoncons::msgpack::msgpack_type::ext16_type: 
530
3.22M
                case jsoncons::msgpack::msgpack_type::ext32_type: 
531
3.22M
                {
532
3.22M
                    std::size_t len = get_size(type,ec);
533
3.22M
                    if (!more_)
534
88
                    {
535
88
                        return;
536
88
                    }
537
538
                    // type
539
3.22M
                    uint8_t buf[sizeof(int8_t)];
540
3.22M
                    if (source_.read(buf, sizeof(int8_t)) != sizeof(int8_t))
541
143
                    {
542
143
                        ec = msgpack_errc::unexpected_eof;
543
143
                        more_ = false;
544
143
                        return;
545
143
                    }
546
547
3.22M
                    int8_t ext_type = binary::big_to_native<int8_t>(buf, sizeof(buf));
548
549
3.22M
                    bool is_timestamp = false; 
550
3.22M
                    if (ext_type == -1)
551
213k
                    {
552
213k
                        is_timestamp = true;;
553
213k
                    }
554
555
                    // payload
556
3.22M
                    if (is_timestamp && len == 4)
557
3.38k
                    {
558
3.38k
                        uint8_t buf32[sizeof(uint32_t)];
559
3.38k
                        if (source_.read(buf32, sizeof(uint32_t)) != sizeof(uint32_t))
560
9
                        {
561
9
                            ec = msgpack_errc::unexpected_eof;
562
9
                            more_ = false;
563
9
                            return;
564
9
                        }
565
3.37k
                        uint32_t val = binary::big_to_native<uint32_t>(buf32, sizeof(buf32));
566
3.37k
                        visitor.uint64_value(val, semantic_tag::epoch_second, *this, ec);
567
3.37k
                        more_ = !cursor_mode_;
568
3.37k
                    }
569
3.21M
                    else if (is_timestamp && len == 8)
570
112k
                    {
571
112k
                        uint8_t buf64[sizeof(uint64_t)];
572
112k
                        if (source_.read(buf64, sizeof(uint64_t)) != sizeof(uint64_t))
573
19
                        {
574
19
                            ec = msgpack_errc::unexpected_eof;
575
19
                            more_ = false;
576
19
                            return;
577
19
                        }
578
112k
                        uint64_t data64 = binary::big_to_native<uint64_t>(buf64, sizeof(buf64));
579
112k
                        uint64_t sec = data64 & 0x00000003ffffffffL;
580
112k
                        uint64_t nsec = data64 >> 34;
581
582
112k
                        bigint nano(sec);
583
112k
                        nano *= uint64_t(nanos_in_second);
584
112k
                        nano += nsec;
585
112k
                        text_buffer_.clear();
586
112k
                        nano.write_string(text_buffer_);
587
112k
                        visitor.string_value(text_buffer_, semantic_tag::epoch_nano, *this, ec);
588
112k
                        more_ = !cursor_mode_;
589
112k
                        if (!more_) return;
590
112k
                    }
591
3.10M
                    else if (is_timestamp && len == 12)
592
92.7k
                    {
593
92.7k
                        uint8_t buf1[sizeof(uint32_t)];
594
92.7k
                        if (source_.read(buf1, sizeof(uint32_t)) != sizeof(uint32_t))
595
12
                        {
596
12
                            ec = msgpack_errc::unexpected_eof;
597
12
                            more_ = false;
598
12
                            return;
599
12
                        }
600
92.7k
                        uint32_t nsec = binary::big_to_native<uint32_t>(buf1, sizeof(buf1));
601
602
92.7k
                        uint8_t buf2[sizeof(int64_t)];
603
92.7k
                        if (source_.read(buf2, sizeof(int64_t)) != sizeof(int64_t))
604
23
                        {
605
23
                            ec = msgpack_errc::unexpected_eof;
606
23
                            more_ = false;
607
23
                            return;
608
23
                        }
609
92.6k
                        int64_t sec = binary::big_to_native<int64_t>(buf2, sizeof(buf2));
610
611
92.6k
                        bigint nano(sec);
612
613
92.6k
                        nano *= uint64_t(nanos_in_second);
614
615
92.6k
                        if (nano < 0)
616
30.6k
                        {
617
30.6k
                            nano -= nsec;
618
30.6k
                        }
619
62.0k
                        else
620
62.0k
                        {
621
62.0k
                            nano += nsec;
622
62.0k
                        }
623
624
92.6k
                        text_buffer_.clear();
625
92.6k
                        nano.write_string(text_buffer_);
626
92.6k
                        visitor.string_value(text_buffer_, semantic_tag::epoch_nano, *this, ec);
627
92.6k
                        more_ = !cursor_mode_;
628
92.6k
                        if (!more_) return;
629
92.6k
                    }
630
3.01M
                    else
631
3.01M
                    {
632
3.01M
                        auto data = source_.read_span(len, bytes_buffer_);
633
3.01M
                        if (JSONCONS_UNLIKELY(data.size() != static_cast<std::size_t>(len)))
634
570
                        {
635
570
                            ec = msgpack_errc::unexpected_eof;
636
570
                            more_ = false;
637
570
                            return;
638
570
                        }
639
640
3.01M
                        visitor.byte_string_value(byte_string_view(data.data(),data.size()), 
641
3.01M
                                                          static_cast<uint8_t>(ext_type), 
642
3.01M
                                                          *this,
643
3.01M
                                                          ec);
644
3.01M
                        more_ = !cursor_mode_;
645
3.01M
                    }
646
3.22M
                    break;
647
3.22M
                }
648
649
3.22M
                case jsoncons::msgpack::msgpack_type::array16_type: 
650
26.8k
                case jsoncons::msgpack::msgpack_type::array32_type: 
651
26.8k
                {
652
26.8k
                    begin_array(visitor,type,ec);
653
26.8k
                    break;
654
16.7k
                }
655
656
18.2k
                case jsoncons::msgpack::msgpack_type::map16_type : 
657
22.3k
                case jsoncons::msgpack::msgpack_type::map32_type : 
658
22.3k
                {
659
22.3k
                    begin_object(visitor, type, ec);
660
22.3k
                    break;
661
18.2k
                }
662
663
42
                default:
664
42
                {
665
42
                    ec = msgpack_errc::unknown_type;
666
42
                    more_ = false;
667
42
                    return;
668
18.2k
                }
669
71.2M
            }
670
71.2M
        }
671
165M
    }
672
673
    void begin_array(generic_visitor& visitor, uint8_t type, std::error_code& ec)
674
7.17M
    {
675
7.17M
        if (JSONCONS_UNLIKELY(++nesting_depth_ > max_nesting_depth_))
676
12
        {
677
12
            ec = msgpack_errc::max_nesting_depth_exceeded;
678
12
            more_ = false;
679
12
            return;
680
12
        } 
681
7.17M
        std::size_t length = get_size(type, ec);
682
7.17M
        if (!more_)
683
51
        {
684
51
            return;
685
51
        }
686
7.17M
        state_stack_.emplace_back(parse_mode::array,length);
687
7.17M
        visitor.begin_array(length, semantic_tag::none, *this, ec);
688
7.17M
        more_ = !cursor_mode_;
689
7.17M
    }
690
691
    void end_array(generic_visitor& visitor, std::error_code& ec)
692
7.08M
    {
693
7.08M
        --nesting_depth_;
694
695
7.08M
        visitor.end_array(*this, ec);
696
7.08M
        more_ = !cursor_mode_;
697
7.08M
        state_stack_.pop_back();
698
7.08M
    }
699
700
    void begin_object(generic_visitor& visitor, uint8_t type, std::error_code& ec)
701
2.87M
    {
702
2.87M
        if (JSONCONS_UNLIKELY(++nesting_depth_ > max_nesting_depth_))
703
5
        {
704
5
            ec = msgpack_errc::max_nesting_depth_exceeded;
705
5
            more_ = false;
706
5
            return;
707
5
        } 
708
2.87M
        std::size_t length = get_size(type, ec);
709
2.87M
        if (!more_)
710
60
        {
711
60
            return;
712
60
        }
713
2.87M
        state_stack_.emplace_back(parse_mode::map_key,length);
714
2.87M
        visitor.begin_object(length, semantic_tag::none, *this, ec);
715
2.87M
        more_ = !cursor_mode_;
716
2.87M
    }
717
718
    void end_object(generic_visitor& visitor, std::error_code& ec)
719
2.80M
    {
720
2.80M
        --nesting_depth_;
721
2.80M
        visitor.end_object(*this, ec);
722
2.80M
        more_ = !cursor_mode_;
723
2.80M
        state_stack_.pop_back();
724
2.80M
    }
725
726
    std::size_t get_size(uint8_t type, std::error_code& ec)
727
13.6M
    {
728
13.6M
        switch (type)
729
13.6M
        {
730
2.59k
            case jsoncons::msgpack::msgpack_type::str8_type: 
731
331k
            case jsoncons::msgpack::msgpack_type::bin8_type: 
732
439k
            case jsoncons::msgpack::msgpack_type::ext8_type: 
733
439k
            {
734
439k
                uint8_t buf[sizeof(int8_t)];
735
439k
                if (source_.read(buf, sizeof(int8_t)) != sizeof(int8_t))
736
86
                {
737
86
                    ec = msgpack_errc::unexpected_eof;
738
86
                    more_ = false;
739
86
                    return 0;
740
86
                }
741
439k
                uint8_t len = binary::big_to_native<uint8_t>(buf, sizeof(buf));
742
439k
                return static_cast<std::size_t>(len);
743
439k
            }
744
745
2.03k
            case jsoncons::msgpack::msgpack_type::str16_type: 
746
10.0k
            case jsoncons::msgpack::msgpack_type::bin16_type: 
747
12.6k
            case jsoncons::msgpack::msgpack_type::ext16_type: 
748
29.3k
            case jsoncons::msgpack::msgpack_type::array16_type: 
749
47.5k
            case jsoncons::msgpack::msgpack_type::map16_type:
750
47.5k
            {
751
47.5k
                uint8_t buf[sizeof(int16_t)];
752
47.5k
                if (source_.read(buf, sizeof(int16_t)) != sizeof(int16_t))
753
134
                {
754
134
                    ec = msgpack_errc::unexpected_eof;
755
134
                    more_ = false;
756
134
                    return 0;
757
134
                }
758
47.4k
                uint16_t len = binary::big_to_native<uint16_t>(buf, sizeof(buf));
759
47.4k
                return static_cast<std::size_t>(len);
760
47.5k
            }
761
762
1.78k
            case jsoncons::msgpack::msgpack_type::str32_type: 
763
3.01k
            case jsoncons::msgpack::msgpack_type::bin32_type: 
764
6.32k
            case jsoncons::msgpack::msgpack_type::ext32_type: 
765
16.4k
            case jsoncons::msgpack::msgpack_type::array32_type: 
766
20.5k
            case jsoncons::msgpack::msgpack_type::map32_type : 
767
20.5k
            {
768
20.5k
                uint8_t buf[sizeof(int32_t)];
769
20.5k
                if (source_.read(buf, sizeof(int32_t)) != sizeof(int32_t))
770
139
                {
771
139
                    ec = msgpack_errc::unexpected_eof;
772
139
                    more_ = false;
773
139
                    return 0;
774
139
                }
775
20.4k
                uint32_t len = binary::big_to_native<uint32_t>(buf, sizeof(buf));
776
20.4k
                return static_cast<std::size_t>(len);
777
20.5k
            }
778
1.22M
            case jsoncons::msgpack::msgpack_type::fixext1_type: 
779
1.22M
                return 1;
780
1.51M
            case jsoncons::msgpack::msgpack_type::fixext2_type: 
781
1.51M
                return 2;
782
102k
            case jsoncons::msgpack::msgpack_type::fixext4_type: 
783
102k
                return 4;
784
126k
            case jsoncons::msgpack::msgpack_type::fixext8_type: 
785
126k
                return 8;
786
135k
            case jsoncons::msgpack::msgpack_type::fixext16_type: 
787
135k
                return 16;
788
10.0M
            default:
789
10.0M
                if ((type > 0x8f && type <= 0x9f) // fixarray
790
2.85M
                    || (type > 0x7f && type <= 0x8f) // fixmap
791
10.0M
        )
792
10.0M
                {
793
10.0M
                    return type & 0x0f;
794
10.0M
                }
795
0
                else
796
0
                {
797
0
                    ec = msgpack_errc::unknown_type;
798
0
                    more_ = false;
799
0
                    return 0;
800
0
                }
801
0
                break;
802
13.6M
        }
803
13.6M
    }
804
};
805
806
} // namespace msgpack
807
} // namespace jsoncons
808
809
#endif // JSONCONS_EXT_MSGPACK_MSGPACK_PARSER_HPP