Zserio C++ runtime library  1.0.1
Built for Zserio 2.14.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  throw CppRuntimeException("JsonReader: Unexpected end in BitBuffer!");
244 
245  return AnyHolder<ALLOC>(BasicBitBuffer<ALLOC>(m_buffer.value(), m_bitSize.value()), get_allocator());
246 }
247 
248 template <typename ALLOC>
249 void BitBufferAdapter<ALLOC>::beginObject()
250 {
251  throw CppRuntimeException("JsonReader: Unexpected beginObject in BitBuffer!");
252 }
253 
254 template <typename ALLOC>
255 void BitBufferAdapter<ALLOC>::endObject()
256 {
257  throw CppRuntimeException("JsonReader: Unexpected endObject in BitBuffer!");
258 }
259 
260 template <typename ALLOC>
261 void BitBufferAdapter<ALLOC>::beginArray()
262 {
263  if (m_state == BEGIN_ARRAY_BUFFER)
264  {
265  m_state = VISIT_VALUE_BUFFER;
266  m_buffer = vector<uint8_t, ALLOC>(get_allocator());
267  }
268  else
269  {
270  throw CppRuntimeException("JsonReader: Unexpected beginArray in BitBuffer!");
271  }
272 }
273 
274 template <typename ALLOC>
275 void BitBufferAdapter<ALLOC>::endArray()
276 {
277  if (m_state == VISIT_VALUE_BUFFER)
278  {
279  m_state = VISIT_KEY;
280  }
281  else
282  {
283  throw CppRuntimeException("JsonReader: Unexpected endArray in BitBuffer!");
284  }
285 }
286 
287 template <typename ALLOC>
288 void BitBufferAdapter<ALLOC>::visitKey(StringView key)
289 {
290  if (m_state == VISIT_KEY)
291  {
292  if (key == "buffer"_sv)
293  m_state = BEGIN_ARRAY_BUFFER;
294  else if (key == "bitSize"_sv)
295  m_state = VISIT_VALUE_BITSIZE;
296  else
297  throw CppRuntimeException("JsonReader: Unexpected key '") << key << "' in BitBuffer!";
298  }
299  else
300  {
301  throw CppRuntimeException("JsonReader: Unexpected visitKey in BitBuffer!");
302  }
303 }
304 
305 template <typename ALLOC>
306 void BitBufferAdapter<ALLOC>::visitValue(std::nullptr_t)
307 {
308  throw CppRuntimeException("JsonReader: Unexpected visitValue (null) in BitBuffer!");
309 }
310 
311 template <typename ALLOC>
312 void BitBufferAdapter<ALLOC>::visitValue(bool)
313 {
314  throw CppRuntimeException("JsonReader: Unexpected visitValue (bool) in BitBuffer!");
315 }
316 
317 template <typename ALLOC>
318 void BitBufferAdapter<ALLOC>::visitValue(int64_t)
319 {
320  throw CppRuntimeException("JsonReader: Unexpected visitValue (int) in BitBuffer!");
321 }
322 
323 template <typename ALLOC>
324 void BitBufferAdapter<ALLOC>::visitValue(uint64_t uintValue)
325 {
326  if (m_state == VISIT_VALUE_BUFFER)
327  {
328  if (uintValue > static_cast<uint64_t>(std::numeric_limits<uint8_t>::max()))
329  {
330  throw CppRuntimeException("JsonReader: Cannot create byte for Bit Buffer from value '")
331  << uintValue << "'!";
332  }
333 
334  m_buffer->push_back(static_cast<uint8_t>(uintValue));
335  }
336  else if (m_state == VISIT_VALUE_BITSIZE)
337  {
338  m_bitSize = convertUInt64ToSize(uintValue);
339  m_state = VISIT_KEY;
340  }
341  else
342  {
343  throw CppRuntimeException("JsonReader: Unexpected visitValue in BitBuffer!");
344  }
345 }
346 
347 template <typename ALLOC>
348 void BitBufferAdapter<ALLOC>::visitValue(double)
349 {
350  throw CppRuntimeException("JsonReader: Unexpected visitValue (double) in BitBuffer!");
351 }
352 
353 template <typename ALLOC>
354 void BitBufferAdapter<ALLOC>::visitValue(StringView)
355 {
356  throw CppRuntimeException("JsonReader: Unexpected visitValue (string) in BitBuffer!");
357 }
358 
359 template <typename ALLOC>
360 AnyHolder<ALLOC> BytesAdapter<ALLOC>::get() const
361 {
362  if (m_state != VISIT_KEY || !m_buffer.hasValue())
363  throw CppRuntimeException("JsonReader: Unexpected end in bytes!");
364 
365  return AnyHolder<ALLOC>(m_buffer.value(), get_allocator());
366 }
367 
368 template <typename ALLOC>
369 void BytesAdapter<ALLOC>::beginObject()
370 {
371  throw CppRuntimeException("JsonReader: Unexpected beginObject in bytes!");
372 }
373 
374 template <typename ALLOC>
375 void BytesAdapter<ALLOC>::endObject()
376 {
377  throw CppRuntimeException("JsonReader: Unexpected endObject in bytes!");
378 }
379 
380 template <typename ALLOC>
381 void BytesAdapter<ALLOC>::beginArray()
382 {
383  if (m_state == BEGIN_ARRAY_BUFFER)
384  {
385  m_state = VISIT_VALUE_BUFFER;
386  m_buffer = vector<uint8_t, ALLOC>(get_allocator());
387  }
388  else
389  {
390  throw CppRuntimeException("JsonReader: Unexpected beginArray in bytes!");
391  }
392 }
393 
394 template <typename ALLOC>
395 void BytesAdapter<ALLOC>::endArray()
396 {
397  if (m_state == VISIT_VALUE_BUFFER)
398  {
399  m_state = VISIT_KEY;
400  }
401  else
402  {
403  throw CppRuntimeException("JsonReader: Unexpected endArray in bytes!");
404  }
405 }
406 
407 template <typename ALLOC>
408 void BytesAdapter<ALLOC>::visitKey(StringView key)
409 {
410  if (m_state == VISIT_KEY)
411  {
412  if (key == "buffer"_sv)
413  m_state = BEGIN_ARRAY_BUFFER;
414  else
415  throw CppRuntimeException("JsonReader: Unexpected key '") << key << "' in bytes!";
416  }
417  else
418  {
419  throw CppRuntimeException("JsonReader: Unexpected visitKey in bytes!");
420  }
421 }
422 
423 template <typename ALLOC>
424 void BytesAdapter<ALLOC>::visitValue(std::nullptr_t)
425 {
426  throw CppRuntimeException("JsonReader: Unexpected visitValue (null) in bytes!");
427 }
428 
429 template <typename ALLOC>
430 void BytesAdapter<ALLOC>::visitValue(bool)
431 {
432  throw CppRuntimeException("JsonReader: Unexpected visitValue (bool) in bytes!");
433 }
434 
435 template <typename ALLOC>
436 void BytesAdapter<ALLOC>::visitValue(int64_t)
437 {
438  throw CppRuntimeException("JsonReader: Unexpected visitValue (int) in bytes!");
439 }
440 
441 template <typename ALLOC>
442 void BytesAdapter<ALLOC>::visitValue(uint64_t uintValue)
443 {
444  if (m_state == VISIT_VALUE_BUFFER)
445  {
446  if (uintValue > static_cast<uint64_t>(std::numeric_limits<uint8_t>::max()))
447  {
448  throw CppRuntimeException("JsonReader: Cannot create byte for bytes from value '")
449  << uintValue << "'!";
450  }
451 
452  m_buffer->push_back(static_cast<uint8_t>(uintValue));
453  }
454  else
455  {
456  throw CppRuntimeException("JsonReader: Unexpected visitValue in bytes!");
457  }
458 }
459 
460 template <typename ALLOC>
461 void BytesAdapter<ALLOC>::visitValue(double)
462 {
463  throw CppRuntimeException("JsonReader: Unexpected visitValue (double) in bytes!");
464 }
465 
466 template <typename ALLOC>
467 void BytesAdapter<ALLOC>::visitValue(StringView)
468 {
469  throw CppRuntimeException("JsonReader: Unexpected visitValue (string) in bytes!");
470 }
471 
472 template <typename ALLOC>
473 void CreatorAdapter<ALLOC>::setType(const IBasicTypeInfo<ALLOC>& typeInfo)
474 {
475  m_creator = BasicZserioTreeCreator<ALLOC>(typeInfo, get_allocator());
476 }
477 
478 template <typename ALLOC>
479 IBasicReflectablePtr<ALLOC> CreatorAdapter<ALLOC>::get() const
480 {
481  if (!m_object)
482  throw CppRuntimeException("JsonReader: Zserio tree not created!");
483 
484  return m_object;
485 }
486 
487 template <typename ALLOC>
488 void CreatorAdapter<ALLOC>::beginObject()
489 {
490  if (m_objectValueAdapter)
491  {
492  m_objectValueAdapter->beginObject();
493  }
494  else
495  {
496  if (!m_creator)
497  throw CppRuntimeException("JsonReader: Adapter not initialized!");
498 
499  if (m_keyStack.empty())
500  {
501  m_creator->beginRoot();
502  }
503  else
504  {
505  if (!m_keyStack.back().empty())
506  {
507  const CppType cppType = m_creator->getFieldType(m_keyStack.back()).getCppType();
508  if (cppType == CppType::BIT_BUFFER)
509  {
510  m_objectValueAdapter =
511  allocate_unique<BitBufferAdapter<ALLOC>>(get_allocator(), get_allocator());
512  }
513  else if (cppType == CppType::BYTES)
514  {
515  m_objectValueAdapter =
516  allocate_unique<BytesAdapter<ALLOC>>(get_allocator(), get_allocator());
517  }
518  else
519  {
520  m_creator->beginCompound(m_keyStack.back());
521  }
522  }
523  else
524  {
525  const CppType cppType = m_creator->getElementType().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->beginCompoundElement();
539  }
540  }
541  }
542  }
543 }
544 
545 template <typename ALLOC>
546 void CreatorAdapter<ALLOC>::endObject()
547 {
548  if (m_objectValueAdapter)
549  {
550  setValue(m_objectValueAdapter->get());
551  m_objectValueAdapter.reset();
552  }
553  else
554  {
555  if (!m_creator)
556  throw CppRuntimeException("JsonReader: Adapter not initialized!");
557 
558  if (m_keyStack.empty())
559  {
560  m_object = m_creator->endRoot();
561  m_creator.reset();
562  }
563  else
564  {
565  if (!m_keyStack.back().empty())
566  {
567  m_creator->endCompound();
568  m_keyStack.pop_back();
569  }
570  else
571  {
572  m_creator->endCompoundElement();
573  }
574  }
575  }
576 }
577 
578 template <typename ALLOC>
579 void CreatorAdapter<ALLOC>::beginArray()
580 {
581  if (m_objectValueAdapter)
582  {
583  m_objectValueAdapter->beginArray();
584  }
585  else
586  {
587  if (!m_creator)
588  throw CppRuntimeException("JsonReader: Adapter not initialized!");
589 
590  if (m_keyStack.empty())
591  throw CppRuntimeException("JsonReader: ZserioTreeCreator expects json object!");
592 
593  m_creator->beginArray(m_keyStack.back());
594 
595  m_keyStack.push_back("");
596  }
597 }
598 
599 template <typename ALLOC>
600 void CreatorAdapter<ALLOC>::endArray()
601 {
602  if (m_objectValueAdapter)
603  {
604  m_objectValueAdapter->endArray();
605  }
606  else
607  {
608  if (!m_creator)
609  throw CppRuntimeException("JsonReader: Adapter not initialized!");
610 
611  m_creator->endArray();
612 
613  m_keyStack.pop_back(); // finish array
614  m_keyStack.pop_back(); // finish field
615  }
616 }
617 
618 template <typename ALLOC>
619 void CreatorAdapter<ALLOC>::visitKey(StringView key)
620 {
621  if (m_objectValueAdapter)
622  {
623  m_objectValueAdapter->visitKey(key);
624  }
625  else
626  {
627  if (!m_creator)
628  throw CppRuntimeException("JsonReader: Adapter not initialized!");
629 
630  m_keyStack.push_back(toString(key, get_allocator()));
631  }
632 }
633 
634 template <typename ALLOC>
635 void CreatorAdapter<ALLOC>::visitValue(std::nullptr_t nullValue)
636 {
637  if (m_objectValueAdapter)
638  {
639  m_objectValueAdapter->visitValue(nullValue);
640  }
641  else
642  {
643  if (!m_creator)
644  throw CppRuntimeException("JsonReader: Adapter not initialized!");
645 
646  setValue(nullValue);
647  }
648 }
649 
650 template <typename ALLOC>
651 void CreatorAdapter<ALLOC>::visitValue(bool boolValue)
652 {
653  if (m_objectValueAdapter)
654  {
655  m_objectValueAdapter->visitValue(boolValue);
656  }
657  else
658  {
659  if (!m_creator)
660  throw CppRuntimeException("JsonReader: Adapter not initialized!");
661 
662  setValue(boolValue);
663  }
664 }
665 
666 template <typename ALLOC>
667 void CreatorAdapter<ALLOC>::visitValue(int64_t intValue)
668 {
669  if (m_objectValueAdapter)
670  {
671  m_objectValueAdapter->visitValue(intValue);
672  }
673  else
674  {
675  if (!m_creator)
676  throw CppRuntimeException("JsonReader: Adapter not initialized!");
677 
678  setValue(intValue);
679  }
680 }
681 
682 template <typename ALLOC>
683 void CreatorAdapter<ALLOC>::visitValue(uint64_t uintValue)
684 {
685  if (m_objectValueAdapter)
686  {
687  m_objectValueAdapter->visitValue(uintValue);
688  }
689  else
690  {
691  if (!m_creator)
692  throw CppRuntimeException("JsonReader: Adapter not initialized!");
693 
694  setValue(uintValue);
695  }
696 }
697 
698 template <typename ALLOC>
699 void CreatorAdapter<ALLOC>::visitValue(double doubleValue)
700 {
701  if (m_objectValueAdapter)
702  {
703  m_objectValueAdapter->visitValue(doubleValue);
704  }
705  else
706  {
707  if (!m_creator)
708  throw CppRuntimeException("JsonReader: Adapter not initialized!");
709 
710  setValue(doubleValue);
711  }
712 }
713 
714 template <typename ALLOC>
715 void CreatorAdapter<ALLOC>::visitValue(StringView stringValue)
716 {
717  if (m_objectValueAdapter)
718  {
719  m_objectValueAdapter->visitValue(stringValue);
720  }
721  else
722  {
723  if (!m_creator)
724  throw CppRuntimeException("JsonReader: Adapter not initialized!");
725 
726  setValue(stringValue);
727  }
728 }
729 
730 template <typename ALLOC>
731 template <typename T>
732 void CreatorAdapter<ALLOC>::setValue(T&& value)
733 {
734  if (m_keyStack.empty())
735  throw CppRuntimeException("JsonReader: ZserioTreeCreator expects json object!");
736 
737  if (!m_keyStack.back().empty())
738  {
739  m_creator->setValue(m_keyStack.back(), std::forward<T>(value));
740  m_keyStack.pop_back();
741  }
742  else
743  {
744  m_creator->addValueElement(std::forward<T>(value));
745  }
746 }
747 
748 } // namespace detail
749 
750 } // namespace zserio
751 
752 #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:936
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:516