Mercurial > hg > dmlib
diff src/dmgrowbuf.c @ 1697:1036b0dcccb5
Refactor DMGrowBuf so that there can be buffers that grow "backwards".
This also removes some support functions like the buffer state push/pop.
author | Matti Hamalainen <ccr@tnsp.org> |
---|---|
date | Tue, 05 Jun 2018 12:55:17 +0300 |
parents | e568535e1a96 |
children | f71cd6691e05 |
line wrap: on
line diff
--- a/src/dmgrowbuf.c Tue Jun 05 11:36:55 2018 +0300 +++ b/src/dmgrowbuf.c Tue Jun 05 12:55:17 2018 +0300 @@ -45,7 +45,7 @@ buf->allocated = FALSE; // Allocate the data - if ((buf->adata = buf->data = dmMalloc0(initial)) == NULL) + if ((buf->data = dmMalloc0(initial)) == NULL) return DMERR_MALLOC; return DMERR_OK; @@ -85,13 +85,11 @@ if (buf != NULL) { DM_DBG( - " buf->adata = %p\n" " buf->data = %p\n" " buf->allocated = %s\n", - buf->adata, buf->data, buf->allocated ? "YES" : "NO"); + buf->data, buf->allocated ? "YES" : "NO"); - dmFreeR(&buf->adata); - buf->data = NULL; + dmFreeR(&buf->data); if (buf->allocated) dmFree(buf); @@ -99,68 +97,38 @@ } -void dmGrowBufPush(DMGrowBuf *buf) -{ - if (buf != NULL && buf->adata != NULL) - { - DM_DBG("dmGrowBufPush(%p): size=%" DM_PRIu_SIZE_T "\n" - " nstack=%d [offs=%" DM_PRIu_SIZE_T ", len=%" DM_PRIu_SIZE_T "]\n", - buf, buf->size, buf->nstack, buf->offs, buf->len); - - 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; - - DM_DBG( - " nstack=%d [offs=%" DM_PRIu_SIZE_T ", len=%" DM_PRIu_SIZE_T "]\n", - buf->nstack, buf->offs, buf->len); - } - else - DM_DBG("dmGrowBufPush(%p)\n", buf); -} - - -void dmGrowBufPop(DMGrowBuf *buf) -{ - if (buf != NULL && buf->adata != NULL && buf->nstack > 0) - { - DM_DBG("dmGrowBufPop(%p): size=%" DM_PRIu_SIZE_T "\n" - " nstack=%d [offs=%" DM_PRIu_SIZE_T ", len=%" DM_PRIu_SIZE_T "]\n", - buf, buf->size, buf->nstack, buf->offs, buf->len); - - buf->nstack--; - buf->offs = buf->stack[buf->nstack].offs; - buf->len += buf->stack[buf->nstack].len; - - buf->data = buf->adata + buf->offs; - - DM_DBG( - " nstack=%d [offs=%" DM_PRIu_SIZE_T ", len=%" DM_PRIu_SIZE_T "]\n", - buf->nstack, buf->offs, buf->len); - - } - else - DM_DBG("dmGrowBufPop(%p)\n", buf); -} - - static BOOL dmGrowBufRealloc(DMGrowBuf *buf, const size_t nsize, const BOOL clear) { - DM_DBG("dmGrowBufRealloc(%p): size=%" DM_PRIu_SIZE_T "\n" - " nstack=%d [offs=%" DM_PRIu_SIZE_T ", len=%" DM_PRIu_SIZE_T "]\n", - buf, buf->size, buf->nstack, buf->offs, buf->len); + DM_DBG("dmGrowBufRealloc(%p):\n" + " size=%" DM_PRIu_SIZE_T ", nsize=" DM_PRIu_SIZE_T + ", nstack=%d, offs=%" DM_PRIu_SIZE_T "\n", + buf, buf->size, nsize, buf->nstack, buf->offs); - if ((buf->adata = dmRealloc(buf->adata, nsize)) == NULL) + // Can't be smaller than current size! + if (nsize < buf->size) + return FALSE; + + if ((buf->data = dmRealloc(buf->data, nsize)) == NULL) return FALSE; + // For buffers growing backwards, we must move the + // current data to the end of the buffer .. + size_t clrsize = nsize - buf->size; + if (buf->backwards) + { + memmove(buf->data + clrsize, buf->data, clrsize); + buf->offs += clrsize; + } + + // Check if we need to clear the newly allocated area? if (clear) - memset(buf->adata + buf->size, 0, nsize - buf->size); + { + if (buf->backwards) + memset(buf->data, 0, clrsize); + else + memset(buf->data + buf->size, 0, clrsize); + } - buf->data = buf->adata + buf->offs; buf->size = nsize; return TRUE; @@ -174,13 +142,17 @@ // BOOL dmGrowBufGrow(DMGrowBuf *buf, const size_t amount) { - if (buf->adata == NULL || buf->offs + buf->len + amount >= buf->size) + size_t grow = (amount > buf->mingrow) ? amount : buf->mingrow; + + if (buf->data == NULL || + (buf->backwards && amount >= buf->offs) || + (!buf->backwards && buf->offs + amount >= buf->size)) { - size_t grow = (amount > buf->mingrow) ? amount : buf->mingrow; - if (!dmGrowBufRealloc(buf, buf->offs + buf->len + grow, TRUE)) + if (!dmGrowBufRealloc(buf, buf->size + grow, TRUE)) return FALSE; } + buf->len += amount; return TRUE; } @@ -191,12 +163,56 @@ // BOOL dmGrowBufCheckGrow(DMGrowBuf *buf, const size_t nsize) { - if (buf->adata == NULL || buf->offs + nsize > buf->size) + if (buf->data == NULL || nsize > buf->size) { - if (!dmGrowBufRealloc(buf, buf->offs + nsize + buf->mingrow, TRUE)) + if (!dmGrowBufRealloc(buf, nsize + buf->mingrow, TRUE)) return FALSE; } + buf->len = nsize; + return TRUE; +} + + +static void dmGrowBufUpdate(DMGrowBuf *buf) +{ + if (buf->offs < buf->min_offs) + buf->min_offs = buf->offs; + + if (buf->offs > buf->max_offs) + buf->max_offs = buf->offs; +} + + +BOOL dmGrowBufPut(DMGrowBuf *buf, const Uint8 *data, const size_t len) +{ + if (data == NULL) + return FALSE; + + if (!dmGrowBufGrow(buf, len)) + return FALSE; + + if (buf->backwards) + { + if (buf->literal) + { + buf->offs -= len; + memcpy(buf->data + buf->offs, data, len); + } + else + { + for (size_t n = 0; n < len; n++) + buf->data[buf->offs--] = data[n]; + } + } + else + { + memcpy(buf->data + buf->offs, data, len); + buf->offs += len; + } + + dmGrowBufUpdate(buf); + return TRUE; } @@ -206,22 +222,13 @@ if (!dmGrowBufGrow(buf, sizeof(Uint8))) return FALSE; - buf->data[buf->len++] = value; - - return TRUE; -} - + buf->data[buf->offs] = value; + if (buf->backwards) + buf->offs--; + else + buf->offs++; -BOOL dmGrowBufPut(DMGrowBuf *buf, const void *str, const size_t len) -{ - if (str == NULL) - return FALSE; - - if (!dmGrowBufGrow(buf, len)) - return FALSE; - - memcpy(buf->data + buf->len, str, len); - buf->len += len; + dmGrowBufUpdate(buf); return TRUE; } @@ -229,51 +236,75 @@ 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; + if (buf->literal && buf->backwards) + { + return + !dmGrowBufPutU8(buf, val & 0xff) || + !dmGrowBufPutU8(buf, (val >> 8) & 0xff); + } + else + { + return + !dmGrowBufPutU8(buf, (val >> 8) & 0xff) || + !dmGrowBufPutU8(buf, val & 0xff); + } } 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; + if (buf->literal && buf->backwards) + { + return + !dmGrowBufPutU8(buf, (val >> 8) & 0xff) || + !dmGrowBufPutU8(buf, val & 0xff); + } + else + { + return + !dmGrowBufPutU8(buf, val & 0xff) || + !dmGrowBufPutU8(buf, (val >> 8) & 0xff); + } } 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; + if (buf->literal && buf->backwards) + { + return + !dmGrowBufPutU8(buf, (val >> 24) & 0xff) || + !dmGrowBufPutU8(buf, (val >> 16) & 0xff) || + !dmGrowBufPutU8(buf, (val >> 8) & 0xff) || + !dmGrowBufPutU8(buf, val & 0xff); + } + else + { + return + !dmGrowBufPutU8(buf, val & 0xff) || + !dmGrowBufPutU8(buf, (val >> 8) & 0xff) || + !dmGrowBufPutU8(buf, (val >> 16) & 0xff) || + !dmGrowBufPutU8(buf, (val >> 24) & 0xff); + } } 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; + if (buf->literal && buf->backwards) + { + return + !dmGrowBufPutU8(buf, val & 0xff) || + !dmGrowBufPutU8(buf, (val >> 8) & 0xff) || + !dmGrowBufPutU8(buf, (val >> 16) & 0xff) || + !dmGrowBufPutU8(buf, (val >> 24) & 0xff); + } + else + { + return + !dmGrowBufPutU8(buf, (val >> 24) & 0xff) || + !dmGrowBufPutU8(buf, (val >> 16) & 0xff) || + !dmGrowBufPutU8(buf, (val >> 8) & 0xff) || + !dmGrowBufPutU8(buf, val & 0xff); + } }