#ifndef SIMDJSON_ERROR_H #define SIMDJSON_ERROR_H #include "simdjson/common_defs.h" #include #include namespace simdjson { /** * All possible errors returned by simdjson. */ enum error_code { SUCCESS = 0, ///< No error SUCCESS_AND_HAS_MORE, ///< No error and buffer still has more data CAPACITY, ///< This parser can't support a document that big MEMALLOC, ///< Error allocating memory, most likely out of memory TAPE_ERROR, ///< Something went wrong while writing to the tape (stage 2), this is a generic error DEPTH_ERROR, ///< Your document exceeds the user-specified depth limitation STRING_ERROR, ///< Problem while parsing a string T_ATOM_ERROR, ///< Problem while parsing an atom starting with the letter 't' F_ATOM_ERROR, ///< Problem while parsing an atom starting with the letter 'f' N_ATOM_ERROR, ///< Problem while parsing an atom starting with the letter 'n' NUMBER_ERROR, ///< Problem while parsing a number UTF8_ERROR, ///< the input is not valid UTF-8 UNINITIALIZED, ///< unknown error, or uninitialized document EMPTY, ///< no structural element found UNESCAPED_CHARS, ///< found unescaped characters in a string. UNCLOSED_STRING, ///< missing quote at the end UNSUPPORTED_ARCHITECTURE, ///< unsupported architecture INCORRECT_TYPE, ///< JSON element has a different type than user expected NUMBER_OUT_OF_RANGE, ///< JSON number does not fit in 64 bits INDEX_OUT_OF_BOUNDS, ///< JSON array index too large NO_SUCH_FIELD, ///< JSON field not found in object IO_ERROR, ///< Error reading a file INVALID_JSON_POINTER, ///< Invalid JSON pointer reference INVALID_URI_FRAGMENT, ///< Invalid URI fragment UNEXPECTED_ERROR, ///< indicative of a bug in simdjson /** @private Number of error codes */ NUM_ERROR_CODES }; /** * Get the error message for the given error code. * * auto [doc, error] = document::parse("foo"); * if (error) { printf("Error: %s\n", error_message(error)); } * * @return The error message. */ inline const char *error_message(error_code error) noexcept; /** * Write the error message to the output stream */ inline std::ostream& operator<<(std::ostream& out, error_code error) noexcept; /** * Exception thrown when an exception-supporting simdjson method is called */ struct simdjson_error : public std::exception { /** * Create an exception from a simdjson error code. * @param error The error code */ simdjson_error(error_code error) noexcept : _error{error} { } /** The error message */ const char *what() const noexcept { return error_message(error()); } /** The error code */ error_code error() const noexcept { return _error; } private: /** The error code that was used */ error_code _error; }; /** * The result of a simd operation that could fail. * * Gives the option of reading error codes, or throwing an exception by casting to the desired result. */ template struct simdjson_result : public std::pair { /** * Move the value and the error to the provided variables. */ void tie(T& t, error_code & e) { // on the clang compiler that comes with current macOS (Apple clang version 11.0.0), // tie(width, error) = size["w"].as_uint64_t(); // fails with "error: no viable overloaded '='"" t = std::move(this->first); e = std::move(this->second); } /** * The error. */ error_code error() const { return this->second; } #if SIMDJSON_EXCEPTIONS /** * The value of the function. * * @throw simdjson_error if there was an error. */ T get() noexcept(false) { if (error()) { throw simdjson_error(error()); } return this->first; }; /** * Cast to the value (will throw on error). * * @throw simdjson_error if there was an error. */ operator T() noexcept(false) { return get(); } #endif // SIMDJSON_EXCEPTIONS /** * Create a new empty result with error = UNINITIALIZED. */ simdjson_result() noexcept : simdjson_result(UNINITIALIZED) {} /** * Create a new error result. */ simdjson_result(error_code _error) noexcept : std::pair({}, _error) {} /** * Create a new successful result. */ simdjson_result(T _value) noexcept : std::pair(_value, SUCCESS) {} /** * Create a new result with both things (use if you don't want to branch when creating the result). */ simdjson_result(T value, error_code error) noexcept : std::pair(value, error) {} }; /** * The result of a simd operation that could fail. * * This class is for values that must be *moved*, like padded_string and document. * * Gives the option of reading error codes, or throwing an exception by casting to the desired result. */ template struct simdjson_move_result : std::pair { /** * Move the value and the error to the provided variables. */ void tie(T& t, error_code & e) { // on the clang compiler that comes with current macOS (Apple clang version 11.0.0), // std::tie(this->json, error) = padded_string::load(filename); // fails with "benchmark/benchmarker.h:266:33: error: no viable overloaded '='"" t = std::move(this->first); e = std::move(this->second); } /** * The error. */ error_code error() const { return this->second; } #if SIMDJSON_EXCEPTIONS /** * The value of the function. * * @throw simdjson_error if there was an error. */ T move() noexcept(false) { if (error()) { throw simdjson_error(error()); } return std::move(this->first); }; /** * Cast to the value (will throw on error). * * @throw simdjson_error if there was an error. */ operator T() noexcept(false) { return move(); } #endif /** * Create a new empty result with error = UNINITIALIZED. */ simdjson_move_result() noexcept : simdjson_move_result(UNINITIALIZED) {} /** * Create a new error result. */ simdjson_move_result(error_code error) noexcept : std::pair(T(), error) {} /** * Create a new successful result. */ simdjson_move_result(T value) noexcept : std::pair(std::move(value), SUCCESS) {} /** * Create a new result with both things (use if you don't want to branch when creating the result). */ simdjson_move_result(T value, error_code error) noexcept : std::pair(std::move(value), error) {} }; /** * @deprecated This is an alias and will be removed, use error_code instead */ using ErrorValues = error_code; /** * @deprecated Error codes should be stored and returned as `error_code`, use `error_message()` instead. */ inline const std::string &error_message(int error) noexcept; } // namespace simdjson #endif // SIMDJSON_ERROR_H