glib: changes to the g*_array API.



Hi, all

I hereby propose to change the g*_array API:

The current g_ptr_array_remove[_index] functions work a little
suprisingly, as they do not preserve order. So I added the argument
gboolean preserve_order.

This will of course break tons of code: namely, lets see,
cvs.gnome.org/lxr -> search for g_ptr_array_remove -> uh,oh only one
program, /ORBit/src/services/name/orbit-name-server.c, written by me (what
a coincidence ;-), which I'll change then. (actually, as you all guess, I
might need it there).

Additionally I added the functions g_array_remove_index and
g_byte_array_remove_index with a similar prototype to make it consistent
and to prevent the people using arrays form doing this on their own. To
cite somebody, whos name I forgot: 'Off by one' is the most common
mistake, and doing the memmove stuff on ones own all over the place is
asking for trouble. 

Anyway, here comes the patch: If approved, I'll apply this (i.e. I do have
cvs write acces), but of course I'm asking first

Bye, Sebastian
-- 
+--------------============####################============--------------+
| Sebastian Wilhelmi, Institute for Computer Design and Fault Tolerance, |
| University of Karlsruhe;  Building 20.20, Room 263,  D-76128 Karlsruhe |
| mail: wilhelmi@ira.uka.de;  fax: +49 721 370455;  fon: +49 721 6084353 |
+-----------------> http://goethe.ira.uka.de/~wilhelmi <-----------------+
Index: ChangeLog
===================================================================
RCS file: /cvs/gnome/glib/ChangeLog,v
retrieving revision 1.88
diff -u -r1.88 ChangeLog
--- ChangeLog	1998/10/28 01:32:50	1.88
+++ ChangeLog	1998/10/28 10:20:08
@@ -1,3 +1,16 @@
+1998-10-28  Sebastian Wilhelmi  <wilhelmi@ira.uka.de>
+
+	* glib.h: 
+	* garray.h:
+	(g_array_remove_index): new function for removing an entry from an
+	array. preserver_order determines, if the last element is moved to
+	the position of the removed one (=FALSE), or if all the remaining
+	elements are moved one position down (=TRUE).
+	(g_ptr_array_remove_index, g_ptr_array_remove): added
+	preserver_order argument working like explained above
+	(g_byte_array_remove_index): new function; byte_array wrapper for
+	g_array_remove_index
+
 Tue Oct 27 07:25:53 1998  Tim Janik  <timj@gtk.org>
 
 	* glib.h:
Index: garray.c
===================================================================
RCS file: /cvs/gnome/glib/garray.c,v
retrieving revision 1.7
diff -u -r1.7 garray.c
--- garray.c	1998/09/07 09:43:46	1.7
+++ garray.c	1998/10/28 10:20:09
@@ -126,6 +126,38 @@
   return farray;
 }
 
