blob: 3d8f6286585cd00458220aa3f5361715dcf7811a [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 Lepilleureadc4782011-05-02 21:09:30 +00009#if !defined(JSON_IS_AMALGAMATION)
Baptiste Lepilleur88681472009-11-18 21:38:54 +000010# include "features.h"
Christopher Dunn6d135cb2007-06-13 15:51:04 +000011# include "value.h"
Baptiste Lepilleureadc4782011-05-02 21:09:30 +000012#endif // if !defined(JSON_IS_AMALGAMATION)
Christopher Dunn6d135cb2007-06-13 15:51:04 +000013# include <deque>
Aaron Jacobs94d17e92014-01-29 00:13:38 +000014# include <iosfwd>
Christopher Dunn6d135cb2007-06-13 15:51:04 +000015# include <stack>
16# include <string>
Christopher Dunn6d135cb2007-06-13 15:51:04 +000017
Baptiste Lepilleureafd7022013-05-08 20:21:11 +000018// Disable warning C4251: <data member>: <type> needs to have dll-interface to be used by...
19#if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING)
20# pragma warning(push)
21# pragma warning(disable:4251)
22#endif // if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING)
23
24
Christopher Dunn6d135cb2007-06-13 15:51:04 +000025namespace Json {
26
Christopher Dunn6d135cb2007-06-13 15:51:04 +000027 /** \brief Unserialize a <a HREF="http://www.json.org">JSON</a> document into a Value.
28 *
Christopher Dunn6d135cb2007-06-13 15:51:04 +000029 */
30 class JSON_API Reader
31 {
32 public:
33 typedef char Char;
34 typedef const Char *Location;
35
Baptiste Lepilleur88681472009-11-18 21:38:54 +000036 /** \brief Constructs a Reader allowing all features
37 * for parsing.
38 */
Christopher Dunn6d135cb2007-06-13 15:51:04 +000039 Reader();
40
Baptiste Lepilleur88681472009-11-18 21:38:54 +000041 /** \brief Constructs a Reader allowing the specified feature set
42 * for parsing.
43 */
44 Reader( const Features &features );
45
Christopher Dunn6d135cb2007-06-13 15:51:04 +000046 /** \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.
Baptiste Lepilleur88681472009-11-18 21:38:54 +000052 * This parameter is ignored if Features::allowComments_
53 * is \c false.
Christopher Dunn6d135cb2007-06-13 15:51:04 +000054 * \return \c true if the document was successfully parsed, \c false if an error occurred.
55 */
56 bool parse( const std::string &document,
57 Value &root,
58 bool collectComments = true );
59
60 /** \brief Read a Value from a <a HREF="http://www.json.org">JSON</a> document.
Baptiste Lepilleur40388492011-05-01 20:50:44 +000061 * \param beginDoc Pointer on the beginning of the UTF-8 encoded string of the document to read.
62 * \param endDoc Pointer on the end of the UTF-8 encoded string of the document to read.
63 \ Must be >= beginDoc.
Christopher Dunn6d135cb2007-06-13 15:51:04 +000064 * \param root [out] Contains the root value of the document if it was
65 * successfully parsed.
66 * \param collectComments \c true to collect comment and allow writing them back during
67 * serialization, \c false to discard comments.
Baptiste Lepilleur88681472009-11-18 21:38:54 +000068 * This parameter is ignored if Features::allowComments_
69 * is \c false.
Christopher Dunn6d135cb2007-06-13 15:51:04 +000070 * \return \c true if the document was successfully parsed, \c false if an error occurred.
71 */
72 bool parse( const char *beginDoc, const char *endDoc,
73 Value &root,
74 bool collectComments = true );
75
76 /// \brief Parse from input stream.
77 /// \see Json::operator>>(std::istream&, Json::Value&).
Baptiste Lepilleur88681472009-11-18 21:38:54 +000078 bool parse( std::istream &is,
Christopher Dunn6d135cb2007-06-13 15:51:04 +000079 Value &root,
80 bool collectComments = true );
81
82 /** \brief Returns a user friendly string that list errors in the parsed document.
83 * \return Formatted error message with the list of errors with their location in
84 * the parsed document. An empty string is returned if no error occurred
85 * during parsing.
Baptiste Lepilleurb2e8ccc2011-05-01 16:27:55 +000086 * \deprecated Use getFormattedErrorMessages() instead (typo fix).
Christopher Dunn6d135cb2007-06-13 15:51:04 +000087 */
Baptiste Lepilleurb2e8ccc2011-05-01 16:27:55 +000088 JSONCPP_DEPRECATED("Use getFormattedErrorMessages instead")
Christopher Dunn6d135cb2007-06-13 15:51:04 +000089 std::string getFormatedErrorMessages() const;
90
Baptiste Lepilleurb2e8ccc2011-05-01 16:27:55 +000091 /** \brief Returns a user friendly string that list errors in the parsed document.
92 * \return Formatted error message with the list of errors with their location in
93 * the parsed document. An empty string is returned if no error occurred
94 * during parsing.
95 */
96 std::string getFormattedErrorMessages() const;
97
Christopher Dunn6d135cb2007-06-13 15:51:04 +000098 private:
99 enum TokenType
100 {
101 tokenEndOfStream = 0,
102 tokenObjectBegin,
103 tokenObjectEnd,
104 tokenArrayBegin,
105 tokenArrayEnd,
106 tokenString,
107 tokenNumber,
108 tokenTrue,
109 tokenFalse,
110 tokenNull,
111 tokenArraySeparator,
112 tokenMemberSeparator,
113 tokenComment,
114 tokenError
115 };
116
117 class Token
118 {
119 public:
120 TokenType type_;
121 Location start_;
122 Location end_;
123 };
124
125 class ErrorInfo
126 {
127 public:
128 Token token_;
129 std::string message_;
130 Location extra_;
131 };
132
133 typedef std::deque<ErrorInfo> Errors;
134
135 bool expectToken( TokenType type, Token &token, const char *message );
136 bool readToken( Token &token );
137 void skipSpaces();
138 bool match( Location pattern,
139 int patternLength );
140 bool readComment();
141 bool readCStyleComment();
142 bool readCppStyleComment();
143 bool readString();
144 void readNumber();
145 bool readValue();
146 bool readObject( Token &token );
147 bool readArray( Token &token );
148 bool decodeNumber( Token &token );
149 bool decodeString( Token &token );
150 bool decodeString( Token &token, std::string &decoded );
151 bool decodeDouble( Token &token );
Malay Shahee4b4da2009-11-13 04:21:14 +0000152 bool decodeUnicodeCodePoint( Token &token,
153 Location &current,
154 Location end,
155 unsigned int &unicode );
Christopher Dunn6d135cb2007-06-13 15:51:04 +0000156 bool decodeUnicodeEscapeSequence( Token &token,
157 Location &current,
158 Location end,
159 unsigned int &unicode );
160 bool addError( const std::string &message,
161 Token &token,
162 Location extra = 0 );
163 bool recoverFromError( TokenType skipUntilToken );
164 bool addErrorAndRecover( const std::string &message,
165 Token &token,
166 TokenType skipUntilToken );
167 void skipUntilSpace();
168 Value &currentValue();
169 Char getNextChar();
170 void getLocationLineAndColumn( Location location,
171 int &line,
172 int &column ) const;
173 std::string getLocationLineAndColumn( Location location ) const;
174 void addComment( Location begin,
175 Location end,
176 CommentPlacement placement );
177 void skipCommentTokens( Token &token );
178
179 typedef std::stack<Value *> Nodes;
180 Nodes nodes_;
181 Errors errors_;
182 std::string document_;
183 Location begin_;
184 Location end_;
185 Location current_;
186 Location lastValueEnd_;
187 Value *lastValue_;
188 std::string commentsBefore_;
Baptiste Lepilleur88681472009-11-18 21:38:54 +0000189 Features features_;
Christopher Dunn6d135cb2007-06-13 15:51:04 +0000190 bool collectComments_;
191 };
192
193 /** \brief Read from 'sin' into 'root'.
194
195 Always keep comments from the input JSON.
196
197 This can be used to read a file into a particular sub-object.
198 For example:
199 \code
200 Json::Value root;
201 cin >> root["dir"]["file"];
202 cout << root;
203 \endcode
204 Result:
205 \verbatim
206 {
Baptiste Lepilleure3cc0f02011-05-02 18:41:01 +0000207 "dir": {
208 "file": {
209 // The input stream JSON would be nested here.
210 }
211 }
Christopher Dunn6d135cb2007-06-13 15:51:04 +0000212 }
213 \endverbatim
214 \throw std::exception on parse error.
215 \see Json::operator<<()
216 */
Baptiste Lepilleureafd7022013-05-08 20:21:11 +0000217 JSON_API std::istream& operator>>( std::istream&, Value& );
Christopher Dunn6d135cb2007-06-13 15:51:04 +0000218
219} // namespace Json
220
Baptiste Lepilleureafd7022013-05-08 20:21:11 +0000221#if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING)
222# pragma warning(pop)
223#endif // if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING)
224
225
Christopher Dunn6d135cb2007-06-13 15:51:04 +0000226#endif // CPPTL_JSON_READER_H_INCLUDED