blob: e1135699f86a18327fff2bbd58f79d075f579a06 [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 );
Malay Shahee4b4da2009-11-13 04:21:14 +0000118 bool decodeUnicodeCodePoint( Token &token,
119 Location &current,
120 Location end,
121 unsigned int &unicode );
Christopher Dunn6d135cb2007-06-13 15:51:04 +0000122 bool decodeUnicodeEscapeSequence( Token &token,
123 Location &current,
124 Location end,
125 unsigned int &unicode );
126 bool addError( const std::string &message,
127 Token &token,
128 Location extra = 0 );
129 bool recoverFromError( TokenType skipUntilToken );
130 bool addErrorAndRecover( const std::string &message,
131 Token &token,
132 TokenType skipUntilToken );
133 void skipUntilSpace();
134 Value &currentValue();
135 Char getNextChar();
136 void getLocationLineAndColumn( Location location,
137 int &line,
138 int &column ) const;
139 std::string getLocationLineAndColumn( Location location ) const;
140 void addComment( Location begin,
141 Location end,
142 CommentPlacement placement );
143 void skipCommentTokens( Token &token );
144
145 typedef std::stack<Value *> Nodes;
146 Nodes nodes_;
147 Errors errors_;
148 std::string document_;
149 Location begin_;
150 Location end_;
151 Location current_;
152 Location lastValueEnd_;
153 Value *lastValue_;
154 std::string commentsBefore_;
155 bool collectComments_;
156 };
157
158 /** \brief Read from 'sin' into 'root'.
159
160 Always keep comments from the input JSON.
161
162 This can be used to read a file into a particular sub-object.
163 For example:
164 \code
165 Json::Value root;
166 cin >> root["dir"]["file"];
167 cout << root;
168 \endcode
169 Result:
170 \verbatim
171 {
172 "dir": {
173 "file": {
174 // The input stream JSON would be nested here.
175 }
176 }
177 }
178 \endverbatim
179 \throw std::exception on parse error.
180 \see Json::operator<<()
181 */
182 std::istream& operator>>( std::istream&, Value& );
183
184} // namespace Json
185
186#endif // CPPTL_JSON_READER_H_INCLUDED