[svn] commit: r164 - in /branches/f2f200910/src/lib/dns: message.cc message.h message_unittest.cc rrset.cc rrset.h rrset_unittest.cc
BIND 10 source code commits
bind10-changes at lists.isc.org
Thu Oct 29 20:03:02 UTC 2009
Author: jinmei
Date: Thu Oct 29 20:03:02 2009
New Revision: 164
Log:
- some style fixes: s/Rr/RR/, s/RDATAPTR/RdataPtr/ (RDATAPTR is still available
for compatibility)
- added some support methods to handle Rdata in more polymorphic way
Modified:
branches/f2f200910/src/lib/dns/message.cc
branches/f2f200910/src/lib/dns/message.h
branches/f2f200910/src/lib/dns/message_unittest.cc
branches/f2f200910/src/lib/dns/rrset.cc
branches/f2f200910/src/lib/dns/rrset.h
branches/f2f200910/src/lib/dns/rrset_unittest.cc
Modified: branches/f2f200910/src/lib/dns/message.cc
==============================================================================
--- branches/f2f200910/src/lib/dns/message.cc (original)
+++ branches/f2f200910/src/lib/dns/message.cc Thu Oct 29 20:03:02 2009
@@ -77,7 +77,7 @@
}
void
-Message::addRrset(section_t section, RRsetPtr rrsetp)
+Message::addRRset(section_t section, RRsetPtr rrsetp)
{
if (section >= SECTION_MAX)
throw DNSInvalidMessageSection();
@@ -90,7 +90,7 @@
Message::addQuestion(const Name& qname, const RRClass& qclass,
const RRType& qtype)
{
- addRrset(SECTION_QUESTION, RRsetPtr(new Question(qname, qclass, qtype)));
+ addRRset(SECTION_QUESTION, RRsetPtr(new Question(qname, qclass, qtype)));
}
void
@@ -185,7 +185,7 @@
RRType rrtype(buffer_->readUint16());
RRClass rrclass(buffer_->readUint16());
- addRrset(SECTION_QUESTION,
+ addRRset(SECTION_QUESTION,
RRsetPtr(new Question(name, rrclass, rrtype)));
}
}
@@ -300,7 +300,7 @@
};
void
-Message::addRr(section_t section, const RR& rr)
+Message::addRR(section_t section, const RR& rr)
{
std::vector<RRsetPtr>::iterator it;
it = find_if(sections_[section].begin(), sections_[section].end(),
Modified: branches/f2f200910/src/lib/dns/message.h
==============================================================================
--- branches/f2f200910/src/lib/dns/message.h (original)
+++ branches/f2f200910/src/lib/dns/message.h Thu Oct 29 20:03:02 2009
@@ -91,14 +91,14 @@
// of RR in the message
const std::vector<RRsetPtr>& getSection(section_t section) const
{ return (sections_[section]); }
- void addRrset(section_t section, RRsetPtr rrset);
+ void addRRset(section_t section, RRsetPtr rrset);
// addQuestion() is redundant in that it's a special case of add_rrset,
// but it'd be convenient for general purpose applications.
void addQuestion(const Name& qname, const RRClass& qclass,
const RRType& qtype);
- void removeRrset(section_t section, RRsetPtr rrset);
- void addRr(section_t section, const RR& rr);
- void removeRr(section_t section, const RR& rr);
+ void removeRRset(section_t section, RRsetPtr rrset);
+ void addRR(section_t section, const RR& rr);
+ void removeRR(section_t section, const RR& rr);
// should we separate methods for different EDNS0-related
// parameters/options? it would probably be better to have a
Modified: branches/f2f200910/src/lib/dns/message_unittest.cc
==============================================================================
--- branches/f2f200910/src/lib/dns/message_unittest.cc (original)
+++ branches/f2f200910/src/lib/dns/message_unittest.cc Thu Oct 29 20:03:02 2009
@@ -99,14 +99,14 @@
TEST_F(MessageTest, addRr)
{
// Add one RR to the answer section.
- response.addRr(SECTION_ANSWER, RR(Name("www.example.com"), RRClass::IN,
+ response.addRR(SECTION_ANSWER, RR(Name("www.example.com"), RRClass::IN,
RRType::A, TTL(3600), A("192.0.2.1")));
EXPECT_EQ("www.example.com. 3600 IN A 192.0.2.1",
(**response.getSection(SECTION_ANSWER).begin()).toText());
// Add another RR of the same RRset with a larger TTL. The original
// (smaller) TTL should remain.
- response.addRr(SECTION_ANSWER, RR(Name("www.example.com"), RRClass::IN,
+ response.addRR(SECTION_ANSWER, RR(Name("www.example.com"), RRClass::IN,
RRType::A, TTL(7200), A("192.0.2.2")));
EXPECT_EQ("www.example.com. 3600 IN A 192.0.2.1\n"
"www.example.com. 3600 IN A 192.0.2.2",
@@ -114,7 +114,7 @@
// Add one more RR of the same RRset with a smaller TTL. The new (smaller)
// TTL should replace with the old one.
- response.addRr(SECTION_ANSWER, RR(Name("www.example.com"), RRClass::IN,
+ response.addRR(SECTION_ANSWER, RR(Name("www.example.com"), RRClass::IN,
RRType::A, TTL(1800), A("192.0.2.3")));
EXPECT_EQ("www.example.com. 1800 IN A 192.0.2.1\n"
"www.example.com. 1800 IN A 192.0.2.2\n"
Modified: branches/f2f200910/src/lib/dns/rrset.cc
==============================================================================
--- branches/f2f200910/src/lib/dns/rrset.cc (original)
+++ branches/f2f200910/src/lib/dns/rrset.cc Thu Oct 29 20:03:02 2009
@@ -20,10 +20,15 @@
#include <arpa/inet.h>
#include <stdexcept>
-#include <cstring>
+//#include <cstring>
+#include <utility>
+#include <map>
#include <dns/buffer.h>
#include <dns/rrset.h>
+
+using std::pair;
+using std::map;
using isc::dns::RRClass;
using isc::dns::RRType;
@@ -111,6 +116,64 @@
buffer.writeUint32(ttlval_);
}
+typedef Rdata* (*RdataFactory)(const std::string& text_rdata);
+typedef pair<RRClass, RRType> RRClassTypePair;
+static map<RRClassTypePair, RdataFactory> rdata_factory_repository;
+
+struct RdataFactoryRegister {
+public:
+ RdataFactoryRegister();
+ ~RdataFactoryRegister() {}
+private:
+};
+
+static RdataFactoryRegister rdata_factory;
+
+Rdata *
+createADataFromText(const std::string& text_rdata)
+{
+ return (new A(text_rdata));
+}
+
+Rdata *
+createAAAADataFromText(const std::string& text_rdata)
+{
+ return (new AAAA(text_rdata));
+}
+
+Rdata *
+createNSDataFromText(const std::string& text_rdata)
+{
+ return (new NS(text_rdata));
+}
+
+RdataFactoryRegister::RdataFactoryRegister()
+{
+ rdata_factory_repository.insert(pair<RRClassTypePair, RdataFactory>
+ (RRClassTypePair(RRClass::IN, RRType::A),
+ createADataFromText));
+ rdata_factory_repository.insert(pair<RRClassTypePair, RdataFactory>
+ (RRClassTypePair(RRClass::IN, RRType::AAAA),
+ createAAAADataFromText));
+ //XXX: NS belongs to the 'generic' class. should revisit it.
+ rdata_factory_repository.insert(pair<RRClassTypePair, RdataFactory>
+ (RRClassTypePair(RRClass::IN, RRType::NS),
+ createNSDataFromText));
+}
+
+Rdata *
+Rdata::fromText(const RRClass& rrclass, const RRType& rrtype,
+ const std::string& text_rdata)
+{
+ map<RRClassTypePair, RdataFactory>::const_iterator entry;
+ entry = rdata_factory_repository.find(RRClassTypePair(rrclass, rrtype));
+ if (entry != rdata_factory_repository.end()) {
+ return (entry->second(text_rdata));
+ }
+
+ throw DNSInvalidRRType();
+}
+
A::A(const std::string& addrstr)
{
if (inet_pton(AF_INET, addrstr.c_str(), &addr_) != 1)
@@ -215,7 +278,7 @@
{
std::string s;
- for (std::vector<Rdata::RDATAPTR>::const_iterator it = rdatalist_.begin();
+ for (std::vector<Rdata::RdataPtr>::const_iterator it = rdatalist_.begin();
it != rdatalist_.end();
++it)
{
@@ -230,7 +293,7 @@
}
void
-RRset::addRdata(Rdata::RDATAPTR rdata)
+RRset::addRdata(Rdata::RdataPtr rdata)
{
if (rdata->getType() != rrtype_)
throw DNSRRtypeMismatch();
@@ -247,7 +310,7 @@
// section is not currently used. will be, when we implement rrset-order
// etc.
- for (std::vector<Rdata::RDATAPTR>::iterator it = rdatalist_.begin();
+ for (std::vector<Rdata::RdataPtr>::iterator it = rdatalist_.begin();
it != rdatalist_.end();
++it, ++num_rrs)
{
@@ -286,17 +349,12 @@
const TTL& ttl, const Rdata::Rdata& rdata) :
rrset_(name, rrclass, rrtype, ttl)
{
- // XXX: this implementation is BAD. we took the ugly bad fastest approach
- // for rapid experiment. should rewrite it.
- if (rrtype == RRType::A) {
- rrset_.addRdata(Rdata::RDATAPTR(new A(rdata.toText())));
- } else if (rrtype == RRType::AAAA) {
- rrset_.addRdata(Rdata::RDATAPTR(new AAAA(rdata.toText())));
- } else if (rrtype == RRType::NS) {
- rrset_.addRdata(Rdata::RDATAPTR(new NS(rdata.toText())));
- } else {
- // XXX
- throw std::runtime_error("RR constructor encountered "
- "an unsupported type");
- }
-}
+ rrset_.addRdata(Rdata::RdataPtr(rdata.copy()));
+}
+
+RR::RR(const Name& name, const RRClass& rrclass, const RRType& rrtype,
+ const TTL& ttl, Rdata::RdataPtr rdata) :
+ rrset_(name, rrclass, rrtype, ttl)
+{
+ rrset_.addRdata(rdata);
+}
Modified: branches/f2f200910/src/lib/dns/rrset.h
==============================================================================
--- branches/f2f200910/src/lib/dns/rrset.h (original)
+++ branches/f2f200910/src/lib/dns/rrset.h Thu Oct 29 20:03:02 2009
@@ -53,6 +53,8 @@
{ return (classval_ == other.classval_); }
bool operator!=(const RRClass& other) const
{ return (classval_ != other.classval_); }
+ bool operator<(const RRClass& other) const
+ { return (classval_ < other.classval_); }
// (Some) well-known RRclass constants
static const RRClass IN;
@@ -73,6 +75,8 @@
{ return (typeval_ == other.typeval_); }
bool operator!=(const RRType& other) const
{ return (typeval_ != other.typeval_); }
+ bool operator<(const RRType& other) const
+ { return (typeval_ < other.typeval_); }
// (Some) Well-known RRtype constants
static const RRType A;
@@ -113,10 +117,11 @@
// if we worry about data copy, we may have to use
// shared pointers at the cost of depending on boost.
class Rdata;
-typedef boost::shared_ptr<Rdata> RDATAPTR;
+typedef boost::shared_ptr<Rdata> RDATAPTR; // for compatibility
+typedef boost::shared_ptr<Rdata> RdataPtr;
// if we want to avoid the dependency, use this; but we'll have
// to care much more about resource leak.
-//typedef Rdata * RDATAPTR;
+//typedef Rdata * RdataPtr;
// Abstract RDATA class
class Rdata {
@@ -129,6 +134,10 @@
virtual void toWire(Buffer& b, NameCompressor& c) const = 0;
// need generic method for getting n-th field? c.f. ldns
// e.g. string getField(int n);
+
+ // A semi polymorphic factory.
+ static Rdata* fromText(const RRClass& rrclass, const RRType& rrtype,
+ const std::string& text_rdata);
// polymorphic copy constructor (XXX should revisit it)
virtual Rdata* copy() const = 0;
@@ -232,7 +241,7 @@
virtual std::string toText() const = 0;
virtual int toWire(Buffer& buffer, NameCompressor& compressor,
section_t section) = 0;
- virtual void addRdata(Rdata::RDATAPTR rdata) = 0;
+ virtual void addRdata(Rdata::RdataPtr rdata) = 0;
virtual unsigned int countRdata() const = 0;
virtual const Name& getName() const = 0;
virtual const RRClass& getClass() const = 0;
@@ -248,7 +257,7 @@
const RRType &rrtype, const TTL &ttl) :
name_(name), rrclass_(rrclass), rrtype_(rrtype), ttl_(ttl) {}
unsigned int countRdata() const { return (rdatalist_.size()); }
- void addRdata(Rdata::RDATAPTR rdata);
+ void addRdata(Rdata::RdataPtr rdata);
void removeRdata(const Rdata::Rdata& rdata);
std::string toText() const;
int toWire(Buffer& buffer, NameCompressor& compressor, section_t section);
@@ -258,7 +267,7 @@
const TTL& getTtl() const { return (ttl_); }
// once constructed, only TTL and rdatalist can be modified.
void setTtl(const TTL& ttl) { ttl_ = ttl; }
- const std::vector<Rdata::RDATAPTR>& getRdatalist() const
+ const std::vector<Rdata::RdataPtr>& getRdatalist() const
{ return (rdatalist_); }
template <typename T> void getRdatalist(std::vector<T>&) const;
private:
@@ -266,7 +275,7 @@
RRClass rrclass_;
RRType rrtype_;
TTL ttl_;
- std::vector<Rdata::RDATAPTR> rdatalist_;
+ std::vector<Rdata::RdataPtr> rdatalist_;
};
//
@@ -287,7 +296,7 @@
const RRType& getType() const { return (rrtype_); }
const TTL& getTtl() const { return (ttl_); } // XXX
void setTtl(const TTL& ttl) {} // XXX
- void addRdata(Rdata::RDATAPTR rdata) {} // XXX
+ void addRdata(Rdata::RdataPtr rdata) {} // XXX
private:
Name name_;
RRClass rrclass_;
@@ -300,7 +309,7 @@
void
RRset::getRdatalist(std::vector<T>& v) const
{
- std::vector<Rdata::RDATAPTR>::const_iterator it;
+ std::vector<Rdata::RdataPtr>::const_iterator it;
for (it = rdatalist_.begin(); it != rdatalist_.end(); ++it) {
const T& concreteRdata = static_cast<const T&>(**it); // XXX
if (T::getTypeStatic() != (**it).getType()) {
@@ -322,12 +331,15 @@
explicit RR(const Name& name, const RRClass& rrclass,
const RRType& rrtype, const TTL& ttl,
const Rdata::Rdata& rdata);
+ explicit RR(const Name& name, const RRClass& rrclass,
+ const RRType& rrtype, const TTL& ttl,
+ Rdata::RdataPtr rdata);
std::string toText() const { return (rrset_.toText()); }
const Name& getName() const { return (rrset_.getName()); }
const RRClass& getClass() const { return (rrset_.getClass()); }
const RRType& getType() const { return (rrset_.getType()); }
const TTL& getTtl() const { return (rrset_.getTtl()); }
- const Rdata::RDATAPTR getRdata() const
+ const Rdata::RdataPtr getRdata() const
{ return (*rrset_.getRdatalist().begin()); }
void setTtl(const TTL& ttl) { rrset_.setTtl(ttl); }
private:
Modified: branches/f2f200910/src/lib/dns/rrset_unittest.cc
==============================================================================
--- branches/f2f200910/src/lib/dns/rrset_unittest.cc (original)
+++ branches/f2f200910/src/lib/dns/rrset_unittest.cc Thu Oct 29 20:03:02 2009
@@ -25,7 +25,8 @@
using isc::dns::RRClass;
using isc::dns::RRType;
using isc::dns::TTL;
-using isc::dns::Rdata::RDATAPTR;
+using isc::dns::Rdata::RdataPtr;
+using isc::dns::Rdata::Rdata;
using isc::dns::Rdata::IN::A;
using isc::dns::Rdata::IN::AAAA;
using isc::dns::Rdata::Generic::NS;
@@ -84,6 +85,18 @@
EXPECT_EQ(0, ttl0.getValue());
}
+// The fixture for testing generic Rdata class
+class RdataTest : public ::testing::Test {
+protected:
+ RdataTest() {}
+};
+
+TEST_F(RdataTest, fromToText)
+{
+ EXPECT_EQ("192.0.2.1",
+ Rdata::fromText(RRClass::IN, RRType::A, "192.0.2.1")->toText());
+}
+
// The fixture for testing class IN/A Rdata
class Rdata_IN_A_Test : public ::testing::Test {
protected:
@@ -129,9 +142,9 @@
rrset_a(Name("www.example.com"), RRClass::IN, RRType::A, TTL(3600)),
rrset_aaaa(Name("ns.example.net"), RRClass::IN, RRType::AAAA, TTL(60))
{
- rrset_a.addRdata(RDATAPTR(new A("192.0.2.1")));
- rrset_a.addRdata(RDATAPTR(new A("192.0.2.255")));
- rrset_aaaa.addRdata(RDATAPTR(new AAAA("2001:db8::1234")));
+ rrset_a.addRdata(RdataPtr(new A("192.0.2.1")));
+ rrset_a.addRdata(RdataPtr(new A("192.0.2.255")));
+ rrset_aaaa.addRdata(RdataPtr(new AAAA("2001:db8::1234")));
}
RRset rrset_a;
@@ -197,4 +210,11 @@
EXPECT_EQ("ns.example.net. 60 IN AAAA 2001:db8::1234", rr_aaaa.toText());
EXPECT_EQ("example.net. 1800 IN NS ns.example.net.", rr_ns.toText());
}
-}
+
+TEST_F(RRTest, construtFromRdataPtr)
+{
+ EXPECT_EQ("www.example.com. 3600 IN A 192.0.2.1",
+ RR(Name("www.example.com"), RRClass::IN, RRType::A, TTL(3600),
+ RdataPtr(new A("192.0.2.1"))).toText());
+}
+}
More information about the bind10-changes
mailing list