/src/simdjson/include/simdjson/error.h
Line | Count | Source (jump to first uncovered line) |
1 | | #ifndef SIMDJSON_ERROR_H |
2 | | #define SIMDJSON_ERROR_H |
3 | | |
4 | | #include "simdjson/common_defs.h" |
5 | | #include <string> |
6 | | |
7 | | namespace simdjson { |
8 | | |
9 | | /** |
10 | | * All possible errors returned by simdjson. These error codes are subject to change |
11 | | * and not all simdjson kernel returns the same error code given the same input: it is not |
12 | | * well defined which error a given input should produce. |
13 | | * |
14 | | * Only SUCCESS evaluates to false as a Boolean. All other error codes will evaluate |
15 | | * to true as a Boolean. |
16 | | */ |
17 | | enum error_code { |
18 | | SUCCESS = 0, ///< No error |
19 | | CAPACITY, ///< This parser can't support a document that big |
20 | | MEMALLOC, ///< Error allocating memory, most likely out of memory |
21 | | TAPE_ERROR, ///< Something went wrong, this is a generic error |
22 | | DEPTH_ERROR, ///< Your document exceeds the user-specified depth limitation |
23 | | STRING_ERROR, ///< Problem while parsing a string |
24 | | T_ATOM_ERROR, ///< Problem while parsing an atom starting with the letter 't' |
25 | | F_ATOM_ERROR, ///< Problem while parsing an atom starting with the letter 'f' |
26 | | N_ATOM_ERROR, ///< Problem while parsing an atom starting with the letter 'n' |
27 | | NUMBER_ERROR, ///< Problem while parsing a number |
28 | | UTF8_ERROR, ///< the input is not valid UTF-8 |
29 | | UNINITIALIZED, ///< unknown error, or uninitialized document |
30 | | EMPTY, ///< no structural element found |
31 | | UNESCAPED_CHARS, ///< found unescaped characters in a string. |
32 | | UNCLOSED_STRING, ///< missing quote at the end |
33 | | UNSUPPORTED_ARCHITECTURE, ///< unsupported architecture |
34 | | INCORRECT_TYPE, ///< JSON element has a different type than user expected |
35 | | NUMBER_OUT_OF_RANGE, ///< JSON number does not fit in 64 bits |
36 | | INDEX_OUT_OF_BOUNDS, ///< JSON array index too large |
37 | | NO_SUCH_FIELD, ///< JSON field not found in object |
38 | | IO_ERROR, ///< Error reading a file |
39 | | INVALID_JSON_POINTER, ///< Invalid JSON pointer reference |
40 | | INVALID_URI_FRAGMENT, ///< Invalid URI fragment |
41 | | UNEXPECTED_ERROR, ///< indicative of a bug in simdjson |
42 | | PARSER_IN_USE, ///< parser is already in use. |
43 | | OUT_OF_ORDER_ITERATION, ///< tried to iterate an array or object out of order |
44 | | INSUFFICIENT_PADDING, ///< The JSON doesn't have enough padding for simdjson to safely parse it. |
45 | | INCOMPLETE_ARRAY_OR_OBJECT, ///< The document ends early. |
46 | | SCALAR_DOCUMENT_AS_VALUE, ///< A scalar document is treated as a value. |
47 | | OUT_OF_BOUNDS, ///< Attempted to access location outside of document. |
48 | | TRAILING_CONTENT, ///< Unexpected trailing content in the JSON input |
49 | | NUM_ERROR_CODES |
50 | | }; |
51 | | |
52 | | /** |
53 | | * Get the error message for the given error code. |
54 | | * |
55 | | * dom::parser parser; |
56 | | * dom::element doc; |
57 | | * auto error = parser.parse("foo",3).get(doc); |
58 | | * if (error) { printf("Error: %s\n", error_message(error)); } |
59 | | * |
60 | | * @return The error message. |
61 | | */ |
62 | | inline const char *error_message(error_code error) noexcept; |
63 | | |
64 | | /** |
65 | | * Write the error message to the output stream |
66 | | */ |
67 | | inline std::ostream& operator<<(std::ostream& out, error_code error) noexcept; |
68 | | |
69 | | /** |
70 | | * Exception thrown when an exception-supporting simdjson method is called |
71 | | */ |
72 | | struct simdjson_error : public std::exception { |
73 | | /** |
74 | | * Create an exception from a simdjson error code. |
75 | | * @param error The error code |
76 | | */ |
77 | 0 | simdjson_error(error_code error) noexcept : _error{error} { } |
78 | | /** The error message */ |
79 | 0 | const char *what() const noexcept { return error_message(error()); } |
80 | | /** The error code */ |
81 | 0 | error_code error() const noexcept { return _error; } |
82 | | private: |
83 | | /** The error code that was used */ |
84 | | error_code _error; |
85 | | }; |
86 | | |
87 | | namespace internal { |
88 | | |
89 | | /** |
90 | | * The result of a simdjson operation that could fail. |
91 | | * |
92 | | * Gives the option of reading error codes, or throwing an exception by casting to the desired result. |
93 | | * |
94 | | * This is a base class for implementations that want to add functions to the result type for |
95 | | * chaining. |
96 | | * |
97 | | * Override like: |
98 | | * |
99 | | * struct simdjson_result<T> : public internal::simdjson_result_base<T> { |
100 | | * simdjson_result() noexcept : internal::simdjson_result_base<T>() {} |
101 | | * simdjson_result(error_code error) noexcept : internal::simdjson_result_base<T>(error) {} |
102 | | * simdjson_result(T &&value) noexcept : internal::simdjson_result_base<T>(std::forward(value)) {} |
103 | | * simdjson_result(T &&value, error_code error) noexcept : internal::simdjson_result_base<T>(value, error) {} |
104 | | * // Your extra methods here |
105 | | * } |
106 | | * |
107 | | * Then any method returning simdjson_result<T> will be chainable with your methods. |
108 | | */ |
109 | | template<typename T> |
110 | | struct simdjson_result_base : protected std::pair<T, error_code> { |
111 | | |
112 | | /** |
113 | | * Create a new empty result with error = UNINITIALIZED. |
114 | | */ |
115 | | simdjson_inline simdjson_result_base() noexcept; |
116 | | |
117 | | /** |
118 | | * Create a new error result. |
119 | | */ |
120 | | simdjson_inline simdjson_result_base(error_code error) noexcept; |
121 | | |
122 | | /** |
123 | | * Create a new successful result. |
124 | | */ |
125 | | simdjson_inline simdjson_result_base(T &&value) noexcept; |
126 | | |
127 | | /** |
128 | | * Create a new result with both things (use if you don't want to branch when creating the result). |
129 | | */ |
130 | | simdjson_inline simdjson_result_base(T &&value, error_code error) noexcept; |
131 | | |
132 | | /** |
133 | | * Move the value and the error to the provided variables. |
134 | | * |
135 | | * @param value The variable to assign the value to. May not be set if there is an error. |
136 | | * @param error The variable to assign the error to. Set to SUCCESS if there is no error. |
137 | | */ |
138 | | simdjson_inline void tie(T &value, error_code &error) && noexcept; |
139 | | |
140 | | /** |
141 | | * Move the value to the provided variable. |
142 | | * |
143 | | * @param value The variable to assign the value to. May not be set if there is an error. |
144 | | */ |
145 | | simdjson_inline error_code get(T &value) && noexcept; |
146 | | |
147 | | /** |
148 | | * The error. |
149 | | */ |
150 | | simdjson_inline error_code error() const noexcept; |
151 | | |
152 | | #if SIMDJSON_EXCEPTIONS |
153 | | |
154 | | /** |
155 | | * Get the result value. |
156 | | * |
157 | | * @throw simdjson_error if there was an error. |
158 | | */ |
159 | | simdjson_inline T& value() & noexcept(false); |
160 | | |
161 | | /** |
162 | | * Take the result value (move it). |
163 | | * |
164 | | * @throw simdjson_error if there was an error. |
165 | | */ |
166 | | simdjson_inline T&& value() && noexcept(false); |
167 | | |
168 | | /** |
169 | | * Take the result value (move it). |
170 | | * |
171 | | * @throw simdjson_error if there was an error. |
172 | | */ |
173 | | simdjson_inline T&& take_value() && noexcept(false); |
174 | | |
175 | | /** |
176 | | * Cast to the value (will throw on error). |
177 | | * |
178 | | * @throw simdjson_error if there was an error. |
179 | | */ |
180 | | simdjson_inline operator T&&() && noexcept(false); |
181 | | #endif // SIMDJSON_EXCEPTIONS |
182 | | |
183 | | /** |
184 | | * Get the result value. This function is safe if and only |
185 | | * the error() method returns a value that evaluates to false. |
186 | | */ |
187 | | simdjson_inline const T& value_unsafe() const& noexcept; |
188 | | |
189 | | /** |
190 | | * Take the result value (move it). This function is safe if and only |
191 | | * the error() method returns a value that evaluates to false. |
192 | | */ |
193 | | simdjson_inline T&& value_unsafe() && noexcept; |
194 | | |
195 | | }; // struct simdjson_result_base |
196 | | |
197 | | } // namespace internal |
198 | | |
199 | | /** |
200 | | * The result of a simdjson operation that could fail. |
201 | | * |
202 | | * Gives the option of reading error codes, or throwing an exception by casting to the desired result. |
203 | | */ |
204 | | template<typename T> |
205 | | struct simdjson_result : public internal::simdjson_result_base<T> { |
206 | | /** |
207 | | * @private Create a new empty result with error = UNINITIALIZED. |
208 | | */ |
209 | | simdjson_inline simdjson_result() noexcept; |
210 | | /** |
211 | | * @private Create a new error result. |
212 | | */ |
213 | | simdjson_inline simdjson_result(T &&value) noexcept; |
214 | | /** |
215 | | * @private Create a new successful result. |
216 | | */ |
217 | | simdjson_inline simdjson_result(error_code error_code) noexcept; |
218 | | /** |
219 | | * @private Create a new result with both things (use if you don't want to branch when creating the result). |
220 | | */ |
221 | | simdjson_inline simdjson_result(T &&value, error_code error) noexcept; |
222 | | |
223 | | /** |
224 | | * Move the value and the error to the provided variables. |
225 | | * |
226 | | * @param value The variable to assign the value to. May not be set if there is an error. |
227 | | * @param error The variable to assign the error to. Set to SUCCESS if there is no error. |
228 | | */ |
229 | | simdjson_inline void tie(T &value, error_code &error) && noexcept; |
230 | | |
231 | | /** |
232 | | * Move the value to the provided variable. |
233 | | * |
234 | | * @param value The variable to assign the value to. May not be set if there is an error. |
235 | | */ |
236 | | simdjson_warn_unused simdjson_inline error_code get(T &value) && noexcept; |
237 | | |
238 | | /** |
239 | | * The error. |
240 | | */ |
241 | | simdjson_inline error_code error() const noexcept; |
242 | | |
243 | | #if SIMDJSON_EXCEPTIONS |
244 | | |
245 | | /** |
246 | | * Get the result value. |
247 | | * |
248 | | * @throw simdjson_error if there was an error. |
249 | | */ |
250 | | simdjson_inline T& value() & noexcept(false); |
251 | | |
252 | | /** |
253 | | * Take the result value (move it). |
254 | | * |
255 | | * @throw simdjson_error if there was an error. |
256 | | */ |
257 | | simdjson_inline T&& value() && noexcept(false); |
258 | | |
259 | | /** |
260 | | * Take the result value (move it). |
261 | | * |
262 | | * @throw simdjson_error if there was an error. |
263 | | */ |
264 | | simdjson_inline T&& take_value() && noexcept(false); |
265 | | |
266 | | /** |
267 | | * Cast to the value (will throw on error). |
268 | | * |
269 | | * @throw simdjson_error if there was an error. |
270 | | */ |
271 | | simdjson_inline operator T&&() && noexcept(false); |
272 | | #endif // SIMDJSON_EXCEPTIONS |
273 | | |
274 | | /** |
275 | | * Get the result value. This function is safe if and only |
276 | | * the error() method returns a value that evaluates to false. |
277 | | */ |
278 | | simdjson_inline const T& value_unsafe() const& noexcept; |
279 | | |
280 | | /** |
281 | | * Take the result value (move it). This function is safe if and only |
282 | | * the error() method returns a value that evaluates to false. |
283 | | */ |
284 | | simdjson_inline T&& value_unsafe() && noexcept; |
285 | | |
286 | | }; // struct simdjson_result |
287 | | |
288 | | #if SIMDJSON_EXCEPTIONS |
289 | | |
290 | | template<typename T> |
291 | | inline std::ostream& operator<<(std::ostream& out, simdjson_result<T> value) { return out << value.value(); } |
292 | | #endif // SIMDJSON_EXCEPTIONS |
293 | | |
294 | | #ifndef SIMDJSON_DISABLE_DEPRECATED_API |
295 | | /** |
296 | | * @deprecated This is an alias and will be removed, use error_code instead |
297 | | */ |
298 | | using ErrorValues [[deprecated("This is an alias and will be removed, use error_code instead")]] = error_code; |
299 | | |
300 | | /** |
301 | | * @deprecated Error codes should be stored and returned as `error_code`, use `error_message()` instead. |
302 | | */ |
303 | | [[deprecated("Error codes should be stored and returned as `error_code`, use `error_message()` instead.")]] |
304 | | inline const std::string error_message(int error) noexcept; |
305 | | #endif // SIMDJSON_DISABLE_DEPRECATED_API |
306 | | } // namespace simdjson |
307 | | |
308 | | #endif // SIMDJSON_ERROR_H |