Coverage Report

Created: 2025-12-20 06:39

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
    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
743
       : source_(std::forward<Sourceable>(source)), 
80
743
         max_nesting_depth_(options.max_nesting_depth()),
81
743
         max_items_(options.max_items()),
82
743
         text_buffer_(alloc),
83
743
         state_stack_(alloc)
84
743
    {
85
743
        state_stack_.emplace_back(parse_mode::root,0);
86
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
79
281
       : source_(std::forward<Sourceable>(source)), 
80
281
         max_nesting_depth_(options.max_nesting_depth()),
81
281
         max_items_(options.max_items()),
82
281
         text_buffer_(alloc),
83
281
         state_stack_(alloc)
84
281
    {
85
281
        state_stack_.emplace_back(parse_mode::root,0);
86
281
    }
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
743
    {
95
743
        more_ = true;
96
743
        done_ = false;
97
743
        text_buffer_.clear();
98
743
        state_stack_.clear();
99
743
        state_stack_.emplace_back(parse_mode::root,0,uint8_t(0));
100
743
        nesting_depth_ = 0;
101
743
    }
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.4M
    {
117
11.4M
        return static_cast<int>(state_stack_.size());
118
11.4M
    }
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
337
    {
142
337
        return 0;
143
337
    }
144
145
    std::size_t column() const override
146
337
    {
147
337
        return source_.position();
148
337
    }
149
150
    void parse(json_visitor& visitor, std::error_code& ec)
151
743
    {
152
71.3M
        while (!done_ && more_)
153
71.3M
        {
154
71.3M
            switch (state_stack_.back().mode)
155
71.3M
            {
156
135k
                case parse_mode::array:
157
135k
                {
158
135k
                    if (state_stack_.back().index < state_stack_.back().length)
159
33.0k
                    {
160
33.0k
                        ++state_stack_.back().index;
161
33.0k
                        read_type_and_value(visitor, ec);
162
33.0k
                        if (JSONCONS_UNLIKELY(ec))
163
3
                        {
164
3
                            return;
165
3
                        }
166
33.0k
                    }
167
102k
                    else
168
102k
                    {
169
102k
                        end_array(visitor, ec);
170
102k
                    }
171
135k
                    break;
172
135k
                }
173
31.4M
                case parse_mode::strongly_typed_array:
174
31.4M
                {
175
31.4M
                    if (state_stack_.back().index < state_stack_.back().length)
176
31.4M
                    {
177
31.4M
                        ++state_stack_.back().index;
178
31.4M
                        read_value(visitor, state_stack_.back().type, ec);
179
31.4M
                        if (JSONCONS_UNLIKELY(ec))
180
167
                        {
181
167
                            return;
182
167
                        }
183
31.4M
                    }
184
24.9k
                    else
185
24.9k
                    {
186
24.9k
                        end_array(visitor, ec);
187
24.9k
                    }
188
31.4M
                    break;
189
31.4M
                }
190
31.4M
                case parse_mode::indefinite_array:
191
21.9M
                {
192
21.9M
                    auto c = source_.peek();
193
21.9M
                    if (JSONCONS_UNLIKELY(c.eof))
194
51
                    {
195
51
                        ec = ubjson_errc::unexpected_eof;
196
51
                        more_ = false;
197
51
                        return;
198
51
                    }
199
21.9M
                    if (c.value == jsoncons::ubjson::ubjson_type::end_array_marker)
200
6.71M
                    {
201
6.71M
                        source_.ignore(1);
202
6.71M
                        end_array(visitor, ec);
203
6.71M
                        if (JSONCONS_UNLIKELY(ec))
204
0
                        {
205
0
                            return;
206
0
                        }
207
6.71M
                    }
208
15.2M
                    else
209
15.2M
                    {
210
15.2M
                        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.2M
                        read_type_and_value(visitor, ec);
217
15.2M
                        if (JSONCONS_UNLIKELY(ec))
218
105
                        {
219
105
                            return;
220
105
                        }
221
15.2M
                    }
222
21.9M
                    break;
223
21.9M
                }
224
21.9M
                case parse_mode::map_key:
225
17.3k
                {
226
17.3k
                    if (state_stack_.back().index < state_stack_.back().length)
227
11.8k
                    {
228
11.8k
                        ++state_stack_.back().index;
229
11.8k
                        read_key(visitor, ec);
230
11.8k
                        if (JSONCONS_UNLIKELY(ec))
231
7
                        {
232
7
                            return;
233
7
                        }
234
11.8k
                        state_stack_.back().mode = parse_mode::map_value;
235
11.8k
                    }
236
5.48k
                    else
237
5.48k
                    {
238
5.48k
                        end_object(visitor, ec);
239
5.48k
                    }
240
17.3k
                    break;
241
17.3k
                }
242
17.3k
                case parse_mode::map_value:
243
11.8k
                {
244
11.8k
                    state_stack_.back().mode = parse_mode::map_key;
245
11.8k
                    read_type_and_value(visitor, ec);
246
11.8k
                    if (JSONCONS_UNLIKELY(ec))
247
9
                    {
248
9
                        return;
249
9
                    }
250
11.8k
                    break;
251
11.8k
                }
252
162k
                case parse_mode::strongly_typed_map_key:
253
162k
                {
254
162k
                    if (state_stack_.back().index < state_stack_.back().length)
255
75.3k
                    {
256
75.3k
                        ++state_stack_.back().index;
257
75.3k
                        read_key(visitor, ec);
258
75.3k
                        if (JSONCONS_UNLIKELY(ec))
259
7
                        {
260
7
                            return;
261
7
                        }
262
75.3k
                        state_stack_.back().mode = parse_mode::strongly_typed_map_value;
263
75.3k
                    }
264
86.7k
                    else
265
86.7k
                    {
266
86.7k
                        end_object(visitor, ec);
267
86.7k
                    }
268
162k
                    break;
269
162k
                }
270
162k
                case parse_mode::strongly_typed_map_value:
271
75.3k
                {
272
75.3k
                    state_stack_.back().mode = parse_mode::strongly_typed_map_key;
273
75.3k
                    read_value(visitor, state_stack_.back().type, ec);
274
75.3k
                    if (JSONCONS_UNLIKELY(ec))
275
1
                    {
276
1
                        return;
277
1
                    }
278
75.3k
                    break;
279
75.3k
                }
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
20
                    {
285
20
                        ec = ubjson_errc::unexpected_eof;
286
20
                        more_ = false;
287
20
                        return;
288
20
                    }
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.49M
                    else
299
6.49M
                    {
300
6.49M
                        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.49M
                        read_key(visitor, ec);
307
6.49M
                        if (JSONCONS_UNLIKELY(ec))
308
95
                        {
309
95
                            return;
310
95
                        }
311
6.49M
                        state_stack_.back().mode = parse_mode::indefinite_map_value;
312
6.49M
                    }
313
11.0M
                    break;
314
11.0M
                }
315
11.0M
                case parse_mode::indefinite_map_value:
316
6.49M
                {
317
6.49M
                    state_stack_.back().mode = parse_mode::indefinite_map_key;
318
6.49M
                    read_type_and_value(visitor, ec);
319
6.49M
                    if (JSONCONS_UNLIKELY(ec))
320
55
                    {
321
55
                        return;
322
55
                    }
323
6.49M
                    break;
324
6.49M
                }
325
6.49M
                case parse_mode::root:
326
743
                {
327
743
                    state_stack_.back().mode = parse_mode::accept;
328
743
                    read_type_and_value(visitor, ec);
329
743
                    if (JSONCONS_UNLIKELY(ec))
330
81
                    {
331
81
                        return;
332
81
                    }
333
662
                    break;
334
743
                }
335
662
                case parse_mode::accept:
336
142
                {
337
142
                    JSONCONS_ASSERT(state_stack_.size() == 1);
338
142
                    state_stack_.clear();
339
142
                    more_ = false;
340
142
                    done_ = true;
341
142
                    visitor.flush();
342
142
                    break;
343
142
                }
344
71.3M
            }
345
71.3M
        }
346
743
    }
