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 866 rarray->element_free_func = element_free_func; 867 } 868 869 /** 870 * g_ptr_array_ref: 871 * @array: A #GArray. 872 * 873 * Atomically increments the reference count of @array by one. This 874 * function is MT-safe and may be called from any thread. 875 * 876 * Returns: The passed in #GPtrArray. 877 * 878 * Since: 2.22 879 **/ 880 GPtrArray * 881 g_ptr_array_ref (GPtrArray *array) 882 { 883 GRealPtrArray *rarray = (GRealPtrArray*) array; 884 885 g_return_val_if_fail (array, NULL); 886 887 g_atomic_int_inc (&rarray->ref_count); 888 889 return array; 890 } 891 892 /** 893 * g_ptr_array_unref: 894 * @array: A #GPtrArray. 895 * 896 * Atomically decrements the reference count of @array by one. If the 897 * reference count drops to 0, the effect is the same as calling 898 * g_ptr_array_free() with @free_segment set to %TRUE. This function 899 * is MT-safe and may be called from any thread. 900 * 901 * Since: 2.22 902 **/ 903 void 904 g_ptr_array_unref (GPtrArray *array) 905 { 906 GRealPtrArray *rarray = (GRealPtrArray*) array; 907 g_return_if_fail (array); 908 909 if (g_atomic_int_dec_and_test (&rarray->ref_count)) 910 g_ptr_array_free (array, TRUE); 911 } 912 913 /** 914 * g_ptr_array_free: 915 * @array: a #GPtrArray. 916 * @free_seg: if %TRUE the actual pointer array is freed as well. 917 * @Returns: the pointer array if @free_seg is %FALSE, otherwise %NULL. 918 * The pointer array should be freed using g_free(). 919 * 920 * Frees the memory allocated for the #GPtrArray. If @free_seg is %TRUE 921 * it frees the memory block holding the elements as well. Pass %FALSE 922 * if you want to free the #GPtrArray wrapper but preserve the 923 * underlying array for use elsewhere. If the reference count of @array 924 * is greater than one, the #GPtrArray wrapper is preserved but the 925 * size of @array will be set to zero. 926 * 927 * <note><para>If array contents point to dynamically-allocated 928 * memory, they should be freed separately if @free_seg is %TRUE and no 929 * #GDestroyNotify function has been set for @array.</para></note> 930 **/ 931 gpointer* 932 g_ptr_array_free (GPtrArray *farray, 933 gboolean free_segment) 934 { 935 GRealPtrArray *array = (GRealPtrArray*) farray; 936 gpointer* segment; 937 gboolean preserve_wrapper; 938 939 g_return_val_if_fail (array, NULL); 940 941 /* if others are holding a reference, preserve the wrapper but do free/return the data */ 942 preserve_wrapper = FALSE; 943 if (g_atomic_int_get (&array->ref_count) > 1) 944 preserve_wrapper = TRUE; 945 946 if (free_segment) 947 { 948 if (array->element_free_func != NULL) 949 g_ptr_array_foreach (farray, (GFunc) array->element_free_func, NULL); 950 g_free (array->pdata); 951 segment = NULL; 952 } 953 else 954 segment = array->pdata; 955 956 if (preserve_wrapper) 957 { 958 array->pdata = NULL; 959 array->len = 0; 960 array->alloc = 0; 961 } 962 else 963 { 964 g_slice_free1 (sizeof (GRealPtrArray), array); 965 } 966 967 return segment; 968 } 969 970 static void 971 g_ptr_array_maybe_expand (GRealPtrArray *array, 972 gint len) 973 { 974 if ((array->len + len) > array->alloc) 975 { 976 guint old_alloc = array->alloc; 977 array->alloc = g_nearest_pow (array->len + len); 978 array->alloc = MAX (array->alloc, MIN_ARRAY_SIZE); 979 array->pdata = g_realloc (array->pdata, sizeof (gpointer) * array->alloc); 980 if (G_UNLIKELY (g_mem_gc_friendly)) 981 for ( ; old_alloc < array->alloc; old_alloc++) 982 array->pdata [old_alloc] = NULL; 983 } 984 } 985 986 /** 987 * g_ptr_array_set_size: 988 * @array: a #GPtrArray. 989 * @length: the new length of the pointer array. 990 * 991 * Sets the size of the array. When making the array larger, 992 * newly-added elements will be set to %NULL. When making it smaller, 993 * if @array has a non-%NULL #GDestroyNotify function then it will be 994 * called for the removed elements. 995 **/ 996 void 997 g_ptr_array_set_size (GPtrArray *farray, 998 gint length) 999 { 1000 GRealPtrArray* array = (GRealPtrArray*) farray; 1001 1002 g_return_if_fail (array); 1003 1004 if (length > array->len) 1005 { 1006 int i; 1007 g_ptr_array_maybe_expand (array, (length - array->len)); 1008 /* This is not 1009 * memset (array->pdata + array->len, 0, 1010 * sizeof (gpointer) * (length - array->len)); 1011 * to make it really portable. Remember (void*)NULL needn't be 1012 * bitwise zero. It of course is silly not to use memset (..,0,..). 1013 */ 1014 for (i = array->len; i < length; i++) 1015 array->pdata[i] = NULL; 1016 } 1017 else if (length < array->len) 1018 g_ptr_array_remove_range (farray, length, array->len - length); 1019 1020 array->len = length; 1021 } 1022 1023 /** 1024 * g_ptr_array_remove_index: 1025 * @array: a #GPtrArray. 1026 * @index_: the index of the pointer to remove. 1027 * @Returns: the pointer which was removed. 1028 * 1029 * Removes the pointer at the given index from the pointer array. The 1030 * following elements are moved down one place. If @array has a 1031 * non-%NULL #GDestroyNotify function it is called for the removed 1032 * element. 1033 **/ 1034 gpointer 1035 g_ptr_array_remove_index (GPtrArray *farray, 1036 guint index_) 1037 { 1038 GRealPtrArray* array = (GRealPtrArray*) farray; 1039 gpointer result; 1040 1041 g_return_val_if_fail (array, NULL); 1042 1043 g_return_val_if_fail (index_ < array->len, NULL); 1044 1045 result = array->pdata[index_]; 1046 1047 if (array->element_free_func != NULL) 1048 array->element_free_func (array->pdata[index_]); 1049 1050 if (index_ != array->len - 1) 1051 g_memmove (array->pdata + index_, array->pdata + index_ + 1, 1052 sizeof (gpointer) * (array->len - index_ - 1)); 1053 1054 array->len -= 1; 1055 1056 if (G_UNLIKELY (g_mem_gc_friendly)) 1057 array->pdata[array->len] = NULL; 1058 1059 return result; 1060 } 1061 1062 /** 1063 * g_ptr_array_remove_index_fast: 1064 * @array: a #GPtrArray. 1065 * @index_: the index of the pointer to remove. 1066 * @Returns: the pointer which was removed. 1067 * 1068 * Removes the pointer at the given index from the pointer array. The 1069 * last element in the array is used to fill in the space, so this 1070 * function does not preserve the order of the array. But it is faster 1071 * than g_ptr_array_remove_index(). If @array has a non-%NULL 1072 * #GDestroyNotify function it is called for the removed element. 1073 **/ 1074 gpointer 1075 g_ptr_array_remove_index_fast (GPtrArray *farray, 1076 guint index_) 1077 { 1078 GRealPtrArray* array = (GRealPtrArray*) farray; 1079 gpointer result; 1080 1081 g_return_val_if_fail (array, NULL); 1082 1083 g_return_val_if_fail (index_ < array->len, NULL); 1084 1085 result = array->pdata[index_]; 1086 1087 if (array->element_free_func != NULL) 1088 array->element_free_func (array->pdata[index_]); 1089 1090 if (index_ != array->len - 1) 1091 array->pdata[index_] = array->pdata[array->len - 1]; 1092 1093 array->len -= 1; 1094 1095 if (G_UNLIKELY (g_mem_gc_friendly)) 1096 array->pdata[array->len] = NULL; 1097 1098 return result; 1099 } 1100 1101 /** 1102 * g_ptr_array_remove_range: 1103 * @array: a @GPtrArray. 1104 * @index_: the index of the first pointer to remove. 1105 * @length: the number of pointers to remove. 1106 * 1107 * Removes the given number of pointers starting at the given index 1108 * from a #GPtrArray. The following elements are moved to close the 1109 * gap. If @array has a non-%NULL #GDestroyNotify function it is called 1110 * for the removed elements. 1111 * 1112 * Since: 2.4 1113 **/ 1114 void 1115 g_ptr_array_remove_range (GPtrArray *farray, 1116 guint index_, 1117 guint length) 1118 { 1119 GRealPtrArray* array = (GRealPtrArray*) farray; 1120 guint n; 1121 1122 g_return_if_fail (array); 1123 g_return_if_fail (index_ < array->len); 1124 g_return_if_fail (index_ + length <= array->len); 1125 1126 if (array->element_free_func != NULL) 1127 { 1128 for (n = index_; n < index_ + length; n++) 1129 array->element_free_func (array->pdata[n]); 1130 } 1131 1132 if (index_ + length != array->len) 1133 { 1134 g_memmove (&array->pdata[index_], 1135 &array->pdata[index_ + length], 1136 (array->len - (index_ + length)) * sizeof (gpointer)); 1137 } 1138 1139 array->len -= length; 1140 if (G_UNLIKELY (g_mem_gc_friendly)) 1141 { 1142 guint i; 1143 for (i = 0; i < length; i++) 1144 array->pdata[array->len + i] = NULL; 1145 } 1146 } 1147 1148 /** 1149 * g_ptr_array_remove: 1150 * @array: a #GPtrArray. 1151 * @data: the pointer to remove. 1152 * @Returns: %TRUE if the pointer is removed. %FALSE if the pointer is 1153 * not found in the array. 1154 * 1155 * Removes the first occurrence of the given pointer from the pointer 1156 * array. The following elements are moved down one place. If @array 1157 * has a non-%NULL #GDestroyNotify function it is called for the 1158 * removed element. 1159 * 1160 * It returns %TRUE if the pointer was removed, or %FALSE if the 1161 * pointer was not found. 1162 **/ 1163 gboolean 1164 g_ptr_array_remove (GPtrArray *farray, 1165 gpointer data) 1166 { 1167 GRealPtrArray* array = (GRealPtrArray*) farray; 1168 guint i; 1169 1170 g_return_val_if_fail (array, FALSE); 1171 1172 for (i = 0; i < array->len; i += 1) 1173 { 1174 if (array->pdata[i] == data) 1175 { 1176 g_ptr_array_remove_index (farray, i); 1177 return TRUE; 1178 } 1179 } 1180 1181 return FALSE; 1182 } 1183 1184 /** 1185 * g_ptr_array_remove_fast: 1186 * @array: a #GPtrArray. 1187 * @data: the pointer to remove. 1188 * @Returns: %TRUE if the pointer was found in the array. 1189 * 1190 * Removes the first occurrence of the given pointer from the pointer 1191 * array. The last element in the array is used to fill in the space, 1192 * so this function does not preserve the order of the array. But it is 1193 * faster than g_ptr_array_remove(). If @array has a non-%NULL 1194 * #GDestroyNotify function it is called for the removed element. 1195 * 1196 * It returns %TRUE if the pointer was removed, or %FALSE if the 1197 * pointer was not found. 1198 **/ 1199 gboolean 1200 g_ptr_array_remove_fast (GPtrArray *farray, 1201 gpointer data) 1202 { 1203 GRealPtrArray* array = (GRealPtrArray*) farray; 1204 guint i; 1205 1206 g_return_val_if_fail (array, FALSE); 1207 1208 for (i = 0; i < array->len; i += 1) 1209 { 1210 if (array->pdata[i] == data) 1211 { 1212 g_ptr_array_remove_index_fast (farray, i); 1213 return TRUE; 1214 } 1215 } 1216 1217 return FALSE; 1218 } 1219 1220 /** 1221 * g_ptr_array_add: 1222 * @array: a #GPtrArray. 1223 * @data: the pointer to add. 1224 * 1225 * Adds a pointer to the end of the pointer array. The array will grow 1226 * in size automatically if necessary. 1227 **/ 1228 void 1229 g_ptr_array_add (GPtrArray *farray, 1230 gpointer data) 1231 { 1232 GRealPtrArray* array = (GRealPtrArray*) farray; 1233 1234 g_return_if_fail (array); 1235 1236 g_ptr_array_maybe_expand (array, 1); 1237 1238 array->pdata[array->len++] = data; 1239 } 1240 1241 /** 1242 * g_ptr_array_sort: 1243 * @array: a #GPtrArray. 1244 * @compare_func: comparison function. 1245 * 1246 * Sorts the array, using @compare_func which should be a qsort()-style 1247 * comparison function (returns less than zero for first arg is less 1248 * than second arg, zero for equal, greater than zero if irst arg is 1249 * greater than second arg). 1250 * 1251 * If two array elements compare equal, their order in the sorted array 1252 * is undefined. 1253 * 1254 * <note><para>The comparison function for g_ptr_array_sort() doesn't 1255 * take the pointers from the array as arguments, it takes pointers to 1256 * the pointers in the array.</para></note> 1257 **/ 1258 void 1259 g_ptr_array_sort (GPtrArray *array, 1260 GCompareFunc compare_func) 1261 { 1262 g_return_if_fail (array != NULL); 1263 1264 qsort (array->pdata, 1265 array->len, 1266 sizeof (gpointer), 1267 compare_func); 1268 } 1269 1270 /** 1271 * g_ptr_array_sort_with_data: 1272 * @array: a #GPtrArray. 1273 * @compare_func: comparison function. 1274 * @user_data: data to pass to @compare_func. 1275 * 1276 * Like g_ptr_array_sort(), but the comparison function has an extra 1277 * user data argument. 1278 * 1279 * <note><para>The comparison function for g_ptr_array_sort_with_data() 1280 * doesn't take the pointers from the array as arguments, it takes 1281 * pointers to the pointers in the array.</para></note> 1282 **/ 1283 void 1284 g_ptr_array_sort_with_data (GPtrArray *array, 1285 GCompareDataFunc compare_func, 1286 gpointer user_data) 1287 { 1288 g_return_if_fail (array != NULL); 1289 1290 g_qsort_with_data (array->pdata, 1291 array->len, 1292 sizeof (gpointer), 1293 compare_func, 1294 user_data); 1295 } 1296 1297 /** 1298 * g_ptr_array_foreach: 1299 * @array: a #GPtrArray 1300 * @func: the function to call for each array element 1301 * @user_data: user data to pass to the function 1302 * 1303 * Calls a function for each element of a #GPtrArray. 1304 * 1305 * Since: 2.4 1306 **/ 1307 void 1308 g_ptr_array_foreach (GPtrArray *array, 1309 GFunc func, 1310 gpointer user_data) 1311 { 1312 guint i; 1313 1314 g_return_if_fail (array); 1315 1316 for (i = 0; i < array->len; i++) 1317 (*func) (array->pdata[i], user_data); 1318 } 1319 1320 /** 1321 * SECTION:arrays_byte 1322 * @title: Byte Arrays 1323 * @short_description: arrays of bytes, which grow automatically as 1324 * elements are added 1325 * 1326 * #GByteArray is based on #GArray, to provide arrays of bytes which 1327 * grow automatically as elements are added. 1328 * 1329 * To create a new #GByteArray use g_byte_array_new(). 1330 * 1331 * To add elements to a #GByteArray, use g_byte_array_append(), and 1332 * g_byte_array_prepend(). 1333 * 1334 * To set the size of a #GByteArray, use g_byte_array_set_size(). 1335 * 1336 * To free a #GByteArray, use g_byte_array_free(). 1337 * 1338 * <example> 1339 * <title>Using a #GByteArray</title> 1340 * <programlisting> 1341 * GByteArray *gbarray; 1342 * gint i; 1343 * 1344 * gbarray = g_byte_array_new (<!-- -->); 1345 * for (i = 0; i < 10000; i++) 1346 * g_byte_array_append (gbarray, (guint8*) "abcd", 4); 1347 * 1348 * for (i = 0; i < 10000; i++) 1349 * { 1350 * g_assert (gbarray->data[4*i] == 'a'); 1351 * g_assert (gbarray->data[4*i+1] == 'b'); 1352 * g_assert (gbarray->data[4*i+2] == 'c'); 1353 * g_assert (gbarray->data[4*i+3] == 'd'); 1354 * } 1355 * 1356 * g_byte_array_free (gbarray, TRUE); 1357 * </programlisting> 1358 * </example> 1359 **/ 1360 1361 /** 1362 * GByteArray: 1363 * @data: a pointer to the element data. The data may be moved as 1364 * elements are added to the #GByteArray. 1365 * @len: the number of elements in the #GByteArray. 1366 * 1367 * The <structname>GByteArray</structname> struct allows access to the 1368 * public fields of a <structname>GByteArray</structname>. 1369 **/ 1370 1371 /** 1372 * g_byte_array_new: 1373 * @Returns: the new #GByteArray. 1374 * 1375 * Creates a new #GByteArray with a reference count of 1. 1376 **/ 1377 GByteArray* g_byte_array_new (void) 1378 { 1379 return (GByteArray*) g_array_sized_new (FALSE, FALSE, 1, 0); 1380 } 1381 1382 /** 1383 * g_byte_array_sized_new: 1384 * @reserved_size: number of bytes preallocated. 1385 * @Returns: the new #GByteArray. 1386 * 1387 * Creates a new #GByteArray with @reserved_size bytes preallocated. 1388 * This avoids frequent reallocation, if you are going to add many 1389 * bytes to the array. Note however that the size of the array is still 1390 * 0. 1391 **/ 1392 GByteArray* g_byte_array_sized_new (guint reserved_size) 1393 { 1394 return (GByteArray*) g_array_sized_new (FALSE, FALSE, 1, reserved_size); 1395 } 1396 1397 /** 1398 * g_byte_array_free: 1399 * @array: a #GByteArray. 1400 * @free_segment: if %TRUE the actual byte data is freed as well. 1401 * @Returns: the element data if @free_segment is %FALSE, otherwise 1402 * %NULL. The element data should be freed using g_free(). 1403 * 1404 * Frees the memory allocated by the #GByteArray. If @free_segment is 1405 * %TRUE it frees the actual byte data. If the reference count of 1406 * @array is greater than one, the #GByteArray wrapper is preserved but 1407 * the size of @array will be set to zero. 1408 **/ 1409 guint8* g_byte_array_free (GByteArray *array, 1410 gboolean free_segment) 1411 { 1412 return (guint8*) g_array_free ((GArray*) array, free_segment); 1413 } 1414 1415 /** 1416 * g_byte_array_ref: 1417 * @array: A #GByteArray. 1418 * 1419 * Atomically increments the reference count of @array by one. This 1420 * function is MT-safe and may be called from any thread. 1421 * 1422 * Returns: The passed in #GByteArray. 1423 * 1424 * Since: 2.22 1425 **/ 1426 GByteArray * 1427 g_byte_array_ref (GByteArray *array) 1428 { 1429 return (GByteArray *) g_array_ref ((GArray *) array); 1430 } 1431 1432 /** 1433 * g_byte_array_unref: 1434 * @array: A #GByteArray. 1435 * 1436 * Atomically decrements the reference count of @array by one. If the 1437 * reference count drops to 0, all memory allocated by the array is 1438 * released. This function is MT-safe and may be called from any 1439 * thread. 1440 * 1441 * Since: 2.22 1442 **/ 1443 void 1444 g_byte_array_unref (GByteArray *array) 1445 { 1446 g_array_unref ((GArray *) array); 1447 } 1448 1449 /** 1450 * g_byte_array_append: 1451 * @array: a #GByteArray. 1452 * @data: the byte data to be added. 1453 * @len: the number of bytes to add. 1454 * @Returns: the #GByteArray. 1455 * 1456 * Adds the given bytes to the end of the #GByteArray. The array will 1457 * grow in size automatically if necessary. 1458 **/ 1459 GByteArray* g_byte_array_append (GByteArray *array, 1460 const guint8 *data, 1461 guint len) 1462 { 1463 g_array_append_vals ((GArray*) array, (guint8*)data, len); 1464 1465 return array; 1466 } 1467 1468 /** 1469 * g_byte_array_prepend: 1470 * @array: a #GByteArray. 1471 * @data: the byte data to be added. 1472 * @len: the number of bytes to add. 1473 * @Returns: the #GByteArray. 1474 * 1475 * Adds the given data to the start of the #GByteArray. The array will 1476 * grow in size automatically if necessary. 1477 **/ 1478 GByteArray* g_byte_array_prepend (GByteArray *array, 1479 const guint8 *data, 1480 guint len) 1481 { 1482 g_array_prepend_vals ((GArray*) array, (guint8*)data, len); 1483 1484 return array; 1485 } 1486 1487 /** 1488 * g_byte_array_set_size: 1489 * @array: a #GByteArray. 1490 * @length: the new size of the #GByteArray. 1491 * @Returns: the #GByteArray. 1492 * 1493 * Sets the size of the #GByteArray, expanding it if necessary. 1494 **/ 1495 GByteArray* g_byte_array_set_size (GByteArray *array, 1496 guint length) 1497 { 1498 g_array_set_size ((GArray*) array, length); 1499 1500 return array; 1501 } 1502 1503 /** 1504 * g_byte_array_remove_index: 1505 * @array: a #GByteArray. 1506 * @index_: the index of the byte to remove. 1507 * @Returns: the #GByteArray. 1508 * 1509 * Removes the byte at the given index from a #GByteArray. The 1510 * following bytes are moved down one place. 1511 **/ 1512 GByteArray* g_byte_array_remove_index (GByteArray *array, 1513 guint index_) 1514 { 1515 g_array_remove_index ((GArray*) array, index_); 1516 1517 return array; 1518 } 1519 1520 /** 1521 * g_byte_array_remove_index_fast: 1522 * @array: a #GByteArray. 1523 * @index_: the index of the byte to remove. 1524 * @Returns: the #GByteArray. 1525 * 1526 * Removes the byte at the given index from a #GByteArray. The last 1527 * element in the array is used to fill in the space, so this function 1528 * does not preserve the order of the #GByteArray. But it is faster 1529 * than g_byte_array_remove_index(). 1530 **/ 1531 GByteArray* g_byte_array_remove_index_fast (GByteArray *array, 1532 guint index_) 1533 { 1534 g_array_remove_index_fast ((GArray*) array, index_); 1535 1536 return array; 1537 } 1538 1539 /** 1540 * g_byte_array_remove_range: 1541 * @array: a @GByteArray. 1542 * @index_: the index of the first byte to remove. 1543 * @length: the number of bytes to remove. 1544 * @Returns: the #GByteArray. 1545 * 1546 * Removes the given number of bytes starting at the given index from a 1547 * #GByteArray. The following elements are moved to close the gap. 1548 * 1549 * Since: 2.4 1550 **/ 1551 GByteArray* 1552 g_byte_array_remove_range (GByteArray *array, 1553 guint index_, 1554 guint length) 1555 { 1556 g_return_val_if_fail (array, NULL); 1557 g_return_val_if_fail (index_ < array->len, NULL); 1558 g_return_val_if_fail (index_ + length <= array->len, NULL); 1559 1560 return (GByteArray *)g_array_remove_range ((GArray*) array, index_, length); 1561 } 1562 1563 /** 1564 * g_byte_array_sort: 1565 * @array: a #GByteArray. 1566 * @compare_func: comparison function. 1567 * 1568 * Sorts a byte array, using @compare_func which should be a 1569 * qsort()-style comparison function (returns less than zero for first 1570 * arg is less than second arg, zero for equal, greater than zero if 1571 * first arg is greater than second arg). 1572 * 1573 * If two array elements compare equal, their order in the sorted array 1574 * is undefined. 1575 **/ 1576 void 1577 g_byte_array_sort (GByteArray *array, 1578 GCompareFunc compare_func) 1579 { 1580 g_array_sort ((GArray *) array, compare_func); 1581 } 1582 1583 /** 1584 * g_byte_array_sort_with_data: 1585 * @array: a #GByteArray. 1586 * @compare_func: comparison function. 1587 * @user_data: data to pass to @compare_func. 1588 * 1589 * Like g_byte_array_sort(), but the comparison function takes an extra 1590 * user data argument. 1591 **/ 1592 void 1593 g_byte_array_sort_with_data (GByteArray *array, 1594 GCompareDataFunc compare_func, 1595 gpointer user_data) 1596 { 1597 g_array_sort_with_data ((GArray *) array, compare_func, user_data); 1598 }