[svn] commit: r393 - in /branches/jinmei-dnsmessageapi/src/lib/dns/cpp: name.cc name.h

BIND 10 source code commits bind10-changes at lists.isc.org
Sat Dec 19 04:50:27 UTC 2009


Author: jinmei
Date: Sat Dec 19 04:50:27 2009
New Revision: 393

Log:
added more description about the implementation

Modified:
    branches/jinmei-dnsmessageapi/src/lib/dns/cpp/name.cc
    branches/jinmei-dnsmessageapi/src/lib/dns/cpp/name.h

Modified: branches/jinmei-dnsmessageapi/src/lib/dns/cpp/name.cc
==============================================================================
--- branches/jinmei-dnsmessageapi/src/lib/dns/cpp/name.cc (original)
+++ branches/jinmei-dnsmessageapi/src/lib/dns/cpp/name.cc Sat Dec 19 04:50:27 2009
@@ -67,14 +67,20 @@
 }
 
 namespace {
+///
+/// Textual name parser states.
+///
 typedef enum {
-    ft_init = 0,
-    ft_start,
-    ft_ordinary,
-    ft_initialescape,
-    ft_escape,
-    ft_escdecimal,
-    ft_at
+    ft_init = 0,                // begin of the name
+    ft_start,                   // begin of a label
+    ft_ordinary,                // parsing an ordinary label
+    ft_initialescape,           // just found '\'
+    ft_escape,                  // begin of handling a '\'-escaped sequence
+    ft_escdecimal,              // parsing a '\DDD' octet.
+
+    // Unused at this moment.  We'll revisit this when we support master file
+    // parser where @ is used to mean an origin name.
+    ft_at                  
 } ft_state;
 }
 
@@ -133,7 +139,7 @@
             }
 
             // FALLTHROUGH
