changeset 22:ecdf21f1d0c6

Added a new function array_swap() that swap elements by index
author David Demelier <markand@malikania.fr>
date Wed, 14 Sep 2011 20:24:14 +0200
parents ae4128d16c92
children 216b6e6a539c
files array.c array.h
diffstat 2 files changed, 41 insertions(+), 5 deletions(-) [+]
line wrap: on
line diff
--- a/array.c	Fri Sep 09 17:32:53 2011 +0200
+++ b/array.c	Wed Sep 14 20:24:14 2011 +0200
@@ -34,11 +34,12 @@
 	if (unit == 0 || !(arr = malloc(sizeof (struct array))))
 		return NULL;
 
+	arr->tmp	= NULL;
+	arr->length	= 0;
+	arr->flags	= flags;
 	arr->bsize	= (bsize == 0) ? ARRAY_DEFAULT_BSIZE : bsize;
-	arr->flags	= flags;
 	arr->unit	= unit;
-	arr->size	= SIZE(bsize);
-	arr->length	= 0;
+	arr->size	= SIZE(arr->bsize);
 
 	if (!(arr->data = malloc(arr->size))) {
 		free(arr);
@@ -165,6 +166,35 @@
 }
 
 /*
+ * 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.
+ */
+
+int
+array_swap(struct array *arr, int i1, int i2)
+{
+	/* Out of bounds */
+	if (i1 > arr->length - 1|| i1 < 0 || i2 > arr->length - 1|| i2 < 0)
+		return -1;
+
+	/*
+	 * Only allocate at this time, the user may do not want to use this
+	 * function.
+	 */
+
+	if (!arr->tmp && !(arr->tmp = malloc(arr->unit)))
+		return -1;
+
+	memcpy(arr->tmp, arr->data + SIZE(i1), arr->unit);
+	memcpy(arr->data + SIZE(i1), arr->data + SIZE(i2), arr->unit);
+	memcpy(arr->data + SIZE(i2), arr->tmp, arr->unit);
+
+	return 0;
+}
+
+
+/*
  * Apply the function `fn' on each object and give the optional `udata'
  * argument to the function too.
  */
@@ -225,7 +255,11 @@
 {
 	array_clear(arr);
 
-	free(arr->data);
+	if (arr->data)
+		free(arr->data);
+	if (arr->tmp)
+		free(arr->tmp);
+
 	free(arr);
 }
 
--- a/array.h	Fri Sep 09 17:32:53 2011 +0200
+++ b/array.h	Wed Sep 14 20:24:14 2011 +0200
@@ -23,11 +23,12 @@
 
 struct array {
 	char	*data;	/* array of data */
+	char	*tmp;	/* only used for array_swap() */
 	int	length;	/* number of element inside */
 
 #define ARRAY_FIXED	0x00000000
 #define ARRAY_AUTO	0x00000001
-	int	flags;		/* array's flags (default FIXED) */
+	int	flags;	/* array's flags (default FIXED) */
 
 	/* Private should not be modified by user */
 	size_t	size;	/* current buffer size */
@@ -45,6 +46,7 @@
 void	*array_pop(struct array *);
 void	*array_unqueue(struct array *);
 void	*array_remove(struct array *, int);
+int	array_swap(struct array *, int, int);
 void	array_map(struct array *, void (*fn)(void *, void *), void *);
 void	*array_find(struct array *, int (*fn)(void *, void *), void *, int *);
 void	array_clear(struct array *);