347
private:
348
    void read_type_and_value(json_visitor& visitor, std::error_code& ec)
349
21.7M
    {
350
21.7M
        if (source_.is_error())
351
0
        {
352
0
            ec = ubjson_errc::source_error;
353
0
            more_ = false;
354
0
            return;
355
0
        }   
356
357
21.7M
        uint8_t b;
358
21.7M
        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
21.7M
        read_value(visitor, b, ec);
365
21.7M
    }
366
367
    void read_value(json_visitor& visitor, uint8_t type, std::error_code& ec)
368
53.2M
    {
369
53.2M
        switch (type)
370
53.2M
        {
371
24.5M
            case jsoncons::ubjson::ubjson_type::null_type: 
372
24.5M
            {
373
24.5M
                visitor.null_value(semantic_tag::none, *this, ec);
374
24.5M
                more_ = !cursor_mode_;
375
24.5M
                break;
376
0
            }
377
492k
            case jsoncons::ubjson::ubjson_type::no_op_type: 
378
492k
            {
379
492k
                break;
380
0
            }
381
2.83M
            case jsoncons::ubjson::ubjson_type::true_type:
382
2.83M
            {
383
2.83M
                visitor.bool_value(true, semantic_tag::none, *this, ec);
384
2.83M
                more_ = !cursor_mode_;
385
2.83M
                break;
386
0
            }
387
2.06M
            case jsoncons::ubjson::ubjson_type::false_type:
388
2.06M
            {
389
2.06M
                visitor.bool_value(false, semantic_tag::none, *this, ec);
390
2.06M
                more_ = !cursor_mode_;
391
2.06M
                break;
392
0
            }
393
2.64M
            case jsoncons::ubjson::ubjson_type::int8_type: 
394
2.64M
            {
395
2.64M
                uint8_t buf[sizeof(int8_t)];
396
2.64M
                if (source_.read(buf, sizeof(int8_t)) != sizeof(int8_t))
397
13
                {
398
13
                    ec = ubjson_errc::unexpected_eof;
399
13
                    more_ = false;
400
13
                    return;
401
13
                }
402
2.64M
                int8_t val = binary::big_to_native<int8_t>(buf, sizeof(buf));
403
2.64M
                visitor.int64_value(val, semantic_tag::none, *this, ec);
404
2.64M
                more_ = !cursor_mode_;
405
2.64M
                break;
406
2.64M
            }
407
2.30M
            case jsoncons::ubjson::ubjson_type::uint8_type: 
408
2.30M
            {
409
2.30M
                uint8_t b;
410
2.30M
                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.30M
                visitor.uint64_value(b, semantic_tag::none, *this, ec);
417
2.30M
                more_ = !cursor_mode_;
418
2.30M
                break;
419
2.30M
            }
420
1.38M
            case jsoncons::ubjson::ubjson_type::int16_type: 
421
1.38M
            {
422
1.38M
                uint8_t buf[sizeof(int16_t)];
423
1.38M
                if (source_.read(buf, sizeof(int16_t)) != sizeof(int16_t))
424
10
                {
425
10
                    ec = ubjson_errc::unexpected_eof;
426
10
                    more_ = false;
427
10
                    return;
428
10
                }
429
1.38M
                int16_t val = binary::big_to_native<int16_t>(buf, sizeof(buf));
430
1.38M
                visitor.int64_value(val, semantic_tag::none, *this, ec);
431
1.38M
                more_ = !cursor_mode_;
432
1.38M
                break;
433
1.38M
            }
434
114k
            case jsoncons::ubjson::ubjson_type::int32_type: 
435
114k
            {
436
114k
                uint8_t buf[sizeof(int32_t)];
437
114k
                if (source_.read(buf, sizeof(int32_t)) != sizeof(int32_t))
438
4
                {
439
4
                    ec = ubjson_errc::unexpected_eof;
440
4
                    more_ = false;
441
4
                    return;
442
4
                }
443
114k
                int32_t val = binary::big_to_native<int32_t>(buf, sizeof(buf));
444
114k
                visitor.int64_value(val, semantic_tag::none, *this, ec);
445
114k
                more_ = !cursor_mode_;
446
114k
                break;
447
114k
            }
448
32.4k
            case jsoncons::ubjson::ubjson_type::int64_type: 
449
32.4k
            {
450
32.4k
                uint8_t buf[sizeof(int64_t)];
451
32.4k
                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.4k
                int64_t val = binary::big_to_native<int64_t>(buf, sizeof(buf));
458
32.4k
                visitor.int64_value(val, semantic_tag::none, *this, ec);
459
32.4k
                more_ = !cursor_mode_;
460
32.4k
                break;
461
32.4k
            }
462
246k
            case jsoncons::ubjson::ubjson_type::float32_type: 
463
246k
            {
464
246k
                uint8_t buf[sizeof(float)];
465
246k
                if (source_.read(buf, sizeof(float)) != sizeof(float))
466
12
                {
467
12
                    ec = ubjson_errc::unexpected_eof;
468
12
                    more_ = false;
469
12
                    return;
470
12
                }
471
246k
                float val = binary::big_to_native<float>(buf, sizeof(buf));
472
246k
                visitor.double_value(val, semantic_tag::none, *this, ec);
473
246k
                more_ = !cursor_mode_;
474
246k
                break;
475
246k
            }
476
1.63k
            case jsoncons::ubjson::ubjson_type::float64_type: 
477
1.63k
            {
478
1.63k
                uint8_t buf[sizeof(double)];
479
1.63k
                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.63k
                double val = binary::big_to_native<double>(buf, sizeof(buf));
486
1.63k
                visitor.double_value(val, semantic_tag::none, *this, ec);
487
1.63k
                more_ = !cursor_mode_;
488
1.63k
                break;
489
1.63k
            }
490
5.08M
            case jsoncons::ubjson::ubjson_type::char_type: 
491
5.08M
            {
492
5.08M
                text_buffer_.clear();
493
5.08M
                if (source_reader<Source>::read(source_,text_buffer_,1) != 1)
494
32
                {
495
32
                    ec = ubjson_errc::unexpected_eof;
496
32
                    more_ = false;
497
32
                    return;
498
32
                }
499
5.08M
                auto result = unicode_traits::validate(text_buffer_.data(),text_buffer_.size());
500
5.08M
                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
5.08M
                visitor.string_value(text_buffer_, semantic_tag::none, *this, ec);
507
5.08M
                more_ = !cursor_mode_;
508
5.08M
                break;
509
5.08M
            }
510
14.3k
            case jsoncons::ubjson::ubjson_type::string_type: 
511
14.3k
            {
512
14.3k
                std::size_t length = get_length(ec);
513
14.3k
                if (JSONCONS_UNLIKELY(ec))
514
1
                {
515
1
                    return;
516
1
                }
517
14.3k
                text_buffer_.clear();
518
14.3k
                if (source_reader<Source>::read(source_,text_buffer_,length) != length)
519
22
                {
520
22
                    ec = ubjson_errc::unexpected_eof;
521
22
                    more_ = false;
522
22
                    return;
523
22
                }
524
14.3k
                auto result = unicode_traits::validate(text_buffer_.data(),text_buffer_.size());
525
14.3k
                if (result.ec != unicode_traits::conv_errc())
526
16
                {
527
16
                    ec = ubjson_errc::invalid_utf8_text_string;
528
16
                    more_ = false;
529
16
                    return;
530
16
                }
531
14.3k
                visitor.string_value(jsoncons::basic_string_view<char>(text_buffer_.data(),text_buffer_.length()), semantic_tag::none, *this, ec);
532
14.3k
                more_ = !cursor_mode_;
533
14.3k
                break;
534
14.3k
            }
535
8.34k
            case jsoncons::ubjson::ubjson_type::high_precision_number_type: 
536
8.34k
            {
537
8.34k
                std::size_t length = get_length(ec);
538
8.34k
                if (JSONCONS_UNLIKELY(ec))
539
1
                {
540
1
                    return;
541
1
                }
542
8.33k
                text_buffer_.clear();
543
8.33k
                if (source_reader<Source>::read(source_,text_buffer_,length) != length)
544
27
                {
545
27
                    ec = ubjson_errc::unexpected_eof;
546
27
                    more_ = false;
547
27
                    return;
548
27
                }
549
8.31k
                if (jsoncons::is_base10(text_buffer_.data(),text_buffer_.length()))
550
185
                {
551
185
                    visitor.string_value(jsoncons::basic_string_view<char>(text_buffer_.data(),text_buffer_.length()), semantic_tag::bigint, *this, ec);
552
185
                    more_ = !cursor_mode_;
553
185
                }
554
8.12k
                else
555
8.12k
                {
556
8.12k
                    visitor.string_value(jsoncons::basic_string_view<char>(text_buffer_.data(),text_buffer_.length()), semantic_tag::bigdec, *this, ec);
557
8.12k
                    more_ = !cursor_mode_;
558
8.12k
                }
559
8.31k
                break;
560
8.33k
            }
561
6.88M
            case jsoncons::ubjson::ubjson_type::start_array_marker: 
562
6.88M
            {
563
6.88M
                begin_array(visitor,ec);
564
6.88M
                break;
565
8.33k
            }
566
4.65M
            case jsoncons::ubjson::ubjson_type::start_object_marker: 
567
4.65M
            {
568
4.65M
                begin_object(visitor, ec);
569
4.65M
                break;
570
8.33k
            }
571
93
            default:
572
93
            {
573
93
                ec = ubjson_errc::unknown_type;
574
93
                break;
575
8.33k
            }
576
53.2M
        }
577
53.2M
        if (JSONCONS_UNLIKELY(ec))
578
231
        {
579
231
            more_ = false;
580
231
        }
581
53.2M
    }
