WPILibC++ 2024.1.1-beta-4
json_sax.h
Go to the documentation of this file.
1// __ _____ _____ _____
2// __| | __| | | | JSON for Modern C++
3// | | |__ | | | | | | version 3.11.2
4// |_____|_____|_____|_|___| https://github.com/nlohmann/json
5//
6// SPDX-FileCopyrightText: 2013-2022 Niels Lohmann <https://nlohmann.me>
7// SPDX-License-Identifier: MIT
8
9#pragma once
10
11#include <cstddef>
12#include <string> // string
13#include <utility> // move
14#include <vector> // vector
15
19
21
22/*!
23@brief SAX interface
24
25This class describes the SAX interface used by @ref wpi::json::sax_parse.
26Each function is called in different situations while the input is parsed. The
27boolean return value informs the parser whether to continue processing the
28input.
29*/
30template<typename BasicJsonType>
32{
33 using number_integer_t = typename BasicJsonType::number_integer_t;
34 using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
35 using number_float_t = typename BasicJsonType::number_float_t;
36 using string_t = typename BasicJsonType::string_t;
37 using binary_t = typename BasicJsonType::binary_t;
38
39 /*!
40 @brief a null value was read
41 @return whether parsing should proceed
42 */
43 virtual bool null() = 0;
44
45 /*!
46 @brief a boolean value was read
47 @param[in] val boolean value
48 @return whether parsing should proceed
49 */
50 virtual bool boolean(bool val) = 0;
51
52 /*!
53 @brief an integer number was read
54 @param[in] val integer value
55 @return whether parsing should proceed
56 */
57 virtual bool number_integer(number_integer_t val) = 0;
58
59 /*!
60 @brief an unsigned integer number was read
61 @param[in] val unsigned integer value
62 @return whether parsing should proceed
63 */
64 virtual bool number_unsigned(number_unsigned_t val) = 0;
65
66 /*!
67 @brief a floating-point number was read
68 @param[in] val floating-point value
69 @param[in] s raw token value
70 @return whether parsing should proceed
71 */
72 virtual bool number_float(number_float_t val, const string_t& s) = 0;
73
74 /*!
75 @brief a string value was read
76 @param[in] val string value
77 @return whether parsing should proceed
78 @note It is safe to move the passed string value.
79 */
80 virtual bool string(string_t& val) = 0;
81
82 /*!
83 @brief a binary value was read
84 @param[in] val binary value
85 @return whether parsing should proceed
86 @note It is safe to move the passed binary value.
87 */
88 virtual bool binary(binary_t& val) = 0;
89
90 /*!
91 @brief the beginning of an object was read
92 @param[in] elements number of object elements or -1 if unknown
93 @return whether parsing should proceed
94 @note binary formats may report the number of elements
95 */
96 virtual bool start_object(std::size_t elements) = 0;
97
98 /*!
99 @brief an object key was read
100 @param[in] val object key
101 @return whether parsing should proceed
102 @note It is safe to move the passed string.
103 */
104 virtual bool key(string_t& val) = 0;
105
106 /*!
107 @brief the end of an object was read
108 @return whether parsing should proceed
109 */
110 virtual bool end_object() = 0;
111
112 /*!
113 @brief the beginning of an array was read
114 @param[in] elements number of array elements or -1 if unknown
115 @return whether parsing should proceed
116 @note binary formats may report the number of elements
117 */
118 virtual bool start_array(std::size_t elements) = 0;
119
120 /*!
121 @brief the end of an array was read
122 @return whether parsing should proceed
123 */
124 virtual bool end_array() = 0;
125
126 /*!
127 @brief a parse error occurred
128 @param[in] position the position in the input where the error occurs
129 @param[in] last_token the last read token
130 @param[in] ex an exception object describing the error
131 @return whether parsing should proceed (must return false)
132 */
133 virtual bool parse_error(std::size_t position,
134 const std::string& last_token,
135 const detail::exception& ex) = 0;
136
137 json_sax() = default;
138 json_sax(const json_sax&) = default;
139 json_sax(json_sax&&) noexcept = default;
140 json_sax& operator=(const json_sax&) = default;
141 json_sax& operator=(json_sax&&) noexcept = default;
142 virtual ~json_sax() = default;
143};
144
145
146namespace detail
147{
148/*!
149@brief SAX implementation to create a JSON value from SAX events
150
151This class implements the @ref json_sax interface and processes the SAX events
152to create a JSON value which makes it basically a DOM parser. The structure or
153hierarchy of the JSON value is managed by the stack `ref_stack` which contains
154a pointer to the respective array or object for each recursion depth.
155
156After successful parsing, the value that is passed by reference to the
157constructor contains the parsed value.
158
159@tparam BasicJsonType the JSON type
160*/
161template<typename BasicJsonType>
163{
164 public:
165 using number_integer_t = typename BasicJsonType::number_integer_t;
166 using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
167 using number_float_t = typename BasicJsonType::number_float_t;
168 using string_t = typename BasicJsonType::string_t;
169 using binary_t = typename BasicJsonType::binary_t;
170
171 /*!
172 @param[in,out] r reference to a JSON value that is manipulated while
173 parsing
174 @param[in] allow_exceptions_ whether parse errors yield exceptions
175 */
176 explicit json_sax_dom_parser(BasicJsonType& r, const bool allow_exceptions_ = true)
177 : root(r), allow_exceptions(allow_exceptions_)
178 {}
179
180 // make class move-only
182 json_sax_dom_parser(json_sax_dom_parser&&) = default; // NOLINT(hicpp-noexcept-move,performance-noexcept-move-constructor)
184 json_sax_dom_parser& operator=(json_sax_dom_parser&&) = default; // NOLINT(hicpp-noexcept-move,performance-noexcept-move-constructor)
186
187 bool null()
188 {
189 handle_value(nullptr);
190 return true;
191 }
192
193 bool boolean(bool val)
194 {
195 handle_value(val);
196 return true;
197 }
198
200 {
201 handle_value(val);
202 return true;
203 }
204
206 {
207 handle_value(val);
208 return true;
209 }
210
211 bool number_float(number_float_t val, const string_t& /*unused*/)
212 {
213 handle_value(val);
214 return true;
215 }
216
217 bool string(string_t& val)
218 {
219 handle_value(val);
220 return true;
221 }
222
223 bool binary(binary_t& val)
224 {
225 handle_value(std::move(val));
226 return true;
227 }
228
229 bool start_object(std::size_t len)
230 {
231 ref_stack.push_back(handle_value(BasicJsonType::value_t::object));
232
233 if (JSON_HEDLEY_UNLIKELY(len != static_cast<std::size_t>(-1) && len > ref_stack.back()->max_size()))
234 {
235 JSON_THROW(out_of_range::create(408, concat("excessive object size: ", std::to_string(len)), ref_stack.back()));
236 }
237
238 return true;
239 }
240
241 bool key(string_t& val)
242 {
243 JSON_ASSERT(!ref_stack.empty());
244 JSON_ASSERT(ref_stack.back()->is_object());
245
246 // add null at given key and store the reference for later
247 object_element = &(ref_stack.back()->m_value.object->operator[](val));
248 return true;
249 }
250
252 {
253 JSON_ASSERT(!ref_stack.empty());
254 JSON_ASSERT(ref_stack.back()->is_object());
255
256 ref_stack.back()->set_parents();
257 ref_stack.pop_back();
258 return true;
259 }
260
261 bool start_array(std::size_t len)
262 {
263 ref_stack.push_back(handle_value(BasicJsonType::value_t::array));
264
265 if (JSON_HEDLEY_UNLIKELY(len != static_cast<std::size_t>(-1) && len > ref_stack.back()->max_size()))
266 {
267 JSON_THROW(out_of_range::create(408, concat("excessive array size: ", std::to_string(len)), ref_stack.back()));
268 }
269
270 return true;
271 }
272
274 {
275 JSON_ASSERT(!ref_stack.empty());
276 JSON_ASSERT(ref_stack.back()->is_array());
277
278 ref_stack.back()->set_parents();
279 ref_stack.pop_back();
280 return true;
281 }
282
283 template<class Exception>
284 bool parse_error(std::size_t /*unused*/, const std::string& /*unused*/,
285 const Exception& ex)
286 {
287 errored = true;
288 static_cast<void>(ex);
289 if (allow_exceptions)
290 {
291 JSON_THROW(ex);
292 }
293 return false;
294 }
295
296 constexpr bool is_errored() const
297 {
298 return errored;
299 }
300
301 private:
302 /*!
303 @invariant If the ref stack is empty, then the passed value will be the new
304 root.
305 @invariant If the ref stack contains a value, then it is an array or an
306 object to which we can add elements
307 */
308 template<typename Value>
310 BasicJsonType* handle_value(Value&& v)
311 {
312 if (ref_stack.empty())
313 {
314 root = BasicJsonType(std::forward<Value>(v));
315 return &root;
316 }
317
318 JSON_ASSERT(ref_stack.back()->is_array() || ref_stack.back()->is_object());
319
320 if (ref_stack.back()->is_array())
321 {
322 ref_stack.back()->m_value.array->emplace_back(std::forward<Value>(v));
323 return &(ref_stack.back()->m_value.array->back());
324 }
325
326 JSON_ASSERT(ref_stack.back()->is_object());
327 JSON_ASSERT(object_element);
328 *object_element = BasicJsonType(std::forward<Value>(v));
329 return object_element;
330 }
331
332 /// the parsed JSON value
333 BasicJsonType& root;
334 /// stack to model hierarchy of values
335 std::vector<BasicJsonType*> ref_stack {};
336 /// helper to hold the reference for the next object element
337 BasicJsonType* object_element = nullptr;
338 /// whether a syntax error occurred
339 bool errored = false;
340 /// whether to throw exceptions in case of errors
341 const bool allow_exceptions = true;
342};
343
344template<typename BasicJsonType>
346{
347 public:
348 using number_integer_t = typename BasicJsonType::number_integer_t;
349 using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
350 using number_float_t = typename BasicJsonType::number_float_t;
351 using string_t = typename BasicJsonType::string_t;
352 using binary_t = typename BasicJsonType::binary_t;
355
357 const parser_callback_t cb,
358 const bool allow_exceptions_ = true)
359 : root(r), callback(cb), allow_exceptions(allow_exceptions_)
360 {
361 keep_stack.push_back(true);
362 }
363
364 // make class move-only
366 json_sax_dom_callback_parser(json_sax_dom_callback_parser&&) = default; // NOLINT(hicpp-noexcept-move,performance-noexcept-move-constructor)
368 json_sax_dom_callback_parser& operator=(json_sax_dom_callback_parser&&) = default; // NOLINT(hicpp-noexcept-move,performance-noexcept-move-constructor)
370
371 bool null()
372 {
373 handle_value(nullptr);
374 return true;
375 }
376
377 bool boolean(bool val)
378 {
379 handle_value(val);
380 return true;
381 }
382
384 {
385 handle_value(val);
386 return true;
387 }
388
390 {
391 handle_value(val);
392 return true;
393 }
394
395 bool number_float(number_float_t val, const string_t& /*unused*/)
396 {
397 handle_value(val);
398 return true;
399 }
400
401 bool string(string_t& val)
402 {
403 handle_value(val);
404 return true;
405 }
406
407 bool binary(binary_t& val)
408 {
409 handle_value(std::move(val));
410 return true;
411 }
412
413 bool start_object(std::size_t len)
414 {
415 // check callback for object start
416 const bool keep = callback(static_cast<int>(ref_stack.size()), parse_event_t::object_start, discarded);
417 keep_stack.push_back(keep);
418
419 auto val = handle_value(BasicJsonType::value_t::object, true);
420 ref_stack.push_back(val.second);
421
422 // check object limit
423 if (ref_stack.back() && JSON_HEDLEY_UNLIKELY(len != static_cast<std::size_t>(-1) && len > ref_stack.back()->max_size()))
424 {
425 JSON_THROW(out_of_range::create(408, concat("excessive object size: ", std::to_string(len)), ref_stack.back()));
426 }
427
428 return true;
429 }
430
431 bool key(string_t& val)
432 {
433 BasicJsonType k = BasicJsonType(val);
434
435 // check callback for key
436 const bool keep = callback(static_cast<int>(ref_stack.size()), parse_event_t::key, k);
437 key_keep_stack.push_back(keep);
438
439 // add discarded value at given key and store the reference for later
440 if (keep && ref_stack.back())
441 {
442 object_element = &(ref_stack.back()->m_value.object->operator[](val) = discarded);
443 }
444
445 return true;
446 }
447
449 {
450 if (ref_stack.back())
451 {
452 if (!callback(static_cast<int>(ref_stack.size()) - 1, parse_event_t::object_end, *ref_stack.back()))
453 {
454 // discard object
455 *ref_stack.back() = discarded;
456 }
457 else
458 {
459 ref_stack.back()->set_parents();
460 }
461 }
462
463 JSON_ASSERT(!ref_stack.empty());
464 JSON_ASSERT(!keep_stack.empty());
465 ref_stack.pop_back();
466 keep_stack.pop_back();
467
468 if (!ref_stack.empty() && ref_stack.back() && ref_stack.back()->is_structured())
469 {
470 // remove discarded value
471 for (auto it = ref_stack.back()->begin(); it != ref_stack.back()->end(); ++it)
472 {
473 if (it->is_discarded())
474 {
475 ref_stack.back()->erase(it);
476 break;
477 }
478 }
479 }
480
481 return true;
482 }
483
484 bool start_array(std::size_t len)
485 {
486 const bool keep = callback(static_cast<int>(ref_stack.size()), parse_event_t::array_start, discarded);
487 keep_stack.push_back(keep);
488
489 auto val = handle_value(BasicJsonType::value_t::array, true);
490 ref_stack.push_back(val.second);
491
492 // check array limit
493 if (ref_stack.back() && JSON_HEDLEY_UNLIKELY(len != static_cast<std::size_t>(-1) && len > ref_stack.back()->max_size()))
494 {
495 JSON_THROW(out_of_range::create(408, concat("excessive array size: ", std::to_string(len)), ref_stack.back()));
496 }
497
498 return true;
499 }
500
502 {
503 bool keep = true;
504
505 if (ref_stack.back())
506 {
507 keep = callback(static_cast<int>(ref_stack.size()) - 1, parse_event_t::array_end, *ref_stack.back());
508 if (keep)
509 {
510 ref_stack.back()->set_parents();
511 }
512 else
513 {
514 // discard array
515 *ref_stack.back() = discarded;
516 }
517 }
518
519 JSON_ASSERT(!ref_stack.empty());
520 JSON_ASSERT(!keep_stack.empty());
521 ref_stack.pop_back();
522 keep_stack.pop_back();
523
524 // remove discarded value
525 if (!keep && !ref_stack.empty() && ref_stack.back()->is_array())
526 {
527 ref_stack.back()->m_value.array->pop_back();
528 }
529
530 return true;
531 }
532
533 template<class Exception>
534 bool parse_error(std::size_t /*unused*/, const std::string& /*unused*/,
535 const Exception& ex)
536 {
537 errored = true;
538 static_cast<void>(ex);
539 if (allow_exceptions)
540 {
541 JSON_THROW(ex);
542 }
543 return false;
544 }
545
546 constexpr bool is_errored() const
547 {
548 return errored;
549 }
550
551 private:
552 /*!
553 @param[in] v value to add to the JSON value we build during parsing
554 @param[in] skip_callback whether we should skip calling the callback
555 function; this is required after start_array() and
556 start_object() SAX events, because otherwise we would call the
557 callback function with an empty array or object, respectively.
558
559 @invariant If the ref stack is empty, then the passed value will be the new
560 root.
561 @invariant If the ref stack contains a value, then it is an array or an
562 object to which we can add elements
563
564 @return pair of boolean (whether value should be kept) and pointer (to the
565 passed value in the ref_stack hierarchy; nullptr if not kept)
566 */
567 template<typename Value>
568 std::pair<bool, BasicJsonType*> handle_value(Value&& v, const bool skip_callback = false)
569 {
570 JSON_ASSERT(!keep_stack.empty());
571
572 // do not handle this value if we know it would be added to a discarded
573 // container
574 if (!keep_stack.back())
575 {
576 return {false, nullptr};
577 }
578
579 // create value
580 auto value = BasicJsonType(std::forward<Value>(v));
581
582 // check callback
583 const bool keep = skip_callback || callback(static_cast<int>(ref_stack.size()), parse_event_t::value, value);
584
585 // do not handle this value if we just learnt it shall be discarded
586 if (!keep)
587 {
588 return {false, nullptr};
589 }
590
591 if (ref_stack.empty())
592 {
593 root = std::move(value);
594 return {true, &root};
595 }
596
597 // skip this value if we already decided to skip the parent
598 // (https://github.com/nlohmann/json/issues/971#issuecomment-413678360)
599 if (!ref_stack.back())
600 {
601 return {false, nullptr};
602 }
603
604 // we now only expect arrays and objects
605 JSON_ASSERT(ref_stack.back()->is_array() || ref_stack.back()->is_object());
606
607 // array
608 if (ref_stack.back()->is_array())
609 {
610 ref_stack.back()->m_value.array->emplace_back(std::move(value));
611 return {true, &(ref_stack.back()->m_value.array->back())};
612 }
613
614 // object
615 JSON_ASSERT(ref_stack.back()->is_object());
616 // check if we should store an element for the current key
617 JSON_ASSERT(!key_keep_stack.empty());
618 const bool store_element = key_keep_stack.back();
619 key_keep_stack.pop_back();
620
621 if (!store_element)
622 {
623 return {false, nullptr};
624 }
625
626 JSON_ASSERT(object_element);
627 *object_element = std::move(value);
628 return {true, object_element};
629 }
630
631 /// the parsed JSON value
632 BasicJsonType& root;
633 /// stack to model hierarchy of values
634 std::vector<BasicJsonType*> ref_stack {};
635 /// stack to manage which values to keep
636 std::vector<bool> keep_stack {};
637 /// stack to manage which object keys to keep
638 std::vector<bool> key_keep_stack {};
639 /// helper to hold the reference for the next object element
640 BasicJsonType* object_element = nullptr;
641 /// whether a syntax error occurred
642 bool errored = false;
643 /// callback function
644 const parser_callback_t callback = nullptr;
645 /// whether to throw exceptions in case of errors
646 const bool allow_exceptions = true;
647 /// a discarded value for the callback
648 BasicJsonType discarded = BasicJsonType::value_t::discarded;
649};
650
651template<typename BasicJsonType>
653{
654 public:
655 using number_integer_t = typename BasicJsonType::number_integer_t;
656 using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
657 using number_float_t = typename BasicJsonType::number_float_t;
658 using string_t = typename BasicJsonType::string_t;
659 using binary_t = typename BasicJsonType::binary_t;
660
661 bool null()
662 {
663 return true;
664 }
665
666 bool boolean(bool /*unused*/)
667 {
668 return true;
669 }
670
672 {
673 return true;
674 }
675
677 {
678 return true;
679 }
680
681 bool number_float(number_float_t /*unused*/, const string_t& /*unused*/)
682 {
683 return true;
684 }
685
686 bool string(string_t& /*unused*/)
687 {
688 return true;
689 }
690
691 bool binary(binary_t& /*unused*/)
692 {
693 return true;
694 }
695
696 bool start_object(std::size_t /*unused*/ = static_cast<std::size_t>(-1))
697 {
698 return true;
699 }
700
701 bool key(string_t& /*unused*/)
702 {
703 return true;
704 }
705
707 {
708 return true;
709 }
710
711 bool start_array(std::size_t /*unused*/ = static_cast<std::size_t>(-1))
712 {
713 return true;
714 }
715
717 {
718 return true;
719 }
720
721 bool parse_error(std::size_t /*unused*/, const std::string& /*unused*/, const detail::exception& /*unused*/)
722 {
723 return false;
724 }
725};
726
727} // namespace detail
#define WPI_JSON_NAMESPACE_END
Definition: abi_macros.h:59
#define WPI_JSON_NAMESPACE_BEGIN
Definition: abi_macros.h:53
general exception of the basic_json class
Definition: exceptions.h:37
Definition: json_sax.h:653
typename BasicJsonType::number_unsigned_t number_unsigned_t
Definition: json_sax.h:656
bool end_object()
Definition: json_sax.h:706
bool start_object(std::size_t=static_cast< std::size_t >(-1))
Definition: json_sax.h:696
bool binary(binary_t &)
Definition: json_sax.h:691
bool number_integer(number_integer_t)
Definition: json_sax.h:671
bool start_array(std::size_t=static_cast< std::size_t >(-1))
Definition: json_sax.h:711
bool boolean(bool)
Definition: json_sax.h:666
bool null()
Definition: json_sax.h:661
bool end_array()
Definition: json_sax.h:716
bool number_unsigned(number_unsigned_t)
Definition: json_sax.h:676
bool string(string_t &)
Definition: json_sax.h:686
typename BasicJsonType::binary_t binary_t
Definition: json_sax.h:659
bool number_float(number_float_t, const string_t &)
Definition: json_sax.h:681
bool parse_error(std::size_t, const std::string &, const detail::exception &)
Definition: json_sax.h:721
bool key(string_t &)
Definition: json_sax.h:701
typename BasicJsonType::number_integer_t number_integer_t
Definition: json_sax.h:655
typename BasicJsonType::number_float_t number_float_t
Definition: json_sax.h:657
typename BasicJsonType::string_t string_t
Definition: json_sax.h:658
Definition: json_sax.h:346
bool boolean(bool val)
Definition: json_sax.h:377
bool parse_error(std::size_t, const std::string &, const Exception &ex)
Definition: json_sax.h:534
typename BasicJsonType::string_t string_t
Definition: json_sax.h:351
bool number_float(number_float_t val, const string_t &)
Definition: json_sax.h:395
constexpr bool is_errored() const
Definition: json_sax.h:546
bool string(string_t &val)
Definition: json_sax.h:401
json_sax_dom_callback_parser & operator=(const json_sax_dom_callback_parser &)=delete
json_sax_dom_callback_parser(const json_sax_dom_callback_parser &)=delete
typename BasicJsonType::number_unsigned_t number_unsigned_t
Definition: json_sax.h:349
typename BasicJsonType::binary_t binary_t
Definition: json_sax.h:352
bool start_object(std::size_t len)
Definition: json_sax.h:413
bool start_array(std::size_t len)
Definition: json_sax.h:484
typename BasicJsonType::number_integer_t number_integer_t
Definition: json_sax.h:348
bool end_array()
Definition: json_sax.h:501
json_sax_dom_callback_parser(json_sax_dom_callback_parser &&)=default
bool key(string_t &val)
Definition: json_sax.h:431
bool end_object()
Definition: json_sax.h:448
typename BasicJsonType::parse_event_t parse_event_t
Definition: json_sax.h:354
typename BasicJsonType::parser_callback_t parser_callback_t
Definition: json_sax.h:353
bool null()
Definition: json_sax.h:371
bool number_unsigned(number_unsigned_t val)
Definition: json_sax.h:389
json_sax_dom_callback_parser & operator=(json_sax_dom_callback_parser &&)=default
json_sax_dom_callback_parser(BasicJsonType &r, const parser_callback_t cb, const bool allow_exceptions_=true)
Definition: json_sax.h:356
typename BasicJsonType::number_float_t number_float_t
Definition: json_sax.h:350
bool number_integer(number_integer_t val)
Definition: json_sax.h:383
bool binary(binary_t &val)
Definition: json_sax.h:407
SAX implementation to create a JSON value from SAX events.
Definition: json_sax.h:163
json_sax_dom_parser(const json_sax_dom_parser &)=delete
json_sax_dom_parser & operator=(json_sax_dom_parser &&)=default
bool string(string_t &val)
Definition: json_sax.h:217
json_sax_dom_parser(BasicJsonType &r, const bool allow_exceptions_=true)
Definition: json_sax.h:176
bool parse_error(std::size_t, const std::string &, const Exception &ex)
Definition: json_sax.h:284
bool null()
Definition: json_sax.h:187
typename BasicJsonType::string_t string_t
Definition: json_sax.h:168
bool start_object(std::size_t len)
Definition: json_sax.h:229
typename BasicJsonType::number_unsigned_t number_unsigned_t
Definition: json_sax.h:166
bool number_unsigned(number_unsigned_t val)
Definition: json_sax.h:205
bool number_integer(number_integer_t val)
Definition: json_sax.h:199
typename BasicJsonType::number_integer_t number_integer_t
Definition: json_sax.h:165
json_sax_dom_parser & operator=(const json_sax_dom_parser &)=delete
bool binary(binary_t &val)
Definition: json_sax.h:223
json_sax_dom_parser(json_sax_dom_parser &&)=default
bool boolean(bool val)
Definition: json_sax.h:193
bool end_array()
Definition: json_sax.h:273
bool number_float(number_float_t val, const string_t &)
Definition: json_sax.h:211
bool end_object()
Definition: json_sax.h:251
constexpr bool is_errored() const
Definition: json_sax.h:296
typename BasicJsonType::binary_t binary_t
Definition: json_sax.h:169
typename BasicJsonType::number_float_t number_float_t
Definition: json_sax.h:167
bool start_array(std::size_t len)
Definition: json_sax.h:261
bool key(string_t &val)
Definition: json_sax.h:241
#define JSON_HEDLEY_RETURNS_NON_NULL
Definition: hedley.h:1729
#define JSON_HEDLEY_UNLIKELY(expr)
Definition: hedley.h:1396
#define JSON_ASSERT(x)
Definition: macro_scope.h:192
#define JSON_THROW(exception)
Definition: macro_scope.h:163
detail namespace with internal helper functions
Definition: ranges.h:23
std::function< bool(int, parse_event_t, BasicJsonType &)> parser_callback_t
Definition: parser.h:52
OutStringType concat(Args &&... args)
Definition: string_concat.h:137
parse_event_t
Definition: parser.h:35
@ value
the parser finished reading a JSON value
@ discarded
discarded by the parser callback function
std::string to_string(const T &t)
Definition: base.h:93
array(T, Ts...) -> array< T, 1+sizeof...(Ts)>
SAX interface.
Definition: json_sax.h:32
virtual bool binary(binary_t &val)=0
a binary value was read
virtual bool number_float(number_float_t val, const string_t &s)=0
a floating-point number was read
virtual bool number_unsigned(number_unsigned_t val)=0
an unsigned integer number was read
virtual bool key(string_t &val)=0
an object key was read
json_sax()=default
virtual bool string(string_t &val)=0
a string value was read
virtual bool number_integer(number_integer_t val)=0
an integer number was read
virtual bool start_object(std::size_t elements)=0
the beginning of an object was read
typename BasicJsonType::number_integer_t number_integer_t
Definition: json_sax.h:33
typename BasicJsonType::string_t string_t
Definition: json_sax.h:36
virtual bool end_array()=0
the end of an array was read
json_sax(const json_sax &)=default
virtual bool boolean(bool val)=0
a boolean value was read
virtual bool end_object()=0
the end of an object was read
typename BasicJsonType::number_float_t number_float_t
Definition: json_sax.h:35
virtual bool null()=0
a null value was read
typename BasicJsonType::number_unsigned_t number_unsigned_t
Definition: json_sax.h:34
json_sax(json_sax &&) noexcept=default
typename BasicJsonType::binary_t binary_t
Definition: json_sax.h:37
virtual bool parse_error(std::size_t position, const std::string &last_token, const detail::exception &ex)=0
a parse error occurred
virtual bool start_array(std::size_t elements)=0
the beginning of an array was read