# HG changeset patch # User Matti Hamalainen # Date 1528192517 -10800 # Node ID 1036b0dcccb5c5f781ed18c849d6e2f127f66b48 # Parent cf0fddd4bf52d8cddb8c0b69bec16914c9b3d411 Refactor DMGrowBuf so that there can be buffers that grow "backwards". This also removes some support functions like the buffer state push/pop. diff -r cf0fddd4bf52 -r 1036b0dcccb5 src/dmgrowbuf.c --- 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); + } } diff -r cf0fddd4bf52 -r 1036b0dcccb5 src/dmgrowbuf.h --- a/src/dmgrowbuf.h Tue Jun 05 11:36:55 2018 +0300 +++ b/src/dmgrowbuf.h Tue Jun 05 12:55:17 2018 +0300 @@ -16,12 +16,21 @@ typedef struct { - Uint8 *data, *adata; - size_t len, size, mingrow, offs; - BOOL allocated; + Uint8 + *data; // Actually allocated data pointer - int nstack; - struct { size_t offs, len; } stack[32]; + size_t + offs, // Current offset + min_offs, + max_offs, + size, // Actual allocated size + len, // Size requested + mingrow; // Minimum amount of bytes the allocation size grows by + + BOOL + allocated, // TRUE if this structure itself has been allocated and can be freed, FALSE if static + backwards, // TRUE if the buffer grows backwards (e.g. "offs" moves backwards) + literal; // TRUE if dmGrowBufPut*() functions stores data "literally" in backwards mode } DMGrowBuf; @@ -30,15 +39,11 @@ int dmGrowBufNew(DMGrowBuf **pbuf, const size_t initial, const size_t mingrow); void dmGrowBufFree(DMGrowBuf *buf); -void dmGrowBufPush(DMGrowBuf *buf); -void dmGrowBufPop(DMGrowBuf *buf); - BOOL dmGrowBufGrow(DMGrowBuf *buf, const size_t amount); BOOL dmGrowBufCheckGrow(DMGrowBuf *buf, const size_t nsize); +BOOL dmGrowBufPut(DMGrowBuf *buf, const Uint8 *data, const size_t len); BOOL dmGrowBufPutU8(DMGrowBuf *buf, const Uint8 value); -BOOL dmGrowBufPut(DMGrowBuf *buf, const void *str, const size_t len); - BOOL dmGrowBufPutU16BE(DMGrowBuf *buf, const Uint16 val); BOOL dmGrowBufPutU16LE(DMGrowBuf *buf, const Uint16 val); BOOL dmGrowBufPutU32BE(DMGrowBuf *buf, const Uint32 val); diff -r cf0fddd4bf52 -r 1036b0dcccb5 tools/lib64fmts.c --- a/tools/lib64fmts.c Tue Jun 05 11:36:55 2018 +0300 +++ b/tools/lib64fmts.c Tue Jun 05 12:55:17 2018 +0300 @@ -146,7 +146,7 @@ dmGenericRLEAnalyze(tmp.data, tmp.len, &cfg); // Add the header bits - if (!dmGrowBufPut(buf, magicID, strlen(magicID)) || + if (!dmGrowBufPut(buf, (Uint8 *) magicID, strlen(magicID)) || !dmGrowBufPutU8(buf, cfg.rleMarkerB)) { res = DMERR_MALLOC; @@ -248,7 +248,7 @@ dmGenericRLEAnalyze(tmp.data, tmp.len, &cfg); // Add the header bits - if (!dmGrowBufPut(buf, fmtBDP5MagicID, strlen(fmtBDP5MagicID)) || + if (!dmGrowBufPut(buf, (Uint8 *) fmtBDP5MagicID, strlen(fmtBDP5MagicID)) || !dmGrowBufPutU8(buf, cfg.rleMarkerB) || !dmGrowBufPutU8(buf, cfg.rleMarkerW)) { @@ -612,7 +612,7 @@ static int fmtEncodeFunPaint2Unpacked(DMGrowBuf *buf, const DMC64Image *img, const DMC64ImageFormat *fmt) { // Add the header bits - if (!dmGrowBufPut(buf, fmtFunPaint2MagicID, strlen(fmtFunPaint2MagicID)) || + if (!dmGrowBufPut(buf, (Uint8 *) fmtFunPaint2MagicID, strlen(fmtFunPaint2MagicID)) || !dmGrowBufPutU8(buf, 0)) return DMERR_MALLOC; @@ -639,7 +639,7 @@ dmGenericRLEAnalyze(tmp.data, tmp.len, &cfg); // Add the header bits - if (!dmGrowBufPut(buf, fmtFunPaint2MagicID, strlen(fmtFunPaint2MagicID)) || + if (!dmGrowBufPut(buf, (Uint8 *) fmtFunPaint2MagicID, strlen(fmtFunPaint2MagicID)) || !dmGrowBufPutU8(buf, cfg.rleMarkerB)) { res = DMERR_MALLOC; diff -r cf0fddd4bf52 -r 1036b0dcccb5 tools/lib64gfx.c --- a/tools/lib64gfx.c Tue Jun 05 11:36:55 2018 +0300 +++ b/tools/lib64gfx.c Tue Jun 05 12:55:17 2018 +0300 @@ -905,7 +905,12 @@ goto err; } - dmGrowBufPush(buf); + if (buf->backwards) + { + dmError(DMERR_INVALID_DATA, + "Buffer specified for dmC64EncodeGenericBMP() is in backwards mode, which is not supported.\n"); + goto err; + } // Perform encoding for (int i = 0; i < D64_MAX_ENCDEC_OPS; i++) @@ -935,7 +940,7 @@ } // Do we need to reallocate some more space? - chksize = op->offs + size; + chksize = buf->offs + op->offs + size; if (!dmGrowBufCheckGrow(buf, chksize)) { res = dmError(DMERR_MALLOC, @@ -948,8 +953,7 @@ buf->len = chksize; // Perform operation - Uint8 *dst; - dst = buf->data + op->offs; + Uint8 *dst = buf->data + buf->offs + op->offs; switch (op->type) { case DO_COPY: @@ -1060,8 +1064,6 @@ } } - dmGrowBufPop(buf); - res = DMERR_OK; err: