Browse Source

[2572] added InputSource::getPosition() to return the current positio of src.

JINMEI Tatuya 12 years ago
parent
commit
989e0535b0

+ 6 - 0
src/lib/dns/master_lexer_inputsource.cc

@@ -65,6 +65,7 @@ InputSource::InputSource(std::istream& input_stream) :
     line_(1),
     saved_line_(line_),
     buffer_pos_(0),
+    total_pos_(0),
     name_(createStreamName(input_stream)),
     input_(input_stream),
     input_size_(getStreamSize(input_))
@@ -96,6 +97,7 @@ InputSource::InputSource(const char* filename) :
     line_(1),
     saved_line_(line_),
     buffer_pos_(0),
+    total_pos_(0),
     name_(filename),
     input_(openFileStream(file_stream_, filename)),
     input_size_(getStreamSize(input_))
@@ -137,6 +139,7 @@ InputSource::getChar() {
 
     const int c = buffer_[buffer_pos_];
     ++buffer_pos_;
+    ++total_pos_;
     if (c == '\n') {
         ++line_;
     }
@@ -153,6 +156,7 @@ InputSource::ungetChar() {
                   "Cannot skip before the start of buffer");
     } else {
         --buffer_pos_;
+        --total_pos_;
         if (buffer_[buffer_pos_] == '\n') {
             --line_;
         }
@@ -161,6 +165,8 @@ InputSource::ungetChar() {
 
 void
 InputSource::ungetAll() {
+    assert(total_pos_ >= buffer_pos_);
+    total_pos_ -= buffer_pos_;
     buffer_pos_ = 0;
     line_ = saved_line_;
     at_eof_ = false;

+ 20 - 1
src/lib/dns/master_lexer_inputsource.h

@@ -91,9 +91,27 @@ public:
     /// the data available in the stream at the time of the construction of
     /// the source.
     ///
-    /// \throw None.
+    /// \throw None
     size_t getSize() const { return (input_size_); }
 
+    /// \brief Returns the current read position in the input source.
+    ///
+    /// This method returns the position of the character that was last
+    /// retrieved from the source.  Unless some characters have been
+    /// "ungotten" by \c ungetChar() or \c ungetAll(), this value is equal
+    /// to the number of calls to \c getChar() until it reaches the
+    /// END_OF_STREAM.  Note that the position of the first character in
+    /// the source is 1.  At the point of the last character, the return value
+    /// of this method should be equal to that of \c getSize(), and
+    /// recognizing END_OF_STREAM doesn't increase the position.
+    ///
+    /// If \c ungetChar() or \c ungetAll() is called, the position is
+    /// decreased by the number of "ungotten" characters.  So the return
+    /// values may not always monotonically increase.
+    ///
+    /// \throw None
+    size_t getPosition() const { return (total_pos_); }
+
     /// \brief Returns if the input source is at end of file.
     bool atEOF() const {
         return (at_eof_);
@@ -153,6 +171,7 @@ private:
 
     std::vector<char> buffer_;
     size_t buffer_pos_;
+    size_t total_pos_;
 
     const std::string name_;
     std::ifstream file_stream_;

+ 19 - 0
src/lib/dns/tests/master_lexer_inputsource_unittest.cc

@@ -76,6 +76,7 @@ checkGetAndUngetChar(InputSource& source,
 {
     for (size_t i = 0; i < str_length; ++i) {
         EXPECT_EQ(str[i], source.getChar());
+        EXPECT_EQ(i + 1, source.getPosition());
         EXPECT_FALSE(source.atEOF());
     }
 
@@ -88,6 +89,10 @@ checkGetAndUngetChar(InputSource& source,
     // Now, EOF should be set.
     EXPECT_TRUE(source.atEOF());
 
+    // It doesn't increase the position count.
+    EXPECT_EQ(str_length, source.getPosition());
+    EXPECT_EQ(str_length, source.getSize()); // this should be == getSize().
+
     // Now, let's go backwards. This should cause the EOF to be set to
     // false.
     source.ungetChar();
@@ -95,6 +100,9 @@ checkGetAndUngetChar(InputSource& source,
     // Now, EOF should be false.
     EXPECT_FALSE(source.atEOF());
 
+    // But the position shouldn't change.
+    EXPECT_EQ(str_length, source.getPosition());
+
     // This should cause EOF to be set again.
     EXPECT_EQ(InputSource::END_OF_STREAM, source.getChar());
 
@@ -109,6 +117,7 @@ checkGetAndUngetChar(InputSource& source,
         // Skip one character.
         source.ungetChar();
         EXPECT_EQ(str[index], source.getChar());
+        EXPECT_EQ(index + 1, source.getPosition());
         // Skip the character we received again.
         source.ungetChar();
     }
@@ -147,6 +156,7 @@ TEST_F(InputSourceTest, ungetAll) {
     // Now we are back to where we started.
     EXPECT_EQ(1, source_.getCurrentLine());
     EXPECT_FALSE(source_.atEOF());
+    EXPECT_EQ(0, source_.getPosition());
 }
 
 TEST_F(InputSourceTest, compact) {
@@ -178,6 +188,9 @@ TEST_F(InputSourceTest, compact) {
     EXPECT_TRUE(source_.atEOF());
     EXPECT_EQ(4, source_.getCurrentLine());
 
+    // compact shouldn't change the position count.
+    EXPECT_EQ(source_.getSize(), source_.getPosition());
+
     // Skip the EOF.
     source_.ungetChar();
 
@@ -343,4 +356,10 @@ TEST_F(InputSourceTest, getSize) {
     EXPECT_EQ(143, InputSource(TEST_DATA_SRCDIR "/masterload.txt").getSize());
 }
 
+TEST_F(InputSourceTest, getPosition) {
+    // Initially the position is set to 0.
+    EXPECT_EQ(0, source_.getPosition());
+    EXPECT_EQ(0, InputSource(TEST_DATA_SRCDIR "/masterload.txt").getPosition());
+}
+
 } // end namespace