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