582
583
    void begin_array(json_visitor& visitor, std::error_code& ec)
584
6.88M
    {
585
6.88M
        if (JSONCONS_UNLIKELY(++nesting_depth_ > max_nesting_depth_))
586
2
        {
587
2
            ec = ubjson_errc::max_nesting_depth_exceeded;
588
2
            more_ = false;
589
2
            return;
590
2
        } 
591
592
6.88M
        auto c = source_.peek();
593
6.88M
        if (JSONCONS_UNLIKELY(c.eof))
594
23
        {
595
23
            ec = ubjson_errc::unexpected_eof;
596
23
            more_ = false;
597
23
            return;
598
23
        }
599
6.88M
        if (c.value == jsoncons::ubjson::ubjson_type::type_marker)
600
41.5k
        {
601
41.5k
            source_.ignore(1);
602
41.5k
            uint8_t b;
603
41.5k
            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
41.5k
            c = source_.peek();
610
41.5k
            if (JSONCONS_UNLIKELY(c.eof))
611
9
            {
612
9
                ec = ubjson_errc::unexpected_eof;
613
9
                more_ = false;
614
9
                return;
615
9
            }
616
41.5k
            if (c.value == jsoncons::ubjson::ubjson_type::count_marker)
617
41.5k
            {
618
41.5k
                source_.ignore(1);
619
41.5k
                std::size_t length = get_length(ec);
620
41.5k
                if (JSONCONS_UNLIKELY(ec))
621
8
                {
622
8
                    return;
623
8
                }
624
41.5k
                if (length > max_items_)
625
0
                {
626
0
                    ec = ubjson_errc::max_items_exceeded;
627
0
                    more_ = false;
628
0
                    return;
629
0
                }
630
41.5k
                state_stack_.emplace_back(parse_mode::strongly_typed_array,length,b);
631
41.5k
                visitor.begin_array(length, semantic_tag::none, *this, ec);
632
41.5k
                more_ = !cursor_mode_;
633
41.5k
            }
634
1
            else
635
1
            {
636
1
                ec = ubjson_errc::count_required_after_type;
637
1
                more_ = false;
638
1
                return;
639
1
            }
640
41.5k
        }
641
6.84M
        else if (c.value == jsoncons::ubjson::ubjson_type::count_marker)
642
102k
        {
643
102k
            source_.ignore(1);
644
102k
            std::size_t length = get_length(ec);
645
102k
            if (JSONCONS_UNLIKELY(ec))
646
11
            {
647
11
                return;
648
11
            }
649
102k
            if (length > max_items_)
650
1
            {
651
1
                ec = ubjson_errc::max_items_exceeded;
652
1
                more_ = false;
653
1
                return;
654
1
            }
655
102k
            state_stack_.emplace_back(parse_mode::array,length);
656
102k
            visitor.begin_array(length, semantic_tag::none, *this, ec);
657
102k
            more_ = !cursor_mode_;
658
102k
        }
659
6.74M
        else
660
6.74M
        {
661
6.74M
            state_stack_.emplace_back(parse_mode::indefinite_array,0);
662
6.74M
            visitor.begin_array(semantic_tag::none, *this, ec);
663
6.74M
            more_ = !cursor_mode_;
664
6.74M
        }
665
6.88M
    }
