BIND 10 master, updated. 1fc2b06b57a008ec602daa2dac79939b3cc6b65d Merge branch 'master' into trac2053

BIND 10 source code commits bind10-changes at lists.isc.org
Thu Jul 5 06:42:01 UTC 2012


The branch, master has been updated
       via  1fc2b06b57a008ec602daa2dac79939b3cc6b65d (commit)
       via  9771dfb067dc0bf250d69bc4c07c811573d2c656 (commit)
       via  398b2215386cb1c28d764333404c1389cb87999c (commit)
       via  23ae3c2bbdf1a9f22c124aeeac2ac3c1692deb76 (commit)
       via  3a1e804a487e5406ec11bd62ae4ed76a15c49970 (commit)
       via  d83d9fe8ef6beaebe03fd486ca9b203aa60b4891 (commit)
       via  fdcc93e8ee07547f9fe86d56999b9ed5b5ac78d2 (commit)
       via  09d780b7f01d9f94e0da683ddc2539f2f5b03d1a (commit)
       via  e20691f8d713bb257033db96533fff11f5872752 (commit)
       via  15364a524a668d37a4fd63427f4eda5fd79e60e6 (commit)
       via  6c78bb408db659d97a4af548da504175a22bfabe (commit)
       via  b945fd1c9eee6fd70016a24b547426e1633faf8f (commit)
       via  efb3f3344d624ca830d07798948e01f07e118820 (commit)
       via  fb5902b031a00a249a32c7561b71e951e1aad6f0 (commit)
       via  36d3b727081be4b49bdb1dc78f71fb231605c057 (commit)
       via  0bebde9e2558dd2303c8b522dfff54281cb5aa0a (commit)
      from  d5ec81ad8f86f860c2b8e5c9980268da2efdd94e (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
commit 1fc2b06b57a008ec602daa2dac79939b3cc6b65d
Merge: 9771dfb d5ec81a
Author: Mukund Sivaraman <muks at isc.org>
Date:   Thu Jul 5 11:15:10 2012 +0530

    Merge branch 'master' into trac2053

-----------------------------------------------------------------------

Summary of changes:
 src/lib/dns/labelsequence.cc                |   88 ++++++++++++++++++++++++++
 src/lib/dns/labelsequence.h                 |   57 ++++++++++++++---
 src/lib/dns/name.cc                         |   78 +----------------------
 src/lib/dns/tests/labelsequence_unittest.cc |   90 ++++++++++++++++++++++++++-
 4 files changed, 227 insertions(+), 86 deletions(-)

-----------------------------------------------------------------------
diff --git a/src/lib/dns/labelsequence.cc b/src/lib/dns/labelsequence.cc
index a9be6bc..c95c5b0 100644
--- a/src/lib/dns/labelsequence.cc
+++ b/src/lib/dns/labelsequence.cc
@@ -127,5 +127,93 @@ LabelSequence::getHash(bool case_sensitive) const {
     return (hash_val);
 }
 
+std::string
+LabelSequence::toText(bool omit_final_dot) const {
+    Name::NameString::const_iterator np = name_.ndata_.begin() +
+        name_.offsets_[first_label_];
+    const Name::NameString::const_iterator np_end = np + getDataLength();
+    // use for integrity check
+    unsigned int labels = last_label_ - first_label_;
+    // init with an impossible value to catch error cases in the end:
+    unsigned int count = Name::MAX_LABELLEN + 1;
+
+    // result string: it will roughly have the same length as the wire format
+    // label sequence data.  reserve that length to minimize reallocation.
+    std::string result;
+    result.reserve(getDataLength());
+
+    while (np != np_end) {
+        labels--;
+        count = *np++;
+
+        if (count == 0) {
+            // We've reached the "final dot".  If we've not dumped any
+            // character, the entire label sequence is the root name.
+            // In that case we don't omit the final dot.
+            if (!omit_final_dot || result.empty()) {
+                result.push_back('.');
+            }
+            break;
+        }
+
+        if (count <= Name::MAX_LABELLEN) {
+            assert(np_end - np >= count);
+
+            if (!result.empty()) {
+                // just after a non-empty label.  add a separating dot.
+                result.push_back('.');
+            }
+
+            while (count-- > 0) {
+                const uint8_t c = *np++;
+                switch (c) {
+                case 0x22: // '"'
+                case 0x28: // '('
+                case 0x29: // ')'
+                case 0x2E: // '.'
+                case 0x3B: // ';'
+                case 0x5C: // '\\'
+                    // Special modifiers in zone files.
+                case 0x40: // '@'
+                case 0x24: // '$'
+                    result.push_back('\\');
+                    result.push_back(c);
+                    break;
+                default:
+                    if (c > 0x20 && c < 0x7f) {
+                        // append printable characters intact
+                        result.push_back(c);
+                    } else {
+                        // encode non-printable characters in the form of \DDD
+                        result.push_back(0x5c);
+                        result.push_back(0x30 + ((c / 100) % 10));
+                        result.push_back(0x30 + ((c / 10) % 10));
+                        result.push_back(0x30 + (c % 10));
+                    }
+                }
+            }
+        } else {
+            isc_throw(BadLabelType, "unknown label type in name data");
+        }
+    }
+
+    // We should be at the end of the data and have consumed all labels.
+    assert(np == np_end);
+    assert(labels == 0);
+
+    return (result);
+}
+
+std::string
+LabelSequence::toText() const {
+    return (toText(!isAbsolute()));
+}
+
+std::ostream&
+operator<<(std::ostream& os, const LabelSequence& label_sequence) {
+    os << label_sequence.toText();
+    return (os);
+}
+
 } // end namespace dns
 } // end namespace isc
