blob: 07713429246c9492baa84c266b549640b121a11d [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 );
Aaron Jacobs642befc2014-04-23 23:28:23 +0000149 bool decodeNumber( Token &token, Value &decoded );
Christopher Dunn6d135cb2007-06-13 15:51:04 +0000150 bool decodeString( Token &token );
151 bool decodeString( Token &token, std::string &decoded );
152 bool decodeDouble( Token &token );
Aaron Jacobs642befc2014-04-23 23:28:23 +0000153 bool decodeDouble( Token &token, Value &decoded );
Malay Shahee4b4da2009-11-13 04:21:14 +0000154 bool decodeUnicodeCodePoint( Token &token,
155 Location &current,
156 Location end,
157 unsigned int &unicode );
Christopher Dunn6d135cb2007-06-13 15:51:04 +0000158 bool decodeUnicodeEscapeSequence( Token &token,
159 Location &current,
160 Location end,
161 unsigned int &unicode );
162 bool addError( const std::string &message,
163 Token &token,
164 Location extra = 0 );
165 bool recoverFromError( TokenType skipUntilToken );
166 bool addErrorAndRecover( const std::string &message,
167 Token &token,
168 TokenType skipUntilToken );
169 void skipUntilSpace();
170 Value &currentValue();
171 Char getNextChar();
172 void getLocationLineAndColumn( Location location,
173 int &line,
174 int &column ) const;
175 std::string getLocationLineAndColumn( Location location ) const;
176 void addComment( Location begin,
177 Location end,
178 CommentPlacement placement );
179 void skipCommentTokens( Token &token );
180
181 typedef std::stack<Value *> Nodes;
182 Nodes nodes_;
183 Errors errors_;
184 std::string document_;
185 Location begin_;
186 Location end_;
187 Location current_;
188 Location lastValueEnd_;
189 Value *lastValue_;
190 std::string commentsBefore_;
Baptiste Lepilleur88681472009-11-18 21:38:54 +0000191 Features features_;
Christopher Dunn6d135cb2007-06-13 15:51:04 +0000192 bool collectComments_;
193 };
194
195 /** \brief Read from 'sin' into 'root'.
196
197 Always keep comments from the input JSON.
198
199 This can be used to read a file into a particular sub-object.
200 For example:
201 \code
202 Json::Value root;
203 cin >> root["dir"]["file"];
204 cout << root;
205 \endcode
206 Result:
207 \verbatim
208 {
Baptiste Lepilleure3cc0f02011-05-02 18:41:01 +0000209 "dir": {
210 "file": {
211 // The input stream JSON would be nested here.
212 }
213 }
Christopher Dunn6d135cb2007-06-13 15:51:04 +0000214 }
215 \endverbatim
216 \throw std::exception on parse error.
217 \see Json::operator<<()
218 */
Baptiste Lepilleureafd7022013-05-08 20:21:11 +0000219 JSON_API std::istream& operator>>( std::istream&, Value& );
Christopher Dunn6d135cb2007-06-13 15:51:04 +0000220
221} // namespace Json
222
Baptiste Lepilleureafd7022013-05-08 20:21:11 +0000223#if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING)
224# pragma warning(pop)
225#endif // if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING)
226
227
Christopher Dunn6d135cb2007-06-13 15:51:04 +0000228#endif // CPPTL_JSON_READER_H_INCLUDED