diff --git a/src/arraylist.c b/src/arraylist.c index 3e8cf12..7dde558 100644 --- a/src/arraylist.c +++ b/src/arraylist.c @@ -1,11 +1,11 @@ #include "arraylist.h" -#include #include +#include #include #include struct ArrayList{ - void *data; + uint8_t *buffer; size_t capacity; size_t len; size_t elem_size; @@ -33,8 +33,8 @@ ArrayList *arraylist_init(size_t capacity, size_t elem_size) { arr->capacity = capacity; arr->elem_size = elem_size; arr->len = 0; - arr->data = malloc(capacity * elem_size); - if (arr->data == NULL) { + arr->buffer = malloc(capacity * elem_size); + if (arr->buffer == NULL) { free(arr); return NULL; } @@ -50,8 +50,8 @@ ArrayListErr arraylist_destroy(ArrayList *arr) { arr->capacity = 0; arr->elem_size = 0; arr->len = 0; - free(arr->data); - arr->data = NULL; + free(arr->buffer); + arr->buffer = NULL; free(arr); return ARRLIST_OK; } @@ -61,7 +61,7 @@ ArrayListErr arraylist_clear(ArrayList *arr) { return ARRLIST_NULL_ARG; } - memset(arr->data, 0, arr->capacity * arr->elem_size); + memset(arr->buffer, 0, arr->capacity * arr->elem_size); arr->capacity = 0; arr->elem_size = 0; arr->len = 0; @@ -94,22 +94,98 @@ static ArrayListErr arraylist_grow(ArrayList *arr) { // and only used by funtions that already verified // arr is not null, same with shrink. size_t new_capacity = arr->capacity * 2; - void *tmp = realloc(arr->data, new_capacity * arr->elem_size); + void *tmp = realloc(arr->buffer, new_capacity * arr->elem_size); if (tmp == NULL) { return ARRLIST_BAD_ALLOC; } arr->capacity = new_capacity; - arr->data = tmp; + arr->buffer = tmp; return ARRLIST_OK; } static ArrayListErr arraylist_shrink(ArrayList *arr) { size_t new_capacity = arr->capacity / 2; - void *tmp = realloc(arr->data, new_capacity *arr->elem_size); + void *tmp = realloc(arr->buffer, new_capacity *arr->elem_size); if (tmp == NULL) { return ARRLIST_BAD_ALLOC; } arr->capacity = new_capacity; - arr->data = tmp; + arr->buffer = tmp; return ARRLIST_OK; } + +ArrayListErr arraylist_push_back(ArrayList *arr, void *data) { + if (arr == NULL || data == NULL) { + return ARRLIST_NULL_ARG; + } + + if (arr->len >= arr->capacity) { + ArrayListErr err = arraylist_grow(arr); + + if (err != ARRLIST_OK) { + return err; + } + } + + memcpy(arr->buffer, data, arr->elem_size); + arr->len++; + return ARRLIST_OK; +} + +ArrayListErr arraylist_push_front(ArrayList *arr, void *data) { + if (arr == NULL || data == NULL) { + return ARRLIST_NULL_ARG; + } + + if (arr->len >= arr->capacity) { + ArrayListErr err = arraylist_grow(arr); + + if (err != ARRLIST_OK) { + return err; + } + } + + // No problem if array is full because it grows if it's full + for (size_t i = arr->len - 1; i >= 0; i--) { + memcpy( + arr->buffer + ((i + 1) * arr->elem_size), + arr->buffer + (i * arr->elem_size), + arr->elem_size); + } + + memcpy(arr->buffer, data, arr->elem_size); + arr->len++; + + return ARRLIST_OK; +} + +ArrayListErr arraylist_insert(ArrayList *arr, size_t index, void *data) { + if (arr == NULL || data == NULL) { + return ARRLIST_NULL_ARG; + } + + if (index >= arr->len) { + return ARRLIST_OUT_OF_BOUNDS; + } + + if (arr->len >= arr->capacity) { + ArrayListErr err = arraylist_grow(arr); + if (err != ARRLIST_OK) { + return err; + } + } + + for (size_t i = arr->len - 1; i >= index; i--) { + memcpy( + arr->buffer + ((i + 1) * arr->elem_size), + arr->buffer + (i * arr->elem_size), + arr->elem_size); + } + + memcpy(arr->buffer + (index * arr->elem_size), data, arr->elem_size); + arr->len++; + + return ARRLIST_OK; +} + +