diff options
author | Søren Sandmann Pedersen <sandmann@daimi.au.dk> | 2009-04-19 19:43:33 -0400 |
---|---|---|
committer | Søren Sandmann Pedersen <sandmann@daimi.au.dk> | 2009-04-19 19:43:33 -0400 |
commit | 1592cccff1d81879726c36c030b6790e7b2c4c6e (patch) | |
tree | aad8052fb07c2ca26062501c1b1c8ef00e30c71a | |
parent | 4d788ecc8f573108842d70b2fe8f17dda938c08e (diff) |
Add removing support to arrays
-rw-r--r-- | Makefile.am | 1 | ||||
-rw-r--r-- | array.c | 65 | ||||
-rw-r--r-- | libnul.h | 59 |
3 files changed, 116 insertions, 9 deletions
diff --git a/Makefile.am b/Makefile.am index 485385a..35c6f3a 100644 --- a/Makefile.am +++ b/Makefile.am @@ -8,6 +8,7 @@ libnul_la_SOURCES = \ dbus.c \ array.c \ epoll.c \ + libdbus.c \ signal-handler.c \ file-utils.c \ libnul.h @@ -186,6 +186,59 @@ array_append (void *data, return data; } +static char * +locate_element (array_t *array, + void *element) +{ + int i; + + for (i = 0; i < array->n_elements; ++i) + { + char *elt = ((char *)array->data) + array->n_prefix_bytes + + i * array->element_size; + + if (memcmp (elt, element, array->element_size) == 0) + return elt; + } + + return NULL; +} + +static void * +array_remove (void *data, + const int *magic, + void *element, + gboolean fast) +{ + array_t *array = get_array (data, magic); + char *location = locate_element (array, element); + char *end; + + if (location) + { + end = (char *)array->data + + array->n_prefix_bytes + array->n_elements * array->element_size; + + if (fast) + { + memmove (location, end - array->element_size, array->element_size); + } + else + { + memmove (location, location + array->element_size, + end - (location + array->element_size)); + } + + array = realloc_array (array, array->n_elements - 1); + + array->n_elements--; + + nul_terminate (array); + } + + return array->data; +} + static gssize array_len (const void *data, const int *magic) { @@ -241,6 +294,18 @@ nul_garray_len (const nul_ptr_t array) return array_len (array, &arr_t_magic); } +nul_ptr_t +nul_garray_remove (nul_ptr_t arr, nul_ptr_t element) +{ + return array_remove (arr, &arr_t_magic, element, FALSE); +} + +nul_ptr_t +nul_garray_remove_fast (nul_ptr_t arr, nul_ptr_t element) +{ + return array_remove (arr, &arr_t_magic, element, TRUE); +} + /* * Strings */ @@ -55,14 +55,18 @@ typedef void * const nul_const_ptr_t; /* * Generic array implementation */ -nul_ptr_t nul_garray_new (int element_size) NUL_UR; -nul_ptr_t nul_garray_new_prefix (int element_size, int prefix_size) NUL_UR; -nul_ptr_t nul_garray_append (nul_ptr_t array, nul_ptr_t element) NUL_UR; -gsize nul_garray_len (nul_ptr_t array); -void nul_garray_free (nul_ptr_t array); - -#define nul_array_new(type) _nul_array_new_impl(type) -#define nul_array_append(array,value) _nul_array_append_impl(array,value) +nul_ptr_t nul_garray_new (int element_size) NUL_UR; +nul_ptr_t nul_garray_new_prefix (int element_size, int prefix_size) NUL_UR; +nul_ptr_t nul_garray_append (nul_ptr_t array, nul_ptr_t element) NUL_UR; +nul_ptr_t nul_garray_remove (nul_ptr_t array, nul_ptr_t element) NUL_UR; +nul_ptr_t nul_garray_remove_fast (nul_ptr_t array, nul_ptr_t element) NUL_UR; +gsize nul_garray_len (nul_ptr_t array); +void nul_garray_free (nul_ptr_t array); + +#define nul_array_new(type) _nul_array_new_impl(type) +#define nul_array_append(array,value) _nul_array_append_impl(array,value) +#define nul_array_remove(array,value) _nul_array_remove_impl(array,value) +#define nul_array_remove_fast(array,value) _nul_array_remove_fast_impl(array,value) #define nul_array_len(array) nul_garray_len(array) #define nul_array_free(array) nul_garray_free(array) @@ -70,6 +74,10 @@ void nul_garray_free (nul_ptr_t array); _nul_prefix_array_new_impl(type,member) #define nul_prefix_array_append(array,member,value) \ _nul_prefix_array_append_impl(array,member,value) +#define nul_prefix_array_remove(array,member,value) \ + _nul_prefix_array_remove_impl(array,member,value) +#define nul_prefix_array_remove_fast(array,member,value) \ + _nul_prefix_array_remove_impl(array,member,value) #define nul_prefix_array_len(array,member) \ _nul_prefix_array_len_impl(array,member) #define nul_prefix_array_free(array,member) \ @@ -348,6 +356,24 @@ void nul_dbus_invoke (nul_dbus_service_t *service, &__nul_temp; \ }))) +#define _nul_array_remove_impl(array,value) \ + ((typeof (array)) \ + nul_garray_remove(array, ({ \ + typeof (value) __nul_temp = (value); \ + _NUL_TYPE_CHECK_ARRAY(array,value); \ + &__nul_temp; \ + }))) + +#define _nul_array_remove_fast_impl(array,value) \ + ((typeof (array)) \ + nul_garray_remove_fast(array, ({ \ + typeof (value) __nul_temp = (value); \ + _NUL_TYPE_CHECK_ARRAY(array,value); \ + &__nul_temp; \ + }))) + +/* Prefix arrays */ + #define _nul_prefix_array_new_impl(type,member) \ ((type *)nul_garray_new_prefix( \ sizeof(((type *)NULL)->member[0]), \ @@ -360,7 +386,22 @@ void nul_dbus_invoke (nul_dbus_service_t *service, _NUL_TYPE_CHECK_ARRAY(&((array)->member)[0], (value)); \ &__nul_temp; \ }))) - +#define _nul_prefix_array_remove_impl(array,member,value) \ + ((typeof (array)) \ + nul_garray_remove(array, ({ \ + typeof (value) __nul_temp = (value); \ + _NUL_TYPE_CHECK_ARRAY(&((array)->member)[0], (value)) \ + &__nul_temp; \ + }))) + +#define _nul_prefix_array_remove_fast_impl(array,member,value) \ + ((typeof (array)) \ + nul_garray_remove_fast(array, ({ \ + typeof (value) __nul_temp = (value); \ + _NUL_TYPE_CHECK_ARRAY(&((array)->member)[0], (value)) \ + &__nul_temp; \ + }))) + #define _nul_prefix_array_len_impl(array,member) \ ({ (void)((array)->member); \ nul_garray_len(array); \ |