258 lines
		
	
	
		
			9.0 KiB
		
	
	
	
		
			C++
		
	
	
	
		
		
			
		
	
	
			258 lines
		
	
	
		
			9.0 KiB
		
	
	
	
		
			C++
		
	
	
	
|  | //     __ _____ _____ _____
 | ||
|  | //  __|  |   __|     |   | |  JSON for Modern C++
 | ||
|  | // |  |  |__   |  |  | | | |  version 3.11.3
 | ||
|  | // |_____|_____|_____|_|___|  https://github.com/nlohmann/json
 | ||
|  | //
 | ||
|  | // SPDX-FileCopyrightText: 2013-2023 Niels Lohmann <https://nlohmann.me>
 | ||
|  | // SPDX-License-Identifier: MIT
 | ||
|  | 
 | ||
|  | #pragma once
 | ||
|  | 
 | ||
|  | #include <cstddef> // nullptr_t
 | ||
|  | #include <exception> // exception
 | ||
|  | #if JSON_DIAGNOSTICS
 | ||
|  |     #include <numeric> // accumulate
 | ||
|  | #endif
 | ||
|  | #include <stdexcept> // runtime_error
 | ||
|  | #include <string> // to_string
 | ||
|  | #include <vector> // vector
 | ||
|  | 
 | ||
|  | #include <nlohmann/detail/value_t.hpp>
 | ||
|  | #include <nlohmann/detail/string_escape.hpp>
 | ||
|  | #include <nlohmann/detail/input/position_t.hpp>
 | ||
|  | #include <nlohmann/detail/macro_scope.hpp>
 | ||
|  | #include <nlohmann/detail/meta/cpp_future.hpp>
 | ||
|  | #include <nlohmann/detail/meta/type_traits.hpp>
 | ||
|  | #include <nlohmann/detail/string_concat.hpp>
 | ||
|  | 
 | ||
