diff -r 7fd13b9f8f60 -r d315a068235a src/array.c --- a/src/array.c Sat Aug 10 11:12:49 2019 +0200 +++ b/src/array.c Tue Sep 24 20:16:00 2019 +0200 @@ -35,6 +35,7 @@ #include #include +#include #ifndef UCX_ARRAY_DISABLE_QSORT #ifdef __GLIBC__ @@ -67,6 +68,51 @@ } } +int ucx_array_util_set_a(UcxAllocator* alloc, void** array, size_t* capacity, + size_t elmsize, size_t index, ...) { + + if(!alloc || !capacity || !array) { + errno = EINVAL; + return 1; + } + + size_t newcapacity = *capacity; + while(index >= newcapacity) { + if(ucx_szmul(newcapacity, 2, &newcapacity)) { + errno = EOVERFLOW; + return 1; + } + } + + size_t memlen, offset; + if(ucx_szmul(newcapacity, elmsize, &memlen)) { + errno = EOVERFLOW; + return 1; + } + /* we don't need to check index*elmsize - it is smaller than memlen */ + + + void* newptr = alrealloc(alloc, *array, memlen); + if(newptr == NULL) { + errno = ENOMEM; /* we cannot assume that every allocator sets this */ + return 1; + } + *array = newptr; + *capacity = newcapacity; + + + char* dest = *array; + dest += elmsize*index; + + va_list ap; + va_start(ap, index); + int elem = va_arg(ap, int); + memcpy(dest, &elem, elmsize); + va_end(ap); + + return 0; +} + UcxArray ucx_array_new(size_t capacity, size_t elemsize) { return ucx_array_new_a(capacity, elemsize, ucx_default_allocator()); }