Coverage Report

Created: 2025-06-22 07:08

/src/jsoncons/include/jsoncons_ext/ubjson/ubjson_parser.hpp
Line
Count
Source (jump to first uncovered line)
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_context.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
14.7M
        : mode(mode), length(length), type(type)
46
14.7M
    {
47
14.7M
    }
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
712
       : source_(std::forward<Sourceable>(source)), 
79
712
         options_(options),
80
712
         text_buffer_(alloc),
81
712
         state_stack_(alloc)
82
712
    {
83
712
        state_stack_.emplace_back(parse_mode::root,0);
84
712
    }
jsoncons::ubjson::basic_ubjson_parser<jsoncons::stream_source<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
274
       : source_(std::forward<Sourceable>(source)), 
79
274
         options_(options),
80
274
         text_buffer_(alloc),
81
274
         state_stack_(alloc)
82
274
    {
83
274
        state_stack_.emplace_back(parse_mode::root,0);
84
274
    }
jsoncons::ubjson::basic_ubjson_parser<jsoncons::stream_source<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
438
       : source_(std::forward<Sourceable>(source)), 
79
438
         options_(options),
80
438
         text_buffer_(alloc),
81
438
         state_stack_(alloc)
82
438
    {
83
438
        state_stack_.emplace_back(parse_mode::root,0);
84
438
    }
85
86
    void restart()
87
    {
88
        more_ = true;
89
    }
90
91
    void reset()
92
712
    {
93
712
        more_ = true;
94
712
        done_ = false;
95
712
        text_buffer_.clear();
96
712
        state_stack_.clear();
97
712
        state_stack_.emplace_back(parse_mode::root,0,uint8_t(0));
98
712
        nesting_depth_ = 0;
99
712
    }
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
14.7M
    {
115
14.7M
        return static_cast<int>(state_stack_.size());
116
14.7M
    }
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
331
    {
140
331
        return 0;
141
331
    }
142
143
    std::size_t column() const override
144
331
    {
145
331
        return source_.position();
146
331
    }
147
148
    void parse(json_visitor& visitor, std::error_code& ec)
