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