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