-        case ft_start:           // begin of a label
+        case ft_start:
             ndata.push_back(0); // placeholder for the label length field
             count = 0;
             if (c == '\\') {
@@ -143,7 +149,7 @@
             state = ft_ordinary;
             assert(ndata.size() < Name::MAX_WIRE);
             // FALLTHROUGH
-        case ft_ordinary:       // parsing a normal label
+        case ft_ordinary:
             if (c == '.') {
                 if (count == 0) {
                     dns_throw(EmptyLabel, "duplicate period");
@@ -164,7 +170,7 @@
                 ndata.push_back(downcase ? maptolower[c] : c);
             }
             break;
-        case ft_initialescape:  // just found '\'
+        case ft_initialescape:
             if (c == '[') {
                 // This looks like a bitstring label, which was deprecated.
                 // Intentionally drop it.
@@ -172,7 +178,7 @@
             }
             state = ft_escape;
             // FALLTHROUGH
-        case ft_escape:         // begin of handling a '\'-escaped sequence
+        case ft_escape:
             if (!isdigit(c & 0xff)) {
                 if (++count > MAX_LABELLEN) {
                     dns_throw(TooLongLabel, "label is too long");
@@ -185,7 +191,7 @@
             value = 0;
             state = ft_escdecimal;
             // FALLTHROUGH
-        case ft_escdecimal:     // parsing a '\DDD' octet.
+        case ft_escdecimal:
             if (!isdigit(c & 0xff)) {
                 dns_throw(BadEscape, "mixture of escaped digit and non-digit");
             }
@@ -234,11 +240,16 @@
     offsets_.assign(offsets.begin(), offsets.end());
 }
 
+namespace {
+///
+/// Wire-format name parser states.
+///
 typedef enum {
-    fw_start = 0,
-    fw_ordinary,
-    fw_newcurrent
+    fw_start = 0,               // beginning of a label
+    fw_ordinary,                // inside an ordinary (non compressed) label
+    fw_newcurrent               // beginning of a compression pointer
 } fw_state;
+}
 
 Name::Name(InputBuffer& buffer, bool downcase)
 {

Modified: branches/jinmei-dnsmessageapi/src/lib/dns/cpp/name.h
==============================================================================
--- branches/jinmei-dnsmessageapi/src/lib/dns/cpp/name.h (original)
+++ branches/jinmei-dnsmessageapi/src/lib/dns/cpp/name.h Sat Dec 19 04:50:27 2009
@@ -91,8 +91,11 @@
 };
 
 ///
-/// \brief A standard DNS module exception that is thrown if the wire-format
-/// name is not a complete domain name.
+/// \brief A standard DNS module exception that is thrown if the name parser
+/// finds the input (string or wire-format data) is incomplete.
+///
+/// An attempt of constructing a name from an empty string will trigger this
+/// exception.
 ///
 class IncompleteName : public Exception {
 public:
@@ -164,11 +167,34 @@
 };
 
 ///
-/// The \c Name class encapsulates DNS names. It provides interfaces
-/// to construct a name from string or wire-format data, transform a name into
-/// a string or wire-format data, compare two names, get access to attributes.
-///
-/// Note that while many other DNS APIs introduce an "absolute or relative"
+/// The \c Name class encapsulates DNS names.
+///
+/// It provides interfaces to construct a name from string or wire-format data,
+/// transform a name into a string or wire-format data, compare two names, get
+/// access to various properties of a name, etc.
+///
+/// Notes to developers: Internally, a name object maintains the name data
+/// in wire format as an instance of \c std::string.  Since many string
+/// implementations adopt copy-on-write data sharing, we expect this approach
+/// will make copying a name less expensive in typical cases.  If this is
+/// found to be a significant performance bottleneck later, we may reconsider
+/// the internal representation or perhaps the API.
+///
+/// A name object also maintains a vector of offsets (\c offsets_ member),
+/// each of which is the offset to a label of the name: The n-th element of
+/// the vector specifies the offset to the n-th label.  For example, if the
+/// object represents "www.example.com", the elements of the offsets vector
+/// are 0, 4, 12, and 16.  Note that the offset to the trailing dot (16) is
+/// included.  In the BIND9 DNS library from which this implementation is
+/// derived, the offsets are optional, probably due to performance
+/// considerations (in fact, offsets can always be calculated from the name
+/// data, and in that sense are redundant).  In our implementation, however,
+/// we always build and maintain the offsets.  We believe we need more low
+/// level, specialized data structure and interface where we really need to
+/// pursue performance, and would rather keep this generic API and
+/// implementation simpler.
+///
+/// While many other DNS APIs introduce an "absolute or relative"
 /// attribute of names as defined in RFC1035, names are always "absolute" in
 /// the initial design of this API.
 /// In fact, separating absolute and relative would confuse API users
@@ -199,6 +225,12 @@
 public:
     /// Constructor from a string
     ///
+    /// If the given string does not represent a valid DNS name, an exception
+    /// of class \c EmptyLabel, \c TooLongLabel, \c BadLabelType, \c BadEscape,
+    /// \c TooLongName, or \c IncompleteName will be thrown.
+    /// In addition, if resource allocation for the new name fails, a
+    /// corresponding standard exception will be thrown.
+    ///
     /// \param namestr A string representation of the name to be constructed.
     /// \param downcase Whether to convert upper case alphabets to lower case.
     explicit Name(const std::string& namestr, bool downcase = false);
@@ -211,6 +243,12 @@
     /// The input data may or may not be compressed; if it's compressed, this
     /// method will automatically decompress it.
     ///
+    /// If the given data does not represent a valid DNS name, an exception
+    /// of class \c TooLongName, \c BadLabelType, \c BadPointer, or
+    /// \c IncompleteName will be thrown.
+    /// In addition, if resource allocation for the new name fails, a
+    /// corresponding standard exception will be thrown.
+    ///
     /// \param buffer A buffer storing the wire format data.
     /// \param downcase Whether to convert upper case alphabets to lower case.
     explicit Name(InputBuffer& buffer, bool downcase = false);
@@ -222,6 +260,8 @@
     //@{
     /// \brief Gets the length of the <code>Name</code> in its wire format.
     ///
+    /// This method never throws an exception.
+    ///
     /// \return the length of the <code>Name</code>
     size_t getLength() const { return (length_); }
 
@@ -229,6 +269,8 @@
     ///
     /// Note that an empty label (corresponding to a trailing '.') is counted
     /// as a single label, so the return value of this method must be >0.
+    ///
+    /// This method never throws an exception.
     ///
     /// \return the number of labels
     unsigned int getLabels() const { return (labels_); }
@@ -249,6 +291,8 @@
     /// 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.
     //
     /// \param omit_final_dot whether to omit the trailing dot in the output.
     /// \return a string representation of the <code>Name</code>.
@@ -260,6 +304,9 @@
     /// which encapsulates output buffer and name compression algorithm to
     /// render the name.
     ///
+    /// If resource allocation in rendering process fails, a corresponding
+    /// standard exception will be thrown.
+    ///
     /// \param renderer DNS message rendering context that encapsulates the
     /// output buffer and name compression information.
     void toWire(MessageRenderer& renderer) const;
@@ -267,6 +314,12 @@
     /// \brief Render the <code>Name</code> in the wire format without
     /// compression.
     ///
+    /// If resource allocation in rendering process fails, a corresponding
+    /// standard exception will be thrown.  This can be avoided by preallocating
+    /// a sufficient size of \c buffer.  Specifically, if
+    /// <code>buffer.getCapacity() - buffer.getLength() >= Name::MAX_WIRE</code>
+    /// then this method should not throw an exception.
+    ///
     void toWire(OutputBuffer& buffer) const;
     //@}
 
@@ -281,6 +334,8 @@
     /// object.
     ///
     /// Note that this is case-insensitive comparison.
+    ///
+    /// This method never throws an exception.
     ///
     /// \param other the right-hand operand to compare against.
     /// \return a <code>NameComparisonResult</code> object representing the
@@ -296,6 +351,8 @@
     /// it would be much faster and the simple equality check would be pretty
     /// common.
     ///
+    /// This method never throws an exception.
+    ///
     /// \param other the <code>Name</code> object to compare against.
     /// \return true if the two names are equal; otherwise false.
     bool equals(const Name& other) const;
@@ -316,6 +373,9 @@
     /// \brief Less-than or equal comparison for Name against <code>other</code>
     ///
     /// The comparison is based on the result of the \c compare() method.
+    ///
+    /// This method never throws an exception.
+    ///
     /// \param other the <code>Name</code> object to compare against.
     /// \return true if <code>compare(other).getOrder() <= 0</code>;
     /// otherwise false.
@@ -328,6 +388,9 @@
     /// <code>other</code>
     ///
     /// The comparison is based on the result of the \c compare() method.
+    ///
+    /// This method never throws an exception.
+    ///
     /// \param other the <code>Name</code> object to compare against.
     /// \return true if <code>compare(other).getOrder() >= 0</code>;
     /// otherwise false.
@@ -339,6 +402,9 @@
     /// \brief Less-than comparison for Name against <code>other</code>
     ///
     /// The comparison is based on the result of the \c compare() method.
+    ///
+    /// This method never throws an exception.
+    ///
     /// \param other the <code>Name</code> object to compare against.
     /// \return true if <code>compare(other).getOrder() < 0</code>;
     /// otherwise false.
@@ -350,6 +416,9 @@
     /// \brief Greater-than comparison for Name against <code>other</code>
     ///
     /// The comparison is based on the result of the \c compare() method.
+    ////
+    /// This method never throws an exception.
+    ///
     /// \param other the <code>Name</code> object to compare against.
     /// \return true if <code>compare(other).getOrder() > 0</code>;
     /// otherwise false.
@@ -475,8 +544,6 @@
     std::vector<unsigned char> offsets_;
     unsigned int length_;
     unsigned int labels_;
-
-    void fromString(const std::string& namestr);
 };
 
 ///




More information about the bind10-changes mailing list