summaryrefslogtreecommitdiffhomepage
path: root/src/sblist.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/sblist.c')
-rw-r--r--src/sblist.c80
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--;
+ }
+}