59 /* a reallocator and a capacity variable must be available */ |
60 /* a reallocator and a capacity variable must be available */ |
60 if (reallocator == NULL || capacity == NULL) { |
61 if (reallocator == NULL || capacity == NULL) { |
61 return CX_ARRAY_COPY_REALLOC_NOT_SUPPORTED; |
62 return CX_ARRAY_COPY_REALLOC_NOT_SUPPORTED; |
62 } |
63 } |
63 |
64 |
|
65 /* check, if we need to repair the src pointer */ |
|
66 uintptr_t targetaddr = (uintptr_t) *target; |
|
67 uintptr_t srcaddr = (uintptr_t) src; |
|
68 bool repairsrc = targetaddr <= srcaddr |
|
69 && srcaddr < targetaddr + cap * elem_size; |
|
70 |
64 /* increase capacity linearly */ |
71 /* increase capacity linearly */ |
65 cap += 16; |
72 cap += 16; |
66 |
73 |
67 /* perform reallocation */ |
74 /* perform reallocation */ |
68 void *newmem = reallocator->realloc( |
75 void *newmem = reallocator->realloc( |
70 ); |
77 ); |
71 if (newmem == NULL) { |
78 if (newmem == NULL) { |
72 return CX_ARRAY_COPY_REALLOC_FAILED; |
79 return CX_ARRAY_COPY_REALLOC_FAILED; |
73 } |
80 } |
74 |
81 |
|
82 /* repair src pointer, if necessary */ |
|
83 if (repairsrc) { |
|
84 src = ((char *) newmem) + (srcaddr - targetaddr); |
|
85 } |
|
86 |
75 /* store new pointer and capacity */ |
87 /* store new pointer and capacity */ |
76 *target = newmem; |
88 *target = newmem; |
77 *capacity = cap; |
89 *capacity = cap; |
78 } |
90 } |
79 |
91 |
80 /* determine target pointer */ |
92 /* determine target pointer */ |
81 char *start = *target; |
93 char *start = *target; |
82 start += index * elem_size; |
94 start += index * elem_size; |
83 |
95 |
84 /* copy elements and set new size */ |
96 /* copy elements and set new size */ |
85 memcpy(start, src, elem_count * elem_size); |
97 memmove(start, src, elem_count * elem_size); |
86 *size = newsize; |
98 *size = newsize; |
87 |
99 |
88 /* return successfully */ |
100 /* return successfully */ |
89 return CX_ARRAY_COPY_SUCCESS; |
101 return CX_ARRAY_COPY_SUCCESS; |
90 } |
102 } |
135 static int cx_arl_insert( |
147 static int cx_arl_insert( |
136 struct cx_list_s *list, |
148 struct cx_list_s *list, |
137 size_t index, |
149 size_t index, |
138 void const *elem |
150 void const *elem |
139 ) { |
151 ) { |
140 return 1; |
152 if (index > list->size) { |
|
153 return 1; |
|
154 } else if (index == list->size) { |
|
155 return cx_arl_add(list, elem); |
|
156 } else { |
|
157 cx_array_list *arl = (cx_array_list *) list; |
|
158 |
|
159 /* move elements starting at index to the right */ |
|
160 if (cx_array_copy( |
|
161 &arl->data, |
|
162 &list->size, |
|
163 &list->capacity, |
|
164 index + 1, |
|
165 ((char *) arl->data) + index * list->itemsize, |
|
166 list->itemsize, |
|
167 list->size - index, |
|
168 &arl->reallocator |
|
169 )) { |
|
170 return 1; |
|
171 } |
|
172 |
|
173 /* place the element */ |
|
174 memcpy(((char *) arl->data) + index * list->itemsize, |
|
175 elem, list->itemsize); |
|
176 |
|
177 return 0; |
|
178 } |
141 } |
179 } |
142 |
180 |
143 static int cx_arl_insert_iter( |
181 static int cx_arl_insert_iter( |
144 struct cx_iterator_s *iter, |
182 struct cx_iterator_s *iter, |
145 void const *elem, |
183 void const *elem, |