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