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