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