LCOV - code coverage report
Current view: top level - glib - garray.c (source / functions) Hit Total Coverage
Test: unnamed Lines: 504 506 99.6 %
Date: 2022-01-17 22:56:14 Functions: 68 68 100.0 %
Branches: 179 186 96.2 %

           Branch data     Line data    Source code
       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.1 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 "ghash.h"
      38                 :            : #include "gslice.h"
      39                 :            : #include "gmem.h"
      40                 :            : #include "gtestutils.h"
      41                 :            : #include "gthread.h"
      42                 :            : #include "gmessages.h"
      43                 :            : #include "gqsort.h"
      44                 :            : #include "grefcount.h"
      45                 :            : #include "gutilsprivate.h"
      46                 :            : 
      47                 :            : /**
      48                 :            :  * SECTION:arrays
      49                 :            :  * @title: Arrays
      50                 :            :  * @short_description: arrays of arbitrary elements which grow
      51                 :            :  *     automatically as elements are added
      52                 :            :  *
      53                 :            :  * Arrays are similar to standard C arrays, except that they grow
      54                 :            :  * automatically as elements are added.
      55                 :            :  *
      56                 :            :  * Array elements can be of any size (though all elements of one array
      57                 :            :  * are the same size), and the array can be automatically cleared to
      58                 :            :  * '0's and zero-terminated.
      59                 :            :  *
      60                 :            :  * To create a new array use g_array_new().
      61                 :            :  *
      62                 :            :  * To add elements to an array with a cost of O(n) at worst, use
      63                 :            :  * g_array_append_val(), g_array_append_vals(), g_array_prepend_val(),
      64                 :            :  * g_array_prepend_vals(), g_array_insert_val() and g_array_insert_vals().
      65                 :            :  *
      66                 :            :  * To access an element of an array in O(1) (to read it or to write it),
      67                 :            :  * use g_array_index().
      68                 :            :  *
      69                 :            :  * To set the size of an array, use g_array_set_size().
      70                 :            :  *
      71                 :            :  * To free an array, use g_array_unref() or g_array_free().
      72                 :            :  *
      73                 :            :  * All the sort functions are internally calling a quick-sort (or similar)
      74                 :            :  * function with an average cost of O(n log(n)) and a worst case
      75                 :            :  * cost of O(n^2).
      76                 :            :  *
      77                 :            :  * Here is an example that stores integers in a #GArray:
      78                 :            :  * |[<!-- language="C" -->
      79                 :            :  *   GArray *garray;
      80                 :            :  *   gint i;
      81                 :            :  *   // We create a new array to store gint values.
      82                 :            :  *   // We don't want it zero-terminated or cleared to 0's.
      83                 :            :  *   garray = g_array_new (FALSE, FALSE, sizeof (gint));
      84                 :            :  *   for (i = 0; i < 10000; i++)
      85                 :            :  *     g_array_append_val (garray, i);
      86                 :            :  *   for (i = 0; i < 10000; i++)
      87                 :            :  *     if (g_array_index (garray, gint, i) != i)
      88                 :            :  *       g_print ("ERROR: got %d instead of %d\n",
      89                 :            :  *                g_array_index (garray, gint, i), i);
      90                 :            :  *   g_array_free (garray, TRUE);
      91                 :            :  * ]|
      92                 :            :  */
      93                 :            : 
      94                 :            : #define MIN_ARRAY_SIZE  16
      95                 :            : 
      96                 :            : typedef struct _GRealArray  GRealArray;
      97                 :            : 
      98                 :            : /**
      99                 :            :  * GArray:
     100                 :            :  * @data: a pointer to the element data. The data may be moved as
     101                 :            :  *     elements are added to the #GArray.
     102                 :            :  * @len: the number of elements in the #GArray not including the
     103                 :            :  *     possible terminating zero element.
     104                 :            :  *
     105                 :            :  * Contains the public fields of a GArray.
     106                 :            :  */
     107                 :            : struct _GRealArray
     108                 :            : {
     109                 :            :   guint8 *data;
     110                 :            :   guint   len;
     111                 :            :   guint   elt_capacity;
     112                 :            :   guint   elt_size;
     113                 :            :   guint   zero_terminated : 1;
     114                 :            :   guint   clear : 1;
     115                 :            :   gatomicrefcount ref_count;
     116                 :            :   GDestroyNotify clear_func;
     117                 :            : };
     118                 :            : 
     119                 :            : /**
     120                 :            :  * g_array_index:
     121                 :            :  * @a: a #GArray
     122                 :            :  * @t: the type of the elements
     123                 :            :  * @i: the index of the element to return
     124                 :            :  *
     125                 :            :  * Returns the element of a #GArray at the given index. The return
     126                 :            :  * value is cast to the given type. This is the main way to read or write an
     127                 :            :  * element in a #GArray.
     128                 :            :  *
     129                 :            :  * Writing an element is typically done by reference, as in the following
     130                 :            :  * example. This example gets a pointer to an element in a #GArray, and then
     131                 :            :  * writes to a field in it:
     132                 :            :  * |[<!-- language="C" -->
     133                 :            :  *   EDayViewEvent *event;
     134                 :            :  *   // This gets a pointer to the 4th element in the array of
     135                 :            :  *   // EDayViewEvent structs.
     136                 :            :  *   event = &g_array_index (events, EDayViewEvent, 3);
     137                 :            :  *   event->start_time = g_get_current_time ();
     138                 :            :  * ]|
     139                 :            :  *
     140                 :            :  * This example reads from and writes to an array of integers:
     141                 :            :  * |[<!-- language="C" -->
     142                 :            :  *   g_autoptr(GArray) int_array = g_array_new (FALSE, FALSE, sizeof (guint));
     143                 :            :  *   for (guint i = 0; i < 10; i++)
     144                 :            :  *     g_array_append_val (int_array, i);
     145                 :            :  *
     146                 :            :  *   guint *my_int = &g_array_index (int_array, guint, 1);
     147                 :            :  *   g_print ("Int at index 1 is %u; decrementing it\n", *my_int);
     148                 :            :  *   *my_int = *my_int - 1;
     149                 :            :  * ]|
     150                 :            :  *
     151                 :            :  * Returns: the element of the #GArray at the index given by @i
     152                 :            :  */
     153                 :            : 
     154                 :            : #define g_array_elt_len(array,i) ((gsize)(array)->elt_size * (i))
     155                 :            : #define g_array_elt_pos(array,i) ((array)->data + g_array_elt_len((array),(i)))
     156                 :            : #define g_array_elt_zero(array, pos, len)                               \
     157                 :            :   (memset (g_array_elt_pos ((array), pos), 0,  g_array_elt_len ((array), len)))
     158                 :            : #define g_array_zero_terminate(array) G_STMT_START{                     \
     159                 :            :   if ((array)->zero_terminated)                                         \
     160                 :            :     g_array_elt_zero ((array), (array)->len, 1);                        \
     161                 :            : }G_STMT_END
     162                 :            : 
     163                 :            : static void  g_array_maybe_expand (GRealArray *array,
     164                 :            :                                    guint       len);
     165                 :            : 
     166                 :            : /**
     167                 :            :  * g_array_new:
     168                 :            :  * @zero_terminated: %TRUE if the array should have an extra element at
     169                 :            :  *     the end which is set to 0
     170                 :            :  * @clear_: %TRUE if #GArray elements should be automatically cleared
     171                 :            :  *     to 0 when they are allocated
     172                 :            :  * @element_size: the size of each element in bytes
     173                 :            :  *
     174                 :            :  * Creates a new #GArray with a reference count of 1.
     175                 :            :  *
     176                 :            :  * Returns: the new #GArray
     177                 :            :  */
     178                 :            : GArray*
     179                 :     405505 : g_array_new (gboolean zero_terminated,
     180                 :            :              gboolean clear,
     181                 :            :              guint    elt_size)
     182                 :            : {
     183                 :     405505 :   g_return_val_if_fail (elt_size > 0, NULL);
     184                 :            : #if (UINT_WIDTH / 8) >= GLIB_SIZEOF_SIZE_T
     185                 :            :   g_return_val_if_fail (elt_size <= G_MAXSIZE / 2 - 1, NULL);
     186                 :            : #endif
     187                 :            : 
     188                 :     405505 :   return g_array_sized_new (zero_terminated, clear, elt_size, 0);
     189                 :            : }
     190                 :            : 
     191                 :            : /**
     192                 :            :  * g_array_steal:
     193                 :            :  * @array: a #GArray.
     194                 :            :  * @len: (optional) (out): pointer to retrieve the number of
     195                 :            :  *    elements of the original array
     196                 :            :  *
     197                 :            :  * Frees the data in the array and resets the size to zero, while
     198                 :            :  * the underlying array is preserved for use elsewhere and returned
     199                 :            :  * to the caller.
     200                 :            :  *
     201                 :            :  * If the array was created with the @zero_terminate property
     202                 :            :  * set to %TRUE, the returned data is zero terminated too.
     203                 :            :  *
     204                 :            :  * If array elements contain dynamically-allocated memory,
     205                 :            :  * the array elements should also be freed by the caller.
     206                 :            :  *
     207                 :            :  * A short example of use:
     208                 :            :  * |[<!-- language="C" -->
     209                 :            :  * ...
     210                 :            :  * gpointer data;
     211                 :            :  * gsize data_len;
     212                 :            :  * data = g_array_steal (some_array, &data_len);
     213                 :            :  * ...
     214                 :            :  * ]|
     215                 :            : 
     216                 :            :  * Returns: (transfer full): the element data, which should be
     217                 :            :  *     freed using g_free().
     218                 :            :  *
     219                 :            :  * Since: 2.64
     220                 :            :  */
     221                 :            : gpointer
     222                 :         10 : g_array_steal (GArray *array,
     223                 :            :                gsize *len)
     224                 :            : {
     225                 :            :   GRealArray *rarray;
     226                 :            :   gpointer segment;
     227                 :            : 
     228                 :         10 :   g_return_val_if_fail (array != NULL, NULL);
     229                 :            : 
     230                 :         10 :   rarray = (GRealArray *) array;
     231                 :         10 :   segment = (gpointer) rarray->data;
     232                 :            : 
     233         [ +  + ]:         10 :   if (len != NULL)
     234                 :          6 :     *len = rarray->len;
     235                 :            : 
     236                 :         10 :   rarray->data  = NULL;
     237                 :         10 :   rarray->len   = 0;
     238                 :         10 :   rarray->elt_capacity = 0;
     239                 :         10 :   return segment;
     240                 :            : }
     241                 :            : 
     242                 :            : /**
     243                 :            :  * g_array_sized_new:
     244                 :            :  * @zero_terminated: %TRUE if the array should have an extra element at
     245                 :            :  *     the end with all bits cleared
     246                 :            :  * @clear_: %TRUE if all bits in the array should be cleared to 0 on
     247                 :            :  *     allocation
     248                 :            :  * @element_size: size of each element in the array
     249                 :            :  * @reserved_size: number of elements preallocated
     250                 :            :  *
     251                 :            :  * Creates a new #GArray with @reserved_size elements preallocated and
     252                 :            :  * a reference count of 1. This avoids frequent reallocation, if you
     253                 :            :  * are going to add many elements to the array. Note however that the
     254                 :            :  * size of the array is still 0.
     255                 :            :  *
     256                 :            :  * Returns: the new #GArray
     257                 :            :  */
     258                 :            : GArray*
     259                 :     407537 : g_array_sized_new (gboolean zero_terminated,
     260                 :            :                    gboolean clear,
     261                 :            :                    guint    elt_size,
     262                 :            :                    guint    reserved_size)
     263                 :            : {
     264                 :            :   GRealArray *array;
     265                 :            :   
     266                 :     407537 :   g_return_val_if_fail (elt_size > 0, NULL);
     267                 :            : #if (UINT_WIDTH / 8) >= GLIB_SIZEOF_SIZE_T
     268                 :            :   g_return_val_if_fail (elt_size <= G_MAXSIZE / 2 - 1, NULL);
     269                 :            : #endif
     270                 :            : 
     271                 :     407537 :   array = g_slice_new (GRealArray);
     272                 :            : 
     273                 :     407537 :   array->data            = NULL;
     274                 :     407537 :   array->len             = 0;
     275                 :     407537 :   array->elt_capacity = 0;
     276                 :     407537 :   array->zero_terminated = (zero_terminated ? 1 : 0);
     277                 :     407537 :   array->clear           = (clear ? 1 : 0);
     278                 :     407537 :   array->elt_size        = elt_size;
     279                 :     407537 :   array->clear_func      = NULL;
     280                 :            : 
     281                 :     407537 :   g_atomic_ref_count_init (&array->ref_count);
     282                 :            : 
     283   [ +  +  +  + ]:     407537 :   if (array->zero_terminated || reserved_size != 0)
     284                 :            :     {
     285                 :       2048 :       g_array_maybe_expand (array, reserved_size);
     286         [ +  + ]:       2048 :       g_array_zero_terminate(array);
     287                 :            :     }
     288                 :            : 
     289                 :     407537 :   return (GArray*) array;
     290                 :            : }
     291                 :            : 
     292                 :            : /**
     293                 :            :  * g_array_set_clear_func:
     294                 :            :  * @array: A #GArray
     295                 :            :  * @clear_func: a function to clear an element of @array
     296                 :            :  *
     297                 :            :  * Sets a function to clear an element of @array.
     298                 :            :  *
     299                 :            :  * The @clear_func will be called when an element in the array
     300                 :            :  * data segment is removed and when the array is freed and data
     301                 :            :  * segment is deallocated as well. @clear_func will be passed a
     302                 :            :  * pointer to the element to clear, rather than the element itself.
     303                 :            :  *
     304                 :            :  * Note that in contrast with other uses of #GDestroyNotify
     305                 :            :  * functions, @clear_func is expected to clear the contents of
     306                 :            :  * the array element it is given, but not free the element itself.
     307                 :            :  *
     308                 :            :  * |[<!-- language="C" -->
     309                 :            :  * typedef struct
     310                 :            :  * {
     311                 :            :  *   gchar *str;
     312                 :            :  *   GObject *obj;
     313                 :            :  * } ArrayElement;
     314                 :            :  *
     315                 :            :  * static void
     316                 :            :  * array_element_clear (ArrayElement *element)
     317                 :            :  * {
     318                 :            :  *   g_clear_pointer (&element->str, g_free);
     319                 :            :  *   g_clear_object (&element->obj);
     320                 :            :  * }
     321                 :            :  *
     322                 :            :  * // main code
     323                 :            :  * GArray *garray = g_array_new (FALSE, FALSE, sizeof (ArrayElement));
     324                 :            :  * g_array_set_clear_func (garray, (GDestroyNotify) array_element_clear);
     325                 :            :  * // assign data to the structure
     326                 :            :  * g_array_free (garray, TRUE);
     327                 :            :  * ]|
     328                 :            :  *
     329                 :            :  * Since: 2.32
     330                 :            :  */
     331                 :            : void
     332                 :         11 : g_array_set_clear_func (GArray         *array,
     333                 :            :                         GDestroyNotify  clear_func)
     334                 :            : {
     335                 :         11 :   GRealArray *rarray = (GRealArray *) array;
     336                 :            : 
     337                 :         11 :   g_return_if_fail (array != NULL);
     338                 :            : 
     339                 :         11 :   rarray->clear_func = clear_func;
     340                 :            : }
     341                 :            : 
     342                 :            : /**
     343                 :            :  * g_array_ref:
     344                 :            :  * @array: A #GArray
     345                 :            :  *
     346                 :            :  * Atomically increments the reference count of @array by one.
     347                 :            :  * This function is thread-safe and may be called from any thread.
     348                 :            :  *
     349                 :            :  * Returns: The passed in #GArray
     350                 :            :  *
     351                 :            :  * Since: 2.22
     352                 :            :  */
     353                 :            : GArray *
     354                 :       3371 : g_array_ref (GArray *array)
     355                 :            : {
     356                 :       3371 :   GRealArray *rarray = (GRealArray*) array;
     357                 :       3371 :   g_return_val_if_fail (array, NULL);
     358                 :            : 
     359                 :       3371 :   g_atomic_ref_count_inc (&rarray->ref_count);
     360                 :            : 
     361                 :       3371 :   return array;
     362                 :            : }
     363                 :            : 
     364                 :            : typedef enum
     365                 :            : {
     366                 :            :   FREE_SEGMENT = 1 << 0,
     367                 :            :   PRESERVE_WRAPPER = 1 << 1
     368                 :            : } ArrayFreeFlags;
     369                 :            : 
     370                 :            : static gchar *array_free (GRealArray *, ArrayFreeFlags);
     371                 :            : 
     372                 :            : /**
     373                 :            :  * g_array_unref:
     374                 :            :  * @array: A #GArray
     375                 :            :  *
     376                 :            :  * Atomically decrements the reference count of @array by one. If the
     377                 :            :  * reference count drops to 0, all memory allocated by the array is
     378                 :            :  * released. This function is thread-safe and may be called from any
     379                 :            :  * thread.
     380                 :            :  *
     381                 :            :  * Since: 2.22
     382                 :            :  */
     383                 :            : void
     384                 :       5166 : g_array_unref (GArray *array)
     385                 :            : {
     386                 :       5166 :   GRealArray *rarray = (GRealArray*) array;
     387                 :       5166 :   g_return_if_fail (array);
     388                 :            : 
     389         [ +  + ]:       5166 :   if (g_atomic_ref_count_dec (&rarray->ref_count))
     390                 :       1799 :     array_free (rarray, FREE_SEGMENT);
     391                 :            : }
     392                 :            : 
     393                 :            : /**
     394                 :            :  * g_array_get_element_size:
     395                 :            :  * @array: A #GArray
     396                 :            :  *
     397                 :            :  * Gets the size of the elements in @array.
     398                 :            :  *
     399                 :            :  * Returns: Size of each element, in bytes
     400                 :            :  *
     401                 :            :  * Since: 2.22
     402                 :            :  */
     403                 :            : guint
     404                 :          2 : g_array_get_element_size (GArray *array)
     405                 :            : {
     406                 :          2 :   GRealArray *rarray = (GRealArray*) array;
     407                 :            : 
     408                 :          2 :   g_return_val_if_fail (array, 0);
     409                 :            : 
     410                 :          2 :   return rarray->elt_size;
     411                 :            : }
     412                 :            : 
     413                 :            : /**
     414                 :            :  * g_array_free:
     415                 :            :  * @array: a #GArray
     416                 :            :  * @free_segment: if %TRUE the actual element data is freed as well
     417                 :            :  *
     418                 :            :  * Frees the memory allocated for the #GArray. If @free_segment is
     419                 :            :  * %TRUE it frees the memory block holding the elements as well. Pass
     420                 :            :  * %FALSE if you want to free the #GArray wrapper but preserve the
     421                 :            :  * underlying array for use elsewhere. If the reference count of
     422                 :            :  * @array is greater than one, the #GArray wrapper is preserved but
     423                 :            :  * the size of  @array will be set to zero.
     424                 :            :  *
     425                 :            :  * If array contents point to dynamically-allocated memory, they should
     426                 :            :  * be freed separately if @free_seg is %TRUE and no @clear_func
     427                 :            :  * function has been set for @array.
     428                 :            :  *
     429                 :            :  * This function is not thread-safe. If using a #GArray from multiple
     430                 :            :  * threads, use only the atomic g_array_ref() and g_array_unref()
     431                 :            :  * functions.
     432                 :            :  *
     433                 :            :  * Returns: the element data if @free_segment is %FALSE, otherwise
     434                 :            :  *     %NULL. The element data should be freed using g_free().
     435                 :            :  */
     436                 :            : gchar*
     437                 :     405668 : g_array_free (GArray   *farray,
     438                 :            :               gboolean  free_segment)
     439                 :            : {
     440                 :     405668 :   GRealArray *array = (GRealArray*) farray;
     441                 :            :   ArrayFreeFlags flags;
     442                 :            : 
     443                 :     405668 :   g_return_val_if_fail (array, NULL);
     444                 :            : 
     445                 :     405668 :   flags = (free_segment ? FREE_SEGMENT : 0);
     446                 :            : 
     447                 :            :   /* if others are holding a reference, preserve the wrapper but do free/return the data */
     448         [ +  + ]:     405668 :   if (!g_atomic_ref_count_dec (&array->ref_count))
     449                 :          4 :     flags |= PRESERVE_WRAPPER;
     450                 :            : 
     451                 :     405668 :   return array_free (array, flags);
     452                 :            : }
     453                 :            : 
     454                 :            : static gchar *
     455                 :     407467 : array_free (GRealArray     *array,
     456                 :            :             ArrayFreeFlags  flags)
     457                 :            : {
     458                 :            :   gchar *segment;
     459                 :            : 
     460         [ +  + ]:     407467 :   if (flags & FREE_SEGMENT)
     461                 :            :     {
     462         [ +  + ]:     407089 :       if (array->clear_func != NULL)
     463                 :            :         {
     464                 :            :           guint i;
     465                 :            : 
     466         [ +  + ]:        129 :           for (i = 0; i < array->len; i++)
     467                 :        118 :             array->clear_func (g_array_elt_pos (array, i));
     468                 :            :         }
     469                 :            : 
     470                 :     407089 :       g_free (array->data);
     471                 :     407089 :       segment = NULL;
     472                 :            :     }
     473                 :            :   else
     474                 :        378 :     segment = (gchar*) array->data;
     475                 :            : 
     476         [ +  + ]:     407467 :   if (flags & PRESERVE_WRAPPER)
     477                 :            :     {
     478                 :          4 :       array->data            = NULL;
     479                 :          4 :       array->len             = 0;
     480                 :          4 :       array->elt_capacity = 0;
     481                 :            :     }
     482                 :            :   else
     483                 :            :     {
     484                 :     407463 :       g_slice_free1 (sizeof (GRealArray), array);
     485                 :            :     }
     486                 :            : 
     487                 :     407467 :   return segment;
     488                 :            : }
     489                 :            : 
     490                 :            : /**
     491                 :            :  * g_array_append_vals:
     492                 :            :  * @array: a #GArray
     493                 :            :  * @data: (not nullable): a pointer to the elements to append to the end of the array
     494                 :            :  * @len: the number of elements to append
     495                 :            :  *
     496                 :            :  * Adds @len elements onto the end of the array.
     497                 :            :  *
     498                 :            :  * Returns: the #GArray
     499                 :            :  */
     500                 :            : /**
     501                 :            :  * g_array_append_val:
     502                 :            :  * @a: a #GArray
     503                 :            :  * @v: the value to append to the #GArray
     504                 :            :  *
     505                 :            :  * Adds the value on to the end of the array. The array will grow in
     506                 :            :  * size automatically if necessary.
     507                 :            :  *
     508                 :            :  * g_array_append_val() is a macro which uses a reference to the value
     509                 :            :  * parameter @v. This means that you cannot use it with literal values
     510                 :            :  * such as "27". You must use variables.
     511                 :            :  *
     512                 :            :  * Returns: the #GArray
     513                 :            :  */
     514                 :            : GArray*
     515                 :     474981 : g_array_append_vals (GArray       *farray,
     516                 :            :                      gconstpointer data,
     517                 :            :                      guint         len)
     518                 :            : {
     519                 :     474981 :   GRealArray *array = (GRealArray*) farray;
     520                 :            : 
     521                 :     474981 :   g_return_val_if_fail (array, NULL);
     522                 :            : 
     523         [ +  + ]:     474981 :   if (len == 0)
     524                 :          3 :     return farray;
     525                 :            : 
     526                 :     474978 :   g_array_maybe_expand (array, len);
     527                 :            : 
     528                 :     474977 :   memcpy (g_array_elt_pos (array, array->len), data, 
     529                 :     474977 :           g_array_elt_len (array, len));
     530                 :            : 
     531                 :     474977 :   array->len += len;
     532                 :            : 
     533         [ +  + ]:     474977 :   g_array_zero_terminate (array);
     534                 :            : 
     535                 :     474977 :   return farray;
     536                 :            : }
     537                 :            : 
     538                 :            : /**
     539                 :            :  * g_array_prepend_vals:
     540                 :            :  * @array: a #GArray
     541                 :            :  * @data: (nullable): a pointer to the elements to prepend to the start of the array
     542                 :            :  * @len: the number of elements to prepend, which may be zero
     543                 :            :  *
     544                 :            :  * Adds @len elements onto the start of the array.
     545                 :            :  *
     546                 :            :  * @data may be %NULL if (and only if) @len is zero. If @len is zero, this
     547                 :            :  * function is a no-op.
     548                 :            :  *
     549                 :            :  * This operation is slower than g_array_append_vals() since the
     550                 :            :  * existing elements in the array have to be moved to make space for
     551                 :            :  * the new elements.
     552                 :            :  *
     553                 :            :  * Returns: the #GArray
     554                 :            :  */
     555                 :            : /**
     556                 :            :  * g_array_prepend_val:
     557                 :            :  * @a: a #GArray
     558                 :            :  * @v: the value to prepend to the #GArray
     559                 :            :  *
     560                 :            :  * Adds the value on to the start of the array. The array will grow in
     561                 :            :  * size automatically if necessary.
     562                 :            :  *
     563                 :            :  * This operation is slower than g_array_append_val() since the
     564                 :            :  * existing elements in the array have to be moved to make space for
     565                 :            :  * the new element.
     566                 :            :  *
     567                 :            :  * g_array_prepend_val() is a macro which uses a reference to the value
     568                 :            :  * parameter @v. This means that you cannot use it with literal values
     569                 :            :  * such as "27". You must use variables.
     570                 :            :  *
     571                 :            :  * Returns: the #GArray
     572                 :            :  */
     573                 :            : GArray*
     574                 :      21240 : g_array_prepend_vals (GArray        *farray,
     575                 :            :                       gconstpointer  data,
     576                 :            :                       guint          len)
     577                 :            : {
     578                 :      21240 :   GRealArray *array = (GRealArray*) farray;
     579                 :            : 
     580                 :      21240 :   g_return_val_if_fail (array, NULL);
     581                 :            : 
     582         [ +  + ]:      21240 :   if (len == 0)
     583                 :         16 :     return farray;
     584                 :            : 
     585                 :      21224 :   g_array_maybe_expand (array, len);
     586                 :            : 
     587                 :      21224 :   memmove (g_array_elt_pos (array, len), g_array_elt_pos (array, 0),
     588                 :      21224 :            g_array_elt_len (array, array->len));
     589                 :            : 
     590                 :      21224 :   memcpy (g_array_elt_pos (array, 0), data, g_array_elt_len (array, len));
     591                 :            : 
     592                 :      21224 :   array->len += len;
     593                 :            : 
     594         [ +  + ]:      21224 :   g_array_zero_terminate (array);
     595                 :            : 
     596                 :      21224 :   return farray;
     597                 :            : }
     598                 :            : 
     599                 :            : /**
     600                 :            :  * g_array_insert_vals:
     601                 :            :  * @array: a #GArray
     602                 :            :  * @index_: the index to place the elements at
     603                 :            :  * @data: (nullable): a pointer to the elements to insert
     604                 :            :  * @len: the number of elements to insert
     605                 :            :  *
     606                 :            :  * Inserts @len elements into a #GArray at the given index.
     607                 :            :  *
     608                 :            :  * If @index_ is greater than the array’s current length, the array is expanded.
     609                 :            :  * The elements between the old end of the array and the newly inserted elements
     610                 :            :  * will be initialised to zero if the array was configured to clear elements;
     611                 :            :  * otherwise their values will be undefined.
     612                 :            :  *
     613                 :            :  * If @index_ is less than the array’s current length, new entries will be
     614                 :            :  * inserted into the array, and the existing entries above @index_ will be moved
     615                 :            :  * upwards.
     616                 :            :  *
     617                 :            :  * @data may be %NULL if (and only if) @len is zero. If @len is zero, this
     618                 :            :  * function is a no-op.
     619                 :            :  *
     620                 :            :  * Returns: the #GArray
     621                 :            :  */
     622                 :            : /**
     623                 :            :  * g_array_insert_val:
     624                 :            :  * @a: a #GArray
     625                 :            :  * @i: the index to place the element at
     626                 :            :  * @v: the value to insert into the array
     627                 :            :  *
     628                 :            :  * Inserts an element into an array at the given index.
     629                 :            :  *
     630                 :            :  * g_array_insert_val() is a macro which uses a reference to the value
     631                 :            :  * parameter @v. This means that you cannot use it with literal values
     632                 :            :  * such as "27". You must use variables.
     633                 :            :  *
     634                 :            :  * Returns: the #GArray
     635                 :            :  */
     636                 :            : GArray*
     637                 :       5436 : g_array_insert_vals (GArray        *farray,
     638                 :            :                      guint          index_,
     639                 :            :                      gconstpointer  data,
     640                 :            :                      guint          len)
     641                 :            : {
     642                 :       5436 :   GRealArray *array = (GRealArray*) farray;
     643                 :            : 
     644                 :       5436 :   g_return_val_if_fail (array, NULL);
     645                 :            : 
     646         [ +  + ]:       5436 :   if (len == 0)
     647                 :         16 :     return farray;
     648                 :            : 
     649                 :            :   /* Is the index off the end of the array, and hence do we need to over-allocate
     650                 :            :    * and clear some elements? */
     651         [ +  + ]:       5420 :   if (index_ >= array->len)
     652                 :            :     {
     653                 :       2678 :       g_array_maybe_expand (array, index_ - array->len + len);
     654                 :       2678 :       return g_array_append_vals (g_array_set_size (farray, index_), data, len);
     655                 :            :     }
     656                 :            : 
     657                 :       2742 :   g_array_maybe_expand (array, len);
     658                 :            : 
     659                 :       2742 :   memmove (g_array_elt_pos (array, len + index_),
     660                 :       2742 :            g_array_elt_pos (array, index_),
     661                 :       2742 :            g_array_elt_len (array, array->len - index_));
     662                 :            : 
     663                 :       2742 :   memcpy (g_array_elt_pos (array, index_), data, g_array_elt_len (array, len));
     664                 :            : 
     665                 :       2742 :   array->len += len;
     666                 :            : 
     667         [ +  + ]:       2742 :   g_array_zero_terminate (array);
     668                 :            : 
     669                 :       2742 :   return farray;
     670                 :            : }
     671                 :            : 
     672                 :            : /**
     673                 :            :  * g_array_set_size:
     674                 :            :  * @array: a #GArray
     675                 :            :  * @length: the new size of the #GArray
     676                 :            :  *
     677                 :            :  * Sets the size of the array, expanding it if necessary. If the array
     678                 :            :  * was created with @clear_ set to %TRUE, the new elements are set to 0.
     679                 :            :  *
     680                 :            :  * Returns: the #GArray
     681                 :            :  */
     682                 :            : GArray*
     683                 :     404588 : g_array_set_size (GArray *farray,
     684                 :            :                   guint   length)
     685                 :            : {
     686                 :     404588 :   GRealArray *array = (GRealArray*) farray;
     687                 :            : 
     688                 :     404588 :   g_return_val_if_fail (array, NULL);
     689                 :            : 
     690         [ +  + ]:     404588 :   if (length > array->len)
     691                 :            :     {
     692                 :     400321 :       g_array_maybe_expand (array, length - array->len);
     693                 :            :       
     694         [ +  + ]:     400320 :       if (array->clear)
     695                 :     400138 :         g_array_elt_zero (array, array->len, length - array->len);
     696                 :            :     }
     697         [ +  + ]:       4267 :   else if (length < array->len)
     698                 :        190 :     g_array_remove_range (farray, length, array->len - length);
     699                 :            :   
     700                 :     404587 :   array->len = length;
     701                 :            :   
     702         [ +  + ]:     404587 :   g_array_zero_terminate (array);
     703                 :            :   
     704                 :     404587 :   return farray;
     705                 :            : }
     706                 :            : 
     707                 :            : /**
     708                 :            :  * g_array_remove_index:
     709                 :            :  * @array: a #GArray
     710                 :            :  * @index_: the index of the element to remove
     711                 :            :  *
     712                 :            :  * Removes the element at the given index from a #GArray. The following
     713                 :            :  * elements are moved down one place.
     714                 :            :  *
     715                 :            :  * Returns: the #GArray
     716                 :            :  */
     717                 :            : GArray*
     718                 :        103 : g_array_remove_index (GArray *farray,
     719                 :            :                       guint   index_)
     720                 :            : {
     721                 :        103 :   GRealArray* array = (GRealArray*) farray;
     722                 :            : 
     723                 :        103 :   g_return_val_if_fail (array, NULL);
     724                 :            : 
     725                 :        103 :   g_return_val_if_fail (index_ < array->len, NULL);
     726                 :            : 
     727         [ +  + ]:        103 :   if (array->clear_func != NULL)
     728                 :          2 :     array->clear_func (g_array_elt_pos (array, index_));
     729                 :            : 
     730         [ +  + ]:        103 :   if (index_ != array->len - 1)
     731                 :         50 :     memmove (g_array_elt_pos (array, index_),
     732                 :         50 :              g_array_elt_pos (array, index_ + 1),
     733                 :         50 :              g_array_elt_len (array, array->len - index_ - 1));
     734                 :            : 
     735                 :        103 :   array->len -= 1;
     736                 :            : 
     737         [ +  + ]:        103 :   if (G_UNLIKELY (g_mem_gc_friendly))
     738                 :         46 :     g_array_elt_zero (array, array->len, 1);
     739                 :            :   else
     740         [ -  + ]:         57 :     g_array_zero_terminate (array);
     741                 :            : 
     742                 :        103 :   return farray;
     743                 :            : }
     744                 :            : 
     745                 :            : /**
     746                 :            :  * g_array_remove_index_fast:
     747                 :            :  * @array: a @GArray
     748                 :            :  * @index_: the index of the element to remove
     749                 :            :  *
     750                 :            :  * Removes the element at the given index from a #GArray. The last
     751                 :            :  * element in the array is used to fill in the space, so this function
     752                 :            :  * does not preserve the order of the #GArray. But it is faster than
     753                 :            :  * g_array_remove_index().
     754                 :            :  *
     755                 :            :  * Returns: the #GArray
     756                 :            :  */
     757                 :            : GArray*
     758                 :         42 : g_array_remove_index_fast (GArray *farray,
     759                 :            :                            guint   index_)
     760                 :            : {
     761                 :         42 :   GRealArray* array = (GRealArray*) farray;
     762                 :            : 
     763                 :         42 :   g_return_val_if_fail (array, NULL);
     764                 :            : 
     765                 :         42 :   g_return_val_if_fail (index_ < array->len, NULL);
     766                 :            : 
     767         [ +  + ]:         42 :   if (array->clear_func != NULL)
     768                 :          2 :     array->clear_func (g_array_elt_pos (array, index_));
     769                 :            : 
     770         [ +  - ]:         42 :   if (index_ != array->len - 1)
     771                 :         42 :     memcpy (g_array_elt_pos (array, index_),
     772                 :         42 :             g_array_elt_pos (array, array->len - 1),
     773                 :         42 :             g_array_elt_len (array, 1));
     774                 :            :   
     775                 :         42 :   array->len -= 1;
     776                 :            : 
     777         [ +  - ]:         42 :   if (G_UNLIKELY (g_mem_gc_friendly))
     778                 :         42 :     g_array_elt_zero (array, array->len, 1);
     779                 :            :   else
     780         [ #  # ]:          0 :     g_array_zero_terminate (array);
     781                 :            : 
     782                 :         42 :   return farray;
     783                 :            : }
     784                 :            : 
     785                 :            : /**
     786                 :            :  * g_array_remove_range:
     787                 :            :  * @array: a @GArray
     788                 :            :  * @index_: the index of the first element to remove
     789                 :            :  * @length: the number of elements to remove
     790                 :            :  *
     791                 :            :  * Removes the given number of elements starting at the given index
     792                 :            :  * from a #GArray.  The following elements are moved to close the gap.
     793                 :            :  *
     794                 :            :  * Returns: the #GArray
     795                 :            :  *
     796                 :            :  * Since: 2.4
     797                 :            :  */
     798                 :            : GArray*
     799                 :        222 : g_array_remove_range (GArray *farray,
     800                 :            :                       guint   index_,
     801                 :            :                       guint   length)
     802                 :            : {
     803                 :        222 :   GRealArray *array = (GRealArray*) farray;
     804                 :            : 
     805                 :        222 :   g_return_val_if_fail (array, NULL);
     806                 :        222 :   g_return_val_if_fail (index_ <= array->len, NULL);
     807                 :        222 :   g_return_val_if_fail (index_ + length <= array->len, NULL);
     808                 :            : 
     809         [ +  + ]:        222 :   if (array->clear_func != NULL)
     810                 :            :     {
     811                 :            :       guint i;
     812                 :            : 
     813         [ +  + ]:          8 :       for (i = 0; i < length; i++)
     814                 :          6 :         array->clear_func (g_array_elt_pos (array, index_ + i));
     815                 :            :     }
     816                 :            : 
     817         [ +  + ]:        222 :   if (index_ + length != array->len)
     818                 :         12 :     memmove (g_array_elt_pos (array, index_),
     819                 :         12 :              g_array_elt_pos (array, index_ + length),
     820                 :         12 :              (array->len - (index_ + length)) * array->elt_size);
     821                 :            : 
     822                 :        222 :   array->len -= length;
     823         [ +  + ]:        222 :   if (G_UNLIKELY (g_mem_gc_friendly))
     824                 :        205 :     g_array_elt_zero (array, array->len, length);
     825                 :            :   else
     826         [ -  + ]:         17 :     g_array_zero_terminate (array);
     827                 :            : 
     828                 :        222 :   return farray;
     829                 :            : }
     830                 :            : 
     831                 :            : /**
     832                 :            :  * g_array_sort:
     833                 :            :  * @array: a #GArray
     834                 :            :  * @compare_func: comparison function
     835                 :            :  *
     836                 :            :  * Sorts a #GArray using @compare_func which should be a qsort()-style
     837                 :            :  * comparison function (returns less than zero for first arg is less
     838                 :            :  * than second arg, zero for equal, greater zero if first arg is
     839                 :            :  * greater than second arg).
     840                 :            :  *
     841                 :            :  * This is guaranteed to be a stable sort since version 2.32.
     842                 :            :  */
     843                 :            : void
     844                 :       1351 : g_array_sort (GArray       *farray,
     845                 :            :               GCompareFunc  compare_func)
     846                 :            : {
     847                 :       1351 :   GRealArray *array = (GRealArray*) farray;
     848                 :            : 
     849                 :       1351 :   g_return_if_fail (array != NULL);
     850                 :            : 
     851                 :            :   /* Don't use qsort as we want a guaranteed stable sort */
     852         [ +  + ]:       1351 :   if (array->len > 0)
     853                 :       1343 :     g_qsort_with_data (array->data,
     854                 :       1343 :                        array->len,
     855                 :       1194 :                        array->elt_size,
     856                 :            :                        (GCompareDataFunc)compare_func,
     857                 :            :                        NULL);
     858                 :            : }
     859                 :            : 
     860                 :            : /**
     861                 :            :  * g_array_sort_with_data:
     862                 :            :  * @array: a #GArray
     863                 :            :  * @compare_func: comparison function
     864                 :            :  * @user_data: data to pass to @compare_func
     865                 :            :  *
     866                 :            :  * Like g_array_sort(), but the comparison function receives an extra
     867                 :            :  * user data argument.
     868                 :            :  *
     869                 :            :  * This is guaranteed to be a stable sort since version 2.32.
     870                 :            :  *
     871                 :            :  * There used to be a comment here about making the sort stable by
     872                 :            :  * using the addresses of the elements in the comparison function.
     873                 :            :  * This did not actually work, so any such code should be removed.
     874                 :            :  */
     875                 :            : void
     876                 :         18 : g_array_sort_with_data (GArray           *farray,
     877                 :            :                         GCompareDataFunc  compare_func,
     878                 :            :                         gpointer          user_data)
     879                 :            : {
     880                 :         18 :   GRealArray *array = (GRealArray*) farray;
     881                 :            : 
     882                 :         18 :   g_return_if_fail (array != NULL);
     883                 :            : 
     884         [ +  + ]:         18 :   if (array->len > 0)
     885                 :         10 :     g_qsort_with_data (array->data,
     886                 :         10 :                        array->len,
     887                 :          5 :                        array->elt_size,
     888                 :            :                        compare_func,
     889                 :            :                        user_data);
     890                 :            : }
     891                 :            : 
     892                 :            : /**
     893                 :            :  * g_array_binary_search:
     894                 :            :  * @array: a #GArray.
     895                 :            :  * @target: a pointer to the item to look up.
     896                 :            :  * @compare_func: A #GCompareFunc used to locate @target.
     897                 :            :  * @out_match_index: (optional) (out): return location
     898                 :            :  *    for the index of the element, if found.
     899                 :            :  *
     900                 :            :  * Checks whether @target exists in @array by performing a binary
     901                 :            :  * search based on the given comparison function @compare_func which
     902                 :            :  * get pointers to items as arguments. If the element is found, %TRUE
     903                 :            :  * is returned and the element’s index is returned in @out_match_index
     904                 :            :  * (if non-%NULL). Otherwise, %FALSE is returned and @out_match_index
     905                 :            :  * is undefined. If @target exists multiple times in @array, the index
     906                 :            :  * of the first instance is returned. This search is using a binary
     907                 :            :  * search, so the @array must absolutely be sorted to return a correct
     908                 :            :  * result (if not, the function may produce false-negative).
     909                 :            :  *
     910                 :            :  * This example defines a comparison function and search an element in a #GArray:
     911                 :            :  * |[<!-- language="C" -->
     912                 :            :  * static gint*
     913                 :            :  * cmpint (gconstpointer a, gconstpointer b)
     914                 :            :  * {
     915                 :            :  *   const gint *_a = a;
     916                 :            :  *   const gint *_b = b;
     917                 :            :  *
     918                 :            :  *   return *_a - *_b;
     919                 :            :  * }
     920                 :            :  * ...
     921                 :            :  * gint i = 424242;
     922                 :            :  * guint matched_index;
     923                 :            :  * gboolean result = g_array_binary_search (garray, &i, cmpint, &matched_index);
     924                 :            :  * ...
     925                 :            :  * ]|
     926                 :            :  *
     927                 :            :  * Returns: %TRUE if @target is one of the elements of @array, %FALSE otherwise.
     928                 :            :  *
     929                 :            :  * Since: 2.62
     930                 :            :  */
     931                 :            : gboolean
     932                 :      40044 : g_array_binary_search (GArray        *array,
     933                 :            :                        gconstpointer  target,
     934                 :            :                        GCompareFunc   compare_func,
     935                 :            :                        guint         *out_match_index)
     936                 :            : {
     937                 :      40044 :   gboolean result = FALSE;
     938                 :      40044 :   GRealArray *_array = (GRealArray *) array;
     939                 :            :   guint left, middle, right;
     940                 :            :   gint val;
     941                 :            : 
     942                 :      40044 :   g_return_val_if_fail (_array != NULL, FALSE);
     943                 :      40042 :   g_return_val_if_fail (compare_func != NULL, FALSE);
     944                 :            : 
     945         [ +  + ]:      40040 :   if (G_LIKELY(_array->len))
     946                 :            :     {
     947                 :      40038 :       left = 0;
     948                 :      40038 :       right = _array->len - 1;
     949                 :            : 
     950         [ +  + ]:     494698 :       while (left <= right)
     951                 :            :         {
     952                 :     494684 :           middle = left + (right - left) / 2;
     953                 :            : 
     954                 :     494684 :           val = compare_func (_array->data + (_array->elt_size * middle), target);
     955         [ +  + ]:     494684 :           if (val == 0)
     956                 :            :             {
     957                 :      40012 :               result = TRUE;
     958                 :      40012 :               break;
     959                 :            :             }
     960         [ +  + ]:     454672 :           else if (val < 0)
     961                 :     236150 :             left = middle + 1;
     962         [ +  + ]:     218522 :           else if (/* val > 0 && */ middle > 0)
     963                 :     218510 :             right = middle - 1;
     964                 :            :           else
     965                 :         12 :             break;  /* element not found */
     966                 :            :         }
     967                 :            :     }
     968                 :            : 
     969   [ +  +  +  + ]:      40040 :   if (result && out_match_index != NULL)
     970                 :      20000 :     *out_match_index = middle;
     971                 :            : 
     972                 :      40040 :   return result;
     973                 :            : }
     974                 :            : 
     975                 :            : static void
     976                 :     903991 : g_array_maybe_expand (GRealArray *array,
     977                 :            :                       guint       len)
     978                 :            : {
     979                 :            :   guint max_len, want_len;
     980                 :            :  
     981                 :            :   /* The maximum array length is derived from following constraints:
     982                 :            :    * - The number of bytes must fit into a gsize / 2.
     983                 :            :    * - The number of elements must fit into guint.
     984                 :            :    * - zero terminated arrays must leave space for the terminating element
     985                 :            :    */
     986                 :     903991 :   max_len = MIN (G_MAXSIZE / 2 / array->elt_size, G_MAXUINT) - array->zero_terminated;
     987                 :            : 
     988                 :            :   /* Detect potential overflow */
     989         [ +  + ]:     903991 :   if G_UNLIKELY ((max_len - array->len) < len)
     990                 :          2 :     g_error ("adding %u to array would overflow", len);
     991                 :            : 
     992                 :     903989 :   want_len = array->len + len + array->zero_terminated;
     993         [ +  + ]:     903989 :   if (want_len > array->elt_capacity)
     994                 :            :     {
     995                 :     407426 :       gsize want_alloc = g_nearest_pow (g_array_elt_len (array, want_len));
     996                 :     407426 :       want_alloc = MAX (want_alloc, MIN_ARRAY_SIZE);
     997                 :            : 
     998                 :     407426 :       array->data = g_realloc (array->data, want_alloc);
     999                 :            : 
    1000         [ +  + ]:     407426 :       if (G_UNLIKELY (g_mem_gc_friendly))
    1001                 :     401463 :         memset (g_array_elt_pos (array, array->elt_capacity), 0,
    1002                 :     401463 :                 g_array_elt_len (array, want_len - array->elt_capacity));
    1003                 :            : 
    1004                 :     407426 :       array->elt_capacity = want_alloc / array->elt_size;
    1005                 :            :     }
    1006                 :     903989 : }
    1007                 :            : 
    1008                 :            : /**
    1009                 :            :  * SECTION:arrays_pointer
    1010                 :            :  * @title: Pointer Arrays
    1011                 :            :  * @short_description: arrays of pointers to any type of data, which
    1012                 :            :  *     grow automatically as new elements are added
    1013                 :            :  *
    1014                 :            :  * Pointer Arrays are similar to Arrays but are used only for storing
    1015                 :            :  * pointers.
    1016                 :            :  *
    1017                 :            :  * If you remove elements from the array, elements at the end of the
    1018                 :            :  * array are moved into the space previously occupied by the removed
    1019                 :            :  * element. This means that you should not rely on the index of particular
    1020                 :            :  * elements remaining the same. You should also be careful when deleting
    1021                 :            :  * elements while iterating over the array.
    1022                 :            :  *
    1023                 :            :  * To create a pointer array, use g_ptr_array_new().
    1024                 :            :  *
    1025                 :            :  * To add elements to a pointer array, use g_ptr_array_add().
    1026                 :            :  *
    1027                 :            :  * To remove elements from a pointer array, use g_ptr_array_remove(),
    1028                 :            :  * g_ptr_array_remove_index() or g_ptr_array_remove_index_fast().
    1029                 :            :  *
    1030                 :            :  * To access an element of a pointer array, use g_ptr_array_index().
    1031                 :            :  *
    1032                 :            :  * To set the size of a pointer array, use g_ptr_array_set_size().
    1033                 :            :  *
    1034                 :            :  * To free a pointer array, use g_ptr_array_free().
    1035                 :            :  *
    1036                 :            :  * An example using a #GPtrArray:
    1037                 :            :  * |[<!-- language="C" -->
    1038                 :            :  *   GPtrArray *array;
    1039                 :            :  *   gchar *string1 = "one";
    1040                 :            :  *   gchar *string2 = "two";
    1041                 :            :  *   gchar *string3 = "three";
    1042                 :            :  *
    1043                 :            :  *   array = g_ptr_array_new ();
    1044                 :            :  *   g_ptr_array_add (array, (gpointer) string1);
    1045                 :            :  *   g_ptr_array_add (array, (gpointer) string2);
    1046                 :            :  *   g_ptr_array_add (array, (gpointer) string3);
    1047                 :            :  *
    1048                 :            :  *   if (g_ptr_array_index (array, 0) != (gpointer) string1)
    1049                 :            :  *     g_print ("ERROR: got %p instead of %p\n",
    1050                 :            :  *              g_ptr_array_index (array, 0), string1);
    1051                 :            :  *
    1052                 :            :  *   g_ptr_array_free (array, TRUE);
    1053                 :            :  * ]|
    1054                 :            :  */
    1055                 :            : 
    1056                 :            : typedef struct _GRealPtrArray  GRealPtrArray;
    1057                 :            : 
    1058                 :            : /**
    1059                 :            :  * GPtrArray:
    1060                 :            :  * @pdata: points to the array of pointers, which may be moved when the
    1061                 :            :  *     array grows
    1062                 :            :  * @len: number of pointers in the array
    1063                 :            :  *
    1064                 :            :  * Contains the public fields of a pointer array.
    1065                 :            :  */
    1066                 :            : struct _GRealPtrArray
    1067                 :            : {
    1068                 :            :   gpointer       *pdata;
    1069                 :            :   guint           len;
    1070                 :            :   guint           alloc;
    1071                 :            :   gatomicrefcount ref_count;
    1072                 :            :   GDestroyNotify  element_free_func;
    1073                 :            : };
    1074                 :            : 
    1075                 :            : /**
    1076                 :            :  * g_ptr_array_index:
    1077                 :            :  * @array: a #GPtrArray
    1078                 :            :  * @index_: the index of the pointer to return
    1079                 :            :  *
    1080                 :            :  * Returns the pointer at the given index of the pointer array.
    1081                 :            :  *
    1082                 :            :  * This does not perform bounds checking on the given @index_,
    1083                 :            :  * so you are responsible for checking it against the array length.
    1084                 :            :  *
    1085                 :            :  * Returns: the pointer at the given index
    1086                 :            :  */
    1087                 :            : 
    1088                 :            : static void g_ptr_array_maybe_expand (GRealPtrArray *array,
    1089                 :            :                                       guint          len);
    1090                 :            : 
    1091                 :            : static GPtrArray *
    1092                 :     106214 : ptr_array_new (guint reserved_size,
    1093                 :            :                GDestroyNotify element_free_func)
    1094                 :            : {
    1095                 :            :   GRealPtrArray *array;
    1096                 :            : 
    1097                 :     106214 :   array = g_slice_new (GRealPtrArray);
    1098                 :            : 
    1099                 :     106209 :   array->pdata = NULL;
    1100                 :     106209 :   array->len = 0;
    1101                 :     106209 :   array->alloc = 0;
    1102                 :     106209 :   array->element_free_func = element_free_func;
    1103                 :            : 
    1104                 :     106209 :   g_atomic_ref_count_init (&array->ref_count);
    1105                 :            : 
    1106         [ +  + ]:     106209 :   if (reserved_size != 0)
    1107                 :        257 :     g_ptr_array_maybe_expand (array, reserved_size);
    1108                 :            : 
    1109                 :     106209 :   return (GPtrArray *) array;
    1110                 :            : }
    1111                 :            : 
    1112                 :            : /**
    1113                 :            :  * g_ptr_array_new:
    1114                 :            :  *
    1115                 :            :  * Creates a new #GPtrArray with a reference count of 1.
    1116                 :            :  *
    1117                 :            :  * Returns: the new #GPtrArray
    1118                 :            :  */
    1119                 :            : GPtrArray*
    1120                 :      96308 : g_ptr_array_new (void)
    1121                 :            : {
    1122                 :      96308 :   return ptr_array_new (0, NULL);
    1123                 :            : }
    1124                 :            : 
    1125                 :            : /**
    1126                 :            :  * g_ptr_array_steal:
    1127                 :            :  * @array: a #GPtrArray.
    1128                 :            :  * @len: (optional) (out): pointer to retrieve the number of
    1129                 :            :  *    elements of the original array
    1130                 :            :  *
    1131                 :            :  * Frees the data in the array and resets the size to zero, while
    1132                 :            :  * the underlying array is preserved for use elsewhere and returned
    1133                 :            :  * to the caller.
    1134                 :            :  *
    1135                 :            :  * Even if set, the #GDestroyNotify function will never be called
    1136                 :            :  * on the current contents of the array and the caller is
    1137                 :            :  * responsible for freeing the array elements.
    1138                 :            :  *
    1139                 :            :  * An example of use:
    1140                 :            :  * |[<!-- language="C" -->
    1141                 :            :  * g_autoptr(GPtrArray) chunk_buffer = g_ptr_array_new_with_free_func (g_bytes_unref);
    1142                 :            :  *
    1143                 :            :  * // Some part of your application appends a number of chunks to the pointer array.
    1144                 :            :  * g_ptr_array_add (chunk_buffer, g_bytes_new_static ("hello", 5));
    1145                 :            :  * g_ptr_array_add (chunk_buffer, g_bytes_new_static ("world", 5));
    1146                 :            :  *
    1147                 :            :  * …
    1148                 :            :  *
    1149                 :            :  * // Periodically, the chunks need to be sent as an array-and-length to some
    1150                 :            :  * // other part of the program.
    1151                 :            :  * GBytes **chunks;
    1152                 :            :  * gsize n_chunks;
    1153                 :            :  *
    1154                 :            :  * chunks = g_ptr_array_steal (chunk_buffer, &n_chunks);
    1155                 :            :  * for (gsize i = 0; i < n_chunks; i++)
    1156                 :            :  *   {
    1157                 :            :  *     // Do something with each chunk here, and then free them, since
    1158                 :            :  *     // g_ptr_array_steal() transfers ownership of all the elements and the
    1159                 :            :  *     // array to the caller.
    1160                 :            :  *     …
    1161                 :            :  *
    1162                 :            :  *     g_bytes_unref (chunks[i]);
    1163                 :            :  *   }
    1164                 :            :  *
    1165                 :            :  * g_free (chunks);
    1166                 :            :  *
    1167                 :            :  * // After calling g_ptr_array_steal(), the pointer array can be reused for the
    1168                 :            :  * // next set of chunks.
    1169                 :            :  * g_assert (chunk_buffer->len == 0);
    1170                 :            :  * ]|
    1171                 :            :  *
    1172                 :            :  * Returns: (transfer full): the element data, which should be
    1173                 :            :  *     freed using g_free().
    1174                 :            :  *
    1175                 :            :  * Since: 2.64
    1176                 :            :  */
    1177                 :            : gpointer *
    1178                 :         78 : g_ptr_array_steal (GPtrArray *array,
    1179                 :            :                    gsize *len)
    1180                 :            : {
    1181                 :            :   GRealPtrArray *rarray;
    1182                 :            :   gpointer *segment;
    1183                 :            : 
    1184                 :         78 :   g_return_val_if_fail (array != NULL, NULL);
    1185                 :            : 
    1186                 :         78 :   rarray = (GRealPtrArray *) array;
    1187                 :         78 :   segment = (gpointer *) rarray->pdata;
    1188                 :            : 
    1189         [ +  + ]:         78 :   if (len != NULL)
    1190                 :          4 :     *len = rarray->len;
    1191                 :            : 
    1192                 :         78 :   rarray->pdata = NULL;
    1193                 :         78 :   rarray->len   = 0;
    1194                 :         78 :   rarray->alloc = 0;
    1195                 :         78 :   return segment;
    1196                 :            : }
    1197                 :            : 
    1198                 :            : /**
    1199                 :            :  * g_ptr_array_copy:
    1200                 :            :  * @array: #GPtrArray to duplicate
    1201                 :            :  * @func: (nullable): a copy function used to copy every element in the array
    1202                 :            :  * @user_data: user data passed to the copy function @func, or %NULL
    1203                 :            :  *
    1204                 :            :  * Makes a full (deep) copy of a #GPtrArray.
    1205                 :            :  *
    1206                 :            :  * @func, as a #GCopyFunc, takes two arguments, the data to be copied
    1207                 :            :  * and a @user_data pointer. On common processor architectures, it's safe to
    1208                 :            :  * pass %NULL as @user_data if the copy function takes only one argument. You
    1209                 :            :  * may get compiler warnings from this though if compiling with GCC’s
    1210                 :            :  * `-Wcast-function-type` warning.
    1211                 :            :  *
    1212                 :            :  * If @func is %NULL, then only the pointers (and not what they are
    1213                 :            :  * pointing to) are copied to the new #GPtrArray.
    1214                 :            :  *
    1215                 :            :  * The copy of @array will have the same #GDestroyNotify for its elements as
    1216                 :            :  * @array.
    1217                 :            :  *
    1218                 :            :  * Returns: (transfer full): a deep copy of the initial #GPtrArray.
    1219                 :            :  *
    1220                 :            :  * Since: 2.62
    1221                 :            :  **/
    1222                 :            : GPtrArray *
    1223                 :          8 : g_ptr_array_copy (GPtrArray *array,
    1224                 :            :                   GCopyFunc  func,
    1225                 :            :                   gpointer   user_data)
    1226                 :            : {
    1227                 :            :   GPtrArray *new_array;
    1228                 :            : 
    1229                 :          8 :   g_return_val_if_fail (array != NULL, NULL);
    1230                 :            : 
    1231                 :          6 :   new_array = ptr_array_new (array->len,
    1232                 :            :                              ((GRealPtrArray *) array)->element_free_func);
    1233                 :            : 
    1234         [ +  + ]:          6 :   if (func != NULL)
    1235                 :            :     {
    1236                 :            :       guint i;
    1237                 :            : 
    1238         [ +  + ]:        202 :       for (i = 0; i < array->len; i++)
    1239                 :        200 :         new_array->pdata[i] = func (array->pdata[i], user_data);
    1240                 :            :     }
    1241         [ +  + ]:          4 :   else if (array->len > 0)
    1242                 :            :     {
    1243                 :          2 :       memcpy (new_array->pdata, array->pdata,
    1244                 :          2 :               array->len * sizeof (*array->pdata));
    1245                 :            :     }
    1246                 :            : 
    1247                 :          6 :   new_array->len = array->len;
    1248                 :            : 
    1249                 :          6 :   return new_array;
    1250                 :            : }
    1251                 :            : 
    1252                 :            : /**
    1253                 :            :  * g_ptr_array_sized_new:
    1254                 :            :  * @reserved_size: number of pointers preallocated
    1255                 :            :  *
    1256                 :            :  * Creates a new #GPtrArray with @reserved_size pointers preallocated
    1257                 :            :  * and a reference count of 1. This avoids frequent reallocation, if
    1258                 :            :  * you are going to add many pointers to the array. Note however that
    1259                 :            :  * the size of the array is still 0.
    1260                 :            :  *
    1261                 :            :  * Returns: the new #GPtrArray
    1262                 :            :  */
    1263                 :            : GPtrArray*
    1264                 :        176 : g_ptr_array_sized_new (guint reserved_size)
    1265                 :            : {
    1266                 :        176 :   return ptr_array_new (reserved_size, NULL);
    1267                 :            : }
    1268                 :            : 
    1269                 :            : /**
    1270                 :            :  * g_array_copy:
    1271                 :            :  * @array: A #GArray.
    1272                 :            :  *
    1273                 :            :  * Create a shallow copy of a #GArray. If the array elements consist of
    1274                 :            :  * pointers to data, the pointers are copied but the actual data is not.
    1275                 :            :  *
    1276                 :            :  * Returns: (transfer container): A copy of @array.
    1277                 :            :  *
    1278                 :            :  * Since: 2.62
    1279                 :            :  **/
    1280                 :            : GArray *
    1281                 :         20 : g_array_copy (GArray *array)
    1282                 :            : {
    1283                 :         20 :   GRealArray *rarray = (GRealArray *) array;
    1284                 :            :   GRealArray *new_rarray;
    1285                 :            : 
    1286                 :         20 :   g_return_val_if_fail (rarray != NULL, NULL);
    1287                 :            : 
    1288                 :            :   new_rarray =
    1289                 :         12 :     (GRealArray *) g_array_sized_new (rarray->zero_terminated, rarray->clear,
    1290                 :            :                                       rarray->elt_size, rarray->elt_capacity);
    1291                 :         12 :   new_rarray->len = rarray->len;
    1292         [ +  + ]:         12 :   if (rarray->len > 0)
    1293                 :         10 :     memcpy (new_rarray->data, rarray->data, rarray->len * rarray->elt_size);
    1294                 :            : 
    1295         [ +  + ]:         12 :   g_array_zero_terminate (new_rarray);
    1296                 :            : 
    1297                 :         12 :   return (GArray *) new_rarray;
    1298                 :            : }
    1299                 :            : 
    1300                 :            : /**
    1301                 :            :  * g_ptr_array_new_with_free_func:
    1302                 :            :  * @element_free_func: (nullable): A function to free elements with
    1303                 :            :  *     destroy @array or %NULL
    1304                 :            :  *
    1305                 :            :  * Creates a new #GPtrArray with a reference count of 1 and use
    1306                 :            :  * @element_free_func for freeing each element when the array is destroyed
    1307                 :            :  * either via g_ptr_array_unref(), when g_ptr_array_free() is called with
    1308                 :            :  * @free_segment set to %TRUE or when removing elements.
    1309                 :            :  *
    1310                 :            :  * Returns: A new #GPtrArray
    1311                 :            :  *
    1312                 :            :  * Since: 2.22
    1313                 :            :  */
    1314                 :            : GPtrArray*
    1315                 :       8593 : g_ptr_array_new_with_free_func (GDestroyNotify element_free_func)
    1316                 :            : {
    1317                 :       8593 :   return ptr_array_new (0, element_free_func);
    1318                 :            : }
    1319                 :            : 
    1320                 :            : /**
    1321                 :            :  * g_ptr_array_new_full:
    1322                 :            :  * @reserved_size: number of pointers preallocated
    1323                 :            :  * @element_free_func: (nullable): A function to free elements with
    1324                 :            :  *     destroy @array or %NULL
    1325                 :            :  *
    1326                 :            :  * Creates a new #GPtrArray with @reserved_size pointers preallocated
    1327                 :            :  * and a reference count of 1. This avoids frequent reallocation, if
    1328                 :            :  * you are going to add many pointers to the array. Note however that
    1329                 :            :  * the size of the array is still 0. It also set @element_free_func
    1330                 :            :  * for freeing each element when the array is destroyed either via
    1331                 :            :  * g_ptr_array_unref(), when g_ptr_array_free() is called with
    1332                 :            :  * @free_segment set to %TRUE or when removing elements.
    1333                 :            :  *
    1334                 :            :  * Returns: A new #GPtrArray
    1335                 :            :  *
    1336                 :            :  * Since: 2.30
    1337                 :            :  */
    1338                 :            : GPtrArray*
    1339                 :       1131 : g_ptr_array_new_full (guint          reserved_size,
    1340                 :            :                       GDestroyNotify element_free_func)
    1341                 :            : {
    1342                 :       1131 :   return ptr_array_new (reserved_size, element_free_func);
    1343                 :            : }
    1344                 :            : 
    1345                 :            : /**
    1346                 :            :  * g_ptr_array_set_free_func:
    1347                 :            :  * @array: A #GPtrArray
    1348                 :            :  * @element_free_func: (nullable): A function to free elements with
    1349                 :            :  *     destroy @array or %NULL
    1350                 :            :  *
    1351                 :            :  * Sets a function for freeing each element when @array is destroyed
    1352                 :            :  * either via g_ptr_array_unref(), when g_ptr_array_free() is called
    1353                 :            :  * with @free_segment set to %TRUE or when removing elements.
    1354                 :            :  *
    1355                 :            :  * Since: 2.22
    1356                 :            :  */
    1357                 :            : void
    1358                 :          4 : g_ptr_array_set_free_func (GPtrArray      *array,
    1359                 :            :                            GDestroyNotify  element_free_func)
    1360                 :            : {
    1361                 :          4 :   GRealPtrArray *rarray = (GRealPtrArray *)array;
    1362                 :            : 
    1363                 :          4 :   g_return_if_fail (array);
    1364                 :            : 
    1365                 :          4 :   rarray->element_free_func = element_free_func;
    1366                 :            : }
    1367                 :            : 
    1368                 :            : /**
    1369                 :            :  * g_ptr_array_ref:
    1370                 :            :  * @array: a #GPtrArray
    1371                 :            :  *
    1372                 :            :  * Atomically increments the reference count of @array by one.
    1373                 :            :  * This function is thread-safe and may be called from any thread.
    1374                 :            :  *
    1375                 :            :  * Returns: The passed in #GPtrArray
    1376                 :            :  *
    1377                 :            :  * Since: 2.22
    1378                 :            :  */
    1379                 :            : GPtrArray*
    1380                 :         18 : g_ptr_array_ref (GPtrArray *array)
    1381                 :            : {
    1382                 :         18 :   GRealPtrArray *rarray = (GRealPtrArray *)array;
    1383                 :            : 
    1384                 :         18 :   g_return_val_if_fail (array, NULL);
    1385                 :            : 
    1386                 :         18 :   g_atomic_ref_count_inc (&rarray->ref_count);
    1387                 :            : 
    1388                 :         18 :   return array;
    1389                 :            : }
    1390                 :            : 
    1391                 :            : static gpointer *ptr_array_free (GPtrArray *, ArrayFreeFlags);
    1392                 :            : 
    1393                 :            : /**
    1394                 :            :  * g_ptr_array_unref:
    1395                 :            :  * @array: A #GPtrArray
    1396                 :            :  *
    1397                 :            :  * Atomically decrements the reference count of @array by one. If the
    1398                 :            :  * reference count drops to 0, the effect is the same as calling
    1399                 :            :  * g_ptr_array_free() with @free_segment set to %TRUE. This function
    1400                 :            :  * is thread-safe and may be called from any thread.
    1401                 :            :  *
    1402                 :            :  * Since: 2.22
    1403                 :            :  */
    1404                 :            : void
    1405                 :       5865 : g_ptr_array_unref (GPtrArray *array)
    1406                 :            : {
    1407                 :       5865 :   GRealPtrArray *rarray = (GRealPtrArray *)array;
    1408                 :            : 
    1409                 :       5865 :   g_return_if_fail (array);
    1410                 :            : 
    1411         [ +  + ]:       5865 :   if (g_atomic_ref_count_dec (&rarray->ref_count))
    1412                 :       5851 :     ptr_array_free (array, FREE_SEGMENT);
    1413                 :            : }
    1414                 :            : 
    1415                 :            : /**
    1416                 :            :  * g_ptr_array_free:
    1417                 :            :  * @array: a #GPtrArray
    1418                 :            :  * @free_seg: if %TRUE the actual pointer array is freed as well
    1419                 :            :  *
    1420                 :            :  * Frees the memory allocated for the #GPtrArray. If @free_seg is %TRUE
    1421                 :            :  * it frees the memory block holding the elements as well. Pass %FALSE
    1422                 :            :  * if you want to free the #GPtrArray wrapper but preserve the
    1423                 :            :  * underlying array for use elsewhere. If the reference count of @array
    1424                 :            :  * is greater than one, the #GPtrArray wrapper is preserved but the
    1425                 :            :  * size of @array will be set to zero.
    1426                 :            :  *
    1427                 :            :  * If array contents point to dynamically-allocated memory, they should
    1428                 :            :  * be freed separately if @free_seg is %TRUE and no #GDestroyNotify
    1429                 :            :  * function has been set for @array.
    1430                 :            :  *
    1431                 :            :  * This function is not thread-safe. If using a #GPtrArray from multiple
    1432                 :            :  * threads, use only the atomic g_ptr_array_ref() and g_ptr_array_unref()
    1433                 :            :  * functions.
    1434                 :            :  *
    1435                 :            :  * Returns: (transfer full) (nullable): the pointer array if @free_seg is
    1436                 :            :  *     %FALSE, otherwise %NULL. The pointer array should be freed using g_free().
    1437                 :            :  */
    1438                 :            : gpointer*
    1439                 :      91378 : g_ptr_array_free (GPtrArray *array,
    1440                 :            :                   gboolean   free_segment)
    1441                 :            : {
    1442                 :      91378 :   GRealPtrArray *rarray = (GRealPtrArray *)array;
    1443                 :            :   ArrayFreeFlags flags;
    1444                 :            : 
    1445                 :      91378 :   g_return_val_if_fail (rarray, NULL);
    1446                 :            : 
    1447                 :      91378 :   flags = (free_segment ? FREE_SEGMENT : 0);
    1448                 :            : 
    1449                 :            :   /* if others are holding a reference, preserve the wrapper but
    1450                 :            :    * do free/return the data
    1451                 :            :    */
    1452         [ +  + ]:      91378 :   if (!g_atomic_ref_count_dec (&rarray->ref_count))
    1453                 :          4 :     flags |= PRESERVE_WRAPPER;
    1454                 :            : 
    1455                 :      91377 :   return ptr_array_free (array, flags);
    1456                 :            : }
    1457                 :            : 
    1458                 :            : static gpointer *
    1459                 :      97228 : ptr_array_free (GPtrArray      *array,
    1460                 :            :                 ArrayFreeFlags  flags)
    1461                 :            : {
    1462                 :      97228 :   GRealPtrArray *rarray = (GRealPtrArray *)array;
    1463                 :            :   gpointer *segment;
    1464                 :            : 
    1465         [ +  + ]:      97228 :   if (flags & FREE_SEGMENT)
    1466                 :            :     {
    1467                 :            :       /* Data here is stolen and freed manually. It is an
    1468                 :            :        * error to attempt to access the array data (including
    1469                 :            :        * mutating the array bounds) during destruction).
    1470                 :            :        *
    1471                 :            :        * https://bugzilla.gnome.org/show_bug.cgi?id=769064
    1472                 :            :        */
    1473                 :      17825 :       gpointer *stolen_pdata = g_steal_pointer (&rarray->pdata);
    1474         [ +  + ]:      17825 :       if (rarray->element_free_func != NULL)
    1475                 :            :         {
    1476                 :            :           guint i;
    1477                 :            : 
    1478         [ +  + ]:     204927 :           for (i = 0; i < rarray->len; ++i)
    1479                 :     203170 :             rarray->element_free_func (stolen_pdata[i]);
    1480                 :            :         }
    1481                 :            : 
    1482                 :      17825 :       g_free (stolen_pdata);
    1483                 :      17825 :       segment = NULL;
    1484                 :            :     }
    1485                 :            :   else
    1486                 :      79403 :     segment = rarray->pdata;
    1487                 :            : 
    1488         [ +  + ]:      97228 :   if (flags & PRESERVE_WRAPPER)
    1489                 :            :     {
    1490                 :          4 :       rarray->pdata = NULL;
    1491                 :          4 :       rarray->len = 0;
    1492                 :          4 :       rarray->alloc = 0;
    1493                 :            :     }
    1494                 :            :   else
    1495                 :            :     {
    1496                 :      97224 :       g_slice_free1 (sizeof (GRealPtrArray), rarray);
    1497                 :            :     }
    1498                 :            : 
    1499                 :      97228 :   return segment;
    1500                 :            : }
    1501                 :            : 
    1502                 :            : static void
    1503                 :    1807855 : g_ptr_array_maybe_expand (GRealPtrArray *array,
    1504                 :            :                           guint          len)
    1505                 :            : {
    1506                 :            :   guint max_len;
    1507                 :            : 
    1508                 :            :   /* The maximum array length is derived from following constraints:
    1509                 :            :    * - The number of bytes must fit into a gsize / 2.
    1510                 :            :    * - The number of elements must fit into guint.
    1511                 :            :    */
    1512                 :    1807855 :   max_len = MIN (G_MAXSIZE / 2 / sizeof (gpointer), G_MAXUINT);
    1513                 :            : 
    1514                 :            :   /* Detect potential overflow */
    1515         [ -  + ]:    1807855 :   if G_UNLIKELY ((max_len - array->len) < len)
    1516                 :          0 :     g_error ("adding %u to array would overflow", len);
    1517                 :            : 
    1518         [ +  + ]:    1807855 :   if ((array->len + len) > array->alloc)
    1519                 :            :     {
    1520                 :      96851 :       guint old_alloc = array->alloc;
    1521                 :      96851 :       array->alloc = g_nearest_pow (array->len + len);
    1522                 :      96851 :       array->alloc = MAX (array->alloc, MIN_ARRAY_SIZE);
    1523                 :      96851 :       array->pdata = g_realloc (array->pdata, sizeof (gpointer) * array->alloc);
    1524         [ +  + ]:      96851 :       if (G_UNLIKELY (g_mem_gc_friendly))
    1525         [ +  + ]:    1034848 :         for ( ; old_alloc < array->alloc; old_alloc++)
    1526                 :     989456 :           array->pdata [old_alloc] = NULL;
    1527                 :            :     }
    1528                 :    1807855 : }
    1529                 :            : 
    1530                 :            : /**
    1531                 :            :  * g_ptr_array_set_size:
    1532                 :            :  * @array: a #GPtrArray
    1533                 :            :  * @length: the new length of the pointer array
    1534                 :            :  *
    1535                 :            :  * Sets the size of the array. When making the array larger,
    1536                 :            :  * newly-added elements will be set to %NULL. When making it smaller,
    1537                 :            :  * if @array has a non-%NULL #GDestroyNotify function then it will be
    1538                 :            :  * called for the removed elements.
    1539                 :            :  */
    1540                 :            : void
    1541                 :    2134783 : g_ptr_array_set_size  (GPtrArray *array,
    1542                 :            :                        gint       length)
    1543                 :            : {
    1544                 :    2134783 :   GRealPtrArray *rarray = (GRealPtrArray *)array;
    1545                 :            :   guint length_unsigned;
    1546                 :            : 
    1547                 :    2134783 :   g_return_if_fail (rarray);
    1548                 :    2134783 :   g_return_if_fail (rarray->len == 0 || (rarray->len != 0 && rarray->pdata != NULL));
    1549                 :    2134781 :   g_return_if_fail (length >= 0);
    1550                 :            : 
    1551                 :    2134781 :   length_unsigned = (guint) length;
    1552                 :            : 
    1553         [ +  + ]:    2134781 :   if (length_unsigned > rarray->len)
    1554                 :            :     {
    1555                 :            :       guint i;
    1556                 :          2 :       g_ptr_array_maybe_expand (rarray, (length_unsigned - rarray->len));
    1557                 :            :       /* This is not 
    1558                 :            :        *     memset (array->pdata + array->len, 0,
    1559                 :            :        *            sizeof (gpointer) * (length_unsigned - array->len));
    1560                 :            :        * to make it really portable. Remember (void*)NULL needn't be
    1561                 :            :        * bitwise zero. It of course is silly not to use memset (..,0,..).
    1562                 :            :        */
    1563         [ +  + ]:         36 :       for (i = rarray->len; i < length_unsigned; i++)
    1564                 :         34 :         rarray->pdata[i] = NULL;
    1565                 :            :     }
    1566         [ +  + ]:    2134779 :   else if (length_unsigned < rarray->len)
    1567                 :     935461 :     g_ptr_array_remove_range (array, length_unsigned, rarray->len - length_unsigned);
    1568                 :            : 
    1569                 :    2134741 :   rarray->len = length_unsigned;
    1570                 :            : }
    1571                 :            : 
    1572                 :            : static gpointer
    1573                 :       3063 : ptr_array_remove_index (GPtrArray *array,
    1574                 :            :                         guint      index_,
    1575                 :            :                         gboolean   fast,
    1576                 :            :                         gboolean   free_element)
    1577                 :            : {
    1578                 :       3063 :   GRealPtrArray *rarray = (GRealPtrArray *) array;
    1579                 :            :   gpointer result;
    1580                 :            : 
    1581                 :       3063 :   g_return_val_if_fail (rarray, NULL);
    1582                 :       3063 :   g_return_val_if_fail (rarray->len == 0 || (rarray->len != 0 && rarray->pdata != NULL), NULL);
    1583                 :            : 
    1584                 :       3063 :   g_return_val_if_fail (index_ < rarray->len, NULL);
    1585                 :            : 
    1586                 :       3063 :   result = rarray->pdata[index_];
    1587                 :            : 
    1588   [ +  +  +  + ]:       3063 :   if (rarray->element_free_func != NULL && free_element)
    1589                 :        735 :     rarray->element_free_func (rarray->pdata[index_]);
    1590                 :            : 
    1591   [ +  +  +  + ]:       3063 :   if (index_ != rarray->len - 1 && !fast)
    1592                 :         69 :     memmove (rarray->pdata + index_, rarray->pdata + index_ + 1,
    1593                 :         69 :              sizeof (gpointer) * (rarray->len - index_ - 1));
    1594         [ +  + ]:       2994 :   else if (index_ != rarray->len - 1)
    1595                 :       1620 :     rarray->pdata[index_] = rarray->pdata[rarray->len - 1];
    1596                 :            : 
    1597                 :       3063 :   rarray->len -= 1;
    1598                 :            : 
    1599         [ +  + ]:       3063 :   if (G_UNLIKELY (g_mem_gc_friendly))
    1600                 :       2046 :     rarray->pdata[rarray->len] = NULL;
    1601                 :            : 
    1602                 :       3063 :   return result;
    1603                 :            : }
    1604                 :            : 
    1605                 :            : /**
    1606                 :            :  * g_ptr_array_remove_index:
    1607                 :            :  * @array: a #GPtrArray
    1608                 :            :  * @index_: the index of the pointer to remove
    1609                 :            :  *
    1610                 :            :  * Removes the pointer at the given index from the pointer array.
    1611                 :            :  * The following elements are moved down one place. If @array has
    1612                 :            :  * a non-%NULL #GDestroyNotify function it is called for the removed
    1613                 :            :  * element. If so, the return value from this function will potentially point
    1614                 :            :  * to freed memory (depending on the #GDestroyNotify implementation).
    1615                 :            :  *
    1616                 :            :  * Returns: (nullable): the pointer which was removed
    1617                 :            :  */
    1618                 :            : gpointer
    1619                 :        311 : g_ptr_array_remove_index (GPtrArray *array,
    1620                 :            :                           guint      index_)
    1621                 :            : {
    1622                 :        311 :   return ptr_array_remove_index (array, index_, FALSE, TRUE);
    1623                 :            : }
    1624                 :            : 
    1625                 :            : /**
    1626                 :            :  * g_ptr_array_remove_index_fast:
    1627                 :            :  * @array: a #GPtrArray
    1628                 :            :  * @index_: the index of the pointer to remove
    1629                 :            :  *
    1630                 :            :  * Removes the pointer at the given index from the pointer array.
    1631                 :            :  * The last element in the array is used to fill in the space, so
    1632                 :            :  * this function does not preserve the order of the array. But it
    1633                 :            :  * is faster than g_ptr_array_remove_index(). If @array has a non-%NULL
    1634                 :            :  * #GDestroyNotify function it is called for the removed element. If so, the
    1635                 :            :  * return value from this function will potentially point to freed memory
    1636                 :            :  * (depending on the #GDestroyNotify implementation).
    1637                 :            :  *
    1638                 :            :  * Returns: (nullable): the pointer which was removed
    1639                 :            :  */
    1640                 :            : gpointer
    1641                 :       2748 : g_ptr_array_remove_index_fast (GPtrArray *array,
    1642                 :            :                                guint      index_)
    1643                 :            : {
    1644                 :       2748 :   return ptr_array_remove_index (array, index_, TRUE, TRUE);
    1645                 :            : }
    1646                 :            : 
    1647                 :            : /**
    1648                 :            :  * g_ptr_array_steal_index:
    1649                 :            :  * @array: a #GPtrArray
    1650                 :            :  * @index_: the index of the pointer to steal
    1651                 :            :  *
    1652                 :            :  * Removes the pointer at the given index from the pointer array.
    1653                 :            :  * The following elements are moved down one place. The #GDestroyNotify for
    1654                 :            :  * @array is *not* called on the removed element; ownership is transferred to
    1655                 :            :  * the caller of this function.
    1656                 :            :  *
    1657                 :            :  * Returns: (transfer full) (nullable): the pointer which was removed
    1658                 :            :  * Since: 2.58
    1659                 :            :  */
    1660                 :            : gpointer
    1661                 :          2 : g_ptr_array_steal_index (GPtrArray *array,
    1662                 :            :                          guint      index_)
    1663                 :            : {
    1664                 :          2 :   return ptr_array_remove_index (array, index_, FALSE, FALSE);
    1665                 :            : }
    1666                 :            : 
    1667                 :            : /**
    1668                 :            :  * g_ptr_array_steal_index_fast:
    1669                 :            :  * @array: a #GPtrArray
    1670                 :            :  * @index_: the index of the pointer to steal
    1671                 :            :  *
    1672                 :            :  * Removes the pointer at the given index from the pointer array.
    1673                 :            :  * The last element in the array is used to fill in the space, so
    1674                 :            :  * this function does not preserve the order of the array. But it
    1675                 :            :  * is faster than g_ptr_array_steal_index(). The #GDestroyNotify for @array is
    1676                 :            :  * *not* called on the removed element; ownership is transferred to the caller
    1677                 :            :  * of this function.
    1678                 :            :  *
    1679                 :            :  * Returns: (transfer full) (nullable): the pointer which was removed
    1680                 :            :  * Since: 2.58
    1681                 :            :  */
    1682                 :            : gpointer
    1683                 :          2 : g_ptr_array_steal_index_fast (GPtrArray *array,
    1684                 :            :                               guint      index_)
    1685                 :            : {
    1686                 :          2 :   return ptr_array_remove_index (array, index_, TRUE, FALSE);
    1687                 :            : }
    1688                 :            : 
    1689                 :            : /**
    1690                 :            :  * g_ptr_array_remove_range:
    1691                 :            :  * @array: a @GPtrArray
    1692                 :            :  * @index_: the index of the first pointer to remove
    1693                 :            :  * @length: the number of pointers to remove
    1694                 :            :  *
    1695                 :            :  * Removes the given number of pointers starting at the given index
    1696                 :            :  * from a #GPtrArray. The following elements are moved to close the
    1697                 :            :  * gap. If @array has a non-%NULL #GDestroyNotify function it is
    1698                 :            :  * called for the removed elements.
    1699                 :            :  *
    1700                 :            :  * Returns: the @array
    1701                 :            :  *
    1702                 :            :  * Since: 2.4
    1703                 :            :  */
    1704                 :            : GPtrArray*
    1705                 :     935469 : g_ptr_array_remove_range (GPtrArray *array,
    1706                 :            :                           guint      index_,
    1707                 :            :                           guint      length)
    1708                 :            : {
    1709                 :     935469 :   GRealPtrArray *rarray = (GRealPtrArray *)array;
    1710                 :            :   guint i;
    1711                 :            : 
    1712                 :     935469 :   g_return_val_if_fail (rarray != NULL, NULL);
    1713                 :     935469 :   g_return_val_if_fail (rarray->len == 0 || (rarray->len != 0 && rarray->pdata != NULL), NULL);
    1714                 :     935469 :   g_return_val_if_fail (index_ <= rarray->len, NULL);
    1715                 :     935469 :   g_return_val_if_fail (index_ + length <= rarray->len, NULL);
    1716                 :            : 
    1717         [ +  + ]:     935469 :   if (rarray->element_free_func != NULL)
    1718                 :            :     {
    1719         [ +  + ]:        159 :       for (i = index_; i < index_ + length; i++)
    1720                 :        130 :         rarray->element_free_func (rarray->pdata[i]);
    1721                 :            :     }
    1722                 :            : 
    1723         [ +  + ]:     935469 :   if (index_ + length != rarray->len)
    1724                 :            :     {
    1725                 :          6 :       memmove (&rarray->pdata[index_],
    1726                 :          6 :                &rarray->pdata[index_ + length],
    1727                 :          6 :                (rarray->len - (index_ + length)) * sizeof (gpointer));
    1728                 :            :     }
    1729                 :            : 
    1730                 :     935469 :   rarray->len -= length;
    1731         [ +  + ]:     935469 :   if (G_UNLIKELY (g_mem_gc_friendly))
    1732                 :            :     {
    1733         [ +  + ]:    1071600 :       for (i = 0; i < length; i++)
    1734                 :     563884 :         rarray->pdata[rarray->len + i] = NULL;
    1735                 :            :     }
    1736                 :            : 
    1737                 :     935469 :   return array;
    1738                 :            : }
    1739                 :            : 
    1740                 :            : /**
    1741                 :            :  * g_ptr_array_remove:
    1742                 :            :  * @array: a #GPtrArray
    1743                 :            :  * @data: the pointer to remove
    1744                 :            :  *
    1745                 :            :  * Removes the first occurrence of the given pointer from the pointer
    1746                 :            :  * array. The following elements are moved down one place. If @array
    1747                 :            :  * has a non-%NULL #GDestroyNotify function it is called for the
    1748                 :            :  * removed element.
    1749                 :            :  *
    1750                 :            :  * It returns %TRUE if the pointer was removed, or %FALSE if the
    1751                 :            :  * pointer was not found.
    1752                 :            :  *
    1753                 :            :  * Returns: %TRUE if the pointer is removed, %FALSE if the pointer
    1754                 :            :  *     is not found in the array
    1755                 :            :  */
    1756                 :            : gboolean
    1757                 :        298 : g_ptr_array_remove (GPtrArray *array,
    1758                 :            :                     gpointer   data)
    1759                 :            : {
    1760                 :            :   guint i;
    1761                 :            : 
    1762                 :        298 :   g_return_val_if_fail (array, FALSE);
    1763                 :        298 :   g_return_val_if_fail (array->len == 0 || (array->len != 0 && array->pdata != NULL), FALSE);
    1764                 :            : 
    1765         [ +  + ]:        400 :   for (i = 0; i < array->len; i += 1)
    1766                 :            :     {
    1767         [ +  + ]:        398 :       if (array->pdata[i] == data)
    1768                 :            :         {
    1769                 :        296 :           g_ptr_array_remove_index (array, i);
    1770                 :        296 :           return TRUE;
    1771                 :            :         }
    1772                 :            :     }
    1773                 :            : 
    1774                 :          2 :   return FALSE;
    1775                 :            : }
    1776                 :            : 
    1777                 :            : /**
    1778                 :            :  * g_ptr_array_remove_fast:
    1779                 :            :  * @array: a #GPtrArray
    1780                 :            :  * @data: the pointer to remove
    1781                 :            :  *
    1782                 :            :  * Removes the first occurrence of the given pointer from the pointer
    1783                 :            :  * array. The last element in the array is used to fill in the space,
    1784                 :            :  * so this function does not preserve the order of the array. But it
    1785                 :            :  * is faster than g_ptr_array_remove(). If @array has a non-%NULL
    1786                 :            :  * #GDestroyNotify function it is called for the removed element.
    1787                 :            :  *
    1788                 :            :  * It returns %TRUE if the pointer was removed, or %FALSE if the
    1789                 :            :  * pointer was not found.
    1790                 :            :  *
    1791                 :            :  * Returns: %TRUE if the pointer was found in the array
    1792                 :            :  */
    1793                 :            : gboolean
    1794                 :       2019 : g_ptr_array_remove_fast (GPtrArray *array,
    1795                 :            :                          gpointer   data)
    1796                 :            : {
    1797                 :       2019 :   GRealPtrArray *rarray = (GRealPtrArray *)array;
    1798                 :            :   guint i;
    1799                 :            : 
    1800                 :       2019 :   g_return_val_if_fail (rarray, FALSE);
    1801                 :       2019 :   g_return_val_if_fail (rarray->len == 0 || (rarray->len != 0 && rarray->pdata != NULL), FALSE);
    1802                 :            : 
    1803         [ +  + ]:       3741 :   for (i = 0; i < rarray->len; i += 1)
    1804                 :            :     {
    1805         [ +  + ]:       3739 :       if (rarray->pdata[i] == data)
    1806                 :            :         {
    1807                 :       2017 :           g_ptr_array_remove_index_fast (array, i);
    1808                 :       2017 :           return TRUE;
    1809                 :            :         }
    1810                 :            :     }
    1811                 :            : 
    1812                 :          2 :   return FALSE;
    1813                 :            : }
    1814                 :            : 
    1815                 :            : /**
    1816                 :            :  * g_ptr_array_add:
    1817                 :            :  * @array: a #GPtrArray
    1818                 :            :  * @data: the pointer to add
    1819                 :            :  *
    1820                 :            :  * Adds a pointer to the end of the pointer array. The array will grow
    1821                 :            :  * in size automatically if necessary.
    1822                 :            :  */
    1823                 :            : void
    1824                 :    1779983 : g_ptr_array_add (GPtrArray *array,
    1825                 :            :                  gpointer   data)
    1826                 :            : {
    1827                 :    1779983 :   GRealPtrArray *rarray = (GRealPtrArray *)array;
    1828                 :            : 
    1829                 :    1779983 :   g_return_if_fail (rarray);
    1830                 :    1779983 :   g_return_if_fail (rarray->len == 0 || (rarray->len != 0 && rarray->pdata != NULL));
    1831                 :            : 
    1832                 :    1779983 :   g_ptr_array_maybe_expand (rarray, 1);
    1833                 :            : 
    1834                 :    1779980 :   rarray->pdata[rarray->len++] = data;
    1835                 :            : }
    1836                 :            : 
    1837                 :            : /**
    1838                 :            :  * g_ptr_array_extend:
    1839                 :            :  * @array_to_extend: a #GPtrArray.
    1840                 :            :  * @array: (transfer none): a #GPtrArray to add to the end of @array_to_extend.
    1841                 :            :  * @func: (nullable): a copy function used to copy every element in the array
    1842                 :            :  * @user_data: user data passed to the copy function @func, or %NULL
    1843                 :            :  *
    1844                 :            :  * Adds all pointers of @array to the end of the array @array_to_extend.
    1845                 :            :  * The array will grow in size automatically if needed. @array_to_extend is
    1846                 :            :  * modified in-place.
    1847                 :            :  *
    1848                 :            :  * @func, as a #GCopyFunc, takes two arguments, the data to be copied
    1849                 :            :  * and a @user_data pointer. On common processor architectures, it's safe to
    1850                 :            :  * pass %NULL as @user_data if the copy function takes only one argument. You
    1851                 :            :  * may get compiler warnings from this though if compiling with GCC’s
    1852                 :            :  * `-Wcast-function-type` warning.
    1853                 :            :  *
    1854                 :            :  * If @func is %NULL, then only the pointers (and not what they are
    1855                 :            :  * pointing to) are copied to the new #GPtrArray.
    1856                 :            :  *
    1857                 :            :  * Since: 2.62
    1858                 :            :  **/
    1859                 :            : void
    1860                 :         18 : g_ptr_array_extend (GPtrArray  *array_to_extend,
    1861                 :            :                     GPtrArray  *array,
    1862                 :            :                     GCopyFunc   func,
    1863                 :            :                     gpointer    user_data)
    1864                 :            : {
    1865                 :         18 :   GRealPtrArray *rarray_to_extend = (GRealPtrArray *) array_to_extend;
    1866                 :            : 
    1867                 :         18 :   g_return_if_fail (array_to_extend != NULL);
    1868                 :         16 :   g_return_if_fail (array != NULL);
    1869                 :            : 
    1870                 :         14 :   g_ptr_array_maybe_expand (rarray_to_extend, array->len);
    1871                 :            : 
    1872         [ +  + ]:         14 :   if (func != NULL)
    1873                 :            :     {
    1874                 :            :       guint i;
    1875                 :            : 
    1876         [ +  + ]:        102 :       for (i = 0; i < array->len; i++)
    1877                 :        100 :         rarray_to_extend->pdata[i + rarray_to_extend->len] =
    1878                 :        100 :           func (array->pdata[i], user_data);
    1879                 :            :     }
    1880         [ +  + ]:         12 :   else if (array->len > 0)
    1881                 :            :     {
    1882                 :          8 :       memcpy (rarray_to_extend->pdata + rarray_to_extend->len, array->pdata,
    1883                 :          8 :               array->len * sizeof (*array->pdata));
    1884                 :            :     }
    1885                 :            : 
    1886                 :         14 :   rarray_to_extend->len += array->len;
    1887                 :            : }
    1888                 :            : 
    1889                 :            : /**
    1890                 :            :  * g_ptr_array_extend_and_steal:
    1891                 :            :  * @array_to_extend: (transfer none): a #GPtrArray.
    1892                 :            :  * @array: (transfer container): a #GPtrArray to add to the end of
    1893                 :            :  *     @array_to_extend.
    1894                 :            :  *
    1895                 :            :  * Adds all the pointers in @array to the end of @array_to_extend, transferring
    1896                 :            :  * ownership of each element from @array to @array_to_extend and modifying
    1897                 :            :  * @array_to_extend in-place. @array is then freed.
    1898                 :            :  *
    1899                 :            :  * As with g_ptr_array_free(), @array will be destroyed if its reference count
    1900                 :            :  * is 1. If its reference count is higher, it will be decremented and the
    1901                 :            :  * length of @array set to zero.
    1902                 :            :  *
    1903                 :            :  * Since: 2.62
    1904                 :            :  **/
    1905                 :            : void
    1906                 :          4 : g_ptr_array_extend_and_steal (GPtrArray  *array_to_extend,
    1907                 :            :                               GPtrArray  *array)
    1908                 :            : {
    1909                 :            :   gpointer *pdata;
    1910                 :            : 
    1911                 :          4 :   g_ptr_array_extend (array_to_extend, array, NULL, NULL);
    1912                 :            : 
    1913                 :            :   /* Get rid of @array without triggering the GDestroyNotify attached
    1914                 :            :    * to the elements moved from @array to @array_to_extend. */
    1915                 :          4 :   pdata = g_steal_pointer (&array->pdata);
    1916                 :          4 :   array->len = 0;
    1917                 :          4 :   ((GRealPtrArray *) array)->alloc = 0;
    1918                 :          4 :   g_ptr_array_unref (array);
    1919                 :          4 :   g_free (pdata);
    1920                 :          4 : }
    1921                 :            : 
    1922                 :            : /**
    1923                 :            :  * g_ptr_array_insert:
    1924                 :            :  * @array: a #GPtrArray
    1925                 :            :  * @index_: the index to place the new element at, or -1 to append
    1926                 :            :  * @data: the pointer to add.
    1927                 :            :  *
    1928                 :            :  * Inserts an element into the pointer array at the given index. The 
    1929                 :            :  * array will grow in size automatically if necessary.
    1930                 :            :  *
    1931                 :            :  * Since: 2.40
    1932                 :            :  */
    1933                 :            : void
    1934                 :      27605 : g_ptr_array_insert (GPtrArray *array,
    1935                 :            :                     gint       index_,
    1936                 :            :                     gpointer   data)
    1937                 :            : {
    1938                 :      27605 :   GRealPtrArray *rarray = (GRealPtrArray *)array;
    1939                 :            : 
    1940                 :      27605 :   g_return_if_fail (rarray);
    1941                 :      27605 :   g_return_if_fail (index_ >= -1);
    1942                 :      27605 :   g_return_if_fail (index_ <= (gint)rarray->len);
    1943                 :            : 
    1944                 :      27605 :   g_ptr_array_maybe_expand (rarray, 1);
    1945                 :            : 
    1946         [ +  + ]:      27605 :   if (index_ < 0)
    1947                 :         17 :     index_ = rarray->len;
    1948                 :            : 
    1949         [ +  + ]:      27605 :   if ((guint) index_ < rarray->len)
    1950                 :      20301 :     memmove (&(rarray->pdata[index_ + 1]),
    1951                 :      20301 :              &(rarray->pdata[index_]),
    1952                 :      20301 :              (rarray->len - index_) * sizeof (gpointer));
    1953                 :            : 
    1954                 :      27605 :   rarray->len++;
    1955                 :      27605 :   rarray->pdata[index_] = data;
    1956                 :            : }
    1957                 :            : 
    1958                 :            : /* Please keep this doc-comment in sync with pointer_array_sort_example()
    1959                 :            :  * in glib/tests/array-test.c */
    1960                 :            : /**
    1961                 :            :  * g_ptr_array_sort:
    1962                 :            :  * @array: a #GPtrArray
    1963                 :            :  * @compare_func: comparison function
    1964                 :            :  *
    1965                 :            :  * Sorts the array, using @compare_func which should be a qsort()-style
    1966                 :            :  * comparison function (returns less than zero for first arg is less
    1967                 :            :  * than second arg, zero for equal, greater than zero if irst arg is
    1968                 :            :  * greater than second arg).
    1969                 :            :  *
    1970                 :            :  * Note that the comparison function for g_ptr_array_sort() doesn't
    1971                 :            :  * take the pointers from the array as arguments, it takes pointers to
    1972                 :            :  * the pointers in the array. Here is a full example of usage:
    1973                 :            :  *
    1974                 :            :  * |[<!-- language="C" -->
    1975                 :            :  * typedef struct
    1976                 :            :  * {
    1977                 :            :  *   gchar *name;
    1978                 :            :  *   gint size;
    1979                 :            :  * } FileListEntry;
    1980                 :            :  *
    1981                 :            :  * static gint
    1982                 :            :  * sort_filelist (gconstpointer a, gconstpointer b)
    1983                 :            :  * {
    1984                 :            :  *   const FileListEntry *entry1 = *((FileListEntry **) a);
    1985                 :            :  *   const FileListEntry *entry2 = *((FileListEntry **) b);
    1986                 :            :  *
    1987                 :            :  *   return g_ascii_strcasecmp (entry1->name, entry2->name);
    1988                 :            :  * }
    1989                 :            :  *
    1990                 :            :  * …
    1991                 :            :  * g_autoptr (GPtrArray) file_list = NULL;
    1992                 :            :  *
    1993                 :            :  * // initialize file_list array and load with many FileListEntry entries
    1994                 :            :  * ...
    1995                 :            :  * // now sort it with
    1996                 :            :  * g_ptr_array_sort (file_list, sort_filelist);
    1997                 :            :  * ]|
    1998                 :            :  *
    1999                 :            :  * This is guaranteed to be a stable sort since version 2.32.
    2000                 :            :  */
    2001                 :            : void
    2002                 :        100 : g_ptr_array_sort (GPtrArray    *array,
    2003                 :            :                   GCompareFunc  compare_func)
    2004                 :            : {
    2005                 :        100 :   g_return_if_fail (array != NULL);
    2006                 :            : 
    2007                 :            :   /* Don't use qsort as we want a guaranteed stable sort */
    2008         [ +  + ]:        100 :   if (array->len > 0)
    2009                 :         98 :     g_qsort_with_data (array->pdata,
    2010                 :         98 :                        array->len,
    2011                 :            :                        sizeof (gpointer),
    2012                 :            :                        (GCompareDataFunc)compare_func,
    2013                 :            :                        NULL);
    2014                 :            : }
    2015                 :            : 
    2016                 :            : /* Please keep this doc-comment in sync with
    2017                 :            :  * pointer_array_sort_with_data_example() in glib/tests/array-test.c */
    2018                 :            : /**
    2019                 :            :  * g_ptr_array_sort_with_data:
    2020                 :            :  * @array: a #GPtrArray
    2021                 :            :  * @compare_func: comparison function
    2022                 :            :  * @user_data: data to pass to @compare_func
    2023                 :            :  *
    2024                 :            :  * Like g_ptr_array_sort(), but the comparison function has an extra
    2025                 :            :  * user data argument.
    2026                 :            :  *
    2027                 :            :  * Note that the comparison function for g_ptr_array_sort_with_data()
    2028                 :            :  * doesn't take the pointers from the array as arguments, it takes
    2029                 :            :  * pointers to the pointers in the array. Here is a full example of use:
    2030                 :            :  *
    2031                 :            :  * |[<!-- language="C" -->
    2032                 :            :  * typedef enum { SORT_NAME, SORT_SIZE } SortMode;
    2033                 :            :  *
    2034                 :            :  * typedef struct
    2035                 :            :  * {
    2036                 :            :  *   gchar *name;
    2037                 :            :  *   gint size;
    2038                 :            :  * } FileListEntry;
    2039                 :            :  *
    2040                 :            :  * static gint
    2041                 :            :  * sort_filelist (gconstpointer a, gconstpointer b, gpointer user_data)
    2042                 :            :  * {
    2043                 :            :  *   gint order;
    2044                 :            :  *   const SortMode sort_mode = GPOINTER_TO_INT (user_data);
    2045                 :            :  *   const FileListEntry *entry1 = *((FileListEntry **) a);
    2046                 :            :  *   const FileListEntry *entry2 = *((FileListEntry **) b);
    2047                 :            :  *
    2048                 :            :  *   switch (sort_mode)
    2049                 :            :  *     {
    2050                 :            :  *     case SORT_NAME:
    2051                 :            :  *       order = g_ascii_strcasecmp (entry1->name, entry2->name);
    2052                 :            :  *       break;
    2053                 :            :  *     case SORT_SIZE:
    2054                 :            :  *       order = entry1->size - entry2->size;
    2055                 :            :  *       break;
    2056                 :            :  *     default:
    2057                 :            :  *       order = 0;
    2058                 :            :  *       break;
    2059                 :            :  *     }
    2060                 :            :  *   return order;
    2061                 :            :  * }
    2062                 :            :  *
    2063                 :            :  * ...
    2064                 :            :  * g_autoptr (GPtrArray) file_list = NULL;
    2065                 :            :  * SortMode sort_mode;
    2066                 :            :  *
    2067                 :            :  * // initialize file_list array and load with many FileListEntry entries
    2068                 :            :  * ...
    2069                 :            :  * // now sort it with
    2070                 :            :  * sort_mode = SORT_NAME;
    2071                 :            :  * g_ptr_array_sort_with_data (file_list,
    2072                 :            :  *                             sort_filelist,
    2073                 :            :  *                             GINT_TO_POINTER (sort_mode));
    2074                 :            :  * ]|
    2075                 :            :  *
    2076                 :            :  * This is guaranteed to be a stable sort since version 2.32.
    2077                 :            :  */
    2078                 :            : void
    2079                 :          8 : g_ptr_array_sort_with_data (GPtrArray        *array,
    2080                 :            :                             GCompareDataFunc  compare_func,
    2081                 :            :                             gpointer          user_data)
    2082                 :            : {
    2083                 :          8 :   g_return_if_fail (array != NULL);
    2084                 :            : 
    2085         [ +  + ]:          8 :   if (array->len > 0)
    2086                 :          6 :     g_qsort_with_data (array->pdata,
    2087                 :          6 :                        array->len,
    2088                 :            :                        sizeof (gpointer),
    2089                 :            :                        compare_func,
    2090                 :            :                        user_data);
    2091                 :            : }
    2092                 :            : 
    2093                 :            : /**
    2094                 :            :  * g_ptr_array_foreach:
    2095                 :            :  * @array: a #GPtrArray
    2096                 :            :  * @func: the function to call for each array element
    2097                 :            :  * @user_data: user data to pass to the function
    2098                 :            :  * 
    2099                 :            :  * Calls a function for each element of a #GPtrArray. @func must not
    2100                 :            :  * add elements to or remove elements from the array.
    2101                 :            :  *
    2102                 :            :  * Since: 2.4
    2103                 :            :  */
    2104                 :            : void
    2105                 :       5877 : g_ptr_array_foreach (GPtrArray *array,
    2106                 :            :                      GFunc      func,
    2107                 :            :                      gpointer   user_data)
    2108                 :            : {
    2109                 :            :   guint i;
    2110                 :            : 
    2111                 :       5877 :   g_return_if_fail (array);
    2112                 :            : 
    2113         [ +  + ]:      65881 :   for (i = 0; i < array->len; i++)
    2114                 :      60004 :     (*func) (array->pdata[i], user_data);
    2115                 :            : }
    2116                 :            : 
    2117                 :            : /**
    2118                 :            :  * g_ptr_array_find: (skip)
    2119                 :            :  * @haystack: pointer array to be searched
    2120                 :            :  * @needle: pointer to look for
    2121                 :            :  * @index_: (optional) (out): return location for the index of
    2122                 :            :  *    the element, if found
    2123                 :            :  *
    2124                 :            :  * Checks whether @needle exists in @haystack. If the element is found, %TRUE is
    2125                 :            :  * returned and the element’s index is returned in @index_ (if non-%NULL).
    2126                 :            :  * Otherwise, %FALSE is returned and @index_ is undefined. If @needle exists
    2127                 :            :  * multiple times in @haystack, the index of the first instance is returned.
    2128                 :            :  *
    2129                 :            :  * This does pointer comparisons only. If you want to use more complex equality
    2130                 :            :  * checks, such as string comparisons, use g_ptr_array_find_with_equal_func().
    2131                 :            :  *
    2132                 :            :  * Returns: %TRUE if @needle is one of the elements of @haystack
    2133                 :            :  * Since: 2.54
    2134                 :            :  */
    2135                 :            : gboolean
    2136                 :          6 : g_ptr_array_find (GPtrArray     *haystack,
    2137                 :            :                   gconstpointer  needle,
    2138                 :            :                   guint         *index_)
    2139                 :            : {
    2140                 :          6 :   return g_ptr_array_find_with_equal_func (haystack, needle, NULL, index_);
    2141                 :            : }
    2142                 :            : 
    2143                 :            : /**
    2144                 :            :  * g_ptr_array_find_with_equal_func: (skip)
    2145                 :            :  * @haystack: pointer array to be searched
    2146                 :            :  * @needle: pointer to look for
    2147                 :            :  * @equal_func: (nullable): the function to call for each element, which should
    2148                 :            :  *    return %TRUE when the desired element is found; or %NULL to use pointer
    2149                 :            :  *    equality
    2150                 :            :  * @index_: (optional) (out): return location for the index of
    2151                 :            :  *    the element, if found
    2152                 :            :  *
    2153                 :            :  * Checks whether @needle exists in @haystack, using the given @equal_func.
    2154                 :            :  * If the element is found, %TRUE is returned and the element’s index is
    2155                 :            :  * returned in @index_ (if non-%NULL). Otherwise, %FALSE is returned and @index_
    2156                 :            :  * is undefined. If @needle exists multiple times in @haystack, the index of
    2157                 :            :  * the first instance is returned.
    2158                 :            :  *
    2159                 :            :  * @equal_func is called with the element from the array as its first parameter,
    2160                 :            :  * and @needle as its second parameter. If @equal_func is %NULL, pointer
    2161                 :            :  * equality is used.
    2162                 :            :  *
    2163                 :            :  * Returns: %TRUE if @needle is one of the elements of @haystack
    2164                 :            :  * Since: 2.54
    2165                 :            :  */
    2166                 :            : gboolean
    2167                 :         26 : g_ptr_array_find_with_equal_func (GPtrArray     *haystack,
    2168                 :            :                                   gconstpointer  needle,
    2169                 :            :                                   GEqualFunc     equal_func,
    2170                 :            :                                   guint         *index_)
    2171                 :            : {
    2172                 :            :   guint i;
    2173                 :            : 
    2174                 :         26 :   g_return_val_if_fail (haystack != NULL, FALSE);
    2175                 :            : 
    2176         [ +  + ]:         26 :   if (equal_func == NULL)
    2177                 :          8 :     equal_func = g_direct_equal;
    2178                 :            : 
    2179         [ +  + ]:         72 :   for (i = 0; i < haystack->len; i++)
    2180                 :            :     {
    2181         [ +  + ]:         62 :       if (equal_func (g_ptr_array_index (haystack, i), needle))
    2182                 :            :         {
    2183         [ +  + ]:         16 :           if (index_ != NULL)
    2184                 :         10 :             *index_ = i;
    2185                 :         16 :           return TRUE;
    2186                 :            :         }
    2187                 :            :     }
    2188                 :            : 
    2189                 :         10 :   return FALSE;
    2190                 :            : }
    2191                 :            : 
    2192                 :            : /**
    2193                 :            :  * SECTION:arrays_byte
    2194                 :            :  * @title: Byte Arrays
    2195                 :            :  * @short_description: arrays of bytes
    2196                 :            :  *
    2197                 :            :  * #GByteArray is a mutable array of bytes based on #GArray, to provide arrays
    2198                 :            :  * of bytes which grow automatically as elements are added.
    2199                 :            :  *
    2200                 :            :  * To create a new #GByteArray use g_byte_array_new(). To add elements to a
    2201                 :            :  * #GByteArray, use g_byte_array_append(), and g_byte_array_prepend().
    2202                 :            :  *
    2203                 :            :  * To set the size of a #GByteArray, use g_byte_array_set_size().
    2204                 :            :  *
    2205                 :            :  * To free a #GByteArray, use g_byte_array_free().
    2206                 :            :  *
    2207                 :            :  * An example for using a #GByteArray:
    2208                 :            :  * |[<!-- language="C" -->
    2209                 :            :  *   GByteArray *gbarray;
    2210                 :            :  *   gint i;
    2211                 :            :  *
    2212                 :            :  *   gbarray = g_byte_array_new ();
    2213                 :            :  *   for (i = 0; i < 10000; i++)
    2214                 :            :  *     g_byte_array_append (gbarray, (guint8*) "abcd", 4);
    2215                 :            :  *
    2216                 :            :  *   for (i = 0; i < 10000; i++)
    2217                 :            :  *     {
    2218                 :            :  *       g_assert (gbarray->data[4*i] == 'a');
    2219                 :            :  *       g_assert (gbarray->data[4*i+1] == 'b');
    2220                 :            :  *       g_assert (gbarray->data[4*i+2] == 'c');
    2221                 :            :  *       g_assert (gbarray->data[4*i+3] == 'd');
    2222                 :            :  *     }
    2223                 :            :  *
    2224                 :            :  *   g_byte_array_free (gbarray, TRUE);
    2225                 :            :  * ]|
    2226                 :            :  *
    2227                 :            :  * See #GBytes if you are interested in an immutable object representing a
    2228                 :            :  * sequence of bytes.
    2229                 :            :  */
    2230                 :            : 
    2231                 :            : /**
    2232                 :            :  * GByteArray:
    2233                 :            :  * @data: a pointer to the element data. The data may be moved as
    2234                 :            :  *     elements are added to the #GByteArray
    2235                 :            :  * @len: the number of elements in the #GByteArray
    2236                 :            :  *
    2237                 :            :  * Contains the public fields of a GByteArray.
    2238                 :            :  */
    2239                 :            : 
    2240                 :            : /**
    2241                 :            :  * g_byte_array_new:
    2242                 :            :  *
    2243                 :            :  * Creates a new #GByteArray with a reference count of 1.
    2244                 :            :  *
    2245                 :            :  * Returns: (transfer full): the new #GByteArray
    2246                 :            :  */
    2247                 :            : GByteArray*
    2248                 :         69 : g_byte_array_new (void)
    2249                 :            : {
    2250                 :         69 :   return (GByteArray *)g_array_sized_new (FALSE, FALSE, 1, 0);
    2251                 :            : }
    2252                 :            : 
    2253                 :            : /**
    2254                 :            :  * g_byte_array_steal:
    2255                 :            :  * @array: a #GByteArray.
    2256                 :            :  * @len: (optional) (out): pointer to retrieve the number of
    2257                 :            :  *    elements of the original array
    2258                 :            :  *
    2259                 :            :  * Frees the data in the array and resets the size to zero, while
    2260                 :            :  * the underlying array is preserved for use elsewhere and returned
    2261                 :            :  * to the caller.
    2262                 :            :  *
    2263                 :            :  * Returns: (transfer full): the element data, which should be
    2264                 :            :  *     freed using g_free().
    2265                 :            :  *
    2266                 :            :  * Since: 2.64
    2267                 :            :  */
    2268                 :            : guint8 *
    2269                 :          4 : g_byte_array_steal (GByteArray *array,
    2270                 :            :                     gsize *len)
    2271                 :            : {
    2272                 :          4 :   return (guint8 *) g_array_steal ((GArray *) array, len);
    2273                 :            : }
    2274                 :            : 
    2275                 :            : /**
    2276                 :            :  * g_byte_array_new_take:
    2277                 :            :  * @data: (transfer full) (array length=len): byte data for the array
    2278                 :            :  * @len: length of @data
    2279                 :            :  *
    2280                 :            :  * Create byte array containing the data. The data will be owned by the array
    2281                 :            :  * and will be freed with g_free(), i.e. it could be allocated using g_strdup().
    2282                 :            :  *
    2283                 :            :  * Do not use it if @len is greater than %G_MAXUINT. #GByteArray
    2284                 :            :  * stores the length of its data in #guint, which may be shorter than
    2285                 :            :  * #gsize.
    2286                 :            :  *
    2287                 :            :  * Since: 2.32
    2288                 :            :  *
    2289                 :            :  * Returns: (transfer full): a new #GByteArray
    2290                 :            :  */
    2291                 :            : GByteArray*
    2292                 :          9 : g_byte_array_new_take (guint8 *data,
    2293                 :            :                        gsize   len)
    2294                 :            : {
    2295                 :            :   GByteArray *array;
    2296                 :            :   GRealArray *real;
    2297                 :            : 
    2298                 :          5 :   g_return_val_if_fail (len <= G_MAXUINT, NULL);
    2299                 :          8 :   array = g_byte_array_new ();
    2300                 :          8 :   real = (GRealArray *)array;
    2301                 :          8 :   g_assert (real->data == NULL);
    2302                 :          8 :   g_assert (real->len == 0);
    2303                 :            : 
    2304                 :          8 :   real->data = data;
    2305                 :          8 :   real->len = len;
    2306                 :          8 :   real->elt_capacity = len;
    2307                 :            : 
    2308                 :          8 :   return array;
    2309                 :            : }
    2310                 :            : 
    2311                 :            : /**
    2312                 :            :  * g_byte_array_sized_new:
    2313                 :            :  * @reserved_size: number of bytes preallocated
    2314                 :            :  *
    2315                 :            :  * Creates a new #GByteArray with @reserved_size bytes preallocated.
    2316                 :            :  * This avoids frequent reallocation, if you are going to add many
    2317                 :            :  * bytes to the array. Note however that the size of the array is still
    2318                 :            :  * 0.
    2319                 :            :  *
    2320                 :            :  * Returns: the new #GByteArray
    2321                 :            :  */
    2322                 :            : GByteArray*
    2323                 :       1677 : g_byte_array_sized_new (guint reserved_size)
    2324                 :            : {
    2325                 :       1677 :   return (GByteArray *)g_array_sized_new (FALSE, FALSE, 1, reserved_size);
    2326                 :            : }
    2327                 :            : 
    2328                 :            : /**
    2329                 :            :  * g_byte_array_free:
    2330                 :            :  * @array: a #GByteArray
    2331                 :            :  * @free_segment: if %TRUE the actual byte data is freed as well
    2332                 :            :  *
    2333                 :            :  * Frees the memory allocated by the #GByteArray. If @free_segment is
    2334                 :            :  * %TRUE it frees the actual byte data. If the reference count of
    2335                 :            :  * @array is greater than one, the #GByteArray wrapper is preserved but
    2336                 :            :  * the size of @array will be set to zero.
    2337                 :            :  *
    2338                 :            :  * Returns: the element data if @free_segment is %FALSE, otherwise
    2339                 :            :  *          %NULL.  The element data should be freed using g_free().
    2340                 :            :  */
    2341                 :            : guint8*
    2342                 :         58 : g_byte_array_free (GByteArray *array,
    2343                 :            :                    gboolean    free_segment)
    2344                 :            : {
    2345                 :         58 :   return (guint8 *)g_array_free ((GArray *)array, free_segment);
    2346                 :            : }
    2347                 :            : 
    2348                 :            : /**
    2349                 :            :  * g_byte_array_free_to_bytes:
    2350                 :            :  * @array: (transfer full): a #GByteArray
    2351                 :            :  *
    2352                 :            :  * Transfers the data from the #GByteArray into a new immutable #GBytes.
    2353                 :            :  *
    2354                 :            :  * The #GByteArray is freed unless the reference count of @array is greater
    2355                 :            :  * than one, the #GByteArray wrapper is preserved but the size of @array
    2356                 :            :  * will be set to zero.
    2357                 :            :  *
    2358                 :            :  * This is identical to using g_bytes_new_take() and g_byte_array_free()
    2359                 :            :  * together.
    2360                 :            :  *
    2361                 :            :  * Since: 2.32
    2362                 :            :  *
    2363                 :            :  * Returns: (transfer full): a new immutable #GBytes representing same
    2364                 :            :  *     byte data that was in the array
    2365                 :            :  */
    2366                 :            : GBytes*
    2367                 :          2 : g_byte_array_free_to_bytes (GByteArray *array)
    2368                 :            : {
    2369                 :            :   gsize length;
    2370                 :            : 
    2371                 :          2 :   g_return_val_if_fail (array != NULL, NULL);
    2372                 :            : 
    2373                 :          2 :   length = array->len;
    2374                 :          2 :   return g_bytes_new_take (g_byte_array_free (array, FALSE), length);
    2375                 :            : }
    2376                 :            : 
    2377                 :            : /**
    2378                 :            :  * g_byte_array_ref:
    2379                 :            :  * @array: A #GByteArray
    2380                 :            :  *
    2381                 :            :  * Atomically increments the reference count of @array by one.
    2382                 :            :  * This function is thread-safe and may be called from any thread.
    2383                 :            :  *
    2384                 :            :  * Returns: The passed in #GByteArray
    2385                 :            :  *
    2386                 :            :  * Since: 2.22
    2387                 :            :  */
    2388                 :            : GByteArray*
    2389                 :       3365 : g_byte_array_ref (GByteArray *array)
    2390                 :            : {
    2391                 :       3365 :   return (GByteArray *)g_array_ref ((GArray *)array);
    2392                 :            : }
    2393                 :            : 
    2394                 :            : /**
    2395                 :            :  * g_byte_array_unref:
    2396                 :            :  * @array: A #GByteArray
    2397                 :            :  *
    2398                 :            :  * Atomically decrements the reference count of @array by one. If the
    2399                 :            :  * reference count drops to 0, all memory allocated by the array is
    2400                 :            :  * released. This function is thread-safe and may be called from any
    2401                 :            :  * thread.
    2402                 :            :  *
    2403                 :            :  * Since: 2.22
    2404                 :            :  */
    2405                 :            : void
    2406                 :       5053 : g_byte_array_unref (GByteArray *array)
    2407                 :            : {
    2408                 :       5053 :   g_array_unref ((GArray *)array);
    2409                 :       5053 : }
    2410                 :            : 
    2411                 :            : /**
    2412                 :            :  * g_byte_array_append:
    2413                 :            :  * @array: a #GByteArray
    2414                 :            :  * @data: the byte data to be added
    2415                 :            :  * @len: the number of bytes to add
    2416                 :            :  *
    2417                 :            :  * Adds the given bytes to the end of the #GByteArray.
    2418                 :            :  * The array will grow in size automatically if necessary.
    2419                 :            :  *
    2420                 :            :  * Returns: the #GByteArray
    2421                 :            :  */
    2422                 :            : GByteArray*
    2423                 :      82685 : g_byte_array_append (GByteArray   *array,
    2424                 :            :                      const guint8 *data,
    2425                 :            :                      guint         len)
    2426                 :            : {
    2427                 :      82685 :   g_array_append_vals ((GArray *)array, (guint8 *)data, len);
    2428                 :            : 
    2429                 :      82685 :   return array;
    2430                 :            : }
    2431                 :            : 
    2432                 :            : /**
    2433                 :            :  * g_byte_array_prepend:
    2434                 :            :  * @array: a #GByteArray
    2435                 :            :  * @data: the byte data to be added
    2436                 :            :  * @len: the number of bytes to add
    2437                 :            :  *
    2438                 :            :  * Adds the given data to the start of the #GByteArray.
    2439                 :            :  * The array will grow in size automatically if necessary.
    2440                 :            :  *
    2441                 :            :  * Returns: the #GByteArray
    2442                 :            :  */
    2443                 :            : GByteArray*
    2444                 :      20000 : g_byte_array_prepend (GByteArray   *array,
    2445                 :            :                       const guint8 *data,
    2446                 :            :                       guint         len)
    2447                 :            : {
    2448                 :      20000 :   g_array_prepend_vals ((GArray *)array, (guint8 *)data, len);
    2449                 :            : 
    2450                 :      20000 :   return array;
    2451                 :            : }
    2452                 :            : 
    2453                 :            : /**
    2454                 :            :  * g_byte_array_set_size:
    2455                 :            :  * @array: a #GByteArray
    2456                 :            :  * @length: the new size of the #GByteArray
    2457                 :            :  *
    2458                 :            :  * Sets the size of the #GByteArray, expanding it if necessary.
    2459                 :            :  *
    2460                 :            :  * Returns: the #GByteArray
    2461                 :            :  */
    2462                 :            : GByteArray*
    2463                 :         64 : g_byte_array_set_size (GByteArray *array,
    2464                 :            :                        guint       length)
    2465                 :            : {
    2466                 :         64 :   g_array_set_size ((GArray *)array, length);
    2467                 :            : 
    2468                 :         64 :   return array;
    2469                 :            : }
    2470                 :            : 
    2471                 :            : /**
    2472                 :            :  * g_byte_array_remove_index:
    2473                 :            :  * @array: a #GByteArray
    2474                 :            :  * @index_: the index of the byte to remove
    2475                 :            :  *
    2476                 :            :  * Removes the byte at the given index from a #GByteArray.
    2477                 :            :  * The following bytes are moved down one place.
    2478                 :            :  *
    2479                 :            :  * Returns: the #GByteArray
    2480                 :            :  **/
    2481                 :            : GByteArray*
    2482                 :         10 : g_byte_array_remove_index (GByteArray *array,
    2483                 :            :                            guint       index_)
    2484                 :            : {
    2485                 :         10 :   g_array_remove_index ((GArray *)array, index_);
    2486                 :            : 
    2487                 :         10 :   return array;
    2488                 :            : }
    2489                 :            : 
    2490                 :            : /**
    2491                 :            :  * g_byte_array_remove_index_fast:
    2492                 :            :  * @array: a #GByteArray
    2493                 :            :  * @index_: the index of the byte to remove
    2494                 :            :  *
    2495                 :            :  * Removes the byte at the given index from a #GByteArray. The last
    2496                 :            :  * element in the array is used to fill in the space, so this function
    2497                 :            :  * does not preserve the order of the #GByteArray. But it is faster
    2498                 :            :  * than g_byte_array_remove_index().
    2499                 :            :  *
    2500                 :            :  * Returns: the #GByteArray
    2501                 :            :  */
    2502                 :            : GByteArray*
    2503                 :          8 : g_byte_array_remove_index_fast (GByteArray *array,
    2504                 :            :                                 guint       index_)
    2505                 :            : {
    2506                 :          8 :   g_array_remove_index_fast ((GArray *)array, index_);
    2507                 :            : 
    2508                 :          8 :   return array;
    2509                 :            : }
    2510                 :            : 
    2511                 :            : /**
    2512                 :            :  * g_byte_array_remove_range:
    2513                 :            :  * @array: a @GByteArray
    2514                 :            :  * @index_: the index of the first byte to remove
    2515                 :            :  * @length: the number of bytes to remove
    2516                 :            :  *
    2517                 :            :  * Removes the given number of bytes starting at the given index from a
    2518                 :            :  * #GByteArray.  The following elements are moved to close the gap.
    2519                 :            :  *
    2520                 :            :  * Returns: the #GByteArray
    2521                 :            :  *
    2522                 :            :  * Since: 2.4
    2523                 :            :  */
    2524                 :            : GByteArray*
    2525                 :          6 : g_byte_array_remove_range (GByteArray *array,
    2526                 :            :                            guint       index_,
    2527                 :            :                            guint       length)
    2528                 :            : {
    2529                 :          6 :   g_return_val_if_fail (array, NULL);
    2530                 :          6 :   g_return_val_if_fail (index_ <= array->len, NULL);
    2531                 :          6 :   g_return_val_if_fail (index_ + length <= array->len, NULL);
    2532                 :            : 
    2533                 :          6 :   return (GByteArray *)g_array_remove_range ((GArray *)array, index_, length);
    2534                 :            : }
    2535                 :            : 
    2536                 :            : /**
    2537                 :            :  * g_byte_array_sort:
    2538                 :            :  * @array: a #GByteArray
    2539                 :            :  * @compare_func: comparison function
    2540                 :            :  *
    2541                 :            :  * Sorts a byte array, using @compare_func which should be a
    2542                 :            :  * qsort()-style comparison function (returns less than zero for first
    2543                 :            :  * arg is less than second arg, zero for equal, greater than zero if
    2544                 :            :  * first arg is greater than second arg).
    2545                 :            :  *
    2546                 :            :  * If two array elements compare equal, their order in the sorted array
    2547                 :            :  * is undefined. If you want equal elements to keep their order (i.e.
    2548                 :            :  * you want a stable sort) you can write a comparison function that,
    2549                 :            :  * if two elements would otherwise compare equal, compares them by
    2550                 :            :  * their addresses.
    2551                 :            :  */
    2552                 :            : void
    2553                 :          2 : g_byte_array_sort (GByteArray   *array,
    2554                 :            :                    GCompareFunc  compare_func)
    2555                 :            : {
    2556                 :          2 :   g_array_sort ((GArray *)array, compare_func);
    2557                 :          2 : }
    2558                 :            : 
    2559                 :            : /**
    2560                 :            :  * g_byte_array_sort_with_data:
    2561                 :            :  * @array: a #GByteArray
    2562                 :            :  * @compare_func: comparison function
    2563                 :            :  * @user_data: data to pass to @compare_func
    2564                 :            :  *
    2565                 :            :  * Like g_byte_array_sort(), but the comparison function takes an extra
    2566                 :            :  * user data argument.
    2567                 :            :  */
    2568                 :            : void
    2569                 :          2 : g_byte_array_sort_with_data (GByteArray       *array,
    2570                 :            :                              GCompareDataFunc  compare_func,
    2571                 :            :                              gpointer          user_data)
    2572                 :            : {
    2573                 :          2 :   g_array_sort_with_data ((GArray *)array, compare_func, user_data);
    2574                 :          2 : }

Generated by: LCOV version 1.14