changeset 1454:fff3b58d031c

Add a growable buffer implementation.
author Matti Hamalainen <ccr@tnsp.org>
date Thu, 10 May 2018 18:33:57 +0300
parents 73a4158b2e55
children a957b318fbe2
files Makefile.gen src/dmgrowbuf.c src/dmgrowbuf.h
diffstat 3 files changed, 204 insertions(+), 1 deletions(-) [+]
line wrap: on
line diff
--- a/Makefile.gen	Thu May 10 18:32:27 2018 +0300
+++ b/Makefile.gen	Thu May 10 18:33:57 2018 +0300
@@ -300,7 +300,7 @@
 DMLIB_A=$(OBJPATH)dmlib.a
 DMLIB_OBJS += \
 	dmfile.o dmlib.o dmcurves.o dmstring.o \
-	dmargs.o dmvecmat.o dmperlin.o dmimage.o \
+	dmgrowbuf.o dmargs.o dmvecmat.o dmperlin.o dmimage.o \
 	dmwav.o dmengine.o dmfft.o dmzlib.o
 
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/dmgrowbuf.c	Thu May 10 18:33:57 2018 +0300
@@ -0,0 +1,160 @@
+/*
+ * DMLib
+ * -- Growable buffer implementation
+ * Programmed and designed by Matti 'ccr' Hamalainen
+ * (C) Copyright 2018 Tecnic Software productions (TNSP)
+ */
+#include "dmgrowbuf.h"
+
+
+int dmGrowBufInit(DMGrowBuf *buf, const size_t initial, const size_t mingrow)
+{
+    if (buf == NULL)
+        return DMERR_NULLPTR;
+
+    buf->len  = 0;
+    buf->size = initial;
+    buf->mingrow = mingrow;
+    buf->allocated = FALSE;
+
+    if ((buf->data = dmMalloc(initial)) == NULL)
+        return DMERR_MALLOC;
+
+    return DMERR_OK;
+}
+
+
+int dmGrowBufAlloc(DMGrowBuf **pbuf, const size_t initial, const size_t mingrow)
+{
+    int res;
+
+    if ((*pbuf = dmMalloc0(sizeof(DMGrowBuf))) == NULL)
+        return DMERR_MALLOC;
+
+    if ((res = dmGrowBufInit(*pbuf, initial, mingrow)) != DMERR_OK)
+    {
+        dmGrowBufFree(*pbuf);
+        return res;
+    }
+
+    (*pbuf)->allocated = TRUE;
+    return res;
+}
+
+
+void dmGrowBufFree(DMGrowBuf *buf)
+{
+    if (buf != NULL)
+    {
+        dmFreeR(&buf->data);
+        if (buf->allocated)
+            dmFree(buf);
+    }
+}
+
+
+BOOL dmGrowBufGrow(DMGrowBuf *buf, const size_t amount)
+{
+    if (buf->data == NULL || buf->len + amount > buf->size)
+    {
+        buf->size += amount + (buf->mingrow > 0 ? buf->mingrow : 1024);
+        if ((buf->data = dmRealloc(buf->data, buf->size)) == NULL)
+            return FALSE;
+    }
+
+    return TRUE;
+}
+
+
+int dmGrowBufResize(DMGrowBuf *buf)
+{
+    if (buf == NULL)
+        return DMERR_NULLPTR;
+
+    buf->size = buf->len;
+    if (buf->len == 0)
+        return DMERR_OK;
+
+    if ((buf->data = dmRealloc(buf->data, buf->len)) == NULL)
+        return DMERR_MALLOC;
+
+    return DMERR_OK;
+}
+
+
+BOOL dmGrowBufPutU8(DMGrowBuf *buf, const Uint8 value)
+{
+    if (!dmGrowBufGrow(buf, sizeof(Uint8)))
+        return FALSE;
+
+    buf->data[buf->len++] = value;
+
+    return TRUE;
+}
+
+
+BOOL dmGrowBufPutStr(DMGrowBuf *buf, const void *str, const size_t len)
+{
+    if (str == NULL)
+        return FALSE;
+
+    if (!dmGrowBufGrow(buf, len + 1))
+        return FALSE;
+
+    memcpy(buf->data + buf->len, str, len + 1);
+    buf->len += len;
+
+    return TRUE;
+}
+
+
+BOOL dmGrowBufPutU16BE(DMGrowBuf *buf, const Uint16 val)
+{
+    if (!dmGrowBufGrow(buf, sizeof(Uint16)))
+        return FALSE;
+
+    buf->data[buf->len++] = (val >> 8) & 0xff;
+    buf->data[buf->len++] = val & 0xff;
+
+    return TRUE;
+}
+
+
+BOOL dmGrowBufPutU16LE(DMGrowBuf *buf, const Uint16 val)
+{
+    if (!dmGrowBufGrow(buf, sizeof(Uint16)))
+        return FALSE;
+
+    buf->data[buf->len++] = val & 0xff;
+    buf->data[buf->len++] = (val >> 8) & 0xff;
+
+    return TRUE;
+}
+
+
+BOOL dmGrowBufPutU32BE(DMGrowBuf *buf, const Uint32 val)
+{
+    if (!dmGrowBufGrow(buf, sizeof(Uint32)))
+        return FALSE;
+
+    buf->data[buf->len++] = (val >> 24) & 0xff;
+    buf->data[buf->len++] = (val >> 16) & 0xff;
+    buf->data[buf->len++] = (val >> 8) & 0xff;
+    buf->data[buf->len++] = val & 0xff;
+
+    return TRUE;
+}
+
+
+BOOL dmGrowBufPutU32LE(DMGrowBuf *buf, const Uint32 val)
+{
+    if (!dmGrowBufGrow(buf, sizeof(Uint32)))
+        return FALSE;
+
+    buf->data[buf->len++] = val & 0xff;
+    buf->data[buf->len++] = (val >> 8) & 0xff;
+    buf->data[buf->len++] = (val >> 16) & 0xff;
+    buf->data[buf->len++] = (val >> 24) & 0xff;
+
+    return TRUE;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/dmgrowbuf.h	Thu May 10 18:33:57 2018 +0300
@@ -0,0 +1,43 @@
+/*
+ * DMLib
+ * -- Growable buffer implementation
+ * Programmed and designed by Matti 'ccr' Hamalainen
+ * (C) Copyright 2018 Tecnic Software productions (TNSP)
+ */
+#ifndef DMGROWBUF_H
+#define DMGROWBUF_H
+
+#include "dmlib.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct
+{
+    Uint8 *data;
+    size_t len, size, mingrow;
+    BOOL allocated;
+} DMGrowBuf;
+
+
+int    dmGrowBufInit(DMGrowBuf *buf, const size_t initial, const size_t mingrow);
+int    dmGrowBufAlloc(DMGrowBuf **pbuf, const size_t initial, const size_t mingrow);
+void   dmGrowBufFree(DMGrowBuf *buf);
+BOOL   dmGrowBufGrow(DMGrowBuf *buf, const size_t amount);
+int    dmGrowBufResize(DMGrowBuf *buf);
+
+BOOL   dmGrowBufPutU8(DMGrowBuf *buf, const Uint8 value);
+BOOL   dmGrowBufPutStrU8(DMGrowBuf *buf, const void *str, const size_t len);
+
+BOOL   dmGrowBufPutU16BE(DMGrowBuf *buf, const Uint16 val);
+BOOL   dmGrowBufPutU16LE(DMGrowBuf *buf, const Uint16 val);
+BOOL   dmGrowBufPutU32BE(DMGrowBuf *buf, const Uint32 val);
+BOOL   dmGrowBufPutU32LE(DMGrowBuf *buf, const Uint32 val);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // DMGROWBUF_H