diff --git a/src/lib/dns/labelsequence.h b/src/lib/dns/labelsequence.h
index cf5495b..25adc71 100644
--- a/src/lib/dns/labelsequence.h
+++ b/src/lib/dns/labelsequence.h
@@ -41,6 +41,9 @@ namespace dns {
 /// data of the associated Name object).
 ///
 class LabelSequence {
+    // Name calls the private toText(bool) method of LabelSequence.
+    friend std::string Name::toText(bool) const;
+
 public:
     /// \brief Constructs a LabelSequence for the given name
     ///
@@ -135,17 +138,38 @@ public:
     /// \return The number of labels
     size_t getLabelCount() const { return (last_label_ - first_label_); }
 
-    /// \brief Returns the original Name object associated with this
-    ///        LabelSequence
+    /// \brief Convert the LabelSequence to a string.
+    ///
+    /// This method returns a <code>std::string</code> object representing the
+    /// LabelSequence as a string.  The returned string ends with a dot
+    /// '.' if the label sequence is absolute.
+    ///
+    /// This function assumes the underlying name is in proper
+    /// uncompressed wire format.  If it finds an unexpected label
+    /// character including compression pointer, an exception of class
+    /// \c BadLabelType will be thrown.  In addition, if resource
+    /// allocation for the result string fails, a corresponding standard
+    /// exception will be thrown.
+    //
+    /// \return a string representation of the <code>LabelSequence</code>.
+    std::string toText() const;
+
+private:
+    /// \brief Convert the LabelSequence to a string.
+    ///
+    /// This method is a version of the zero-argument toText() method,
+    /// that accepts a <code>omit_final_dot</code> argument. The
+    /// returned string ends with a dot '.' if
+    /// <code>omit_final_dot</code> is <code>false</code>.
     ///
-    /// While the Name should still be in scope during the lifetime of
-    /// the LabelSequence, it can still be useful to have access to it,
-    /// for instance in helper functions that are only passed the
-    /// LabelSequence itself.
+    /// This method is used as a helper for <code>Name::toText()</code>
+    /// only.
     ///
-    /// \return Reference to the original Name object
-    const Name& getName() const { return (name_); }
+    /// \param omit_final_dot whether to omit the trailing dot in the output.
+    /// \return a string representation of the <code>LabelSequence</code>.
+    std::string toText(bool omit_final_dot) const;
 
+public:
     /// \brief Calculate a simple hash for the label sequence.
     ///
     /// This method calculates a hash value for the label sequence as binary
@@ -183,6 +207,23 @@ private:
 };
 
 
+///
+/// \brief Insert the label sequence as a string into stream.
+///
+/// This method convert the \c label_sequence into a string and inserts
+/// it into the output stream \c os.
+///
+/// This function overloads the global operator<< to behave as described in
+/// ostream::operator<< but applied to \c LabelSequence objects.
+///
+/// \param os A \c std::ostream object on which the insertion operation is
+/// performed.
+/// \param name The \c LabelSequence object output by the operation.
+/// \return A reference to the same \c std::ostream object referenced by
+/// parameter \c os after the insertion operation.
+std::ostream&
+operator<<(std::ostream& os, const LabelSequence& label_sequence);
+
 } // end namespace dns
 } // end namespace isc
 
diff --git a/src/lib/dns/name.cc b/src/lib/dns/name.cc
index a8b080c..d7df7bd 100644
--- a/src/lib/dns/name.cc
+++ b/src/lib/dns/name.cc
@@ -25,6 +25,7 @@
 #include <dns/name.h>
 #include <dns/name_internal.h>
 #include <dns/messagerenderer.h>
