Coverage Report

Created: 2025-12-05 06:20

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/jsoncons/include/jsoncons_ext/ubjson/ubjson_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_UBJSON_UBJSON_PARSER_HPP
8
#define JSONCONS_EXT_UBJSON_UBJSON_PARSER_HPP
9
10
#include <cstddef>
11
#include <cstdint>
12
#include <memory>
13
#include <string>
14
#include <system_error>
15
#include <vector>
16
#include <utility> // std::move
17
18
#include <jsoncons/config/jsoncons_config.hpp>
19
#include <jsoncons/utility/read_number.hpp>
20
#include <jsoncons/json_type.hpp>
21
#include <jsoncons/json_visitor.hpp>
22
#include <jsoncons/semantic_tag.hpp>
23
#include <jsoncons/ser_util.hpp>
24
#include <jsoncons/source.hpp>
25
#include <jsoncons/utility/binary.hpp>
26
#include <jsoncons/utility/unicode_traits.hpp>
27
28
#include <jsoncons_ext/ubjson/ubjson_error.hpp>
29
#include <jsoncons_ext/ubjson/ubjson_options.hpp>
30
#include <jsoncons_ext/ubjson/ubjson_type.hpp>
31
32
namespace jsoncons { 
33
namespace ubjson {
34
35
enum class parse_mode {root,accept,array,indefinite_array,strongly_typed_array,map_key,map_value,strongly_typed_map_key,strongly_typed_map_value,indefinite_map_key,indefinite_map_value};
36
37
struct parse_state 
38
{
39
    parse_mode mode; 
40
    std::size_t length{0};
41
    uint8_t type;
42
    std::size_t index{0};
43
44
    parse_state(parse_mode mode, std::size_t length, uint8_t type = 0) noexcept
45
11.6M
        : mode(mode), length(length), type(type)
46
11.6M
    {
47
11.6M
    }
48
49
    parse_state(const parse_state&) = default;
50
    parse_state(parse_state&&) = default;
51
};
52
53
template <typename Source,typename Allocator=std::allocator<char>>
54
class basic_ubjson_parser : public ser_context
55
{
56
    using char_type = char;
57
    using char_traits_type = std::char_traits<char>;
58
    using temp_allocator_type = Allocator;
59
    using char_allocator_type = typename std::allocator_traits<temp_allocator_type>:: template rebind_alloc<char_type>;                  
60
    using byte_allocator_type = typename std::allocator_traits<temp_allocator_type>:: template rebind_alloc<uint8_t>;                  
61
    using parse_state_allocator_type = typename std::allocator_traits<temp_allocator_type>:: template rebind_alloc<parse_state>;                         
62
63
    bool more_{true};
64
    bool done_{false};
65
    int nesting_depth_{0};
66
    bool cursor_mode_{false};
67
    int mark_level_{0};
68
69
    Source source_;
70
    int max_nesting_depth_;
71
    std::size_t max_items_;
72
    std::basic_string<char,std::char_traits<char>,char_allocator_type> text_buffer_;
73
    std::vector<parse_state,parse_state_allocator_type> state_stack_;
74
public:
75
    template <typename Sourceable>
76
        basic_ubjson_parser(Sourceable&& source,
77
                          const ubjson_decode_options& options = ubjson_decode_options(),
78
                          const Allocator& alloc = Allocator())
79
744
       : source_(std::forward<Sourceable>(source)), 
80
744
         max_nesting_depth_(options.max_nesting_depth()),
81
744
         max_items_(options.max_items()),
82
744
         text_buffer_(alloc),
83
744
         state_stack_(alloc)
84
744
    {
85
744
        state_stack_.emplace_back(parse_mode::root,0);
86
744
    }
jsoncons::ubjson::basic_ubjson_parser<jsoncons::stream_source<unsigned char, std::__1::allocator<unsigned char> >, std::__1::allocator<char> >::basic_ubjson_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::ubjson::ubjson_decode_options const&, std::__1::allocator<char> const&)
Line
Count
Source
79
282
       : source_(std::forward<Sourceable>(source)), 
80
282
         max_nesting_depth_(options.max_nesting_depth()),
81
282
         max_items_(options.max_items()),
82
282
         text_buffer_(alloc),
83
282
         state_stack_(alloc)
84
282
    {
85
282
        state_stack_.emplace_back(parse_mode::root,0);
86
282
    }
jsoncons::ubjson::basic_ubjson_parser<jsoncons::stream_source<unsigned char, std::__1::allocator<unsigned char> >, std::__1::allocator<char> >::basic_ubjson_parser<std::__1::basic_istream<char, std::__1::char_traits<char> >&>(std::__1::basic_istream<char, std::__1::char_traits<char> >&, jsoncons::ubjson::ubjson_decode_options const&, std::__1::allocator<char> const&)
Line
Count
Source
79
462
       : source_(std::forward<Sourceable>(source)), 
80
462
         max_nesting_depth_(options.max_nesting_depth()),
81
462
         max_items_(options.max_items()),
82
462
         text_buffer_(alloc),
83
462
         state_stack_(alloc)
84
462
    {
85
462
        state_stack_.emplace_back(parse_mode::root,0);
86
462
    }
87
88
    void restart()
89
    {
90
        more_ = true;
91
    }
92
93
    void reset()
94
744
    {
95
744
        more_ = true;
96
744
        done_ = false;
97
744
        text_buffer_.clear();
98
744
        state_stack_.clear();
99
744
        state_stack_.emplace_back(parse_mode::root,0,uint8_t(0));
100
744
        nesting_depth_ = 0;
101
744
    }
102
103
    template <typename Sourceable>
104
    void reset(Sourceable&& source)
105
    {
106
        source_ = std::forward<Sourceable>(source);
107
        reset();
108
    }
109
110
    void cursor_mode(bool value)
111
    {
112
        cursor_mode_ = value;
113
    }
114
115
    int level() const
116
11.6M
    {
117
11.6M
        return static_cast<int>(state_stack_.size());
118
11.6M
    }
119
120
    int mark_level() const 
121
    {
122
        return mark_level_;
123
    }
124
125
    void mark_level(int value)
126
    {
127
        mark_level_ = value;
128
    }
129
130
    bool done() const
131
    {
132
        return done_;
133
    }
134
135
    bool stopped() const
136
    {
137
        return !more_;
138
    }
139
140
    std::size_t line() const override
141
336
    {
142
336
        return 0;
143
336
    }
144
145
    std::size_t column() const override
146
336
    {
147
336
        return source_.position();
148
336
    }
149
150
    void parse(json_visitor& visitor, std::error_code& ec)
151
744
    {
152
64.8M
        while (!done_ && more_)
153
64.8M
        {
154
64.8M
            switch (state_stack_.back().mode)
155
64.8M
            {
156
133k
                case parse_mode::array:
157
133k
                {
158
133k
                    if (state_stack_.back().index < state_stack_.back().length)
159
27.5k
                    {
160
27.5k
                        ++state_stack_.back().index;
161
27.5k
                        read_type_and_value(visitor, ec);
162
27.5k
                        if (JSONCONS_UNLIKELY(ec))
163
2
                        {
164
2
                            return;
165
2
                        }
166
27.5k
                    }
167
105k
                    else
168
105k
                    {
169
105k
                        end_array(visitor, ec);
170
105k
                    }
171
133k
                    break;
172
133k
                }
173
24.5M
                case parse_mode::strongly_typed_array:
174
24.5M
                {
175
24.5M
                    if (state_stack_.back().index < state_stack_.back().length)
176
24.5M
                    {
177
24.5M
                        ++state_stack_.back().index;
178
24.5M
                        read_value(visitor, state_stack_.back().type, ec);
179
24.5M
                        if (JSONCONS_UNLIKELY(ec))
180
166
                        {
181
166
                            return;
182
166
                        }
183
24.5M
                    }
184
27.0k
                    else
185
27.0k
                    {
186
27.0k
                        end_array(visitor, ec);
187
27.0k
                    }
188
24.5M
                    break;
189
24.5M
                }
190
24.5M
                case parse_mode::indefinite_array:
191
22.2M
                {
192
22.2M
                    auto c = source_.peek();
193
22.2M
                    if (JSONCONS_UNLIKELY(c.eof))
194
53
                    {
195
53
                        ec = ubjson_errc::unexpected_eof;
196
53
                        more_ = false;
197
53
                        return;
198
53
                    }
199
22.2M
                    if (c.value == jsoncons::ubjson::ubjson_type::end_array_marker)
200
6.80M
                    {
201
6.80M
                        source_.ignore(1);
202
6.80M
                        end_array(visitor, ec);
203
6.80M
                        if (JSONCONS_UNLIKELY(ec))
204
0
                        {
205
0
                            return;
206
0
                        }
207
6.80M
                    }
208
15.4M
                    else
209
15.4M
                    {
210
15.4M
                        if (++state_stack_.back().index > max_items_)
211
0
                        {
212
0
                            ec = ubjson_errc::max_items_exceeded;
213
0
                            more_ = false;
214
0
                            return;
215
0
                        }
216
15.4M
                        read_type_and_value(visitor, ec);
217
15.4M
                        if (JSONCONS_UNLIKELY(ec))
218
105
                        {
219
105
                            return;
220
105
                        }
221
15.4M
                    }
222
22.2M
                    break;
223
22.2M
                }
224
22.2M
                case parse_mode::map_key:
225
17.5k
                {
226
17.5k
                    if (state_stack_.back().index < state_stack_.back().length)
227
11.9k
                    {
228
11.9k
                        ++state_stack_.back().index;
229
11.9k
                        read_key(visitor, ec);
230
11.9k
                        if (JSONCONS_UNLIKELY(ec))
231
5
                        {
232
5
                            return;
233
5
                        }
234
11.9k
                        state_stack_.back().mode = parse_mode::map_value;
235
11.9k
                    }
236
5.58k
                    else
237
5.58k
                    {
238
5.58k
                        end_object(visitor, ec);
239
5.58k
                    }
240
17.5k
                    break;
241
17.5k
                }
242
17.5k
                case parse_mode::map_value:
243
11.9k
                {
244
11.9k
                    state_stack_.back().mode = parse_mode::map_key;
245
11.9k
                    read_type_and_value(visitor, ec);
246
11.9k
                    if (JSONCONS_UNLIKELY(ec))
247
8
                    {
248
8
                        return;
249
8
                    }
250
11.9k
                    break;
251
11.9k
                }
252
153k
                case parse_mode::strongly_typed_map_key:
253
153k
                {
254
153k
                    if (state_stack_.back().index < state_stack_.back().length)
255
57.9k
                    {
256
57.9k
                        ++state_stack_.back().index;
257
57.9k
                        read_key(visitor, ec);
258
57.9k
                        if (JSONCONS_UNLIKELY(ec))
259
5
                        {
260
5
                            return;
261
5
                        }
262
57.9k
                        state_stack_.back().mode = parse_mode::strongly_typed_map_value;
263
57.9k
                    }
264
95.1k
                    else
265
95.1k
                    {
266
95.1k
                        end_object(visitor, ec);
267
95.1k
                    }
268
153k
                    break;
269
153k
                }
270
153k
                case parse_mode::strongly_typed_map_value:
271
57.9k
                {
272
57.9k
                    state_stack_.back().mode = parse_mode::strongly_typed_map_key;
273
57.9k
                    read_value(visitor, state_stack_.back().type, ec);
274
57.9k
                    if (JSONCONS_UNLIKELY(ec))
275
1
                    {
276
1
                        return;
277
1
                    }
278
57.9k
                    break;
279
57.9k
                }
280
11.0M
                case parse_mode::indefinite_map_key:
281
11.0M
                {
282
11.0M
                    auto c = source_.peek();
283
11.0M
                    if (JSONCONS_UNLIKELY(c.eof))
284
19
                    {
285
19
                        ec = ubjson_errc::unexpected_eof;
286
19
                        more_ = false;
287
19
                        return;
288
19
                    }
289
11.0M
                    if (c.value == jsoncons::ubjson::ubjson_type::end_object_marker)
290
4.56M
                    {
291
4.56M
                        source_.ignore(1);
292
4.56M
                        end_object(visitor, ec);
293
4.56M
                        if (JSONCONS_UNLIKELY(ec))
294
0
                        {
295
0
                            return;
296
0
                        }
297
4.56M
                    }
298
6.50M
                    else
299
6.50M
                    {
300
6.50M
                        if (++state_stack_.back().index > max_items_)
301
0
                        {
302
0
                            ec = ubjson_errc::max_items_exceeded;
303
0
                            more_ = false;
304
0
                            return;
305
0
                        }
306
6.50M
                        read_key(visitor, ec);
307
6.50M
                        if (JSONCONS_UNLIKELY(ec))
308
97
                        {
309
97
                            return;
310
97
                        }
311
6.50M
                        state_stack_.back().mode = parse_mode::indefinite_map_value;
312
6.50M
                    }
313
11.0M
                    break;
314
11.0M
                }
315
11.0M
                case parse_mode::indefinite_map_value:
316
6.50M
                {
317
6.50M
                    state_stack_.back().mode = parse_mode::indefinite_map_key;
318
6.50M
                    read_type_and_value(visitor, ec);
319
6.50M
                    if (JSONCONS_UNLIKELY(ec))
320
61
                    {
321
61
                        return;
322
61
                    }
323
6.50M
                    break;
324
6.50M
                }
325
6.50M
                case parse_mode::root:
326
744
                {
327
744
                    state_stack_.back().mode = parse_mode::accept;
328
744
                    read_type_and_value(visitor, ec);
329
744
                    if (JSONCONS_UNLIKELY(ec))
330
79
                    {
331
79
                        return;
332
79
                    }
333
665
                    break;
334
744
                }
335
665
                case parse_mode::accept:
336
143
                {
337
143
                    JSONCONS_ASSERT(state_stack_.size() == 1);
338
143
                    state_stack_.clear();
339
143
                    more_ = false;
340
143
                    done_ = true;
341
143
                    visitor.flush();
342
143
                    break;
343
143
                }
344
64.8M
            }
345
64.8M
        }
346
744
    }
347
private:
348
    void read_type_and_value(json_visitor& visitor, std::error_code& ec)
349
22.0M
    {
350
22.0M
        if (source_.is_error())
351
0
        {
352
0
            ec = ubjson_errc::source_error;
353
0
            more_ = false;
354
0
            return;
355
0
        }   
356
357
22.0M
        uint8_t b;
358
22.0M
        if (source_.read(&b, 1) == 0)
359
30
        {
360
30
            ec = ubjson_errc::unexpected_eof;
361
30
            more_ = false;
362
30
            return;
363
30
        }
364
22.0M
        read_value(visitor, b, ec);
365
22.0M
    }
366
367
    void read_value(json_visitor& visitor, uint8_t type, std::error_code& ec)
368
46.6M
    {
369
46.6M
        switch (type)
370
46.6M
        {
371
17.5M
            case jsoncons::ubjson::ubjson_type::null_type: 
372
17.5M
            {
373
17.5M
                visitor.null_value(semantic_tag::none, *this, ec);
374
17.5M
                more_ = !cursor_mode_;
375
17.5M
                break;
376
0
            }
377
496k
            case jsoncons::ubjson::ubjson_type::no_op_type: 
378
496k
            {
379
496k
                break;
380
0
            }
381
2.99M
            case jsoncons::ubjson::ubjson_type::true_type:
382
2.99M
            {
383
2.99M
                visitor.bool_value(true, semantic_tag::none, *this, ec);
384
2.99M
                more_ = !cursor_mode_;
385
2.99M
                break;
386
0
            }
387
2.22M
            case jsoncons::ubjson::ubjson_type::false_type:
388
2.22M
            {
389
2.22M
                visitor.bool_value(false, semantic_tag::none, *this, ec);
390
2.22M
                more_ = !cursor_mode_;
391
2.22M
                break;
392
0
            }
393
2.11M
            case jsoncons::ubjson::ubjson_type::int8_type: 
394
2.11M
            {
395
2.11M
                uint8_t buf[sizeof(int8_t)];
396
2.11M
                if (source_.read(buf, sizeof(int8_t)) != sizeof(int8_t))
397
14
                {
398
14
                    ec = ubjson_errc::unexpected_eof;
399
14
                    more_ = false;
400
14
                    return;
401
14
                }
402
2.11M
                int8_t val = binary::big_to_native<int8_t>(buf, sizeof(buf));
403
2.11M
                visitor.int64_value(val, semantic_tag::none, *this, ec);
404
2.11M
                more_ = !cursor_mode_;
405
2.11M
                break;
406
2.11M
            }
407
2.32M
            case jsoncons::ubjson::ubjson_type::uint8_type: 
408
2.32M
            {
409
2.32M
                uint8_t b;
410
2.32M
                if (source_.read(&b, 1) == 0)
411
13
                {
412
13
                    ec = ubjson_errc::unexpected_eof;
413
13
                    more_ = false;
414
13
                    return;
415
13
                }
416
2.32M
                visitor.uint64_value(b, semantic_tag::none, *this, ec);
417
2.32M
                more_ = !cursor_mode_;
418
2.32M
                break;
419
2.32M
            }
420
851k
            case jsoncons::ubjson::ubjson_type::int16_type: 
421
851k
            {
422
851k
                uint8_t buf[sizeof(int16_t)];
423
851k
                if (source_.read(buf, sizeof(int16_t)) != sizeof(int16_t))
424
7
                {
425
7
                    ec = ubjson_errc::unexpected_eof;
426
7
                    more_ = false;
427
7
                    return;
428
7
                }
429
851k
                int16_t val = binary::big_to_native<int16_t>(buf, sizeof(buf));
430
851k
                visitor.int64_value(val, semantic_tag::none, *this, ec);
431
851k
                more_ = !cursor_mode_;
432
851k
                break;
433
851k
            }
434
115k
            case jsoncons::ubjson::ubjson_type::int32_type: 
435
115k
            {
436
115k
                uint8_t buf[sizeof(int32_t)];
437
115k
                if (source_.read(buf, sizeof(int32_t)) != sizeof(int32_t))
438
6
                {
439
6
                    ec = ubjson_errc::unexpected_eof;
440
6
                    more_ = false;
441
6
                    return;
442
6
                }
443
115k
                int32_t val = binary::big_to_native<int32_t>(buf, sizeof(buf));
444
115k
                visitor.int64_value(val, semantic_tag::none, *this, ec);
445
115k
                more_ = !cursor_mode_;
446
115k
                break;
447
115k
            }
448
32.2k
            case jsoncons::ubjson::ubjson_type::int64_type: 
449
32.2k
            {
450
32.2k
                uint8_t buf[sizeof(int64_t)];
451
32.2k
                if (source_.read(buf, sizeof(int64_t)) != sizeof(int64_t))
452
6
                {
453
6
                    ec = ubjson_errc::unexpected_eof;
454
6
                    more_ = false;
455
6
                    return;
456
6
                }
457
32.2k
                int64_t val = binary::big_to_native<int64_t>(buf, sizeof(buf));
458
32.2k
                visitor.int64_value(val, semantic_tag::none, *this, ec);
459
32.2k
                more_ = !cursor_mode_;
460
32.2k
                break;
461
32.2k
            }
462
215k
            case jsoncons::ubjson::ubjson_type::float32_type: 
463
215k
            {
464
215k
                uint8_t buf[sizeof(float)];
465
215k
                if (source_.read(buf, sizeof(float)) != sizeof(float))
466
11
                {
467
11
                    ec = ubjson_errc::unexpected_eof;
468
11
                    more_ = false;
469
11
                    return;
470
11
                }
471
215k
                float val = binary::big_to_native<float>(buf, sizeof(buf));
472
215k
                visitor.double_value(val, semantic_tag::none, *this, ec);
473
215k
                more_ = !cursor_mode_;
474
215k
                break;
475
215k
            }
476
1.87k
            case jsoncons::ubjson::ubjson_type::float64_type: 
477
1.87k
            {
478
1.87k
                uint8_t buf[sizeof(double)];
479
1.87k
                if (source_.read(buf, sizeof(double)) != sizeof(double))
480
0
                {
481
0
                    ec = ubjson_errc::unexpected_eof;
482
0
                    more_ = false;
483
0
                    return;
484
0
                }
485
1.87k
                double val = binary::big_to_native<double>(buf, sizeof(buf));
486
1.87k
                visitor.double_value(val, semantic_tag::none, *this, ec);
487
1.87k
                more_ = !cursor_mode_;
488
1.87k
                break;
489
1.87k
            }
490
6.06M
            case jsoncons::ubjson::ubjson_type::char_type: 
491
6.06M
            {
492
6.06M
                text_buffer_.clear();
493
6.06M
                if (source_reader<Source>::read(source_,text_buffer_,1) != 1)
494
33
                {
495
33
                    ec = ubjson_errc::unexpected_eof;
496
33
                    more_ = false;
497
33
                    return;
498
33
                }
499
6.06M
                auto result = unicode_traits::validate(text_buffer_.data(),text_buffer_.size());
500
6.06M
                if (result.ec != unicode_traits::conv_errc())
501
3
                {
502
3
                    ec = ubjson_errc::invalid_utf8_text_string;
503
3
                    more_ = false;
504
3
                    return;
505
3
                }
506
6.06M
                visitor.string_value(text_buffer_, semantic_tag::none, *this, ec);
507
6.06M
                more_ = !cursor_mode_;
508
6.06M
                break;
509
6.06M
            }
510
14.5k
            case jsoncons::ubjson::ubjson_type::string_type: 
511
14.5k
            {
512
14.5k
                std::size_t length = get_length(ec);
513
14.5k
                if (JSONCONS_UNLIKELY(ec))
514
1
                {
515
1
                    return;
516
1
                }
517
14.5k
                text_buffer_.clear();
518
14.5k
                if (source_reader<Source>::read(source_,text_buffer_,length) != length)
519
13
                {
520
13
                    ec = ubjson_errc::unexpected_eof;
521
13
                    more_ = false;
522
13
                    return;
523
13
                }
524
14.5k
                auto result = unicode_traits::validate(text_buffer_.data(),text_buffer_.size());
525
14.5k
                if (result.ec != unicode_traits::conv_errc())
526
17
                {
527
17
                    ec = ubjson_errc::invalid_utf8_text_string;
528
17
                    more_ = false;
529
17
                    return;
530
17
                }
531
14.5k
                visitor.string_value(jsoncons::basic_string_view<char>(text_buffer_.data(),text_buffer_.length()), semantic_tag::none, *this, ec);
532
14.5k
                more_ = !cursor_mode_;
533
14.5k
                break;
534
14.5k
            }
535
9.02k
            case jsoncons::ubjson::ubjson_type::high_precision_number_type: 
536
9.02k
            {
537
9.02k
                std::size_t length = get_length(ec);
538
9.02k
                if (JSONCONS_UNLIKELY(ec))
539
1
                {
540
1
                    return;
541
1
                }
542
9.01k
                text_buffer_.clear();
543
9.01k
                if (source_reader<Source>::read(source_,text_buffer_,length) != length)
544
29
                {
545
29
                    ec = ubjson_errc::unexpected_eof;
546
29
                    more_ = false;
547
29
                    return;
548
29
                }
549
8.99k
                if (jsoncons::is_base10(text_buffer_.data(),text_buffer_.length()))
550
186
                {
551
186
                    visitor.string_value(jsoncons::basic_string_view<char>(text_buffer_.data(),text_buffer_.length()), semantic_tag::bigint, *this, ec);
552
186
                    more_ = !cursor_mode_;
553
186
                }
554
8.80k
                else
555
8.80k
                {
556
8.80k
                    visitor.string_value(jsoncons::basic_string_view<char>(text_buffer_.data(),text_buffer_.length()), semantic_tag::bigdec, *this, ec);
557
8.80k
                    more_ = !cursor_mode_;
558
8.80k
                }
559
8.99k
                break;
560
9.01k
            }
561
6.98M
            case jsoncons::ubjson::ubjson_type::start_array_marker: 
562
6.98M
            {
563
6.98M
                begin_array(visitor,ec);
564
6.98M
                break;
565
9.01k
            }
566
4.66M
            case jsoncons::ubjson::ubjson_type::start_object_marker: 
567
4.66M
            {
568
4.66M
                begin_object(visitor, ec);
569
4.66M
                break;
570
9.01k
            }
571
99
            default:
572
99
            {
573
99
                ec = ubjson_errc::unknown_type;
574
99
                break;
575
9.01k
            }
576
46.6M
        }
577
46.6M
        if (JSONCONS_UNLIKELY(ec))
578
238
        {
579
238
            more_ = false;
580
238
        }
581
46.6M
    }
582
583
    void begin_array(json_visitor& visitor, std::error_code& ec)
584
6.98M
    {
585
6.98M
        if (JSONCONS_UNLIKELY(++nesting_depth_ > max_nesting_depth_))
586
3
        {
587
3
            ec = ubjson_errc::max_nesting_depth_exceeded;
588
3
            more_ = false;
589
3
            return;
590
3
        } 
591
592
6.98M
        auto c = source_.peek();
593
6.98M
        if (JSONCONS_UNLIKELY(c.eof))
594
20
        {
595
20
            ec = ubjson_errc::unexpected_eof;
596
20
            more_ = false;
597
20
            return;
598
20
        }
599
6.98M
        if (c.value == jsoncons::ubjson::ubjson_type::type_marker)
600
45.4k
        {
601
45.4k
            source_.ignore(1);
602
45.4k
            uint8_t b;
603
45.4k
            if (source_.read(&b, 1) == 0)
604
8
            {
605
8
                ec = ubjson_errc::unexpected_eof;
606
8
                more_ = false;
607
8
                return;
608
8
            }
609
45.3k
            c = source_.peek();
610
45.3k
            if (JSONCONS_UNLIKELY(c.eof))
611
9
            {
612
9
                ec = ubjson_errc::unexpected_eof;
613
9
                more_ = false;
614
9
                return;
615
9
            }
616
45.3k
            if (c.value == jsoncons::ubjson::ubjson_type::count_marker)
617
45.3k
            {
618
45.3k
                source_.ignore(1);
619
45.3k
                std::size_t length = get_length(ec);
620
45.3k
                if (JSONCONS_UNLIKELY(ec))
621
9
                {
622
9
                    return;
623
9
                }
624
45.3k
                if (length > max_items_)
625
0
                {
626
0
                    ec = ubjson_errc::max_items_exceeded;
627
0
                    more_ = false;
628
0
                    return;
629
0
                }
630
45.3k
                state_stack_.emplace_back(parse_mode::strongly_typed_array,length,b);
631
45.3k
                visitor.begin_array(length, semantic_tag::none, *this, ec);
632
45.3k
                more_ = !cursor_mode_;
633
45.3k
            }
634
1
            else
635
1
            {
636
1
                ec = ubjson_errc::count_required_after_type;
637
1
                more_ = false;
638
1
                return;
639
1
            }
640
45.3k
        }
641
6.93M
        else if (c.value == jsoncons::ubjson::ubjson_type::count_marker)
642
105k
        {
643
105k
            source_.ignore(1);
644
105k
            std::size_t length = get_length(ec);
645
105k
            if (JSONCONS_UNLIKELY(ec))
646
9
            {
647
9
                return;
648
9
            }
649
105k
            if (length > max_items_)
650
1
            {
651
1
                ec = ubjson_errc::max_items_exceeded;
652
1
                more_ = false;
653
1
                return;
654
1
            }
655
105k
            state_stack_.emplace_back(parse_mode::array,length);
656
105k
            visitor.begin_array(length, semantic_tag::none, *this, ec);
657
105k
            more_ = !cursor_mode_;
658
105k
        }
659
6.83M
        else
660
6.83M
        {
661
6.83M
            state_stack_.emplace_back(parse_mode::indefinite_array,0);
662
6.83M
            visitor.begin_array(semantic_tag::none, *this, ec);
663
6.83M
            more_ = !cursor_mode_;
664
6.83M
        }
665
6.98M
    }
666
667
    void end_array(json_visitor& visitor, std::error_code& ec)
668
6.93M
    {
669
6.93M
        --nesting_depth_;
670
671
6.93M
        visitor.end_array(*this, ec);
672
6.93M
        more_ = !cursor_mode_;
673
6.93M
        if (level() == mark_level_)
674
0
        {
675
0
            more_ = false;
676
0
        }
677
6.93M
        state_stack_.pop_back();
678
6.93M
    }
679
680
    void begin_object(json_visitor& visitor, std::error_code& ec)
681
4.66M
    {
682
4.66M
        if (JSONCONS_UNLIKELY(++nesting_depth_ > max_nesting_depth_))
683
0
        {
684
0
            ec = ubjson_errc::max_nesting_depth_exceeded;
685
0
            more_ = false;
686
0
            return;
687
0
        } 
688
689
4.66M
        auto c = source_.peek();
690
4.66M
        if (JSONCONS_UNLIKELY(c.eof))
691
25
        {
692
25
            ec = ubjson_errc::unexpected_eof;
693
25
            more_ = false;
694
25
            return;
695
25
        }
696
4.66M
        if (c.value == jsoncons::ubjson::ubjson_type::type_marker)
697
95.1k
        {
698
95.1k
            source_.ignore(1);
699
95.1k
            uint8_t b;
700
95.1k
            if (source_.read(&b, 1) == 0)
701
9
            {
702
9
                ec = ubjson_errc::unexpected_eof;
703
9
                more_ = false;
704
9
                return;
705
9
            }
706
95.1k
            c = source_.peek();
707
95.1k
            if (JSONCONS_UNLIKELY(c.eof))
708
7
            {
709
7
                ec = ubjson_errc::unexpected_eof;
710
7
                more_ = false;
711
7
                return;
712
7
            }
713
95.1k
            if (c.value == jsoncons::ubjson::ubjson_type::count_marker)
714
95.1k
            {
715
95.1k
                source_.ignore(1);
716
95.1k
                std::size_t length = get_length(ec);
717
95.1k
                if (JSONCONS_UNLIKELY(ec))
718
8
                {
719
8
                    return;
720
8
                }
721
95.1k
                if (length > max_items_)
722
9
                {
723
9
                    ec = ubjson_errc::max_items_exceeded;
724
9
                    more_ = false;
725
9
                    return;
726
9
                }
727
95.1k
                state_stack_.emplace_back(parse_mode::strongly_typed_map_key,length,b);
728
95.1k
                visitor.begin_object(length, semantic_tag::none, *this, ec);
729
95.1k
                more_ = !cursor_mode_;
730
95.1k
            }
731
1
            else
732
1
            {
733
1
                ec = ubjson_errc::count_required_after_type;
734
1
                more_ = false;
735
1
                return;
736
1
            }
737
95.1k
        }
738
4.57M
        else
739
4.57M
        {
740
4.57M
            c = source_.peek();
741
4.57M
            if (JSONCONS_UNLIKELY(c.eof))
742
0
            {
743
0
                ec = ubjson_errc::unexpected_eof;
744
0
                more_ = false;
745
0
                return;
746
0
            }
747
4.57M
            if (c.value == jsoncons::ubjson::ubjson_type::count_marker)
748
6.39k
            {
749
6.39k
                source_.ignore(1);
750
6.39k
                std::size_t length = get_length(ec);
751
6.39k
                if (JSONCONS_UNLIKELY(ec))
752
5
                {
753
5
                    return;
754
5
                }
755
6.39k
                if (length > max_items_)
756
2
                {
757
2
                    ec = ubjson_errc::max_items_exceeded;
758
2
                    more_ = false;
759
2
                    return;
760
2
                }
761
6.38k
                state_stack_.emplace_back(parse_mode::map_key,length);
762
6.38k
                visitor.begin_object(length, semantic_tag::none, *this, ec);
763
6.38k
                more_ = !cursor_mode_;
764
6.38k
            }
765
4.56M
            else
766
4.56M
            {
767
4.56M
                state_stack_.emplace_back(parse_mode::indefinite_map_key,0);
768
4.56M
                visitor.begin_object(semantic_tag::none, *this, ec);
769
4.56M
                more_ = !cursor_mode_;
770
4.56M
            }
771
4.57M
        }
772
4.66M
    }
773
774
    void end_object(json_visitor& visitor, std::error_code& ec)
775
4.66M
    {
776
4.66M
        --nesting_depth_;
777
4.66M
        visitor.end_object(*this, ec);
778
4.66M
        more_ = !cursor_mode_;
779
4.66M
        if (level() == mark_level_)
780
0
        {
781
0
            more_ = false;
782
0
        }
783
4.66M
        state_stack_.pop_back();
784
4.66M
    }
785
786
    std::size_t get_length(std::error_code& ec)
787
6.85M
    {
788
6.85M
        std::size_t length = 0;
789
6.85M
        uint8_t type;
790
6.85M
        if (source_.read(&type, 1) == 0)
791
30
        {
792
30
            ec = ubjson_errc::unexpected_eof;
793
30
            more_ = false;
794
30
            return length;
795
30
        }
796
6.85M
        switch (type)
797
6.85M
        {
798
1.41M
            case jsoncons::ubjson::ubjson_type::int8_type: 
799
1.41M
            {
800
1.41M
                uint8_t buf[sizeof(int8_t)];
801
1.41M
                if (source_.read(buf, sizeof(int8_t)) != sizeof(int8_t))
802
1
                {
803
1
                    ec = ubjson_errc::unexpected_eof;
804
1
                    more_ = false;
805
1
                    return length;
806
1
                }
807
1.41M
                int8_t val = binary::big_to_native<int8_t>(buf, sizeof(buf));
808
1.41M
                if (val >= 0)
809
1.41M
                {
810
1.41M
                    length = val;
811
1.41M
                }
812
0
                else
813
0
                {
814
0
                    ec = ubjson_errc::length_is_negative;
815
0
                    more_ = false;
816
0
                    return length;
817
0
                }
818
1.41M
                break;
819
1.41M
            }
820
5.42M
            case jsoncons::ubjson::ubjson_type::uint8_type: 
821
5.42M
            {
822
5.42M
                uint8_t b;
823
5.42M
                if (source_.read(&b, 1) == 0)
824
0
                {
825
0
                    ec = ubjson_errc::unexpected_eof;
826
0
                    more_ = false;
827
0
                    return length;
828
0
                }
829
5.42M
                length = b;
830
5.42M
                break;
831
5.42M
            }
832
15.4k
            case jsoncons::ubjson::ubjson_type::int16_type: 
833
15.4k
            {
834
15.4k
                uint8_t buf[sizeof(int16_t)];
835
15.4k
                if (source_.read(buf, sizeof(int16_t)) != sizeof(int16_t))
836
0
                {
837
0
                    ec = ubjson_errc::unexpected_eof;
838
0
                    more_ = false;
839
0
                    return length;
840
0
                }
841
15.4k
                int16_t val = binary::big_to_native<int16_t>(buf, sizeof(buf));
842
15.4k
                if (val >= 0)
843
15.4k
                {
844
15.4k
                    length = val;
845
15.4k
                }
846
0
                else
847
0
                {
848
0
                    ec = ubjson_errc::length_is_negative;
849
0
                    more_ = false;
850
0
                    return length;
851
0
                }
852
15.4k
                break;
853
15.4k
            }
854
15.4k
            case jsoncons::ubjson::ubjson_type::int32_type: 
855
874
            {
856
874
                uint8_t buf[sizeof(int32_t)];
857
874
                if (source_.read(buf, sizeof(int32_t)) != sizeof(int32_t))
858
0
                {
859
0
                    ec = ubjson_errc::unexpected_eof;
860
0
                    more_ = false;
861
0
                    return length;
862
0
                }
863
874
                int32_t val = binary::big_to_native<int32_t>(buf, sizeof(buf));
864
874
                if (val >= 0)
865
874
                {
866
874
                    length = static_cast<std::size_t>(val);
867
874
                }
868
0
                else
869
0
                {
870
0
                    ec = ubjson_errc::length_is_negative;
871
0
                    more_ = false;
872
0
                    return length;
873
0
                }
874
874
                break;
875
874
            }
876
874
            case jsoncons::ubjson::ubjson_type::int64_type: 
877
112
            {
878
112
                uint8_t buf[sizeof(int64_t)];
879
112
                if (source_.read(buf, sizeof(int64_t)) != sizeof(int64_t))
880
0
                {
881
0
                    ec = ubjson_errc::unexpected_eof;
882
0
                    more_ = false;
883
0
                    return length;
884
0
                }
885
112
                int64_t val = binary::big_to_native<int64_t>(buf, sizeof(buf));
886
112
                if (val >= 0)
887
112
                {
888
112
                    length = (std::size_t)val;
889
112
                    if (length != (uint64_t)val)
890
0
                    {
891
0
                        ec = ubjson_errc::number_too_large;
892
0
                        more_ = false;
893
0
                        return length;
894
0
                    }
895
112
                }
896
0
                else
897
0
                {
898
0
                    ec = ubjson_errc::length_is_negative;
899
0
                    more_ = false;
900
0
                    return length;
901
0
                }
902
112
                break;
903
112
            }
904
112
            default:
905
45
            {
906
45
                ec = ubjson_errc::length_must_be_integer;
907
45
                more_ = false;
908
45
                return length;
909
112
            }
910
6.85M
        }
911
6.85M
        return length;
912
6.85M
    }
913
914
    void read_key(json_visitor& visitor, std::error_code& ec)
915
6.57M
    {
916
6.57M
        std::size_t length = get_length(ec);
917
6.57M
        if (JSONCONS_UNLIKELY(ec))
918
43
        {
919
43
            ec = ubjson_errc::key_expected;
920
43
            more_ = false;
921
43
            return;
922
43
        }
923
6.57M
        text_buffer_.clear();
924
6.57M
        if (source_reader<Source>::read(source_,text_buffer_,length) != length)
925
44
        {
926
44
            ec = ubjson_errc::unexpected_eof;
927
44
            more_ = false;
928
44
            return;
929
44
        }
930
931
6.57M
        auto result = unicode_traits::validate(text_buffer_.data(),text_buffer_.size());
932
6.57M
        if (result.ec != unicode_traits::conv_errc())
933
20
        {
934
20
            ec = ubjson_errc::invalid_utf8_text_string;
935
20
            more_ = false;
936
20
            return;
937
20
        }
938
6.57M
        visitor.key(jsoncons::basic_string_view<char>(text_buffer_.data(),text_buffer_.length()), *this, ec);
939
6.57M
        more_ = !cursor_mode_;
940
6.57M
    }
941
};
942
943
} // namespace ubjson
944
} // namespace jsoncons
945
946
#endif