Commit c4cf50a3 authored by JINMEI Tatuya's avatar JINMEI Tatuya
Browse files

- added detaild documentation

- some more tests
- overall cleanup


git-svn-id: svn://bind10.isc.org/svn/bind10/branches/jinmei-dnsrrset@917 e5f2f494-b856-4b98-b285-d166d9295462
parent ffd4fcba
......@@ -568,7 +568,7 @@ WARN_LOGFILE =
# directories like "/usr/src/myproject". Separate the files or directories
# with spaces.
INPUT = ../src/lib/cc/cpp
INPUT = ../src/lib/cc/cpp ../src/lib/dns/cpp
# This tag can be used to specify the character encoding of the source files
# that doxygen parses. Internally doxygen uses the UTF-8 encoding, which is
......
......@@ -65,6 +65,7 @@ public:
class Rdata;
typedef boost::shared_ptr<Rdata> RdataPtr;
typedef boost::shared_ptr<const Rdata> ConstRdataPtr;
/// Abstract RDATA class
class Rdata {
......
......@@ -46,16 +46,20 @@ AbstractRRset::toText() const
string s;
RdataIteratorPtr it = getRdataIterator();
for (it->first(); !it->isLast(); it->next()) {
s += getName().toText() + " " +
getTTL().toText() + " " +
getClass().toText() + " " +
getType().toText() + " " +
it->getCurrent().toText() + "\n";
it->first();
if (it->isLast()) {
dns_throw(EmptyRRset, "ToText() is attempted for an empty RRset");
}
do {
s += getName().toText() + " " + getTTL().toText() + " " +
getClass().toText() + " " + getType().toText() + " " +
it->getCurrent().toText() + "\n";
it->next();
} while (!it->isLast());
return (s);
}
}
namespace {
template <typename T>
......@@ -65,9 +69,14 @@ rrsetToWire(const AbstractRRset& rrset, T& output)
unsigned int n = 0;
RdataIteratorPtr it = rrset.getRdataIterator();
it->first();
if (it->isLast()) {
dns_throw(EmptyRRset, "ToWire() is attempted for an empty RRset");
}
// sort the set of Rdata based on rrset-order and sortlist, and possible
// other options. Details to be considered.
for (it->first(); !it->isLast(); it->next(), ++n) {
do {
rrset.getName().toWire(output);
rrset.getType().toWire(output);
rrset.getClass().toWire(output);
......@@ -77,7 +86,10 @@ rrsetToWire(const AbstractRRset& rrset, T& output)
output.skip(sizeof(uint16_t)); // leave the space for RDLENGTH
it->getCurrent().toWire(output);
output.writeUint16At(output.getLength() - pos - sizeof(uint16_t), pos);
}
it->next();
++n;
} while (!it->isLast());
return (n);
}
......@@ -102,7 +114,10 @@ operator<<(ostream& os, const AbstractRRset& rrset)
return (os);
}
struct BasicRRsetImpl {
/// \brief This encapsulates the actual implementation of the \c BasicRRset
/// class. It's hidden from applications.
class BasicRRsetImpl {
public:
BasicRRsetImpl(const Name& name, const RRClass& rrclass,
const RRType& rrtype, const RRTTL& ttl) :
name_(name), rrclass_(rrclass), rrtype_(rrtype), ttl_(ttl) {}
......@@ -110,7 +125,10 @@ struct BasicRRsetImpl {
RRClass rrclass_;
RRType rrtype_;
RRTTL ttl_;
vector<RdataPtr> rdatalist_;
// XXX: "list" is not a good name: It in fact isn't a list; more conceptual
// name than a data structure name is generally better. But since this
// is only used in the internal implementation we'll live with it.
vector<ConstRdataPtr> rdatalist_;
};
BasicRRset::BasicRRset(const Name& name, const RRClass& rrclass,
......@@ -125,11 +143,17 @@ BasicRRset::~BasicRRset()
}
void
BasicRRset::addRdata(const RdataPtr rdata)
BasicRRset::addRdata(ConstRdataPtr rdata)
{
impl_->rdatalist_.push_back(rdata);
}
void
BasicRRset::addRdata(const Rdata& rdata)
{
AbstractRRset::addRdata(rdata);
}
unsigned int
BasicRRset::getRdataCount() const
{
......@@ -160,18 +184,42 @@ BasicRRset::getTTL() const
return (impl_->ttl_);
}
void
BasicRRset::setName(const Name& name)
{
impl_->name_ = name;
}
void
BasicRRset::setTTL(const RRTTL& ttl)
{
impl_->ttl_ = ttl;
}
string
BasicRRset::toText() const
{
return (AbstractRRset::toText());
}
unsigned int
BasicRRset::toWire(OutputBuffer& buffer) const
{
return (AbstractRRset::toWire(buffer));
}
unsigned int
BasicRRset::toWire(MessageRenderer& renderer) const
{
return (AbstractRRset::toWire(renderer));
}
namespace {
class BasicRdataIterator : public RdataIterator {
private:
BasicRdataIterator() {}
public:
BasicRdataIterator(const std::vector<rdata::RdataPtr>& datavector) :
BasicRdataIterator(const std::vector<rdata::ConstRdataPtr>& datavector) :
datavector_(&datavector) {}
~BasicRdataIterator() {}
virtual void first() { it_ = datavector_->begin(); }
......@@ -179,8 +227,8 @@ public:
virtual const rdata::Rdata& getCurrent() const { return (**it_); }
virtual bool isLast() const { return (it_ == datavector_->end()); }
private:
const std::vector<rdata::RdataPtr>* datavector_;
std::vector<rdata::RdataPtr>::const_iterator it_;
const std::vector<rdata::ConstRdataPtr>* datavector_;
std::vector<rdata::ConstRdataPtr>::const_iterator it_;
};
}
......
This diff is collapsed.
......@@ -168,6 +168,17 @@ TEST_F(RRsetTest, iterator)
rrset_a_empty.addRdata(in::A("192.0.2.1"));
rrset_a_empty.addRdata(in::A("192.0.2.2"));
addRdataTestCommon(rrset_a_empty);
// Rewind test: should be repeat the iteration by calling first().
for (int i = 0; i < 2; ++i) {
it = rrset_a_empty.getRdataIterator();
it->first();
EXPECT_FALSE(it->isLast());
it->next();
EXPECT_FALSE(it->isLast());
it->next();
EXPECT_TRUE(it->isLast());
}
}
TEST_F(RRsetTest, toText)
......@@ -175,6 +186,9 @@ TEST_F(RRsetTest, toText)
EXPECT_EQ("test.example.com. 3600 IN A 192.0.2.1\n"
"test.example.com. 3600 IN A 192.0.2.2\n",
rrset_a.toText());
// toText() cannot be performed for an empty RRset.
EXPECT_THROW(rrset_a_empty.toText(), EmptyRRset);
}
TEST_F(RRsetTest, toWireBuffer)
......@@ -184,6 +198,10 @@ TEST_F(RRsetTest, toWireBuffer)
UnitTestUtil::readWireData("testdata/rrset_toWire1", wiredata);
EXPECT_PRED_FORMAT4(UnitTestUtil::matchWireData, buffer.getData(),
buffer.getLength(), &wiredata[0], wiredata.size());
// toWire() cannot be performed for an empty RRset.
buffer.clear();
EXPECT_THROW(rrset_a_empty.toWire(buffer), EmptyRRset);
}
TEST_F(RRsetTest, toWireRenderer)
......@@ -196,6 +214,10 @@ TEST_F(RRsetTest, toWireRenderer)
UnitTestUtil::readWireData("testdata/rrset_toWire2", wiredata);
EXPECT_PRED_FORMAT4(UnitTestUtil::matchWireData, buffer.getData(),
buffer.getLength(), &wiredata[0], wiredata.size());
// toWire() cannot be performed for an empty RRset.
renderer.clear();
EXPECT_THROW(rrset_a_empty.toWire(renderer), EmptyRRset);
}
// test operator<<. We simply confirm it appends the result of toText().
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment