blob: ac8b7bd806d9bf314cc97be523ba69d28bd938c5 [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)
Aaron Jacobs9fa4e842014-07-01 08:48:54 +100010#include "features.h"
11#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
Christopher Dunn6d135cb2007-06-13 15:51:04 +000028namespace Json {
29
Aaron Jacobs9fa4e842014-07-01 08:48:54 +100030/** \brief Unserialize a <a HREF="http://www.json.org">JSON</a> document into a
31 *Value.
32 *
Christopher Dunn8df98f62015-02-09 11:15:39 -060033 * \deprecated Use CharReader and CharReaderBuilder.
Aaron Jacobs9fa4e842014-07-01 08:48:54 +100034 */
Christof Krügeredb4bdb2018-01-12 21:35:17 +010035class JSON_API Reader {
Aaron Jacobs9fa4e842014-07-01 08:48:54 +100036public:
37 typedef char Char;
Aaron Jacobs11086dd2014-09-15 10:15:29 +100038 typedef const Char* Location;
Christopher Dunn6d135cb2007-06-13 15:51:04 +000039
Aaron Jacobs9fa4e842014-07-01 08:48:54 +100040 /** \brief An error tagged with where in the JSON text it was encountered.
41 *
42 * The offsets give the [start, limit) range of bytes within the text. Note
43 * that this is bytes, not codepoints.
44 *
Christopher Dunn6d135cb2007-06-13 15:51:04 +000045 */
Aaron Jacobs9fa4e842014-07-01 08:48:54 +100046 struct StructuredError {
Christopher Dunnd4513fc2016-02-06 09:25:20 -060047 ptrdiff_t offset_start;
48 ptrdiff_t offset_limit;
Christopher Dawes75570d72016-03-07 08:29:59 +000049 JSONCPP_STRING message;
Aaron Jacobs9fa4e842014-07-01 08:48:54 +100050 };
51
52 /** \brief Constructs a Reader allowing all features
53 * for parsing.
54 */
Billy Donahueb5e1fe82018-05-20 16:55:27 -040055 JSONCPP_DEPRECATED("Use CharReader and CharReaderBuilder instead")
Aaron Jacobs9fa4e842014-07-01 08:48:54 +100056 Reader();
57
58 /** \brief Constructs a Reader allowing the specified feature set
59 * for parsing.
60 */
Billy Donahueb5e1fe82018-05-20 16:55:27 -040061 JSONCPP_DEPRECATED("Use CharReader and CharReaderBuilder instead")
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.
66 * \param document UTF-8 encoded string containing the document to read.
67 * \param root [out] Contains the root value of the document if it was
68 * successfully parsed.
69 * \param collectComments \c true to collect comment and allow writing them
70 * back during
71 * serialization, \c false to discard comments.
72 * This parameter is ignored if
73 * Features::allowComments_
74 * is \c false.
75 * \return \c true if the document was successfully parsed, \c false if an
76 * error occurred.
77 */
78 bool
Aaron Jacobs11086dd2014-09-15 10:15:29 +100079 parse(const std::string& document, Value& root, 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>
82 document.
83 * \param beginDoc Pointer on the beginning of the UTF-8 encoded string of the
84 document to read.
85 * \param endDoc Pointer on the end of the UTF-8 encoded string of the
86 document to read.
Christopher Dunn2c1197c2015-01-29 14:29:40 -060087 * Must be >= beginDoc.
Aaron Jacobs9fa4e842014-07-01 08:48:54 +100088 * \param root [out] Contains the root value of the document if it was
89 * successfully parsed.
90 * \param collectComments \c true to collect comment and allow writing them
91 back during
92 * serialization, \c false to discard comments.
93 * This parameter is ignored if
94 Features::allowComments_
95 * is \c false.
96 * \return \c true if the document was successfully parsed, \c false if an
97 error occurred.
98 */
Aaron Jacobs11086dd2014-09-15 10:15:29 +100099 bool parse(const char* beginDoc,
100 const char* endDoc,
101 Value& root,
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000102 bool collectComments = true);
103
104 /// \brief Parse from input stream.
105 /// \see Json::operator>>(std::istream&, Json::Value&).
Christopher Dunnb84e0c12016-03-06 11:54:27 -0600106 bool parse(JSONCPP_ISTREAM& is, Value& root, bool collectComments = true);
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000107
108 /** \brief Returns a user friendly string that list errors in the parsed
109 * document.
110 * \return Formatted error message with the list of errors with their location
111 * in
112 * the parsed document. An empty string is returned if no error
113 * occurred
114 * during parsing.
115 * \deprecated Use getFormattedErrorMessages() instead (typo fix).
116 */
Christopher Dunned495ed2015-03-08 14:01:28 -0500117 JSONCPP_DEPRECATED("Use getFormattedErrorMessages() instead.")
Christopher Dawes75570d72016-03-07 08:29:59 +0000118 JSONCPP_STRING getFormatedErrorMessages() const;
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000119
120 /** \brief Returns a user friendly string that list errors in the parsed
121 * document.
122 * \return Formatted error message with the list of errors with their location
123 * in
124 * the parsed document. An empty string is returned if no error
125 * occurred
126 * during parsing.
127 */
Christopher Dawes75570d72016-03-07 08:29:59 +0000128 JSONCPP_STRING getFormattedErrorMessages() const;
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000129
130 /** \brief Returns a vector of structured erros encounted while parsing.
131 * \return A (possibly empty) vector of StructuredError objects. Currently
132 * only one error can be returned, but the caller should tolerate
133 * multiple
134 * errors. This can occur if the parser recovers from a non-fatal
135 * parse error and then encounters additional errors.
136 */
137 std::vector<StructuredError> getStructuredErrors() const;
138
Mara Kimb84a39c2014-10-23 02:03:43 -0500139 /** \brief Add a semantic error message.
140 * \param value JSON Value location associated with the error
141 * \param message The error message.
142 * \return \c true if the error was successfully added, \c false if the
143 * Value offset exceeds the document size.
144 */
Christopher Dawes75570d72016-03-07 08:29:59 +0000145 bool pushError(const Value& value, const JSONCPP_STRING& message);
Mara Kimb84a39c2014-10-23 02:03:43 -0500146
147 /** \brief Add a semantic error message with extra context.
148 * \param value JSON Value location associated with the error
149 * \param message The error message.
150 * \param extra Additional JSON Value location to contextualize the error
151 * \return \c true if the error was successfully added, \c false if either
152 * Value offset exceeds the document size.
153 */
Billy Donahueb5e1fe82018-05-20 16:55:27 -0400154 bool pushError(const Value& value,
155 const JSONCPP_STRING& message,
156 const Value& extra);
Mara Kimb84a39c2014-10-23 02:03:43 -0500157
158 /** \brief Return whether there are any errors.
159 * \return \c true if there are no errors to report \c false if
160 * errors have occurred.
161 */
162 bool good() const;
163
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000164private:
165 enum TokenType {
166 tokenEndOfStream = 0,
167 tokenObjectBegin,
168 tokenObjectEnd,
169 tokenArrayBegin,
170 tokenArrayEnd,
171 tokenString,
172 tokenNumber,
173 tokenTrue,
174 tokenFalse,
175 tokenNull,
176 tokenArraySeparator,
177 tokenMemberSeparator,
178 tokenComment,
179 tokenError
180 };
181
182 class Token {
183 public:
184 TokenType type_;
185 Location start_;
186 Location end_;
187 };
188
189 class ErrorInfo {
190 public:
191 Token token_;
Christopher Dawes75570d72016-03-07 08:29:59 +0000192 JSONCPP_STRING message_;
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000193 Location extra_;
194 };
195
196 typedef std::deque<ErrorInfo> Errors;
197
Aaron Jacobs11086dd2014-09-15 10:15:29 +1000198 bool readToken(Token& token);
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000199 void skipSpaces();
200 bool match(Location pattern, int patternLength);
201 bool readComment();
202 bool readCStyleComment();
203 bool readCppStyleComment();
204 bool readString();
205 void readNumber();
206 bool readValue();
Aaron Jacobs11086dd2014-09-15 10:15:29 +1000207 bool readObject(Token& token);
208 bool readArray(Token& token);
209 bool decodeNumber(Token& token);
210 bool decodeNumber(Token& token, Value& decoded);
211 bool decodeString(Token& token);
Christopher Dawes75570d72016-03-07 08:29:59 +0000212 bool decodeString(Token& token, JSONCPP_STRING& decoded);
Aaron Jacobs11086dd2014-09-15 10:15:29 +1000213 bool decodeDouble(Token& token);
214 bool decodeDouble(Token& token, Value& decoded);
215 bool decodeUnicodeCodePoint(Token& token,
216 Location& current,
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000217 Location end,
Aaron Jacobs11086dd2014-09-15 10:15:29 +1000218 unsigned int& unicode);
219 bool decodeUnicodeEscapeSequence(Token& token,
220 Location& current,
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000221 Location end,
Aaron Jacobs11086dd2014-09-15 10:15:29 +1000222 unsigned int& unicode);
Billy Donahueb5e1fe82018-05-20 16:55:27 -0400223 bool
Hans Johnsonf64244e2018-12-12 13:41:06 -0600224 addError(const JSONCPP_STRING& message, Token& token, Location extra = nullptr);
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000225 bool recoverFromError(TokenType skipUntilToken);
Christopher Dawes75570d72016-03-07 08:29:59 +0000226 bool addErrorAndRecover(const JSONCPP_STRING& message,
Aaron Jacobs11086dd2014-09-15 10:15:29 +1000227 Token& token,
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000228 TokenType skipUntilToken);
229 void skipUntilSpace();
Aaron Jacobs11086dd2014-09-15 10:15:29 +1000230 Value& currentValue();
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000231 Char getNextChar();
232 void
Aaron Jacobs11086dd2014-09-15 10:15:29 +1000233 getLocationLineAndColumn(Location location, int& line, int& column) const;
Christopher Dawes75570d72016-03-07 08:29:59 +0000234 JSONCPP_STRING getLocationLineAndColumn(Location location) const;
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000235 void addComment(Location begin, Location end, CommentPlacement placement);
Aaron Jacobs11086dd2014-09-15 10:15:29 +1000236 void skipCommentTokens(Token& token);
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000237
damiramef16a352017-08-02 22:44:42 -0700238 static bool containsNewLine(Location begin, Location end);
239 static JSONCPP_STRING normalizeEOL(Location begin, Location end);
240
Aaron Jacobs11086dd2014-09-15 10:15:29 +1000241 typedef std::stack<Value*> Nodes;
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000242 Nodes nodes_;
243 Errors errors_;
Christopher Dawes75570d72016-03-07 08:29:59 +0000244 JSONCPP_STRING document_;
Hans Johnsone817e4f2019-01-14 17:09:22 -0600245 Location begin_{};
246 Location end_{};
247 Location current_{};
248 Location lastValueEnd_{};
249 Value* lastValue_{};
Christopher Dawes75570d72016-03-07 08:29:59 +0000250 JSONCPP_STRING commentsBefore_;
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000251 Features features_;
Hans Johnsone817e4f2019-01-14 17:09:22 -0600252 bool collectComments_{};
Billy Donahueb5e1fe82018-05-20 16:55:27 -0400253}; // Reader
Christopher Dunn2c1197c2015-01-29 14:29:40 -0600254
255/** Interface for reading JSON from a char array.
256 */
257class JSON_API CharReader {
258public:
Hans Johnsone3e05c72019-01-14 17:09:26 -0600259 virtual ~CharReader() = default;
Christopher Dunn2c1197c2015-01-29 14:29:40 -0600260 /** \brief Read a Value from a <a HREF="http://www.json.org">JSON</a>
261 document.
Billy Donahueb5e1fe82018-05-20 16:55:27 -0400262 * The document must be a UTF-8 encoded string containing the document to
263 read.
Christopher Dunn2c1197c2015-01-29 14:29:40 -0600264 *
265 * \param beginDoc Pointer on the beginning of the UTF-8 encoded string of the
266 document to read.
267 * \param endDoc Pointer on the end of the UTF-8 encoded string of the
268 document to read.
269 * Must be >= beginDoc.
270 * \param root [out] Contains the root value of the document if it was
271 * successfully parsed.
272 * \param errs [out] Formatted error messages (if not NULL)
273 * a user friendly string that lists errors in the parsed
274 * document.
275 * \return \c true if the document was successfully parsed, \c false if an
276 error occurred.
277 */
Billy Donahueb5e1fe82018-05-20 16:55:27 -0400278 virtual bool parse(char const* beginDoc,
279 char const* endDoc,
280 Value* root,
281 JSONCPP_STRING* errs) = 0;
Christopher Dunn2c1197c2015-01-29 14:29:40 -0600282
Ben Boeckel80def662015-09-28 15:45:11 -0400283 class JSON_API Factory {
Christopher Dunn2c1197c2015-01-29 14:29:40 -0600284 public:
Hans Johnsone3e05c72019-01-14 17:09:26 -0600285 virtual ~Factory() = default;
Christopher Dunna9e1ab32015-02-09 17:22:28 -0600286 /** \brief Allocate a CharReader via operator new().
287 * \throw std::exception if something goes wrong (e.g. invalid settings)
288 */
Christopher Dunn2c1197c2015-01-29 14:29:40 -0600289 virtual CharReader* newCharReader() const = 0;
Billy Donahueb5e1fe82018-05-20 16:55:27 -0400290 }; // Factory
291}; // CharReader
Christopher Dunn2c1197c2015-01-29 14:29:40 -0600292
Christopher Dunn66a8ba22015-02-09 01:29:43 -0600293/** \brief Build a CharReader implementation.
294
295Usage:
296\code
297 using namespace Json;
298 CharReaderBuilder builder;
Christopher Dunnc312dd52015-03-04 14:56:37 -0600299 builder["collectComments"] = false;
Christopher Dunn66a8ba22015-02-09 01:29:43 -0600300 Value value;
Christopher Dawes75570d72016-03-07 08:29:59 +0000301 JSONCPP_STRING errs;
Christopher Dunn8df98f62015-02-09 11:15:39 -0600302 bool ok = parseFromStream(builder, std::cin, &value, &errs);
Christopher Dunn66a8ba22015-02-09 01:29:43 -0600303\endcode
304*/
Christopher Dunna9e1ab32015-02-09 17:22:28 -0600305class JSON_API CharReaderBuilder : public CharReader::Factory {
Christopher Dunn66a8ba22015-02-09 01:29:43 -0600306public:
Christopher Dunna9e1ab32015-02-09 17:22:28 -0600307 // Note: We use a Json::Value so that we can add data-members to this class
308 // without a major version bump.
309 /** Configuration of this builder.
Christopher Dunn3cf91752015-02-09 18:16:24 -0600310 These are case-sensitive.
Christopher Dunna9e1ab32015-02-09 17:22:28 -0600311 Available settings (case-sensitive):
Christopher Dunnaa13a8b2015-02-13 09:37:39 -0600312 - `"collectComments": false or true`
Christopher Dunn29501c42015-02-10 23:03:27 -0600313 - true to collect comment and allow writing them
314 back during serialization, false to discard comments.
315 This parameter is ignored if allowComments is false.
Christopher Dunnaa13a8b2015-02-13 09:37:39 -0600316 - `"allowComments": false or true`
Christopher Dunn29501c42015-02-10 23:03:27 -0600317 - true if comments are allowed.
Christopher Dunnaa13a8b2015-02-13 09:37:39 -0600318 - `"strictRoot": false or true`
Christopher Dunn29501c42015-02-10 23:03:27 -0600319 - true if root must be either an array or an object value
Christopher Dunnaa13a8b2015-02-13 09:37:39 -0600320 - `"allowDroppedNullPlaceholders": false or true`
Billy Donahueb5e1fe82018-05-20 16:55:27 -0400321 - true if dropped null placeholders are allowed. (See
322 StreamWriterBuilder.)
Christopher Dunnaa13a8b2015-02-13 09:37:39 -0600323 - `"allowNumericKeys": false or true`
Christopher Dunn29501c42015-02-10 23:03:27 -0600324 - true if numeric object keys are allowed.
Christopher Dunn0c66e692015-02-23 15:55:12 -0600325 - `"allowSingleQuotes": false or true`
326 - true if '' are allowed for strings (both keys and values)
Christopher Dunnaa13a8b2015-02-13 09:37:39 -0600327 - `"stackLimit": integer`
328 - Exceeding stackLimit (recursive depth of `readValue()`) will
329 cause an exception.
Christopher Dunn249ad9f2015-02-10 12:16:03 -0600330 - This is a security issue (seg-faults caused by deeply nested JSON),
331 so the default is low.
Christopher Dunnf4be8152015-02-12 12:34:23 -0600332 - `"failIfExtra": false or true`
333 - If true, `parse()` returns false when extra non-whitespace trails
334 the JSON value in the input string.
Christopher Dunn527332d2015-03-06 12:18:59 -0600335 - `"rejectDupKeys": false or true`
Billy Donahueb5e1fe82018-05-20 16:55:27 -0400336 - If true, `parse()` returns false when a key is duplicated within an
337 object.
drgler20845632015-09-03 22:19:22 +0200338 - `"allowSpecialFloats": false or true`
Billy Donahueb5e1fe82018-05-20 16:55:27 -0400339 - If true, special float values (NaNs and infinities) are allowed
drgler20845632015-09-03 22:19:22 +0200340 and their values are lossfree restorable.
Christopher Dunnf757c182015-02-09 18:24:56 -0600341
Christopher Dunn3cf91752015-02-09 18:16:24 -0600342 You can examine 'settings_` yourself
Christopher Dunna9e1ab32015-02-09 17:22:28 -0600343 to see the defaults. You can also write and read them just like any
344 JSON Value.
Christopher Dunnf757c182015-02-09 18:24:56 -0600345 \sa setDefaults()
Christopher Dunna9e1ab32015-02-09 17:22:28 -0600346 */
347 Json::Value settings_;
Christopher Dunn66a8ba22015-02-09 01:29:43 -0600348
Christopher Dunn2c1197c2015-01-29 14:29:40 -0600349 CharReaderBuilder();
Hans Johnson2853b1c2019-01-11 13:58:53 -0600350 ~CharReaderBuilder() override;
Christopher Dunn2c1197c2015-01-29 14:29:40 -0600351
Hans Johnson2853b1c2019-01-11 13:58:53 -0600352 CharReader* newCharReader() const override;
Christopher Dunna9e1ab32015-02-09 17:22:28 -0600353
Christopher Dunnf757c182015-02-09 18:24:56 -0600354 /** \return true if 'settings' are legal and consistent;
Christopher Dunna9e1ab32015-02-09 17:22:28 -0600355 * otherwise, indicate bad settings via 'invalid'.
356 */
357 bool validate(Json::Value* invalid) const;
Christopher Dunnc312dd52015-03-04 14:56:37 -0600358
359 /** A simple way to update a specific setting.
360 */
Radoslav Atanasovccd077f2018-12-13 14:18:04 +0100361 Value& operator[](const JSONCPP_STRING& key);
Christopher Dunnc312dd52015-03-04 14:56:37 -0600362
Christopher Dunna9e1ab32015-02-09 17:22:28 -0600363 /** Called by ctor, but you can use this to reset settings_.
364 * \pre 'settings' != NULL (but Json::null is fine)
Christopher Dunn3cf91752015-02-09 18:16:24 -0600365 * \remark Defaults:
Christopher Dunn56650e82015-04-20 13:10:31 -0700366 * \snippet src/lib_json/json_reader.cpp CharReaderBuilderDefaults
Christopher Dunna9e1ab32015-02-09 17:22:28 -0600367 */
368 static void setDefaults(Json::Value* settings);
Christopher Dunn3cf91752015-02-09 18:16:24 -0600369 /** Same as old Features::strictMode().
370 * \pre 'settings' != NULL (but Json::null is fine)
371 * \remark Defaults:
Christopher Dunn56650e82015-04-20 13:10:31 -0700372 * \snippet src/lib_json/json_reader.cpp CharReaderBuilderStrictMode
Christopher Dunn3cf91752015-02-09 18:16:24 -0600373 */
374 static void strictMode(Json::Value* settings);
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000375};
376
Christopher Dunn2c1197c2015-01-29 14:29:40 -0600377/** Consume entire stream and use its begin/end.
Billy Donahueb5e1fe82018-05-20 16:55:27 -0400378 * Someday we might have a real StreamReader, but for now this
379 * is convenient.
380 */
381bool JSON_API parseFromStream(CharReader::Factory const&,
382 JSONCPP_ISTREAM&,
383 Value* root,
384 std::string* errs);
Christopher Dunn2c1197c2015-01-29 14:29:40 -0600385
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000386/** \brief Read from 'sin' into 'root'.
387
388 Always keep comments from the input JSON.
389
390 This can be used to read a file into a particular sub-object.
391 For example:
392 \code
393 Json::Value root;
394 cin >> root["dir"]["file"];
395 cout << root;
396 \endcode
397 Result:
398 \verbatim
399 {
400 "dir": {
401 "file": {
402 // The input stream JSON would be nested here.
403 }
404 }
405 }
406 \endverbatim
407 \throw std::exception on parse error.
408 \see Json::operator<<()
409*/
Christopher Dunnb84e0c12016-03-06 11:54:27 -0600410JSON_API JSONCPP_ISTREAM& operator>>(JSONCPP_ISTREAM&, Value&);
Christopher Dunn6d135cb2007-06-13 15:51:04 +0000411
412} // namespace Json
413
Sergiy80d6e666f2016-12-03 22:29:14 +0200414#pragma pack(pop)
415
Baptiste Lepilleureafd7022013-05-08 20:21:11 +0000416#if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING)
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000417#pragma warning(pop)
Baptiste Lepilleureafd7022013-05-08 20:21:11 +0000418#endif // if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING)
419
Christopher Dunn6d135cb2007-06-13 15:51:04 +0000420#endif // CPPTL_JSON_READER_H_INCLUDED