Mercurial > hg > th-libs
view th_ioctx_mem.c @ 684:a6e7a29ecd30
Constify.
author | Matti Hamalainen <ccr@tnsp.org> |
---|---|
date | Wed, 04 Mar 2020 23:39:11 +0200 |
parents | 81d1a3f53b87 |
children | ea6bcbfb9d18 |
line wrap: on
line source
/* * Simple I/O abstraction and context handling layer * Programmed and designed by Matti 'ccr' Hamalainen * (C) Copyright 2012-2020 Tecnic Software productions (TNSP) * * Please read file 'COPYING' for information on license and distribution. */ #include "th_ioctx.h" static BOOL th_mem_realloc(th_ioctx *ctx, const size_t newSize) { size_t grow; if (ctx->maxSize > 0 && newSize > ctx->maxSize) { ctx->status = THERR_BOUNDS; return FALSE; } if (newSize < ctx->memAlloc) return TRUE; grow = (ctx->minAlloc > 0) ? ctx->minAlloc : 8 * 1024; if (newSize - ctx->memAlloc > grow) grow += newSize - ctx->memAlloc; if (ctx->maxSize > 0 && ctx->memAlloc + grow >= ctx->maxSize) { ctx->status = THERR_BOUNDS; return FALSE; } ctx->memAlloc += grow; if ((ctx->memData = th_realloc(ctx->memData, ctx->memAlloc)) == NULL) { ctx->status = THERR_MALLOC; return FALSE; } ctx->memSize = newSize; return TRUE; } static int th_mem_freset(th_ioctx *ctx) { ctx->memOffset = 0; return THERR_OK; } static int th_mem_ferror(th_ioctx *ctx) { return ctx->status; } static int th_mem_fseek(th_ioctx *ctx, const off_t offset, const int whence) { off_t newPos; // Calculate the new position switch (whence) { case SEEK_SET: newPos = offset; break; case SEEK_CUR: newPos = ctx->memOffset + offset; break; case SEEK_END: newPos = ctx->memSize + offset; break; default: return -1; } // Set the new position ctx->memOffset = newPos; // Check the new position if (newPos < 0) return -1; //if (!th_mem_realloc(ctx, newPos)) // return -1; return 0; } static off_t th_mem_fsize(th_ioctx *ctx) { return ctx->memSize; } static off_t th_mem_ftell(th_ioctx *ctx) { return ctx->memOffset; } static BOOL th_mem_feof(th_ioctx *ctx) { return ((size_t) ctx->memOffset) >= ctx->memSize; } static int th_mem_fgetc(th_ioctx *ctx) { // Check for EOF if ((size_t) ctx->memOffset < ctx->memSize) return ctx->memData[ctx->memOffset++]; else return EOF; } static size_t th_mem_fread(void *buf, size_t size, size_t nmemb, th_ioctx *ctx) { size_t length = size * nmemb; // Check if we can read the whole chunk if (((size_t) ctx->memOffset + length) >= ctx->memSize) { nmemb = (ctx->memSize - ctx->memOffset) / size; length = size * nmemb; } memcpy(buf, ctx->memData + ctx->memOffset, length); ctx->memOffset += length; return nmemb; } static int th_mem_fputc(int ch, th_ioctx *ctx) { // Check for EOF if (!th_mem_realloc(ctx, ctx->memOffset + 1)) return EOF; ctx->memData[ctx->memOffset++] = ch; return ch; } static size_t th_mem_fwrite(const void *buf, size_t size, size_t nmemb, th_ioctx *ctx) { size_t length = size * nmemb; // Check if we can write the whole chunk if (!th_mem_realloc(ctx, ctx->memOffset + length)) { nmemb = (ctx->memSize - ctx->memOffset) / size; length = size * nmemb; } if (length > 0) { memcpy(ctx->memData + ctx->memOffset, buf, length); ctx->memOffset += length; } return nmemb; } const th_ioctx_ops th_mem_io_ops = { "MemIO", NULL, NULL, th_mem_freset, th_mem_ferror, th_mem_fseek, th_mem_fsize, th_mem_ftell, th_mem_feof, th_mem_fgetc, th_mem_fputc, th_mem_fread, th_mem_fwrite, NULL, NULL, NULL };