changeset 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 23a3ebcbf08e
children b972758ddcd5
files array.c array.h
diffstat 2 files changed, 60 insertions(+), 25 deletions(-) [+]
line wrap: on
line diff
--- a/array.c	Sun Sep 25 19:16:21 2011 +0200
+++ b/array.c	Fri Sep 30 16:38:40 2011 +0200
@@ -27,16 +27,16 @@
 static int	array_grow(struct array *);
 
 struct array *
-array_new(const void *data, size_t unit, size_t bsize, int flags)
+array_new(const void *data, size_t unit, int bsize, int type)
 {
 	struct array *arr;
 
 	if (unit == 0 || (arr = malloc(sizeof (struct array))) == NULL)
 		return NULL;
 
-	arr->tmp	= NULL;
-	arr->length	= 0;
-	arr->flags	= flags;
+	memset(arr, 0, sizeof (struct array));
+
+	arr->type	= type;
 	arr->bsize	= (bsize == 0) ? ARRAY_DEFAULT_BSIZE : bsize;
 	arr->unit	= unit;
 	arr->size	= OFFSET(arr->bsize);
@@ -144,6 +144,30 @@
 }
 
 /*
+ * Remove the object referenced by the `data' argument. Useful when you
+ * don't know the index.
+ */
+
+struct personne {
+	char *name;
+	int age;
+};
+
+void
+array_unref(struct array *arr, const void *data)
+{
+	void *elm;
+	int i;
+
+	for (i = 0; i < arr->length; ++i) {
+		elm = ARRAY_INDEX(arr, i);
+
+		if (memcmp(elm, data, arr->unit) == 0)
+			array_remove(arr, i);
+	}
+}
+
+/*
  * Swap the two elements referenced by index `i1' and `i2'. This function needs
  * to allocate data to swap elements thus if the functions fails it returns -1
  * otherwise 0 is returned.
@@ -161,13 +185,19 @@
 	 * function.
 	 */
 
-	if (arr->tmp == NULL && (arr->tmp = malloc(arr->unit)) == NULL)
+	if (arr->_tmp == NULL && (arr->_tmp = malloc(arr->unit)) == NULL)
 		return -1;
 
-	memcpy((char *) arr->tmp, (char *) arr->data + OFFSET(i1), arr->unit);
+	memcpy((char *) arr->_tmp, (char *) arr->data + OFFSET(i1), arr->unit);
 	memcpy((char *) arr->data + OFFSET(i1), (char *) arr->data + OFFSET(i2),
 	    arr->unit);
-	memcpy((char *) arr->data + OFFSET(i2), (char *) arr->tmp, arr->unit);
+	memcpy((char *) arr->data + OFFSET(i2), (char *) arr->_tmp, arr->unit);
+
+	/*
+	 * Clear bytes for safety.
+	 */
+
+	memset(arr->_tmp, 0, arr->unit);
 
 	return 0;
 }
@@ -235,8 +265,8 @@
 
 	if (arr->data)
 		free(arr->data);
-	if (arr->tmp)
-		free(arr->tmp);
+	if (arr->_tmp)
+		free(arr->_tmp);
 
 	free(arr);
 }
@@ -253,7 +283,7 @@
 	if ((arr->size / arr->unit) > (size_t) arr->length)
 		return 0;
 
-	if (arr->flags & ARRAY_AUTO) {
+	if (arr->type == ARRAY_AUTO) {
 		if ((arr->data = realloc(arr->data, arr->size +
 		    OFFSET(arr->bsize))) == NULL)
 			return -1;
--- a/array.h	Sun Sep 25 19:16:21 2011 +0200
+++ b/array.h	Fri Sep 30 16:38:40 2011 +0200
@@ -21,22 +21,23 @@
 
 #define ARRAY_DEFAULT_BSIZE	128
 
+#define ARRAY_FIXED	0x00
+#define ARRAY_AUTO	0x01
+
 struct array {
 	void	*data;	/* array of data */
-	void	*tmp;	/* only used for array_swap() */
 	int	length;	/* number of element inside */
+	int	type;	/* array's flags (default FIXED) */
+	size_t	size;	/* current buffer size (allocated memory) */
+	size_t	unit;	/* unit size (sizeof the object) */
+	int	bsize;	/* block size (used when growing array) */
 
-#define ARRAY_FIXED	0x00000000
-#define ARRAY_AUTO	0x00000001
-	int	flags;	/* array's flags (default FIXED) */
-
-	/* Private should not be modified by user */
-	size_t	size;	/* current buffer size */
-	size_t	unit;	/* unit size (sizeof the object) */
-	size_t	bsize;	/* block size (used when growing array) */
+	/* Private, do not modify */
+	void	*_tmp;	/* only used for array_swap() */
+	int	_i;	/* only for ARRAY_FOREACH(_R) */
 };
 
-struct array	*array_new(const void *, size_t, size_t, int);
+struct array	*array_new(const void *, size_t, int, int);
 #define array_new_auto(size)		array_new(NULL, size, 0, ARRAY_AUTO)
 #define array_new_fixed(size, max)	array_new(NULL, size, max, ARRAY_FIXED)
 
@@ -46,23 +47,27 @@
 void	array_pop(struct array *);
 void	array_unqueue(struct array *);
 void	array_remove(struct array *, int);
+void	array_unref(struct array *, const void *);
 int	array_swap(struct array *, int, int);
 void	array_map(const struct array *, void (*fn)(void *, void *), void *);
 void	*array_find(const struct array *, int (*fn)(void *, void *), int *, void *);
 void	array_clear(struct array *);
 void	array_free(struct array *);
 
-#define ARRAY_FOREACH(a, var, i)						\
-	for (i = 0, var = a->data; i < a->length; ++i, ++var)
+#define ARRAY_FOREACH(a, var)							\
+	for (a->_i = 0, var = a->data; a->_i < a->length; ++a->_i, ++var)
 
-#define ARRAY_FOREACH_R(a, var, i)						\
-	for (i = 0,								\
+#define ARRAY_FOREACH_R(a, var)							\
+	for (a->_i = 0,								\
 	    var = (void *) ((char *) a->data + a->unit * (a->length - 1));	\
-	    i < a->length; ++i, --var)	
+	    a->_i < a->length; ++a->_i, --var)	
 
 #define ARRAY_HEAD(a)								\
 	a->data
 #define ARRAY_TAIL(a)								\
 	(void *) ((char *) a->data + (a->unit * (a->length - 1)))
+#define ARRAY_INDEX(a, i)							\
+	(void *) ((char *) a->data + (a->unit *					\
+	    ((i >= a->length) ? (a->length -1) : i)))
 
 #endif /* _ARRAY_H_ */