Bug 580450 – Reference counting and boxed types for arrays
[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 #define MIN_ARRAY_SIZE  16
47
48 typedef struct _GRealArray  GRealArray;
49
50 struct _GRealArray
51 {
52   guint8 *data;
53   guint   len;
54   guint   alloc;
55   guint   elt_size;
56   guint   zero_terminated : 1;
57   guint   clear : 1;
58   volatile gint ref_count;
59 };
60
61 #define g_array_elt_len(array,i) ((array)->elt_size * (i))
62 #define g_array_elt_pos(array,i) ((array)->data + g_array_elt_len((array),(i)))
63 #define g_array_elt_zero(array, pos, len)                               \
64   (memset (g_array_elt_pos ((array), pos), 0,  g_array_elt_len ((array), len)))
65 #define g_array_zero_terminate(array) G_STMT_START{                     \
66   if ((array)->zero_terminated)                                         \
67     g_array_elt_zero ((array), (array)->len, 1);                        \
68 }G_STMT_END
69
70 static gint g_nearest_pow        (gint        num) G_GNUC_CONST;
71 static void g_array_maybe_expand (GRealArray *array,
72                                   gint        len);
73
74 GArray*
75 g_array_new (gboolean zero_terminated,
76              gboolean clear,
77              guint    elt_size)
78 {
79   return (GArray*) g_array_sized_new (zero_terminated, clear, elt_size, 0);
80 }
81
82 GArray* g_array_sized_new (gboolean zero_terminated,
83                            gboolean clear,
84                            guint    elt_size,
85                            guint    reserved_size)
86 {
87   GRealArray *array = g_slice_new (GRealArray);
88
89   array->data            = NULL;
90   array->len             = 0;
91   array->alloc           = 0;
92   array->zero_terminated = (zero_terminated ? 1 : 0);
93   array->clear           = (clear ? 1 : 0);
94   array->elt_size        = elt_size;
95   array->ref_count       = 1;
96
97   if (array->zero_terminated || reserved_size != 0)
98     {
99       g_array_maybe_expand (array, reserved_size);
100       g_array_zero_terminate(array);
101     }
102
103   return (GArray*) array;
104 }
105
106 /**
107  * g_array_ref:
108  * @array: A #GArray.
109  *
110  * Atomically increments the reference count of @array by one. This
111  * function is MT-safe and may be called from any thread.
112  *
113  * Returns: The passed in #GArray.
114  *
115  * Since: 2.22
116  **/
117 GArray *
118 g_array_ref (GArray *array)
119 {
120   GRealArray *rarray = (GRealArray*) array;
121   g_return_val_if_fail (g_atomic_int_get (&rarray->ref_count) > 0, array);
122   g_atomic_int_inc (&rarray->ref_count);
123   return array;
124 }
125
126 /**
127  * g_array_unref:
128  * @array: A #GArray.
129  *
130  * Atomically decrements the reference count of @array by one. If the
131  * reference count drops to 0, all memory allocated by the array is
132  * released. This function is MT-safe and may be called from any
133  * thread.
134  *
135  * Since: 2.22
136  **/
137 void
138 g_array_unref (GArray *array)
139 {
140   GRealArray *rarray = (GRealArray*) array;
141   g_return_if_fail (g_atomic_int_get (&rarray->ref_count) > 0);
142   if (g_atomic_int_dec_and_test (&rarray->ref_count))
143     g_array_free (array, TRUE);
144 }
145
146 /**
147  * g_array_get_element_size:
148  * @array: A #GArray.
149  *
150  * Gets the size of the elements in @array.
151  *
152  * Returns: Size of each element, in bytes.
153  *
154  * Since: 2.22
155  **/
156 guint
157 g_array_get_element_size (GArray *array)
158 {
159   GRealArray *rarray = (GRealArray*) array;
160   return rarray->elt_size;
161 }
162
163 gchar*
164 g_array_free (GArray   *farray,
165               gboolean  free_segment)
166 {
167   GRealArray *array = (GRealArray*) farray;
168   gchar* segment;
169   gboolean preserve_wrapper;
170
171   g_return_val_if_fail (array, NULL);
172
173   /* if others are holding a reference, preserve the wrapper but do free/return the data */
174   preserve_wrapper = FALSE;
175   if (g_atomic_int_get (&array->ref_count) > 1)
176     preserve_wrapper = TRUE;
177
178   if (free_segment)
179     {
180       g_free (array->data);
181       segment = NULL;
182     }
183   else
184     segment = array->data;
185
186   if (preserve_wrapper)
187     {
188       array->data            = NULL;
189       array->len             = 0;
190       array->alloc           = 0;
191     }
192   else
193     {
194       g_slice_free1 (sizeof (GRealArray), array);
195     }
196
197   return segment;
198 }
199
200 GArray*
201 g_array_append_vals (GArray       *farray,
202                      gconstpointer data,
203                      guint         len)
204 {
205   GRealArray *array = (GRealArray*) farray;
206
207   g_array_maybe_expand (array, len);
208
209   memcpy (g_array_elt_pos (array, array->len), data, 
210           g_array_elt_len (array, len));
211
212   array->len += len;
213
214   g_array_zero_terminate (array);
215
216   return farray;
217 }
218
219 GArray*
220 g_array_prepend_vals (GArray        *farray,
221                       gconstpointer  data,
222                       guint          len)
223 {
224   GRealArray *array = (GRealArray*) farray;
225
226   g_array_maybe_expand (array, len);
227
228   g_memmove (g_array_elt_pos (array, len), g_array_elt_pos (array, 0), 
229              g_array_elt_len (array, array->len));
230
231   memcpy (g_array_elt_pos (array, 0), data, g_array_elt_len (array, len));
232
233   array->len += len;
234
235   g_array_zero_terminate (array);
236
237   return farray;
238 }
239
240 GArray*
241 g_array_insert_vals (GArray        *farray,
242                      guint          index_,
243                      gconstpointer  data,
244                      guint          len)
245 {
246   GRealArray *array = (GRealArray*) farray;
247
248   g_array_maybe_expand (array, len);
249
250   g_memmove (g_array_elt_pos (array, len + index_), 
251              g_array_elt_pos (array, index_), 
252              g_array_elt_len (array, array->len - index_));
253
254   memcpy (g_array_elt_pos (array, index_), data, g_array_elt_len (array, len));
255
256   array->len += len;
257
258   g_array_zero_terminate (array);
259
260   return farray;
261 }
262
263 GArray*
264 g_array_set_size (GArray *farray,
265                   guint   length)
266 {
267   GRealArray *array = (GRealArray*) farray;
268   if (length > array->len)
269     {
270       g_array_maybe_expand (array, length - array->len);
271       
272       if (array->clear)
273         g_array_elt_zero (array, array->len, length - array->len);
274     }
275   else if (G_UNLIKELY (g_mem_gc_friendly) && length < array->len)
276     g_array_elt_zero (array, length, array->len - length);
277   
278   array->len = length;
279   
280   g_array_zero_terminate (array);
281   
282   return farray;
283 }
284
285 GArray*
286 g_array_remove_index (GArray *farray,
287                       guint   index_)
288 {
289   GRealArray* array = (GRealArray*) farray;
290
291   g_return_val_if_fail (array, NULL);
292
293   g_return_val_if_fail (index_ < array->len, NULL);
294
295   if (index_ != array->len - 1)
296     g_memmove (g_array_elt_pos (array, index_),
297                g_array_elt_pos (array, index_ + 1),
298                g_array_elt_len (array, array->len - index_ - 1));
299   
300   array->len -= 1;
301
302   if (G_UNLIKELY (g_mem_gc_friendly))
303     g_array_elt_zero (array, array->len, 1);
304   else
305     g_array_zero_terminate (array);
306
307   return farray;
308 }
309
310 GArray*
311 g_array_remove_index_fast (GArray *farray,
312                            guint   index_)
313 {
314   GRealArray* array = (GRealArray*) farray;
315
316   g_return_val_if_fail (array, NULL);
317
318   g_return_val_if_fail (index_ < array->len, NULL);
319
320   if (index_ != array->len - 1)
321     memcpy (g_array_elt_pos (array, index_), 
322             g_array_elt_pos (array, array->len - 1),
323             g_array_elt_len (array, 1));
324   
325   array->len -= 1;
326
327   if (G_UNLIKELY (g_mem_gc_friendly))
328     g_array_elt_zero (array, array->len, 1);
329   else
330     g_array_zero_terminate (array);
331
332   return farray;
333 }
334
335 GArray*
336 g_array_remove_range (GArray *farray,
337                       guint   index_,
338                       guint   length)
339 {
340   GRealArray *array = (GRealArray*) farray;
341
342   g_return_val_if_fail (array, NULL);
343   g_return_val_if_fail (index_ < array->len, NULL);
344   g_return_val_if_fail (index_ + length <= array->len, NULL);
345
346   if (index_ + length != array->len)
347     g_memmove (g_array_elt_pos (array, index_), 
348                g_array_elt_pos (array, index_ + length), 
349                (array->len - (index_ + length)) * array->elt_size);
350
351   array->len -= length;
352   if (G_UNLIKELY (g_mem_gc_friendly))
353     g_array_elt_zero (array, array->len, length);
354   else
355     g_array_zero_terminate (array);
356
357   return farray;
358 }
359
360 void
361 g_array_sort (GArray       *farray,
362               GCompareFunc  compare_func)
363 {
364   GRealArray *array = (GRealArray*) farray;
365
366   g_return_if_fail (array != NULL);
367
368   qsort (array->data,
369          array->len,
370          array->elt_size,
371          compare_func);
372 }
373
374 void
375 g_array_sort_with_data (GArray           *farray,
376                         GCompareDataFunc  compare_func,
377                         gpointer          user_data)
378 {
379   GRealArray *array = (GRealArray*) farray;
380
381   g_return_if_fail (array != NULL);
382
383   g_qsort_with_data (array->data,
384                      array->len,
385                      array->elt_size,
386                      compare_func,
387                      user_data);
388 }
389
390
391 static gint
392 g_nearest_pow (gint num)
393 {
394   gint n = 1;
395
396   while (n < num)
397     n <<= 1;
398
399   return n;
400 }
401
402 static void
403 g_array_maybe_expand (GRealArray *array,
404                       gint        len)
405 {
406   guint want_alloc = g_array_elt_len (array, array->len + len + 
407                                       array->zero_terminated);
408
409   if (want_alloc > array->alloc)
410     {
411       want_alloc = g_nearest_pow (want_alloc);
412       want_alloc = MAX (want_alloc, MIN_ARRAY_SIZE);
413
414       array->data = g_realloc (array->data, want_alloc);
415
416       if (G_UNLIKELY (g_mem_gc_friendly))
417         memset (array->data + array->alloc, 0, want_alloc - array->alloc);
418
419       array->alloc = want_alloc;
420     }
421 }
422
423 /* Pointer Array
424  */
425
426 typedef struct _GRealPtrArray  GRealPtrArray;
427
428 struct _GRealPtrArray
429 {
430   gpointer     *pdata;
431   guint         len;
432   guint         alloc;
433   volatile gint ref_count;
434   GDestroyNotify element_free_func;
435 };
436
437 static void g_ptr_array_maybe_expand (GRealPtrArray *array,
438                                       gint           len);
439
440 GPtrArray*
441 g_ptr_array_new (void)
442 {
443   return g_ptr_array_sized_new (0);
444 }
445
446 GPtrArray*  
447 g_ptr_array_sized_new (guint reserved_size)
448 {
449   GRealPtrArray *array = g_slice_new (GRealPtrArray);
450
451   array->pdata = NULL;
452   array->len = 0;
453   array->alloc = 0;
454   array->ref_count = 1;
455   array->element_free_func = NULL;
456
457   if (reserved_size != 0)
458     g_ptr_array_maybe_expand (array, reserved_size);
459
460   return (GPtrArray*) array;  
461 }
462
463 /**
464  * g_ptr_array_new_with_free_func:
465  * @element_free_func: A function to free elements with destroy @array or %NULL.
466  *
467  * Creates a new #GPtrArray with a reference count of 1 and use @element_free_func
468  * for freeing each element when the array is destroyed either via
469  * g_ptr_array_unref(), when g_ptr_array_free() is called with @free_segment
470  * set to %TRUE or when removing elements.
471  *
472  * Returns: A new #GPtrArray.
473  *
474  * Since: 2.22
475  **/
476 GPtrArray *
477 g_ptr_array_new_with_free_func (GDestroyNotify element_free_func)
478 {
479   GPtrArray *array;
480
481   array = g_ptr_array_new ();
482   g_ptr_array_set_free_func (array, element_free_func);
483   return array;
484 }
485
486 /**
487  * g_ptr_array_set_free_func:
488  * @array: A #GPtrArray.
489  * @element_free_func: A function to free elements with destroy @array or %NULL.
490  *
491  * Sets a function for freeing each element when @array is destroyed
492  * either via g_ptr_array_unref(), when g_ptr_array_free() is called
493  * with @free_segment set to %TRUE or when removing elements.
494  *
495  * Since: 2.22
496  **/
497 void
498 g_ptr_array_set_free_func (GPtrArray        *array,
499                            GDestroyNotify    element_free_func)
500 {
501   GRealPtrArray* rarray = (GRealPtrArray*) array;
502   rarray->element_free_func = element_free_func;
503 }
504
505 /**
506  * g_ptr_array_ref:
507  * @array: A #GArray.
508  *
509  * Atomically increments the reference count of @array by one. This
510  * function is MT-safe and may be called from any thread.
511  *
512  * Returns: The passed in #GPtrArray.
513  *
514  * Since: 2.22
515  **/
516 GPtrArray *
517 g_ptr_array_ref (GPtrArray *array)
518 {
519   GRealPtrArray *rarray = (GRealPtrArray*) array;
520   g_return_val_if_fail (g_atomic_int_get (&rarray->ref_count) > 0, array);
521   g_atomic_int_inc (&rarray->ref_count);
522   return array;
523 }
524
525 /**
526  * g_ptr_array_unref:
527  * @array: A #GPtrArray.
528  *
529  * Atomically decrements the reference count of @array by one. If the
530  * reference count drops to 0, the effect is the same as calling
531  * g_ptr_array_free() with @free_segment set to %TRUE. This function
532  * is MT-safe and may be called from any thread.
533  *
534  * Since: 2.22
535  **/
536 void
537 g_ptr_array_unref (GPtrArray *array)
538 {
539   GRealPtrArray *rarray = (GRealPtrArray*) array;
540   g_return_if_fail (g_atomic_int_get (&rarray->ref_count) > 0);
541   if (g_atomic_int_dec_and_test (&rarray->ref_count))
542     g_ptr_array_free (array, TRUE);
543 }
544
545 gpointer*
546 g_ptr_array_free (GPtrArray *farray,
547                   gboolean   free_segment)
548 {
549   GRealPtrArray *array = (GRealPtrArray*) farray;
550   gpointer* segment;
551   gboolean preserve_wrapper;
552
553   g_return_val_if_fail (array, NULL);
554
555   /* if others are holding a reference, preserve the wrapper but do free/return the data */
556   preserve_wrapper = FALSE;
557   if (g_atomic_int_get (&array->ref_count) > 1)
558     preserve_wrapper = TRUE;
559
560   if (free_segment)
561     {
562       if (array->element_free_func != NULL)
563         g_ptr_array_foreach (farray, (GFunc) array->element_free_func, NULL);
564       g_free (array->pdata);
565       segment = NULL;
566     }
567   else
568     segment = array->pdata;
569
570   if (preserve_wrapper)
571     {
572       array->pdata = NULL;
573       array->len = 0;
574       array->alloc = 0;
575     }
576   else
577     {
578       g_slice_free1 (sizeof (GRealPtrArray), array);
579     }
580
581   return segment;
582 }
583
584 static void
585 g_ptr_array_maybe_expand (GRealPtrArray *array,
586                           gint           len)
587 {
588   if ((array->len + len) > array->alloc)
589     {
590       guint old_alloc = array->alloc;
591       array->alloc = g_nearest_pow (array->len + len);
592       array->alloc = MAX (array->alloc, MIN_ARRAY_SIZE);
593       array->pdata = g_realloc (array->pdata, sizeof (gpointer) * array->alloc);
594       if (G_UNLIKELY (g_mem_gc_friendly))
595         for ( ; old_alloc < array->alloc; old_alloc++)
596           array->pdata [old_alloc] = NULL;
597     }
598 }
599
600 void
601 g_ptr_array_set_size  (GPtrArray *farray,
602                        gint       length)
603 {
604   GRealPtrArray* array = (GRealPtrArray*) farray;
605
606   g_return_if_fail (array);
607
608   if (length > array->len)
609     {
610       int i;
611       g_ptr_array_maybe_expand (array, (length - array->len));
612       /* This is not 
613        *     memset (array->pdata + array->len, 0,
614        *            sizeof (gpointer) * (length - array->len));
615        * to make it really portable. Remember (void*)NULL needn't be
616        * bitwise zero. It of course is silly not to use memset (..,0,..).
617        */
618       for (i = array->len; i < length; i++)
619         array->pdata[i] = NULL;
620     }
621   if (G_UNLIKELY (g_mem_gc_friendly) && length < array->len)
622     {
623       int i;
624       for (i = length; i < array->len; i++)
625         array->pdata[i] = NULL;
626     }
627
628   array->len = length;
629 }
630
631 gpointer
632 g_ptr_array_remove_index (GPtrArray *farray,
633                           guint      index_)
634 {
635   GRealPtrArray* array = (GRealPtrArray*) farray;
636   gpointer result;
637
638   g_return_val_if_fail (array, NULL);
639
640   g_return_val_if_fail (index_ < array->len, NULL);
641
642   result = array->pdata[index_];
643   
644   if (array->element_free_func != NULL)
645     array->element_free_func (array->pdata[index_]);
646
647   if (index_ != array->len - 1)
648     g_memmove (array->pdata + index_, array->pdata + index_ + 1, 
649                sizeof (gpointer) * (array->len - index_ - 1));
650   
651   array->len -= 1;
652
653   if (G_UNLIKELY (g_mem_gc_friendly))
654     array->pdata[array->len] = NULL;
655
656   return result;
657 }
658
659 gpointer
660 g_ptr_array_remove_index_fast (GPtrArray *farray,
661                                guint      index_)
662 {
663   GRealPtrArray* array = (GRealPtrArray*) farray;
664   gpointer result;
665
666   g_return_val_if_fail (array, NULL);
667
668   g_return_val_if_fail (index_ < array->len, NULL);
669
670   result = array->pdata[index_];
671   
672   if (index_ != array->len - 1)
673     {
674       if (array->element_free_func != NULL)
675         array->element_free_func (array->pdata[index_]);
676       array->pdata[index_] = array->pdata[array->len - 1];
677     }
678
679   array->len -= 1;
680
681   if (G_UNLIKELY (g_mem_gc_friendly))
682     array->pdata[array->len] = NULL;
683
684   return result;
685 }
686
687 void
688 g_ptr_array_remove_range (GPtrArray *farray,
689                           guint      index_,
690                           guint      length)
691 {
692   GRealPtrArray* array = (GRealPtrArray*) farray;
693   guint n;
694
695   g_return_if_fail (array);
696   g_return_if_fail (index_ < array->len);
697   g_return_if_fail (index_ + length <= array->len);
698
699   if (array->element_free_func != NULL)
700     {
701       for (n = index_; n < index_ + length; n++)
702         array->element_free_func (array->pdata[n]);
703     }
704
705   if (index_ + length != array->len)
706     {
707       g_memmove (&array->pdata[index_],
708                  &array->pdata[index_ + length], 
709                  (array->len - (index_ + length)) * sizeof (gpointer));
710     }
711
712   array->len -= length;
713   if (G_UNLIKELY (g_mem_gc_friendly))
714     {
715       guint i;
716       for (i = 0; i < length; i++)
717         array->pdata[array->len + i] = NULL;
718     }
719 }
720
721 gboolean
722 g_ptr_array_remove (GPtrArray *farray,
723                     gpointer   data)
724 {
725   GRealPtrArray* array = (GRealPtrArray*) farray;
726   guint i;
727
728   g_return_val_if_fail (array, FALSE);
729
730   for (i = 0; i < array->len; i += 1)
731     {
732       if (array->pdata[i] == data)
733         {
734           g_ptr_array_remove_index (farray, i);
735           return TRUE;
736         }
737     }
738
739   return FALSE;
740 }
741
742 gboolean
743 g_ptr_array_remove_fast (GPtrArray *farray,
744                          gpointer   data)
745 {
746   GRealPtrArray* array = (GRealPtrArray*) farray;
747   guint i;
748
749   g_return_val_if_fail (array, FALSE);
750
751   for (i = 0; i < array->len; i += 1)
752     {
753       if (array->pdata[i] == data)
754         {
755           g_ptr_array_remove_index_fast (farray, i);
756           return TRUE;
757         }
758     }
759
760   return FALSE;
761 }
762
763 void
764 g_ptr_array_add (GPtrArray *farray,
765                  gpointer   data)
766 {
767   GRealPtrArray* array = (GRealPtrArray*) farray;
768
769   g_return_if_fail (array);
770
771   g_ptr_array_maybe_expand (array, 1);
772
773   array->pdata[array->len++] = data;
774 }
775
776 void
777 g_ptr_array_sort (GPtrArray    *array,
778                   GCompareFunc  compare_func)
779 {
780   g_return_if_fail (array != NULL);
781
782   qsort (array->pdata,
783          array->len,
784          sizeof (gpointer),
785          compare_func);
786 }
787
788 void
789 g_ptr_array_sort_with_data (GPtrArray        *array,
790                             GCompareDataFunc  compare_func,
791                             gpointer          user_data)
792 {
793   g_return_if_fail (array != NULL);
794
795   g_qsort_with_data (array->pdata,
796                      array->len,
797                      sizeof (gpointer),
798                      compare_func,
799                      user_data);
800 }
801
802 /**
803  * g_ptr_array_foreach:
804  * @array: a #GPtrArray
805  * @func: the function to call for each array element
806  * @user_data: user data to pass to the function
807  * 
808  * Calls a function for each element of a #GPtrArray.
809  *
810  * Since: 2.4
811  **/
812 void
813 g_ptr_array_foreach (GPtrArray *array,
814                      GFunc      func,
815                      gpointer   user_data)
816 {
817   guint i;
818
819   g_return_if_fail (array);
820
821   for (i = 0; i < array->len; i++)
822     (*func) (array->pdata[i], user_data);
823 }
824
825 /* Byte arrays 
826  */
827
828 GByteArray* g_byte_array_new (void)
829 {
830   return (GByteArray*) g_array_sized_new (FALSE, FALSE, 1, 0);
831 }
832
833 GByteArray* g_byte_array_sized_new (guint reserved_size)
834 {
835   return (GByteArray*) g_array_sized_new (FALSE, FALSE, 1, reserved_size);
836 }
837
838 guint8*     g_byte_array_free     (GByteArray *array,
839                                    gboolean    free_segment)
840 {
841   return (guint8*) g_array_free ((GArray*) array, free_segment);
842 }
843
844 /**
845  * g_byte_array_ref:
846  * @array: A #GByteArray.
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 #GByteArray.
852  *
853  * Since: 2.22
854  **/
855 GByteArray *
856 g_byte_array_ref (GByteArray *array)
857 {
858   return (GByteArray *) g_array_ref ((GArray *) array);
859 }
860
861 /**
862  * g_byte_array_unref:
863  * @array: A #GByteArray.
864  *
865  * Atomically decrements the reference count of @array by one. If the
866  * reference count drops to 0, all memory allocated by the array is
867  * released. This function is MT-safe and may be called from any
868  * thread.
869  *
870  * Since: 2.22
871  **/
872 void
873 g_byte_array_unref (GByteArray *array)
874 {
875   g_array_unref ((GArray *) array);
876 }
877
878 GByteArray* g_byte_array_append   (GByteArray   *array,
879                                    const guint8 *data,
880                                    guint         len)
881 {
882   g_array_append_vals ((GArray*) array, (guint8*)data, len);
883
884   return array;
885 }
886
887 GByteArray* g_byte_array_prepend  (GByteArray   *array,
888                                    const guint8 *data,
889                                    guint         len)
890 {
891   g_array_prepend_vals ((GArray*) array, (guint8*)data, len);
892
893   return array;
894 }
895
896 GByteArray* g_byte_array_set_size (GByteArray *array,
897                                    guint       length)
898 {
899   g_array_set_size ((GArray*) array, length);
900
901   return array;
902 }
903
904 GByteArray* g_byte_array_remove_index (GByteArray *array,
905                                        guint       index_)
906 {
907   g_array_remove_index ((GArray*) array, index_);
908
909   return array;
910 }
911
912 GByteArray* g_byte_array_remove_index_fast (GByteArray *array,
913                                             guint       index_)
914 {
915   g_array_remove_index_fast ((GArray*) array, index_);
916
917   return array;
918 }
919
920 GByteArray*
921 g_byte_array_remove_range (GByteArray *array,
922                            guint       index_,
923                            guint       length)
924 {
925   g_return_val_if_fail (array, NULL);
926   g_return_val_if_fail (index_ < array->len, NULL);
927   g_return_val_if_fail (index_ + length <= array->len, NULL);
928
929   return (GByteArray *)g_array_remove_range ((GArray*) array, index_, length);
930 }
931
932 void
933 g_byte_array_sort (GByteArray   *array,
934                    GCompareFunc  compare_func)
935 {
936   g_array_sort ((GArray *) array, compare_func);
937 }
938
939 void
940 g_byte_array_sort_with_data (GByteArray       *array,
941                              GCompareDataFunc  compare_func,
942                              gpointer          user_data)
943 {
944   g_array_sort_with_data ((GArray *) array, compare_func, user_data);
945 }
946
947 #define __G_ARRAY_C__
948 #include "galiasdef.c"