666
667
    void end_array(json_visitor& visitor, std::error_code& ec)
668
6.84M
    {
669
6.84M
        --nesting_depth_;
670
671
6.84M
        visitor.end_array(*this, ec);
672
6.84M
        more_ = !cursor_mode_;
673
6.84M
        if (level() == mark_level_)
674
0
        {
675
0
            more_ = false;
676
0
        }
677
6.84M
        state_stack_.pop_back();
678
6.84M
    }
679
680
    void begin_object(json_visitor& visitor, std::error_code& ec)
681
4.65M
    {
682
4.65M
        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.65M
        auto c = source_.peek();
690
4.65M
        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.65M
        if (c.value == jsoncons::ubjson::ubjson_type::type_marker)
697
86.8k
        {
698
86.8k
            source_.ignore(1);
699
86.8k
            uint8_t b;
700
86.8k
            if (source_.read(&b, 1) == 0)
701
10
            {
702
10
                ec = ubjson_errc::unexpected_eof;
703
10
                more_ = false;
704
10
                return;
705
10
            }
706
86.8k
            c = source_.peek();
707
86.8k
            if (JSONCONS_UNLIKELY(c.eof))
708
7
            {
709
7
                ec = ubjson_errc::unexpected_eof;
710
7
                more_ = false;
711
7
                return;
712
7
            }
713
86.7k
            if (c.value == jsoncons::ubjson::ubjson_type::count_marker)
714
86.7k
            {
715
86.7k
                source_.ignore(1);
716
86.7k
                std::size_t length = get_length(ec);
717
86.7k
                if (JSONCONS_UNLIKELY(ec))
718
8
                {
719
8
                    return;
720
8
                }
721
86.7k
                if (length > max_items_)
722
5
                {
723
5
                    ec = ubjson_errc::max_items_exceeded;
724
5
                    more_ = false;
725
5
                    return;
726
5
                }
727
86.7k
                state_stack_.emplace_back(parse_mode::strongly_typed_map_key,length,b);
728
86.7k
                visitor.begin_object(length, semantic_tag::none, *this, ec);
729
86.7k
                more_ = !cursor_mode_;
730
86.7k
            }
731
1
            else
732
1
            {
733
1
                ec = ubjson_errc::count_required_after_type;
734
1
                more_ = false;
735
1
                return;
736
1
            }
737
86.7k
        }
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.27k
            {
749
6.27k
                source_.ignore(1);
750
6.27k
                std::size_t length = get_length(ec);
751
6.27k
                if (JSONCONS_UNLIKELY(ec))
752
5
                {
753
5
                    return;
754
5
                }
755
6.26k
                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.26k
                state_stack_.emplace_back(parse_mode::map_key,length);
762
6.26k
                visitor.begin_object(length, semantic_tag::none, *this, ec);
763
6.26k
                more_ = !cursor_mode_;
764
6.26k
            }
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.65M
    }