+#include <dns/labelsequence.h>
 
 using namespace std;
 using namespace isc::util;
@@ -428,81 +429,8 @@ Name::toWire(AbstractMessageRenderer& renderer) const {
 
 std::string
 Name::toText(bool omit_final_dot) const {
-    if (length_ == 1) {
-        //
-        // Special handling for the root label.  We ignore omit_final_dot.
-        //
-        assert(labelcount_ == 1 && ndata_[0] == '\0');
-        return (".");
-    }
-
-    NameString::const_iterator np = ndata_.begin();
-    NameString::const_iterator np_end = ndata_.end();
-    unsigned int labels = labelcount_; // use for integrity check
-    // init with an impossible value to catch error cases in the end:
-    unsigned int count = MAX_LABELLEN + 1;
-
-    // result string: it will roughly have the same length as the wire format
-    // name data.  reserve that length to minimize reallocation.
-    std::string result;
-    result.reserve(length_);
-
-    while (np != np_end) {
-        labels--;
-        count = *np++;
-
-        if (count == 0) {
-            if (!omit_final_dot) {
-                result.push_back('.');
-            }
-            break;
-        }
-            
-        if (count <= MAX_LABELLEN) {
-            assert(np_end - np >= count);
-
-            if (!result.empty()) {
-                // just after a non-empty label.  add a separating dot.
-                result.push_back('.');
-            }
-
-            while (count-- > 0) {
-                uint8_t c = *np++;
-                switch (c) {
-                case 0x22: // '"'
-                case 0x28: // '('
-                case 0x29: // ')'
-                case 0x2E: // '.'
-                case 0x3B: // ';'
-                case 0x5C: // '\\'
-                    // Special modifiers in zone files.
-                case 0x40: // '@'
-                case 0x24: // '$'
-                    result.push_back('\\');
-                    result.push_back(c);
-                    break;
-                default:
-                    if (c > 0x20 && c < 0x7f) {
-                        // append printable characters intact
-                        result.push_back(c);
-                    } else {
-                        // encode non-printable characters in the form of \DDD
-                        result.push_back(0x5c);
-                        result.push_back(0x30 + ((c / 100) % 10));
-                        result.push_back(0x30 + ((c / 10) % 10));
-                        result.push_back(0x30 + (c % 10));
-                    }
-                }
-            }
-        } else {
-            isc_throw(BadLabelType, "unknown label type in name data");
-        }
-    }
-
-    assert(labels == 0);
-    assert(count == 0);         // a valid name must end with a 'dot'.
-
-    return (result);
+    LabelSequence ls(*this);
+    return (ls.toText(omit_final_dot));
 }
 
 NameComparisonResult
diff --git a/src/lib/dns/tests/labelsequence_unittest.cc b/src/lib/dns/tests/labelsequence_unittest.cc
index d1671a2..3ba1d73 100644
--- a/src/lib/dns/tests/labelsequence_unittest.cc
+++ b/src/lib/dns/tests/labelsequence_unittest.cc
@@ -366,14 +366,14 @@ getDataCheck(const uint8_t* expected_data, size_t expected_len,
     size_t len;
     const uint8_t* data = ls.getData(&len);
     ASSERT_EQ(expected_len, len) << "Expected data: " << expected_data <<
-                                    " name: " << ls.getName().toText();
+                                    ", label sequence: " << ls;
     EXPECT_EQ(expected_len, ls.getDataLength()) <<
         "Expected data: " << expected_data <<
-        " name: " << ls.getName().toText();
+        ", label sequence: " << ls;
     for (size_t i = 0; i < len; ++i) {
         EXPECT_EQ(expected_data[i], data[i]) <<
           "Difference at pos " << i << ": Expected data: " << expected_data <<
-          " name: " << ls.getName().toText();;
+          ", label sequence: " << ls;
     }
 }
 
@@ -509,6 +509,84 @@ TEST_F(LabelSequenceTest, isAbsolute) {
     ASSERT_TRUE(ls3.isAbsolute());
 }
 
+TEST_F(LabelSequenceTest, toText) {
+    EXPECT_EQ(".", ls7.toText());
+
+    EXPECT_EQ("example.org.", ls1.toText());
+    ls1.stripLeft(1);
+    EXPECT_EQ("org.", ls1.toText());
+    ls1.stripLeft(1);
+    EXPECT_EQ(".", ls1.toText());
+
+    EXPECT_EQ("example.com.", ls2.toText());
+    ls2.stripRight(1);
+    EXPECT_EQ("example.com", ls2.toText());
+    ls2.stripRight(1);
+    EXPECT_EQ("example", ls2.toText());
+
+    EXPECT_EQ("foo.example.org.bar.", ls8.toText());
+    ls8.stripRight(2);
+    EXPECT_EQ("foo.example.org", ls8.toText());
+
+    EXPECT_EQ(".", ls7.toText());
+    EXPECT_THROW(ls7.stripLeft(1), isc::OutOfRange);
+
+    Name n_long1("012345678901234567890123456789"
+                 "012345678901234567890123456789012."
+                 "012345678901234567890123456789"
+                 "012345678901234567890123456789012."
+                 "012345678901234567890123456789"
+                 "012345678901234567890123456789012."
+                 "012345678901234567890123456789"
+                 "0123456789012345678901234567890");
+    LabelSequence ls_long1(n_long1);
+
+    EXPECT_EQ("012345678901234567890123456789"
+              "012345678901234567890123456789012."
+              "012345678901234567890123456789"
+              "012345678901234567890123456789012."
+              "012345678901234567890123456789"
+              "012345678901234567890123456789012."
+              "012345678901234567890123456789"
+              "0123456789012345678901234567890.", ls_long1.toText());
+    ls_long1.stripRight(1);
+    EXPECT_EQ("012345678901234567890123456789"
+              "012345678901234567890123456789012."
+              "012345678901234567890123456789"
+              "012345678901234567890123456789012."
+              "012345678901234567890123456789"
+              "012345678901234567890123456789012."
+              "012345678901234567890123456789"
+              "0123456789012345678901234567890", ls_long1.toText());
+
+    Name n_long2("0.1.2.3.4.5.6.7.8.9.0.1.2.3.4.5.6.7.8.9."
+                 "0.1.2.3.4.5.6.7.8.9.0.1.2.3.4.5.6.7.8.9."
+                 "0.1.2.3.4.5.6.7.8.9.0.1.2.3.4.5.6.7.8.9."
+                 "0.1.2.3.4.5.6.7.8.9.0.1.2.3.4.5.6.7.8.9."
+                 "0.1.2.3.4.5.6.7.8.9.0.1.2.3.4.5.6.7.8.9."
+                 "0.1.2.3.4.5.6.7.8.9.0.1.2.3.4.5.6.7.8.9."
+                 "0.1.2.3.4.5.6");
+    LabelSequence ls_long2(n_long2);
+
+    EXPECT_EQ("0.1.2.3.4.5.6.7.8.9.0.1.2.3.4.5.6.7.8.9."
+              "0.1.2.3.4.5.6.7.8.9.0.1.2.3.4.5.6.7.8.9."
+              "0.1.2.3.4.5.6.7.8.9.0.1.2.3.4.5.6.7.8.9."
+              "0.1.2.3.4.5.6.7.8.9.0.1.2.3.4.5.6.7.8.9."
+              "0.1.2.3.4.5.6.7.8.9.0.1.2.3.4.5.6.7.8.9."
+              "0.1.2.3.4.5.6.7.8.9.0.1.2.3.4.5.6.7.8.9."
+              "0.1.2.3.4.5.6.", ls_long2.toText());
+    ls_long2.stripRight(1);
+    EXPECT_EQ("0.1.2.3.4.5.6.7.8.9.0.1.2.3.4.5.6.7.8.9."
+              "0.1.2.3.4.5.6.7.8.9.0.1.2.3.4.5.6.7.8.9."
+              "0.1.2.3.4.5.6.7.8.9.0.1.2.3.4.5.6.7.8.9."
+              "0.1.2.3.4.5.6.7.8.9.0.1.2.3.4.5.6.7.8.9."
+              "0.1.2.3.4.5.6.7.8.9.0.1.2.3.4.5.6.7.8.9."
+              "0.1.2.3.4.5.6.7.8.9.0.1.2.3.4.5.6.7.8.9."
+              "0.1.2.3.4.5.6", ls_long2.toText());
+    ls_long2.stripRight(125);
+    EXPECT_EQ("0.1", ls_long2.toText());
+}
+
 // The following are test data used in the getHash test below.  Normally
 // we use example/documentation domain names for testing, but in this case
 // we'd specifically like to use more realistic data, and are intentionally
@@ -590,4 +668,10 @@ TEST_F(LabelSequenceTest, getHash) {
     hashDistributionCheck(ca_servers);
 }
 
+// test operator<<.  We simply confirm it appends the result of toText().
+TEST_F(LabelSequenceTest, LeftShiftOperator) {
+    ostringstream oss;
+    oss << ls1;
+    EXPECT_EQ(ls1.toText(), oss.str());
+}
 }



More information about the bind10-changes mailing list