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
< 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
< 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,
316 sizeof (gpointer
) * (array
->alloc
- old_alloc
));
321 g_ptr_array_set_size (GPtrArray
*farray
,
324 GRealPtrArray
* array
= (GRealPtrArray
*) farray
;
326 g_return_if_fail (array
);
328 if (length
> array
->len
)
329 g_ptr_array_maybe_expand (array
, (length
- array
->len
));
335 g_ptr_array_remove_index (GPtrArray
* farray
,
338 GRealPtrArray
* array
= (GRealPtrArray
*) farray
;
341 g_return_val_if_fail (array
, NULL
);
343 g_return_val_if_fail (index
< array
->len
, NULL
);
345 result
= array
->pdata
[index
];
347 if (index
!= array
->len
- 1)
348 g_memmove (array
->pdata
+ index
, array
->pdata
+ index
+ 1,
349 sizeof (gpointer
) * (array
->len
- index
- 1));
351 array
->pdata
[array
->len
- 1] = NULL
;
359 g_ptr_array_remove_index_fast (GPtrArray
* farray
,
362 GRealPtrArray
* array
= (GRealPtrArray
*) farray
;
365 g_return_val_if_fail (array
, NULL
);
367 g_return_val_if_fail (index
< array
->len
, NULL
);
369 result
= array
->pdata
[index
];
371 if (index
!= array
->len
- 1)
372 array
->pdata
[index
] = array
->pdata
[array
->len
- 1];
374 array
->pdata
[array
->len
- 1] = NULL
;
382 g_ptr_array_remove (GPtrArray
* farray
,
385 GRealPtrArray
* array
= (GRealPtrArray
*) farray
;
388 g_return_val_if_fail (array
, FALSE
);
390 for (i
= 0; i
< array
->len
; i
+= 1)
392 if (array
->pdata
[i
] == data
)
394 g_ptr_array_remove_index (farray
, i
);
403 g_ptr_array_remove_fast (GPtrArray
* farray
,
406 GRealPtrArray
* array
= (GRealPtrArray
*) farray
;
409 g_return_val_if_fail (array
, FALSE
);
411 for (i
= 0; i
< array
->len
; i
+= 1)
413 if (array
->pdata
[i
] == data
)
415 g_ptr_array_remove_index_fast (farray
, i
);
424 g_ptr_array_add (GPtrArray
* farray
,
427 GRealPtrArray
* array
= (GRealPtrArray
*) farray
;
429 g_return_if_fail (array
);
431 g_ptr_array_maybe_expand (array
, 1);
433 array
->pdata
[array
->len
++] = data
;
439 GByteArray
* g_byte_array_new (void)
441 return (GByteArray
*) g_array_new (FALSE
, FALSE
, 1);
444 void g_byte_array_free (GByteArray
*array
,
445 gboolean free_segment
)
447 g_array_free ((GArray
*) array
, free_segment
);
450 GByteArray
* g_byte_array_append (GByteArray
*array
,
454 g_array_append_vals ((GArray
*) array
, (guint8
*)data
, len
);
459 GByteArray
* g_byte_array_prepend (GByteArray
*array
,
463 g_array_prepend_vals ((GArray
*) array
, (guint8
*)data
, len
);
468 GByteArray
* g_byte_array_set_size (GByteArray
*array
,
471 g_array_set_size ((GArray
*) array
, length
);
476 GByteArray
* g_byte_array_remove_index (GByteArray
*array
,
479 g_array_remove_index((GArray
*) array
, index
);
484 GByteArray
* g_byte_array_remove_index_fast (GByteArray
*array
,
487 g_array_remove_index_fast((GArray
*) array
, index
);