5 * Chris Toshok (toshok@novell.com)
7 * (C) 2006 Novell, Inc.
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:
17 * The above copyright notice and this permission notice shall be
18 * included in all copies or substantial portions of the Software.
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.
32 #define INITIAL_CAPACITY 16
34 #define element_offset(p,i) ((p)->array.data + (i) * (p)->element_size)
35 #define element_length(p,i) ((i) * (p)->element_size)
41 gboolean zero_terminated
;
46 ensure_capacity (GArrayPriv
*priv
, guint capacity
)
50 if (capacity
<= priv
->capacity
)
53 new_capacity
= (capacity
+ 63) & ~63;
55 priv
->array
.data
= g_realloc (priv
->array
.data
, element_length (priv
, new_capacity
));
58 memset (element_offset (priv
, priv
->capacity
),
60 element_length (priv
, new_capacity
- priv
->capacity
));
63 priv
->capacity
= new_capacity
;
67 g_array_new (gboolean zero_terminated
,
71 GArrayPriv
*rv
= g_new0 (GArrayPriv
, 1);
72 rv
->zero_terminated
= zero_terminated
;
74 rv
->element_size
= element_size
;
76 ensure_capacity (rv
, INITIAL_CAPACITY
);
82 g_array_sized_new (gboolean zero_terminated
,
87 GArrayPriv
*rv
= g_new0 (GArrayPriv
, 1);
88 rv
->zero_terminated
= zero_terminated
;
90 rv
->element_size
= element_size
;
92 ensure_capacity (rv
, reserved_size
);
98 g_array_free (GArray
*array
,
99 gboolean free_segment
)
103 g_return_val_if_fail (array
!= NULL
, NULL
);
106 g_free (array
->data
);
116 g_array_append_vals (GArray
*array
,
120 GArrayPriv
*priv
= (GArrayPriv
*)array
;
122 g_return_val_if_fail (array
!= NULL
, NULL
);
124 ensure_capacity (priv
, priv
->array
.len
+ len
+ (priv
->zero_terminated
? 1 : 0));
126 memmove (element_offset (priv
, priv
->array
.len
),
128 element_length (priv
, len
));
130 priv
->array
.len
+= len
;
132 if (priv
->zero_terminated
) {
133 memset (element_offset (priv
, priv
->array
.len
),
142 g_array_insert_vals (GArray
*array
,
147 GArrayPriv
*priv
= (GArrayPriv
*)array
;
148 guint extra
= (priv
->zero_terminated
? 1 : 0);
150 g_return_val_if_fail (array
!= NULL
, NULL
);
152 ensure_capacity (priv
, array
->len
+ len
+ extra
);
154 /* first move the existing elements out of the way */
155 memmove (element_offset (priv
, index_
+ len
),
156 element_offset (priv
, index_
),
157 element_length (priv
, array
->len
- index_
));
159 /* then copy the new elements into the array */
160 memmove (element_offset (priv
, index_
),
162 element_length (priv
, len
));
166 if (priv
->zero_terminated
) {
167 memset (element_offset (priv
, priv
->array
.len
),
176 g_array_remove_index (GArray
*array
,
179 GArrayPriv
*priv
= (GArrayPriv
*)array
;
181 g_return_val_if_fail (array
!= NULL
, NULL
);
183 memmove (element_offset (priv
, index_
),
184 element_offset (priv
, index_
+ 1),
185 element_length (priv
, array
->len
- index_
));
189 if (priv
->zero_terminated
) {
190 memset (element_offset (priv
, priv
->array
.len
),
199 g_array_remove_index_fast (GArray
*array
,
202 GArrayPriv
*priv
= (GArrayPriv
*)array
;
204 g_return_val_if_fail (array
!= NULL
, NULL
);
206 memmove (element_offset (priv
, index_
),
207 element_offset (priv
, array
->len
- 1),
208 element_length (priv
, 1));
212 if (priv
->zero_terminated
) {
213 memset (element_offset (priv
, priv
->array
.len
),
222 g_array_set_size (GArray
*array
, gint length
)
224 GArrayPriv
*priv
= (GArrayPriv
*)array
;
226 g_return_if_fail (array
!= NULL
);
227 g_return_if_fail (length
>= 0);
229 if (length
== priv
->capacity
)
230 return; // nothing to be done
232 if (length
> priv
->capacity
) {
234 ensure_capacity (priv
, length
);