Home | History | Annotate | Download | only in json
      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 &current,
    146                                    Location end,
    147                                    unsigned int &unicode );
    148       bool decodeUnicodeEscapeSequence( Token &token,
    149                                         Location &current,
    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 &currentValue();
    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