1 /* GLIB - Library of useful routines for C programming
2 * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Library General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Library General Public License for more details.
14 * You should have received a copy of the GNU Library General Public
15 * License along with this library; if not, write to the
16 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17 * Boston, MA 02111-1307, USA.
28 #define MIN_ARRAY_SIZE 16
31 typedef struct _GRealArray GRealArray;
39 guint zero_terminated : 1;
44 static gint g_nearest_pow (gint num);
45 static void g_array_maybe_expand (GRealArray *array,
48 static GMemChunk *array_mem_chunk = NULL;
49 static G_LOCK_DEFINE(array_mem_chunk);
52 g_array_new (gboolean zero_terminated,
58 g_lock (array_mem_chunk);
60 array_mem_chunk = g_mem_chunk_new ("array mem chunk",
62 1024, G_ALLOC_AND_FREE);
64 array = g_chunk_new (GRealArray, array_mem_chunk);
65 g_unlock (array_mem_chunk);
70 array->zero_terminated = (zero_terminated ? 1 : 0);
71 array->clear = (clear ? 1 : 0);
72 array->elt_size = elt_size;
74 return (GArray*) array;
78 g_array_free (GArray *array,
79 gboolean free_segment)
84 g_lock (array_mem_chunk);
85 g_mem_chunk_free (array_mem_chunk, array);
86 g_unlock (array_mem_chunk);
90 g_array_append_vals (GArray *farray,
94 GRealArray *array = (GRealArray*) farray;
96 g_array_maybe_expand (array, len);
98 memcpy (array->data + array->elt_size * array->len, data, array->elt_size * len);
106 g_array_prepend_vals (GArray *farray,
110 GRealArray *array = (GRealArray*) farray;
112 g_array_maybe_expand (array, len);
114 g_memmove (array->data + array->elt_size * len, array->data, array->elt_size * array->len);
116 memcpy (array->data, data, len * array->elt_size);
124 g_array_insert_vals (GArray *farray,
129 GRealArray *array = (GRealArray*) farray;
131 g_array_maybe_expand (array, len);
133 g_memmove (array->data + array->elt_size * (len + index),
134 array->data + array->elt_size * index,
135 array->elt_size * (array->len - index));
137 memcpy (array->data + array->elt_size * index, data, len * array->elt_size);
145 g_array_set_size (GArray *farray,
148 GRealArray *array = (GRealArray*) farray;
150 if (array->len < length)
151 g_array_maybe_expand (array, length - array->len);
159 g_array_remove_index (GArray* farray,
162 GRealArray* array = (GRealArray*) farray;
164 g_return_val_if_fail (array, NULL);
166 g_return_val_if_fail (index >= 0 && index < array->len, NULL);
168 if (index != array->len - 1)
169 g_memmove (array->data + array->elt_size * index,
170 array->data + array->elt_size * (index + 1),
171 array->elt_size * (array->len - index - 1));
173 if (array->zero_terminated)
174 memset (array->data + array->elt_size * (array->len - 1), 0,
183 g_array_remove_index_fast (GArray* farray,
186 GRealArray* array = (GRealArray*) farray;
188 g_return_val_if_fail (array, NULL);
190 g_return_val_if_fail (index >= 0 && index < array->len, NULL);
192 if (index != array->len - 1)
193 g_memmove (array->data + array->elt_size * index,
194 array->data + array->elt_size * (array->len - 1),
197 if (array->zero_terminated)
198 memset (array->data + array->elt_size * (array->len - 1), 0,
207 g_nearest_pow (gint num)
218 g_array_maybe_expand (GRealArray *array,
221 guint want_alloc = (array->len + len + array->zero_terminated) * array->elt_size;
223 if (want_alloc > array->alloc)
225 guint old_alloc = array->alloc;
227 array->alloc = g_nearest_pow (want_alloc);
228 array->alloc = MAX (array->alloc, MIN_ARRAY_SIZE);
230 array->data = g_realloc (array->data, array->alloc);
232 if (array->clear || array->zero_terminated)
233 memset (array->data + old_alloc, 0, array->alloc - old_alloc);
240 typedef struct _GRealPtrArray GRealPtrArray;
242 struct _GRealPtrArray
249 static void g_ptr_array_maybe_expand (GRealPtrArray *array,
252 static GMemChunk *ptr_array_mem_chunk = NULL;
253 static G_LOCK_DEFINE(ptr_array_mem_chunk);
257 g_ptr_array_new (void)
259 GRealPtrArray *array;
261 g_lock (ptr_array_mem_chunk);
262 if (!ptr_array_mem_chunk)
263 ptr_array_mem_chunk = g_mem_chunk_new ("array mem chunk",
264 sizeof (GRealPtrArray),
265 1024, G_ALLOC_AND_FREE);
267 array = g_chunk_new (GRealPtrArray, ptr_array_mem_chunk);
268 g_unlock (ptr_array_mem_chunk);
274 return (GPtrArray*) array;
278 g_ptr_array_free (GPtrArray *array,
279 gboolean free_segment)
281 g_return_if_fail (array);
284 g_free (array->pdata);
286 g_lock (ptr_array_mem_chunk);
287 g_mem_chunk_free (ptr_array_mem_chunk, array);
288 g_unlock (ptr_array_mem_chunk);
292 g_ptr_array_maybe_expand (GRealPtrArray *array,
297 if ((array->len + len) > array->alloc)
299 old_alloc = array->alloc;
301 array->alloc = g_nearest_pow (array->len + len);
302 array->alloc = MAX (array->alloc, MIN_ARRAY_SIZE);
304 array->pdata = g_realloc (array->pdata, sizeof(gpointer) * array->alloc);
306 array->pdata = g_new0 (gpointer, array->alloc);
308 memset (array->pdata + old_alloc, 0, array->alloc - old_alloc);
313 g_ptr_array_set_size (GPtrArray *farray,
316 GRealPtrArray* array = (GRealPtrArray*) farray;
318 g_return_if_fail (array);
320 if (length > array->len)
321 g_ptr_array_maybe_expand (array, (length - array->len));
327 g_ptr_array_remove_index (GPtrArray* farray,
330 GRealPtrArray* array = (GRealPtrArray*) farray;
333 g_return_val_if_fail (array, NULL);
335 g_return_val_if_fail (index >= 0 && index < array->len, NULL);
337 result = array->pdata[index];
339 if (index != array->len - 1)
340 g_memmove (array->pdata + index, array->pdata + index + 1,
341 array->len - index - 1);
343 array->pdata[array->len - 1] = NULL;
351 g_ptr_array_remove_index_fast (GPtrArray* farray,
354 GRealPtrArray* array = (GRealPtrArray*) farray;
357 g_return_val_if_fail (array, NULL);
359 g_return_val_if_fail (index >= 0 && index < array->len, NULL);
361 result = array->pdata[index];
363 if (index != array->len - 1)
364 array->pdata[index] = array->pdata[array->len - 1];
366 array->pdata[array->len - 1] = NULL;
374 g_ptr_array_remove (GPtrArray* farray,
377 GRealPtrArray* array = (GRealPtrArray*) farray;
380 g_return_val_if_fail (array, FALSE);
382 for (i = 0; i < array->len; i += 1)
384 if (array->pdata[i] == data)
386 g_ptr_array_remove_index (farray, i);
395 g_ptr_array_remove_fast (GPtrArray* farray,
398 GRealPtrArray* array = (GRealPtrArray*) farray;
401 g_return_val_if_fail (array, FALSE);
403 for (i = 0; i < array->len; i += 1)
405 if (array->pdata[i] == data)
407 g_ptr_array_remove_index_fast (farray, i);
416 g_ptr_array_add (GPtrArray* farray,
419 GRealPtrArray* array = (GRealPtrArray*) farray;
421 g_return_if_fail (array);
423 g_ptr_array_maybe_expand (array, 1);
425 array->pdata[array->len++] = data;
431 GByteArray* g_byte_array_new (void)
433 return (GByteArray*) g_array_new (FALSE, FALSE, 1);
436 void g_byte_array_free (GByteArray *array,
437 gboolean free_segment)
439 g_array_free ((GArray*) array, free_segment);
442 GByteArray* g_byte_array_append (GByteArray *array,
446 g_array_append_vals ((GArray*) array, (guint8*)data, len);
451 GByteArray* g_byte_array_prepend (GByteArray *array,
455 g_array_prepend_vals ((GArray*) array, (guint8*)data, len);
460 GByteArray* g_byte_array_set_size (GByteArray *array,
463 g_array_set_size ((GArray*) array, length);
468 GByteArray* g_byte_array_remove_index (GByteArray *array,
471 g_array_remove_index((GArray*) array, index);
476 GByteArray* g_byte_array_remove_index_fast (GByteArray *array,
479 g_array_remove_index_fast((GArray*) array, index);