blob: fb2365ab32b85000a0f75750fd08426dd2418288 [file] [log] [blame]
Devin Jeanpierre59e4d352017-07-21 03:44:36 -07001// Copyright 2007-2010 Baptiste Lepilleur and The JsonCpp Authors
Baptiste Lepilleur7469f1d2010-04-20 21:35:19 +00002// 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
Christopher Dunn6d135cb2007-06-13 15:51:04 +00006#ifndef CPPTL_JSON_READER_H_INCLUDED
Aaron Jacobs9fa4e842014-07-01 08:48:54 +10007#define CPPTL_JSON_READER_H_INCLUDED
Christopher Dunn6d135cb2007-06-13 15:51:04 +00008
Baptiste Lepilleureadc4782011-05-02 21:09:30 +00009#if !defined(JSON_IS_AMALGAMATION)
Jordan Bayles00b979f2019-09-25 14:04:53 -070010#include "json_features.h"
Aaron Jacobs9fa4e842014-07-01 08:48:54 +100011#include "value.h"
Baptiste Lepilleureadc4782011-05-02 21:09:30 +000012#endif // if !defined(JSON_IS_AMALGAMATION)
Aaron Jacobs9fa4e842014-07-01 08:48:54 +100013#include <deque>
14#include <iosfwd>
Billy Donahueb5e1fe82018-05-20 16:55:27 -040015#include <istream>
Aaron Jacobs9fa4e842014-07-01 08:48:54 +100016#include <stack>
17#include <string>
Christopher Dunn6d135cb2007-06-13 15:51:04 +000018
Aaron Jacobs9fa4e842014-07-01 08:48:54 +100019// Disable warning C4251: <data member>: <type> needs to have dll-interface to
20// be used by...
Baptiste Lepilleureafd7022013-05-08 20:21:11 +000021#if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING)
Aaron Jacobs9fa4e842014-07-01 08:48:54 +100022#pragma warning(push)
23#pragma warning(disable : 4251)
Baptiste Lepilleureafd7022013-05-08 20:21:11 +000024#endif // if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING)
25
Sergiy80d6e666f2016-12-03 22:29:14 +020026#pragma pack(push, 8)
27
dota17b27c83f2019-07-18 04:35:33 +080028#if defined(_MSC_VER)
29#pragma warning(disable : 4996)
30#endif
31
Christopher Dunn6d135cb2007-06-13 15:51:04 +000032namespace Json {
33
Aaron Jacobs9fa4e842014-07-01 08:48:54 +100034/** \brief Unserialize a <a HREF="http://www.json.org">JSON</a> document into a
Billy Donahue483eba82019-07-14 18:41:48 -040035 * Value.
Aaron Jacobs9fa4e842014-07-01 08:48:54 +100036 *
Christopher Dunn8df98f62015-02-09 11:15:39 -060037 * \deprecated Use CharReader and CharReaderBuilder.
Aaron Jacobs9fa4e842014-07-01 08:48:54 +100038 */
Jordan Bayles81ae1d52019-09-16 12:37:14 -070039class [[deprecated(
40 "deprecated Use CharReader and CharReaderBuilder.")]] JSON_API Reader {
Aaron Jacobs9fa4e842014-07-01 08:48:54 +100041public:
42 typedef char Char;
Aaron Jacobs11086dd2014-09-15 10:15:29 +100043 typedef const Char* Location;
Christopher Dunn6d135cb2007-06-13 15:51:04 +000044
Aaron Jacobs9fa4e842014-07-01 08:48:54 +100045 /** \brief An error tagged with where in the JSON text it was encountered.
46 *
47 * The offsets give the [start, limit) range of bytes within the text. Note
48 * that this is bytes, not codepoints.
Christopher Dunn6d135cb2007-06-13 15:51:04 +000049 */
Aaron Jacobs9fa4e842014-07-01 08:48:54 +100050 struct StructuredError {
Christopher Dunnd4513fc2016-02-06 09:25:20 -060051 ptrdiff_t offset_start;
52 ptrdiff_t offset_limit;
Billy Donahue1c2ed7a2019-01-17 16:35:29 -050053 String message;
Aaron Jacobs9fa4e842014-07-01 08:48:54 +100054 };
55
Billy Donahue483eba82019-07-14 18:41:48 -040056 /** \brief Constructs a Reader allowing all features for parsing.
Aaron Jacobs9fa4e842014-07-01 08:48:54 +100057 */
58 Reader();
59
Billy Donahue483eba82019-07-14 18:41:48 -040060 /** \brief Constructs a Reader allowing the specified feature set for parsing.
Aaron Jacobs9fa4e842014-07-01 08:48:54 +100061 */
Aaron Jacobs11086dd2014-09-15 10:15:29 +100062 Reader(const Features& features);
Aaron Jacobs9fa4e842014-07-01 08:48:54 +100063
64 /** \brief Read a Value from a <a HREF="http://www.json.org">JSON</a>
65 * document.
Billy Donahue483eba82019-07-14 18:41:48 -040066 *
67 * \param document UTF-8 encoded string containing the document
68 * to read.
69 * \param[out] root Contains the root value of the document if it
70 * was successfully parsed.
71 * \param collectComments \c true to collect comment and allow writing
72 * them back during serialization, \c false to
73 * discard comments. This parameter is ignored
74 * if Features::allowComments_ is \c false.
Aaron Jacobs9fa4e842014-07-01 08:48:54 +100075 * \return \c true if the document was successfully parsed, \c false if an
76 * error occurred.
77 */
Jordan Bayles81ae1d52019-09-16 12:37:14 -070078 bool parse(const std::string& document, Value& root,
79 bool collectComments = true);
Aaron Jacobs9fa4e842014-07-01 08:48:54 +100080
81 /** \brief Read a Value from a <a HREF="http://www.json.org">JSON</a>
Billy Donahue483eba82019-07-14 18:41:48 -040082 * document.
83 *
84 * \param beginDoc Pointer on the beginning of the UTF-8 encoded
85 * string of the document to read.
86 * \param endDoc Pointer on the end of the UTF-8 encoded string
87 * of the document to read. Must be >= beginDoc.
88 * \param[out] root Contains the root value of the document if it
89 * was successfully parsed.
90 * \param collectComments \c true to collect comment and allow writing
91 * them back during serialization, \c false to
92 * discard comments. This parameter is ignored
93 * if Features::allowComments_ is \c false.
Aaron Jacobs9fa4e842014-07-01 08:48:54 +100094 * \return \c true if the document was successfully parsed, \c false if an
Billy Donahue483eba82019-07-14 18:41:48 -040095 * error occurred.
Aaron Jacobs9fa4e842014-07-01 08:48:54 +100096 */
Jordan Bayles81ae1d52019-09-16 12:37:14 -070097 bool parse(const char* beginDoc, const char* endDoc, Value& root,
Aaron Jacobs9fa4e842014-07-01 08:48:54 +100098 bool collectComments = true);
99
100 /// \brief Parse from input stream.
101 /// \see Json::operator>>(std::istream&, Json::Value&).
Jordan Bayles81ae1d52019-09-16 12:37:14 -0700102 bool parse(IStream & is, Value & root, bool collectComments = true);
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000103
104 /** \brief Returns a user friendly string that list errors in the parsed
105 * document.
Billy Donahue483eba82019-07-14 18:41:48 -0400106 *
107 * \return Formatted error message with the list of errors with their
108 * location in the parsed document. An empty string is returned if no error
109 * occurred during parsing.
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000110 * \deprecated Use getFormattedErrorMessages() instead (typo fix).
111 */
Jordan Bayles81ae1d52019-09-16 12:37:14 -0700112 [[deprecated("Use getFormattedErrorMessages() instead.")]] String
113 getFormatedErrorMessages() const;
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000114
115 /** \brief Returns a user friendly string that list errors in the parsed
116 * document.
Billy Donahue483eba82019-07-14 18:41:48 -0400117 *
118 * \return Formatted error message with the list of errors with their
119 * location in the parsed document. An empty string is returned if no error
120 * occurred during parsing.
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000121 */
Billy Donahue1c2ed7a2019-01-17 16:35:29 -0500122 String getFormattedErrorMessages() const;
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000123
aliha472adb62019-08-26 15:37:05 -0400124 /** \brief Returns a vector of structured errors encountered while parsing.
Billy Donahue483eba82019-07-14 18:41:48 -0400125 *
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000126 * \return A (possibly empty) vector of StructuredError objects. Currently
Billy Donahue483eba82019-07-14 18:41:48 -0400127 * only one error can be returned, but the caller should tolerate multiple
128 * errors. This can occur if the parser recovers from a non-fatal parse
129 * error and then encounters additional errors.
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000130 */
131 std::vector<StructuredError> getStructuredErrors() const;
132
Mara Kimb84a39c2014-10-23 02:03:43 -0500133 /** \brief Add a semantic error message.
Billy Donahue483eba82019-07-14 18:41:48 -0400134 *
135 * \param value JSON Value location associated with the error
Mara Kimb84a39c2014-10-23 02:03:43 -0500136 * \param message The error message.
Billy Donahue483eba82019-07-14 18:41:48 -0400137 * \return \c true if the error was successfully added, \c false if the Value
138 * offset exceeds the document size.
Mara Kimb84a39c2014-10-23 02:03:43 -0500139 */
Billy Donahue1c2ed7a2019-01-17 16:35:29 -0500140 bool pushError(const Value& value, const String& message);
Mara Kimb84a39c2014-10-23 02:03:43 -0500141
142 /** \brief Add a semantic error message with extra context.
Billy Donahue483eba82019-07-14 18:41:48 -0400143 *
144 * \param value JSON Value location associated with the error
Mara Kimb84a39c2014-10-23 02:03:43 -0500145 * \param message The error message.
Billy Donahue483eba82019-07-14 18:41:48 -0400146 * \param extra Additional JSON Value location to contextualize the error
Mara Kimb84a39c2014-10-23 02:03:43 -0500147 * \return \c true if the error was successfully added, \c false if either
148 * Value offset exceeds the document size.
149 */
Billy Donahue1c2ed7a2019-01-17 16:35:29 -0500150 bool pushError(const Value& value, const String& message, const Value& extra);
Mara Kimb84a39c2014-10-23 02:03:43 -0500151
152 /** \brief Return whether there are any errors.
Billy Donahue483eba82019-07-14 18:41:48 -0400153 *
154 * \return \c true if there are no errors to report \c false if errors have
155 * occurred.
Mara Kimb84a39c2014-10-23 02:03:43 -0500156 */
157 bool good() const;
158
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000159private:
160 enum TokenType {
161 tokenEndOfStream = 0,
162 tokenObjectBegin,
163 tokenObjectEnd,
164 tokenArrayBegin,
165 tokenArrayEnd,
166 tokenString,
167 tokenNumber,
168 tokenTrue,
169 tokenFalse,
170 tokenNull,
171 tokenArraySeparator,
172 tokenMemberSeparator,
173 tokenComment,
174 tokenError
175 };
176
177 class Token {
178 public:
179 TokenType type_;
180 Location start_;
181 Location end_;
182 };
183
184 class ErrorInfo {
185 public:
186 Token token_;
Billy Donahue1c2ed7a2019-01-17 16:35:29 -0500187 String message_;
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000188 Location extra_;
189 };
190
191 typedef std::deque<ErrorInfo> Errors;
192
Jordan Bayles81ae1d52019-09-16 12:37:14 -0700193 bool readToken(Token & token);
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000194 void skipSpaces();
dota17db61dba2019-09-17 01:35:48 +0800195 bool match(const Char* pattern, int patternLength);
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000196 bool readComment();
197 bool readCStyleComment();
198 bool readCppStyleComment();
199 bool readString();
200 void readNumber();
201 bool readValue();
Jordan Bayles81ae1d52019-09-16 12:37:14 -0700202 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,
Aaron Jacobs11086dd2014-09-15 10:15:29 +1000211 unsigned int& unicode);
Jordan Bayles81ae1d52019-09-16 12:37:14 -0700212 bool decodeUnicodeEscapeSequence(Token & token, Location & current,
213 Location end, unsigned int& unicode);
Billy Donahue1c2ed7a2019-01-17 16:35:29 -0500214 bool addError(const String& message, Token& token, Location extra = nullptr);
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000215 bool recoverFromError(TokenType skipUntilToken);
Jordan Bayles81ae1d52019-09-16 12:37:14 -0700216 bool addErrorAndRecover(const String& message, Token& token,
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000217 TokenType skipUntilToken);
218 void skipUntilSpace();
Aaron Jacobs11086dd2014-09-15 10:15:29 +1000219 Value& currentValue();
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000220 Char getNextChar();
Jordan Bayles81ae1d52019-09-16 12:37:14 -0700221 void getLocationLineAndColumn(Location location, int& line, int& column)
222 const;
Billy Donahue1c2ed7a2019-01-17 16:35:29 -0500223 String getLocationLineAndColumn(Location location) const;
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000224 void addComment(Location begin, Location end, CommentPlacement placement);
Jordan Bayles81ae1d52019-09-16 12:37:14 -0700225 void skipCommentTokens(Token & token);
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000226
damiramef16a352017-08-02 22:44:42 -0700227 static bool containsNewLine(Location begin, Location end);
Billy Donahue1c2ed7a2019-01-17 16:35:29 -0500228 static String normalizeEOL(Location begin, Location end);
damiramef16a352017-08-02 22:44:42 -0700229
Aaron Jacobs11086dd2014-09-15 10:15:29 +1000230 typedef std::stack<Value*> Nodes;
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000231 Nodes nodes_;
232 Errors errors_;
Billy Donahue1c2ed7a2019-01-17 16:35:29 -0500233 String document_;
Hans Johnsone817e4f2019-01-14 17:09:22 -0600234 Location begin_{};
235 Location end_{};
236 Location current_{};
237 Location lastValueEnd_{};
238 Value* lastValue_{};
Billy Donahue1c2ed7a2019-01-17 16:35:29 -0500239 String commentsBefore_;
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000240 Features features_;
Hans Johnsone817e4f2019-01-14 17:09:22 -0600241 bool collectComments_{};
Billy Donahueb5e1fe82018-05-20 16:55:27 -0400242}; // Reader
Christopher Dunn2c1197c2015-01-29 14:29:40 -0600243
244/** Interface for reading JSON from a char array.
245 */
246class JSON_API CharReader {
247public:
Hans Johnsone3e05c72019-01-14 17:09:26 -0600248 virtual ~CharReader() = default;
Christopher Dunn2c1197c2015-01-29 14:29:40 -0600249 /** \brief Read a Value from a <a HREF="http://www.json.org">JSON</a>
Billy Donahue483eba82019-07-14 18:41:48 -0400250 * document. The document must be a UTF-8 encoded string containing the
251 * document to read.
Christopher Dunn2c1197c2015-01-29 14:29:40 -0600252 *
Billy Donahue483eba82019-07-14 18:41:48 -0400253 * \param beginDoc Pointer on the beginning of the UTF-8 encoded string
254 * of the document to read.
255 * \param endDoc Pointer on the end of the UTF-8 encoded string of the
256 * document to read. Must be >= beginDoc.
257 * \param[out] root Contains the root value of the document if it was
258 * successfully parsed.
259 * \param[out] errs Formatted error messages (if not NULL) a user
260 * friendly string that lists errors in the parsed
261 * document.
Christopher Dunn2c1197c2015-01-29 14:29:40 -0600262 * \return \c true if the document was successfully parsed, \c false if an
Billy Donahue483eba82019-07-14 18:41:48 -0400263 * error occurred.
Christopher Dunn2c1197c2015-01-29 14:29:40 -0600264 */
Billy Donahueb5e1fe82018-05-20 16:55:27 -0400265 virtual bool parse(char const* beginDoc,
266 char const* endDoc,
267 Value* root,
Billy Donahue1c2ed7a2019-01-17 16:35:29 -0500268 String* errs) = 0;
Christopher Dunn2c1197c2015-01-29 14:29:40 -0600269
Ben Boeckel80def662015-09-28 15:45:11 -0400270 class JSON_API Factory {
Christopher Dunn2c1197c2015-01-29 14:29:40 -0600271 public:
Hans Johnsone3e05c72019-01-14 17:09:26 -0600272 virtual ~Factory() = default;
Christopher Dunna9e1ab32015-02-09 17:22:28 -0600273 /** \brief Allocate a CharReader via operator new().
274 * \throw std::exception if something goes wrong (e.g. invalid settings)
275 */
Christopher Dunn2c1197c2015-01-29 14:29:40 -0600276 virtual CharReader* newCharReader() const = 0;
Billy Donahueb5e1fe82018-05-20 16:55:27 -0400277 }; // Factory
278}; // CharReader
Christopher Dunn2c1197c2015-01-29 14:29:40 -0600279
Christopher Dunn66a8ba22015-02-09 01:29:43 -0600280/** \brief Build a CharReader implementation.
Billy Donahue483eba82019-07-14 18:41:48 -0400281 *
282 * Usage:
283 * \code
284 * using namespace Json;
285 * CharReaderBuilder builder;
286 * builder["collectComments"] = false;
287 * Value value;
288 * String errs;
289 * bool ok = parseFromStream(builder, std::cin, &value, &errs);
290 * \endcode
291 */
Christopher Dunna9e1ab32015-02-09 17:22:28 -0600292class JSON_API CharReaderBuilder : public CharReader::Factory {
Christopher Dunn66a8ba22015-02-09 01:29:43 -0600293public:
Christopher Dunna9e1ab32015-02-09 17:22:28 -0600294 // Note: We use a Json::Value so that we can add data-members to this class
295 // without a major version bump.
296 /** Configuration of this builder.
Billy Donahue483eba82019-07-14 18:41:48 -0400297 * These are case-sensitive.
298 * Available settings (case-sensitive):
299 * - `"collectComments": false or true`
300 * - true to collect comment and allow writing them back during
301 * serialization, false to discard comments. This parameter is ignored
302 * if allowComments is false.
303 * - `"allowComments": false or true`
304 * - true if comments are allowed.
305 * - `"strictRoot": false or true`
306 * - true if root must be either an array or an object value
307 * - `"allowDroppedNullPlaceholders": false or true`
308 * - true if dropped null placeholders are allowed. (See
309 * StreamWriterBuilder.)
310 * - `"allowNumericKeys": false or true`
311 * - true if numeric object keys are allowed.
312 * - `"allowSingleQuotes": false or true`
313 * - true if '' are allowed for strings (both keys and values)
314 * - `"stackLimit": integer`
315 * - Exceeding stackLimit (recursive depth of `readValue()`) will cause an
316 * exception.
317 * - This is a security issue (seg-faults caused by deeply nested JSON), so
318 * the default is low.
319 * - `"failIfExtra": false or true`
320 * - If true, `parse()` returns false when extra non-whitespace trails the
321 * JSON value in the input string.
322 * - `"rejectDupKeys": false or true`
323 * - If true, `parse()` returns false when a key is duplicated within an
324 * object.
325 * - `"allowSpecialFloats": false or true`
326 * - If true, special float values (NaNs and infinities) are allowed and
327 * their values are lossfree restorable.
328 *
329 * You can examine 'settings_` yourself to see the defaults. You can also
330 * write and read them just like any JSON Value.
331 * \sa setDefaults()
332 */
Christopher Dunna9e1ab32015-02-09 17:22:28 -0600333 Json::Value settings_;
Christopher Dunn66a8ba22015-02-09 01:29:43 -0600334
Christopher Dunn2c1197c2015-01-29 14:29:40 -0600335 CharReaderBuilder();
Hans Johnson2853b1c2019-01-11 13:58:53 -0600336 ~CharReaderBuilder() override;
Christopher Dunn2c1197c2015-01-29 14:29:40 -0600337
Hans Johnson2853b1c2019-01-11 13:58:53 -0600338 CharReader* newCharReader() const override;
Christopher Dunna9e1ab32015-02-09 17:22:28 -0600339
Christopher Dunnf757c182015-02-09 18:24:56 -0600340 /** \return true if 'settings' are legal and consistent;
Christopher Dunna9e1ab32015-02-09 17:22:28 -0600341 * otherwise, indicate bad settings via 'invalid'.
342 */
343 bool validate(Json::Value* invalid) const;
Christopher Dunnc312dd52015-03-04 14:56:37 -0600344
345 /** A simple way to update a specific setting.
346 */
Billy Donahue1c2ed7a2019-01-17 16:35:29 -0500347 Value& operator[](const String& key);
Christopher Dunnc312dd52015-03-04 14:56:37 -0600348
Christopher Dunna9e1ab32015-02-09 17:22:28 -0600349 /** Called by ctor, but you can use this to reset settings_.
350 * \pre 'settings' != NULL (but Json::null is fine)
Christopher Dunn3cf91752015-02-09 18:16:24 -0600351 * \remark Defaults:
Christopher Dunn56650e82015-04-20 13:10:31 -0700352 * \snippet src/lib_json/json_reader.cpp CharReaderBuilderDefaults
Christopher Dunna9e1ab32015-02-09 17:22:28 -0600353 */
354 static void setDefaults(Json::Value* settings);
Christopher Dunn3cf91752015-02-09 18:16:24 -0600355 /** Same as old Features::strictMode().
356 * \pre 'settings' != NULL (but Json::null is fine)
357 * \remark Defaults:
Christopher Dunn56650e82015-04-20 13:10:31 -0700358 * \snippet src/lib_json/json_reader.cpp CharReaderBuilderStrictMode
Christopher Dunn3cf91752015-02-09 18:16:24 -0600359 */
360 static void strictMode(Json::Value* settings);
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000361};
362
Christopher Dunn2c1197c2015-01-29 14:29:40 -0600363/** Consume entire stream and use its begin/end.
Billy Donahueb5e1fe82018-05-20 16:55:27 -0400364 * Someday we might have a real StreamReader, but for now this
365 * is convenient.
366 */
367bool JSON_API parseFromStream(CharReader::Factory const&,
Billy Donahue1c2ed7a2019-01-17 16:35:29 -0500368 IStream&,
Billy Donahueb5e1fe82018-05-20 16:55:27 -0400369 Value* root,
Jordan Bayles645250b2019-07-10 18:56:30 -0700370 String* errs);
Christopher Dunn2c1197c2015-01-29 14:29:40 -0600371
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000372/** \brief Read from 'sin' into 'root'.
Billy Donahue483eba82019-07-14 18:41:48 -0400373 *
374 * Always keep comments from the input JSON.
Jordan Bayles7b286982019-08-13 22:41:43 -0700375 *
Billy Donahue483eba82019-07-14 18:41:48 -0400376 * This can be used to read a file into a particular sub-object.
377 * For example:
378 * \code
379 * Json::Value root;
380 * cin >> root["dir"]["file"];
381 * cout << root;
382 * \endcode
383 * Result:
384 * \verbatim
385 * {
386 * "dir": {
387 * "file": {
388 * // The input stream JSON would be nested here.
389 * }
390 * }
391 * }
392 * \endverbatim
393 * \throw std::exception on parse error.
394 * \see Json::operator<<()
395 */
Billy Donahue1c2ed7a2019-01-17 16:35:29 -0500396JSON_API IStream& operator>>(IStream&, Value&);
Christopher Dunn6d135cb2007-06-13 15:51:04 +0000397
398} // namespace Json
399
Sergiy80d6e666f2016-12-03 22:29:14 +0200400#pragma pack(pop)
401
Baptiste Lepilleureafd7022013-05-08 20:21:11 +0000402#if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING)
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000403#pragma warning(pop)
Baptiste Lepilleureafd7022013-05-08 20:21:11 +0000404#endif // if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING)
405
Christopher Dunn6d135cb2007-06-13 15:51:04 +0000406#endif // CPPTL_JSON_READER_H_INCLUDED