diff options
author | Luo Jinghua <sunmoon1997@gmail.com> | 2009-10-31 12:12:52 +0800 |
---|---|---|
committer | Luo Jinghua <sunmoon1997@gmail.com> | 2009-10-31 12:12:52 +0800 |
commit | 015ce5f7fa6b07de7101a70b2893426f248ab5f6 (patch) | |
tree | 3cc9745eb41a37c491e8e3d886d4f8cc47c547e0 | |
parent | 4ff1a3460cce81c21e1a2be245663f1359570c9e (diff) |
milkway: steal array implementation from glib
-rw-r--r-- | milkway/Makefile.am | 4 | ||||
-rw-r--r-- | milkway/mw-array.c | 343 | ||||
-rw-r--r-- | milkway/mw-array.h | 129 | ||||
-rw-r--r-- | milkway/mw-ptr-array.c | 386 | ||||
-rw-r--r-- | milkway/mw-ptr-array.h | 123 |
5 files changed, 985 insertions, 0 deletions
diff --git a/milkway/Makefile.am b/milkway/Makefile.am index d869a23..c98febd 100644 --- a/milkway/Makefile.am +++ b/milkway/Makefile.am @@ -22,6 +22,8 @@ milkway_headers = \ mw-object.h \ mw-error.h \ mw-qsort.h \ + mw-array.h \ + mw-ptr-array.h \ mw-connection-mgr.h \ mw-list.h \ mw-slist.h \ @@ -57,6 +59,8 @@ libmilkway_la_SOURCES = \ mw-object.c \ mw-error.c \ mw-qsort.c \ + mw-array.c \ + mw-ptr-array.c \ mw-connection-mgr.c \ mw-list.c \ mw-slist.c \ diff --git a/milkway/mw-array.c b/milkway/mw-array.c new file mode 100644 index 0000000..b2bb2ca --- /dev/null +++ b/milkway/mw-array.c @@ -0,0 +1,343 @@ +/* GLIB - Library of useful routines for C programming + * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +/* + * Modified by the GLib Team and others 1997-2000. See the AUTHORS + * file for a list of people on the GLib Team. See the ChangeLog + * files for a list of changes. These files are distributed with + * GLib at ftp://ftp.gtk.org/pub/gtk/. + */ + +/* + * MT safe + */ +#include "milkwayint.h" +#include "milkway/mw-array.h" +#include "milkway/mw-qsort.h" + +#include <string.h> +#include <stdlib.h> + +#define MIN_ARRAY_SIZE 16 + +#define mw_array_elt_len(array, i) ((array)->elt_size * (i)) +#define mw_array_elt_pos(array,i) ((array)->data + mw_array_elt_len((array),(i))) +#define mw_array_elt_zero(array, pos, len) \ + (memset (mw_array_elt_pos ((array), pos), 0, mw_array_elt_len ((array), len))) +#define mw_array_zero_terminate(array) \ + do { \ + if ((array)->zero_terminated) \ + mw_array_elt_zero ((array), (array)->len, 1); \ + } while (0) + +static int mw_nearest_pow (int num); +static void mw_array_maybe_expand (mw_array_t *array, + int len); + +static mw_array_t* +mw_array_init (mw_array_t *array, + mw_array_type_t *type, + mw_bool_t zero_terminated, + mw_bool_t clear, + mw_uint_t elt_size, + mw_uint_t reserved_size) +{ + if (!mw_object_init(&array->base, &type->base)) + return NULL; + + array->data = NULL; + array->len = 0; + array->alloc = 0; + array->zero_terminated = (zero_terminated ? 1 : 0); + array->clear = (clear ? 1 : 0); + array->elt_size = elt_size; + + if (array->zero_terminated || reserved_size != 0) + { + mw_array_maybe_expand (array, reserved_size); + mw_array_zero_terminate(array); + } + + return array; +} + +mw_array_t* +mw_array_new (mw_bool_t zero_terminated, + mw_bool_t clear, + mw_uint_t elt_size) +{ + return mw_array_sized_new (zero_terminated, clear, elt_size, 0); +} + +mw_array_t* +mw_array_sized_new (mw_bool_t zero_terminated, + mw_bool_t clear, + mw_uint_t elt_size, + mw_uint_t reserved_size) +{ + mw_array_t *self = mw_object_alloc(MW_ARRAY_TYPE); + + if (!self) + return NULL; + if (!mw_array_init(self, MW_ARRAY_TYPE, zero_terminated, clear, elt_size, + reserved_size)) + return NULL; + return self; +} + +/** + * mw_array_get_element_size: + * @array: A #mw_array_t. + * + * Gets the size of the elements in @array. + * + * Returns: Size of each element, in bytes. + * + * Since: 2.22 + **/ +mw_uint_t +mw_array_get_element_size (mw_array_t *array) +{ + return array->elt_size; +} + +char* +mw_array_take (mw_array_t *array) +{ + char* segment; + + segment = (char*) array->data; + + array->data = NULL; + array->len = 0; + array->alloc = 0; + + return segment; +} + +mw_array_t* +mw_array_append_vals (mw_array_t *array, + const mw_pointer_t data, + mw_uint_t len) +{ + mw_array_maybe_expand (array, len); + + memcpy (mw_array_elt_pos (array, array->len), data, + mw_array_elt_len (array, len)); + + array->len += len; + + mw_array_zero_terminate (array); + + return array; +} + +mw_array_t* +mw_array_prepend_vals (mw_array_t *array, + const mw_pointer_t data, + mw_uint_t len) +{ + mw_array_maybe_expand (array, len); + + memmove (mw_array_elt_pos (array, len), mw_array_elt_pos (array, 0), + mw_array_elt_len (array, array->len)); + + memcpy (mw_array_elt_pos (array, 0), data, mw_array_elt_len (array, len)); + + array->len += len; + + mw_array_zero_terminate (array); + + return array; +} + +mw_array_t* +mw_array_insert_vals (mw_array_t *array, + mw_uint_t index_, + const mw_pointer_t data, + mw_uint_t len) +{ + mw_array_maybe_expand (array, len); + + memmove (mw_array_elt_pos (array, len + index_), + mw_array_elt_pos (array, index_), + mw_array_elt_len (array, array->len - index_)); + + memcpy (mw_array_elt_pos (array, index_), data, + mw_array_elt_len (array, len)); + + array->len += len; + + mw_array_zero_terminate (array); + + return array; +} + +mw_array_t* +mw_array_set_size (mw_array_t *array, + mw_uint_t length) +{ + if (length > array->len) + { + mw_array_maybe_expand (array, length - array->len); + + if (array->clear) + mw_array_elt_zero (array, array->len, length - array->len); + } + else if (length < array->len) + mw_array_elt_zero (array, length, array->len - length); + + array->len = length; + + mw_array_zero_terminate (array); + + return array; +} + +mw_array_t* +mw_array_remove_index (mw_array_t *array, + mw_uint_t index_) +{ + mw_assert (array); + mw_assert (index_ < array->len); + + if (index_ != array->len - 1) + memmove (mw_array_elt_pos (array, index_), + mw_array_elt_pos (array, index_ + 1), + mw_array_elt_len (array, array->len - index_ - 1)); + + array->len -= 1; + mw_array_elt_zero (array, array->len, 1); + + return array; +} + +mw_array_t* +mw_array_remove_index_fast (mw_array_t *array, + mw_uint_t index_) +{ + mw_assert (array); + mw_assert (index_ < array->len); + + if (index_ != array->len - 1) + memcpy (mw_array_elt_pos (array, index_), + mw_array_elt_pos (array, array->len - 1), + mw_array_elt_len (array, 1)); + + array->len -= 1; + mw_array_elt_zero (array, array->len, 1); + return array; +} + +mw_array_t* +mw_array_remove_range (mw_array_t *array, + mw_uint_t index_, + mw_uint_t length) +{ + mw_assert (array); + mw_assert (index_ < array->len); + mw_assert (index_ + length <= array->len); + + if (index_ + length != array->len) + memmove (mw_array_elt_pos (array, index_), + mw_array_elt_pos (array, index_ + length), + (array->len - (index_ + length)) * array->elt_size); + + array->len -= length; + mw_array_elt_zero (array, array->len, length); + + return array; +} + +void +mw_array_sort (mw_array_t *array, + mw_compare_func_t compare_func) +{ + mw_assert (array != NULL); + + qsort (array->data, + array->len, + array->elt_size, + (int (*)(const void*, const void*))compare_func); +} + +void +mw_array_sort_with_data (mw_array_t *array, + mw_compare_data_func_t compare_func, + mw_pointer_t user_data) +{ + mw_assert (array != NULL); + + mw_qsort_with_data (array->data, + array->len, + array->elt_size, + compare_func, + user_data); +} + + +static int +mw_nearest_pow (int num) +{ + int n = 1; + + while (n < num) + n <<= 1; + + return n; +} + +#define MAX(a, b) ((a) > (b) ? (a) : (b)) +static void +mw_array_maybe_expand (mw_array_t *array, + int len) +{ + mw_uint_t want_alloc = mw_array_elt_len (array, array->len + len + + array->zero_terminated); + + if (want_alloc > array->alloc) + { + want_alloc = mw_nearest_pow (want_alloc); + want_alloc = MAX (want_alloc, MIN_ARRAY_SIZE); + + array->data = realloc (array->data, want_alloc); + + memset (array->data + array->alloc, 0, want_alloc - array->alloc); + array->alloc = want_alloc; + } +} + +static void +mw_array_finalize(mw_object_t *super) +{ + mw_array_t *self = (mw_array_t*)super; + mw_object_type_t *stype = MW_SUPER_TYPE_BASE(super, MW_ARRAY_TYPE); + + free (self->data); + stype->finalize(super); +} + +static void +mw_array_type_init(mw_array_type_t *self) +{ + self->base.finalize = mw_array_finalize; +} + +MW_DEFINE_GET_TYPE(mw_array, mw_array_type_t, + MW_OBJECT_TYPE, "MWArray", 0); diff --git a/milkway/mw-array.h b/milkway/mw-array.h new file mode 100644 index 0000000..f4cefc4 --- /dev/null +++ b/milkway/mw-array.h @@ -0,0 +1,129 @@ +/* GLIB - Library of useful routines for C programming + * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +/* + * Modified by the GLib Team and others 1997-2000. See the AUTHORS + * file for a list of people on the GLib Team. See the ChangeLog + * files for a list of changes. These files are distributed with + * GLib at ftp://ftp.gtk.org/pub/gtk/. + */ + +#ifndef __MW_ARRAY_H__ +#define __MW_ARRAY_H__ + +MW_BEGIN_DECLS + +#include <milkway/mw-object.h> + +typedef struct _mw_array mw_array_t; +typedef struct _mw_array_type mw_array_type_t; + +struct _mw_array +{ + mw_object_t base; + + mw_char_t *data; + mw_uint_t len; + mw_uint_t alloc; + mw_uint_t elt_size; + mw_uint_t zero_terminated : 1; + mw_uint_t clear : 1; +}; + +struct _mw_array_type { + mw_object_type_t base; +}; + +/* Resizable arrays. remove fills any cleared spot and shortens the + * array, while preserving the order. remove_fast will distort the + * order by moving the last element to the position of the removed. + */ + +#define mw_array_append_val(a,v) mw_array_append_vals (a, &(v), 1) +#define mw_array_prepend_val(a,v) mw_array_prepend_vals (a, &(v), 1) +#define mw_array_insert_val(a,i,v) mw_array_insert_vals (a, i, &(v), 1) +#define mw_array_index(a,t,i) (((t*) (void *) (a)->data) [(i)]) + +#define MW_ARRAY_TYPE mw_array_get_type() + +mw_public mw_array_type_t* +mw_array_get_type(void); + +mw_public mw_array_t* +mw_array_new (mw_bool_t zero_terminated, + mw_bool_t clear_, + mw_uint_t element_size); + +mw_public mw_array_t* +mw_array_sized_new (mw_bool_t zero_terminated, + mw_bool_t clear_, + mw_uint_t element_size, + mw_uint_t reserved_size); + +mw_public char* +mw_array_take (mw_array_t *array); + +mw_public mw_uint_t +mw_array_get_element_size (mw_array_t *array); + +mw_public mw_array_t* +mw_array_append_vals (mw_array_t *array, + const mw_pointer_t data, + mw_uint_t len); + +mw_public mw_array_t* +mw_array_prepend_vals (mw_array_t *array, + const mw_pointer_t data, + mw_uint_t len); + +mw_public mw_array_t* +mw_array_insert_vals (mw_array_t *array, + mw_uint_t index_, + const mw_pointer_t data, + mw_uint_t len); + +mw_public mw_array_t* +mw_array_set_size (mw_array_t *array, + mw_uint_t length); + +mw_public mw_array_t* +mw_array_remove_index (mw_array_t *array, + mw_uint_t index_); + +mw_public mw_array_t* +mw_array_remove_index_fast (mw_array_t *array, + mw_uint_t index_); + +mw_public mw_array_t* +mw_array_remove_range (mw_array_t *array, + mw_uint_t index_, + mw_uint_t length); + +mw_public void +mw_array_sort (mw_array_t *array, + mw_compare_func_t compare_func); + +mw_public void +mw_array_sort_with_data (mw_array_t *array, + mw_compare_data_func_t compare_func, + mw_pointer_t user_data); + +MW_END_DECLS + +#endif /* __MW_ARRAY_H__ */ diff --git a/milkway/mw-ptr-array.c b/milkway/mw-ptr-array.c new file mode 100644 index 0000000..14d9958 --- /dev/null +++ b/milkway/mw-ptr-array.c @@ -0,0 +1,386 @@ +/* GLIB - Library of useful routines for C programming + * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +/* + * Modified by the GLib Team and others 1997-2000. See the AUTHORS + * file for a list of people on the GLib Team. See the ChangeLog + * files for a list of changes. These files are distributed with + * GLib at ftp://ftp.gtk.org/pub/gtk/. + */ + +/* + * MT safe + */ +#include "milkwayint.h" +#include "milkway/mw-ptr-array.h" +#include "milkway/mw-qsort.h" + +#include <string.h> +#include <stdlib.h> + +#define MIN_ARRAY_SIZE 16 + +#define mw_array_elt_len(array, i) ((array)->elt_size * (i)) +#define mw_array_elt_pos(array,i) ((array)->data + mw_array_elt_len((array),(i))) +#define mw_array_elt_zero(array, pos, len) \ + (memset (mw_array_elt_pos ((array), pos), 0, mw_array_elt_len ((array), len))) +#define mw_array_zero_terminate(array) \ + do { \ + if ((array)->zero_terminated) \ + mw_array_elt_zero ((array), (array)->len, 1); \ + } while (0) + +static void mw_ptr_array_maybe_expand (mw_ptr_array_t *array, + int len); + +static mw_ptr_array_t* +mw_ptr_array_init (mw_ptr_array_t *array, + mw_ptr_array_type_t *type, + mw_uint_t reserved_size) +{ + if (!mw_object_init(&array->base, &type->base)) + return NULL; + + array->pdata = NULL; + array->len = 0; + array->alloc = 0; + array->element_free_func = NULL; + + if (reserved_size != 0) + mw_ptr_array_maybe_expand (array, reserved_size); + + return array; +} + +mw_ptr_array_t* +mw_ptr_array_new (void) +{ + return mw_ptr_array_sized_new (0); +} + +mw_ptr_array_t* +mw_ptr_array_sized_new (mw_uint_t reserved_size) +{ + mw_ptr_array_t *self = mw_object_alloc(MW_PTR_ARRAY_TYPE); + + if (!self) + return NULL; + if (!mw_ptr_array_init(self, MW_PTR_ARRAY_TYPE, reserved_size)) + return NULL; + return self; +} + + +/** + * mw_ptr_array_new_with_free_func: + * @element_free_func: A function to free elements with destroy @array or %NULL. + * + * Creates a new #mw_ptr_array_t with a reference count of 1 and use @element_free_func + * for freeing each element when the array is destroyed either via + * mw_ptr_array_unref(), when mw_ptr_array_free() is called with @free_segment + * set to %TRUE or when removing elements. + * + * Returns: A new #mw_ptr_array_t. + * + * Since: 2.22 + **/ +mw_ptr_array_t * +mw_ptr_array_new_with_free_func (mw_destroy_func_t element_free_func) +{ + mw_ptr_array_t *array; + + array = mw_ptr_array_new (); + mw_ptr_array_set_free_func (array, element_free_func); + return array; +} + +/** + * mw_ptr_array_set_free_func: + * @array: A #mw_ptr_array_t. + * @element_free_func: A function to free elements with destroy @array or %NULL. + * + * Sets a function for freeing each element when @array is destroyed + * either via mw_ptr_array_unref(), when mw_ptr_array_free() is called + * with @free_segment set to %TRUE or when removing elements. + * + * Since: 2.22 + **/ +void +mw_ptr_array_set_free_func (mw_ptr_array_t *array, + mw_destroy_func_t element_free_func) +{ + array->element_free_func = element_free_func; +} + +mw_pointer_t* +mw_ptr_array_take (mw_ptr_array_t *array) +{ + mw_pointer_t *segment; + + segment = array->pdata; + array->pdata = NULL; + array->len = 0; + array->alloc = 0; + return segment; +} + +static int +mw_nearest_pow (int num) +{ + int n = 1; + + while (n < num) + n <<= 1; + + return n; +} + +#undef MAX +#define MAX(a, b) ((a) > (b) ? (a) : (b)) +static void +mw_ptr_array_maybe_expand (mw_ptr_array_t *array, + int len) +{ + if ((array->len + len) > array->alloc) + { + mw_uint_t old_alloc = array->alloc; + + array->alloc = mw_nearest_pow (array->len + len); + array->alloc = MAX (array->alloc, MIN_ARRAY_SIZE); + array->pdata = realloc (array->pdata, sizeof (mw_pointer_t) * array->alloc); + + mw_unless(array->pdata); + + for ( ; old_alloc < array->alloc; old_alloc++) + array->pdata [old_alloc] = NULL; + } +} + +void +mw_ptr_array_set_size (mw_ptr_array_t *array, + unsigned int length) +{ + if (length > array->len) + { + unsigned int i; + + mw_ptr_array_maybe_expand (array, (length - array->len)); + /* This is not + * memset (array->pdata + array->len, 0, + * sizeof (mw_pointer_t) * (length - array->len)); + * to make it really portable. Remember (void*)NULL needn't be + * bitwise zero. It of course is silly not to use memset (..,0,..). + */ + for (i = array->len; i < length; i++) + array->pdata[i] = NULL; + } + else if (length < array->len) + mw_ptr_array_remove_range (array, length, array->len - length); + + array->len = length; +} + +mw_pointer_t +mw_ptr_array_remove_index (mw_ptr_array_t *array, + mw_uint_t index_) +{ + mw_pointer_t result; + + mw_assert (array); + mw_assert (index_ < array->len); + + result = array->pdata[index_]; + + if (array->element_free_func != NULL) + array->element_free_func (array->pdata[index_]); + + if (index_ != array->len - 1) + memmove (array->pdata + index_, array->pdata + index_ + 1, + sizeof (mw_pointer_t) * (array->len - index_ - 1)); + + array->len -= 1; + array->pdata[array->len] = NULL; + + return result; +} + +mw_pointer_t +mw_ptr_array_remove_index_fast (mw_ptr_array_t *array, + mw_uint_t index_) +{ + mw_pointer_t result; + + mw_assert (array); + mw_assert (index_ < array->len); + + result = array->pdata[index_]; + + if (index_ != array->len - 1) + { + if (array->element_free_func != NULL) + array->element_free_func (array->pdata[index_]); + array->pdata[index_] = array->pdata[array->len - 1]; + } + + array->len -= 1; + array->pdata[array->len] = NULL; + + return result; +} + +void +mw_ptr_array_remove_range (mw_ptr_array_t *array, + mw_uint_t index_, + mw_uint_t length) +{ + mw_uint_t n, i; + + mw_assert (array); + mw_assert (index_ < array->len); + mw_assert (index_ + length <= array->len); + + if (array->element_free_func != NULL) + { + for (n = index_; n < index_ + length; n++) + array->element_free_func (array->pdata[n]); + } + + if (index_ + length != array->len) + { + memmove (&array->pdata[index_], + &array->pdata[index_ + length], + (array->len - (index_ + length)) * sizeof (mw_pointer_t)); + } + + array->len -= length; + + for (i = 0; i < length; i++) + array->pdata[array->len + i] = NULL; +} + +mw_bool_t +mw_ptr_array_remove (mw_ptr_array_t *array, + mw_pointer_t data) +{ + mw_uint_t i; + + for (i = 0; i < array->len; i += 1) + { + if (array->pdata[i] == data) + { + mw_ptr_array_remove_index (array, i); + return MW_TRUE; + } + } + + return MW_FALSE; +} + +mw_bool_t +mw_ptr_array_remove_fast (mw_ptr_array_t *array, + mw_pointer_t data) +{ + mw_uint_t i; + + mw_assert (array); + + for (i = 0; i < array->len; i += 1) + { + if (array->pdata[i] == data) + { + mw_ptr_array_remove_index_fast (array, i); + return MW_TRUE; + } + } + + return MW_FALSE; +} + +void +mw_ptr_array_add (mw_ptr_array_t *array, + mw_pointer_t data) +{ + mw_ptr_array_maybe_expand (array, 1); + array->pdata[array->len++] = data; +} + +void +mw_ptr_array_sort (mw_ptr_array_t *array, + mw_compare_func_t compare_func) +{ + qsort (array->pdata, + array->len, + sizeof (mw_pointer_t), + (int (*)(const void*, const void*))compare_func); +} + +void +mw_ptr_array_sort_with_data (mw_ptr_array_t *array, + mw_compare_data_func_t compare_func, + mw_pointer_t user_data) +{ + mw_qsort_with_data (array->pdata, + array->len, + sizeof (mw_pointer_t), + compare_func, + user_data); +} + +/** + * mw_ptr_array_foreach: + * @array: a #mw_ptr_array_t + * @func: the function to call for each array element + * @user_data: user data to pass to the function + * + * Calls a function for each element of a #mw_ptr_array_t. + * + * Since: 2.4 + **/ +void +mw_ptr_array_foreach (mw_ptr_array_t *array, + mw_func_t func, + mw_pointer_t user_data) +{ + mw_uint_t i; + + for (i = 0; i < array->len; i++) + (*func) (array->pdata[i], user_data); +} + +static void +mw_ptr_array_finalize(mw_object_t *super) +{ + mw_ptr_array_t *self = (mw_ptr_array_t*)super; + mw_object_type_t *stype = MW_SUPER_TYPE_BASE(super, MW_PTR_ARRAY_TYPE); + + if (self->pdata && self->element_free_func != NULL) + mw_ptr_array_foreach (self, (mw_func_t) self->element_free_func, NULL); + + free (self->pdata); + stype->finalize(super); +} + +static void +mw_ptr_array_type_init(mw_ptr_array_type_t *self) +{ + self->base.finalize = mw_ptr_array_finalize; +} + +MW_DEFINE_GET_TYPE(mw_ptr_array, mw_ptr_array_type_t, + MW_OBJECT_TYPE, "MWPtrArray", 0); diff --git a/milkway/mw-ptr-array.h b/milkway/mw-ptr-array.h new file mode 100644 index 0000000..da2e4e0 --- /dev/null +++ b/milkway/mw-ptr-array.h @@ -0,0 +1,123 @@ +/* GLIB - Library of useful routines for C programming + * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +/* + * Modified by the GLib Team and others 1997-2000. See the AUTHORS + * file for a list of people on the GLib Team. See the ChangeLog + * files for a list of changes. These files are distributed with + * GLib at ftp://ftp.gtk.org/pub/gtk/. + */ + +#ifndef __MW_PTR_ARRAY_H__ +#define __MW_PTR_ARRAY_H__ + +MW_BEGIN_DECLS + +#include <milkway/mw-object.h> + +typedef struct _mw_ptr_array mw_ptr_array_t; +typedef struct _mw_ptr_array_type mw_ptr_array_type_t; + +struct _mw_ptr_array +{ + mw_object_t base; + + mw_pointer_t *pdata; + mw_uint_t len; + mw_uint_t alloc; + mw_destroy_func_t element_free_func; +}; + +struct _mw_ptr_array_type { + mw_object_type_t base; +}; + +#define MW_PTR_ARRAY_TYPE mw_ptr_array_get_type() + +/* Resizable pointer array. This interface is much less complicated + * than the above. Add appends a pointer. Remove fills any cleared + * spot and shortens the array. remove_fast will again distort order. + */ +#define mw_ptr_array_index(array,index_) ((array)->pdata)[index_] + +mw_public mw_ptr_array_type_t* +mw_ptr_array_get_type(void); + +mw_public +mw_ptr_array_t* mw_ptr_array_new (void); + +mw_public mw_ptr_array_t* +mw_ptr_array_new_with_free_func (mw_destroy_func_t element_free_func); + +mw_public mw_ptr_array_t* +mw_ptr_array_sized_new (mw_uint_t reserved_size); + +mw_public mw_pointer_t* +mw_ptr_array_take (mw_ptr_array_t *array); + +mw_public void +mw_ptr_array_set_free_func (mw_ptr_array_t *array, + mw_destroy_func_t element_free_func); + +mw_public void +mw_ptr_array_set_size (mw_ptr_array_t *array, + unsigned int length); + +mw_public mw_pointer_t +mw_ptr_array_remove_index (mw_ptr_array_t *array, + mw_uint_t index_); + +mw_public mw_pointer_t +mw_ptr_array_remove_index_fast (mw_ptr_array_t *array, + mw_uint_t index_); + +mw_public mw_bool_t +mw_ptr_array_remove (mw_ptr_array_t *array, + mw_pointer_t data); + +mw_public mw_bool_t +mw_ptr_array_remove_fast (mw_ptr_array_t *array, + mw_pointer_t data); + +mw_public void +mw_ptr_array_remove_range (mw_ptr_array_t *array, + mw_uint_t index_, + mw_uint_t length); + +mw_public void +mw_ptr_array_add (mw_ptr_array_t *array, + mw_pointer_t data); + +mw_public void +mw_ptr_array_sort (mw_ptr_array_t *array, + mw_compare_func_t compare_func); + +mw_public void +mw_ptr_array_sort_with_data (mw_ptr_array_t *array, + mw_compare_data_func_t compare_func, + mw_pointer_t user_data); + +mw_public void +mw_ptr_array_foreach (mw_ptr_array_t *array, + mw_func_t func, + mw_pointer_t user_data); + +MW_END_DECLS + +#endif /* __MW_ARRAY_H__ */ |