4d9b96f7c5078130086dcf1f30e03ac23de61b4c
[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 #define MAX(a,b) ((a) > (b) ? (a) : (b))
34
35 typedef struct _GPtrArrayPriv {
36         gpointer *pdata;
37         guint len;
38         guint size;
39 } GPtrArrayPriv;
40
41 static void 
42 g_ptr_array_grow(GPtrArrayPriv *array, guint length)
43 {
44         gint new_length = array->len + length;
45
46         g_return_if_fail(array != NULL);
47
48         if(new_length <= array->size) {
49                 return;
50         }
51
52         array->size = 1;
53
54         while(array->size < new_length) {
55                 array->size <<= 1;
56         }
57
58         array->size = MAX(array->size, 16);
59         array->pdata = g_realloc(array->pdata, array->size * sizeof(gpointer));
60 }
61
62 GPtrArray *
63 g_ptr_array_new()
64 {
65         return g_ptr_array_sized_new(0);
66 }
67
68 GPtrArray *
69 g_ptr_array_sized_new(guint reserved_size)
70 {
71         GPtrArrayPriv *array = g_new0(GPtrArrayPriv, 1);
72
73         array->pdata = NULL;
74         array->len = 0;
75         array->size = 0;
76
77         if(reserved_size > 0) {
78                 g_ptr_array_grow(array, reserved_size);
79         }
80
81         return (GPtrArray *)array;
82 }
83
84 gpointer *
85 g_ptr_array_free(GPtrArray *array, gboolean free_seg)
86 {
87         gpointer *data = NULL;
88         
89         g_return_val_if_fail(array != NULL, NULL);
90
91         if(free_seg) {
92                 g_free(array->pdata);
93         } else {
94                 data = array->pdata;
95         }
96
97         g_free(array);
98         
99         return data;
100 }
101
102 void
103 g_ptr_array_add(GPtrArray *array, gpointer data)
104 {
105         g_return_if_fail(array != NULL);
106         g_ptr_array_grow((GPtrArrayPriv *)array, 1);
107         array->pdata[array->len++] = data;
108 }
109
110 void 
111 g_ptr_array_foreach(GPtrArray *array, GFunc func, gpointer user_data)
112 {
113         gint i;
114
115         for(i = 0; i < array->len; i++) {
116                 func(g_ptr_array_index(array, i), user_data);
117         }
118 }
119