Coverage Report

Created: 2026-09-06 07:05

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
9.85M
        : mode(mode), length(length)
47
9.85M
    {
48
9.85M
    }
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.5k
       : source_(std::forward<Sourceable>(source)),
87
18.5k
         max_nesting_depth_(options.max_nesting_depth()),
88
18.5k
         text_buffer_(alloc),
89
18.5k
         bytes_buffer_(alloc),
90
18.5k
         state_stack_(alloc)
91
18.5k
    {
92
18.5k
        state_stack_.emplace_back(parse_mode::root,0);
93
18.5k
    }
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.3k
       : source_(std::forward<Sourceable>(source)),
87
11.3k
         max_nesting_depth_(options.max_nesting_depth()),
88
11.3k
         text_buffer_(alloc),
89
11.3k
         bytes_buffer_(alloc),
90
11.3k
         state_stack_(alloc)
91
11.3k
    {
92
11.3k
        state_stack_.emplace_back(parse_mode::root,0);
93
11.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_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.22k
       : source_(std::forward<Sourceable>(source)),
87
7.22k
         max_nesting_depth_(options.max_nesting_depth()),
88
7.22k
         text_buffer_(alloc),
89
7.22k
         bytes_buffer_(alloc),
90
7.22k
         state_stack_(alloc)
91
7.22k
    {
92
7.22k
        state_stack_.emplace_back(parse_mode::root,0);
93
7.22k
    }
94
95
    void restart()
96
    {
97
        more_ = true;
98
    }
99
100
    void reset()
101
18.5k
    {
102
18.5k
        more_ = true;
103
18.5k
        done_ = false;
104
18.5k
        text_buffer_.clear();
105
18.5k
        bytes_buffer_.clear();
106
18.5k
        state_stack_.clear();
107
18.5k
        state_stack_.emplace_back(parse_mode::root,0);
108
18.5k
        nesting_depth_ = 0;
109
18.5k
    }
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.78k
    {
150
4.78k
        return 0;
151
4.78k
    }
152
153
    std::size_t column() const final
154
4.78k
    {
155
4.78k
        return source_.position();
156
4.78k
    }
157
158
    void parse(generic_visitor& visitor, std::error_code& ec)
159
18.5k
    {
160
174M
        while (!done_ && more_)
161
174M
        {
162
174M
            switch (state_stack_.back().mode)
163
174M
            {
164
114M
                case parse_mode::array:
165
114M
                {
166
114M
                    if (state_stack_.back().index < state_stack_.back().length)
167
107M
                    {
168
107M
                        ++state_stack_.back().index;
169
107M
                        read_item(visitor, ec);
170
107M
                        if (JSONCONS_UNLIKELY(ec))
171
3.90k
                        {
172
3.90k
                            return;
173
3.90k
                        }
174
107M
                    }
175
7.62M
                    else
176
7.62M
                    {
177
7.62M
                        end_array(visitor, ec);
178
7.62M
                    }
179
114M
                    break;
180
114M
                }
181
114M
                case parse_mode::map_key:
182
30.9M
                {
183
30.9M
                    if (state_stack_.back().index < state_stack_.back().length)
184
28.9M
                    {
185
28.9M
                        ++state_stack_.back().index;
186
28.9M
                        state_stack_.back().mode = parse_mode::map_value;
187
28.9M
                        read_item(visitor, ec);
188
28.9M
                        if (JSONCONS_UNLIKELY(ec))
189
2.51k
                        {
190
2.51k
                            return;
191
2.51k
                        }
192
28.9M
                    }
193
2.03M
                    else
194
2.03M
                    {
195
2.03M
                        end_object(visitor, ec);
196
2.03M
                    }
197
30.9M
                    break;
198
30.9M
                }
199
30.9M
                case parse_mode::map_value:
200
28.9M
                {
201
28.9M
                    state_stack_.back().mode = parse_mode::map_key;
202
28.9M
                    read_item(visitor, ec);
203
28.9M
                    if (JSONCONS_UNLIKELY(ec))
204
5.83k
                    {
205
5.83k
                        return;
206
5.83k
                    }
207
28.9M
                    break;
208
28.9M
                }
209
28.9M
                case parse_mode::root:
210
18.5k
                {
211
18.5k
                    state_stack_.back().mode = parse_mode::accept;
212
18.5k
                    read_item(visitor, ec);
213
18.5k
                    if (JSONCONS_UNLIKELY(ec))
214
1.33k
                    {
215
1.33k
                        return;
216
1.33k
                    }
217
17.2k
                    break;
218
18.5k
                }
219
17.2k
                case parse_mode::accept:
220
4.99k
                {
221
4.99k
                    JSONCONS_ASSERT(state_stack_.size() == 1);
222
4.99k
                    state_stack_.clear();
223
4.99k
                    more_ = false;
224
4.99k
                    done_ = true;
225
4.99k
                    visitor.flush();
226
4.99k
                    break;
227
4.99k
                }
228
174M
            }
229
174M
        }
230
18.5k
    }
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.6k
        {
245
10.6k
            ec = msgpack_errc::unexpected_eof;
246
10.6k
            more_ = false;
247
10.6k
            return;
248
10.6k
        }
249
250
165M
        if (type <= 0xbf)
251
78.6M
        {
252
78.6M
            if (type <= 0x7f) 
253
61.8M
            {
254
                // positive fixint
255
61.8M
                visitor.uint64_value(type, semantic_tag::none, *this, ec);
256
61.8M
                more_ = !cursor_mode_;
257
61.8M
            }
258
16.8M
            else if (type <= 0x8f) 
259
2.08M
            {
260
2.08M
                begin_object(visitor,type,ec); // fixmap
261
2.08M
            }
262
14.7M
            else if (type <= 0x9f) 
263
7.68M
            {
264
7.68M
                begin_array(visitor,type,ec); // fixarray
265
7.68M
            }
266
7.06M
            else 
267
7.06M
            {
268
                // fixstr
269
7.06M
                const size_t len = type & 0x1f;
270
271
7.06M
                auto data = source_.read_span(len, bytes_buffer_);
272
7.06M
                if (data.size() != static_cast<std::size_t>(len))
273
152
                {
274
152
                    ec = msgpack_errc::unexpected_eof;
275
152
                    more_ = false;
276
152
                    return;
277
152
                }
278
279
7.06M
                auto result = unicode_traits::validate(data.data(), data.size());
280
7.06M
                if (result.ec != unicode_traits::unicode_errc())
281
498
                {
282
498
                    ec = msgpack_errc::invalid_utf8_text_string;
283
498
                    more_ = false;
284
498
                    return;
285
498
                }
286
7.06M
                visitor.string_value(jsoncons::string_view(reinterpret_cast<const char*>(data.data()),data.size()), 
287
7.06M
                    semantic_tag::none, *this, ec);
288
7.06M
                more_ = !cursor_mode_;
289
7.06M
            }
290
78.6M
        }
291
86.5M
        else if (type >= 0xe0) 
292
13.7M
        {
293
            // negative fixint
294
13.7M
            visitor.int64_value(static_cast<int8_t>(type), semantic_tag::none, *this, ec);
295
13.7M
            more_ = !cursor_mode_;
296
13.7M
        }
297
72.8M
        else
298
72.8M
        {
299
72.8M
            switch (type)
300
72.8M
            {
301
2.85M
                case jsoncons::msgpack::msgpack_type::nil_type: 
302
2.85M
                {
303
2.85M
                    visitor.null_value(semantic_tag::none, *this, ec);
304
2.85M
                    more_ = !cursor_mode_;
305
2.85M
                    break;
306
0
                }
307
9.12M
                case jsoncons::msgpack::msgpack_type::true_type:
308
9.12M
                {
309
9.12M
                    visitor.bool_value(true, semantic_tag::none, *this, ec);
310
9.12M
                    more_ = !cursor_mode_;
311
9.12M
                    break;
312
0
                }
313
55.3M
                case jsoncons::msgpack::msgpack_type::false_type:
314
55.3M
                {
315
55.3M
                    visitor.bool_value(false, semantic_tag::none, *this, ec);
316
55.3M
                    more_ = !cursor_mode_;
317
55.3M
                    break;
318
0
                }
319
270k
                case jsoncons::msgpack::msgpack_type::float32_type: 
320
270k
                {
321
270k
                    uint8_t buf[sizeof(float)];
322
270k
                    if (source_.read(buf, sizeof(float)) != sizeof(float))
323
61
                    {
324
61
                        ec = msgpack_errc::unexpected_eof;
325
61
                        more_ = false;
326
61
                        return;
327
61
                    }
328
270k
                    float val = binary::big_to_native<float>(buf, sizeof(buf));
329
270k
                    visitor.double_value(val, semantic_tag::none, *this, ec);
330
270k
                    more_ = !cursor_mode_;
331
270k
                    break;
332
270k
                }
333
334
86.0k
                case jsoncons::msgpack::msgpack_type::float64_type: 
335
86.0k
                {
336
86.0k
                    uint8_t buf[sizeof(double)];
337
86.0k
                    if (source_.read(buf, sizeof(double)) != sizeof(double))
338
28
                    {
339
28
                        ec = msgpack_errc::unexpected_eof;
340
28
                        more_ = false;
341
28
                        return;
342
28
                    }
343
86.0k
                    double val = binary::big_to_native<double>(buf, sizeof(buf));
344
86.0k
                    visitor.double_value(val, semantic_tag::none, *this, ec);
345
86.0k
                    more_ = !cursor_mode_;
346
86.0k
                    break;
347
86.0k
                }
348
349
38.6k
                case jsoncons::msgpack::msgpack_type::uint8_type: 
350
38.6k
                {
351
38.6k
                    uint8_t b;
352
38.6k
                    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
38.6k
                    visitor.uint64_value(b, semantic_tag::none, *this, ec);
359
38.6k
                    more_ = !cursor_mode_;
360
38.6k
                    break;
361
38.6k
                }
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
89.2k
                case jsoncons::msgpack::msgpack_type::uint32_type: 
379
89.2k
                {
380
89.2k
                    uint8_t buf[sizeof(uint32_t)];
381
89.2k
                    if (source_.read(buf, sizeof(uint32_t)) != sizeof(uint32_t))
382
12
                    {
383
12
                        ec = msgpack_errc::unexpected_eof;
384
12
                        more_ = false;
385
12
                        return;
386
12
                    }
387
89.2k
                    uint32_t val = binary::big_to_native<uint32_t>(buf, sizeof(buf));
388
89.2k
                    visitor.uint64_value(val, semantic_tag::none, *this, ec);
389
89.2k
                    more_ = !cursor_mode_;
390
89.2k
                    break;
391
89.2k
                }
392
393
11.3k
                case jsoncons::msgpack::msgpack_type::uint64_type: 
394
11.3k
                {
395
11.3k
                    uint8_t buf[sizeof(uint64_t)];
396
11.3k
                    if (source_.read(buf, sizeof(uint64_t)) != sizeof(uint64_t))
397
20
                    {
398
20
                        ec = msgpack_errc::unexpected_eof;
399
20
                        more_ = false;
400
20
                        return;
401
20
                    }
402
11.3k
                    uint64_t val = binary::big_to_native<uint64_t>(buf, sizeof(buf));
403
11.3k
                    visitor.uint64_value(val, semantic_tag::none, *this, ec);
404
11.3k
                    more_ = !cursor_mode_;
405
11.3k
                    break;
406
11.3k
                }
407
408
408k
                case jsoncons::msgpack::msgpack_type::int8_type: 
409
408k
                {
410
408k
                    uint8_t buf[sizeof(int8_t)];
411
408k
                    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
408k
                    int8_t val = binary::big_to_native<int8_t>(buf, sizeof(buf));
418
408k
                    visitor.int64_value(val, semantic_tag::none, *this, ec);
419
408k
                    more_ = !cursor_mode_;
420
408k
                    break;
421
408k
                }
422
423
150k
                case jsoncons::msgpack::msgpack_type::int16_type: 
424
150k
                {
425
150k
                    uint8_t buf[sizeof(int16_t)];
426
150k
                    if (source_.read(buf, sizeof(int16_t)) != sizeof(int16_t))
427
10
                    {
428
10
                        ec = msgpack_errc::unexpected_eof;
429
10
                        more_ = false;
430
10
                        return;
431
10
                    }
432
150k
                    int16_t val = binary::big_to_native<int16_t>(buf, sizeof(buf));
433
150k
                    visitor.int64_value(val, semantic_tag::none, *this, ec);
434
150k
                    more_ = !cursor_mode_;
435
150k
                    break;
436
150k
                }
437
438
27.0k
                case jsoncons::msgpack::msgpack_type::int32_type: 
439
27.0k
                {
440
27.0k
                    uint8_t buf[sizeof(int32_t)];
441
27.0k
                    if (source_.read(buf, sizeof(int32_t)) != sizeof(int32_t))
442
9
                    {
443
9
                        ec = msgpack_errc::unexpected_eof;
444
9
                        more_ = false;
445
9
                        return;
446
9
                    }
447
27.0k
                    int32_t val = binary::big_to_native<int32_t>(buf, sizeof(buf));
448
27.0k
                    visitor.int64_value(val, semantic_tag::none, *this, ec);
449
27.0k
                    more_ = !cursor_mode_;
450
27.0k
                    break;
451
27.0k
                }
452
453
38.0k
                case jsoncons::msgpack::msgpack_type::int64_type: 
454
38.0k
                {
455
38.0k
                    uint8_t buf[sizeof(int64_t)];
456
38.0k
                    if (source_.read(buf, sizeof(int64_t)) != sizeof(int64_t))
457
32
                    {
458
32
                        ec = msgpack_errc::unexpected_eof;
459
32
                        more_ = false;
460
32
                        return;
461
32
                    }
462
38.0k
                    int64_t val = binary::big_to_native<int64_t>(buf, sizeof(buf));
463
38.0k
                    visitor.int64_value(val, semantic_tag::none, *this, ec);
464
38.0k
                    more_ = !cursor_mode_;
465
38.0k
                    break;
466
38.0k
                }
467
468
2.63k
                case jsoncons::msgpack::msgpack_type::str8_type: 
469
4.25k
                case jsoncons::msgpack::msgpack_type::str16_type: 
470
6.04k
                case jsoncons::msgpack::msgpack_type::str32_type: 
471
6.04k
                {
472
6.04k
                    std::size_t len = get_size(type, ec);
473
6.04k
                    if (!more_)
474
78
                    {
475
78
                        return;
476
78
                    }
477
478
5.96k
                    auto data = source_.read_span(len, bytes_buffer_);
479
5.96k
                    if (data.size() != static_cast<std::size_t>(len))
480
350
                    {
481
350
                        ec = msgpack_errc::unexpected_eof;
482
350
                        more_ = false;
483
350
                        return;
484
350
                    }
485
486
5.61k
                    auto result = unicode_traits::validate(data.data(), data.size());
487
5.61k
                    if (result.ec != unicode_traits::unicode_errc())
488
149
                    {
489
149
                        ec = msgpack_errc::invalid_utf8_text_string;
490
149
                        more_ = false;
491
149
                        return;
492
149
                    }
493
5.46k
                    visitor.string_value(jsoncons::string_view(reinterpret_cast<const char*>(data.data()),data.size()), 
494
5.46k
                        semantic_tag::none, *this, ec);
495
5.46k
                    more_ = !cursor_mode_;
496
5.46k
                    break;
497
5.61k
                }
498
499
249k
                case jsoncons::msgpack::msgpack_type::bin8_type: 
500
258k
                case jsoncons::msgpack::msgpack_type::bin16_type: 
501
259k
                case jsoncons::msgpack::msgpack_type::bin32_type: 
502
259k
                {
503
259k
                    std::size_t len = get_size(type,ec);
504
259k
                    if (!more_)
505
83
                    {
506
83
                        return;
507
83
                    }
508
259k
                    auto data = source_.read_span(len, bytes_buffer_);
509
259k
                    if (JSONCONS_UNLIKELY(data.size() != static_cast<std::size_t>(len)))
510
435
                    {
511
435
                        ec = msgpack_errc::unexpected_eof;
512
435
                        more_ = false;
513
435
                        return;
514
435
                    }
515
516
259k
                    visitor.byte_string_value(byte_string_view(data.data(),data.size()), 
517
259k
                        semantic_tag::none, 
518
259k
                        *this,
519
259k
                        ec);
520
259k
                    more_ = !cursor_mode_;
521
259k
                    break;
522
259k
                }
523
864k
                case jsoncons::msgpack::msgpack_type::fixext1_type: 
524
3.31M
                case jsoncons::msgpack::msgpack_type::fixext2_type: 
525
3.58M
                case jsoncons::msgpack::msgpack_type::fixext4_type: 
526
3.67M
                case jsoncons::msgpack::msgpack_type::fixext8_type: 
527
3.78M
                case jsoncons::msgpack::msgpack_type::fixext16_type: 
528
3.88M
                case jsoncons::msgpack::msgpack_type::ext8_type: 
529
3.88M
                case jsoncons::msgpack::msgpack_type::ext16_type: 
530
3.89M
                case jsoncons::msgpack::msgpack_type::ext32_type: 
531
3.89M
                {
532
3.89M
                    std::size_t len = get_size(type,ec);
533
3.89M
                    if (!more_)
534
87
                    {
535
87
                        return;
536
87
                    }
537
538
                    // type
539
3.89M
                    uint8_t buf[sizeof(int8_t)];
540
3.89M
                    if (source_.read(buf, sizeof(int8_t)) != sizeof(int8_t))
541
148
                    {
542
148
                        ec = msgpack_errc::unexpected_eof;
543
148
                        more_ = false;
544
148
                        return;
545
148
                    }
546
547
3.89M
                    int8_t ext_type = binary::big_to_native<int8_t>(buf, sizeof(buf));
548
549
3.89M
                    bool is_timestamp = false; 
550
3.89M
                    if (ext_type == -1)
551
176k
                    {
552
176k
                        is_timestamp = true;;
553
176k
                    }
554
555
                    // payload
556
3.89M
                    if (is_timestamp && len == 4)
557
4.43k
                    {
558
4.43k
                        uint8_t buf32[sizeof(uint32_t)];
559
4.43k
                        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
4.42k
                        uint32_t val = binary::big_to_native<uint32_t>(buf32, sizeof(buf32));
566
4.42k
                        visitor.uint64_value(val, semantic_tag::epoch_second, *this, ec);
567
4.42k
                        more_ = !cursor_mode_;
568
4.42k
                    }
569
3.88M
                    else if (is_timestamp && len == 8)
570
83.1k
                    {
571
83.1k
                        uint8_t buf64[sizeof(uint64_t)];
572
83.1k
                        if (source_.read(buf64, sizeof(uint64_t)) != sizeof(uint64_t))
573
21
                        {
574
21
                            ec = msgpack_errc::unexpected_eof;
575
21
                            more_ = false;
576
21
                            return;
577
21
                        }
578
83.1k
                        uint64_t data64 = binary::big_to_native<uint64_t>(buf64, sizeof(buf64));
579
83.1k
                        uint64_t sec = data64 & 0x00000003ffffffffL;
580
83.1k
                        uint64_t nsec = data64 >> 34;
581
582
83.1k
                        bigint nano(sec);
583
83.1k
                        nano *= uint64_t(nanos_in_second);
584
83.1k
                        nano += nsec;
585
83.1k
                        text_buffer_.clear();
586
83.1k
                        nano.write_string(text_buffer_);
587
83.1k
                        visitor.string_value(text_buffer_, semantic_tag::epoch_nano, *this, ec);
588
83.1k
                        more_ = !cursor_mode_;
589
83.1k
                        if (!more_) return;
590
83.1k
                    }
591
3.80M
                    else if (is_timestamp && len == 12)
592
84.8k
                    {
593
84.8k
                        uint8_t buf1[sizeof(uint32_t)];
594
84.8k
                        if (source_.read(buf1, sizeof(uint32_t)) != sizeof(uint32_t))
595
13
                        {
596
13
                            ec = msgpack_errc::unexpected_eof;
597
13
                            more_ = false;
598
13
                            return;
599
13
                        }
600
84.8k
                        uint32_t nsec = binary::big_to_native<uint32_t>(buf1, sizeof(buf1));
601
602
84.8k
                        uint8_t buf2[sizeof(int64_t)];
603
84.8k
                        if (source_.read(buf2, sizeof(int64_t)) != sizeof(int64_t))
604
19
                        {
605
19
                            ec = msgpack_errc::unexpected_eof;
606
19
                            more_ = false;
607
19
                            return;
608
19
                        }
609
84.7k
                        int64_t sec = binary::big_to_native<int64_t>(buf2, sizeof(buf2));
610
611
84.7k
                        bigint nano(sec);
612
613
84.7k
                        nano *= uint64_t(nanos_in_second);
614
615
84.7k
                        if (nano < 0)
616
29.5k
                        {
617
29.5k
                            nano -= nsec;
618
29.5k
                        }
619
55.2k
                        else
620
55.2k
                        {
621
55.2k
                            nano += nsec;
622
55.2k
                        }
623
624
84.7k
                        text_buffer_.clear();
625
84.7k
                        nano.write_string(text_buffer_);
626
84.7k
                        visitor.string_value(text_buffer_, semantic_tag::epoch_nano, *this, ec);
627
84.7k
                        more_ = !cursor_mode_;
628
84.7k
                        if (!more_) return;
629
84.7k
                    }
630
3.71M
                    else
631
3.71M
                    {
632
3.71M
                        auto data = source_.read_span(len, bytes_buffer_);
633
3.71M
                        if (JSONCONS_UNLIKELY(data.size() != static_cast<std::size_t>(len)))
634
583
                        {
635
583
                            ec = msgpack_errc::unexpected_eof;
636
583
                            more_ = false;
637
583
                            return;
638
583
                        }
639
640
3.71M
                        visitor.byte_string_value(byte_string_view(data.data(),data.size()), 
641
3.71M
                                                          static_cast<uint8_t>(ext_type), 
642
3.71M
                                                          *this,
643
3.71M
                                                          ec);
644
3.71M
                        more_ = !cursor_mode_;
645
3.71M
                    }
646
3.89M
                    break;
647
3.89M
                }
648
649
3.89M
                case jsoncons::msgpack::msgpack_type::array16_type: 
650
24.3k
                case jsoncons::msgpack::msgpack_type::array32_type: 
651
24.3k
                {
652
24.3k
                    begin_array(visitor,type,ec);
653
24.3k
                    break;
654
14.7k
                }
655
656
17.2k
                case jsoncons::msgpack::msgpack_type::map16_type : 
657
21.8k
                case jsoncons::msgpack::msgpack_type::map32_type : 
658
21.8k
                {
659
21.8k
                    begin_object(visitor, type, ec);
660
21.8k
                    break;
661
17.2k
                }
662
663
45
                default:
664
45
                {
665
45
                    ec = msgpack_errc::unknown_type;
666
45
                    more_ = false;
667
45
                    return;
668
17.2k
                }
669
72.8M
            }
670
72.8M
        }
671
165M
    }
