1 /* GLIB - Library of useful routines for C programming
2 * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
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.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
19 * Modified by the GLib Team and others 1997-2000. See the AUTHORS
20 * file for a list of people on the GLib Team. See the ChangeLog
21 * files for a list of changes. These files are distributed with
22 * GLib at ftp://ftp.gtk.org/pub/gtk/.
25 #undef G_DISABLE_ASSERT
33 /* Test data to be passed to any function which calls g_array_new(), providing
34 * the parameters for that call. Most #GArray tests should be repeated for all
35 * possible values of #ArrayTestData. */
38 gboolean zero_terminated
;
42 /* Assert that @garray contains @n_expected_elements as given in @expected_data.
43 * @garray must contain #gint elements. */
45 assert_int_array_equal (GArray
*garray
,
46 const gint
*expected_data
,
47 gsize n_expected_elements
)
51 g_assert_cmpuint (garray
->len
, ==, n_expected_elements
);
52 for (i
= 0; i
< garray
->len
; i
++)
53 g_assert_cmpint (g_array_index (garray
, gint
, i
), ==, expected_data
[i
]);
56 /* Iff config->zero_terminated is %TRUE, assert that the final element of
57 * @garray is zero. @garray must contain #gint elements. */
59 assert_int_array_zero_terminated (const ArrayTestData
*config
,
62 if (config
->zero_terminated
)
64 gint
*data
= (gint
*) garray
->data
;
65 g_assert_cmpint (data
[garray
->len
], ==, 0);
70 sum_up (gpointer data
,
73 gint
*sum
= (gint
*)user_data
;
75 *sum
+= GPOINTER_TO_INT (data
);
78 /* Check that expanding an array with g_array_set_size() clears the new elements
79 * if @clear_ was specified during construction. */
81 array_set_size (gconstpointer test_data
)
83 const ArrayTestData
*config
= test_data
;
87 garray
= g_array_new (config
->zero_terminated
, config
->clear_
, sizeof (gint
));
88 g_assert_cmpuint (garray
->len
, ==, 0);
89 assert_int_array_zero_terminated (config
, garray
);
91 g_array_set_size (garray
, 5);
92 g_assert_cmpuint (garray
->len
, ==, 5);
93 assert_int_array_zero_terminated (config
, garray
);
96 for (i
= 0; i
< 5; i
++)
97 g_assert_cmpint (g_array_index (garray
, gint
, i
), ==, 0);
99 g_array_unref (garray
);
102 /* As with array_set_size(), but with a sized array. */
104 array_set_size_sized (gconstpointer test_data
)
106 const ArrayTestData
*config
= test_data
;
110 garray
= g_array_sized_new (config
->zero_terminated
, config
->clear_
, sizeof (gint
), 10);
111 g_assert_cmpuint (garray
->len
, ==, 0);
112 assert_int_array_zero_terminated (config
, garray
);
114 g_array_set_size (garray
, 5);
115 g_assert_cmpuint (garray
->len
, ==, 5);
116 assert_int_array_zero_terminated (config
, garray
);
119 for (i
= 0; i
< 5; i
++)
120 g_assert_cmpint (g_array_index (garray
, gint
, i
), ==, 0);
122 g_array_unref (garray
);
125 /* Check that a zero-terminated array does actually have a zero terminator. */
127 array_new_zero_terminated (void)
130 gchar
*out_str
= NULL
;
132 garray
= g_array_new (TRUE
, FALSE
, sizeof (gchar
));
133 g_assert_cmpuint (garray
->len
, ==, 0);
135 g_array_append_vals (garray
, "hello", strlen ("hello"));
136 g_assert_cmpuint (garray
->len
, ==, 5);
137 g_assert_cmpstr (garray
->data
, ==, "hello");
139 out_str
= g_array_free (garray
, FALSE
);
140 g_assert_cmpstr (out_str
, ==, "hello");
144 /* Check that g_array_append_val() works correctly for various #GArray
147 array_append_val (gconstpointer test_data
)
149 const ArrayTestData
*config
= test_data
;
154 garray
= g_array_new (config
->zero_terminated
, config
->clear_
, sizeof (gint
));
155 for (i
= 0; i
< 10000; i
++)
156 g_array_append_val (garray
, i
);
157 assert_int_array_zero_terminated (config
, garray
);
159 for (i
= 0; i
< 10000; i
++)
160 g_assert_cmpint (g_array_index (garray
, gint
, i
), ==, i
);
162 segment
= (gint
*)g_array_free (garray
, FALSE
);
163 for (i
= 0; i
< 10000; i
++)
164 g_assert_cmpint (segment
[i
], ==, i
);
165 if (config
->zero_terminated
)
166 g_assert_cmpint (segment
[10000], ==, 0);
171 /* Check that g_array_prepend_val() works correctly for various #GArray
174 array_prepend_val (gconstpointer test_data
)
176 const ArrayTestData
*config
= test_data
;
180 garray
= g_array_new (config
->zero_terminated
, config
->clear_
, sizeof (gint
));
181 for (i
= 0; i
< 100; i
++)
182 g_array_prepend_val (garray
, i
);
183 assert_int_array_zero_terminated (config
, garray
);
185 for (i
= 0; i
< 100; i
++)
186 g_assert_cmpint (g_array_index (garray
, gint
, i
), ==, (100 - i
- 1));
188 g_array_free (garray
, TRUE
);
191 /* Test that g_array_prepend_vals() works correctly with various array
194 array_prepend_vals (gconstpointer test_data
)
196 const ArrayTestData
*config
= test_data
;
197 GArray
*garray
, *garray_out
;
198 const gint vals
[] = { 0, 1, 2, 3, 4 };
199 const gint expected_vals1
[] = { 0, 1 };
200 const gint expected_vals2
[] = { 2, 0, 1 };
201 const gint expected_vals3
[] = { 3, 4, 2, 0, 1 };
203 /* Set up an array. */
204 garray
= g_array_new (config
->zero_terminated
, config
->clear_
, sizeof (gint
));
205 assert_int_array_zero_terminated (config
, garray
);
207 /* Prepend several values to an empty array. */
208 garray_out
= g_array_prepend_vals (garray
, vals
, 2);
209 g_assert_true (garray
== garray_out
);
210 assert_int_array_equal (garray
, expected_vals1
, G_N_ELEMENTS (expected_vals1
));
211 assert_int_array_zero_terminated (config
, garray
);
213 /* Prepend a single value. */
214 garray_out
= g_array_prepend_vals (garray
, vals
+ 2, 1);
215 g_assert_true (garray
== garray_out
);
216 assert_int_array_equal (garray
, expected_vals2
, G_N_ELEMENTS (expected_vals2
));
217 assert_int_array_zero_terminated (config
, garray
);
219 /* Prepend several values to a non-empty array. */
220 garray_out
= g_array_prepend_vals (garray
, vals
+ 3, 2);
221 g_assert_true (garray
== garray_out
);
222 assert_int_array_equal (garray
, expected_vals3
, G_N_ELEMENTS (expected_vals3
));
223 assert_int_array_zero_terminated (config
, garray
);
225 /* Prepend no values. */
226 garray_out
= g_array_prepend_vals (garray
, vals
, 0);
227 g_assert_true (garray
== garray_out
);
228 assert_int_array_equal (garray
, expected_vals3
, G_N_ELEMENTS (expected_vals3
));
229 assert_int_array_zero_terminated (config
, garray
);
231 /* Prepend no values with %NULL data. */
232 garray_out
= g_array_prepend_vals (garray
, NULL
, 0);
233 g_assert_true (garray
== garray_out
);
234 assert_int_array_equal (garray
, expected_vals3
, G_N_ELEMENTS (expected_vals3
));
235 assert_int_array_zero_terminated (config
, garray
);
237 g_array_free (garray
, TRUE
);
240 /* Test that g_array_insert_vals() works correctly with various array
243 array_insert_vals (gconstpointer test_data
)
245 const ArrayTestData
*config
= test_data
;
246 GArray
*garray
, *garray_out
;
248 const gint vals
[] = { 0, 1, 2, 3, 4, 5, 6, 7 };
249 const gint expected_vals1
[] = { 0, 1 };
250 const gint expected_vals2
[] = { 0, 2, 3, 1 };
251 const gint expected_vals3
[] = { 0, 2, 3, 1, 4 };
252 const gint expected_vals4
[] = { 5, 0, 2, 3, 1, 4 };
253 const gint expected_vals5
[] = { 5, 0, 2, 3, 1, 4, 0, 0, 0, 0, 6, 7 };
255 /* Set up an array. */
256 garray
= g_array_new (config
->zero_terminated
, config
->clear_
, sizeof (gint
));
257 assert_int_array_zero_terminated (config
, garray
);
259 /* Insert several values at the beginning. */
260 garray_out
= g_array_insert_vals (garray
, 0, vals
, 2);
261 g_assert_true (garray
== garray_out
);
262 assert_int_array_equal (garray
, expected_vals1
, G_N_ELEMENTS (expected_vals1
));
263 assert_int_array_zero_terminated (config
, garray
);
265 /* Insert some more part-way through. */
266 garray_out
= g_array_insert_vals (garray
, 1, vals
+ 2, 2);
267 g_assert_true (garray
== garray_out
);
268 assert_int_array_equal (garray
, expected_vals2
, G_N_ELEMENTS (expected_vals2
));
269 assert_int_array_zero_terminated (config
, garray
);
271 /* And at the end. */
272 garray_out
= g_array_insert_vals (garray
, garray
->len
, vals
+ 4, 1);
273 g_assert_true (garray
== garray_out
);
274 assert_int_array_equal (garray
, expected_vals3
, G_N_ELEMENTS (expected_vals3
));
275 assert_int_array_zero_terminated (config
, garray
);
277 /* Then back at the beginning again. */
278 garray_out
= g_array_insert_vals (garray
, 0, vals
+ 5, 1);
279 g_assert_true (garray
== garray_out
);
280 assert_int_array_equal (garray
, expected_vals4
, G_N_ELEMENTS (expected_vals4
));
281 assert_int_array_zero_terminated (config
, garray
);
283 /* Insert zero elements. */
284 garray_out
= g_array_insert_vals (garray
, 0, vals
, 0);
285 g_assert_true (garray
== garray_out
);
286 assert_int_array_equal (garray
, expected_vals4
, G_N_ELEMENTS (expected_vals4
));
287 assert_int_array_zero_terminated (config
, garray
);
289 /* Insert zero elements with a %NULL pointer. */
290 garray_out
= g_array_insert_vals (garray
, 0, NULL
, 0);
291 g_assert_true (garray
== garray_out
);
292 assert_int_array_equal (garray
, expected_vals4
, G_N_ELEMENTS (expected_vals4
));
293 assert_int_array_zero_terminated (config
, garray
);
295 /* Insert some elements off the end of the array. The behaviour here depends
296 * on whether the array clears entries. */
297 garray_out
= g_array_insert_vals (garray
, garray
->len
+ 4, vals
+ 6, 2);
298 g_assert_true (garray
== garray_out
);
300 g_assert_cmpuint (garray
->len
, ==, G_N_ELEMENTS (expected_vals5
));
301 for (i
= 0; i
< G_N_ELEMENTS (expected_vals5
); i
++)
303 if (config
->clear_
|| i
< 6 || i
> 9)
304 g_assert_cmpint (g_array_index (garray
, gint
, i
), ==, expected_vals5
[i
]);
307 assert_int_array_zero_terminated (config
, garray
);
309 g_array_free (garray
, TRUE
);
312 /* Check that g_array_remove_index() works correctly for various #GArray
315 array_remove_index (gconstpointer test_data
)
317 const ArrayTestData
*config
= test_data
;
322 garray
= g_array_new (config
->zero_terminated
, config
->clear_
, sizeof (gint
));
323 for (i
= 0; i
< 100; i
++)
324 g_array_append_val (garray
, i
);
325 assert_int_array_zero_terminated (config
, garray
);
327 g_assert_cmpint (garray
->len
, ==, 100);
329 g_array_remove_index (garray
, 1);
330 g_array_remove_index (garray
, 3);
331 g_array_remove_index (garray
, 21);
332 g_array_remove_index (garray
, 57);
334 g_assert_cmpint (garray
->len
, ==, 96);
335 assert_int_array_zero_terminated (config
, garray
);
338 for (i
= 0; i
< garray
->len
; i
++)
340 cur
= g_array_index (garray
, gint
, i
);
341 g_assert (cur
!= 1 && cur
!= 4 && cur
!= 23 && cur
!= 60);
342 g_assert_cmpint (prev
, <, cur
);
346 g_array_free (garray
, TRUE
);
349 /* Check that g_array_remove_index_fast() works correctly for various #GArray
352 array_remove_index_fast (gconstpointer test_data
)
354 const ArrayTestData
*config
= test_data
;
359 garray
= g_array_new (config
->zero_terminated
, config
->clear_
, sizeof (gint
));
360 for (i
= 0; i
< 100; i
++)
361 g_array_append_val (garray
, i
);
363 g_assert_cmpint (garray
->len
, ==, 100);
364 assert_int_array_zero_terminated (config
, garray
);
366 g_array_remove_index_fast (garray
, 1);
367 g_array_remove_index_fast (garray
, 3);
368 g_array_remove_index_fast (garray
, 21);
369 g_array_remove_index_fast (garray
, 57);
371 g_assert_cmpint (garray
->len
, ==, 96);
372 assert_int_array_zero_terminated (config
, garray
);
375 for (i
= 0; i
< garray
->len
; i
++)
377 cur
= g_array_index (garray
, gint
, i
);
378 g_assert (cur
!= 1 && cur
!= 3 && cur
!= 21 && cur
!= 57);
381 g_assert_cmpint (prev
, <, cur
);
386 g_array_free (garray
, TRUE
);
389 /* Check that g_array_remove_range() works correctly for various #GArray
392 array_remove_range (gconstpointer test_data
)
394 const ArrayTestData
*config
= test_data
;
399 garray
= g_array_new (config
->zero_terminated
, config
->clear_
, sizeof (gint
));
400 for (i
= 0; i
< 100; i
++)
401 g_array_append_val (garray
, i
);
403 g_assert_cmpint (garray
->len
, ==, 100);
404 assert_int_array_zero_terminated (config
, garray
);
406 g_array_remove_range (garray
, 31, 4);
408 g_assert_cmpint (garray
->len
, ==, 96);
409 assert_int_array_zero_terminated (config
, garray
);
412 for (i
= 0; i
< garray
->len
; i
++)
414 cur
= g_array_index (garray
, gint
, i
);
415 g_assert (cur
< 31 || cur
> 34);
416 g_assert_cmpint (prev
, <, cur
);
420 /* Ensure the entire array can be cleared, even when empty. */
421 g_array_remove_range (garray
, 0, garray
->len
);
423 g_assert_cmpint (garray
->len
, ==, 0);
424 assert_int_array_zero_terminated (config
, garray
);
426 g_array_remove_range (garray
, 0, garray
->len
);
428 g_assert_cmpint (garray
->len
, ==, 0);
429 assert_int_array_zero_terminated (config
, garray
);
431 g_array_free (garray
, TRUE
);
435 array_ref_count (void)
441 garray
= g_array_new (FALSE
, FALSE
, sizeof (gint
));
442 g_assert_cmpint (g_array_get_element_size (garray
), ==, sizeof (gint
));
443 for (i
= 0; i
< 100; i
++)
444 g_array_prepend_val (garray
, i
);
446 /* check we can ref, unref and still access the array */
447 garray2
= g_array_ref (garray
);
448 g_assert (garray
== garray2
);
449 g_array_unref (garray2
);
450 for (i
= 0; i
< 100; i
++)
451 g_assert_cmpint (g_array_index (garray
, gint
, i
), ==, (100 - i
- 1));
453 /* garray2 should be an empty valid GArray wrapper */
454 garray2
= g_array_ref (garray
);
455 g_array_free (garray
, TRUE
);
457 g_assert_cmpint (garray2
->len
, ==, 0);
458 g_array_unref (garray2
);
462 int_compare (gconstpointer p1
, gconstpointer p2
)
471 int_compare_data (gconstpointer p1
, gconstpointer p2
, gpointer data
)
479 /* Check that g_array_sort() works correctly for various #GArray
482 array_sort (gconstpointer test_data
)
484 const ArrayTestData
*config
= test_data
;
489 garray
= g_array_new (config
->zero_terminated
, config
->clear_
, sizeof (gint
));
490 for (i
= 0; i
< 10000; i
++)
492 cur
= g_random_int_range (0, 10000);
493 g_array_append_val (garray
, cur
);
495 assert_int_array_zero_terminated (config
, garray
);
497 g_array_sort (garray
, int_compare
);
498 assert_int_array_zero_terminated (config
, garray
);
501 for (i
= 0; i
< garray
->len
; i
++)
503 cur
= g_array_index (garray
, gint
, i
);
504 g_assert_cmpint (prev
, <=, cur
);
508 g_array_free (garray
, TRUE
);
511 /* Check that g_array_sort_with_data() works correctly for various #GArray
514 array_sort_with_data (gconstpointer test_data
)
516 const ArrayTestData
*config
= test_data
;
521 garray
= g_array_new (config
->zero_terminated
, config
->clear_
, sizeof (gint
));
522 for (i
= 0; i
< 10000; i
++)
524 cur
= g_random_int_range (0, 10000);
525 g_array_append_val (garray
, cur
);
527 assert_int_array_zero_terminated (config
, garray
);
529 g_array_sort_with_data (garray
, int_compare_data
, NULL
);
530 assert_int_array_zero_terminated (config
, garray
);
533 for (i
= 0; i
< garray
->len
; i
++)
535 cur
= g_array_index (garray
, gint
, i
);
536 g_assert_cmpint (prev
, <=, cur
);
540 g_array_free (garray
, TRUE
);
543 static gint num_clear_func_invocations
= 0;
546 my_clear_func (gpointer data
)
548 num_clear_func_invocations
+= 1;
552 array_clear_func (void)
558 garray
= g_array_new (FALSE
, FALSE
, sizeof (gint
));
559 g_array_set_clear_func (garray
, my_clear_func
);
561 for (i
= 0; i
< 10; i
++)
563 cur
= g_random_int_range (0, 100);
564 g_array_append_val (garray
, cur
);
567 g_array_remove_index (garray
, 9);
568 g_assert_cmpint (num_clear_func_invocations
, ==, 1);
570 g_array_remove_range (garray
, 5, 3);
571 g_assert_cmpint (num_clear_func_invocations
, ==, 4);
573 g_array_remove_index_fast (garray
, 4);
574 g_assert_cmpint (num_clear_func_invocations
, ==, 5);
576 g_array_free (garray
, TRUE
);
577 g_assert_cmpint (num_clear_func_invocations
, ==, 10);
581 pointer_array_add (void)
588 gparray
= g_ptr_array_sized_new (1000);
590 for (i
= 0; i
< 10000; i
++)
591 g_ptr_array_add (gparray
, GINT_TO_POINTER (i
));
593 for (i
= 0; i
< 10000; i
++)
594 g_assert (g_ptr_array_index (gparray
, i
) == GINT_TO_POINTER (i
));
596 g_ptr_array_foreach (gparray
, sum_up
, &sum
);
597 g_assert (sum
== 49995000);
599 segment
= g_ptr_array_free (gparray
, FALSE
);
600 for (i
= 0; i
< 10000; i
++)
601 g_assert (segment
[i
] == GINT_TO_POINTER (i
));
606 pointer_array_insert (void)
613 gparray
= g_ptr_array_sized_new (1000);
615 for (i
= 0; i
< 10000; i
++)
617 index
= g_random_int_range (-1, i
+ 1);
618 g_ptr_array_insert (gparray
, index
, GINT_TO_POINTER (i
));
621 g_ptr_array_foreach (gparray
, sum_up
, &sum
);
622 g_assert (sum
== 49995000);
624 g_ptr_array_free (gparray
, TRUE
);
628 pointer_array_ref_count (void)
635 gparray
= g_ptr_array_new ();
636 for (i
= 0; i
< 10000; i
++)
637 g_ptr_array_add (gparray
, GINT_TO_POINTER (i
));
639 /* check we can ref, unref and still access the array */
640 gparray2
= g_ptr_array_ref (gparray
);
641 g_assert (gparray
== gparray2
);
642 g_ptr_array_unref (gparray2
);
643 for (i
= 0; i
< 10000; i
++)
644 g_assert (g_ptr_array_index (gparray
, i
) == GINT_TO_POINTER (i
));
646 g_ptr_array_foreach (gparray
, sum_up
, &sum
);
647 g_assert (sum
== 49995000);
649 /* gparray2 should be an empty valid GPtrArray wrapper */
650 gparray2
= g_ptr_array_ref (gparray
);
651 g_ptr_array_free (gparray
, TRUE
);
653 g_assert_cmpint (gparray2
->len
, ==, 0);
654 g_ptr_array_unref (gparray2
);
657 static gint num_free_func_invocations
= 0;
660 my_free_func (gpointer data
)
662 num_free_func_invocations
++;
667 pointer_array_free_func (void)
674 num_free_func_invocations
= 0;
675 gparray
= g_ptr_array_new_with_free_func (my_free_func
);
676 g_ptr_array_unref (gparray
);
677 g_assert_cmpint (num_free_func_invocations
, ==, 0);
679 gparray
= g_ptr_array_new_with_free_func (my_free_func
);
680 g_ptr_array_free (gparray
, TRUE
);
681 g_assert_cmpint (num_free_func_invocations
, ==, 0);
683 num_free_func_invocations
= 0;
684 gparray
= g_ptr_array_new_with_free_func (my_free_func
);
685 g_ptr_array_add (gparray
, g_strdup ("foo"));
686 g_ptr_array_add (gparray
, g_strdup ("bar"));
687 g_ptr_array_add (gparray
, g_strdup ("baz"));
688 g_ptr_array_remove_index (gparray
, 0);
689 g_assert_cmpint (num_free_func_invocations
, ==, 1);
690 g_ptr_array_remove_index_fast (gparray
, 1);
691 g_assert_cmpint (num_free_func_invocations
, ==, 2);
692 s
= g_strdup ("frob");
693 g_ptr_array_add (gparray
, s
);
694 g_assert (g_ptr_array_remove (gparray
, s
));
695 g_assert (!g_ptr_array_remove (gparray
, "nuun"));
696 g_assert (!g_ptr_array_remove_fast (gparray
, "mlo"));
697 g_assert_cmpint (num_free_func_invocations
, ==, 3);
698 s
= g_strdup ("frob");
699 g_ptr_array_add (gparray
, s
);
700 g_ptr_array_set_size (gparray
, 1);
701 g_assert_cmpint (num_free_func_invocations
, ==, 4);
702 g_ptr_array_ref (gparray
);
703 g_ptr_array_unref (gparray
);
704 g_assert_cmpint (num_free_func_invocations
, ==, 4);
705 g_ptr_array_unref (gparray
);
706 g_assert_cmpint (num_free_func_invocations
, ==, 5);
708 num_free_func_invocations
= 0;
709 gparray
= g_ptr_array_new_full (10, my_free_func
);
710 g_ptr_array_add (gparray
, g_strdup ("foo"));
711 g_ptr_array_add (gparray
, g_strdup ("bar"));
712 g_ptr_array_add (gparray
, g_strdup ("baz"));
713 g_ptr_array_set_size (gparray
, 20);
714 g_ptr_array_add (gparray
, NULL
);
715 gparray2
= g_ptr_array_ref (gparray
);
716 strv
= (gchar
**) g_ptr_array_free (gparray
, FALSE
);
717 g_assert_cmpint (num_free_func_invocations
, ==, 0);
719 g_ptr_array_unref (gparray2
);
720 g_assert_cmpint (num_free_func_invocations
, ==, 0);
722 num_free_func_invocations
= 0;
723 gparray
= g_ptr_array_new_with_free_func (my_free_func
);
724 g_ptr_array_add (gparray
, g_strdup ("foo"));
725 g_ptr_array_add (gparray
, g_strdup ("bar"));
726 g_ptr_array_add (gparray
, g_strdup ("baz"));
727 g_ptr_array_remove_range (gparray
, 1, 1);
728 g_ptr_array_unref (gparray
);
729 g_assert_cmpint (num_free_func_invocations
, ==, 3);
731 num_free_func_invocations
= 0;
732 gparray
= g_ptr_array_new_with_free_func (my_free_func
);
733 g_ptr_array_add (gparray
, g_strdup ("foo"));
734 g_ptr_array_add (gparray
, g_strdup ("bar"));
735 g_ptr_array_add (gparray
, g_strdup ("baz"));
736 g_ptr_array_free (gparray
, TRUE
);
737 g_assert_cmpint (num_free_func_invocations
, ==, 3);
739 num_free_func_invocations
= 0;
740 gparray
= g_ptr_array_new_with_free_func (my_free_func
);
741 g_ptr_array_add (gparray
, "foo");
742 g_ptr_array_add (gparray
, "bar");
743 g_ptr_array_add (gparray
, "baz");
744 g_ptr_array_set_free_func (gparray
, NULL
);
745 g_ptr_array_free (gparray
, TRUE
);
746 g_assert_cmpint (num_free_func_invocations
, ==, 0);
750 ptr_compare (gconstpointer p1
, gconstpointer p2
)
752 gpointer i1
= *(gpointer
*)p1
;
753 gpointer i2
= *(gpointer
*)p2
;
755 return GPOINTER_TO_INT (i1
) - GPOINTER_TO_INT (i2
);
759 ptr_compare_data (gconstpointer p1
, gconstpointer p2
, gpointer data
)
761 gpointer i1
= *(gpointer
*)p1
;
762 gpointer i2
= *(gpointer
*)p2
;
764 return GPOINTER_TO_INT (i1
) - GPOINTER_TO_INT (i2
);
768 pointer_array_sort (void)
775 gparray
= g_ptr_array_new ();
776 for (i
= 0; i
< 10000; i
++)
778 val
= g_random_int_range (0, 10000);
779 g_ptr_array_add (gparray
, GINT_TO_POINTER (val
));
782 g_ptr_array_sort (gparray
, ptr_compare
);
785 for (i
= 0; i
< 10000; i
++)
787 cur
= GPOINTER_TO_INT (g_ptr_array_index (gparray
, i
));
788 g_assert_cmpint (prev
, <=, cur
);
792 g_ptr_array_free (gparray
, TRUE
);
796 pointer_array_sort_with_data (void)
802 gparray
= g_ptr_array_new ();
803 for (i
= 0; i
< 10000; i
++)
804 g_ptr_array_add (gparray
, GINT_TO_POINTER (g_random_int_range (0, 10000)));
806 g_ptr_array_sort_with_data (gparray
, ptr_compare_data
, NULL
);
809 for (i
= 0; i
< 10000; i
++)
811 cur
= GPOINTER_TO_INT (g_ptr_array_index (gparray
, i
));
812 g_assert_cmpint (prev
, <=, cur
);
816 g_ptr_array_free (gparray
, TRUE
);
820 pointer_array_find_empty (void)
825 array
= g_ptr_array_new ();
827 g_assert_false (g_ptr_array_find (array
, "some-value", NULL
)); /* NULL index */
828 g_assert_false (g_ptr_array_find (array
, "some-value", &idx
)); /* non-NULL index */
829 g_assert_false (g_ptr_array_find_with_equal_func (array
, "some-value", g_str_equal
, NULL
)); /* NULL index */
830 g_assert_false (g_ptr_array_find_with_equal_func (array
, "some-value", g_str_equal
, &idx
)); /* non-NULL index */
832 g_ptr_array_free (array
, TRUE
);
836 pointer_array_find_non_empty (void)
840 const gchar
*str_pointer
= "static-string";
842 array
= g_ptr_array_new ();
844 g_ptr_array_add (array
, "some");
845 g_ptr_array_add (array
, "random");
846 g_ptr_array_add (array
, "values");
847 g_ptr_array_add (array
, "some");
848 g_ptr_array_add (array
, "duplicated");
849 g_ptr_array_add (array
, (gpointer
) str_pointer
);
851 g_assert_true (g_ptr_array_find_with_equal_func (array
, "random", g_str_equal
, NULL
)); /* NULL index */
852 g_assert_true (g_ptr_array_find_with_equal_func (array
, "random", g_str_equal
, &idx
)); /* non-NULL index */
853 g_assert_cmpuint (idx
, ==, 1);
855 g_assert_true (g_ptr_array_find_with_equal_func (array
, "some", g_str_equal
, &idx
)); /* duplicate element */
856 g_assert_cmpuint (idx
, ==, 0);
858 g_assert_false (g_ptr_array_find_with_equal_func (array
, "nope", g_str_equal
, NULL
));
860 g_assert_true (g_ptr_array_find_with_equal_func (array
, str_pointer
, g_str_equal
, &idx
));
861 g_assert_cmpuint (idx
, ==, 5);
863 g_assert_true (g_ptr_array_find_with_equal_func (array
, str_pointer
, NULL
, &idx
)); /* NULL equal func */
864 g_assert_cmpuint (idx
, ==, 5);
866 g_assert_true (g_ptr_array_find (array
, str_pointer
, &idx
)); /* NULL equal func */
867 g_assert_cmpuint (idx
, ==, 5);
869 g_ptr_array_free (array
, TRUE
);
873 steal_destroy_notify (gpointer data
)
875 guint
*counter
= data
;
876 *counter
= *counter
+ 1;
879 /* Test that g_ptr_array_steal_index() and g_ptr_array_steal_index_fast() can
880 * remove elements from a pointer array without the #GDestroyNotify being called. */
882 pointer_array_steal (void)
884 guint i1
= 0, i2
= 0, i3
= 0, i4
= 0;
886 GPtrArray
*array
= g_ptr_array_new_with_free_func (steal_destroy_notify
);
888 g_ptr_array_add (array
, &i1
);
889 g_ptr_array_add (array
, &i2
);
890 g_ptr_array_add (array
, &i3
);
891 g_ptr_array_add (array
, &i4
);
893 g_assert_cmpuint (array
->len
, ==, 4);
895 /* Remove a single element. */
896 out1
= g_ptr_array_steal_index (array
, 0);
897 g_assert_true (out1
== &i1
);
898 g_assert_cmpuint (i1
, ==, 0); /* should not have been destroyed */
900 /* Following elements should have been moved down. */
901 g_assert_cmpuint (array
->len
, ==, 3);
902 g_assert_true (g_ptr_array_index (array
, 0) == &i2
);
903 g_assert_true (g_ptr_array_index (array
, 1) == &i3
);
904 g_assert_true (g_ptr_array_index (array
, 2) == &i4
);
906 /* Remove another element, quickly. */
907 out2
= g_ptr_array_steal_index_fast (array
, 0);
908 g_assert_true (out2
== &i2
);
909 g_assert_cmpuint (i2
, ==, 0); /* should not have been destroyed */
911 /* Last element should have been swapped in place. */
912 g_assert_cmpuint (array
->len
, ==, 2);
913 g_assert_true (g_ptr_array_index (array
, 0) == &i4
);
914 g_assert_true (g_ptr_array_index (array
, 1) == &i3
);
916 /* Check that destroying the pointer array doesn’t affect the stolen elements. */
917 g_ptr_array_unref (array
);
919 g_assert_cmpuint (i1
, ==, 0);
920 g_assert_cmpuint (i2
, ==, 0);
921 g_assert_cmpuint (i3
, ==, 1);
922 g_assert_cmpuint (i4
, ==, 1);
926 byte_array_append (void)
932 gbarray
= g_byte_array_sized_new (1000);
933 for (i
= 0; i
< 10000; i
++)
934 g_byte_array_append (gbarray
, (guint8
*) "abcd", 4);
936 for (i
= 0; i
< 10000; i
++)
938 g_assert (gbarray
->data
[4*i
] == 'a');
939 g_assert (gbarray
->data
[4*i
+1] == 'b');
940 g_assert (gbarray
->data
[4*i
+2] == 'c');
941 g_assert (gbarray
->data
[4*i
+3] == 'd');
944 segment
= g_byte_array_free (gbarray
, FALSE
);
946 for (i
= 0; i
< 10000; i
++)
948 g_assert (segment
[4*i
] == 'a');
949 g_assert (segment
[4*i
+1] == 'b');
950 g_assert (segment
[4*i
+2] == 'c');
951 g_assert (segment
[4*i
+3] == 'd');
958 byte_array_prepend (void)
963 gbarray
= g_byte_array_new ();
964 g_byte_array_set_size (gbarray
, 1000);
966 for (i
= 0; i
< 10000; i
++)
967 g_byte_array_prepend (gbarray
, (guint8
*) "abcd", 4);
969 for (i
= 0; i
< 10000; i
++)
971 g_assert (gbarray
->data
[4*i
] == 'a');
972 g_assert (gbarray
->data
[4*i
+1] == 'b');
973 g_assert (gbarray
->data
[4*i
+2] == 'c');
974 g_assert (gbarray
->data
[4*i
+3] == 'd');
977 g_byte_array_free (gbarray
, TRUE
);
981 byte_array_ref_count (void)
984 GByteArray
*gbarray2
;
987 gbarray
= g_byte_array_new ();
988 for (i
= 0; i
< 10000; i
++)
989 g_byte_array_append (gbarray
, (guint8
*) "abcd", 4);
991 gbarray2
= g_byte_array_ref (gbarray
);
992 g_assert (gbarray2
== gbarray
);
993 g_byte_array_unref (gbarray2
);
994 for (i
= 0; i
< 10000; i
++)
996 g_assert (gbarray
->data
[4*i
] == 'a');
997 g_assert (gbarray
->data
[4*i
+1] == 'b');
998 g_assert (gbarray
->data
[4*i
+2] == 'c');
999 g_assert (gbarray
->data
[4*i
+3] == 'd');
1002 gbarray2
= g_byte_array_ref (gbarray
);
1003 g_assert (gbarray2
== gbarray
);
1004 g_byte_array_free (gbarray
, TRUE
);
1005 g_assert_cmpint (gbarray2
->len
, ==, 0);
1006 g_byte_array_unref (gbarray2
);
1010 byte_array_remove (void)
1012 GByteArray
*gbarray
;
1015 gbarray
= g_byte_array_new ();
1016 for (i
= 0; i
< 100; i
++)
1017 g_byte_array_append (gbarray
, (guint8
*) "abcd", 4);
1019 g_assert_cmpint (gbarray
->len
, ==, 400);
1021 g_byte_array_remove_index (gbarray
, 4);
1022 g_byte_array_remove_index (gbarray
, 4);
1023 g_byte_array_remove_index (gbarray
, 4);
1024 g_byte_array_remove_index (gbarray
, 4);
1026 g_assert_cmpint (gbarray
->len
, ==, 396);
1028 for (i
= 0; i
< 99; i
++)
1030 g_assert (gbarray
->data
[4*i
] == 'a');
1031 g_assert (gbarray
->data
[4*i
+1] == 'b');
1032 g_assert (gbarray
->data
[4*i
+2] == 'c');
1033 g_assert (gbarray
->data
[4*i
+3] == 'd');
1036 g_byte_array_free (gbarray
, TRUE
);
1040 byte_array_remove_fast (void)
1042 GByteArray
*gbarray
;
1045 gbarray
= g_byte_array_new ();
1046 for (i
= 0; i
< 100; i
++)
1047 g_byte_array_append (gbarray
, (guint8
*) "abcd", 4);
1049 g_assert_cmpint (gbarray
->len
, ==, 400);
1051 g_byte_array_remove_index_fast (gbarray
, 4);
1052 g_byte_array_remove_index_fast (gbarray
, 4);
1053 g_byte_array_remove_index_fast (gbarray
, 4);
1054 g_byte_array_remove_index_fast (gbarray
, 4);
1056 g_assert_cmpint (gbarray
->len
, ==, 396);
1058 for (i
= 0; i
< 99; i
++)
1060 g_assert (gbarray
->data
[4*i
] == 'a');
1061 g_assert (gbarray
->data
[4*i
+1] == 'b');
1062 g_assert (gbarray
->data
[4*i
+2] == 'c');
1063 g_assert (gbarray
->data
[4*i
+3] == 'd');
1066 g_byte_array_free (gbarray
, TRUE
);
1070 byte_array_remove_range (void)
1072 GByteArray
*gbarray
;
1075 gbarray
= g_byte_array_new ();
1076 for (i
= 0; i
< 100; i
++)
1077 g_byte_array_append (gbarray
, (guint8
*) "abcd", 4);
1079 g_assert_cmpint (gbarray
->len
, ==, 400);
1081 g_byte_array_remove_range (gbarray
, 12, 4);
1083 g_assert_cmpint (gbarray
->len
, ==, 396);
1085 for (i
= 0; i
< 99; i
++)
1087 g_assert (gbarray
->data
[4*i
] == 'a');
1088 g_assert (gbarray
->data
[4*i
+1] == 'b');
1089 g_assert (gbarray
->data
[4*i
+2] == 'c');
1090 g_assert (gbarray
->data
[4*i
+3] == 'd');
1093 /* Ensure the entire array can be cleared, even when empty. */
1094 g_byte_array_remove_range (gbarray
, 0, gbarray
->len
);
1095 g_byte_array_remove_range (gbarray
, 0, gbarray
->len
);
1097 g_byte_array_free (gbarray
, TRUE
);
1101 byte_compare (gconstpointer p1
, gconstpointer p2
)
1103 const guint8
*i1
= p1
;
1104 const guint8
*i2
= p2
;
1110 byte_compare_data (gconstpointer p1
, gconstpointer p2
, gpointer data
)
1112 const guint8
*i1
= p1
;
1113 const guint8
*i2
= p2
;
1119 byte_array_sort (void)
1121 GByteArray
*gbarray
;
1126 gbarray
= g_byte_array_new ();
1127 for (i
= 0; i
< 100; i
++)
1129 val
= 'a' + g_random_int_range (0, 26);
1130 g_byte_array_append (gbarray
, (guint8
*) &val
, 1);
1133 g_byte_array_sort (gbarray
, byte_compare
);
1136 for (i
= 0; i
< gbarray
->len
; i
++)
1138 cur
= gbarray
->data
[i
];
1139 g_assert_cmpint (prev
, <=, cur
);
1143 g_byte_array_free (gbarray
, TRUE
);
1147 byte_array_sort_with_data (void)
1149 GByteArray
*gbarray
;
1154 gbarray
= g_byte_array_new ();
1155 for (i
= 0; i
< 100; i
++)
1157 val
= 'a' + g_random_int_range (0, 26);
1158 g_byte_array_append (gbarray
, (guint8
*) &val
, 1);
1161 g_byte_array_sort_with_data (gbarray
, byte_compare_data
, NULL
);
1164 for (i
= 0; i
< gbarray
->len
; i
++)
1166 cur
= gbarray
->data
[i
];
1167 g_assert_cmpint (prev
, <=, cur
);
1171 g_byte_array_free (gbarray
, TRUE
);
1175 byte_array_new_take (void)
1177 GByteArray
*gbarray
;
1180 data
= g_memdup ("woooweeewow", 11);
1181 gbarray
= g_byte_array_new_take (data
, 11);
1182 g_assert (gbarray
->data
== data
);
1183 g_assert_cmpuint (gbarray
->len
, ==, 11);
1184 g_byte_array_free (gbarray
, TRUE
);
1188 byte_array_free_to_bytes (void)
1190 GByteArray
*gbarray
;
1195 gbarray
= g_byte_array_new ();
1196 g_byte_array_append (gbarray
, (guint8
*)"woooweeewow", 11);
1197 memory
= gbarray
->data
;
1199 bytes
= g_byte_array_free_to_bytes (gbarray
);
1200 g_assert (bytes
!= NULL
);
1201 g_assert_cmpuint (g_bytes_get_size (bytes
), ==, 11);
1202 g_assert (g_bytes_get_data (bytes
, &size
) == memory
);
1203 g_assert_cmpuint (size
, ==, 11);
1205 g_bytes_unref (bytes
);
1209 add_array_test (const gchar
*test_path
,
1210 const ArrayTestData
*config
,
1211 GTestDataFunc test_func
)
1213 gchar
*test_name
= NULL
;
1215 test_name
= g_strdup_printf ("%s/%s-%s",
1217 config
->zero_terminated
? "zero-terminated" : "non-zero-terminated",
1218 config
->clear_
? "clear" : "no-clear");
1219 g_test_add_data_func (test_name
, config
, test_func
);
1224 main (int argc
, char *argv
[])
1226 /* Test all possible combinations of g_array_new() parameters. */
1227 const ArrayTestData array_configurations
[] =
1236 g_test_init (&argc
, &argv
, NULL
);
1238 g_test_bug_base ("https://bugzilla.gnome.org/");
1241 g_test_add_func ("/array/new/zero-terminated", array_new_zero_terminated
);
1242 g_test_add_func ("/array/ref-count", array_ref_count
);
1243 g_test_add_func ("/array/clear-func", array_clear_func
);
1245 for (i
= 0; i
< G_N_ELEMENTS (array_configurations
); i
++)
1247 add_array_test ("/array/set-size", &array_configurations
[i
], array_set_size
);
1248 add_array_test ("/array/set-size/sized", &array_configurations
[i
], array_set_size_sized
);
1249 add_array_test ("/array/append-val", &array_configurations
[i
], array_append_val
);
1250 add_array_test ("/array/prepend-val", &array_configurations
[i
], array_prepend_val
);
1251 add_array_test ("/array/prepend-vals", &array_configurations
[i
], array_prepend_vals
);
1252 add_array_test ("/array/insert-vals", &array_configurations
[i
], array_insert_vals
);
1253 add_array_test ("/array/remove-index", &array_configurations
[i
], array_remove_index
);
1254 add_array_test ("/array/remove-index-fast", &array_configurations
[i
], array_remove_index_fast
);
1255 add_array_test ("/array/remove-range", &array_configurations
[i
], array_remove_range
);
1256 add_array_test ("/array/sort", &array_configurations
[i
], array_sort
);
1257 add_array_test ("/array/sort-with-data", &array_configurations
[i
], array_sort_with_data
);
1260 /* pointer arrays */
1261 g_test_add_func ("/pointerarray/add", pointer_array_add
);
1262 g_test_add_func ("/pointerarray/insert", pointer_array_insert
);
1263 g_test_add_func ("/pointerarray/ref-count", pointer_array_ref_count
);
1264 g_test_add_func ("/pointerarray/free-func", pointer_array_free_func
);
1265 g_test_add_func ("/pointerarray/sort", pointer_array_sort
);
1266 g_test_add_func ("/pointerarray/sort-with-data", pointer_array_sort_with_data
);
1267 g_test_add_func ("/pointerarray/find/empty", pointer_array_find_empty
);
1268 g_test_add_func ("/pointerarray/find/non-empty", pointer_array_find_non_empty
);
1269 g_test_add_func ("/pointerarray/steal", pointer_array_steal
);
1272 g_test_add_func ("/bytearray/append", byte_array_append
);
1273 g_test_add_func ("/bytearray/prepend", byte_array_prepend
);
1274 g_test_add_func ("/bytearray/remove", byte_array_remove
);
1275 g_test_add_func ("/bytearray/remove-fast", byte_array_remove_fast
);
1276 g_test_add_func ("/bytearray/remove-range", byte_array_remove_range
);
1277 g_test_add_func ("/bytearray/ref-count", byte_array_ref_count
);
1278 g_test_add_func ("/bytearray/sort", byte_array_sort
);
1279 g_test_add_func ("/bytearray/sort-with-data", byte_array_sort_with_data
);
1280 g_test_add_func ("/bytearray/new-take", byte_array_new_take
);
1281 g_test_add_func ("/bytearray/free-to-bytes", byte_array_free_to_bytes
);
1283 return g_test_run ();