Coverage Report

Created: 2026-08-13 06:30

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.4M
        : mode(mode), length(length)
47
10.4M
    {
48
10.4M
    }
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.2k
       : source_(std::forward<Sourceable>(source)),
87
18.2k
         max_nesting_depth_(options.max_nesting_depth()),
88
18.2k
         text_buffer_(alloc),
89
18.2k
         bytes_buffer_(alloc),
90
18.2k
         state_stack_(alloc)
91
18.2k
    {
92
18.2k
        state_stack_.emplace_back(parse_mode::root,0);
93
18.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
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.11k
       : source_(std::forward<Sourceable>(source)),
87
7.11k
         max_nesting_depth_(options.max_nesting_depth()),
88
7.11k
         text_buffer_(alloc),
89
7.11k
         bytes_buffer_(alloc),
90
7.11k
         state_stack_(alloc)
91
7.11k
    {
92
7.11k
        state_stack_.emplace_back(parse_mode::root,0);
93
7.11k
    }
94
95
    void restart()
96
    {
97
        more_ = true;
98
    }
99
100
    void reset()
101
18.2k
    {
102
18.2k
        more_ = true;
103
18.2k
        done_ = false;
104
18.2k
        text_buffer_.clear();
105
18.2k
        bytes_buffer_.clear();
106
18.2k
        state_stack_.clear();
107
18.2k
        state_stack_.emplace_back(parse_mode::root,0);
108
18.2k
        nesting_depth_ = 0;
109
18.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 final
149
4.72k
    {
150
4.72k
        return 0;
151
4.72k
    }
152
153
    std::size_t column() const final
154
4.72k
    {
155
4.72k
        return source_.position();
156
4.72k
    }
157
158
    void parse(generic_visitor& visitor, std::error_code& ec)
159
18.2k
    {
160
174M
        while (!done_ && more_)
161
174M
        {
162
174M
            switch (state_stack_.back().mode)
163
174M
            {
164
111M
                case parse_mode::array:
165
111M
                {
166
111M
                    if (state_stack_.back().index < state_stack_.back().length)
167
104M
                    {
168
104M
                        ++state_stack_.back().index;
169
104M
                        read_item(visitor, ec);
170
104M
                        if (JSONCONS_UNLIKELY(ec))
171
3.88k
                        {
172
3.88k
                            return;
173
3.88k
                        }
174
104M
                    }
175
7.33M
                    else
176
7.33M
                    {
177
7.33M
                        end_array(visitor, ec);
178
7.33M
                    }
179
111M
                    break;
180
111M
                }
181
111M
                case parse_mode::map_key:
182
32.6M
                {
183
32.6M
                    if (state_stack_.back().index < state_stack_.back().length)
184
29.7M
                    {
185
29.7M
                        ++state_stack_.back().index;
186
29.7M
                        state_stack_.back().mode = parse_mode::map_value;
187
29.7M
                        read_item(visitor, ec);
188
29.7M
                        if (JSONCONS_UNLIKELY(ec))
189
2.49k
                        {
190
2.49k
                            return;
191
2.49k
                        }
192
29.7M
                    }
193
2.86M
                    else
194
2.86M
                    {
195
2.86M
                        end_object(visitor, ec);
196
2.86M
                    }
197
32.6M
                    break;
198
32.6M
                }
199
32.6M
                case parse_mode::map_value:
200
29.7M
                {
201
29.7M
                    state_stack_.back().mode = parse_mode::map_key;
202
29.7M
                    read_item(visitor, ec);
203
29.7M
                    if (JSONCONS_UNLIKELY(ec))
204
5.70k
                    {
205
5.70k
                        return;
206
5.70k
                    }
207
29.7M
                    break;
208
29.7M
                }
209
29.7M
                case parse_mode::root:
210
18.2k
                {
211
18.2k
                    state_stack_.back().mode = parse_mode::accept;
212
18.2k
                    read_item(visitor, ec);
213
18.2k
                    if (JSONCONS_UNLIKELY(ec))
214
1.29k
                    {
215
1.29k
                        return;
216
1.29k
                    }
217
16.9k
                    break;
218
18.2k
                }
219
16.9k
                case parse_mode::accept:
220
4.91k
                {
221
4.91k
                    JSONCONS_ASSERT(state_stack_.size() == 1);
222
4.91k
                    state_stack_.clear();
223
4.91k
                    more_ = false;
224
4.91k
                    done_ = true;
225
4.91k
                    visitor.flush();
226
4.91k
                    break;
227
4.91k
                }
228
174M
            }
229
174M
        }
230
18.2k
    }
231
private:
232
233
    void read_item(generic_visitor& visitor, std::error_code& ec)
234
164M
    {
235
164M
        if (source_.is_error())
236
0
        {
237
0
            ec = msgpack_errc::source_error;
238
0
            more_ = false;
239
0
            return;
240
0
        }   
241
242
164M
        uint8_t type;
243
164M
        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
164M
        if (type <= 0xbf)
251
80.8M
        {
252
80.8M
            if (type <= 0x7f) 
253
62.1M
            {
254
                // positive fixint
255
62.1M
                visitor.uint64_value(type, semantic_tag::none, *this, ec);
256
62.1M
                more_ = !cursor_mode_;
257
62.1M
            }
258
18.6M
            else if (type <= 0x8f) 
259
2.92M
            {
260
2.92M
                begin_object(visitor,type,ec); // fixmap
261
2.92M
            }
262
15.7M
            else if (type <= 0x9f) 
263
7.40M
            {
264
7.40M
                begin_array(visitor,type,ec); // fixarray
265
7.40M
            }
266
8.34M
            else 
267
8.34M
            {
268
                // fixstr
269
8.34M
                const size_t len = type & 0x1f;
270
271
8.34M
                auto data = source_.read_span(len, bytes_buffer_);
272
8.34M
                if (data.size() != static_cast<std::size_t>(len))
273
146
                {
274
146
                    ec = msgpack_errc::unexpected_eof;
275
146
                    more_ = false;
276
146
                    return;
277
146
                }
278
279
8.34M
                auto result = unicode_traits::validate(data.data(), data.size());
280
8.34M
                if (result.ec != unicode_traits::unicode_errc())
281
491
                {
282
491
                    ec = msgpack_errc::invalid_utf8_text_string;
283
491
                    more_ = false;
284
491
                    return;
285
491
                }
286
8.34M
                visitor.string_value(jsoncons::string_view(reinterpret_cast<const char*>(data.data()),data.size()), 
287
8.34M
                    semantic_tag::none, *this, ec);
288
8.34M
                more_ = !cursor_mode_;
289
8.34M
            }
290
80.8M
        }
291
83.2M
        else if (type >= 0xe0) 
292
15.0M
        {
293
            // negative fixint
294
15.0M
            visitor.int64_value(static_cast<int8_t>(type), semantic_tag::none, *this, ec);
295
15.0M
            more_ = !cursor_mode_;
296
15.0M
        }
297
68.1M
        else
298
68.1M
        {
299
68.1M
            switch (type)
300
68.1M
            {
301
3.12M
                case jsoncons::msgpack::msgpack_type::nil_type: 
302
3.12M
                {
303
3.12M
                    visitor.null_value(semantic_tag::none, *this, ec);
304
3.12M
                    more_ = !cursor_mode_;
305
3.12M
                    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
51.8M
                case jsoncons::msgpack::msgpack_type::false_type:
314
51.8M
                {
315
51.8M
                    visitor.bool_value(false, semantic_tag::none, *this, ec);
316
51.8M
                    more_ = !cursor_mode_;
317
51.8M
                    break;
318
0
                }
319
312k
                case jsoncons::msgpack::msgpack_type::float32_type: 
320
312k
                {
321
312k
                    uint8_t buf[sizeof(float)];
322
312k
                    if (source_.read(buf, sizeof(float)) != sizeof(float))
323
64
                    {
324
64
                        ec = msgpack_errc::unexpected_eof;
325
64
                        more_ = false;
326
64
                        return;
327
64
                    }
328
311k
                    float val = binary::big_to_native<float>(buf, sizeof(buf));
329
311k
                    visitor.double_value(val, semantic_tag::none, *this, ec);
330
311k
                    more_ = !cursor_mode_;
331
311k
                    break;
332
312k
                }
333
334
90.0k
                case jsoncons::msgpack::msgpack_type::float64_type: 
335
90.0k
                {
336
90.0k
                    uint8_t buf[sizeof(double)];
337
90.0k
                    if (source_.read(buf, sizeof(double)) != sizeof(double))
338
33
                    {
339
33
                        ec = msgpack_errc::unexpected_eof;
340
33
                        more_ = false;
341
33
                        return;
342
33
                    }
343
90.0k
                    double val = binary::big_to_native<double>(buf, sizeof(buf));
344
90.0k
                    visitor.double_value(val, semantic_tag::none, *this, ec);
345
90.0k
                    more_ = !cursor_mode_;
346
90.0k
                    break;
347
90.0k
                }
348
349
26.7k
                case jsoncons::msgpack::msgpack_type::uint8_type: 
350
26.7k
                {
351
26.7k
                    uint8_t b;
352
26.7k
                    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
26.7k
                    visitor.uint64_value(b, semantic_tag::none, *this, ec);
359
26.7k
                    more_ = !cursor_mode_;
360
26.7k
                    break;
361
26.7k
                }
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
139k
                case jsoncons::msgpack::msgpack_type::uint32_type: 
379
139k
                {
380
139k
                    uint8_t buf[sizeof(uint32_t)];
381
139k
                    if (source_.read(buf, sizeof(uint32_t)) != sizeof(uint32_t))
382
13
                    {
383
13
                        ec = msgpack_errc::unexpected_eof;
384
13
                        more_ = false;
385
13
                        return;
386
13
                    }
387
139k
                    uint32_t val = binary::big_to_native<uint32_t>(buf, sizeof(buf));
388
139k
                    visitor.uint64_value(val, semantic_tag::none, *this, ec);
389
139k
                    more_ = !cursor_mode_;
390
139k
                    break;
391
139k
                }
392
393
11.4k
                case jsoncons::msgpack::msgpack_type::uint64_type: 
394
11.4k
                {
395
11.4k
                    uint8_t buf[sizeof(uint64_t)];
396
11.4k
                    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.4k
                    uint64_t val = binary::big_to_native<uint64_t>(buf, sizeof(buf));
403
11.4k
                    visitor.uint64_value(val, semantic_tag::none, *this, ec);
404
11.4k
                    more_ = !cursor_mode_;
405
11.4k
                    break;
406
11.4k
                }
407
408
400k
                case jsoncons::msgpack::msgpack_type::int8_type: 
409
400k
                {
410
400k
                    uint8_t buf[sizeof(int8_t)];
411
400k
                    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
400k
                    int8_t val = binary::big_to_native<int8_t>(buf, sizeof(buf));
418
400k
                    visitor.int64_value(val, semantic_tag::none, *this, ec);
419
400k
                    more_ = !cursor_mode_;
420
400k
                    break;
421
400k
                }
422
423
156k
                case jsoncons::msgpack::msgpack_type::int16_type: 
424
156k
                {
425
156k
                    uint8_t buf[sizeof(int16_t)];
426
156k
                    if (source_.read(buf, sizeof(int16_t)) != sizeof(int16_t))
427
9
                    {
428
9
                        ec = msgpack_errc::unexpected_eof;
429
9
                        more_ = false;
430
9
                        return;
431
9
                    }
432
156k
                    int16_t val = binary::big_to_native<int16_t>(buf, sizeof(buf));
433
156k
                    visitor.int64_value(val, semantic_tag::none, *this, ec);
434
156k
                    more_ = !cursor_mode_;
435
156k
                    break;
436
156k
                }
437
438
28.4k
                case jsoncons::msgpack::msgpack_type::int32_type: 
439
28.4k
                {
440
28.4k
                    uint8_t buf[sizeof(int32_t)];
441
28.4k
                    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
28.4k
                    int32_t val = binary::big_to_native<int32_t>(buf, sizeof(buf));
448
28.4k
                    visitor.int64_value(val, semantic_tag::none, *this, ec);
449
28.4k
                    more_ = !cursor_mode_;
450
28.4k
                    break;
451
28.4k
                }
452
453
24.9k
                case jsoncons::msgpack::msgpack_type::int64_type: 
454
24.9k
                {
455
24.9k
                    uint8_t buf[sizeof(int64_t)];
456
24.9k
                    if (source_.read(buf, sizeof(int64_t)) != sizeof(int64_t))
457
29
                    {
458
29
                        ec = msgpack_errc::unexpected_eof;
459
29
                        more_ = false;
460
29
                        return;
461
29
                    }
462
24.8k
                    int64_t val = binary::big_to_native<int64_t>(buf, sizeof(buf));
463
24.8k
                    visitor.int64_value(val, semantic_tag::none, *this, ec);
464
24.8k
                    more_ = !cursor_mode_;
465
24.8k
                    break;
466
24.9k
                }
467
468
2.42k
                case jsoncons::msgpack::msgpack_type::str8_type: 
469
4.48k
                case jsoncons::msgpack::msgpack_type::str16_type: 
470
6.28k
                case jsoncons::msgpack::msgpack_type::str32_type: 
471
6.28k
                {
472
6.28k
                    std::size_t len = get_size(type, ec);
473
6.28k
                    if (!more_)
474
78
                    {
475
78
                        return;
476
78
                    }
477
478
6.20k
                    auto data = source_.read_span(len, bytes_buffer_);
479
6.20k
                    if (data.size() != static_cast<std::size_t>(len))
480
346
                    {
481
346
                        ec = msgpack_errc::unexpected_eof;
482
346
                        more_ = false;
483
346
                        return;
484
346
                    }
485
486
5.85k
                    auto result = unicode_traits::validate(data.data(), data.size());
487
5.85k
                    if (result.ec != unicode_traits::unicode_errc())
488
138
                    {
489
138
                        ec = msgpack_errc::invalid_utf8_text_string;
490
138
                        more_ = false;
491
138
                        return;
492
138
                    }
493
5.72k
                    visitor.string_value(jsoncons::string_view(reinterpret_cast<const char*>(data.data()),data.size()), 
494
5.72k
                        semantic_tag::none, *this, ec);
495
5.72k
                    more_ = !cursor_mode_;
496
5.72k
                    break;
497
5.85k
                }
498
499
347k
                case jsoncons::msgpack::msgpack_type::bin8_type: 
500
354k
                case jsoncons::msgpack::msgpack_type::bin16_type: 
501
355k
                case jsoncons::msgpack::msgpack_type::bin32_type: 
502
355k
                {
503
355k
                    std::size_t len = get_size(type,ec);
504
355k
                    if (!more_)
505
80
                    {
506
80
                        return;
507
80
                    }
508
355k
                    auto data = source_.read_span(len, bytes_buffer_);
509
355k
                    if (JSONCONS_UNLIKELY(data.size() != static_cast<std::size_t>(len)))
510
434
                    {
511
434
                        ec = msgpack_errc::unexpected_eof;
512
434
                        more_ = false;
513
434
                        return;
514
434
                    }
515
516
355k
                    visitor.byte_string_value(byte_string_view(data.data(),data.size()), 
517
355k
                        semantic_tag::none, 
518
355k
                        *this,
519
355k
                        ec);
520
355k
                    more_ = !cursor_mode_;
521
355k
                    break;
522
355k
                }
523
1.24M
                case jsoncons::msgpack::msgpack_type::fixext1_type: 
524
2.79M
                case jsoncons::msgpack::msgpack_type::fixext2_type: 
525
2.89M
                case jsoncons::msgpack::msgpack_type::fixext4_type: 
526
3.01M
                case jsoncons::msgpack::msgpack_type::fixext8_type: 
527
3.12M
                case jsoncons::msgpack::msgpack_type::fixext16_type: 
528
3.23M
                case jsoncons::msgpack::msgpack_type::ext8_type: 
529
3.23M
                case jsoncons::msgpack::msgpack_type::ext16_type: 
530
3.24M
                case jsoncons::msgpack::msgpack_type::ext32_type: 
531
3.24M
                {
532
3.24M
                    std::size_t len = get_size(type,ec);
533
3.24M
                    if (!more_)
534
86
                    {
535
86
                        return;
536
86
                    }
537
538
                    // type
539
3.24M
                    uint8_t buf[sizeof(int8_t)];
540
3.24M
                    if (source_.read(buf, sizeof(int8_t)) != sizeof(int8_t))
541
144
                    {
542
144
                        ec = msgpack_errc::unexpected_eof;
543
144
                        more_ = false;
544
144
                        return;
545
144
                    }
546
547
3.24M
                    int8_t ext_type = binary::big_to_native<int8_t>(buf, sizeof(buf));
548
549
3.24M
                    bool is_timestamp = false; 
550
3.24M
                    if (ext_type == -1)
551
210k
                    {
552
210k
                        is_timestamp = true;;
553
210k
                    }
554
555
                    // payload
556
3.24M
                    if (is_timestamp && len == 4)
557
3.62k
                    {
558
3.62k
                        uint8_t buf32[sizeof(uint32_t)];
559
3.62k
                        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.61k
                        uint32_t val = binary::big_to_native<uint32_t>(buf32, sizeof(buf32));
566
3.61k
                        visitor.uint64_value(val, semantic_tag::epoch_second, *this, ec);
567
3.61k
                        more_ = !cursor_mode_;
568
3.61k
                    }
569
3.23M
                    else if (is_timestamp && len == 8)
570
109k
                    {
571
109k
                        uint8_t buf64[sizeof(uint64_t)];
572
109k
                        if (source_.read(buf64, sizeof(uint64_t)) != sizeof(uint64_t))
573
26
                        {
574
26
                            ec = msgpack_errc::unexpected_eof;
575
26
                            more_ = false;
576
26
                            return;
577
26
                        }
578
109k
                        uint64_t data64 = binary::big_to_native<uint64_t>(buf64, sizeof(buf64));
579
109k
                        uint64_t sec = data64 & 0x00000003ffffffffL;
580
109k
                        uint64_t nsec = data64 >> 34;
581
582
109k
                        bigint nano(sec);
583
109k
                        nano *= uint64_t(nanos_in_second);
584
109k
                        nano += nsec;
585
109k
                        text_buffer_.clear();
586
109k
                        nano.write_string(text_buffer_);
587
109k
                        visitor.string_value(text_buffer_, semantic_tag::epoch_nano, *this, ec);
588
109k
                        more_ = !cursor_mode_;
589
109k
                        if (!more_) return;
590
109k
                    }
591
3.12M
                    else if (is_timestamp && len == 12)
592
91.6k
                    {
593
91.6k
                        uint8_t buf1[sizeof(uint32_t)];
594
91.6k
                        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
91.6k
                        uint32_t nsec = binary::big_to_native<uint32_t>(buf1, sizeof(buf1));
601
602
91.6k
                        uint8_t buf2[sizeof(int64_t)];
603
91.6k
                        if (source_.read(buf2, sizeof(int64_t)) != sizeof(int64_t))
604
24
                        {
605
24
                            ec = msgpack_errc::unexpected_eof;
606
24
                            more_ = false;
607
24
                            return;
608
24
                        }
609
91.6k
                        int64_t sec = binary::big_to_native<int64_t>(buf2, sizeof(buf2));
610
611
91.6k
                        bigint nano(sec);
612
613
91.6k
                        nano *= uint64_t(nanos_in_second);
614
615
91.6k
                        if (nano < 0)
616
33.4k
                        {
617
33.4k
                            nano -= nsec;
618
33.4k
                        }
619
58.1k
                        else
620
58.1k
                        {
621
58.1k
                            nano += nsec;
622
58.1k
                        }
623
624
91.6k
                        text_buffer_.clear();
625
91.6k
                        nano.write_string(text_buffer_);
626
91.6k
                        visitor.string_value(text_buffer_, semantic_tag::epoch_nano, *this, ec);
627
91.6k
                        more_ = !cursor_mode_;
628
91.6k
                        if (!more_) return;
629
91.6k
                    }
630
3.03M
                    else
631
3.03M
                    {
632
3.03M
                        auto data = source_.read_span(len, bytes_buffer_);
633
3.03M
                        if (JSONCONS_UNLIKELY(data.size() != static_cast<std::size_t>(len)))
634
579
                        {
635
579
                            ec = msgpack_errc::unexpected_eof;
636
579
                            more_ = false;
637
579
                            return;
638
579
                        }
639
640
3.03M
                        visitor.byte_string_value(byte_string_view(data.data(),data.size()), 
641
3.03M
                                                          static_cast<uint8_t>(ext_type), 
642
3.03M
                                                          *this,
643
3.03M
                                                          ec);
644
3.03M
                        more_ = !cursor_mode_;
645
3.03M
                    }
646
3.24M
                    break;
647
3.24M
                }
648
649
3.24M
                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
17.5k
                }
655
656
18.5k
                case jsoncons::msgpack::msgpack_type::map16_type : 
657
22.7k
                case jsoncons::msgpack::msgpack_type::map32_type : 
658
22.7k
                {
659
22.7k
                    begin_object(visitor, type, ec);
660
22.7k
                    break;
661
18.5k
                }
662
663
38
                default:
664
38
                {
665
38
                    ec = msgpack_errc::unknown_type;
666
38
                    more_ = false;
667
38
                    return;
668
18.5k
                }
669
68.1M
            }
670
68.1M
        }
671
164M
    }
672
673
    void begin_array(generic_visitor& visitor, uint8_t type, std::error_code& ec)
674
7.42M
    {
675
7.42M
        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.42M
        std::size_t length = get_size(type, ec);
682
7.42M
        if (!more_)
683
53
        {
684
53
            return;
685
53
        }
686
7.42M
        state_stack_.emplace_back(parse_mode::array,length);
687
7.42M
        visitor.begin_array(length, semantic_tag::none, *this, ec);
688
7.42M
        more_ = !cursor_mode_;
689
7.42M
    }
690
691
    void end_array(generic_visitor& visitor, std::error_code& ec)
692
7.33M
    {
693
7.33M
        --nesting_depth_;
694
695
7.33M
        visitor.end_array(*this, ec);
696
7.33M
        more_ = !cursor_mode_;
697
7.33M
        state_stack_.pop_back();
698
7.33M
    }
699
700
    void begin_object(generic_visitor& visitor, uint8_t type, std::error_code& ec)
701
2.94M
    {
702
2.94M
        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.94M
        std::size_t length = get_size(type, ec);
709
2.94M
        if (!more_)
710
57
        {
711
57
            return;
712
57
        }
713
2.94M
        state_stack_.emplace_back(parse_mode::map_key,length);
714
2.94M
        visitor.begin_object(length, semantic_tag::none, *this, ec);
715
2.94M
        more_ = !cursor_mode_;
716
2.94M
    }
717
718
    void end_object(generic_visitor& visitor, std::error_code& ec)
719
2.86M
    {
720
2.86M
        --nesting_depth_;
721
2.86M
        visitor.end_object(*this, ec);
722
2.86M
        more_ = !cursor_mode_;
723
2.86M
        state_stack_.pop_back();
724
2.86M
    }
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.42k
            case jsoncons::msgpack::msgpack_type::str8_type: 
731
350k
            case jsoncons::msgpack::msgpack_type::bin8_type: 
732
462k
            case jsoncons::msgpack::msgpack_type::ext8_type: 
733
462k
            {
734
462k
                uint8_t buf[sizeof(int8_t)];
735
462k
                if (source_.read(buf, sizeof(int8_t)) != sizeof(int8_t))
736
84
                {
737
84
                    ec = msgpack_errc::unexpected_eof;
738
84
                    more_ = false;
739
84
                    return 0;
740
84
                }
741
462k
                uint8_t len = binary::big_to_native<uint8_t>(buf, sizeof(buf));
742
462k
                return static_cast<std::size_t>(len);
743
462k
            }
744
745
2.05k
            case jsoncons::msgpack::msgpack_type::str16_type: 
746
8.77k
            case jsoncons::msgpack::msgpack_type::bin16_type: 
747
11.6k
            case jsoncons::msgpack::msgpack_type::ext16_type: 
748
29.1k
            case jsoncons::msgpack::msgpack_type::array16_type: 
749
47.7k
            case jsoncons::msgpack::msgpack_type::map16_type:
750
47.7k
            {
751
47.7k
                uint8_t buf[sizeof(int16_t)];
752
47.7k
                if (source_.read(buf, sizeof(int16_t)) != sizeof(int16_t))
753
132
                {
754
132
                    ec = msgpack_errc::unexpected_eof;
755
132
                    more_ = false;
756
132
                    return 0;
757
132
                }
758
47.5k
                uint16_t len = binary::big_to_native<uint16_t>(buf, sizeof(buf));
759
47.5k
                return static_cast<std::size_t>(len);
760
47.7k
            }
761
762
1.79k
            case jsoncons::msgpack::msgpack_type::str32_type: 
763
2.99k
            case jsoncons::msgpack::msgpack_type::bin32_type: 
764
6.05k
            case jsoncons::msgpack::msgpack_type::ext32_type: 
765
15.3k
            case jsoncons::msgpack::msgpack_type::array32_type: 
766
19.5k
            case jsoncons::msgpack::msgpack_type::map32_type : 
767
19.5k
            {
768
19.5k
                uint8_t buf[sizeof(int32_t)];
769
19.5k
                if (source_.read(buf, sizeof(int32_t)) != sizeof(int32_t))
770
138
                {
771
138
                    ec = msgpack_errc::unexpected_eof;
772
138
                    more_ = false;
773
138
                    return 0;
774
138
                }
775
19.4k
                uint32_t len = binary::big_to_native<uint32_t>(buf, sizeof(buf));
776
19.4k
                return static_cast<std::size_t>(len);
777
19.5k
            }
778
1.24M
            case jsoncons::msgpack::msgpack_type::fixext1_type: 
779
1.24M
                return 1;
780
1.54M
            case jsoncons::msgpack::msgpack_type::fixext2_type: 
781
1.54M
                return 2;
782
102k
            case jsoncons::msgpack::msgpack_type::fixext4_type: 
783
102k
                return 4;
784
124k
            case jsoncons::msgpack::msgpack_type::fixext8_type: 
785
124k
                return 8;
786
106k
            case jsoncons::msgpack::msgpack_type::fixext16_type: 
787
106k
                return 16;
788
10.3M
            default:
789
10.3M
                if ((type > 0x8f && type <= 0x9f) // fixarray
790
2.92M
                    || (type > 0x7f && type <= 0x8f) // fixmap
791
10.3M
        )
792
10.3M
                {
793
10.3M
                    return type & 0x0f;
794
10.3M
                }
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