Coverage Report

Created: 2025-11-11 06:22

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