JsonCpp源码阅读(一)——Reader类

 class JSON_API Reader
   {
   public:
      typedef char Char;
      typedef const Char *Location;

      /** rief Constructs a Reader allowing all features
       * for parsing.
       */
      Reader();

      /** rief Constructs a Reader allowing the specified feature set
       * for parsing.
       */
      Reader( const Features &features );

      /** rief Read a Value from a <a HREF="http://www.json.org">JSON</a> 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.
       * 
eturn 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 );

      /** rief Read a Value from a <a HREF="http://www.json.org">JSON</a> 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.
       * 
eturn 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 );

      /// rief Parse from input stream.
      /// see Json::operator>>(std::istream&, Json::Value&).
      bool parse( std::istream &is,
                  Value &root,
                  bool collectComments = true );

      /** rief Returns a user friendly string that list errors in the parsed document.
       * 
eturn 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
      };

      class Token
      {
      public:
         TokenType type_;
         Location start_;
         Location end_;
      };

      class ErrorInfo
      {
      public:
         Token token_;
         std::string message_;
         Location extra_;
      };

      typedef std::deque<ErrorInfo> 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 &current, 
                                   Location end, 
                                   unsigned int &unicode );
      bool decodeUnicodeEscapeSequence( Token &token, 
                                        Location &current, 
                                        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 &currentValue();
      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<Value *> 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_;
   };

简而言之:

Reader类的对外接口只有两个构造函数:
Reader();
Reader( const Features &features );
第二个构造函数,我们在后面再进行分析。

三个解析重载的解析函数:
 bool parse( const std::string &document, Value &root, bool collectComments = true );
 bool parse( const char *beginDoc, const char *endDoc, Value &root, bool collectComments = true );
 bool parse( std::istream &is, Value &root, bool collectComments = true );

一个获取错误信息函数:

  std::string getFormatedErrorMessages() const;

这些是Reader类的对外接口。接着我们看是如何实现的,从它的简单的私有函数开始:

void Reader::skipSpaces()
{
   while ( current_ != end_ )
   {
      Char c = *current_;
      if ( c == ' '  ||  c == '	'  ||  c == '
'  ||  c == '
' )
         ++current_;
      else
         break;
   }
}

void skipSpaces(); 该函数是跳过开通所有空格,' ',' '和' '字符。使用的是私有成员变量:

Location begin_;
Location end_;
Location current_;
Location lastValueEnd_;

其中的Location类型是const char *类型的指针,从typedef char Char;和typedef const Char *Location;这知道。

Reader::Char Reader::getNextChar()
{
   if ( current_ == end_ )
      return 0;
   return *current_++;
}

这里的getNextChar(),是获取到当前字符,然后 current_指针往后移动一次。这里感觉这个函数名和函数的行为不符合啊,大家有什么见解可以提出了,有可能是我的疏漏。





未完待续...
原文地址:https://www.cnblogs.com/hpcpp/p/7890427.html