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.
21 * Modified by the GLib Team and others 1997-1999. See the AUTHORS
22 * file for a list of people on the GLib Team. See the ChangeLog
23 * files for a list of changes. These files are distributed with
24 * GLib at ftp://ftp.gtk.org/pub/gtk/.
35 #define MIN_ARRAY_SIZE 16
38 typedef struct _GRealArray GRealArray;
46 guint zero_terminated : 1;
51 static gint g_nearest_pow (gint num);
52 static void g_array_maybe_expand (GRealArray *array,
55 static GMemChunk *array_mem_chunk = NULL;
56 G_LOCK_DEFINE_STATIC (array_mem_chunk);
59 g_array_new (gboolean zero_terminated,
65 G_LOCK (array_mem_chunk);
67 array_mem_chunk = g_mem_chunk_new ("array mem chunk",
69 1024, G_ALLOC_AND_FREE);
71 array = g_chunk_new (GRealArray, array_mem_chunk);
72 G_UNLOCK (array_mem_chunk);
77 array->zero_terminated = (zero_terminated ? 1 : 0);
78 array->clear = (clear ? 1 : 0);
79 array->elt_size = elt_size;
81 return (GArray*) array;
85 g_array_free (GArray *array,
86 gboolean free_segment)
91 G_LOCK (array_mem_chunk);
92 g_mem_chunk_free (array_mem_chunk, array);
93 G_UNLOCK (array_mem_chunk);
97 g_array_append_vals (GArray *farray,
101 GRealArray *array = (GRealArray*) farray;
103 g_array_maybe_expand (array, len);
105 memcpy (array->data + array->elt_size * array->len, data, array->elt_size * len);
113 g_array_prepend_vals (GArray *farray,
117 GRealArray *array = (GRealArray*) farray;
119 g_array_maybe_expand (array, len);
121 g_memmove (array->data + array->elt_size * len, array->data, array->elt_size * array->len);
123 memcpy (array->data, data, len * array->elt_size);
131 g_array_insert_vals (GArray *farray,
136 GRealArray *array = (GRealArray*) farray;
138 g_array_maybe_expand (array, len);
140 g_memmove (array->data + array->elt_size * (len + index),
141 array->data + array->elt_size * index,
142 array->elt_size * (array->len - index));
144 memcpy (array->data + array->elt_size * index, data, len * array->elt_size);
152 g_array_set_size (GArray *farray,
155 GRealArray *array = (GRealArray*) farray;
157 if (array->len < length)
158 g_array_maybe_expand (array, length - array->len);
166 g_array_remove_index (GArray* farray,
169 GRealArray* array = (GRealArray*) farray;
171 g_return_val_if_fail (array, NULL);
173 g_return_val_if_fail (index >= 0 && index < array->len, NULL);
175 if (index != array->len - 1)
176 g_memmove (array->data + array->elt_size * index,
177 array->data + array->elt_size * (index + 1),
178 array->elt_size * (array->len - index - 1));
180 if (array->zero_terminated)
181 memset (array->data + array->elt_size * (array->len - 1), 0,
190 g_array_remove_index_fast (GArray* farray,
193 GRealArray* array = (GRealArray*) farray;
195 g_return_val_if_fail (array, NULL);
197 g_return_val_if_fail (index >= 0 && index < array->len, NULL);
199 if (index != array->len - 1)
200 g_memmove (array->data + array->elt_size * index,
201 array->data + array->elt_size * (array->len - 1),
204 if (array->zero_terminated)
205 memset (array->data + array->elt_size * (array->len - 1), 0,
214 g_nearest_pow (gint num)
225 g_array_maybe_expand (GRealArray *array,
228 guint want_alloc = (array->len + len + array->zero_terminated) * array->elt_size;
230 if (want_alloc > array->alloc)
232 guint old_alloc = array->alloc;
234 array->alloc = g_nearest_pow (want_alloc);
235 array->alloc = MAX (array->alloc, MIN_ARRAY_SIZE);
237 array->data = g_realloc (array->data, array->alloc);
239 if (array->clear || array->zero_terminated)
240 memset (array->data + old_alloc, 0, array->alloc - old_alloc);
247 typedef struct _GRealPtrArray GRealPtrArray;
249 struct _GRealPtrArray
256 static void g_ptr_array_maybe_expand (GRealPtrArray *array,
259 static GMemChunk *ptr_array_mem_chunk = NULL;
260 G_LOCK_DEFINE_STATIC (ptr_array_mem_chunk);
264 g_ptr_array_new (void)
266 GRealPtrArray *array;
268 G_LOCK (ptr_array_mem_chunk);
269 if (!ptr_array_mem_chunk)
270 ptr_array_mem_chunk = g_mem_chunk_new ("array mem chunk",
271 sizeof (GRealPtrArray),
272 1024, G_ALLOC_AND_FREE);
274 array = g_chunk_new (GRealPtrArray, ptr_array_mem_chunk);
275 G_UNLOCK (ptr_array_mem_chunk);
281 return (GPtrArray*) array;
285 g_ptr_array_free (GPtrArray *array,
286 gboolean free_segment)
288 g_return_if_fail (array);
291 g_free (array->pdata);
293 G_LOCK (ptr_array_mem_chunk);
294 g_mem_chunk_free (ptr_array_mem_chunk, array);
295 G_UNLOCK (ptr_array_mem_chunk);
299 g_ptr_array_maybe_expand (GRealPtrArray *array,
304 if ((array->len + len) > array->alloc)
306 old_alloc = array->alloc;
308 array->alloc = g_nearest_pow (array->len + len);
309 array->alloc = MAX (array->alloc, MIN_ARRAY_SIZE);
311 array->pdata = g_realloc (array->pdata, sizeof(gpointer) * array->alloc);
313 array->pdata = g_new0 (gpointer, array->alloc);
315 memset (array->pdata + old_alloc, 0, array->alloc - old_alloc);
320 g_ptr_array_set_size (GPtrArray *farray,
323 GRealPtrArray* array = (GRealPtrArray*) farray;
325 g_return_if_fail (array);
327 if (length > array->len)
328 g_ptr_array_maybe_expand (array, (length - array->len));
334 g_ptr_array_remove_index (GPtrArray* farray,
337 GRealPtrArray* array = (GRealPtrArray*) farray;
340 g_return_val_if_fail (array, NULL);
342 g_return_val_if_fail (index >= 0 && index < array->len, NULL);
344 result = array->pdata[index];
346 if (index != array->len - 1)
347 g_memmove (array->pdata + index, array->pdata + index + 1,
348 sizeof (gpointer) * (array->len - index - 1));
350 array->pdata[array->len - 1] = NULL;
358 g_ptr_array_remove_index_fast (GPtrArray* farray,
361 GRealPtrArray* array = (GRealPtrArray*) farray;
364 g_return_val_if_fail (array, NULL);
366 g_return_val_if_fail (index >= 0 && index < array->len, NULL);
368 result = array->pdata[index];
370 if (index != array->len - 1)
371 array->pdata[index] = array->pdata[array->len - 1];
373 array->pdata[array->len - 1] = NULL;
381 g_ptr_array_remove (GPtrArray* farray,
384 GRealPtrArray* array = (GRealPtrArray*) farray;
387 g_return_val_if_fail (array, FALSE);
389 for (i = 0; i < array->len; i += 1)
391 if (array->pdata[i] == data)
393 g_ptr_array_remove_index (farray, i);
402 g_ptr_array_remove_fast (GPtrArray* farray,
405 GRealPtrArray* array = (GRealPtrArray*) farray;
408 g_return_val_if_fail (array, FALSE);
410 for (i = 0; i < array->len; i += 1)
412 if (array->pdata[i] == data)
414 g_ptr_array_remove_index_fast (farray, i);
423 g_ptr_array_add (GPtrArray* farray,
426 GRealPtrArray* array = (GRealPtrArray*) farray;
428 g_return_if_fail (array);
430 g_ptr_array_maybe_expand (array, 1);
432 array->pdata[array->len++] = data;
438 GByteArray* g_byte_array_new (void)
440 return (GByteArray*) g_array_new (FALSE, FALSE, 1);
443 void g_byte_array_free (GByteArray *array,
444 gboolean free_segment)
446 g_array_free ((GArray*) array, free_segment);
449 GByteArray* g_byte_array_append (GByteArray *array,
453 g_array_append_vals ((GArray*) array, (guint8*)data, len);
458 GByteArray* g_byte_array_prepend (GByteArray *array,
462 g_array_prepend_vals ((GArray*) array, (guint8*)data, len);
467 GByteArray* g_byte_array_set_size (GByteArray *array,
470 g_array_set_size ((GArray*) array, length);
475 GByteArray* g_byte_array_remove_index (GByteArray *array,
478 g_array_remove_index((GArray*) array, index);
483 GByteArray* g_byte_array_remove_index_fast (GByteArray *array,
486 g_array_remove_index_fast((GArray*) array, index);