diff options
Diffstat (limited to 'src/sblist.c')
-rw-r--r-- | src/sblist.c | 80 |
1 files changed, 80 insertions, 0 deletions
diff --git a/src/sblist.c b/src/sblist.c new file mode 100644 index 0000000..4ddc4aa --- /dev/null +++ b/src/sblist.c @@ -0,0 +1,80 @@ +#undef _POSIX_C_SOURCE +#define _POSIX_C_SOURCE 200809L +#include "sblist.h" +#include <limits.h> +#include <stdlib.h> +#include <string.h> +#define MY_PAGE_SIZE 4096 + +sblist* sblist_new(size_t itemsize, size_t blockitems) { + sblist* ret = (sblist*) malloc(sizeof(sblist)); + sblist_init(ret, itemsize, blockitems); + return ret; +} + +static void sblist_clear(sblist* l) { + l->items = NULL; + l->capa = 0; + l->count = 0; +} + +void sblist_init(sblist* l, size_t itemsize, size_t blockitems) { + if(l) { + l->blockitems = blockitems ? blockitems : MY_PAGE_SIZE / itemsize; + l->itemsize = itemsize; + sblist_clear(l); + } +} + +void sblist_free_items(sblist* l) { + if(l) { + if(l->items) free(l->items); + sblist_clear(l); + } +} + +void sblist_free(sblist* l) { + if(l) { + sblist_free_items(l); + free(l); + } +} + +char* sblist_item_from_index(sblist* l, size_t idx) { + return l->items + (idx * l->itemsize); +} + +void* sblist_get(sblist* l, size_t item) { + if(item < l->count) return (void*) sblist_item_from_index(l, item); + return NULL; +} + +int sblist_set(sblist* l, void* item, size_t pos) { + if(pos >= l->count) return 0; + memcpy(sblist_item_from_index(l, pos), item, l->itemsize); + return 1; +} + +int sblist_grow_if_needed(sblist* l) { + char* temp; + if(l->count == l->capa) { + temp = realloc(l->items, (l->capa + l->blockitems) * l->itemsize); + if(!temp) return 0; + l->capa += l->blockitems; + l->items = temp; + } + return 1; +} + +int sblist_add(sblist* l, void* item) { + if(!sblist_grow_if_needed(l)) return 0; + l->count++; + return sblist_set(l, item, l->count - 1); +} + +void sblist_delete(sblist* l, size_t item) { + if (l->count && item < l->count) { + memmove(sblist_item_from_index(l, item), sblist_item_from_index(l, item + 1), (sblist_getsize(l) - (item + 1)) * l->itemsize); + l->count--; + } +} |