1 // This is a simple implementation of an elastic array class in pure C language.
3 // Copyright (c) 2021-2023 by Art Cancro
5 // This program is open source software. Use, duplication, or disclosure
6 // is subject to the terms of the GNU General Public License, version 3.
12 #include "libcitadel.h"
15 // Constructor for elastic array
16 Array *array_new(size_t element_size) {
17 Array *newarr = malloc(sizeof(Array));
19 memset(newarr, 0, sizeof(Array));
21 newarr->element_size = element_size;
26 // Destructor for elastic array
27 void array_free(Array *arr) {
28 free(arr->the_elements);
33 // Append an element to an array (we already know the element size because it's in the data type)
34 void array_append(Array *arr, void *new_element) {
36 if (!arr) { // silently fail if they gave us a null array
40 if ( (arr->the_elements == NULL) || (arr->num_alloc == 0)) {
42 arr->num_elements = 0;
43 arr->the_elements = malloc(arr->element_size * arr->num_alloc);
44 if (arr->the_elements == NULL) {
50 if (arr->num_elements > arr->num_alloc) {
51 arr->num_alloc = arr->num_alloc * 2; // whenever we exceed the buffer size, we double it.
52 arr->the_elements = realloc(arr->the_elements, (arr->element_size * arr->num_alloc));
53 if (arr->the_elements == NULL) {
58 memcpy((arr->the_elements + ( (arr->num_elements-1) * arr->element_size )), new_element, arr->element_size);
62 // Return the element in an array at the specified index
63 void *array_get_element_at(Array *arr, int index) {
64 return (arr->the_elements + ( index * arr->element_size ));
68 // Return the number of elements in an array
69 int array_len(Array *arr) {
74 return arr->num_elements;
78 // Sort an array. We already know the element size and number of elements, so all we need is
79 // a sort function, which we will pass along to qsort().
80 void array_sort(Array *arr, int (*compar)(const void *, const void *)) {
81 qsort(arr->the_elements, arr->num_elements, arr->element_size, compar);
85 // Delete an element from an array
86 void array_delete_element_at(Array *arr, int index) {
88 if (index >= arr->num_elements) { // If the supplied index is out of bounds, return quietly.
92 if (index < 0) { // If the supplied index is invalid, return quietly.
98 if (index == arr->num_elements) { // If we deleted the element at the end, there's no more to be done.
102 memmove( // memmove() is supposed to be safer than memcpy()
103 (arr->the_elements + (index * arr->element_size)),
104 arr->the_elements + ((index+1) * arr->element_size),
105 (arr->num_elements - index) * arr->element_size