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 #define g_array_elt_len(array,i) ((array)->elt_size * (i))
154 #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 (memset (g_array_elt_pos ((array), pos), 0, g_array_elt_len ((array), len)))
157 #define g_array_zero_terminate(array) G_STMT_START{ \
158 if ((array)->zero_terminated) \
159 g_array_elt_zero ((array), (array)->len, 1); \
160 }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*
g_array_new(gboolean zero_terminated,gboolean clear,guint elt_size)179 g_array_new (gboolean zero_terminated,
180 gboolean clear,
181 guint elt_size)
182 {
183 g_return_val_if_fail (elt_size > 0, NULL);
184
185 return g_array_sized_new (zero_terminated, clear, elt_size, 0);
186 }
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
g_array_steal(GArray * array,gsize * len)219 g_array_steal (GArray *array,
220 gsize *len)
221 {
222 GRealArray *rarray;
223 gpointer segment;
224
225 g_return_val_if_fail (array != NULL, NULL);
226
227 rarray = (GRealArray *) array;
228 segment = (gpointer) rarray->data;
229
230 if (len != NULL)
231 *len = rarray->len;
232
233 rarray->data = NULL;
234 rarray->len = 0;
235 rarray->alloc = 0;
236 return segment;
237 }
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*
g_array_sized_new(gboolean zero_terminated,gboolean clear,guint elt_size,guint reserved_size)256 g_array_sized_new (gboolean zero_terminated,
257 gboolean clear,
258 guint elt_size,
259 guint reserved_size)
260 {
261 GRealArray *array;
262
263 g_return_val_if_fail (elt_size > 0, NULL);
264
265 array = g_slice_new (GRealArray);
266
267 array->data = NULL;
268 array->len = 0;
269 array->alloc = 0;
270 array->zero_terminated = (zero_terminated ? 1 : 0);
271 array->clear = (clear ? 1 : 0);
272 array->elt_size = elt_size;
273 array->clear_func = NULL;
274
275 g_atomic_ref_count_init (&array->ref_count);
276
277 if (array->zero_terminated || reserved_size != 0)
278 {
279 g_array_maybe_expand (array, reserved_size);
280 g_array_zero_terminate(array);
281 }
282
283 return (GArray*) array;
284 }
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
g_array_set_clear_func(GArray * array,GDestroyNotify clear_func)305 g_array_set_clear_func (GArray *array,
306 GDestroyNotify clear_func)
307 {
308 GRealArray *rarray = (GRealArray *) array;
309
310 g_return_if_fail (array != NULL);
311
312 rarray->clear_func = clear_func;
313 }
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 *
g_array_ref(GArray * array)327 g_array_ref (GArray *array)
328 {
329 GRealArray *rarray = (GRealArray*) array;
330 g_return_val_if_fail (array, NULL);
331
332 g_atomic_ref_count_inc (&rarray->ref_count);
333
334 return array;
335 }
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
g_array_unref(GArray * array)357 g_array_unref (GArray *array)
358 {
359 GRealArray *rarray = (GRealArray*) array;
360 g_return_if_fail (array);
361
362 if (g_atomic_ref_count_dec (&rarray->ref_count))
363 array_free (rarray, FREE_SEGMENT);
364 }
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
g_array_get_element_size(GArray * array)377 g_array_get_element_size (GArray *array)
378 {
379 GRealArray *rarray = (GRealArray*) array;
380
381 g_return_val_if_fail (array, 0);
382
383 return rarray->elt_size;
384 }
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*
g_array_free(GArray * farray,gboolean free_segment)410 g_array_free (GArray *farray,
411 gboolean free_segment)
412 {
413 GRealArray *array = (GRealArray*) farray;
414 ArrayFreeFlags flags;
415
416 g_return_val_if_fail (array, NULL);
417
418 flags = (free_segment ? FREE_SEGMENT : 0);
419
420 /* if others are holding a reference, preserve the wrapper but do free/return the data */
421 if (!g_atomic_ref_count_dec (&array->ref_count))
422 flags |= PRESERVE_WRAPPER;
423
424 return array_free (array, flags);
425 }
426
427 static gchar *
array_free(GRealArray * array,ArrayFreeFlags flags)428 array_free (GRealArray *array,
429 ArrayFreeFlags flags)
430 {
431 gchar *segment;
432
433 if (flags & FREE_SEGMENT)
434 {
435 if (array->clear_func != NULL)
436 {
437 guint i;
438
439 for (i = 0; i < array->len; i++)
440 array->clear_func (g_array_elt_pos (array, i));
441 }
442
443 g_free (array->data);
444 segment = NULL;
445 }
446 else
447 segment = (gchar*) array->data;
448
449 if (flags & PRESERVE_WRAPPER)
450 {
451 array->data = NULL;
452 array->len = 0;
453 array->alloc = 0;
454 }
455 else
456 {
457 g_slice_free1 (sizeof (GRealArray), array);
458 }
459
460 return segment;
461 }
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*
g_array_append_vals(GArray * farray,gconstpointer data,guint len)488 g_array_append_vals (GArray *farray,
489 gconstpointer data,
490 guint len)
491 {
492 GRealArray *array = (GRealArray*) farray;
493
494 g_return_val_if_fail (array, NULL);
495
496 if (len == 0)
497 return farray;
498
499 g_array_maybe_expand (array, len);
500
501 memcpy (g_array_elt_pos (array, array->len), data,
502 g_array_elt_len (array, len));
503
504 array->len += len;
505
506 g_array_zero_terminate (array);
507
508 return farray;
509 }
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*
g_array_prepend_vals(GArray * farray,gconstpointer data,guint len)547 g_array_prepend_vals (GArray *farray,
548 gconstpointer data,
549 guint len)
550 {
551 GRealArray *array = (GRealArray*) farray;
552
553 g_return_val_if_fail (array, NULL);
554
555 if (len == 0)
556 return farray;
557
558 g_array_maybe_expand (array, len);
559
560 memmove (g_array_elt_pos (array, len), g_array_elt_pos (array, 0),
561 g_array_elt_len (array, array->len));
562
563 memcpy (g_array_elt_pos (array, 0), data, g_array_elt_len (array, len));
564
565 array->len += len;
566
567 g_array_zero_terminate (array);
568
569 return farray;
570 }
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*
g_array_insert_vals(GArray * farray,guint index_,gconstpointer data,guint len)610 g_array_insert_vals (GArray *farray,
611 guint index_,
612 gconstpointer data,
613 guint len)
614 {
615 GRealArray *array = (GRealArray*) farray;
616
617 g_return_val_if_fail (array, NULL);
618
619 if (len == 0)
620 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 if (index_ >= array->len)
625 {
626 g_array_maybe_expand (array, index_ - array->len + len);
627 return g_array_append_vals (g_array_set_size (farray, index_), data, len);
628 }
629
630 g_array_maybe_expand (array, len);
631
632 memmove (g_array_elt_pos (array, len + index_),
633 g_array_elt_pos (array, index_),
634 g_array_elt_len (array, array->len - index_));
635
636 memcpy (g_array_elt_pos (array, index_), data, g_array_elt_len (array, len));
637
638 array->len += len;
639
640 g_array_zero_terminate (array);
641
642 return farray;
643 }
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*
g_array_set_size(GArray * farray,guint length)656 g_array_set_size (GArray *farray,
657 guint length)
658 {
659 GRealArray *array = (GRealArray*) farray;
660
661 g_return_val_if_fail (array, NULL);
662
663 if (length > array->len)
664 {
665 g_array_maybe_expand (array, length - array->len);
666
667 if (array->clear)
668 g_array_elt_zero (array, array->len, length - array->len);
669 }
670 else if (length < array->len)
671 g_array_remove_range (farray, length, array->len - length);
672
673 array->len = length;
674
675 g_array_zero_terminate (array);
676
677 return farray;
678 }
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*
g_array_remove_index(GArray * farray,guint index_)691 g_array_remove_index (GArray *farray,
692 guint index_)
693 {
694 GRealArray* array = (GRealArray*) farray;
695
696 g_return_val_if_fail (array, NULL);
697
698 g_return_val_if_fail (index_ < array->len, NULL);
699
700 if (array->clear_func != NULL)
701 array->clear_func (g_array_elt_pos (array, index_));
702
703 if (index_ != array->len - 1)
704 memmove (g_array_elt_pos (array, index_),
705 g_array_elt_pos (array, index_ + 1),
706 g_array_elt_len (array, array->len - index_ - 1));
707
708 array->len -= 1;
709
710 if (G_UNLIKELY (g_mem_gc_friendly))
711 g_array_elt_zero (array, array->len, 1);
712 else
713 g_array_zero_terminate (array);
714
715 return farray;
716 }
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*
g_array_remove_index_fast(GArray * farray,guint index_)731 g_array_remove_index_fast (GArray *farray,
732 guint index_)
733 {
734 GRealArray* array = (GRealArray*) farray;
735
736 g_return_val_if_fail (array, NULL);
737
738 g_return_val_if_fail (index_ < array->len, NULL);
739
740 if (array->clear_func != NULL)
741 array->clear_func (g_array_elt_pos (array, index_));
742
743 if (index_ != array->len - 1)
744 memcpy (g_array_elt_pos (array, index_),
745 g_array_elt_pos (array, array->len - 1),
746 g_array_elt_len (array, 1));
747
748 array->len -= 1;
749
750 if (G_UNLIKELY (g_mem_gc_friendly))
751 g_array_elt_zero (array, array->len, 1);
752 else
753 g_array_zero_terminate (array);
754
755 return farray;
756 }
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*
g_array_remove_range(GArray * farray,guint index_,guint length)772 g_array_remove_range (GArray *farray,
773 guint index_,
774 guint length)
775 {
776 GRealArray *array = (GRealArray*) farray;
777
778 g_return_val_if_fail (array, NULL);
779 g_return_val_if_fail (index_ <= array->len, NULL);
780 g_return_val_if_fail (index_ + length <= array->len, NULL);
781
782 if (array->clear_func != NULL)
783 {
784 guint i;
785
786 for (i = 0; i < length; i++)
787 array->clear_func (g_array_elt_pos (array, index_ + i));
788 }
789
790 if (index_ + length != array->len)
791 memmove (g_array_elt_pos (array, index_),
792 g_array_elt_pos (array, index_ + length),
793 (array->len - (index_ + length)) * array->elt_size);
794
795 array->len -= length;
796 if (G_UNLIKELY (g_mem_gc_friendly))
797 g_array_elt_zero (array, array->len, length);
798 else
799 g_array_zero_terminate (array);
800
801 return farray;
802 }
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
g_array_sort(GArray * farray,GCompareFunc compare_func)817 g_array_sort (GArray *farray,
818 GCompareFunc compare_func)
819 {
820 GRealArray *array = (GRealArray*) farray;
821
822 g_return_if_fail (array != NULL);
823
824 /* Don't use qsort as we want a guaranteed stable sort */
825 if (array->len > 0)
826 g_qsort_with_data (array->data,
827 array->len,
828 array->elt_size,
829 (GCompareDataFunc)compare_func,
830 NULL);
831 }
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
g_array_sort_with_data(GArray * farray,GCompareDataFunc compare_func,gpointer user_data)849 g_array_sort_with_data (GArray *farray,
850 GCompareDataFunc compare_func,
851 gpointer user_data)
852 {
853 GRealArray *array = (GRealArray*) farray;
854
855 g_return_if_fail (array != NULL);
856
857 if (array->len > 0)
858 g_qsort_with_data (array->data,
859 array->len,
860 array->elt_size,
861 compare_func,
862 user_data);
863 }
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
g_array_binary_search(GArray * array,gconstpointer target,GCompareFunc compare_func,guint * out_match_index)905 g_array_binary_search (GArray *array,
906 gconstpointer target,
907 GCompareFunc compare_func,
908 guint *out_match_index)
909 {
910 gboolean result = FALSE;
911 GRealArray *_array = (GRealArray *) array;
912 guint left, middle, right;
913 gint val;
914
915 g_return_val_if_fail (_array != NULL, FALSE);
916 g_return_val_if_fail (compare_func != NULL, FALSE);
917
918 if (G_LIKELY(_array->len))
919 {
920 left = 0;
921 right = _array->len - 1;
922
923 while (left <= right)
924 {
925 middle = left + (right - left) / 2;
926
927 val = compare_func (_array->data + (_array->elt_size * middle), target);
928 if (val == 0)
929 {
930 result = TRUE;
931 break;
932 }
933 else if (val < 0)
934 left = middle + 1;
935 else if (/* val > 0 && */ middle > 0)
936 right = middle - 1;
937 else
938 break; /* element not found */
939 }
940 }
941
942 if (result && out_match_index != NULL)
943 *out_match_index = middle;
944
945 return result;
946 }
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
g_nearest_pow(guint num)952 g_nearest_pow (guint num)
953 {
954 guint n = num - 1;
955
956 g_assert (num > 0);
957
958 n |= n >> 1;
959 n |= n >> 2;
960 n |= n >> 4;
961 n |= n >> 8;
962 n |= n >> 16;
963 #if SIZEOF_INT == 8
964 n |= n >> 32;
965 #endif
966
967 return n + 1;
968 }
969
970 static void
g_array_maybe_expand(GRealArray * array,guint len)971 g_array_maybe_expand (GRealArray *array,
972 guint len)
973 {
974 guint want_alloc;
975
976 /* Detect potential overflow */
977 if G_UNLIKELY ((G_MAXUINT - array->len) < len)
978 g_error ("adding %u to array would overflow", len);
979
980 want_alloc = g_array_elt_len (array, array->len + len +
981 array->zero_terminated);
982
983 if (want_alloc > array->alloc)
984 {
985 want_alloc = g_nearest_pow (want_alloc);
986 want_alloc = MAX (want_alloc, MIN_ARRAY_SIZE);
987
988 array->data = g_realloc (array->data, want_alloc);
989
990 if (G_UNLIKELY (g_mem_gc_friendly))
991 memset (array->data + array->alloc, 0, want_alloc - array->alloc);
992
993 array->alloc = want_alloc;
994 }
995 }
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 *
ptr_array_new(guint reserved_size,GDestroyNotify element_free_func)1081 ptr_array_new (guint reserved_size,
1082 GDestroyNotify element_free_func)
1083 {
1084 GRealPtrArray *array;
1085
1086 array = g_slice_new (GRealPtrArray);
1087
1088 array->pdata = NULL;
1089 array->len = 0;
1090 array->alloc = 0;
1091 array->element_free_func = element_free_func;
1092
1093 g_atomic_ref_count_init (&array->ref_count);
1094
1095 if (reserved_size != 0)
1096 g_ptr_array_maybe_expand (array, reserved_size);
1097
1098 return (GPtrArray *) array;
1099 }
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*
g_ptr_array_new(void)1109 g_ptr_array_new (void)
1110 {
1111 return ptr_array_new (0, NULL);
1112 }
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 *
g_ptr_array_steal(GPtrArray * array,gsize * len)1167 g_ptr_array_steal (GPtrArray *array,
1168 gsize *len)
1169 {
1170 GRealPtrArray *rarray;
1171 gpointer *segment;
1172
1173 g_return_val_if_fail (array != NULL, NULL);
1174
1175 rarray = (GRealPtrArray *) array;
1176 segment = (gpointer *) rarray->pdata;
1177
1178 if (len != NULL)
1179 *len = rarray->len;
1180
1181 rarray->pdata = NULL;
1182 rarray->len = 0;
1183 rarray->alloc = 0;
1184 return segment;
1185 }
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 *
g_ptr_array_copy(GPtrArray * array,GCopyFunc func,gpointer user_data)1212 g_ptr_array_copy (GPtrArray *array,
1213 GCopyFunc func,
1214 gpointer user_data)
1215 {
1216 GPtrArray *new_array;
1217
1218 g_return_val_if_fail (array != NULL, NULL);
1219
1220 new_array = ptr_array_new (array->len,
1221 ((GRealPtrArray *) array)->element_free_func);
1222
1223 if (func != NULL)
1224 {
1225 guint i;
1226
1227 for (i = 0; i < array->len; i++)
1228 new_array->pdata[i] = func (array->pdata[i], user_data);
1229 }
1230 else if (array->len > 0)
1231 {
1232 memcpy (new_array->pdata, array->pdata,
1233 array->len * sizeof (*array->pdata));
1234 }
1235
1236 new_array->len = array->len;
1237
1238 return new_array;
1239 }
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*
g_ptr_array_sized_new(guint reserved_size)1253 g_ptr_array_sized_new (guint reserved_size)
1254 {
1255 return ptr_array_new (reserved_size, NULL);
1256 }
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 *
g_array_copy(GArray * array)1270 g_array_copy (GArray *array)
1271 {
1272 GRealArray *rarray = (GRealArray *) array;
1273 GRealArray *new_rarray;
1274
1275 g_return_val_if_fail (rarray != NULL, NULL);
1276
1277 new_rarray =
1278 (GRealArray *) g_array_sized_new (rarray->zero_terminated, rarray->clear,
1279 rarray->elt_size, rarray->alloc / rarray->elt_size);
1280 new_rarray->len = rarray->len;
1281 if (rarray->len > 0)
1282 memcpy (new_rarray->data, rarray->data, rarray->len * rarray->elt_size);
1283
1284 g_array_zero_terminate (new_rarray);
1285
1286 return (GArray *) new_rarray;
1287 }
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*
g_ptr_array_new_with_free_func(GDestroyNotify element_free_func)1304 g_ptr_array_new_with_free_func (GDestroyNotify element_free_func)
1305 {
1306 return ptr_array_new (0, element_free_func);
1307 }
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*
g_ptr_array_new_full(guint reserved_size,GDestroyNotify element_free_func)1328 g_ptr_array_new_full (guint reserved_size,
1329 GDestroyNotify element_free_func)
1330 {
1331 return ptr_array_new (reserved_size, element_free_func);
1332 }
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
g_ptr_array_set_free_func(GPtrArray * array,GDestroyNotify element_free_func)1347 g_ptr_array_set_free_func (GPtrArray *array,
1348 GDestroyNotify element_free_func)
1349 {
1350 GRealPtrArray *rarray = (GRealPtrArray *)array;
1351
1352 g_return_if_fail (array);
1353
1354 rarray->element_free_func = element_free_func;
1355 }
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*
g_ptr_array_ref(GPtrArray * array)1369 g_ptr_array_ref (GPtrArray *array)
1370 {
1371 GRealPtrArray *rarray = (GRealPtrArray *)array;
1372
1373 g_return_val_if_fail (array, NULL);
1374
1375 g_atomic_ref_count_inc (&rarray->ref_count);
1376
1377 return array;
1378 }
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
g_ptr_array_unref(GPtrArray * array)1394 g_ptr_array_unref (GPtrArray *array)
1395 {
1396 GRealPtrArray *rarray = (GRealPtrArray *)array;
1397
1398 g_return_if_fail (array);
1399
1400 if (g_atomic_ref_count_dec (&rarray->ref_count))
1401 ptr_array_free (array, FREE_SEGMENT);
1402 }
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*
g_ptr_array_free(GPtrArray * array,gboolean free_segment)1428 g_ptr_array_free (GPtrArray *array,
1429 gboolean free_segment)
1430 {
1431 GRealPtrArray *rarray = (GRealPtrArray *)array;
1432 ArrayFreeFlags flags;
1433
1434 g_return_val_if_fail (rarray, NULL);
1435
1436 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 if (!g_atomic_ref_count_dec (&rarray->ref_count))
1442 flags |= PRESERVE_WRAPPER;
1443
1444 return ptr_array_free (array, flags);
1445 }
1446
1447 static gpointer *
ptr_array_free(GPtrArray * array,ArrayFreeFlags flags)1448 ptr_array_free (GPtrArray *array,
1449 ArrayFreeFlags flags)
1450 {
1451 GRealPtrArray *rarray = (GRealPtrArray *)array;
1452 gpointer *segment;
1453
1454 if (flags & FREE_SEGMENT)
1455 {
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 gpointer *stolen_pdata = g_steal_pointer (&rarray->pdata);
1463 if (rarray->element_free_func != NULL)
1464 {
1465 guint i;
1466
1467 for (i = 0; i < rarray->len; ++i)
1468 rarray->element_free_func (stolen_pdata[i]);
1469 }
1470
1471 g_free (stolen_pdata);
1472 segment = NULL;
1473 }
1474 else
1475 segment = rarray->pdata;
1476
1477 if (flags & PRESERVE_WRAPPER)
1478 {
1479 rarray->pdata = NULL;
1480 rarray->len = 0;
1481 rarray->alloc = 0;
1482 }
1483 else
1484 {
1485 g_slice_free1 (sizeof (GRealPtrArray), rarray);
1486 }
1487
1488 return segment;
1489 }
1490
1491 static void
g_ptr_array_maybe_expand(GRealPtrArray * array,guint len)1492 g_ptr_array_maybe_expand (GRealPtrArray *array,
1493 guint len)
1494 {
1495 /* Detect potential overflow */
1496 if G_UNLIKELY ((G_MAXUINT - array->len) < len)
1497 g_error ("adding %u to array would overflow", len);
1498
1499 if ((array->len + len) > array->alloc)
1500 {
1501 guint old_alloc = array->alloc;
1502 array->alloc = g_nearest_pow (array->len + len);
1503 array->alloc = MAX (array->alloc, MIN_ARRAY_SIZE);
1504 array->pdata = g_realloc (array->pdata, sizeof (gpointer) * array->alloc);
1505 if (G_UNLIKELY (g_mem_gc_friendly))
1506 for ( ; old_alloc < array->alloc; old_alloc++)
1507 array->pdata [old_alloc] = NULL;
1508 }
1509 }
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
g_ptr_array_set_size(GPtrArray * array,gint length)1522 g_ptr_array_set_size (GPtrArray *array,
1523 gint length)
1524 {
1525 GRealPtrArray *rarray = (GRealPtrArray *)array;
1526 guint length_unsigned;
1527
1528 g_return_if_fail (rarray);
1529 g_return_if_fail (rarray->len == 0 || (rarray->len != 0 && rarray->pdata != NULL));
1530 g_return_if_fail (length >= 0);
1531
1532 length_unsigned = (guint) length;
1533
1534 if (length_unsigned > rarray->len)
1535 {
1536 guint i;
1537 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 for (i = rarray->len; i < length_unsigned; i++)
1545 rarray->pdata[i] = NULL;
1546 }
1547 else if (length_unsigned < rarray->len)
1548 g_ptr_array_remove_range (array, length_unsigned, rarray->len - length_unsigned);
1549
1550 rarray->len = length_unsigned;
1551 }
1552
1553 static gpointer
ptr_array_remove_index(GPtrArray * array,guint index_,gboolean fast,gboolean free_element)1554 ptr_array_remove_index (GPtrArray *array,
1555 guint index_,
1556 gboolean fast,
1557 gboolean free_element)
1558 {
1559 GRealPtrArray *rarray = (GRealPtrArray *) array;
1560 gpointer result;
1561
1562 g_return_val_if_fail (rarray, NULL);
1563 g_return_val_if_fail (rarray->len == 0 || (rarray->len != 0 && rarray->pdata != NULL), NULL);
1564
1565 g_return_val_if_fail (index_ < rarray->len, NULL);
1566
1567 result = rarray->pdata[index_];
1568
1569 if (rarray->element_free_func != NULL && free_element)
1570 rarray->element_free_func (rarray->pdata[index_]);
1571
1572 if (index_ != rarray->len - 1 && !fast)
1573 memmove (rarray->pdata + index_, rarray->pdata + index_ + 1,
1574 sizeof (gpointer) * (rarray->len - index_ - 1));
1575 else if (index_ != rarray->len - 1)
1576 rarray->pdata[index_] = rarray->pdata[rarray->len - 1];
1577
1578 rarray->len -= 1;
1579
1580 if (G_UNLIKELY (g_mem_gc_friendly))
1581 rarray->pdata[rarray->len] = NULL;
1582
1583 return result;
1584 }
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
g_ptr_array_remove_index(GPtrArray * array,guint index_)1600 g_ptr_array_remove_index (GPtrArray *array,
1601 guint index_)
1602 {
1603 return ptr_array_remove_index (array, index_, FALSE, TRUE);
1604 }
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
g_ptr_array_remove_index_fast(GPtrArray * array,guint index_)1622 g_ptr_array_remove_index_fast (GPtrArray *array,
1623 guint index_)
1624 {
1625 return ptr_array_remove_index (array, index_, TRUE, TRUE);
1626 }
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
g_ptr_array_steal_index(GPtrArray * array,guint index_)1642 g_ptr_array_steal_index (GPtrArray *array,
1643 guint index_)
1644 {
1645 return ptr_array_remove_index (array, index_, FALSE, FALSE);
1646 }
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
g_ptr_array_steal_index_fast(GPtrArray * array,guint index_)1664 g_ptr_array_steal_index_fast (GPtrArray *array,
1665 guint index_)
1666 {
1667 return ptr_array_remove_index (array, index_, TRUE, FALSE);
1668 }
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*
g_ptr_array_remove_range(GPtrArray * array,guint index_,guint length)1686 g_ptr_array_remove_range (GPtrArray *array,
1687 guint index_,
1688 guint length)
1689 {
1690 GRealPtrArray *rarray = (GRealPtrArray *)array;
1691 guint i;
1692
1693 g_return_val_if_fail (rarray != NULL, NULL);
1694 g_return_val_if_fail (rarray->len == 0 || (rarray->len != 0 && rarray->pdata != NULL), NULL);
1695 g_return_val_if_fail (index_ <= rarray->len, NULL);
1696 g_return_val_if_fail (index_ + length <= rarray->len, NULL);
1697
1698 if (rarray->element_free_func != NULL)
1699 {
1700 for (i = index_; i < index_ + length; i++)
1701 rarray->element_free_func (rarray->pdata[i]);
1702 }
1703
1704 if (index_ + length != rarray->len)
1705 {
1706 memmove (&rarray->pdata[index_],
1707 &rarray->pdata[index_ + length],
1708 (rarray->len - (index_ + length)) * sizeof (gpointer));
1709 }
1710
1711 rarray->len -= length;
1712 if (G_UNLIKELY (g_mem_gc_friendly))
1713 {
1714 for (i = 0; i < length; i++)
1715 rarray->pdata[rarray->len + i] = NULL;
1716 }
1717
1718 return array;
1719 }
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
g_ptr_array_remove(GPtrArray * array,gpointer data)1738 g_ptr_array_remove (GPtrArray *array,
1739 gpointer data)
1740 {
1741 guint i;
1742
1743 g_return_val_if_fail (array, FALSE);
1744 g_return_val_if_fail (array->len == 0 || (array->len != 0 && array->pdata != NULL), FALSE);
1745
1746 for (i = 0; i < array->len; i += 1)
1747 {
1748 if (array->pdata[i] == data)
1749 {
1750 g_ptr_array_remove_index (array, i);
1751 return TRUE;
1752 }
1753 }
1754
1755 return FALSE;
1756 }
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
g_ptr_array_remove_fast(GPtrArray * array,gpointer data)1775 g_ptr_array_remove_fast (GPtrArray *array,
1776 gpointer data)
1777 {
1778 GRealPtrArray *rarray = (GRealPtrArray *)array;
1779 guint i;
1780
1781 g_return_val_if_fail (rarray, FALSE);
1782 g_return_val_if_fail (rarray->len == 0 || (rarray->len != 0 && rarray->pdata != NULL), FALSE);
1783
1784 for (i = 0; i < rarray->len; i += 1)
1785 {
1786 if (rarray->pdata[i] == data)
1787 {
1788 g_ptr_array_remove_index_fast (array, i);
1789 return TRUE;
1790 }
1791 }
1792
1793 return FALSE;
1794 }
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
g_ptr_array_add(GPtrArray * array,gpointer data)1805 g_ptr_array_add (GPtrArray *array,
1806 gpointer data)
1807 {
1808 GRealPtrArray *rarray = (GRealPtrArray *)array;
1809
1810 g_return_if_fail (rarray);
1811 g_return_if_fail (rarray->len == 0 || (rarray->len != 0 && rarray->pdata != NULL));
1812
1813 g_ptr_array_maybe_expand (rarray, 1);
1814
1815 rarray->pdata[rarray->len++] = data;
1816 }
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
g_ptr_array_extend(GPtrArray * array_to_extend,GPtrArray * array,GCopyFunc func,gpointer user_data)1841 g_ptr_array_extend (GPtrArray *array_to_extend,
1842 GPtrArray *array,
1843 GCopyFunc func,
1844 gpointer user_data)
1845 {
1846 GRealPtrArray *rarray_to_extend = (GRealPtrArray *) array_to_extend;
1847
1848 g_return_if_fail (array_to_extend != NULL);
1849 g_return_if_fail (array != NULL);
1850
1851 g_ptr_array_maybe_expand (rarray_to_extend, array->len);
1852
1853 if (func != NULL)
1854 {
1855 guint i;
1856
1857 for (i = 0; i < array->len; i++)
1858 rarray_to_extend->pdata[i + rarray_to_extend->len] =
1859 func (array->pdata[i], user_data);
1860 }
1861 else if (array->len > 0)
1862 {
1863 memcpy (rarray_to_extend->pdata + rarray_to_extend->len, array->pdata,
1864 array->len * sizeof (*array->pdata));
1865 }
1866
1867 rarray_to_extend->len += array->len;
1868 }
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
g_ptr_array_extend_and_steal(GPtrArray * array_to_extend,GPtrArray * array)1887 g_ptr_array_extend_and_steal (GPtrArray *array_to_extend,
1888 GPtrArray *array)
1889 {
1890 gpointer *pdata;
1891
1892 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 pdata = g_steal_pointer (&array->pdata);
1897 array->len = 0;
1898 ((GRealPtrArray *) array)->alloc = 0;
1899 g_ptr_array_unref (array);
1900 g_free (pdata);
1901 }
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
g_ptr_array_insert(GPtrArray * array,gint index_,gpointer data)1915 g_ptr_array_insert (GPtrArray *array,
1916 gint index_,
1917 gpointer data)
1918 {
1919 GRealPtrArray *rarray = (GRealPtrArray *)array;
1920
1921 g_return_if_fail (rarray);
1922 g_return_if_fail (index_ >= -1);
1923 g_return_if_fail (index_ <= (gint)rarray->len);
1924
1925 g_ptr_array_maybe_expand (rarray, 1);
1926
1927 if (index_ < 0)
1928 index_ = rarray->len;
1929
1930 if ((guint) index_ < rarray->len)
1931 memmove (&(rarray->pdata[index_ + 1]),
1932 &(rarray->pdata[index_]),
1933 (rarray->len - index_) * sizeof (gpointer));
1934
1935 rarray->len++;
1936 rarray->pdata[index_] = data;
1937 }
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
g_ptr_array_sort(GPtrArray * array,GCompareFunc compare_func)1983 g_ptr_array_sort (GPtrArray *array,
1984 GCompareFunc compare_func)
1985 {
1986 g_return_if_fail (array != NULL);
1987
1988 /* Don't use qsort as we want a guaranteed stable sort */
1989 if (array->len > 0)
1990 g_qsort_with_data (array->pdata,
1991 array->len,
1992 sizeof (gpointer),
1993 (GCompareDataFunc)compare_func,
1994 NULL);
1995 }
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
g_ptr_array_sort_with_data(GPtrArray * array,GCompareDataFunc compare_func,gpointer user_data)2060 g_ptr_array_sort_with_data (GPtrArray *array,
2061 GCompareDataFunc compare_func,
2062 gpointer user_data)
2063 {
2064 g_return_if_fail (array != NULL);
2065
2066 if (array->len > 0)
2067 g_qsort_with_data (array->pdata,
2068 array->len,
2069 sizeof (gpointer),
2070 compare_func,
2071 user_data);
2072 }
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
g_ptr_array_foreach(GPtrArray * array,GFunc func,gpointer user_data)2086 g_ptr_array_foreach (GPtrArray *array,
2087 GFunc func,
2088 gpointer user_data)
2089 {
2090 guint i;
2091
2092 g_return_if_fail (array);
2093
2094 for (i = 0; i < array->len; i++)
2095 (*func) (array->pdata[i], user_data);
2096 }
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
g_ptr_array_find(GPtrArray * haystack,gconstpointer needle,guint * index_)2117 g_ptr_array_find (GPtrArray *haystack,
2118 gconstpointer needle,
2119 guint *index_)
2120 {
2121 return g_ptr_array_find_with_equal_func (haystack, needle, NULL, index_);
2122 }
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
g_ptr_array_find_with_equal_func(GPtrArray * haystack,gconstpointer needle,GEqualFunc equal_func,guint * index_)2148 g_ptr_array_find_with_equal_func (GPtrArray *haystack,
2149 gconstpointer needle,
2150 GEqualFunc equal_func,
2151 guint *index_)
2152 {
2153 guint i;
2154
2155 g_return_val_if_fail (haystack != NULL, FALSE);
2156
2157 if (equal_func == NULL)
2158 equal_func = g_direct_equal;
2159
2160 for (i = 0; i < haystack->len; i++)
2161 {
2162 if (equal_func (g_ptr_array_index (haystack, i), needle))
2163 {
2164 if (index_ != NULL)
2165 *index_ = i;
2166 return TRUE;
2167 }
2168 }
2169
2170 return FALSE;
2171 }
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*
g_byte_array_new(void)2229 g_byte_array_new (void)
2230 {
2231 return (GByteArray *)g_array_sized_new (FALSE, FALSE, 1, 0);
2232 }
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 *
g_byte_array_steal(GByteArray * array,gsize * len)2250 g_byte_array_steal (GByteArray *array,
2251 gsize *len)
2252 {
2253 return (guint8 *) g_array_steal ((GArray *) array, len);
2254 }
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*
g_byte_array_new_take(guint8 * data,gsize len)2273 g_byte_array_new_take (guint8 *data,
2274 gsize len)
2275 {
2276 GByteArray *array;
2277 GRealArray *real;
2278
2279 g_return_val_if_fail (len <= G_MAXUINT, NULL);
2280
2281 array = g_byte_array_new ();
2282 real = (GRealArray *)array;
2283 g_assert (real->data == NULL);
2284 g_assert (real->len == 0);
2285
2286 real->data = data;
2287 real->len = len;
2288 real->alloc = len;
2289
2290 return array;
2291 }
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*
g_byte_array_sized_new(guint reserved_size)2305 g_byte_array_sized_new (guint reserved_size)
2306 {
2307 return (GByteArray *)g_array_sized_new (FALSE, FALSE, 1, reserved_size);
2308 }
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*
g_byte_array_free(GByteArray * array,gboolean free_segment)2324 g_byte_array_free (GByteArray *array,
2325 gboolean free_segment)
2326 {
2327 return (guint8 *)g_array_free ((GArray *)array, free_segment);
2328 }
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*
g_byte_array_free_to_bytes(GByteArray * array)2349 g_byte_array_free_to_bytes (GByteArray *array)
2350 {
2351 gsize length;
2352
2353 g_return_val_if_fail (array != NULL, NULL);
2354
2355 length = array->len;
2356 return g_bytes_new_take (g_byte_array_free (array, FALSE), length);
2357 }
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*
g_byte_array_ref(GByteArray * array)2371 g_byte_array_ref (GByteArray *array)
2372 {
2373 return (GByteArray *)g_array_ref ((GArray *)array);
2374 }
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
g_byte_array_unref(GByteArray * array)2388 g_byte_array_unref (GByteArray *array)
2389 {
2390 g_array_unref ((GArray *)array);
2391 }
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*
g_byte_array_append(GByteArray * array,const guint8 * data,guint len)2405 g_byte_array_append (GByteArray *array,
2406 const guint8 *data,
2407 guint len)
2408 {
2409 g_array_append_vals ((GArray *)array, (guint8 *)data, len);
2410
2411 return array;
2412 }
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*
g_byte_array_prepend(GByteArray * array,const guint8 * data,guint len)2426 g_byte_array_prepend (GByteArray *array,
2427 const guint8 *data,
2428 guint len)
2429 {
2430 g_array_prepend_vals ((GArray *)array, (guint8 *)data, len);
2431
2432 return array;
2433 }
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*
g_byte_array_set_size(GByteArray * array,guint length)2445 g_byte_array_set_size (GByteArray *array,
2446 guint length)
2447 {
2448 g_array_set_size ((GArray *)array, length);
2449
2450 return array;
2451 }
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*
g_byte_array_remove_index(GByteArray * array,guint index_)2464 g_byte_array_remove_index (GByteArray *array,
2465 guint index_)
2466 {
2467 g_array_remove_index ((GArray *)array, index_);
2468
2469 return array;
2470 }
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*
g_byte_array_remove_index_fast(GByteArray * array,guint index_)2485 g_byte_array_remove_index_fast (GByteArray *array,
2486 guint index_)
2487 {
2488 g_array_remove_index_fast ((GArray *)array, index_);
2489
2490 return array;
2491 }
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*
g_byte_array_remove_range(GByteArray * array,guint index_,guint length)2507 g_byte_array_remove_range (GByteArray *array,
2508 guint index_,
2509 guint length)
2510 {
2511 g_return_val_if_fail (array, NULL);
2512 g_return_val_if_fail (index_ <= array->len, NULL);
2513 g_return_val_if_fail (index_ + length <= array->len, NULL);
2514
2515 return (GByteArray *)g_array_remove_range ((GArray *)array, index_, length);
2516 }
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
g_byte_array_sort(GByteArray * array,GCompareFunc compare_func)2535 g_byte_array_sort (GByteArray *array,
2536 GCompareFunc compare_func)
2537 {
2538 g_array_sort ((GArray *)array, compare_func);
2539 }
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
g_byte_array_sort_with_data(GByteArray * array,GCompareDataFunc compare_func,gpointer user_data)2551 g_byte_array_sort_with_data (GByteArray *array,
2552 GCompareDataFunc compare_func,
2553 gpointer user_data)
2554 {
2555 g_array_sort_with_data ((GArray *)array, compare_func, user_data);
2556 }
2557