Zserio C++ runtime library  1.3.0
Built for Zserio 2.18.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  unique_ptr<IObjectValueAdapter<ALLOC>, RebindAlloc<ALLOC, 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  m_objectValueAdapter->beginObject();
510  }
511  else
512  {
513  if (!m_creator)
514  {
515  throw CppRuntimeException("JsonReader: Adapter not initialized!");
516  }
517 
518  if (m_keyStack.empty())
519  {
520  m_creator->beginRoot();
521  }
522  else
523  {
524  if (!m_keyStack.back().empty())
525  {
526  const CppType cppType = m_creator->getFieldType(m_keyStack.back()).getCppType();
527  if (cppType == CppType::BIT_BUFFER)
528  {
529  m_objectValueAdapter =
530  allocate_unique<BitBufferAdapter<ALLOC>>(get_allocator(), get_allocator());
531  }
532  else if (cppType == CppType::BYTES)
533  {
534  m_objectValueAdapter =
535  allocate_unique<BytesAdapter<ALLOC>>(get_allocator(), get_allocator());
536  }
537  else
538  {
539  m_creator->beginCompound(m_keyStack.back());
540  }
541  }
542  else
543  {
544  const CppType cppType = m_creator->getElementType().getCppType();
545  if (cppType == CppType::BIT_BUFFER)
546  {
547  m_objectValueAdapter =
548  allocate_unique<BitBufferAdapter<ALLOC>>(get_allocator(), get_allocator());
549  }
550  else if (cppType == CppType::BYTES)
551  {
552  m_objectValueAdapter =
553  allocate_unique<BytesAdapter<ALLOC>>(get_allocator(), get_allocator());
554  }
555  else
556  {
557  m_creator->beginCompoundElement();
558  }
559  }
560  }
561  }
562 }
563 
564 template <typename ALLOC>
565 void CreatorAdapter<ALLOC>::endObject()
566 {
567  if (m_objectValueAdapter)
568  {
569  setValue(m_objectValueAdapter->get());
570  m_objectValueAdapter.reset();
571  }
572  else
573  {
574  if (!m_creator)
575  {
576  throw CppRuntimeException("JsonReader: Adapter not initialized!");
577  }
578 
579  if (m_keyStack.empty())
580  {
581  m_object = m_creator->endRoot();
582  m_creator.reset();
583  }
584  else
585  {
586  if (!m_keyStack.back().empty())
587  {
588  m_creator->endCompound();
589  m_keyStack.pop_back();
590  }
591  else
592  {
593  m_creator->endCompoundElement();
594  }
595  }
596  }
597 }
598 
599 template <typename ALLOC>
600 void CreatorAdapter<ALLOC>::beginArray()
601 {
602  if (m_objectValueAdapter)
603  {
604  m_objectValueAdapter->beginArray();
605  }
606  else
607  {
608  if (!m_creator)
609  {
610  throw CppRuntimeException("JsonReader: Adapter not initialized!");
611  }
612 
613  if (m_keyStack.empty())
614  {
615  throw CppRuntimeException("JsonReader: ZserioTreeCreator expects json object!");
616  }
617 
618  m_creator->beginArray(m_keyStack.back());
619 
620  m_keyStack.push_back("");
621  }
622 }
623 
624 template <typename ALLOC>
625 void CreatorAdapter<ALLOC>::endArray()
626 {
627  if (m_objectValueAdapter)
628  {
629  m_objectValueAdapter->endArray();
630  }
631  else
632  {
633  if (!m_creator)
634  {
635  throw CppRuntimeException("JsonReader: Adapter not initialized!");
636  }
637 
638  m_creator->endArray();
639 
640  m_keyStack.pop_back(); // finish array
641  m_keyStack.pop_back(); // finish field
642  }
643 }
644 
645 template <typename ALLOC>
646 void CreatorAdapter<ALLOC>::visitKey(StringView key)
647 {
648  if (m_objectValueAdapter)
649  {
650  m_objectValueAdapter->visitKey(key);
651  }
652  else
653  {
654  if (!m_creator)
655  {
656  throw CppRuntimeException("JsonReader: Adapter not initialized!");
657  }
658 
659  m_keyStack.push_back(toString(key, get_allocator()));
660  }
661 }
662 
663 template <typename ALLOC>
664 void CreatorAdapter<ALLOC>::visitValue(std::nullptr_t nullValue)
665 {
666  if (m_objectValueAdapter)
667  {
668  m_objectValueAdapter->visitValue(nullValue);
669  }
670  else
671  {
672  if (!m_creator)
673  {
674  throw CppRuntimeException("JsonReader: Adapter not initialized!");
675  }
676 
677  setValue(nullValue);
678  }
679 }
680 
681 template <typename ALLOC>
682 void CreatorAdapter<ALLOC>::visitValue(bool boolValue)
683 {
684  if (m_objectValueAdapter)
685  {
686  m_objectValueAdapter->visitValue(boolValue);
687  }
688  else
689  {
690  if (!m_creator)
691  {
692  throw CppRuntimeException("JsonReader: Adapter not initialized!");
693  }
694 
695  setValue(boolValue);
696  }
697 }
698 
699 template <typename ALLOC>
700 void CreatorAdapter<ALLOC>::visitValue(int64_t intValue)
701 {
702  if (m_objectValueAdapter)
703  {
704  m_objectValueAdapter->visitValue(intValue);
705  }
706  else
707  {
708  if (!m_creator)
709  {
710  throw CppRuntimeException("JsonReader: Adapter not initialized!");
711  }
712 
713  setValue(intValue);
714  }
715 }
716 
717 template <typename ALLOC>
718 void CreatorAdapter<ALLOC>::visitValue(uint64_t uintValue)
719 {
720  if (m_objectValueAdapter)
721  {
722  m_objectValueAdapter->visitValue(uintValue);
723  }
724  else
725  {
726  if (!m_creator)
727  {
728  throw CppRuntimeException("JsonReader: Adapter not initialized!");
729  }
730 
731  setValue(uintValue);
732  }
733 }
734 
735 template <typename ALLOC>
736 void CreatorAdapter<ALLOC>::visitValue(double doubleValue)
737 {
738  if (m_objectValueAdapter)
739  {
740  m_objectValueAdapter->visitValue(doubleValue);
741  }
742  else
743  {
744  if (!m_creator)
745  {
746  throw CppRuntimeException("JsonReader: Adapter not initialized!");
747  }
748 
749  setValue(doubleValue);
750  }
751 }
752 
753 template <typename ALLOC>
754 void CreatorAdapter<ALLOC>::visitValue(StringView stringValue)
755 {
756  if (m_objectValueAdapter)
757  {
758  m_objectValueAdapter->visitValue(stringValue);
759  }
760  else
761  {
762  if (!m_creator)
763  {
764  throw CppRuntimeException("JsonReader: Adapter not initialized!");
765  }
766 
767  setValue(stringValue);
768  }
769 }
770 
771 template <typename ALLOC>
772 template <typename T>
773 void CreatorAdapter<ALLOC>::setValue(T&& value)
774 {
775  if (m_keyStack.empty())
776  {
777  throw CppRuntimeException("JsonReader: ZserioTreeCreator expects json object!");
778  }
779 
780  if (!m_keyStack.back().empty())
781  {
782  m_creator->setValue(m_keyStack.back(), std::forward<T>(value));
783  m_keyStack.pop_back();
784  }
785  else
786  {
787  m_creator->addValueElement(std::forward<T>(value));
788  }
789 }
790 
791 } // namespace detail
792 
793 } // namespace zserio
794 
795 #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