672
673
    void begin_array(generic_visitor& visitor, uint8_t type, std::error_code& ec)
674
7.71M
    {
675
7.71M
        if (JSONCONS_UNLIKELY(++nesting_depth_ > max_nesting_depth_))
676
10
        {
677
10
            ec = msgpack_errc::max_nesting_depth_exceeded;
678
10
            more_ = false;
679
10
            return;
680
10
        } 
681
7.71M
        std::size_t length = get_size(type, ec);
682
7.71M
        if (!more_)
683
57
        {
684
57
            return;
685
57
        }
686
7.71M
        state_stack_.emplace_back(parse_mode::array,length);
687
7.71M
        visitor.begin_array(length, semantic_tag::none, *this, ec);
688
7.71M
        more_ = !cursor_mode_;
689
7.71M
    }
690
691
    void end_array(generic_visitor& visitor, std::error_code& ec)
692
7.62M
    {
693
7.62M
        --nesting_depth_;
694
695
7.62M
        visitor.end_array(*this, ec);
696
7.62M
        more_ = !cursor_mode_;
697
7.62M
        state_stack_.pop_back();
698
7.62M
    }
699
700
    void begin_object(generic_visitor& visitor, uint8_t type, std::error_code& ec)
701
2.10M
    {
702
2.10M
        if (JSONCONS_UNLIKELY(++nesting_depth_ > max_nesting_depth_))
703
6
        {
704
6
            ec = msgpack_errc::max_nesting_depth_exceeded;
705
6
            more_ = false;
706
6
            return;
707
6
        } 
708
2.10M
        std::size_t length = get_size(type, ec);
709
2.10M
        if (!more_)
710
57
        {
711
57
            return;
712
57
        }
713
2.10M
        state_stack_.emplace_back(parse_mode::map_key,length);
714
2.10M
        visitor.begin_object(length, semantic_tag::none, *this, ec);
715
2.10M
        more_ = !cursor_mode_;
716
2.10M
    }
