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