[svn] commit: r530 - in /branches/parkinglot: ./ src/lib/dns/ src/lib/dns/cpp/ src/lib/dns/cpp/testdata/

BIND 10 source code commits bind10-changes at lists.isc.org
Tue Jan 26 22:15:42 UTC 2010


Author: jinmei
Date: Tue Jan 26 22:15:42 2010
New Revision: 530

Log:
merged the latest snapshot of DNS message library to parkinglot

Added:
    branches/parkinglot/src/lib/dns/cpp/   (props changed)
      - copied from r526, trunk/src/lib/dns/cpp/
    branches/parkinglot/src/lib/dns/cpp/message.cc
      - copied unchanged from r527, branches/jinmei-dnsrdata/src/lib/dns/cpp/message.cc
    branches/parkinglot/src/lib/dns/cpp/message.h
      - copied unchanged from r527, branches/jinmei-dnsrdata/src/lib/dns/cpp/message.h
    branches/parkinglot/src/lib/dns/cpp/message_unittest.cc
      - copied unchanged from r527, branches/jinmei-dnsrdata/src/lib/dns/cpp/message_unittest.cc
    branches/parkinglot/src/lib/dns/cpp/question.cc
      - copied unchanged from r527, branches/jinmei-dnsrdata/src/lib/dns/cpp/question.cc
    branches/parkinglot/src/lib/dns/cpp/question.h
      - copied unchanged from r527, branches/jinmei-dnsrdata/src/lib/dns/cpp/question.h
    branches/parkinglot/src/lib/dns/cpp/question_unittest.cc
      - copied unchanged from r527, branches/jinmei-dnsrdata/src/lib/dns/cpp/question_unittest.cc
    branches/parkinglot/src/lib/dns/cpp/rdata.cc
      - copied unchanged from r527, branches/jinmei-dnsrdata/src/lib/dns/cpp/rdata.cc
    branches/parkinglot/src/lib/dns/cpp/rdata.h
      - copied unchanged from r527, branches/jinmei-dnsrdata/src/lib/dns/cpp/rdata.h
    branches/parkinglot/src/lib/dns/cpp/rdata_unittest.cc
      - copied unchanged from r527, branches/jinmei-dnsrdata/src/lib/dns/cpp/rdata_unittest.cc
    branches/parkinglot/src/lib/dns/cpp/rrset.cc
      - copied unchanged from r527, branches/jinmei-dnsrdata/src/lib/dns/cpp/rrset.cc
    branches/parkinglot/src/lib/dns/cpp/rrset.h
      - copied unchanged from r527, branches/jinmei-dnsrdata/src/lib/dns/cpp/rrset.h
    branches/parkinglot/src/lib/dns/cpp/rrset_unittest.cc
      - copied unchanged from r527, branches/jinmei-dnsrdata/src/lib/dns/cpp/rrset_unittest.cc
    branches/parkinglot/src/lib/dns/cpp/testdata/message_fromWire1
      - copied unchanged from r527, branches/jinmei-dnsrdata/src/lib/dns/cpp/testdata/message_fromWire1
    branches/parkinglot/src/lib/dns/cpp/testdata/message_toWire1
      - copied unchanged from r527, branches/jinmei-dnsrdata/src/lib/dns/cpp/testdata/message_toWire1
    branches/parkinglot/src/lib/dns/cpp/testdata/rdata_in_a_fromWire
      - copied unchanged from r527, branches/jinmei-dnsrdata/src/lib/dns/cpp/testdata/rdata_in_a_fromWire
    branches/parkinglot/src/lib/dns/cpp/testdata/rdata_in_aaaa_fromWire
      - copied unchanged from r527, branches/jinmei-dnsrdata/src/lib/dns/cpp/testdata/rdata_in_aaaa_fromWire
    branches/parkinglot/src/lib/dns/cpp/testdata/rdata_mx_fromWire
      - copied unchanged from r527, branches/jinmei-dnsrdata/src/lib/dns/cpp/testdata/rdata_mx_fromWire
    branches/parkinglot/src/lib/dns/cpp/testdata/rdata_mx_toWire1
      - copied unchanged from r527, branches/jinmei-dnsrdata/src/lib/dns/cpp/testdata/rdata_mx_toWire1
    branches/parkinglot/src/lib/dns/cpp/testdata/rdata_ns_fromWire
      - copied unchanged from r527, branches/jinmei-dnsrdata/src/lib/dns/cpp/testdata/rdata_ns_fromWire
    branches/parkinglot/src/lib/dns/cpp/testdata/rdata_soa_fromWire
      - copied unchanged from r527, branches/jinmei-dnsrdata/src/lib/dns/cpp/testdata/rdata_soa_fromWire
    branches/parkinglot/src/lib/dns/cpp/testdata/rdata_txt_fromWire
      - copied unchanged from r527, branches/jinmei-dnsrdata/src/lib/dns/cpp/testdata/rdata_txt_fromWire
    branches/parkinglot/src/lib/dns/cpp/testdata/rrset_toWire1
      - copied unchanged from r527, branches/jinmei-dnsrdata/src/lib/dns/cpp/testdata/rrset_toWire1
    branches/parkinglot/src/lib/dns/cpp/testdata/rrset_toWire2
      - copied unchanged from r527, branches/jinmei-dnsrdata/src/lib/dns/cpp/testdata/rrset_toWire2
Removed:
    branches/parkinglot/src/lib/dns/buffer.cc
    branches/parkinglot/src/lib/dns/buffer.h
    branches/parkinglot/src/lib/dns/data_source.cc
    branches/parkinglot/src/lib/dns/data_source.h
    branches/parkinglot/src/lib/dns/exceptions.h
    branches/parkinglot/src/lib/dns/message.cc
    branches/parkinglot/src/lib/dns/message.h
    branches/parkinglot/src/lib/dns/message_unittest.cc
    branches/parkinglot/src/lib/dns/name.cc
    branches/parkinglot/src/lib/dns/name.h
    branches/parkinglot/src/lib/dns/name_unittest.cc
    branches/parkinglot/src/lib/dns/name_unittest.h
    branches/parkinglot/src/lib/dns/rrset.cc
    branches/parkinglot/src/lib/dns/rrset.h
    branches/parkinglot/src/lib/dns/rrset_unittest.cc
    branches/parkinglot/src/lib/dns/run_unittests.cc
