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