Coverage Report

Created: 2026-02-24 07:11

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