GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: src/zserio/JsonReader.h Lines: 238 242 98.3 %
Date: 2023-12-13 14:51:09 Branches: 243 687 35.4 %

Line Branch Exec Source
1
#ifndef ZSERIO_JSON_READER_H_INC
2
#define ZSERIO_JSON_READER_H_INC
3
4
#include <istream>
5
#include <limits>
6
7
#include "zserio/AllocatorHolder.h"
8
#include "zserio/JsonParser.h"
9
#include "zserio/OptionalHolder.h"
10
#include "zserio/StringView.h"
11
#include "zserio/ZserioTreeCreator.h"
12
#include "zserio/UniquePtr.h"
13
#include "zserio/SizeConvertUtil.h"
14
15
namespace zserio
16
{
17
18
namespace detail
19
{
20
21
// adapter for values which are encoded as a JSON object
22
template <typename ALLOC>
23

62
class IObjectValueAdapter : public BasicJsonParser<ALLOC>::IObserver
24
{
25
public:
26
    virtual AnyHolder<ALLOC> get() const = 0;
27
};
28
29
template <typename ALLOC>
30
class BitBufferAdapter : public IObjectValueAdapter<ALLOC>, public AllocatorHolder<ALLOC>
31
{
32
public:
33
    using AllocatorHolder<ALLOC>::get_allocator;
34
35
19
    explicit BitBufferAdapter(const ALLOC& allocator) :
36
19
            AllocatorHolder<ALLOC>(allocator), m_state(VISIT_KEY)
37
19
    {}
38

19
    ~BitBufferAdapter() override = default;
39
40
    BitBufferAdapter(BitBufferAdapter& other) = delete;
41
    BitBufferAdapter& operator=(BitBufferAdapter& other) = delete;
42
43
    BitBufferAdapter(BitBufferAdapter&& other) :
44
            m_state(other.m_state), m_buffer(std::move(other.m_buffer)), m_bitSize(other.m_bitSize)
45
    {}
46
47
    BitBufferAdapter& operator=(BitBufferAdapter&& other)
48
    {
49
        m_state = other.m_state;
50
        m_buffer = std::move(other.m_buffer);
51
        m_bitSize = other.m_bitSize;
52
53
        return *this;
54
    }
55
56
    AnyHolder<ALLOC> get() const override;
57
58
    void beginObject() override;
59
    void endObject() override;
60
    void beginArray() override;
61
    void endArray() override;
62
    void visitKey(StringView key) override;
63
    void visitValue(std::nullptr_t) override;
64
    void visitValue(bool boolValue) override;
65
    void visitValue(int64_t intValue) override;
66
    void visitValue(uint64_t uintValue) override;
67
    void visitValue(double doubleValue) override;
68
    void visitValue(StringView stringValue) override;
69
70
private:
71
    enum State : uint8_t
72
    {
73
        VISIT_KEY,
74
        BEGIN_ARRAY_BUFFER,
75
        VISIT_VALUE_BUFFER,
76
        VISIT_VALUE_BITSIZE
77
    };
78
79
    State m_state;
80
    InplaceOptionalHolder<vector<uint8_t, ALLOC>> m_buffer;
81
    InplaceOptionalHolder<size_t> m_bitSize;
82
};
83
84
template <typename ALLOC>
85
class BytesAdapter : public IObjectValueAdapter<ALLOC>, public AllocatorHolder<ALLOC>
86
{
87
public:
88
    using AllocatorHolder<ALLOC>::get_allocator;
89
90
12
    explicit BytesAdapter(const ALLOC& allocator) :
91
12
            AllocatorHolder<ALLOC>(allocator), m_state(VISIT_KEY)
92
12
    {}
93

12
    ~BytesAdapter() override = default;
94
95
    BytesAdapter(BytesAdapter& other) = delete;
96
    BytesAdapter& operator=(BytesAdapter& other) = delete;
97
98
    BytesAdapter(BytesAdapter&& other) :
99
            m_state(other.m_state), m_buffer(std::move(other.m_buffer))
100
    {}
101
102
    BytesAdapter& operator=(BytesAdapter&& other)
103
    {
104
        m_state = other.m_state;
105
        m_buffer = std::move(other.m_buffer);
106
107
        return *this;
108
    }
109
110
    AnyHolder<ALLOC> get() const override;
111
112
    void beginObject() override;
113
    void endObject() override;
114
    void beginArray() override;
115
    void endArray() override;
116
    void visitKey(StringView key) override;
117
    void visitValue(std::nullptr_t) override;
118
    void visitValue(bool boolValue) override;
119
    void visitValue(int64_t intValue) override;
120
    void visitValue(uint64_t uintValue) override;
121
    void visitValue(double doubleValue) override;
122
    void visitValue(StringView stringValue) override;
123
124
private:
125
    enum State : uint8_t
126
    {
127
        VISIT_KEY,
128
        BEGIN_ARRAY_BUFFER,
129
        VISIT_VALUE_BUFFER,
130
    };
131
132
    State m_state;
133
    InplaceOptionalHolder<vector<uint8_t, ALLOC>> m_buffer;
134
};
135
136
template <typename ALLOC>
137

75
class CreatorAdapter : public BasicJsonParser<ALLOC>::IObserver, public AllocatorHolder<ALLOC>
138
{
139
public:
140
    using AllocatorHolder<ALLOC>::get_allocator;
141
142
75
    explicit CreatorAdapter(const ALLOC& allocator) :
143
75
            AllocatorHolder<ALLOC>(allocator)
144
75
    {}
145
146
    void setType(const IBasicTypeInfo<ALLOC>& typeInfo);
147
    IBasicReflectablePtr<ALLOC> get() const;
148
149
    void beginObject() override;
150
    void endObject() override;
151
    void beginArray() override;
152
    void endArray() override;
153
    void visitKey(StringView key) override;
154
    void visitValue(std::nullptr_t) override;
155
    void visitValue(bool boolValue) override;
156
    void visitValue(int64_t intValue) override;
157
    void visitValue(uint64_t uintValue) override;
158
    void visitValue(double doubleValue) override;
159
    void visitValue(StringView stringValue) override;
160
161
private:
162
    template <typename T>
163
    void setValue(T&& value);
164
165
    template <typename T>
166
    void convertValue(T&& value) const;
167
168
    InplaceOptionalHolder<BasicZserioTreeCreator<ALLOC>> m_creator;
169
    vector<string<ALLOC>, ALLOC> m_keyStack;
170
    IBasicReflectablePtr<ALLOC> m_object;
171
    unique_ptr<IObjectValueAdapter<ALLOC>, RebindAlloc<ALLOC, IObjectValueAdapter<ALLOC>>> m_objectValueAdapter;
172
};
173
174
} // namespace detail
175
176
/**
177
 * Reads zserio object tree defined by a type info from a text stream.
178
 */
179
template <typename ALLOC = std::allocator<uint8_t>>
180
74
class BasicJsonReader
181
{
182
public:
183
    /**
184
     * Constructor.
185
     *
186
     * \param in Text stream to read.
187
     * \param allocator Allocator to use.
188
     */
189
74
    explicit BasicJsonReader(std::istream& in, const ALLOC& allocator = ALLOC()) :
190

74
            m_creatorAdapter(allocator), m_parser(in, m_creatorAdapter, allocator)
191
74
    {}
192
193
    /**
194
     * Reads a zserio object tree defined by the given type info from the text stream.
195
     *
196
     * \param typeInfo Type info defining the expected zserio object tree.
197
     *
198
     * \return Zserio object tree initialized using the JSON data.
199
     * \throw CppRuntimeException When the JSON doesn't contain expected zserio object tree.
200
     */
201
75
    IBasicReflectablePtr<ALLOC> read(const IBasicTypeInfo<ALLOC>& typeInfo)
202
    {
203
75
        m_creatorAdapter.setType(typeInfo);
204
205
        try
206
        {
207

75
            m_parser.parse();
208
        }
209
4
        catch (const JsonParserException&)
210
        {
211
2
            throw;
212
        }
213
56
        catch (const CppRuntimeException& e)
214
        {
215


84
            throw CppRuntimeException(e.what()) <<
216






84
                    " (JsonParser:" << m_parser.getLine() << ":" << m_parser.getColumn() << ")";
217
        }
218
219

45
        return m_creatorAdapter.get();
220
    }
221
222
private:
223
    detail::CreatorAdapter<ALLOC> m_creatorAdapter;
224
    BasicJsonParser<ALLOC> m_parser;
225
};
226
227
/** Typedef to Json Reader provided for convenience - using default std::allocator<uint8_t>. */
228
using JsonReader = BasicJsonReader<>;
229
230
namespace detail
231
{
232
233
template <typename ALLOC>
234
12
AnyHolder<ALLOC> BitBufferAdapter<ALLOC>::get() const
235
{
236




12
    if (m_state != VISIT_KEY || !m_buffer.hasValue() || !m_bitSize.hasValue())
237

3
        throw CppRuntimeException("JsonReader: Unexpected end in BitBuffer!");
238
239





9
    return AnyHolder<ALLOC>(BasicBitBuffer<ALLOC>(m_buffer.value(), m_bitSize.value()), get_allocator());
240
}
241
242
template <typename ALLOC>
243
2
void BitBufferAdapter<ALLOC>::beginObject()
244
{
245

2
    throw CppRuntimeException("JsonReader: Unexpected beginObject in BitBuffer!");
246
}
247
248
template <typename ALLOC>
249
1
void BitBufferAdapter<ALLOC>::endObject()
250
{
251

1
    throw CppRuntimeException("JsonReader: Unexpected endObject in BitBuffer!");
252
}
253
254
template <typename ALLOC>
255
19
void BitBufferAdapter<ALLOC>::beginArray()
256
{
257

19
    if (m_state == BEGIN_ARRAY_BUFFER)
258
18
        m_state = VISIT_VALUE_BUFFER;
259
    else
260

1
        throw CppRuntimeException("JsonReader: Unexpected beginArray in BitBuffer!");
261
18
}
262
263
template <typename ALLOC>
264
17
void BitBufferAdapter<ALLOC>::endArray()
265
{
266

17
    if (m_state == VISIT_VALUE_BUFFER)
267
16
        m_state = VISIT_KEY;
268
    else
269

1
        throw CppRuntimeException("JsonReader: Unexpected endArray in BitBuffer!");
270
16
}
271
272
template <typename ALLOC>
273
36
void BitBufferAdapter<ALLOC>::visitKey(StringView key)
274
{
275

36
    if (m_state == VISIT_KEY)
276
    {
277

35
        if (key == "buffer"_sv)
278
19
            m_state = BEGIN_ARRAY_BUFFER;
279

16
        else if (key == "bitSize"_sv)
280
15
            m_state = VISIT_VALUE_BITSIZE;
281
        else
282



1
            throw CppRuntimeException("JsonReader: Unexpected key '") << key << "' in BitBuffer!";
283
    }
284
    else
285
    {
286

1
        throw CppRuntimeException("JsonReader: Unexpected visitKey in BitBuffer!");
287
    }
288
34
}
289
290
template <typename ALLOC>
291
2
void BitBufferAdapter<ALLOC>::visitValue(std::nullptr_t)
292
{
293

2
    throw CppRuntimeException("JsonReader: Unexpected visitValue (null) in BitBuffer!");
294
}
295
296
template <typename ALLOC>
297
2
void BitBufferAdapter<ALLOC>::visitValue(bool)
298
{
299

2
    throw CppRuntimeException("JsonReader: Unexpected visitValue (bool) in BitBuffer!");
300
}
301
302
template <typename ALLOC>
303
2
void BitBufferAdapter<ALLOC>::visitValue(int64_t)
304
{
305

2
    throw CppRuntimeException("JsonReader: Unexpected visitValue (int) in BitBuffer!");
306
}
307
308
template <typename ALLOC>
309
39
void BitBufferAdapter<ALLOC>::visitValue(uint64_t uintValue)
310
{
311

39
    if (m_state == VISIT_VALUE_BUFFER)
312
    {
313

28
        if (uintValue > static_cast<uint64_t>(std::numeric_limits<uint8_t>::max()))
314
        {
315


2
            throw CppRuntimeException("JsonReader: Cannot create byte for Bit Buffer from value '") <<
316

2
                    uintValue << "'!";
317
        }
318
319

27
        if (!m_buffer.hasValue())
320


16
            m_buffer = vector<uint8_t, ALLOC>(1, static_cast<uint8_t>(uintValue), get_allocator());
321
        else
322


11
            m_buffer->push_back(static_cast<uint8_t>(uintValue));
323
    }
324

11
    else if (m_state == VISIT_VALUE_BITSIZE)
325
    {
326

9
        m_bitSize = convertUInt64ToSize(uintValue);
327
9
        m_state = VISIT_KEY;
328
    }
329
    else
330
    {
331

2
        throw CppRuntimeException("JsonReader: Unexpected visitValue in BitBuffer!");
332
    }
333
36
}
334
335
template <typename ALLOC>
336
2
void BitBufferAdapter<ALLOC>::visitValue(double)
337
{
338

2
    throw CppRuntimeException("JsonReader: Unexpected visitValue (double) in BitBuffer!");
339
}
340
341
template <typename ALLOC>
342
2
void BitBufferAdapter<ALLOC>::visitValue(StringView)
343
{
344

2
    throw CppRuntimeException("JsonReader: Unexpected visitValue (string) in BitBuffer!");
345
}
346
347
template <typename ALLOC>
348
10
AnyHolder<ALLOC> BytesAdapter<ALLOC>::get() const
349
{
350



10
    if (m_state != VISIT_KEY || !m_buffer.hasValue())
351

2
        throw CppRuntimeException("JsonReader: Unexpected end in bytes!");
352
353


8
    return AnyHolder<ALLOC>(m_buffer.value(), get_allocator());
354
}
355
356
template <typename ALLOC>
357
2
void BytesAdapter<ALLOC>::beginObject()
358
{
359

2
    throw CppRuntimeException("JsonReader: Unexpected beginObject in bytes!");
360
}
361
362
template <typename ALLOC>
363
1
void BytesAdapter<ALLOC>::endObject()
364
{
365

1
    throw CppRuntimeException("JsonReader: Unexpected endObject in bytes!");
366
}
367
368
template <typename ALLOC>
369
11
void BytesAdapter<ALLOC>::beginArray()
370
{
371

11
    if (m_state == BEGIN_ARRAY_BUFFER)
372
10
        m_state = VISIT_VALUE_BUFFER;
373
    else
374

1
        throw CppRuntimeException("JsonReader: Unexpected beginArray in bytes!");
375
10
}
376
377
template <typename ALLOC>
378
9
void BytesAdapter<ALLOC>::endArray()
379
{
380

9
    if (m_state == VISIT_VALUE_BUFFER)
381
8
        m_state = VISIT_KEY;
382
    else
383

1
        throw CppRuntimeException("JsonReader: Unexpected endArray in bytes!");
384
8
}
385
386
template <typename ALLOC>
387
14
void BytesAdapter<ALLOC>::visitKey(StringView key)
388
{
389

14
    if (m_state == VISIT_KEY)
390
    {
391

13
        if (key == "buffer"_sv)
392
12
            m_state = BEGIN_ARRAY_BUFFER;
393
        else
394



1
            throw CppRuntimeException("JsonReader: Unexpected key '") << key << "' in bytes!";
395
    }
396
    else
397
    {
398

1
        throw CppRuntimeException("JsonReader: Unexpected visitKey in bytes!");
399
    }
400
12
}
401
402
template <typename ALLOC>
403
1
void BytesAdapter<ALLOC>::visitValue(std::nullptr_t)
404
{
405

1
    throw CppRuntimeException("JsonReader: Unexpected visitValue (null) in bytes!");
406
}
407
408
template <typename ALLOC>
409
1
void BytesAdapter<ALLOC>::visitValue(bool)
410
{
411

1
    throw CppRuntimeException("JsonReader: Unexpected visitValue (bool) in bytes!");
412
}
413
414
template <typename ALLOC>
415
2
void BytesAdapter<ALLOC>::visitValue(int64_t)
416
{
417

2
    throw CppRuntimeException("JsonReader: Unexpected visitValue (int) in bytes!");
418
}
419
420
template <typename ALLOC>
421
17
void BytesAdapter<ALLOC>::visitValue(uint64_t uintValue)
422
{
423

17
    if (m_state == VISIT_VALUE_BUFFER)
424
    {
425

15
        if (uintValue > static_cast<uint64_t>(std::numeric_limits<uint8_t>::max()))
426
        {
427


2
            throw CppRuntimeException("JsonReader: Cannot create byte for bytes from value '") <<
428

2
                    uintValue << "'!";
429
        }
430
431

14
        if (!m_buffer.hasValue())
432


8
            m_buffer = vector<uint8_t, ALLOC>(1, static_cast<uint8_t>(uintValue), get_allocator());
433
        else
434


6
            m_buffer->push_back(static_cast<uint8_t>(uintValue));
435
    }
436
    else
437
    {
438

2
        throw CppRuntimeException("JsonReader: Unexpected visitValue in bytes!");
439
    }
440
14
}
441
442
template <typename ALLOC>
443
1
void BytesAdapter<ALLOC>::visitValue(double)
444
{
445

1
    throw CppRuntimeException("JsonReader: Unexpected visitValue (double) in bytes!");
446
}
447
448
template <typename ALLOC>
449
1
void BytesAdapter<ALLOC>::visitValue(StringView)
450
{
451

1
    throw CppRuntimeException("JsonReader: Unexpected visitValue (string) in bytes!");
452
}
453
454
template <typename ALLOC>
455
75
void CreatorAdapter<ALLOC>::setType(const IBasicTypeInfo<ALLOC>& typeInfo)
456
{
457

75
    m_creator = BasicZserioTreeCreator<ALLOC>(typeInfo, get_allocator());
458
75
}
459
460
template <typename ALLOC>
461
46
IBasicReflectablePtr<ALLOC> CreatorAdapter<ALLOC>::get() const
462
{
463

46
    if (!m_object)
464

1
        throw CppRuntimeException("JsonReader: Zserio tree not created!");
465
466
45
    return m_object;
467
}
468
469
template <typename ALLOC>
470
140
void CreatorAdapter<ALLOC>::beginObject()
471
{
472

140
    if (m_objectValueAdapter)
473
    {
474
2
        m_objectValueAdapter->beginObject();
475
    }
476
    else
477
    {
478

138
        if (!m_creator)
479

1
            throw CppRuntimeException("JsonReader: Adapter not initialized!");
480
481

137
        if (m_keyStack.empty())
482
        {
483
73
            m_creator->beginRoot();
484
        }
485
        else
486
        {
487

64
            if (!m_keyStack.back().empty())
488
            {
489
58
                const CppType cppType = m_creator->getFieldType(m_keyStack.back()).getCppType();
490

58
                if (cppType == CppType::BIT_BUFFER)
491
                {
492


16
                    m_objectValueAdapter = allocate_unique<BitBufferAdapter<ALLOC>>(get_allocator(),
493
                            get_allocator());
494
                }
495

42
                else if (cppType == CppType::BYTES)
496
                {
497


9
                    m_objectValueAdapter = allocate_unique<BytesAdapter<ALLOC>>(get_allocator(),
498
                            get_allocator());
499
                }
500
                else
501
                {
502
33
                    m_creator->beginCompound(m_keyStack.back());
503
                }
504
            }
505
            else
506
            {
507
6
                const CppType cppType = m_creator->getElementType().getCppType();
508

6
                if (cppType == CppType::BIT_BUFFER)
509
                {
510


2
                    m_objectValueAdapter = allocate_unique<BitBufferAdapter<ALLOC>>(get_allocator(),
511
                            get_allocator());
512
                }
513

4
                else if (cppType == CppType::BYTES)
514
                {
515


2
                    m_objectValueAdapter = allocate_unique<BytesAdapter<ALLOC>>(get_allocator(),
516
                            get_allocator());
517
                }
518
                else
519
                {
520
2
                    m_creator->beginCompoundElement();
521
                }
522
            }
523
        }
524
    }
525
137
}
526
527
template <typename ALLOC>
528
76
void CreatorAdapter<ALLOC>::endObject()
529
{
530

76
    if (m_objectValueAdapter)
531
    {
532

18
        setValue(m_objectValueAdapter->get());
533
17
        m_objectValueAdapter.reset();
534
    }
535
    else
536
    {
537

58
        if (!m_creator)
538

1
            throw CppRuntimeException("JsonReader: Adapter not initialized!");
539
540

57
        if (m_keyStack.empty())
541
        {
542
45
            m_object = m_creator->endRoot();
543
45
            m_creator.reset();
544
        }
545
        else
546
        {
547

12
            if (!m_keyStack.back().empty())
548
            {
549
10
                m_creator->endCompound();
550
10
                m_keyStack.pop_back();
551
            }
552
            else
553
            {
554
2
                m_creator->endCompoundElement();
555
            }
556
        }
557
    }
558
74
}
559
560
template <typename ALLOC>
561
38
void CreatorAdapter<ALLOC>::beginArray()
562
{
563

38
    if (m_objectValueAdapter)
564
    {
565
28
        m_objectValueAdapter->beginArray();
566
    }
567
    else
568
    {
569

10
        if (!m_creator)
570

1
            throw CppRuntimeException("JsonReader: Adapter not initialized!");
571
572

9
        if (m_keyStack.empty())
573

1
            throw CppRuntimeException("JsonReader: ZserioTreeCreator expects json object!");
574
575
8
        m_creator->beginArray(m_keyStack.back());
576
577


8
        m_keyStack.push_back("");
578
    }
579
36
}
580
581
template <typename ALLOC>
582
33
void CreatorAdapter<ALLOC>::endArray()
583
{
584

33
    if (m_objectValueAdapter)
585
    {
586
24
        m_objectValueAdapter->endArray();
587
    }
588
    else
589
    {
590

9
        if (!m_creator)
591

1
            throw CppRuntimeException("JsonReader: Adapter not initialized!");
592
593
8
        m_creator->endArray();
594
595
8
        m_keyStack.pop_back(); // finish array
596
8
        m_keyStack.pop_back(); // finish field
597
    }
598
32
}
599
600
template <typename ALLOC>
601
210
void CreatorAdapter<ALLOC>::visitKey(StringView key)
602
{
603

210
    if (m_objectValueAdapter)
604
    {
605
44
        m_objectValueAdapter->visitKey(key);
606
    }
607
    else
608
    {
609

166
        if (!m_creator)
610

1
            throw CppRuntimeException("JsonReader: Adapter not initialized!");
611
612


165
        m_keyStack.push_back(toString(key, get_allocator()));
613
    }
614
209
}
615
616
template <typename ALLOC>
617
3
void CreatorAdapter<ALLOC>::visitValue(std::nullptr_t nullValue)
618
{
619

3
    if (m_objectValueAdapter)
620
    {
621
1
        m_objectValueAdapter->visitValue(nullValue);
622
    }
623
    else
624
    {
625

2
        if (!m_creator)
626

1
            throw CppRuntimeException("JsonReader: Adapter not initialized!");
627
628
1
        setValue(nullValue);
629
    }
630
1
}
631
632
template <typename ALLOC>
633
3
void CreatorAdapter<ALLOC>::visitValue(bool boolValue)
634
{
635

3
    if (m_objectValueAdapter)
636
    {
637
1
        m_objectValueAdapter->visitValue(boolValue);
638
    }
639
    else
640
    {
641

2
        if (!m_creator)
642

1
            throw CppRuntimeException("JsonReader: Adapter not initialized!");
643
644
1
        setValue(boolValue);
645
    }
646
1
}
647
648
template <typename ALLOC>
649
4
void CreatorAdapter<ALLOC>::visitValue(int64_t intValue)
650
{
651

4
    if (m_objectValueAdapter)
652
    {
653
2
        m_objectValueAdapter->visitValue(intValue);
654
    }
655
    else
656
    {
657

2
        if (!m_creator)
658

1
            throw CppRuntimeException("JsonReader: Adapter not initialized!");
659
660
1
        setValue(intValue);
661
    }
662
1
}
663
664
template <typename ALLOC>
665
84
void CreatorAdapter<ALLOC>::visitValue(uint64_t uintValue)
666
{
667

84
    if (m_objectValueAdapter)
668
    {
669
52
        m_objectValueAdapter->visitValue(uintValue);
670
    }
671
    else
672
    {
673

32
        if (!m_creator)
674

1
            throw CppRuntimeException("JsonReader: Adapter not initialized!");
675
676
31
        setValue(uintValue);
677
    }
678
79
}
679
680
template <typename ALLOC>
681
3
void CreatorAdapter<ALLOC>::visitValue(double doubleValue)
682
{
683

3
    if (m_objectValueAdapter)
684
    {
685
1
        m_objectValueAdapter->visitValue(doubleValue);
686
    }
687
    else
688
    {
689

2
        if (!m_creator)
690

1
            throw CppRuntimeException("JsonReader: Adapter not initialized!");
691
692
1
        setValue(doubleValue);
693
    }
694
}
695
696
template <typename ALLOC>
697
74
void CreatorAdapter<ALLOC>::visitValue(StringView stringValue)
698
{
699

74
    if (m_objectValueAdapter)
700
    {
701
1
        m_objectValueAdapter->visitValue(stringValue);
702
    }
703
    else
704
    {
705

73
        if (!m_creator)
706

1
            throw CppRuntimeException("JsonReader: Adapter not initialized!");
707
708
72
        setValue(stringValue);
709
    }
710
59
}
711
712
template <typename ALLOC>
713
template <typename T>
714
124
void CreatorAdapter<ALLOC>::setValue(T&& value)
715
{
716







124
    if (m_keyStack.empty())
717







1
        throw CppRuntimeException("JsonReader: ZserioTreeCreator expects json object!");
718
719







123
    if (!m_keyStack.back().empty())
720
    {
721
111
        m_creator->setValue(m_keyStack.back(), std::forward<T>(value));
722
96
        m_keyStack.pop_back();
723
    }
724
    else
725
    {
726
12
        m_creator->addValueElement(std::forward<T>(value));
727
    }
728
108
}
729
730
} // namespace detail
731
732
} // namespace zserio
733
734
#endif // ZSERIO_JSON_READER_H_INC