Modified:
    branches/parkinglot/configure.ac
    branches/parkinglot/src/lib/dns/Makefile.am
    branches/parkinglot/src/lib/dns/cpp/Makefile.am
    branches/parkinglot/src/lib/dns/cpp/exceptions.h
    branches/parkinglot/src/lib/dns/cpp/messagerenderer.cc
    branches/parkinglot/src/lib/dns/cpp/messagerenderer.h
    branches/parkinglot/src/lib/dns/cpp/name.h
    branches/parkinglot/src/lib/dns/cpp/name_unittest.cc
    branches/parkinglot/src/lib/dns/cpp/rrclass_unittest.cc
    branches/parkinglot/src/lib/dns/cpp/rrparamregistry.cc
    branches/parkinglot/src/lib/dns/cpp/rrparamregistry.h
    branches/parkinglot/src/lib/dns/cpp/rrparamregistry_unittest.cc
    branches/parkinglot/src/lib/dns/cpp/rrtype_unittest.cc
    branches/parkinglot/src/lib/dns/cpp/unittest_util.h

Modified: branches/parkinglot/configure.ac
==============================================================================
--- branches/parkinglot/configure.ac (original)
+++ branches/parkinglot/configure.ac Tue Jan 26 22:15:42 2010
@@ -12,8 +12,20 @@
 AC_PROG_CC
 AC_PROG_RANLIB
 
+AC_PROG_LIBTOOL
+
 m4_define([_AM_PYTHON_INTERPRETER_LIST], [python python3 python3.1])
 AM_PATH_PYTHON([3.1])
+
+# default compiler warning settings
+if test "X$GCC" = "Xyes"; then
+CXXFLAGS="-g -Wall -Wwrite-strings -Woverloaded-virtual -Wno-sign-compare"
+fi
+
+# produce PIC unless we disable shared libraries. need this for python bindings.
+if test $enable_shared != "no" -a "X$GCC" = "Xyes"; then
+   CXXFLAGS="$CXXFLAGS -fPIC"
+fi
 
 # Checks for libraries.
 
@@ -141,6 +153,7 @@
                  src/lib/config/Makefile
                  src/lib/config/cpp/Makefile
                  src/lib/dns/Makefile
+                 src/lib/dns/cpp/Makefile
                ])
 AC_OUTPUT([src/bin/bind-cfgd/bind-cfgd
            src/bin/cmd-ctrld/cmd-ctrld

Modified: branches/parkinglot/src/lib/dns/Makefile.am
==============================================================================
--- branches/parkinglot/src/lib/dns/Makefile.am (original)
+++ branches/parkinglot/src/lib/dns/Makefile.am Tue Jan 26 22:15:42 2010
@@ -1,17 +1,1 @@
-AM_CPPFLAGS = -I$(top_srcdir)/src/lib -I$(top_srcdir)/ext
-
-lib_LIBRARIES = libdns.a
-libdns_a_SOURCES = name.cc buffer.cc rrset.cc message.cc \
-	name.h buffer.h rrset.h message.h data_source.cc data_source.h
-
-TESTS =
-if HAVE_GTEST
-TESTS += run_unittests
-run_unittests_SOURCES = run_unittests.cc name_unittest.cc rrset_unittest.cc
-run_unittests_SOURCES += message_unittest.cc
-run_unittests_CPPFLAGS = $(AM_CPPFLAGS) $(GTEST_INCLUDES)
-run_unittests_LDFLAGS = $(GTEST_LDFLAGS)
-run_unittests_LDADD = ./libdns.a $(GTEST_LDADD)
-endif
-
-noinst_PROGRAMS = $(TESTS)
+SUBDIRS = cpp

Modified: branches/parkinglot/src/lib/dns/cpp/Makefile.am
==============================================================================
--- branches/parkinglot/src/lib/dns/cpp/Makefile.am (original)
+++ branches/parkinglot/src/lib/dns/cpp/Makefile.am Tue Jan 26 22:15:42 2010
@@ -1,4 +1,4 @@
-AM_CPPFLAGS = $(BOOST_INCLUDES)
+AM_CPPFLAGS = -I$(top_srcdir)/ext
 
 CLEANFILES = *.gcno *.gcda
 
@@ -6,6 +6,9 @@
 libdns_la_SOURCES = buffer.h name.cc name.h messagerenderer.h messagerenderer.cc
 libdns_la_SOURCES += rrparamregistry.h rrparamregistry.cc
 libdns_la_SOURCES += rrclass.h rrclass.cc rrtype.h rrtype.cc rrttl.h rrttl.cc
+libdns_la_SOURCES += rdata.h rdata.cc rrset.h rrset.cc
+libdns_la_SOURCES += question.h question.cc
+libdns_la_SOURCES += message.h message.cc
 libdns_la_SOURCES += exceptions.h exceptions.cc
 
 TESTS =
@@ -16,7 +19,11 @@
 run_unittests_SOURCES += messagerenderer_unittest.cc exceptions_unittest.cc
 run_unittests_SOURCES += rrclass_unittest.cc rrtype_unittest.cc
 run_unittests_SOURCES += rrttl_unittest.cc
+run_unittests_SOURCES += rdata_unittest.cc
+run_unittests_SOURCES += rrset_unittest.cc
+run_unittests_SOURCES += question_unittest.cc
 run_unittests_SOURCES += rrparamregistry_unittest.cc
+run_unittests_SOURCES += message_unittest.cc
 run_unittests_SOURCES += run_unittests.cc
 run_unittests_CPPFLAGS = $(GTEST_INCLUDES)
 run_unittests_LDFLAGS = $(GTEST_LDFLAGS)

Modified: branches/parkinglot/src/lib/dns/cpp/exceptions.h
==============================================================================
--- branches/parkinglot/src/lib/dns/cpp/exceptions.h (original)
+++ branches/parkinglot/src/lib/dns/cpp/exceptions.h Tue Jan 26 22:15:42 2010
@@ -104,6 +104,16 @@
 };
 
 ///
+/// \brief A standard DNS module exception that is thrown when an unexpected
+/// error condition occurs.
+///
+class Unexpected : public Exception {
+public:
+    Unexpected(const char* file, size_t line, const char* what) :
+        isc::dns::Exception(file, line, what) {}
+};
+
+///
 /// A shortcut macro to insert known values into exception arguments.
 ///
 #define dns_throw(type, args...) throw type(__FILE__, __LINE__, args)

Modified: branches/parkinglot/src/lib/dns/cpp/messagerenderer.cc
==============================================================================
--- branches/parkinglot/src/lib/dns/cpp/messagerenderer.cc (original)
+++ branches/parkinglot/src/lib/dns/cpp/messagerenderer.cc Tue Jan 26 22:15:42 2010
@@ -157,15 +157,39 @@
 }
 
 void
