blob: a3023b31f5fe7299e9ad83288ca17778c3362578 [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>
14# include <stack>
15# include <string>
Christopher Dunn6d135cb2007-06-13 15:51:04 +000016
17namespace Json {
18
Christopher Dunn6d135cb2007-06-13 15:51:04 +000019 /** \brief Unserialize a <a HREF="http://www.json.org">JSON</a> document into a Value.
20 *
Christopher Dunn6d135cb2007-06-13 15:51:04 +000021 */
22 class JSON_API Reader
23 {
24 public:
25 typedef char Char;
26 typedef const Char *Location;
27
Baptiste Lepilleur88681472009-11-18 21:38:54 +000028 /** \brief Constructs a Reader allowing all features
29 * for parsing.
30 */
Christopher Dunn6d135cb2007-06-13 15:51:04 +000031 Reader();
32
Baptiste Lepilleur88681472009-11-18 21:38:54 +000033 /** \brief Constructs a Reader allowing the specified feature set
34 * for parsing.
35 */
36 Reader( const Features &features );
37
Christopher Dunn6d135cb2007-06-13 15:51:04 +000038 /** \brief Read a Value from a <a HREF="http://www.json.org">JSON</a> document.
39 * \param document UTF-8 encoded string containing the document to read.
40 * \param root [out] Contains the root value of the document if it was
41 * successfully parsed.
42 * \param collectComments \c true to collect comment and allow writing them back during
43 * serialization, \c false to discard comments.
Baptiste Lepilleur88681472009-11-18 21:38:54 +000044 * This parameter is ignored if Features::allowComments_
45 * is \c false.
Christopher Dunn6d135cb2007-06-13 15:51:04 +000046 * \return \c true if the document was successfully parsed, \c false if an error occurred.
47 */
48 bool parse( const std::string &document,
49 Value &root,
50 bool collectComments = true );
51
52 /** \brief Read a Value from a <a HREF="http://www.json.org">JSON</a> document.
Baptiste Lepilleur40388492011-05-01 20:50:44 +000053 * \param beginDoc Pointer on the beginning of the UTF-8 encoded string of the document to read.
54 * \param endDoc Pointer on the end of the UTF-8 encoded string of the document to read.
55 \ Must be >= beginDoc.
Christopher Dunn6d135cb2007-06-13 15:51:04 +000056 * \param root [out] Contains the root value of the document if it was
57 * successfully parsed.
58 * \param collectComments \c true to collect comment and allow writing them back during
59 * serialization, \c false to discard comments.
Baptiste Lepilleur88681472009-11-18 21:38:54 +000060 * This parameter is ignored if Features::allowComments_
61 * is \c false.
Christopher Dunn6d135cb2007-06-13 15:51:04 +000062 * \return \c true if the document was successfully parsed, \c false if an error occurred.
63 */
64 bool parse( const char *beginDoc, const char *endDoc,
65 Value &root,
66 bool collectComments = true );
67
68 /// \brief Parse from input stream.
69 /// \see Json::operator>>(std::istream&, Json::Value&).
Baptiste Lepilleur88681472009-11-18 21:38:54 +000070 bool parse( std::istream &is,
Christopher Dunn6d135cb2007-06-13 15:51:04 +000071 Value &root,
72 bool collectComments = true );
73
74 /** \brief Returns a user friendly string that list errors in the parsed document.
75 * \return Formatted error message with the list of errors with their location in
76 * the parsed document. An empty string is returned if no error occurred
77 * during parsing.
Baptiste Lepilleurb2e8ccc2011-05-01 16:27:55 +000078 * \deprecated Use getFormattedErrorMessages() instead (typo fix).
Christopher Dunn6d135cb2007-06-13 15:51:04 +000079 */
Baptiste Lepilleurb2e8ccc2011-05-01 16:27:55 +000080 JSONCPP_DEPRECATED("Use getFormattedErrorMessages instead")
Christopher Dunn6d135cb2007-06-13 15:51:04 +000081 std::string getFormatedErrorMessages() const;
82
Baptiste Lepilleurb2e8ccc2011-05-01 16:27:55 +000083 /** \brief Returns a user friendly string that list errors in the parsed document.
84 * \return Formatted error message with the list of errors with their location in
85 * the parsed document. An empty string is returned if no error occurred
86 * during parsing.
87 */
88 std::string getFormattedErrorMessages() const;
89
Christopher Dunn6d135cb2007-06-13 15:51:04 +000090 private:
91 enum TokenType
92 {
93 tokenEndOfStream = 0,
94 tokenObjectBegin,
95 tokenObjectEnd,
96 tokenArrayBegin,
97 tokenArrayEnd,
98 tokenString,
99 tokenNumber,
100 tokenTrue,
101 tokenFalse,
102 tokenNull,
103 tokenArraySeparator,
104 tokenMemberSeparator,
105 tokenComment,
106 tokenError
107 };
108
109 class Token
110 {
111 public:
112 TokenType type_;
113 Location start_;
114 Location end_;
115 };
116
117 class ErrorInfo
118 {
119 public:
120 Token token_;
121 std::string message_;
122 Location extra_;
123 };
124
125 typedef std::deque<ErrorInfo> Errors;
126
127 bool expectToken( TokenType type, Token &token, const char *message );
128 bool readToken( Token &token );
129 void skipSpaces();
130 bool match( Location pattern,
131 int patternLength );
132 bool readComment();
133 bool readCStyleComment();
134 bool readCppStyleComment();
135 bool readString();
136 void readNumber();
137 bool readValue();
138 bool readObject( Token &token );
139 bool readArray( Token &token );
140 bool decodeNumber( Token &token );
141 bool decodeString( Token &token );
142 bool decodeString( Token &token, std::string &decoded );
143 bool decodeDouble( Token &token );
Malay Shahee4b4da2009-11-13 04:21:14 +0000144 bool decodeUnicodeCodePoint( Token &token,
145 Location &current,
146 Location end,
147 unsigned int &unicode );
Christopher Dunn6d135cb2007-06-13 15:51:04 +0000148 bool decodeUnicodeEscapeSequence( Token &token,
149 Location &current,
150 Location end,
151 unsigned int &unicode );
152 bool addError( const std::string &message,
153 Token &token,
154 Location extra = 0 );
155 bool recoverFromError( TokenType skipUntilToken );
156 bool addErrorAndRecover( const std::string &message,
157 Token &token,
158 TokenType skipUntilToken );
159 void skipUntilSpace();
160 Value &currentValue();
161 Char getNextChar();
162 void getLocationLineAndColumn( Location location,
163 int &line,
164 int &column ) const;
165 std::string getLocationLineAndColumn( Location location ) const;
166 void addComment( Location begin,
167 Location end,
168 CommentPlacement placement );
169 void skipCommentTokens( Token &token );
170
171 typedef std::stack<Value *> Nodes;
172 Nodes nodes_;
173 Errors errors_;
174 std::string document_;
175 Location begin_;
176 Location end_;
177 Location current_;
178 Location lastValueEnd_;
179 Value *lastValue_;
180 std::string commentsBefore_;
Baptiste Lepilleur88681472009-11-18 21:38:54 +0000181 Features features_;
Christopher Dunn6d135cb2007-06-13 15:51:04 +0000182 bool collectComments_;
183 };
184
185 /** \brief Read from 'sin' into 'root'.
186
187 Always keep comments from the input JSON.
188
189 This can be used to read a file into a particular sub-object.
190 For example:
191 \code
192 Json::Value root;
193 cin >> root["dir"]["file"];
194 cout << root;
195 \endcode
196 Result:
197 \verbatim
198 {
Baptiste Lepilleure3cc0f02011-05-02 18:41:01 +0000199 "dir": {
200 "file": {
201 // The input stream JSON would be nested here.
202 }
203 }
Christopher Dunn6d135cb2007-06-13 15:51:04 +0000204 }
205 \endverbatim
206 \throw std::exception on parse error.
207 \see Json::operator<<()
208 */
209 std::istream& operator>>( std::istream&, Value& );
210
211} // namespace Json
212
213#endif // CPPTL_JSON_READER_H_INCLUDED