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, see <http://www.gnu.org/licenses/>.
  16  */
  17 
  18 /*
  19  * Modified by the GLib Team and others 1997-2000.  See the AUTHORS
  20  * file for a list of people on the GLib Team.  See the ChangeLog
  21  * files for a list of changes.  These files are distributed with
  22  * GLib at ftp://ftp.gtk.org/pub/gtk/.
  23  */
  24 
  25 /*
  26  * MT safe
  27  */
  28 
  29 #include "config.h"
  30 
  31 #include <string.h>
  32 #include <stdlib.h>
  33 
  34 #include "garray.h"
  35 
  36 #include "gbytes.h"
  37 #include "gslice.h"
  38 #include "gmem.h"
  39 #include "gtestutils.h"
  40 #include "gthread.h"
  41 #include "gmessages.h"
  42 #include "gqsort.h"
  43 
  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  * Here is an example that stores integers in a #GArray:
  71  * |[<!-- language="C" -->
  72  *   GArray *garray;
  73  *   gint i;
  74  *   // We create a new array to store gint values.
  75  *   // We don't want it zero-terminated or cleared to 0's.
  76  *   garray = g_array_new (FALSE, FALSE, sizeof (gint));
  77  *   for (i = 0; i < 10000; i++)
  78  *     g_array_append_val (garray, i);
  79  *   for (i = 0; i < 10000; i++)
  80  *     if (g_array_index (garray, gint, i) != i)
  81  *       g_print ("ERROR: got %d instead of %d\n",
  82  *                g_array_index (garray, gint, i), i);
  83  *   g_array_free (garray, TRUE);
  84  * ]|
  85  */
  86 
  87 #define MIN_ARRAY_SIZE  16
  88 
  89 typedef struct _GRealArray  GRealArray;
  90 
  91 /**
  92  * GArray:
  93  * @data: a pointer to the element data. The data may be moved as
  94  *     elements are added to the #GArray.
  95  * @len: the number of elements in the #GArray not including the
  96  *     possible terminating zero element.
  97  *
  98  * Contains the public fields of a GArray.
  99  */
 100 struct _GRealArray
 101 {
 102   guint8 *data;
 103   guint   len;
 104   guint   alloc;
 105   guint   elt_size;
 106   guint   zero_terminated : 1;
 107   guint   clear : 1;
 108   gint    ref_count;
 109   GDestroyNotify clear_func;
 110 };
 111 
 112 /**
 113  * g_array_index:
 114  * @a: a #GArray
 115  * @t: the type of the elements
 116  * @i: the index of the element to return
 117  *
 118  * Returns the element of a #GArray at the given index. The return
 119  * value is cast to the given type.
 120  *
 121  * This example gets a pointer to an element in a #GArray:
 122  * |[<!-- language="C" -->
 123  *   EDayViewEvent *event;
 124  *   // This gets a pointer to the 4th element in the array of
 125  *   // EDayViewEvent structs.
 126  *   event = &g_array_index (events, EDayViewEvent, 3);
 127  * ]|
 128  *
 129  * Returns: the element of the #GArray at the index given by @i
 130  */
 131 
 132 #define g_array_elt_len(array,i) ((array)->elt_size * (i))
 133 #define g_array_elt_pos(array,i) ((array)->data + g_array_elt_len((array),(i)))
 134 #define g_array_elt_zero(array, pos, len)                               \
 135   (memset (g_array_elt_pos ((array), pos), 0,  g_array_elt_len ((array), len)))
 136 #define g_array_zero_terminate(array) G_STMT_START{                     \
 137   if ((array)->zero_terminated)                                         \
 138     g_array_elt_zero ((array), (array)->len, 1);                        \
 139 }G_STMT_END
 140 
 141 static guint g_nearest_pow        (gint        num) G_GNUC_CONST;
 142 static void  g_array_maybe_expand (GRealArray *array,
 143                                    gint        len);
 144 
 145 /**
 146  * g_array_new:
 147  * @zero_terminated: %TRUE if the array should have an extra element at
 148  *     the end which is set to 0
 149  * @clear_: %TRUE if #GArray elements should be automatically cleared
 150  *     to 0 when they are allocated
 151  * @element_size: the size of each element in bytes
 152  *
 153  * Creates a new #GArray with a reference count of 1.
 154  *
 155  * Returns: the new #GArray
 156  */
 157 GArray*
 158 g_array_new (gboolean zero_terminated,
 159              gboolean clear,
 160              guint    elt_size)
 161 {
 162   g_return_val_if_fail (elt_size > 0, NULL);
 163 
 164   return 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  *
 176  * Creates a new #GArray with @reserved_size elements preallocated and
 177  * a reference count of 1. This avoids frequent reallocation, if you
 178  * are going to add many elements to the array. Note however that the
 179  * size of the array is still 0.
 180  *
 181  * Returns: the new #GArray
 182  */
 183 GArray*
 184 g_array_sized_new (gboolean zero_terminated,
 185                    gboolean clear,
 186                    guint    elt_size,
 187                    guint    reserved_size)
 188 {
 189   GRealArray *array;
 190 
 191   g_return_val_if_fail (elt_size > 0, NULL);
 192 
 193   array = g_slice_new (GRealArray);
 194 #ifdef GSTREAMER_LITE
 195   if (array == NULL) {
 196     return NULL;
 197   }
 198 #endif // GSTREAMER_LITE
 199 
 200   array->data            = NULL;
 201   array->len             = 0;
 202   array->alloc           = 0;
 203   array->zero_terminated = (zero_terminated ? 1 : 0);
 204   array->clear           = (clear ? 1 : 0);
 205   array->elt_size        = elt_size;
 206   array->ref_count       = 1;
 207   array->clear_func      = NULL;
 208 
 209   if (array->zero_terminated || reserved_size != 0)
 210     {
 211       g_array_maybe_expand (array, reserved_size);
 212       g_array_zero_terminate(array);
 213     }
 214 
 215   return (GArray*) array;
 216 }
 217 
 218 /**
 219  * g_array_set_clear_func:
 220  * @array: A #GArray
 221  * @clear_func: a function to clear an element of @array
 222  *
 223  * Sets a function to clear an element of @array.
 224  *
 225  * The @clear_func will be called when an element in the array
 226  * data segment is removed and when the array is freed and data
 227  * segment is deallocated as well.
 228  *
 229  * Note that in contrast with other uses of #GDestroyNotify
 230  * functions, @clear_func is expected to clear the contents of
 231  * the array element it is given, but not free the element itself.
 232  *
 233  * Since: 2.32
 234  */
 235 void
 236 g_array_set_clear_func (GArray         *array,
 237                         GDestroyNotify  clear_func)
 238 {
 239   GRealArray *rarray = (GRealArray *) array;
 240 
 241   g_return_if_fail (array != NULL);
 242 
 243   rarray->clear_func = clear_func;
 244 }
 245 
 246 /**
 247  * g_array_ref:
 248  * @array: A #GArray
 249  *
 250  * Atomically increments the reference count of @array by one.
 251  * This function is MT-safe and may be called from any thread.
 252  *
 253  * Returns: The passed in #GArray
 254  *
 255  * Since: 2.22
 256  */
 257 GArray *
 258 g_array_ref (GArray *array)
 259 {
 260   GRealArray *rarray = (GRealArray*) array;
 261   g_return_val_if_fail (array, NULL);
 262 
 263   g_atomic_int_inc (&rarray->ref_count);
 264 
 265   return array;
 266 }
 267 
 268 typedef enum
 269 {
 270   FREE_SEGMENT = 1 << 0,
 271   PRESERVE_WRAPPER = 1 << 1
 272 } ArrayFreeFlags;
 273 
 274 static gchar *array_free (GRealArray *, ArrayFreeFlags);
 275 
 276 /**
 277  * g_array_unref:
 278  * @array: A #GArray
 279  *
 280  * Atomically decrements the reference count of @array by one. If the
 281  * reference count drops to 0, all memory allocated by the array is
 282  * released. This function is MT-safe and may be called from any
 283  * thread.
 284  *
 285  * Since: 2.22
 286  */
 287 void
 288 g_array_unref (GArray *array)
 289 {
 290   GRealArray *rarray = (GRealArray*) array;
 291   g_return_if_fail (array);
 292 
 293   if (g_atomic_int_dec_and_test (&rarray->ref_count))
 294     array_free (rarray, FREE_SEGMENT);
 295 }
 296 
 297 /**
 298  * g_array_get_element_size:
 299  * @array: A #GArray
 300  *
 301  * Gets the size of the elements in @array.
 302  *
 303  * Returns: Size of each element, in bytes
 304  *
 305  * Since: 2.22
 306  */
 307 guint
 308 g_array_get_element_size (GArray *array)
 309 {
 310   GRealArray *rarray = (GRealArray*) array;
 311 
 312   g_return_val_if_fail (array, 0);
 313 
 314   return rarray->elt_size;
 315 }
 316 
 317 /**
 318  * g_array_free:
 319  * @array: a #GArray
 320  * @free_segment: if %TRUE the actual element data is freed as well
 321  *
 322  * Frees the memory allocated for the #GArray. If @free_segment is
 323  * %TRUE it frees the memory block holding the elements as well and
 324  * also each element if @array has a @element_free_func set. Pass
 325  * %FALSE if you want to free the #GArray wrapper but preserve the
 326  * underlying array for use elsewhere. If the reference count of @array
 327  * is greater than one, the #GArray wrapper is preserved but the size
 328  * of @array will be set to zero.
 329  *
 330  * If array elements contain dynamically-allocated memory, they should
 331  * be freed separately.
 332  *
 333  * Returns: the element data if @free_segment is %FALSE, otherwise
 334  *     %NULL. The element data should be freed using g_free().
 335  */
 336 gchar*
 337 g_array_free (GArray   *farray,
 338               gboolean  free_segment)
 339 {
 340   GRealArray *array = (GRealArray*) farray;
 341   ArrayFreeFlags flags;
 342 
 343   g_return_val_if_fail (array, NULL);
 344 
 345   flags = (free_segment ? FREE_SEGMENT : 0);
 346 
 347   /* if others are holding a reference, preserve the wrapper but do free/return the data */
 348   if (!g_atomic_int_dec_and_test (&array->ref_count))
 349     flags |= PRESERVE_WRAPPER;
 350 
 351   return array_free (array, flags);
 352 }
 353 
 354 static gchar *
 355 array_free (GRealArray     *array,
 356             ArrayFreeFlags  flags)
 357 {
 358   gchar *segment;
 359 
 360   if (flags & FREE_SEGMENT)
 361     {
 362       if (array->clear_func != NULL)
 363         {
 364           guint i;
 365 
 366           for (i = 0; i < array->len; i++)
 367             array->clear_func (g_array_elt_pos (array, i));
 368         }
 369 
 370       g_free (array->data);
 371       segment = NULL;
 372     }
 373   else
 374     segment = (gchar*) array->data;
 375 
 376   if (flags & PRESERVE_WRAPPER)
 377     {
 378       array->data            = NULL;
 379       array->len             = 0;
 380       array->alloc           = 0;
 381     }
 382   else
 383     {
 384       g_slice_free1 (sizeof (GRealArray), array);
 385     }
 386 
 387   return segment;
 388 }
 389 
 390 /**
 391  * g_array_append_vals:
 392  * @array: a #GArray
 393  * @data: a pointer to the elements to append to the end of the array
 394  * @len: the number of elements to append
 395  *
 396  * Adds @len elements onto the end of the array.
 397  *
 398  * Returns: the #GArray
 399  */
 400 /**
 401  * g_array_append_val:
 402  * @a: a #GArray
 403  * @v: the value to append to the #GArray
 404  *
 405  * Adds the value on to the end of the array. The array will grow in
 406  * size automatically if necessary.
 407  *
 408  * g_array_append_val() is a macro which uses a reference to the value
 409  * parameter @v. This means that you cannot use it with literal values
 410  * such as "27". You must use variables.
 411  *
 412  * Returns: the #GArray
 413  */
 414 GArray*
 415 g_array_append_vals (GArray       *farray,
 416                      gconstpointer data,
 417                      guint         len)
 418 {
 419   GRealArray *array = (GRealArray*) farray;
 420 
 421   g_return_val_if_fail (array, NULL);
 422 
 423   g_array_maybe_expand (array, len);
 424 
 425   memcpy (g_array_elt_pos (array, array->len), data,
 426           g_array_elt_len (array, len));
 427 
 428   array->len += len;
 429 
 430   g_array_zero_terminate (array);
 431 
 432   return farray;
 433 }
 434 
 435 /**
 436  * g_array_prepend_vals:
 437  * @array: a #GArray
 438  * @data: a pointer to the elements to prepend to the start of the array
 439  * @len: the number of elements to prepend
 440  *
 441  * Adds @len elements onto the start of the array.
 442  *
 443  * This operation is slower than g_array_append_vals() since the
 444  * existing elements in the array have to be moved to make space for
 445  * the new elements.
 446  *
 447  * Returns: the #GArray
 448  */
 449 /**
 450  * g_array_prepend_val:
 451  * @a: a #GArray
 452  * @v: the value to prepend to the #GArray
 453  *
 454  * Adds the value on to the start of the array. The array will grow in
 455  * size automatically if necessary.
 456  *
 457  * This operation is slower than g_array_append_val() since the
 458  * existing elements in the array have to be moved to make space for
 459  * the new element.
 460  *
 461  * g_array_prepend_val() is a macro which uses a reference to the value
 462  * parameter @v. This means that you cannot use it with literal values
 463  * such as "27". You must use variables.
 464  *
 465  * Returns: the #GArray
 466  */
 467 GArray*
 468 g_array_prepend_vals (GArray        *farray,
 469                       gconstpointer  data,
 470                       guint          len)
 471 {
 472   GRealArray *array = (GRealArray*) farray;
 473 
 474   g_return_val_if_fail (array, NULL);
 475 
 476   g_array_maybe_expand (array, len);
 477 
 478   memmove (g_array_elt_pos (array, len), g_array_elt_pos (array, 0),
 479            g_array_elt_len (array, array->len));
 480 
 481   memcpy (g_array_elt_pos (array, 0), data, g_array_elt_len (array, len));
 482 
 483   array->len += len;
 484 
 485   g_array_zero_terminate (array);
 486 
 487   return farray;
 488 }
 489 
 490 /**
 491  * g_array_insert_vals:
 492  * @array: a #GArray
 493  * @index_: the index to place the elements at
 494  * @data: a pointer to the elements to insert
 495  * @len: the number of elements to insert
 496  *
 497  * Inserts @len elements into a #GArray at the given index.
 498  *
 499  * Returns: the #GArray
 500  */
 501 /**
 502  * g_array_insert_val:
 503  * @a: a #GArray
 504  * @i: the index to place the element at
 505  * @v: the value to insert into the array
 506  *
 507  * Inserts an element into an array at the given index.
 508  *
 509  * g_array_insert_val() is a macro which uses a reference to the value
 510  * parameter @v. This means that you cannot use it with literal values
 511  * such as "27". You must use variables.
 512  *
 513  * Returns: the #GArray
 514  */
 515 GArray*
 516 g_array_insert_vals (GArray        *farray,
 517                      guint          index_,
 518                      gconstpointer  data,
 519                      guint          len)
 520 {
 521   GRealArray *array = (GRealArray*) farray;
 522 
 523   g_return_val_if_fail (array, NULL);
 524 
 525   g_array_maybe_expand (array, len);
 526 
 527   memmove (g_array_elt_pos (array, len + index_),
 528            g_array_elt_pos (array, index_),
 529            g_array_elt_len (array, array->len - index_));
 530 
 531   memcpy (g_array_elt_pos (array, index_), data, g_array_elt_len (array, len));
 532 
 533   array->len += len;
 534 
 535   g_array_zero_terminate (array);
 536 
 537   return farray;
 538 }
 539 
 540 /**
 541  * g_array_set_size:
 542  * @array: a #GArray
 543  * @length: the new size of the #GArray
 544  *
 545  * Sets the size of the array, expanding it if necessary. If the array
 546  * was created with @clear_ set to %TRUE, the new elements are set to 0.
 547  *
 548  * Returns: the #GArray
 549  */
 550 GArray*
 551 g_array_set_size (GArray *farray,
 552                   guint   length)
 553 {
 554   GRealArray *array = (GRealArray*) farray;
 555 
 556   g_return_val_if_fail (array, NULL);
 557 
 558   if (length > array->len)
 559     {
 560       g_array_maybe_expand (array, length - array->len);
 561 
 562       if (array->clear)
 563         g_array_elt_zero (array, array->len, length - array->len);
 564     }
 565   else if (length < array->len)
 566     g_array_remove_range (farray, length, array->len - length);
 567 
 568   array->len = length;
 569 
 570   g_array_zero_terminate (array);
 571 
 572   return farray;
 573 }
 574 
 575 /**
 576  * g_array_remove_index:
 577  * @array: a #GArray
 578  * @index_: the index of the element to remove
 579  *
 580  * Removes the element at the given index from a #GArray. The following
 581  * elements are moved down one place.
 582  *
 583  * Returns: the #GArray
 584  */
 585 GArray*
 586 g_array_remove_index (GArray *farray,
 587                       guint   index_)
 588 {
 589   GRealArray* array = (GRealArray*) farray;
 590 
 591   g_return_val_if_fail (array, NULL);
 592 
 593   g_return_val_if_fail (index_ < array->len, NULL);
 594 
 595   if (array->clear_func != NULL)
 596     array->clear_func (g_array_elt_pos (array, index_));
 597 
 598   if (index_ != array->len - 1)
 599     memmove (g_array_elt_pos (array, index_),
 600              g_array_elt_pos (array, index_ + 1),
 601              g_array_elt_len (array, array->len - index_ - 1));
 602 
 603   array->len -= 1;
 604 
 605   if (G_UNLIKELY (g_mem_gc_friendly))
 606     g_array_elt_zero (array, array->len, 1);
 607   else
 608     g_array_zero_terminate (array);
 609 
 610   return farray;
 611 }
 612 
 613 /**
 614  * g_array_remove_index_fast:
 615  * @array: a @GArray
 616  * @index_: the index of the element to remove
 617  *
 618  * Removes the element at the given index from a #GArray. The last
 619  * element in the array is used to fill in the space, so this function
 620  * does not preserve the order of the #GArray. But it is faster than
 621  * g_array_remove_index().
 622  *
 623  * Returns: the #GArray
 624  */
 625 GArray*
 626 g_array_remove_index_fast (GArray *farray,
 627                            guint   index_)
 628 {
 629   GRealArray* array = (GRealArray*) farray;
 630 
 631   g_return_val_if_fail (array, NULL);
 632 
 633   g_return_val_if_fail (index_ < array->len, NULL);
 634 
 635   if (array->clear_func != NULL)
 636     array->clear_func (g_array_elt_pos (array, index_));
 637 
 638   if (index_ != array->len - 1)
 639     memcpy (g_array_elt_pos (array, index_),
 640             g_array_elt_pos (array, array->len - 1),
 641             g_array_elt_len (array, 1));
 642 
 643   array->len -= 1;
 644 
 645   if (G_UNLIKELY (g_mem_gc_friendly))
 646     g_array_elt_zero (array, array->len, 1);
 647   else
 648     g_array_zero_terminate (array);
 649 
 650   return farray;
 651 }
 652 
 653 /**
 654  * g_array_remove_range:
 655  * @array: a @GArray
 656  * @index_: the index of the first element to remove
 657  * @length: the number of elements to remove
 658  *
 659  * Removes the given number of elements starting at the given index
 660  * from a #GArray.  The following elements are moved to close the gap.
 661  *
 662  * Returns: the #GArray
 663  *
 664  * Since: 2.4
 665  */
 666 GArray*
 667 g_array_remove_range (GArray *farray,
 668                       guint   index_,
 669                       guint   length)
 670 {
 671   GRealArray *array = (GRealArray*) farray;
 672 
 673   g_return_val_if_fail (array, NULL);
 674   g_return_val_if_fail (index_ < array->len, NULL);
 675   g_return_val_if_fail (index_ + length <= array->len, NULL);
 676 
 677   if (array->clear_func != NULL)
 678     {
 679       guint i;
 680 
 681       for (i = 0; i < length; i++)
 682         array->clear_func (g_array_elt_pos (array, index_ + i));
 683     }
 684 
 685   if (index_ + length != array->len)
 686     memmove (g_array_elt_pos (array, index_),
 687              g_array_elt_pos (array, index_ + length),
 688              (array->len - (index_ + length)) * array->elt_size);
 689 
 690   array->len -= length;
 691   if (G_UNLIKELY (g_mem_gc_friendly))
 692     g_array_elt_zero (array, array->len, length);
 693   else
 694     g_array_zero_terminate (array);
 695 
 696   return farray;
 697 }
 698 
 699 /**
 700  * g_array_sort:
 701  * @array: a #GArray
 702  * @compare_func: comparison function
 703  *
 704  * Sorts a #GArray using @compare_func which should be a qsort()-style
 705  * comparison function (returns less than zero for first arg is less
 706  * than second arg, zero for equal, greater zero if first arg is
 707  * greater than second arg).
 708  *
 709  * This is guaranteed to be a stable sort since version 2.32.
 710  */
 711 void
 712 g_array_sort (GArray       *farray,
 713               GCompareFunc  compare_func)
 714 {
 715   GRealArray *array = (GRealArray*) farray;
 716 
 717   g_return_if_fail (array != NULL);
 718 
 719   /* Don't use qsort as we want a guaranteed stable sort */
 720   g_qsort_with_data (array->data,
 721                      array->len,
 722                      array->elt_size,
 723                      (GCompareDataFunc)compare_func,
 724                      NULL);
 725 }
 726 
 727 /**
 728  * g_array_sort_with_data:
 729  * @array: a #GArray
 730  * @compare_func: comparison function
 731  * @user_data: data to pass to @compare_func
 732  *
 733  * Like g_array_sort(), but the comparison function receives an extra
 734  * user data argument.
 735  *
 736  * This is guaranteed to be a stable sort since version 2.32.
 737  *
 738  * There used to be a comment here about making the sort stable by
 739  * using the addresses of the elements in the comparison function.
 740  * This did not actually work, so any such code should be removed.
 741  */
 742 void
 743 g_array_sort_with_data (GArray           *farray,
 744                         GCompareDataFunc  compare_func,
 745                         gpointer          user_data)
 746 {
 747   GRealArray *array = (GRealArray*) farray;
 748 
 749   g_return_if_fail (array != NULL);
 750 
 751   g_qsort_with_data (array->data,
 752                      array->len,
 753                      array->elt_size,
 754                      compare_func,
 755                      user_data);
 756 }
 757 
 758 /* Returns the smallest power of 2 greater than n, or n if
 759  * such power does not fit in a guint
 760  */
 761 static guint
 762 g_nearest_pow (gint num)
 763 {
 764   guint n = 1;
 765 
 766   while (n < num && n > 0)
 767     n <<= 1;
 768 
 769   return n ? n : num;
 770 }
 771 
 772 static void
 773 g_array_maybe_expand (GRealArray *array,
 774                       gint        len)
 775 {
 776   guint want_alloc = g_array_elt_len (array, array->len + len +
 777                                       array->zero_terminated);
 778 
 779   if (want_alloc > array->alloc)
 780     {
 781       want_alloc = g_nearest_pow (want_alloc);
 782       want_alloc = MAX (want_alloc, MIN_ARRAY_SIZE);
 783 
 784       array->data = g_realloc (array->data, want_alloc);
 785 
 786       if (G_UNLIKELY (g_mem_gc_friendly))
 787         memset (array->data + array->alloc, 0, want_alloc - array->alloc);
 788 
 789       array->alloc = want_alloc;
 790     }
 791 }
 792 
 793 /**
 794  * SECTION:arrays_pointer
 795  * @title: Pointer Arrays
 796  * @short_description: arrays of pointers to any type of data, which
 797  *     grow automatically as new elements are added
 798  *
 799  * Pointer Arrays are similar to Arrays but are used only for storing
 800  * pointers.
 801  *
 802  * If you remove elements from the array, elements at the end of the
 803  * array are moved into the space previously occupied by the removed
 804  * element. This means that you should not rely on the index of particular
 805  * elements remaining the same. You should also be careful when deleting
 806  * elements while iterating over the array.
 807  *
 808  * To create a pointer array, use g_ptr_array_new().
 809  *
 810  * To add elements to a pointer array, use g_ptr_array_add().
 811  *
 812  * To remove elements from a pointer array, use g_ptr_array_remove(),
 813  * g_ptr_array_remove_index() or g_ptr_array_remove_index_fast().
 814  *
 815  * To access an element of a pointer array, use g_ptr_array_index().
 816  *
 817  * To set the size of a pointer array, use g_ptr_array_set_size().
 818  *
 819  * To free a pointer array, use g_ptr_array_free().
 820  *
 821  * An example using a #GPtrArray:
 822  * |[<!-- language="C" -->
 823  *   GPtrArray *array;
 824  *   gchar *string1 = "one";
 825  *   gchar *string2 = "two";
 826  *   gchar *string3 = "three";
 827  *
 828  *   array = g_ptr_array_new ();
 829  *   g_ptr_array_add (array, (gpointer) string1);
 830  *   g_ptr_array_add (array, (gpointer) string2);
 831  *   g_ptr_array_add (array, (gpointer) string3);
 832  *
 833  *   if (g_ptr_array_index (array, 0) != (gpointer) string1)
 834  *     g_print ("ERROR: got %p instead of %p\n",
 835  *              g_ptr_array_index (array, 0), string1);
 836  *
 837  *   g_ptr_array_free (array, TRUE);
 838  * ]|
 839  */
 840 
 841 typedef struct _GRealPtrArray  GRealPtrArray;
 842 
 843 /**
 844  * GPtrArray:
 845  * @pdata: points to the array of pointers, which may be moved when the
 846  *     array grows
 847  * @len: number of pointers in the array
 848  *
 849  * Contains the public fields of a pointer array.
 850  */
 851 struct _GRealPtrArray
 852 {
 853   gpointer       *pdata;
 854   guint           len;
 855   guint           alloc;
 856   gint            ref_count;
 857   GDestroyNotify  element_free_func;
 858 };
 859 
 860 /**
 861  * g_ptr_array_index:
 862  * @array: a #GPtrArray
 863  * @index_: the index of the pointer to return
 864  *
 865  * Returns the pointer at the given index of the pointer array.
 866  *
 867  * This does not perform bounds checking on the given @index_,
 868  * so you are responsible for checking it against the array length.
 869  *
 870  * Returns: the pointer at the given index
 871  */
 872 
 873 static void g_ptr_array_maybe_expand (GRealPtrArray *array,
 874                                       gint           len);
 875 
 876 /**
 877  * g_ptr_array_new:
 878  *
 879  * Creates a new #GPtrArray with a reference count of 1.
 880  *
 881  * Returns: the new #GPtrArray
 882  */
 883 GPtrArray*
 884 g_ptr_array_new (void)
 885 {
 886   return g_ptr_array_sized_new (0);
 887 }
 888 
 889 /**
 890  * g_ptr_array_sized_new:
 891  * @reserved_size: number of pointers preallocated
 892  *
 893  * Creates a new #GPtrArray with @reserved_size pointers preallocated
 894  * and a reference count of 1. This avoids frequent reallocation, if
 895  * you are going to add many pointers to the array. Note however that
 896  * the size of the array is still 0.
 897  *
 898  * Returns: the new #GPtrArray
 899  */
 900 GPtrArray*
 901 g_ptr_array_sized_new (guint reserved_size)
 902 {
 903   GRealPtrArray *array;
 904 
 905   array = g_slice_new (GRealPtrArray);
 906 #ifdef GSTREAMER_LITE
 907   if (array == NULL) {
 908     return NULL;
 909   }
 910 #endif // GSTREAMER_LITE
 911 
 912   array->pdata = NULL;
 913   array->len = 0;
 914   array->alloc = 0;
 915   array->ref_count = 1;
 916   array->element_free_func = NULL;
 917 
 918   if (reserved_size != 0)
 919     g_ptr_array_maybe_expand (array, reserved_size);
 920 
 921   return (GPtrArray*) array;
 922 }
 923 
 924 /**
 925  * g_ptr_array_new_with_free_func:
 926  * @element_free_func: (allow-none): A function to free elements with
 927  *     destroy @array or %NULL
 928  *
 929  * Creates a new #GPtrArray with a reference count of 1 and use
 930  * @element_free_func for freeing each element when the array is destroyed
 931  * either via g_ptr_array_unref(), when g_ptr_array_free() is called with
 932  * @free_segment set to %TRUE or when removing elements.
 933  *
 934  * Returns: A new #GPtrArray
 935  *
 936  * Since: 2.22
 937  */
 938 GPtrArray*
 939 g_ptr_array_new_with_free_func (GDestroyNotify element_free_func)
 940 {
 941   GPtrArray *array;
 942 
 943   array = g_ptr_array_new ();
 944   g_ptr_array_set_free_func (array, element_free_func);
 945 
 946   return array;
 947 }
 948 
 949 /**
 950  * g_ptr_array_new_full:
 951  * @reserved_size: number of pointers preallocated
 952  * @element_free_func: (allow-none): A function to free elements with
 953  *     destroy @array or %NULL
 954  *
 955  * Creates a new #GPtrArray with @reserved_size pointers preallocated
 956  * and a reference count of 1. This avoids frequent reallocation, if
 957  * you are going to add many pointers to the array. Note however that
 958  * the size of the array is still 0. It also set @element_free_func
 959  * for freeing each element when the array is destroyed either via
 960  * g_ptr_array_unref(), when g_ptr_array_free() is called with
 961  * @free_segment set to %TRUE or when removing elements.
 962  *
 963  * Returns: A new #GPtrArray
 964  *
 965  * Since: 2.30
 966  */
 967 GPtrArray*
 968 g_ptr_array_new_full (guint          reserved_size,
 969                       GDestroyNotify element_free_func)
 970 {
 971   GPtrArray *array;
 972 
 973   array = g_ptr_array_sized_new (reserved_size);
 974   g_ptr_array_set_free_func (array, element_free_func);
 975 
 976   return array;
 977 }
 978 
 979 /**
 980  * g_ptr_array_set_free_func:
 981  * @array: A #GPtrArray
 982  * @element_free_func: (allow-none): A function to free elements with
 983  *     destroy @array or %NULL
 984  *
 985  * Sets a function for freeing each element when @array is destroyed
 986  * either via g_ptr_array_unref(), when g_ptr_array_free() is called
 987  * with @free_segment set to %TRUE or when removing elements.
 988  *
 989  * Since: 2.22
 990  */
 991 void
 992 g_ptr_array_set_free_func (GPtrArray      *array,
 993                            GDestroyNotify  element_free_func)
 994 {
 995   GRealPtrArray *rarray = (GRealPtrArray *)array;
 996 
 997   g_return_if_fail (array);
 998 
 999   rarray->element_free_func = element_free_func;
1000 }
1001 
1002 /**
1003  * g_ptr_array_ref:
1004  * @array: a #GPtrArray
1005  *
1006  * Atomically increments the reference count of @array by one.
1007  * This function is thread-safe and may be called from any thread.
1008  *
1009  * Returns: The passed in #GPtrArray
1010  *
1011  * Since: 2.22
1012  */
1013 GPtrArray*
1014 g_ptr_array_ref (GPtrArray *array)
1015 {
1016   GRealPtrArray *rarray = (GRealPtrArray *)array;
1017 
1018   g_return_val_if_fail (array, NULL);
1019 
1020   g_atomic_int_inc (&rarray->ref_count);
1021 
1022   return array;
1023 }
1024 
1025 static gpointer *ptr_array_free (GPtrArray *, ArrayFreeFlags);
1026 
1027 /**
1028  * g_ptr_array_unref:
1029  * @array: A #GPtrArray
1030  *
1031  * Atomically decrements the reference count of @array by one. If the
1032  * reference count drops to 0, the effect is the same as calling
1033  * g_ptr_array_free() with @free_segment set to %TRUE. This function
1034  * is MT-safe and may be called from any thread.
1035  *
1036  * Since: 2.22
1037  */
1038 void
1039 g_ptr_array_unref (GPtrArray *array)
1040 {
1041   GRealPtrArray *rarray = (GRealPtrArray *)array;
1042 
1043   g_return_if_fail (array);
1044 
1045   if (g_atomic_int_dec_and_test (&rarray->ref_count))
1046     ptr_array_free (array, FREE_SEGMENT);
1047 }
1048 
1049 /**
1050  * g_ptr_array_free:
1051  * @array: a #GPtrArray
1052  * @free_seg: if %TRUE the actual pointer array is freed as well
1053  *
1054  * Frees the memory allocated for the #GPtrArray. If @free_seg is %TRUE
1055  * it frees the memory block holding the elements as well. Pass %FALSE
1056  * if you want to free the #GPtrArray wrapper but preserve the
1057  * underlying array for use elsewhere. If the reference count of @array
1058  * is greater than one, the #GPtrArray wrapper is preserved but the
1059  * size of @array will be set to zero.
1060  *
1061  * If array contents point to dynamically-allocated memory, they should
1062  * be freed separately if @free_seg is %TRUE and no #GDestroyNotify
1063  * function has been set for @array.
1064  *
1065  * Returns: the pointer array if @free_seg is %FALSE, otherwise %NULL.
1066  *     The pointer array should be freed using g_free().
1067  */
1068 gpointer*
1069 g_ptr_array_free (GPtrArray *array,
1070                   gboolean   free_segment)
1071 {
1072   GRealPtrArray *rarray = (GRealPtrArray *)array;
1073   ArrayFreeFlags flags;
1074 
1075   g_return_val_if_fail (rarray, NULL);
1076 
1077   flags = (free_segment ? FREE_SEGMENT : 0);
1078 
1079   /* if others are holding a reference, preserve the wrapper but
1080    * do free/return the data
1081    */
1082   if (!g_atomic_int_dec_and_test (&rarray->ref_count))
1083     flags |= PRESERVE_WRAPPER;
1084 
1085   return ptr_array_free (array, flags);
1086 }
1087 
1088 static gpointer *
1089 ptr_array_free (GPtrArray      *array,
1090                 ArrayFreeFlags  flags)
1091 {
1092   GRealPtrArray *rarray = (GRealPtrArray *)array;
1093   gpointer *segment;
1094 
1095   if (flags & FREE_SEGMENT)
1096     {
1097       if (rarray->element_free_func != NULL)
1098         g_ptr_array_foreach (array, (GFunc) rarray->element_free_func, NULL);
1099       g_free (rarray->pdata);
1100       segment = NULL;
1101     }
1102   else
1103     segment = rarray->pdata;
1104 
1105   if (flags & PRESERVE_WRAPPER)
1106     {
1107       rarray->pdata = NULL;
1108       rarray->len = 0;
1109       rarray->alloc = 0;
1110     }
1111   else
1112     {
1113       g_slice_free1 (sizeof (GRealPtrArray), rarray);
1114     }
1115 
1116   return segment;
1117 }
1118 
1119 static void
1120 g_ptr_array_maybe_expand (GRealPtrArray *array,
1121                           gint           len)
1122 {
1123   if ((array->len + len) > array->alloc)
1124     {
1125       guint old_alloc = array->alloc;
1126       array->alloc = g_nearest_pow (array->len + len);
1127       array->alloc = MAX (array->alloc, MIN_ARRAY_SIZE);
1128       array->pdata = g_realloc (array->pdata, sizeof (gpointer) * array->alloc);
1129       if (G_UNLIKELY (g_mem_gc_friendly))
1130         for ( ; old_alloc < array->alloc; old_alloc++)
1131           array->pdata [old_alloc] = NULL;
1132     }
1133 }
1134 
1135 /**
1136  * g_ptr_array_set_size:
1137  * @array: a #GPtrArray
1138  * @length: the new length of the pointer array
1139  *
1140  * Sets the size of the array. When making the array larger,
1141  * newly-added elements will be set to %NULL. When making it smaller,
1142  * if @array has a non-%NULL #GDestroyNotify function then it will be
1143  * called for the removed elements.
1144  */
1145 void
1146 g_ptr_array_set_size  (GPtrArray *array,
1147                        gint       length)
1148 {
1149   GRealPtrArray *rarray = (GRealPtrArray *)array;
1150 
1151   g_return_if_fail (rarray);
1152 
1153   if (length > rarray->len)
1154     {
1155       int i;
1156       g_ptr_array_maybe_expand (rarray, (length - rarray->len));
1157       /* This is not
1158        *     memset (array->pdata + array->len, 0,
1159        *            sizeof (gpointer) * (length - array->len));
1160        * to make it really portable. Remember (void*)NULL needn't be
1161        * bitwise zero. It of course is silly not to use memset (..,0,..).
1162        */
1163       for (i = rarray->len; i < length; i++)
1164         rarray->pdata[i] = NULL;
1165     }
1166   else if (length < rarray->len)
1167     g_ptr_array_remove_range (array, length, rarray->len - length);
1168 
1169   rarray->len = length;
1170 }
1171 
1172 /**
1173  * g_ptr_array_remove_index:
1174  * @array: a #GPtrArray
1175  * @index_: the index of the pointer to remove
1176  *
1177  * Removes the pointer at the given index from the pointer array.
1178  * The following elements are moved down one place. If @array has
1179  * a non-%NULL #GDestroyNotify function it is called for the removed
1180  * element.
1181  *
1182  * Returns: the pointer which was removed
1183  */
1184 gpointer
1185 g_ptr_array_remove_index (GPtrArray *array,
1186                           guint      index_)
1187 {
1188   GRealPtrArray *rarray = (GRealPtrArray *)array;
1189   gpointer result;
1190 
1191   g_return_val_if_fail (rarray, NULL);
1192 
1193   g_return_val_if_fail (index_ < rarray->len, NULL);
1194 
1195   result = rarray->pdata[index_];
1196 
1197   if (rarray->element_free_func != NULL)
1198     rarray->element_free_func (rarray->pdata[index_]);
1199 
1200   if (index_ != rarray->len - 1)
1201     memmove (rarray->pdata + index_, rarray->pdata + index_ + 1,
1202              sizeof (gpointer) * (rarray->len - index_ - 1));
1203 
1204   rarray->len -= 1;
1205 
1206   if (G_UNLIKELY (g_mem_gc_friendly))
1207     rarray->pdata[rarray->len] = NULL;
1208 
1209   return result;
1210 }
1211 
1212 /**
1213  * g_ptr_array_remove_index_fast:
1214  * @array: a #GPtrArray
1215  * @index_: the index of the pointer to remove
1216  *
1217  * Removes the pointer at the given index from the pointer array.
1218  * The last element in the array is used to fill in the space, so
1219  * this function does not preserve the order of the array. But it
1220  * is faster than g_ptr_array_remove_index(). If @array has a non-%NULL
1221  * #GDestroyNotify function it is called for the removed element.
1222  *
1223  * Returns: the pointer which was removed
1224  */
1225 gpointer
1226 g_ptr_array_remove_index_fast (GPtrArray *array,
1227                                guint      index_)
1228 {
1229   GRealPtrArray *rarray = (GRealPtrArray *)array;
1230   gpointer result;
1231 
1232   g_return_val_if_fail (rarray, NULL);
1233 
1234   g_return_val_if_fail (index_ < rarray->len, NULL);
1235 
1236   result = rarray->pdata[index_];
1237 
1238   if (rarray->element_free_func != NULL)
1239     rarray->element_free_func (rarray->pdata[index_]);
1240 
1241   if (index_ != rarray->len - 1)
1242     rarray->pdata[index_] = rarray->pdata[rarray->len - 1];
1243 
1244   rarray->len -= 1;
1245 
1246   if (G_UNLIKELY (g_mem_gc_friendly))
1247     rarray->pdata[rarray->len] = NULL;
1248 
1249   return result;
1250 }
1251 
1252 /**
1253  * g_ptr_array_remove_range:
1254  * @array: a @GPtrArray
1255  * @index_: the index of the first pointer to remove
1256  * @length: the number of pointers to remove
1257  *
1258  * Removes the given number of pointers starting at the given index
1259  * from a #GPtrArray. The following elements are moved to close the
1260  * gap. If @array has a non-%NULL #GDestroyNotify function it is
1261  * called for the removed elements.
1262  *
1263  * Returns: the @array
1264  *
1265  * Since: 2.4
1266  */
1267 GPtrArray*
1268 g_ptr_array_remove_range (GPtrArray *array,
1269                           guint      index_,
1270                           guint      length)
1271 {
1272   GRealPtrArray *rarray = (GRealPtrArray *)array;
1273   guint n;
1274 
1275   g_return_val_if_fail (rarray != NULL, NULL);
1276   g_return_val_if_fail (index_ < rarray->len, NULL);
1277   g_return_val_if_fail (index_ + length <= rarray->len, NULL);
1278 
1279   if (rarray->element_free_func != NULL)
1280     {
1281       for (n = index_; n < index_ + length; n++)
1282         rarray->element_free_func (rarray->pdata[n]);
1283     }
1284 
1285   if (index_ + length != rarray->len)
1286     {
1287       memmove (&rarray->pdata[index_],
1288                &rarray->pdata[index_ + length],
1289                (rarray->len - (index_ + length)) * sizeof (gpointer));
1290     }
1291 
1292   rarray->len -= length;
1293   if (G_UNLIKELY (g_mem_gc_friendly))
1294     {
1295       guint i;
1296       for (i = 0; i < length; i++)
1297         rarray->pdata[rarray->len + i] = NULL;
1298     }
1299 
1300   return array;
1301 }
1302 
1303 /**
1304  * g_ptr_array_remove:
1305  * @array: a #GPtrArray
1306  * @data: the pointer to remove
1307  *
1308  * Removes the first occurrence of the given pointer from the pointer
1309  * array. The following elements are moved down one place. If @array
1310  * has a non-%NULL #GDestroyNotify function it is called for the
1311  * removed element.
1312  *
1313  * It returns %TRUE if the pointer was removed, or %FALSE if the
1314  * pointer was not found.
1315  *
1316  * Returns: %TRUE if the pointer is removed, %FALSE if the pointer
1317  *     is not found in the array
1318  */
1319 gboolean
1320 g_ptr_array_remove (GPtrArray *array,
1321                     gpointer   data)
1322 {
1323   guint i;
1324 
1325   g_return_val_if_fail (array, FALSE);
1326 
1327   for (i = 0; i < array->len; i += 1)
1328     {
1329       if (array->pdata[i] == data)
1330         {
1331           g_ptr_array_remove_index (array, i);
1332           return TRUE;
1333         }
1334     }
1335 
1336   return FALSE;
1337 }
1338 
1339 /**
1340  * g_ptr_array_remove_fast:
1341  * @array: a #GPtrArray
1342  * @data: the pointer to remove
1343  *
1344  * Removes the first occurrence of the given pointer from the pointer
1345  * array. The last element in the array is used to fill in the space,
1346  * so this function does not preserve the order of the array. But it
1347  * is faster than g_ptr_array_remove(). If @array has a non-%NULL
1348  * #GDestroyNotify function it is called for the removed element.
1349  *
1350  * It returns %TRUE if the pointer was removed, or %FALSE if the
1351  * pointer was not found.
1352  *
1353  * Returns: %TRUE if the pointer was found in the array
1354  */
1355 gboolean
1356 g_ptr_array_remove_fast (GPtrArray *array,
1357                          gpointer   data)
1358 {
1359   GRealPtrArray *rarray = (GRealPtrArray *)array;
1360   guint i;
1361 
1362   g_return_val_if_fail (rarray, FALSE);
1363 
1364   for (i = 0; i < rarray->len; i += 1)
1365     {
1366       if (rarray->pdata[i] == data)
1367         {
1368           g_ptr_array_remove_index_fast (array, i);
1369           return TRUE;
1370         }
1371     }
1372 
1373   return FALSE;
1374 }
1375 
1376 /**
1377  * g_ptr_array_add:
1378  * @array: a #GPtrArray
1379  * @data: the pointer to add
1380  *
1381  * Adds a pointer to the end of the pointer array. The array will grow
1382  * in size automatically if necessary.
1383  */
1384 void
1385 g_ptr_array_add (GPtrArray *array,
1386                  gpointer   data)
1387 {
1388   GRealPtrArray *rarray = (GRealPtrArray *)array;
1389 
1390   g_return_if_fail (rarray);
1391 
1392   g_ptr_array_maybe_expand (rarray, 1);
1393 
1394   rarray->pdata[rarray->len++] = data;
1395 }
1396 
1397 /**
1398  * g_ptr_array_insert:
1399  * @array: a #GPtrArray
1400  * @index_: the index to place the new element at, or -1 to append
1401  * @data: the pointer to add.
1402  *
1403  * Inserts an element into the pointer array at the given index. The
1404  * array will grow in size automatically if necessary.
1405  *
1406  * Since: 2.40
1407  */
1408 void
1409 g_ptr_array_insert (GPtrArray *array,
1410                     gint       index_,
1411                     gpointer   data)
1412 {
1413   GRealPtrArray *rarray = (GRealPtrArray *)array;
1414 
1415   g_return_if_fail (rarray);
1416   g_return_if_fail (index_ >= -1);
1417   g_return_if_fail (index_ <= (gint)rarray->len);
1418 
1419   g_ptr_array_maybe_expand (rarray, 1);
1420 
1421   if (index_ < 0)
1422     index_ = rarray->len;
1423 
1424   if (index_ < rarray->len)
1425     memmove (&(rarray->pdata[index_ + 1]),
1426              &(rarray->pdata[index_]),
1427              (rarray->len - index_) * sizeof (gpointer));
1428 
1429   rarray->len++;
1430   rarray->pdata[index_] = data;
1431 }
1432 
1433 /**
1434  * g_ptr_array_sort:
1435  * @array: a #GPtrArray
1436  * @compare_func: comparison function
1437  *
1438  * Sorts the array, using @compare_func which should be a qsort()-style
1439  * comparison function (returns less than zero for first arg is less
1440  * than second arg, zero for equal, greater than zero if irst arg is
1441  * greater than second arg).
1442  *
1443  * Note that the comparison function for g_ptr_array_sort() doesn't
1444  * take the pointers from the array as arguments, it takes pointers to
1445  * the pointers in the array.
1446  *
1447  * This is guaranteed to be a stable sort since version 2.32.
1448  */
1449 void
1450 g_ptr_array_sort (GPtrArray    *array,
1451                   GCompareFunc  compare_func)
1452 {
1453   g_return_if_fail (array != NULL);
1454 
1455   /* Don't use qsort as we want a guaranteed stable sort */
1456   g_qsort_with_data (array->pdata,
1457                      array->len,
1458                      sizeof (gpointer),
1459                      (GCompareDataFunc)compare_func,
1460                      NULL);
1461 }
1462 
1463 /**
1464  * g_ptr_array_sort_with_data:
1465  * @array: a #GPtrArray
1466  * @compare_func: comparison function
1467  * @user_data: data to pass to @compare_func
1468  *
1469  * Like g_ptr_array_sort(), but the comparison function has an extra
1470  * user data argument.
1471  *
1472  * Note that the comparison function for g_ptr_array_sort_with_data()
1473  * doesn't take the pointers from the array as arguments, it takes
1474  * pointers to the pointers in the array.
1475  *
1476  * This is guaranteed to be a stable sort since version 2.32.
1477  */
1478 void
1479 g_ptr_array_sort_with_data (GPtrArray        *array,
1480                             GCompareDataFunc  compare_func,
1481                             gpointer          user_data)
1482 {
1483   g_return_if_fail (array != NULL);
1484 
1485   g_qsort_with_data (array->pdata,
1486                      array->len,
1487                      sizeof (gpointer),
1488                      compare_func,
1489                      user_data);
1490 }
1491 
1492 /**
1493  * g_ptr_array_foreach:
1494  * @array: a #GPtrArray
1495  * @func: the function to call for each array element
1496  * @user_data: user data to pass to the function
1497  *
1498  * Calls a function for each element of a #GPtrArray.
1499  *
1500  * Since: 2.4
1501  */
1502 void
1503 g_ptr_array_foreach (GPtrArray *array,
1504                      GFunc      func,
1505                      gpointer   user_data)
1506 {
1507   guint i;
1508 
1509   g_return_if_fail (array);
1510 
1511   for (i = 0; i < array->len; i++)
1512     (*func) (array->pdata[i], user_data);
1513 }
1514 
1515 /**
1516  * SECTION:arrays_byte
1517  * @title: Byte Arrays
1518  * @short_description: arrays of bytes
1519  *
1520  * #GByteArray is a mutable array of bytes based on #GArray, to provide arrays
1521  * of bytes which grow automatically as elements are added.
1522  *
1523  * To create a new #GByteArray use g_byte_array_new(). To add elements to a
1524  * #GByteArray, use g_byte_array_append(), and g_byte_array_prepend().
1525  *
1526  * To set the size of a #GByteArray, use g_byte_array_set_size().
1527  *
1528  * To free a #GByteArray, use g_byte_array_free().
1529  *
1530  * An example for using a #GByteArray:
1531  * |[<!-- language="C" -->
1532  *   GByteArray *gbarray;
1533  *   gint i;
1534  *
1535  *   gbarray = g_byte_array_new ();
1536  *   for (i = 0; i < 10000; i++)
1537  *     g_byte_array_append (gbarray, (guint8*) "abcd", 4);
1538  *
1539  *   for (i = 0; i < 10000; i++)
1540  *     {
1541  *       g_assert (gbarray->data[4*i] == 'a');
1542  *       g_assert (gbarray->data[4*i+1] == 'b');
1543  *       g_assert (gbarray->data[4*i+2] == 'c');
1544  *       g_assert (gbarray->data[4*i+3] == 'd');
1545  *     }
1546  *
1547  *   g_byte_array_free (gbarray, TRUE);
1548  * ]|
1549  *
1550  * See #GBytes if you are interested in an immutable object representing a
1551  * sequence of bytes.
1552  */
1553 
1554 /**
1555  * GByteArray:
1556  * @data: a pointer to the element data. The data may be moved as
1557  *     elements are added to the #GByteArray
1558  * @len: the number of elements in the #GByteArray
1559  *
1560  * Contains the public fields of a GByteArray.
1561  */
1562 
1563 /**
1564  * g_byte_array_new:
1565  *
1566  * Creates a new #GByteArray with a reference count of 1.
1567  *
1568  * Returns: (transfer full): the new #GByteArray
1569  */
1570 GByteArray*
1571 g_byte_array_new (void)
1572 {
1573   return (GByteArray *)g_array_sized_new (FALSE, FALSE, 1, 0);
1574 }
1575 
1576 /**
1577  * g_byte_array_new_take:
1578  * @data: (transfer full) (array length=len): byte data for the array
1579  * @len: length of @data
1580  *
1581  * Create byte array containing the data. The data will be owned by the array
1582  * and will be freed with g_free(), i.e. it could be allocated using g_strdup().
1583  *
1584  * Since: 2.32
1585  *
1586  * Returns: (transfer full): a new #GByteArray
1587  */
1588 GByteArray*
1589 g_byte_array_new_take (guint8 *data,
1590                        gsize   len)
1591 {
1592   GByteArray *array;
1593   GRealArray *real;
1594 
1595   array = g_byte_array_new ();
1596   real = (GRealArray *)array;
1597   g_assert (real->data == NULL);
1598   g_assert (real->len == 0);
1599 
1600   real->data = data;
1601   real->len = len;
1602   real->alloc = len;
1603 
1604   return array;
1605 }
1606 
1607 /**
1608  * g_byte_array_sized_new:
1609  * @reserved_size: number of bytes preallocated
1610  *
1611  * Creates a new #GByteArray with @reserved_size bytes preallocated.
1612  * This avoids frequent reallocation, if you are going to add many
1613  * bytes to the array. Note however that the size of the array is still
1614  * 0.
1615  *
1616  * Returns: the new #GByteArray
1617  */
1618 GByteArray*
1619 g_byte_array_sized_new (guint reserved_size)
1620 {
1621   return (GByteArray *)g_array_sized_new (FALSE, FALSE, 1, reserved_size);
1622 }
1623 
1624 /**
1625  * g_byte_array_free:
1626  * @array: a #GByteArray
1627  * @free_segment: if %TRUE the actual byte data is freed as well
1628  *
1629  * Frees the memory allocated by the #GByteArray. If @free_segment is
1630  * %TRUE it frees the actual byte data. If the reference count of
1631  * @array is greater than one, the #GByteArray wrapper is preserved but
1632  * the size of @array will be set to zero.
1633  *
1634  * Returns: the element data if @free_segment is %FALSE, otherwise
1635  *          %NULL.  The element data should be freed using g_free().
1636  */
1637 guint8*
1638 g_byte_array_free (GByteArray *array,
1639                    gboolean    free_segment)
1640 {
1641   return (guint8 *)g_array_free ((GArray *)array, free_segment);
1642 }
1643 
1644 /**
1645  * g_byte_array_free_to_bytes:
1646  * @array: (transfer full): a #GByteArray
1647  *
1648  * Transfers the data from the #GByteArray into a new immutable #GBytes.
1649  *
1650  * The #GByteArray is freed unless the reference count of @array is greater
1651  * than one, the #GByteArray wrapper is preserved but the size of @array
1652  * will be set to zero.
1653  *
1654  * This is identical to using g_bytes_new_take() and g_byte_array_free()
1655  * together.
1656  *
1657  * Since: 2.32
1658  *
1659  * Returns: (transfer full): a new immutable #GBytes representing same
1660  *     byte data that was in the array
1661  */
1662 GBytes*
1663 g_byte_array_free_to_bytes (GByteArray *array)
1664 {
1665   gsize length;
1666 
1667   g_return_val_if_fail (array != NULL, NULL);
1668 
1669   length = array->len;
1670   return g_bytes_new_take (g_byte_array_free (array, FALSE), length);
1671 }
1672 
1673 /**
1674  * g_byte_array_ref:
1675  * @array: A #GByteArray
1676  *
1677  * Atomically increments the reference count of @array by one.
1678  * This function is thread-safe and may be called from any thread.
1679  *
1680  * Returns: The passed in #GByteArray
1681  *
1682  * Since: 2.22
1683  */
1684 GByteArray*
1685 g_byte_array_ref (GByteArray *array)
1686 {
1687   return (GByteArray *)g_array_ref ((GArray *)array);
1688 }
1689 
1690 /**
1691  * g_byte_array_unref:
1692  * @array: A #GByteArray
1693  *
1694  * Atomically decrements the reference count of @array by one. If the
1695  * reference count drops to 0, all memory allocated by the array is
1696  * released. This function is thread-safe and may be called from any
1697  * thread.
1698  *
1699  * Since: 2.22
1700  */
1701 void
1702 g_byte_array_unref (GByteArray *array)
1703 {
1704   g_array_unref ((GArray *)array);
1705 }
1706 
1707 /**
1708  * g_byte_array_append:
1709  * @array: a #GByteArray
1710  * @data: the byte data to be added
1711  * @len: the number of bytes to add
1712  *
1713  * Adds the given bytes to the end of the #GByteArray.
1714  * The array will grow in size automatically if necessary.
1715  *
1716  * Returns: the #GByteArray
1717  */
1718 GByteArray*
1719 g_byte_array_append (GByteArray   *array,
1720                      const guint8 *data,
1721                      guint         len)
1722 {
1723   g_array_append_vals ((GArray *)array, (guint8 *)data, len);
1724 
1725   return array;
1726 }
1727 
1728 /**
1729  * g_byte_array_prepend:
1730  * @array: a #GByteArray
1731  * @data: the byte data to be added
1732  * @len: the number of bytes to add
1733  *
1734  * Adds the given data to the start of the #GByteArray.
1735  * The array will grow in size automatically if necessary.
1736  *
1737  * Returns: the #GByteArray
1738  */
1739 GByteArray*
1740 g_byte_array_prepend (GByteArray   *array,
1741                       const guint8 *data,
1742                       guint         len)
1743 {
1744   g_array_prepend_vals ((GArray *)array, (guint8 *)data, len);
1745 
1746   return array;
1747 }
1748 
1749 /**
1750  * g_byte_array_set_size:
1751  * @array: a #GByteArray
1752  * @length: the new size of the #GByteArray
1753  *
1754  * Sets the size of the #GByteArray, expanding it if necessary.
1755  *
1756  * Returns: the #GByteArray
1757  */
1758 GByteArray*
1759 g_byte_array_set_size (GByteArray *array,
1760                        guint       length)
1761 {
1762   g_array_set_size ((GArray *)array, length);
1763 
1764   return array;
1765 }
1766 
1767 /**
1768  * g_byte_array_remove_index:
1769  * @array: a #GByteArray
1770  * @index_: the index of the byte to remove
1771  *
1772  * Removes the byte at the given index from a #GByteArray.
1773  * The following bytes are moved down one place.
1774  *
1775  * Returns: the #GByteArray
1776  **/
1777 GByteArray*
1778 g_byte_array_remove_index (GByteArray *array,
1779                            guint       index_)
1780 {
1781   g_array_remove_index ((GArray *)array, index_);
1782 
1783   return array;
1784 }
1785 
1786 /**
1787  * g_byte_array_remove_index_fast:
1788  * @array: a #GByteArray
1789  * @index_: the index of the byte to remove
1790  *
1791  * Removes the byte at the given index from a #GByteArray. The last
1792  * element in the array is used to fill in the space, so this function
1793  * does not preserve the order of the #GByteArray. But it is faster
1794  * than g_byte_array_remove_index().
1795  *
1796  * Returns: the #GByteArray
1797  */
1798 GByteArray*
1799 g_byte_array_remove_index_fast (GByteArray *array,
1800                                 guint       index_)
1801 {
1802   g_array_remove_index_fast ((GArray *)array, index_);
1803 
1804   return array;
1805 }
1806 
1807 /**
1808  * g_byte_array_remove_range:
1809  * @array: a @GByteArray
1810  * @index_: the index of the first byte to remove
1811  * @length: the number of bytes to remove
1812  *
1813  * Removes the given number of bytes starting at the given index from a
1814  * #GByteArray.  The following elements are moved to close the gap.
1815  *
1816  * Returns: the #GByteArray
1817  *
1818  * Since: 2.4
1819  */
1820 GByteArray*
1821 g_byte_array_remove_range (GByteArray *array,
1822                            guint       index_,
1823                            guint       length)
1824 {
1825   g_return_val_if_fail (array, NULL);
1826   g_return_val_if_fail (index_ < array->len, NULL);
1827   g_return_val_if_fail (index_ + length <= array->len, NULL);
1828 
1829   return (GByteArray *)g_array_remove_range ((GArray *)array, index_, length);
1830 }
1831 
1832 /**
1833  * g_byte_array_sort:
1834  * @array: a #GByteArray
1835  * @compare_func: comparison function
1836  *
1837  * Sorts a byte array, using @compare_func which should be a
1838  * qsort()-style comparison function (returns less than zero for first
1839  * arg is less than second arg, zero for equal, greater than zero if
1840  * first arg is greater than second arg).
1841  *
1842  * If two array elements compare equal, their order in the sorted array
1843  * is undefined. If you want equal elements to keep their order (i.e.
1844  * you want a stable sort) you can write a comparison function that,
1845  * if two elements would otherwise compare equal, compares them by
1846  * their addresses.
1847  */
1848 void
1849 g_byte_array_sort (GByteArray   *array,
1850                    GCompareFunc  compare_func)
1851 {
1852   g_array_sort ((GArray *)array, compare_func);
1853 }
1854 
1855 /**
1856  * g_byte_array_sort_with_data:
1857  * @array: a #GByteArray
1858  * @compare_func: comparison function
1859  * @user_data: data to pass to @compare_func
1860  *
1861  * Like g_byte_array_sort(), but the comparison function takes an extra
1862  * user data argument.
1863  */
1864 void
1865 g_byte_array_sort_with_data (GByteArray       *array,
1866                              GCompareDataFunc  compare_func,
1867                              gpointer          user_data)
1868 {
1869   g_array_sort_with_data ((GArray *)array, compare_func, user_data);
1870 }