[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