149
712
    {
150
68.6M
        while (!done_ && more_)
151
68.6M
        {
152
68.6M
            switch (state_stack_.back().mode)
153
68.6M
            {
154
127k
                case parse_mode::array:
155
127k
                {
156
127k
                    if (state_stack_.back().index < state_stack_.back().length)
157
27.2k
                    {
158
27.2k
                        ++state_stack_.back().index;
159
27.2k
                        read_type_and_value(visitor, ec);
160
27.2k
                        if (JSONCONS_UNLIKELY(ec))
161
1
                        {
162
1
                            return;
163
1
                        }
164
27.2k
                    }
165
100k
                    else
166
100k
                    {
167
100k
                        end_array(visitor, ec);
168
100k
                    }
169
127k
                    break;
170
127k
                }
171
27.1M
                case parse_mode::strongly_typed_array:
172
27.1M
                {
173
27.1M
                    if (state_stack_.back().index < state_stack_.back().length)
174
27.1M
                    {
175
27.1M
                        ++state_stack_.back().index;
176
27.1M
                        read_value(visitor, state_stack_.back().type, ec);
177
27.1M
                        if (JSONCONS_UNLIKELY(ec))
178
185
                        {
179
185
                            return;
180
185
                        }
181
27.1M
                    }
182
24.2k
                    else
183
24.2k
                    {
184
24.2k
                        end_array(visitor, ec);
185
24.2k
                    }
186
27.1M
                    break;
187
27.1M
                }
188
27.1M
                case parse_mode::indefinite_array:
189
26.4M
                {
190
26.4M
                    auto c = source_.peek();
191
26.4M
                    if (JSONCONS_UNLIKELY(c.eof))
192
54
                    {
193
54
                        ec = ubjson_errc::unexpected_eof;
194
54
                        more_ = false;
195
54
                        return;
196
54
                    }
197
26.4M
                    if (c.value == jsoncons::ubjson::ubjson_type::end_array_marker)
198
9.44M
                    {
199
9.44M
                        source_.ignore(1);
200
9.44M
                        end_array(visitor, ec);
201
9.44M
                        if (JSONCONS_UNLIKELY(ec))
202
0
                        {
203
0
                            return;
204
0
                        }
205
9.44M
                    }
206
16.9M
                    else
207
16.9M
                    {
208
16.9M
                        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
16.9M
                        read_type_and_value(visitor, ec);
215
16.9M
                        if (JSONCONS_UNLIKELY(ec))
216
116
                        {
217
116
                            return;
218
116
                        }
219
16.9M
                    }
220
26.4M
                    break;
221
26.4M
                }
222
26.4M
                case parse_mode::map_key:
223
19.4k
                {
224
19.4k
                    if (state_stack_.back().index < state_stack_.back().length)
225
13.1k
                    {
226
13.1k
                        ++state_stack_.back().index;
227
13.1k
                        read_key(visitor, ec);
228
13.1k
                        if (JSONCONS_UNLIKELY(ec))
229
1
                        {
230
1
                            return;
231
1
                        }
232
13.1k
                        state_stack_.back().mode = parse_mode::map_value;
233
13.1k
                    }
234
6.22k
                    else
235
6.22k
                    {
236
6.22k
                        end_object(visitor, ec);
237
6.22k
                    }
238
19.4k
                    break;
239
19.4k
                }
240
19.4k
                case parse_mode::map_value:
241
13.1k
                {
242
13.1k
                    state_stack_.back().mode = parse_mode::map_key;
243
13.1k
                    read_type_and_value(visitor, ec);
244
13.1k
                    if (JSONCONS_UNLIKELY(ec))
245
7
                    {
246
7
                        return;
247
7
                    }
248
13.1k
                    break;
249
13.1k
                }
250
107k
                case parse_mode::strongly_typed_map_key:
251
107k
                {
252
107k
                    if (state_stack_.back().index < state_stack_.back().length)
253
22.4k
                    {
254
22.4k
                        ++state_stack_.back().index;
255
22.4k
                        read_key(visitor, ec);
256
22.4k
                        if (JSONCONS_UNLIKELY(ec))
257
8
                        {
258
8
                            return;
259
8
                        }
260
22.4k
                        state_stack_.back().mode = parse_mode::strongly_typed_map_value;
261
22.4k
                    }
262
84.9k
                    else
263
84.9k
                    {
264
84.9k
                        end_object(visitor, ec);
265
84.9k
                    }
266
107k
                    break;
267
107k
                }
268
107k
                case parse_mode::strongly_typed_map_value:
269
22.4k
                {
270
22.4k
                    state_stack_.back().mode = parse_mode::strongly_typed_map_key;
271
22.4k
                    read_value(visitor, state_stack_.back().type, ec);
272
22.4k
                    if (JSONCONS_UNLIKELY(ec))
273
1
                    {
274
1
                        return;
275
1
                    }
276
22.4k
                    break;
277
22.4k
                }
278
9.92M
                case parse_mode::indefinite_map_key:
279
9.92M
                {
280
9.92M
                    auto c = source_.peek();
281
9.92M
                    if (JSONCONS_UNLIKELY(c.eof))
282
21
                    {
283
21
                        ec = ubjson_errc::unexpected_eof;
284
21
                        more_ = false;
285
21
                        return;
286
21
                    }
287
9.92M
                    if (c.value == jsoncons::ubjson::ubjson_type::end_object_marker)
288
5.07M
                    {
289
5.07M
                        source_.ignore(1);
290
5.07M
                        end_object(visitor, ec);
291
5.07M
                        if (JSONCONS_UNLIKELY(ec))
292
0
                        {
293
0
                            return;
294
0
                        }
295
5.07M
                    }
296
4.85M
                    else
297
4.85M
                    {
298
4.85M
                        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
4.85M
                        read_key(visitor, ec);
305
4.85M
                        if (JSONCONS_UNLIKELY(ec))
306
89
                        {
307
89
                            return;
308
89
                        }
309
4.85M
                        state_stack_.back().mode = parse_mode::indefinite_map_value;
310
4.85M
                    }
311
9.92M
                    break;
312
9.92M
                }
313
9.92M
                case parse_mode::indefinite_map_value:
314
4.85M
                {
315
4.85M
                    state_stack_.back().mode = parse_mode::indefinite_map_key;
316
4.85M
                    read_type_and_value(visitor, ec);
317
4.85M
                    if (JSONCONS_UNLIKELY(ec))
318
41
                    {
319
41
                        return;
320
41
                    }
321
4.85M
                    break;
322
4.85M
                }
323
4.85M
                case parse_mode::root:
324
712
                {
325
712
                    state_stack_.back().mode = parse_mode::accept;
326
712
                    read_type_and_value(visitor, ec);
327
712
                    if (JSONCONS_UNLIKELY(ec))
328
67
                    {
329
67
                        return;
330
67
                    }
331
645
                    break;
332
712
                }
333
645
                case parse_mode::accept:
334
121
                {
335
121
                    JSONCONS_ASSERT(state_stack_.size() == 1);
336
121
                    state_stack_.clear();
337
121
                    more_ = false;
338
121
                    done_ = true;
339
121
                    visitor.flush();
340
121
                    break;
341
121
                }
342
68.6M
            }
343
68.6M
        }
344
712
    }
