blob: a3023b31f5fe7299e9ad83288ca17778c3362578 [file] [log] [blame]
Leon Scroggins IIIf59fb0e2014-05-28 15:19:42 -04001// 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
6#ifndef CPPTL_JSON_READER_H_INCLUDED
7# define CPPTL_JSON_READER_H_INCLUDED
8
9#if !defined(JSON_IS_AMALGAMATION)
10# include "features.h"
11# include "value.h"
12#endif // if !defined(JSON_IS_AMALGAMATION)
13# include <deque>
14# include <stack>
15# include <string>
16
17namespace Json {
18
19 /** \brief Unserialize a <a HREF="http://www.json.org">JSON</a> document into a Value.
20 *
21 */
22 class JSON_API Reader
23 {
24 public:
25 typedef char Char;
26 typedef const Char *Location;
27
28 /** \brief Constructs a Reader allowing all features
29 * for parsing.
30 */
31 Reader();
32
33 /** \brief Constructs a Reader allowing the specified feature set
34 * for parsing.
35 */
36 Reader( const Features &features );
37
38 /** \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.
44 * This parameter is ignored if Features::allowComments_
45 * is \c false.
46 * \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.
53 * \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.
56 * \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.
60 * This parameter is ignored if Features::allowComments_
61 * is \c false.
62 * \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&).
70 bool parse( std::istream &is,
71 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.
78 * \deprecated Use getFormattedErrorMessages() instead (typo fix).
79 */
80 JSONCPP_DEPRECATED("Use getFormattedErrorMessages instead")
81 std::string getFormatedErrorMessages() const;
82
83 /** \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
90 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 );
144 bool decodeUnicodeCodePoint( Token &token,
145 Location &current,
146 Location end,
147 unsigned int &unicode );
148 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_;
181 Features features_;
182 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 {
199 "dir": {
200 "file": {
201 // The input stream JSON would be nested here.
202 }
203 }
204 }
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