blob: dc1da1f3e8d057f992c2e4cddc472d1108668038 [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>
15#include <stack>
16#include <string>
Christopher Dunn2c1197c2015-01-29 14:29:40 -060017#include <istream>
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 */
Christof Krügeredb4bdb2018-01-12 21:35:17 +010055 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 */
Christof Krügeredb4bdb2018-01-12 21:35:17 +010061 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 */
Christopher Dawes75570d72016-03-07 08:29:59 +0000154 bool pushError(const Value& value, const JSONCPP_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_;
Christopher Dawes75570d72016-03-07 08:29:59 +0000190 JSONCPP_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);
Christopher Dawes75570d72016-03-07 08:29:59 +0000210 bool decodeString(Token& token, JSONCPP_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);
Christopher Dawes75570d72016-03-07 08:29:59 +0000221 bool addError(const JSONCPP_STRING& message, Token& token, Location extra = 0);
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000222 bool recoverFromError(TokenType skipUntilToken);
Christopher Dawes75570d72016-03-07 08:29:59 +0000223 bool addErrorAndRecover(const JSONCPP_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;
Christopher Dawes75570d72016-03-07 08:29:59 +0000231 JSONCPP_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);
236 static JSONCPP_STRING normalizeEOL(Location begin, Location end);
237
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_;
Christopher Dawes75570d72016-03-07 08:29:59 +0000241 JSONCPP_STRING document_;
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000242 Location begin_;
243 Location end_;
244 Location current_;
245 Location lastValueEnd_;
Aaron Jacobs11086dd2014-09-15 10:15:29 +1000246 Value* lastValue_;
Christopher Dawes75570d72016-03-07 08:29:59 +0000247 JSONCPP_STRING commentsBefore_;
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000248 Features features_;
249 bool collectComments_;
Christopher Dunn2c1197c2015-01-29 14:29:40 -0600250}; // Reader
251
252/** Interface for reading JSON from a char array.
253 */
254class JSON_API CharReader {
255public:
256 virtual ~CharReader() {}
257 /** \brief Read a Value from a <a HREF="http://www.json.org">JSON</a>
258 document.
259 * The document must be a UTF-8 encoded string containing the document to read.
260 *
261 * \param beginDoc Pointer on the beginning of the UTF-8 encoded string of the
262 document to read.
263 * \param endDoc Pointer on the end of the UTF-8 encoded string of the
264 document to read.
265 * Must be >= beginDoc.
266 * \param root [out] Contains the root value of the document if it was
267 * successfully parsed.
268 * \param errs [out] Formatted error messages (if not NULL)
269 * a user friendly string that lists errors in the parsed
270 * document.
271 * \return \c true if the document was successfully parsed, \c false if an
272 error occurred.
273 */
274 virtual bool parse(
275 char const* beginDoc, char const* endDoc,
Christopher Dawes75570d72016-03-07 08:29:59 +0000276 Value* root, JSONCPP_STRING* errs) = 0;
Christopher Dunn2c1197c2015-01-29 14:29:40 -0600277
Ben Boeckel80def662015-09-28 15:45:11 -0400278 class JSON_API Factory {
Christopher Dunn2c1197c2015-01-29 14:29:40 -0600279 public:
Tengiz Sharafievbe183de2015-03-14 21:30:00 +0300280 virtual ~Factory() {}
Christopher Dunna9e1ab32015-02-09 17:22:28 -0600281 /** \brief Allocate a CharReader via operator new().
282 * \throw std::exception if something goes wrong (e.g. invalid settings)
283 */
Christopher Dunn2c1197c2015-01-29 14:29:40 -0600284 virtual CharReader* newCharReader() const = 0;
285 }; // Factory
286}; // CharReader
287
Christopher Dunn66a8ba22015-02-09 01:29:43 -0600288/** \brief Build a CharReader implementation.
289
290Usage:
291\code
292 using namespace Json;
293 CharReaderBuilder builder;
Christopher Dunnc312dd52015-03-04 14:56:37 -0600294 builder["collectComments"] = false;
Christopher Dunn66a8ba22015-02-09 01:29:43 -0600295 Value value;
Christopher Dawes75570d72016-03-07 08:29:59 +0000296 JSONCPP_STRING errs;
Christopher Dunn8df98f62015-02-09 11:15:39 -0600297 bool ok = parseFromStream(builder, std::cin, &value, &errs);
Christopher Dunn66a8ba22015-02-09 01:29:43 -0600298\endcode
299*/
Christopher Dunna9e1ab32015-02-09 17:22:28 -0600300class JSON_API CharReaderBuilder : public CharReader::Factory {
Christopher Dunn66a8ba22015-02-09 01:29:43 -0600301public:
Christopher Dunna9e1ab32015-02-09 17:22:28 -0600302 // Note: We use a Json::Value so that we can add data-members to this class
303 // without a major version bump.
304 /** Configuration of this builder.
Christopher Dunn3cf91752015-02-09 18:16:24 -0600305 These are case-sensitive.
Christopher Dunna9e1ab32015-02-09 17:22:28 -0600306 Available settings (case-sensitive):
Christopher Dunnaa13a8b2015-02-13 09:37:39 -0600307 - `"collectComments": false or true`
Christopher Dunn29501c42015-02-10 23:03:27 -0600308 - true to collect comment and allow writing them
309 back during serialization, false to discard comments.
310 This parameter is ignored if allowComments is false.
Christopher Dunnaa13a8b2015-02-13 09:37:39 -0600311 - `"allowComments": false or true`
Christopher Dunn29501c42015-02-10 23:03:27 -0600312 - true if comments are allowed.
Christopher Dunnaa13a8b2015-02-13 09:37:39 -0600313 - `"strictRoot": false or true`
Christopher Dunn29501c42015-02-10 23:03:27 -0600314 - true if root must be either an array or an object value
Christopher Dunnaa13a8b2015-02-13 09:37:39 -0600315 - `"allowDroppedNullPlaceholders": false or true`
Christopher Dunn29501c42015-02-10 23:03:27 -0600316 - true if dropped null placeholders are allowed. (See StreamWriterBuilder.)
Christopher Dunnaa13a8b2015-02-13 09:37:39 -0600317 - `"allowNumericKeys": false or true`
Christopher Dunn29501c42015-02-10 23:03:27 -0600318 - true if numeric object keys are allowed.
Christopher Dunn0c66e692015-02-23 15:55:12 -0600319 - `"allowSingleQuotes": false or true`
320 - true if '' are allowed for strings (both keys and values)
Christopher Dunnaa13a8b2015-02-13 09:37:39 -0600321 - `"stackLimit": integer`
322 - Exceeding stackLimit (recursive depth of `readValue()`) will
323 cause an exception.
Christopher Dunn249ad9f2015-02-10 12:16:03 -0600324 - This is a security issue (seg-faults caused by deeply nested JSON),
325 so the default is low.
Christopher Dunnf4be8152015-02-12 12:34:23 -0600326 - `"failIfExtra": false or true`
327 - If true, `parse()` returns false when extra non-whitespace trails
328 the JSON value in the input string.
Christopher Dunn527332d2015-03-06 12:18:59 -0600329 - `"rejectDupKeys": false or true`
330 - If true, `parse()` returns false when a key is duplicated within an object.
drgler20845632015-09-03 22:19:22 +0200331 - `"allowSpecialFloats": false or true`
332 - If true, special float values (NaNs and infinities) are allowed
333 and their values are lossfree restorable.
Christopher Dunnf757c182015-02-09 18:24:56 -0600334
Christopher Dunn3cf91752015-02-09 18:16:24 -0600335 You can examine 'settings_` yourself
Christopher Dunna9e1ab32015-02-09 17:22:28 -0600336 to see the defaults. You can also write and read them just like any
337 JSON Value.
Christopher Dunnf757c182015-02-09 18:24:56 -0600338 \sa setDefaults()
Christopher Dunna9e1ab32015-02-09 17:22:28 -0600339 */
340 Json::Value settings_;
Christopher Dunn66a8ba22015-02-09 01:29:43 -0600341
Christopher Dunn2c1197c2015-01-29 14:29:40 -0600342 CharReaderBuilder();
Christopher Dunn98e981d2016-03-21 21:00:24 -0500343 ~CharReaderBuilder() JSONCPP_OVERRIDE;
Christopher Dunn2c1197c2015-01-29 14:29:40 -0600344
Christopher Dunn98e981d2016-03-21 21:00:24 -0500345 CharReader* newCharReader() const JSONCPP_OVERRIDE;
Christopher Dunna9e1ab32015-02-09 17:22:28 -0600346
Christopher Dunnf757c182015-02-09 18:24:56 -0600347 /** \return true if 'settings' are legal and consistent;
Christopher Dunna9e1ab32015-02-09 17:22:28 -0600348 * otherwise, indicate bad settings via 'invalid'.
349 */
350 bool validate(Json::Value* invalid) const;
Christopher Dunnc312dd52015-03-04 14:56:37 -0600351
352 /** A simple way to update a specific setting.
353 */
Christopher Dawes75570d72016-03-07 08:29:59 +0000354 Value& operator[](JSONCPP_STRING key);
Christopher Dunnc312dd52015-03-04 14:56:37 -0600355
Christopher Dunna9e1ab32015-02-09 17:22:28 -0600356 /** Called by ctor, but you can use this to reset settings_.
357 * \pre 'settings' != NULL (but Json::null is fine)
Christopher Dunn3cf91752015-02-09 18:16:24 -0600358 * \remark Defaults:
Christopher Dunn56650e82015-04-20 13:10:31 -0700359 * \snippet src/lib_json/json_reader.cpp CharReaderBuilderDefaults
Christopher Dunna9e1ab32015-02-09 17:22:28 -0600360 */
361 static void setDefaults(Json::Value* settings);
Christopher Dunn3cf91752015-02-09 18:16:24 -0600362 /** Same as old Features::strictMode().
363 * \pre 'settings' != NULL (but Json::null is fine)
364 * \remark Defaults:
Christopher Dunn56650e82015-04-20 13:10:31 -0700365 * \snippet src/lib_json/json_reader.cpp CharReaderBuilderStrictMode
Christopher Dunn3cf91752015-02-09 18:16:24 -0600366 */
367 static void strictMode(Json::Value* settings);
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000368};
369
Christopher Dunn2c1197c2015-01-29 14:29:40 -0600370/** Consume entire stream and use its begin/end.
371 * Someday we might have a real StreamReader, but for now this
372 * is convenient.
373 */
Christopher Dunneaa3fd82015-03-05 10:11:43 -0600374bool JSON_API parseFromStream(
Christopher Dunn2c1197c2015-01-29 14:29:40 -0600375 CharReader::Factory const&,
Christopher Dunnb84e0c12016-03-06 11:54:27 -0600376 JSONCPP_ISTREAM&,
Christopher Dunn2c1197c2015-01-29 14:29:40 -0600377 Value* root, std::string* errs);
378
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000379/** \brief Read from 'sin' into 'root'.
380
381 Always keep comments from the input JSON.
382
383 This can be used to read a file into a particular sub-object.
384 For example:
385 \code
386 Json::Value root;
387 cin >> root["dir"]["file"];
388 cout << root;
389 \endcode
390 Result:
391 \verbatim
392 {
393 "dir": {
394 "file": {
395 // The input stream JSON would be nested here.
396 }
397 }
398 }
399 \endverbatim
400 \throw std::exception on parse error.
401 \see Json::operator<<()
402*/
Christopher Dunnb84e0c12016-03-06 11:54:27 -0600403JSON_API JSONCPP_ISTREAM& operator>>(JSONCPP_ISTREAM&, Value&);
Christopher Dunn6d135cb2007-06-13 15:51:04 +0000404
405} // namespace Json
406
Sergiy80d6e666f2016-12-03 22:29:14 +0200407#pragma pack(pop)
408
Baptiste Lepilleureafd7022013-05-08 20:21:11 +0000409#if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING)
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000410#pragma warning(pop)
Baptiste Lepilleureafd7022013-05-08 20:21:11 +0000411#endif // if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING)
412
Christopher Dunn6d135cb2007-06-13 15:51:04 +0000413#endif // CPPTL_JSON_READER_H_INCLUDED