[svn] commit: r524 - in /branches/jinmei-dnsrdata/src/lib/dns/cpp: messagerenderer.cc messagerenderer.h rdata.cc rdata.h rdata_unittest.cc rrparamregistry.cc testdata/rdata_txt_fromWire

BIND 10 source code commits bind10-changes at lists.isc.org
Tue Jan 26 20:49:10 UTC 2010


Author: jinmei
Date: Tue Jan 26 20:49:10 2010
New Revision: 524

Log:
added quick implementation of TXT RDATA

Added:
    branches/jinmei-dnsrdata/src/lib/dns/cpp/testdata/rdata_txt_fromWire
Modified:
    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/rdata.cc
    branches/jinmei-dnsrdata/src/lib/dns/cpp/rdata.h
    branches/jinmei-dnsrdata/src/lib/dns/cpp/rdata_unittest.cc
    branches/jinmei-dnsrdata/src/lib/dns/cpp/rrparamregistry.cc

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 Tue Jan 26 20:49:10 2010
@@ -163,6 +163,12 @@
 }
 
 void
+MessageRenderer::writeUint8(uint8_t data)
+{
+    impl_->buffer_.writeUint8(data);
+}
+
+void
 MessageRenderer::writeUint16(uint16_t data)
 {
     impl_->buffer_.writeUint16(data);

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 Tue Jan 26 20:49:10 2010
@@ -113,6 +113,10 @@
     ///
     /// \param len The length of the gap to be inserted in bytes.
     void skip(size_t len);
+    /// \brief Write an unsigned 8-bit integer into the internal buffer.
+    ///
+    /// \param data The 8-bit integer to be written into the internal buffer.
+    void writeUint8(uint8_t data);
     /// \brief Write an unsigned 16-bit integer in host byte order into the
     /// internal buffer in network byte order.
     ///

Modified: branches/jinmei-dnsrdata/src/lib/dns/cpp/rdata.cc
==============================================================================
--- branches/jinmei-dnsrdata/src/lib/dns/cpp/rdata.cc (original)
+++ branches/jinmei-dnsrdata/src/lib/dns/cpp/rdata.cc Tue Jan 26 20:49:10 2010
@@ -130,16 +130,16 @@
 {
     const Generic& other_rdata = dynamic_cast<const Generic&>(other);
 
-    size_t len_this = data_.size();
-    size_t len_other = other_rdata.data_.size();
-    size_t len = (len_this < len_other) ? len_this : len_other;
+    size_t this_len = data_.size();
+    size_t other_len = other_rdata.data_.size();
+    size_t len = (this_len < other_len) ? this_len : other_len;
     int cmp;
 
     if ((cmp = memcmp(&data_[0], &other_rdata.data_[0], len)) != 0) {
         return (cmp);
     } else {
-        return ((len_this == len_other) ? 0 :
-                (len_this < len_other) ? -1 : 1);
+        return ((this_len == other_len) ? 0 :
+                (this_len < other_len) ? -1 : 1);
     }
 }
 
@@ -273,7 +273,7 @@
     // check consistency.
 }
 
-MX::MX(const std::string& soastr) :
+MX::MX(const std::string& mxstr) :
     preference_(0), mxname_(".")
 {
     dns_throw(InvalidRdataText, "Not implemented yet");
@@ -321,6 +321,111 @@
     return (compareNames(mxname_, other_mx.mxname_));
 }
 