345
private:
346
    void read_type_and_value(json_visitor& visitor, std::error_code& ec)
347
21.8M
    {
348
21.8M
        if (source_.is_error())
349
0
        {
350
0
            ec = ubjson_errc::source_error;
351
0
            more_ = false;
352
0
            return;
353
0
        }   
354
355
21.8M
        uint8_t b;
356
21.8M
        if (source_.read(&b, 1) == 0)
357
31
        {
358
31
            ec = ubjson_errc::unexpected_eof;
359
31
            more_ = false;
360
31
            return;
361
31
        }
362
21.8M
        read_value(visitor, b, ec);
363
21.8M
    }
364
365
    void read_value(json_visitor& visitor, uint8_t type, std::error_code& ec)
366
49.0M
    {
367
49.0M
        switch (type)
368
49.0M
        {
369
17.4M
            case jsoncons::ubjson::ubjson_type::null_type: 
370
17.4M
            {
371
17.4M
                visitor.null_value(semantic_tag::none, *this, ec);
372
17.4M
                more_ = !cursor_mode_;
373
17.4M
                break;
374
0
            }
375
108k
            case jsoncons::ubjson::ubjson_type::no_op_type: 
376
108k
            {
377
108k
                break;
378
0
            }
379
637k
            case jsoncons::ubjson::ubjson_type::true_type:
380
637k
            {
381
637k
                visitor.bool_value(true, semantic_tag::none, *this, ec);
382
637k
                more_ = !cursor_mode_;
383
637k
                break;
384
0
            }
385
2.36M
            case jsoncons::ubjson::ubjson_type::false_type:
386
2.36M
            {
387
2.36M
                visitor.bool_value(false, semantic_tag::none, *this, ec);
388
2.36M
                more_ = !cursor_mode_;
389
2.36M
                break;
390
0
            }
391
3.03M
            case jsoncons::ubjson::ubjson_type::int8_type: 
392
3.03M
            {
393
3.03M
                uint8_t buf[sizeof(int8_t)];
394
3.03M
                if (source_.read(buf, sizeof(int8_t)) != sizeof(int8_t))
395
19
                {
396
19
                    ec = ubjson_errc::unexpected_eof;
397
19
                    more_ = false;
398
19
                    return;
399
19
                }
400
3.03M
                int8_t val = binary::big_to_native<int8_t>(buf, sizeof(buf));
401
3.03M
                visitor.int64_value(val, semantic_tag::none, *this, ec);
402
3.03M
                more_ = !cursor_mode_;
403
3.03M
                break;
404
3.03M
            }
405
3.97M
            case jsoncons::ubjson::ubjson_type::uint8_type: 
406
3.97M
            {
407
3.97M
                uint8_t b;
408
3.97M
                if (source_.read(&b, 1) == 0)
409
18
                {
410
18
                    ec = ubjson_errc::unexpected_eof;
411
18
                    more_ = false;
412
18
                    return;
413
18
                }
414
3.97M
                visitor.uint64_value(b, semantic_tag::none, *this, ec);
415
3.97M
                more_ = !cursor_mode_;
416
3.97M
                break;
417
3.97M
            }
418
843k
            case jsoncons::ubjson::ubjson_type::int16_type: 
419
843k
            {
420
843k
                uint8_t buf[sizeof(int16_t)];
421
843k
                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
843k
                int16_t val = binary::big_to_native<int16_t>(buf, sizeof(buf));
428
843k
                visitor.int64_value(val, semantic_tag::none, *this, ec);
429
843k
                more_ = !cursor_mode_;
430
843k
                break;
431
843k
            }
432
127k
            case jsoncons::ubjson::ubjson_type::int32_type: 
433
127k
            {
434
127k
                uint8_t buf[sizeof(int32_t)];
435
127k
                if (source_.read(buf, sizeof(int32_t)) != sizeof(int32_t))
436
7
                {
437
7
                    ec = ubjson_errc::unexpected_eof;
438
7
                    more_ = false;
439
7
                    return;
440
7
                }
441
127k
                int32_t val = binary::big_to_native<int32_t>(buf, sizeof(buf));
442
127k
                visitor.int64_value(val, semantic_tag::none, *this, ec);
443
127k
                more_ = !cursor_mode_;
444
127k
                break;
445
127k
            }
446
36.0k
            case jsoncons::ubjson::ubjson_type::int64_type: 
447
36.0k
            {
448
36.0k
                uint8_t buf[sizeof(int64_t)];
449
36.0k
                if (source_.read(buf, sizeof(int64_t)) != sizeof(int64_t))
450
8
                {
451
8
                    ec = ubjson_errc::unexpected_eof;
452
8
                    more_ = false;
453
8
                    return;
454
8
                }
455
36.0k
                int64_t val = binary::big_to_native<int64_t>(buf, sizeof(buf));
456
36.0k
                visitor.int64_value(val, semantic_tag::none, *this, ec);
457
36.0k
                more_ = !cursor_mode_;
458
36.0k
                break;
459
36.0k
            }
460
220k
            case jsoncons::ubjson::ubjson_type::float32_type: 
461
220k
            {
462
220k
                uint8_t buf[sizeof(float)];
463
220k
                if (source_.read(buf, sizeof(float)) != sizeof(float))
464
10
                {
465
10
                    ec = ubjson_errc::unexpected_eof;
466
10
                    more_ = false;
467
10
                    return;
468
10
                }
469
220k
                float val = binary::big_to_native<float>(buf, sizeof(buf));
470
220k
                visitor.double_value(val, semantic_tag::none, *this, ec);
471
220k
                more_ = !cursor_mode_;
472
220k
                break;
473
220k
            }
474
1.87k
            case jsoncons::ubjson::ubjson_type::float64_type: 
475
1.87k
            {
476
1.87k
                uint8_t buf[sizeof(double)];
477
1.87k
                if (source_.read(buf, sizeof(double)) != sizeof(double))
478
0
                {
479
0
                    ec = ubjson_errc::unexpected_eof;
480
0
                    more_ = false;
481
0
                    return;
482
0
                }
483
1.87k
                double val = binary::big_to_native<double>(buf, sizeof(buf));
484
1.87k
                visitor.double_value(val, semantic_tag::none, *this, ec);
485
1.87k
                more_ = !cursor_mode_;
486
1.87k
                break;
487
1.87k
            }
488
5.43M
            case jsoncons::ubjson::ubjson_type::char_type: 
489
5.43M
            {
490
5.43M
                text_buffer_.clear();
491
5.43M
                if (source_reader<Source>::read(source_,text_buffer_,1) != 1)
492
36
                {
493
36
                    ec = ubjson_errc::unexpected_eof;
494
36
                    more_ = false;
495
36
                    return;
496
36
                }
497
5.43M
                auto result = unicode_traits::validate(text_buffer_.data(),text_buffer_.size());
498
5.43M
                if (result.ec != unicode_traits::conv_errc())
499
4
                {
500
4
                    ec = ubjson_errc::invalid_utf8_text_string;
501
4
                    more_ = false;
502
4
                    return;
503
4
                }
504
5.43M
                visitor.string_value(text_buffer_, semantic_tag::none, *this, ec);
505
5.43M
                more_ = !cursor_mode_;
506
5.43M
                break;
507
5.43M
            }
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
14
                {
518
14
                    ec = ubjson_errc::unexpected_eof;
519
14
                    more_ = false;
520
14
                    return;
521
14
                }
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
17
                {
525
17
                    ec = ubjson_errc::invalid_utf8_text_string;
526
17
                    more_ = false;
527
17
                    return;
528
17
                }
529
14.5k
                visitor.string_value(jsoncons::basic_string_view<char>(text_buffer_.data(),text_buffer_.length()), semantic_tag::none, *this, ec);
530
14.5k
                more_ = !cursor_mode_;
531
14.5k
                break;
532
14.5k
            }
533
9.34k
            case jsoncons::ubjson::ubjson_type::high_precision_number_type: 
534
9.34k
            {
535
9.34k
                std::size_t length = get_length(ec);
536
9.34k
                if (JSONCONS_UNLIKELY(ec))
537
2
                {
538
2
                    return;
539
2
                }
540
9.33k
                text_buffer_.clear();
541
9.33k
                if (source_reader<Source>::read(source_,text_buffer_,length) != length)
542
19
                {
543
19
                    ec = ubjson_errc::unexpected_eof;
544
19
                    more_ = false;
545
19
                    return;
546
19
                }
547
9.32k
                if (jsoncons::utility::is_base10(text_buffer_.data(),text_buffer_.length()))
548
37
                {
549
37
                    visitor.string_value(jsoncons::basic_string_view<char>(text_buffer_.data(),text_buffer_.length()), semantic_tag::bigint, *this, ec);
550
37
                    more_ = !cursor_mode_;
551
37
                }
552
9.28k
                else
553
9.28k
                {
554
9.28k
                    visitor.string_value(jsoncons::basic_string_view<char>(text_buffer_.data(),text_buffer_.length()), semantic_tag::bigdec, *this, ec);
555
9.28k
                    more_ = !cursor_mode_;
556
9.28k
                }
557
9.32k
                break;
558
9.33k
            }
559
9.61M
            case jsoncons::ubjson::ubjson_type::start_array_marker: 
560
9.61M
            {
561
9.61M
                begin_array(visitor,ec);
562
9.61M
                break;
563
9.33k
            }
564
5.17M
            case jsoncons::ubjson::ubjson_type::start_object_marker: 
565
5.17M
            {
566
5.17M
                begin_object(visitor, ec);
567
5.17M
                break;
568
9.33k
            }
569
68
            default:
570
68
            {
571
68
                ec = ubjson_errc::unknown_type;
572
68
                break;
573
9.33k
            }
574
49.0M
        }
