/* Copyright (C) 2015-2020, Dirk Krause SPDX-License-Identifier: BSD-3-Clause */ /* WARNING: This file was generated by the dkct program (see http://dktools.sourceforge.net/ for details). Changes you make here will be lost if dkct is run again! You should modify the original source and run dkct on it. Original source: dk4membuf.ctr */ /** @file dk4membuf.c The dk4membuf module. */ #line 113 "dk4membuf.ctr" #include "dk4conf.h" #include "dk4membuf.h" #include "dk4mem.h" #include "dk4maasz.h" #if DK4_HAVE_ASSERT_H #ifndef ASSERT_H_INCLUDED #include #define ASSERT_H_INCLUDED 1 #endif #endif #line 128 "dk4membuf.ctr" static void dk4membuf_cell_close(dk4_membuf_cell_t *mcptr) { #if DK4_USE_ASSERT assert(NULL != mcptr); #endif if (NULL != mcptr) { dk4mem_release(mcptr->buf); mcptr->next = NULL; mcptr->max = mcptr->used = 0; dk4mem_free(mcptr); } } static dk4_membuf_cell_t * dk4membuf_cell_open(size_t sz, dk4_er_t *erp) { dk4_er_t er; dk4_membuf_cell_t *back = NULL; size_t nb; /* Ensure number of bytes is a multiple of the chunk size. */ nb = sz / DK4MEMBUF_CHUNK_SIZE; if (0 != (sz % DK4MEMBUF_CHUNK_SIZE)) { nb++; } dk4error_init(&er); nb = dk4ma_size_t_mul(nb, (size_t)(DK4MEMBUF_CHUNK_SIZE), &er); if (0 != er.ec) { nb = sz; } /* Allocate */ back = dk4mem_new(dk4_membuf_cell_t,1,erp); if (NULL != back) { back->next = NULL; back->max = nb; back->used = 0; back->buf = dk4mem_new(char,nb,erp); if (NULL == back->buf) { dk4mem_free(back); back = NULL; } } return back; } dk4_membuf_t * dk4membuf_open(dk4_er_t *erp) { dk4_membuf_t *back = NULL; back = dk4mem_new(dk4_membuf_t,1,erp); if (NULL != back) { back->he = 0; back->last = NULL; back->first = dk4membuf_cell_open(DK4MEMBUF_CHUNK_SIZE, erp); if (NULL != back->first) { back->last = back->first; } else { dk4mem_free(back); back = NULL; } } return back; } void dk4membuf_close(dk4_membuf_t *mbptr) { dk4_membuf_cell_t *pc; dk4_membuf_cell_t *pn; #if DK4_USE_ASSERT assert(NULL != mbptr); #endif if (NULL != mbptr) { pc = mbptr->first; while (NULL != pc) { pn = pc->next; dk4membuf_cell_close(pc); pc = pn; } dk4mem_free(mbptr); } } int dk4membuf_store(dk4_membuf_t *mbptr, const void *src, size_t sz, dk4_er_t *erp) { dk4_membuf_cell_t *pc = NULL; dk4_membuf_cell_t *pn = NULL; const char *psrc = NULL; size_t bl = 0; int back = 0; #if DK4_USE_ASSERT assert(NULL != src); assert(0 < sz); assert(NULL != mbptr); #endif if ((NULL != mbptr) && (NULL != src) && (0 < sz)) { /* Initialize variables. */ back = 1; pc = mbptr->last; psrc = (const char *)src; /* Attempt to fill current cell. */ if (pc->max > pc->used) { bl = pc->max - pc->used; if (sz < bl) { bl = sz; } DK4_MEMCPY(&((pc->buf)[pc->used]), psrc, bl); pc->used += bl; sz -= bl; psrc = &(psrc[bl]); } /* Use new cell if necessary. */ if (0 < sz) { back = 0; pn = dk4membuf_cell_open(sz, erp); if (NULL != pn) { pc->next = pn; mbptr->last = pn; DK4_MEMCPY(pn->buf, psrc, sz); back = 1; pn->used = sz; } else { mbptr->he = 1; } } } else { dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS); } return back; } int dk4membuf_size(size_t *szptr, dk4_membuf_t const *mbptr, dk4_er_t *erp) { dk4_er_t er; dk4_membuf_cell_t *cp = NULL; size_t result = (size_t)0U; int back = 0; #line 284 "dk4membuf.ctr" #if DK4_USE_ASSERT assert(NULL != szptr); assert(NULL != mbptr); #endif if ((NULL != szptr) && (NULL != mbptr)) { back = 1; cp = mbptr->first; dk4error_init(&er); #line 293 "dk4membuf.ctr" while (NULL != cp) { #line 295 "dk4membuf.ctr" result = dk4ma_size_t_add(result, cp->used, &er); cp = cp->next; } if (DK4_E_NONE == er.ec) { back = 1; *szptr = result; } #if TRACE_DEBUG else { #line 304 "dk4membuf.ctr" } #endif } else { #if TRACE_DEBUG if (NULL == szptr) { #line 309 "dk4membuf.ctr" } if (NULL == mbptr) { #line 311 "dk4membuf.ctr" } #endif dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS); } #line 316 "dk4membuf.ctr" return back; }