* 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
+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:
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
#include <stdarg.h>
#include <stdlib.h>
#include <string.h>
+#include <stdio.h>
/*
* Basic data types
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);
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
*/
--- /dev/null
+/*
+ * 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);
+ }
+}
+
hashtable.c \
string-util.c \
string.c \
- slist.c
+ slist.c \
+ ptrarray.c
test_CFLAGS = -Wall -Werror -D_FORTIFY_SOURCE=2
INCLUDES = -I../src
"string", strutil_tests_init,
"hashtable", hashtable_tests_init,
"slist", slist_tests_init,
+ "ptrarray", ptrarray_tests_init,
"gstring", string_tests_init,
NULL
);
--- /dev/null
+#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)
+
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);
+