Zserio C++17 runtime library 1.3.0
Built for Zserio 2.20.0
Loading...
Searching...
No Matches
JsonReader.h
Go to the documentation of this file.
1#ifndef ZSERIO_JSON_READER_H_INC
2#define ZSERIO_JSON_READER_H_INC
3
4#include <istream>
5#include <limits>
6#include <memory>
7#include <string_view>
8
10#include "zserio/JsonParser.h"
11#include "zserio/Optional.h"
13#include "zserio/UniquePtr.h"
15
16namespace zserio
17{
18
19namespace detail
20{
21
22// adapter for values which are encoded as a JSON object
23template <typename ALLOC>
24class IObjectValueAdapter : public BasicJsonParser<ALLOC>::IObserver
25{
26public:
27 virtual BasicAny<ALLOC> get() const = 0;
28};
29
30template <typename ALLOC>
31class BitBufferAdapter : public IObjectValueAdapter<ALLOC>, public AllocatorHolder<ALLOC>
32{
33public:
35
36 BitBufferAdapter() :
37 m_state(VISIT_KEY)
38 {}
39 explicit BitBufferAdapter(const ALLOC& allocator) :
40 AllocatorHolder<ALLOC>(allocator),
41 m_state(VISIT_KEY)
42 {}
43 ~BitBufferAdapter() override = default;
44
45 BitBufferAdapter(BitBufferAdapter& other) = delete;
46 BitBufferAdapter& operator=(BitBufferAdapter& other) = delete;
47
48 BitBufferAdapter(BitBufferAdapter&& other) :
49 m_state(other.m_state),
50 m_buffer(std::move(other.m_buffer)),
51 m_bitSize(other.m_bitSize)
52 {}
53
54 BitBufferAdapter& operator=(BitBufferAdapter&& other)
55 {
56 m_state = other.m_state;
57 m_buffer = std::move(other.m_buffer);
58 m_bitSize = other.m_bitSize;
59
60 return *this;
61 }
62
63 BasicAny<ALLOC> get() const override;
64
65 void beginObject() override;
66 void endObject() override;
67 void beginArray() override;
68 void endArray() override;
69 void visitKey(std::string_view key) override;
70 void visitValue(std::nullptr_t) override;
71 void visitValue(bool boolValue) override;
72 void visitValue(int64_t intValue) override;
73 void visitValue(uint64_t uintValue) override;
74 void visitValue(double doubleValue) override;
75 void visitValue(std::string_view stringValue) override;
76
77private:
78 enum State : uint8_t
79 {
80 VISIT_KEY,
81 BEGIN_ARRAY_BUFFER,
82 VISIT_VALUE_BUFFER,
83 VISIT_VALUE_BITSIZE
84 };
85
86 State m_state;
87 Optional<Vector<uint8_t, ALLOC>> m_buffer;
88 Optional<size_t> m_bitSize;
89};
90
91template <typename ALLOC>
92class BytesAdapter : public IObjectValueAdapter<ALLOC>, public AllocatorHolder<ALLOC>
93{
94public:
96
97 BytesAdapter() :
98 m_state(VISIT_KEY)
99 {}
100 explicit BytesAdapter(const ALLOC& allocator) :
101 AllocatorHolder<ALLOC>(allocator),
102 m_state(VISIT_KEY)
103 {}
104 ~BytesAdapter() override = default;
105
106 BytesAdapter(BytesAdapter& other) = delete;
107 BytesAdapter& operator=(BytesAdapter& other) = delete;
108
109 BytesAdapter(BytesAdapter&& other) :
110 m_state(other.m_state),
111 m_buffer(std::move(other.m_buffer))
112 {}
113
114 BytesAdapter& operator=(BytesAdapter&& other)
115 {
116 m_state = other.m_state;
117 m_buffer = std::move(other.m_buffer);
118
119 return *this;
120 }
121
122 BasicAny<ALLOC> get() const override;
123
124 void beginObject() override;
125 void endObject() override;
126 void beginArray() override;
127 void endArray() override;
128 void visitKey(std::string_view key) override;
129 void visitValue(std::nullptr_t) override;
130 void visitValue(bool boolValue) override;
131 void visitValue(int64_t intValue) override;
132 void visitValue(uint64_t uintValue) override;
133 void visitValue(double doubleValue) override;
134 void visitValue(std::string_view stringValue) override;
135
136private:
137 enum State : uint8_t
138 {
139 VISIT_KEY,
140 BEGIN_ARRAY_BUFFER,
141 VISIT_VALUE_BUFFER,
142 };
143
144 State m_state;
145 Optional<Vector<uint8_t, ALLOC>> m_buffer;
146};
147
148template <typename ALLOC>
149class CreatorAdapter : public BasicJsonParser<ALLOC>::IObserver, public AllocatorHolder<ALLOC>
150{
151public:
153
154 explicit CreatorAdapter(const ALLOC& allocator) :
155 AllocatorHolder<ALLOC>(allocator)
156 {}
157
158 void setType(const IBasicTypeInfo<ALLOC>& typeInfo);
159 IBasicReflectableDataPtr<ALLOC> get() const;
160
161 void beginObject() override;
162 void endObject() override;
163 void beginArray() override;
164 void endArray() override;
165 void visitKey(std::string_view key) override;
166 void visitValue(std::nullptr_t) override;
167 void visitValue(bool boolValue) override;
168 void visitValue(int64_t intValue) override;
169 void visitValue(uint64_t uintValue) override;
170 void visitValue(double doubleValue) override;
171 void visitValue(std::string_view stringValue) override;
172
173private:
174 template <typename T>
175 void setValue(T&& value);
176
177 template <typename T>
178 void convertValue(T&& value) const;
179
180 Optional<BasicZserioTreeCreator<ALLOC>> m_creator;
181 using StringType = BasicString<RebindAlloc<ALLOC, char>>;
182 Vector<StringType, RebindAlloc<ALLOC, StringType>> m_keyStack;
183 IBasicReflectableDataPtr<ALLOC> m_object;
184 std::shared_ptr<IObjectValueAdapter<ALLOC>> m_objectValueAdapter;
185};
186
187} // namespace detail
188
189using namespace std::literals::string_view_literals;
190
194template <typename ALLOC = std::allocator<uint8_t>>
196{
197public:
204 explicit BasicJsonReader(std::istream& in, const ALLOC& allocator = ALLOC()) :
205 m_creatorAdapter(allocator),
206 m_parser(in, m_creatorAdapter, allocator)
207 {}
208
218 {
219 m_creatorAdapter.setType(typeInfo);
220
221 try
222 {
223 m_parser.parse();
224 }
225 catch (const JsonParserException&)
226 {
227 throw;
228 }
229 catch (const CppRuntimeException& e)
230 {
231 throw CppRuntimeException(e.what())
232 << " (JsonParser:" << m_parser.getLine() << ":" << m_parser.getColumn() << ")";
233 }
234
235 return m_creatorAdapter.get();
236 }
237
238private:
239 detail::CreatorAdapter<ALLOC> m_creatorAdapter;
240 BasicJsonParser<ALLOC> m_parser;
241};
242
245
246namespace detail
247{
248
249template <typename ALLOC>
250BasicAny<ALLOC> BitBufferAdapter<ALLOC>::get() const
251{
252 if (m_state != VISIT_KEY || !m_buffer.has_value() || !m_bitSize.has_value())
253 {
254 throw CppRuntimeException("JsonReader: Unexpected end in BitBuffer!");
255 }
256
257 return BasicAny<ALLOC>(BasicBitBuffer<ALLOC>(m_buffer.value(), m_bitSize.value()), get_allocator());
258}
259
260template <typename ALLOC>
261void BitBufferAdapter<ALLOC>::beginObject()
262{
263 throw CppRuntimeException("JsonReader: Unexpected beginObject in BitBuffer!");
264}
265
266template <typename ALLOC>
267void BitBufferAdapter<ALLOC>::endObject()
268{
269 throw CppRuntimeException("JsonReader: Unexpected endObject in BitBuffer!");
270}
271
272template <typename ALLOC>
273void BitBufferAdapter<ALLOC>::beginArray()
274{
275 if (m_state == BEGIN_ARRAY_BUFFER)
276 {
277 m_state = VISIT_VALUE_BUFFER;
278 m_buffer = Vector<uint8_t, ALLOC>(get_allocator());
279 }
280 else
281 {
282 throw CppRuntimeException("JsonReader: Unexpected beginArray in BitBuffer!");
283 }
284}
285
286template <typename ALLOC>
287void BitBufferAdapter<ALLOC>::endArray()
288{
289 if (m_state == VISIT_VALUE_BUFFER)
290 {
291 m_state = VISIT_KEY;
292 }
293 else
294 {
295 throw CppRuntimeException("JsonReader: Unexpected endArray in BitBuffer!");
296 }
297}
298
299template <typename ALLOC>
300void BitBufferAdapter<ALLOC>::visitKey(std::string_view key)
301{
302 if (m_state == VISIT_KEY)
303 {
304 if (key == "buffer"sv)
305 {
306 m_state = BEGIN_ARRAY_BUFFER;
307 }
308 else if (key == "bitSize"sv)
309 {
310 m_state = VISIT_VALUE_BITSIZE;
311 }
312 else
313 {
314 throw CppRuntimeException("JsonReader: Unexpected key '") << key << "' in BitBuffer!";
315 }
316 }
317 else
318 {
319 throw CppRuntimeException("JsonReader: Unexpected visitKey in BitBuffer!");
320 }
321}
322
323template <typename ALLOC>
324void BitBufferAdapter<ALLOC>::visitValue(std::nullptr_t)
325{
326 throw CppRuntimeException("JsonReader: Unexpected visitValue (null) in BitBuffer!");
327}
328
329template <typename ALLOC>
330void BitBufferAdapter<ALLOC>::visitValue(bool)
331{
332 throw CppRuntimeException("JsonReader: Unexpected visitValue (bool) in BitBuffer!");
333}
334
335template <typename ALLOC>
336void BitBufferAdapter<ALLOC>::visitValue(int64_t)
337{
338 throw CppRuntimeException("JsonReader: Unexpected visitValue (int) in BitBuffer!");
339}
340
341template <typename ALLOC>
342void BitBufferAdapter<ALLOC>::visitValue(uint64_t uintValue)
343{
344 if (m_state == VISIT_VALUE_BUFFER)
345 {
346 if (uintValue > static_cast<uint64_t>(std::numeric_limits<uint8_t>::max()))
347 {
348 throw CppRuntimeException("JsonReader: Cannot create byte for Bit Buffer from value '")
349 << uintValue << "'!";
350 }
351
352 m_buffer->push_back(static_cast<uint8_t>(uintValue));
353 }
354 else if (m_state == VISIT_VALUE_BITSIZE)
355 {
356 m_bitSize = convertUInt64ToSize(uintValue);
357 m_state = VISIT_KEY;
358 }
359 else
360 {
361 throw CppRuntimeException("JsonReader: Unexpected visitValue in BitBuffer!");
362 }
363}
364
365template <typename ALLOC>
366void BitBufferAdapter<ALLOC>::visitValue(double)
367{
368 throw CppRuntimeException("JsonReader: Unexpected visitValue (double) in BitBuffer!");
369}
370
371template <typename ALLOC>
372void BitBufferAdapter<ALLOC>::visitValue(std::string_view)
373{
374 throw CppRuntimeException("JsonReader: Unexpected visitValue (string) in BitBuffer!");
375}
376
377template <typename ALLOC>
378BasicAny<ALLOC> BytesAdapter<ALLOC>::get() const
379{
380 if (m_state != VISIT_KEY || !m_buffer.has_value())
381 {
382 throw CppRuntimeException("JsonReader: Unexpected end in bytes!");
383 }
384
385 return BasicAny<ALLOC>(m_buffer.value(), get_allocator());
386}
387
388template <typename ALLOC>
389void BytesAdapter<ALLOC>::beginObject()
390{
391 throw CppRuntimeException("JsonReader: Unexpected beginObject in bytes!");
392}
393
394template <typename ALLOC>
395void BytesAdapter<ALLOC>::endObject()
396{
397 throw CppRuntimeException("JsonReader: Unexpected endObject in bytes!");
398}
399
400template <typename ALLOC>
401void BytesAdapter<ALLOC>::beginArray()
402{
403 if (m_state == BEGIN_ARRAY_BUFFER)
404 {
405 m_state = VISIT_VALUE_BUFFER;
406 m_buffer = Vector<uint8_t, ALLOC>(get_allocator());
407 }
408 else
409 {
410 throw CppRuntimeException("JsonReader: Unexpected beginArray in bytes!");
411 }
412}
413
414template <typename ALLOC>
415void BytesAdapter<ALLOC>::endArray()
416{
417 if (m_state == VISIT_VALUE_BUFFER)
418 {
419 m_state = VISIT_KEY;
420 }
421 else
422 {
423 throw CppRuntimeException("JsonReader: Unexpected endArray in bytes!");
424 }
425}
426
427template <typename ALLOC>
428void BytesAdapter<ALLOC>::visitKey(std::string_view key)
429{
430 if (m_state == VISIT_KEY)
431 {
432 if (key == "buffer"sv)
433 {
434 m_state = BEGIN_ARRAY_BUFFER;
435 }
436 else
437 {
438 throw CppRuntimeException("JsonReader: Unexpected key '") << key << "' in bytes!";
439 }
440 }
441 else
442 {
443 throw CppRuntimeException("JsonReader: Unexpected visitKey in bytes!");
444 }
445}
446
447template <typename ALLOC>
448void BytesAdapter<ALLOC>::visitValue(std::nullptr_t)
449{
450 throw CppRuntimeException("JsonReader: Unexpected visitValue (null) in bytes!");
451}
452
453template <typename ALLOC>
454void BytesAdapter<ALLOC>::visitValue(bool)
455{
456 throw CppRuntimeException("JsonReader: Unexpected visitValue (bool) in bytes!");
457}
458
459template <typename ALLOC>
460void BytesAdapter<ALLOC>::visitValue(int64_t)
461{
462 throw CppRuntimeException("JsonReader: Unexpected visitValue (int) in bytes!");
463}
464
465template <typename ALLOC>
466void BytesAdapter<ALLOC>::visitValue(uint64_t uintValue)
467{
468 if (m_state == VISIT_VALUE_BUFFER)
469 {
470 if (uintValue > static_cast<uint64_t>(std::numeric_limits<uint8_t>::max()))
471 {
472 throw CppRuntimeException("JsonReader: Cannot create byte for bytes from value '")
473 << uintValue << "'!";
474 }
475
476 m_buffer->push_back(static_cast<uint8_t>(uintValue));
477 }
478 else
479 {
480 throw CppRuntimeException("JsonReader: Unexpected visitValue in bytes!");
481 }
482}
483
484template <typename ALLOC>
485void BytesAdapter<ALLOC>::visitValue(double)
486{
487 throw CppRuntimeException("JsonReader: Unexpected visitValue (double) in bytes!");
488}
489
490template <typename ALLOC>
491void BytesAdapter<ALLOC>::visitValue(std::string_view)
492{
493 throw CppRuntimeException("JsonReader: Unexpected visitValue (string) in bytes!");
494}
495
496template <typename ALLOC>
497void CreatorAdapter<ALLOC>::setType(const IBasicTypeInfo<ALLOC>& typeInfo)
498{
499 m_creator = BasicZserioTreeCreator<ALLOC>(typeInfo, get_allocator());
500}
501
502template <typename ALLOC>
503IBasicReflectableDataPtr<ALLOC> CreatorAdapter<ALLOC>::get() const
504{
505 if (!m_object)
506 {
507 throw CppRuntimeException("JsonReader: Zserio tree not created!");
508 }
509
510 return m_object;
511}
512
513template <typename ALLOC>
514void CreatorAdapter<ALLOC>::beginObject()
515{
516 if (m_objectValueAdapter)
517 {
518 m_objectValueAdapter->beginObject();
519 }
520 else
521 {
522 if (!m_creator)
523 {
524 throw CppRuntimeException("JsonReader: Adapter not initialized!");
525 }
526
527 if (m_keyStack.empty())
528 {
529 m_creator->beginRoot();
530 }
531 else
532 {
533 if (!m_keyStack.back().empty())
534 {
535 const CppType cppType = m_creator->getFieldType(m_keyStack.back()).getCppType();
537 {
538 m_objectValueAdapter = std::allocate_shared<BitBufferAdapter<ALLOC>>(get_allocator());
539 }
540 else if (cppType == CppType::BYTES)
541 {
542 m_objectValueAdapter = std::allocate_shared<BytesAdapter<ALLOC>>(get_allocator());
543 }
544 else
545 {
546 m_creator->beginCompound(m_keyStack.back());
547 }
548 }
549 else
550 {
551 const CppType cppType = m_creator->getElementType().getCppType();
553 {
554 m_objectValueAdapter = std::allocate_shared<BitBufferAdapter<ALLOC>>(get_allocator());
555 }
556 else if (cppType == CppType::BYTES)
557 {
558 m_objectValueAdapter = std::allocate_shared<BytesAdapter<ALLOC>>(get_allocator());
559 }
560 else
561 {
562 m_creator->beginCompoundElement();
563 }
564 }
565 }
566 }
567}
568
569template <typename ALLOC>
570void CreatorAdapter<ALLOC>::endObject()
571{
572 if (m_objectValueAdapter)
573 {
574 setValue(m_objectValueAdapter->get());
575 m_objectValueAdapter.reset();
576 }
577 else
578 {
579 if (!m_creator)
580 {
581 throw CppRuntimeException("JsonReader: Adapter not initialized!");
582 }
583
584 if (m_keyStack.empty())
585 {
586 m_object = m_creator->endRoot();
587 m_creator.reset();
588 }
589 else
590 {
591 if (!m_keyStack.back().empty())
592 {
593 m_creator->endCompound();
594 m_keyStack.pop_back();
595 }
596 else
597 {
598 m_creator->endCompoundElement();
599 }
600 }
601 }
602}
603
604template <typename ALLOC>
605void CreatorAdapter<ALLOC>::beginArray()
606{
607 if (m_objectValueAdapter)
608 {
609 m_objectValueAdapter->beginArray();
610 }
611 else
612 {
613 if (!m_creator)
614 {
615 throw CppRuntimeException("JsonReader: Adapter not initialized!");
616 }
617
618 if (m_keyStack.empty())
619 {
620 throw CppRuntimeException("JsonReader: ZserioTreeCreator expects json object!");
621 }
622
623 m_creator->beginArray(m_keyStack.back());
624
625 m_keyStack.push_back("");
626 }
627}
628
629template <typename ALLOC>
630void CreatorAdapter<ALLOC>::endArray()
631{
632 if (m_objectValueAdapter)
633 {
634 m_objectValueAdapter->endArray();
635 }
636 else
637 {
638 if (!m_creator)
639 {
640 throw CppRuntimeException("JsonReader: Adapter not initialized!");
641 }
642
643 m_creator->endArray();
644
645 m_keyStack.pop_back(); // finish array
646 m_keyStack.pop_back(); // finish field
647 }
648}
649
650template <typename ALLOC>
651void CreatorAdapter<ALLOC>::visitKey(std::string_view key)
652{
653 if (m_objectValueAdapter)
654 {
655 m_objectValueAdapter->visitKey(key);
656 }
657 else
658 {
659 if (!m_creator)
660 {
661 throw CppRuntimeException("JsonReader: Adapter not initialized!");
662 }
663
664 m_keyStack.push_back(toString(key, get_allocator()));
665 }
666}
667
668template <typename ALLOC>
669void CreatorAdapter<ALLOC>::visitValue(std::nullptr_t nullValue)
670{
671 if (m_objectValueAdapter)
672 {
673 m_objectValueAdapter->visitValue(nullValue);
674 }
675 else
676 {
677 if (!m_creator)
678 {
679 throw CppRuntimeException("JsonReader: Adapter not initialized!");
680 }
681
682 setValue(nullValue);
683 }
684}
685
686template <typename ALLOC>
687void CreatorAdapter<ALLOC>::visitValue(bool boolValue)
688{
689 if (m_objectValueAdapter)
690 {
691 m_objectValueAdapter->visitValue(boolValue);
692 }
693 else
694 {
695 if (!m_creator)
696 {
697 throw CppRuntimeException("JsonReader: Adapter not initialized!");
698 }
699
700 setValue(boolValue);
701 }
702}
703
704template <typename ALLOC>
705void CreatorAdapter<ALLOC>::visitValue(int64_t intValue)
706{
707 if (m_objectValueAdapter)
708 {
709 m_objectValueAdapter->visitValue(intValue);
710 }
711 else
712 {
713 if (!m_creator)
714 {
715 throw CppRuntimeException("JsonReader: Adapter not initialized!");
716 }
717
718 setValue(intValue);
719 }
720}
721
722template <typename ALLOC>
723void CreatorAdapter<ALLOC>::visitValue(uint64_t uintValue)
724{
725 if (m_objectValueAdapter)
726 {
727 m_objectValueAdapter->visitValue(uintValue);
728 }
729 else
730 {
731 if (!m_creator)
732 {
733 throw CppRuntimeException("JsonReader: Adapter not initialized!");
734 }
735
736 setValue(uintValue);
737 }
738}
739
740template <typename ALLOC>
741void CreatorAdapter<ALLOC>::visitValue(double doubleValue)
742{
743 if (m_objectValueAdapter)
744 {
745 m_objectValueAdapter->visitValue(doubleValue);
746 }
747 else
748 {
749 if (!m_creator)
750 {
751 throw CppRuntimeException("JsonReader: Adapter not initialized!");
752 }
753
754 setValue(doubleValue);
755 }
756}
757
758template <typename ALLOC>
759void CreatorAdapter<ALLOC>::visitValue(std::string_view stringValue)
760{
761 if (m_objectValueAdapter)
762 {
763 m_objectValueAdapter->visitValue(stringValue);
764 }
765 else
766 {
767 if (!m_creator)
768 {
769 throw CppRuntimeException("JsonReader: Adapter not initialized!");
770 }
771
772 setValue(stringValue);
773 }
774}
775
776template <typename ALLOC>
777template <typename T>
778void CreatorAdapter<ALLOC>::setValue(T&& value)
779{
780 if (m_keyStack.empty())
781 {
782 throw CppRuntimeException("JsonReader: ZserioTreeCreator expects json object!");
783 }
784
785 if (!m_keyStack.back().empty())
786 {
787 m_creator->setValue(m_keyStack.back(), std::forward<T>(value));
788 m_keyStack.pop_back();
789 }
790 else
791 {
792 m_creator->addValueElement(std::forward<T>(value));
793 }
794}
795
796} // namespace detail
797
798} // namespace zserio
799
800#endif // ZSERIO_JSON_READER_H_INC
allocator_type get_allocator() const
AllocatorHolder & operator=(const AllocatorHolder &other)=default
virtual void visitKey(std::string_view key)=0
virtual void visitValue(std::nullptr_t nullValue)=0
BasicJsonReader(std::istream &in, const ALLOC &allocator=ALLOC())
Definition JsonReader.h:204
IBasicReflectableDataPtr< ALLOC > read(const IBasicTypeInfo< ALLOC > &typeInfo)
Definition JsonReader.h:217
const IBasicTypeInfo< ALLOC > & typeInfo()
Definition ITypeInfo.h:668
decltype(auto) get(BasicVariant< ALLOC, INDEX, T... > &var)
Definition Variant.h:511
BasicString< RebindAlloc< ALLOC, char > > toString(T value, const ALLOC &allocator=ALLOC())
size_t convertUInt64ToSize(uint64_t value)