--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/project_files/frontlib/util/buffer.c Sat Jun 09 03:28:38 2012 +0200
@@ -0,0 +1,90 @@
+#include "buffer.h"
+#include "logging.h"
+
+#include <stdlib.h>
+#include <limits.h>
+#include <string.h>
+
+typedef struct _flib_vector {
+ void *data;
+ size_t size;
+ size_t capacity;
+} _flib_vector;
+
+flib_vector flib_vector_create() {
+ flib_vector result = malloc(sizeof(_flib_vector));
+ if(result == NULL) {
+ return NULL;
+ }
+ result->data = malloc(16);
+ if(result->data == NULL) {
+ free(result);
+ return NULL;
+ }
+ result->size = 0;
+ result->capacity = 16;
+ return result;
+}
+
+void flib_vector_destroy(flib_vector *vec) {
+ if(vec && *vec) {
+ free((*vec)->data);
+ free(*vec);
+ *vec = NULL;
+ }
+}
+
+static void try_realloc(flib_vector vec, size_t newCapacity) {
+ void *newData = realloc(vec->data, newCapacity);
+ if(newData) {
+ vec->data = newData;
+ vec->capacity = newCapacity;
+ }
+}
+
+static size_t getFreeCapacity(flib_vector vec) {
+ return vec->capacity - vec->size;
+}
+
+int flib_vector_append(flib_vector vec, const void *data, size_t len) {
+ if(getFreeCapacity(vec) < len) {
+ // Resize exponentially for constant amortized time,
+ // But at least by as much as we need of course,
+ // and be extra careful with integer overflows...
+ size_t extraCapacity = (vec->capacity)/2;
+
+ size_t minExtraCapacity = len - getFreeCapacity(vec);
+ if(extraCapacity < minExtraCapacity) {
+ extraCapacity = minExtraCapacity;
+ }
+
+ if(extraCapacity <= SIZE_MAX - vec->capacity) {
+ try_realloc(vec, vec->capacity+extraCapacity);
+ }
+
+ // Check if we were able to resize.
+ // If not, try to allocate at least what we need...
+ if(getFreeCapacity(vec) < len) {
+ try_realloc(vec, vec->capacity+minExtraCapacity);
+
+ // Still not working? Then we fail.
+ if(getFreeCapacity(vec) < len) {
+ return 0;
+ }
+ }
+ }
+
+ memmove(vec->data + vec->size, data, len);
+ vec->size += len;
+ return len;
+}
+
+flib_buffer flib_vector_as_buffer(flib_vector vec) {
+ flib_buffer result = {vec->data, vec->size};
+ return result;
+}
+
+flib_constbuffer flib_vector_as_constbuffer(flib_vector vec) {
+ flib_constbuffer result = {vec->data, vec->size};
+ return result;
+}