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 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 "gslice.h" 38 #include "gmem.h" 39 #include "gtestutils.h" 40 #include "gthread.h" 41 #include "gmessages.h" 42 #include "gqsort.h" 43 44 45 /** 46 * SECTION:arrays 47 * @title: Arrays 48 * @short_description: arrays of arbitrary elements which grow 49 * automatically as elements are added 50 * 51 * Arrays are similar to standard C arrays, except that they grow 52 * automatically as elements are added. 53 * 54 * Array elements can be of any size (though all elements of one array 55 * are the same size), and the array can be automatically cleared to 56 * '0's and zero-terminated. 57 * 58 * To create a new array use g_array_new(). 59 * 60 * To add elements to an array, use g_array_append_val(), 61 * g_array_append_vals(), g_array_prepend_val(), and 62 * g_array_prepend_vals(). 63 * 64 * To access an element of an array, use g_array_index(). 65 * 66 * To set the size of an array, use g_array_set_size(). 67 * 68 * To free an array, use g_array_free(). 69 * 70 * Here is an example that stores integers in a #GArray: 71 * |[<!-- language="C" --> 72 * GArray *garray; 73 * gint i; 74 * // We create a new array to store gint values. 75 * // We don't want it zero-terminated or cleared to 0's. 76 * garray = g_array_new (FALSE, FALSE, sizeof (gint)); 77 * for (i = 0; i < 10000; i++) 78 * g_array_append_val (garray, i); 79 * for (i = 0; i < 10000; i++) 80 * if (g_array_index (garray, gint, i) != i) 81 * g_print ("ERROR: got %d instead of %d\n", 82 * g_array_index (garray, gint, i), i); 83 * g_array_free (garray, TRUE); 84 * ]| 85 */ 86 87 #define MIN_ARRAY_SIZE 16 88 89 typedef struct _GRealArray GRealArray; 90 91 /** 92 * GArray: 93 * @data: a pointer to the element data. The data may be moved as 94 * elements are added to the #GArray. 95 * @len: the number of elements in the #GArray not including the 96 * possible terminating zero element. 97 * 98 * Contains the public fields of a GArray. 99 */ 100 struct _GRealArray 101 { 102 guint8 *data; 103 guint len; 104 guint alloc; 105 guint elt_size; 106 guint zero_terminated : 1; 107 guint clear : 1; 108 gint ref_count; 109 GDestroyNotify clear_func; 110 }; 111 112 /** 113 * g_array_index: 114 * @a: a #GArray 115 * @t: the type of the elements 116 * @i: the index of the element to return 117 * 118 * Returns the element of a #GArray at the given index. The return 119 * value is cast to the given type. 120 * 121 * This example gets a pointer to an element in a #GArray: 122 * |[<!-- language="C" --> 123 * EDayViewEvent *event; 124 * // This gets a pointer to the 4th element in the array of 125 * // EDayViewEvent structs. 126 * event = &g_array_index (events, EDayViewEvent, 3); 127 * ]| 128 * 129 * Returns: the element of the #GArray at the index given by @i 130 */ 131 132 #define g_array_elt_len(array,i) ((array)->elt_size * (i)) 133 #define g_array_elt_pos(array,i) ((array)->data + g_array_elt_len((array),(i))) 134 #define g_array_elt_zero(array, pos, len) \ 135 (memset (g_array_elt_pos ((array), pos), 0, g_array_elt_len ((array), len))) 136 #define g_array_zero_terminate(array) G_STMT_START{ \ 137 if ((array)->zero_terminated) \ 138 g_array_elt_zero ((array), (array)->len, 1); \ 139 }G_STMT_END 140 141 static guint g_nearest_pow (gint num) G_GNUC_CONST; 142 static void g_array_maybe_expand (GRealArray *array, 143 gint len); 144 145 /** 146 * g_array_new: 147 * @zero_terminated: %TRUE if the array should have an extra element at 148 * the end which is set to 0 149 * @clear_: %TRUE if #GArray elements should be automatically cleared 150 * to 0 when they are allocated 151 * @element_size: the size of each element in bytes 152 * 153 * Creates a new #GArray with a reference count of 1. 154 * 155 * Returns: the new #GArray 156 */ 157 GArray* 158 g_array_new (gboolean zero_terminated, 159 gboolean clear, 160 guint elt_size) 161 { 162 g_return_val_if_fail (elt_size > 0, NULL); 163 164 return g_array_sized_new (zero_terminated, clear, elt_size, 0); 165 } 166 167 /** 168 * g_array_sized_new: 169 * @zero_terminated: %TRUE if the array should have an extra element at 170 * the end with all bits cleared 171 * @clear_: %TRUE if all bits in the array should be cleared to 0 on 172 * allocation 173 * @element_size: size of each element in the array 174 * @reserved_size: number of elements preallocated 175 * 176 * Creates a new #GArray with @reserved_size elements preallocated and 177 * a reference count of 1. This avoids frequent reallocation, if you 178 * are going to add many elements to the array. Note however that the 179 * size of the array is still 0. 180 * 181 * Returns: the new #GArray 182 */ 183 GArray* 184 g_array_sized_new (gboolean zero_terminated, 185 gboolean clear, 186 guint elt_size, 187 guint reserved_size) 188 { 189 GRealArray *array; 190 191 g_return_val_if_fail (elt_size > 0, NULL); 192 193 array = g_slice_new (GRealArray); 194 #ifdef GSTREAMER_LITE 195 if (array == NULL) { 196 return NULL; 197 } 198 #endif // GSTREAMER_LITE 199 200 array->data = NULL; 201 array->len = 0; 202 array->alloc = 0; 203 array->zero_terminated = (zero_terminated ? 1 : 0); 204 array->clear = (clear ? 1 : 0); 205 array->elt_size = elt_size; 206 array->ref_count = 1; 207 array->clear_func = NULL; 208 209 if (array->zero_terminated || reserved_size != 0) 210 { 211 g_array_maybe_expand (array, reserved_size); 212 g_array_zero_terminate(array); 213 } 214 215 return (GArray*) array; 216 } 217 218 /** 219 * g_array_set_clear_func: 220 * @array: A #GArray 221 * @clear_func: a function to clear an element of @array 222 * 223 * Sets a function to clear an element of @array. 224 * 225 * The @clear_func will be called when an element in the array 226 * data segment is removed and when the array is freed and data 227 * segment is deallocated as well. 228 * 229 * Note that in contrast with other uses of #GDestroyNotify 230 * functions, @clear_func is expected to clear the contents of 231 * the array element it is given, but not free the element itself. 232 * 233 * Since: 2.32 234 */ 235 void 236 g_array_set_clear_func (GArray *array, 237 GDestroyNotify clear_func) 238 { 239 GRealArray *rarray = (GRealArray *) array; 240 241 g_return_if_fail (array != NULL); 242 243 rarray->clear_func = clear_func; 244 } 245 246 /** 247 * g_array_ref: 248 * @array: A #GArray 249 * 250 * Atomically increments the reference count of @array by one. 251 * This function is MT-safe and may be called from any thread. 252 * 253 * Returns: The passed in #GArray 254 * 255 * Since: 2.22 256 */ 257 GArray * 258 g_array_ref (GArray *array) 259 { 260 GRealArray *rarray = (GRealArray*) array; 261 g_return_val_if_fail (array, NULL); 262 263 g_atomic_int_inc (&rarray->ref_count); 264 265 return array; 266 } 267 268 typedef enum 269 { 270 FREE_SEGMENT = 1 << 0, 271 PRESERVE_WRAPPER = 1 << 1 272 } ArrayFreeFlags; 273 274 static gchar *array_free (GRealArray *, ArrayFreeFlags); 275 276 /** 277 * g_array_unref: 278 * @array: A #GArray 279 * 280 * Atomically decrements the reference count of @array by one. If the 281 * reference count drops to 0, all memory allocated by the array is 282 * released. This function is MT-safe and may be called from any 283 * thread. 284 * 285 * Since: 2.22 286 */ 287 void 288 g_array_unref (GArray *array) 289 { 290 GRealArray *rarray = (GRealArray*) array; 291 g_return_if_fail (array); 292 293 if (g_atomic_int_dec_and_test (&rarray->ref_count)) 294 array_free (rarray, FREE_SEGMENT); 295 } 296 297 /** 298 * g_array_get_element_size: 299 * @array: A #GArray 300 * 301 * Gets the size of the elements in @array. 302 * 303 * Returns: Size of each element, in bytes 304 * 305 * Since: 2.22 306 */ 307 guint 308 g_array_get_element_size (GArray *array) 309 { 310 GRealArray *rarray = (GRealArray*) array; 311 312 g_return_val_if_fail (array, 0); 313 314 return rarray->elt_size; 315 } 316 317 /** 318 * g_array_free: 319 * @array: a #GArray 320 * @free_segment: if %TRUE the actual element data is freed as well 321 * 322 * Frees the memory allocated for the #GArray. If @free_segment is 323 * %TRUE it frees the memory block holding the elements as well and 324 * also each element if @array has a @element_free_func set. Pass 325 * %FALSE if you want to free the #GArray wrapper but preserve the 326 * underlying array for use elsewhere. If the reference count of @array 327 * is greater than one, the #GArray wrapper is preserved but the size 328 * of @array will be set to zero. 329 * 330 * If array elements contain dynamically-allocated memory, they should 331 * be freed separately. 332 * 333 * Returns: the element data if @free_segment is %FALSE, otherwise 334 * %NULL. The element data should be freed using g_free(). 335 */ 336 gchar* 337 g_array_free (GArray *farray, 338 gboolean free_segment) 339 { 340 GRealArray *array = (GRealArray*) farray; 341 ArrayFreeFlags flags; 342 343 g_return_val_if_fail (array, NULL); 344 345 flags = (free_segment ? FREE_SEGMENT : 0); 346 347 /* if others are holding a reference, preserve the wrapper but do free/return the data */ 348 if (!g_atomic_int_dec_and_test (&array->ref_count)) 349 flags |= PRESERVE_WRAPPER; 350 351 return array_free (array, flags); 352 } 353 354 static gchar * 355 array_free (GRealArray *array, 356 ArrayFreeFlags flags) 357 { 358 gchar *segment; 359 360 if (flags & FREE_SEGMENT) 361 { 362 if (array->clear_func != NULL) 363 { 364 guint i; 365 366 for (i = 0; i < array->len; i++) 367 array->clear_func (g_array_elt_pos (array, i)); 368 } 369 370 g_free (array->data); 371 segment = NULL; 372 } 373 else 374 segment = (gchar*) array->data; 375 376 if (flags & PRESERVE_WRAPPER) 377 { 378 array->data = NULL; 379 array->len = 0; 380 array->alloc = 0; 381 } 382 else 383 { 384 g_slice_free1 (sizeof (GRealArray), array); 385 } 386 387 return segment; 388 } 389 390 /** 391 * g_array_append_vals: 392 * @array: a #GArray 393 * @data: a pointer to the elements to append to the end of the array 394 * @len: the number of elements to append 395 * 396 * Adds @len elements onto the end of the array. 397 * 398 * Returns: the #GArray 399 */ 400 /** 401 * g_array_append_val: 402 * @a: a #GArray 403 * @v: the value to append to the #GArray 404 * 405 * Adds the value on to the end of the array. The array will grow in 406 * size automatically if necessary. 407 * 408 * g_array_append_val() is a macro which uses a reference to the value 409 * parameter @v. This means that you cannot use it with literal values 410 * such as "27". You must use variables. 411 * 412 * Returns: the #GArray 413 */ 414 GArray* 415 g_array_append_vals (GArray *farray, 416 gconstpointer data, 417 guint len) 418 { 419 GRealArray *array = (GRealArray*) farray; 420 421 g_return_val_if_fail (array, NULL); 422 423 g_array_maybe_expand (array, len); 424 425 memcpy (g_array_elt_pos (array, array->len), data, 426 g_array_elt_len (array, len)); 427 428 array->len += len; 429 430 g_array_zero_terminate (array); 431 432 return farray; 433 } 434 435 /** 436 * g_array_prepend_vals: 437 * @array: a #GArray 438 * @data: a pointer to the elements to prepend to the start of the array 439 * @len: the number of elements to prepend 440 * 441 * Adds @len elements onto the start of the array. 442 * 443 * This operation is slower than g_array_append_vals() since the 444 * existing elements in the array have to be moved to make space for 445 * the new elements. 446 * 447 * Returns: the #GArray 448 */ 449 /** 450 * g_array_prepend_val: 451 * @a: a #GArray 452 * @v: the value to prepend to the #GArray 453 * 454 * Adds the value on to the start of the array. The array will grow in 455 * size automatically if necessary. 456 * 457 * This operation is slower than g_array_append_val() since the 458 * existing elements in the array have to be moved to make space for 459 * the new element. 460 * 461 * g_array_prepend_val() is a macro which uses a reference to the value 462 * parameter @v. This means that you cannot use it with literal values 463 * such as "27". You must use variables. 464 * 465 * Returns: the #GArray 466 */ 467 GArray* 468 g_array_prepend_vals (GArray *farray, 469 gconstpointer data, 470 guint len) 471 { 472 GRealArray *array = (GRealArray*) farray; 473 474 g_return_val_if_fail (array, NULL); 475 476 g_array_maybe_expand (array, len); 477 478 memmove (g_array_elt_pos (array, len), g_array_elt_pos (array, 0), 479 g_array_elt_len (array, array->len)); 480 481 memcpy (g_array_elt_pos (array, 0), data, g_array_elt_len (array, len)); 482 483 array->len += len; 484 485 g_array_zero_terminate (array); 486 487 return farray; 488 } 489 490 /** 491 * g_array_insert_vals: 492 * @array: a #GArray 493 * @index_: the index to place the elements at 494 * @data: a pointer to the elements to insert 495 * @len: the number of elements to insert 496 * 497 * Inserts @len elements into a #GArray at the given index. 498 * 499 * Returns: the #GArray 500 */ 501 /** 502 * g_array_insert_val: 503 * @a: a #GArray 504 * @i: the index to place the element at 505 * @v: the value to insert into the array 506 * 507 * Inserts an element into an array at the given index. 508 * 509 * g_array_insert_val() is a macro which uses a reference to the value 510 * parameter @v. This means that you cannot use it with literal values 511 * such as "27". You must use variables. 512 * 513 * Returns: the #GArray 514 */ 515 GArray* 516 g_array_insert_vals (GArray *farray, 517 guint index_, 518 gconstpointer data, 519 guint len) 520 { 521 GRealArray *array = (GRealArray*) farray; 522 523 g_return_val_if_fail (array, NULL); 524 525 g_array_maybe_expand (array, len); 526 527 memmove (g_array_elt_pos (array, len + index_), 528 g_array_elt_pos (array, index_), 529 g_array_elt_len (array, array->len - index_)); 530 531 memcpy (g_array_elt_pos (array, index_), data, g_array_elt_len (array, len)); 532 533 array->len += len; 534 535 g_array_zero_terminate (array); 536 537 return farray; 538 } 539 540 /** 541 * g_array_set_size: 542 * @array: a #GArray 543 * @length: the new size of the #GArray 544 * 545 * Sets the size of the array, expanding it if necessary. If the array 546 * was created with @clear_ set to %TRUE, the new elements are set to 0. 547 * 548 * Returns: the #GArray 549 */ 550 GArray* 551 g_array_set_size (GArray *farray, 552 guint length) 553 { 554 GRealArray *array = (GRealArray*) farray; 555 556 g_return_val_if_fail (array, NULL); 557 558 if (length > array->len) 559 { 560 g_array_maybe_expand (array, length - array->len); 561 562 if (array->clear) 563 g_array_elt_zero (array, array->len, length - array->len); 564 } 565 else if (length < array->len) 566 g_array_remove_range (farray, length, array->len - length); 567 568 array->len = length; 569 570 g_array_zero_terminate (array); 571 572 return farray; 573 } 574 575 /** 576 * g_array_remove_index: 577 * @array: a #GArray 578 * @index_: the index of the element to remove 579 * 580 * Removes the element at the given index from a #GArray. The following 581 * elements are moved down one place. 582 * 583 * Returns: the #GArray 584 */ 585 GArray* 586 g_array_remove_index (GArray *farray, 587 guint index_) 588 { 589 GRealArray* array = (GRealArray*) farray; 590 591 g_return_val_if_fail (array, NULL); 592 593 g_return_val_if_fail (index_ < array->len, NULL); 594 595 if (array->clear_func != NULL) 596 array->clear_func (g_array_elt_pos (array, index_)); 597 598 if (index_ != array->len - 1) 599 memmove (g_array_elt_pos (array, index_), 600 g_array_elt_pos (array, index_ + 1), 601 g_array_elt_len (array, array->len - index_ - 1)); 602 603 array->len -= 1; 604 605 if (G_UNLIKELY (g_mem_gc_friendly)) 606 g_array_elt_zero (array, array->len, 1); 607 else 608 g_array_zero_terminate (array); 609 610 return farray; 611 } 612 613 /** 614 * g_array_remove_index_fast: 615 * @array: a @GArray 616 * @index_: the index of the element to remove 617 * 618 * Removes the element at the given index from a #GArray. The last 619 * element in the array is used to fill in the space, so this function 620 * does not preserve the order of the #GArray. But it is faster than 621 * g_array_remove_index(). 622 * 623 * Returns: the #GArray 624 */ 625 GArray* 626 g_array_remove_index_fast (GArray *farray, 627 guint index_) 628 { 629 GRealArray* array = (GRealArray*) farray; 630 631 g_return_val_if_fail (array, NULL); 632 633 g_return_val_if_fail (index_ < array->len, NULL); 634 635 if (array->clear_func != NULL) 636 array->clear_func (g_array_elt_pos (array, index_)); 637 638 if (index_ != array->len - 1) 639 memcpy (g_array_elt_pos (array, index_), 640 g_array_elt_pos (array, array->len - 1), 641 g_array_elt_len (array, 1)); 642 643 array->len -= 1; 644 645 if (G_UNLIKELY (g_mem_gc_friendly)) 646 g_array_elt_zero (array, array->len, 1); 647 else 648 g_array_zero_terminate (array); 649 650 return farray; 651 } 652 653 /** 654 * g_array_remove_range: 655 * @array: a @GArray 656 * @index_: the index of the first element to remove 657 * @length: the number of elements to remove 658 * 659 * Removes the given number of elements starting at the given index 660 * from a #GArray. The following elements are moved to close the gap. 661 * 662 * Returns: the #GArray 663 * 664 * Since: 2.4 665 */ 666 GArray* 667 g_array_remove_range (GArray *farray, 668 guint index_, 669 guint length) 670 { 671 GRealArray *array = (GRealArray*) farray; 672 673 g_return_val_if_fail (array, NULL); 674 g_return_val_if_fail (index_ < array->len, NULL); 675 g_return_val_if_fail (index_ + length <= array->len, NULL); 676 677 if (array->clear_func != NULL) 678 { 679 guint i; 680 681 for (i = 0; i < length; i++) 682 array->clear_func (g_array_elt_pos (array, index_ + i)); 683 } 684 685 if (index_ + length != array->len) 686 memmove (g_array_elt_pos (array, index_), 687 g_array_elt_pos (array, index_ + length), 688 (array->len - (index_ + length)) * array->elt_size); 689 690 array->len -= length; 691 if (G_UNLIKELY (g_mem_gc_friendly)) 692 g_array_elt_zero (array, array->len, length); 693 else 694 g_array_zero_terminate (array); 695 696 return farray; 697 } 698 699 /** 700 * g_array_sort: 701 * @array: a #GArray 702 * @compare_func: comparison function 703 * 704 * Sorts a #GArray using @compare_func which should be a qsort()-style 705 * comparison function (returns less than zero for first arg is less 706 * than second arg, zero for equal, greater zero if first arg is 707 * greater than second arg). 708 * 709 * This is guaranteed to be a stable sort since version 2.32. 710 */ 711 void 712 g_array_sort (GArray *farray, 713 GCompareFunc compare_func) 714 { 715 GRealArray *array = (GRealArray*) farray; 716 717 g_return_if_fail (array != NULL); 718 719 /* Don't use qsort as we want a guaranteed stable sort */ 720 g_qsort_with_data (array->data, 721 array->len, 722 array->elt_size, 723 (GCompareDataFunc)compare_func, 724 NULL); 725 } 726 727 /** 728 * g_array_sort_with_data: 729 * @array: a #GArray 730 * @compare_func: comparison function 731 * @user_data: data to pass to @compare_func 732 * 733 * Like g_array_sort(), but the comparison function receives an extra 734 * user data argument. 735 * 736 * This is guaranteed to be a stable sort since version 2.32. 737 * 738 * There used to be a comment here about making the sort stable by 739 * using the addresses of the elements in the comparison function. 740 * This did not actually work, so any such code should be removed. 741 */ 742 void 743 g_array_sort_with_data (GArray *farray, 744 GCompareDataFunc compare_func, 745 gpointer user_data) 746 { 747 GRealArray *array = (GRealArray*) farray; 748 749 g_return_if_fail (array != NULL); 750 751 g_qsort_with_data (array->data, 752 array->len, 753 array->elt_size, 754 compare_func, 755 user_data); 756 } 757 758 /* Returns the smallest power of 2 greater than n, or n if 759 * such power does not fit in a guint 760 */ 761 static guint 762 g_nearest_pow (gint num) 763 { 764 guint n = 1; 765 766 while (n < num && n > 0) 767 n <<= 1; 768 769 return n ? n : num; 770 } 771 772 static void 773 g_array_maybe_expand (GRealArray *array, 774 gint len) 775 { 776 guint want_alloc = g_array_elt_len (array, array->len + len + 777 array->zero_terminated); 778 779 if (want_alloc > array->alloc) 780 { 781 want_alloc = g_nearest_pow (want_alloc); 782 want_alloc = MAX (want_alloc, MIN_ARRAY_SIZE); 783 784 array->data = g_realloc (array->data, want_alloc); 785 786 if (G_UNLIKELY (g_mem_gc_friendly)) 787 memset (array->data + array->alloc, 0, want_alloc - array->alloc); 788 789 array->alloc = want_alloc; 790 } 791 } 792 793 /** 794 * SECTION:arrays_pointer 795 * @title: Pointer Arrays 796 * @short_description: arrays of pointers to any type of data, which 797 * grow automatically as new elements are added 798 * 799 * Pointer Arrays are similar to Arrays but are used only for storing 800 * pointers. 801 * 802 * If you remove elements from the array, elements at the end of the 803 * array are moved into the space previously occupied by the removed 804 * element. This means that you should not rely on the index of particular 805 * elements remaining the same. You should also be careful when deleting 806 * elements while iterating over the array. 807 * 808 * To create a pointer array, use g_ptr_array_new(). 809 * 810 * To add elements to a pointer array, use g_ptr_array_add(). 811 * 812 * To remove elements from a pointer array, use g_ptr_array_remove(), 813 * g_ptr_array_remove_index() or g_ptr_array_remove_index_fast(). 814 * 815 * To access an element of a pointer array, use g_ptr_array_index(). 816 * 817 * To set the size of a pointer array, use g_ptr_array_set_size(). 818 * 819 * To free a pointer array, use g_ptr_array_free(). 820 * 821 * An example using a #GPtrArray: 822 * |[<!-- language="C" --> 823 * GPtrArray *array; 824 * gchar *string1 = "one"; 825 * gchar *string2 = "two"; 826 * gchar *string3 = "three"; 827 * 828 * array = g_ptr_array_new (); 829 * g_ptr_array_add (array, (gpointer) string1); 830 * g_ptr_array_add (array, (gpointer) string2); 831 * g_ptr_array_add (array, (gpointer) string3); 832 * 833 * if (g_ptr_array_index (array, 0) != (gpointer) string1) 834 * g_print ("ERROR: got %p instead of %p\n", 835 * g_ptr_array_index (array, 0), string1); 836 * 837 * g_ptr_array_free (array, TRUE); 838 * ]| 839 */ 840 841 typedef struct _GRealPtrArray GRealPtrArray; 842 843 /** 844 * GPtrArray: 845 * @pdata: points to the array of pointers, which may be moved when the 846 * array grows 847 * @len: number of pointers in the array 848 * 849 * Contains the public fields of a pointer array. 850 */ 851 struct _GRealPtrArray 852 { 853 gpointer *pdata; 854 guint len; 855 guint alloc; 856 gint ref_count; 857 GDestroyNotify element_free_func; 858 }; 859 860 /** 861 * g_ptr_array_index: 862 * @array: a #GPtrArray 863 * @index_: the index of the pointer to return 864 * 865 * Returns the pointer at the given index of the pointer array. 866 * 867 * This does not perform bounds checking on the given @index_, 868 * so you are responsible for checking it against the array length. 869 * 870 * Returns: the pointer at the given index 871 */ 872 873 static void g_ptr_array_maybe_expand (GRealPtrArray *array, 874 gint len); 875 876 /** 877 * g_ptr_array_new: 878 * 879 * Creates a new #GPtrArray with a reference count of 1. 880 * 881 * Returns: the new #GPtrArray 882 */ 883 GPtrArray* 884 g_ptr_array_new (void) 885 { 886 return g_ptr_array_sized_new (0); 887 } 888 889 /** 890 * g_ptr_array_sized_new: 891 * @reserved_size: number of pointers preallocated 892 * 893 * Creates a new #GPtrArray with @reserved_size pointers preallocated 894 * and a reference count of 1. This avoids frequent reallocation, if 895 * you are going to add many pointers to the array. Note however that 896 * the size of the array is still 0. 897 * 898 * Returns: the new #GPtrArray 899 */ 900 GPtrArray* 901 g_ptr_array_sized_new (guint reserved_size) 902 { 903 GRealPtrArray *array; 904 905 array = g_slice_new (GRealPtrArray); 906 #ifdef GSTREAMER_LITE 907 if (array == NULL) { 908 return NULL; 909 } 910 #endif // GSTREAMER_LITE 911 912 array->pdata = NULL; 913 array->len = 0; 914 array->alloc = 0; 915 array->ref_count = 1; 916 array->element_free_func = NULL; 917 918 if (reserved_size != 0) 919 g_ptr_array_maybe_expand (array, reserved_size); 920 921 return (GPtrArray*) array; 922 } 923 924 /** 925 * g_ptr_array_new_with_free_func: 926 * @element_free_func: (allow-none): A function to free elements with 927 * destroy @array or %NULL 928 * 929 * Creates a new #GPtrArray with a reference count of 1 and use 930 * @element_free_func for freeing each element when the array is destroyed 931 * either via g_ptr_array_unref(), when g_ptr_array_free() is called with 932 * @free_segment set to %TRUE or when removing elements. 933 * 934 * Returns: A new #GPtrArray 935 * 936 * Since: 2.22 937 */ 938 GPtrArray* 939 g_ptr_array_new_with_free_func (GDestroyNotify element_free_func) 940 { 941 GPtrArray *array; 942 943 array = g_ptr_array_new (); 944 g_ptr_array_set_free_func (array, element_free_func); 945 946 return array; 947 } 948 949 /** 950 * g_ptr_array_new_full: 951 * @reserved_size: number of pointers preallocated 952 * @element_free_func: (allow-none): A function to free elements with 953 * destroy @array or %NULL 954 * 955 * Creates a new #GPtrArray with @reserved_size pointers preallocated 956 * and a reference count of 1. This avoids frequent reallocation, if 957 * you are going to add many pointers to the array. Note however that 958 * the size of the array is still 0. It also set @element_free_func 959 * for freeing each element when the array is destroyed either via 960 * g_ptr_array_unref(), when g_ptr_array_free() is called with 961 * @free_segment set to %TRUE or when removing elements. 962 * 963 * Returns: A new #GPtrArray 964 * 965 * Since: 2.30 966 */ 967 GPtrArray* 968 g_ptr_array_new_full (guint reserved_size, 969 GDestroyNotify element_free_func) 970 { 971 GPtrArray *array; 972 973 array = g_ptr_array_sized_new (reserved_size); 974 g_ptr_array_set_free_func (array, element_free_func); 975 976 return array; 977 } 978 979 /** 980 * g_ptr_array_set_free_func: 981 * @array: A #GPtrArray 982 * @element_free_func: (allow-none): A function to free elements with 983 * destroy @array or %NULL 984 * 985 * Sets a function for freeing each element when @array is destroyed 986 * either via g_ptr_array_unref(), when g_ptr_array_free() is called 987 * with @free_segment set to %TRUE or when removing elements. 988 * 989 * Since: 2.22 990 */ 991 void 992 g_ptr_array_set_free_func (GPtrArray *array, 993 GDestroyNotify element_free_func) 994 { 995 GRealPtrArray *rarray = (GRealPtrArray *)array; 996 997 g_return_if_fail (array); 998 999 rarray->element_free_func = element_free_func; 1000 } 1001 1002 /** 1003 * g_ptr_array_ref: 1004 * @array: a #GPtrArray 1005 * 1006 * Atomically increments the reference count of @array by one. 1007 * This function is thread-safe and may be called from any thread. 1008 * 1009 * Returns: The passed in #GPtrArray 1010 * 1011 * Since: 2.22 1012 */ 1013 GPtrArray* 1014 g_ptr_array_ref (GPtrArray *array) 1015 { 1016 GRealPtrArray *rarray = (GRealPtrArray *)array; 1017 1018 g_return_val_if_fail (array, NULL); 1019 1020 g_atomic_int_inc (&rarray->ref_count); 1021 1022 return array; 1023 } 1024 1025 static gpointer *ptr_array_free (GPtrArray *, ArrayFreeFlags); 1026 1027 /** 1028 * g_ptr_array_unref: 1029 * @array: A #GPtrArray 1030 * 1031 * Atomically decrements the reference count of @array by one. If the 1032 * reference count drops to 0, the effect is the same as calling 1033 * g_ptr_array_free() with @free_segment set to %TRUE. This function 1034 * is MT-safe and may be called from any thread. 1035 * 1036 * Since: 2.22 1037 */ 1038 void 1039 g_ptr_array_unref (GPtrArray *array) 1040 { 1041 GRealPtrArray *rarray = (GRealPtrArray *)array; 1042 1043 g_return_if_fail (array); 1044 1045 if (g_atomic_int_dec_and_test (&rarray->ref_count)) 1046 ptr_array_free (array, FREE_SEGMENT); 1047 } 1048 1049 /** 1050 * g_ptr_array_free: 1051 * @array: a #GPtrArray 1052 * @free_seg: if %TRUE the actual pointer array is freed as well 1053 * 1054 * Frees the memory allocated for the #GPtrArray. If @free_seg is %TRUE 1055 * it frees the memory block holding the elements as well. Pass %FALSE 1056 * if you want to free the #GPtrArray wrapper but preserve the 1057 * underlying array for use elsewhere. If the reference count of @array 1058 * is greater than one, the #GPtrArray wrapper is preserved but the 1059 * size of @array will be set to zero. 1060 * 1061 * If array contents point to dynamically-allocated memory, they should 1062 * be freed separately if @free_seg is %TRUE and no #GDestroyNotify 1063 * function has been set for @array. 1064 * 1065 * Returns: the pointer array if @free_seg is %FALSE, otherwise %NULL. 1066 * The pointer array should be freed using g_free(). 1067 */ 1068 gpointer* 1069 g_ptr_array_free (GPtrArray *array, 1070 gboolean free_segment) 1071 { 1072 GRealPtrArray *rarray = (GRealPtrArray *)array; 1073 ArrayFreeFlags flags; 1074 1075 g_return_val_if_fail (rarray, NULL); 1076 1077 flags = (free_segment ? FREE_SEGMENT : 0); 1078 1079 /* if others are holding a reference, preserve the wrapper but 1080 * do free/return the data 1081 */ 1082 if (!g_atomic_int_dec_and_test (&rarray->ref_count)) 1083 flags |= PRESERVE_WRAPPER; 1084 1085 return ptr_array_free (array, flags); 1086 } 1087 1088 static gpointer * 1089 ptr_array_free (GPtrArray *array, 1090 ArrayFreeFlags flags) 1091 { 1092 GRealPtrArray *rarray = (GRealPtrArray *)array; 1093 gpointer *segment; 1094 1095 if (flags & FREE_SEGMENT) 1096 { 1097 if (rarray->element_free_func != NULL) 1098 g_ptr_array_foreach (array, (GFunc) rarray->element_free_func, NULL); 1099 g_free (rarray->pdata); 1100 segment = NULL; 1101 } 1102 else 1103 segment = rarray->pdata; 1104 1105 if (flags & PRESERVE_WRAPPER) 1106 { 1107 rarray->pdata = NULL; 1108 rarray->len = 0; 1109 rarray->alloc = 0; 1110 } 1111 else 1112 { 1113 g_slice_free1 (sizeof (GRealPtrArray), rarray); 1114 } 1115 1116 return segment; 1117 } 1118 1119 static void 1120 g_ptr_array_maybe_expand (GRealPtrArray *array, 1121 gint len) 1122 { 1123 if ((array->len + len) > array->alloc) 1124 { 1125 guint old_alloc = array->alloc; 1126 array->alloc = g_nearest_pow (array->len + len); 1127 array->alloc = MAX (array->alloc, MIN_ARRAY_SIZE); 1128 array->pdata = g_realloc (array->pdata, sizeof (gpointer) * array->alloc); 1129 if (G_UNLIKELY (g_mem_gc_friendly)) 1130 for ( ; old_alloc < array->alloc; old_alloc++) 1131 array->pdata [old_alloc] = NULL; 1132 } 1133 } 1134 1135 /** 1136 * g_ptr_array_set_size: 1137 * @array: a #GPtrArray 1138 * @length: the new length of the pointer array 1139 * 1140 * Sets the size of the array. When making the array larger, 1141 * newly-added elements will be set to %NULL. When making it smaller, 1142 * if @array has a non-%NULL #GDestroyNotify function then it will be 1143 * called for the removed elements. 1144 */ 1145 void 1146 g_ptr_array_set_size (GPtrArray *array, 1147 gint length) 1148 { 1149 GRealPtrArray *rarray = (GRealPtrArray *)array; 1150 1151 g_return_if_fail (rarray); 1152 1153 if (length > rarray->len) 1154 { 1155 int i; 1156 g_ptr_array_maybe_expand (rarray, (length - rarray->len)); 1157 /* This is not 1158 * memset (array->pdata + array->len, 0, 1159 * sizeof (gpointer) * (length - array->len)); 1160 * to make it really portable. Remember (void*)NULL needn't be 1161 * bitwise zero. It of course is silly not to use memset (..,0,..). 1162 */ 1163 for (i = rarray->len; i < length; i++) 1164 rarray->pdata[i] = NULL; 1165 } 1166 else if (length < rarray->len) 1167 g_ptr_array_remove_range (array, length, rarray->len - length); 1168 1169 rarray->len = length; 1170 } 1171 1172 /** 1173 * g_ptr_array_remove_index: 1174 * @array: a #GPtrArray 1175 * @index_: the index of the pointer to remove 1176 * 1177 * Removes the pointer at the given index from the pointer array. 1178 * The following elements are moved down one place. If @array has 1179 * a non-%NULL #GDestroyNotify function it is called for the removed 1180 * element. 1181 * 1182 * Returns: the pointer which was removed 1183 */ 1184 gpointer 1185 g_ptr_array_remove_index (GPtrArray *array, 1186 guint index_) 1187 { 1188 GRealPtrArray *rarray = (GRealPtrArray *)array; 1189 gpointer result; 1190 1191 g_return_val_if_fail (rarray, NULL); 1192 1193 g_return_val_if_fail (index_ < rarray->len, NULL); 1194 1195 result = rarray->pdata[index_]; 1196 1197 if (rarray->element_free_func != NULL) 1198 rarray->element_free_func (rarray->pdata[index_]); 1199 1200 if (index_ != rarray->len - 1) 1201 memmove (rarray->pdata + index_, rarray->pdata + index_ + 1, 1202 sizeof (gpointer) * (rarray->len - index_ - 1)); 1203 1204 rarray->len -= 1; 1205 1206 if (G_UNLIKELY (g_mem_gc_friendly)) 1207 rarray->pdata[rarray->len] = NULL; 1208 1209 return result; 1210 } 1211 1212 /** 1213 * g_ptr_array_remove_index_fast: 1214 * @array: a #GPtrArray 1215 * @index_: the index of the pointer to remove 1216 * 1217 * Removes the pointer at the given index from the pointer array. 1218 * The last element in the array is used to fill in the space, so 1219 * this function does not preserve the order of the array. But it 1220 * is faster than g_ptr_array_remove_index(). If @array has a non-%NULL 1221 * #GDestroyNotify function it is called for the removed element. 1222 * 1223 * Returns: the pointer which was removed 1224 */ 1225 gpointer 1226 g_ptr_array_remove_index_fast (GPtrArray *array, 1227 guint index_) 1228 { 1229 GRealPtrArray *rarray = (GRealPtrArray *)array; 1230 gpointer result; 1231 1232 g_return_val_if_fail (rarray, NULL); 1233 1234 g_return_val_if_fail (index_ < rarray->len, NULL); 1235 1236 result = rarray->pdata[index_]; 1237 1238 if (rarray->element_free_func != NULL) 1239 rarray->element_free_func (rarray->pdata[index_]); 1240 1241 if (index_ != rarray->len - 1) 1242 rarray->pdata[index_] = rarray->pdata[rarray->len - 1]; 1243 1244 rarray->len -= 1; 1245 1246 if (G_UNLIKELY (g_mem_gc_friendly)) 1247 rarray->pdata[rarray->len] = NULL; 1248 1249 return result; 1250 } 1251 1252 /** 1253 * g_ptr_array_remove_range: 1254 * @array: a @GPtrArray 1255 * @index_: the index of the first pointer to remove 1256 * @length: the number of pointers to remove 1257 * 1258 * Removes the given number of pointers starting at the given index 1259 * from a #GPtrArray. The following elements are moved to close the 1260 * gap. If @array has a non-%NULL #GDestroyNotify function it is 1261 * called for the removed elements. 1262 * 1263 * Returns: the @array 1264 * 1265 * Since: 2.4 1266 */ 1267 GPtrArray* 1268 g_ptr_array_remove_range (GPtrArray *array, 1269 guint index_, 1270 guint length) 1271 { 1272 GRealPtrArray *rarray = (GRealPtrArray *)array; 1273 guint n; 1274 1275 g_return_val_if_fail (rarray != NULL, NULL); 1276 g_return_val_if_fail (index_ < rarray->len, NULL); 1277 g_return_val_if_fail (index_ + length <= rarray->len, NULL); 1278 1279 if (rarray->element_free_func != NULL) 1280 { 1281 for (n = index_; n < index_ + length; n++) 1282 rarray->element_free_func (rarray->pdata[n]); 1283 } 1284 1285 if (index_ + length != rarray->len) 1286 { 1287 memmove (&rarray->pdata[index_], 1288 &rarray->pdata[index_ + length], 1289 (rarray->len - (index_ + length)) * sizeof (gpointer)); 1290 } 1291 1292 rarray->len -= length; 1293 if (G_UNLIKELY (g_mem_gc_friendly)) 1294 { 1295 guint i; 1296 for (i = 0; i < length; i++) 1297 rarray->pdata[rarray->len + i] = NULL; 1298 } 1299 1300 return array; 1301 } 1302 1303 /** 1304 * g_ptr_array_remove: 1305 * @array: a #GPtrArray 1306 * @data: the pointer to remove 1307 * 1308 * Removes the first occurrence of the given pointer from the pointer 1309 * array. The following elements are moved down one place. If @array 1310 * has a non-%NULL #GDestroyNotify function it is called for the 1311 * removed element. 1312 * 1313 * It returns %TRUE if the pointer was removed, or %FALSE if the 1314 * pointer was not found. 1315 * 1316 * Returns: %TRUE if the pointer is removed, %FALSE if the pointer 1317 * is not found in the array 1318 */ 1319 gboolean 1320 g_ptr_array_remove (GPtrArray *array, 1321 gpointer data) 1322 { 1323 guint i; 1324 1325 g_return_val_if_fail (array, FALSE); 1326 1327 for (i = 0; i < array->len; i += 1) 1328 { 1329 if (array->pdata[i] == data) 1330 { 1331 g_ptr_array_remove_index (array, i); 1332 return TRUE; 1333 } 1334 } 1335 1336 return FALSE; 1337 } 1338 1339 /** 1340 * g_ptr_array_remove_fast: 1341 * @array: a #GPtrArray 1342 * @data: the pointer to remove 1343 * 1344 * Removes the first occurrence of the given pointer from the pointer 1345 * array. The last element in the array is used to fill in the space, 1346 * so this function does not preserve the order of the array. But it 1347 * is faster than g_ptr_array_remove(). If @array has a non-%NULL 1348 * #GDestroyNotify function it is called for the removed element. 1349 * 1350 * It returns %TRUE if the pointer was removed, or %FALSE if the 1351 * pointer was not found. 1352 * 1353 * Returns: %TRUE if the pointer was found in the array 1354 */ 1355 gboolean 1356 g_ptr_array_remove_fast (GPtrArray *array, 1357 gpointer data) 1358 { 1359 GRealPtrArray *rarray = (GRealPtrArray *)array; 1360 guint i; 1361 1362 g_return_val_if_fail (rarray, FALSE); 1363 1364 for (i = 0; i < rarray->len; i += 1) 1365 { 1366 if (rarray->pdata[i] == data) 1367 { 1368 g_ptr_array_remove_index_fast (array, i); 1369 return TRUE; 1370 } 1371 } 1372 1373 return FALSE; 1374 } 1375 1376 /** 1377 * g_ptr_array_add: 1378 * @array: a #GPtrArray 1379 * @data: the pointer to add 1380 * 1381 * Adds a pointer to the end of the pointer array. The array will grow 1382 * in size automatically if necessary. 1383 */ 1384 void 1385 g_ptr_array_add (GPtrArray *array, 1386 gpointer data) 1387 { 1388 GRealPtrArray *rarray = (GRealPtrArray *)array; 1389 1390 g_return_if_fail (rarray); 1391 1392 g_ptr_array_maybe_expand (rarray, 1); 1393 1394 rarray->pdata[rarray->len++] = data; 1395 } 1396 1397 /** 1398 * g_ptr_array_insert: 1399 * @array: a #GPtrArray 1400 * @index_: the index to place the new element at, or -1 to append 1401 * @data: the pointer to add. 1402 * 1403 * Inserts an element into the pointer array at the given index. The 1404 * array will grow in size automatically if necessary. 1405 * 1406 * Since: 2.40 1407 */ 1408 void 1409 g_ptr_array_insert (GPtrArray *array, 1410 gint index_, 1411 gpointer data) 1412 { 1413 GRealPtrArray *rarray = (GRealPtrArray *)array; 1414 1415 g_return_if_fail (rarray); 1416 g_return_if_fail (index_ >= -1); 1417 g_return_if_fail (index_ <= (gint)rarray->len); 1418 1419 g_ptr_array_maybe_expand (rarray, 1); 1420 1421 if (index_ < 0) 1422 index_ = rarray->len; 1423 1424 if (index_ < rarray->len) 1425 memmove (&(rarray->pdata[index_ + 1]), 1426 &(rarray->pdata[index_]), 1427 (rarray->len - index_) * sizeof (gpointer)); 1428 1429 rarray->len++; 1430 rarray->pdata[index_] = data; 1431 } 1432 1433 /** 1434 * g_ptr_array_sort: 1435 * @array: a #GPtrArray 1436 * @compare_func: comparison function 1437 * 1438 * Sorts the array, using @compare_func which should be a qsort()-style 1439 * comparison function (returns less than zero for first arg is less 1440 * than second arg, zero for equal, greater than zero if irst arg is 1441 * greater than second arg). 1442 * 1443 * Note that the comparison function for g_ptr_array_sort() doesn't 1444 * take the pointers from the array as arguments, it takes pointers to 1445 * the pointers in the array. 1446 * 1447 * This is guaranteed to be a stable sort since version 2.32. 1448 */ 1449 void 1450 g_ptr_array_sort (GPtrArray *array, 1451 GCompareFunc compare_func) 1452 { 1453 g_return_if_fail (array != NULL); 1454 1455 /* Don't use qsort as we want a guaranteed stable sort */ 1456 g_qsort_with_data (array->pdata, 1457 array->len, 1458 sizeof (gpointer), 1459 (GCompareDataFunc)compare_func, 1460 NULL); 1461 } 1462 1463 /** 1464 * g_ptr_array_sort_with_data: 1465 * @array: a #GPtrArray 1466 * @compare_func: comparison function 1467 * @user_data: data to pass to @compare_func 1468 * 1469 * Like g_ptr_array_sort(), but the comparison function has an extra 1470 * user data argument. 1471 * 1472 * Note that the comparison function for g_ptr_array_sort_with_data() 1473 * doesn't take the pointers from the array as arguments, it takes 1474 * pointers to the pointers in the array. 1475 * 1476 * This is guaranteed to be a stable sort since version 2.32. 1477 */ 1478 void 1479 g_ptr_array_sort_with_data (GPtrArray *array, 1480 GCompareDataFunc compare_func, 1481 gpointer user_data) 1482 { 1483 g_return_if_fail (array != NULL); 1484 1485 g_qsort_with_data (array->pdata, 1486 array->len, 1487 sizeof (gpointer), 1488 compare_func, 1489 user_data); 1490 } 1491 1492 /** 1493 * g_ptr_array_foreach: 1494 * @array: a #GPtrArray 1495 * @func: the function to call for each array element 1496 * @user_data: user data to pass to the function 1497 * 1498 * Calls a function for each element of a #GPtrArray. 1499 * 1500 * Since: 2.4 1501 */ 1502 void 1503 g_ptr_array_foreach (GPtrArray *array, 1504 GFunc func, 1505 gpointer user_data) 1506 { 1507 guint i; 1508 1509 g_return_if_fail (array); 1510 1511 for (i = 0; i < array->len; i++) 1512 (*func) (array->pdata[i], user_data); 1513 } 1514 1515 /** 1516 * SECTION:arrays_byte 1517 * @title: Byte Arrays 1518 * @short_description: arrays of bytes 1519 * 1520 * #GByteArray is a mutable array of bytes based on #GArray, to provide arrays 1521 * of bytes which grow automatically as elements are added. 1522 * 1523 * To create a new #GByteArray use g_byte_array_new(). To add elements to a 1524 * #GByteArray, use g_byte_array_append(), and g_byte_array_prepend(). 1525 * 1526 * To set the size of a #GByteArray, use g_byte_array_set_size(). 1527 * 1528 * To free a #GByteArray, use g_byte_array_free(). 1529 * 1530 * An example for using a #GByteArray: 1531 * |[<!-- language="C" --> 1532 * GByteArray *gbarray; 1533 * gint i; 1534 * 1535 * gbarray = g_byte_array_new (); 1536 * for (i = 0; i < 10000; i++) 1537 * g_byte_array_append (gbarray, (guint8*) "abcd", 4); 1538 * 1539 * for (i = 0; i < 10000; i++) 1540 * { 1541 * g_assert (gbarray->data[4*i] == 'a'); 1542 * g_assert (gbarray->data[4*i+1] == 'b'); 1543 * g_assert (gbarray->data[4*i+2] == 'c'); 1544 * g_assert (gbarray->data[4*i+3] == 'd'); 1545 * } 1546 * 1547 * g_byte_array_free (gbarray, TRUE); 1548 * ]| 1549 * 1550 * See #GBytes if you are interested in an immutable object representing a 1551 * sequence of bytes. 1552 */ 1553 1554 /** 1555 * GByteArray: 1556 * @data: a pointer to the element data. The data may be moved as 1557 * elements are added to the #GByteArray 1558 * @len: the number of elements in the #GByteArray 1559 * 1560 * Contains the public fields of a GByteArray. 1561 */ 1562 1563 /** 1564 * g_byte_array_new: 1565 * 1566 * Creates a new #GByteArray with a reference count of 1. 1567 * 1568 * Returns: (transfer full): the new #GByteArray 1569 */ 1570 GByteArray* 1571 g_byte_array_new (void) 1572 { 1573 return (GByteArray *)g_array_sized_new (FALSE, FALSE, 1, 0); 1574 } 1575 1576 /** 1577 * g_byte_array_new_take: 1578 * @data: (transfer full) (array length=len): byte data for the array 1579 * @len: length of @data 1580 * 1581 * Create byte array containing the data. The data will be owned by the array 1582 * and will be freed with g_free(), i.e. it could be allocated using g_strdup(). 1583 * 1584 * Since: 2.32 1585 * 1586 * Returns: (transfer full): a new #GByteArray 1587 */ 1588 GByteArray* 1589 g_byte_array_new_take (guint8 *data, 1590 gsize len) 1591 { 1592 GByteArray *array; 1593 GRealArray *real; 1594 1595 array = g_byte_array_new (); 1596 real = (GRealArray *)array; 1597 g_assert (real->data == NULL); 1598 g_assert (real->len == 0); 1599 1600 real->data = data; 1601 real->len = len; 1602 real->alloc = len; 1603 1604 return array; 1605 } 1606 1607 /** 1608 * g_byte_array_sized_new: 1609 * @reserved_size: number of bytes preallocated 1610 * 1611 * Creates a new #GByteArray with @reserved_size bytes preallocated. 1612 * This avoids frequent reallocation, if you are going to add many 1613 * bytes to the array. Note however that the size of the array is still 1614 * 0. 1615 * 1616 * Returns: the new #GByteArray 1617 */ 1618 GByteArray* 1619 g_byte_array_sized_new (guint reserved_size) 1620 { 1621 return (GByteArray *)g_array_sized_new (FALSE, FALSE, 1, reserved_size); 1622 } 1623 1624 /** 1625 * g_byte_array_free: 1626 * @array: a #GByteArray 1627 * @free_segment: if %TRUE the actual byte data is freed as well 1628 * 1629 * Frees the memory allocated by the #GByteArray. If @free_segment is 1630 * %TRUE it frees the actual byte data. If the reference count of 1631 * @array is greater than one, the #GByteArray wrapper is preserved but 1632 * the size of @array will be set to zero. 1633 * 1634 * Returns: the element data if @free_segment is %FALSE, otherwise 1635 * %NULL. The element data should be freed using g_free(). 1636 */ 1637 guint8* 1638 g_byte_array_free (GByteArray *array, 1639 gboolean free_segment) 1640 { 1641 return (guint8 *)g_array_free ((GArray *)array, free_segment); 1642 } 1643 1644 /** 1645 * g_byte_array_free_to_bytes: 1646 * @array: (transfer full): a #GByteArray 1647 * 1648 * Transfers the data from the #GByteArray into a new immutable #GBytes. 1649 * 1650 * The #GByteArray is freed unless the reference count of @array is greater 1651 * than one, the #GByteArray wrapper is preserved but the size of @array 1652 * will be set to zero. 1653 * 1654 * This is identical to using g_bytes_new_take() and g_byte_array_free() 1655 * together. 1656 * 1657 * Since: 2.32 1658 * 1659 * Returns: (transfer full): a new immutable #GBytes representing same 1660 * byte data that was in the array 1661 */ 1662 GBytes* 1663 g_byte_array_free_to_bytes (GByteArray *array) 1664 { 1665 gsize length; 1666 1667 g_return_val_if_fail (array != NULL, NULL); 1668 1669 length = array->len; 1670 return g_bytes_new_take (g_byte_array_free (array, FALSE), length); 1671 } 1672 1673 /** 1674 * g_byte_array_ref: 1675 * @array: A #GByteArray 1676 * 1677 * Atomically increments the reference count of @array by one. 1678 * This function is thread-safe and may be called from any thread. 1679 * 1680 * Returns: The passed in #GByteArray 1681 * 1682 * Since: 2.22 1683 */ 1684 GByteArray* 1685 g_byte_array_ref (GByteArray *array) 1686 { 1687 return (GByteArray *)g_array_ref ((GArray *)array); 1688 } 1689 1690 /** 1691 * g_byte_array_unref: 1692 * @array: A #GByteArray 1693 * 1694 * Atomically decrements the reference count of @array by one. If the 1695 * reference count drops to 0, all memory allocated by the array is 1696 * released. This function is thread-safe and may be called from any 1697 * thread. 1698 * 1699 * Since: 2.22 1700 */ 1701 void 1702 g_byte_array_unref (GByteArray *array) 1703 { 1704 g_array_unref ((GArray *)array); 1705 } 1706 1707 /** 1708 * g_byte_array_append: 1709 * @array: a #GByteArray 1710 * @data: the byte data to be added 1711 * @len: the number of bytes to add 1712 * 1713 * Adds the given bytes to the end of the #GByteArray. 1714 * The array will grow in size automatically if necessary. 1715 * 1716 * Returns: the #GByteArray 1717 */ 1718 GByteArray* 1719 g_byte_array_append (GByteArray *array, 1720 const guint8 *data, 1721 guint len) 1722 { 1723 g_array_append_vals ((GArray *)array, (guint8 *)data, len); 1724 1725 return array; 1726 } 1727 1728 /** 1729 * g_byte_array_prepend: 1730 * @array: a #GByteArray 1731 * @data: the byte data to be added 1732 * @len: the number of bytes to add 1733 * 1734 * Adds the given data to the start of the #GByteArray. 1735 * The array will grow in size automatically if necessary. 1736 * 1737 * Returns: the #GByteArray 1738 */ 1739 GByteArray* 1740 g_byte_array_prepend (GByteArray *array, 1741 const guint8 *data, 1742 guint len) 1743 { 1744 g_array_prepend_vals ((GArray *)array, (guint8 *)data, len); 1745 1746 return array; 1747 } 1748 1749 /** 1750 * g_byte_array_set_size: 1751 * @array: a #GByteArray 1752 * @length: the new size of the #GByteArray 1753 * 1754 * Sets the size of the #GByteArray, expanding it if necessary. 1755 * 1756 * Returns: the #GByteArray 1757 */ 1758 GByteArray* 1759 g_byte_array_set_size (GByteArray *array, 1760 guint length) 1761 { 1762 g_array_set_size ((GArray *)array, length); 1763 1764 return array; 1765 } 1766 1767 /** 1768 * g_byte_array_remove_index: 1769 * @array: a #GByteArray 1770 * @index_: the index of the byte to remove 1771 * 1772 * Removes the byte at the given index from a #GByteArray. 1773 * The following bytes are moved down one place. 1774 * 1775 * Returns: the #GByteArray 1776 **/ 1777 GByteArray* 1778 g_byte_array_remove_index (GByteArray *array, 1779 guint index_) 1780 { 1781 g_array_remove_index ((GArray *)array, index_); 1782 1783 return array; 1784 } 1785 1786 /** 1787 * g_byte_array_remove_index_fast: 1788 * @array: a #GByteArray 1789 * @index_: the index of the byte to remove 1790 * 1791 * Removes the byte at the given index from a #GByteArray. The last 1792 * element in the array is used to fill in the space, so this function 1793 * does not preserve the order of the #GByteArray. But it is faster 1794 * than g_byte_array_remove_index(). 1795 * 1796 * Returns: the #GByteArray 1797 */ 1798 GByteArray* 1799 g_byte_array_remove_index_fast (GByteArray *array, 1800 guint index_) 1801 { 1802 g_array_remove_index_fast ((GArray *)array, index_); 1803 1804 return array; 1805 } 1806 1807 /** 1808 * g_byte_array_remove_range: 1809 * @array: a @GByteArray 1810 * @index_: the index of the first byte to remove 1811 * @length: the number of bytes to remove 1812 * 1813 * Removes the given number of bytes starting at the given index from a 1814 * #GByteArray. The following elements are moved to close the gap. 1815 * 1816 * Returns: the #GByteArray 1817 * 1818 * Since: 2.4 1819 */ 1820 GByteArray* 1821 g_byte_array_remove_range (GByteArray *array, 1822 guint index_, 1823 guint length) 1824 { 1825 g_return_val_if_fail (array, NULL); 1826 g_return_val_if_fail (index_ < array->len, NULL); 1827 g_return_val_if_fail (index_ + length <= array->len, NULL); 1828 1829 return (GByteArray *)g_array_remove_range ((GArray *)array, index_, length); 1830 } 1831 1832 /** 1833 * g_byte_array_sort: 1834 * @array: a #GByteArray 1835 * @compare_func: comparison function 1836 * 1837 * Sorts a byte array, using @compare_func which should be a 1838 * qsort()-style comparison function (returns less than zero for first 1839 * arg is less than second arg, zero for equal, greater than zero if 1840 * first arg is greater than second arg). 1841 * 1842 * If two array elements compare equal, their order in the sorted array 1843 * is undefined. If you want equal elements to keep their order (i.e. 1844 * you want a stable sort) you can write a comparison function that, 1845 * if two elements would otherwise compare equal, compares them by 1846 * their addresses. 1847 */ 1848 void 1849 g_byte_array_sort (GByteArray *array, 1850 GCompareFunc compare_func) 1851 { 1852 g_array_sort ((GArray *)array, compare_func); 1853 } 1854 1855 /** 1856 * g_byte_array_sort_with_data: 1857 * @array: a #GByteArray 1858 * @compare_func: comparison function 1859 * @user_data: data to pass to @compare_func 1860 * 1861 * Like g_byte_array_sort(), but the comparison function takes an extra 1862 * user data argument. 1863 */ 1864 void 1865 g_byte_array_sort_with_data (GByteArray *array, 1866 GCompareDataFunc compare_func, 1867 gpointer user_data) 1868 { 1869 g_array_sort_with_data ((GArray *)array, compare_func, user_data); 1870 }