CPlay/dynbuf/dynbuf.c

79 lines
1.6 KiB
C

#include "dynbuf.h"
#include <stdio.h>
#ifndef GROWTH_FACTOR
#define GROWTH_FACTOR 2
#endif
#ifndef INITIAL_CAPACITY
#define INITIAL_CAPACITY 4
#endif
#ifdef GROWTH_POW2
#define ROUND_UP_POW2(x) round_up_pow2(x)
static inline int round_up_pow2(int x) {
if (x <= 1)
return 1;
x--;
x |= x >> 1;
x |= x >> 2;
x |= x >> 4;
x |= x >> 8;
x |= x >> 16;
return x + 1;
}
#else
#define ROUND_UP_POW2(x) (x)
#endif
void dynbuf_init(Dynbuf *v, size_t elem_size) {
v->elem_size = elem_size;
v->length = 0;
v->capacity = INITIAL_CAPACITY;
v->data = malloc(v->capacity * elem_size);
assert(v->data != NULL);
}
void dynbuf_free(Dynbuf *v) {
free(v->data);
v->data = NULL;
v->length = 0;
v->capacity = 0;
v->elem_size = 0;
}
void dynbuf_push(Dynbuf *v, const void *elem) {
if (v->length == v->capacity) {
dynbuf_resize(v, ROUND_UP_POW2(v->capacity * GROWTH_FACTOR));
}
memcpy((char *)v->data + v->length * v->elem_size, elem, v->elem_size);
v->length++;
}
void dynbuf_resize(Dynbuf *v, size_t newcap) {
printf("Resize to %zu\n", newcap);
if (newcap > v->capacity) {
v->capacity = newcap;
v->data = realloc(v->data, v->capacity * v->elem_size);
assert(v->data != NULL);
}
}
void dynbuf_pop(Dynbuf *v) {
if (v->length > 0) {
v->length--;
}
}
void *dynbuf_get(Dynbuf *v, size_t index) {
assert(index < v->length);
return (char *)v->data + index * v->elem_size;
}
inline size_t dynbuf_size(const Dynbuf *v) { return v->length; }
inline size_t dynbuf_capacity(const Dynbuf *v) { return v->capacity; }