#include <errno.h>
#include <stdlib.h>
#include <string.h>
#include "si_array.h"
typedef struct {
void *data;
uint32_t len;
uint32_t eltm_capacity;
uint32_t eltm_size;
} _si_array_t;
#define si_array_eltm_len(arr, len) ((uint32_t)(arr)->eltm_size * (len))
#define si_array_eltm_pos(arr, i) ((arr)->data + si_array_eltm_len((arr), (i)))
#define DEFAULT_ARRAY_CAP 32
#define MAX_ELEMENT_SIZE 536870912
si_array_t *si_array_new(uint32_t elem_size)
{
_si_array_t *arr;
if (elem_size == 0 || elem_size > MAX_ELEMENT_SIZE) {
return NULL;
}
arr = malloc(sizeof(_si_array_t));
if (!arr) {
return NULL;
}
arr->data = malloc(elem_size * DEFAULT_ARRAY_CAP);
arr->len = 0;
arr->eltm_capacity = DEFAULT_ARRAY_CAP;
arr->eltm_size = elem_size;
return (si_array_t *)arr;
}
void si_array_free(si_array_t *_arr)
{
_si_array_t *arr = (_si_array_t *)_arr;
free(arr->data);
free(arr);
}
static void si_array_maybe_expand(_si_array_t *arr, uint32_t elem_nr)
{
uint32_t need_len;
void *tmp;
need_len = arr->len + elem_nr;
if (need_len <= arr->eltm_capacity) {
return;
}
need_len = max(need_len, arr->eltm_capacity * 2);
tmp = realloc(arr->data, si_array_eltm_len(arr, need_len));
arr->data = tmp;
arr->eltm_capacity = need_len;
}
int si_array_append_vals(si_array_t *_arr, void *data, uint32_t elem_nr)
{
_si_array_t *arr = (_si_array_t *)_arr;
if (!arr || (elem_nr == 0)) {
return -1;
}
si_array_maybe_expand(arr, elem_nr);
int data_len = si_array_eltm_len(arr, elem_nr);
memcpy(si_array_eltm_pos(arr, arr->len), data, data_len);
arr->len += elem_nr;
return 0;
}
void si_array_sort(si_array_t *_arr, si_cmp_func cmp_func)
{
_si_array_t *arr = (_si_array_t *)_arr;
if (arr->len == 0) {
return;
}
qsort(arr->data, arr->len, arr->eltm_size, cmp_func);
}
si_array_t *si_array_new_strings(void)
{
return si_array_new(sizeof(char *));
}
void si_array_free_strings(si_array_t *_arr)
{
si_array_free(_arr);
}
int si_array_append_strings(si_array_t *_arr, char *item)
{
return si_array_append(_arr, &item);
}
bool si_array_in_strings(si_array_t *_arr, char *item)
{
int len = _arr->len;
char **string_arr = _arr->data;
char *string_item = NULL;
for (int i = 0; i < len; i++) {
string_item = string_arr[i];
if (strcmp(string_item, item) == 0) {
return true;
}
}
return false;
}
int si_array_append_strings_uniq(si_array_t *_arr, char *item)
{
if (si_array_in_strings(_arr, item) == true) {
return -1;
}
return si_array_append(_arr, &item);
}
void si_array_foreach_strings(si_array_t *_arr, si_foreach_func foreach_func, void *pridata)
{
_si_array_t *arr = (_si_array_t *)_arr;
if (arr->len == 0) {
return;
}
int len = _arr->len;
char **string_arr = _arr->data;
char *string_item = NULL;
for (int i = 0; i < len; i++) {
string_item = string_arr[i];
if (foreach_func(string_item, pridata) != 0) {
return;
}
}
}