• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

dota17 / jsoncpp / 10821679301

12 Sep 2024 12:14AM UTC coverage: 95.295% (+1.5%) from 93.801%
10821679301

push

github

web-flow
Merge branch 'master' into fix-cmake

189 of 212 new or added lines in 8 files covered. (89.15%)

23 existing lines in 5 files now uncovered.

5306 of 5568 relevant lines covered (95.29%)

11935.1 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

80.0
/include/json/reader.h
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 {
96✔
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 {
36✔
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 {
6✔
248
    ptrdiff_t offset_start;
249
    ptrdiff_t offset_limit;
250
    String message;
251
  };
252

UNCOV
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)) {}
894✔
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
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc