src/array_list.c

changeset 610
de5d3ee6435f
parent 607
2d99e978dc34
child 611
77efa5163ae5
equal deleted inserted replaced
609:6ae8146d9f62 610:de5d3ee6435f
25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26 * POSSIBILITY OF SUCH DAMAGE. 26 * POSSIBILITY OF SUCH DAMAGE.
27 */ 27 */
28 28
29 #include "cx/array_list.h" 29 #include "cx/array_list.h"
30 #include <assert.h>
31 #include <string.h>
30 32
31 /* LOW LEVEL ARRAY LIST FUNCTIONS */ 33 /* LOW LEVEL ARRAY LIST FUNCTIONS */
32 34
33 35 enum cx_array_coppy_result cx_array_copy(
36 void **target,
37 size_t *size,
38 size_t *capacity,
39 size_t index,
40 void const *src,
41 size_t elem_size,
42 size_t elem_count,
43 struct cx_array_reallocator_s *reallocator
44 ) {
45 /* assert pointers */
46 assert(target != NULL);
47 assert(size != NULL);
48 assert(src != NULL);
49
50 /* determine capacity */
51 size_t cap = capacity == NULL ? *size : *capacity;
52
53 /* check if resize is required */
54 size_t newsize = index + elem_count;
55 bool needrealloc = newsize > cap;
56
57 /* reallocate if possible */
58 if (needrealloc) {
59 /* a reallocator and a capacity variable must be available */
60 if (reallocator == NULL || capacity == NULL) {
61 return CX_ARRAY_COPY_REALLOC_NOT_SUPPORTED;
62 }
63
64 /* increase capacity linearly */
65 cap += 16;
66
67 /* perform reallocation */
68 void *newmem = reallocator->realloc(
69 *target, cap, elem_size, reallocator
70 );
71 if (newmem == NULL) {
72 return CX_ARRAY_COPY_REALLOC_FAILED;
73 }
74
75 /* store new pointer and capacity */
76 *target = newmem;
77 *capacity = cap;
78 }
79
80 /* determine target pointer */
81 char *start = *target;
82 start += index * elem_size;
83
84 /* copy elements and set new size */
85 memcpy(start, src, elem_count * elem_size);
86 *size = newsize;
87
88 /* return successfully */
89 return CX_ARRAY_COPY_SUCCESS;
90 }
34 91
35 /* HIGH LEVEL ARRAY LIST FUNCTIONS */ 92 /* HIGH LEVEL ARRAY LIST FUNCTIONS */
36 93
37 typedef struct { 94 typedef struct {
38 struct cx_list_s base; 95 struct cx_list_s base;
39 void *data; 96 void *data;
97 struct cx_array_reallocator_s reallocator;
40 } cx_array_list; 98 } cx_array_list;
41 99
100 static void *cx_arl_realloc(
101 void *array,
102 size_t capacity,
103 size_t elem_size,
104 struct cx_array_reallocator_s *alloc
105 ) {
106 /* retrieve the pointer to the list allocator */
107 CxAllocator const *al = alloc->ptr1;
108
109 /* use the list allocator to reallocate the memory */
110 return cxRealloc(al, array, capacity * elem_size);
111 }
112
42 static void cx_arl_destructor(struct cx_list_s *list) { 113 static void cx_arl_destructor(struct cx_list_s *list) {
43 cx_array_list *arl = (cx_array_list*) list; 114 cx_array_list *arl = (cx_array_list *) list;
44 cxFree(list->allocator, arl->data); 115 cxFree(list->allocator, arl->data);
45 } 116 }
46 117
47 static int cx_arl_add( 118 static int cx_arl_add(
48 struct cx_list_s *list, 119 struct cx_list_s *list,
49 void const *elem 120 void const *elem
50 ) { 121 ) {
51 return 1; 122 cx_array_list *arl = (cx_array_list *) list;
123 return cx_array_copy(
124 &arl->data,
125 &list->size,
126 &list->capacity,
127 list->size,
128 elem,
129 list->itemsize,
130 1,
131 &arl->reallocator
132 );
52 } 133 }
53 134
54 static int cx_arl_insert( 135 static int cx_arl_insert(
55 struct cx_list_s *list, 136 struct cx_list_s *list,
56 size_t index, 137 size_t index,
72 size_t index 153 size_t index
73 ) { 154 ) {
74 return 1; 155 return 1;
75 } 156 }
76 157
77 static void * cx_arl_at( 158 static void *cx_arl_at(
78 struct cx_list_s const *list, 159 struct cx_list_s const *list,
79 size_t index 160 size_t index
80 ) { 161 ) {
81 return NULL; 162 if (index < list->size) {
163 cx_array_list const *arl = (cx_array_list const *) list;
164 char *space = arl->data;
165 return space + index * list->itemsize;
166 } else {
167 return NULL;
168 }
82 } 169 }
83 170
84 static size_t cx_arl_find( 171 static size_t cx_arl_find(
85 struct cx_list_s const *list, 172 struct cx_list_s const *list,
86 void const *elem 173 void const *elem
145 list->base.allocator = allocator; 232 list->base.allocator = allocator;
146 list->base.cmpfunc = comparator; 233 list->base.cmpfunc = comparator;
147 list->base.itemsize = item_size; 234 list->base.itemsize = item_size;
148 list->base.capacity = initial_capacity; 235 list->base.capacity = initial_capacity;
149 236
237 /* configure the reallocator */
238 list->reallocator.realloc = cx_arl_realloc;
239 list->reallocator.ptr1 = (void *) allocator;
240
150 return (CxList *) list; 241 return (CxList *) list;
151 } 242 }

mercurial