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