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