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