Mercurial > hg > dmlib
view src/dmgrowbuf.c @ 1556:8f06c23e197d last_SDL1
Cosmetics.
author | Matti Hamalainen <ccr@tnsp.org> |
---|---|
date | Sun, 13 May 2018 05:59:42 +0300 |
parents | 064fc2e3ee64 |
children | 383ca5f6e78b |
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" //#define DM_GROWBUF_DEBUG 1 #ifdef DM_GROWBUF_DEBUG # define DM_DBG(...) do { fprintf(stderr, __VA_ARGS__); } while (0) #else # define DM_DBG(...) do { } while (0) #endif int dmGrowBufInit(DMGrowBuf *buf) { DM_DBG("dmGrowBufInit(%p)\n", 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; DM_DBG("dmGrowBufAlloc(%p, %" DM_PRIu_SIZE_T ", %" DM_PRIu_SIZE_T ")\n", buf, initial, mingrow); if ((res = dmGrowBufInit(buf)) != DMERR_OK) return res; buf->len = 0; buf->offs = 0; buf->size = initial; buf->mingrow = mingrow; buf->allocated = FALSE; // Allocate the data if ((buf->adata = 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; DM_DBG("dmGrowBufNew(%p, %" DM_PRIu_SIZE_T ", %" DM_PRIu_SIZE_T ")\n", pbuf, initial, mingrow); 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) { DM_DBG("dmGrowBufFree(%p)\n", buf); 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"); dmFreeR(&buf->adata); buf->data = NULL; if (buf->allocated) dmFree(buf); } } 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); 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; } // // 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->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)) 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->adata == 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; }