Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
godotengine
GitHub Repository: godotengine/godot
Path: blob/master/thirdparty/openxr/src/external/jsoncpp/include/json/reader.h
9913 views
1
// Copyright 2007-2010 Baptiste Lepilleur and The JsonCpp Authors
2
// Distributed under MIT license, or public domain if desired and
3
// recognized in your jurisdiction.
4
// See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE
5
6
#ifndef JSON_READER_H_INCLUDED
7
#define JSON_READER_H_INCLUDED
8
9
#if !defined(JSON_IS_AMALGAMATION)
10
#include "json_features.h"
11
#include "value.h"
12
#endif // if !defined(JSON_IS_AMALGAMATION)
13
#include <deque>
14
#include <iosfwd>
15
#include <istream>
16
#include <stack>
17
#include <string>
18
19
// Disable warning C4251: <data member>: <type> needs to have dll-interface to
20
// be used by...
21
#if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING)
22
#pragma warning(push)
23
#pragma warning(disable : 4251)
24
#endif // if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING)
25
26
#pragma pack(push)
27
#pragma pack()
28
29
namespace Json {
30
31
/** \brief Unserialize a <a HREF="http://www.json.org">JSON</a> document into a
32
* Value.
33
*
34
* \deprecated Use CharReader and CharReaderBuilder.
35
*/
36
37
class JSON_API Reader {
38
public:
39
using Char = char;
40
using Location = const Char*;
41
42
/** \brief An error tagged with where in the JSON text it was encountered.
43
*
44
* The offsets give the [start, limit) range of bytes within the text. Note
45
* that this is bytes, not codepoints.
46
*/
47
struct StructuredError {
48
ptrdiff_t offset_start;
49
ptrdiff_t offset_limit;
50
String message;
51
};
52
53
/** \brief Constructs a Reader allowing all features for parsing.
54
* \deprecated Use CharReader and CharReaderBuilder.
55
*/
56
Reader();
57
58
/** \brief Constructs a Reader allowing the specified feature set for parsing.
59
* \deprecated Use CharReader and CharReaderBuilder.
60
*/
61
Reader(const Features& features);
62
63
/** \brief Read a Value from a <a HREF="http://www.json.org">JSON</a>
64
* document.
65
*
66
* \param document UTF-8 encoded string containing the document
67
* to read.
68
* \param[out] root Contains the root value of the document if it
69
* was successfully parsed.
70
* \param collectComments \c true to collect comment and allow writing
71
* them back during serialization, \c false to
72
* discard comments. This parameter is ignored
73
* if Features::allowComments_ is \c false.
74
* \return \c true if the document was successfully parsed, \c false if an
75
* error occurred.
76
*/
77
bool parse(const std::string& document, Value& root,
78
bool collectComments = true);
79
80
/** \brief Read a Value from a <a HREF="http://www.json.org">JSON</a>
81
* document.
82
*
83
* \param beginDoc Pointer on the beginning of the UTF-8 encoded
84
* string of the document to read.
85
* \param endDoc Pointer on the end of the UTF-8 encoded string
86
* of the document to read. Must be >= beginDoc.
87
* \param[out] root Contains the root value of the document if it
88
* was successfully parsed.
89
* \param collectComments \c true to collect comment and allow writing
90
* them back during serialization, \c false to
91
* discard comments. This parameter is ignored
92
* if Features::allowComments_ is \c false.
93
* \return \c true if the document was successfully parsed, \c false if an
94
* error occurred.
95
*/
96
bool parse(const char* beginDoc, const char* endDoc, Value& root,
97
bool collectComments = true);
98
99
/// \brief Parse from input stream.
100
/// \see Json::operator>>(std::istream&, Json::Value&).
101
bool parse(IStream& is, Value& root, bool collectComments = true);
102
103
/** \brief Returns a user friendly string that list errors in the parsed
104
* document.
105
*
106
* \return Formatted error message with the list of errors with their
107
* location in the parsed document. An empty string is returned if no error
108
* occurred during parsing.
109
* \deprecated Use getFormattedErrorMessages() instead (typo fix).
110
*/
111
JSONCPP_DEPRECATED("Use getFormattedErrorMessages() instead.")
112
String getFormatedErrorMessages() const;
113
114
/** \brief Returns a user friendly string that list errors in the parsed
115
* document.
116
*
117
* \return Formatted error message with the list of errors with their
118
* location in the parsed document. An empty string is returned if no error
119
* occurred during parsing.
120
*/
121
String getFormattedErrorMessages() const;
122
123
/** \brief Returns a vector of structured errors encountered while parsing.
124
*
125
* \return A (possibly empty) vector of StructuredError objects. Currently
126
* only one error can be returned, but the caller should tolerate multiple
127
* errors. This can occur if the parser recovers from a non-fatal parse
128
* error and then encounters additional errors.
129
*/
130
std::vector<StructuredError> getStructuredErrors() const;
131
132
/** \brief Add a semantic error message.
133
*
134
* \param value JSON Value location associated with the error
135
* \param message The error message.
136
* \return \c true if the error was successfully added, \c false if the Value
137
* offset exceeds the document size.
138
*/
139
bool pushError(const Value& value, const String& message);
140
141
/** \brief Add a semantic error message with extra context.
142
*
143
* \param value JSON Value location associated with the error
144
* \param message The error message.
145
* \param extra Additional JSON Value location to contextualize the error
146
* \return \c true if the error was successfully added, \c false if either
147
* Value offset exceeds the document size.
148
*/
149
bool pushError(const Value& value, const String& message, const Value& extra);
150
151
/** \brief Return whether there are any errors.
152
*
153
* \return \c true if there are no errors to report \c false if errors have
154
* occurred.
155
*/
156
bool good() const;
157
158
private:
159
enum TokenType {
160
tokenEndOfStream = 0,
161
tokenObjectBegin,
162
tokenObjectEnd,
163
tokenArrayBegin,
164
tokenArrayEnd,
165
tokenString,
166
tokenNumber,
167
tokenTrue,
168
tokenFalse,
169
tokenNull,
170
tokenArraySeparator,
171
tokenMemberSeparator,
172
tokenComment,
173
tokenError
174
};
175
176
class Token {
177
public:
178
TokenType type_;
179
Location start_;
180
Location end_;
181
};
182
183
class ErrorInfo {
184
public:
185
Token token_;
186
String message_;
187
Location extra_;
188
};
189
190
using Errors = std::deque<ErrorInfo>;
191
192
bool readToken(Token& token);
193
bool readTokenSkippingComments(Token& token);
194
void skipSpaces();
195
bool match(const Char* pattern, int patternLength);
196
bool readComment();
197
bool readCStyleComment();
198
bool readCppStyleComment();
199
bool readString();
200
void readNumber();
201
bool readValue();
202
bool readObject(Token& token);
203
bool readArray(Token& token);
204
bool decodeNumber(Token& token);
205
bool decodeNumber(Token& token, Value& decoded);
206
bool decodeString(Token& token);
207
bool decodeString(Token& token, String& decoded);
208
bool decodeDouble(Token& token);
209
bool decodeDouble(Token& token, Value& decoded);
210
bool decodeUnicodeCodePoint(Token& token, Location& current, Location end,
211
unsigned int& unicode);
212
bool decodeUnicodeEscapeSequence(Token& token, Location& current,
213
Location end, unsigned int& unicode);
214
bool addError(const String& message, Token& token, Location extra = nullptr);
215
bool recoverFromError(TokenType skipUntilToken);
216
bool addErrorAndRecover(const String& message, Token& token,
217
TokenType skipUntilToken);
218
void skipUntilSpace();
219
Value& currentValue();
220
Char getNextChar();
221
void getLocationLineAndColumn(Location location, int& line,
222
int& column) const;
223
String getLocationLineAndColumn(Location location) const;
224
void addComment(Location begin, Location end, CommentPlacement placement);
225
226
static bool containsNewLine(Location begin, Location end);
227
static String normalizeEOL(Location begin, Location end);
228
229
using Nodes = std::stack<Value*>;
230
Nodes nodes_;
231
Errors errors_;
232
String document_;
233
Location begin_{};
234
Location end_{};
235
Location current_{};
236
Location lastValueEnd_{};
237
Value* lastValue_{};
238
String commentsBefore_;
239
Features features_;
240
bool collectComments_{};
241
}; // Reader
242
243
/** Interface for reading JSON from a char array.
244
*/
245
class JSON_API CharReader {
246
public:
247
struct JSON_API StructuredError {
248
ptrdiff_t offset_start;
249
ptrdiff_t offset_limit;
250
String message;
251
};
252
253
virtual ~CharReader() = default;
254
/** \brief Read a Value from a <a HREF="http://www.json.org">JSON</a>
255
* document. The document must be a UTF-8 encoded string containing the
256
* document to read.
257
*
258
* \param beginDoc Pointer on the beginning of the UTF-8 encoded string
259
* of the document to read.
260
* \param endDoc Pointer on the end of the UTF-8 encoded string of the
261
* document to read. Must be >= beginDoc.
262
* \param[out] root Contains the root value of the document if it was
263
* successfully parsed.
264
* \param[out] errs Formatted error messages (if not NULL) a user
265
* friendly string that lists errors in the parsed
266
* document.
267
* \return \c true if the document was successfully parsed, \c false if an
268
* error occurred.
269
*/
270
virtual bool parse(char const* beginDoc, char const* endDoc, Value* root,
271
String* errs);
272
273
/** \brief Returns a vector of structured errors encountered while parsing.
274
* Each parse call resets the stored list of errors.
275
*/
276
std::vector<StructuredError> getStructuredErrors() const;
277
278
class JSON_API Factory {
279
public:
280
virtual ~Factory() = default;
281
/** \brief Allocate a CharReader via operator new().
282
* \throw std::exception if something goes wrong (e.g. invalid settings)
283
*/
284
virtual CharReader* newCharReader() const = 0;
285
}; // Factory
286
287
protected:
288
class Impl {
289
public:
290
virtual ~Impl() = default;
291
virtual bool parse(char const* beginDoc, char const* endDoc, Value* root,
292
String* errs) = 0;
293
virtual std::vector<StructuredError> getStructuredErrors() const = 0;
294
};
295
296
explicit CharReader(std::unique_ptr<Impl> impl) : _impl(std::move(impl)) {}
297
298
private:
299
std::unique_ptr<Impl> _impl;
300
}; // CharReader
301
302
/** \brief Build a CharReader implementation.
303
*
304
* Usage:
305
* \code
306
* using namespace Json;
307
* CharReaderBuilder builder;
308
* builder["collectComments"] = false;
309
* Value value;
310
* String errs;
311
* bool ok = parseFromStream(builder, std::cin, &value, &errs);
312
* \endcode
313
*/
314
class JSON_API CharReaderBuilder : public CharReader::Factory {
315
public:
316
// Note: We use a Json::Value so that we can add data-members to this class
317
// without a major version bump.
318
/** Configuration of this builder.
319
* These are case-sensitive.
320
* Available settings (case-sensitive):
321
* - `"collectComments": false or true`
322
* - true to collect comment and allow writing them back during
323
* serialization, false to discard comments. This parameter is ignored
324
* if allowComments is false.
325
* - `"allowComments": false or true`
326
* - true if comments are allowed.
327
* - `"allowTrailingCommas": false or true`
328
* - true if trailing commas in objects and arrays are allowed.
329
* - `"strictRoot": false or true`
330
* - true if root must be either an array or an object value
331
* - `"allowDroppedNullPlaceholders": false or true`
332
* - true if dropped null placeholders are allowed. (See
333
* StreamWriterBuilder.)
334
* - `"allowNumericKeys": false or true`
335
* - true if numeric object keys are allowed.
336
* - `"allowSingleQuotes": false or true`
337
* - true if '' are allowed for strings (both keys and values)
338
* - `"stackLimit": integer`
339
* - Exceeding stackLimit (recursive depth of `readValue()`) will cause an
340
* exception.
341
* - This is a security issue (seg-faults caused by deeply nested JSON), so
342
* the default is low.
343
* - `"failIfExtra": false or true`
344
* - If true, `parse()` returns false when extra non-whitespace trails the
345
* JSON value in the input string.
346
* - `"rejectDupKeys": false or true`
347
* - If true, `parse()` returns false when a key is duplicated within an
348
* object.
349
* - `"allowSpecialFloats": false or true`
350
* - If true, special float values (NaNs and infinities) are allowed and
351
* their values are lossfree restorable.
352
* - `"skipBom": false or true`
353
* - If true, if the input starts with the Unicode byte order mark (BOM),
354
* it is skipped.
355
*
356
* You can examine 'settings_` yourself to see the defaults. You can also
357
* write and read them just like any JSON Value.
358
* \sa setDefaults()
359
*/
360
Json::Value settings_;
361
362
CharReaderBuilder();
363
~CharReaderBuilder() override;
364
365
CharReader* newCharReader() const override;
366
367
/** \return true if 'settings' are legal and consistent;
368
* otherwise, indicate bad settings via 'invalid'.
369
*/
370
bool validate(Json::Value* invalid) const;
371
372
/** A simple way to update a specific setting.
373
*/
374
Value& operator[](const String& key);
375
376
/** Called by ctor, but you can use this to reset settings_.
377
* \pre 'settings' != NULL (but Json::null is fine)
378
* \remark Defaults:
379
* \snippet src/lib_json/json_reader.cpp CharReaderBuilderDefaults
380
*/
381
static void setDefaults(Json::Value* settings);
382
/** Same as old Features::strictMode().
383
* \pre 'settings' != NULL (but Json::null is fine)
384
* \remark Defaults:
385
* \snippet src/lib_json/json_reader.cpp CharReaderBuilderStrictMode
386
*/
387
static void strictMode(Json::Value* settings);
388
/** ECMA-404 mode.
389
* \pre 'settings' != NULL (but Json::null is fine)
390
* \remark Defaults:
391
* \snippet src/lib_json/json_reader.cpp CharReaderBuilderECMA404Mode
392
*/
393
static void ecma404Mode(Json::Value* settings);
394
};
395
396
/** Consume entire stream and use its begin/end.
397
* Someday we might have a real StreamReader, but for now this
398
* is convenient.
399
*/
400
bool JSON_API parseFromStream(CharReader::Factory const&, IStream&, Value* root,
401
String* errs);
402
403
/** \brief Read from 'sin' into 'root'.
404
*
405
* Always keep comments from the input JSON.
406
*
407
* This can be used to read a file into a particular sub-object.
408
* For example:
409
* \code
410
* Json::Value root;
411
* cin >> root["dir"]["file"];
412
* cout << root;
413
* \endcode
414
* Result:
415
* \verbatim
416
* {
417
* "dir": {
418
* "file": {
419
* // The input stream JSON would be nested here.
420
* }
421
* }
422
* }
423
* \endverbatim
424
* \throw std::exception on parse error.
425
* \see Json::operator<<()
426
*/
427
JSON_API IStream& operator>>(IStream&, Value&);
428
429
} // namespace Json
430
431
#pragma pack(pop)
432
433
#if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING)
434
#pragma warning(pop)
435
#endif // if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING)
436
437
#endif // JSON_READER_H_INCLUDED
438
439