All pastes #545015 Raw Edit

dynarray.c

public c v1 · immutable
·published 2007-06-06 17:56 UTC
rendered paste body
#include <string.h>#include <stdlib.h>#include <assert.h>#include "config.h"#include "tools/dynarray.h"/* * Dynamic array starting size in bytes. Will be at least one item, if * it's smaller than it. */#ifndef DYNARR_SSIZE#define DYNARR_SSIZE 1024#endif/* Dynamic array */dynarray *dynarray_init(size_t isize, const void *dflt) {	uint32_t nsize;	dynarray *d = (dynarray *)malloc(sizeof (dynarray));	if (!d) return NULL;	d->isize = isize;	d->count = 0;	nsize = DYNARR_SSIZE/isize;	if (!nsize) nsize = 1;	d->dflt = malloc(isize);	if (!d->dflt) return NULL;	memcpy(d->dflt, dflt, isize);	d->data = NULL;	if (!dynarray_resize(d, nsize)) return NULL;	return d;}void dynarray_del(dynarray *d, const uint32_t pos, const uint32_t nitems) {	assert(d);	assert(pos + nitems < d->count);	/* Copy the data above the deleted area onto it */	memmove((void *)dynarray_peek(d, pos), dynarray_peek(d, pos + nitems), \		(d->count - pos - nitems) * d->isize);	d->count -= nitems;}void dynarray_free(dynarray **d) {	assert(d);	assert(*d);	free((*d)->data);	free(*d);	*d = NULL;}int dynarray_put(dynarray *d, const uint32_t pos, const void *n, const uint32_t nitems) {	uint32_t i;	assert(d);	if (!nitems) return 1;	if (pos + nitems > d->avail) {		/*		 * This should be slightly less than 2x the expected size. Adding		 * larger vectors will grow the table in increments of its size		 * before addition. Should be more efficient in case of bulk		 * addition and maybe less wasteful.		 */		d->avail += (pos + nitems + 1) * 1.5 / d->avail * d->avail;		/* Do the resizin on our own, fill only required elements */		if (!(d->data = (char *)realloc(d->data, d->avail * d->isize)))			return 0;		/* Fill empty fields with defaults */		for (i = d->count; i < pos; i++)			memcpy(d->data + i * d->isize, d->dflt, d->isize);	}	/* Copy the items */	memmove(d->data + pos * d->isize, n, nitems * d->isize);	if (d->count < pos + nitems)		d->count = pos + nitems;	return 1;}int dynarray_append(dynarray *d, const void *n, const uint32_t nitems) {	assert(d);	return dynarray_put(d, d->count, n, nitems);}int dynarray_insert(dynarray *d, const uint32_t pos, const void *n, const uint32_t nitems) {	assert(d);	if (!nitems) return 1;	if (pos > d->count)		/* Should be the same */		return dynarray_put(d, pos, n, nitems);	if (d->count + nitems > d->avail) {		d->avail += (d->count + nitems + 1) * 1.5 / d->avail * d->avail;		/* Do the resizing on our own - no default-filling */		if (!(d->data = (char *)realloc(d->data, d->avail * d->isize)))			return 0;	}	/* Move the objects in the path */	memmove(d->data + (pos + nitems) * d->isize, d->data + pos * d->isize, \		(d->count - pos) * d->isize);	/* Copy the data */	memmove(d->data + pos * d->isize, n, nitems * d->isize);	d->count += nitems;	return 1;}const void *dynarray_peek(const dynarray *d, const uint32_t pos) {	if (pos > d->count) return NULL;	return d->data + pos * d->isize;}void *dynarray_get(const dynarray *d, const uint32_t pos, const uint32_t nitems) {	void *res;	if (!nitems) return NULL;	if (d->count < pos + nitems) return NULL;	if (!(res = malloc(nitems * d->isize))) return NULL;	memcpy(res, dynarray_peek(d, pos), nitems * d->isize);	return res;}int dynarray_resize(dynarray *d, const uint32_t nitems) {	uint32_t i;	assert(d);	if (!(d->data = (char *)realloc(d->data, nitems * d->isize)))		return 0;	if (d->avail < nitems)		/* Fill with default items */		for (i = 0; i < nitems - d->avail; i++)			memcpy(d->data + d->avail + i, d->dflt, d->isize);	d->avail = nitems;	if (d->count > d->avail) d->count = d->avail;	return 1;}