9 #include <nlohmann/detail/exceptions.hpp>
10 #include <nlohmann/detail/macro_scope.hpp>
23 template<
typename BasicJsonType>
33 using string_t =
typename BasicJsonType::string_t;
39 virtual bool null() = 0;
122 const std::string& last_token,
144 template<
typename BasicJsonType>
148 using number_integer_t =
typename BasicJsonType::number_integer_t;
149 using number_unsigned_t =
typename BasicJsonType::number_unsigned_t;
150 using number_float_t =
typename BasicJsonType::number_float_t;
151 using string_t =
typename BasicJsonType::string_t;
159 : root(r), allow_exceptions(allow_exceptions_)
171 handle_value(
nullptr);
175 bool boolean(
bool val)
181 bool number_integer(number_integer_t val)
187 bool number_unsigned(number_unsigned_t val)
193 bool number_float(number_float_t val,
const string_t& )
199 bool string(string_t& val)
205 bool start_object(std::size_t len)
207 ref_stack.push_back(handle_value(BasicJsonType::value_t::object));
209 if (JSON_HEDLEY_UNLIKELY(len != std::size_t(-1) and len > ref_stack.back()->max_size()))
211 JSON_THROW(out_of_range::create(408,
212 "excessive object size: " + std::to_string(len)));
218 bool key(string_t& val)
221 object_element = &(ref_stack.back()->m_value.object->operator[](val));
227 ref_stack.pop_back();
231 bool start_array(std::size_t len)
233 ref_stack.push_back(handle_value(BasicJsonType::value_t::array));
235 if (JSON_HEDLEY_UNLIKELY(len != std::size_t(-1) and len > ref_stack.back()->max_size()))
237 JSON_THROW(out_of_range::create(408,
238 "excessive array size: " + std::to_string(len)));
246 ref_stack.pop_back();
250 bool parse_error(std::size_t ,
const std::string& ,
251 const detail::exception& ex)
254 if (allow_exceptions)
257 switch ((ex.id / 100) % 100)
260 JSON_THROW(*
static_cast<const detail::parse_error*
>(&ex));
262 JSON_THROW(*
static_cast<const detail::out_of_range*
>(&ex));
265 JSON_THROW(*
static_cast<const detail::invalid_iterator*
>(&ex));
267 JSON_THROW(*
static_cast<const detail::type_error*
>(&ex));
269 JSON_THROW(*
static_cast<const detail::other_error*
>(&ex));
278 constexpr
bool is_errored()
const
290 template<
typename Value>
291 JSON_HEDLEY_RETURNS_NON_NULL
292 BasicJsonType* handle_value(Value&& v)
294 if (ref_stack.empty())
296 root = BasicJsonType(std::forward<Value>(v));
300 assert(ref_stack.back()->is_array() or ref_stack.back()->is_object());
302 if (ref_stack.back()->is_array())
304 ref_stack.back()->m_value.array->emplace_back(std::forward<Value>(v));
305 return &(ref_stack.back()->m_value.array->back());
308 assert(ref_stack.back()->is_object());
309 assert(object_element);
310 *object_element = BasicJsonType(std::forward<Value>(v));
311 return object_element;
317 std::vector<BasicJsonType*> ref_stack {};
319 BasicJsonType* object_element =
nullptr;
321 bool errored =
false;
323 const bool allow_exceptions =
true;
326 template<
typename BasicJsonType>
330 using number_integer_t =
typename BasicJsonType::number_integer_t;
331 using number_unsigned_t =
typename BasicJsonType::number_unsigned_t;
332 using number_float_t =
typename BasicJsonType::number_float_t;
333 using string_t =
typename BasicJsonType::string_t;
334 using parser_callback_t =
typename BasicJsonType::parser_callback_t;
335 using parse_event_t =
typename BasicJsonType::parse_event_t;
338 const parser_callback_t cb,
339 const bool allow_exceptions_ =
true)
340 : root(r), callback(cb), allow_exceptions(allow_exceptions_)
342 keep_stack.push_back(
true);
354 handle_value(
nullptr);
358 bool boolean(
bool val)
364 bool number_integer(number_integer_t val)
370 bool number_unsigned(number_unsigned_t val)
376 bool number_float(number_float_t val,
const string_t& )
382 bool string(string_t& val)
388 bool start_object(std::size_t len)
391 const bool keep = callback(
static_cast<int>(ref_stack.size()), parse_event_t::object_start, discarded);
392 keep_stack.push_back(keep);
394 auto val = handle_value(BasicJsonType::value_t::object,
true);
395 ref_stack.push_back(val.second);
398 if (ref_stack.back() and JSON_HEDLEY_UNLIKELY(len != std::size_t(-1) and len > ref_stack.back()->max_size()))
400 JSON_THROW(out_of_range::create(408,
"excessive object size: " + std::to_string(len)));
406 bool key(string_t& val)
408 BasicJsonType k = BasicJsonType(val);
411 const bool keep = callback(
static_cast<int>(ref_stack.size()), parse_event_t::key, k);
412 key_keep_stack.push_back(keep);
415 if (keep and ref_stack.back())
417 object_element = &(ref_stack.back()->m_value.object->operator[](val) = discarded);
425 if (ref_stack.back() and not callback(
static_cast<int>(ref_stack.size()) - 1, parse_event_t::object_end, *ref_stack.back()))
428 *ref_stack.back() = discarded;
431 assert(not ref_stack.empty());
432 assert(not keep_stack.empty());
433 ref_stack.pop_back();
434 keep_stack.pop_back();
436 if (not ref_stack.empty() and ref_stack.back() and ref_stack.back()->is_object())
439 for (
auto it = ref_stack.back()->begin(); it != ref_stack.back()->end(); ++it)
441 if (it->is_discarded())
443 ref_stack.back()->erase(it);
452 bool start_array(std::size_t len)
454 const bool keep = callback(
static_cast<int>(ref_stack.size()), parse_event_t::array_start, discarded);
455 keep_stack.push_back(keep);
457 auto val = handle_value(BasicJsonType::value_t::array,
true);
458 ref_stack.push_back(val.second);
461 if (ref_stack.back() and JSON_HEDLEY_UNLIKELY(len != std::size_t(-1) and len > ref_stack.back()->max_size()))
463 JSON_THROW(out_of_range::create(408,
"excessive array size: " + std::to_string(len)));
473 if (ref_stack.back())
475 keep = callback(
static_cast<int>(ref_stack.size()) - 1, parse_event_t::array_end, *ref_stack.back());
479 *ref_stack.back() = discarded;
483 assert(not ref_stack.empty());
484 assert(not keep_stack.empty());
485 ref_stack.pop_back();
486 keep_stack.pop_back();
489 if (not keep and not ref_stack.empty() and ref_stack.back()->is_array())
491 ref_stack.back()->m_value.array->pop_back();
497 bool parse_error(std::size_t ,
const std::string& ,
501 if (allow_exceptions)
504 switch ((ex.
id / 100) % 100)
525 constexpr
bool is_errored()
const
546 template<
typename Value>
547 std::pair<bool, BasicJsonType*> handle_value(Value&& v,
const bool skip_callback =
false)
549 assert(not keep_stack.empty());
553 if (not keep_stack.back())
555 return {
false,
nullptr};
559 auto value = BasicJsonType(std::forward<Value>(v));
562 const bool keep = skip_callback or callback(
static_cast<int>(ref_stack.size()), parse_event_t::value, value);
567 return {
false,
nullptr};
570 if (ref_stack.empty())
572 root = std::move(value);
573 return {
true, &root};
578 if (not ref_stack.back())
580 return {
false,
nullptr};
584 assert(ref_stack.back()->is_array() or ref_stack.back()->is_object());
587 if (ref_stack.back()->is_array())
589 ref_stack.back()->m_value.array->push_back(std::move(value));
590 return {
true, &(ref_stack.back()->m_value.array->back())};
594 assert(ref_stack.back()->is_object());
596 assert(not key_keep_stack.empty());
597 const bool store_element = key_keep_stack.back();
598 key_keep_stack.pop_back();
600 if (not store_element)
602 return {
false,
nullptr};
605 assert(object_element);
606 *object_element = std::move(value);
607 return {
true, object_element};
613 std::vector<BasicJsonType*> ref_stack {};
615 std::vector<bool> keep_stack {};
617 std::vector<bool> key_keep_stack {};
619 BasicJsonType* object_element =
nullptr;
621 bool errored =
false;
623 const parser_callback_t callback =
nullptr;
625 const bool allow_exceptions =
true;
627 BasicJsonType discarded = BasicJsonType::value_t::discarded;
630 template<
typename BasicJsonType>
634 using number_integer_t =
typename BasicJsonType::number_integer_t;
635 using number_unsigned_t =
typename BasicJsonType::number_unsigned_t;
636 using number_float_t =
typename BasicJsonType::number_float_t;
637 using string_t =
typename BasicJsonType::string_t;
649 bool number_integer(number_integer_t )
654 bool number_unsigned(number_unsigned_t )
659 bool number_float(number_float_t ,
const string_t& )
664 bool string(string_t& )
669 bool start_object(std::size_t = std::size_t(-1))
684 bool start_array(std::size_t = std::size_t(-1))
general exception of the basic_json class
Definition: exceptions.hpp:47
const int id
the id of the exception
Definition: exceptions.hpp:57
exception indicating errors with iterators
Definition: exceptions.hpp:204
Definition: json_sax.hpp:632
Definition: json_sax.hpp:328
SAX implementation to create a JSON value from SAX events.
Definition: json_sax.hpp:146
json_sax_dom_parser(BasicJsonType &r, const bool allow_exceptions_=true)
Definition: json_sax.hpp:158
exception indicating other library errors
Definition: exceptions.hpp:343
exception indicating access out of the defined range
Definition: exceptions.hpp:305
exception indicating a parse error
Definition: exceptions.hpp:118
exception indicating executing a member function with a wrong type
Definition: exceptions.hpp:258
namespace for Niels Lohmann
Definition: adl_serializer.hpp:9
SAX interface.
Definition: json_sax.hpp:25
virtual bool start_object(std::size_t elements)=0
the beginning of an object was read
virtual bool string(string_t &val)=0
a string was read
typename BasicJsonType::number_integer_t number_integer_t
type for (signed) integers
Definition: json_sax.hpp:27
virtual bool end_array()=0
the end of an array was read
virtual bool key(string_t &val)=0
an object key was read
typename BasicJsonType::number_unsigned_t number_unsigned_t
type for unsigned integers
Definition: json_sax.hpp:29
typename BasicJsonType::number_float_t number_float_t
type for floating-point numbers
Definition: json_sax.hpp:31
virtual bool start_array(std::size_t elements)=0
the beginning of an array was read
virtual bool parse_error(std::size_t position, const std::string &last_token, const detail::exception &ex)=0
a parse error occurred
virtual bool boolean(bool val)=0
a boolean value was read
virtual bool end_object()=0
the end of an object was read
virtual bool number_unsigned(number_unsigned_t val)=0
an unsigned integer number was read
typename BasicJsonType::string_t string_t
type for strings
Definition: json_sax.hpp:33
virtual bool number_float(number_float_t val, const string_t &s)=0
an floating-point number was read
virtual bool number_integer(number_integer_t val)=0
an integer number was read