G{Byte,Ptr,}Array: move docs from tmpl to .c
[platform/upstream/glib.git] / glib / garray.c
1 /* GLIB - Library of useful routines for C programming
2  * Copyright (C) 1995-1997  Peter Mattis, Spencer Kimball and Josh MacDonald
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser 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.
8  *
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  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser 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.
18  */
19
20 /*
21  * Modified by the GLib Team and others 1997-2000.  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/. 
25  */
26
27 /* 
28  * MT safe
29  */
30
31 #include "config.h"
32
33 #include <string.h>
34 #include <stdlib.h>
35
36 #include "garray.h"
37
38 #include "gmem.h"
39 #include "gthread.h"
40 #include "gmessages.h"
41 #include "gqsort.h"
42
43 #include "galias.h"
44
45 /**
46  * SECTION: arrays
47  * @title: Arrays
48  * @short_description: arrays of arbitrary elements which grow
49  *                     automatically as elements are added
50  *
51  * Arrays are similar to standard C arrays, except that they grow
52  * automatically as elements are added.
53  *
54  * Array elements can be of any size (though all elements of one array
55  * are the same size), and the array can be automatically cleared to
56  * '0's and zero-terminated.
57  *
58  * To create a new array use g_array_new().
59  *
60  * To add elements to an array, use g_array_append_val(),
61  * g_array_append_vals(), g_array_prepend_val(), and
62  * g_array_prepend_vals().
63  *
64  * To access an element of an array, use g_array_index().
65  *
66  * To set the size of an array, use g_array_set_size().
67  *
68  * To free an array, use g_array_free().
69  *
70  * <example>
71  *  <title>Using a #GArray to store #gint values</title>
72  *  <programlisting>
73  *   GArray *garray;
74  *   gint i;
75  *   /<!-- -->* We create a new array to store gint values.
76  *      We don't want it zero-terminated or cleared to 0's. *<!-- -->/
77  *   garray = g_array_new (FALSE, FALSE, sizeof (gint));
78  *   for (i = 0; i &lt; 10000; i++)
79  *     g_array_append_val (garray, i);
80  *   for (i = 0; i &lt; 10000; i++)
81  *     if (g_array_index (garray, gint, i) != i)
82  *       g_print ("ERROR: got &percnt;d instead of &percnt;d\n",
83  *                g_array_index (garray, gint, i), i);
84  *   g_array_free (garray, TRUE);
85  *  </programlisting>
86  * </example>
87  **/
88
89 #define MIN_ARRAY_SIZE  16
90
91 typedef struct _GRealArray  GRealArray;
92
93 /**
94  * GArray:
95  * @data: a pointer to the element data. The data may be moved as
96  *        elements are added to the #GArray.
97  * @len: the number of elements in the #GArray not including the
98  *       possible terminating zero element.
99  *
100  * Contains the public fields of an <link
101  * linkend="glib-arrays">Array</link>.
102  **/
103 struct _GRealArray
104 {
105   guint8 *data;
106   guint   len;
107   guint   alloc;
108   guint   elt_size;
109   guint   zero_terminated : 1;
110   guint   clear : 1;
111   volatile gint ref_count;
112 };
113
114 /**
115  * g_array_index:
116  * @a: a #GArray.
117  * @t: the type of the elements.
118  * @i: the index of the element to return.
119  * @Returns: the element of the #GArray at the index given by @i.
120  *
121  * Returns the element of a #GArray at the given index. The return
122  * value is cast to the given type.
123  *
124  * <example>
125  *  <title>Getting a pointer to an element in a #GArray</title>
126  *  <programlisting>
127  *   EDayViewEvent *event;
128  *   /<!-- -->* This gets a pointer to the 4th element
129  *      in the array of EDayViewEvent structs. *<!-- -->/
130  *   event = &amp;g_array_index (events, EDayViewEvent, 3);
131  *  </programlisting>
132  * </example>
133  **/
134
135 #define g_array_elt_len(array,i) ((array)->elt_size * (i))
136 #define g_array_elt_pos(array,i) ((array)->data + g_array_elt_len((array),(i)))
137 #define g_array_elt_zero(array, pos, len)                               \
138   (memset (g_array_elt_pos ((array), pos), 0,  g_array_elt_len ((array), len)))
139 #define g_array_zero_terminate(array) G_STMT_START{                     \
140   if ((array)->zero_terminated)                                         \
141     g_array_elt_zero ((array), (array)->len, 1);                        \
142 }G_STMT_END
143
144 static guint g_nearest_pow        (gint        num) G_GNUC_CONST;
145 static void  g_array_maybe_expand (GRealArray *array,
146                                    gint        len);
147
148 /**
149  * g_array_new:
150  * @zero_terminated: %TRUE if the array should have an extra element at
151  *                   the end which is set to 0.
152  * @clear_: %TRUE if #GArray elements should be automatically cleared
153  *          to 0 when they are allocated.
154  * @element_size: the size of each element in bytes.
155  * @Returns: the new #GArray.
156  *
157  * Creates a new #GArray with a reference count of 1.
158  **/
159 GArray*
160 g_array_new (gboolean zero_terminated,
161              gboolean clear,
162              guint    elt_size)
163 {
164   return (GArray*) g_array_sized_new (zero_terminated, clear, elt_size, 0);
165 }
166
167 /**
168  * g_array_sized_new:
169  * @zero_terminated: %TRUE if the array should have an extra element at
170  *                   the end with all bits cleared.
171  * @clear_: %TRUE if all bits in the array should be cleared to 0 on
172  *          allocation.
173  * @element_size: size of each element in the array.
174  * @reserved_size: number of elements preallocated.
175  * @Returns: the new #GArray.
176  *
177  * Creates a new #GArray with @reserved_size elements preallocated and
178  * a reference count of 1. This avoids frequent reallocation, if you
179  * are going to add many elements to the array. Note however that the
180  * size of the array is still 0.
181  **/
182 GArray* g_array_sized_new (gboolean zero_terminated,
183                            gboolean clear,
184                            guint    elt_size,
185                            guint    reserved_size)
186 {
187   GRealArray *array = g_slice_new (GRealArray);
188
189   array->data            = NULL;
190   array->len             = 0;
191   array->alloc           = 0;
192   array->zero_terminated = (zero_terminated ? 1 : 0);
193   array->clear           = (clear ? 1 : 0);
194   array->elt_size        = elt_size;
195   array->ref_count       = 1;
196
197   if (array->zero_terminated || reserved_size != 0)
198     {
199       g_array_maybe_expand (array, reserved_size);
200       g_array_zero_terminate(array);
201     }
202
203   return (GArray*) array;
204 }
205
206 /**
207  * g_array_ref:
208  * @array: A #GArray.
209  *
210  * Atomically increments the reference count of @array by one. This
211  * function is MT-safe and may be called from any thread.
212  *
213  * Returns: The passed in #GArray.
214  *
215  * Since: 2.22
216  **/
217 GArray *
218 g_array_ref (GArray *array)
219 {
220   GRealArray *rarray = (GRealArray*) array;
221   g_return_val_if_fail (g_atomic_int_get (&rarray->ref_count) > 0, array);
222   g_atomic_int_inc (&rarray->ref_count);
223   return array;
224 }
225
226 /**
227  * g_array_unref:
228  * @array: A #GArray.
229  *
230  * Atomically decrements the reference count of @array by one. If the
231  * reference count drops to 0, all memory allocated by the array is
232  * released. This function is MT-safe and may be called from any
233  * thread.
234  *
235  * Since: 2.22
236  **/
237 void
238 g_array_unref (GArray *array)
239 {
240   GRealArray *rarray = (GRealArray*) array;
241   g_return_if_fail (g_atomic_int_get (&rarray->ref_count) > 0);
242   if (g_atomic_int_dec_and_test (&rarray->ref_count))
243     g_array_free (array, TRUE);
244 }
245
246 /**
247  * g_array_get_element_size:
248  * @array: A #GArray.
249  *
250  * Gets the size of the elements in @array.
251  *
252  * Returns: Size of each element, in bytes.
253  *
254  * Since: 2.22
255  **/
256 guint
257 g_array_get_element_size (GArray *array)
258 {
259   GRealArray *rarray = (GRealArray*) array;
260   return rarray->elt_size;
261 }
262
263 /**
264  * g_array_free:
265  * @array: a #GArray.
266  * @free_segment: if %TRUE the actual element data is freed as well.
267  * @Returns: the element data if @free_segment is %FALSE, otherwise
268  *           %NULL.  The element data should be freed using g_free().
269  *
270  * Frees the memory allocated for the #GArray. If @free_segment is
271  * %TRUE it frees the memory block holding the elements as well and
272  * also each element if @array has a @element_free_func set. Pass
273  * %FALSE if you want to free the #GArray wrapper but preserve the
274  * underlying array for use elsewhere. If the reference count of @array
275  * is greater than one, the #GArray wrapper is preserved but the size
276  * of @array will be set to zero.
277  *
278  * <note><para>If array elements contain dynamically-allocated memory,
279  * they should be freed separately.</para></note>
280  **/
281 gchar*
282 g_array_free (GArray   *farray,
283               gboolean  free_segment)
284 {
285   GRealArray *array = (GRealArray*) farray;
286   gchar* segment;
287   gboolean preserve_wrapper;
288
289   g_return_val_if_fail (array, NULL);
290
291   /* if others are holding a reference, preserve the wrapper but do free/return the data */
292   preserve_wrapper = FALSE;
293   if (g_atomic_int_get (&array->ref_count) > 1)
294     preserve_wrapper = TRUE;
295
296   if (free_segment)
297     {
298       g_free (array->data);
299       segment = NULL;
300     }
301   else
302     segment = (gchar*) array->data;
303
304   if (preserve_wrapper)
305     {
306       array->data            = NULL;
307       array->len             = 0;
308       array->alloc           = 0;
309     }
310   else
311     {
312       g_slice_free1 (sizeof (GRealArray), array);
313     }
314
315   return segment;
316 }
317
318 /**
319  * g_array_append_vals:
320  * @array: a #GArray.
321  * @data: a pointer to the elements to append to the end of the array.
322  * @len: the number of elements to append.
323  * @Returns: the #GArray.
324  *
325  * Adds @len elements onto the end of the array.
326  **/
327 /**
328  * g_array_append_val:
329  * @a: a #GArray.
330  * @v: the value to append to the #GArray.
331  * @Returns: the #GArray.
332  *
333  * Adds the value on to the end of the array. The array will grow in
334  * size automatically if necessary.
335  *
336  * <note><para>g_array_append_val() is a macro which uses a reference
337  * to the value parameter @v. This means that you cannot use it with
338  * literal values such as "27". You must use variables.</para></note>
339  **/
340 GArray*
341 g_array_append_vals (GArray       *farray,
342                      gconstpointer data,
343                      guint         len)
344 {
345   GRealArray *array = (GRealArray*) farray;
346
347   g_array_maybe_expand (array, len);
348
349   memcpy (g_array_elt_pos (array, array->len), data, 
350           g_array_elt_len (array, len));
351
352   array->len += len;
353
354   g_array_zero_terminate (array);
355
356   return farray;
357 }
358
359 /**
360  * g_array_prepend_vals:
361  * @array: a #GArray.
362  * @data: a pointer to the elements to prepend to the start of the
363  *        array.
364  * @len: the number of elements to prepend.
365  * @Returns: the #GArray.
366  *
367  * Adds @len elements onto the start of the array.
368  *
369  * This operation is slower than g_array_append_vals() since the
370  * existing elements in the array have to be moved to make space for
371  * the new elements.
372  **/
373 /**
374  * g_array_prepend_val:
375  * @a: a #GArray.
376  * @v: the value to prepend to the #GArray.
377  * @Returns: the #GArray.
378  *
379  * Adds the value on to the start of the array. The array will grow in
380  * size automatically if necessary.
381  *
382  * This operation is slower than g_array_append_val() since the
383  * existing elements in the array have to be moved to make space for
384  * the new element.
385  *
386  * <note><para>g_array_prepend_val() is a macro which uses a reference
387  * to the value parameter @v. This means that you cannot use it with
388  * literal values such as "27". You must use variables.</para></note>
389  **/
390 GArray*
391 g_array_prepend_vals (GArray        *farray,
392                       gconstpointer  data,
393                       guint          len)
394 {
395   GRealArray *array = (GRealArray*) farray;
396
397   g_array_maybe_expand (array, len);
398
399   g_memmove (g_array_elt_pos (array, len), g_array_elt_pos (array, 0), 
400              g_array_elt_len (array, array->len));
401
402   memcpy (g_array_elt_pos (array, 0), data, g_array_elt_len (array, len));
403
404   array->len += len;
405
406   g_array_zero_terminate (array);
407
408   return farray;
409 }
410
411 /**
412  * g_array_insert_vals:
413  * @array: a #GArray.
414  * @index_: the index to place the elements at.
415  * @data: a pointer to the elements to insert.
416  * @len: the number of elements to insert.
417  * @Returns: the #GArray.
418  *
419  * Inserts @len elements into a #GArray at the given index.
420  **/
421 /**
422  * g_array_insert_val:
423  * @a: a #GArray.
424  * @i: the index to place the element at.
425  * @v: the value to insert into the array.
426  * @Returns: the #GArray.
427  *
428  * Inserts an element into an array at the given index.
429  *
430  * <note><para>g_array_insert_val() is a macro which uses a reference
431  * to the value parameter @v. This means that you cannot use it with
432  * literal values such as "27". You must use variables.</para></note>
433  **/
434 GArray*
435 g_array_insert_vals (GArray        *farray,
436                      guint          index_,
437                      gconstpointer  data,
438                      guint          len)
439 {
440   GRealArray *array = (GRealArray*) farray;
441
442   g_array_maybe_expand (array, len);
443
444   g_memmove (g_array_elt_pos (array, len + index_), 
445              g_array_elt_pos (array, index_), 
446              g_array_elt_len (array, array->len - index_));
447
448   memcpy (g_array_elt_pos (array, index_), data, g_array_elt_len (array, len));
449
450   array->len += len;
451
452   g_array_zero_terminate (array);
453
454   return farray;
455 }
456
457 /**
458  * g_array_set_size:
459  * @array: a #GArray.
460  * @length: the new size of the #GArray.
461  * @Returns: the #GArray.
462  *
463  * Sets the size of the array, expanding it if necessary. If the array
464  * was created with @clear_ set to %TRUE, the new elements are set to 0.
465  **/
466 GArray*
467 g_array_set_size (GArray *farray,
468                   guint   length)
469 {
470   GRealArray *array = (GRealArray*) farray;
471   if (length > array->len)
472     {
473       g_array_maybe_expand (array, length - array->len);
474       
475       if (array->clear)
476         g_array_elt_zero (array, array->len, length - array->len);
477     }
478   else if (G_UNLIKELY (g_mem_gc_friendly) && length < array->len)
479     g_array_elt_zero (array, length, array->len - length);
480   
481   array->len = length;
482   
483   g_array_zero_terminate (array);
484   
485   return farray;
486 }
487
488 /**
489  * g_array_remove_index:
490  * @array: a #GArray.
491  * @index_: the index of the element to remove.
492  * @Returns: the #GArray.
493  *
494  * Removes the element at the given index from a #GArray. The following
495  * elements are moved down one place.
496  **/
497 GArray*
498 g_array_remove_index (GArray *farray,
499                       guint   index_)
500 {
501   GRealArray* array = (GRealArray*) farray;
502
503   g_return_val_if_fail (array, NULL);
504
505   g_return_val_if_fail (index_ < array->len, NULL);
506
507   if (index_ != array->len - 1)
508     g_memmove (g_array_elt_pos (array, index_),
509                g_array_elt_pos (array, index_ + 1),
510                g_array_elt_len (array, array->len - index_ - 1));
511   
512   array->len -= 1;
513
514   if (G_UNLIKELY (g_mem_gc_friendly))
515     g_array_elt_zero (array, array->len, 1);
516   else
517     g_array_zero_terminate (array);
518
519   return farray;
520 }
521
522 /**
523  * g_array_remove_index_fast:
524  * @array: a @GArray.
525  * @index_: the index of the element to remove.
526  * @Returns: the #GArray.
527  *
528  * Removes the element at the given index from a #GArray. The last
529  * element in the array is used to fill in the space, so this function
530  * does not preserve the order of the #GArray. But it is faster than
531  * g_array_remove_index().
532  **/
533 GArray*
534 g_array_remove_index_fast (GArray *farray,
535                            guint   index_)
536 {
537   GRealArray* array = (GRealArray*) farray;
538
539   g_return_val_if_fail (array, NULL);
540
541   g_return_val_if_fail (index_ < array->len, NULL);
542
543   if (index_ != array->len - 1)
544     memcpy (g_array_elt_pos (array, index_), 
545             g_array_elt_pos (array, array->len - 1),
546             g_array_elt_len (array, 1));
547   
548   array->len -= 1;
549
550   if (G_UNLIKELY (g_mem_gc_friendly))
551     g_array_elt_zero (array, array->len, 1);
552   else
553     g_array_zero_terminate (array);
554
555   return farray;
556 }
557
558 /**
559  * g_array_remove_range:
560  * @array: a @GArray.
561  * @index_: the index of the first element to remove.
562  * @length: the number of elements to remove.
563  * @Returns: the #GArray.
564  *
565  * Removes the given number of elements starting at the given index
566  * from a #GArray.  The following elements are moved to close the gap.
567  *
568  * Since: 2.4
569  **/
570 GArray*
571 g_array_remove_range (GArray *farray,
572                       guint   index_,
573                       guint   length)
574 {
575   GRealArray *array = (GRealArray*) farray;
576
577   g_return_val_if_fail (array, NULL);
578   g_return_val_if_fail (index_ < array->len, NULL);
579   g_return_val_if_fail (index_ + length <= array->len, NULL);
580
581   if (index_ + length != array->len)
582     g_memmove (g_array_elt_pos (array, index_), 
583                g_array_elt_pos (array, index_ + length), 
584                (array->len - (index_ + length)) * array->elt_size);
585
586   array->len -= length;
587   if (G_UNLIKELY (g_mem_gc_friendly))
588     g_array_elt_zero (array, array->len, length);
589   else
590     g_array_zero_terminate (array);
591
592   return farray;
593 }
594
595 /**
596  * g_array_sort:
597  * @array: a #GArray.
598  * @compare_func: comparison function.
599  *
600  * Sorts a #GArray using @compare_func which should be a qsort()-style
601  * comparison function (returns less than zero for first arg is less
602  * than second arg, zero for equal, greater zero if first arg is
603  * greater than second arg).
604  *
605  * If two array elements compare equal, their order in the sorted array
606  * is undefined.
607  **/
608 void
609 g_array_sort (GArray       *farray,
610               GCompareFunc  compare_func)
611 {
612   GRealArray *array = (GRealArray*) farray;
613
614   g_return_if_fail (array != NULL);
615
616   qsort (array->data,
617          array->len,
618          array->elt_size,
619          compare_func);
620 }
621
622 /**
623  * g_array_sort_with_data:
624  * @array: a #GArray.
625  * @compare_func: comparison function.
626  * @user_data: data to pass to @compare_func.
627  *
628  * Like g_array_sort(), but the comparison function receives an extra
629  * user data argument.
630  **/
631 void
632 g_array_sort_with_data (GArray           *farray,
633                         GCompareDataFunc  compare_func,
634                         gpointer          user_data)
635 {
636   GRealArray *array = (GRealArray*) farray;
637
638   g_return_if_fail (array != NULL);
639
640   g_qsort_with_data (array->data,
641                      array->len,
642                      array->elt_size,
643                      compare_func,
644                      user_data);
645 }
646
647 /* Returns the smallest power of 2 greater than n, or n if
648  * such power does not fit in a guint
649  */
650 static guint
651 g_nearest_pow (gint num)
652 {
653   guint n = 1;
654
655   while (n < num && n > 0)
656     n <<= 1;
657
658   return n ? n : num;
659 }
660
661 static void
662 g_array_maybe_expand (GRealArray *array,
663                       gint        len)
664 {
665   guint want_alloc = g_array_elt_len (array, array->len + len + 
666                                       array->zero_terminated);
667
668   if (want_alloc > array->alloc)
669     {
670       want_alloc = g_nearest_pow (want_alloc);
671       want_alloc = MAX (want_alloc, MIN_ARRAY_SIZE);
672
673       array->data = g_realloc (array->data, want_alloc);
674
675       if (G_UNLIKELY (g_mem_gc_friendly))
676         memset (array->data + array->alloc, 0, want_alloc - array->alloc);
677
678       array->alloc = want_alloc;
679     }
680 }
681
682 /* Pointer Array
683  */
684 /**
685  * SECTION: arrays_pointer
686  * @title: Pointer Arrays
687  * @short_description: arrays of pointers to any type of data, which
688  *                     grow automatically as new elements are added
689  *
690  * Pointer Arrays are similar to Arrays but are used only for storing
691  * pointers.
692  *
693  * <note><para>If you remove elements from the array, elements at the
694  * end of the array are moved into the space previously occupied by the
695  * removed element. This means that you should not rely on the index of
696  * particular elements remaining the same. You should also be careful
697  * when deleting elements while iterating over the array.</para></note>
698  *
699  * To create a pointer array, use g_ptr_array_new().
700  *
701  * To add elements to a pointer array, use g_ptr_array_add().
702  *
703  * To remove elements from a pointer array, use g_ptr_array_remove(),
704  * g_ptr_array_remove_index() or g_ptr_array_remove_index_fast().
705  *
706  * To access an element of a pointer array, use g_ptr_array_index().
707  *
708  * To set the size of a pointer array, use g_ptr_array_set_size().
709  *
710  * To free a pointer array, use g_ptr_array_free().
711  *
712  * <example>
713  *  <title>Using a #GPtrArray</title>
714  *  <programlisting>
715  *   GPtrArray *gparray;
716  *   gchar *string1 = "one", *string2 = "two", *string3 = "three";
717  *
718  *   gparray = g_ptr_array_new (<!-- -->);
719  *   g_ptr_array_add (gparray, (gpointer) string1);
720  *   g_ptr_array_add (gparray, (gpointer) string2);
721  *   g_ptr_array_add (gparray, (gpointer) string3);
722  *
723  *   if (g_ptr_array_index (gparray, 0) != (gpointer) string1)
724  *     g_print ("ERROR: got &percnt;p instead of &percnt;p\n",
725  *              g_ptr_array_index (gparray, 0), string1);
726  *
727  *   g_ptr_array_free (gparray, TRUE);
728  *  </programlisting>
729  * </example>
730  **/
731
732 typedef struct _GRealPtrArray  GRealPtrArray;
733
734 /**
735  * GPtrArray:
736  * @pdata: points to the array of pointers, which may be moved when the
737  *         array grows.
738  * @len: number of pointers in the array.
739  *
740  * Contains the public fields of a pointer array.
741  **/
742 struct _GRealPtrArray
743 {
744   gpointer     *pdata;
745   guint         len;
746   guint         alloc;
747   volatile gint ref_count;
748   GDestroyNotify element_free_func;
749 };
750
751 /**
752  * g_ptr_array_index:
753  * @array: a #GPtrArray.
754  * @index_: the index of the pointer to return.
755  * @Returns: the pointer at the given index.
756  *
757  * Returns the pointer at the given index of the pointer array.
758  **/
759
760 static void g_ptr_array_maybe_expand (GRealPtrArray *array,
761                                       gint           len);
762
763 /**
764  * g_ptr_array_new:
765  * @Returns: the new #GPtrArray.
766  *
767  * Creates a new #GPtrArray with a reference count of 1.
768  **/
769 GPtrArray*
770 g_ptr_array_new (void)
771 {
772   return g_ptr_array_sized_new (0);
773 }
774
775 /**
776  * g_ptr_array_sized_new:
777  * @reserved_size: number of pointers preallocated.
778  * @Returns: the new #GPtrArray.
779  *
780  * Creates a new #GPtrArray with @reserved_size pointers preallocated
781  * and a reference count of 1. This avoids frequent reallocation, if
782  * you are going to add many pointers to the array. Note however that
783  * the size of the array is still 0.
784  **/
785 GPtrArray*  
786 g_ptr_array_sized_new (guint reserved_size)
787 {
788   GRealPtrArray *array = g_slice_new (GRealPtrArray);
789
790   array->pdata = NULL;
791   array->len = 0;
792   array->alloc = 0;
793   array->ref_count = 1;
794   array->element_free_func = NULL;
795
796   if (reserved_size != 0)
797     g_ptr_array_maybe_expand (array, reserved_size);
798
799   return (GPtrArray*) array;  
800 }
801
802 /**
803  * g_ptr_array_new_with_free_func:
804  * @element_free_func: A function to free elements with destroy @array or %NULL.
805  *
806  * Creates a new #GPtrArray with a reference count of 1 and use @element_free_func
807  * for freeing each element when the array is destroyed either via
808  * g_ptr_array_unref(), when g_ptr_array_free() is called with @free_segment
809  * set to %TRUE or when removing elements.
810  *
811  * Returns: A new #GPtrArray.
812  *
813  * Since: 2.22
814  **/
815 GPtrArray *
816 g_ptr_array_new_with_free_func (GDestroyNotify element_free_func)
817 {
818   GPtrArray *array;
819
820   array = g_ptr_array_new ();
821   g_ptr_array_set_free_func (array, element_free_func);
822   return array;
823 }
824
825 /**
826  * g_ptr_array_set_free_func:
827  * @array: A #GPtrArray.
828  * @element_free_func: A function to free elements with destroy @array or %NULL.
829  *
830  * Sets a function for freeing each element when @array is destroyed
831  * either via g_ptr_array_unref(), when g_ptr_array_free() is called
832  * with @free_segment set to %TRUE or when removing elements.
833  *
834  * Since: 2.22
835  **/
836 void
837 g_ptr_array_set_free_func (GPtrArray        *array,
838                            GDestroyNotify    element_free_func)
839 {
840   GRealPtrArray* rarray = (GRealPtrArray*) array;
841   rarray->element_free_func = element_free_func;
842 }
843
844 /**
845  * g_ptr_array_ref:
846  * @array: A #GArray.
847  *
848  * Atomically increments the reference count of @array by one. This
849  * function is MT-safe and may be called from any thread.
850  *
851  * Returns: The passed in #GPtrArray.
852  *
853  * Since: 2.22
854  **/
855 GPtrArray *
856 g_ptr_array_ref (GPtrArray *array)
857 {
858   GRealPtrArray *rarray = (GRealPtrArray*) array;
859   g_return_val_if_fail (g_atomic_int_get (&rarray->ref_count) > 0, array);
860   g_atomic_int_inc (&rarray->ref_count);
861   return array;
862 }
863
864 /**
865  * g_ptr_array_unref:
866  * @array: A #GPtrArray.
867  *
868  * Atomically decrements the reference count of @array by one. If the
869  * reference count drops to 0, the effect is the same as calling
870  * g_ptr_array_free() with @free_segment set to %TRUE. This function
871  * is MT-safe and may be called from any thread.
872  *
873  * Since: 2.22
874  **/
875 void
876 g_ptr_array_unref (GPtrArray *array)
877 {
878   GRealPtrArray *rarray = (GRealPtrArray*) array;
879   g_return_if_fail (g_atomic_int_get (&rarray->ref_count) > 0);
880   if (g_atomic_int_dec_and_test (&rarray->ref_count))
881     g_ptr_array_free (array, TRUE);
882 }
883
884 /**
885  * g_ptr_array_free:
886  * @array: a #GPtrArray.
887  * @free_seg: if %TRUE the actual pointer array is freed as well.
888  * @Returns: the pointer array if @free_seg is %FALSE, otherwise %NULL.
889  *           The pointer array should be freed using g_free().
890  *
891  * Frees the memory allocated for the #GPtrArray. If @free_seg is %TRUE
892  * it frees the memory block holding the elements as well. Pass %FALSE
893  * if you want to free the #GPtrArray wrapper but preserve the
894  * underlying array for use elsewhere. If the reference count of @array
895  * is greater than one, the #GPtrArray wrapper is preserved but the
896  * size of @array will be set to zero.
897  *
898  * <note><para>If array contents point to dynamically-allocated
899  * memory, they should be freed separately if @free_seg is %TRUE and no
900  * #GDestroyNotify function has been set for @array.</para></note>
901  **/
902 gpointer*
903 g_ptr_array_free (GPtrArray *farray,
904                   gboolean   free_segment)
905 {
906   GRealPtrArray *array = (GRealPtrArray*) farray;
907   gpointer* segment;
908   gboolean preserve_wrapper;
909
910   g_return_val_if_fail (array, NULL);
911
912   /* if others are holding a reference, preserve the wrapper but do free/return the data */
913   preserve_wrapper = FALSE;
914   if (g_atomic_int_get (&array->ref_count) > 1)
915     preserve_wrapper = TRUE;
916
917   if (free_segment)
918     {
919       if (array->element_free_func != NULL)
920         g_ptr_array_foreach (farray, (GFunc) array->element_free_func, NULL);
921       g_free (array->pdata);
922       segment = NULL;
923     }
924   else
925     segment = array->pdata;
926
927   if (preserve_wrapper)
928     {
929       array->pdata = NULL;
930       array->len = 0;
931       array->alloc = 0;
932     }
933   else
934     {
935       g_slice_free1 (sizeof (GRealPtrArray), array);
936     }
937
938   return segment;
939 }
940
941 static void
942 g_ptr_array_maybe_expand (GRealPtrArray *array,
943                           gint           len)
944 {
945   if ((array->len + len) > array->alloc)
946     {
947       guint old_alloc = array->alloc;
948       array->alloc = g_nearest_pow (array->len + len);
949       array->alloc = MAX (array->alloc, MIN_ARRAY_SIZE);
950       array->pdata = g_realloc (array->pdata, sizeof (gpointer) * array->alloc);
951       if (G_UNLIKELY (g_mem_gc_friendly))
952         for ( ; old_alloc < array->alloc; old_alloc++)
953           array->pdata [old_alloc] = NULL;
954     }
955 }
956
957 /**
958  * g_ptr_array_set_size:
959  * @array: a #GPtrArray.
960  * @length: the new length of the pointer array.
961  *
962  * Sets the size of the array. When making the array larger,
963  * newly-added elements will be set to %NULL. When making it smaller,
964  * if @array has a non-%NULL #GDestroyNotify function then it will be
965  * called for the removed elements.
966  **/
967 void
968 g_ptr_array_set_size  (GPtrArray *farray,
969                        gint       length)
970 {
971   GRealPtrArray* array = (GRealPtrArray*) farray;
972
973   g_return_if_fail (array);
974
975   if (length > array->len)
976     {
977       int i;
978       g_ptr_array_maybe_expand (array, (length - array->len));
979       /* This is not 
980        *     memset (array->pdata + array->len, 0,
981        *            sizeof (gpointer) * (length - array->len));
982        * to make it really portable. Remember (void*)NULL needn't be
983        * bitwise zero. It of course is silly not to use memset (..,0,..).
984        */
985       for (i = array->len; i < length; i++)
986         array->pdata[i] = NULL;
987     }
988   else if (length < array->len)
989     g_ptr_array_remove_range (farray, length, array->len - length);
990
991   array->len = length;
992 }
993
994 /**
995  * g_ptr_array_remove_index:
996  * @array: a #GPtrArray.
997  * @index_: the index of the pointer to remove.
998  * @Returns: the pointer which was removed.
999  *
1000  * Removes the pointer at the given index from the pointer array. The
1001  * following elements are moved down one place. If @array has a
1002  * non-%NULL #GDestroyNotify function it is called for the removed
1003  * element.
1004  **/
1005 gpointer
1006 g_ptr_array_remove_index (GPtrArray *farray,
1007                           guint      index_)
1008 {
1009   GRealPtrArray* array = (GRealPtrArray*) farray;
1010   gpointer result;
1011
1012   g_return_val_if_fail (array, NULL);
1013
1014   g_return_val_if_fail (index_ < array->len, NULL);
1015
1016   result = array->pdata[index_];
1017   
1018   if (array->element_free_func != NULL)
1019     array->element_free_func (array->pdata[index_]);
1020
1021   if (index_ != array->len - 1)
1022     g_memmove (array->pdata + index_, array->pdata + index_ + 1, 
1023                sizeof (gpointer) * (array->len - index_ - 1));
1024   
1025   array->len -= 1;
1026
1027   if (G_UNLIKELY (g_mem_gc_friendly))
1028     array->pdata[array->len] = NULL;
1029
1030   return result;
1031 }
1032
1033 /**
1034  * g_ptr_array_remove_index_fast:
1035  * @array: a #GPtrArray.
1036  * @index_: the index of the pointer to remove.
1037  * @Returns: the pointer which was removed.
1038  *
1039  * Removes the pointer at the given index from the pointer array. The
1040  * last element in the array is used to fill in the space, so this
1041  * function does not preserve the order of the array. But it is faster
1042  * than g_ptr_array_remove_index(). If @array has a non-%NULL
1043  * #GDestroyNotify function it is called for the removed element.
1044  **/
1045 gpointer
1046 g_ptr_array_remove_index_fast (GPtrArray *farray,
1047                                guint      index_)
1048 {
1049   GRealPtrArray* array = (GRealPtrArray*) farray;
1050   gpointer result;
1051
1052   g_return_val_if_fail (array, NULL);
1053
1054   g_return_val_if_fail (index_ < array->len, NULL);
1055
1056   result = array->pdata[index_];
1057   
1058   if (index_ != array->len - 1)
1059     {
1060       if (array->element_free_func != NULL)
1061         array->element_free_func (array->pdata[index_]);
1062       array->pdata[index_] = array->pdata[array->len - 1];
1063     }
1064
1065   array->len -= 1;
1066
1067   if (G_UNLIKELY (g_mem_gc_friendly))
1068     array->pdata[array->len] = NULL;
1069
1070   return result;
1071 }
1072
1073 /**
1074  * g_ptr_array_remove_range:
1075  * @array: a @GPtrArray.
1076  * @index_: the index of the first pointer to remove.
1077  * @length: the number of pointers to remove.
1078  *
1079  * Removes the given number of pointers starting at the given index
1080  * from a #GPtrArray.  The following elements are moved to close the
1081  * gap. If @array has a non-%NULL #GDestroyNotify function it is called
1082  * for the removed elements.
1083  *
1084  * Since: 2.4
1085  **/
1086 void
1087 g_ptr_array_remove_range (GPtrArray *farray,
1088                           guint      index_,
1089                           guint      length)
1090 {
1091   GRealPtrArray* array = (GRealPtrArray*) farray;
1092   guint n;
1093
1094   g_return_if_fail (array);
1095   g_return_if_fail (index_ < array->len);
1096   g_return_if_fail (index_ + length <= array->len);
1097
1098   if (array->element_free_func != NULL)
1099     {
1100       for (n = index_; n < index_ + length; n++)
1101         array->element_free_func (array->pdata[n]);
1102     }
1103
1104   if (index_ + length != array->len)
1105     {
1106       g_memmove (&array->pdata[index_],
1107                  &array->pdata[index_ + length], 
1108                  (array->len - (index_ + length)) * sizeof (gpointer));
1109     }
1110
1111   array->len -= length;
1112   if (G_UNLIKELY (g_mem_gc_friendly))
1113     {
1114       guint i;
1115       for (i = 0; i < length; i++)
1116         array->pdata[array->len + i] = NULL;
1117     }
1118 }
1119
1120 /**
1121  * g_ptr_array_remove:
1122  * @array: a #GPtrArray.
1123  * @data: the pointer to remove.
1124  * @Returns: %TRUE if the pointer is removed. %FALSE if the pointer is
1125  *           not found in the array.
1126  *
1127  * Removes the first occurrence of the given pointer from the pointer
1128  * array. The following elements are moved down one place. If @array
1129  * has a non-%NULL #GDestroyNotify function it is called for the
1130  * removed element.
1131  *
1132  * It returns %TRUE if the pointer was removed, or %FALSE if the
1133  * pointer was not found.
1134  **/
1135 gboolean
1136 g_ptr_array_remove (GPtrArray *farray,
1137                     gpointer   data)
1138 {
1139   GRealPtrArray* array = (GRealPtrArray*) farray;
1140   guint i;
1141
1142   g_return_val_if_fail (array, FALSE);
1143
1144   for (i = 0; i < array->len; i += 1)
1145     {
1146       if (array->pdata[i] == data)
1147         {
1148           g_ptr_array_remove_index (farray, i);
1149           return TRUE;
1150         }
1151     }
1152
1153   return FALSE;
1154 }
1155
1156 /**
1157  * g_ptr_array_remove_fast:
1158  * @array: a #GPtrArray.
1159  * @data: the pointer to remove.
1160  * @Returns: %TRUE if the pointer was found in the array.
1161  *
1162  * Removes the first occurrence of the given pointer from the pointer
1163  * array. The last element in the array is used to fill in the space,
1164  * so this function does not preserve the order of the array. But it is
1165  * faster than g_ptr_array_remove(). If @array has a non-%NULL
1166  * #GDestroyNotify function it is called for the removed element.
1167  *
1168  * It returns %TRUE if the pointer was removed, or %FALSE if the
1169  * pointer was not found.
1170  **/
1171 gboolean
1172 g_ptr_array_remove_fast (GPtrArray *farray,
1173                          gpointer   data)
1174 {
1175   GRealPtrArray* array = (GRealPtrArray*) farray;
1176   guint i;
1177
1178   g_return_val_if_fail (array, FALSE);
1179
1180   for (i = 0; i < array->len; i += 1)
1181     {
1182       if (array->pdata[i] == data)
1183         {
1184           g_ptr_array_remove_index_fast (farray, i);
1185           return TRUE;
1186         }
1187     }
1188
1189   return FALSE;
1190 }
1191
1192 /**
1193  * g_ptr_array_add:
1194  * @array: a #GPtrArray.
1195  * @data: the pointer to add.
1196  *
1197  * Adds a pointer to the end of the pointer array. The array will grow
1198  * in size automatically if necessary.
1199  **/
1200 void
1201 g_ptr_array_add (GPtrArray *farray,
1202                  gpointer   data)
1203 {
1204   GRealPtrArray* array = (GRealPtrArray*) farray;
1205
1206   g_return_if_fail (array);
1207
1208   g_ptr_array_maybe_expand (array, 1);
1209
1210   array->pdata[array->len++] = data;
1211 }
1212
1213 /**
1214  * g_ptr_array_sort:
1215  * @array: a #GPtrArray.
1216  * @compare_func: comparison function.
1217  *
1218  * Sorts the array, using @compare_func which should be a qsort()-style
1219  * comparison function (returns less than zero for first arg is less
1220  * than second arg, zero for equal, greater than zero if irst arg is
1221  * greater than second arg).
1222  *
1223  * If two array elements compare equal, their order in the sorted array
1224  * is undefined.
1225  *
1226  * <note><para>The comparison function for g_ptr_array_sort() doesn't
1227  * take the pointers from the array as arguments, it takes pointers to
1228  * the pointers in the array.</para></note>
1229  **/
1230 void
1231 g_ptr_array_sort (GPtrArray    *array,
1232                   GCompareFunc  compare_func)
1233 {
1234   g_return_if_fail (array != NULL);
1235
1236   qsort (array->pdata,
1237          array->len,
1238          sizeof (gpointer),
1239          compare_func);
1240 }
1241
1242 /**
1243  * g_ptr_array_sort_with_data:
1244  * @array: a #GPtrArray.
1245  * @compare_func: comparison function.
1246  * @user_data: data to pass to @compare_func.
1247  *
1248  * Like g_ptr_array_sort(), but the comparison function has an extra
1249  * user data argument.
1250  *
1251  * <note><para>The comparison function for g_ptr_array_sort_with_data()
1252  * doesn't take the pointers from the array as arguments, it takes
1253  * pointers to the pointers in the array.</para></note>
1254  **/
1255 void
1256 g_ptr_array_sort_with_data (GPtrArray        *array,
1257                             GCompareDataFunc  compare_func,
1258                             gpointer          user_data)
1259 {
1260   g_return_if_fail (array != NULL);
1261
1262   g_qsort_with_data (array->pdata,
1263                      array->len,
1264                      sizeof (gpointer),
1265                      compare_func,
1266                      user_data);
1267 }
1268
1269 /**
1270  * g_ptr_array_foreach:
1271  * @array: a #GPtrArray
1272  * @func: the function to call for each array element
1273  * @user_data: user data to pass to the function
1274  * 
1275  * Calls a function for each element of a #GPtrArray.
1276  *
1277  * Since: 2.4
1278  **/
1279 void
1280 g_ptr_array_foreach (GPtrArray *array,
1281                      GFunc      func,
1282                      gpointer   user_data)
1283 {
1284   guint i;
1285
1286   g_return_if_fail (array);
1287
1288   for (i = 0; i < array->len; i++)
1289     (*func) (array->pdata[i], user_data);
1290 }
1291
1292 /* Byte arrays 
1293  */
1294 /**
1295  * SECTION: arrays_byte
1296  * @title: Byte Arrays
1297  * @short_description: arrays of bytes, which grow automatically as
1298  *                     elements are added
1299  *
1300  * #GByteArray is based on #GArray, to provide arrays of bytes which
1301  * grow automatically as elements are added.
1302  *
1303  * To create a new #GByteArray use g_byte_array_new().
1304  *
1305  * To add elements to a #GByteArray, use g_byte_array_append(), and
1306  * g_byte_array_prepend().
1307  *
1308  * To set the size of a #GByteArray, use g_byte_array_set_size().
1309  *
1310  * To free a #GByteArray, use g_byte_array_free().
1311  *
1312  * <example>
1313  *  <title>Using a #GByteArray</title>
1314  *  <programlisting>
1315  *   GByteArray *gbarray;
1316  *   gint i;
1317  *
1318  *   gbarray = g_byte_array_new (<!-- -->);
1319  *   for (i = 0; i &lt; 10000; i++)
1320  *     g_byte_array_append (gbarray, (guint8*) "abcd", 4);
1321  *
1322  *   for (i = 0; i &lt; 10000; i++)
1323  *     {
1324  *       g_assert (gbarray->data[4*i] == 'a');
1325  *       g_assert (gbarray->data[4*i+1] == 'b');
1326  *       g_assert (gbarray->data[4*i+2] == 'c');
1327  *       g_assert (gbarray->data[4*i+3] == 'd');
1328  *     }
1329  *
1330  *   g_byte_array_free (gbarray, TRUE);
1331  *  </programlisting>
1332  * </example>
1333  **/
1334
1335 /**
1336  * GByteArray:
1337  * @data: a pointer to the element data. The data may be moved as
1338  *        elements are added to the #GByteArray.
1339  * @len: the number of elements in the #GByteArray.
1340  *
1341  * The <structname>GByteArray</structname> struct allows access to the
1342  * public fields of a <structname>GByteArray</structname>.
1343  **/
1344
1345 /**
1346  * g_byte_array_new:
1347  * @Returns: the new #GByteArray.
1348  *
1349  * Creates a new #GByteArray with a reference count of 1.
1350  **/
1351 GByteArray* g_byte_array_new (void)
1352 {
1353   return (GByteArray*) g_array_sized_new (FALSE, FALSE, 1, 0);
1354 }
1355
1356 /**
1357  * g_byte_array_sized_new:
1358  * @reserved_size: number of bytes preallocated.
1359  * @Returns: the new #GByteArray.
1360  *
1361  * Creates a new #GByteArray with @reserved_size bytes preallocated.
1362  * This avoids frequent reallocation, if you are going to add many
1363  * bytes to the array. Note however that the size of the array is still
1364  * 0.
1365  **/
1366 GByteArray* g_byte_array_sized_new (guint reserved_size)
1367 {
1368   return (GByteArray*) g_array_sized_new (FALSE, FALSE, 1, reserved_size);
1369 }
1370
1371 /**
1372  * g_byte_array_free:
1373  * @array: a #GByteArray.
1374  * @free_segment: if %TRUE the actual byte data is freed as well.
1375  * @Returns: the element data if @free_segment is %FALSE, otherwise
1376  *           %NULL.  The element data should be freed using g_free().
1377  *
1378  * Frees the memory allocated by the #GByteArray. If @free_segment is
1379  * %TRUE it frees the actual byte data. If the reference count of
1380  * @array is greater than one, the #GByteArray wrapper is preserved but
1381  * the size of @array will be set to zero.
1382  **/
1383 guint8*     g_byte_array_free     (GByteArray *array,
1384                                    gboolean    free_segment)
1385 {
1386   return (guint8*) g_array_free ((GArray*) array, free_segment);
1387 }
1388
1389 /**
1390  * g_byte_array_ref:
1391  * @array: A #GByteArray.
1392  *
1393  * Atomically increments the reference count of @array by one. This
1394  * function is MT-safe and may be called from any thread.
1395  *
1396  * Returns: The passed in #GByteArray.
1397  *
1398  * Since: 2.22
1399  **/
1400 GByteArray *
1401 g_byte_array_ref (GByteArray *array)
1402 {
1403   return (GByteArray *) g_array_ref ((GArray *) array);
1404 }
1405
1406 /**
1407  * g_byte_array_unref:
1408  * @array: A #GByteArray.
1409  *
1410  * Atomically decrements the reference count of @array by one. If the
1411  * reference count drops to 0, all memory allocated by the array is
1412  * released. This function is MT-safe and may be called from any
1413  * thread.
1414  *
1415  * Since: 2.22
1416  **/
1417 void
1418 g_byte_array_unref (GByteArray *array)
1419 {
1420   g_array_unref ((GArray *) array);
1421 }
1422
1423 /**
1424  * g_byte_array_append:
1425  * @array: a #GByteArray.
1426  * @data: the byte data to be added.
1427  * @len: the number of bytes to add.
1428  * @Returns: the #GByteArray.
1429  *
1430  * Adds the given bytes to the end of the #GByteArray. The array will
1431  * grow in size automatically if necessary.
1432  **/
1433 GByteArray* g_byte_array_append   (GByteArray   *array,
1434                                    const guint8 *data,
1435                                    guint         len)
1436 {
1437   g_array_append_vals ((GArray*) array, (guint8*)data, len);
1438
1439   return array;
1440 }
1441
1442 /**
1443  * g_byte_array_prepend:
1444  * @array: a #GByteArray.
1445  * @data: the byte data to be added.
1446  * @len: the number of bytes to add.
1447  * @Returns: the #GByteArray.
1448  *
1449  * Adds the given data to the start of the #GByteArray. The array will
1450  * grow in size automatically if necessary.
1451  **/
1452 GByteArray* g_byte_array_prepend  (GByteArray   *array,
1453                                    const guint8 *data,
1454                                    guint         len)
1455 {
1456   g_array_prepend_vals ((GArray*) array, (guint8*)data, len);
1457
1458   return array;
1459 }
1460
1461 /**
1462  * g_byte_array_set_size:
1463  * @array: a #GByteArray.
1464  * @length: the new size of the #GByteArray.
1465  * @Returns: the #GByteArray.
1466  *
1467  * Sets the size of the #GByteArray, expanding it if necessary.
1468  **/
1469 GByteArray* g_byte_array_set_size (GByteArray *array,
1470                                    guint       length)
1471 {
1472   g_array_set_size ((GArray*) array, length);
1473
1474   return array;
1475 }
1476
1477 /**
1478  * g_byte_array_remove_index:
1479  * @array: a #GByteArray.
1480  * @index_: the index of the byte to remove.
1481  * @Returns: the #GByteArray.
1482  *
1483  * Removes the byte at the given index from a #GByteArray. The
1484  * following bytes are moved down one place.
1485  **/
1486 GByteArray* g_byte_array_remove_index (GByteArray *array,
1487                                        guint       index_)
1488 {
1489   g_array_remove_index ((GArray*) array, index_);
1490
1491   return array;
1492 }
1493
1494 /**
1495  * g_byte_array_remove_index_fast:
1496  * @array: a #GByteArray.
1497  * @index_: the index of the byte to remove.
1498  * @Returns: the #GByteArray.
1499  *
1500  * Removes the byte at the given index from a #GByteArray. The last
1501  * element in the array is used to fill in the space, so this function
1502  * does not preserve the order of the #GByteArray. But it is faster
1503  * than g_byte_array_remove_index().
1504  **/
1505 GByteArray* g_byte_array_remove_index_fast (GByteArray *array,
1506                                             guint       index_)
1507 {
1508   g_array_remove_index_fast ((GArray*) array, index_);
1509
1510   return array;
1511 }
1512
1513 /**
1514  * g_byte_array_remove_range:
1515  * @array: a @GByteArray.
1516  * @index_: the index of the first byte to remove.
1517  * @length: the number of bytes to remove.
1518  * @Returns: the #GByteArray.
1519  *
1520  * Removes the given number of bytes starting at the given index from a
1521  * #GByteArray.  The following elements are moved to close the gap.
1522  *
1523  * Since: 2.4
1524  **/
1525 GByteArray*
1526 g_byte_array_remove_range (GByteArray *array,
1527                            guint       index_,
1528                            guint       length)
1529 {
1530   g_return_val_if_fail (array, NULL);
1531   g_return_val_if_fail (index_ < array->len, NULL);
1532   g_return_val_if_fail (index_ + length <= array->len, NULL);
1533
1534   return (GByteArray *)g_array_remove_range ((GArray*) array, index_, length);
1535 }
1536
1537 /**
1538  * g_byte_array_sort:
1539  * @array: a #GByteArray.
1540  * @compare_func: comparison function.
1541  *
1542  * Sorts a byte array, using @compare_func which should be a
1543  * qsort()-style comparison function (returns less than zero for first
1544  * arg is less than second arg, zero for equal, greater than zero if
1545  * first arg is greater than second arg).
1546  *
1547  * If two array elements compare equal, their order in the sorted array
1548  * is undefined.
1549  **/
1550 void
1551 g_byte_array_sort (GByteArray   *array,
1552                    GCompareFunc  compare_func)
1553 {
1554   g_array_sort ((GArray *) array, compare_func);
1555 }
1556
1557 /**
1558  * g_byte_array_sort_with_data:
1559  * @array: a #GByteArray.
1560  * @compare_func: comparison function.
1561  * @user_data: data to pass to @compare_func.
1562  *
1563  * Like g_byte_array_sort(), but the comparison function takes an extra
1564  * user data argument.
1565  **/
1566 void
1567 g_byte_array_sort_with_data (GByteArray       *array,
1568                              GCompareDataFunc  compare_func,
1569                              gpointer          user_data)
1570 {
1571   g_array_sort_with_data ((GArray *) array, compare_func, user_data);
1572 }
1573
1574 #define __G_ARRAY_C__
1575 #include "galiasdef.c"