Coverage Report

Created: 2025-08-29 06:32

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