2006-08-17 Aaron Bockover <abockover@novell.com>
authorAaron Bockover <abockover@novell.com>
Thu, 17 Aug 2006 21:49:00 +0000 (21:49 -0000)
committerAaron Bockover <abockover@novell.com>
Thu, 17 Aug 2006 21:49:00 +0000 (21:49 -0000)
    * src/gptrarray.c: Added beginnings of GPtrArray (alloc, free, add, iterate)
    * src/glib.h: Added GPtrArray signatures

    * src/Makefile.am: Added gptrarray.c to build

    * test/ptrarray.c:
    * test/tests.h:
    * test/driver.c:
    * test/Makefile.am: Add ptrarray tests for available functionality

svn path=/trunk/mono/; revision=63947

eglib/ChangeLog
eglib/src/Makefile.am
eglib/src/glib.h
eglib/src/gptrarray.c [new file with mode: 0644]
eglib/test/Makefile.am
eglib/test/driver.c
eglib/test/ptrarray.c [new file with mode: 0644]
eglib/test/tests.h

index d9dff20e7064073b7445ee13eb92322fee674ba6..5414e3390f9371e7d0bb322d1b309d93ef5e27db 100644 (file)
@@ -1,3 +1,16 @@
+2006-08-17  Aaron Bockover  <abockover@novell.com>
+
+       * src/gptrarray.c: Added beginnings of GPtrArray (alloc, free, add, iterate)
+
+       * src/glib.h: Added GPtrArray signatures
+
+       * src/Makefile.am: Added gptrarray.c to build
+
+       * test/ptrarray.c:
+       * test/tests.h:
+       * test/driver.c:
+       * test/Makefile.am: Add ptrarray tests for available functionality
+
 2006-08-17  Aaron Bockover  <abockover@novell.com>
        
        * test/test.h: 
index f5604c9ec4cddb21af91f7bd0800c13b44128a7c..4d084d09a66acf2770a30b5d4b433f0b90d6e830 100644 (file)
@@ -1,13 +1,14 @@
 noinst_LTLIBRARIES = libeglib.la
 
 libeglib_la_SOURCES = \
-       ghashtable.c    \
-       gmem.c          \
-       gmodule.c       \
-       goutput.c       \
-       gstr.c          \
-       gslist.c        \
-       gstring.c
+       ghashtable.c \
+       gmem.c       \
+       gmodule.c    \
+       goutput.c    \
+       gstr.c       \
+       gslist.c     \
+       gstring.c    \
+       gptrarray.c
 
 libeglib_la_CFLAGS = -Wall -Werror -D_FORTIFY_SOURCE=2
 
index 1261fc5993643c9024691d20f5b58c770c3788f5..bad2f0bc3a28288c25250154bfd49de542a0cf76 100644 (file)
@@ -4,6 +4,7 @@
 #include <stdarg.h>
 #include <stdlib.h>
 #include <string.h>
+#include <stdio.h>
 
 /*
  * Basic data types
@@ -74,6 +75,7 @@ gpointer g_memdup (gconstpointer mem, guint byte_size);
 typedef struct _GHashTable GHashTable;
 typedef void     (*GFunc)          (gpointer data, gpointer user_data);
 typedef gint     (*GCompareFunc)   (gconstpointer a, gconstpointer b);
+typedef gint     (*GCompareDataFunc) (gconstpointer a, gconstpointer b, gpointer user_data);
 typedef void     (*GHFunc)         (gpointer key, gpointer value, gpointer user_data);
 typedef gboolean (*GHRFunc)        (gpointer key, gpointer value, gpointer user_data);
 typedef void     (*GDestroyNotify) (gpointer data);
@@ -168,6 +170,31 @@ GSList *g_slist_insert_sorted (GSList *list, gpointer data, GCompareFunc func);
 guint  g_slist_length     (GSList *list);
 #define g_slist_next (slist) ((slist) ? (((GSList *) slist)->next) : NULL)
 
+/*
+ * Pointer Array
+ */
+
+typedef struct _GPtrArray GPtrArray;
+struct _GPtrArray {
+       gpointer *pdata;
+       guint len;
+};
+
+GPtrArray *g_ptr_array_new                ();
+GPtrArray *g_ptr_array_sized_new          (guint reserved_size);
+void       g_ptr_array_add                (GPtrArray *array, gpointer data);
+gboolean   g_ptr_array_remove             (GPtrArray *array, gpointer data);
+gpointer   g_ptr_array_remove_index       (GPtrArray *array, guint index);
+gboolean   g_ptr_array_remove_fast        (GPtrArray *array, gpointer data);
+gpointer   g_ptr_array_remove_index_fast  (GPtrArray *array, gpointer data);
+void       g_ptr_array_sort               (GPtrArray *array, GCompareFunc compare_func);
+void       g_ptr_array_sort_with_data     (GPtrArray *array, GCompareDataFunc compare_func, gpointer user_data);
+void       g_ptr_array_set_size           (GPtrArray *array, gint length);
+gpointer  *g_ptr_array_free               (GPtrArray *array, gboolean free_seg);
+void       g_ptr_array_foreach            (GPtrArray *array, GFunc func, gpointer user_data);
+#define    g_ptr_array_index(array,index) array->pdata[index]
+
+
 /*
  * Modules
  */
