changeset 1531:260bf529a8f2

Implement current len/offs push/pop for growbuf.
author Matti Hamalainen <ccr@tnsp.org>
date Sat, 12 May 2018 03:23:32 +0300
parents 94eb6a8a7d56
children 74febc66d90d
files src/dmgrowbuf.c src/dmgrowbuf.h
diffstat 2 files changed, 44 insertions(+), 7 deletions(-) [+]
line wrap: on
line diff
--- a/src/dmgrowbuf.c	Sat May 12 03:10:47 2018 +0300
+++ b/src/dmgrowbuf.c	Sat May 12 03:23:32 2018 +0300
@@ -26,12 +26,13 @@
         return res;
 
     buf->len  = 0;
+    buf->offs = 0;
     buf->size = initial;
     buf->mingrow = mingrow;
     buf->allocated = FALSE;
 
     // Allocate the data
-    if ((buf->data = dmMalloc0(initial)) == NULL)
+    if ((buf->adata = buf->data = dmMalloc0(initial)) == NULL)
         return DMERR_MALLOC;
 
     return DMERR_OK;
@@ -66,21 +67,52 @@
 {
     if (buf != NULL)
     {
-        dmFreeR(&buf->data);
+        dmFreeR(&buf->adata);
+        buf->data = NULL;
+
         if (buf->allocated)
             dmFree(buf);
     }
 }
 
 
+void dmGrowBufPush(DMGrowBuf *buf)
+{
+    if (buf != NULL && buf->adata != NULL)
+    {
+        buf->stack[buf->nstack].offs = buf->offs;
+        buf->stack[buf->nstack].len = buf->len;
+        buf->nstack++;
+
+        buf->offs = buf->len;
+        buf->data = buf->adata + buf->offs;
+        buf->len  = 0;
+    }
+}
+
+
+void dmGrowBufPop(DMGrowBuf *buf)
+{
+    if (buf != NULL && buf->adata != NULL && buf->nstack > 0)
+    {
+        buf->nstack--;
+        buf->offs  = buf->stack[buf->nstack].offs;
+        buf->len  += buf->stack[buf->nstack].len;
+
+        buf->data = buf->adata + buf->offs;
+    }
+}
+
+
 static BOOL dmGrowBufRealloc(DMGrowBuf *buf, const size_t nsize, const BOOL clear)
 {
-    if ((buf->data = dmRealloc(buf->data, nsize)) == NULL)
+    if ((buf->adata = dmRealloc(buf->adata, nsize)) == NULL)
         return FALSE;
 
     if (clear)
         memset(buf->adata + buf->size, 0, nsize - buf->size);
 
+    buf->data = buf->adata + buf->offs;
     buf->size = nsize;
 
     return TRUE;
@@ -94,7 +126,7 @@
 //
 BOOL dmGrowBufGrow(DMGrowBuf *buf, const size_t amount)
 {
-    if (buf->data == NULL || buf->offs + buf->len + amount >= buf->size)
+    if (buf->adata == NULL || buf->offs + buf->len + amount >= buf->size)
     {
         size_t grow = (amount > buf->mingrow) ? amount : buf->mingrow;
         if (!dmGrowBufRealloc(buf, buf->offs + buf->len + grow, TRUE))
@@ -111,7 +143,7 @@
 //
 BOOL dmGrowBufCheckGrow(DMGrowBuf *buf, const size_t nsize)
 {
-    if (buf->data == NULL || buf->offs + nsize > buf->size)
+    if (buf->adata == NULL || buf->offs + nsize > buf->size)
     {
         if (!dmGrowBufRealloc(buf, buf->offs + nsize + buf->mingrow, TRUE))
             return FALSE;
--- a/src/dmgrowbuf.h	Sat May 12 03:10:47 2018 +0300
+++ b/src/dmgrowbuf.h	Sat May 12 03:23:32 2018 +0300
@@ -15,9 +15,11 @@
 
 typedef struct
 {
-    Uint8 *data;
-    size_t len, size, mingrow;
+    Uint8 *data, *adata;
+    size_t len, size, mingrow, offs;
     BOOL allocated;
+    int nstack;
+    struct { size_t offs, len; } stack[32];
 } DMGrowBuf;
 
 
@@ -37,6 +39,9 @@
 BOOL   dmGrowBufPutU32BE(DMGrowBuf *buf, const Uint32 val);
 BOOL   dmGrowBufPutU32LE(DMGrowBuf *buf, const Uint32 val);
 
+void    dmGrowBufPush(DMGrowBuf *buf);
+void    dmGrowBufPop(DMGrowBuf *buf);
+
 
 #ifdef __cplusplus
 }