Browse Source

[2373] unrelated extension to getString(): allow recycling the string

I expect we'll need the string object version of token pretty often
for rrtype and TTL, and this version will help make it a bit more
efficient.
JINMEI Tatuya 12 years ago
parent
commit
ac107fab88
2 changed files with 31 additions and 2 deletions
  1. 24 2
      src/lib/dns/master_lexer.h
  2. 7 0
      src/lib/dns/tests/master_lexer_token_unittest.cc

+ 24 - 2
src/lib/dns/master_lexer.h

@@ -340,12 +340,34 @@ public:
     ///                       string object.
     /// \return A std::string object corresponding to the string token value.
     std::string getString() const {
+        std::string ret;
+        getString(ret);
+        return (ret);
+    }
+
+    /// \brief Fill in a string with the value of a string-variant token.
+    ///
+    /// This is similar to the other version of \c getString(), but
+    /// the caller is supposed to pass a placeholder string object.
+    /// This will be more efficient if the caller uses the same
+    /// \c MasterLexer repeatedly and needs to get string token in the
+    /// form of a string object many times as this version could reuse
+    /// the existing internal storage of the passed string.
+    ///
+    /// Any existing content of the passed string will be removed.
+    ///
+    /// \throw InvalidOperation Called on a non string-variant types of token.
+    /// \throw std::bad_alloc Resource allocation failure in constructing the
+    ///                       string object.
+    ///
+    /// \param ret A string object to be filled with the token string.
+    void getString(std::string& ret) const {
         if (type_ != STRING && type_ != QSTRING) {
             isc_throw(InvalidOperation,
                       "Token::getString() for non string-variant type");
         }
-        return (std::string(val_.str_region_.beg,
-                            val_.str_region_.beg + val_.str_region_.len));
+        ret.assign(val_.str_region_.beg,
+                   val_.str_region_.beg + val_.str_region_.len);
     }
 
     /// \brief Return the value of a string-variant token as a string object.

+ 7 - 0
src/lib/dns/tests/master_lexer_token_unittest.cc

@@ -48,6 +48,9 @@ TEST_F(MasterLexerTokenTest, strings) {
     // basic construction and getter checks
     EXPECT_EQ(MasterLexer::Token::STRING, token_str.getType());
     EXPECT_EQ(std::string("string token"), token_str.getString());
+    std::string strval = "dummy"; // this should be replaced
+    token_str.getString(strval);
+    EXPECT_EQ(std::string("string token"), strval);
     const MasterLexer::Token::StringRegion str_region =
         token_str.getStringRegion();
     EXPECT_EQ(TEST_STRING, str_region.beg);
@@ -60,6 +63,8 @@ TEST_F(MasterLexerTokenTest, strings) {
     expected_str.push_back('\0');
     EXPECT_EQ(expected_str,
               MasterLexer::Token(TEST_STRING, TEST_STRING_LEN + 1).getString());
+    MasterLexer::Token(TEST_STRING, TEST_STRING_LEN + 1).getString(strval);
+    EXPECT_EQ(expected_str, strval);
 
     // Construct type of qstring
     EXPECT_EQ(MasterLexer::Token::QSTRING,
@@ -72,7 +77,9 @@ TEST_F(MasterLexerTokenTest, strings) {
 
     // getString/StringRegion() aren't allowed for non string(-variant) types
     EXPECT_THROW(token_eof.getString(), isc::InvalidOperation);
+    EXPECT_THROW(token_eof.getString(strval), isc::InvalidOperation);
     EXPECT_THROW(token_num.getString(), isc::InvalidOperation);
+    EXPECT_THROW(token_num.getString(strval), isc::InvalidOperation);
     EXPECT_THROW(token_eof.getStringRegion(), isc::InvalidOperation);
     EXPECT_THROW(token_num.getStringRegion(), isc::InvalidOperation);
 }