[svn] commit: r491 - in /branches/jinmei-dnsrdata/src/lib/dns/cpp: ./ testdata/

BIND 10 source code commits bind10-changes at lists.isc.org
Thu Jan 21 08:06:59 UTC 2010


Author: jinmei
Date: Thu Jan 21 08:06:59 2010
New Revision: 491

Log:
added the Rdata class.
completed: basic interfaces, sample concrete classes for NS and IN/A, and
test cases for the concrete classes.
TBD: cleanup and documentation, and perhaps add more concrete classes

Added:
    branches/jinmei-dnsrdata/src/lib/dns/cpp/rdata.cc   (with props)
    branches/jinmei-dnsrdata/src/lib/dns/cpp/rdata.h   (with props)
    branches/jinmei-dnsrdata/src/lib/dns/cpp/rdata_unittest.cc
    branches/jinmei-dnsrdata/src/lib/dns/cpp/testdata/rdata_in_a_fromWire
    branches/jinmei-dnsrdata/src/lib/dns/cpp/testdata/rdata_ns_fromWire
Modified:
    branches/jinmei-dnsrdata/src/lib/dns/cpp/Makefile.am
    branches/jinmei-dnsrdata/src/lib/dns/cpp/exceptions.h
    branches/jinmei-dnsrdata/src/lib/dns/cpp/messagerenderer.cc
    branches/jinmei-dnsrdata/src/lib/dns/cpp/messagerenderer.h
    branches/jinmei-dnsrdata/src/lib/dns/cpp/name.h
    branches/jinmei-dnsrdata/src/lib/dns/cpp/rrclass_unittest.cc
    branches/jinmei-dnsrdata/src/lib/dns/cpp/rrparamregistry.cc
    branches/jinmei-dnsrdata/src/lib/dns/cpp/rrparamregistry.h
    branches/jinmei-dnsrdata/src/lib/dns/cpp/rrparamregistry_unittest.cc
    branches/jinmei-dnsrdata/src/lib/dns/cpp/rrtype_unittest.cc

Modified: branches/jinmei-dnsrdata/src/lib/dns/cpp/Makefile.am
==============================================================================
--- branches/jinmei-dnsrdata/src/lib/dns/cpp/Makefile.am (original)
+++ branches/jinmei-dnsrdata/src/lib/dns/cpp/Makefile.am Thu Jan 21 08:06:59 2010
@@ -6,6 +6,7 @@
 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
 libdns_la_SOURCES += exceptions.h exceptions.cc
 
 TESTS =
@@ -16,6 +17,7 @@
 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 += rrparamregistry_unittest.cc
 run_unittests_SOURCES += run_unittests.cc
 run_unittests_CPPFLAGS = $(GTEST_INCLUDES)

Modified: branches/jinmei-dnsrdata/src/lib/dns/cpp/exceptions.h
==============================================================================
--- branches/jinmei-dnsrdata/src/lib/dns/cpp/exceptions.h (original)
+++ branches/jinmei-dnsrdata/src/lib/dns/cpp/exceptions.h Thu Jan 21 08:06:59 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/jinmei-dnsrdata/src/lib/dns/cpp/messagerenderer.cc
==============================================================================
--- branches/jinmei-dnsrdata/src/lib/dns/cpp/messagerenderer.cc (original)
+++ branches/jinmei-dnsrdata/src/lib/dns/cpp/messagerenderer.cc Thu Jan 21 08:06:59 2010
@@ -168,6 +168,12 @@
     impl_->buffer_.writeUint32(data);
 }
 
+void
+MessageRenderer::writeData(const void* data, size_t len)
+{
+    impl_->buffer_.writeData(data, len);
+}
+
 const void*
 MessageRenderer::getData() const
 {

Modified: branches/jinmei-dnsrdata/src/lib/dns/cpp/messagerenderer.h
==============================================================================
--- branches/jinmei-dnsrdata/src/lib/dns/cpp/messagerenderer.h (original)
+++ branches/jinmei-dnsrdata/src/lib/dns/cpp/messagerenderer.h Thu Jan 21 08:06:59 2010
@@ -115,6 +115,14 @@
     ///
     /// \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/jinmei-dnsrdata/src/lib/dns/cpp/name.h
==============================================================================
--- branches/jinmei-dnsrdata/src/lib/dns/cpp/name.h (original)
+++ branches/jinmei-dnsrdata/src/lib/dns/cpp/name.h Thu Jan 21 08:06:59 2010
@@ -267,6 +267,11 @@
     /// \name Getter Methods
     ///
     //@{
+    /// \brief TBD
+    const uint8_t at(size_t pos) const
+    {
+        return (ndata_.at(pos));
+    }
     /// \brief Gets the length of the <code>Name</code> in its wire format.
     ///
     /// This method never throws an exception.

Modified: branches/jinmei-dnsrdata/src/lib/dns/cpp/rrclass_unittest.cc
==============================================================================
--- branches/jinmei-dnsrdata/src/lib/dns/cpp/rrclass_unittest.cc (original)
+++ branches/jinmei-dnsrdata/src/lib/dns/cpp/rrclass_unittest.cc Thu Jan 21 08:06:59 2010
@@ -18,7 +18,6 @@
 
 #include "buffer.h"
 #include "messagerenderer.h"
-#include "rrparamregistry.h"
 #include "rrclass.h"
 
 #include "unittest_util.h"

Modified: branches/jinmei-dnsrdata/src/lib/dns/cpp/rrparamregistry.cc
==============================================================================
--- branches/jinmei-dnsrdata/src/lib/dns/cpp/rrparamregistry.cc (original)
+++ branches/jinmei-dnsrdata/src/lib/dns/cpp/rrparamregistry.cc Thu Jan 21 08:06:59 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,31 @@
 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 fromText(const string& rdata_str) const
+    {
+        return (shared_ptr<T>(new T(rdata_str)));
+    }
+
+    virtual RdataPtr fromWire(InputBuffer& buffer, size_t rdata_len) const
+    {
+        return (shared_ptr<T>(new T(buffer, rdata_len)));
+    }
+};
 
 ///
 /// \brief The \c RRParamRegistryImpl class is the actual implementation of
