Zserio C++17 runtime library  0.5.0
Built for Zserio 2.17.0
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"
12 #include "zserio/SizeConvertUtil.h"
13 #include "zserio/UniquePtr.h"
15 
16 namespace zserio
17 {
18 
19 namespace detail
20 {
21 
22 // adapter for values which are encoded as a JSON object
23 template <typename ALLOC>
24 class IObjectValueAdapter : public BasicJsonParser<ALLOC>::IObserver
25 {
26 public:
27  virtual BasicAny<ALLOC> get() const = 0;
28 };
29 
30 template <typename ALLOC>
31 class BitBufferAdapter : public IObjectValueAdapter<ALLOC>, public AllocatorHolder<ALLOC>
32 {
33 public:
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 
77 private:
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 
91 template <typename ALLOC>
92 class BytesAdapter : public IObjectValueAdapter<ALLOC>, public AllocatorHolder<ALLOC>
93 {
94 public:
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 
136 private:
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 
148 template <typename ALLOC>
149 class CreatorAdapter : public BasicJsonParser<ALLOC>::IObserver, public AllocatorHolder<ALLOC>
150 {
151 public:
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 
173 private:
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 
189 using namespace std::literals::string_view_literals;
190 
194 template <typename ALLOC = std::allocator<uint8_t>>
196 {
197 public:
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 
238 private:
239  detail::CreatorAdapter<ALLOC> m_creatorAdapter;
240  BasicJsonParser<ALLOC> m_parser;
241 };
242 
245 
246 namespace detail
247 {
248 
249 template <typename ALLOC>
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 
260 template <typename ALLOC>
261 void BitBufferAdapter<ALLOC>::beginObject()
262 {
263  throw CppRuntimeException("JsonReader: Unexpected beginObject in BitBuffer!");
264 }
265 
266 template <typename ALLOC>
267 void BitBufferAdapter<ALLOC>::endObject()
268 {
269  throw CppRuntimeException("JsonReader: Unexpected endObject in BitBuffer!");
270 }
271 
272 template <typename ALLOC>
273 void 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 
286 template <typename ALLOC>
287 void 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 
299 template <typename ALLOC>
300 void 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 
323 template <typename ALLOC>
324 void BitBufferAdapter<ALLOC>::visitValue(std::nullptr_t)
325 {
326  throw CppRuntimeException("JsonReader: Unexpected visitValue (null) in BitBuffer!");
327 }
328 
329 template <typename ALLOC>
330 void BitBufferAdapter<ALLOC>::visitValue(bool)
331 {
332  throw CppRuntimeException("JsonReader: Unexpected visitValue (bool) in BitBuffer!");
333 }
334 
335 template <typename ALLOC>
336 void BitBufferAdapter<ALLOC>::visitValue(int64_t)
337 {
338  throw CppRuntimeException("JsonReader: Unexpected visitValue (int) in BitBuffer!");
339 }
340 
341 template <typename ALLOC>
342 void 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 
365 template <typename ALLOC>
366 void BitBufferAdapter<ALLOC>::visitValue(double)
367 {
368  throw CppRuntimeException("JsonReader: Unexpected visitValue (double) in BitBuffer!");
369 }
370 
371 template <typename ALLOC>
372 void BitBufferAdapter<ALLOC>::visitValue(std::string_view)
373 {
374  throw CppRuntimeException("JsonReader: Unexpected visitValue (string) in BitBuffer!");
375 }
376 
377 template <typename ALLOC>
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 
388 template <typename ALLOC>
389 void BytesAdapter<ALLOC>::beginObject()
390 {
391  throw CppRuntimeException("JsonReader: Unexpected beginObject in bytes!");
392 }
393 
394 template <typename ALLOC>
395 void BytesAdapter<ALLOC>::endObject()
396 {
397  throw CppRuntimeException("JsonReader: Unexpected endObject in bytes!");
398 }
399 
400 template <typename ALLOC>
401 void 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 
414 template <typename ALLOC>
415 void 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 
427 template <typename ALLOC>
428 void 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 
447 template <typename ALLOC>
448 void BytesAdapter<ALLOC>::visitValue(std::nullptr_t)
449 {
450  throw CppRuntimeException("JsonReader: Unexpected visitValue (null) in bytes!");
451 }
452 
453 template <typename ALLOC>
454 void BytesAdapter<ALLOC>::visitValue(bool)
455 {
456  throw CppRuntimeException("JsonReader: Unexpected visitValue (bool) in bytes!");
457 }
458 
459 template <typename ALLOC>
460 void BytesAdapter<ALLOC>::visitValue(int64_t)
461 {
462  throw CppRuntimeException("JsonReader: Unexpected visitValue (int) in bytes!");
463 }
464 
465 template <typename ALLOC>
466 void 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 
484 template <typename ALLOC>
485 void BytesAdapter<ALLOC>::visitValue(double)
486 {
487  throw CppRuntimeException("JsonReader: Unexpected visitValue (double) in bytes!");
488 }
489 
490 template <typename ALLOC>
491 void BytesAdapter<ALLOC>::visitValue(std::string_view)
492 {
493  throw CppRuntimeException("JsonReader: Unexpected visitValue (string) in bytes!");
494 }
495 
496 template <typename ALLOC>
497 void CreatorAdapter<ALLOC>::setType(const IBasicTypeInfo<ALLOC>& typeInfo)
498 {
499  m_creator = BasicZserioTreeCreator<ALLOC>(typeInfo, get_allocator());
500 }
501 
502 template <typename ALLOC>
504 {
505  if (!m_object)
506  {
507  throw CppRuntimeException("JsonReader: Zserio tree not created!");
508  }
509 
510  return m_object;
511 }
512 
513 template <typename ALLOC>
514 void 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();
536  if (cppType == CppType::BIT_BUFFER)
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();
552  if (cppType == CppType::BIT_BUFFER)
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 
569 template <typename ALLOC>
570 void 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 
604 template <typename ALLOC>
605 void 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 
629 template <typename ALLOC>
630 void 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 
650 template <typename ALLOC>
651 void 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 
668 template <typename ALLOC>
669 void 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 
686 template <typename ALLOC>
687 void 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 
704 template <typename ALLOC>
705 void 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 
722 template <typename ALLOC>
723 void 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 
740 template <typename ALLOC>
741 void 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 
758 template <typename ALLOC>
759 void 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 
776 template <typename ALLOC>
777 template <typename T>
778 void 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
IBasicReflectableDataPtr< ALLOC > read(const IBasicTypeInfo< ALLOC > &typeInfo)
Definition: JsonReader.h:217
BasicJsonReader(std::istream &in, const ALLOC &allocator=ALLOC())
Definition: JsonReader.h:204
const char * what() const noexcept override
Definition: BitBuffer.h:602
typename IBasicReflectableData< ALLOC >::Ptr IBasicReflectableDataPtr
std::vector< T, ALLOC > Vector
Definition: Vector.h:13
decltype(auto) get(BasicVariant< ALLOC, INDEX, T... > &var)
Definition: Variant.h:812
const IBasicTypeInfo< ALLOC > & typeInfo()
Definition: ITypeInfo.h:668
BasicString< RebindAlloc< ALLOC, char > > toString(T value, const ALLOC &allocator=ALLOC())
size_t convertUInt64ToSize(uint64_t value)