add growing buffer
authorDavid ‘Bombe’ Roden <bombe@pterodactylus.net>
Sat, 5 Jul 2008 04:40:33 +0000 (06:40 +0200)
committerDavid ‘Bombe’ Roden <bombe@pterodactylus.net>
Sat, 5 Jul 2008 04:40:33 +0000 (06:40 +0200)
GrowingBuffer.cpp [new file with mode: 0644]
GrowingBuffer.h [new file with mode: 0644]

diff --git a/GrowingBuffer.cpp b/GrowingBuffer.cpp
new file mode 100644 (file)
index 0000000..492f244
--- /dev/null
@@ -0,0 +1,79 @@
+/**
+ * © 2008 by David ‘Bombe’ Roden <bombe@pterodactylus.net>
+ */
+
+#include <stdlib.h>
+#include <string.h>
+#include "GrowingBuffer.h"
+
+GrowingBuffer::GrowingBuffer(size_t initialSize) {
+       this->data = malloc(1024);
+       this->size = 1024;
+       this->limit = 0;
+       this->position = 0;
+}
+
+GrowingBuffer::~GrowingBuffer() {
+       if (this->data) {
+               free(this->data);
+       }
+}
+
+size_t GrowingBuffer::getPosition() {
+       return position;
+}
+
+size_t GrowingBuffer::getLimit() {
+       return limit;
+}
+
+size_t GrowingBuffer::getSize() {
+       return size;
+}
+
+void GrowingBuffer::seek(size_t position) {
+       this->position = (position > limit) ? limit : position;
+}
+
+void* GrowingBuffer::read(void* buffer, size_t length) {
+       size_t bytesToCopy = (length > (limit - position)) ? (limit - position) : length;
+       memcpy(buffer, (char*) data + position, bytesToCopy);
+       position += bytesToCopy;
+       return buffer;
+}
+
+void GrowingBuffer::write(const void* buffer, size_t length) {
+       if (length > (size - position)) {
+               int newSize = size;
+               do {
+                       newSize *= 2;
+               } while (length > (newSize - position));
+               void* newData = malloc(newSize);
+               memcpy(newData, data, position);
+               free(data);
+               data = newData;
+       }
+       memcpy((char*) data + position, buffer, length);
+}
+
+void GrowingBuffer::truncate() {
+       limit = position;
+}
+
+void GrowingBuffer::clear() {
+       position = 0;
+       limit = 0;
+}
+
+void GrowingBuffer::resize(double factor) {
+       if (factor < 1.0) {
+               factor = 1.0;
+       }
+       if (size != (limit * factor)) {
+               void* newData = malloc((size_t) (limit * factor));
+               memcpy(newData, data, limit);
+               free(data);
+               data = newData;
+       }
+}
+
diff --git a/GrowingBuffer.h b/GrowingBuffer.h
new file mode 100644 (file)
index 0000000..894267d
--- /dev/null
@@ -0,0 +1,51 @@
+/**
+ * © 2008 by David ‘Bombe’ Roden <bombe@pterodactylus.net>
+ */
+
+#pragma once
+
+/**
+ * A buffer that will grow to accomodate the data being put into it.
+ */
+class GrowingBuffer {
+
+public:
+
+       /**
+        * Empty constructor. Creates a buffer with a default size of 1024 bytes.
+        *
+        * @param initialSize The initial size of the buffer in bytes
+        */
+       GrowingBuffer(size_t initialSize = 1024);
+
+       /**
+        * Destructor. Frees all used resources.
+        */
+       ~GrowingBuffer();
+
+       size_t getPosition();
+       size_t getLimit();
+       size_t getSize();
+
+       /**
+        * Sets the position of the buffer. The next {@link read(void*, size_t)} or
+        * {@link write(const void*, size_t)} operation will be applied at the new
+        * position.
+        *
+        * @param position The position to seek to
+        */
+       void seek(size_t position);
+       void* read(void* buffer, size_t length);
+       void write(const void* buffer, size_t length);
+       void truncate();
+       void clear();
+       void resize(double factor = 1.0);
+
+private:
+       void* data;
+       size_t size;
+       size_t limit;
+       size_t position;
+
+};
+