Browse Source

[2053] Move toText() implementation from Name to LabelSequence class

Mukund Sivaraman 13 years ago
parent
commit
efb3f3344d
4 changed files with 116 additions and 126 deletions
  1. 96 1
      src/lib/dns/labelsequence.cc
  2. 17 0
      src/lib/dns/labelsequence.h
  3. 3 98
      src/lib/dns/name.cc
  4. 0 27
      src/lib/dns/name.h

+ 96 - 1
src/lib/dns/labelsequence.cc

@@ -113,8 +113,103 @@ LabelSequence::getHash(bool case_sensitive) const {
 }
 
 std::string
+LabelSequence::toText(bool omit_final_dot) const {
+    if ((first_label_ > name_.labelcount_) ||
+        (last_label_ > name_.labelcount_) ||
+        (first_label_ > last_label_)) {
+        isc_throw(BadValue, "Bad first label indices were passed");
+    }
+
+    if (name_.length_ == 1) {
+        //
+        // Special handling for the root label.  We ignore omit_final_dot.
+        //
+        assert(name_.labelcount_ == 1 && name_.ndata_[0] == '\0');
+        return (".");
+    }
+
+    Name::NameString::const_iterator np = name_.ndata_.begin();
+    Name::NameString::const_iterator np_end = name_.ndata_.end();
+    unsigned int labels = last_label_ - first_label_; // use for integrity check
+    // 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
+    // name data.  reserve that length to minimize reallocation.
+    std::string result;
+    result.reserve(name_.length_);
+
+    for (unsigned int i = 0; i < first_label_; i++) {
+        count = *np++;
+        np += count;
+    }
+
+    while (np != np_end) {
+        labels--;
+        count = *np++;
+
+        if (count == 0) {
+            if (!omit_final_dot) {
+                result.push_back('.');
+            }
+            break;
+        }
+
+        if (labels == 0) {
+            count = 0;
+            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) {
+                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);
+}
+
+std::string
 LabelSequence::toText() const {
-    return (name_.toText(!isAbsolute(), first_label_, last_label_));
+    return (toText(!isAbsolute()));
 }
 
 std::ostream&

+ 17 - 0
src/lib/dns/labelsequence.h

@@ -127,6 +127,23 @@ public:
     ///
     /// This method returns a <code>std::string</code> object representing the
     /// LabelSequence as a string.  The returned string ends with a dot
+    /// '.' if <code>omit_final_dot</code> is <code>false</code>.
+    ///
+    /// 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.
+    //
+    /// \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;
+
+    /// \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

+ 3 - 98
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;
@@ -427,105 +428,9 @@ Name::toWire(AbstractMessageRenderer& renderer) const {
 }
 
 std::string
-Name::toText(bool omit_final_dot,
-             unsigned int first_label,
-             unsigned int last_label) const {
-    if ((first_label > labelcount_) ||
-        (last_label > labelcount_) ||
-        (first_label > last_label)) {
-        isc_throw(BadValue, "Bad first label indices were passed");
-    }
-
-    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 = last_label - first_label; // 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_);
-
-    for (unsigned int i = 0; i < first_label; i++) {
-        count = *np++;
-        np += count;
-    }
-
-    while (np != np_end) {
-        labels--;
-        count = *np++;
-
-        if (count == 0) {
-            if (!omit_final_dot) {
-                result.push_back('.');
-            }
-            break;
-        }
-            
-        if (labels == 0) {
-            count = 0;
-            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);
-}
-
-std::string
 Name::toText(bool omit_final_dot) const {
-    return toText(omit_final_dot, 0, labelcount_);
+    LabelSequence ls(*this);
+    return (ls.toText(omit_final_dot));
 }
 
 NameComparisonResult

+ 0 - 27
src/lib/dns/name.h

@@ -359,33 +359,6 @@ public:
     /// \return a string representation of the <code>Name</code>.
     std::string toText(bool omit_final_dot = false) const;
 
-private:
-    /// \brief Convert the Name to a string.
-    ///
-    /// This method returns a <code>std::string</code> object representing the
-    /// Name as a string.  Unless <code>omit_final_dot</code> is
-    /// <code>true</code>, the returned string ends with a dot '.'; the default
-    /// is <code>false</code>.  The default value of this parameter is
-    /// <code>true</code>; converted names will have a trailing dot by default.
-    ///
-    /// This function assumes the 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.
-    ///
-    /// This function only returns a string for the range of labels
-    /// between <code>first_label</code> and <code>last_label</code>.
-    //
-    /// \param omit_final_dot whether to omit the trailing dot in the output.
-    /// \param first_label the first label which should be contained in the result.
-    /// \param last_label the last label which should be contained in the result.
-    /// \return a string representation of the <code>Name</code>.
-    std::string toText(bool omit_final_dot,
-                       unsigned int first_label,
-                       unsigned int last_label) const;
-
-public:
     /// \brief Render the <code>Name</code> in the wire format with compression.
     ///
     /// This method dumps the Name in wire format with help of \c renderer,