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