Parcourir la source

[trac536] Allocation and dealocation routines

The rest of class is still not updated, it doesn't compile yet.
Michal 'vorner' Vaner il y a 14 ans
Parent
commit
8599f0c0c2
1 fichiers modifiés avec 67 ajouts et 3 suppressions
  1. 67 3
      src/lib/dns/buffer.h

+ 67 - 3
src/lib/dns/buffer.h

@@ -15,6 +15,8 @@
 #ifndef __BUFFER_H
 #define __BUFFER_H 1
 
+#include <cstdlib>
+#include <cstring>
 #include <vector>
 
 #include <string.h>
@@ -286,9 +288,51 @@ public:
     /// \brief Constructor from the initial size of the buffer.
     ///
     /// \param len The initial length of the buffer in bytes.
-    OutputBuffer(size_t len) { data_.reserve(len); }
+    OutputBuffer(size_t len) :
+        buffer_(NULL),
+        size_(0),
+        allocated_(len)
+    {
+        // We use malloc and free instead of C++ new[] and delete[].
+        // This way we can use realloc, which may in fact do it without a copy.
+        buffer_ = static_cast<uint8_t*>(malloc(allocated_));
+        if (buffer_ == NULL) {
+            throw std::bad_alloc();
+        }
+    }
+
+    /// \brief Copy constructor
+    OutputBuffer(const OutputBuffer& other) :
+        buffer_(NULL),
+        size_(other.size_),
+        allocated_(other.allocated_)
+    {
+        buffer_ = static_cast<uint8_t*>(malloc(allocated_));
+        if (buffer_ == NULL) {
+            throw std::bad_alloc();
+        }
+        memcpy(buffer_, other.buffer_, size_);
+    }
+
+    ~ OutputBuffer() {
+        free(buffer_);
+    }
     //@}
 
+    /// \brief Assignment operator
+    OutputBuffer& operator =(const OutputBuffer& other) {
+        uint8_t* newbuff(static_cast<uint8_t*>(malloc(other.allocated_)));
+        if (newbuff == NULL) {
+            throw std::bad_alloc();
+        }
+        free(buffer_);
+        buffer_ = newbuff;
+        size_ = other.size_;
+        allocated_ = other.allocated_;
+        memcpy(buffer_, other.buffer_, size_);
+        return (*this);
+    }
+
     ///
     /// \name Getter Methods
     ///
@@ -408,9 +452,29 @@ public:
         data_.insert(data_.end(), cp, cp + len);
     }
     //@}
-    
+
 private:
-    std::vector<uint8_t> data_;
+    uint8_t* buffer_;
+    size_t size_;
+    size_t allocated_;
+    void ensureAllocated(size_t needed_size) {
+        if (allocated_ < needed_size) {
+            // Guess some bigger size
+            size_t new_size = (allocated_ == 0) ? 1024 : allocated_;
+            while (new_size < needed_size) {
+                new_size *= 2;
+            }
+            // Allocate bigger space
+            uint8_t* new_buffer_(static_cast<uint8_t*>(realloc(buffer_,
+                new_size)));
+            if (new_buffer_ == NULL) {
+                // If it fails, the original block is left intact by it
+                throw std::bad_alloc();
+            }
+            buffer_ = new_buffer_;
+            allocated_ = new_size;
+        }
+    }
 };
 
 /// \brief Pointer-like types pointing to \c InputBuffer or \c OutputBuffer