summaryrefslogtreecommitdiff
path: root/src/utils/buffer.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/utils/buffer.c')
-rw-r--r--src/utils/buffer.c156
1 files changed, 156 insertions, 0 deletions
diff --git a/src/utils/buffer.c b/src/utils/buffer.c
new file mode 100644
index 0000000..21c47fc
--- /dev/null
+++ b/src/utils/buffer.c
@@ -0,0 +1,156 @@
+/*
+ * This file is part of LibParserUtils.
+ * Licensed under the MIT License,
+ * http://www.opensource.org/licenses/mit-license.php
+ * Copyright 2008 John-Mark Bell <jmb@netsurf-browser.org>
+ */
+
+#include <string.h>
+
+#include <parserutils/utils/buffer.h>
+
+#define DEFAULT_SIZE (4096)
+
+/**
+ * Create a memory buffer
+ *
+ * \param alloc Memory (de)allocation function
+ * \param pw Pointer to client-specific private data
+ * \return Pointer to memory buffer, or NULL on memory exhaustion
+ */
+parserutils_buffer *parserutils_buffer_create(parserutils_alloc alloc, void *pw)
+{
+ parserutils_buffer *buffer =
+ alloc(NULL, sizeof(parserutils_buffer), pw);
+
+ if (buffer == NULL)
+ return NULL;
+
+ buffer->data = alloc(NULL, DEFAULT_SIZE, pw);
+ if (buffer->data == NULL) {
+ alloc(buffer, 0, pw);
+ return NULL;
+ }
+
+ buffer->length = 0;
+ buffer->allocated = DEFAULT_SIZE;
+
+ buffer->alloc = alloc;
+ buffer->pw = pw;
+
+ return buffer;
+}
+
+/**
+ * Destroy a memory buffer
+ *
+ * \param buffer The buffer to destroy
+ */
+void parserutils_buffer_destroy(parserutils_buffer *buffer)
+{
+ if (buffer == NULL)
+ return;
+
+ buffer->alloc(buffer->data, 0, buffer->pw);
+ buffer->alloc(buffer, 0, buffer->pw);
+}
+
+/**
+ * Append data to a memory buffer
+ *
+ * \param buffer The buffer to append to
+ * \param data The data to append
+ * \param len The length, in bytes, of the data to append
+ * \return PARSERUTILS_OK on success, appropriate error otherwise.
+ */
+parserutils_error parserutils_buffer_append(parserutils_buffer *buffer,
+ const uint8_t *data, size_t len)
+{
+ while (len >= buffer->allocated - buffer->length) {
+ parserutils_error error = parserutils_buffer_grow(buffer);
+ if (error != PARSERUTILS_OK)
+ return error;
+ }
+
+ memcpy(buffer->data + buffer->length, data, len);
+
+ buffer->length += len;
+
+ return PARSERUTILS_OK;
+}
+
+/**
+ * Insert data into a memory buffer
+ *
+ * \param buffer The buffer to insert into
+ * \param offset The offset into the buffer to insert at
+ * \param data The data to insert
+ * \param len The length, in bytes, of the data to insert
+ * \return PARSERUTILS_OK on success, appropriate error otherwise
+ */
+parserutils_error parserutils_buffer_insert(parserutils_buffer *buffer,
+ size_t offset, const uint8_t *data, size_t len)
+{
+ if (offset > buffer->length)
+ return PARSERUTILS_BADPARM;
+
+ if (offset == buffer->length)
+ return parserutils_buffer_append(buffer, data, len);
+
+ while (len >= buffer->allocated - buffer->length) {
+ parserutils_error error = parserutils_buffer_grow(buffer);
+ if (error != PARSERUTILS_OK)
+ return error;
+ }
+
+ memmove(buffer->data + buffer->length + len,
+ buffer->data + offset, buffer->length - offset);
+
+ memcpy(buffer->data + offset, data, len);
+
+ buffer->length += len;
+
+ return PARSERUTILS_OK;
+}
+
+/**
+ * Discard a section of a memory buffer
+ *
+ * \param buffer The buffer to discard data from
+ * \param offset The offset into the buffer of the start of the section
+ * \param len The number of bytes to discard
+ * \return PARSERUTILS_OK on success, appropriate error otherwise.
+ */
+parserutils_error parserutils_buffer_discard(parserutils_buffer *buffer,
+ size_t offset, size_t len)
+{
+ if (offset >= buffer->length || offset + len > buffer->length)
+ return PARSERUTILS_BADPARM;
+
+ memmove(buffer->data + offset, buffer->data + offset + len,
+ buffer->length - len);
+
+ buffer->length -= len;
+
+ return PARSERUTILS_OK;
+}
+
+/**
+ * Extend the amount of space allocated for a memory buffer
+ *
+ * \param buffer The buffer to extend
+ * \return PARSERUTILS_OK on success, appropriate error otherwise.
+ */
+parserutils_error parserutils_buffer_grow(parserutils_buffer *buffer)
+{
+ uint8_t *temp = buffer->alloc(buffer->data,
+ buffer->allocated * 2, buffer->pw);
+ if (temp == NULL)
+ return PARSERUTILS_NOMEM;
+
+ buffer->data = temp;
+ buffer->allocated *= 2;
+
+ return PARSERUTILS_OK;
+}
+