575
49.0M
        if (JSONCONS_UNLIKELY(ec))
576
223
        {
577
223
            more_ = false;
578
223
        }
579
49.0M
    }
580
581
    void begin_array(json_visitor& visitor, std::error_code& ec)
582
9.61M
    {
583
9.61M
        if (JSONCONS_UNLIKELY(++nesting_depth_ > options_.max_nesting_depth()))
584
3
        {
585
3
            ec = ubjson_errc::max_nesting_depth_exceeded;
586
3
            more_ = false;
587
3
            return;
588
3
        } 
589
590
9.61M
        auto c = source_.peek();
591
9.61M
        if (JSONCONS_UNLIKELY(c.eof))
592
29
        {
593
29
            ec = ubjson_errc::unexpected_eof;
594
29
            more_ = false;
595
29
            return;
596
29
        }
597
9.61M
        if (c.value == jsoncons::ubjson::ubjson_type::type_marker)
598
40.6k
        {
599
40.6k
            source_.ignore(1);
600
40.6k
            uint8_t b;
601
40.6k
            if (source_.read(&b, 1) == 0)
602
9
            {
603
9
                ec = ubjson_errc::unexpected_eof;
604
9
                more_ = false;
605
9
                return;
606
9
            }
607
40.6k
            c = source_.peek();
608
40.6k
            if (JSONCONS_UNLIKELY(c.eof))
609
8
            {
610
8
                ec = ubjson_errc::unexpected_eof;
611
8
                more_ = false;
612
8
                return;
613
8
            }
614
40.6k
            if (c.value == jsoncons::ubjson::ubjson_type::count_marker)
615
40.6k
            {
616
40.6k
                source_.ignore(1);
617
40.6k
                std::size_t length = get_length(ec);
618
40.6k
                if (JSONCONS_UNLIKELY(ec))
619
10
                {
620
10
                    return;
621
10
                }
622
40.6k
                if (length > options_.max_items())
623
1
                {
624
1
                    ec = ubjson_errc::max_items_exceeded;
625
1
                    more_ = false;
626
1
                    return;
627
1
                }
628
40.6k
                state_stack_.emplace_back(parse_mode::strongly_typed_array,length,b);
629
40.6k
                visitor.begin_array(length, semantic_tag::none, *this, ec);
630
40.6k
                more_ = !cursor_mode_;
631
40.6k
            }
632
0
            else
633
0
            {
634
0
                ec = ubjson_errc::count_required_after_type;
635
0
                more_ = false;
636
0
                return;
637
0
            }
638
40.6k
        }
639
9.57M
        else if (c.value == jsoncons::ubjson::ubjson_type::count_marker)
640
100k
        {
641
100k
            source_.ignore(1);
642
100k
            std::size_t length = get_length(ec);
643
100k
            if (JSONCONS_UNLIKELY(ec))
644
10
            {
645
10
                return;
646
10
            }
647
100k
            if (length > options_.max_items())
648
2
            {
649
2
                ec = ubjson_errc::max_items_exceeded;
650
2
                more_ = false;
651
2
                return;
652
2
            }
653
100k
            state_stack_.emplace_back(parse_mode::array,length);
654
100k
            visitor.begin_array(length, semantic_tag::none, *this, ec);
655
100k
            more_ = !cursor_mode_;
656
100k
        }
657
9.47M
        else
658
9.47M
        {
659
9.47M
            state_stack_.emplace_back(parse_mode::indefinite_array,0);
660
9.47M
            visitor.begin_array(semantic_tag::none, *this, ec);
661
9.47M
            more_ = !cursor_mode_;
662
9.47M
        }
663
9.61M
    }