773
774
    void end_object(json_visitor& visitor, std::error_code& ec)
775
4.65M
    {
776
4.65M
        --nesting_depth_;
777
4.65M
        visitor.end_object(*this, ec);
778
4.65M
        more_ = !cursor_mode_;
779
4.65M
        if (level() == mark_level_)
780
0
        {
781
0
            more_ = false;
782
0
        }
783
4.65M
        state_stack_.pop_back();
784
4.65M
    }
785
786
    std::size_t get_length(std::error_code& ec)
787
6.84M
    {
788
6.84M
        std::size_t length = 0;
789
6.84M
        uint8_t type;
790
6.84M
        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.84M
        switch (type)
797
6.84M
        {
798
1.24M
            case jsoncons::ubjson::ubjson_type::int8_type: 
799
1.24M
            {
800
1.24M
                uint8_t buf[sizeof(int8_t)];
801
1.24M
                if (source_.read(buf, sizeof(int8_t)) != sizeof(int8_t))
802
0
                {
803
0
                    ec = ubjson_errc::unexpected_eof;
804
0
                    more_ = false;
805
0
                    return length;
806
0
                }
807
1.24M
                int8_t val = binary::big_to_native<int8_t>(buf, sizeof(buf));
808
1.24M
                if (val >= 0)
809
1.24M
                {
810
1.24M
                    length = val;
811
1.24M
                }
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.24M
                break;
819
1.24M
            }
820
5.58M
            case jsoncons::ubjson::ubjson_type::uint8_type: 
821
5.58M
            {
822
5.58M
                uint8_t b;
823
5.58M
                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.58M
                length = b;
830
5.58M
                break;
831
5.58M
            }
832
14.0k
            case jsoncons::ubjson::ubjson_type::int16_type: 
833
14.0k
            {
834
14.0k
                uint8_t buf[sizeof(int16_t)];
835
14.0k
                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
14.0k
                int16_t val = binary::big_to_native<int16_t>(buf, sizeof(buf));
842
14.0k
                if (val >= 0)
843
14.0k
                {
844
14.0k
                    length = val;
845
14.0k
                }
846
0
                else
847
0
                {
848
0
                    ec = ubjson_errc::length_is_negative;
849
0
                    more_ = false;
850
0
                    return length;
851
0
                }
852
14.0k
                break;
853
14.0k
            }
854
14.0k
            case jsoncons::ubjson::ubjson_type::int32_type: 
855
457
            {
856
457
                uint8_t buf[sizeof(int32_t)];
857
457
                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
457
                int32_t val = binary::big_to_native<int32_t>(buf, sizeof(buf));
864
457
                if (val >= 0)
865
457
                {
866
457
                    length = static_cast<std::size_t>(val);
867
457
                }
868
0
                else
869
0
                {
870
0
                    ec = ubjson_errc::length_is_negative;
871
0
                    more_ = false;
872
0
                    return length;
873
0
                }
874
457
                break;
875
457
            }
876
457
            case jsoncons::ubjson::ubjson_type::int64_type: 
877
246
            {
878
246
                uint8_t buf[sizeof(int64_t)];
879
246
                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
246
                int64_t val = binary::big_to_native<int64_t>(buf, sizeof(buf));
886
246
                if (val >= 0)
887
246
                {
888
246
                    length = (std::size_t)val;
889
246
                    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
246
                }
896
0
                else
897
0
                {
898
0
                    ec = ubjson_errc::length_is_negative;
899
0
                    more_ = false;
900
0
                    return length;
901
0
                }
902
246
                break;
903
246
            }
904
246
            default:
905
46
            {
906
46
                ec = ubjson_errc::length_must_be_integer;
907
46
                more_ = false;
908
46
                return length;
909
246
            }
910
6.84M
        }
911
6.84M
        return length;
912
6.84M
    }
913
914
    void read_key(json_visitor& visitor, std::error_code& ec)
915
6.58M
    {
916
6.58M
        std::size_t length = get_length(ec);
917
6.58M
        if (JSONCONS_UNLIKELY(ec))
918
42
        {
919
42
            ec = ubjson_errc::key_expected;
920
42
            more_ = false;
921
42
            return;
922
42
        }
923
6.58M
        text_buffer_.clear();
924
6.58M
        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.58M
        auto result = unicode_traits::validate(text_buffer_.data(),text_buffer_.size());
932
6.58M
        if (result.ec != unicode_traits::conv_errc())
933
23
        {
934
23
            ec = ubjson_errc::invalid_utf8_text_string;
935
23
            more_ = false;
936
23
            return;
937
23
        }
938
6.58M
        visitor.key(jsoncons::basic_string_view<char>(text_buffer_.data(),text_buffer_.length()), *this, ec);
939
6.58M
        more_ = !cursor_mode_;
940
6.58M
    }
941
};
942
943
} // namespace ubjson
944
} // namespace jsoncons
945
946
#endif