+GArray*
+g_array_remove_index (GArray* farray,
+		      guint index,
+		      gboolean preserve_order)
+{
+  GRealArray* array = (GRealArray*) farray;
+
+  g_return_val_if_fail (array, NULL);
+
+  g_return_val_if_fail (index >= 0 && index < array->len, NULL);
+
+  if (index != array->len - 1)
+    {
+      if (preserve_order)
+	g_memmove (array->data + array->elt_size * index, 
+		   array->data + array->elt_size * (index + 1), 
+		   array->elt_size * (array->len - index - 1));
+      else
+	g_memmove (array->data + array->elt_size * index, 
+		   array->data + array->elt_size * (array->len - 1), 
+		   array->elt_size);
+    }
+  
+  if (array->zero_terminated)
+    memset (array->data + array->elt_size * (array->len - 1), 0, 
+	    array->elt_size);
+
+  array->len -= 1;
+
+  return farray;
+}
+
 static gint
 g_nearest_pow (gint num)
 {
@@ -245,7 +277,8 @@
 
 gpointer
 g_ptr_array_remove_index (GPtrArray* farray,
-			  gint index)
+			  guint index,
+			  gboolean preserve_order)
 {
   GRealPtrArray* array = (GRealPtrArray*) farray;
   gpointer result;
@@ -255,8 +288,15 @@
   g_return_val_if_fail (index >= 0 && index < array->len, NULL);
 
   result = array->pdata[index];
-
-  array->pdata[index] = array->pdata[array->len - 1];
+  
+  if (index != array->len - 1)
+    {
+      if (preserve_order)
+	g_memmove (array->pdata + index, array->pdata + index + 1, 
+		   array->len - index - 1);
+      else
+	array->pdata[index] = array->pdata[array->len - 1];
+    }
 
   array->pdata[array->len - 1] = NULL;
 
@@ -267,7 +307,8 @@
 
 gboolean
 g_ptr_array_remove (GPtrArray* farray,
-		    gpointer data)
+		    gpointer data,
+		    gboolean preserve_order)
 {
   GRealPtrArray* array = (GRealPtrArray*) farray;
   int i;
@@ -278,7 +319,7 @@
     {
       if (array->pdata[i] == data)
 	{
-	  g_ptr_array_remove_index (farray, i);
+	  g_ptr_array_remove_index (farray, i, preserve_order);
 	  return TRUE;
 	}
     }
@@ -335,6 +376,15 @@
 				   guint       length)
 {
   g_array_set_size ((GArray*) array, length);
+
+  return array;
+}
+
+GByteArray* g_byte_array_remove_index (GByteArray *array,
+				       guint index,
+				       gboolean preserve_order)
+{
+  g_array_remove_index((GArray*) array, index, preserve_order);
 
   return array;
 }
Index: glib.h
===================================================================
RCS file: /cvs/gnome/glib/glib.h,v
retrieving revision 1.63
diff -u -r1.63 glib.h
--- glib.h	1998/10/28 01:32:53	1.63
+++ glib.h	1998/10/28 10:20:14
@@ -1800,6 +1800,9 @@
 			      guint	    len);
 GArray* g_array_set_size     (GArray	   *array,
 			      guint	    length);
+GArray* g_array_remove_index (GArray	   *array,
+			      guint	    index,
+			      gboolean	    preserve_order);
 
 /* Resizable pointer array.  This interface is much less complicated
  * than the above.  Add appends appends a pointer.  Remove fills any
@@ -1812,9 +1815,11 @@
 void	    g_ptr_array_set_size	   (GPtrArray	*array,
 					    gint	 length);
 gpointer    g_ptr_array_remove_index	   (GPtrArray	*array,
-					    gint	 index);
+					    guint	 index,
+					    gboolean 	 preserve_order);
 gboolean    g_ptr_array_remove		   (GPtrArray	*array,
-					    gpointer	 data);
+					    gpointer	 data,
+					    gboolean 	 preserve_order);
 void	    g_ptr_array_add		   (GPtrArray	*array,
 					    gpointer	 data);
 
@@ -1822,17 +1827,20 @@
  * but type-safe.
  */
 
-GByteArray* g_byte_array_new	  (void);
-void	    g_byte_array_free	  (GByteArray	*array,
-				   gboolean	 free_segment);
-GByteArray* g_byte_array_append	  (GByteArray	*array,
-				   const guint8 *data,
-				   guint	 len);
-GByteArray* g_byte_array_prepend  (GByteArray	*array,
-				   const guint8 *data,
-				   guint	 len);
-GByteArray* g_byte_array_set_size (GByteArray	*array,
-				   guint	 length);
+GByteArray* g_byte_array_new	      (void);
+void	    g_byte_array_free	      (GByteArray	*array,
+				       gboolean 	 free_segment);
+GByteArray* g_byte_array_append	      (GByteArray	*array,
+				       const guint8 	*data,
+				       guint	 	 len);
+GByteArray* g_byte_array_prepend      (GByteArray	*array,
+				       const guint8 	*data,
+				       guint	 	 len);
+GByteArray* g_byte_array_set_size     (GByteArray	*array,
+				       guint	 	 length);
+GByteArray* g_byte_array_remove_index (GByteArray 	*array,
+				       guint 		 index,
+				       gboolean 	 preserve_order);
 
 
 /* Hash Functions


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]