New test.
[mono.git] / eglib / src / gptrarray.c
1 /*
2  * Pointer Array
3  *
4  * Author:
5  *   Aaron Bockover (abockover@novell.com)
6  *
7  * (C) 2006 Novell, Inc.
8  *
9  * Permission is hereby granted, free of charge, to any person obtaining
10  * a copy of this software and associated documentation files (the
11  * "Software"), to deal in the Software without restriction, including
12  * without limitation the rights to use, copy, modify, merge, publish,
13  * distribute, sublicense, and/or sell copies of the Software, and to
14  * permit persons to whom the Software is furnished to do so, subject to
15  * the following conditions:
16  *
17  * The above copyright notice and this permission notice shall be
18  * included in all copies or substantial portions of the Software.
19  *
20  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
21  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
22  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
23  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
24  * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
25  * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
26  * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
27  */
28  
29 #define _GNU_SOURCE
30 #include <stdlib.h>
31 #include <glib.h>
32
33 typedef struct _GPtrArrayPriv {
34         gpointer *pdata;
35         guint len;
36         guint size;
37 } GPtrArrayPriv;
38
39 static void 
40 g_ptr_array_grow(GPtrArrayPriv *array, guint length)
41 {
42         gint new_length = array->len + length;
43
44         g_return_if_fail(array != NULL);
45
46         if(new_length <= array->size) {
47                 return;
48         }
49
50         array->size = 1;
51
52         while(array->size < new_length) {
53                 array->size <<= 1;
54         }
55
56         array->size = MAX(array->size, 16);
57         array->pdata = g_realloc(array->pdata, array->size * sizeof(gpointer));
58 }
59
60 GPtrArray *
61 g_ptr_array_new()
62 {
63         return g_ptr_array_sized_new(0);
64 }
65
66 GPtrArray *
67 g_ptr_array_sized_new(guint reserved_size)
68 {
69         GPtrArrayPriv *array = g_new0(GPtrArrayPriv, 1);
70
71         array->pdata = NULL;
72         array->len = 0;
73         array->size = 0;
74
75         if(reserved_size > 0) {
76                 g_ptr_array_grow(array, reserved_size);
77         }
78
79         return (GPtrArray *)array;
80 }
81
82 gpointer *
83 g_ptr_array_free(GPtrArray *array, gboolean free_seg)
84 {
85         gpointer *data = NULL;
86         
87         g_return_val_if_fail(array != NULL, NULL);
88
89         if(free_seg) {
90                 g_free(array->pdata);
91         } else {
92                 data = array->pdata;
93         }
94
95         g_free(array);
96         
97         return data;
98 }
99
100 void
101 g_ptr_array_set_size(GPtrArray *array, gint length)
102 {
103         g_return_if_fail(array != NULL);
104
105         if(length > array->len) {
106                 g_ptr_array_grow((GPtrArrayPriv *)array, length);
107                 memset(array->pdata + array->len, 0, (length - array->len) 
108                         * sizeof(gpointer));
109         }
110
111         array->len = length;
112 }
113
114 void
115 g_ptr_array_add(GPtrArray *array, gpointer data)
116 {
117         g_return_if_fail(array != NULL);
118         g_ptr_array_grow((GPtrArrayPriv *)array, 1);
119         array->pdata[array->len++] = data;
120 }
121
122 gpointer
123 g_ptr_array_remove_index(GPtrArray *array, guint index)
124 {
125         gpointer removed_node;
126         
127         g_return_val_if_fail(array != NULL, NULL);
128         g_return_val_if_fail(index >= 0 || index < array->len, NULL);
129
130         removed_node = array->pdata[index];
131
132         if(index != array->len - 1) {
133                 g_memmove(array->pdata + index, array->pdata + index + 1,
134                         (array->len - index - 1) * sizeof(gpointer));
135         }
136         
137         array->len--;
138         array->pdata[array->len] = NULL;
139
140         return removed_node;
141 }
142
143 gboolean
144 g_ptr_array_remove(GPtrArray *array, gpointer data)
145 {
146         guint i;
147
148         g_return_val_if_fail(array != NULL, FALSE);
149
150         for(i = 0; i < array->len; i++) {
151                 if(array->pdata[i] == data) {
152                         g_ptr_array_remove_index(array, i);
153                         return TRUE;
154                 }
155         }
156
157         return FALSE;
158 }
159
160 void 
161 g_ptr_array_foreach(GPtrArray *array, GFunc func, gpointer user_data)
162 {
163         gint i;
164
165         for(i = 0; i < array->len; i++) {
166                 func(g_ptr_array_index(array, i), user_data);
167         }
168 }
169
170 void
171 g_ptr_array_sort(GPtrArray *array, GCompareFunc compare_func)
172 {
173         g_return_if_fail(array != NULL);
174         qsort(array->pdata, array->len, sizeof(gpointer), compare_func);
175 }
176
177 void
178 g_ptr_array_sort_with_data(GPtrArray *array, GCompareDataFunc compare_func, 
179         gpointer user_data)
180 {
181 }
182
183