Mercurial > hg > dmlib
diff src/dmgrowbuf.c @ 1454:fff3b58d031c
Add a growable buffer implementation.
author | Matti Hamalainen <ccr@tnsp.org> |
---|---|
date | Thu, 10 May 2018 18:33:57 +0300 |
parents | |
children | a957b318fbe2 |
line wrap: on
line diff
--- /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; +}