blob: f1bc5a2efe79645bf5b32115968293f43e0e4b85 [file] [log] [blame]
Christopher Dunn6d135cb2007-06-13 15:51:04 +00001#ifndef CPPTL_JSON_READER_H_INCLUDED
2# define CPPTL_JSON_READER_H_INCLUDED
3
4# include "forwards.h"
5# include "value.h"
6# include <deque>
7# include <stack>
8# include <string>
9# include <iostream>
10
11namespace Json {
12
13 class Value;
14
15 /** \brief Unserialize a <a HREF="http://www.json.org">JSON</a> document into a Value.
16 *
17 *
18 */
19 class JSON_API Reader
20 {
21 public:
22 typedef char Char;
23 typedef const Char *Location;
24
25 Reader();
26
27 /** \brief Read a Value from a <a HREF="http://www.json.org">JSON</a> document.
28 * \param document UTF-8 encoded string containing the document to read.
29 * \param root [out] Contains the root value of the document if it was
30 * successfully parsed.
31 * \param collectComments \c true to collect comment and allow writing them back during
32 * serialization, \c false to discard comments.
33 * \return \c true if the document was successfully parsed, \c false if an error occurred.
34 */
35 bool parse( const std::string &document,
36 Value &root,
37 bool collectComments = true );
38
39 /** \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.
45 * \return \c true if the document was successfully parsed, \c false if an error occurred.
46 */
47 bool parse( const char *beginDoc, const char *endDoc,
48 Value &root,
49 bool collectComments = true );
50
51 /// \brief Parse from input stream.
52 /// \see Json::operator>>(std::istream&, Json::Value&).
53 bool parse( std::istream&,
54 Value &root,
55 bool collectComments = true );
56
57 /** \brief Returns a user friendly string that list errors in the parsed document.
58 * \return Formatted error message with the list of errors with their location in
59 * the parsed document. An empty string is returned if no error occurred
60 * during parsing.
61 */
62 std::string getFormatedErrorMessages() const;
63
64 private:
65 enum TokenType
66 {
67 tokenEndOfStream = 0,
68 tokenObjectBegin,
69 tokenObjectEnd,
70 tokenArrayBegin,
71 tokenArrayEnd,
72 tokenString,
73 tokenNumber,
74 tokenTrue,
75 tokenFalse,
76 tokenNull,
77 tokenArraySeparator,
78 tokenMemberSeparator,
79 tokenComment,
80 tokenError
81 };
82
83 class Token
84 {
85 public:
86 TokenType type_;
87 Location start_;
88 Location end_;
89 };
90
91 class ErrorInfo
92 {
93 public:
94 Token token_;
95 std::string message_;
96 Location extra_;
97 };
98
99 typedef std::deque<ErrorInfo> Errors;
100
101 bool expectToken( TokenType type, Token &token, const char *message );
102 bool readToken( Token &token );
103 void skipSpaces();
104 bool match( Location pattern,
105 int patternLength );
106 bool readComment();
107 bool readCStyleComment();
108 bool readCppStyleComment();
109 bool readString();
110 void readNumber();
111 bool readValue();
112 bool readObject( Token &token );
113 bool readArray( Token &token );
114 bool decodeNumber( Token &token );
115 bool decodeString( Token &token );
116 bool decodeString( Token &token, std::string &decoded );
117 bool decodeDouble( Token &token );
118 bool decodeUnicodeEscapeSequence( Token &token,
119 Location &current,
120 Location end,
121 unsigned int &unicode );
122 bool addError( const std::string &message,
123 Token &token,
124 Location extra = 0 );
125 bool recoverFromError( TokenType skipUntilToken );
126 bool addErrorAndRecover( const std::string &message,
127 Token &token,
128 TokenType skipUntilToken );
129 void skipUntilSpace();
130 Value &currentValue();
131 Char getNextChar();
132 void getLocationLineAndColumn( Location location,
133 int &line,
134 int &column ) const;
135 std::string getLocationLineAndColumn( Location location ) const;
136 void addComment( Location begin,
137 Location end,
138 CommentPlacement placement );
139 void skipCommentTokens( Token &token );
140
141 typedef std::stack<Value *> Nodes;
142 Nodes nodes_;
143 Errors errors_;
144 std::string document_;
145 Location begin_;
146 Location end_;
147 Location current_;
148 Location lastValueEnd_;
149 Value *lastValue_;
150 std::string commentsBefore_;
151 bool collectComments_;
152 };
153
154 /** \brief Read from 'sin' into 'root'.
155
156 Always keep comments from the input JSON.
157
158 This can be used to read a file into a particular sub-object.
159 For example:
160 \code
161 Json::Value root;
162 cin >> root["dir"]["file"];
163 cout << root;
164 \endcode
165 Result:
166 \verbatim
167 {
168 "dir": {
169 "file": {
170 // The input stream JSON would be nested here.
171 }
172 }
173 }
174 \endverbatim
175 \throw std::exception on parse error.
176 \see Json::operator<<()
177 */
178 std::istream& operator>>( std::istream&, Value& );
179
180} // namespace Json
181
182#endif // CPPTL_JSON_READER_H_INCLUDED