|  | NLOHMANN_JSON_NAMESPACE_BEGIN | ||
|  | namespace detail | ||
|  | { | ||
|  | 
 | ||
|  | ////////////////
 | ||
|  | // exceptions //
 | ||
|  | ////////////////
 | ||
|  | 
 | ||
|  | /// @brief general exception of the @ref basic_json class
 | ||
|  | /// @sa https://json.nlohmann.me/api/basic_json/exception/
 | ||
|  | class exception : public std::exception | ||
|  | { | ||
|  |   public: | ||
|  |     /// returns the explanatory string
 | ||
|  |     const char* what() const noexcept override | ||
|  |     { | ||
|  |         return m.what(); | ||
|  |     } | ||
|  | 
 | ||
|  |     /// the id of the exception
 | ||
|  |     const int id; // NOLINT(cppcoreguidelines-non-private-member-variables-in-classes)
 | ||
|  | 
 | ||
|  |   protected: | ||
|  |     JSON_HEDLEY_NON_NULL(3) | ||
|  |     exception(int id_, const char* what_arg) : id(id_), m(what_arg) {} // NOLINT(bugprone-throw-keyword-missing)
 | ||
|  | 
 | ||
|  |     static std::string name(const std::string& ename, int id_) | ||
|  |     { | ||
|  |         return concat("[json.exception.", ename, '.', std::to_string(id_), "] "); | ||
|  |     } | ||
|  | 
 | ||
|  |     static std::string diagnostics(std::nullptr_t /*leaf_element*/) | ||
|  |     { | ||
|  |         return ""; | ||
|  |     } | ||
|  | 
 | ||
|  |     template<typename BasicJsonType> | ||
|  |     static std::string diagnostics(const BasicJsonType* leaf_element) | ||
|  |     { | ||
|  | #if JSON_DIAGNOSTICS
 | ||
|  |         std::vector<std::string> tokens; | ||
|  |         for (const auto* current = leaf_element; current != nullptr && current->m_parent != nullptr; current = current->m_parent) | ||
|  |         { | ||
|  |             switch (current->m_parent->type()) | ||
|  |             { | ||
|  |                 case value_t::array: | ||
|  |                 { | ||
|  |                     for (std::size_t i = 0; i < current->m_parent->m_data.m_value.array->size(); ++i) | ||
|  |                     { | ||
|  |                         if (¤t->m_parent->m_data.m_value.array->operator[](i) == current) | ||
|  |                         { | ||
|  |                             tokens.emplace_back(std::to_string(i)); | ||
|  |                             break; | ||
|  |                         } | ||
|  |                     } | ||
|  |                     break; | ||
|  |                 } | ||
|  | 
 | ||
|  |                 case value_t::object: | ||
|  |                 { | ||
|  |                     for (const auto& element : *current->m_parent->m_data.m_value.object) | ||
|  |                     { | ||
|  |                         if (&element.second == current) | ||
|  |                         { | ||
|  |                             tokens.emplace_back(element.first.c_str()); | ||
|  |                             break; | ||
|  |                         } | ||
|  |                     } | ||
|  |                     break; | ||
|  |                 } | ||
|  | 
 | ||
|  |                 case value_t::null: // LCOV_EXCL_LINE
 | ||
|  |                 case value_t::string: // LCOV_EXCL_LINE
 | ||
|  |                 case value_t::boolean: // LCOV_EXCL_LINE
 | ||
|  |                 case value_t::number_integer: // LCOV_EXCL_LINE
 | ||
|  |                 case value_t::number_unsigned: // LCOV_EXCL_LINE
 | ||
|  |                 case value_t::number_float: // LCOV_EXCL_LINE
 | ||
|  |                 case value_t::binary: // LCOV_EXCL_LINE
 | ||
|  |                 case value_t::discarded: // LCOV_EXCL_LINE
 | ||
|  |                 default:   // LCOV_EXCL_LINE
 | ||
|  |                     break; // LCOV_EXCL_LINE
 | ||
|  |             } | ||
|  |         } | ||
|  | 
 | ||
|  |         if (tokens.empty()) | ||
|  |         { | ||
|  |             return ""; | ||
|  |         } | ||
|  | 
 | ||
|  |         auto str = std::accumulate(tokens.rbegin(), tokens.rend(), std::string{}, | ||
|  |                                    [](const std::string & a, const std::string & b) | ||
|  |         { | ||
|  |             return concat(a, '/', detail::escape(b)); | ||
|  |         }); | ||
|  |         return concat('(', str, ") "); | ||
|  | #else
 | ||
|  |         static_cast<void>(leaf_element); | ||
|  |         return ""; | ||
|  | #endif
 | ||
|  |     } | ||
|  | 
 | ||
|  |   private: | ||
|  |     /// an exception object as storage for error messages
 | ||
|  |     std::runtime_error m; | ||
|  | }; | ||
|  | 
 | ||
|  | /// @brief exception indicating a parse error
 | ||
|  | /// @sa https://json.nlohmann.me/api/basic_json/parse_error/
 | ||
|  | class parse_error : public exception | ||
|  | { | ||
|  |   public: | ||
|  |     /*!
 | ||
|  |     @brief create a parse error exception | ||
|  |     @param[in] id_       the id of the exception | ||
|  |     @param[in] pos       the position where the error occurred (or with | ||
|  |                          chars_read_total=0 if the position cannot be | ||
|  |                          determined) | ||
|  |     @param[in] what_arg  the explanatory string | ||
|  |     @return parse_error object | ||
|  |     */ | ||
|  |     template<typename BasicJsonContext, enable_if_t<is_basic_json_context<BasicJsonContext>::value, int> = 0> | ||
|  |     static parse_error create(int id_, const position_t& pos, const std::string& what_arg, BasicJsonContext context) | ||
|  |     { | ||
|  |         const std::string w = concat(exception::name("parse_error", id_), "parse error", | ||
|  |                                      position_string(pos), ": ", exception::diagnostics(context), what_arg); | ||
|  |         return {id_, pos.chars_read_total, w.c_str()}; | ||
|  |     } | ||
|  | 
 | ||
|  |     template<typename BasicJsonContext, enable_if_t<is_basic_json_context<BasicJsonContext>::value, int> = 0> | ||
|  |     static parse_error create(int id_, std::size_t byte_, const std::string& what_arg, BasicJsonContext context) | ||
|  |     { | ||
|  |         const std::string w = concat(exception::name("parse_error", id_), "parse error", | ||
|  |                                      (byte_ != 0 ? (concat(" at byte ", std::to_string(byte_))) : ""), | ||
|  |                                      ": ", exception::diagnostics(context), what_arg); | ||
|  |         return {id_, byte_, w.c_str()}; | ||
|  |     } | ||
|  | 
 | ||
|  |     /*!
 | ||
|  |     @brief byte index of the parse error | ||
|  | 
 | ||
|  |     The byte index of the last read character in the input file. | ||
|  | 
 | ||
|  |     @note For an input with n bytes, 1 is the index of the first character and | ||
|  |           n+1 is the index of the terminating null byte or the end of file. | ||
|  |           This also holds true when reading a byte vector (CBOR or MessagePack). | ||
|  |     */ | ||
|  |     const std::size_t byte; | ||
|  | 
 | ||
|  |   private: | ||
|  |     parse_error(int id_, std::size_t byte_, const char* what_arg) | ||
|  |         : exception(id_, what_arg), byte(byte_) {} | ||
|  | 
 | ||
|  |     static std::string position_string(const position_t& pos) | ||
|  |     { | ||
|  |         return concat(" at line ", std::to_string(pos.lines_read + 1), | ||
|  |                       ", column ", std::to_string(pos.chars_read_current_line)); | ||
|  |     } | ||
|  | }; | ||
|  | 
 | ||
|  | /// @brief exception indicating errors with iterators
 | ||
|  | /// @sa https://json.nlohmann.me/api/basic_json/invalid_iterator/
 | ||
|  | class invalid_iterator : public exception | ||
|  | { | ||
|  |   public: | ||
|  |     template<typename BasicJsonContext, enable_if_t<is_basic_json_context<BasicJsonContext>::value, int> = 0> | ||
|  |     static invalid_iterator create(int id_, const std::string& what_arg, BasicJsonContext context) | ||
|  |     { | ||
|  |         const std::string w = concat(exception::name("invalid_iterator", id_), exception::diagnostics(context), what_arg); | ||
|  |         return {id_, w.c_str()}; | ||
|  |     } | ||
|  | 
 | ||
|  |   private: | ||
|  |     JSON_HEDLEY_NON_NULL(3) | ||
|  |     invalid_iterator(int id_, const char* what_arg) | ||
|  |         : exception(id_, what_arg) {} | ||
|  | }; | ||
|  | 
 | ||
|  | /// @brief exception indicating executing a member function with a wrong type
 | ||
|  | /// @sa https://json.nlohmann.me/api/basic_json/type_error/
 | ||
|  | class type_error : public exception | ||
|  | { | ||
|  |   public: | ||
|  |     template<typename BasicJsonContext, enable_if_t<is_basic_json_context<BasicJsonContext>::value, int> = 0> | ||
|  |     static type_error create(int id_, const std::string& what_arg, BasicJsonContext context) | ||
|  |     { | ||
|  |         const std::string w = concat(exception::name("type_error", id_), exception::diagnostics(context), what_arg); | ||
|  |         return {id_, w.c_str()}; | ||
|  |     } | ||
|  | 
 | ||
|  |   private: | ||
|  |     JSON_HEDLEY_NON_NULL(3) | ||
|  |     type_error(int id_, const char* what_arg) : exception(id_, what_arg) {} | ||
|  | }; | ||
|  | 
 | ||
|  | /// @brief exception indicating access out of the defined range
 | ||
|  | /// @sa https://json.nlohmann.me/api/basic_json/out_of_range/
 | ||
|  | class out_of_range : public exception | ||
|  | { | ||
|  |   public: | ||
|  |     template<typename BasicJsonContext, enable_if_t<is_basic_json_context<BasicJsonContext>::value, int> = 0> | ||
|  |     static out_of_range create(int id_, const std::string& what_arg, BasicJsonContext context) | ||
|  |     { | ||
|  |         const std::string w = concat(exception::name("out_of_range", id_), exception::diagnostics(context), what_arg); | ||
|  |         return {id_, w.c_str()}; | ||
|  |     } | ||
|  | 
 | ||
|  |   private: | ||
|  |     JSON_HEDLEY_NON_NULL(3) | ||
|  |     out_of_range(int id_, const char* what_arg) : exception(id_, what_arg) {} | ||
|  | }; | ||
|  | 
 | ||
|  | /// @brief exception indicating other library errors
 | ||
|  | /// @sa https://json.nlohmann.me/api/basic_json/other_error/
 | ||
|  | class other_error : public exception | ||
|  | { | ||
|  |   public: | ||
|  |     template<typename BasicJsonContext, enable_if_t<is_basic_json_context<BasicJsonContext>::value, int> = 0> | ||
|  |     static other_error create(int id_, const std::string& what_arg, BasicJsonContext context) | ||
|  |     { | ||
|  |         const std::string w = concat(exception::name("other_error", id_), exception::diagnostics(context), what_arg); | ||
|  |         return {id_, w.c_str()}; | ||
|  |     } | ||
|  | 
 | ||
|  |   private: | ||
|  |     JSON_HEDLEY_NON_NULL(3) | ||
|  |     other_error(int id_, const char* what_arg) : exception(id_, what_arg) {} | ||
|  | }; | ||
|  | 
 | ||
|  | }  // namespace detail
 | ||
|  | NLOHMANN_JSON_NAMESPACE_END |