blob: 6271f71bc3b812728c83fbd49bf3a9a767fd67e8 [file] [log] [blame]
Baptiste Lepilleur7469f1d2010-04-20 21:35:19 +00001// Copyright 2007-2010 Baptiste Lepilleur
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
Christopher Dunn6d135cb2007-06-13 15:51:04 +00006#ifndef CPPTL_JSON_READER_H_INCLUDED
7# define CPPTL_JSON_READER_H_INCLUDED
8
Baptiste Lepilleureadc4782011-05-02 21:09:30 +00009#if !defined(JSON_IS_AMALGAMATION)
Baptiste Lepilleur88681472009-11-18 21:38:54 +000010# include "features.h"
Christopher Dunn6d135cb2007-06-13 15:51:04 +000011# include "value.h"
Baptiste Lepilleureadc4782011-05-02 21:09:30 +000012#endif // if !defined(JSON_IS_AMALGAMATION)
Christopher Dunn6d135cb2007-06-13 15:51:04 +000013# include <deque>
Aaron Jacobs94d17e92014-01-29 00:13:38 +000014# include <iosfwd>
Christopher Dunn6d135cb2007-06-13 15:51:04 +000015# include <stack>
16# include <string>
Christopher Dunn6d135cb2007-06-13 15:51:04 +000017
Baptiste Lepilleureafd7022013-05-08 20:21:11 +000018// Disable warning C4251: <data member>: <type> needs to have dll-interface to be used by...
19#if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING)
20# pragma warning(push)
21# pragma warning(disable:4251)
22#endif // if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING)
23
24
Christopher Dunn6d135cb2007-06-13 15:51:04 +000025namespace Json {
26
Christopher Dunn6d135cb2007-06-13 15:51:04 +000027 /** \brief Unserialize a <a HREF="http://www.json.org">JSON</a> document into a Value.
28 *
Christopher Dunn6d135cb2007-06-13 15:51:04 +000029 */
30 class JSON_API Reader
31 {
32 public:
33 typedef char Char;
34 typedef const Char *Location;
35
Aaron Jacobs68db6552014-04-23 23:41:12 +000036 /** \brief An error tagged with where in the JSON text it was encountered.
37 *
38 * The offsets give the [start, limit) range of bytes within the text. Note
39 * that this is bytes, not codepoints.
40 *
41 */
42 struct StructuredError
43 {
44 size_t offset_start;
45 size_t offset_limit;
46 std::string message;
47 };
48
Baptiste Lepilleur88681472009-11-18 21:38:54 +000049 /** \brief Constructs a Reader allowing all features
50 * for parsing.
51 */
Christopher Dunn6d135cb2007-06-13 15:51:04 +000052 Reader();
53
Baptiste Lepilleur88681472009-11-18 21:38:54 +000054 /** \brief Constructs a Reader allowing the specified feature set
55 * for parsing.
56 */
57 Reader( const Features &features );
58
Christopher Dunn6d135cb2007-06-13 15:51:04 +000059 /** \brief Read a Value from a <a HREF="http://www.json.org">JSON</a> document.
60 * \param document UTF-8 encoded string containing the document to read.
61 * \param root [out] Contains the root value of the document if it was
62 * successfully parsed.
63 * \param collectComments \c true to collect comment and allow writing them back during
64 * serialization, \c false to discard comments.
Baptiste Lepilleur88681472009-11-18 21:38:54 +000065 * This parameter is ignored if Features::allowComments_
66 * is \c false.
Christopher Dunn6d135cb2007-06-13 15:51:04 +000067 * \return \c true if the document was successfully parsed, \c false if an error occurred.
68 */
69 bool parse( const std::string &document,
70 Value &root,
71 bool collectComments = true );
72
73 /** \brief Read a Value from a <a HREF="http://www.json.org">JSON</a> document.
Baptiste Lepilleur40388492011-05-01 20:50:44 +000074 * \param beginDoc Pointer on the beginning of the UTF-8 encoded string of the document to read.
75 * \param endDoc Pointer on the end of the UTF-8 encoded string of the document to read.
76 \ Must be >= beginDoc.
Christopher Dunn6d135cb2007-06-13 15:51:04 +000077 * \param root [out] Contains the root value of the document if it was
78 * successfully parsed.
79 * \param collectComments \c true to collect comment and allow writing them back during
80 * serialization, \c false to discard comments.
Baptiste Lepilleur88681472009-11-18 21:38:54 +000081 * This parameter is ignored if Features::allowComments_
82 * is \c false.
Christopher Dunn6d135cb2007-06-13 15:51:04 +000083 * \return \c true if the document was successfully parsed, \c false if an error occurred.
84 */
85 bool parse( const char *beginDoc, const char *endDoc,
86 Value &root,
87 bool collectComments = true );
88
89 /// \brief Parse from input stream.
90 /// \see Json::operator>>(std::istream&, Json::Value&).
Baptiste Lepilleur88681472009-11-18 21:38:54 +000091 bool parse( std::istream &is,
Christopher Dunn6d135cb2007-06-13 15:51:04 +000092 Value &root,
93 bool collectComments = true );
94
95 /** \brief Returns a user friendly string that list errors in the parsed document.
96 * \return Formatted error message with the list of errors with their location in
97 * the parsed document. An empty string is returned if no error occurred
98 * during parsing.
Baptiste Lepilleurb2e8ccc2011-05-01 16:27:55 +000099 * \deprecated Use getFormattedErrorMessages() instead (typo fix).
Christopher Dunn6d135cb2007-06-13 15:51:04 +0000100 */
Baptiste Lepilleurb2e8ccc2011-05-01 16:27:55 +0000101 JSONCPP_DEPRECATED("Use getFormattedErrorMessages instead")
Christopher Dunn6d135cb2007-06-13 15:51:04 +0000102 std::string getFormatedErrorMessages() const;
103
Baptiste Lepilleurb2e8ccc2011-05-01 16:27:55 +0000104 /** \brief Returns a user friendly string that list errors in the parsed document.
105 * \return Formatted error message with the list of errors with their location in
106 * the parsed document. An empty string is returned if no error occurred
107 * during parsing.
108 */
109 std::string getFormattedErrorMessages() const;
110
Aaron Jacobs68db6552014-04-23 23:41:12 +0000111 /** \brief Returns a vector of structured erros encounted while parsing.
112 * \return A (possibly empty) vector of StructuredError objects. Currently
113 * only one error can be returned, but the caller should tolerate multiple
114 * errors. This can occur if the parser recovers from a non-fatal
115 * parse error and then encounters additional errors.
116 */
117 std::vector<StructuredError> getStructuredErrors() const;
118
Christopher Dunn6d135cb2007-06-13 15:51:04 +0000119 private:
120 enum TokenType
121 {
122 tokenEndOfStream = 0,
123 tokenObjectBegin,
124 tokenObjectEnd,
125 tokenArrayBegin,
126 tokenArrayEnd,
127 tokenString,
128 tokenNumber,
129 tokenTrue,
130 tokenFalse,
131 tokenNull,
132 tokenArraySeparator,
133 tokenMemberSeparator,
134 tokenComment,
135 tokenError
136 };
137
138 class Token
139 {
140 public:
141 TokenType type_;
142 Location start_;
143 Location end_;
144 };
145
146 class ErrorInfo
147 {
148 public:
149 Token token_;
150 std::string message_;
151 Location extra_;
152 };
153
154 typedef std::deque<ErrorInfo> Errors;
155
156 bool expectToken( TokenType type, Token &token, const char *message );
157 bool readToken( Token &token );
158 void skipSpaces();
159 bool match( Location pattern,
160 int patternLength );
161 bool readComment();
162 bool readCStyleComment();
163 bool readCppStyleComment();
164 bool readString();
165 void readNumber();
166 bool readValue();
167 bool readObject( Token &token );
168 bool readArray( Token &token );
169 bool decodeNumber( Token &token );
Aaron Jacobs642befc2014-04-23 23:28:23 +0000170 bool decodeNumber( Token &token, Value &decoded );
Christopher Dunn6d135cb2007-06-13 15:51:04 +0000171 bool decodeString( Token &token );
172 bool decodeString( Token &token, std::string &decoded );
173 bool decodeDouble( Token &token );
Aaron Jacobs642befc2014-04-23 23:28:23 +0000174 bool decodeDouble( Token &token, Value &decoded );
Malay Shahee4b4da2009-11-13 04:21:14 +0000175 bool decodeUnicodeCodePoint( Token &token,
176 Location &current,
177 Location end,
178 unsigned int &unicode );
Christopher Dunn6d135cb2007-06-13 15:51:04 +0000179 bool decodeUnicodeEscapeSequence( Token &token,
180 Location &current,
181 Location end,
182 unsigned int &unicode );
183 bool addError( const std::string &message,
184 Token &token,
185 Location extra = 0 );
186 bool recoverFromError( TokenType skipUntilToken );
187 bool addErrorAndRecover( const std::string &message,
188 Token &token,
189 TokenType skipUntilToken );
190 void skipUntilSpace();
191 Value &currentValue();
192 Char getNextChar();
193 void getLocationLineAndColumn( Location location,
194 int &line,
195 int &column ) const;
196 std::string getLocationLineAndColumn( Location location ) const;
197 void addComment( Location begin,
198 Location end,
199 CommentPlacement placement );
200 void skipCommentTokens( Token &token );
201
202 typedef std::stack<Value *> Nodes;
203 Nodes nodes_;
204 Errors errors_;
205 std::string document_;
206 Location begin_;
207 Location end_;
208 Location current_;
209 Location lastValueEnd_;
210 Value *lastValue_;
211 std::string commentsBefore_;
Baptiste Lepilleur88681472009-11-18 21:38:54 +0000212 Features features_;
Christopher Dunn6d135cb2007-06-13 15:51:04 +0000213 bool collectComments_;
214 };
215
216 /** \brief Read from 'sin' into 'root'.
217
218 Always keep comments from the input JSON.
219
220 This can be used to read a file into a particular sub-object.
221 For example:
222 \code
223 Json::Value root;
224 cin >> root["dir"]["file"];
225 cout << root;
226 \endcode
227 Result:
228 \verbatim
229 {
Baptiste Lepilleure3cc0f02011-05-02 18:41:01 +0000230 "dir": {
231 "file": {
232 // The input stream JSON would be nested here.
233 }
234 }
Christopher Dunn6d135cb2007-06-13 15:51:04 +0000235 }
236 \endverbatim
237 \throw std::exception on parse error.
238 \see Json::operator<<()
239 */
Baptiste Lepilleureafd7022013-05-08 20:21:11 +0000240 JSON_API std::istream& operator>>( std::istream&, Value& );
Christopher Dunn6d135cb2007-06-13 15:51:04 +0000241
242} // namespace Json
243
Baptiste Lepilleureafd7022013-05-08 20:21:11 +0000244#if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING)
245# pragma warning(pop)
246#endif // if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING)
247
248
Christopher Dunn6d135cb2007-06-13 15:51:04 +0000249#endif // CPPTL_JSON_READER_H_INCLUDED