view: add functions to save/restore arbitrary ranges
[vis.git] / array.c
blobd0f937dd322d2b56d285a37fa9dbb7d969564e5e
1 #include <stdlib.h>
2 #include <string.h>
3 #include <errno.h>
5 #include "array.h"
6 #include "util.h"
8 #define ARRAY_SIZE 16
10 void array_init(Array *arr) {
11 array_init_sized(arr, sizeof(void*));
14 void array_init_sized(Array *arr, size_t elem_size) {
15 memset(arr, 0, sizeof *arr);
16 arr->elem_size = elem_size;
19 bool array_reserve(Array *arr, size_t count) {
20 if (count < ARRAY_SIZE)
21 count = ARRAY_SIZE;
22 if (arr->count < count) {
23 count = MAX(count, arr->count*2);
24 char *items = realloc(arr->items, count * arr->elem_size);
25 if (!items)
26 return false;
27 arr->count = count;
28 arr->items = items;
30 return true;
33 void array_release(Array *arr) {
34 if (!arr)
35 return;
36 free(arr->items);
37 array_init_sized(arr, arr->elem_size);
40 void array_release_full(Array *arr) {
41 if (!arr)
42 return;
43 for (size_t i = 0; i < arr->len; i++)
44 free(array_get_ptr(arr, i));
45 array_release(arr);
48 void array_clear(Array *arr) {
49 arr->len = 0;
50 if (arr->items)
51 memset(arr->items, 0, arr->count * arr->elem_size);
54 void *array_get(Array *arr, size_t idx) {
55 if (idx >= arr->len) {
56 errno = EINVAL;
57 return NULL;
59 return arr->items + (idx * arr->elem_size);
62 void *array_get_ptr(Array *arr, size_t idx) {
63 if (arr->elem_size != sizeof(void*)) {
64 errno = ENOTSUP;
65 return NULL;
67 void **ptr = array_get(arr, idx);
68 return ptr ? *ptr : NULL;
71 bool array_set(Array *arr, size_t idx, void *item) {
72 if (idx >= arr->len) {
73 errno = EINVAL;
74 return false;
76 if (item)
77 memcpy(arr->items + (idx * arr->elem_size), item, arr->elem_size);
78 else
79 memset(arr->items + (idx * arr->elem_size), 0, arr->elem_size);
80 return true;
83 bool array_set_ptr(Array *arr, size_t idx, void *item) {
84 if (arr->elem_size != sizeof(void*)) {
85 errno = ENOTSUP;
86 return false;
88 return array_set(arr, idx, &item);
91 bool array_add(Array *arr, void *item) {
92 if (!array_reserve(arr, arr->len+1))
93 return false;
94 if (!array_set(arr, arr->len++, item)) {
95 arr->len--;
96 return false;
98 return true;
101 bool array_add_ptr(Array *arr, void *item) {
102 if (!array_reserve(arr, arr->len+1))
103 return false;
104 if (!array_set_ptr(arr, arr->len++, item)) {
105 arr->len--;
106 return false;
108 return true;
111 bool array_remove(Array *arr, size_t idx) {
112 if (idx >= arr->len) {
113 errno = EINVAL;
114 return false;
116 char *dest = arr->items + idx * arr->elem_size;
117 char *src = arr->items + (idx + 1) * arr->elem_size;
118 memmove(dest, src, (arr->len - idx) * arr->elem_size);
119 arr->len--;
120 return true;
123 size_t array_length(Array *arr) {
124 return arr->len;
127 size_t array_capacity(Array *arr) {
128 return arr->count;
131 bool array_truncate(Array *arr, size_t len) {
132 if (len <= arr->len) {
133 arr->len = len;
134 return true;
136 return false;
139 bool array_resize(Array *arr, size_t len) {
140 if (len <= arr->count) {
141 arr->len = len;
142 return true;
144 return false;
147 void array_sort(Array *arr, int (*compar)(const void*, const void*)) {
148 qsort(arr->items, arr->len, arr->elem_size, compar);