comparison array.c @ 8:127254037b30

Switch to a void * array instead of void **
author David Demelier <markand@malikania.fr>
date Wed, 07 Sep 2011 20:12:40 +0200
parents e8829146ebc7
children bf25ed2cf42a
comparison
equal deleted inserted replaced
7:e8829146ebc7 8:127254037b30
9 * 9 *
10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 14 * WHSIZESOEVER RESULTING FROM LOSS OF USE, DSIZEA OR PROFITS, WHETHER IN AN
15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17 */ 17 */
18 18
19 #include <stdio.h> 19 #include <stdio.h>
20 #include <stdlib.h> 20 #include <stdlib.h>
21 #include <string.h> 21 #include <string.h>
22 22
23 #include "array.h" 23 #include "array.h"
24 24
25 #define SIZE(x) (sizeof (void *) * (x)) 25 #define SIZE(x) (arr->unit * (x))
26 26
27 static int array_grow(struct array *); 27 static int array_grow(struct array *);
28 28
29 struct array * 29 struct array *
30 array_new(const void *data, size_t bsize, int flags) 30 array_new(const void *data, size_t unit, size_t bsize, int flags)
31 { 31 {
32 struct array *arr; 32 struct array *arr;
33 33
34 if (!(arr = malloc(sizeof (struct array)))) 34 if (unit == 0 || !(arr = malloc(sizeof (struct array))))
35 return NULL; 35 return NULL;
36 36
37 memset(arr, 0, sizeof (struct array));
38 arr->bsize = (bsize == 0) ? ARRAY_DEFAULT_BSIZE : bsize; 37 arr->bsize = (bsize == 0) ? ARRAY_DEFAULT_BSIZE : bsize;
39 arr->size = bsize + 1;
40 arr->flags = flags; 38 arr->flags = flags;
41 39 arr->unit = unit;
42 if (!(arr->data = calloc(bsize + 1, sizeof (void *)))) { 40 arr->size = SIZE(bsize);
41 arr->length = 0;
42
43 if (!(arr->data = malloc(arr->size))) {
43 free(arr); 44 free(arr);
44 return NULL; 45 return NULL;
45 } 46 }
46 47
47 if (data) 48 if (data)
48 arr->data[arr->length++] = (void *) data; 49 memcpy(&arr->data[0], data, arr->unit);
49 50
50 return arr; 51 return arr;
51 } 52 }
52 53
53 /* 54 /*
61 array_push(struct array *arr, const void *data) 62 array_push(struct array *arr, const void *data)
62 { 63 {
63 if (array_grow(arr) < 0) 64 if (array_grow(arr) < 0)
64 return -1; 65 return -1;
65 66
66 memmove(arr->data + 1, arr->data, SIZE(arr->length++)); 67 memmove(&arr->data[SIZE(1)], arr->data, SIZE(arr->length++));
67 arr->data[0] = (void *) data; 68 memcpy(&arr->data[0], data, arr->unit);
68 69
69 return 0; 70 return 0;
70 } 71 }
71 72
72 /* 73 /*
79 array_insert(struct array *arr, const void *data, int index) 80 array_insert(struct array *arr, const void *data, int index)
80 { 81 {
81 if (index > arr->length - 1 || index < 0 || array_grow(arr) < 0) 82 if (index > arr->length - 1 || index < 0 || array_grow(arr) < 0)
82 return -1; 83 return -1;
83 84
84 memmove(arr->data + index + 1, arr->data + index, 85 memmove(&arr->data[SIZE(index + 1)], &arr->data[SIZE(index)],
85 SIZE(arr->length++ - index)); 86 SIZE(arr->length++ - index));
86 arr->data[index] = (void *) data; 87 memcpy(&arr->data[SIZE(index)], data, arr->unit);
87 88
88 return 0; 89 return 0;
89 } 90 }
90 91
91 /* 92 /*
96 array_append(struct array *arr, const void *data) 97 array_append(struct array *arr, const void *data)
97 { 98 {
98 if (array_grow(arr) < 0) 99 if (array_grow(arr) < 0)
99 return -1; 100 return -1;
100 101
101 arr->data[arr->length++] = (void *) data; 102 memcpy(&arr->data[SIZE(arr->length++)], data, arr->unit);
102 103
103 return 0; 104 return 0;
104 } 105 }
105 106
106 /* 107 /*
114 void *data; 115 void *data;
115 116
116 if (arr->length == 0) 117 if (arr->length == 0)
117 return NULL; 118 return NULL;
118 119
119 data = arr->data[0]; 120 data = &arr->data[0];
120 memmove(arr->data, arr->data + 1, SIZE(arr->length)); 121 memmove(&arr->data[0], &arr->data[SIZE(1)], SIZE(arr->length));
121 arr->data[--arr->length] = NULL; 122 memset(&arr->data[SIZE(--arr->length)], 0, arr->unit);
122 123
123 return data; 124 return data;
124 } 125 }
125 126
126 /* 127 /*
134 void *data; 135 void *data;
135 136
136 if (arr->length == 0) 137 if (arr->length == 0)
137 return NULL; 138 return NULL;
138 139
139 data = arr->data[--arr->length]; 140 data = &arr->data[SIZE(--arr->length)];
140 arr->data[arr->length] = NULL; 141 memset(&arr->data[SIZE(arr->length)], 0, arr->unit);
141 142
142 return data; 143 return data;
143 } 144 }
144 145
145 /* 146 /*
153 void *data; 154 void *data;
154 155
155 if (arr->length == 0 || index < 0 || index > arr->length - 1) 156 if (arr->length == 0 || index < 0 || index > arr->length - 1)
156 return NULL; 157 return NULL;
157 158
158 data = arr->data[index]; 159 data = &arr->data[index];
159 memmove(arr->data + index, arr->data + index + 1, 160 memmove(&arr->data[index], &arr->data[index + 1],
160 SIZE(arr->length - index)); 161 SIZE(arr->length - index));
161 arr->data[--arr->length] = NULL; 162 memset(&arr->data[SIZE(--arr->length)], 0, arr->unit);
162 163
163 return data; 164 return data;
164 } 165 }
165 166
166 /* 167 /*
169 */ 170 */
170 171
171 void 172 void
172 array_map(struct array *arr, void (*fn)(void *, void *), void *udata) 173 array_map(struct array *arr, void (*fn)(void *, void *), void *udata)
173 { 174 {
174 size_t i; 175 int i;
175 176
176 for (i = 0; arr->data[i]; ++i) 177 for (i = 0; i < arr->length; ++i)
177 fn(arr->data[i], udata); 178 fn(&arr->data[i], udata);
178 } 179 }
179 180
180 /* 181 /*
181 * Compare each object with the user supplied function. If the `fn' function 182 * Compare each object with the user supplied function. If the `fn' function
182 * returns 1 then the data is returned. Optional idx argument can be set to 183 * returns 1 then the data is returned. Optional idx argument can be set to
185 */ 186 */
186 187
187 void * 188 void *
188 array_find(struct array *arr, int (*fn)(void *, void *), void *udata, int *idx) 189 array_find(struct array *arr, int (*fn)(void *, void *), void *udata, int *idx)
189 { 190 {
190 size_t i; 191 int st, i;
191 int st; 192 void *data;
192 void *data; 193
193 194 for (i = st = 0; i < arr->length && !st; ++i)
194 for (i = st = 0; arr->data[i] && !st; ++i) 195 st = fn(&arr->data[i], udata);
195 st = fn(arr->data[i], udata);
196 196
197 if (st) { 197 if (st) {
198 data = arr->data[--i]; 198 data = &arr->data[--i];
199 if (idx) 199 if (idx)
200 *idx = i; 200 *idx = i;
201 } else 201 } else
202 data = NULL; 202 data = NULL;
203 203
208 * Reset the array, if the trash argument is set it will free the object 208 * Reset the array, if the trash argument is set it will free the object
209 * too, otherwise the array is just truncated to 0 length. 209 * too, otherwise the array is just truncated to 0 length.
210 */ 210 */
211 211
212 void 212 void
213 array_clear(struct array *arr, int trashit) 213 array_clear(struct array *arr)
214 { 214 {
215 if (trashit) { 215 memset(arr->data, 0, arr->size);
216 size_t i;
217
218 for (i = 0; arr->data[i]; ++i)
219 free(arr->data[i]);
220 }
221
222 memset(arr->data, 0, SIZE(arr->size));
223 arr->length = 0; 216 arr->length = 0;
224 } 217 }
225 218
226 /* 219 /*
227 * Same as array_clear except it also free the array object. 220 * Same as array_clear except it also free the array object.
228 */ 221 */
229 222
230 void 223 void
231 array_free(struct array *arr, int trashit) 224 array_free(struct array *arr)
232 { 225 {
233 array_clear(arr, trashit); 226 array_clear(arr);
234 227
235 free(arr->data); 228 free(arr->data);
236 free(arr); 229 free(arr);
237 } 230 }
238 231
243 */ 236 */
244 237
245 static int 238 static int
246 array_grow(struct array *arr) 239 array_grow(struct array *arr)
247 { 240 {
248 if (arr->size - 1 > arr->length) 241 if (arr->size / arr->unit > arr->length)
249 return 0; 242 return 0;
250 243
251 if (arr->flags & ARRAY_AUTO) { 244 if (arr->flags & ARRAY_AUTO) {
252 if (!(arr->data = realloc(arr->data, SIZE(arr->size + arr->bsize)))) 245 if (!(arr->data = realloc(arr->data, arr->size +
246 SIZE(arr->bsize))))
253 return -1; 247 return -1;
254 248
255 arr->size += arr->bsize; 249 arr->size += arr->bsize;
256 } else 250 } else
257 return (arr->size - 1 == arr->length) ? -1 : 0; 251 return ((arr->size / arr->unit) <= arr->length) ? -1 : 0;
258 252
259 memset(arr->data + arr->length, 0, SIZE(arr->size - arr->length)); 253 return 0;
260 254 }
261 return 0;
262 }