75 lines
1.7 KiB
C
75 lines
1.7 KiB
C
|
|
#include <assert.h>
|
||
|
|
#include <stdlib.h>
|
||
|
|
#include <stddef.h>
|
||
|
|
#include <stdbool.h>
|
||
|
|
#include <string.h>
|
||
|
|
|
||
|
|
#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 + elem_size * 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);
|
||
|
|
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;
|
||
|
|
}
|