summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSøren Sandmann Pedersen <sandmann@daimi.au.dk>2009-04-19 19:43:33 -0400
committerSøren Sandmann Pedersen <sandmann@daimi.au.dk>2009-04-19 19:43:33 -0400
commit1592cccff1d81879726c36c030b6790e7b2c4c6e (patch)
treeaad8052fb07c2ca26062501c1b1c8ef00e30c71a
parent4d788ecc8f573108842d70b2fe8f17dda938c08e (diff)
Add removing support to arrays
-rw-r--r--Makefile.am1
-rw-r--r--array.c65
-rw-r--r--libnul.h59
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
diff --git a/array.c b/array.c
index df5a293..5fdd721 100644
--- a/array.c
+++ b/array.c
@@ -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
*/
diff --git a/libnul.h b/libnul.h
index 413d535..02cfd98 100644
--- a/libnul.h
+++ b/libnul.h
@@ -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); \