@@ -128,6 +155,7 @@
     StrRRClassMap str2classmap;
     /// Mappings from textual representations of RR classes to integer codes.
     CodeRRClassMap code2classmap;
+    RdataFactoryMap rdata_factories;
 };
 
 RRParamRegistry::RRParamRegistry()
@@ -137,10 +165,20 @@
     // 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);
+        add("A", 1, "IN", 1, RdataFactoryPtr(new RdataFactory<in::A>()));
+        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>()));
+
+        // XXX merge this to add().
+        //impl_->rdata_factories.insert(
+        //  pair<RRTypeClass, RdataFactoryPtr>(RRTypeClass(RRType(2),
+        //                                                 RRClass(1)),
+        //                                     RdataFactoryPtr(new RdataFactory<generic::NS>())));
     } catch (...) {
         delete impl_;
         throw;
@@ -163,8 +201,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 +216,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 +411,37 @@
     return (codeToText<RRClassParam, CodeRRClassMap>(code,
                                                      impl_->code2classmap));
 }
-}
-}
+
+RdataPtr
+RRParamRegistry::createRdataFromText(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->fromText(rdata_string));
+    }
+
+    dns_throw(InvalidRdataText, "Unrecognized Rdata type to create from text");
+}
+
+RdataPtr
+RRParamRegistry::createRdataFromWire(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->fromWire(buffer, rdata_len));
+    }
+
+    // construct an "unknown" type of RDATA
+    return (RdataPtr(new generic::Generic(buffer, rdata_len)));
+}
+}
+}

Modified: branches/jinmei-dnsrdata/src/lib/dns/cpp/rrparamregistry.h
==============================================================================
--- branches/jinmei-dnsrdata/src/lib/dns/cpp/rrparamregistry.h (original)
+++ branches/jinmei-dnsrdata/src/lib/dns/cpp/rrparamregistry.h Thu Jan 21 08:06:59 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,29 @@
     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 fromText(const std::string& rdata_str) const = 0;
+    virtual RdataPtr fromWire(InputBuffer& buffer, size_t rdata_len) 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 +175,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 +330,20 @@
     std::string codeToClassText(uint16_t class_code) const;
     //@}
 
+    ///
+    /// \name RDATA Factories
+    ///
+    //@{
+    /// \brief TBD
+    rdata::RdataPtr createRdataFromText(const RRType& rrtype,
+                                        const RRClass& rrclass,
+                                        const std::string& rdata_string);
+    /// \brief TBD
+    rdata::RdataPtr createRdataFromWire(const RRType& rrtype,
+                                        const RRClass& rrclass,
+                                        InputBuffer& buffer, size_t len);
+    //@}
+
 private:
     RRParamRegistryImpl* impl_;
 };

Modified: branches/jinmei-dnsrdata/src/lib/dns/cpp/rrparamregistry_unittest.cc
==============================================================================
--- branches/jinmei-dnsrdata/src/lib/dns/cpp/rrparamregistry_unittest.cc (original)
+++ branches/jinmei-dnsrdata/src/lib/dns/cpp/rrparamregistry_unittest.cc Thu Jan 21 08:06:59 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/jinmei-dnsrdata/src/lib/dns/cpp/rrtype_unittest.cc
==============================================================================
--- branches/jinmei-dnsrdata/src/lib/dns/cpp/rrtype_unittest.cc (original)
+++ branches/jinmei-dnsrdata/src/lib/dns/cpp/rrtype_unittest.cc Thu Jan 21 08:06:59 2010
@@ -18,7 +18,6 @@
 
 #include "buffer.h"
 #include "messagerenderer.h"
-#include "rrparamregistry.h"
 #include "rrtype.h"
 
 #include "unittest_util.h"




More information about the bind10-changes mailing list