664
665
    void end_array(json_visitor& visitor, std::error_code& ec)
666
9.57M
    {
667
9.57M
        --nesting_depth_;
668
669
9.57M
        visitor.end_array(*this, ec);
670
9.57M
        more_ = !cursor_mode_;
671
9.57M
        if (level() == mark_level_)
672
0
        {
673
0
            more_ = false;
674
0
        }
675
9.57M
        state_stack_.pop_back();
676
9.57M
    }
677
678
    void begin_object(json_visitor& visitor, std::error_code& ec)
679
5.17M
    {
680
5.17M
        if (JSONCONS_UNLIKELY(++nesting_depth_ > options_.max_nesting_depth()))
681
1
        {
682
1
            ec = ubjson_errc::max_nesting_depth_exceeded;
683
1
            more_ = false;
684
1
            return;
685
1
        } 
686
687
5.17M
        auto c = source_.peek();
688
5.17M
        if (JSONCONS_UNLIKELY(c.eof))
689
29
        {
690
29
            ec = ubjson_errc::unexpected_eof;
691
29
            more_ = false;
692
29
            return;
693
29
        }
694
5.17M
        if (c.value == jsoncons::ubjson::ubjson_type::type_marker)
695
85.0k
        {
696
85.0k
            source_.ignore(1);
697
85.0k
            uint8_t b;
698
85.0k
            if (source_.read(&b, 1) == 0)
699
10
            {
700
10
                ec = ubjson_errc::unexpected_eof;
701
10
                more_ = false;
702
10
                return;
703
10
            }
704
85.0k
            c = source_.peek();
705
85.0k
            if (JSONCONS_UNLIKELY(c.eof))
706
7
            {
707
7
                ec = ubjson_errc::unexpected_eof;
708
7
                more_ = false;
709
7
                return;
710
7
            }
711
85.0k
            if (c.value == jsoncons::ubjson::ubjson_type::count_marker)
712
85.0k
            {
713
85.0k
                source_.ignore(1);
714
85.0k
                std::size_t length = get_length(ec);
715
85.0k
                if (JSONCONS_UNLIKELY(ec))
716
7
                {
717
7
                    return;
718
7
                }
719
85.0k
                if (length > options_.max_items())
720
4
                {
721
4
                    ec = ubjson_errc::max_items_exceeded;
722
4
                    more_ = false;
723
4
                    return;
724
4
                }
725
85.0k
                state_stack_.emplace_back(parse_mode::strongly_typed_map_key,length,b);
726
85.0k
                visitor.begin_object(length, semantic_tag::none, *this, ec);
727
85.0k
                more_ = !cursor_mode_;
728
85.0k
            }
729
4
            else
730
4
            {
731
4
                ec = ubjson_errc::count_required_after_type;
732
4
                more_ = false;
733
4
                return;
734
4
            }
735
85.0k
        }
736
5.08M
        else
737
5.08M
        {
738
5.08M
            c = source_.peek();
739
5.08M
            if (JSONCONS_UNLIKELY(c.eof))
740
0
            {
741
0
                ec = ubjson_errc::unexpected_eof;
742
0
                more_ = false;
743
0
                return;
744
0
            }
745
5.08M
            if (c.value == jsoncons::ubjson::ubjson_type::count_marker)
746
7.18k
            {
747
7.18k
                source_.ignore(1);
748
7.18k
                std::size_t length = get_length(ec);
749
7.18k
                if (JSONCONS_UNLIKELY(ec))
750
7
                {
751
7
                    return;
752
7
                }
753
7.17k
                if (length > options_.max_items())
754
2
                {
755
2
                    ec = ubjson_errc::max_items_exceeded;
756
2
                    more_ = false;
757
2
                    return;
758
2
                }
759
7.17k
                state_stack_.emplace_back(parse_mode::map_key,length);
760
7.17k
                visitor.begin_object(length, semantic_tag::none, *this, ec);
761
7.17k
                more_ = !cursor_mode_;
762
7.17k
            }
763
5.07M
            else
764
5.07M
            {
765
5.07M
                state_stack_.emplace_back(parse_mode::indefinite_map_key,0);
766
5.07M
                visitor.begin_object(semantic_tag::none, *this, ec);
767
5.07M
                more_ = !cursor_mode_;
768
5.07M
            }
769
5.08M
        }
770
5.17M
    }
