blob: 5e4c32af984555db574b74c9f8caaba4496deee6 [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.
Baptiste Lepilleur40388492011-05-01 20:50:44 +000054 * \param beginDoc Pointer on the beginning of the UTF-8 encoded string of the document to read.
55 * \param endDoc Pointer on the end of the UTF-8 encoded string of the document to read.
56 \ Must be >= beginDoc.
Christopher Dunn6d135cb2007-06-13 15:51:04 +000057 * \param root [out] Contains the root value of the document if it was
58 * successfully parsed.
59 * \param collectComments \c true to collect comment and allow writing them back during
60 * serialization, \c false to discard comments.
Baptiste Lepilleur88681472009-11-18 21:38:54 +000061 * This parameter is ignored if Features::allowComments_
62 * is \c false.
Christopher Dunn6d135cb2007-06-13 15:51:04 +000063 * \return \c true if the document was successfully parsed, \c false if an error occurred.
64 */
65 bool parse( const char *beginDoc, const char *endDoc,
66 Value &root,
67 bool collectComments = true );
68
69 /// \brief Parse from input stream.
70 /// \see Json::operator>>(std::istream&, Json::Value&).
Baptiste Lepilleur88681472009-11-18 21:38:54 +000071 bool parse( std::istream &is,
Christopher Dunn6d135cb2007-06-13 15:51:04 +000072 Value &root,
73 bool collectComments = true );
74
75 /** \brief Returns a user friendly string that list errors in the parsed document.
76 * \return Formatted error message with the list of errors with their location in
77 * the parsed document. An empty string is returned if no error occurred
78 * during parsing.
Baptiste Lepilleurb2e8ccc2011-05-01 16:27:55 +000079 * \deprecated Use getFormattedErrorMessages() instead (typo fix).
Christopher Dunn6d135cb2007-06-13 15:51:04 +000080 */
Baptiste Lepilleurb2e8ccc2011-05-01 16:27:55 +000081 JSONCPP_DEPRECATED("Use getFormattedErrorMessages instead")
Christopher Dunn6d135cb2007-06-13 15:51:04 +000082 std::string getFormatedErrorMessages() const;
83
Baptiste Lepilleurb2e8ccc2011-05-01 16:27:55 +000084 /** \brief Returns a user friendly string that list errors in the parsed document.
85 * \return Formatted error message with the list of errors with their location in
86 * the parsed document. An empty string is returned if no error occurred
87 * during parsing.
88 */
89 std::string getFormattedErrorMessages() const;
90
Christopher Dunn6d135cb2007-06-13 15:51:04 +000091 private:
92 enum TokenType
93 {
94 tokenEndOfStream = 0,
95 tokenObjectBegin,
96 tokenObjectEnd,
97 tokenArrayBegin,
98 tokenArrayEnd,
99 tokenString,
100 tokenNumber,
101 tokenTrue,
102 tokenFalse,
103 tokenNull,
104 tokenArraySeparator,
105 tokenMemberSeparator,
106 tokenComment,
107 tokenError
108 };
109
110 class Token
111 {
112 public:
113 TokenType type_;
114 Location start_;
115 Location end_;
116 };
117
118 class ErrorInfo
119 {
120 public:
121 Token token_;
122 std::string message_;
123 Location extra_;
124 };
125
126 typedef std::deque<ErrorInfo> Errors;
127
128 bool expectToken( TokenType type, Token &token, const char *message );
129 bool readToken( Token &token );
130 void skipSpaces();
131 bool match( Location pattern,
132 int patternLength );
133 bool readComment();
134 bool readCStyleComment();
135 bool readCppStyleComment();
136 bool readString();
137 void readNumber();
138 bool readValue();
139 bool readObject( Token &token );
140 bool readArray( Token &token );
141 bool decodeNumber( Token &token );
142 bool decodeString( Token &token );
143 bool decodeString( Token &token, std::string &decoded );
144 bool decodeDouble( Token &token );
Malay Shahee4b4da2009-11-13 04:21:14 +0000145 bool decodeUnicodeCodePoint( Token &token,
146 Location &current,
147 Location end,
148 unsigned int &unicode );
Christopher Dunn6d135cb2007-06-13 15:51:04 +0000149 bool decodeUnicodeEscapeSequence( Token &token,
150 Location &current,
151 Location end,
152 unsigned int &unicode );
153 bool addError( const std::string &message,
154 Token &token,
155 Location extra = 0 );
156 bool recoverFromError( TokenType skipUntilToken );
157 bool addErrorAndRecover( const std::string &message,
158 Token &token,
159 TokenType skipUntilToken );
160 void skipUntilSpace();
161 Value &currentValue();
162 Char getNextChar();
163 void getLocationLineAndColumn( Location location,
164 int &line,
165 int &column ) const;
166 std::string getLocationLineAndColumn( Location location ) const;
167 void addComment( Location begin,
168 Location end,
169 CommentPlacement placement );
170 void skipCommentTokens( Token &token );
171
172 typedef std::stack<Value *> Nodes;
173 Nodes nodes_;
174 Errors errors_;
175 std::string document_;
176 Location begin_;
177 Location end_;
178 Location current_;
179 Location lastValueEnd_;
180 Value *lastValue_;
181 std::string commentsBefore_;
Baptiste Lepilleur88681472009-11-18 21:38:54 +0000182 Features features_;
Christopher Dunn6d135cb2007-06-13 15:51:04 +0000183 bool collectComments_;
184 };
185
186 /** \brief Read from 'sin' into 'root'.
187
188 Always keep comments from the input JSON.
189
190 This can be used to read a file into a particular sub-object.
191 For example:
192 \code
193 Json::Value root;
194 cin >> root["dir"]["file"];
195 cout << root;
196 \endcode
197 Result:
198 \verbatim
199 {
200 "dir": {
201 "file": {
202 // The input stream JSON would be nested here.
203 }
204 }
205 }
206 \endverbatim
207 \throw std::exception on parse error.
208 \see Json::operator<<()
209 */
210 std::istream& operator>>( std::istream&, Value& );
211
212} // namespace Json
213
214#endif // CPPTL_JSON_READER_H_INCLUDED