Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-05-20 22:39:45

0001 #ifndef CPPTL_JSON_READER_H_INCLUDED
0002 #define CPPTL_JSON_READER_H_INCLUDED
0003 
0004 #include "features.h"
0005 #include "value.h"
0006 #include <deque>
0007 #include <stack>
0008 #include <string>
0009 #include <iostream>
0010 
0011 namespace jsoncollector {
0012   namespace Json {
0013 
0014     /** \brief Unserialize a <a HREF="http://www.json.org">JSON</a> document into a Value.
0015     *
0016     */
0017     class JSON_API Reader {
0018     public:
0019       typedef char Char;
0020       typedef const Char *Location;
0021 
0022       /** \brief Constructs a Reader allowing all features
0023        * for parsing.
0024        */
0025       Reader();
0026 
0027       /** \brief Constructs a Reader allowing the specified feature set
0028        * for parsing.
0029        */
0030       Reader(const Features &features);
0031 
0032       /** \brief Read a Value from a <a HREF="http://www.json.org">JSON</a> document.
0033        * \param document UTF-8 encoded string containing the document to read.
0034        * \param root [out] Contains the root value of the document if it was
0035        *             successfully parsed.
0036        * \param collectComments \c true to collect comment and allow writing them back during
0037        *                        serialization, \c false to discard comments.
0038        *                        This parameter is ignored if Features::allowComments_
0039        *                        is \c false.
0040        * \return \c true if the document was successfully parsed, \c false if an error occurred.
0041        */
0042       bool parse(const std::string &document, Value &root, bool collectComments = true);
0043 
0044       /** \brief Read a Value from a <a HREF="http://www.json.org">JSON</a> document.
0045        * \param document UTF-8 encoded string containing the document to read.
0046        * \param root [out] Contains the root value of the document if it was
0047        *             successfully parsed.
0048        * \param collectComments \c true to collect comment and allow writing them back during
0049        *                        serialization, \c false to discard comments.
0050        *                        This parameter is ignored if Features::allowComments_
0051        *                        is \c false.
0052        * \return \c true if the document was successfully parsed, \c false if an error occurred.
0053        */
0054       bool parse(const char *beginDoc, const char *endDoc, Value &root, bool collectComments = true);
0055 
0056       /// \brief Parse from input stream.
0057       /// \see Json::operator>>(std::istream&, Json::Value&).
0058       bool parse(std::istream &is, Value &root, bool collectComments = true);
0059 
0060       /** \brief Returns a user friendly string that list errors in the parsed document.
0061        * \return Formatted error message with the list of errors with their location in 
0062        *         the parsed document. An empty string is returned if no error occurred
0063        *         during parsing.
0064        */
0065       std::string getFormatedErrorMessages() const;
0066 
0067     private:
0068       enum TokenType {
0069         tokenEndOfStream = 0,
0070         tokenObjectBegin,
0071         tokenObjectEnd,
0072         tokenArrayBegin,
0073         tokenArrayEnd,
0074         tokenString,
0075         tokenNumber,
0076         tokenTrue,
0077         tokenFalse,
0078         tokenNull,
0079         tokenArraySeparator,
0080         tokenMemberSeparator,
0081         tokenComment,
0082         tokenError
0083       };
0084 
0085       class Token {
0086       public:
0087         TokenType type_;
0088         Location start_;
0089         Location end_;
0090       };
0091 
0092       class ErrorInfo {
0093       public:
0094         Token token_;
0095         std::string message_;
0096         Location extra_;
0097       };
0098 
0099       typedef std::deque<ErrorInfo> Errors;
0100 
0101       bool expectToken(TokenType type, Token &token, const char *message);
0102       bool readToken(Token &token);
0103       void skipSpaces();
0104       bool match(Location pattern, int patternLength);
0105       bool readComment();
0106       bool readCStyleComment();
0107       bool readCppStyleComment();
0108       bool readString();
0109       void readNumber();
0110       bool readValue();
0111       bool readObject(Token &token);
0112       bool readArray(Token &token);
0113       bool decodeNumber(Token &token);
0114       bool decodeString(Token &token);
0115       bool decodeString(Token &token, std::string &decoded);
0116       bool decodeDouble(Token &token);
0117       bool decodeUnicodeCodePoint(Token &token, Location &current, Location end, unsigned int &unicode);
0118       bool decodeUnicodeEscapeSequence(Token &token, Location &current, Location end, unsigned int &unicode);
0119       bool addError(const std::string &message, Token &token, Location extra = nullptr);
0120       bool recoverFromError(TokenType skipUntilToken);
0121       bool addErrorAndRecover(const std::string &message, Token &token, TokenType skipUntilToken);
0122       void skipUntilSpace();
0123       Value &currentValue();
0124       Char getNextChar();
0125       void getLocationLineAndColumn(Location location, int &line, int &column) const;
0126       std::string getLocationLineAndColumn(Location location) const;
0127       void addComment(Location begin, Location end, CommentPlacement placement);
0128       void skipCommentTokens(Token &token);
0129 
0130       typedef std::stack<Value *> Nodes;
0131       Nodes nodes_;
0132       Errors errors_;
0133       std::string document_;
0134       Location begin_;
0135       Location end_;
0136       Location current_;
0137       Location lastValueEnd_;
0138       Value *lastValue_;
0139       std::string commentsBefore_;
0140       Features features_;
0141       bool collectComments_;
0142     };
0143 
0144     /** \brief Read from 'sin' into 'root'.
0145 
0146     Always keep comments from the input JSON.
0147 
0148     This can be used to read a file into a particular sub-object.
0149     For example:
0150     \code
0151     Json::Value root;
0152     cin >> root["dir"]["file"];
0153     cout << root;
0154     \endcode
0155     Result:
0156     \verbatim
0157     {
0158     "dir": {
0159         "file": {
0160         // The input stream JSON would be nested here.
0161         }
0162     }
0163     }
0164     \endverbatim
0165     \throw std::exception on parse error.
0166     \see Json::operator<<()
0167    */
0168     std::istream &operator>>(std::istream &, Value &);
0169 
0170   }  // namespace Json
0171 }  // namespace jsoncollector
0172 #endif  // CPPTL_JSON_READER_H_INCLUDED