Coverage Report

Created: 2025-10-28 07:12

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