RdataPtr rdata =
RRParamRegistry::getRegistry().createRdata(rrtype, rrclass, buffer,
len);
-
+
if (buffer.getPosition() - old_pos != len) {
isc_throw(InvalidRdataLength, "RDLENGTH mismatch: " <<
buffer.getPosition() - old_pos << " != " << len);
source));
}
+RdataPtr
+createRdata(const RRType& rrtype, const RRClass& rrclass,
+ MasterLexer& lexer, const Name* origin,
+ MasterLoader::Options options,
+ MasterLoaderCallbacks& callbacks)
+{
+ return (RRParamRegistry::getRegistry().createRdata(rrtype, rrclass,
+ lexer, origin,
+ options, callbacks));
+}
+
int
compareNames(const Name& n1, const Name& n2) {
size_t len1 = n1.getLength();
impl_ = new GenericImpl(data);
}
-Generic::Generic(const std::string& rdata_string) {
+void
+Generic::constructHelper(const std::string& rdata_string) {
istringstream iss(rdata_string);
string unknown_mark;
iss >> unknown_mark;
impl_ = new GenericImpl(data);
}
+Generic::Generic(const std::string& rdata_string) {
+ constructHelper(rdata_string);
+}
+
+Generic::Generic(MasterLexer& lexer, const Name*,
+ MasterLoader::Options,
+ MasterLoaderCallbacks&)
+{
+ std::string s;
+
+ while (true) {
+ const MasterLexer::Token& token = lexer.getNextToken();
+ if (token.getType() == MasterLexer::Token::END_OF_FILE) {
+ break;
+ }
+
+ if (!s.empty()) {
+ s += " ";
+ }
+
+ s += token.getString();
+ }
+
+ constructHelper(s);
+}
+
Generic::~Generic() {
delete impl_;
}
#ifndef RDATA_H
#define RDATA_H 1
-#include <stdint.h>
+#include <dns/master_lexer.h>
+#include <dns/master_loader.h>
+#include <dns/master_loader_callbacks.h>
+
+#include <exceptions/exceptions.h>
#include <boost/shared_ptr.hpp>
-#include <exceptions/exceptions.h>
+#include <stdint.h>
namespace isc {
namespace util {
/// \param rdata_len The length in buffer of the \c Rdata. In bytes.
Generic(isc::util::InputBuffer& buffer, size_t rdata_len);
+ /// \brief Constructor from master lexer.
+ ///
+ Generic(MasterLexer& lexer, const Name* name,
+ MasterLoader::Options options, MasterLoaderCallbacks& callbacks);
+
///
/// \brief The destructor.
virtual ~Generic();
/// \return > 0 if \c this would be sorted after \c other.
virtual int compare(const Rdata& other) const;
//@}
+
private:
+ void constructHelper(const std::string& rdata_string);
+
GenericImpl* impl_;
};
/// \c Rdata object.
RdataPtr createRdata(const RRType& rrtype, const RRClass& rrclass,
const Rdata& source);
+
+/// \brief Create RDATA of a given pair of RR type and class from the
+/// master lexer.
+RdataPtr createRdata(const RRType& rrtype, const RRClass& rrclass,
+ MasterLexer& lexer, const Name* origin,
+ MasterLoader::Options options,
+ MasterLoaderCallbacks& callbacks);
+
//@}
///
}
#endif // RDATA_H
-// Local Variables:
+// Local Variables:
// mode: c++
-// End:
+// End:
return (RdataPtr(new rdata::generic::Generic(
dynamic_cast<const generic::Generic&>(source))));
}
+
+RdataPtr
+RRParamRegistry::createRdata(const RRType& rrtype, const RRClass& rrclass,
+ MasterLexer& lexer, const Name* name,
+ MasterLoader::Options options,
+ MasterLoaderCallbacks& callbacks)
+{
+ RdataFactoryMap::const_iterator found =
+ impl_->rdata_factories.find(RRTypeClass(rrtype, rrclass));
+ if (found != impl_->rdata_factories.end()) {
+ return (found->second->create(lexer, name, options, callbacks));
+ }
+
+ GenericRdataFactoryMap::const_iterator genfound =
+ impl_->genericrdata_factories.find(rrtype);
+ if (genfound != impl_->genericrdata_factories.end()) {
+ return (genfound->second->create(lexer, name, options, callbacks));
+ }
+
+ return (RdataPtr(new generic::Generic(lexer, name, options, callbacks)));
+}
}
}
#include <exceptions/exceptions.h>
#include <dns/rdata.h>
-#include <dns/master_lexer.h>
-#include <dns/master_loader.h>
-#include <dns/master_loader_callbacks.h>
namespace isc {
namespace dns {
/// \c rdata::Rdata object.
rdata::RdataPtr createRdata(const RRType& rrtype, const RRClass& rrclass,
const rdata::Rdata& source);
+
+ /// \brief Create RDATA from MasterLexer
+ rdata::RdataPtr createRdata(const RRType& rrtype, const RRClass& rrclass,
+ MasterLexer& lexer, const Name* name,
+ MasterLoader::Options options,
+ MasterLoaderCallbacks& callbacks);
//@}
private:
}
#endif // RRPARAMREGISTRY_H
-// Local Variables:
+// Local Variables:
// mode: c++
-// End:
+// End:
InvalidRdataLength);
}
+TEST_F(Rdata_CNAME_Test, createFromLexer) {
+ EXPECT_EQ(0, rdata_cname.compare(
+ *test::createRdataUsingLexer(RRType::CNAME(), RRClass::IN(),
+ "cn.example.com")));
+}
+
TEST_F(Rdata_CNAME_Test, toWireBuffer) {
rdata_cname.toWire(obuffer);
EXPECT_PRED_FORMAT4(UnitTestUtil::matchWireData,
InvalidRdataLength);
}
+TEST_F(Rdata_DNAME_Test, createFromLexer) {
+ EXPECT_EQ(0, rdata_dname.compare(
+ *test::createRdataUsingLexer(RRType::DNAME(), RRClass::IN(),
+ "dn.example.com")));
+}
+
TEST_F(Rdata_DNAME_Test, toWireBuffer) {
rdata_dname.toWire(obuffer);
EXPECT_PRED_FORMAT4(UnitTestUtil::matchWireData,
DNSMessageFORMERR);
}
+TEST_F(Rdata_IN_A_Test, createFromLexer) {
+ EXPECT_EQ(0, rdata_in_a.compare(
+ *test::createRdataUsingLexer(RRType::A(), RRClass::IN(), "192.0.2.1")));
+}
+
TEST_F(Rdata_IN_A_Test, toWireBuffer) {
rdata_in_a.toWire(obuffer);
EXPECT_PRED_FORMAT4(UnitTestUtil::matchWireData,
DNSMessageFORMERR);
}
+TEST_F(Rdata_IN_AAAA_Test, createFromLexer) {
+ EXPECT_EQ(0, rdata_in_aaaa.compare(
+ *test::createRdataUsingLexer(RRType::AAAA(), RRClass::IN(),
+ "2001:db8::1234")));
+}
+
TEST_F(Rdata_IN_AAAA_Test, toWireBuffer) {
rdata_in_aaaa.toWire(obuffer);
EXPECT_PRED_FORMAT4(UnitTestUtil::matchWireData,
// TBD: more tests
}
+TEST_F(Rdata_MX_Test, createFromLexer) {
+ EXPECT_EQ(0, rdata_mx.compare(
+ *test::createRdataUsingLexer(RRType::MX(), RRClass::IN(),
+ "10 mx.example.com")));
+
+ EXPECT_THROW({
+ test::createRdataUsingLexer(RRType::MX(), RRClass::IN(),
+ "10 mx. example.com");
+ }, InvalidRdataText);
+}
+
TEST_F(Rdata_MX_Test, toWireRenderer) {
renderer.writeName(Name("example.com"));
rdata_mx.toWire(renderer);
InvalidRdataLength);
}
+TEST_F(Rdata_NS_Test, createFromLexer) {
+ EXPECT_EQ(0, rdata_ns.compare(
+ *test::createRdataUsingLexer(RRType::NS(), RRClass::IN(),
+ "ns.example.com")));
+
+ EXPECT_THROW({
+ test::createRdataUsingLexer(RRType::NS(), RRClass::IN(),
+ "");
+ }, IncompleteName);
+}
+
TEST_F(Rdata_NS_Test, toWireBuffer) {
rdata_ns.toWire(obuffer);
EXPECT_PRED_FORMAT4(UnitTestUtil::matchWireData,
EXPECT_EQ(0, rdata_sshfp4.compare(rdata_sshfp));
}
+TEST_F(Rdata_SSHFP_Test, createFromLexer) {
+ EXPECT_EQ(0, rdata_sshfp.compare(
+ *test::createRdataUsingLexer(RRType::SSHFP(), RRClass::IN(),
+ "2 1 123456789abcdef67890123456789abcdef67890")));
+}
+
TEST_F(Rdata_SSHFP_Test, algorithmTypes) {
// Some of these may not be RFC conformant, but we relax the check
// in our code to work with algorithm and fingerprint types that may
#include <dns/tests/unittest_util.h>
#include <dns/tests/rdata_unittest.h>
+#include <boost/bind.hpp>
+
using isc::UnitTestUtil;
using namespace std;
using namespace isc::dns;
uint16_t rdlen = buffer.readUint16();
return (createRdata(rrtype, rrclass, buffer, rdlen));
}
+
+namespace test {
+
+void dummyCallback(const string&, size_t, const string&) {
+}
+
+RdataPtr
+createRdataUsingLexer(const RRType& rrtype, const RRClass& rrclass,
+ const std::string& str)
+{
+ std::stringstream ss(str);
+ MasterLexer lexer;
+ lexer.pushSource(ss);
+
+ const MasterLoaderCallbacks::IssueCallback callback
+ (boost::bind(&dummyCallback, _1, _2, _3));
+ MasterLoaderCallbacks callbacks(callback, callback);
+ Name origin("example.org.");
+
+ return (createRdata(rrtype, rrclass, lexer, &origin,
+ MasterLoader::MANY_ERRORS, callbacks));
+}
+
+} // end of namespace isc::dns::rdata::test
+
}
}
}
/// used to test the compare() method against a well-known RR type.
RdataPtr rdata_nomatch;
};
+
+namespace test {
+RdataPtr
+createRdataUsingLexer(const RRType& rrtype, const RRClass& rrclass,
+ const std::string& str);
+}
+
}
}
}
#endif // RDATA_UNITTEST_H
-// Local Variables:
+// Local Variables:
// mode: c++
-// End:
+// End: