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