1 /* GLIB - Library of useful routines for C programming
2 * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
3 *
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
8 *
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
13 *
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
16 */
17
18 /*
19 * Modified by the GLib Team and others 1997-2000. See the AUTHORS
20 * file for a list of people on the GLib Team. See the ChangeLog
21 * files for a list of changes. These files are distributed with
22 * GLib at ftp://ftp.gtk.org/pub/gtk/.
23 */
24
25 #undef G_DISABLE_ASSERT
26
27 #include <stdio.h>
28 #include <stdlib.h>
29 #include <string.h>
30 #include "glib.h"
31
32 /* Test data to be passed to any function which calls g_array_new(), providing
33 * the parameters for that call. Most #GArray tests should be repeated for all
34 * possible values of #ArrayTestData. */
35 typedef struct
36 {
37 gboolean zero_terminated;
38 gboolean clear_;
39 } ArrayTestData;
40
41 /* Assert that @garray contains @n_expected_elements as given in @expected_data.
42 * @garray must contain #gint elements. */
43 static void
assert_int_array_equal(GArray * garray,const gint * expected_data,gsize n_expected_elements)44 assert_int_array_equal (GArray *garray,
45 const gint *expected_data,
46 gsize n_expected_elements)
47 {
48 gsize i;
49
50 g_assert_cmpuint (garray->len, ==, n_expected_elements);
51 for (i = 0; i < garray->len; i++)
52 g_assert_cmpint (g_array_index (garray, gint, i), ==, expected_data[i]);
53 }
54
55 /* Iff config->zero_terminated is %TRUE, assert that the final element of
56 * @garray is zero. @garray must contain #gint elements. */
57 static void
assert_int_array_zero_terminated(const ArrayTestData * config,GArray * garray)58 assert_int_array_zero_terminated (const ArrayTestData *config,
59 GArray *garray)
60 {
61 if (config->zero_terminated)
62 {
63 gint *data = (gint *) garray->data;
64 g_assert_cmpint (data[garray->len], ==, 0);
65 }
66 }
67
68 static void
sum_up(gpointer data,gpointer user_data)69 sum_up (gpointer data,
70 gpointer user_data)
71 {
72 gint *sum = (gint *)user_data;
73
74 *sum += GPOINTER_TO_INT (data);
75 }
76
77 /* Check that expanding an array with g_array_set_size() clears the new elements
78 * if @clear_ was specified during construction. */
79 static void
array_set_size(gconstpointer test_data)80 array_set_size (gconstpointer test_data)
81 {
82 const ArrayTestData *config = test_data;
83 GArray *garray;
84 gsize i;
85
86 garray = g_array_new (config->zero_terminated, config->clear_, sizeof (gint));
87 g_assert_cmpuint (garray->len, ==, 0);
88 assert_int_array_zero_terminated (config, garray);
89
90 g_array_set_size (garray, 5);
91 g_assert_cmpuint (garray->len, ==, 5);
92 assert_int_array_zero_terminated (config, garray);
93
94 if (config->clear_)
95 for (i = 0; i < 5; i++)
96 g_assert_cmpint (g_array_index (garray, gint, i), ==, 0);
97
98 g_array_unref (garray);
99 }
100
101 /* As with array_set_size(), but with a sized array. */
102 static void
array_set_size_sized(gconstpointer test_data)103 array_set_size_sized (gconstpointer test_data)
104 {
105 const ArrayTestData *config = test_data;
106 GArray *garray;
107 gsize i;
108
109 garray = g_array_sized_new (config->zero_terminated, config->clear_, sizeof (gint), 10);
110 g_assert_cmpuint (garray->len, ==, 0);
111 assert_int_array_zero_terminated (config, garray);
112
113 g_array_set_size (garray, 5);
114 g_assert_cmpuint (garray->len, ==, 5);
115 assert_int_array_zero_terminated (config, garray);
116
117 if (config->clear_)
118 for (i = 0; i < 5; i++)
119 g_assert_cmpint (g_array_index (garray, gint, i), ==, 0);
120
121 g_array_unref (garray);
122 }
123
124 /* Check that a zero-terminated array does actually have a zero terminator. */
125 static void
array_new_zero_terminated(void)126 array_new_zero_terminated (void)
127 {
128 GArray *garray;
129 gchar *out_str = NULL;
130
131 garray = g_array_new (TRUE, FALSE, sizeof (gchar));
132 g_assert_cmpuint (garray->len, ==, 0);
133
134 g_array_append_vals (garray, "hello", strlen ("hello"));
135 g_assert_cmpuint (garray->len, ==, 5);
136 g_assert_cmpstr (garray->data, ==, "hello");
137
138 out_str = g_array_free (garray, FALSE);
139 g_assert_cmpstr (out_str, ==, "hello");
140 g_free (out_str);
141 }
142
143 /* Check g_array_steal() function */
144 static void
array_steal(void)145 array_steal (void)
146 {
147 const guint array_size = 10000;
148 GArray *garray;
149 gint *adata;
150 guint i;
151 gsize len, past_len;
152
153 garray = g_array_new (FALSE, FALSE, sizeof (gint));
154 adata = (gint *) g_array_steal (garray, NULL);
155 g_assert_null (adata);
156
157 adata = (gint *) g_array_steal (garray, &len);
158 g_assert_null (adata);
159 g_assert_cmpint (len, ==, 0);
160
161 for (i = 0; i < array_size; i++)
162 g_array_append_val (garray, i);
163
164 for (i = 0; i < array_size; i++)
165 g_assert_cmpint (g_array_index (garray, gint, i), ==, i);
166
167
168 past_len = garray->len;
169 adata = (gint *) g_array_steal (garray, &len);
170 for (i = 0; i < array_size; i++)
171 g_assert_cmpint (adata[i], ==, i);
172
173 g_assert_cmpint (past_len, ==, len);
174 g_assert_cmpint (garray->len, ==, 0);
175
176 g_array_append_val (garray, i);
177
178 g_assert_cmpint (adata[0], ==, 0);
179 g_assert_cmpint (g_array_index (garray, gint, 0), ==, array_size);
180 g_assert_cmpint (garray->len, ==, 1);
181
182 g_array_remove_index (garray, 0);
183
184 for (i = 0; i < array_size; i++)
185 g_array_append_val (garray, i);
186
187 g_assert_cmpint (garray->len, ==, array_size);
188 g_assert_cmpmem (adata, array_size * sizeof (gint),
189 garray->data, array_size * sizeof (gint));
190 g_free (adata);
191 g_array_free (garray, TRUE);
192 }
193
194 /* Check that g_array_append_val() works correctly for various #GArray
195 * configurations. */
196 static void
array_append_val(gconstpointer test_data)197 array_append_val (gconstpointer test_data)
198 {
199 const ArrayTestData *config = test_data;
200 GArray *garray;
201 gint i;
202 gint *segment;
203
204 garray = g_array_new (config->zero_terminated, config->clear_, sizeof (gint));
205 for (i = 0; i < 10000; i++)
206 g_array_append_val (garray, i);
207 assert_int_array_zero_terminated (config, garray);
208
209 for (i = 0; i < 10000; i++)
210 g_assert_cmpint (g_array_index (garray, gint, i), ==, i);
211
212 segment = (gint*)g_array_free (garray, FALSE);
213 for (i = 0; i < 10000; i++)
214 g_assert_cmpint (segment[i], ==, i);
215 if (config->zero_terminated)
216 g_assert_cmpint (segment[10000], ==, 0);
217
218 g_free (segment);
219 }
220
221 /* Check that g_array_prepend_val() works correctly for various #GArray
222 * configurations. */
223 static void
array_prepend_val(gconstpointer test_data)224 array_prepend_val (gconstpointer test_data)
225 {
226 const ArrayTestData *config = test_data;
227 GArray *garray;
228 gint i;
229
230 garray = g_array_new (config->zero_terminated, config->clear_, sizeof (gint));
231 for (i = 0; i < 100; i++)
232 g_array_prepend_val (garray, i);
233 assert_int_array_zero_terminated (config, garray);
234
235 for (i = 0; i < 100; i++)
236 g_assert_cmpint (g_array_index (garray, gint, i), ==, (100 - i - 1));
237
238 g_array_free (garray, TRUE);
239 }
240
241 /* Test that g_array_prepend_vals() works correctly with various array
242 * configurations. */
243 static void
array_prepend_vals(gconstpointer test_data)244 array_prepend_vals (gconstpointer test_data)
245 {
246 const ArrayTestData *config = test_data;
247 GArray *garray, *garray_out;
248 const gint vals[] = { 0, 1, 2, 3, 4 };
249 const gint expected_vals1[] = { 0, 1 };
250 const gint expected_vals2[] = { 2, 0, 1 };
251 const gint expected_vals3[] = { 3, 4, 2, 0, 1 };
252
253 /* Set up an array. */
254 garray = g_array_new (config->zero_terminated, config->clear_, sizeof (gint));
255 assert_int_array_zero_terminated (config, garray);
256
257 /* Prepend several values to an empty array. */
258 garray_out = g_array_prepend_vals (garray, vals, 2);
259 g_assert_true (garray == garray_out);
260 assert_int_array_equal (garray, expected_vals1, G_N_ELEMENTS (expected_vals1));
261 assert_int_array_zero_terminated (config, garray);
262
263 /* Prepend a single value. */
264 garray_out = g_array_prepend_vals (garray, vals + 2, 1);
265 g_assert_true (garray == garray_out);
266 assert_int_array_equal (garray, expected_vals2, G_N_ELEMENTS (expected_vals2));
267 assert_int_array_zero_terminated (config, garray);
268
269 /* Prepend several values to a non-empty array. */
270 garray_out = g_array_prepend_vals (garray, vals + 3, 2);
271 g_assert_true (garray == garray_out);
272 assert_int_array_equal (garray, expected_vals3, G_N_ELEMENTS (expected_vals3));
273 assert_int_array_zero_terminated (config, garray);
274
275 /* Prepend no values. */
276 garray_out = g_array_prepend_vals (garray, vals, 0);
277 g_assert_true (garray == garray_out);
278 assert_int_array_equal (garray, expected_vals3, G_N_ELEMENTS (expected_vals3));
279 assert_int_array_zero_terminated (config, garray);
280
281 /* Prepend no values with %NULL data. */
282 garray_out = g_array_prepend_vals (garray, NULL, 0);
283 g_assert_true (garray == garray_out);
284 assert_int_array_equal (garray, expected_vals3, G_N_ELEMENTS (expected_vals3));
285 assert_int_array_zero_terminated (config, garray);
286
287 g_array_free (garray, TRUE);
288 }
289
290 /* Test that g_array_insert_vals() works correctly with various array
291 * configurations. */
292 static void
array_insert_vals(gconstpointer test_data)293 array_insert_vals (gconstpointer test_data)
294 {
295 const ArrayTestData *config = test_data;
296 GArray *garray, *garray_out;
297 gsize i;
298 const gint vals[] = { 0, 1, 2, 3, 4, 5, 6, 7 };
299 const gint expected_vals1[] = { 0, 1 };
300 const gint expected_vals2[] = { 0, 2, 3, 1 };
301 const gint expected_vals3[] = { 0, 2, 3, 1, 4 };
302 const gint expected_vals4[] = { 5, 0, 2, 3, 1, 4 };
303 const gint expected_vals5[] = { 5, 0, 2, 3, 1, 4, 0, 0, 0, 0, 6, 7 };
304
305 /* Set up an array. */
306 garray = g_array_new (config->zero_terminated, config->clear_, sizeof (gint));
307 assert_int_array_zero_terminated (config, garray);
308
309 /* Insert several values at the beginning. */
310 garray_out = g_array_insert_vals (garray, 0, vals, 2);
311 g_assert_true (garray == garray_out);
312 assert_int_array_equal (garray, expected_vals1, G_N_ELEMENTS (expected_vals1));
313 assert_int_array_zero_terminated (config, garray);
314
315 /* Insert some more part-way through. */
316 garray_out = g_array_insert_vals (garray, 1, vals + 2, 2);
317 g_assert_true (garray == garray_out);
318 assert_int_array_equal (garray, expected_vals2, G_N_ELEMENTS (expected_vals2));
319 assert_int_array_zero_terminated (config, garray);
320
321 /* And at the end. */
322 garray_out = g_array_insert_vals (garray, garray->len, vals + 4, 1);
323 g_assert_true (garray == garray_out);
324 assert_int_array_equal (garray, expected_vals3, G_N_ELEMENTS (expected_vals3));
325 assert_int_array_zero_terminated (config, garray);
326
327 /* Then back at the beginning again. */
328 garray_out = g_array_insert_vals (garray, 0, vals + 5, 1);
329 g_assert_true (garray == garray_out);
330 assert_int_array_equal (garray, expected_vals4, G_N_ELEMENTS (expected_vals4));
331 assert_int_array_zero_terminated (config, garray);
332
333 /* Insert zero elements. */
334 garray_out = g_array_insert_vals (garray, 0, vals, 0);
335 g_assert_true (garray == garray_out);
336 assert_int_array_equal (garray, expected_vals4, G_N_ELEMENTS (expected_vals4));
337 assert_int_array_zero_terminated (config, garray);
338
339 /* Insert zero elements with a %NULL pointer. */
340 garray_out = g_array_insert_vals (garray, 0, NULL, 0);
341 g_assert_true (garray == garray_out);
342 assert_int_array_equal (garray, expected_vals4, G_N_ELEMENTS (expected_vals4));
343 assert_int_array_zero_terminated (config, garray);
344
345 /* Insert some elements off the end of the array. The behaviour here depends
346 * on whether the array clears entries. */
347 garray_out = g_array_insert_vals (garray, garray->len + 4, vals + 6, 2);
348 g_assert_true (garray == garray_out);
349
350 g_assert_cmpuint (garray->len, ==, G_N_ELEMENTS (expected_vals5));
351 for (i = 0; i < G_N_ELEMENTS (expected_vals5); i++)
352 {
353 if (config->clear_ || i < 6 || i > 9)
354 g_assert_cmpint (g_array_index (garray, gint, i), ==, expected_vals5[i]);
355 }
356
357 assert_int_array_zero_terminated (config, garray);
358
359 g_array_free (garray, TRUE);
360 }
361
362 /* Check that g_array_remove_index() works correctly for various #GArray
363 * configurations. */
364 static void
array_remove_index(gconstpointer test_data)365 array_remove_index (gconstpointer test_data)
366 {
367 const ArrayTestData *config = test_data;
368 GArray *garray;
369 guint i;
370 gint prev, cur;
371
372 garray = g_array_new (config->zero_terminated, config->clear_, sizeof (gint));
373 for (i = 0; i < 100; i++)
374 g_array_append_val (garray, i);
375 assert_int_array_zero_terminated (config, garray);
376
377 g_assert_cmpint (garray->len, ==, 100);
378
379 g_array_remove_index (garray, 1);
380 g_array_remove_index (garray, 3);
381 g_array_remove_index (garray, 21);
382 g_array_remove_index (garray, 57);
383
384 g_assert_cmpint (garray->len, ==, 96);
385 assert_int_array_zero_terminated (config, garray);
386
387 prev = -1;
388 for (i = 0; i < garray->len; i++)
389 {
390 cur = g_array_index (garray, gint, i);
391 g_assert (cur != 1 && cur != 4 && cur != 23 && cur != 60);
392 g_assert_cmpint (prev, <, cur);
393 prev = cur;
394 }
395
396 g_array_free (garray, TRUE);
397 }
398
399 /* Check that g_array_remove_index_fast() works correctly for various #GArray
400 * configurations. */
401 static void
array_remove_index_fast(gconstpointer test_data)402 array_remove_index_fast (gconstpointer test_data)
403 {
404 const ArrayTestData *config = test_data;
405 GArray *garray;
406 guint i;
407 gint prev, cur;
408
409 garray = g_array_new (config->zero_terminated, config->clear_, sizeof (gint));
410 for (i = 0; i < 100; i++)
411 g_array_append_val (garray, i);
412
413 g_assert_cmpint (garray->len, ==, 100);
414 assert_int_array_zero_terminated (config, garray);
415
416 g_array_remove_index_fast (garray, 1);
417 g_array_remove_index_fast (garray, 3);
418 g_array_remove_index_fast (garray, 21);
419 g_array_remove_index_fast (garray, 57);
420
421 g_assert_cmpint (garray->len, ==, 96);
422 assert_int_array_zero_terminated (config, garray);
423
424 prev = -1;
425 for (i = 0; i < garray->len; i++)
426 {
427 cur = g_array_index (garray, gint, i);
428 g_assert (cur != 1 && cur != 3 && cur != 21 && cur != 57);
429 if (cur < 96)
430 {
431 g_assert_cmpint (prev, <, cur);
432 prev = cur;
433 }
434 }
435
436 g_array_free (garray, TRUE);
437 }
438
439 /* Check that g_array_remove_range() works correctly for various #GArray
440 * configurations. */
441 static void
array_remove_range(gconstpointer test_data)442 array_remove_range (gconstpointer test_data)
443 {
444 const ArrayTestData *config = test_data;
445 GArray *garray;
446 guint i;
447 gint prev, cur;
448
449 garray = g_array_new (config->zero_terminated, config->clear_, sizeof (gint));
450 for (i = 0; i < 100; i++)
451 g_array_append_val (garray, i);
452
453 g_assert_cmpint (garray->len, ==, 100);
454 assert_int_array_zero_terminated (config, garray);
455
456 g_array_remove_range (garray, 31, 4);
457
458 g_assert_cmpint (garray->len, ==, 96);
459 assert_int_array_zero_terminated (config, garray);
460
461 prev = -1;
462 for (i = 0; i < garray->len; i++)
463 {
464 cur = g_array_index (garray, gint, i);
465 g_assert (cur < 31 || cur > 34);
466 g_assert_cmpint (prev, <, cur);
467 prev = cur;
468 }
469
470 /* Ensure the entire array can be cleared, even when empty. */
471 g_array_remove_range (garray, 0, garray->len);
472
473 g_assert_cmpint (garray->len, ==, 0);
474 assert_int_array_zero_terminated (config, garray);
475
476 g_array_remove_range (garray, 0, garray->len);
477
478 g_assert_cmpint (garray->len, ==, 0);
479 assert_int_array_zero_terminated (config, garray);
480
481 g_array_free (garray, TRUE);
482 }
483
484 static void
array_ref_count(void)485 array_ref_count (void)
486 {
487 GArray *garray;
488 GArray *garray2;
489 gint i;
490
491 garray = g_array_new (FALSE, FALSE, sizeof (gint));
492 g_assert_cmpint (g_array_get_element_size (garray), ==, sizeof (gint));
493 for (i = 0; i < 100; i++)
494 g_array_prepend_val (garray, i);
495
496 /* check we can ref, unref and still access the array */
497 garray2 = g_array_ref (garray);
498 g_assert (garray == garray2);
499 g_array_unref (garray2);
500 for (i = 0; i < 100; i++)
501 g_assert_cmpint (g_array_index (garray, gint, i), ==, (100 - i - 1));
502
503 /* garray2 should be an empty valid GArray wrapper */
504 garray2 = g_array_ref (garray);
505 g_array_free (garray, TRUE);
506
507 g_assert_cmpint (garray2->len, ==, 0);
508 g_array_unref (garray2);
509 }
510
511 static int
int_compare(gconstpointer p1,gconstpointer p2)512 int_compare (gconstpointer p1, gconstpointer p2)
513 {
514 const gint *i1 = p1;
515 const gint *i2 = p2;
516
517 return *i1 - *i2;
518 }
519
520 static void
array_copy(gconstpointer test_data)521 array_copy (gconstpointer test_data)
522 {
523 GArray *array, *array_copy;
524 gsize i;
525 const ArrayTestData *config = test_data;
526 const gsize array_size = 100;
527
528 /* Testing degenerated cases */
529 if (g_test_undefined ())
530 {
531 g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL,
532 "*assertion*!= NULL*");
533 array = g_array_copy (NULL);
534 g_test_assert_expected_messages ();
535
536 g_assert_null (array);
537 }
538
539 /* Testing simple copy */
540 array = g_array_new (config->zero_terminated, config->clear_, sizeof (gint));
541
542 for (i = 0; i < array_size; i++)
543 g_array_append_val (array, i);
544
545 array_copy = g_array_copy (array);
546
547 /* Check internal data */
548 for (i = 0; i < array_size; i++)
549 g_assert_cmpuint (g_array_index (array, gint, i), ==,
550 g_array_index (array_copy, gint, i));
551
552 /* Check internal parameters ('zero_terminated' flag) */
553 if (config->zero_terminated)
554 {
555 const gint *data = (const gint *) array_copy->data;
556 g_assert_cmpint (data[array_copy->len], ==, 0);
557 }
558
559 /* Check internal parameters ('clear' flag) */
560 if (config->clear_)
561 {
562 guint old_length = array_copy->len;
563 g_array_set_size (array_copy, old_length + 5);
564 for (i = old_length; i < old_length + 5; i++)
565 g_assert_cmpint (g_array_index (array_copy, gint, i), ==, 0);
566 }
567
568 /* Clean-up */
569 g_array_unref (array);
570 g_array_unref (array_copy);
571 }
572
573 static int
int_compare_data(gconstpointer p1,gconstpointer p2,gpointer data)574 int_compare_data (gconstpointer p1, gconstpointer p2, gpointer data)
575 {
576 const gint *i1 = p1;
577 const gint *i2 = p2;
578
579 return *i1 - *i2;
580 }
581
582 /* Check that g_array_sort() works correctly for various #GArray
583 * configurations. */
584 static void
array_sort(gconstpointer test_data)585 array_sort (gconstpointer test_data)
586 {
587 const ArrayTestData *config = test_data;
588 GArray *garray;
589 guint i;
590 gint prev, cur;
591
592 garray = g_array_new (config->zero_terminated, config->clear_, sizeof (gint));
593
594 /* Sort empty array */
595 g_array_sort (garray, int_compare);
596
597 for (i = 0; i < 10000; i++)
598 {
599 cur = g_random_int_range (0, 10000);
600 g_array_append_val (garray, cur);
601 }
602 assert_int_array_zero_terminated (config, garray);
603
604 g_array_sort (garray, int_compare);
605 assert_int_array_zero_terminated (config, garray);
606
607 prev = -1;
608 for (i = 0; i < garray->len; i++)
609 {
610 cur = g_array_index (garray, gint, i);
611 g_assert_cmpint (prev, <=, cur);
612 prev = cur;
613 }
614
615 g_array_free (garray, TRUE);
616 }
617
618 /* Check that g_array_sort_with_data() works correctly for various #GArray
619 * configurations. */
620 static void
array_sort_with_data(gconstpointer test_data)621 array_sort_with_data (gconstpointer test_data)
622 {
623 const ArrayTestData *config = test_data;
624 GArray *garray;
625 guint i;
626 gint prev, cur;
627
628 garray = g_array_new (config->zero_terminated, config->clear_, sizeof (gint));
629
630 /* Sort empty array */
631 g_array_sort_with_data (garray, int_compare_data, NULL);
632
633 for (i = 0; i < 10000; i++)
634 {
635 cur = g_random_int_range (0, 10000);
636 g_array_append_val (garray, cur);
637 }
638 assert_int_array_zero_terminated (config, garray);
639
640 g_array_sort_with_data (garray, int_compare_data, NULL);
641 assert_int_array_zero_terminated (config, garray);
642
643 prev = -1;
644 for (i = 0; i < garray->len; i++)
645 {
646 cur = g_array_index (garray, gint, i);
647 g_assert_cmpint (prev, <=, cur);
648 prev = cur;
649 }
650
651 g_array_free (garray, TRUE);
652 }
653
654 static gint num_clear_func_invocations = 0;
655
656 static void
my_clear_func(gpointer data)657 my_clear_func (gpointer data)
658 {
659 num_clear_func_invocations += 1;
660 }
661
662 static void
array_clear_func(void)663 array_clear_func (void)
664 {
665 GArray *garray;
666 gint i;
667 gint cur;
668
669 garray = g_array_new (FALSE, FALSE, sizeof (gint));
670 g_array_set_clear_func (garray, my_clear_func);
671
672 for (i = 0; i < 10; i++)
673 {
674 cur = g_random_int_range (0, 100);
675 g_array_append_val (garray, cur);
676 }
677
678 g_array_remove_index (garray, 9);
679 g_assert_cmpint (num_clear_func_invocations, ==, 1);
680
681 g_array_remove_range (garray, 5, 3);
682 g_assert_cmpint (num_clear_func_invocations, ==, 4);
683
684 g_array_remove_index_fast (garray, 4);
685 g_assert_cmpint (num_clear_func_invocations, ==, 5);
686
687 g_array_free (garray, TRUE);
688 g_assert_cmpint (num_clear_func_invocations, ==, 10);
689 }
690
691 /* Defining a comparison function for testing g_array_binary_search() */
692 static gint
cmpint(gconstpointer a,gconstpointer b)693 cmpint (gconstpointer a, gconstpointer b)
694 {
695 const gint *_a = a;
696 const gint *_b = b;
697
698 return *_a - *_b;
699 }
700
701 /* Testing g_array_binary_search() function */
702 static void
test_array_binary_search(void)703 test_array_binary_search (void)
704 {
705 GArray *garray;
706 guint i, matched_index;
707
708 if (g_test_undefined ())
709 {
710 /* Testing degenerated cases */
711 garray = g_array_sized_new (FALSE, FALSE, sizeof (guint), 0);
712 g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL,
713 "*assertion*!= NULL*");
714 g_assert_false (g_array_binary_search (NULL, &i, cmpint, NULL));
715 g_test_assert_expected_messages ();
716
717 g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL,
718 "*assertion*!= NULL*");
719 g_assert_false (g_array_binary_search (garray, &i, NULL, NULL));
720 g_test_assert_expected_messages ();
721 g_array_free (garray, TRUE);
722 }
723
724 /* Testing array of size 0 */
725 garray = g_array_sized_new (FALSE, FALSE, sizeof (guint), 0);
726
727 i = 1;
728 g_assert_false (g_array_binary_search (garray, &i, cmpint, NULL));
729
730 g_array_free (garray, TRUE);
731
732 /* Testing array of size 1 */
733 garray = g_array_sized_new (FALSE, FALSE, sizeof (guint), 1);
734 i = 1;
735 g_array_append_val (garray, i);
736
737 g_assert_true (g_array_binary_search (garray, &i, cmpint, NULL));
738
739 i = 0;
740 g_assert_false (g_array_binary_search (garray, &i, cmpint, NULL));
741
742 i = 2;
743 g_assert_false (g_array_binary_search (garray, &i, cmpint, NULL));
744
745 g_array_free (garray, TRUE);
746
747 /* Testing array of size 2 */
748 garray = g_array_sized_new (FALSE, FALSE, sizeof (guint), 2);
749 for (i = 1; i < 3; i++)
750 g_array_append_val (garray, i);
751
752 for (i = 1; i < 3; i++)
753 g_assert_true (g_array_binary_search (garray, &i, cmpint, NULL));
754
755 i = 0;
756 g_assert_false (g_array_binary_search (garray, &i, cmpint, NULL));
757
758 i = 4;
759 g_assert_false (g_array_binary_search (garray, &i, cmpint, NULL));
760
761 g_array_free (garray, TRUE);
762
763 /* Testing array of size 3 */
764 garray = g_array_sized_new (FALSE, FALSE, sizeof (guint), 3);
765 for (i = 1; i < 4; i++)
766 g_array_append_val (garray, i);
767
768 for (i = 1; i < 4; i++)
769 g_assert_true (g_array_binary_search (garray, &i, cmpint, NULL));
770
771 i = 0;
772 g_assert_false (g_array_binary_search (garray, &i, cmpint, NULL));
773
774 i = 5;
775 g_assert_false (g_array_binary_search (garray, &i, cmpint, NULL));
776
777 g_array_free (garray, TRUE);
778
779 /* Testing array of size 10000 */
780 garray = g_array_sized_new (FALSE, FALSE, sizeof (guint), 10000);
781
782 for (i = 1; i < 10001; i++)
783 g_array_append_val (garray, i);
784
785 for (i = 1; i < 10001; i++)
786 g_assert_true (g_array_binary_search (garray, &i, cmpint, NULL));
787
788 for (i = 1; i < 10001; i++)
789 {
790 g_assert_true (g_array_binary_search (garray, &i, cmpint, &matched_index));
791 g_assert_cmpint (i, ==, matched_index + 1);
792 }
793
794 /* Testing negative result */
795 i = 0;
796 g_assert_false (g_array_binary_search (garray, &i, cmpint, NULL));
797 g_assert_false (g_array_binary_search (garray, &i, cmpint, &matched_index));
798
799 i = 10002;
800 g_assert_false (g_array_binary_search (garray, &i, cmpint, NULL));
801 g_assert_false (g_array_binary_search (garray, &i, cmpint, &matched_index));
802
803 g_array_free (garray, TRUE);
804
805 /* Test for a not-found element in the middle of the array. */
806 garray = g_array_sized_new (FALSE, FALSE, sizeof (guint), 3);
807 for (i = 1; i < 10; i += 2)
808 g_array_append_val (garray, i);
809
810 i = 0;
811 g_assert_false (g_array_binary_search (garray, &i, cmpint, NULL));
812
813 i = 2;
814 g_assert_false (g_array_binary_search (garray, &i, cmpint, NULL));
815
816 i = 10;
817 g_assert_false (g_array_binary_search (garray, &i, cmpint, NULL));
818
819 g_array_free (garray, TRUE);
820 }
821
822 static void
test_array_copy_sized(void)823 test_array_copy_sized (void)
824 {
825 GArray *array1 = NULL, *array2 = NULL, *array3 = NULL;
826 int val = 5;
827
828 g_test_summary ("Test that copying a newly-allocated sized array works.");
829
830 array1 = g_array_sized_new (FALSE, FALSE, sizeof (int), 1);
831 array2 = g_array_copy (array1);
832
833 g_assert_cmpuint (array2->len, ==, array1->len);
834
835 g_array_append_val (array1, val);
836 array3 = g_array_copy (array1);
837
838 g_assert_cmpuint (array3->len, ==, array1->len);
839 g_assert_cmpuint (g_array_index (array3, int, 0), ==, g_array_index (array1, int, 0));
840 g_assert_cmpuint (array3->len, ==, 1);
841 g_assert_cmpuint (g_array_index (array3, int, 0), ==, val);
842
843 g_array_unref (array3);
844 g_array_unref (array2);
845 g_array_unref (array1);
846 }
847
848 /* Check g_ptr_array_steal() function */
849 static void
pointer_array_steal(void)850 pointer_array_steal (void)
851 {
852 const guint array_size = 10000;
853 GPtrArray *gparray;
854 gpointer *pdata;
855 guint i;
856 gsize len, past_len;
857
858 gparray = g_ptr_array_new ();
859 pdata = g_ptr_array_steal (gparray, NULL);
860 g_assert_null (pdata);
861
862 pdata = g_ptr_array_steal (gparray, &len);
863 g_assert_null (pdata);
864 g_assert_cmpint (len, ==, 0);
865
866 for (i = 0; i < array_size; i++)
867 g_ptr_array_add (gparray, GINT_TO_POINTER (i));
868
869 past_len = gparray->len;
870 pdata = g_ptr_array_steal (gparray, &len);
871 g_assert_cmpint (gparray->len, ==, 0);
872 g_assert_cmpint (past_len, ==, len);
873 g_ptr_array_add (gparray, GINT_TO_POINTER (10));
874
875 g_assert_cmpint ((gsize) pdata[0], ==, (gsize) GINT_TO_POINTER (0));
876 g_assert_cmpint ((gsize) g_ptr_array_index (gparray, 0), ==,
877 (gsize) GINT_TO_POINTER (10));
878 g_assert_cmpint (gparray->len, ==, 1);
879
880 g_ptr_array_remove_index (gparray, 0);
881
882 for (i = 0; i < array_size; i++)
883 g_ptr_array_add (gparray, GINT_TO_POINTER (i));
884 g_assert_cmpmem (pdata, array_size * sizeof (gpointer),
885 gparray->pdata, array_size * sizeof (gpointer));
886 g_free (pdata);
887
888 g_ptr_array_free (gparray, TRUE);
889 }
890
891 static void
pointer_array_add(void)892 pointer_array_add (void)
893 {
894 GPtrArray *gparray;
895 gint i;
896 gint sum = 0;
897 gpointer *segment;
898
899 gparray = g_ptr_array_sized_new (1000);
900
901 for (i = 0; i < 10000; i++)
902 g_ptr_array_add (gparray, GINT_TO_POINTER (i));
903
904 for (i = 0; i < 10000; i++)
905 g_assert (g_ptr_array_index (gparray, i) == GINT_TO_POINTER (i));
906
907 g_ptr_array_foreach (gparray, sum_up, &sum);
908 g_assert (sum == 49995000);
909
910 segment = g_ptr_array_free (gparray, FALSE);
911 for (i = 0; i < 10000; i++)
912 g_assert (segment[i] == GINT_TO_POINTER (i));
913 g_free (segment);
914 }
915
916 static void
pointer_array_insert(void)917 pointer_array_insert (void)
918 {
919 GPtrArray *gparray;
920 gint i;
921 gint sum = 0;
922 gint index;
923
924 gparray = g_ptr_array_sized_new (1000);
925
926 for (i = 0; i < 10000; i++)
927 {
928 index = g_random_int_range (-1, i + 1);
929 g_ptr_array_insert (gparray, index, GINT_TO_POINTER (i));
930 }
931
932 g_ptr_array_foreach (gparray, sum_up, &sum);
933 g_assert (sum == 49995000);
934
935 g_ptr_array_free (gparray, TRUE);
936 }
937
938 static void
pointer_array_ref_count(void)939 pointer_array_ref_count (void)
940 {
941 GPtrArray *gparray;
942 GPtrArray *gparray2;
943 gint i;
944 gint sum = 0;
945
946 gparray = g_ptr_array_new ();
947 for (i = 0; i < 10000; i++)
948 g_ptr_array_add (gparray, GINT_TO_POINTER (i));
949
950 /* check we can ref, unref and still access the array */
951 gparray2 = g_ptr_array_ref (gparray);
952 g_assert (gparray == gparray2);
953 g_ptr_array_unref (gparray2);
954 for (i = 0; i < 10000; i++)
955 g_assert (g_ptr_array_index (gparray, i) == GINT_TO_POINTER (i));
956
957 g_ptr_array_foreach (gparray, sum_up, &sum);
958 g_assert (sum == 49995000);
959
960 /* gparray2 should be an empty valid GPtrArray wrapper */
961 gparray2 = g_ptr_array_ref (gparray);
962 g_ptr_array_free (gparray, TRUE);
963
964 g_assert_cmpint (gparray2->len, ==, 0);
965 g_ptr_array_unref (gparray2);
966 }
967
968 static gint num_free_func_invocations = 0;
969
970 static void
my_free_func(gpointer data)971 my_free_func (gpointer data)
972 {
973 num_free_func_invocations++;
974 g_free (data);
975 }
976
977 static void
pointer_array_free_func(void)978 pointer_array_free_func (void)
979 {
980 GPtrArray *gparray;
981 GPtrArray *gparray2;
982 gchar **strv;
983 gchar *s;
984
985 num_free_func_invocations = 0;
986 gparray = g_ptr_array_new_with_free_func (my_free_func);
987 g_ptr_array_unref (gparray);
988 g_assert_cmpint (num_free_func_invocations, ==, 0);
989
990 gparray = g_ptr_array_new_with_free_func (my_free_func);
991 g_ptr_array_free (gparray, TRUE);
992 g_assert_cmpint (num_free_func_invocations, ==, 0);
993
994 num_free_func_invocations = 0;
995 gparray = g_ptr_array_new_with_free_func (my_free_func);
996 g_ptr_array_add (gparray, g_strdup ("foo"));
997 g_ptr_array_add (gparray, g_strdup ("bar"));
998 g_ptr_array_add (gparray, g_strdup ("baz"));
999 g_ptr_array_remove_index (gparray, 0);
1000 g_assert_cmpint (num_free_func_invocations, ==, 1);
1001 g_ptr_array_remove_index_fast (gparray, 1);
1002 g_assert_cmpint (num_free_func_invocations, ==, 2);
1003 s = g_strdup ("frob");
1004 g_ptr_array_add (gparray, s);
1005 g_assert (g_ptr_array_remove (gparray, s));
1006 g_assert (!g_ptr_array_remove (gparray, "nuun"));
1007 g_assert (!g_ptr_array_remove_fast (gparray, "mlo"));
1008 g_assert_cmpint (num_free_func_invocations, ==, 3);
1009 s = g_strdup ("frob");
1010 g_ptr_array_add (gparray, s);
1011 g_ptr_array_set_size (gparray, 1);
1012 g_assert_cmpint (num_free_func_invocations, ==, 4);
1013 g_ptr_array_ref (gparray);
1014 g_ptr_array_unref (gparray);
1015 g_assert_cmpint (num_free_func_invocations, ==, 4);
1016 g_ptr_array_unref (gparray);
1017 g_assert_cmpint (num_free_func_invocations, ==, 5);
1018
1019 num_free_func_invocations = 0;
1020 gparray = g_ptr_array_new_full (10, my_free_func);
1021 g_ptr_array_add (gparray, g_strdup ("foo"));
1022 g_ptr_array_add (gparray, g_strdup ("bar"));
1023 g_ptr_array_add (gparray, g_strdup ("baz"));
1024 g_ptr_array_set_size (gparray, 20);
1025 g_ptr_array_add (gparray, NULL);
1026 gparray2 = g_ptr_array_ref (gparray);
1027 strv = (gchar **) g_ptr_array_free (gparray, FALSE);
1028 g_assert_cmpint (num_free_func_invocations, ==, 0);
1029 g_strfreev (strv);
1030 g_ptr_array_unref (gparray2);
1031 g_assert_cmpint (num_free_func_invocations, ==, 0);
1032
1033 num_free_func_invocations = 0;
1034 gparray = g_ptr_array_new_with_free_func (my_free_func);
1035 g_ptr_array_add (gparray, g_strdup ("foo"));
1036 g_ptr_array_add (gparray, g_strdup ("bar"));
1037 g_ptr_array_add (gparray, g_strdup ("baz"));
1038 g_ptr_array_remove_range (gparray, 1, 1);
1039 g_ptr_array_unref (gparray);
1040 g_assert_cmpint (num_free_func_invocations, ==, 3);
1041
1042 num_free_func_invocations = 0;
1043 gparray = g_ptr_array_new_with_free_func (my_free_func);
1044 g_ptr_array_add (gparray, g_strdup ("foo"));
1045 g_ptr_array_add (gparray, g_strdup ("bar"));
1046 g_ptr_array_add (gparray, g_strdup ("baz"));
1047 g_ptr_array_free (gparray, TRUE);
1048 g_assert_cmpint (num_free_func_invocations, ==, 3);
1049
1050 num_free_func_invocations = 0;
1051 gparray = g_ptr_array_new_with_free_func (my_free_func);
1052 g_ptr_array_add (gparray, "foo");
1053 g_ptr_array_add (gparray, "bar");
1054 g_ptr_array_add (gparray, "baz");
1055 g_ptr_array_set_free_func (gparray, NULL);
1056 g_ptr_array_free (gparray, TRUE);
1057 g_assert_cmpint (num_free_func_invocations, ==, 0);
1058 }
1059
1060 static gpointer
ptr_array_copy_func(gconstpointer src,gpointer userdata)1061 ptr_array_copy_func (gconstpointer src, gpointer userdata)
1062 {
1063 gsize *dst = g_malloc (sizeof (gsize));
1064 *dst = *((gsize *) src);
1065 return dst;
1066 }
1067
1068 /* Test the g_ptr_array_copy() function */
1069 static void
pointer_array_copy(void)1070 pointer_array_copy (void)
1071 {
1072 GPtrArray *ptr_array, *ptr_array2;
1073 gsize i;
1074 const gsize array_size = 100;
1075 gsize *array_test = g_malloc (array_size * sizeof (gsize));
1076
1077 g_test_summary ("Check all normal behaviour of stealing elements from one "
1078 "array to append to another, covering different array sizes "
1079 "and element copy functions");
1080
1081 if (g_test_undefined ())
1082 {
1083 /* Testing degenerated cases */
1084 g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL,
1085 "*assertion*!= NULL*");
1086 ptr_array = g_ptr_array_copy (NULL, NULL, NULL);
1087 g_test_assert_expected_messages ();
1088 g_assert_cmpuint ((gsize) ptr_array, ==, (gsize) NULL);
1089 }
1090
1091 /* Initializing array_test */
1092 for (i = 0; i < array_size; i++)
1093 array_test[i] = i;
1094
1095 /* Test copy an empty array */
1096 ptr_array = g_ptr_array_sized_new (0);
1097 ptr_array2 = g_ptr_array_copy (ptr_array, NULL, NULL);
1098
1099 g_assert_cmpuint (ptr_array2->len, ==, ptr_array->len);
1100
1101 g_ptr_array_unref (ptr_array);
1102 g_ptr_array_unref (ptr_array2);
1103
1104 /* Test simple copy */
1105 ptr_array = g_ptr_array_sized_new (array_size);
1106
1107 for (i = 0; i < array_size; i++)
1108 g_ptr_array_add (ptr_array, &array_test[i]);
1109
1110 ptr_array2 = g_ptr_array_copy (ptr_array, NULL, NULL);
1111
1112 g_assert_cmpuint (ptr_array2->len, ==, ptr_array->len);
1113 for (i = 0; i < array_size; i++)
1114 g_assert_cmpuint (*((gsize *) g_ptr_array_index (ptr_array2, i)), ==, i);
1115
1116 for (i = 0; i < array_size; i++)
1117 g_assert_cmpuint ((gsize) g_ptr_array_index (ptr_array, i), ==,
1118 (gsize) g_ptr_array_index (ptr_array2, i));
1119
1120 g_ptr_array_free (ptr_array2, TRUE);
1121
1122 /* Test copy through GCopyFunc */
1123 ptr_array2 = g_ptr_array_copy (ptr_array, ptr_array_copy_func, NULL);
1124 g_ptr_array_set_free_func (ptr_array2, g_free);
1125
1126 g_assert_cmpuint (ptr_array2->len, ==, ptr_array->len);
1127 for (i = 0; i < array_size; i++)
1128 g_assert_cmpuint (*((gsize *) g_ptr_array_index (ptr_array2, i)), ==, i);
1129
1130 for (i = 0; i < array_size; i++)
1131 g_assert_cmpuint ((gsize) g_ptr_array_index (ptr_array, i), !=,
1132 (gsize) g_ptr_array_index (ptr_array2, i));
1133
1134 g_ptr_array_free (ptr_array2, TRUE);
1135
1136 /* Final cleanup */
1137 g_ptr_array_free (ptr_array, TRUE);
1138 g_free (array_test);
1139 }
1140
1141 /* Test the g_ptr_array_extend() function */
1142 static void
pointer_array_extend(void)1143 pointer_array_extend (void)
1144 {
1145 GPtrArray *ptr_array, *ptr_array2;
1146 gsize i;
1147 const gsize array_size = 100;
1148 gsize *array_test = g_malloc (array_size * sizeof (gsize));
1149
1150 if (g_test_undefined ())
1151 {
1152 /* Testing degenerated cases */
1153 ptr_array = g_ptr_array_sized_new (0);
1154 g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL,
1155 "*assertion*!= NULL*");
1156 g_ptr_array_extend (NULL, ptr_array, NULL, NULL);
1157 g_test_assert_expected_messages ();
1158
1159 g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL,
1160 "*assertion*!= NULL*");
1161 g_ptr_array_extend (ptr_array, NULL, NULL, NULL);
1162 g_test_assert_expected_messages ();
1163
1164 g_ptr_array_unref (ptr_array);
1165 }
1166
1167 /* Initializing array_test */
1168 for (i = 0; i < array_size; i++)
1169 array_test[i] = i;
1170
1171 /* Testing extend with array of size zero */
1172 ptr_array = g_ptr_array_sized_new (0);
1173 ptr_array2 = g_ptr_array_sized_new (0);
1174
1175 g_ptr_array_extend (ptr_array, ptr_array2, NULL, NULL);
1176
1177 g_assert_cmpuint (ptr_array->len, ==, 0);
1178 g_assert_cmpuint (ptr_array2->len, ==, 0);
1179
1180 g_ptr_array_unref (ptr_array);
1181 g_ptr_array_unref (ptr_array2);
1182
1183 /* Testing extend an array of size zero */
1184 ptr_array = g_ptr_array_sized_new (array_size);
1185 ptr_array2 = g_ptr_array_sized_new (0);
1186
1187 for (i = 0; i < array_size; i++)
1188 {
1189 g_ptr_array_add (ptr_array, &array_test[i]);
1190 }
1191
1192 g_ptr_array_extend (ptr_array, ptr_array2, NULL, NULL);
1193
1194 for (i = 0; i < array_size; i++)
1195 g_assert_cmpuint (*((gsize *) g_ptr_array_index (ptr_array, i)), ==, i);
1196
1197 g_ptr_array_unref (ptr_array);
1198 g_ptr_array_unref (ptr_array2);
1199
1200 /* Testing extend an array of size zero */
1201 ptr_array = g_ptr_array_sized_new (0);
1202 ptr_array2 = g_ptr_array_sized_new (array_size);
1203
1204 for (i = 0; i < array_size; i++)
1205 {
1206 g_ptr_array_add (ptr_array2, &array_test[i]);
1207 }
1208
1209 g_ptr_array_extend (ptr_array, ptr_array2, NULL, NULL);
1210
1211 for (i = 0; i < array_size; i++)
1212 g_assert_cmpuint (*((gsize *) g_ptr_array_index (ptr_array, i)), ==, i);
1213
1214 g_ptr_array_unref (ptr_array);
1215 g_ptr_array_unref (ptr_array2);
1216
1217 /* Testing simple extend */
1218 ptr_array = g_ptr_array_sized_new (array_size / 2);
1219 ptr_array2 = g_ptr_array_sized_new (array_size / 2);
1220
1221 for (i = 0; i < array_size / 2; i++)
1222 {
1223 g_ptr_array_add (ptr_array, &array_test[i]);
1224 g_ptr_array_add (ptr_array2, &array_test[i + (array_size / 2)]);
1225 }
1226
1227 g_ptr_array_extend (ptr_array, ptr_array2, NULL, NULL);
1228
1229 for (i = 0; i < array_size; i++)
1230 g_assert_cmpuint (*((gsize *) g_ptr_array_index (ptr_array, i)), ==, i);
1231
1232 g_ptr_array_unref (ptr_array);
1233 g_ptr_array_unref (ptr_array2);
1234
1235 /* Testing extend with GCopyFunc */
1236 ptr_array = g_ptr_array_sized_new (array_size / 2);
1237 ptr_array2 = g_ptr_array_sized_new (array_size / 2);
1238
1239 for (i = 0; i < array_size / 2; i++)
1240 {
1241 g_ptr_array_add (ptr_array, &array_test[i]);
1242 g_ptr_array_add (ptr_array2, &array_test[i + (array_size / 2)]);
1243 }
1244
1245 g_ptr_array_extend (ptr_array, ptr_array2, ptr_array_copy_func, NULL);
1246
1247 for (i = 0; i < array_size; i++)
1248 g_assert_cmpuint (*((gsize *) g_ptr_array_index (ptr_array, i)), ==, i);
1249
1250 /* Clean-up memory */
1251 for (i = array_size / 2; i < array_size; i++)
1252 g_free (g_ptr_array_index (ptr_array, i));
1253
1254 g_ptr_array_unref (ptr_array);
1255 g_ptr_array_unref (ptr_array2);
1256 g_free (array_test);
1257 }
1258
1259 /* Test the g_ptr_array_extend_and_steal() function */
1260 static void
pointer_array_extend_and_steal(void)1261 pointer_array_extend_and_steal (void)
1262 {
1263 GPtrArray *ptr_array, *ptr_array2, *ptr_array3;
1264 gsize i;
1265 const gsize array_size = 100;
1266 gsize *array_test = g_malloc (array_size * sizeof (gsize));
1267
1268 /* Initializing array_test */
1269 for (i = 0; i < array_size; i++)
1270 array_test[i] = i;
1271
1272 /* Testing simple extend_and_steal() */
1273 ptr_array = g_ptr_array_sized_new (array_size / 2);
1274 ptr_array2 = g_ptr_array_sized_new (array_size / 2);
1275
1276 for (i = 0; i < array_size / 2; i++)
1277 {
1278 g_ptr_array_add (ptr_array, &array_test[i]);
1279 g_ptr_array_add (ptr_array2, &array_test[i + (array_size / 2)]);
1280 }
1281
1282 g_ptr_array_extend_and_steal (ptr_array, ptr_array2);
1283
1284 for (i = 0; i < array_size; i++)
1285 g_assert_cmpuint (*((gsize *) g_ptr_array_index (ptr_array, i)), ==, i);
1286
1287 g_ptr_array_free (ptr_array, TRUE);
1288
1289 /* Testing extend_and_steal() with a pending reference to stolen array */
1290 ptr_array = g_ptr_array_sized_new (array_size / 2);
1291 ptr_array2 = g_ptr_array_sized_new (array_size / 2);
1292
1293 for (i = 0; i < array_size / 2; i++)
1294 {
1295 g_ptr_array_add (ptr_array, &array_test[i]);
1296 g_ptr_array_add (ptr_array2, &array_test[i + (array_size / 2)]);
1297 }
1298
1299 ptr_array3 = g_ptr_array_ref (ptr_array2);
1300
1301 g_ptr_array_extend_and_steal (ptr_array, ptr_array2);
1302
1303 for (i = 0; i < array_size; i++)
1304 g_assert_cmpuint (*((gsize *) g_ptr_array_index (ptr_array, i)), ==, i);
1305
1306 g_assert_cmpuint (ptr_array3->len, ==, 0);
1307 g_assert_null (ptr_array3->pdata);
1308
1309 g_ptr_array_add (ptr_array2, NULL);
1310
1311 g_ptr_array_free (ptr_array, TRUE);
1312 g_ptr_array_free (ptr_array3, TRUE);
1313
1314 /* Final memory clean-up */
1315 g_free (array_test);
1316 }
1317
1318 static gint
ptr_compare(gconstpointer p1,gconstpointer p2)1319 ptr_compare (gconstpointer p1, gconstpointer p2)
1320 {
1321 gpointer i1 = *(gpointer*)p1;
1322 gpointer i2 = *(gpointer*)p2;
1323
1324 return GPOINTER_TO_INT (i1) - GPOINTER_TO_INT (i2);
1325 }
1326
1327 static gint
ptr_compare_data(gconstpointer p1,gconstpointer p2,gpointer data)1328 ptr_compare_data (gconstpointer p1, gconstpointer p2, gpointer data)
1329 {
1330 gpointer i1 = *(gpointer*)p1;
1331 gpointer i2 = *(gpointer*)p2;
1332
1333 return GPOINTER_TO_INT (i1) - GPOINTER_TO_INT (i2);
1334 }
1335
1336 static void
pointer_array_sort(void)1337 pointer_array_sort (void)
1338 {
1339 GPtrArray *gparray;
1340 gint i;
1341 gint val;
1342 gint prev, cur;
1343
1344 gparray = g_ptr_array_new ();
1345
1346 /* Sort empty array */
1347 g_ptr_array_sort (gparray, ptr_compare);
1348
1349 for (i = 0; i < 10000; i++)
1350 {
1351 val = g_random_int_range (0, 10000);
1352 g_ptr_array_add (gparray, GINT_TO_POINTER (val));
1353 }
1354
1355 g_ptr_array_sort (gparray, ptr_compare);
1356
1357 prev = -1;
1358 for (i = 0; i < 10000; i++)
1359 {
1360 cur = GPOINTER_TO_INT (g_ptr_array_index (gparray, i));
1361 g_assert_cmpint (prev, <=, cur);
1362 prev = cur;
1363 }
1364
1365 g_ptr_array_free (gparray, TRUE);
1366 }
1367
1368 /* Please keep pointer_array_sort_example() in sync with the doc-comment
1369 * of g_ptr_array_sort() */
1370
1371 typedef struct
1372 {
1373 gchar *name;
1374 gint size;
1375 } FileListEntry;
1376
1377 static void
file_list_entry_free(gpointer p)1378 file_list_entry_free (gpointer p)
1379 {
1380 FileListEntry *entry = p;
1381
1382 g_free (entry->name);
1383 g_free (entry);
1384 }
1385
1386 static gint
sort_filelist(gconstpointer a,gconstpointer b)1387 sort_filelist (gconstpointer a, gconstpointer b)
1388 {
1389 const FileListEntry *entry1 = *((FileListEntry **) a);
1390 const FileListEntry *entry2 = *((FileListEntry **) b);
1391
1392 return g_ascii_strcasecmp (entry1->name, entry2->name);
1393 }
1394
1395 static void
pointer_array_sort_example(void)1396 pointer_array_sort_example (void)
1397 {
1398 GPtrArray *file_list = NULL;
1399 FileListEntry *entry;
1400
1401 g_test_summary ("Check that the doc-comment for g_ptr_array_sort() is correct");
1402
1403 file_list = g_ptr_array_new_with_free_func (file_list_entry_free);
1404
1405 entry = g_new0 (FileListEntry, 1);
1406 entry->name = g_strdup ("README");
1407 entry->size = 42;
1408 g_ptr_array_add (file_list, g_steal_pointer (&entry));
1409
1410 entry = g_new0 (FileListEntry, 1);
1411 entry->name = g_strdup ("empty");
1412 entry->size = 0;
1413 g_ptr_array_add (file_list, g_steal_pointer (&entry));
1414
1415 entry = g_new0 (FileListEntry, 1);
1416 entry->name = g_strdup ("aardvark");
1417 entry->size = 23;
1418 g_ptr_array_add (file_list, g_steal_pointer (&entry));
1419
1420 g_ptr_array_sort (file_list, sort_filelist);
1421
1422 g_assert_cmpuint (file_list->len, ==, 3);
1423 entry = g_ptr_array_index (file_list, 0);
1424 g_assert_cmpstr (entry->name, ==, "aardvark");
1425 entry = g_ptr_array_index (file_list, 1);
1426 g_assert_cmpstr (entry->name, ==, "empty");
1427 entry = g_ptr_array_index (file_list, 2);
1428 g_assert_cmpstr (entry->name, ==, "README");
1429
1430 g_ptr_array_unref (file_list);
1431 }
1432
1433 /* Please keep pointer_array_sort_with_data_example() in sync with the
1434 * doc-comment of g_ptr_array_sort_with_data() */
1435
1436 typedef enum { SORT_NAME, SORT_SIZE } SortMode;
1437
1438 static gint
sort_filelist_how(gconstpointer a,gconstpointer b,gpointer user_data)1439 sort_filelist_how (gconstpointer a, gconstpointer b, gpointer user_data)
1440 {
1441 gint order;
1442 const SortMode sort_mode = GPOINTER_TO_INT (user_data);
1443 const FileListEntry *entry1 = *((FileListEntry **) a);
1444 const FileListEntry *entry2 = *((FileListEntry **) b);
1445
1446 switch (sort_mode)
1447 {
1448 case SORT_NAME:
1449 order = g_ascii_strcasecmp (entry1->name, entry2->name);
1450 break;
1451 case SORT_SIZE:
1452 order = entry1->size - entry2->size;
1453 break;
1454 default:
1455 order = 0;
1456 break;
1457 }
1458 return order;
1459 }
1460
1461 static void
pointer_array_sort_with_data_example(void)1462 pointer_array_sort_with_data_example (void)
1463 {
1464 GPtrArray *file_list = NULL;
1465 FileListEntry *entry;
1466 SortMode sort_mode;
1467
1468 g_test_summary ("Check that the doc-comment for g_ptr_array_sort_with_data() is correct");
1469
1470 file_list = g_ptr_array_new_with_free_func (file_list_entry_free);
1471
1472 entry = g_new0 (FileListEntry, 1);
1473 entry->name = g_strdup ("README");
1474 entry->size = 42;
1475 g_ptr_array_add (file_list, g_steal_pointer (&entry));
1476
1477 entry = g_new0 (FileListEntry, 1);
1478 entry->name = g_strdup ("empty");
1479 entry->size = 0;
1480 g_ptr_array_add (file_list, g_steal_pointer (&entry));
1481
1482 entry = g_new0 (FileListEntry, 1);
1483 entry->name = g_strdup ("aardvark");
1484 entry->size = 23;
1485 g_ptr_array_add (file_list, g_steal_pointer (&entry));
1486
1487 sort_mode = SORT_NAME;
1488 g_ptr_array_sort_with_data (file_list, sort_filelist_how, GINT_TO_POINTER (sort_mode));
1489
1490 g_assert_cmpuint (file_list->len, ==, 3);
1491 entry = g_ptr_array_index (file_list, 0);
1492 g_assert_cmpstr (entry->name, ==, "aardvark");
1493 entry = g_ptr_array_index (file_list, 1);
1494 g_assert_cmpstr (entry->name, ==, "empty");
1495 entry = g_ptr_array_index (file_list, 2);
1496 g_assert_cmpstr (entry->name, ==, "README");
1497
1498 sort_mode = SORT_SIZE;
1499 g_ptr_array_sort_with_data (file_list, sort_filelist_how, GINT_TO_POINTER (sort_mode));
1500
1501 g_assert_cmpuint (file_list->len, ==, 3);
1502 entry = g_ptr_array_index (file_list, 0);
1503 g_assert_cmpstr (entry->name, ==, "empty");
1504 entry = g_ptr_array_index (file_list, 1);
1505 g_assert_cmpstr (entry->name, ==, "aardvark");
1506 entry = g_ptr_array_index (file_list, 2);
1507 g_assert_cmpstr (entry->name, ==, "README");
1508
1509 g_ptr_array_unref (file_list);
1510 }
1511
1512 static void
pointer_array_sort_with_data(void)1513 pointer_array_sort_with_data (void)
1514 {
1515 GPtrArray *gparray;
1516 gint i;
1517 gint prev, cur;
1518
1519 gparray = g_ptr_array_new ();
1520
1521 /* Sort empty array */
1522 g_ptr_array_sort_with_data (gparray, ptr_compare_data, NULL);
1523
1524 for (i = 0; i < 10000; i++)
1525 g_ptr_array_add (gparray, GINT_TO_POINTER (g_random_int_range (0, 10000)));
1526
1527 g_ptr_array_sort_with_data (gparray, ptr_compare_data, NULL);
1528
1529 prev = -1;
1530 for (i = 0; i < 10000; i++)
1531 {
1532 cur = GPOINTER_TO_INT (g_ptr_array_index (gparray, i));
1533 g_assert_cmpint (prev, <=, cur);
1534 prev = cur;
1535 }
1536
1537 g_ptr_array_free (gparray, TRUE);
1538 }
1539
1540 static void
pointer_array_find_empty(void)1541 pointer_array_find_empty (void)
1542 {
1543 GPtrArray *array;
1544 guint idx;
1545
1546 array = g_ptr_array_new ();
1547
1548 g_assert_false (g_ptr_array_find (array, "some-value", NULL)); /* NULL index */
1549 g_assert_false (g_ptr_array_find (array, "some-value", &idx)); /* non-NULL index */
1550 g_assert_false (g_ptr_array_find_with_equal_func (array, "some-value", g_str_equal, NULL)); /* NULL index */
1551 g_assert_false (g_ptr_array_find_with_equal_func (array, "some-value", g_str_equal, &idx)); /* non-NULL index */
1552
1553 g_ptr_array_free (array, TRUE);
1554 }
1555
1556 static void
pointer_array_find_non_empty(void)1557 pointer_array_find_non_empty (void)
1558 {
1559 GPtrArray *array;
1560 guint idx;
1561 const gchar *str_pointer = "static-string";
1562
1563 array = g_ptr_array_new ();
1564
1565 g_ptr_array_add (array, "some");
1566 g_ptr_array_add (array, "random");
1567 g_ptr_array_add (array, "values");
1568 g_ptr_array_add (array, "some");
1569 g_ptr_array_add (array, "duplicated");
1570 g_ptr_array_add (array, (gpointer) str_pointer);
1571
1572 g_assert_true (g_ptr_array_find_with_equal_func (array, "random", g_str_equal, NULL)); /* NULL index */
1573 g_assert_true (g_ptr_array_find_with_equal_func (array, "random", g_str_equal, &idx)); /* non-NULL index */
1574 g_assert_cmpuint (idx, ==, 1);
1575
1576 g_assert_true (g_ptr_array_find_with_equal_func (array, "some", g_str_equal, &idx)); /* duplicate element */
1577 g_assert_cmpuint (idx, ==, 0);
1578
1579 g_assert_false (g_ptr_array_find_with_equal_func (array, "nope", g_str_equal, NULL));
1580
1581 g_assert_true (g_ptr_array_find_with_equal_func (array, str_pointer, g_str_equal, &idx));
1582 g_assert_cmpuint (idx, ==, 5);
1583 idx = G_MAXUINT;
1584 g_assert_true (g_ptr_array_find_with_equal_func (array, str_pointer, NULL, &idx)); /* NULL equal func */
1585 g_assert_cmpuint (idx, ==, 5);
1586 idx = G_MAXUINT;
1587 g_assert_true (g_ptr_array_find (array, str_pointer, &idx)); /* NULL equal func */
1588 g_assert_cmpuint (idx, ==, 5);
1589
1590 g_ptr_array_free (array, TRUE);
1591 }
1592
1593 static void
steal_destroy_notify(gpointer data)1594 steal_destroy_notify (gpointer data)
1595 {
1596 guint *counter = data;
1597 *counter = *counter + 1;
1598 }
1599
1600 /* Test that g_ptr_array_steal_index() and g_ptr_array_steal_index_fast() can
1601 * remove elements from a pointer array without the #GDestroyNotify being called. */
1602 static void
pointer_array_steal_index(void)1603 pointer_array_steal_index (void)
1604 {
1605 guint i1 = 0, i2 = 0, i3 = 0, i4 = 0;
1606 gpointer out1, out2;
1607 GPtrArray *array = g_ptr_array_new_with_free_func (steal_destroy_notify);
1608
1609 g_ptr_array_add (array, &i1);
1610 g_ptr_array_add (array, &i2);
1611 g_ptr_array_add (array, &i3);
1612 g_ptr_array_add (array, &i4);
1613
1614 g_assert_cmpuint (array->len, ==, 4);
1615
1616 /* Remove a single element. */
1617 out1 = g_ptr_array_steal_index (array, 0);
1618 g_assert_true (out1 == &i1);
1619 g_assert_cmpuint (i1, ==, 0); /* should not have been destroyed */
1620
1621 /* Following elements should have been moved down. */
1622 g_assert_cmpuint (array->len, ==, 3);
1623 g_assert_true (g_ptr_array_index (array, 0) == &i2);
1624 g_assert_true (g_ptr_array_index (array, 1) == &i3);
1625 g_assert_true (g_ptr_array_index (array, 2) == &i4);
1626
1627 /* Remove another element, quickly. */
1628 out2 = g_ptr_array_steal_index_fast (array, 0);
1629 g_assert_true (out2 == &i2);
1630 g_assert_cmpuint (i2, ==, 0); /* should not have been destroyed */
1631
1632 /* Last element should have been swapped in place. */
1633 g_assert_cmpuint (array->len, ==, 2);
1634 g_assert_true (g_ptr_array_index (array, 0) == &i4);
1635 g_assert_true (g_ptr_array_index (array, 1) == &i3);
1636
1637 /* Check that destroying the pointer array doesn’t affect the stolen elements. */
1638 g_ptr_array_unref (array);
1639
1640 g_assert_cmpuint (i1, ==, 0);
1641 g_assert_cmpuint (i2, ==, 0);
1642 g_assert_cmpuint (i3, ==, 1);
1643 g_assert_cmpuint (i4, ==, 1);
1644 }
1645
1646 static void
byte_array_steal(void)1647 byte_array_steal (void)
1648 {
1649 const guint array_size = 10000;
1650 GByteArray *gbarray;
1651 guint8 *bdata;
1652 guint i;
1653 gsize len, past_len;
1654
1655 gbarray = g_byte_array_new ();
1656 bdata = g_byte_array_steal (gbarray, NULL);
1657 g_assert_cmpint ((gsize) bdata, ==, (gsize) gbarray->data);
1658 g_free (bdata);
1659
1660 for (i = 0; i < array_size; i++)
1661 g_byte_array_append (gbarray, (guint8 *) "abcd", 4);
1662
1663 past_len = gbarray->len;
1664 bdata = g_byte_array_steal (gbarray, &len);
1665
1666 g_assert_cmpint (len, ==, past_len);
1667 g_assert_cmpint (gbarray->len, ==, 0);
1668
1669 g_byte_array_append (gbarray, (guint8 *) "@", 1);
1670
1671 g_assert_cmpint (bdata[0], ==, 'a');
1672 g_assert_cmpint (gbarray->data[0], ==, '@');
1673 g_assert_cmpint (gbarray->len, ==, 1);
1674
1675 g_byte_array_remove_index (gbarray, 0);
1676
1677 g_free (bdata);
1678 g_byte_array_free (gbarray, TRUE);
1679 }
1680
1681 static void
byte_array_append(void)1682 byte_array_append (void)
1683 {
1684 GByteArray *gbarray;
1685 gint i;
1686 guint8 *segment;
1687
1688 gbarray = g_byte_array_sized_new (1000);
1689 for (i = 0; i < 10000; i++)
1690 g_byte_array_append (gbarray, (guint8*) "abcd", 4);
1691
1692 for (i = 0; i < 10000; i++)
1693 {
1694 g_assert (gbarray->data[4*i] == 'a');
1695 g_assert (gbarray->data[4*i+1] == 'b');
1696 g_assert (gbarray->data[4*i+2] == 'c');
1697 g_assert (gbarray->data[4*i+3] == 'd');
1698 }
1699
1700 segment = g_byte_array_free (gbarray, FALSE);
1701
1702 for (i = 0; i < 10000; i++)
1703 {
1704 g_assert (segment[4*i] == 'a');
1705 g_assert (segment[4*i+1] == 'b');
1706 g_assert (segment[4*i+2] == 'c');
1707 g_assert (segment[4*i+3] == 'd');
1708 }
1709
1710 g_free (segment);
1711 }
1712
1713 static void
byte_array_prepend(void)1714 byte_array_prepend (void)
1715 {
1716 GByteArray *gbarray;
1717 gint i;
1718
1719 gbarray = g_byte_array_new ();
1720 g_byte_array_set_size (gbarray, 1000);
1721
1722 for (i = 0; i < 10000; i++)
1723 g_byte_array_prepend (gbarray, (guint8*) "abcd", 4);
1724
1725 for (i = 0; i < 10000; i++)
1726 {
1727 g_assert (gbarray->data[4*i] == 'a');
1728 g_assert (gbarray->data[4*i+1] == 'b');
1729 g_assert (gbarray->data[4*i+2] == 'c');
1730 g_assert (gbarray->data[4*i+3] == 'd');
1731 }
1732
1733 g_byte_array_free (gbarray, TRUE);
1734 }
1735
1736 static void
byte_array_ref_count(void)1737 byte_array_ref_count (void)
1738 {
1739 GByteArray *gbarray;
1740 GByteArray *gbarray2;
1741 gint i;
1742
1743 gbarray = g_byte_array_new ();
1744 for (i = 0; i < 10000; i++)
1745 g_byte_array_append (gbarray, (guint8*) "abcd", 4);
1746
1747 gbarray2 = g_byte_array_ref (gbarray);
1748 g_assert (gbarray2 == gbarray);
1749 g_byte_array_unref (gbarray2);
1750 for (i = 0; i < 10000; i++)
1751 {
1752 g_assert (gbarray->data[4*i] == 'a');
1753 g_assert (gbarray->data[4*i+1] == 'b');
1754 g_assert (gbarray->data[4*i+2] == 'c');
1755 g_assert (gbarray->data[4*i+3] == 'd');
1756 }
1757
1758 gbarray2 = g_byte_array_ref (gbarray);
1759 g_assert (gbarray2 == gbarray);
1760 g_byte_array_free (gbarray, TRUE);
1761 g_assert_cmpint (gbarray2->len, ==, 0);
1762 g_byte_array_unref (gbarray2);
1763 }
1764
1765 static void
byte_array_remove(void)1766 byte_array_remove (void)
1767 {
1768 GByteArray *gbarray;
1769 gint i;
1770
1771 gbarray = g_byte_array_new ();
1772 for (i = 0; i < 100; i++)
1773 g_byte_array_append (gbarray, (guint8*) "abcd", 4);
1774
1775 g_assert_cmpint (gbarray->len, ==, 400);
1776
1777 g_byte_array_remove_index (gbarray, 4);
1778 g_byte_array_remove_index (gbarray, 4);
1779 g_byte_array_remove_index (gbarray, 4);
1780 g_byte_array_remove_index (gbarray, 4);
1781
1782 g_assert_cmpint (gbarray->len, ==, 396);
1783
1784 for (i = 0; i < 99; i++)
1785 {
1786 g_assert (gbarray->data[4*i] == 'a');
1787 g_assert (gbarray->data[4*i+1] == 'b');
1788 g_assert (gbarray->data[4*i+2] == 'c');
1789 g_assert (gbarray->data[4*i+3] == 'd');
1790 }
1791
1792 g_byte_array_free (gbarray, TRUE);
1793 }
1794
1795 static void
byte_array_remove_fast(void)1796 byte_array_remove_fast (void)
1797 {
1798 GByteArray *gbarray;
1799 gint i;
1800
1801 gbarray = g_byte_array_new ();
1802 for (i = 0; i < 100; i++)
1803 g_byte_array_append (gbarray, (guint8*) "abcd", 4);
1804
1805 g_assert_cmpint (gbarray->len, ==, 400);
1806
1807 g_byte_array_remove_index_fast (gbarray, 4);
1808 g_byte_array_remove_index_fast (gbarray, 4);
1809 g_byte_array_remove_index_fast (gbarray, 4);
1810 g_byte_array_remove_index_fast (gbarray, 4);
1811
1812 g_assert_cmpint (gbarray->len, ==, 396);
1813
1814 for (i = 0; i < 99; i++)
1815 {
1816 g_assert (gbarray->data[4*i] == 'a');
1817 g_assert (gbarray->data[4*i+1] == 'b');
1818 g_assert (gbarray->data[4*i+2] == 'c');
1819 g_assert (gbarray->data[4*i+3] == 'd');
1820 }
1821
1822 g_byte_array_free (gbarray, TRUE);
1823 }
1824
1825 static void
byte_array_remove_range(void)1826 byte_array_remove_range (void)
1827 {
1828 GByteArray *gbarray;
1829 gint i;
1830
1831 gbarray = g_byte_array_new ();
1832 for (i = 0; i < 100; i++)
1833 g_byte_array_append (gbarray, (guint8*) "abcd", 4);
1834
1835 g_assert_cmpint (gbarray->len, ==, 400);
1836
1837 g_byte_array_remove_range (gbarray, 12, 4);
1838
1839 g_assert_cmpint (gbarray->len, ==, 396);
1840
1841 for (i = 0; i < 99; i++)
1842 {
1843 g_assert (gbarray->data[4*i] == 'a');
1844 g_assert (gbarray->data[4*i+1] == 'b');
1845 g_assert (gbarray->data[4*i+2] == 'c');
1846 g_assert (gbarray->data[4*i+3] == 'd');
1847 }
1848
1849 /* Ensure the entire array can be cleared, even when empty. */
1850 g_byte_array_remove_range (gbarray, 0, gbarray->len);
1851 g_byte_array_remove_range (gbarray, 0, gbarray->len);
1852
1853 g_byte_array_free (gbarray, TRUE);
1854 }
1855
1856 static int
byte_compare(gconstpointer p1,gconstpointer p2)1857 byte_compare (gconstpointer p1, gconstpointer p2)
1858 {
1859 const guint8 *i1 = p1;
1860 const guint8 *i2 = p2;
1861
1862 return *i1 - *i2;
1863 }
1864
1865 static int
byte_compare_data(gconstpointer p1,gconstpointer p2,gpointer data)1866 byte_compare_data (gconstpointer p1, gconstpointer p2, gpointer data)
1867 {
1868 const guint8 *i1 = p1;
1869 const guint8 *i2 = p2;
1870
1871 return *i1 - *i2;
1872 }
1873
1874 static void
byte_array_sort(void)1875 byte_array_sort (void)
1876 {
1877 GByteArray *gbarray;
1878 guint i;
1879 guint8 val;
1880 guint8 prev, cur;
1881
1882 gbarray = g_byte_array_new ();
1883 for (i = 0; i < 100; i++)
1884 {
1885 val = 'a' + g_random_int_range (0, 26);
1886 g_byte_array_append (gbarray, (guint8*) &val, 1);
1887 }
1888
1889 g_byte_array_sort (gbarray, byte_compare);
1890
1891 prev = 'a';
1892 for (i = 0; i < gbarray->len; i++)
1893 {
1894 cur = gbarray->data[i];
1895 g_assert_cmpint (prev, <=, cur);
1896 prev = cur;
1897 }
1898
1899 g_byte_array_free (gbarray, TRUE);
1900 }
1901
1902 static void
byte_array_sort_with_data(void)1903 byte_array_sort_with_data (void)
1904 {
1905 GByteArray *gbarray;
1906 guint i;
1907 guint8 val;
1908 guint8 prev, cur;
1909
1910 gbarray = g_byte_array_new ();
1911 for (i = 0; i < 100; i++)
1912 {
1913 val = 'a' + g_random_int_range (0, 26);
1914 g_byte_array_append (gbarray, (guint8*) &val, 1);
1915 }
1916
1917 g_byte_array_sort_with_data (gbarray, byte_compare_data, NULL);
1918
1919 prev = 'a';
1920 for (i = 0; i < gbarray->len; i++)
1921 {
1922 cur = gbarray->data[i];
1923 g_assert_cmpint (prev, <=, cur);
1924 prev = cur;
1925 }
1926
1927 g_byte_array_free (gbarray, TRUE);
1928 }
1929
1930 static void
byte_array_new_take(void)1931 byte_array_new_take (void)
1932 {
1933 GByteArray *gbarray;
1934 guint8 *data;
1935
1936 data = g_memdup2 ("woooweeewow", 11);
1937 gbarray = g_byte_array_new_take (data, 11);
1938 g_assert (gbarray->data == data);
1939 g_assert_cmpuint (gbarray->len, ==, 11);
1940 g_byte_array_free (gbarray, TRUE);
1941 }
1942
1943 static void
byte_array_free_to_bytes(void)1944 byte_array_free_to_bytes (void)
1945 {
1946 GByteArray *gbarray;
1947 gpointer memory;
1948 GBytes *bytes;
1949 gsize size;
1950
1951 gbarray = g_byte_array_new ();
1952 g_byte_array_append (gbarray, (guint8 *)"woooweeewow", 11);
1953 memory = gbarray->data;
1954
1955 bytes = g_byte_array_free_to_bytes (gbarray);
1956 g_assert (bytes != NULL);
1957 g_assert_cmpuint (g_bytes_get_size (bytes), ==, 11);
1958 g_assert (g_bytes_get_data (bytes, &size) == memory);
1959 g_assert_cmpuint (size, ==, 11);
1960
1961 g_bytes_unref (bytes);
1962 }
1963
1964 static void
add_array_test(const gchar * test_path,const ArrayTestData * config,GTestDataFunc test_func)1965 add_array_test (const gchar *test_path,
1966 const ArrayTestData *config,
1967 GTestDataFunc test_func)
1968 {
1969 gchar *test_name = NULL;
1970
1971 test_name = g_strdup_printf ("%s/%s-%s",
1972 test_path,
1973 config->zero_terminated ? "zero-terminated" : "non-zero-terminated",
1974 config->clear_ ? "clear" : "no-clear");
1975 g_test_add_data_func (test_name, config, test_func);
1976 g_free (test_name);
1977 }
1978
1979 int
main(int argc,char * argv[])1980 main (int argc, char *argv[])
1981 {
1982 /* Test all possible combinations of g_array_new() parameters. */
1983 const ArrayTestData array_configurations[] =
1984 {
1985 { FALSE, FALSE },
1986 { FALSE, TRUE },
1987 { TRUE, FALSE },
1988 { TRUE, TRUE },
1989 };
1990 gsize i;
1991
1992 g_test_init (&argc, &argv, NULL);
1993
1994 g_test_bug_base ("https://bugzilla.gnome.org/");
1995
1996 /* array tests */
1997 g_test_add_func ("/array/new/zero-terminated", array_new_zero_terminated);
1998 g_test_add_func ("/array/ref-count", array_ref_count);
1999 g_test_add_func ("/array/steal", array_steal);
2000 g_test_add_func ("/array/clear-func", array_clear_func);
2001 g_test_add_func ("/array/binary-search", test_array_binary_search);
2002 g_test_add_func ("/array/copy-sized", test_array_copy_sized);
2003
2004 for (i = 0; i < G_N_ELEMENTS (array_configurations); i++)
2005 {
2006 add_array_test ("/array/set-size", &array_configurations[i], array_set_size);
2007 add_array_test ("/array/set-size/sized", &array_configurations[i], array_set_size_sized);
2008 add_array_test ("/array/append-val", &array_configurations[i], array_append_val);
2009 add_array_test ("/array/prepend-val", &array_configurations[i], array_prepend_val);
2010 add_array_test ("/array/prepend-vals", &array_configurations[i], array_prepend_vals);
2011 add_array_test ("/array/insert-vals", &array_configurations[i], array_insert_vals);
2012 add_array_test ("/array/remove-index", &array_configurations[i], array_remove_index);
2013 add_array_test ("/array/remove-index-fast", &array_configurations[i], array_remove_index_fast);
2014 add_array_test ("/array/remove-range", &array_configurations[i], array_remove_range);
2015 add_array_test ("/array/copy", &array_configurations[i], array_copy);
2016 add_array_test ("/array/sort", &array_configurations[i], array_sort);
2017 add_array_test ("/array/sort-with-data", &array_configurations[i], array_sort_with_data);
2018 }
2019
2020 /* pointer arrays */
2021 g_test_add_func ("/pointerarray/add", pointer_array_add);
2022 g_test_add_func ("/pointerarray/insert", pointer_array_insert);
2023 g_test_add_func ("/pointerarray/ref-count", pointer_array_ref_count);
2024 g_test_add_func ("/pointerarray/free-func", pointer_array_free_func);
2025 g_test_add_func ("/pointerarray/array_copy", pointer_array_copy);
2026 g_test_add_func ("/pointerarray/array_extend", pointer_array_extend);
2027 g_test_add_func ("/pointerarray/array_extend_and_steal", pointer_array_extend_and_steal);
2028 g_test_add_func ("/pointerarray/sort", pointer_array_sort);
2029 g_test_add_func ("/pointerarray/sort/example", pointer_array_sort_example);
2030 g_test_add_func ("/pointerarray/sort-with-data", pointer_array_sort_with_data);
2031 g_test_add_func ("/pointerarray/sort-with-data/example", pointer_array_sort_with_data_example);
2032 g_test_add_func ("/pointerarray/find/empty", pointer_array_find_empty);
2033 g_test_add_func ("/pointerarray/find/non-empty", pointer_array_find_non_empty);
2034 g_test_add_func ("/pointerarray/steal", pointer_array_steal);
2035 g_test_add_func ("/pointerarray/steal_index", pointer_array_steal_index);
2036
2037 /* byte arrays */
2038 g_test_add_func ("/bytearray/steal", byte_array_steal);
2039 g_test_add_func ("/bytearray/append", byte_array_append);
2040 g_test_add_func ("/bytearray/prepend", byte_array_prepend);
2041 g_test_add_func ("/bytearray/remove", byte_array_remove);
2042 g_test_add_func ("/bytearray/remove-fast", byte_array_remove_fast);
2043 g_test_add_func ("/bytearray/remove-range", byte_array_remove_range);
2044 g_test_add_func ("/bytearray/ref-count", byte_array_ref_count);
2045 g_test_add_func ("/bytearray/sort", byte_array_sort);
2046 g_test_add_func ("/bytearray/sort-with-data", byte_array_sort_with_data);
2047 g_test_add_func ("/bytearray/new-take", byte_array_new_take);
2048 g_test_add_func ("/bytearray/free-to-bytes", byte_array_free_to_bytes);
2049
2050 return g_test_run ();
2051 }
2052