Mercurial > hg > dmlib
view src/dmgrowbuf.c @ 1530:94eb6a8a7d56
Add helper function dmGrowBufRealloc() to handle the common case of
reallocating the grow buffer in various enlargement functions.
author | Matti Hamalainen <ccr@tnsp.org> |
---|---|
date | Sat, 12 May 2018 03:10:47 +0300 |
parents | 15afe578f0ae |
children | 260bf529a8f2 |
line wrap: on
line source
/* * 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) { if (buf == NULL) return DMERR_NULLPTR; memset(buf, 0, sizeof(DMGrowBuf)); return DMERR_OK; } int dmGrowBufAlloc(DMGrowBuf *buf, const size_t initial, const size_t mingrow) { int res; if ((res = dmGrowBufInit(buf)) != DMERR_OK) return res; buf->len = 0; buf->size = initial; buf->mingrow = mingrow; buf->allocated = FALSE; // Allocate the data if ((buf->data = dmMalloc0(initial)) == NULL) return DMERR_MALLOC; return DMERR_OK; } int dmGrowBufNew(DMGrowBuf **pbuf, const size_t initial, const size_t mingrow) { int res; if (pbuf == NULL) return DMERR_NULLPTR; if ((*pbuf = dmMalloc0(sizeof(DMGrowBuf))) == NULL) return DMERR_MALLOC; if ((res = dmGrowBufAlloc(*pbuf, initial, mingrow)) != DMERR_OK) { // The "allocated" flag has not yet been set dmGrowBufFree(*pbuf); // .. thus free the allocated struct here dmFreeR(pbuf); return res; } (*pbuf)->allocated = TRUE; return res; } void dmGrowBufFree(DMGrowBuf *buf) { if (buf != NULL) { dmFreeR(&buf->data); if (buf->allocated) dmFree(buf); } } static BOOL dmGrowBufRealloc(DMGrowBuf *buf, const size_t nsize, const BOOL clear) { if ((buf->data = dmRealloc(buf->data, nsize)) == NULL) return FALSE; if (clear) memset(buf->adata + buf->size, 0, nsize - buf->size); buf->size = nsize; return TRUE; } // // Grow the buffer by "amount" bytes, but at least by buf->mingrow, // if there is not enough space for at least that amount compared to // current buffer "len". // BOOL dmGrowBufGrow(DMGrowBuf *buf, const size_t amount) { if (buf->data == 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)) return FALSE; } return TRUE; } // // Grow the buffer if "nsize" is larger than the current buffer size. // Buffer is enlarged to nsize + mingrow. // BOOL dmGrowBufCheckGrow(DMGrowBuf *buf, const size_t nsize) { if (buf->data == NULL || buf->offs + nsize > buf->size) { if (!dmGrowBufRealloc(buf, buf->offs + nsize + buf->mingrow, TRUE)) 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 (!dmGrowBufRealloc(buf, buf->size, FALSE)) 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 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; 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; }