Coverage Report

Created: 2025-08-29 06:18

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