771
772
    void end_object(json_visitor& visitor, std::error_code& ec)
773
5.16M
    {
774
5.16M
        --nesting_depth_;
775
5.16M
        visitor.end_object(*this, ec);
776
5.16M
        more_ = !cursor_mode_;
777
5.16M
        if (level() == mark_level_)
778
0
        {
779
0
            more_ = false;
780
0
        }
781
5.16M
        state_stack_.pop_back();
782
5.16M
    }
783
784
    std::size_t get_length(std::error_code& ec)
785
5.14M
    {
786
5.14M
        std::size_t length = 0;
787
5.14M
        uint8_t type;
788
5.14M
        if (source_.read(&type, 1) == 0)
789
34
        {
790
34
            ec = ubjson_errc::unexpected_eof;
791
34
            more_ = false;
792
34
            return length;
793
34
        }
794
5.14M
        switch (type)
795
5.14M
        {
796
1.12M
            case jsoncons::ubjson::ubjson_type::int8_type: 
797
1.12M
            {
798
1.12M
                uint8_t buf[sizeof(int8_t)];
799
1.12M
                if (source_.read(buf, sizeof(int8_t)) != sizeof(int8_t))
800
0
                {
801
0
                    ec = ubjson_errc::unexpected_eof;
802
0
                    more_ = false;
803
0
                    return length;
804
0
                }
805
1.12M
                int8_t val = binary::big_to_native<int8_t>(buf, sizeof(buf));
806
1.12M
                if (val >= 0)
807
1.12M
                {
808
1.12M
                    length = val;
809
1.12M
                }
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.12M
                break;
817
1.12M
            }
818
4.00M
            case jsoncons::ubjson::ubjson_type::uint8_type: 
819
4.00M
            {
820
4.00M
                uint8_t b;
821
4.00M
                if (source_.read(&b, 1) == 0)
822
2
                {
823
2
                    ec = ubjson_errc::unexpected_eof;
824
2
                    more_ = false;
825
2
                    return length;
826
2
                }
827
4.00M
                length = b;
828
4.00M
                break;
829
4.00M
            }
830
13.5k
            case jsoncons::ubjson::ubjson_type::int16_type: 
831
13.5k
            {
832
13.5k
                uint8_t buf[sizeof(int16_t)];
833
13.5k
                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
13.5k
                int16_t val = binary::big_to_native<int16_t>(buf, sizeof(buf));
840
13.5k
                if (val >= 0)
841
13.5k
                {
842
13.5k
                    length = val;
843
13.5k
                }
844
0
                else
845
0
                {
846
0
                    ec = ubjson_errc::length_is_negative;
847
0
                    more_ = false;
848
0
                    return length;
849
0
                }
850
13.5k
                break;
851
13.5k
            }
852
13.5k
            case jsoncons::ubjson::ubjson_type::int32_type: 
853
428
            {
854
428
                uint8_t buf[sizeof(int32_t)];
855
428
                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
428
                int32_t val = binary::big_to_native<int32_t>(buf, sizeof(buf));
862
428
                if (val >= 0)
863
428
                {
864
428
                    length = static_cast<std::size_t>(val);
865
428
                }
866
0
                else
867
0
                {
868
0
                    ec = ubjson_errc::length_is_negative;
869
0
                    more_ = false;
870
0
                    return length;
871
0
                }
872
428
                break;
873
428
            }
874
428
            case jsoncons::ubjson::ubjson_type::int64_type: 
875
145
            {
876
145
                uint8_t buf[sizeof(int64_t)];
877
145
                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
145
                int64_t val = binary::big_to_native<int64_t>(buf, sizeof(buf));
884
145
                if (val >= 0)
885
145
                {
886
145
                    length = (std::size_t)val;
887
145
                    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
145
                }
894
0
                else
895
0
                {
896
0
                    ec = ubjson_errc::length_is_negative;
897
0
                    more_ = false;
898
0
                    return length;
899
0
                }
900
145
                break;
901
145
            }
902
145
            default:
903
37
            {
904
37
                ec = ubjson_errc::length_must_be_integer;
905
37
                more_ = false;
906
37
                return length;
907
145
            }
908
5.14M
        }
909
5.14M
        return length;
910
5.14M
    }