+MessageRenderer::skip(size_t len)
+{
+    impl_->buffer_.skip(len);
+}
+
+void
+MessageRenderer::writeUint8(uint8_t data)
+{
+    impl_->buffer_.writeUint8(data);
+}
+
+void
 MessageRenderer::writeUint16(uint16_t data)
 {
     impl_->buffer_.writeUint16(data);
 }
 
 void
+MessageRenderer::writeUint16At(uint16_t data, size_t pos)
+{
+    impl_->buffer_.writeUint16At(data, pos);
+}
+
+void
 MessageRenderer::writeUint32(uint32_t data)
 {
     impl_->buffer_.writeUint32(data);
+}
+
+void
+MessageRenderer::writeData(const void* data, size_t len)
+{
+    impl_->buffer_.writeData(data, len);
 }
 
 const void*

Modified: branches/parkinglot/src/lib/dns/cpp/messagerenderer.h
==============================================================================
--- branches/parkinglot/src/lib/dns/cpp/messagerenderer.h (original)
+++ branches/parkinglot/src/lib/dns/cpp/messagerenderer.h Tue Jan 26 22:15:42 2010
@@ -105,16 +105,48 @@
     /// \name Methods for writing data into the internal buffer.
     ///
     //@{
+    /// \brief Insert a specified length of gap at the end of the buffer.
+    ///
+    /// The caller should not assume any particular value to be inserted.
+    /// This method is provided as a shortcut to make a hole in the buffer
+    /// that is to be filled in later, e.g, by \ref writeUint16At().
+    ///
+    /// \param len The length of the gap to be inserted in bytes.
+    void skip(size_t len);
+    /// \brief Write an unsigned 8-bit integer into the internal buffer.
+    ///
+    /// \param data The 8-bit integer to be written into the internal buffer.
+    void writeUint8(uint8_t data);
     /// \brief Write an unsigned 16-bit integer in host byte order into the
     /// internal buffer in network byte order.
     ///
     /// \param data The 16-bit integer to be written into the buffer.
     void writeUint16(uint16_t data);
+    /// \brief Write an unsigned 16-bit integer in host byte order at the
+    /// specified position of the internal buffer in network byte order.
+    ///
+    /// The buffer must have a sufficient room to store the given data at the
+    /// given position, that is, <code>pos + 2 < getLength()</code>;
+    /// otherwise an exception of class \c isc::dns::InvalidBufferPosition will
+    /// be thrown.
+    /// Note also that this method never extends the internal buffer.
+    ///
+    /// \param data The 16-bit integer to be written into the internal buffer.
+    /// \param pos The beginning position in the buffer to write the data.
+    void writeUint16At(uint16_t data, size_t pos);
     /// \brief Write an unsigned 32-bit integer in host byte order into the
     /// internal buffer in network byte order.
     ///
     /// \param data The 32-bit integer to be written into the buffer.
     void writeUint32(uint32_t data);
+    /// \brief Copy an arbitrary length of data into the internal buffer
+    /// of the \c MessageRenderer.
+    ///
+    /// No conversion on the copied data is performed.
+    ///
+    /// \param data A pointer to the data to be copied into the internal buffer.
+    /// \param len The length of the data in bytes.
+    void writeData(const void *data, size_t len);
     //@}
 
     ///

Modified: branches/parkinglot/src/lib/dns/cpp/name.h
==============================================================================
--- branches/parkinglot/src/lib/dns/cpp/name.h (original)
+++ branches/parkinglot/src/lib/dns/cpp/name.h Tue Jan 26 22:15:42 2010
@@ -267,6 +267,43 @@
     /// \name Getter Methods
     ///
     //@{
+    /// \brief Provides one-byte name data in wire format at the specified
+    /// position.
+    ///
+    /// This method returns the unsigned 8-bit value of wire-format \c Name
+    /// data at the given position from the head.
+    ///
+    /// For example, if \c n is a \c Name object for "example.com",
+    /// \c n.at(3) would return \c 'a', and \c n.at(7) would return \c 'e'.
+    /// Note that \c n.at(0) would be 7 (decimal), the label length of
+    /// "example", instead of \c 'e', because it returns a data portion
+    /// in wire-format.  Likewise, \c n.at(8) would return 3 (decimal)
+    /// instead of <code>'.'</code>
+    ///
+    /// This method would be useful for an application to examine the
+    /// wire-format name data without dumping the data into a buffer,
+    /// which would involve data copies and would be less efficient.
+    /// One common usage of this method would be something like this:
+    /// \code for (size_t i = 0; i < name.getLength(); ++i) {
+    ///     uint8_t c = name.at(i);
+    ///     // do something with c
+    /// } \endcode
+    ///
+    /// Parameter \c pos must be in the valid range of the name data, that is,
+    /// must be less than \c Name.getLength().  Otherwise, an exception of
+    /// class \c OutOfRange will be thrown.
+    /// This method never throws an exception in other ways.
+    ///
+    /// \param pos The position in the wire format name data to be returned.
+    /// \return An unsigned 8-bit integer corresponding to the name data
+    /// at the position of \c pos.
+    const uint8_t at(size_t pos) const
+    {
+        if (pos >= length_) {
+            dns_throw(OutOfRange, "Out of range access in Name::at()");
+        }
+        return (ndata_[pos]);
+    }
     /// \brief Gets the length of the <code>Name</code> in its wire format.
     ///
     /// This method never throws an exception.

