blob: 111e5dd9867c8614c0212765ef9c1ce1916e6560 [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;
Billy Donahue1c2ed7a2019-01-17 16:35:29 -050049 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&).
Billy Donahue1c2ed7a2019-01-17 16:35:29 -0500106 bool parse(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.")
Billy Donahue1c2ed7a2019-01-17 16:35:29 -0500118 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 */
Billy Donahue1c2ed7a2019-01-17 16:35:29 -0500128 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 */
Billy Donahue1c2ed7a2019-01-17 16:35:29 -0500145 bool pushError(const Value& value, const 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 Donahue1c2ed7a2019-01-17 16:35:29 -0500154 bool pushError(const Value& value, const String& message, const Value& extra);
Mara Kimb84a39c2014-10-23 02:03:43 -0500155
156 /** \brief Return whether there are any errors.
157 * \return \c true if there are no errors to report \c false if
158 * errors have occurred.
159 */
160 bool good() const;
161
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000162private:
163 enum TokenType {
164 tokenEndOfStream = 0,
165 tokenObjectBegin,
166 tokenObjectEnd,
167 tokenArrayBegin,
168 tokenArrayEnd,
169 tokenString,
170 tokenNumber,
171 tokenTrue,
172 tokenFalse,
173 tokenNull,
174 tokenArraySeparator,
175 tokenMemberSeparator,
176 tokenComment,
177 tokenError
178 };
179
180 class Token {
181 public:
182 TokenType type_;
183 Location start_;
184 Location end_;
185 };
186
187 class ErrorInfo {
188 public:
189 Token token_;
Billy Donahue1c2ed7a2019-01-17 16:35:29 -0500190 String message_;
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000191 Location extra_;
192 };
193
194 typedef std::deque<ErrorInfo> Errors;
195
Aaron Jacobs11086dd2014-09-15 10:15:29 +1000196 bool readToken(Token& token);
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000197 void skipSpaces();
198 bool match(Location pattern, int patternLength);
199 bool readComment();
200 bool readCStyleComment();
201 bool readCppStyleComment();
202 bool readString();
203 void readNumber();
204 bool readValue();
Aaron Jacobs11086dd2014-09-15 10:15:29 +1000205 bool readObject(Token& token);
206 bool readArray(Token& token);
207 bool decodeNumber(Token& token);
208 bool decodeNumber(Token& token, Value& decoded);
209 bool decodeString(Token& token);
Billy Donahue1c2ed7a2019-01-17 16:35:29 -0500210 bool decodeString(Token& token, String& decoded);
Aaron Jacobs11086dd2014-09-15 10:15:29 +1000211 bool decodeDouble(Token& token);
212 bool decodeDouble(Token& token, Value& decoded);
213 bool decodeUnicodeCodePoint(Token& token,
214 Location& current,
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000215 Location end,
Aaron Jacobs11086dd2014-09-15 10:15:29 +1000216 unsigned int& unicode);
217 bool decodeUnicodeEscapeSequence(Token& token,
218 Location& current,
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000219 Location end,
Aaron Jacobs11086dd2014-09-15 10:15:29 +1000220 unsigned int& unicode);
Billy Donahue1c2ed7a2019-01-17 16:35:29 -0500221 bool addError(const String& message, Token& token, Location extra = nullptr);
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000222 bool recoverFromError(TokenType skipUntilToken);
Billy Donahue1c2ed7a2019-01-17 16:35:29 -0500223 bool addErrorAndRecover(const String& message,
Aaron Jacobs11086dd2014-09-15 10:15:29 +1000224 Token& token,
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000225 TokenType skipUntilToken);
226 void skipUntilSpace();
Aaron Jacobs11086dd2014-09-15 10:15:29 +1000227 Value& currentValue();
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000228 Char getNextChar();
229 void
Aaron Jacobs11086dd2014-09-15 10:15:29 +1000230 getLocationLineAndColumn(Location location, int& line, int& column) const;
Billy Donahue1c2ed7a2019-01-17 16:35:29 -0500231 String getLocationLineAndColumn(Location location) const;
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000232 void addComment(Location begin, Location end, CommentPlacement placement);
Aaron Jacobs11086dd2014-09-15 10:15:29 +1000233 void skipCommentTokens(Token& token);
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000234
damiramef16a352017-08-02 22:44:42 -0700235 static bool containsNewLine(Location begin, Location end);
Billy Donahue1c2ed7a2019-01-17 16:35:29 -0500236 static String normalizeEOL(Location begin, Location end);
damiramef16a352017-08-02 22:44:42 -0700237
Aaron Jacobs11086dd2014-09-15 10:15:29 +1000238 typedef std::stack<Value*> Nodes;
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000239 Nodes nodes_;
240 Errors errors_;
Billy Donahue1c2ed7a2019-01-17 16:35:29 -0500241 String document_;
Hans Johnsone817e4f2019-01-14 17:09:22 -0600242 Location begin_{};
243 Location end_{};
244 Location current_{};
245 Location lastValueEnd_{};
246 Value* lastValue_{};
Billy Donahue1c2ed7a2019-01-17 16:35:29 -0500247 String commentsBefore_;
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000248 Features features_;
Hans Johnsone817e4f2019-01-14 17:09:22 -0600249 bool collectComments_{};
Billy Donahueb5e1fe82018-05-20 16:55:27 -0400250}; // Reader
Christopher Dunn2c1197c2015-01-29 14:29:40 -0600251
252/** Interface for reading JSON from a char array.
253 */
254class JSON_API CharReader {
255public:
Hans Johnsone3e05c72019-01-14 17:09:26 -0600256 virtual ~CharReader() = default;
Christopher Dunn2c1197c2015-01-29 14:29:40 -0600257 /** \brief Read a Value from a <a HREF="http://www.json.org">JSON</a>
258 document.
Billy Donahueb5e1fe82018-05-20 16:55:27 -0400259 * The document must be a UTF-8 encoded string containing the document to
260 read.
Christopher Dunn2c1197c2015-01-29 14:29:40 -0600261 *
262 * \param beginDoc Pointer on the beginning of the UTF-8 encoded string of the
263 document to read.
264 * \param endDoc Pointer on the end of the UTF-8 encoded string of the
265 document to read.
266 * Must be >= beginDoc.
267 * \param root [out] Contains the root value of the document if it was
268 * successfully parsed.
269 * \param errs [out] Formatted error messages (if not NULL)
270 * a user friendly string that lists errors in the parsed
271 * document.
272 * \return \c true if the document was successfully parsed, \c false if an
273 error occurred.
274 */
Billy Donahueb5e1fe82018-05-20 16:55:27 -0400275 virtual bool parse(char const* beginDoc,
276 char const* endDoc,
277 Value* root,
Billy Donahue1c2ed7a2019-01-17 16:35:29 -0500278 String* errs) = 0;
Christopher Dunn2c1197c2015-01-29 14:29:40 -0600279
Ben Boeckel80def662015-09-28 15:45:11 -0400280 class JSON_API Factory {
Christopher Dunn2c1197c2015-01-29 14:29:40 -0600281 public:
Hans Johnsone3e05c72019-01-14 17:09:26 -0600282 virtual ~Factory() = default;
Christopher Dunna9e1ab32015-02-09 17:22:28 -0600283 /** \brief Allocate a CharReader via operator new().
284 * \throw std::exception if something goes wrong (e.g. invalid settings)
285 */
Christopher Dunn2c1197c2015-01-29 14:29:40 -0600286 virtual CharReader* newCharReader() const = 0;
Billy Donahueb5e1fe82018-05-20 16:55:27 -0400287 }; // Factory
288}; // CharReader
Christopher Dunn2c1197c2015-01-29 14:29:40 -0600289
Christopher Dunn66a8ba22015-02-09 01:29:43 -0600290/** \brief Build a CharReader implementation.
291
292Usage:
293\code
294 using namespace Json;
295 CharReaderBuilder builder;
Christopher Dunnc312dd52015-03-04 14:56:37 -0600296 builder["collectComments"] = false;
Christopher Dunn66a8ba22015-02-09 01:29:43 -0600297 Value value;
Billy Donahue1c2ed7a2019-01-17 16:35:29 -0500298 String errs;
Christopher Dunn8df98f62015-02-09 11:15:39 -0600299 bool ok = parseFromStream(builder, std::cin, &value, &errs);
Christopher Dunn66a8ba22015-02-09 01:29:43 -0600300\endcode
301*/
Christopher Dunna9e1ab32015-02-09 17:22:28 -0600302class JSON_API CharReaderBuilder : public CharReader::Factory {
Christopher Dunn66a8ba22015-02-09 01:29:43 -0600303public:
Christopher Dunna9e1ab32015-02-09 17:22:28 -0600304 // Note: We use a Json::Value so that we can add data-members to this class
305 // without a major version bump.
306 /** Configuration of this builder.
Christopher Dunn3cf91752015-02-09 18:16:24 -0600307 These are case-sensitive.
Christopher Dunna9e1ab32015-02-09 17:22:28 -0600308 Available settings (case-sensitive):
Christopher Dunnaa13a8b2015-02-13 09:37:39 -0600309 - `"collectComments": false or true`
Christopher Dunn29501c42015-02-10 23:03:27 -0600310 - true to collect comment and allow writing them
311 back during serialization, false to discard comments.
312 This parameter is ignored if allowComments is false.
Christopher Dunnaa13a8b2015-02-13 09:37:39 -0600313 - `"allowComments": false or true`
Christopher Dunn29501c42015-02-10 23:03:27 -0600314 - true if comments are allowed.
Christopher Dunnaa13a8b2015-02-13 09:37:39 -0600315 - `"strictRoot": false or true`
Christopher Dunn29501c42015-02-10 23:03:27 -0600316 - true if root must be either an array or an object value
Christopher Dunnaa13a8b2015-02-13 09:37:39 -0600317 - `"allowDroppedNullPlaceholders": false or true`
Billy Donahueb5e1fe82018-05-20 16:55:27 -0400318 - true if dropped null placeholders are allowed. (See
319 StreamWriterBuilder.)
Christopher Dunnaa13a8b2015-02-13 09:37:39 -0600320 - `"allowNumericKeys": false or true`
Christopher Dunn29501c42015-02-10 23:03:27 -0600321 - true if numeric object keys are allowed.
Christopher Dunn0c66e692015-02-23 15:55:12 -0600322 - `"allowSingleQuotes": false or true`
323 - true if '' are allowed for strings (both keys and values)
Christopher Dunnaa13a8b2015-02-13 09:37:39 -0600324 - `"stackLimit": integer`
325 - Exceeding stackLimit (recursive depth of `readValue()`) will
326 cause an exception.
Christopher Dunn249ad9f2015-02-10 12:16:03 -0600327 - This is a security issue (seg-faults caused by deeply nested JSON),
328 so the default is low.
Christopher Dunnf4be8152015-02-12 12:34:23 -0600329 - `"failIfExtra": false or true`
330 - If true, `parse()` returns false when extra non-whitespace trails
331 the JSON value in the input string.
Christopher Dunn527332d2015-03-06 12:18:59 -0600332 - `"rejectDupKeys": false or true`
Billy Donahueb5e1fe82018-05-20 16:55:27 -0400333 - If true, `parse()` returns false when a key is duplicated within an
334 object.
drgler20845632015-09-03 22:19:22 +0200335 - `"allowSpecialFloats": false or true`
Billy Donahueb5e1fe82018-05-20 16:55:27 -0400336 - If true, special float values (NaNs and infinities) are allowed
drgler20845632015-09-03 22:19:22 +0200337 and their values are lossfree restorable.
Christopher Dunnf757c182015-02-09 18:24:56 -0600338
Christopher Dunn3cf91752015-02-09 18:16:24 -0600339 You can examine 'settings_` yourself
Christopher Dunna9e1ab32015-02-09 17:22:28 -0600340 to see the defaults. You can also write and read them just like any
341 JSON Value.
Christopher Dunnf757c182015-02-09 18:24:56 -0600342 \sa setDefaults()
Christopher Dunna9e1ab32015-02-09 17:22:28 -0600343 */
344 Json::Value settings_;
Christopher Dunn66a8ba22015-02-09 01:29:43 -0600345
Christopher Dunn2c1197c2015-01-29 14:29:40 -0600346 CharReaderBuilder();
Hans Johnson2853b1c2019-01-11 13:58:53 -0600347 ~CharReaderBuilder() override;
Christopher Dunn2c1197c2015-01-29 14:29:40 -0600348
Hans Johnson2853b1c2019-01-11 13:58:53 -0600349 CharReader* newCharReader() const override;
Christopher Dunna9e1ab32015-02-09 17:22:28 -0600350
Christopher Dunnf757c182015-02-09 18:24:56 -0600351 /** \return true if 'settings' are legal and consistent;
Christopher Dunna9e1ab32015-02-09 17:22:28 -0600352 * otherwise, indicate bad settings via 'invalid'.
353 */
354 bool validate(Json::Value* invalid) const;
Christopher Dunnc312dd52015-03-04 14:56:37 -0600355
356 /** A simple way to update a specific setting.
357 */
Billy Donahue1c2ed7a2019-01-17 16:35:29 -0500358 Value& operator[](const String& key);
Christopher Dunnc312dd52015-03-04 14:56:37 -0600359
Christopher Dunna9e1ab32015-02-09 17:22:28 -0600360 /** Called by ctor, but you can use this to reset settings_.
361 * \pre 'settings' != NULL (but Json::null is fine)
Christopher Dunn3cf91752015-02-09 18:16:24 -0600362 * \remark Defaults:
Christopher Dunn56650e82015-04-20 13:10:31 -0700363 * \snippet src/lib_json/json_reader.cpp CharReaderBuilderDefaults
Christopher Dunna9e1ab32015-02-09 17:22:28 -0600364 */
365 static void setDefaults(Json::Value* settings);
Christopher Dunn3cf91752015-02-09 18:16:24 -0600366 /** Same as old Features::strictMode().
367 * \pre 'settings' != NULL (but Json::null is fine)
368 * \remark Defaults:
Christopher Dunn56650e82015-04-20 13:10:31 -0700369 * \snippet src/lib_json/json_reader.cpp CharReaderBuilderStrictMode
Christopher Dunn3cf91752015-02-09 18:16:24 -0600370 */
371 static void strictMode(Json::Value* settings);
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000372};
373
Christopher Dunn2c1197c2015-01-29 14:29:40 -0600374/** Consume entire stream and use its begin/end.
Billy Donahueb5e1fe82018-05-20 16:55:27 -0400375 * Someday we might have a real StreamReader, but for now this
376 * is convenient.
377 */
378bool JSON_API parseFromStream(CharReader::Factory const&,
Billy Donahue1c2ed7a2019-01-17 16:35:29 -0500379 IStream&,
Billy Donahueb5e1fe82018-05-20 16:55:27 -0400380 Value* root,
381 std::string* errs);
Christopher Dunn2c1197c2015-01-29 14:29:40 -0600382
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000383/** \brief Read from 'sin' into 'root'.
384
385 Always keep comments from the input JSON.
386
387 This can be used to read a file into a particular sub-object.
388 For example:
389 \code
390 Json::Value root;
391 cin >> root["dir"]["file"];
392 cout << root;
393 \endcode
394 Result:
395 \verbatim
396 {
397 "dir": {
398 "file": {
399 // The input stream JSON would be nested here.
400 }
401 }
402 }
403 \endverbatim
404 \throw std::exception on parse error.
405 \see Json::operator<<()
406*/
Billy Donahue1c2ed7a2019-01-17 16:35:29 -0500407JSON_API IStream& operator>>(IStream&, Value&);
Christopher Dunn6d135cb2007-06-13 15:51:04 +0000408
409} // namespace Json
410
Sergiy80d6e666f2016-12-03 22:29:14 +0200411#pragma pack(pop)
412
Baptiste Lepilleureafd7022013-05-08 20:21:11 +0000413#if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING)
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000414#pragma warning(pop)
Baptiste Lepilleureafd7022013-05-08 20:21:11 +0000415#endif // if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING)
416
Christopher Dunn6d135cb2007-06-13 15:51:04 +0000417#endif // CPPTL_JSON_READER_H_INCLUDED