Mercurial > code
comparison array.c @ 34:653bb22d3c0c
For array.c:
o No index needed in ARRAY_FOREACH or ARRAY_FOREACH_R, it is stored in
the structure.
o Added a function to remove by data : array_unref()
author | David Demelier <markand@malikania.fr> |
---|---|
date | Fri, 30 Sep 2011 16:38:40 +0200 |
parents | e532a973f43d |
children | b972758ddcd5 |
comparison
equal
deleted
inserted
replaced
33:23a3ebcbf08e | 34:653bb22d3c0c |
---|---|
25 #define OFFSET(x) (arr->unit * (x)) | 25 #define OFFSET(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 unit, size_t bsize, int flags) | 30 array_new(const void *data, size_t unit, int bsize, int type) |
31 { | 31 { |
32 struct array *arr; | 32 struct array *arr; |
33 | 33 |
34 if (unit == 0 || (arr = malloc(sizeof (struct array))) == NULL) | 34 if (unit == 0 || (arr = malloc(sizeof (struct array))) == NULL) |
35 return NULL; | 35 return NULL; |
36 | 36 |
37 arr->tmp = NULL; | 37 memset(arr, 0, sizeof (struct array)); |
38 arr->length = 0; | 38 |
39 arr->flags = flags; | 39 arr->type = type; |
40 arr->bsize = (bsize == 0) ? ARRAY_DEFAULT_BSIZE : bsize; | 40 arr->bsize = (bsize == 0) ? ARRAY_DEFAULT_BSIZE : bsize; |
41 arr->unit = unit; | 41 arr->unit = unit; |
42 arr->size = OFFSET(arr->bsize); | 42 arr->size = OFFSET(arr->bsize); |
43 | 43 |
44 if ((arr->data = malloc(arr->size)) == NULL) { | 44 if ((arr->data = malloc(arr->size)) == NULL) { |
142 memset((char *) arr->data + OFFSET(--arr->length), 0, arr->unit); | 142 memset((char *) arr->data + OFFSET(--arr->length), 0, arr->unit); |
143 } | 143 } |
144 } | 144 } |
145 | 145 |
146 /* | 146 /* |
147 * Remove the object referenced by the `data' argument. Useful when you | |
148 * don't know the index. | |
149 */ | |
150 | |
151 struct personne { | |
152 char *name; | |
153 int age; | |
154 }; | |
155 | |
156 void | |
157 array_unref(struct array *arr, const void *data) | |
158 { | |
159 void *elm; | |
160 int i; | |
161 | |
162 for (i = 0; i < arr->length; ++i) { | |
163 elm = ARRAY_INDEX(arr, i); | |
164 | |
165 if (memcmp(elm, data, arr->unit) == 0) | |
166 array_remove(arr, i); | |
167 } | |
168 } | |
169 | |
170 /* | |
147 * Swap the two elements referenced by index `i1' and `i2'. This function needs | 171 * Swap the two elements referenced by index `i1' and `i2'. This function needs |
148 * to allocate data to swap elements thus if the functions fails it returns -1 | 172 * to allocate data to swap elements thus if the functions fails it returns -1 |
149 * otherwise 0 is returned. | 173 * otherwise 0 is returned. |
150 */ | 174 */ |
151 | 175 |
159 /* | 183 /* |
160 * Only allocate at this time, the user may do not want to use this | 184 * Only allocate at this time, the user may do not want to use this |
161 * function. | 185 * function. |
162 */ | 186 */ |
163 | 187 |
164 if (arr->tmp == NULL && (arr->tmp = malloc(arr->unit)) == NULL) | 188 if (arr->_tmp == NULL && (arr->_tmp = malloc(arr->unit)) == NULL) |
165 return -1; | 189 return -1; |
166 | 190 |
167 memcpy((char *) arr->tmp, (char *) arr->data + OFFSET(i1), arr->unit); | 191 memcpy((char *) arr->_tmp, (char *) arr->data + OFFSET(i1), arr->unit); |
168 memcpy((char *) arr->data + OFFSET(i1), (char *) arr->data + OFFSET(i2), | 192 memcpy((char *) arr->data + OFFSET(i1), (char *) arr->data + OFFSET(i2), |
169 arr->unit); | 193 arr->unit); |
170 memcpy((char *) arr->data + OFFSET(i2), (char *) arr->tmp, arr->unit); | 194 memcpy((char *) arr->data + OFFSET(i2), (char *) arr->_tmp, arr->unit); |
195 | |
196 /* | |
197 * Clear bytes for safety. | |
198 */ | |
199 | |
200 memset(arr->_tmp, 0, arr->unit); | |
171 | 201 |
172 return 0; | 202 return 0; |
173 } | 203 } |
174 | 204 |
175 /* | 205 /* |
233 { | 263 { |
234 array_clear(arr); | 264 array_clear(arr); |
235 | 265 |
236 if (arr->data) | 266 if (arr->data) |
237 free(arr->data); | 267 free(arr->data); |
238 if (arr->tmp) | 268 if (arr->_tmp) |
239 free(arr->tmp); | 269 free(arr->_tmp); |
240 | 270 |
241 free(arr); | 271 free(arr); |
242 } | 272 } |
243 | 273 |
244 /* | 274 /* |
251 array_grow(struct array *arr) | 281 array_grow(struct array *arr) |
252 { | 282 { |
253 if ((arr->size / arr->unit) > (size_t) arr->length) | 283 if ((arr->size / arr->unit) > (size_t) arr->length) |
254 return 0; | 284 return 0; |
255 | 285 |
256 if (arr->flags & ARRAY_AUTO) { | 286 if (arr->type == ARRAY_AUTO) { |
257 if ((arr->data = realloc(arr->data, arr->size + | 287 if ((arr->data = realloc(arr->data, arr->size + |
258 OFFSET(arr->bsize))) == NULL) | 288 OFFSET(arr->bsize))) == NULL) |
259 return -1; | 289 return -1; |
260 | 290 |
261 arr->size += OFFSET(arr->bsize); | 291 arr->size += OFFSET(arr->bsize); |