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