Modified: branches/parkinglot/src/lib/dns/cpp/name_unittest.cc
==============================================================================
--- branches/parkinglot/src/lib/dns/cpp/name_unittest.cc (original)
+++ branches/parkinglot/src/lib/dns/cpp/name_unittest.cc Tue Jan 26 22:15:42 2010
@@ -28,19 +28,16 @@
 
 #include <gtest/gtest.h>
 
-using isc::UnitTestUtil;
-using isc::dns::InputBuffer;
-using isc::dns::OutputBuffer;
-using isc::dns::Name;
-using isc::dns::MessageRenderer;
-using isc::dns::NameComparisonResult;
+using namespace std;
+using namespace isc;
+using namespace isc::dns;
 
 //
 // XXX: these are defined as class static constants, but some compilers
 // seemingly cannot find the symbols when used in the EXPECT_xxx macros.
 //
-const size_t isc::dns::Name::MAX_WIRE;
-const size_t isc::dns::Name::MAX_LABELS;
+const size_t Name::MAX_WIRE;
+const size_t Name::MAX_LABELS;
 
 namespace {
 class NameTest : public ::testing::Test {
@@ -73,7 +70,7 @@
 NameTest::nameFactoryFromWire(const char* datafile, size_t position,
                               bool downcase)
 {
-    std::vector<unsigned char> data;
+    vector<unsigned char> data;
     UnitTestUtil::readWireData(datafile, data);
 
     InputBuffer buffer(&data[0], data.size());
@@ -85,17 +82,17 @@
 Name
 NameTest::nameFactoryLowerCase()
 {
-    std::string lowercase_namestr;
+    string lowercase_namestr;
     lowercase_namestr.reserve(Name::MAX_WIRE);
 
     unsigned int ch = 0;
     unsigned int labelcount = 0;
     do {
         if (ch < 'A' || ch > 'Z') {
-            std::ostringstream ss;
-            ss.setf(std::ios_base::right, std::ios_base::adjustfield);
+            ostringstream ss;
+            ss.setf(ios_base::right, ios_base::adjustfield);
             ss.width(3);
-            ss << std::setfill('0') << ch;
+            ss << setfill('0') << ch;
             lowercase_namestr += '\\' + ss.str();
 
             if (++labelcount == Name::MAX_LABELLEN) {
@@ -125,7 +122,7 @@
 
 TEST_F(NameTest, fromText)
 {
-    std::vector<std::string> strnames;
+    vector<string> strnames;
     strnames.push_back("www.example.com");
     strnames.push_back("www.example.com."); // with a trailing dot
     strnames.push_back("wWw.exAmpLe.com");  // mixed cases
@@ -133,7 +130,7 @@
     // decimal representation for "WWW"
     strnames.push_back("\\087\\087\\087.example.com");
 
-    std::vector<std::string>::const_iterator it;
+    vector<string>::const_iterator it;
     for (it = strnames.begin(); it != strnames.end(); ++it) {
         EXPECT_PRED_FORMAT2(UnitTestUtil::matchName, example_name, Name(*it));
     }
@@ -148,32 +145,32 @@
     // Tests for bogus names.  These should trigger an exception.
     //
     // empty label cannot be followed by another label
-    EXPECT_THROW(Name(".a"), isc::dns::EmptyLabel);
+    EXPECT_THROW(Name(".a"), EmptyLabel);
     // duplicate period
-    EXPECT_THROW(Name("a.."), isc::dns::EmptyLabel);
+    EXPECT_THROW(Name("a.."), EmptyLabel);
     // label length must be < 64
     EXPECT_THROW(Name("012345678901234567890123456789"
                       "012345678901234567890123456789"
-                      "0123"), isc::dns::TooLongLabel);
+                      "0123"), TooLongLabel);
     // now-unsupported bitstring labels
-    EXPECT_THROW(Name("\\[b11010000011101]"), isc::dns::BadLabelType);
+    EXPECT_THROW(Name("\\[b11010000011101]"), BadLabelType);
     // label length must be < 64
     EXPECT_THROW(Name("012345678901234567890123456789"
                       "012345678901234567890123456789"
-                      "012\\x"), isc::dns::TooLongLabel);
+                      "012\\x"), TooLongLabel);
     // but okay as long as resulting len < 64 even if the original string is
     // "too long"
     EXPECT_NO_THROW(Name("012345678901234567890123456789"
                          "012345678901234567890123456789"
                          "01\\x"));
     // incomplete \DDD pattern (exactly 3 D's must appear)
-    EXPECT_THROW(Name("\\12abc"), isc::dns::BadEscape);
+    EXPECT_THROW(Name("\\12abc"), BadEscape);
     // \DDD must not exceed 255
-    EXPECT_THROW(Name("\\256"), isc::dns::BadEscape);
+    EXPECT_THROW(Name("\\256"), BadEscape);
     // Same tests for \111 as for \\x above
     EXPECT_THROW(Name("012345678901234567890123456789"
                       "012345678901234567890123456789"
-                      "012\\111"), isc::dns::TooLongLabel);
+                      "012\\111"), TooLongLabel);
     EXPECT_NO_THROW(Name("012345678901234567890123456789"
                          "012345678901234567890123456789"
                          "01\\111"));
@@ -183,7 +180,7 @@
                       "123456789.123456789.123456789.123456789.123456789."
                       "123456789.123456789.123456789.123456789.123456789."
                       "123456789.123456789.123456789.123456789.123456789."
-                      "1234"), isc::dns::TooLongName);
+                      "1234"), TooLongName);
     // This is a possible longest name and should be accepted
     EXPECT_NO_THROW(Name("123456789.123456789.123456789.123456789.123456789."
                          "123456789.123456789.123456789.123456789.123456789."
@@ -192,7 +189,7 @@
                          "123456789.123456789.123456789.123456789.123456789."
                          "123"));
     // \DDD must consist of 3 digits.
