Browse Source

[1697] added AbstractMessageRenderer::setBuffer method

JINMEI Tatuya 13 years ago
parent
commit
a9d3e3d624

+ 3 - 2
src/lib/asiodns/io_fetch.cc

@@ -205,7 +205,8 @@ IOFetch::IOFetch(Protocol protocol, IOService& service,
 }
 
 void
-IOFetch::initIOFetch(MessagePtr& query_msg, Protocol protocol, IOService& service,
+IOFetch::initIOFetch(MessagePtr& query_msg, Protocol protocol,
+                     IOService& service,
                      const isc::dns::Question& question,
                      const IOAddress& address, uint16_t port,
                      OutputBufferPtr& buff, Callback* cb, int wait, bool edns)
@@ -225,7 +226,7 @@ IOFetch::initIOFetch(MessagePtr& query_msg, Protocol protocol, IOService& servic
         query_msg->setEDNS(edns_query);
     }
 
-    MessageRenderer renderer(*data_->msgbuf);
+    MessageRenderer renderer; // XXX this doesn't work need to set data_->msgbuf;
     query_msg->toWire(renderer);
 }
 

+ 4 - 5
src/lib/bench/benchmark_util.cc

@@ -61,8 +61,7 @@ loadQueryData(istream& input, BenchQueries& queries, const RRClass& qclass,
     string line;
     unsigned int linenum = 0;
     Message query_message(Message::RENDER);
-    OutputBuffer buffer(128); // this should be sufficiently large
-    MessageRenderer renderer(buffer);
+    MessageRenderer renderer;
     while (getline(input, line), !input.eof()) {
         ++linenum;
         if (input.bad() || input.fail()) {
@@ -99,9 +98,9 @@ loadQueryData(istream& input, BenchQueries& queries, const RRClass& qclass,
             renderer.clear();
             query_message.toWire(renderer);
             vector<unsigned char> query_data(
-                static_cast<const unsigned char*>(buffer.getData()),
-                static_cast<const unsigned char*>(buffer.getData()) +
-                buffer.getLength());
+                static_cast<const unsigned char*>(renderer.getData()),
+                static_cast<const unsigned char*>(renderer.getData()) +
+                renderer.getLength());
             queries.push_back(query_data);
         } catch (const Exception&) {
             if (strict) {

+ 23 - 4
src/lib/dns/messagerenderer.cc

@@ -12,14 +12,15 @@
 // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 // PERFORMANCE OF THIS SOFTWARE.
 
-#include <cctype>
-#include <cassert>
-#include <set>
-
+#include <exceptions/exceptions.h>
 #include <util/buffer.h>
 #include <dns/name.h>
 #include <dns/messagerenderer.h>
 
+#include <cctype>
+#include <cassert>
+#include <set>
+
 using namespace isc::util;
 
 namespace isc {
@@ -279,6 +280,24 @@ AbstractMessageRenderer::AbstractMessageRenderer() :
 }
 
 void
+AbstractMessageRenderer::setBuffer(OutputBuffer* buffer) {
+    if (buffer != NULL && buffer_->getLength() != 0) {
+        isc_throw(isc::InvalidParameter,
+                  "MessageRenderer buffer cannot be set when in use");
+    } if (buffer == NULL && buffer_ == &local_buffer_) {
+        isc_throw(isc::InvalidParameter,
+                  "Default MessageRenderer buffer cannot be reset");
+    }
+
+    if (buffer == NULL) {
+        clear();
+        buffer_ = &local_buffer_;
+    } else {
+        buffer_ = buffer;
+    }
+}
+
+void
 AbstractMessageRenderer::clear() {
     buffer_->clear();
 }

+ 3 - 0
src/lib/dns/messagerenderer.h

@@ -178,6 +178,9 @@ public:
     /// \name Setter Methods
     ///
     //@{
+    /// TBD
+    void setBuffer(isc::util::OutputBuffer* buffer);
+
     /// \brief Mark the renderer to indicate truncation has occurred while
     /// rendering.
     ///

+ 44 - 2
src/lib/dns/tests/messagerenderer_unittest.cc

@@ -12,8 +12,7 @@
 // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 // PERFORMANCE OF THIS SOFTWARE.
 
-#include <vector>
-
+#include <exceptions/exceptions.h>
 #include <util/buffer.h>
 #include <dns/name.h>
 #include <dns/messagerenderer.h>
@@ -22,6 +21,8 @@
 
 #include <gtest/gtest.h>
 
+#include <vector>
+
 using isc::UnitTestUtil;
 using isc::dns::Name;
 using isc::dns::MessageRenderer;
@@ -168,4 +169,45 @@ TEST_F(MessageRendererTest, writeRootName) {
                         static_cast<const uint8_t*>(expected.getData()),
                         expected.getLength());
 }
+
+TEST_F(MessageRendererTest, setBuffer) {
+    OutputBuffer new_buffer(0);
+    renderer.setBuffer(&new_buffer);
+    EXPECT_EQ(0, new_buffer.getLength()); // the buffer should be still empty
+    renderer.writeUint32(42);
+    EXPECT_EQ(sizeof(uint32_t), new_buffer.getLength());
+    EXPECT_EQ(sizeof(uint32_t), renderer.getLength());
+
+    // Change some other internal state for the reset test below.
+    EXPECT_EQ(512, renderer.getLengthLimit());
+    renderer.setLengthLimit(4096);
+    EXPECT_EQ(4096, renderer.getLengthLimit());
+
+    // Reset the buffer to the default again.  Other internal states and
+    // resources should be cleared.
+    renderer.setBuffer(NULL);
+    EXPECT_EQ(0, renderer.getLength());
+    EXPECT_EQ(512, renderer.getLengthLimit());
+}
+
+TEST_F(MessageRendererTest, setBufferErrors) {
+    OutputBuffer new_buffer(0);
+
+    // Buffer cannot be rest when the renderer is in use.
+    renderer.writeUint32(10);
+    EXPECT_THROW(renderer.setBuffer(&new_buffer), isc::InvalidParameter);
+
+    renderer.clear();
+    renderer.setBuffer(&new_buffer);
+    renderer.writeUint32(10);
+    EXPECT_THROW(renderer.setBuffer(&new_buffer), isc::InvalidParameter);
+
+    // Resetting the buffer isn't allowed for the default buffer.
+    renderer.setBuffer(NULL);
+    EXPECT_THROW(renderer.setBuffer(NULL), isc::InvalidParameter);
+
+    // It's okay to reset a temporary buffer without using it.
+    renderer.setBuffer(&new_buffer);
+    EXPECT_NO_THROW(renderer.setBuffer(NULL));
+}
 }