#include #include #include #include #include #include "resizable.h" void apfl_resizable_init(void **mem, size_t *len, size_t *cap) { *mem = NULL; *len = 0; *cap = 0; } bool apfl_resizable_resize(size_t elem_size, void **mem, size_t *len, size_t *cap, size_t newlen) { // TODO: We're wasteful here by never actually shrinking the memory. if (newlen <= *len || newlen < *cap) { *len = newlen; return true; } assert(newlen >= *cap); if (!apfl_resizable_grow_cap(elem_size, mem, len, cap, newlen - *cap)) { return false; } *len = newlen; return true; } bool apfl_resizable_grow_cap(size_t elem_size, void **mem, size_t *len, size_t *cap, size_t inc_cap) { (void)len;// \mystuff\TODO:better not even have the arg if (inc_cap == 0) { return true; } size_t newcap = *cap + inc_cap; // TODO: We currently simply grow the memory to have space for exactly // inc_cap more elements. It would probably be smarter to grow the // memory a bit larger to reduce calls to realloc. void *newmem = realloc(*mem, newcap * elem_size); if (newmem == NULL) { return false; } *mem = newmem; *cap = newcap; return true; } bool apfl_resizable_append(size_t elem_size, void **mem, size_t *len, size_t *cap, const void *other_mem, size_t other_len) { size_t newlen = *len + other_len; if (newlen > *cap) { if (!apfl_resizable_grow_cap(elem_size, mem, len, cap, newlen - *cap)) { return false; } } memcpy(*((char**)mem) + (elem_size * *len), other_mem, other_len * elem_size); *len += other_len; return true; }