rt300@0: #ifndef CPPTL_JSON_READER_H_INCLUDED rt300@0: # define CPPTL_JSON_READER_H_INCLUDED rt300@0: rt300@0: # include "features.h" rt300@0: # include "value.h" rt300@0: # include rt300@0: # include rt300@0: # include rt300@0: # include rt300@0: rt300@0: namespace Json { rt300@0: rt300@0: /** \brief Unserialize a JSON document into a Value. rt300@0: * rt300@0: */ rt300@0: class JSON_API Reader rt300@0: { rt300@0: public: rt300@0: typedef char Char; rt300@0: typedef const Char *Location; rt300@0: rt300@0: /** \brief Constructs a Reader allowing all features rt300@0: * for parsing. rt300@0: */ rt300@0: Reader(); rt300@0: rt300@0: /** \brief Constructs a Reader allowing the specified feature set rt300@0: * for parsing. rt300@0: */ rt300@0: Reader( const Features &features ); rt300@0: rt300@0: /** \brief Read a Value from a JSON document. rt300@0: * \param document UTF-8 encoded string containing the document to read. rt300@0: * \param root [out] Contains the root value of the document if it was rt300@0: * successfully parsed. rt300@0: * \param collectComments \c true to collect comment and allow writing them back during rt300@0: * serialization, \c false to discard comments. rt300@0: * This parameter is ignored if Features::allowComments_ rt300@0: * is \c false. rt300@0: * \return \c true if the document was successfully parsed, \c false if an error occurred. rt300@0: */ rt300@0: bool parse( const std::string &document, rt300@0: Value &root, rt300@0: bool collectComments = true ); rt300@0: rt300@0: /** \brief Read a Value from a JSON document. rt300@0: * \param document UTF-8 encoded string containing the document to read. rt300@0: * \param root [out] Contains the root value of the document if it was rt300@0: * successfully parsed. rt300@0: * \param collectComments \c true to collect comment and allow writing them back during rt300@0: * serialization, \c false to discard comments. rt300@0: * This parameter is ignored if Features::allowComments_ rt300@0: * is \c false. rt300@0: * \return \c true if the document was successfully parsed, \c false if an error occurred. rt300@0: */ rt300@0: bool parse( const char *beginDoc, const char *endDoc, rt300@0: Value &root, rt300@0: bool collectComments = true ); rt300@0: rt300@0: /// \brief Parse from input stream. rt300@0: /// \see Json::operator>>(std::istream&, Json::Value&). rt300@0: bool parse( std::istream &is, rt300@0: Value &root, rt300@0: bool collectComments = true ); rt300@0: rt300@0: /** \brief Returns a user friendly string that list errors in the parsed document. rt300@0: * \return Formatted error message with the list of errors with their location in rt300@0: * the parsed document. An empty string is returned if no error occurred rt300@0: * during parsing. rt300@0: */ rt300@0: std::string getFormatedErrorMessages() const; rt300@0: rt300@0: private: rt300@0: enum TokenType rt300@0: { rt300@0: tokenEndOfStream = 0, rt300@0: tokenObjectBegin, rt300@0: tokenObjectEnd, rt300@0: tokenArrayBegin, rt300@0: tokenArrayEnd, rt300@0: tokenString, rt300@0: tokenNumber, rt300@0: tokenTrue, rt300@0: tokenFalse, rt300@0: tokenNull, rt300@0: tokenArraySeparator, rt300@0: tokenMemberSeparator, rt300@0: tokenComment, rt300@0: tokenError rt300@0: }; rt300@0: rt300@0: class Token rt300@0: { rt300@0: public: rt300@0: TokenType type_; rt300@0: Location start_; rt300@0: Location end_; rt300@0: }; rt300@0: rt300@0: class ErrorInfo rt300@0: { rt300@0: public: rt300@0: Token token_; rt300@0: std::string message_; rt300@0: Location extra_; rt300@0: }; rt300@0: rt300@0: typedef std::deque Errors; rt300@0: rt300@0: bool expectToken( TokenType type, Token &token, const char *message ); rt300@0: bool readToken( Token &token ); rt300@0: void skipSpaces(); rt300@0: bool match( Location pattern, rt300@0: int patternLength ); rt300@0: bool readComment(); rt300@0: bool readCStyleComment(); rt300@0: bool readCppStyleComment(); rt300@0: bool readString(); rt300@0: void readNumber(); rt300@0: bool readValue(); rt300@0: bool readObject( Token &token ); rt300@0: bool readArray( Token &token ); rt300@0: bool decodeNumber( Token &token ); rt300@0: bool decodeString( Token &token ); rt300@0: bool decodeString( Token &token, std::string &decoded ); rt300@0: bool decodeDouble( Token &token ); rt300@0: bool decodeUnicodeCodePoint( Token &token, rt300@0: Location ¤t, rt300@0: Location end, rt300@0: unsigned int &unicode ); rt300@0: bool decodeUnicodeEscapeSequence( Token &token, rt300@0: Location ¤t, rt300@0: Location end, rt300@0: unsigned int &unicode ); rt300@0: bool addError( const std::string &message, rt300@0: Token &token, rt300@0: Location extra = 0 ); rt300@0: bool recoverFromError( TokenType skipUntilToken ); rt300@0: bool addErrorAndRecover( const std::string &message, rt300@0: Token &token, rt300@0: TokenType skipUntilToken ); rt300@0: void skipUntilSpace(); rt300@0: Value ¤tValue(); rt300@0: Char getNextChar(); rt300@0: void getLocationLineAndColumn( Location location, rt300@0: int &line, rt300@0: int &column ) const; rt300@0: std::string getLocationLineAndColumn( Location location ) const; rt300@0: void addComment( Location begin, rt300@0: Location end, rt300@0: CommentPlacement placement ); rt300@0: void skipCommentTokens( Token &token ); rt300@0: rt300@0: typedef std::stack Nodes; rt300@0: Nodes nodes_; rt300@0: Errors errors_; rt300@0: std::string document_; rt300@0: Location begin_; rt300@0: Location end_; rt300@0: Location current_; rt300@0: Location lastValueEnd_; rt300@0: Value *lastValue_; rt300@0: std::string commentsBefore_; rt300@0: Features features_; rt300@0: bool collectComments_; rt300@0: }; rt300@0: rt300@0: /** \brief Read from 'sin' into 'root'. rt300@0: rt300@0: Always keep comments from the input JSON. rt300@0: rt300@0: This can be used to read a file into a particular sub-object. rt300@0: For example: rt300@0: \code rt300@0: Json::Value root; rt300@0: cin >> root["dir"]["file"]; rt300@0: cout << root; rt300@0: \endcode rt300@0: Result: rt300@0: \verbatim rt300@0: { rt300@0: "dir": { rt300@0: "file": { rt300@0: // The input stream JSON would be nested here. rt300@0: } rt300@0: } rt300@0: } rt300@0: \endverbatim rt300@0: \throw std::exception on parse error. rt300@0: \see Json::operator<<() rt300@0: */ rt300@0: std::istream& operator>>( std::istream&, Value& ); rt300@0: rt300@0: } // namespace Json rt300@0: rt300@0: #endif // CPPTL_JSON_READER_H_INCLUDED