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