+TXT::TXT(InputBuffer& buffer, size_t rdata_len)
+{
+    uint8_t len;
+
+    // TBD: this is a simple, incomplete implementation that only supports
+    // a single character-string.
+    len = buffer.readUint8();
+    vector<uint8_t> data(len + 1);
+    data[0] = len;
+    buffer.readData(&data[0] + 1, len);
+    string_list_.push_back(data);
+}
+
+TXT::TXT(const std::string& txtstr)
+{
+    size_t length = txtstr.size();
+    size_t pos_begin = 0;
+
+    if (length > 1 && txtstr[0] == '"' && txtstr[length - 1] == '"') {
+        pos_begin = 1;
+        length -= 2;
+    }
+    if (length > MAX_CHARSTRING_LEN) {
+        dns_throw(CharStringTooLong, "");
+    }
+
+    vector<uint8_t> data;
+    data.reserve(length + 1);
+    data.push_back(length);
+    data.insert(data.end(), txtstr.begin() + pos_begin,
+                txtstr.begin() + pos_begin + length);
+    string_list_.push_back(data);
+}
+
+TXT::TXT(const TXT& other) :
+    string_list_(other.string_list_)
+{}
+
+void
+TXT::toWire(OutputBuffer& buffer) const
+{
+    for (vector<vector<uint8_t> >::const_iterator it = string_list_.begin();
+         it != string_list_.end();
+         ++it)
+    {
+        buffer.writeData(&(*it)[0], (*it).size());
+    }
+}
+
+void
+TXT::toWire(MessageRenderer& renderer) const
+{
+    for (vector<vector<uint8_t> >::const_iterator it = string_list_.begin();
+         it != string_list_.end();
+         ++it)
+    {
+        renderer.writeData(&(*it)[0], (*it).size());
+    }
+}
+
+string
+TXT::toText() const
+{
+    string s;
+
+    // XXX: this implementation is not entirely correct.  for example, it
+    // should escape double-quotes if they appear in the character string.
+    for (vector<vector<uint8_t> >::const_iterator it = string_list_.begin();
+         it != string_list_.end();
+         ++it)
+    {
+        if (!s.empty()) {
+            s.push_back(' ');
+        }
+        s.push_back('"');
+        s.insert(s.end(), (*it).begin() + 1, (*it).end());
+        s.push_back('"');
+    }
+
+    return (s);
+}
+
+int
+TXT::compare(const Rdata& other) const
+{
+    const TXT& other_txt = dynamic_cast<const TXT&>(other);
+
+    // This implementation is not efficient.  Revisit this (TBD).
+    OutputBuffer this_buffer(0);
+    toWire(this_buffer);
+    size_t this_len = this_buffer.getLength();
+
+    OutputBuffer other_buffer(0);
+    other_txt.toWire(other_buffer);
+    size_t other_len = other_buffer.getLength();
+
+    size_t cmplen = min(this_len, other_len);
+    int cmp = memcmp(this_buffer.getData(), other_buffer.getData(), cmplen);
+    if (cmp != 0) {
+        return (cmp);
+    } else {
+        return ((this_len == other_len) ? 0 :
+                (this_len < other_len) ? -1 : 1);
+    }
+}
 } // end of namespace generic
 
 namespace in {

Modified: branches/jinmei-dnsrdata/src/lib/dns/cpp/rdata.h
==============================================================================
--- branches/jinmei-dnsrdata/src/lib/dns/cpp/rdata.h (original)
+++ branches/jinmei-dnsrdata/src/lib/dns/cpp/rdata.h Tue Jan 26 20:49:10 2010
@@ -54,6 +54,15 @@
         isc::dns::Exception(file, line, what) {}
 };
 
+///
+/// \brief A standard DNS module exception that is thrown if ...TBD
+///
+class CharStringTooLong : public Exception {
+public:
+    CharStringTooLong(const char* file, size_t line, const char* what) :
+        isc::dns::Exception(file, line, what) {}
+};
+
 class Rdata;
 typedef boost::shared_ptr<Rdata> RdataPtr;
 
