Mercurial > code
diff array.c @ 136:c6d9eb5702e8
array:
o add ARRAY_FASTREMOVE, use last object when removing,
o add ARRAY_CLEARBITS, set to 0 the bytes when removing
parray:
o add PARRAY_FASTREMOVE, use last object when removing,
o add PARRAY_NULLEND, always has a last NULL entry
author | David Demelier <markand@malikania.fr> |
---|---|
date | Mon, 26 Mar 2012 10:24:49 +0200 |
parents | 5917096facb9 |
children | e3cf5ac9a5aa |
line wrap: on
line diff
--- a/array.c Tue Mar 20 22:49:37 2012 +0100 +++ b/array.c Mon Mar 26 10:24:49 2012 +0200 @@ -43,6 +43,9 @@ if ((arr->data = arr->malloc(arr->size)) == NULL) return -1; + if (arr->flags & ARRAY_CLEARBITS) + memset(arr->data, 0, arr->size); + return 0; } @@ -51,7 +54,7 @@ * l -> optional array block size of type int * m -> malloc function that must matches void * (*malloc)(size_t) * r -> realloc function that must matches void * (*realloc)(void *, size_t) - * t -> type of array of type int + * f -> array flags of type int */ void @@ -72,8 +75,8 @@ case 'r': arr->realloc = va_arg(ap, void *(*)(void *, size_t)); break; - case 't': - arr->type = va_arg(ap, int); + case 'f': + arr->flags = va_arg(ap, int); break; default: break; @@ -141,11 +144,7 @@ void array_pop(struct array *arr) { - if (arr->length > 0) { - memmove((char *)arr->data, (char *)arr->data + OFFSET(1), - OFFSET(--arr->length)); - memset((char *)arr->data + OFFSET(arr->length), 0, arr->unit); - } + array_iremove(arr, 0); } /* @@ -155,8 +154,7 @@ void array_unqueue(struct array *arr) { - if (arr->length > 0) - memset((char *)arr->data + OFFSET(--arr->length), 0, arr->unit); + array_iremove(arr, arr->length - 1); } /* @@ -167,11 +165,18 @@ array_iremove(struct array *arr, int index) { if (arr->length > 0 && index >= 0 && index < arr->length) { - memmove((char *)arr->data + OFFSET(index), - (char *)arr->data + OFFSET(index + 1), - OFFSET(arr->length - index - 1)); - memset((char *)arr->data + OFFSET(--arr->length), 0, arr->unit); + if (arr->flags & ARRAY_FASTREMOVE) + memmove((char *)arr->data + OFFSET(index), + (char *)arr->data + OFFSET(--arr->length), + arr->unit); + else + memmove((char *)arr->data + OFFSET(index), + (char *)arr->data + OFFSET(index + 1), + OFFSET(arr->length-- - index - 1)); } + + if (arr->flags & ARRAY_CLEARBITS) + memset((char *)arr->data + OFFSET(arr->length), 0, arr->unit); } /* @@ -188,8 +193,10 @@ for (i = 0; i < arr->length; ++i) { elm = (char *)arr->data + OFFSET(i); - if (memcmp(elm, data, arr->unit) == 0) + if (memcmp(elm, data, arr->unit) == 0) { array_iremove(arr, i); + break; + } } } @@ -208,11 +215,6 @@ if (i1 >= arr->length || i1 < 0 || i2 >= arr->length || i2 < 0) return -1; - /* - * Only allocate at this time, the user may do not want to use this - * function. - */ - if ((tmp = arr->malloc(arr->unit)) == NULL) return -1; @@ -226,7 +228,8 @@ * secure data to be left somewhere in the memory. */ - memset(tmp, 0, arr->unit); + if (arr->flags & ARRAY_CLEARBITS) + memset(tmp, 0, arr->unit); free(tmp); return 0; @@ -292,6 +295,33 @@ return (st) ? i - 1 : -1; } +void * +array_first(const struct array *arr) +{ + return arr->data; +} + +void * +array_last(const struct array *arr) +{ + if (arr->length == 0) + return array_first(arr); + + return (char *)arr->data + OFFSET(arr->length - 1); + +} + +void * +array_index(const struct array *arr, int idx) +{ + if (idx < 0) + return array_first(arr); + if (idx >= arr->length) + return array_last(arr); + + return (char *)arr->data + OFFSET(idx); +} + /* * Erase every bytes and set the length to 0. */ @@ -299,7 +329,9 @@ void array_clear(struct array *arr) { - memset(arr->data, 0, arr->size); + if (arr->flags & ARRAY_CLEARBITS) + memset(arr->data, 0, arr->size); + arr->length = 0; } @@ -310,7 +342,11 @@ void array_free(struct array *arr) { + array_clear(arr); free(arr->data); + + arr->data = NULL; + arr->size = 0; } /* @@ -322,13 +358,15 @@ static int grow(struct array *arr) { - if ((arr->size / arr->unit) > (size_t) arr->length) + if ((arr->size / arr->unit) > (size_t)arr->length) return 0; - if (arr->type == ARRAY_AUTO) { + if (!(arr->flags & ARRAY_FIXED)) { if ((arr->data = arr->realloc(arr->data, arr->size + - OFFSET(arr->bsize))) == NULL) + OFFSET(arr->bsize))) == NULL) { + arr->size = arr->length = 0; return -1; + } arr->size += OFFSET(arr->bsize); } else