-    EXPECT_THROW(Name("\\12"), isc::dns::IncompleteName);
+    EXPECT_THROW(Name("\\12"), IncompleteName);
 
     // a name with the max number of labels.  should be constructed without
     // an error, and its length should be the max value.
@@ -217,26 +214,26 @@
                         Name("vix.com"));
     // bogus label character (looks like a local compression pointer)
     EXPECT_THROW(nameFactoryFromWire("testdata/name_fromWire2", 25),
-                 isc::dns::BadLabelType);
+                 BadLabelType);
     // a bad compression pointer (too big)
     EXPECT_THROW(nameFactoryFromWire("testdata/name_fromWire3_1", 25),
-                 isc::dns::BadPointer);
+                 BadPointer);
     // forward reference
     EXPECT_THROW(nameFactoryFromWire("testdata/name_fromWire3_2", 25),
-                 isc::dns::BadPointer);
+                 BadPointer);
     // invalid name length
     EXPECT_THROW(nameFactoryFromWire("testdata/name_fromWire4", 550),
-                 isc::dns::TooLongName);
+                 TooLongName);
 
     // skip test for from Wire5.  It's for disabling decompression, but our
     // implementation always allows it.
 
     // bad pointer (too big)
     EXPECT_THROW(nameFactoryFromWire("testdata/name_fromWire6", 25),
-                 isc::dns::BadPointer);
+                 BadPointer);
     // input ends unexpectedly
     EXPECT_THROW(nameFactoryFromWire("testdata/name_fromWire7", 25),
-                 isc::dns::IncompleteName);
+                 IncompleteName);
     // many hops of compression but valid.  should succeed.
     EXPECT_PRED_FORMAT2(UnitTestUtil::matchName,
                         nameFactoryFromWire("testdata/name_fromWire8", 383),
@@ -250,7 +247,7 @@
     EXPECT_EQ(Name::MAX_WIRE,
               nameFactoryFromWire("testdata/name_fromWire9", 0).getLength());
     EXPECT_THROW(nameFactoryFromWire("testdata/name_fromWire10", 0).getLength(),
-                 isc::dns::TooLongName);
+                 TooLongName);
 
     // A name with possible maximum number of labels; awkward but valid
     EXPECT_EQ(nameFactoryFromWire("testdata/name_fromWire11",
@@ -259,7 +256,7 @@
 
     // Wire format including an invalid label length
     EXPECT_THROW(nameFactoryFromWire("testdata/name_fromWire12", 0),
-                 isc::dns::BadLabelType);
+                 BadLabelType);
 
     // converting upper-case letters to down-case
     EXPECT_EQ("vix.com.", nameFactoryFromWire("testdata/name_fromWire1",
@@ -288,13 +285,13 @@
     // escaped while the others are intact.  note that the conversion is
     // implementation specific; for example, it's not invalid to escape a
     // "normal" character such as 'a' with regard to the standard.
-    std::string all_printable("!\\\"#\\$%&'\\(\\)*+,-\\./0123456789:\\;<=>?\\@"
+    string all_printable("!\\\"#\\$%&'\\(\\)*+,-\\./0123456789:\\;<=>?\\@"
                               "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
                               "[\\\\]^_.`abcdefghijklmnopqrstuvwxyz{|}~.");
     EXPECT_EQ(all_printable,
               nameFactoryFromWire("testdata/name_fromWire13", 0).toText());
 
-    std::string all_nonprintable(
+    string all_nonprintable(
         "\\000\\001\\002\\003\\004\\005\\006\\007\\008\\009"
         "\\010\\011\\012\\013\\014\\015\\016\\017\\018\\019"
         "\\020\\021\\022\\023\\024\\025\\026\\027\\028\\029"
@@ -319,10 +316,10 @@
 
 TEST_F(NameTest, toWireBuffer)
 {
-    std::vector<unsigned char> data;
+    vector<unsigned char> data;
     OutputBuffer buffer(0);
 
-    UnitTestUtil::readWireData(std::string("01610376697803636f6d00"), data);
+    UnitTestUtil::readWireData(string("01610376697803636f6d00"), data);
     Name("a.vix.com.").toWire(buffer);
     EXPECT_EQ(true, buffer.getLength() == data.size() &&
               memcmp(buffer.getData(), &data[0], data.size()) == 0);
@@ -334,11 +331,11 @@
 //
 TEST_F(NameTest, toWireRenderer)
 {
-    std::vector<unsigned char> data;
+    vector<unsigned char> data;
     OutputBuffer buffer(0);
     MessageRenderer renderer(buffer);
 
-    UnitTestUtil::readWireData(std::string("01610376697803636f6d00"), data);
+    UnitTestUtil::readWireData(string("01610376697803636f6d00"), data);
     Name("a.vix.com.").toWire(renderer);
     EXPECT_EQ(true, buffer.getLength() == data.size() &&
               memcmp(buffer.getData(), &data[0], data.size()) == 0);
@@ -370,7 +367,7 @@
 
 TEST_F(NameTest, compare)
 {
-    std::vector<CompareParameters> params;
+    vector<CompareParameters> params;
     params.push_back(CompareParameters(Name("c.d"), Name("a.b.c.d"),
                                        NameComparisonResult::SUPERDOMAIN,
                                        -1, 3));
@@ -386,7 +383,7 @@
                                        NameComparisonResult::EQUAL,
                                        0, 5));
 
-    std::vector<CompareParameters>::const_iterator it;
+    vector<CompareParameters>::const_iterator it;
     for (it = params.begin(); it != params.end(); ++it) {
         NameComparisonResult result = (*it).name1.compare((*it).name2);
         EXPECT_EQ((*it).reln, result.getRelation());
@@ -438,7 +435,7 @@
     Name n2("123456789.123456789.123456789.123456789.123456789."
             "123456789.123456789.123456789.123456789.123456789."
             "1234.");
-    EXPECT_THROW(n1.concatenate(n2), isc::dns::TooLongName);
+    EXPECT_THROW(n1.concatenate(n2), TooLongName);
 }
 
 TEST_F(NameTest, split)
@@ -454,8 +451,8 @@
     EXPECT_PRED_FORMAT2(UnitTestUtil::matchName, example_name.split(3, 1),
                         Name("."));
     // invalid range: an exception should be thrown.
-    EXPECT_THROW(example_name.split(1, 0), isc::dns::OutOfRange);
-    EXPECT_THROW(example_name.split(2, 3), isc::dns::OutOfRange);
+    EXPECT_THROW(example_name.split(1, 0), OutOfRange);
+    EXPECT_THROW(example_name.split(2, 3), OutOfRange);
 }
 
 TEST_F(NameTest, downcase)
@@ -471,6 +468,24 @@
     
 }
 
+TEST_F(NameTest, at)
+{
+    // Confirm at() produces the exact sequence of wire-format name data
+    vector<uint8_t> data;
+
+    for (size_t i = 0; i < example_name.getLength(); i++) {
+        data.push_back(example_name.at(i));
+    }
+
+    example_name.toWire(buffer_expected);
+    EXPECT_PRED_FORMAT4(UnitTestUtil::matchWireData,
+                        &data[0], data.size(),
+                        buffer_expected.getData(), buffer_expected.getLength());
+
+    // Out-of-range access: should trigger an exception.
+    EXPECT_THROW(example_name.at(example_name.getLength()), OutOfRange);
+}
+
 //
 // The following set of tests confirm the result of <=, <, >=, >
 // The test logic is simple, and all tests are just straightforward variations
@@ -530,7 +545,7 @@
 // test operator<<.  We simply confirm it appends the result of toText().
 TEST_F(NameTest, LeftShiftOperator)
 {
-    std::ostringstream oss;
+    ostringstream oss;
     oss << example_name;
     EXPECT_EQ(example_name.toText(), oss.str());
 }

Modified: branches/parkinglot/src/lib/dns/cpp/rrclass_unittest.cc
==============================================================================
--- branches/parkinglot/src/lib/dns/cpp/rrclass_unittest.cc (original)
+++ branches/parkinglot/src/lib/dns/cpp/rrclass_unittest.cc Tue Jan 26 22:15:42 2010
@@ -18,7 +18,6 @@
 
 #include "buffer.h"
 #include "messagerenderer.h"
-#include "rrparamregistry.h"
 #include "rrclass.h"
 
 #include "unittest_util.h"
@@ -38,7 +37,7 @@
     static RRClass rrclassFactoryFromWire(const char* datafile);
     static const RRClass rrclass_1, rrclass_0x80, rrclass_0x800,
         rrclass_0x8000, rrclass_max;
-    static const uint8_t wiredata[10];
+    static const uint8_t wiredata[];
 };
 
 const RRClass RRClassTest::rrclass_1(1);
@@ -48,8 +47,8 @@
 const RRClass RRClassTest::rrclass_max(0xffff);
 // This is wire-format data for the above sample RRClasss rendered in the
 // appearing order.
-const uint8_t RRClassTest::wiredata[10] = { 0x00, 0x01, 0x00, 0x80, 0x08,
-                                           0x00, 0x80, 0x00, 0xff, 0xff };
+const uint8_t RRClassTest::wiredata[] = { 0x00, 0x01, 0x00, 0x80, 0x08,
+                                          0x00, 0x80, 0x00, 0xff, 0xff };
 
 RRClass
 RRClassTest::rrclassFactoryFromWire(const char* datafile)

Modified: branches/parkinglot/src/lib/dns/cpp/rrparamregistry.cc
==============================================================================
--- branches/parkinglot/src/lib/dns/cpp/rrparamregistry.cc (original)
+++ branches/parkinglot/src/lib/dns/cpp/rrparamregistry.cc Tue Jan 26 22:15:42 2010
@@ -31,13 +31,15 @@
 #include "rrparamregistry.h"
 #include "rrclass.h"
 #include "rrtype.h"
+#include "rdata.h"
 
 using namespace std;
 using namespace boost;
 
+using namespace isc::dns::rdata; 
+
 namespace isc {
 namespace dns {
-
 namespace {
 ///
 /// The following function and class are a helper to define case-insensitive
@@ -111,6 +113,36 @@
 const size_t RRClassParam::UNKNOWN_MAXLEN =
     RRClassParam::UNKNOWN_MAX.size();
 }
+
+/// Note: the element ordering in the type/class pair is intentional.
+/// The standard library will perform inequality comparison (i.e, '<')
+/// in the way that the second elements (RRClass) are compared only when
+/// the first elements are equivalent.
+/// In practice, when we compare two pairs of RRType and RRClass, RRClass
+/// would be the same (and, in particular, be class IN) in the majority of
+/// cases.  So this comparison ordering should be more efficient in common
+/// cases.
+typedef pair<RRType, RRClass> RRTypeClass;
+typedef map<RRTypeClass, RdataFactoryPtr> RdataFactoryMap;
+
+template <typename T>
+class RdataFactory : public AbstractRdataFactory {
+public:
+    virtual RdataPtr create(const string& rdata_str) const
+    {
+        return (shared_ptr<T>(new T(rdata_str)));
+    }
+
+    virtual RdataPtr create(InputBuffer& buffer, size_t rdata_len) const
+    {
+        return (shared_ptr<T>(new T(buffer, rdata_len)));
+    }
+
+    virtual RdataPtr create(const Rdata& source) const
+    {
+        return (shared_ptr<T>(new T(dynamic_cast<const T&>(source))));
+    }
+};
 
 ///
 /// \brief The \c RRParamRegistryImpl class is the actual implementation of
@@ -128,6 +160,7 @@
     StrRRClassMap str2classmap;
     /// Mappings from textual representations of RR classes to integer codes.
     CodeRRClassMap code2classmap;
+    RdataFactoryMap rdata_factories;
 };
 
 RRParamRegistry::RRParamRegistry()
@@ -137,15 +170,34 @@
     // set up parameters for well-known RRs
     // XXX: this should eventually be more automatic.
     try {
-        add("A", 1, "IN", 1);
-        add("NS", 2, "IN", 1);
-
-        add("A", 1, "CH", 3);
+        // Class-IN specific types
+        add("A", 1, "IN", 1, RdataFactoryPtr(new RdataFactory<in::A>()));
+        add("AAAA", 28, "IN", 1, RdataFactoryPtr(new RdataFactory<in::AAAA>()));
+
+        // Class-CH specific types
+        add("A", 1, "CH", 3, RdataFactoryPtr(new RdataFactory<ch::A>()));
+
+        // should we add factories for class-independent (generic) types to
+        // each class repeatedly?  Or should we have a special mapping category
+        // of "generic" as a last resort?
+        add("NS", 2, "IN", 1, RdataFactoryPtr(new RdataFactory<generic::NS>()));
+        add("NS", 2, "CH", 3, RdataFactoryPtr(new RdataFactory<generic::NS>()));
+        add("SOA", 6, "IN", 1,
+            RdataFactoryPtr(new RdataFactory<generic::SOA>()));
+        add("SOA", 6, "CH", 3,
+            RdataFactoryPtr(new RdataFactory<generic::SOA>()));
+        add("MX", 15, "IN", 1,
+            RdataFactoryPtr(new RdataFactory<generic::MX>()));
+        add("MX", 15, "CH", 3,
+            RdataFactoryPtr(new RdataFactory<generic::MX>()));
+        add("TXT", 16, "IN", 1,
+            RdataFactoryPtr(new RdataFactory<generic::TXT>()));
+        add("TXT", 16, "CH", 3,
+            RdataFactoryPtr(new RdataFactory<generic::TXT>()));
     } catch (...) {
         delete impl_;
         throw;
     }
-    //...
 }
 
 RRParamRegistry::~RRParamRegistry()
@@ -163,8 +215,8 @@
 
 void
 RRParamRegistry::add(const string& typecode_string, uint16_t typecode,
-                     const string& classcode_string, uint16_t classcode
-                     /* rdata_factory (notyet) */)
+                     const string& classcode_string, uint16_t classcode,
+                     RdataFactoryPtr rdata_factory)
 {
     // Rollback logic on failure is complicated.  If adding the new type or
     // class fails, we should revert to the original state, cleaning up
@@ -178,6 +230,10 @@
     try {
         type_added = addType(typecode_string, typecode);
         class_added = addClass(classcode_string, classcode);
+        impl_->rdata_factories.insert(pair<RRTypeClass, RdataFactoryPtr>(
+                                          RRTypeClass(RRType(typecode),
+                                                      RRClass(classcode)),
+                                          rdata_factory));
     } catch (...) {
         if (type_added) {
             removeType(typecode);
@@ -369,5 +425,48 @@
     return (codeToText<RRClassParam, CodeRRClassMap>(code,
                                                      impl_->code2classmap));
 }
-}
-}
+
+RdataPtr
+RRParamRegistry::createRdata(const RRType& rrtype, const RRClass& rrclass,
+                             const string& rdata_string)
+{
+    // If the text indicates that it's rdata of an "unknown" type (beginning
+    // with '\# n'), parse it that way. (TBD)
+
+    RdataFactoryMap::const_iterator found;
+    found = impl_->rdata_factories.find(RRTypeClass(rrtype, rrclass));
+    if (found != impl_->rdata_factories.end()) {
+        return (found->second->create(rdata_string));
+    }
+
+    dns_throw(InvalidRdataText, "Unrecognized Rdata type to create from text");
+}
+
+RdataPtr
+RRParamRegistry::createRdata(const RRType& rrtype, const RRClass& rrclass,
+                             InputBuffer& buffer, size_t rdata_len)
+{
+    RdataFactoryMap::const_iterator found =
+        impl_->rdata_factories.find(RRTypeClass(rrtype, rrclass));
+    if (found != impl_->rdata_factories.end()) {
+        return (found->second->create(buffer, rdata_len));
+    }
+
+    // construct an "unknown" type of RDATA
+    return (RdataPtr(new generic::Generic(buffer, rdata_len)));
+}
+
+RdataPtr
+RRParamRegistry::createRdata(const RRType& rrtype, const RRClass& rrclass,
+                             const Rdata& source)
+{
+    RdataFactoryMap::const_iterator found =
+        impl_->rdata_factories.find(RRTypeClass(rrtype, rrclass));
+    if (found != impl_->rdata_factories.end()) {
+        return (found->second->create(source));
+    }
+
+    dns_throw(InvalidRdataText, "TBD");
+}
+}
+}

Modified: branches/parkinglot/src/lib/dns/cpp/rrparamregistry.h
==============================================================================
--- branches/parkinglot/src/lib/dns/cpp/rrparamregistry.h (original)
+++ branches/parkinglot/src/lib/dns/cpp/rrparamregistry.h Tue Jan 26 22:15:42 2010
@@ -21,7 +21,10 @@
 
 #include <stdint.h>
 
+#include <boost/shared_ptr.hpp>
+
 #include "exceptions.h"
+#include "rdata.h"
 
 namespace isc {
 namespace dns {
@@ -48,6 +51,30 @@
     RRClassExists(const char* file, size_t line, const char* what) :
         isc::dns::Exception(file, line, what) {}
 };
+
+class InvalidRdataText : public Exception {
+public:
+    InvalidRdataText(const char* file, size_t line, const char* what) :
+        isc::dns::Exception(file, line, what) {}
+};
+
+namespace rdata {
+class AbstractRdataFactory {
+protected:
+    AbstractRdataFactory() {}
+public:
+    virtual ~AbstractRdataFactory() {};
+
+    // Factory methods for polymorphic creation:
+    virtual RdataPtr create(const std::string& rdata_str) const = 0;
+    virtual RdataPtr create(InputBuffer& buffer, size_t rdata_len) const = 0;
+    virtual RdataPtr create(const rdata::Rdata& source) const = 0;
+};
+///
+/// TBD: describe it
+///
+typedef boost::shared_ptr<AbstractRdataFactory> RdataFactoryPtr;
+} // end of namespace rdata
 
 ///
 /// The \c RRParamRegistry class represents a registry of parameters to
@@ -149,7 +176,8 @@
     /// \param class_string The textual representation of the RR class.
     /// \param class_code The integer code of the RR class.
     void add(const std::string& type_string, uint16_t type_code,
-             const std::string& class_string, uint16_t class_code);
+             const std::string& class_string, uint16_t class_code,
+             rdata::RdataFactoryPtr rdata_factory);
 
     /// \brief Add mappings between RR type code and textual representation.
     ///
@@ -303,6 +331,21 @@
     std::string codeToClassText(uint16_t class_code) const;
     //@}
 
+    ///
+    /// \name RDATA Factories
+    ///
+    //@{
+    /// \brief TBD
+    rdata::RdataPtr createRdata(const RRType& rrtype, const RRClass& rrclass,
+                                const std::string& rdata_string);
+    /// \brief TBD
+    rdata::RdataPtr createRdata(const RRType& rrtype, const RRClass& rrclass,
+                                InputBuffer& buffer, size_t len);
+    /// \brief Polymorphic copy constructor (detailed TBD)
+    rdata::RdataPtr createRdata(const RRType& rrtype, const RRClass& rrclass,
+                                const rdata::Rdata& source);
+    //@}
+
 private:
     RRParamRegistryImpl* impl_;
 };

