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