diff --git a/eglib/src/gptrarray.c b/eglib/src/gptrarray.c
new file mode 100644 (file)
index 0000000..4d9b96f
--- /dev/null
@@ -0,0 +1,119 @@
+/*
+ * Pointer Array
+ *
+ * Author:
+ *   Aaron Bockover (abockover@novell.com)
+ *
+ * (C) 2006 Novell, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+#define _GNU_SOURCE
+#include <stdlib.h>
+#include <glib.h>
+
+#define MAX(a,b) ((a) > (b) ? (a) : (b))
+
+typedef struct _GPtrArrayPriv {
+       gpointer *pdata;
+       guint len;
+       guint size;
+} GPtrArrayPriv;
+
+static void 
+g_ptr_array_grow(GPtrArrayPriv *array, guint length)
+{
+       gint new_length = array->len + length;
+
+       g_return_if_fail(array != NULL);
+
+       if(new_length <= array->size) {
+               return;
+       }
+
+       array->size = 1;
+
+       while(array->size < new_length) {
+               array->size <<= 1;
+       }
+
+       array->size = MAX(array->size, 16);
+       array->pdata = g_realloc(array->pdata, array->size * sizeof(gpointer));
+}
+
+GPtrArray *
+g_ptr_array_new()
+{
+       return g_ptr_array_sized_new(0);
+}
+
+GPtrArray *
+g_ptr_array_sized_new(guint reserved_size)
+{
+       GPtrArrayPriv *array = g_new0(GPtrArrayPriv, 1);
+
+       array->pdata = NULL;
+       array->len = 0;
+       array->size = 0;
+
+       if(reserved_size > 0) {
+               g_ptr_array_grow(array, reserved_size);
+       }
+
+       return (GPtrArray *)array;
+}
+
+gpointer *
+g_ptr_array_free(GPtrArray *array, gboolean free_seg)
+{
+       gpointer *data = NULL;
+       
+       g_return_val_if_fail(array != NULL, NULL);
+
+       if(free_seg) {
+               g_free(array->pdata);
+       } else {
+               data = array->pdata;
+       }
+
+       g_free(array);
+       
+       return data;
+}
+
+void
+g_ptr_array_add(GPtrArray *array, gpointer data)
+{
+       g_return_if_fail(array != NULL);
+       g_ptr_array_grow((GPtrArrayPriv *)array, 1);
+       array->pdata[array->len++] = data;
+}
+
+void 
+g_ptr_array_foreach(GPtrArray *array, GFunc func, gpointer user_data)
+{
+       gint i;
+
+       for(i = 0; i < array->len; i++) {
+               func(g_ptr_array_index(array, i), user_data);
+       }
+}
+
index 0820e9392ec3d44dcf2b0e1fff0a65403f81ba47..36df80a4007f774835fa408b3a062aa39451ee3e 100644 (file)
@@ -8,7 +8,8 @@ test_SOURCES =    \
        hashtable.c     \
        string-util.c   \
        string.c        \
-       slist.c
+       slist.c       \
+       ptrarray.c
 
 test_CFLAGS = -Wall -Werror -D_FORTIFY_SOURCE=2
 INCLUDES = -I../src
index 99b6dd178a9755148899b40875d9a733ae2eb009..d3fc878fed841efaf09668460dde1e1475e42ca9 100644 (file)
@@ -9,6 +9,7 @@ int main()
                "string",    strutil_tests_init,
                "hashtable", hashtable_tests_init,
                "slist",     slist_tests_init,
+               "ptrarray",  ptrarray_tests_init,
                "gstring",   string_tests_init,
                NULL
        );
diff --git a/eglib/test/ptrarray.c b/eglib/test/ptrarray.c
new file mode 100644 (file)
index 0000000..420cd32
--- /dev/null
@@ -0,0 +1,128 @@
+#include <stdio.h>
+#include <glib.h>
+#include "test.h"
+
+/* Redefine the private structure only to verify proper allocations */
+typedef struct _GPtrArrayPriv {
+       gpointer *pdata;
+       guint len;
+       guint size;
+} GPtrArrayPriv;
+
+/* Don't add more than 32 items to this please */
+static const char *items [] = {
+       "Apples", "Oranges", "Plumbs", "Goats", "Snorps", "Grapes", 
+       "Tickle", "Place", "Coffee", "Cookies", "Cake", "Cheese",
+       "Tseng", "Holiday", "Avenue", "Smashing", "Water", "Toilet",
+       NULL
+};
+
+static GPtrArray *ptrarray_alloc_and_fill(gint *item_count)
+{
+       GPtrArray *array = g_ptr_array_new();
+       gint i;
+       
+       for(i = 0; items[i] != NULL; i++) {
+               g_ptr_array_add(array, (gpointer)items[i]);
+       }
+
+       if(item_count != NULL) {
+               *item_count = i;
+       }
+       
+       return array;
+}
+
+static gint guess_size(gint length)
+{
+       gint size = 1;
+
+       while(size < length) {
+               size <<= 1;
+       }
+
+       return size;
+}
+
+char *ptrarray_alloc()
+{
+       GPtrArrayPriv *array;
+       gint i;
+       
+       array = (GPtrArrayPriv *)ptrarray_alloc_and_fill(&i);
+       
+       if(array->size != guess_size(array->len)) {
+               return g_strdup_printf("Size should be %d, but it is %d", 
+                       guess_size(array->len), array->size);
+       }
+       
+       if(array->len != i) {
+               return g_strdup_printf("Expected %d node(s) in the array", i);
+       }
+       
+       g_ptr_array_free((GPtrArray *)array, TRUE);
+
+       return NULL;
+}
+
+char *ptrarray_for_iterate()
+{
+       GPtrArray *array = ptrarray_alloc_and_fill(NULL);
+       gint i;
+
+       for(i = 0; i < array->len; i++) {
+               char *item = (char *)g_ptr_array_index(array, i);
+               if(item != items[i]) {
+                       return g_strdup_printf(
+                               "Expected item at %d to be %s, but it was %s", 
+                               i, items[i], item);
+               }
+       }
+
+       g_ptr_array_free(array, TRUE);
+
+       return NULL;
+}
+
+static gint foreach_iterate_index = 0;
+static char *foreach_iterate_error = NULL;
+
+void foreach_callback(gpointer data, gpointer user_data)
+{
+       char *item = (char *)data;
+       const char *item_cmp = items[foreach_iterate_index++];
+
+       if(foreach_iterate_error != NULL) {
+               return;
+       }
+
+       if(item != item_cmp) {
+               foreach_iterate_error = g_strdup_printf(
+                       "Expected item at %d to be %s, but it was %s", 
+                               foreach_iterate_index - 1, item_cmp, item);
+       }
+}
+
+char *ptrarray_foreach_iterate()
+{
+       GPtrArray *array = ptrarray_alloc_and_fill(NULL);
+       
+       foreach_iterate_index = 0;
+       foreach_iterate_error = NULL;
+       
+       g_ptr_array_foreach(array, foreach_callback, array);
+       
+       g_ptr_array_free(array, TRUE);
+
+       return foreach_iterate_error;
+}
+
+static Test ptrarray_tests [] = {
+       {"ptrarray_alloc", ptrarray_alloc},
+       {"ptrarray_for_iterate", ptrarray_for_iterate},
+       {"ptrarray_foreach_iterate", ptrarray_foreach_iterate},
+       {NULL, NULL}
+};
+
+DEFINE_TEST_GROUP_INIT(ptrarray_tests_init, ptrarray_tests)
+
index 7d9f72c6a87cc999814b7c8bba262698b810dc40..775a054525b7519a89e0852312eadf4d2a0034a4 100644 (file)
@@ -3,3 +3,5 @@ DEFINE_TEST_GROUP_INIT_H(string_tests_init);
 DEFINE_TEST_GROUP_INIT_H(strutil_tests_init);
 DEFINE_TEST_GROUP_INIT_H(slist_tests_init);
 DEFINE_TEST_GROUP_INIT_H(hashtable_tests_init);
+DEFINE_TEST_GROUP_INIT_H(ptrarray_tests_init);
+