Coverage Report

Created: 2026-02-26 06:27

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