911
912
    void read_key(json_visitor& visitor, std::error_code& ec)
913
4.88M
    {
914
4.88M
        std::size_t length = get_length(ec);
915
4.88M
        if (JSONCONS_UNLIKELY(ec))
916
37
        {
917
37
            ec = ubjson_errc::key_expected;
918
37
            more_ = false;
919
37
            return;
920
37
        }
921
4.88M
        text_buffer_.clear();
922
4.88M
        if (source_reader<Source>::read(source_,text_buffer_,length) != length)
923
44
        {
924
44
            ec = ubjson_errc::unexpected_eof;
925
44
            more_ = false;
926
44
            return;
927
44
        }
928
929
4.88M
        auto result = unicode_traits::validate(text_buffer_.data(),text_buffer_.size());
930
4.88M
        if (result.ec != unicode_traits::conv_errc())
931
17
        {
932
17
            ec = ubjson_errc::invalid_utf8_text_string;
933
17
            more_ = false;
934
17
            return;
935
17
        }
936
4.88M
        visitor.key(jsoncons::basic_string_view<char>(text_buffer_.data(),text_buffer_.length()), *this, ec);
937
4.88M
        more_ = !cursor_mode_;
938
4.88M
    }
939
};
940
941
} // namespace ubjson
942
} // namespace jsoncons
943
944
#endif