@@ -142,7 +151,7 @@
 
 class SOA : public Rdata {
 public:
-    explicit SOA(const std::string& namestr);
+    explicit SOA(const std::string& soastr);
     explicit SOA(InputBuffer& buffer, size_t rdata_len);
     explicit SOA(const Name& mname, const Name& rname, uint32_t serial,
                  uint32_t refresh, uint32_t retry, uint32_t expire,
@@ -164,7 +173,7 @@
 
 class MX : public Rdata {
 public:
-    explicit MX(const std::string& namestr);
+    explicit MX(const std::string& mxstr);
     explicit MX(InputBuffer& buffer, size_t rdata_len);
     explicit MX(uint16_t preference, const Name& mxname);
     MX(const MX& other);
@@ -177,6 +186,22 @@
     /// this representation later.
     uint16_t preference_;
     Name mxname_;
+};
+
+class TXT : public Rdata {
+public:
+    explicit TXT(const std::string& txtstr);
+    explicit TXT(InputBuffer& buffer, size_t rdata_len);
+    TXT(const TXT& other);
+    virtual std::string toText() const;
+    virtual void toWire(OutputBuffer& buffer) const;
+    virtual void toWire(MessageRenderer& buffer) const;
+    virtual int compare(const Rdata& other) const;
+private:
+    /// Note: this is a prototype version; we may reconsider
+    /// this representation later.
+    static const unsigned int MAX_CHARSTRING_LEN = 255;
+    std::vector<std::vector<uint8_t> > string_list_;
 };
 } // end of namespace "generic"
 

Modified: branches/jinmei-dnsrdata/src/lib/dns/cpp/rdata_unittest.cc
==============================================================================
--- branches/jinmei-dnsrdata/src/lib/dns/cpp/rdata_unittest.cc (original)
+++ branches/jinmei-dnsrdata/src/lib/dns/cpp/rdata_unittest.cc Tue Jan 26 20:49:10 2010
@@ -47,10 +47,13 @@
     static const uint8_t wiredata_in_aaaa[];
     static const uint8_t wiredata_ns[];
     static const uint8_t wiredata_ns2[];
+    static const uint8_t wiredata_txt[];
     static const generic::NS rdata_ns;
     static const generic::NS rdata_ns2;
     static const generic::SOA rdata_soa;
     static const generic::MX rdata_mx;
+    static const generic::TXT rdata_txt;
+    static const generic::TXT rdata_txt_quoated;
 };
 
 const in::A RdataTest::rdata_in_a("192.0.2.1");
@@ -61,6 +64,8 @@
                                         Name("root.example.com"),
                                         2010012601, 3600, 300, 3600000, 1200);
 const generic::MX RdataTest::rdata_mx(10, Name("mx.example.com"));
+const generic::TXT RdataTest::rdata_txt("Test String");
+const generic::TXT RdataTest::rdata_txt_quoated("\"Test String\"");
 
 const uint8_t RdataTest::wiredata_in_a[] = { 192, 0, 2, 1 };
 const uint8_t RdataTest::wiredata_in_aaaa[] = {
@@ -76,6 +81,10 @@
     // second name: ns2.example.com.  all labels except the first should be
     // compressed.
     0x03, 0x6e, 0x73, 0x32, 0xc0, 0x03 };
+const uint8_t RdataTest::wiredata_txt[] = {
+    sizeof("Test String") - 1,
+    'T', 'e', 's', 't', ' ', 'S', 't', 'r', 'i', 'n', 'g'
+};
 
 RdataPtr
 RdataTest::rdataFactoryFromFile(const RRType& rrtype, const RRClass& rrclass,
@@ -377,4 +386,29 @@
     EXPECT_THROW(rdata_mx.compare(rdata_ns), bad_cast); 
 }
 
-}
+TEST_F(RdataTest, createFromText_TXT)
+{
+    EXPECT_EQ(0, rdata_txt.compare(rdata_txt_quoated));
+}
+
+TEST_F(RdataTest, createFromWire_TXT)
+{
+    EXPECT_EQ(0, rdata_txt.compare(
+                  *rdataFactoryFromFile(RRType("TXT"), RRClass("IN"),
+                                        "testdata/rdata_txt_fromWire")));
+}
+
+TEST_F(RdataTest, toWireBuffer_TXT)
+{
+    rdata_txt.toWire(obuffer);
+    EXPECT_PRED_FORMAT4(UnitTestUtil::matchWireData,
+                        obuffer.getData(), obuffer.getLength(),
+                        wiredata_txt, sizeof(wiredata_txt));
+}
+
+TEST_F(RdataTest, toText_TXT)
+{
+    EXPECT_EQ("\"Test String\"", rdata_txt.toText());
+}
+
+}

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 Tue Jan 26 20:49:10 2010
@@ -190,6 +190,10 @@
             RdataFactoryPtr(new RdataFactory<generic::MX>()));
         add("MX", 15, "CH", 3,
             RdataFactoryPtr(new RdataFactory<generic::MX>()));
+        add("TXT", 16, "IN", 1,
+            RdataFactoryPtr(new RdataFactory<generic::TXT>()));
+        add("TXT", 16, "CH", 3,
+            RdataFactoryPtr(new RdataFactory<generic::TXT>()));
     } catch (...) {
         delete impl_;
         throw;




More information about the bind10-changes mailing list