717
718
    void end_object(generic_visitor& visitor, std::error_code& ec)
719
2.03M
    {
720
2.03M
        --nesting_depth_;
721
2.03M
        visitor.end_object(*this, ec);
722
2.03M
        more_ = !cursor_mode_;
723
2.03M
        state_stack_.pop_back();
724
2.03M
    }
725
726
    std::size_t get_size(uint8_t type, std::error_code& ec)
727
13.9M
    {
728
13.9M
        switch (type)
729
13.9M
        {
730
2.63k
            case jsoncons::msgpack::msgpack_type::str8_type: 
731
252k
            case jsoncons::msgpack::msgpack_type::bin8_type: 
732
352k
            case jsoncons::msgpack::msgpack_type::ext8_type: 
733
352k
            {
734
352k
                uint8_t buf[sizeof(int8_t)];
735
352k
                if (source_.read(buf, sizeof(int8_t)) != sizeof(int8_t))
736
85
                {
737
85
                    ec = msgpack_errc::unexpected_eof;
738
85
                    more_ = false;
739
85
                    return 0;
740
85
                }
741
352k
                uint8_t len = binary::big_to_native<uint8_t>(buf, sizeof(buf));
742
352k
                return static_cast<std::size_t>(len);
743
352k
            }
744
745
1.62k
            case jsoncons::msgpack::msgpack_type::str16_type: 
746
10.2k
            case jsoncons::msgpack::msgpack_type::bin16_type: 
747
12.3k
            case jsoncons::msgpack::msgpack_type::ext16_type: 
748
27.0k
            case jsoncons::msgpack::msgpack_type::array16_type: 
749
44.2k
            case jsoncons::msgpack::msgpack_type::map16_type:
750
44.2k
            {
751
44.2k
                uint8_t buf[sizeof(int16_t)];
752
44.2k
                if (source_.read(buf, sizeof(int16_t)) != sizeof(int16_t))
753
136
                {
754
136
                    ec = msgpack_errc::unexpected_eof;
755
136
                    more_ = false;
756
136
                    return 0;
757
136
                }
758
44.1k
                uint16_t len = binary::big_to_native<uint16_t>(buf, sizeof(buf));
759
44.1k
                return static_cast<std::size_t>(len);
760
44.2k
            }
761
762
1.79k
            case jsoncons::msgpack::msgpack_type::str32_type: 
763
3.24k
            case jsoncons::msgpack::msgpack_type::bin32_type: 
764
6.71k
            case jsoncons::msgpack::msgpack_type::ext32_type: 
765
16.2k
            case jsoncons::msgpack::msgpack_type::array32_type: 
766
20.8k
            case jsoncons::msgpack::msgpack_type::map32_type : 
767
20.8k
            {
768
20.8k
                uint8_t buf[sizeof(int32_t)];
769
20.8k
                if (source_.read(buf, sizeof(int32_t)) != sizeof(int32_t))
770
141
                {
771
141
                    ec = msgpack_errc::unexpected_eof;
772
141
                    more_ = false;
773
141
                    return 0;
774
141
                }
775
20.7k
                uint32_t len = binary::big_to_native<uint32_t>(buf, sizeof(buf));
776
20.7k
                return static_cast<std::size_t>(len);
777
20.8k
            }
778
864k
            case jsoncons::msgpack::msgpack_type::fixext1_type: 
779
864k
                return 1;
780
2.44M
            case jsoncons::msgpack::msgpack_type::fixext2_type: 
781
2.44M
                return 2;
782
272k
            case jsoncons::msgpack::msgpack_type::fixext4_type: 
783
272k
                return 4;
784
95.2k
            case jsoncons::msgpack::msgpack_type::fixext8_type: 
785
95.2k
                return 8;
786
108k
            case jsoncons::msgpack::msgpack_type::fixext16_type: 
787
108k
                return 16;
788
9.77M
            default:
789
9.77M
                if ((type > 0x8f && type <= 0x9f) // fixarray
790
2.08M
                    || (type > 0x7f && type <= 0x8f) // fixmap
791
9.77M
        )
792
9.77M
                {
793
9.77M
                    return type & 0x0f;
794
9.77M
                }
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.9M
        }
803
13.9M
    }
804
};
805
806
} // namespace msgpack
807
} // namespace jsoncons
808
809
#endif // JSONCONS_EXT_MSGPACK_MSGPACK_PARSER_HPP