LCOV - code coverage report
Current view: top level - glib - garray.c (source / functions) Coverage Total Hit
Test: unnamed Lines: 99.4 % 727 723
Test Date: 2026-07-14 05:12:09 Functions: 100.0 % 82 82
Branches: - 0 0

             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                 :             :  * SPDX-License-Identifier: LGPL-2.1-or-later
       5                 :             :  *
       6                 :             :  * This library is free software; you can redistribute it and/or
       7                 :             :  * modify it under the terms of the GNU Lesser General Public
       8                 :             :  * License as published by the Free Software Foundation; either
       9                 :             :  * version 2.1 of the License, or (at your option) any later version.
      10                 :             :  *
      11                 :             :  * This library is distributed in the hope that it will be useful,
      12                 :             :  * but WITHOUT ANY WARRANTY; without even the implied warranty of
      13                 :             :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      14                 :             :  * Lesser General Public License for more details.
      15                 :             :  *
      16                 :             :  * You should have received a copy of the GNU Lesser General Public
      17                 :             :  * License along with this library; if not, see <http://www.gnu.org/licenses/>.
      18                 :             :  */
      19                 :             : 
      20                 :             : /*
      21                 :             :  * Modified by the GLib Team and others 1997-2000.  See the AUTHORS
      22                 :             :  * file for a list of people on the GLib Team.  See the ChangeLog
      23                 :             :  * files for a list of changes.  These files are distributed with
      24                 :             :  * GLib at ftp://ftp.gtk.org/pub/gtk/. 
      25                 :             :  */
      26                 :             : 
      27                 :             : /* 
      28                 :             :  * MT safe
      29                 :             :  */
      30                 :             : 
      31                 :             : #include "config.h"
      32                 :             : 
      33                 :             : #include <string.h>
      34                 :             : #include <stdlib.h>
      35                 :             : 
      36                 :             : #include "garray.h"
      37                 :             : 
      38                 :             : #include "galloca.h"
      39                 :             : #include "gbytes.h"
      40                 :             : #include "ghash.h"
      41                 :             : #include "gslice.h"
      42                 :             : #include "gmem.h"
      43                 :             : #include "gtestutils.h"
      44                 :             : #include "gthread.h"
      45                 :             : #include "gmessages.h"
      46                 :             : #include "gqsort.h"
      47                 :             : #include "grefcount.h"
      48                 :             : #include "gutilsprivate.h"
      49                 :             : 
      50                 :             : #define MIN_ARRAY_SIZE  16
      51                 :             : 
      52                 :             : typedef struct _GRealArray  GRealArray;
      53                 :             : 
      54                 :             : /**
      55                 :             :  * GArray: (copy-func g_array_ref) (free-func g_array_unref)
      56                 :             :  * @data: a pointer to the element data. The data may be moved as
      57                 :             :  *     elements are added to the `GArray`.
      58                 :             :  * @len: the number of elements in the `GArray` not including the
      59                 :             :  *     possible terminating zero element
      60                 :             :  *
      61                 :             :  * Contains the public fields of a `GArray`.
      62                 :             :  */
      63                 :             : struct _GRealArray
      64                 :             : {
      65                 :             :   guint8 *data;
      66                 :             :   guint   len;
      67                 :             :   guint   elt_capacity;
      68                 :             :   guint   elt_size;
      69                 :             :   guint   zero_terminated : 1;
      70                 :             :   guint   clear : 1;
      71                 :             :   guint   max_len;
      72                 :             :   gatomicrefcount ref_count;
      73                 :             :   GDestroyNotify clear_func;
      74                 :             : };
      75                 :             : 
      76                 :             : /**
      77                 :             :  * g_array_index:
      78                 :             :  * @a: an array
      79                 :             :  * @t: the type of the elements
      80                 :             :  * @i: the index of the element to return
      81                 :             :  *
      82                 :             :  * Returns the element of a `GArray` at the given index. The return
      83                 :             :  * value is cast to the given type. This is the main way to read or write an
      84                 :             :  * element in a `GArray`.
      85                 :             :  *
      86                 :             :  * Writing an element is typically done by reference, as in the following
      87                 :             :  * example. This example gets a pointer to an element in a `GArray`, and then
      88                 :             :  * writes to a field in it:
      89                 :             :  * ```c
      90                 :             :  *   EDayViewEvent *event;
      91                 :             :  *   // This gets a pointer to the 4th element in the array of
      92                 :             :  *   // EDayViewEvent structs.
      93                 :             :  *   event = &g_array_index (events, EDayViewEvent, 3);
      94                 :             :  *   event->start_time = g_get_current_time ();
      95                 :             :  * ```
      96                 :             :  *
      97                 :             :  * This example reads from and writes to an array of integers:
      98                 :             :  * ```c
      99                 :             :  *   g_autoptr(GArray) int_array = g_array_new (FALSE, FALSE, sizeof (guint));
     100                 :             :  *   for (guint i = 0; i < 10; i++)
     101                 :             :  *     g_array_append_val (int_array, i);
     102                 :             :  *
     103                 :             :  *   guint *my_int = &g_array_index (int_array, guint, 1);
     104                 :             :  *   g_print ("Int at index 1 is %u; decrementing it\n", *my_int);
     105                 :             :  *   *my_int = *my_int - 1;
     106                 :             :  * ```
     107                 :             :  *
     108                 :             :  * Returns: (transfer none): The element of the `GArray` at the index given by @i
     109                 :             :  */
     110                 :             : 
     111                 :             : #define g_array_elt_len(array,i) ((gsize)(array)->elt_size * (i))
     112                 :             : #define g_array_elt_pos(array,i) ((array)->data + g_array_elt_len((array),(i)))
     113                 :             : #define g_array_elt_zero(array, pos, len)                               \
     114                 :             :   (memset (g_array_elt_pos ((array), pos), 0,  g_array_elt_len ((array), len)))
     115                 :             : #define g_array_zero_terminate(array) G_STMT_START{                     \
     116                 :             :   if ((array)->zero_terminated)                                         \
     117                 :             :     g_array_elt_zero ((array), (array)->len, 1);                        \
     118                 :             : }G_STMT_END
     119                 :             : 
     120                 :             : static void  g_array_maybe_expand (GRealArray *array,
     121                 :             :                                    guint       len);
     122                 :             : 
     123                 :             : /**
     124                 :             :  * g_array_new:
     125                 :             :  * @zero_terminated: if true, the array should have an extra element at
     126                 :             :  *     the end which is set to 0
     127                 :             :  * @clear_: if true, `GArray` elements should be automatically cleared
     128                 :             :  *     to 0 when they are allocated
     129                 :             :  * @element_size: the size of each element in bytes
     130                 :             :  *
     131                 :             :  * Creates a new `GArray` with a reference count of 1.
     132                 :             :  *
     133                 :             :  * Returns: (transfer full): The new `GArray`
     134                 :             :  */
     135                 :             : GArray*
     136                 :       11025 : g_array_new (gboolean zero_terminated,
     137                 :             :              gboolean clear,
     138                 :             :              guint    elt_size)
     139                 :             : {
     140                 :       11025 :   g_return_val_if_fail (elt_size > 0, NULL);
     141                 :             : #if (UINT_WIDTH / 8) >= GLIB_SIZEOF_SIZE_T
     142                 :             :   g_return_val_if_fail (elt_size <= G_MAXSIZE / 2 - 1, NULL);
     143                 :             : #endif
     144                 :             : 
     145                 :       11025 :   return g_array_sized_new (zero_terminated, clear, elt_size, 0);
     146                 :        2800 : }
     147                 :             : 
     148                 :             : /**
     149                 :             :  * g_array_new_take: (skip)
     150                 :             :  * @data: (array length=len) (transfer full) (nullable): an array of
     151                 :             :  *   elements of @element_size
     152                 :             :  * @len: the number of elements in @data
     153                 :             :  * @clear: if true, `GArray` elements should be automatically cleared
     154                 :             :  *     to 0 when they are allocated
     155                 :             :  * @element_size: the size of each element in bytes
     156                 :             :  *
     157                 :             :  * Creates a new `GArray` with @data as array data, @len as length and a
     158                 :             :  * reference count of 1.
     159                 :             :  *
     160                 :             :  * This avoids having to copy the data manually, when it can just be
     161                 :             :  * inherited.
     162                 :             :  * After this call, @data belongs to the `GArray` and may no longer be
     163                 :             :  * modified by the caller. The memory of @data has to be dynamically
     164                 :             :  * allocated and will eventually be freed with [func@GLib.free].
     165                 :             :  *
     166                 :             :  * In case the elements need to be cleared when the array is freed, use
     167                 :             :  * [func@GLib.Array.set_clear_func] to set a [callback@GLib.DestroyNotify]
     168                 :             :  * function to perform such task.
     169                 :             :  *
     170                 :             :  * Do not use it if @len or @element_size are greater than
     171                 :             :  *  [`G_MAXUINT`](types.html#guint). `GArray` stores the length of its data in
     172                 :             :  *  `guint`, which may be shorter than `gsize`.
     173                 :             :  *
     174                 :             :  * Returns: (transfer full): The new #GArray
     175                 :             :  *
     176                 :             :  * Since: 2.76
     177                 :             :  */
     178                 :             : GArray *
     179                 :          22 : g_array_new_take (gpointer  data,
     180                 :             :                   gsize     len,
     181                 :             :                   gboolean  clear,
     182                 :             :                   gsize     element_size)
     183                 :             : {
     184                 :             :   GRealArray *rarray;
     185                 :             :   GArray *array;
     186                 :             : 
     187                 :          22 :   g_return_val_if_fail (data != NULL || len == 0, NULL);
     188                 :          22 :   g_return_val_if_fail (len <= G_MAXUINT, NULL);
     189                 :          21 :   g_return_val_if_fail (element_size > 0 && element_size <= G_MAXUINT, NULL);
     190                 :             : 
     191                 :          18 :   array = g_array_sized_new (FALSE, clear, element_size, 0);
     192                 :          18 :   rarray = (GRealArray *) array;
     193                 :          18 :   rarray->data = (guint8 *) g_steal_pointer (&data);
     194                 :          18 :   rarray->len = len;
     195                 :          18 :   rarray->elt_capacity = len;
     196                 :             : 
     197                 :          18 :   return array;
     198                 :          10 : }
     199                 :             : 
     200                 :             : /**
     201                 :             :  * g_array_new_take_zero_terminated: (skip)
     202                 :             :  * @data: (array zero-terminated=1) (transfer full) (nullable): an array
     203                 :             :  *     of elements of @element_size, `NULL` terminated
     204                 :             :  * @clear: if true, `GArray` elements should be automatically cleared
     205                 :             :  *     to 0 when they are allocated
     206                 :             :  * @element_size: the size of each element in bytes
     207                 :             :  *
     208                 :             :  * Creates a new `GArray` with @data as array data, computing the length of it
     209                 :             :  * and setting the reference count to 1.
     210                 :             :  *
     211                 :             :  * This avoids having to copy the data manually, when it can just be
     212                 :             :  * inherited.
     213                 :             :  * After this call, @data belongs to the `GArray` and may no longer be
     214                 :             :  * modified by the caller. The memory of @data has to be dynamically
     215                 :             :  * allocated and will eventually be freed with [func@GLib.free].
     216                 :             :  *
     217                 :             :  * The length is calculated by iterating through @data until the first `NULL`
     218                 :             :  * element is found.
     219                 :             :  *
     220                 :             :  * In case the elements need to be cleared when the array is freed, use
     221                 :             :  * [func@GLib.Array.set_clear_func] to set a [callback@GLib.DestroyNotify]
     222                 :             :  * function to perform such task.
     223                 :             :  *
     224                 :             :  * Do not use it if @data length or @element_size are greater than
     225                 :             :  * [`G_MAXUINT`](types.html#guint). `GArray` stores the length of its data in
     226                 :             :  * `guint`, which may be shorter than `gsize`.
     227                 :             :  *
     228                 :             :  * Returns: (transfer full): The new `GArray`
     229                 :             :  *
     230                 :             :  * Since: 2.76
     231                 :             :  */
     232                 :             : GArray *
     233                 :          14 : g_array_new_take_zero_terminated (gpointer  data,
     234                 :             :                                   gboolean  clear,
     235                 :             :                                   gsize     element_size)
     236                 :             : {
     237                 :             :   GRealArray *rarray;
     238                 :             :   GArray *array;
     239                 :          14 :   gsize len = 0;
     240                 :             : 
     241                 :          14 :   g_return_val_if_fail (element_size > 0 && element_size <= G_MAXUINT, NULL);
     242                 :             : 
     243                 :          12 :   if (data != NULL)
     244                 :             :     {
     245                 :           4 :       guint8 *array_data = data;
     246                 :             : 
     247                 :       10259 :       for (gsize i = 0; ; ++i)
     248                 :       10255 :         {
     249                 :       20514 :           const guint8 *element_start = array_data + (i * element_size);
     250                 :             : 
     251                 :       20514 :           if (*element_start == 0 &&
     252                 :          82 :               memcmp (element_start, element_start + 1, element_size - 1) == 0)
     253                 :           4 :             break;
     254                 :             : 
     255                 :       20510 :           len += 1;
     256                 :       10255 :         }
     257                 :           2 :     }
     258                 :             : 
     259                 :          12 :   g_return_val_if_fail (len < G_MAXUINT, NULL);
     260                 :             : 
     261                 :          12 :   array = g_array_new_take (data, len, clear, element_size);
     262                 :          12 :   rarray = (GRealArray *) array;
     263                 :          12 :   rarray->zero_terminated = TRUE;
     264                 :          12 :   if (G_LIKELY (rarray->data != NULL))
     265                 :           4 :     rarray->elt_capacity = len + 1;
     266                 :             : 
     267                 :          12 :   return array;
     268                 :           7 : }
     269                 :             : 
     270                 :             : /**
     271                 :             :  * g_array_steal:
     272                 :             :  * @array: an array
     273                 :             :  * @len: (optional) (out): a pointer to retrieve the number of
     274                 :             :  *    elements of the original array
     275                 :             :  *
     276                 :             :  * Frees the data in the array and resets the size to zero, while
     277                 :             :  * the underlying array is preserved for use elsewhere and returned
     278                 :             :  * to the caller.
     279                 :             :  *
     280                 :             :  * Note that if the array was created with the @zero_terminate
     281                 :             :  * property set to true, this may still return `NULL` if the length
     282                 :             :  * of the array was zero and data was not yet allocated.
     283                 :             :  *
     284                 :             :  * If array elements contain dynamically-allocated memory,
     285                 :             :  * the array elements should also be freed by the caller.
     286                 :             :  *
     287                 :             :  * A short example of use:
     288                 :             :  * ```c
     289                 :             :  * ...
     290                 :             :  * gpointer data;
     291                 :             :  * gsize data_len;
     292                 :             :  * data = g_array_steal (some_array, &data_len);
     293                 :             :  * ...
     294                 :             :  * ```
     295                 :             :  *
     296                 :             :  * Returns: (transfer full): The allocated element data
     297                 :             :  *
     298                 :             :  * Since: 2.64
     299                 :             :  */
     300                 :             : gpointer
     301                 :          18 : g_array_steal (GArray *array,
     302                 :             :                gsize *len)
     303                 :             : {
     304                 :             :   GRealArray *rarray;
     305                 :             :   gpointer segment;
     306                 :             : 
     307                 :          18 :   g_return_val_if_fail (array != NULL, NULL);
     308                 :             : 
     309                 :          18 :   rarray = (GRealArray *) array;
     310                 :          18 :   segment = (gpointer) rarray->data;
     311                 :             : 
     312                 :          18 :   if (len != NULL)
     313                 :          14 :     *len = rarray->len;
     314                 :             : 
     315                 :          18 :   rarray->data  = NULL;
     316                 :          18 :   rarray->len   = 0;
     317                 :          18 :   rarray->elt_capacity = 0;
     318                 :          18 :   return segment;
     319                 :           9 : }
     320                 :             : 
     321                 :             : /**
     322                 :             :  * g_array_sized_new:
     323                 :             :  * @zero_terminated: if true, the array should have an extra element at
     324                 :             :  *     the end with all bits cleared
     325                 :             :  * @clear_: if true, all bits in the array should be cleared to 0 on
     326                 :             :  *     allocation
     327                 :             :  * @element_size: the size of each element in the array
     328                 :             :  * @reserved_size: the number of elements preallocated
     329                 :             :  *
     330                 :             :  * Creates a new `GArray` with @reserved_size elements preallocated and
     331                 :             :  * a reference count of 1. This avoids frequent reallocation, if you
     332                 :             :  * are going to add many elements to the array. Note however that the
     333                 :             :  * size of the array is still 0.
     334                 :             :  *
     335                 :             :  * Returns: (transfer full): The new `GArray`
     336                 :             :  */
     337                 :             : GArray*
     338                 :       12477 : g_array_sized_new (gboolean zero_terminated,
     339                 :             :                    gboolean clear,
     340                 :             :                    guint    elt_size,
     341                 :             :                    guint    reserved_size)
     342                 :             : {
     343                 :             :   GRealArray *array;
     344                 :             :   
     345                 :       12477 :   g_return_val_if_fail (elt_size > 0, NULL);
     346                 :             : #if (UINT_WIDTH / 8) >= GLIB_SIZEOF_SIZE_T
     347                 :             :   g_return_val_if_fail (elt_size <= G_MAXSIZE / 2 - 1, NULL);
     348                 :             : #endif
     349                 :             : 
     350                 :       12477 :   array = g_slice_new (GRealArray);
     351                 :             : 
     352                 :       12477 :   array->data            = NULL;
     353                 :       12477 :   array->len             = 0;
     354                 :       12477 :   array->elt_capacity = 0;
     355                 :       12477 :   array->zero_terminated = (zero_terminated ? 1 : 0);
     356                 :       12477 :   array->clear           = (clear ? 1 : 0);
     357                 :       12477 :   array->elt_size        = elt_size;
     358                 :       12477 :   array->clear_func      = NULL;
     359                 :             : 
     360                 :             :   /* The maximum array length is derived from following constraints:
     361                 :             :    * - The number of bytes must fit into a gsize / 2.
     362                 :             :    * - The number of elements must fit into guint.
     363                 :             :    * - zero terminated arrays must leave space for the terminating element
     364                 :             :    */
     365                 :       12477 :   array->max_len = MIN (G_MAXSIZE / 2 / elt_size, G_MAXUINT) - array->zero_terminated;
     366                 :             : 
     367                 :       12477 :   g_atomic_ref_count_init (&array->ref_count);
     368                 :             : 
     369                 :       12477 :   if (array->zero_terminated || reserved_size != 0)
     370                 :             :     {
     371                 :         717 :       g_array_maybe_expand (array, reserved_size);
     372                 :         717 :       g_assert (array->data != NULL);
     373                 :         717 :       g_array_zero_terminate (array);
     374                 :         433 :     }
     375                 :             : 
     376                 :       12477 :   return (GArray*) array;
     377                 :        3591 : }
     378                 :             : 
     379                 :             : /**
     380                 :             :  * g_array_set_clear_func:
     381                 :             :  * @array: an array
     382                 :             :  * @clear_func: (nullable): a function to clear an element of @array
     383                 :             :  *
     384                 :             :  * Sets a function to clear an element of @array.
     385                 :             :  *
     386                 :             :  * The @clear_func will be called when an element in the array
     387                 :             :  * data segment is removed and when the array is freed and data
     388                 :             :  * segment is deallocated as well. @clear_func will be passed a
     389                 :             :  * pointer to the element to clear, rather than the element itself.
     390                 :             :  *
     391                 :             :  * Note that in contrast with other uses of [callback@GLib.DestroyNotify]
     392                 :             :  * functions, @clear_func is expected to clear the contents of
     393                 :             :  * the array element it is given, but not free the element itself.
     394                 :             :  *
     395                 :             :  * ```c
     396                 :             :  * typedef struct
     397                 :             :  * {
     398                 :             :  *   gchar *str;
     399                 :             :  *   GObject *obj;
     400                 :             :  * } ArrayElement;
     401                 :             :  *
     402                 :             :  * static void
     403                 :             :  * array_element_clear (ArrayElement *element)
     404                 :             :  * {
     405                 :             :  *   g_clear_pointer (&element->str, g_free);
     406                 :             :  *   g_clear_object (&element->obj);
     407                 :             :  * }
     408                 :             :  *
     409                 :             :  * // main code
     410                 :             :  * GArray *garray = g_array_new (FALSE, FALSE, sizeof (ArrayElement));
     411                 :             :  * g_array_set_clear_func (garray, (GDestroyNotify) array_element_clear);
     412                 :             :  * // assign data to the structure
     413                 :             :  * g_array_free (garray, TRUE);
     414                 :             :  * ```
     415                 :             :  *
     416                 :             :  * Since: 2.32
     417                 :             :  */
     418                 :             : void
     419                 :          13 : g_array_set_clear_func (GArray         *array,
     420                 :             :                         GDestroyNotify  clear_func)
     421                 :             : {
     422                 :          13 :   GRealArray *rarray = (GRealArray *) array;
     423                 :             : 
     424                 :          13 :   g_return_if_fail (array != NULL);
     425                 :             : 
     426                 :          13 :   rarray->clear_func = clear_func;
     427                 :           2 : }
     428                 :             : 
     429                 :             : /**
     430                 :             :  * g_array_ref:
     431                 :             :  * @array: an array
     432                 :             :  *
     433                 :             :  * Atomically increments the reference count of @array by one.
     434                 :             :  * This function is thread-safe and may be called from any thread.
     435                 :             :  *
     436                 :             :  * Returns: (transfer full): The passed in `GArray`
     437                 :             :  *
     438                 :             :  * Since: 2.22
     439                 :             :  */
     440                 :             : GArray *
     441                 :          11 : g_array_ref (GArray *array)
     442                 :             : {
     443                 :          11 :   GRealArray *rarray = (GRealArray*) array;
     444                 :          11 :   g_return_val_if_fail (array, NULL);
     445                 :             : 
     446                 :          11 :   g_atomic_ref_count_inc (&rarray->ref_count);
     447                 :             : 
     448                 :          11 :   return array;
     449                 :           5 : }
     450                 :             : 
     451                 :             : typedef enum
     452                 :             : {
     453                 :             :   FREE_SEGMENT = 1 << 0,
     454                 :             :   PRESERVE_WRAPPER = 1 << 1
     455                 :             : } G_GNUC_FLAG_ENUM ArrayFreeFlags;
     456                 :             : 
     457                 :             : static gchar *array_free (GRealArray *, ArrayFreeFlags);
     458                 :             : 
     459                 :             : /**
     460                 :             :  * g_array_unref:
     461                 :             :  * @array: (transfer full): an array
     462                 :             :  *
     463                 :             :  * Atomically decrements the reference count of @array by one. If the
     464                 :             :  * reference count drops to 0, the effect is the same as calling
     465                 :             :  * [func@GLib.Array.free] with @free_segment set to true. This function is
     466                 :             :  * thread-safe and may be called from any thread.
     467                 :             :  *
     468                 :             :  * Since: 2.22
     469                 :             :  */
     470                 :             : void
     471                 :         253 : g_array_unref (GArray *array)
     472                 :             : {
     473                 :         253 :   GRealArray *rarray = (GRealArray*) array;
     474                 :         253 :   g_return_if_fail (array);
     475                 :             : 
     476                 :         253 :   if (g_atomic_ref_count_dec (&rarray->ref_count))
     477                 :         246 :     array_free (rarray, FREE_SEGMENT);
     478                 :          76 : }
     479                 :             : 
     480                 :             : /**
     481                 :             :  * g_array_get_element_size:
     482                 :             :  * @array: an array
     483                 :             :  *
     484                 :             :  * Gets the size of the elements in @array.
     485                 :             :  *
     486                 :             :  * Returns: The size of each element, in bytes
     487                 :             :  *
     488                 :             :  * Since: 2.22
     489                 :             :  */
     490                 :             : guint
     491                 :           2 : g_array_get_element_size (GArray *array)
     492                 :             : {
     493                 :           2 :   GRealArray *rarray = (GRealArray*) array;
     494                 :             : 
     495                 :           2 :   g_return_val_if_fail (array, 0);
     496                 :             : 
     497                 :           2 :   return rarray->elt_size;
     498                 :           1 : }
     499                 :             : 
     500                 :             : /**
     501                 :             :  * g_array_free:
     502                 :             :  * @array: (transfer full): an array
     503                 :             :  * @free_segment: if true, the actual element data is freed as well
     504                 :             :  *
     505                 :             :  * Frees the memory allocated for the `GArray`. If @free_segment is
     506                 :             :  * true it frees the memory block holding the elements as well. Pass
     507                 :             :  * false if you want to free the `GArray` wrapper but preserve the
     508                 :             :  * underlying array for use elsewhere. If the reference count of
     509                 :             :  * @array is greater than one, the `GArray` wrapper is preserved but
     510                 :             :  * the size of @array will be set to zero.
     511                 :             :  *
     512                 :             :  * If array contents point to dynamically-allocated memory, they should
     513                 :             :  * be freed separately if @free_segment is true and no @clear_func
     514                 :             :  * function has been set for @array.
     515                 :             :  *
     516                 :             :  * This function is not thread-safe. If using a `GArray` from multiple
     517                 :             :  * threads, use only the atomic [func@GLib.Array.ref] and
     518                 :             :  * [func@GLib.Array.unref] functions.
     519                 :             :  *
     520                 :             :  * Returns: The allocated element data if @free_segment is false, otherwise
     521                 :             :  *     `NULL`
     522                 :             :  */
     523                 :             : gchar*
     524                 :       12110 : g_array_free (GArray   *farray,
     525                 :             :               gboolean  free_segment)
     526                 :             : {
     527                 :       12110 :   GRealArray *array = (GRealArray*) farray;
     528                 :             :   ArrayFreeFlags flags;
     529                 :             : 
     530                 :       12110 :   g_return_val_if_fail (array, NULL);
     531                 :             : 
     532                 :       12110 :   flags = (free_segment ? FREE_SEGMENT : 0);
     533                 :             : 
     534                 :             :   /* if others are holding a reference, preserve the wrapper but do free/return the data */
     535                 :       12110 :   if (!g_atomic_ref_count_dec (&array->ref_count))
     536                 :           4 :     flags |= PRESERVE_WRAPPER;
     537                 :             : 
     538                 :       12110 :   return array_free (array, flags);
     539                 :        3474 : }
     540                 :             : 
     541                 :             : static gchar *
     542                 :       12356 : array_free (GRealArray     *array,
     543                 :             :             ArrayFreeFlags  flags)
     544                 :             : {
     545                 :             :   gchar *segment;
     546                 :             : 
     547                 :       12356 :   if (flags & FREE_SEGMENT)
     548                 :             :     {
     549                 :       11202 :       if (array->clear_func != NULL)
     550                 :             :         {
     551                 :             :           guint i;
     552                 :             : 
     553                 :         133 :           for (i = 0; i < array->len; i++)
     554                 :         120 :             array->clear_func (g_array_elt_pos (array, i));
     555                 :           2 :         }
     556                 :             : 
     557                 :       11202 :       g_free (array->data);
     558                 :       11202 :       segment = NULL;
     559                 :        2983 :     }
     560                 :             :   else
     561                 :        1154 :     segment = (gchar*) array->data;
     562                 :             : 
     563                 :       12356 :   if (flags & PRESERVE_WRAPPER)
     564                 :             :     {
     565                 :           4 :       array->data            = NULL;
     566                 :           4 :       array->len             = 0;
     567                 :           4 :       array->elt_capacity = 0;
     568                 :           2 :     }
     569                 :             :   else
     570                 :             :     {
     571                 :       12352 :       g_slice_free1 (sizeof (GRealArray), array);
     572                 :             :     }
     573                 :             : 
     574                 :       12356 :   return segment;
     575                 :             : }
     576                 :             : 
     577                 :             : /**
     578                 :             :  * g_array_append_vals:
     579                 :             :  * @array: an array
     580                 :             :  * @data: (nullable): a pointer to the elements to append to the end of the array
     581                 :             :  * @len: the number of elements to append
     582                 :             :  *
     583                 :             :  * Adds @len elements onto the end of the array.
     584                 :             :  *
     585                 :             :  * @data may be `NULL` if (and only if) @len is zero. If @len is zero, this
     586                 :             :  * function is a no-op.
     587                 :             :  *
     588                 :             :  * Returns: (transfer none): The `GArray`
     589                 :             :  */
     590                 :             : /**
     591                 :             :  * g_array_append_val:
     592                 :             :  * @a: an array
     593                 :             :  * @v: the value to append to the #GArray
     594                 :             :  *
     595                 :             :  * Adds the value on to the end of the array. The array will grow in
     596                 :             :  * size automatically if necessary.
     597                 :             :  *
     598                 :             :  * `g_array_append_val()` is a macro which uses a reference to the value
     599                 :             :  * parameter @v. This means that you cannot use it with literal values
     600                 :             :  * such as `"27"`. You must use variables.
     601                 :             :  *
     602                 :             :  * Returns: (transfer none): The `GArray`
     603                 :             :  */
     604                 :             : GArray*
     605                 :      504813 : g_array_append_vals (GArray       *farray,
     606                 :             :                      gconstpointer data,
     607                 :             :                      guint         len)
     608                 :             : {
     609                 :      504813 :   GRealArray *array = (GRealArray*) farray;
     610                 :             : 
     611                 :      504813 :   g_return_val_if_fail (array, NULL);
     612                 :             : 
     613                 :      504811 :   if (len == 0)
     614                 :           5 :     return farray;
     615                 :             : 
     616                 :      504806 :   g_array_maybe_expand (array, len);
     617                 :             : 
     618                 :      731725 :   memcpy (g_array_elt_pos (array, array->len), data, 
     619                 :      504806 :           g_array_elt_len (array, len));
     620                 :             : 
     621                 :      504806 :   array->len += len;
     622                 :             : 
     623                 :      504806 :   g_array_zero_terminate (array);
     624                 :             : 
     625                 :      504806 :   return farray;
     626                 :      226920 : }
     627                 :             : 
     628                 :             : /**
     629                 :             :  * g_array_prepend_vals:
     630                 :             :  * @array: an array
     631                 :             :  * @data: (nullable): a pointer to the elements to prepend to the start of the array
     632                 :             :  * @len: the number of elements to prepend, which may be zero
     633                 :             :  *
     634                 :             :  * Adds @len elements onto the start of the array.
     635                 :             :  *
     636                 :             :  * @data may be `NULL` if (and only if) @len is zero. If @len is zero, this
     637                 :             :  * function is a no-op.
     638                 :             :  *
     639                 :             :  * This operation is slower than [func@GLib.Array.append_vals] since the
     640                 :             :  * existing elements in the array have to be moved to make space for
     641                 :             :  * the new elements.
     642                 :             :  *
     643                 :             :  * Returns: (transfer none): The `GArray`
     644                 :             :  */
     645                 :             : /**
     646                 :             :  * g_array_prepend_val:
     647                 :             :  * @a: an array
     648                 :             :  * @v: the value to prepend to the #GArray
     649                 :             :  *
     650                 :             :  * Adds the value on to the start of the array. The array will grow in
     651                 :             :  * size automatically if necessary.
     652                 :             :  *
     653                 :             :  * This operation is slower than [func@GLib.array_append_val] since the
     654                 :             :  * existing elements in the array have to be moved to make space for
     655                 :             :  * the new element.
     656                 :             :  *
     657                 :             :  * `g_array_prepend_val()` is a macro which uses a reference to the value
     658                 :             :  * parameter @v. This means that you cannot use it with literal values
     659                 :             :  * such as `"27"`. You must use variables.
     660                 :             :  *
     661                 :             :  * Returns: (transfer none): The `GArray`
     662                 :             :  */
     663                 :             : GArray*
     664                 :       21048 : g_array_prepend_vals (GArray        *farray,
     665                 :             :                       gconstpointer  data,
     666                 :             :                       guint          len)
     667                 :             : {
     668                 :       21048 :   GRealArray *array = (GRealArray*) farray;
     669                 :             : 
     670                 :       21048 :   g_return_val_if_fail (array, NULL);
     671                 :             : 
     672                 :       21046 :   if (len == 0)
     673                 :          16 :     return farray;
     674                 :             : 
     675                 :       21030 :   g_array_maybe_expand (array, len);
     676                 :             : 
     677                 :       31545 :   memmove (g_array_elt_pos (array, len), g_array_elt_pos (array, 0),
     678                 :       21030 :            g_array_elt_len (array, array->len));
     679                 :             : 
     680                 :       21030 :   memcpy (g_array_elt_pos (array, 0), data, g_array_elt_len (array, len));
     681                 :             : 
     682                 :       21030 :   array->len += len;
     683                 :             : 
     684                 :       21030 :   g_array_zero_terminate (array);
     685                 :             : 
     686                 :       21030 :   return farray;
     687                 :       10524 : }
     688                 :             : 
     689                 :             : /**
     690                 :             :  * g_array_insert_vals:
     691                 :             :  * @array: an array
     692                 :             :  * @index_: the index to place the elements at
     693                 :             :  * @data: (nullable): a pointer to the elements to insert
     694                 :             :  * @len: the number of elements to insert
     695                 :             :  *
     696                 :             :  * Inserts @len elements into a `GArray` at the given index.
     697                 :             :  *
     698                 :             :  * If @index_ is greater than the array’s current length, the array is expanded.
     699                 :             :  * The elements between the old end of the array and the newly inserted elements
     700                 :             :  * will be initialised to zero if the array was configured to clear elements;
     701                 :             :  * otherwise their values will be undefined.
     702                 :             :  *
     703                 :             :  * If @index_ is less than the array’s current length, new entries will be
     704                 :             :  * inserted into the array, and the existing entries above @index_ will be moved
     705                 :             :  * upwards.
     706                 :             :  *
     707                 :             :  * @data may be `NULL` if (and only if) @len is zero. If @len is zero, this
     708                 :             :  * function is a no-op.
     709                 :             :  *
     710                 :             :  * Returns: The `GArray`
     711                 :             :  */
     712                 :             : /**
     713                 :             :  * g_array_insert_val:
     714                 :             :  * @a: an array
     715                 :             :  * @i: the index to place the element at
     716                 :             :  * @v: the value to insert into the array
     717                 :             :  *
     718                 :             :  * Inserts an element into an array at the given index.
     719                 :             :  *
     720                 :             :  * `g_array_insert_val()` is a macro which uses a reference to the value
     721                 :             :  * parameter @v. This means that you cannot use it with literal values
     722                 :             :  * such as `"27"`. You must use variables.
     723                 :             :  *
     724                 :             :  * Returns: (transfer none): The `GArray`
     725                 :             :  */
     726                 :             : GArray*
     727                 :        7346 : g_array_insert_vals (GArray        *farray,
     728                 :             :                      guint          index_,
     729                 :             :                      gconstpointer  data,
     730                 :             :                      guint          len)
     731                 :             : {
     732                 :        7346 :   GRealArray *array = (GRealArray*) farray;
     733                 :             : 
     734                 :        7346 :   g_return_val_if_fail (array, NULL);
     735                 :             : 
     736                 :        7346 :   if (len == 0)
     737                 :          16 :     return farray;
     738                 :             : 
     739                 :             :   /* Is the index off the end of the array, and hence do we need to over-allocate
     740                 :             :    * and clear some elements? */
     741                 :        7330 :   if (index_ >= array->len)
     742                 :             :     {
     743                 :        3536 :       g_array_maybe_expand (array, index_ - array->len + len);
     744                 :        3536 :       return g_array_append_vals (g_array_set_size (farray, index_), data, len);
     745                 :             :     }
     746                 :             : 
     747                 :        3794 :   g_array_maybe_expand (array, len);
     748                 :             : 
     749                 :        4060 :   memmove (g_array_elt_pos (array, len + index_),
     750                 :        3794 :            g_array_elt_pos (array, index_),
     751                 :        3794 :            g_array_elt_len (array, array->len - index_));
     752                 :             : 
     753                 :        3794 :   memcpy (g_array_elt_pos (array, index_), data, g_array_elt_len (array, len));
     754                 :             : 
     755                 :        3794 :   array->len += len;
     756                 :             : 
     757                 :        3794 :   g_array_zero_terminate (array);
     758                 :             : 
     759                 :        3794 :   return farray;
     760                 :         631 : }
     761                 :             : 
     762                 :             : /**
     763                 :             :  * g_array_set_size:
     764                 :             :  * @array: an array
     765                 :             :  * @length: the new size of the #GArray
     766                 :             :  *
     767                 :             :  * Sets the size of the array, expanding it if necessary. If the array
     768                 :             :  * was created with @clear_ set to true, the new elements are set to 0.
     769                 :             :  *
     770                 :             :  * Returns: (transfer none): The `GArray`
     771                 :             :  */
     772                 :             : GArray*
     773                 :        9901 : g_array_set_size (GArray *farray,
     774                 :             :                   guint   length)
     775                 :             : {
     776                 :        9901 :   GRealArray *array = (GRealArray*) farray;
     777                 :             : 
     778                 :        9901 :   g_return_val_if_fail (array, NULL);
     779                 :             : 
     780                 :        9899 :   if (length > array->len)
     781                 :             :     {
     782                 :        4417 :       g_array_maybe_expand (array, length - array->len);
     783                 :             :       
     784                 :        4417 :       if (array->clear)
     785                 :        4142 :         g_array_elt_zero (array, array->len, length - array->len);
     786                 :        2337 :     }
     787                 :        5482 :   else if (length < array->len)
     788                 :         341 :     g_array_remove_range (farray, length, array->len - length);
     789                 :             : 
     790                 :        9899 :   array->len = length;
     791                 :             : 
     792                 :        9899 :   if (G_LIKELY (array->data != NULL))
     793                 :        9897 :     g_array_zero_terminate (array);
     794                 :             : 
     795                 :        9899 :   return farray;
     796                 :        3407 : }
     797                 :             : 
     798                 :             : /**
     799                 :             :  * g_array_remove_index:
     800                 :             :  * @array: an array
     801                 :             :  * @index_: the index of the element to remove
     802                 :             :  *
     803                 :             :  * Removes the element at the given index from a `GArray`. The following
     804                 :             :  * elements are moved down one place.
     805                 :             :  *
     806                 :             :  * Returns: (transfer none): The `GArray`
     807                 :             :  */
     808                 :             : GArray*
     809                 :         175 : g_array_remove_index (GArray *farray,
     810                 :             :                       guint   index_)
     811                 :             : {
     812                 :         175 :   GRealArray* array = (GRealArray*) farray;
     813                 :             : 
     814                 :         175 :   g_return_val_if_fail (array, NULL);
     815                 :             : 
     816                 :         173 :   g_return_val_if_fail (index_ < array->len, NULL);
     817                 :             : 
     818                 :         173 :   if (array->clear_func != NULL)
     819                 :           2 :     array->clear_func (g_array_elt_pos (array, index_));
     820                 :             : 
     821                 :         173 :   if (index_ != array->len - 1)
     822                 :         104 :     memmove (g_array_elt_pos (array, index_),
     823                 :          56 :              g_array_elt_pos (array, index_ + 1),
     824                 :          56 :              g_array_elt_len (array, array->len - index_ - 1));
     825                 :             : 
     826                 :         173 :   array->len -= 1;
     827                 :             : 
     828                 :         173 :   if (G_UNLIKELY (g_mem_gc_friendly))
     829                 :         173 :     g_array_elt_zero (array, array->len, 1);
     830                 :             :   else
     831                 :           0 :     g_array_zero_terminate (array);
     832                 :             : 
     833                 :         173 :   return farray;
     834                 :          37 : }
     835                 :             : 
     836                 :             : /**
     837                 :             :  * g_array_remove_index_fast:
     838                 :             :  * @array: an array
     839                 :             :  * @index_: the index of the element to remove
     840                 :             :  *
     841                 :             :  * Removes the element at the given index from a `GArray`. The last
     842                 :             :  * element in the array is used to fill in the space, so this function
     843                 :             :  * does not preserve the order of the `GArray`. But it is faster than
     844                 :             :  * [func@GLib.Array.remove_index].
     845                 :             :  *
     846                 :             :  * Returns: (transfer none): The `GArray`
     847                 :             :  */
     848                 :             : GArray*
     849                 :          44 : g_array_remove_index_fast (GArray *farray,
     850                 :             :                            guint   index_)
     851                 :             : {
     852                 :          44 :   GRealArray* array = (GRealArray*) farray;
     853                 :             : 
     854                 :          44 :   g_return_val_if_fail (array, NULL);
     855                 :             : 
     856                 :          42 :   g_return_val_if_fail (index_ < array->len, NULL);
     857                 :             : 
     858                 :          42 :   if (array->clear_func != NULL)
     859                 :           2 :     array->clear_func (g_array_elt_pos (array, index_));
     860                 :             : 
     861                 :          42 :   if (index_ != array->len - 1)
     862                 :          84 :     memcpy (g_array_elt_pos (array, index_),
     863                 :          42 :             g_array_elt_pos (array, array->len - 1),
     864                 :          42 :             g_array_elt_len (array, 1));
     865                 :             :   
     866                 :          42 :   array->len -= 1;
     867                 :             : 
     868                 :          42 :   if (G_UNLIKELY (g_mem_gc_friendly))
     869                 :          42 :     g_array_elt_zero (array, array->len, 1);
     870                 :             :   else
     871                 :           0 :     g_array_zero_terminate (array);
     872                 :             : 
     873                 :          42 :   return farray;
     874                 :          22 : }
     875                 :             : 
     876                 :             : /**
     877                 :             :  * g_array_remove_range:
     878                 :             :  * @array: an array
     879                 :             :  * @index_: the index of the first element to remove
     880                 :             :  * @length: the number of elements to remove
     881                 :             :  *
     882                 :             :  * Removes the given number of elements starting at the given index
     883                 :             :  * from a `GArray`. The following elements are moved to close the gap.
     884                 :             :  *
     885                 :             :  * Returns: (transfer none): The `GArray`
     886                 :             :  *
     887                 :             :  * Since: 2.4
     888                 :             :  */
     889                 :             : GArray*
     890                 :         375 : g_array_remove_range (GArray *farray,
     891                 :             :                       guint   index_,
     892                 :             :                       guint   length)
     893                 :             : {
     894                 :         375 :   GRealArray *array = (GRealArray*) farray;
     895                 :             : 
     896                 :         375 :   g_return_val_if_fail (array, NULL);
     897                 :         375 :   g_return_val_if_fail (index_ <= array->len, NULL);
     898                 :         375 :   g_return_val_if_fail (index_ <= G_MAXUINT - length, NULL);
     899                 :         375 :   g_return_val_if_fail (index_ + length <= array->len, NULL);
     900                 :             : 
     901                 :         375 :   if (length == 0)
     902                 :          12 :     return farray;
     903                 :             : 
     904                 :         363 :   if (array->clear_func != NULL)
     905                 :             :     {
     906                 :             :       guint i;
     907                 :             : 
     908                 :          48 :       for (i = 0; i < length; i++)
     909                 :          44 :         array->clear_func (g_array_elt_pos (array, index_ + i));
     910                 :           2 :     }
     911                 :             : 
     912                 :         363 :   if (index_ + length != array->len)
     913                 :          24 :     memmove (g_array_elt_pos (array, index_),
     914                 :          12 :              g_array_elt_pos (array, index_ + length),
     915                 :          12 :              g_array_elt_len (array, array->len - (index_ + length)));
     916                 :             : 
     917                 :         363 :   array->len -= length;
     918                 :         363 :   if (G_UNLIKELY (g_mem_gc_friendly))
     919                 :         363 :     g_array_elt_zero (array, array->len, length);
     920                 :             :   else
     921                 :           0 :     g_array_zero_terminate (array);
     922                 :             : 
     923                 :         363 :   return farray;
     924                 :         315 : }
     925                 :             : 
     926                 :             : /**
     927                 :             :  * g_array_sort:
     928                 :             :  * @array: an array
     929                 :             :  * @compare_func: (scope call): a comparison function
     930                 :             :  *
     931                 :             :  * Sorts a `GArray` using @compare_func which should be a `qsort()`-style
     932                 :             :  * comparison function (returns less than zero for first arg is less
     933                 :             :  * than second arg, zero for equal, greater zero if first arg is
     934                 :             :  * greater than second arg).
     935                 :             :  *
     936                 :             :  * This is guaranteed to be a stable sort since version 2.32.
     937                 :             :  */
     938                 :             : void
     939                 :        1561 : g_array_sort (GArray       *farray,
     940                 :             :               GCompareFunc  compare_func)
     941                 :             : {
     942                 :        1561 :   GRealArray *array = (GRealArray*) farray;
     943                 :             : 
     944                 :        1561 :   g_return_if_fail (array != NULL);
     945                 :             : 
     946                 :             :   /* Don't use qsort as we want a guaranteed stable sort */
     947                 :        1561 :   if (array->len > 0)
     948                 :        1808 :     g_sort_array (array->data,
     949                 :        1553 :                   array->len,
     950                 :        1553 :                   array->elt_size,
     951                 :         255 :                   (GCompareDataFunc) compare_func,
     952                 :             :                   NULL);
     953                 :         259 : }
     954                 :             : 
     955                 :             : /**
     956                 :             :  * g_array_sort_with_data:
     957                 :             :  * @array: an array
     958                 :             :  * @compare_func: (scope call): a comparison function
     959                 :             :  * @user_data: the data to pass to @compare_func
     960                 :             :  *
     961                 :             :  * Like [func@GLib.Array.sort], but the comparison function receives an extra
     962                 :             :  * user data argument.
     963                 :             :  *
     964                 :             :  * This is guaranteed to be a stable sort since version 2.32.
     965                 :             :  *
     966                 :             :  * There used to be a comment here about making the sort stable by
     967                 :             :  * using the addresses of the elements in the comparison function.
     968                 :             :  * This did not actually work, so any such code should be removed.
     969                 :             :  */
     970                 :             : void
     971                 :          18 : g_array_sort_with_data (GArray           *farray,
     972                 :             :                         GCompareDataFunc  compare_func,
     973                 :             :                         gpointer          user_data)
     974                 :             : {
     975                 :          18 :   GRealArray *array = (GRealArray*) farray;
     976                 :             : 
     977                 :          18 :   g_return_if_fail (array != NULL);
     978                 :             : 
     979                 :          18 :   if (array->len > 0)
     980                 :          15 :     g_sort_array (array->data,
     981                 :          10 :                   array->len,
     982                 :          10 :                   array->elt_size,
     983                 :           5 :                   compare_func,
     984                 :           5 :                   user_data);
     985                 :           9 : }
     986                 :             : 
     987                 :             : /**
     988                 :             :  * g_array_binary_search:
     989                 :             :  * @array: an array
     990                 :             :  * @target: a pointer to the item to look up
     991                 :             :  * @compare_func: (scope call): a comparison function to locate @target
     992                 :             :  * @out_match_index: (optional) (out): the return location
     993                 :             :  *    for the index of the element, if found
     994                 :             :  *
     995                 :             :  * Checks whether @target exists in @array by performing a binary
     996                 :             :  * search based on the given comparison function @compare_func which
     997                 :             :  * gets pointers to items as arguments. If the element is found, true
     998                 :             :  * is returned and the element’s index is returned in @out_match_index
     999                 :             :  * (if non-`NULL`). Otherwise, false is returned and @out_match_index
    1000                 :             :  * is undefined. This search is using a binary search, so the @array must
    1001                 :             :  * absolutely be sorted to return a correct result (if not, the function may
    1002                 :             :  * produce false-negative).
    1003                 :             :  *
    1004                 :             :  * This example defines a comparison function and searches an element in a
    1005                 :             :  * `GArray`:
    1006                 :             :  * ```c
    1007                 :             :  * static gint
    1008                 :             :  * cmpint (gconstpointer a, gconstpointer b)
    1009                 :             :  * {
    1010                 :             :  *   const gint *_a = a;
    1011                 :             :  *   const gint *_b = b;
    1012                 :             :  *
    1013                 :             :  *   return *_a - *_b;
    1014                 :             :  * }
    1015                 :             :  * ...
    1016                 :             :  * gint i = 424242;
    1017                 :             :  * guint matched_index;
    1018                 :             :  * gboolean result = g_array_binary_search (garray, &i, cmpint, &matched_index);
    1019                 :             :  * ...
    1020                 :             :  * ```
    1021                 :             :  *
    1022                 :             :  * Returns: true if @target is one of the elements of @array; false otherwise
    1023                 :             :  *
    1024                 :             :  * Since: 2.62
    1025                 :             :  */
    1026                 :             : gboolean
    1027                 :       40048 : g_array_binary_search (GArray        *array,
    1028                 :             :                        gconstpointer  target,
    1029                 :             :                        GCompareFunc   compare_func,
    1030                 :             :                        guint         *out_match_index)
    1031                 :             : {
    1032                 :       40048 :   gboolean result = FALSE;
    1033                 :       40048 :   GRealArray *_array = (GRealArray *) array;
    1034                 :       40048 :   guint left, middle = 0, right;
    1035                 :             :   gint val;
    1036                 :             : 
    1037                 :       40048 :   g_return_val_if_fail (_array != NULL, FALSE);
    1038                 :       40046 :   g_return_val_if_fail (compare_func != NULL, FALSE);
    1039                 :             : 
    1040                 :       40044 :   if (G_LIKELY(_array->len))
    1041                 :             :     {
    1042                 :       40042 :       left = 0;
    1043                 :       40042 :       right = _array->len - 1;
    1044                 :             : 
    1045                 :      494726 :       while (left <= right)
    1046                 :             :         {
    1047                 :      494710 :           middle = left + (right - left) / 2;
    1048                 :             : 
    1049                 :      494710 :           val = compare_func (g_array_elt_pos (_array, middle), target);
    1050                 :      494710 :           if (val == 0)
    1051                 :             :             {
    1052                 :       40012 :               result = TRUE;
    1053                 :       40012 :               break;
    1054                 :             :             }
    1055                 :      454698 :           else if (val < 0)
    1056                 :      236164 :             left = middle + 1;
    1057                 :      218534 :           else if (/* val > 0 && */ middle > 0)
    1058                 :      218520 :             right = middle - 1;
    1059                 :             :           else
    1060                 :          14 :             break;  /* element not found */
    1061                 :             :         }
    1062                 :       20021 :     }
    1063                 :             : 
    1064                 :       40044 :   if (result && out_match_index != NULL)
    1065                 :       20000 :     *out_match_index = middle;
    1066                 :             : 
    1067                 :       40044 :   return result;
    1068                 :       20024 : }
    1069                 :             : 
    1070                 :             : static void
    1071                 :      538302 : g_array_maybe_expand (GRealArray *array,
    1072                 :             :                       guint       len)
    1073                 :             : {
    1074                 :             :   guint want_len;
    1075                 :             : 
    1076                 :             :   /* Detect potential overflow */
    1077                 :      538302 :   if G_UNLIKELY ((array->max_len - array->len) < len)
    1078                 :           2 :     g_error ("adding %u to array would overflow", len);
    1079                 :             : 
    1080                 :      538300 :   want_len = array->len + len + array->zero_terminated;
    1081                 :      538300 :   if (want_len > array->elt_capacity)
    1082                 :             :     {
    1083                 :       13587 :       gsize want_alloc = g_nearest_pow (g_array_elt_len (array, want_len));
    1084                 :       13587 :       g_assert (want_alloc >= g_array_elt_len (array, want_len));
    1085                 :       13587 :       want_alloc = MAX (want_alloc, MIN_ARRAY_SIZE);
    1086                 :             : 
    1087                 :       13587 :       array->data = g_realloc (array->data, want_alloc);
    1088                 :             : 
    1089                 :       13587 :       if (G_UNLIKELY (g_mem_gc_friendly))
    1090                 :       15027 :         memset (g_array_elt_pos (array, array->elt_capacity), 0,
    1091                 :       11289 :                 g_array_elt_len (array, want_len - array->elt_capacity));
    1092                 :             : 
    1093                 :       13587 :       array->elt_capacity = MIN (want_alloc / array->elt_size, G_MAXUINT);
    1094                 :        4844 :     }
    1095                 :      538300 : }
    1096                 :             : 
    1097                 :             : typedef struct _GRealPtrArray  GRealPtrArray;
    1098                 :             : 
    1099                 :             : /**
    1100                 :             :  * GPtrArray: (copy-func g_ptr_array_ref) (free-func g_ptr_array_unref)
    1101                 :             :  * @pdata: a pointer to the array of pointers, which may be moved when the
    1102                 :             :  *     array grows
    1103                 :             :  * @len: the number of pointers in the array
    1104                 :             :  *
    1105                 :             :  * Contains the public fields of a `GPtrArray`.
    1106                 :             :  */
    1107                 :             : struct _GRealPtrArray
    1108                 :             : {
    1109                 :             :   gpointer       *pdata;
    1110                 :             :   guint           len;
    1111                 :             :   guint           alloc;
    1112                 :             :   gatomicrefcount ref_count;
    1113                 :             :   guint8          null_terminated : 1; /* always either 0 or 1, so it can be added to array lengths */
    1114                 :             :   GDestroyNotify  element_free_func;
    1115                 :             : };
    1116                 :             : 
    1117                 :             : /**
    1118                 :             :  * g_ptr_array_index:
    1119                 :             :  * @array: a pointer array
    1120                 :             :  * @index_: the index of the pointer to return
    1121                 :             :  *
    1122                 :             :  * Returns the pointer at the given index of the pointer array.
    1123                 :             :  *
    1124                 :             :  * This does not perform bounds checking on the given @index_,
    1125                 :             :  * so you are responsible for checking it against the array length.
    1126                 :             :  *
    1127                 :             :  * Returns: (transfer none): The pointer at the given index
    1128                 :             :  */
    1129                 :             : 
    1130                 :             : static void g_ptr_array_maybe_expand (GRealPtrArray *array,
    1131                 :             :                                       guint          len);
    1132                 :             : 
    1133                 :             : static void
    1134                 :     2847282 : ptr_array_maybe_null_terminate (GRealPtrArray *rarray)
    1135                 :             : {
    1136                 :     2847282 :   if (G_UNLIKELY (rarray->null_terminated))
    1137                 :      101771 :     rarray->pdata[rarray->len] = NULL;
    1138                 :     2847282 : }
    1139                 :             : 
    1140                 :             : static GPtrArray *
    1141                 :      288934 : ptr_array_new (guint reserved_size,
    1142                 :             :                GDestroyNotify element_free_func,
    1143                 :             :                gboolean null_terminated)
    1144                 :             : {
    1145                 :             :   GRealPtrArray *array;
    1146                 :             : 
    1147                 :      288934 :   array = g_slice_new (GRealPtrArray);
    1148                 :             : 
    1149                 :      288934 :   array->pdata = NULL;
    1150                 :      288934 :   array->len = 0;
    1151                 :      288934 :   array->alloc = 0;
    1152                 :      288934 :   array->null_terminated = null_terminated ? 1 : 0;
    1153                 :      288934 :   array->element_free_func = element_free_func;
    1154                 :             : 
    1155                 :      288934 :   g_atomic_ref_count_init (&array->ref_count);
    1156                 :             : 
    1157                 :      288934 :   if (reserved_size != 0)
    1158                 :             :     {
    1159                 :        1542 :       g_ptr_array_maybe_expand (array, reserved_size);
    1160                 :        1542 :       g_assert (array->pdata != NULL);
    1161                 :             : 
    1162                 :        1542 :       if (null_terminated)
    1163                 :             :         {
    1164                 :             :           /* don't use ptr_array_maybe_null_terminate(). It helps the compiler
    1165                 :             :            * to see when @null_terminated is false and thereby inline
    1166                 :             :            * ptr_array_new() and possibly remove the code entirely. */
    1167                 :         246 :           array->pdata[0] = NULL;
    1168                 :         117 :         }
    1169                 :         637 :     }
    1170                 :             : 
    1171                 :      288934 :   return (GPtrArray *) array;
    1172                 :             : }
    1173                 :             : 
    1174                 :             : /**
    1175                 :             :  * g_ptr_array_new:
    1176                 :             :  *
    1177                 :             :  * Creates a new `GPtrArray` with a reference count of 1.
    1178                 :             :  *
    1179                 :             :  * Returns: (transfer full): The new `GPtrArray`
    1180                 :             :  */
    1181                 :             : GPtrArray*
    1182                 :      264322 : g_ptr_array_new (void)
    1183                 :             : {
    1184                 :      264322 :   return ptr_array_new (0, NULL, FALSE);
    1185                 :             : }
    1186                 :             : 
    1187                 :             : /**
    1188                 :             :  * g_ptr_array_new_take: (skip)
    1189                 :             :  * @data: (array length=len) (transfer full) (nullable): an array of pointers
    1190                 :             :  * @len: the number of pointers in @data
    1191                 :             :  * @element_free_func: (nullable): a function to free elements on @array
    1192                 :             :  *   destruction
    1193                 :             :  *
    1194                 :             :  * Creates a new `GPtrArray` with @data as pointers, @len as length and a
    1195                 :             :  * reference count of 1.
    1196                 :             :  *
    1197                 :             :  * This avoids having to copy such data manually.
    1198                 :             :  * After this call, @data belongs to the `GPtrArray` and may no longer be
    1199                 :             :  * modified by the caller. The memory of @data has to be dynamically
    1200                 :             :  * allocated and will eventually be freed with [func@GLib.free].
    1201                 :             :  *
    1202                 :             :  * It also sets @element_free_func for freeing each element when the array is
    1203                 :             :  * destroyed either via [func@GLib.PtrArray.unref], when
    1204                 :             :  * [func@GLib.PtrArray.free] is called with @free_segment set to true or when
    1205                 :             :  * removing elements.
    1206                 :             :  *
    1207                 :             :  * Do not use it if @len is greater than [`G_MAXUINT`](types.html#guint).
    1208                 :             :  * `GPtrArray` stores the length of its data in `guint`, which may be shorter
    1209                 :             :  * than `gsize`.
    1210                 :             :  *
    1211                 :             :  * Returns: (transfer full): The new `GPtrArray`
    1212                 :             :  *
    1213                 :             :  * Since: 2.76
    1214                 :             :  */
    1215                 :             : GPtrArray *
    1216                 :         192 : g_ptr_array_new_take (gpointer       *data,
    1217                 :             :                       gsize           len,
    1218                 :             :                       GDestroyNotify  element_free_func)
    1219                 :             : {
    1220                 :             :   GPtrArray *array;
    1221                 :             :   GRealPtrArray *rarray;
    1222                 :             : 
    1223                 :         192 :   g_return_val_if_fail (data != NULL || len == 0, NULL);
    1224                 :         190 :   g_return_val_if_fail (len <= G_MAXUINT, NULL);
    1225                 :             : 
    1226                 :         189 :   array = ptr_array_new (0, element_free_func, FALSE);
    1227                 :         189 :   rarray = (GRealPtrArray *)array;
    1228                 :             : 
    1229                 :         189 :   rarray->pdata = g_steal_pointer (&data);
    1230                 :         189 :   rarray->len = len;
    1231                 :         189 :   rarray->alloc = len;
    1232                 :             : 
    1233                 :         189 :   return array;
    1234                 :          95 : }
    1235                 :             : 
    1236                 :             : /**
    1237                 :             :  * g_ptr_array_new_take_null_terminated: (skip)
    1238                 :             :  * @data: (array zero-terminated=1) (transfer full) (nullable): an array
    1239                 :             :  *  of pointers, `NULL` terminated
    1240                 :             :  * @element_free_func: (nullable): a function to free elements on @array
    1241                 :             :  *   destruction
    1242                 :             :  *
    1243                 :             :  * Creates a new `GPtrArray` with @data as pointers, computing the length of it
    1244                 :             :  * and setting the reference count to 1.
    1245                 :             :  *
    1246                 :             :  * This avoids having to copy such data manually.
    1247                 :             :  * After this call, @data belongs to the `GPtrArray` and may no longer be
    1248                 :             :  * modified by the caller. The memory of @data has to be dynamically
    1249                 :             :  * allocated and will eventually be freed with [func@GLib.free].
    1250                 :             :  *
    1251                 :             :  * The length is calculated by iterating through @data until the first `NULL`
    1252                 :             :  * element is found.
    1253                 :             :  *
    1254                 :             :  * It also sets @element_free_func for freeing each element when the array is
    1255                 :             :  * destroyed either via [func@GLib.PtrArray.unref], when
    1256                 :             :  * [func@GLib.PtrArray.free] is called with @free_segment set to true or when
    1257                 :             :  * removing elements.
    1258                 :             :  *
    1259                 :             :  * Do not use it if the @data length is greater than
    1260                 :             :  * [`G_MAXUINT`](types.html#guint). `GPtrArray` stores the length of its data
    1261                 :             :  * in `guint`, which may be shorter than `gsize`.
    1262                 :             :  *
    1263                 :             :  * Returns: (transfer full): The new `GPtrArray`
    1264                 :             :  *
    1265                 :             :  * Since: 2.76
    1266                 :             :  */
    1267                 :             : GPtrArray *
    1268                 :         181 : g_ptr_array_new_take_null_terminated (gpointer       *data,
    1269                 :             :                                       GDestroyNotify  element_free_func)
    1270                 :             : {
    1271                 :             :   GRealPtrArray *rarray;
    1272                 :             :   GPtrArray *array;
    1273                 :         181 :   gsize len = 0;
    1274                 :             : 
    1275                 :         181 :   if (data != NULL)
    1276                 :             :     {
    1277                 :       40358 :       for (gsize i = 0; data[i] != NULL; ++i)
    1278                 :       40179 :         len += 1;
    1279                 :          89 :     }
    1280                 :             : 
    1281                 :         181 :   g_return_val_if_fail (len < G_MAXUINT, NULL);
    1282                 :             : 
    1283                 :         181 :   array = g_ptr_array_new_take (g_steal_pointer (&data), len, element_free_func);
    1284                 :         181 :   rarray = (GRealPtrArray *) array;
    1285                 :         181 :   rarray->null_terminated = TRUE;
    1286                 :         181 :   if (G_LIKELY (rarray->pdata != NULL))
    1287                 :         179 :     rarray->alloc = len + 1;
    1288                 :             : 
    1289                 :         181 :   return array;
    1290                 :          90 : }
    1291                 :             : 
    1292                 :             : static GPtrArray *
    1293                 :          16 : ptr_array_new_from_array (gpointer       *data,
    1294                 :             :                           gsize           len,
    1295                 :             :                           GCopyFunc       copy_func,
    1296                 :             :                           gpointer        copy_func_user_data,
    1297                 :             :                           GDestroyNotify  element_free_func,
    1298                 :             :                           gboolean        null_terminated)
    1299                 :             : {
    1300                 :             :   GPtrArray *array;
    1301                 :             :   GRealPtrArray *rarray;
    1302                 :             : 
    1303                 :          16 :   g_assert (data != NULL || len == 0);
    1304                 :          16 :   g_assert (len <= G_MAXUINT - (null_terminated ? 1 : 0));
    1305                 :             : 
    1306                 :          16 :   array = ptr_array_new (len, element_free_func, null_terminated);
    1307                 :          16 :   rarray = (GRealPtrArray *)array;
    1308                 :             : 
    1309                 :          16 :   if (copy_func != NULL)
    1310                 :             :     {
    1311                 :       40004 :       for (gsize i = 0; i < len; i++)
    1312                 :       40000 :         rarray->pdata[i] = copy_func (data[i], copy_func_user_data);
    1313                 :           2 :     }
    1314                 :          12 :   else if (len != 0)
    1315                 :             :     {
    1316                 :           6 :       memcpy (rarray->pdata, data, len * sizeof (gpointer));
    1317                 :           3 :     }
    1318                 :             : 
    1319                 :          16 :   if (null_terminated && rarray->pdata != NULL)
    1320                 :           6 :     rarray->pdata[len] = NULL;
    1321                 :             : 
    1322                 :          16 :   rarray->len = len;
    1323                 :             : 
    1324                 :          16 :   return array;
    1325                 :             : }
    1326                 :             : 
    1327                 :             : /**
    1328                 :             :  * g_ptr_array_new_from_array: (skip)
    1329                 :             :  * @data: (array length=len) (transfer none) (nullable): an array of pointers
    1330                 :             :  * @len: the number of pointers in @data
    1331                 :             :  * @copy_func: (nullable): a copy function used to copy every element in the
    1332                 :             :  *   array
    1333                 :             :  * @copy_func_user_data: the user data passed to @copy_func
    1334                 :             :  * @element_free_func: (nullable): a function to free elements on @array
    1335                 :             :  *   destruction
    1336                 :             :  *
    1337                 :             :  * Creates a new `GPtrArray`, copying @len pointers from @data, and setting
    1338                 :             :  * the array’s reference count to 1.
    1339                 :             :  *
    1340                 :             :  * This avoids having to manually add each element one by one.
    1341                 :             :  *
    1342                 :             :  * If @copy_func is provided, then it is used to copy each element before
    1343                 :             :  * adding them to the new array. If it is `NULL` then the pointers are copied
    1344                 :             :  * directly.
    1345                 :             :  *
    1346                 :             :  * It also sets @element_free_func for freeing each element when the array is
    1347                 :             :  * destroyed either via [func@GLib.PtrArray.unref], when
    1348                 :             :  * [func@GLib.PtrArray.free] is called with @free_segment set to true or when
    1349                 :             :  * removing elements.
    1350                 :             :  *
    1351                 :             :  * Do not use it if @len is greater than [`G_MAXUINT`](types.html#guint).
    1352                 :             :  * `GPtrArray` stores the length of its data in `guint`, which may be shorter
    1353                 :             :  * than `gsize`.
    1354                 :             :  *
    1355                 :             :  * Returns: (transfer full): The new `GPtrArray`
    1356                 :             :  *
    1357                 :             :  * Since: 2.76
    1358                 :             :  */
    1359                 :             : GPtrArray *
    1360                 :           9 : g_ptr_array_new_from_array (gpointer       *data,
    1361                 :             :                             gsize           len,
    1362                 :             :                             GCopyFunc       copy_func,
    1363                 :             :                             gpointer        copy_func_user_data,
    1364                 :             :                             GDestroyNotify  element_free_func)
    1365                 :             : {
    1366                 :           9 :   g_return_val_if_fail (data != NULL || len == 0, NULL);
    1367                 :           7 :   g_return_val_if_fail (len <= G_MAXUINT, NULL);
    1368                 :             : 
    1369                 :           6 :   return ptr_array_new_from_array (
    1370                 :           3 :     data, len, copy_func, copy_func_user_data, element_free_func, FALSE);
    1371                 :           4 : }
    1372                 :             : 
    1373                 :             : /**
    1374                 :             :  * g_ptr_array_new_from_null_terminated_array: (skip)
    1375                 :             :  * @data: (array zero-terminated=1) (transfer none) (nullable): an array of
    1376                 :             :  *   pointers, `NULL` terminated
    1377                 :             :  * @copy_func: (nullable): a copy function used to copy every element in the
    1378                 :             :  *   array
    1379                 :             :  * @copy_func_user_data: the user data passed to @copy_func
    1380                 :             :  * @element_free_func: (nullable): a function to free elements on @array
    1381                 :             :  *   destruction
    1382                 :             :  *
    1383                 :             :  * Creates a new `GPtrArray` copying the pointers from @data after having
    1384                 :             :  * computed the length of it and with a reference count of 1.
    1385                 :             :  * This avoids having to manually add each element one by one.
    1386                 :             :  * If @copy_func is provided, then it is used to copy the data in the new
    1387                 :             :  * array.
    1388                 :             :  * It also sets @element_free_func for freeing each element when the array is
    1389                 :             :  * destroyed either via [func@GLib.PtrArray.unref], when
    1390                 :             :  * [func@GLib.PtrArray.free] is called with @free_segment set to true or when
    1391                 :             :  * removing elements.
    1392                 :             :  *
    1393                 :             :  * Do not use it if the @data has more than [`G_MAXUINT`](types.html#guint)
    1394                 :             :  * elements. `GPtrArray` stores the length of its data in `guint`, which may be
    1395                 :             :  * shorter than `gsize`.
    1396                 :             :  *
    1397                 :             :  * Returns: (transfer full): The new `GPtrArray`
    1398                 :             :  *
    1399                 :             :  * Since: 2.76
    1400                 :             :  */
    1401                 :             : GPtrArray *
    1402                 :          10 : g_ptr_array_new_from_null_terminated_array (gpointer       *data,
    1403                 :             :                                             GCopyFunc       copy_func,
    1404                 :             :                                             gpointer        copy_func_user_data,
    1405                 :             :                                             GDestroyNotify  element_free_func)
    1406                 :             : {
    1407                 :          10 :   gsize len = 0;
    1408                 :             : 
    1409                 :          10 :   if (data != NULL)
    1410                 :             :     {
    1411                 :       40016 :       for (gsize i = 0; data[i] != NULL; ++i)
    1412                 :       40008 :         len += 1;
    1413                 :           4 :     }
    1414                 :             : 
    1415                 :          10 :   g_assert (data != NULL || len == 0);
    1416                 :          10 :   g_return_val_if_fail (len < G_MAXUINT, NULL);
    1417                 :             : 
    1418                 :          10 :   return ptr_array_new_from_array (
    1419                 :           5 :     data, len, copy_func, copy_func_user_data, element_free_func, TRUE);
    1420                 :           5 : }
    1421                 :             : 
    1422                 :             : /**
    1423                 :             :  * g_ptr_array_steal:
    1424                 :             :  * @array: a pointer array
    1425                 :             :  * @len: (optional) (out): a pointer to retrieve the number of
    1426                 :             :  *    elements of the original array
    1427                 :             :  *
    1428                 :             :  * Frees the data in the array and resets the size to zero, while
    1429                 :             :  * the underlying array is preserved for use elsewhere and returned
    1430                 :             :  * to the caller.
    1431                 :             :  *
    1432                 :             :  * Note that if the array is `NULL` terminated this may still return
    1433                 :             :  * `NULL` if the length of the array was zero and pdata was not yet
    1434                 :             :  * allocated.
    1435                 :             :  *
    1436                 :             :  * Even if set, the [callback@GLib.DestroyNotify] function will never be called
    1437                 :             :  * on the current contents of the array and the caller is
    1438                 :             :  * responsible for freeing the array elements.
    1439                 :             :  *
    1440                 :             :  * An example of use:
    1441                 :             :  * ```c
    1442                 :             :  * g_autoptr(GPtrArray) chunk_buffer = g_ptr_array_new_with_free_func (g_bytes_unref);
    1443                 :             :  *
    1444                 :             :  * // Some part of your application appends a number of chunks to the pointer array.
    1445                 :             :  * g_ptr_array_add (chunk_buffer, g_bytes_new_static ("hello", 5));
    1446                 :             :  * g_ptr_array_add (chunk_buffer, g_bytes_new_static ("world", 5));
    1447                 :             :  *
    1448                 :             :  * …
    1449                 :             :  *
    1450                 :             :  * // Periodically, the chunks need to be sent as an array-and-length to some
    1451                 :             :  * // other part of the program.
    1452                 :             :  * GBytes **chunks;
    1453                 :             :  * gsize n_chunks;
    1454                 :             :  *
    1455                 :             :  * chunks = g_ptr_array_steal (chunk_buffer, &n_chunks);
    1456                 :             :  * for (gsize i = 0; i < n_chunks; i++)
    1457                 :             :  *   {
    1458                 :             :  *     // Do something with each chunk here, and then free them, since
    1459                 :             :  *     // g_ptr_array_steal() transfers ownership of all the elements and the
    1460                 :             :  *     // array to the caller.
    1461                 :             :  *     …
    1462                 :             :  *
    1463                 :             :  *     g_bytes_unref (chunks[i]);
    1464                 :             :  *   }
    1465                 :             :  *
    1466                 :             :  * g_free (chunks);
    1467                 :             :  *
    1468                 :             :  * // After calling g_ptr_array_steal(), the pointer array can be reused for the
    1469                 :             :  * // next set of chunks.
    1470                 :             :  * g_assert (chunk_buffer->len == 0);
    1471                 :             :  * ```
    1472                 :             :  *
    1473                 :             :  * Returns: (transfer full) (nullable) (array length=len): The allocated element data.
    1474                 :             :  *   This may be `NULL`if the array doesn’t have any elements (i.e. if `*len` is zero).
    1475                 :             :  *
    1476                 :             :  * Since: 2.64
    1477                 :             :  */
    1478                 :             : gpointer *
    1479                 :       31698 : g_ptr_array_steal (GPtrArray *array,
    1480                 :             :                    gsize *len)
    1481                 :             : {
    1482                 :             :   GRealPtrArray *rarray;
    1483                 :             :   gpointer *segment;
    1484                 :             : 
    1485                 :       31698 :   g_return_val_if_fail (array != NULL, NULL);
    1486                 :             : 
    1487                 :       31698 :   rarray = (GRealPtrArray *) array;
    1488                 :       31698 :   segment = (gpointer *) rarray->pdata;
    1489                 :             : 
    1490                 :       31698 :   if (len != NULL)
    1491                 :       30608 :     *len = rarray->len;
    1492                 :             : 
    1493                 :       31698 :   rarray->pdata = NULL;
    1494                 :       31698 :   rarray->len   = 0;
    1495                 :       31698 :   rarray->alloc = 0;
    1496                 :       31698 :   return segment;
    1497                 :       12896 : }
    1498                 :             : 
    1499                 :             : /**
    1500                 :             :  * g_ptr_array_copy:
    1501                 :             :  * @array: a pointer array to duplicate
    1502                 :             :  * @func: (scope call) (nullable): a copy function used to copy every element in the array
    1503                 :             :  * @user_data: the user data passed to the copy function @func
    1504                 :             :  *
    1505                 :             :  * Makes a full (deep) copy of a `GPtrArray`.
    1506                 :             :  *
    1507                 :             :  * @func, as a [callback@GLib.CopyFunc], takes two arguments, the data to be
    1508                 :             :  * copied
    1509                 :             :  * and a @user_data pointer. On common processor architectures, it’s safe to
    1510                 :             :  * pass `NULL` as @user_data if the copy function takes only one argument. You
    1511                 :             :  * may get compiler warnings from this though if compiling with GCC’s
    1512                 :             :  * `-Wcast-function-type` warning.
    1513                 :             :  *
    1514                 :             :  * If @func is `NULL`, then only the pointers (and not what they are
    1515                 :             :  * pointing to) are copied to the new `GPtrArray`.
    1516                 :             :  *
    1517                 :             :  * The copy of @array will have the same [callback@GLib.DestroyNotify] for its
    1518                 :             :  * elements as
    1519                 :             :  * @array. The copy will also be `NULL` terminated if (and only if) the source
    1520                 :             :  * array is.
    1521                 :             :  *
    1522                 :             :  * Returns: (transfer full): The deep copy of the initial `GPtrArray`
    1523                 :             :  *
    1524                 :             :  * Since: 2.62
    1525                 :             :  **/
    1526                 :             : GPtrArray *
    1527                 :          16 : g_ptr_array_copy (GPtrArray *array,
    1528                 :             :                   GCopyFunc  func,
    1529                 :             :                   gpointer   user_data)
    1530                 :             : {
    1531                 :          16 :   GRealPtrArray *rarray = (GRealPtrArray *) array;
    1532                 :             :   GPtrArray *new_array;
    1533                 :             : 
    1534                 :          16 :   g_return_val_if_fail (array != NULL, NULL);
    1535                 :             : 
    1536                 :          12 :   new_array = ptr_array_new (0,
    1537                 :           6 :                              rarray->element_free_func,
    1538                 :          12 :                              rarray->null_terminated);
    1539                 :             : 
    1540                 :          12 :   if (rarray->alloc > 0)
    1541                 :             :     {
    1542                 :           8 :       g_ptr_array_maybe_expand ((GRealPtrArray *) new_array, array->len);
    1543                 :             : 
    1544                 :           8 :       if (array->len > 0)
    1545                 :             :         {
    1546                 :           8 :           if (func != NULL)
    1547                 :             :             {
    1548                 :             :               guint i;
    1549                 :             : 
    1550                 :         404 :               for (i = 0; i < array->len; i++)
    1551                 :         400 :                 new_array->pdata[i] = func (array->pdata[i], user_data);
    1552                 :           2 :             }
    1553                 :             :           else
    1554                 :             :             {
    1555                 :           6 :               memcpy (new_array->pdata, array->pdata,
    1556                 :           4 :                       array->len * sizeof (*array->pdata));
    1557                 :             :             }
    1558                 :             : 
    1559                 :           8 :           new_array->len = array->len;
    1560                 :           4 :         }
    1561                 :             : 
    1562                 :           8 :       ptr_array_maybe_null_terminate ((GRealPtrArray *) new_array);
    1563                 :           4 :     }
    1564                 :             : 
    1565                 :          12 :   return new_array;
    1566                 :           8 : }
    1567                 :             : 
    1568                 :             : /**
    1569                 :             :  * g_ptr_array_sized_new:
    1570                 :             :  * @reserved_size: the number of pointers preallocated
    1571                 :             :  *
    1572                 :             :  * Creates a new `GPtrArray` with @reserved_size pointers preallocated
    1573                 :             :  * and a reference count of 1. This avoids frequent reallocation, if
    1574                 :             :  * you are going to add many pointers to the array. Note however that
    1575                 :             :  * the size of the array is still 0.
    1576                 :             :  *
    1577                 :             :  * Returns: (transfer full): The new `GPtrArray`
    1578                 :             :  */
    1579                 :             : GPtrArray*
    1580                 :         599 : g_ptr_array_sized_new (guint reserved_size)
    1581                 :             : {
    1582                 :         599 :   return ptr_array_new (reserved_size, NULL, FALSE);
    1583                 :             : }
    1584                 :             : 
    1585                 :             : /**
    1586                 :             :  * g_array_copy:
    1587                 :             :  * @array: an array
    1588                 :             :  *
    1589                 :             :  * Creates a shallow copy of a #GArray. If the array elements consist of
    1590                 :             :  * pointers to data, the pointers are copied but the actual data is not.
    1591                 :             :  *
    1592                 :             :  * Returns: (transfer container): The copy of @array
    1593                 :             :  *
    1594                 :             :  * Since: 2.62
    1595                 :             :  **/
    1596                 :             : GArray *
    1597                 :          84 : g_array_copy (GArray *array)
    1598                 :             : {
    1599                 :          84 :   GRealArray *rarray = (GRealArray *) array;
    1600                 :             :   GRealArray *new_rarray;
    1601                 :             : 
    1602                 :          84 :   g_return_val_if_fail (rarray != NULL, NULL);
    1603                 :             : 
    1604                 :          38 :   new_rarray =
    1605                 :         114 :       (GRealArray *) g_array_sized_new (rarray->zero_terminated, rarray->clear,
    1606                 :          38 :                                         rarray->elt_size, rarray->len);
    1607                 :          76 :   new_rarray->len = rarray->len;
    1608                 :          76 :   if (rarray->len > 0)
    1609                 :          10 :     memcpy (new_rarray->data, rarray->data, g_array_elt_len (rarray, rarray->len));
    1610                 :             : 
    1611                 :          76 :   g_array_zero_terminate (new_rarray);
    1612                 :             : 
    1613                 :          76 :   return (GArray *) new_rarray;
    1614                 :          42 : }
    1615                 :             : 
    1616                 :             : /**
    1617                 :             :  * g_ptr_array_new_with_free_func:
    1618                 :             :  * @element_free_func: (nullable): a function to free elements with
    1619                 :             :  *     destroy @array
    1620                 :             :  *
    1621                 :             :  * Creates a new `GPtrArray` with a reference count of 1 and use
    1622                 :             :  * @element_free_func for freeing each element when the array is destroyed
    1623                 :             :  * either via [func@GLib.PtrArray.unref], when [func@GLib.PtrArray.free] is
    1624                 :             :  * called with @free_segment set to true or when removing elements.
    1625                 :             :  *
    1626                 :             :  * Returns: (transfer full): The new `GPtrArray`
    1627                 :             :  *
    1628                 :             :  * Since: 2.22
    1629                 :             :  */
    1630                 :             : GPtrArray*
    1631                 :       19870 : g_ptr_array_new_with_free_func (GDestroyNotify element_free_func)
    1632                 :             : {
    1633                 :       19870 :   return ptr_array_new (0, element_free_func, FALSE);
    1634                 :             : }
    1635                 :             : 
    1636                 :             : /**
    1637                 :             :  * g_ptr_array_new_full:
    1638                 :             :  * @reserved_size: the number of pointers preallocated
    1639                 :             :  * @element_free_func: (nullable): a function to free elements with
    1640                 :             :  *     destroy @array
    1641                 :             :  *
    1642                 :             :  * Creates a new `GPtrArray` with @reserved_size pointers preallocated
    1643                 :             :  * and a reference count of 1. This avoids frequent reallocation, if
    1644                 :             :  * you are going to add many pointers to the array. Note however that
    1645                 :             :  * the size of the array is still 0. It also sets @element_free_func
    1646                 :             :  * for freeing each element when the array is destroyed either via
    1647                 :             :  * [func@GLib.PtrArray.unref], when [func@GLib.PtrArray.free] is called with
    1648                 :             :  * @free_segment set to true or when removing elements.
    1649                 :             :  *
    1650                 :             :  * Returns: (transfer full): The new `GPtrArray`
    1651                 :             :  *
    1652                 :             :  * Since: 2.30
    1653                 :             :  */
    1654                 :             : GPtrArray*
    1655                 :        3629 : g_ptr_array_new_full (guint          reserved_size,
    1656                 :             :                       GDestroyNotify element_free_func)
    1657                 :             : {
    1658                 :        3629 :   return ptr_array_new (reserved_size, element_free_func, FALSE);
    1659                 :             : }
    1660                 :             : 
    1661                 :             : /**
    1662                 :             :  * g_ptr_array_new_null_terminated:
    1663                 :             :  * @reserved_size: the number of pointers preallocated.
    1664                 :             :  *     If @null_terminated is `TRUE`, the actually allocated
    1665                 :             :  *     buffer size is @reserved_size plus 1, unless @reserved_size
    1666                 :             :  *     is zero, in which case no initial buffer gets allocated.
    1667                 :             :  * @element_free_func: (nullable): a function to free elements during
    1668                 :             :  *     destruction of @array
    1669                 :             :  * @null_terminated: if true, make the array `NULL` terminated
    1670                 :             :  *
    1671                 :             :  * Like [func@GLib.PtrArray.new_full] but also allows to set the array to
    1672                 :             :  * be `NULL` terminated. A `NULL` terminated pointer array has an
    1673                 :             :  * additional `NULL` pointer after the last element, beyond the
    1674                 :             :  * current length.
    1675                 :             :  *
    1676                 :             :  * `GPtrArray` created by other constructors are not automatically `NULL`
    1677                 :             :  * terminated.
    1678                 :             :  *
    1679                 :             :  * Note that if the @array’s length is zero and currently no
    1680                 :             :  * data array is allocated, then `pdata` will still be `NULL`.
    1681                 :             :  * `GPtrArray` will only `NULL` terminate `pdata`, if an actual
    1682                 :             :  * array is allocated. It does not guarantee that an array
    1683                 :             :  * is always allocated. In other words, if the length is zero,
    1684                 :             :  * then `pdata` may either point to a `NULL` terminated array of length
    1685                 :             :  * zero or be `NULL`.
    1686                 :             :  *
    1687                 :             :  * Returns: (transfer full): The new `GPtrArray`
    1688                 :             :  *
    1689                 :             :  * Since: 2.74
    1690                 :             :  */
    1691                 :             : GPtrArray *
    1692                 :         297 : g_ptr_array_new_null_terminated (guint          reserved_size,
    1693                 :             :                                  GDestroyNotify element_free_func,
    1694                 :             :                                  gboolean       null_terminated)
    1695                 :             : {
    1696                 :         297 :   return ptr_array_new (reserved_size, element_free_func, null_terminated);
    1697                 :             : }
    1698                 :             : 
    1699                 :             : /**
    1700                 :             :  * g_ptr_array_set_free_func:
    1701                 :             :  * @array: a pointer array
    1702                 :             :  * @element_free_func: (nullable): a function to free elements during
    1703                 :             :  *     destruction of @array
    1704                 :             :  *
    1705                 :             :  * Sets a function for freeing each element when @array is destroyed
    1706                 :             :  * either via [func@GLib.PtrArray.unref], when [func@GLib.PtrArray.free] is
    1707                 :             :  * called with @free_segment set to true or when removing elements.
    1708                 :             :  *
    1709                 :             :  * Since: 2.22
    1710                 :             :  */
    1711                 :             : void
    1712                 :          84 : g_ptr_array_set_free_func (GPtrArray      *array,
    1713                 :             :                            GDestroyNotify  element_free_func)
    1714                 :             : {
    1715                 :          84 :   GRealPtrArray *rarray = (GRealPtrArray *)array;
    1716                 :             : 
    1717                 :          84 :   g_return_if_fail (array);
    1718                 :             : 
    1719                 :          84 :   rarray->element_free_func = element_free_func;
    1720                 :           8 : }
    1721                 :             : 
    1722                 :             : /**
    1723                 :             :  * g_ptr_array_is_null_terminated:
    1724                 :             :  * @array: a pointer array
    1725                 :             :  *
    1726                 :             :  * Checks whether the @array was constructed as `NULL`-terminated.
    1727                 :             :  *
    1728                 :             :  * This will only return true for arrays constructed by passing true to the
    1729                 :             :  * `null_terminated` argument of [func@GLib.PtrArray.new_null_terminated]. It
    1730                 :             :  * will not return true for normal arrays which have had a `NULL` element
    1731                 :             :  * appended to them.
    1732                 :             :  *
    1733                 :             :  * Returns: true if the array is made to be `NULL` terminated; false otherwise
    1734                 :             :  *
    1735                 :             :  * Since: 2.74
    1736                 :             :  */
    1737                 :             : gboolean
    1738                 :       40188 : g_ptr_array_is_null_terminated (GPtrArray *array)
    1739                 :             : {
    1740                 :       40188 :   g_return_val_if_fail (array, FALSE);
    1741                 :             : 
    1742                 :       40188 :   return ((GRealPtrArray *) array)->null_terminated;
    1743                 :       20094 : }
    1744                 :             : 
    1745                 :             : /**
    1746                 :             :  * g_ptr_array_ref:
    1747                 :             :  * @array: a pointer array
    1748                 :             :  *
    1749                 :             :  * Atomically increments the reference count of @array by one.
    1750                 :             :  * This function is thread-safe and may be called from any thread.
    1751                 :             :  *
    1752                 :             :  * Returns: (transfer full): The passed in `GPtrArray`
    1753                 :             :  *
    1754                 :             :  * Since: 2.22
    1755                 :             :  */
    1756                 :             : GPtrArray*
    1757                 :         725 : g_ptr_array_ref (GPtrArray *array)
    1758                 :             : {
    1759                 :         725 :   GRealPtrArray *rarray = (GRealPtrArray *)array;
    1760                 :             : 
    1761                 :         725 :   g_return_val_if_fail (array, NULL);
    1762                 :             : 
    1763                 :         725 :   g_atomic_ref_count_inc (&rarray->ref_count);
    1764                 :             : 
    1765                 :         725 :   return array;
    1766                 :         339 : }
    1767                 :             : 
    1768                 :             : static gpointer *ptr_array_free (GPtrArray *, ArrayFreeFlags);
    1769                 :             : 
    1770                 :             : /**
    1771                 :             :  * g_ptr_array_unref:
    1772                 :             :  * @array: (transfer full): a pointer array
    1773                 :             :  *
    1774                 :             :  * Atomically decrements the reference count of @array by one. If the
    1775                 :             :  * reference count drops to 0, the effect is the same as calling
    1776                 :             :  * [func@GLib.PtrArray.free] with @free_segment set to true. This function
    1777                 :             :  * is thread-safe and may be called from any thread.
    1778                 :             :  *
    1779                 :             :  * Since: 2.22
    1780                 :             :  */
    1781                 :             : void
    1782                 :       17925 : g_ptr_array_unref (GPtrArray *array)
    1783                 :             : {
    1784                 :       17925 :   GRealPtrArray *rarray = (GRealPtrArray *)array;
    1785                 :             : 
    1786                 :       17925 :   g_return_if_fail (array);
    1787                 :             : 
    1788                 :       17925 :   if (g_atomic_ref_count_dec (&rarray->ref_count))
    1789                 :       17206 :     ptr_array_free (array, FREE_SEGMENT);
    1790                 :        5417 : }
    1791                 :             : 
    1792                 :             : /**
    1793                 :             :  * g_ptr_array_free:
    1794                 :             :  * @array: (transfer full): a pointer array
    1795                 :             :  * @free_segment: if true, the actual pointer array is freed as well
    1796                 :             :  *
    1797                 :             :  * Frees the memory allocated for the `GPtrArray`. If @free_segment is true
    1798                 :             :  * it frees the memory block holding the elements as well. Pass false
    1799                 :             :  * if you want to free the `GPtrArray` wrapper but preserve the
    1800                 :             :  * underlying array for use elsewhere. If the reference count of @array
    1801                 :             :  * is greater than one, the `GPtrArray` wrapper is preserved but the
    1802                 :             :  * size of @array will be set to zero.
    1803                 :             :  *
    1804                 :             :  * If array contents point to dynamically-allocated memory, they should
    1805                 :             :  * be freed separately if @free_segment is true and no
    1806                 :             :  * [callback@GLib.DestroyNotify] function has been set for @array.
    1807                 :             :  *
    1808                 :             :  * Note that if the array is `NULL` terminated and @free_segment is false
    1809                 :             :  * then this will always return an allocated `NULL` terminated buffer.
    1810                 :             :  * If `pdata` is previously `NULL`, a new buffer will be allocated.
    1811                 :             :  *
    1812                 :             :  * This function is not thread-safe. If using a `GPtrArray` from multiple
    1813                 :             :  * threads, use only the atomic [func@GLib.PtrArray.ref] and
    1814                 :             :  * [func@GLib.PtrArray.unref] functions.
    1815                 :             :  *
    1816                 :             :  * Returns: (transfer full) (array) (nullable): The allocated pointer array if
    1817                 :             :  *   @free_segment is false, otherwise `NULL`.
    1818                 :             :  */
    1819                 :             : gpointer*
    1820                 :      252795 : g_ptr_array_free (GPtrArray *array,
    1821                 :             :                   gboolean   free_segment)
    1822                 :             : {
    1823                 :      252795 :   GRealPtrArray *rarray = (GRealPtrArray *)array;
    1824                 :             :   ArrayFreeFlags flags;
    1825                 :             : 
    1826                 :      252795 :   g_return_val_if_fail (rarray, NULL);
    1827                 :             : 
    1828                 :      252795 :   flags = (free_segment ? FREE_SEGMENT : 0);
    1829                 :             : 
    1830                 :             :   /* if others are holding a reference, preserve the wrapper but
    1831                 :             :    * do free/return the data
    1832                 :             :    *
    1833                 :             :    * Coverity doesn’t understand this and assumes it’s a leak, so comment this
    1834                 :             :    * out.
    1835                 :             :    */
    1836                 :             : #ifndef __COVERITY__
    1837                 :      252795 :   if (!g_atomic_ref_count_dec (&rarray->ref_count))
    1838                 :           6 :     flags |= PRESERVE_WRAPPER;
    1839                 :             : #endif
    1840                 :             : 
    1841                 :      252795 :   return ptr_array_free (array, flags);
    1842                 :      108763 : }
    1843                 :             : 
    1844                 :             : static gpointer *
    1845                 :      270001 : ptr_array_free (GPtrArray      *array,
    1846                 :             :                 ArrayFreeFlags  flags)
    1847                 :             : {
    1848                 :      270001 :   GRealPtrArray *rarray = (GRealPtrArray *)array;
    1849                 :             :   gpointer *segment;
    1850                 :             : 
    1851                 :      270001 :   if (flags & FREE_SEGMENT)
    1852                 :             :     {
    1853                 :             :       /* Data here is stolen and freed manually. It is an
    1854                 :             :        * error to attempt to access the array data (including
    1855                 :             :        * mutating the array bounds) during destruction).
    1856                 :             :        *
    1857                 :             :        * https://bugzilla.gnome.org/show_bug.cgi?id=769064
    1858                 :             :        */
    1859                 :       55381 :       gpointer *stolen_pdata = g_steal_pointer (&rarray->pdata);
    1860                 :       55381 :       if (rarray->element_free_func != NULL)
    1861                 :             :         {
    1862                 :             :           guint i;
    1863                 :             : 
    1864                 :      329421 :           for (i = 0; i < rarray->len; ++i)
    1865                 :      323923 :             rarray->element_free_func (stolen_pdata[i]);
    1866                 :        3845 :         }
    1867                 :             : 
    1868                 :       55381 :       g_free (stolen_pdata);
    1869                 :       55381 :       segment = NULL;
    1870                 :       18138 :     }
    1871                 :             :   else
    1872                 :             :     {
    1873                 :      214620 :       segment = rarray->pdata;
    1874                 :      214620 :       if (!segment && rarray->null_terminated)
    1875                 :           7 :         segment = (gpointer *) g_new0 (char *, 1);
    1876                 :             :     }
    1877                 :             : 
    1878                 :      270001 :   if (flags & PRESERVE_WRAPPER)
    1879                 :             :     {
    1880                 :           6 :       rarray->pdata = NULL;
    1881                 :           6 :       rarray->len = 0;
    1882                 :           6 :       rarray->alloc = 0;
    1883                 :           3 :     }
    1884                 :             :   else
    1885                 :             :     {
    1886                 :      269995 :       g_slice_free1 (sizeof (GRealPtrArray), rarray);
    1887                 :             :     }
    1888                 :             : 
    1889                 :      270001 :   return segment;
    1890                 :             : }
    1891                 :             : 
    1892                 :             : static void
    1893                 :     2848789 : g_ptr_array_maybe_expand (GRealPtrArray *array,
    1894                 :             :                           guint          len)
    1895                 :             : {
    1896                 :             :   guint max_len, want_len;
    1897                 :             : 
    1898                 :             :   /* The maximum array length is derived from following constraints:
    1899                 :             :    * - The number of bytes must fit into a gsize / 2.
    1900                 :             :    * - The number of elements must fit into guint.
    1901                 :             :    * - null terminated arrays must leave space for the terminating element
    1902                 :             :    */
    1903                 :     2848789 :   max_len = MIN (G_MAXSIZE / 2 / sizeof (gpointer), G_MAXUINT) - (array->null_terminated ? 1 : 0);
    1904                 :             : 
    1905                 :             :   /* Detect potential overflow */
    1906                 :     2848789 :   if G_UNLIKELY ((max_len - array->len) < len)
    1907                 :           0 :     g_error ("adding %u to array would overflow", len);
    1908                 :             : 
    1909                 :     2848789 :   want_len = array->len + len + (array->null_terminated ? 1 : 0);
    1910                 :     2848789 :   if (want_len > array->alloc)
    1911                 :             :     {
    1912                 :      525098 :       guint old_alloc = array->alloc;
    1913                 :      525098 :       gsize want_alloc = g_nearest_pow (sizeof (gpointer) * want_len);
    1914                 :      525098 :       want_alloc = MAX (want_alloc, MIN_ARRAY_SIZE);
    1915                 :      525098 :       array->alloc = MIN (want_alloc / sizeof (gpointer), G_MAXUINT);
    1916                 :      525098 :       array->pdata = g_realloc (array->pdata, want_alloc);
    1917                 :      525098 :       if (G_UNLIKELY (g_mem_gc_friendly))
    1918                 :     2786614 :         for ( ; old_alloc < array->alloc; old_alloc++)
    1919                 :     2552917 :           array->pdata [old_alloc] = NULL;
    1920                 :      247125 :     }
    1921                 :     2848789 : }
    1922                 :             : 
    1923                 :             : /**
    1924                 :             :  * g_ptr_array_set_size:
    1925                 :             :  * @array: a pointer array
    1926                 :             :  * @length: the new length of the pointer array
    1927                 :             :  *
    1928                 :             :  * Sets the size of the array. When making the array larger,
    1929                 :             :  * newly-added elements will be set to `NULL`. When making it smaller,
    1930                 :             :  * if @array has a non-`NULL` [callback@GLib.DestroyNotify] function then it
    1931                 :             :  * will be called for the removed elements.
    1932                 :             :  */
    1933                 :             : void
    1934                 :     2003416 : g_ptr_array_set_size  (GPtrArray *array,
    1935                 :             :                        gint       length)
    1936                 :             : {
    1937                 :     2003416 :   GRealPtrArray *rarray = (GRealPtrArray *)array;
    1938                 :             :   guint length_unsigned;
    1939                 :             : 
    1940                 :     2003416 :   g_return_if_fail (rarray);
    1941                 :     2003416 :   g_return_if_fail (rarray->len == 0 || (rarray->len != 0 && rarray->pdata != NULL));
    1942                 :     2003416 :   g_return_if_fail (length >= 0);
    1943                 :             : 
    1944                 :     2003416 :   length_unsigned = (guint) length;
    1945                 :             : 
    1946                 :     2003416 :   if (length_unsigned > rarray->len)
    1947                 :             :     {
    1948                 :             :       guint i;
    1949                 :             : 
    1950                 :          13 :       g_ptr_array_maybe_expand (rarray, length_unsigned - rarray->len);
    1951                 :             : 
    1952                 :             :       /* This is not
    1953                 :             :        *     memset (array->pdata + array->len, 0,
    1954                 :             :        *            sizeof (gpointer) * (length_unsigned - array->len));
    1955                 :             :        * to make it really portable. Remember (void*)NULL needn't be
    1956                 :             :        * bitwise zero. It of course is silly not to use memset (..,0,..).
    1957                 :             :        */
    1958                 :          58 :       for (i = rarray->len; i < length_unsigned; i++)
    1959                 :          45 :         rarray->pdata[i] = NULL;
    1960                 :             : 
    1961                 :          13 :       rarray->len = length_unsigned;
    1962                 :             : 
    1963                 :          13 :       ptr_array_maybe_null_terminate (rarray);
    1964                 :           1 :     }
    1965                 :     2003403 :   else if (length_unsigned < rarray->len)
    1966                 :      903104 :     g_ptr_array_remove_range (array, length_unsigned, rarray->len - length_unsigned);
    1967                 :      489804 : }
    1968                 :             : 
    1969                 :             : static gpointer
    1970                 :      205961 : ptr_array_remove_index (GPtrArray *array,
    1971                 :             :                         guint      index_,
    1972                 :             :                         gboolean   fast,
    1973                 :             :                         gboolean   free_element)
    1974                 :             : {
    1975                 :      205961 :   GRealPtrArray *rarray = (GRealPtrArray *) array;
    1976                 :             :   gpointer result;
    1977                 :             : 
    1978                 :      205961 :   g_return_val_if_fail (rarray, NULL);
    1979                 :      205961 :   g_return_val_if_fail (rarray->len == 0 || (rarray->len != 0 && rarray->pdata != NULL), NULL);
    1980                 :             : 
    1981                 :      205961 :   g_return_val_if_fail (index_ < rarray->len, NULL);
    1982                 :             : 
    1983                 :      205961 :   result = rarray->pdata[index_];
    1984                 :             : 
    1985                 :      205961 :   if (rarray->element_free_func != NULL && free_element)
    1986                 :         927 :     rarray->element_free_func (rarray->pdata[index_]);
    1987                 :             : 
    1988                 :      205961 :   if (index_ != rarray->len - 1 && !fast)
    1989                 :         125 :     memmove (rarray->pdata + index_, rarray->pdata + index_ + 1,
    1990                 :         111 :              sizeof (gpointer) * (rarray->len - index_ - 1));
    1991                 :      205850 :   else if (index_ != rarray->len - 1)
    1992                 :      169723 :     rarray->pdata[index_] = rarray->pdata[rarray->len - 1];
    1993                 :             : 
    1994                 :      205961 :   rarray->len -= 1;
    1995                 :             : 
    1996                 :      205961 :   if (rarray->null_terminated || G_UNLIKELY (g_mem_gc_friendly))
    1997                 :      205933 :     rarray->pdata[rarray->len] = NULL;
    1998                 :             : 
    1999                 :      205961 :   return result;
    2000                 :       34919 : }
    2001                 :             : 
    2002                 :             : /**
    2003                 :             :  * g_ptr_array_remove_index:
    2004                 :             :  * @array: a pointer array
    2005                 :             :  * @index_: the index of the pointer to remove
    2006                 :             :  *
    2007                 :             :  * Removes the pointer at the given index from the pointer array.
    2008                 :             :  * The following elements are moved down one place. If @array has
    2009                 :             :  * a non-`NULL` [callback@GLib.DestroyNotify] function it is called for the
    2010                 :             :  * removed
    2011                 :             :  * element. If so, the return value from this function will potentially point
    2012                 :             :  * to freed memory (depending on the [callback@GLib.DestroyNotify]
    2013                 :             :  * implementation).
    2014                 :             :  *
    2015                 :             :  * Returns: (nullable): The pointer which was removed
    2016                 :             :  */
    2017                 :             : gpointer
    2018                 :         494 : g_ptr_array_remove_index (GPtrArray *array,
    2019                 :             :                           guint      index_)
    2020                 :             : {
    2021                 :         494 :   return ptr_array_remove_index (array, index_, FALSE, TRUE);
    2022                 :             : }
    2023                 :             : 
    2024                 :             : /**
    2025                 :             :  * g_ptr_array_remove_index_fast:
    2026                 :             :  * @array: a pointer array
    2027                 :             :  * @index_: the index of the pointer to remove
    2028                 :             :  *
    2029                 :             :  * Removes the pointer at the given index from the pointer array.
    2030                 :             :  * The last element in the array is used to fill in the space, so
    2031                 :             :  * this function does not preserve the order of the array. But it
    2032                 :             :  * is faster than [func@GLib.PtrArray.remove_index]. If @array has a non-`NULL`
    2033                 :             :  * [callback@GLib.DestroyNotify] function it is called for the removed element.
    2034                 :             :  * If so, the
    2035                 :             :  * return value from this function will potentially point to freed memory
    2036                 :             :  * (depending on the [callback@GLib.DestroyNotify] implementation).
    2037                 :             :  *
    2038                 :             :  * Returns: (nullable): The pointer which was removed
    2039                 :             :  */
    2040                 :             : gpointer
    2041                 :      143850 : g_ptr_array_remove_index_fast (GPtrArray *array,
    2042                 :             :                                guint      index_)
    2043                 :             : {
    2044                 :      143850 :   return ptr_array_remove_index (array, index_, TRUE, TRUE);
    2045                 :             : }
    2046                 :             : 
    2047                 :             : /**
    2048                 :             :  * g_ptr_array_steal_index:
    2049                 :             :  * @array: a pointer array
    2050                 :             :  * @index_: the index of the pointer to steal
    2051                 :             :  *
    2052                 :             :  * Removes the pointer at the given index from the pointer array.
    2053                 :             :  * The following elements are moved down one place. The
    2054                 :             :  * [callback@GLib.DestroyNotify] for
    2055                 :             :  * @array is *not* called on the removed element; ownership is transferred to
    2056                 :             :  * the caller of this function.
    2057                 :             :  *
    2058                 :             :  * Returns: (transfer full) (nullable): The pointer which was removed
    2059                 :             :  * Since: 2.58
    2060                 :             :  */
    2061                 :             : gpointer
    2062                 :           4 : g_ptr_array_steal_index (GPtrArray *array,
    2063                 :             :                          guint      index_)
    2064                 :             : {
    2065                 :           4 :   return ptr_array_remove_index (array, index_, FALSE, FALSE);
    2066                 :             : }
    2067                 :             : 
    2068                 :             : /**
    2069                 :             :  * g_ptr_array_steal_index_fast:
    2070                 :             :  * @array: a pointer array
    2071                 :             :  * @index_: the index of the pointer to steal
    2072                 :             :  *
    2073                 :             :  * Removes the pointer at the given index from the pointer array.
    2074                 :             :  * The last element in the array is used to fill in the space, so
    2075                 :             :  * this function does not preserve the order of the array. But it
    2076                 :             :  * is faster than [func@GLib.PtrArray.steal_index]. The
    2077                 :             :  * [callback@GLib.DestroyNotify] for @array is
    2078                 :             :  * *not* called on the removed element; ownership is transferred to the caller
    2079                 :             :  * of this function.
    2080                 :             :  *
    2081                 :             :  * Returns: (transfer full) (nullable): The pointer which was removed
    2082                 :             :  * Since: 2.58
    2083                 :             :  */
    2084                 :             : gpointer
    2085                 :       61613 : g_ptr_array_steal_index_fast (GPtrArray *array,
    2086                 :             :                               guint      index_)
    2087                 :             : {
    2088                 :       61613 :   return ptr_array_remove_index (array, index_, TRUE, FALSE);
    2089                 :             : }
    2090                 :             : 
    2091                 :             : /**
    2092                 :             :  * g_ptr_array_remove_range:
    2093                 :             :  * @array: a pointer array
    2094                 :             :  * @index_: the index of the first pointer to remove
    2095                 :             :  * @length: the number of pointers to remove
    2096                 :             :  *
    2097                 :             :  * Removes the given number of pointers starting at the given index
    2098                 :             :  * from a `GPtrArray`. The following elements are moved to close the
    2099                 :             :  * gap. If @array has a non-`NULL` [callback@GLib.DestroyNotify] function it is
    2100                 :             :  * called for the removed elements.
    2101                 :             :  *
    2102                 :             :  * Returns: (transfer none): The @array
    2103                 :             :  *
    2104                 :             :  * Since: 2.4
    2105                 :             :  */
    2106                 :             : GPtrArray*
    2107                 :      903114 : g_ptr_array_remove_range (GPtrArray *array,
    2108                 :             :                           guint      index_,
    2109                 :             :                           guint      length)
    2110                 :             : {
    2111                 :      903114 :   GRealPtrArray *rarray = (GRealPtrArray *)array;
    2112                 :             :   guint i;
    2113                 :             : 
    2114                 :      903114 :   g_return_val_if_fail (rarray != NULL, NULL);
    2115                 :      903114 :   g_return_val_if_fail (rarray->len == 0 || (rarray->len != 0 && rarray->pdata != NULL), NULL);
    2116                 :      903114 :   g_return_val_if_fail (index_ <= rarray->len, NULL);
    2117                 :      903114 :   g_return_val_if_fail (index_ <= G_MAXUINT - length, NULL);
    2118                 :      903114 :   g_return_val_if_fail (length == 0 || index_ + length <= rarray->len, NULL);
    2119                 :             : 
    2120                 :      903114 :   if (length == 0)
    2121                 :           2 :     return array;
    2122                 :             : 
    2123                 :      903112 :   if (rarray->element_free_func != NULL)
    2124                 :             :     {
    2125                 :         494 :       for (i = index_; i < index_ + length; i++)
    2126                 :         416 :         rarray->element_free_func (rarray->pdata[i]);
    2127                 :          10 :     }
    2128                 :             : 
    2129                 :      903112 :   if (index_ + length != rarray->len)
    2130                 :             :     {
    2131                 :           9 :       memmove (&rarray->pdata[index_],
    2132                 :           6 :                &rarray->pdata[index_ + length],
    2133                 :           6 :                (rarray->len - (index_ + length)) * sizeof (gpointer));
    2134                 :           3 :     }
    2135                 :             : 
    2136                 :      903112 :   rarray->len -= length;
    2137                 :      903112 :   if (G_UNLIKELY (g_mem_gc_friendly))
    2138                 :             :     {
    2139                 :     1837941 :       for (i = 0; i < length; i++)
    2140                 :      934865 :         rarray->pdata[rarray->len + i] = NULL;
    2141                 :      242606 :     }
    2142                 :             :   else
    2143                 :          36 :     ptr_array_maybe_null_terminate (rarray);
    2144                 :             : 
    2145                 :      903112 :   return array;
    2146                 :      242608 : }
    2147                 :             : 
    2148                 :             : /**
    2149                 :             :  * g_ptr_array_remove:
    2150                 :             :  * @array: a pointer array
    2151                 :             :  * @data: the pointer to remove
    2152                 :             :  *
    2153                 :             :  * Removes the first occurrence of the given pointer from the pointer
    2154                 :             :  * array. The following elements are moved down one place. If @array
    2155                 :             :  * has a non-`NULL` [callback@GLib.DestroyNotify] function it is called for the
    2156                 :             :  * removed element.
    2157                 :             :  *
    2158                 :             :  * It returns true if the pointer was removed, or false if the
    2159                 :             :  * pointer was not found.
    2160                 :             :  *
    2161                 :             :  * Returns: true if the pointer is found and removed; false otherwise
    2162                 :             :  */
    2163                 :             : gboolean
    2164                 :         445 : g_ptr_array_remove (GPtrArray *array,
    2165                 :             :                     gpointer   data)
    2166                 :             : {
    2167                 :             :   guint i;
    2168                 :             : 
    2169                 :         445 :   g_return_val_if_fail (array, FALSE);
    2170                 :         445 :   g_return_val_if_fail (array->len == 0 || (array->len != 0 && array->pdata != NULL), FALSE);
    2171                 :             : 
    2172                 :         566 :   for (i = 0; i < array->len; i += 1)
    2173                 :             :     {
    2174                 :         564 :       if (array->pdata[i] == data)
    2175                 :             :         {
    2176                 :         443 :           g_ptr_array_remove_index (array, i);
    2177                 :         443 :           return TRUE;
    2178                 :             :         }
    2179                 :           2 :     }
    2180                 :             : 
    2181                 :           2 :   return FALSE;
    2182                 :           8 : }
    2183                 :             : 
    2184                 :             : /**
    2185                 :             :  * g_ptr_array_remove_fast:
    2186                 :             :  * @array: a pointer array
    2187                 :             :  * @data: the pointer to remove
    2188                 :             :  *
    2189                 :             :  * Removes the first occurrence of the given pointer from the pointer
    2190                 :             :  * array. The last element in the array is used to fill in the space,
    2191                 :             :  * so this function does not preserve the order of the array. But it
    2192                 :             :  * is faster than [func@GLib.PtrArray.remove]. If @array has a non-`NULL`
    2193                 :             :  * [callback@GLib.DestroyNotify] function it is called for the removed element.
    2194                 :             :  *
    2195                 :             :  * It returns true if the pointer was removed, or false if the
    2196                 :             :  * pointer was not found.
    2197                 :             :  *
    2198                 :             :  * Returns: true if the pointer is found and removed; false otherwise
    2199                 :             :  */
    2200                 :             : gboolean
    2201                 :      142958 : g_ptr_array_remove_fast (GPtrArray *array,
    2202                 :             :                          gpointer   data)
    2203                 :             : {
    2204                 :      142958 :   GRealPtrArray *rarray = (GRealPtrArray *)array;
    2205                 :             :   guint i;
    2206                 :             : 
    2207                 :      142958 :   g_return_val_if_fail (rarray, FALSE);
    2208                 :      142958 :   g_return_val_if_fail (rarray->len == 0 || (rarray->len != 0 && rarray->pdata != NULL), FALSE);
    2209                 :             : 
    2210                 :      395023 :   for (i = 0; i < rarray->len; i += 1)
    2211                 :             :     {
    2212                 :      395021 :       if (rarray->pdata[i] == data)
    2213                 :             :         {
    2214                 :      142956 :           g_ptr_array_remove_index_fast (array, i);
    2215                 :      142956 :           return TRUE;
    2216                 :             :         }
    2217                 :       19573 :     }
    2218                 :             : 
    2219                 :           2 :   return FALSE;
    2220                 :        4567 : }
    2221                 :             : 
    2222                 :             : /**
    2223                 :             :  * g_ptr_array_add:
    2224                 :             :  * @array: a pointer array
    2225                 :             :  * @data: the pointer to add
    2226                 :             :  *
    2227                 :             :  * Adds a pointer to the end of the pointer array. The array will grow
    2228                 :             :  * in size automatically if necessary.
    2229                 :             :  */
    2230                 :             : void
    2231                 :     2810371 : g_ptr_array_add (GPtrArray *array,
    2232                 :             :                  gpointer   data)
    2233                 :             : {
    2234                 :     2810371 :   GRealPtrArray *rarray = (GRealPtrArray *)array;
    2235                 :             : 
    2236                 :     2810371 :   g_return_if_fail (rarray);
    2237                 :     2810371 :   g_return_if_fail (rarray->len == 0 || (rarray->len != 0 && rarray->pdata != NULL));
    2238                 :             : 
    2239                 :     2810371 :   g_ptr_array_maybe_expand (rarray, 1u);
    2240                 :             : 
    2241                 :     2810371 :   rarray->pdata[rarray->len++] = data;
    2242                 :             : 
    2243                 :     2810371 :   ptr_array_maybe_null_terminate (rarray);
    2244                 :     1087250 : }
    2245                 :             : 
    2246                 :             : /**
    2247                 :             :  * g_ptr_array_extend:
    2248                 :             :  * @array_to_extend: a pointer array
    2249                 :             :  * @array: (transfer none): a pointer array to add to the end of @array_to_extend
    2250                 :             :  * @func: (scope call) (nullable): a copy function used to copy every element in the array
    2251                 :             :  * @user_data: the user data passed to the copy function @func
    2252                 :             :  *
    2253                 :             :  * Adds all pointers of @array to the end of the array @array_to_extend.
    2254                 :             :  * The array will grow in size automatically if needed. @array_to_extend is
    2255                 :             :  * modified in-place.
    2256                 :             :  *
    2257                 :             :  * @func, as a [callback@GLib.CopyFunc], takes two arguments, the data to be
    2258                 :             :  * copied
    2259                 :             :  * and a @user_data pointer. On common processor architectures, it’s safe to
    2260                 :             :  * pass `NULL` as @user_data if the copy function takes only one argument. You
    2261                 :             :  * may get compiler warnings from this though if compiling with GCC’s
    2262                 :             :  * `-Wcast-function-type` warning.
    2263                 :             :  *
    2264                 :             :  * If @func is `NULL`, then only the pointers (and not what they are
    2265                 :             :  * pointing to) are copied to the new `GPtrArray`.
    2266                 :             :  *
    2267                 :             :  * Whether @array_to_extend is `NULL` terminated stays unchanged by this function.
    2268                 :             :  *
    2269                 :             :  * Since: 2.62
    2270                 :             :  **/
    2271                 :             : void
    2272                 :          32 : g_ptr_array_extend (GPtrArray  *array_to_extend,
    2273                 :             :                     GPtrArray  *array,
    2274                 :             :                     GCopyFunc   func,
    2275                 :             :                     gpointer    user_data)
    2276                 :             : {
    2277                 :          32 :   GRealPtrArray *rarray_to_extend = (GRealPtrArray *) array_to_extend;
    2278                 :             : 
    2279                 :          32 :   g_return_if_fail (array_to_extend != NULL);
    2280                 :          28 :   g_return_if_fail (array != NULL);
    2281                 :             : 
    2282                 :          24 :   if (array->len == 0u)
    2283                 :           8 :     return;
    2284                 :             : 
    2285                 :          16 :   g_ptr_array_maybe_expand (rarray_to_extend, array->len);
    2286                 :             : 
    2287                 :          16 :   if (func != NULL)
    2288                 :             :     {
    2289                 :             :       guint i;
    2290                 :             : 
    2291                 :         204 :       for (i = 0; i < array->len; i++)
    2292                 :         200 :         rarray_to_extend->pdata[i + rarray_to_extend->len] =
    2293                 :         200 :           func (array->pdata[i], user_data);
    2294                 :           2 :     }
    2295                 :          12 :   else if (array->len > 0)
    2296                 :             :     {
    2297                 :          18 :       memcpy (rarray_to_extend->pdata + rarray_to_extend->len, array->pdata,
    2298                 :          12 :               array->len * sizeof (*array->pdata));
    2299                 :           6 :     }
    2300                 :             : 
    2301                 :          16 :   rarray_to_extend->len += array->len;
    2302                 :             : 
    2303                 :          16 :   ptr_array_maybe_null_terminate (rarray_to_extend);
    2304                 :          16 : }
    2305                 :             : 
    2306                 :             : /**
    2307                 :             :  * g_ptr_array_extend_and_steal:
    2308                 :             :  * @array_to_extend: (transfer none): a pointer array
    2309                 :             :  * @array: (transfer container): a pointer array to add to the end of
    2310                 :             :  *     @array_to_extend
    2311                 :             :  *
    2312                 :             :  * Adds all the pointers in @array to the end of @array_to_extend, transferring
    2313                 :             :  * ownership of each element from @array to @array_to_extend and modifying
    2314                 :             :  * @array_to_extend in-place. @array is then freed.
    2315                 :             :  *
    2316                 :             :  * As with [func@GLib.PtrArray.free], @array will be destroyed if its reference
    2317                 :             :  * count is 1. If its reference count is higher, it will be decremented and the
    2318                 :             :  * length of @array set to zero.
    2319                 :             :  *
    2320                 :             :  * Since: 2.62
    2321                 :             :  **/
    2322                 :             : void
    2323                 :           8 : g_ptr_array_extend_and_steal (GPtrArray  *array_to_extend,
    2324                 :             :                               GPtrArray  *array)
    2325                 :             : {
    2326                 :             :   gpointer *pdata;
    2327                 :             : 
    2328                 :           8 :   g_return_if_fail (array_to_extend != NULL);
    2329                 :           6 :   g_return_if_fail (array != NULL);
    2330                 :             : 
    2331                 :           4 :   g_ptr_array_extend (array_to_extend, array, NULL, NULL);
    2332                 :             : 
    2333                 :             :   /* Get rid of @array without triggering the GDestroyNotify attached
    2334                 :             :    * to the elements moved from @array to @array_to_extend. */
    2335                 :           4 :   pdata = g_steal_pointer (&array->pdata);
    2336                 :           4 :   array->len = 0;
    2337                 :           4 :   ((GRealPtrArray *) array)->alloc = 0;
    2338                 :           4 :   g_ptr_array_unref (array);
    2339                 :           4 :   g_free (pdata);
    2340                 :           4 : }
    2341                 :             : 
    2342                 :             : /**
    2343                 :             :  * g_ptr_array_insert:
    2344                 :             :  * @array: a pointer array
    2345                 :             :  * @index_: the index to place the new element at, or -1 to append
    2346                 :             :  * @data: the pointer to add
    2347                 :             :  *
    2348                 :             :  * Inserts an element into the pointer array at the given index. The
    2349                 :             :  * array will grow in size automatically if necessary.
    2350                 :             :  *
    2351                 :             :  * Since: 2.40
    2352                 :             :  */
    2353                 :             : void
    2354                 :       36841 : g_ptr_array_insert (GPtrArray *array,
    2355                 :             :                     gint       index_,
    2356                 :             :                     gpointer   data)
    2357                 :             : {
    2358                 :       36841 :   GRealPtrArray *rarray = (GRealPtrArray *)array;
    2359                 :             :   guint real_index;
    2360                 :             : 
    2361                 :       36841 :   g_return_if_fail (rarray);
    2362                 :       36841 :   g_return_if_fail (index_ >= -1);
    2363                 :       36841 :   g_return_if_fail (index_ < 0 || (guint) index_ <= rarray->len);
    2364                 :             : 
    2365                 :       36841 :   g_ptr_array_maybe_expand (rarray, 1u);
    2366                 :             : 
    2367                 :       36841 :   real_index = (index_ >= 0) ? (guint) index_ : rarray->len;
    2368                 :             : 
    2369                 :       36841 :   if (real_index < rarray->len)
    2370                 :       31165 :     memmove (&(rarray->pdata[real_index + 1]),
    2371                 :       20619 :              &(rarray->pdata[real_index]),
    2372                 :       20619 :              (rarray->len - real_index) * sizeof (gpointer));
    2373                 :             : 
    2374                 :       36841 :   rarray->len++;
    2375                 :       36841 :   rarray->pdata[real_index] = data;
    2376                 :             : 
    2377                 :       36841 :   ptr_array_maybe_null_terminate (rarray);
    2378                 :       26720 : }
    2379                 :             : 
    2380                 :             : /* Please keep this doc-comment in sync with pointer_array_sort_example()
    2381                 :             :  * in glib/tests/array-test.c */
    2382                 :             : /**
    2383                 :             :  * g_ptr_array_sort:
    2384                 :             :  * @array: a pointer array
    2385                 :             :  * @compare_func: (scope call): a comparison function
    2386                 :             :  *
    2387                 :             :  * Sorts the array, using @compare_func which should be a `qsort()`-style
    2388                 :             :  * comparison function (returns less than zero for first arg is less
    2389                 :             :  * than second arg, zero for equal, greater than zero if first arg is
    2390                 :             :  * greater than second arg).
    2391                 :             :  *
    2392                 :             :  * Note that the comparison function for [func@GLib.PtrArray.sort] doesn’t
    2393                 :             :  * take the pointers from the array as arguments, it takes pointers to
    2394                 :             :  * the pointers in the array.
    2395                 :             :  *
    2396                 :             :  * Use [func@GLib.PtrArray.sort_values] if you want to use normal
    2397                 :             :  * [callback@GLib.CompareFunc] instances, otherwise here is a full example of
    2398                 :             :  * use:
    2399                 :             :  *
    2400                 :             :  * ```c
    2401                 :             :  * typedef struct
    2402                 :             :  * {
    2403                 :             :  *   gchar *name;
    2404                 :             :  *   gint size;
    2405                 :             :  * } FileListEntry;
    2406                 :             :  *
    2407                 :             :  * static gint
    2408                 :             :  * sort_filelist (gconstpointer a, gconstpointer b)
    2409                 :             :  * {
    2410                 :             :  *   const FileListEntry *entry1 = *((FileListEntry **) a);
    2411                 :             :  *   const FileListEntry *entry2 = *((FileListEntry **) b);
    2412                 :             :  *
    2413                 :             :  *   return g_ascii_strcasecmp (entry1->name, entry2->name);
    2414                 :             :  * }
    2415                 :             :  *
    2416                 :             :  * …
    2417                 :             :  * g_autoptr (GPtrArray) file_list = NULL;
    2418                 :             :  *
    2419                 :             :  * // initialize file_list array and load with many FileListEntry entries
    2420                 :             :  * ...
    2421                 :             :  * // now sort it with
    2422                 :             :  * g_ptr_array_sort (file_list, sort_filelist);
    2423                 :             :  * ```
    2424                 :             :  *
    2425                 :             :  * This is guaranteed to be a stable sort since version 2.32.
    2426                 :             :  */
    2427                 :             : void
    2428                 :         602 : g_ptr_array_sort (GPtrArray    *array,
    2429                 :             :                   GCompareFunc  compare_func)
    2430                 :             : {
    2431                 :         602 :   g_return_if_fail (array != NULL);
    2432                 :             : 
    2433                 :             :   /* Don't use qsort as we want a guaranteed stable sort */
    2434                 :         602 :   if (array->len > 0)
    2435                 :         883 :     g_sort_array (array->pdata,
    2436                 :         591 :                   array->len,
    2437                 :             :                   sizeof (gpointer),
    2438                 :         292 :                   (GCompareDataFunc) compare_func,
    2439                 :             :                   NULL);
    2440                 :         293 : }
    2441                 :             : 
    2442                 :             : /* Please keep this doc-comment in sync with
    2443                 :             :  * pointer_array_sort_with_data_example() in glib/tests/array-test.c */
    2444                 :             : /**
    2445                 :             :  * g_ptr_array_sort_with_data:
    2446                 :             :  * @array: a pointer array
    2447                 :             :  * @compare_func: (scope call): a comparison function
    2448                 :             :  * @user_data: the data to pass to @compare_func
    2449                 :             :  *
    2450                 :             :  * Like [func@GLib.PtrArray.sort], but the comparison function has an extra
    2451                 :             :  * user data argument.
    2452                 :             :  *
    2453                 :             :  * Note that the comparison function for [func@GLib.PtrArray.sort_with_data]
    2454                 :             :  * doesn’t take the pointers from the array as arguments, it takes
    2455                 :             :  * pointers to the pointers in the array.
    2456                 :             :  *
    2457                 :             :  * Use [func@GLib.PtrArray.sort_values_with_data] if you want to use normal
    2458                 :             :  * [callback@GLib.CompareDataFunc] instances, otherwise here is a full example
    2459                 :             :  * of use:
    2460                 :             :  *
    2461                 :             :  * ```c
    2462                 :             :  * typedef enum { SORT_NAME, SORT_SIZE } SortMode;
    2463                 :             :  *
    2464                 :             :  * typedef struct
    2465                 :             :  * {
    2466                 :             :  *   gchar *name;
    2467                 :             :  *   gint size;
    2468                 :             :  * } FileListEntry;
    2469                 :             :  *
    2470                 :             :  * static gint
    2471                 :             :  * sort_filelist (gconstpointer a, gconstpointer b, gpointer user_data)
    2472                 :             :  * {
    2473                 :             :  *   gint order;
    2474                 :             :  *   const SortMode sort_mode = GPOINTER_TO_INT (user_data);
    2475                 :             :  *   const FileListEntry *entry1 = *((FileListEntry **) a);
    2476                 :             :  *   const FileListEntry *entry2 = *((FileListEntry **) b);
    2477                 :             :  *
    2478                 :             :  *   switch (sort_mode)
    2479                 :             :  *     {
    2480                 :             :  *     case SORT_NAME:
    2481                 :             :  *       order = g_ascii_strcasecmp (entry1->name, entry2->name);
    2482                 :             :  *       break;
    2483                 :             :  *     case SORT_SIZE:
    2484                 :             :  *       order = entry1->size - entry2->size;
    2485                 :             :  *       break;
    2486                 :             :  *     default:
    2487                 :             :  *       order = 0;
    2488                 :             :  *       break;
    2489                 :             :  *     }
    2490                 :             :  *   return order;
    2491                 :             :  * }
    2492                 :             :  *
    2493                 :             :  * ...
    2494                 :             :  * g_autoptr (GPtrArray) file_list = NULL;
    2495                 :             :  * SortMode sort_mode;
    2496                 :             :  *
    2497                 :             :  * // initialize file_list array and load with many FileListEntry entries
    2498                 :             :  * ...
    2499                 :             :  * // now sort it with
    2500                 :             :  * sort_mode = SORT_NAME;
    2501                 :             :  * g_ptr_array_sort_with_data (file_list,
    2502                 :             :  *                             sort_filelist,
    2503                 :             :  *                             GINT_TO_POINTER (sort_mode));
    2504                 :             :  * ```
    2505                 :             :  *
    2506                 :             :  * This is guaranteed to be a stable sort since version 2.32.
    2507                 :             :  */
    2508                 :             : void
    2509                 :         118 : g_ptr_array_sort_with_data (GPtrArray        *array,
    2510                 :             :                             GCompareDataFunc  compare_func,
    2511                 :             :                             gpointer          user_data)
    2512                 :             : {
    2513                 :         118 :   g_return_if_fail (array != NULL);
    2514                 :             : 
    2515                 :         118 :   if (array->len > 0)
    2516                 :         122 :     g_sort_array (array->pdata,
    2517                 :         112 :                   array->len,
    2518                 :             :                   sizeof (gpointer),
    2519                 :          10 :                   compare_func,
    2520                 :          10 :                   user_data);
    2521                 :          13 : }
    2522                 :             : 
    2523                 :             : static inline gint
    2524                 :      241840 : compare_ptr_array_values (gconstpointer a, gconstpointer b, gpointer user_data)
    2525                 :             : {
    2526                 :      241840 :   gconstpointer aa = *((gconstpointer *) a);
    2527                 :      241840 :   gconstpointer bb = *((gconstpointer *) b);
    2528                 :      241840 :   GCompareFunc compare_func = user_data;
    2529                 :             : 
    2530                 :      241840 :   return compare_func (aa, bb);
    2531                 :             : }
    2532                 :             : 
    2533                 :             : /**
    2534                 :             :  * g_ptr_array_sort_values:
    2535                 :             :  * @array: a pointer array
    2536                 :             :  * @compare_func: (scope call): a comparison function
    2537                 :             :  *
    2538                 :             :  * Sorts the array, using @compare_func which should be a `qsort()`-style
    2539                 :             :  * comparison function (returns less than zero for first arg is less
    2540                 :             :  * than second arg, zero for equal, greater than zero if first arg is
    2541                 :             :  * greater than second arg).
    2542                 :             :  *
    2543                 :             :  * This is guaranteed to be a stable sort.
    2544                 :             :  *
    2545                 :             :  * Since: 2.76
    2546                 :             :  */
    2547                 :             : void
    2548                 :         102 : g_ptr_array_sort_values (GPtrArray    *array,
    2549                 :             :                          GCompareFunc  compare_func)
    2550                 :             : {
    2551                 :         102 :   g_ptr_array_sort_with_data (array, compare_ptr_array_values, compare_func);
    2552                 :         102 : }
    2553                 :             : 
    2554                 :             : typedef struct
    2555                 :             : {
    2556                 :             :   GCompareDataFunc compare_func;
    2557                 :             :   gpointer user_data;
    2558                 :             : } GPtrArraySortValuesData;
    2559                 :             : 
    2560                 :             : static inline gint
    2561                 :      240860 : compare_ptr_array_values_with_data (gconstpointer a,
    2562                 :             :                                     gconstpointer b,
    2563                 :             :                                     gpointer      user_data)
    2564                 :             : {
    2565                 :      240860 :   gconstpointer aa = *((gconstpointer *) a);
    2566                 :      240860 :   gconstpointer bb = *((gconstpointer *) b);
    2567                 :      240860 :   GPtrArraySortValuesData *data = user_data;
    2568                 :             : 
    2569                 :      240860 :   return data->compare_func (aa, bb, data->user_data);
    2570                 :             : }
    2571                 :             : 
    2572                 :             : /**
    2573                 :             :  * g_ptr_array_sort_values_with_data:
    2574                 :             :  * @array: a pointer array
    2575                 :             :  * @compare_func: (scope call): a comparison function
    2576                 :             :  * @user_data: the data to pass to @compare_func
    2577                 :             :  *
    2578                 :             :  * Like [func@GLib.PtrArray.sort_values], but the comparison function has an
    2579                 :             :  * extra user data argument.
    2580                 :             :  *
    2581                 :             :  * This is guaranteed to be a stable sort.
    2582                 :             :  *
    2583                 :             :  * Since: 2.76
    2584                 :             :  */
    2585                 :             : void
    2586                 :           8 : g_ptr_array_sort_values_with_data (GPtrArray        *array,
    2587                 :             :                                    GCompareDataFunc  compare_func,
    2588                 :             :                                    gpointer          user_data)
    2589                 :             : {
    2590                 :          12 :   g_ptr_array_sort_with_data (array, compare_ptr_array_values_with_data,
    2591                 :          16 :                               &(GPtrArraySortValuesData){
    2592                 :           4 :                                   .compare_func = compare_func,
    2593                 :           4 :                                   .user_data = user_data,
    2594                 :             :                               });
    2595                 :           8 : }
    2596                 :             : 
    2597                 :             : /**
    2598                 :             :  * g_ptr_array_foreach:
    2599                 :             :  * @array: a pointer array
    2600                 :             :  * @func: (scope call): the function to call for each array element
    2601                 :             :  * @user_data: the user data to pass to the function
    2602                 :             :  *
    2603                 :             :  * Calls a function for each element of a `GPtrArray`. @func must not
    2604                 :             :  * add elements to or remove elements from the array.
    2605                 :             :  *
    2606                 :             :  * Since: 2.4
    2607                 :             :  */
    2608                 :             : void
    2609                 :        6431 : g_ptr_array_foreach (GPtrArray *array,
    2610                 :             :                      GFunc      func,
    2611                 :             :                      gpointer   user_data)
    2612                 :             : {
    2613                 :             :   guint i;
    2614                 :             : 
    2615                 :        6431 :   g_return_if_fail (array);
    2616                 :             : 
    2617                 :       86448 :   for (i = 0; i < array->len; i++)
    2618                 :       80017 :     (*func) (array->pdata[i], user_data);
    2619                 :         249 : }
    2620                 :             : 
    2621                 :             : /**
    2622                 :             :  * g_ptr_array_find: (skip)
    2623                 :             :  * @haystack: the pointer array to be searched
    2624                 :             :  * @needle: the pointer to look for
    2625                 :             :  * @index_: (optional) (out): the return location for the index of
    2626                 :             :  *    the element, if found
    2627                 :             :  *
    2628                 :             :  * Checks whether @needle exists in @haystack. If the element is found, true
    2629                 :             :  * is returned and the element’s index is returned in @index_ (if non-`NULL`).
    2630                 :             :  * Otherwise, false is returned and @index_ is undefined. If @needle exists
    2631                 :             :  * multiple times in @haystack, the index of the first instance is returned.
    2632                 :             :  *
    2633                 :             :  * This does pointer comparisons only. If you want to use more complex equality
    2634                 :             :  * checks, such as string comparisons, use
    2635                 :             :  * [func@GLib.PtrArray.find_with_equal_func].
    2636                 :             :  *
    2637                 :             :  * Returns: true if @needle is one of the elements of @haystack; false otherwise
    2638                 :             :  * Since: 2.54
    2639                 :             :  */
    2640                 :             : gboolean
    2641                 :          20 : g_ptr_array_find (GPtrArray     *haystack,
    2642                 :             :                   gconstpointer  needle,
    2643                 :             :                   guint         *index_)
    2644                 :             : {
    2645                 :          20 :   return g_ptr_array_find_with_equal_func (haystack, needle, NULL, index_);
    2646                 :             : }
    2647                 :             : 
    2648                 :             : /**
    2649                 :             :  * g_ptr_array_find_with_equal_func: (skip)
    2650                 :             :  * @haystack: the pointer array to be searched
    2651                 :             :  * @needle: the pointer to look for
    2652                 :             :  * @equal_func: (nullable): the function to call for each element, which should
    2653                 :             :  *    return true when the desired element is found; or `NULL` to use pointer
    2654                 :             :  *    equality
    2655                 :             :  * @index_: (optional) (out): the return location for the index of
    2656                 :             :  *    the element, if found
    2657                 :             :  *
    2658                 :             :  * Checks whether @needle exists in @haystack, using the given @equal_func.
    2659                 :             :  * If the element is found, true is returned and the element’s index is
    2660                 :             :  * returned in @index_ (if non-`NULL`). Otherwise, false is returned and @index_
    2661                 :             :  * is undefined. If @needle exists multiple times in @haystack, the index of
    2662                 :             :  * the first instance is returned.
    2663                 :             :  *
    2664                 :             :  * @equal_func is called with the element from the array as its first parameter,
    2665                 :             :  * and @needle as its second parameter. If @equal_func is `NULL`, pointer
    2666                 :             :  * equality is used.
    2667                 :             :  *
    2668                 :             :  * Returns: true if @needle is one of the elements of @haystack; false otherwise
    2669                 :             :  * Since: 2.54
    2670                 :             :  */
    2671                 :             : gboolean
    2672                 :          48 : g_ptr_array_find_with_equal_func (GPtrArray     *haystack,
    2673                 :             :                                   gconstpointer  needle,
    2674                 :             :                                   GEqualFunc     equal_func,
    2675                 :             :                                   guint         *index_)
    2676                 :             : {
    2677                 :             :   guint i;
    2678                 :             : 
    2679                 :          48 :   g_return_val_if_fail (haystack != NULL, FALSE);
    2680                 :             : 
    2681                 :          48 :   if (equal_func == NULL)
    2682                 :          22 :     equal_func = g_direct_equal;
    2683                 :             : 
    2684                 :         110 :   for (i = 0; i < haystack->len; i++)
    2685                 :             :     {
    2686                 :         100 :       if (equal_func (g_ptr_array_index (haystack, i), needle))
    2687                 :             :         {
    2688                 :          38 :           if (index_ != NULL)
    2689                 :          10 :             *index_ = i;
    2690                 :          38 :           return TRUE;
    2691                 :             :         }
    2692                 :          31 :     }
    2693                 :             : 
    2694                 :          10 :   return FALSE;
    2695                 :          24 : }
    2696                 :             : 
    2697                 :             : /**
    2698                 :             :  * GByteArray: (copy-func g_byte_array_ref) (free-func g_byte_array_unref)
    2699                 :             :  * @data: a pointer to the element data. The data may be moved as
    2700                 :             :  *     elements are added to the `GByteArray`
    2701                 :             :  * @len: the number of elements in the `GByteArray`
    2702                 :             :  *
    2703                 :             :  * Contains the public fields of a `GByteArray`.
    2704                 :             :  */
    2705                 :             : 
    2706                 :             : /**
    2707                 :             :  * g_byte_array_new:
    2708                 :             :  *
    2709                 :             :  * Creates a new `GByteArray` with a reference count of 1.
    2710                 :             :  *
    2711                 :             :  * Returns: (transfer full): The new `GByteArray`
    2712                 :             :  */
    2713                 :             : GByteArray*
    2714                 :         853 : g_byte_array_new (void)
    2715                 :             : {
    2716                 :         853 :   return (GByteArray *)g_array_sized_new (FALSE, FALSE, 1, 0);
    2717                 :             : }
    2718                 :             : 
    2719                 :             : /**
    2720                 :             :  * g_byte_array_steal:
    2721                 :             :  * @array: a byte array
    2722                 :             :  * @len: (optional) (out): the pointer to retrieve the number of
    2723                 :             :  *    elements of the original array
    2724                 :             :  *
    2725                 :             :  * Frees the data in the array and resets the size to zero, while
    2726                 :             :  * the underlying array is preserved for use elsewhere and returned
    2727                 :             :  * to the caller.
    2728                 :             :  *
    2729                 :             :  * Returns: (transfer full) (array length=len): The allocated element data
    2730                 :             :  *
    2731                 :             :  * Since: 2.64
    2732                 :             :  */
    2733                 :             : guint8 *
    2734                 :           4 : g_byte_array_steal (GByteArray *array,
    2735                 :             :                     gsize *len)
    2736                 :             : {
    2737                 :           4 :   return (guint8 *) g_array_steal ((GArray *) array, len);
    2738                 :             : }
    2739                 :             : 
    2740                 :             : /**
    2741                 :             :  * g_byte_array_new_take:
    2742                 :             :  * @data: (transfer full) (array length=len): the byte data for the array
    2743                 :             :  * @len: the length of @data
    2744                 :             :  *
    2745                 :             :  * Creates a byte array containing the @data.
    2746                 :             :  * After this call, @data belongs to the `GByteArray` and may no longer be
    2747                 :             :  * modified by the caller. The memory of @data has to be dynamically
    2748                 :             :  * allocated and will eventually be freed with [func@GLib.free].
    2749                 :             :  *
    2750                 :             :  * Do not use it if @len is greater than [`G_MAXUINT`](types.html#guint).
    2751                 :             :  * `GByteArray` stores the length of its data in `guint`, which may be shorter
    2752                 :             :  * than `gsize`.
    2753                 :             :  *
    2754                 :             :  * Since: 2.32
    2755                 :             :  *
    2756                 :             :  * Returns: (transfer full): The new `GByteArray`
    2757                 :             :  */
    2758                 :             : GByteArray*
    2759                 :          11 : g_byte_array_new_take (guint8 *data,
    2760                 :             :                        gsize   len)
    2761                 :             : {
    2762                 :             :   GByteArray *array;
    2763                 :             :   GRealArray *real;
    2764                 :             : 
    2765                 :          11 :   g_return_val_if_fail (len <= G_MAXUINT, NULL);
    2766                 :           8 :   array = g_byte_array_new ();
    2767                 :           8 :   real = (GRealArray *)array;
    2768                 :           8 :   g_assert (real->data == NULL);
    2769                 :           8 :   g_assert (real->len == 0);
    2770                 :             : 
    2771                 :           8 :   real->data = data;
    2772                 :           8 :   real->len = len;
    2773                 :           8 :   real->elt_capacity = len;
    2774                 :             : 
    2775                 :           8 :   return array;
    2776                 :           5 : }
    2777                 :             : 
    2778                 :             : /**
    2779                 :             :  * g_byte_array_sized_new:
    2780                 :             :  * @reserved_size: the number of bytes preallocated
    2781                 :             :  *
    2782                 :             :  * Creates a new `GByteArray` with @reserved_size bytes preallocated.
    2783                 :             :  * This avoids frequent reallocation, if you are going to add many
    2784                 :             :  * bytes to the array. Note however that the size of the array is still
    2785                 :             :  * 0.
    2786                 :             :  *
    2787                 :             :  * Returns: (transfer full): The new `GByteArray`
    2788                 :             :  */
    2789                 :             : GByteArray*
    2790                 :          28 : g_byte_array_sized_new (guint reserved_size)
    2791                 :             : {
    2792                 :          28 :   return (GByteArray *)g_array_sized_new (FALSE, FALSE, 1, reserved_size);
    2793                 :             : }
    2794                 :             : 
    2795                 :             : /**
    2796                 :             :  * g_byte_array_free:
    2797                 :             :  * @array: (transfer full): a byte array
    2798                 :             :  * @free_segment: if true, the actual byte data is freed as well
    2799                 :             :  *
    2800                 :             :  * Frees the memory allocated by the `GByteArray`. If @free_segment is
    2801                 :             :  * true it frees the actual byte data. If the reference count of
    2802                 :             :  * @array is greater than one, the `GByteArray` wrapper is preserved but
    2803                 :             :  * the size of @array will be set to zero.
    2804                 :             :  *
    2805                 :             :  * Returns: (nullable) (array) (transfer full): The allocated element data if
    2806                 :             :  *   @free_segment is false, otherwise `NULL`.
    2807                 :             :  */
    2808                 :             : guint8*
    2809                 :         843 : g_byte_array_free (GByteArray *array,
    2810                 :             :                    gboolean    free_segment)
    2811                 :             : {
    2812                 :         843 :   return (guint8 *)g_array_free ((GArray *)array, free_segment);
    2813                 :             : }
    2814                 :             : 
    2815                 :             : /**
    2816                 :             :  * g_byte_array_free_to_bytes:
    2817                 :             :  * @array: (transfer full): a byte array
    2818                 :             :  *
    2819                 :             :  * Transfers the data from the `GByteArray` into a new immutable
    2820                 :             :  * [struct@GLib.Bytes].
    2821                 :             :  *
    2822                 :             :  * The `GByteArray` is freed unless the reference count of @array is greater
    2823                 :             :  * than one, in which the `GByteArray` wrapper is preserved but the size of
    2824                 :             :  * @array will be set to zero.
    2825                 :             :  *
    2826                 :             :  * This is identical to using [ctor@GLib.Bytes.new_take] and
    2827                 :             :  * [func@GLib.ByteArray.free] together.
    2828                 :             :  *
    2829                 :             :  * Since: 2.32
    2830                 :             :  *
    2831                 :             :  * Returns: (transfer full): The new immutable [struct@GLib.Bytes] representing
    2832                 :             :  *   same byte data that was in the array
    2833                 :             :  */
    2834                 :             : GBytes*
    2835                 :           2 : g_byte_array_free_to_bytes (GByteArray *array)
    2836                 :             : {
    2837                 :             :   gsize length;
    2838                 :             : 
    2839                 :           2 :   g_return_val_if_fail (array != NULL, NULL);
    2840                 :             : 
    2841                 :           2 :   length = array->len;
    2842                 :           2 :   return g_bytes_new_take (g_byte_array_free (array, FALSE), length);
    2843                 :           1 : }
    2844                 :             : 
    2845                 :             : /**
    2846                 :             :  * g_byte_array_ref:
    2847                 :             :  * @array: a byte array
    2848                 :             :  *
    2849                 :             :  * Atomically increments the reference count of @array by one.
    2850                 :             :  * This function is thread-safe and may be called from any thread.
    2851                 :             :  *
    2852                 :             :  * Returns: (transfer full): The passed in `GByteArray`
    2853                 :             :  *
    2854                 :             :  * Since: 2.22
    2855                 :             :  */
    2856                 :             : GByteArray*
    2857                 :           5 : g_byte_array_ref (GByteArray *array)
    2858                 :             : {
    2859                 :           5 :   return (GByteArray *)g_array_ref ((GArray *)array);
    2860                 :             : }
    2861                 :             : 
    2862                 :             : /**
    2863                 :             :  * g_byte_array_unref:
    2864                 :             :  * @array: (transfer full): a byte array
    2865                 :             :  *
    2866                 :             :  * Atomically decrements the reference count of @array by one. If the
    2867                 :             :  * reference count drops to 0, all memory allocated by the array is
    2868                 :             :  * released. This function is thread-safe and may be called from any
    2869                 :             :  * thread.
    2870                 :             :  *
    2871                 :             :  * Since: 2.22
    2872                 :             :  */
    2873                 :             : void
    2874                 :          43 : g_byte_array_unref (GByteArray *array)
    2875                 :             : {
    2876                 :          43 :   g_array_unref ((GArray *)array);
    2877                 :          43 : }
    2878                 :             : 
    2879                 :             : /**
    2880                 :             :  * g_byte_array_append:
    2881                 :             :  * @array: a byte array
    2882                 :             :  * @data: (array length=len): the byte data to be added
    2883                 :             :  * @len: the number of bytes to add
    2884                 :             :  *
    2885                 :             :  * Adds the given bytes to the end of the `GByteArray`.
    2886                 :             :  * The array will grow in size automatically if necessary.
    2887                 :             :  *
    2888                 :             :  * Returns: (transfer none): The `GByteArray`
    2889                 :             :  */
    2890                 :             : GByteArray*
    2891                 :       89346 : g_byte_array_append (GByteArray   *array,
    2892                 :             :                      const guint8 *data,
    2893                 :             :                      guint         len)
    2894                 :             : {
    2895                 :       89346 :   return (GByteArray *) g_array_append_vals ((GArray *) array, (guint8 *) data, len);
    2896                 :             : }
    2897                 :             : 
    2898                 :             : /**
    2899                 :             :  * g_byte_array_prepend:
    2900                 :             :  * @array: a byte array
    2901                 :             :  * @data: (array length=len): the byte data to be added
    2902                 :             :  * @len: the number of bytes to add
    2903                 :             :  *
    2904                 :             :  * Adds the given data to the start of the `GByteArray`.
    2905                 :             :  * The array will grow in size automatically if necessary.
    2906                 :             :  *
    2907                 :             :  * Returns: (transfer none): The `GByteArray`
    2908                 :             :  */
    2909                 :             : GByteArray*
    2910                 :       20002 : g_byte_array_prepend (GByteArray   *array,
    2911                 :             :                       const guint8 *data,
    2912                 :             :                       guint         len)
    2913                 :             : {
    2914                 :       20002 :   return (GByteArray *) g_array_prepend_vals ((GArray *) array, (guint8 *) data, len);
    2915                 :             : }
    2916                 :             : 
    2917                 :             : /**
    2918                 :             :  * g_byte_array_set_size:
    2919                 :             :  * @array: a byte array
    2920                 :             :  * @length: the new size of the `GByteArray`
    2921                 :             :  *
    2922                 :             :  * Sets the size of the `GByteArray`, expanding it if necessary.
    2923                 :             :  *
    2924                 :             :  * Returns: (transfer none): The `GByteArray`
    2925                 :             :  */
    2926                 :             : GByteArray*
    2927                 :           4 : g_byte_array_set_size (GByteArray *array,
    2928                 :             :                        guint       length)
    2929                 :             : {
    2930                 :           4 :   return (GByteArray *) g_array_set_size ((GArray *) array, length);
    2931                 :             : }
    2932                 :             : 
    2933                 :             : /**
    2934                 :             :  * g_byte_array_remove_index:
    2935                 :             :  * @array: a byte array
    2936                 :             :  * @index_: the index of the byte to remove
    2937                 :             :  *
    2938                 :             :  * Removes the byte at the given index from a `GByteArray`.
    2939                 :             :  * The following bytes are moved down one place.
    2940                 :             :  *
    2941                 :             :  * Returns: (transfer none): The `GByteArray`
    2942                 :             :  **/
    2943                 :             : GByteArray*
    2944                 :          12 : g_byte_array_remove_index (GByteArray *array,
    2945                 :             :                            guint       index_)
    2946                 :             : {
    2947                 :          12 :   return (GByteArray *) g_array_remove_index ((GArray *) array, index_);
    2948                 :             : }
    2949                 :             : 
    2950                 :             : /**
    2951                 :             :  * g_byte_array_remove_index_fast:
    2952                 :             :  * @array: a byte array
    2953                 :             :  * @index_: the index of the byte to remove
    2954                 :             :  *
    2955                 :             :  * Removes the byte at the given index from a `GByteArray`. The last
    2956                 :             :  * element in the array is used to fill in the space, so this function
    2957                 :             :  * does not preserve the order of the `GByteArray`. But it is faster
    2958                 :             :  * than [func@GLib.ByteArray.remove_index].
    2959                 :             :  *
    2960                 :             :  * Returns: (transfer none): The `GByteArray`
    2961                 :             :  */
    2962                 :             : GByteArray*
    2963                 :          10 : g_byte_array_remove_index_fast (GByteArray *array,
    2964                 :             :                                 guint       index_)
    2965                 :             : {
    2966                 :          10 :   return (GByteArray *) g_array_remove_index_fast ((GArray *) array, index_);
    2967                 :             : }
    2968                 :             : 
    2969                 :             : /**
    2970                 :             :  * g_byte_array_remove_range:
    2971                 :             :  * @array: a byte array
    2972                 :             :  * @index_: the index of the first byte to remove
    2973                 :             :  * @length: the number of bytes to remove
    2974                 :             :  *
    2975                 :             :  * Removes the given number of bytes starting at the given index from a
    2976                 :             :  * `GByteArray`. The following elements are moved to close the gap.
    2977                 :             :  *
    2978                 :             :  * Returns: (transfer none): The `GByteArray`
    2979                 :             :  *
    2980                 :             :  * Since: 2.4
    2981                 :             :  */
    2982                 :             : GByteArray*
    2983                 :           6 : g_byte_array_remove_range (GByteArray *array,
    2984                 :             :                            guint       index_,
    2985                 :             :                            guint       length)
    2986                 :             : {
    2987                 :           6 :   g_return_val_if_fail (array, NULL);
    2988                 :           6 :   g_return_val_if_fail (index_ <= array->len, NULL);
    2989                 :           6 :   g_return_val_if_fail (index_ <= G_MAXUINT - length, NULL);
    2990                 :           6 :   g_return_val_if_fail (index_ + length <= array->len, NULL);
    2991                 :             : 
    2992                 :           6 :   return (GByteArray *)g_array_remove_range ((GArray *)array, index_, length);
    2993                 :           3 : }
    2994                 :             : 
    2995                 :             : /**
    2996                 :             :  * g_byte_array_sort:
    2997                 :             :  * @array: a byte array
    2998                 :             :  * @compare_func: (scope call): the comparison function
    2999                 :             :  *
    3000                 :             :  * Sorts a byte array, using @compare_func which should be a
    3001                 :             :  * `qsort()`-style comparison function (returns less than zero for first
    3002                 :             :  * arg is less than second arg, zero for equal, greater than zero if
    3003                 :             :  * first arg is greater than second arg).
    3004                 :             :  *
    3005                 :             :  * If two array elements compare equal, their order in the sorted array
    3006                 :             :  * is undefined. If you want equal elements to keep their order (i.e.
    3007                 :             :  * you want a stable sort) you can write a comparison function that,
    3008                 :             :  * if two elements would otherwise compare equal, compares them by
    3009                 :             :  * their addresses.
    3010                 :             :  */
    3011                 :             : void
    3012                 :           2 : g_byte_array_sort (GByteArray   *array,
    3013                 :             :                    GCompareFunc  compare_func)
    3014                 :             : {
    3015                 :           2 :   g_array_sort ((GArray *)array, compare_func);
    3016                 :           2 : }
    3017                 :             : 
    3018                 :             : /**
    3019                 :             :  * g_byte_array_sort_with_data:
    3020                 :             :  * @array: a byte array
    3021                 :             :  * @compare_func: (scope call): the comparison function
    3022                 :             :  * @user_data: the data to pass to @compare_func
    3023                 :             :  *
    3024                 :             :  * Like [func@GLib.ByteArray.sort], but the comparison function takes an extra
    3025                 :             :  * user data argument.
    3026                 :             :  */
    3027                 :             : void
    3028                 :           2 : g_byte_array_sort_with_data (GByteArray       *array,
    3029                 :             :                              GCompareDataFunc  compare_func,
    3030                 :             :                              gpointer          user_data)
    3031                 :             : {
    3032                 :           2 :   g_array_sort_with_data ((GArray *)array, compare_func, user_data);
    3033                 :           2 : }
        

Generated by: LCOV version 2.0-1