// __ _____ _____ _____ // __| | __| | | | JSON for Modern C++ // | | |__ | | | | | | version 3.12.0 // |_____|_____|_____|_|___| https://github.com/nlohmann/json // // SPDX-FileCopyrightText: 2013-2026 Niels Lohmann // SPDX-License-Identifier: MIT #pragma once #include // min #include // size_t #include // string #include #include #include NLOHMANN_JSON_NAMESPACE_BEGIN namespace detail { namespace view { // Exceptions are thrown out of line, so that the accessors that may throw stay // small enough to be inlined. [[noreturn]] NLOHMANN_VIEW_NOINLINE inline void throw_type_error(int id, const char* prefix, const char* type) { NLOHMANN_VIEW_THROW(type_error::create(id, concat(prefix, type), nullptr)); } [[noreturn]] NLOHMANN_VIEW_NOINLINE inline void throw_out_of_range(int id, const std::string& msg) { NLOHMANN_VIEW_THROW(out_of_range::create(id, msg, nullptr)); } [[noreturn]] NLOHMANN_VIEW_NOINLINE inline void throw_invalid_iterator(int id, const char* msg) { NLOHMANN_VIEW_THROW(invalid_iterator::create(id, msg, nullptr)); } /// SAX handler of the error replay: accepts every event without storing it, /// and throws the exception the parser reports template struct throwing_sax { using number_integer_t = typename BasicJsonType::number_integer_t; using number_unsigned_t = typename BasicJsonType::number_unsigned_t; using number_float_t = typename BasicJsonType::number_float_t; using string_t = typename BasicJsonType::string_t; using binary_t = typename BasicJsonType::binary_t; bool null() { return true; } bool boolean(bool /*unused*/) { return true; } bool number_integer(number_integer_t /*unused*/) { return true; } bool number_unsigned(number_unsigned_t /*unused*/) { return true; } bool number_float(number_float_t /*unused*/, const string_t& /*unused*/) { return true; } bool string(string_t& /*unused*/) { return true; } bool binary(binary_t& /*unused*/) { return true; } bool start_object(std::size_t /*unused*/) { return true; } bool key(string_t& /*unused*/) { return true; } bool end_object() { return true; } bool start_array(std::size_t /*unused*/) { return true; } bool end_array() { return true; } /// (a template, as in json_sax_dom_parser: the parser passes the concrete /// exception type, which is thrown as is) template [[noreturn]] bool parse_error(std::size_t /*unused*/, const std::string& /*unused*/, const Exception& ex) { NLOHMANN_VIEW_THROW(ex); } }; /*! @brief throw the exception BasicJsonType::parse would throw for this input The view accepts exactly the inputs parse() accepts, so on a failure the library parser is run on the same bytes: it throws the exception parse() would throw, with the same message, position, and "last read" token. The replay uses a SAX handler that stores nothing, so it only lexes and parses up to the error, without building values. The error path is cold, so this costs nothing on valid input. Should parse() accept the input nevertheless (a bug), the view's own failure is reported. */ template [[noreturn]] NLOHMANN_VIEW_NOINLINE void throw_parse_failure(const parse_failure& f, const char* src, std::size_t size, bool ignore_comments, bool ignore_trailing_commas) { if (f.code == error_code::input_too_large) { // (the limit is detail::view::max_input_size(): 4 GiB minus 16 bytes) NLOHMANN_VIEW_THROW(out_of_range::create(416, "input of 4294967280 bytes or more is not supported by json_document", nullptr)); } throwing_sax sax; const bool accepted = BasicJsonType::sax_parse(src, src + size, &sax, input_format_t::json, true, ignore_comments, ignore_trailing_commas); // LCOV_EXCL_START (only if parse() accepts what the view rejects: a bug) static_cast(accepted); position_t pos; const std::size_t off = (std::min)(f.offset, size); pos.chars_read_total = off + 1; std::size_t line_start = 0; for (std::size_t i = 0; i < off; ++i) { if (src[i] == '\n') { ++pos.lines_read; line_start = i + 1; } } pos.chars_read_current_line = off + 1 - line_start; NLOHMANN_VIEW_THROW(parse_error::create(101, pos, "syntax error while parsing value", nullptr)); // LCOV_EXCL_STOP } } // namespace view } // namespace detail NLOHMANN_JSON_NAMESPACE_END