Modified: branches/parkinglot/src/lib/dns/cpp/rrparamregistry_unittest.cc
==============================================================================
--- branches/parkinglot/src/lib/dns/cpp/rrparamregistry_unittest.cc (original)
+++ branches/parkinglot/src/lib/dns/cpp/rrparamregistry_unittest.cc Tue Jan 26 22:15:42 2010
@@ -57,8 +57,8 @@
 
 TEST_F(RRParamRegistryTest, addRemove)
 {
-    RRParamRegistry::getRegistry().add(test_type_str, test_type_code,
-                                       test_class_str, test_class_code);
+    RRParamRegistry::getRegistry().addType(test_type_str, test_type_code);
+    RRParamRegistry::getRegistry().addClass(test_class_str, test_class_code);
     EXPECT_EQ(65533, RRClass("TESTCLASS").getCode());
     EXPECT_EQ(65534, RRType("TESTTYPE").getCode());
 
@@ -79,16 +79,12 @@
 {
     // An attempt to override a pre-registered class should fail with an
     // exception, and the pre-registered one should remain in the registry.
-    EXPECT_THROW(RRParamRegistry::getRegistry().add(test_type_str,
-                                                    test_type_code,
-                                                    test_class_str, 1),
+    EXPECT_THROW(RRParamRegistry::getRegistry().addClass(test_class_str, 1),
                  RRClassExists);
     EXPECT_EQ("IN", RRClass(1).toText());
 
     // Same for RRType
-    EXPECT_THROW(RRParamRegistry::getRegistry().add(test_type_str, 1,
-                                                    test_class_str,
-                                                    test_class_code),
+    EXPECT_THROW(RRParamRegistry::getRegistry().addType(test_type_str, 1),
                  RRTypeExists);
     EXPECT_EQ("A", RRType(1).toText());
 }

Modified: branches/parkinglot/src/lib/dns/cpp/rrtype_unittest.cc
==============================================================================
--- branches/parkinglot/src/lib/dns/cpp/rrtype_unittest.cc (original)
+++ branches/parkinglot/src/lib/dns/cpp/rrtype_unittest.cc Tue Jan 26 22:15:42 2010
@@ -18,7 +18,6 @@
 
 #include "buffer.h"
 #include "messagerenderer.h"
-#include "rrparamregistry.h"
 #include "rrtype.h"
 
 #include "unittest_util.h"
@@ -38,7 +37,7 @@
     static RRType rrtypeFactoryFromWire(const char* datafile);
     static const RRType rrtype_1, rrtype_0x80, rrtype_0x800, rrtype_0x8000,
         rrtype_max;
-    static const uint8_t wiredata[10];
+    static const uint8_t wiredata[];
 };
 
 const RRType RRTypeTest::rrtype_1(1);
@@ -48,8 +47,8 @@
 const RRType RRTypeTest::rrtype_max(0xffff);
 // This is wire-format data for the above sample RRTypes rendered in the
 // appearing order.
-const uint8_t RRTypeTest::wiredata[10] = { 0x00, 0x01, 0x00, 0x80, 0x08,
-                                           0x00, 0x80, 0x00, 0xff, 0xff };
+const uint8_t RRTypeTest::wiredata[] = { 0x00, 0x01, 0x00, 0x80, 0x08,
+                                         0x00, 0x80, 0x00, 0xff, 0xff };
 
 RRType
 RRTypeTest::rrtypeFactoryFromWire(const char* datafile)

Modified: branches/parkinglot/src/lib/dns/cpp/unittest_util.h
==============================================================================
--- branches/parkinglot/src/lib/dns/cpp/unittest_util.h (original)
+++ branches/parkinglot/src/lib/dns/cpp/unittest_util.h Tue Jan 26 22:15:42 2010
@@ -76,7 +76,6 @@
     matchName(const char* nameexp1, const char* nameexp2,
               const isc::dns::Name& name1, const isc::dns::Name& name2);
 };
-
 }
 #endif // __UNITTEST_UTIL_H
 




More information about the bind10-changes mailing list