Imported Upstream version 2.72.3
[platform/upstream/glib.git] / glib / tests / array-test.c
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
657 my_clear_func (gpointer data)
658 {
659   num_clear_func_invocations += 1;
660 }
661
662 static 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
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
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
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 static void
849 array_overflow_append_vals (void)
850 {
851   if (!g_test_undefined ())
852       return;
853
854   if (g_test_subprocess ())
855     {
856       GArray *array = g_array_new (TRUE, FALSE, 1);
857       /* Check for overflow should happen before data is accessed. */
858       g_array_append_vals (array, NULL, G_MAXUINT);
859     }
860   else
861     {
862       g_test_trap_subprocess (NULL, 0, 0);
863       g_test_trap_assert_failed ();
864       g_test_trap_assert_stderr ("*adding 4294967295 to array would overflow*");
865     }
866 }
867
868 static void
869 array_overflow_set_size (void)
870 {
871   if (!g_test_undefined ())
872       return;
873
874   if (g_test_subprocess ())
875     {
876       GArray *array = g_array_new (TRUE, FALSE, 1);
877       g_array_set_size (array, G_MAXUINT);
878     }
879   else
880     {
881       g_test_trap_subprocess (NULL, 0, 0);
882       g_test_trap_assert_failed ();
883       g_test_trap_assert_stderr ("*adding 4294967295 to array would overflow*");
884     }
885 }
886
887 /* Check g_ptr_array_steal() function */
888 static void
889 pointer_array_steal (void)
890 {
891   const guint array_size = 10000;
892   GPtrArray *gparray;
893   gpointer *pdata;
894   guint i;
895   gsize len, past_len;
896
897   gparray = g_ptr_array_new ();
898   pdata = g_ptr_array_steal (gparray, NULL);
899   g_assert_null (pdata);
900
901   pdata = g_ptr_array_steal (gparray, &len);
902   g_assert_null (pdata);
903   g_assert_cmpint (len, ==, 0);
904
905   for (i = 0; i < array_size; i++)
906     g_ptr_array_add (gparray, GINT_TO_POINTER (i));
907
908   past_len = gparray->len;
909   pdata = g_ptr_array_steal (gparray, &len);
910   g_assert_cmpint (gparray->len, ==, 0);
911   g_assert_cmpint (past_len, ==, len);
912   g_ptr_array_add (gparray, GINT_TO_POINTER (10));
913
914   g_assert_cmpint ((gsize) pdata[0], ==, (gsize) GINT_TO_POINTER (0));
915   g_assert_cmpint ((gsize) g_ptr_array_index (gparray, 0), ==,
916                    (gsize) GINT_TO_POINTER (10));
917   g_assert_cmpint (gparray->len, ==, 1);
918
919   g_ptr_array_remove_index (gparray, 0);
920
921   for (i = 0; i < array_size; i++)
922     g_ptr_array_add (gparray, GINT_TO_POINTER (i));
923   g_assert_cmpmem (pdata, array_size * sizeof (gpointer),
924                    gparray->pdata, array_size * sizeof (gpointer));
925   g_free (pdata);
926
927   g_ptr_array_free (gparray, TRUE);
928 }
929
930 static void
931 pointer_array_add (void)
932 {
933   GPtrArray *gparray;
934   gint i;
935   gint sum = 0;
936   gpointer *segment;
937
938   gparray = g_ptr_array_sized_new (1000);
939
940   for (i = 0; i < 10000; i++)
941     g_ptr_array_add (gparray, GINT_TO_POINTER (i));
942
943   for (i = 0; i < 10000; i++)
944     g_assert (g_ptr_array_index (gparray, i) == GINT_TO_POINTER (i));
945   
946   g_ptr_array_foreach (gparray, sum_up, &sum);
947   g_assert (sum == 49995000);
948
949   segment = g_ptr_array_free (gparray, FALSE);
950   for (i = 0; i < 10000; i++)
951     g_assert (segment[i] == GINT_TO_POINTER (i));
952   g_free (segment);
953 }
954
955 static void
956 pointer_array_insert (void)
957 {
958   GPtrArray *gparray;
959   gint i;
960   gint sum = 0;
961   gint index;
962
963   gparray = g_ptr_array_sized_new (1000);
964
965   for (i = 0; i < 10000; i++)
966     {
967       index = g_random_int_range (-1, i + 1);
968       g_ptr_array_insert (gparray, index, GINT_TO_POINTER (i));
969     }
970
971   g_ptr_array_foreach (gparray, sum_up, &sum);
972   g_assert (sum == 49995000);
973
974   g_ptr_array_free (gparray, TRUE);
975 }
976
977 static void
978 pointer_array_ref_count (void)
979 {
980   GPtrArray *gparray;
981   GPtrArray *gparray2;
982   gint i;
983   gint sum = 0;
984
985   gparray = g_ptr_array_new ();
986   for (i = 0; i < 10000; i++)
987     g_ptr_array_add (gparray, GINT_TO_POINTER (i));
988
989   /* check we can ref, unref and still access the array */
990   gparray2 = g_ptr_array_ref (gparray);
991   g_assert (gparray == gparray2);
992   g_ptr_array_unref (gparray2);
993   for (i = 0; i < 10000; i++)
994     g_assert (g_ptr_array_index (gparray, i) == GINT_TO_POINTER (i));
995
996   g_ptr_array_foreach (gparray, sum_up, &sum);
997   g_assert (sum == 49995000);
998
999   /* gparray2 should be an empty valid GPtrArray wrapper */
1000   gparray2 = g_ptr_array_ref (gparray);
1001   g_ptr_array_free (gparray, TRUE);
1002
1003   g_assert_cmpint (gparray2->len, ==, 0);
1004   g_ptr_array_unref (gparray2);
1005 }
1006
1007 static gint num_free_func_invocations = 0;
1008
1009 static void
1010 my_free_func (gpointer data)
1011 {
1012   num_free_func_invocations++;
1013   g_free (data);
1014 }
1015
1016 static void
1017 pointer_array_free_func (void)
1018 {
1019   GPtrArray *gparray;
1020   GPtrArray *gparray2;
1021   gchar **strv;
1022   gchar *s;
1023
1024   num_free_func_invocations = 0;
1025   gparray = g_ptr_array_new_with_free_func (my_free_func);
1026   g_ptr_array_unref (gparray);
1027   g_assert_cmpint (num_free_func_invocations, ==, 0);
1028
1029   gparray = g_ptr_array_new_with_free_func (my_free_func);
1030   g_ptr_array_free (gparray, TRUE);
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_index (gparray, 0);
1039   g_assert_cmpint (num_free_func_invocations, ==, 1);
1040   g_ptr_array_remove_index_fast (gparray, 1);
1041   g_assert_cmpint (num_free_func_invocations, ==, 2);
1042   s = g_strdup ("frob");
1043   g_ptr_array_add (gparray, s);
1044   g_assert (g_ptr_array_remove (gparray, s));
1045   g_assert (!g_ptr_array_remove (gparray, "nuun"));
1046   g_assert (!g_ptr_array_remove_fast (gparray, "mlo"));
1047   g_assert_cmpint (num_free_func_invocations, ==, 3);
1048   s = g_strdup ("frob");
1049   g_ptr_array_add (gparray, s);
1050   g_ptr_array_set_size (gparray, 1);
1051   g_assert_cmpint (num_free_func_invocations, ==, 4);
1052   g_ptr_array_ref (gparray);
1053   g_ptr_array_unref (gparray);
1054   g_assert_cmpint (num_free_func_invocations, ==, 4);
1055   g_ptr_array_unref (gparray);
1056   g_assert_cmpint (num_free_func_invocations, ==, 5);
1057
1058   num_free_func_invocations = 0;
1059   gparray = g_ptr_array_new_full (10, my_free_func);
1060   g_ptr_array_add (gparray, g_strdup ("foo"));
1061   g_ptr_array_add (gparray, g_strdup ("bar"));
1062   g_ptr_array_add (gparray, g_strdup ("baz"));
1063   g_ptr_array_set_size (gparray, 20);
1064   g_ptr_array_add (gparray, NULL);
1065   gparray2 = g_ptr_array_ref (gparray);
1066   strv = (gchar **) g_ptr_array_free (gparray, FALSE);
1067   g_assert_cmpint (num_free_func_invocations, ==, 0);
1068   g_strfreev (strv);
1069   g_ptr_array_unref (gparray2);
1070   g_assert_cmpint (num_free_func_invocations, ==, 0);
1071
1072   num_free_func_invocations = 0;
1073   gparray = g_ptr_array_new_with_free_func (my_free_func);
1074   g_ptr_array_add (gparray, g_strdup ("foo"));
1075   g_ptr_array_add (gparray, g_strdup ("bar"));
1076   g_ptr_array_add (gparray, g_strdup ("baz"));
1077   g_ptr_array_remove_range (gparray, 1, 1);
1078   g_ptr_array_unref (gparray);
1079   g_assert_cmpint (num_free_func_invocations, ==, 3);
1080
1081   num_free_func_invocations = 0;
1082   gparray = g_ptr_array_new_with_free_func (my_free_func);
1083   g_ptr_array_add (gparray, g_strdup ("foo"));
1084   g_ptr_array_add (gparray, g_strdup ("bar"));
1085   g_ptr_array_add (gparray, g_strdup ("baz"));
1086   g_ptr_array_free (gparray, TRUE);
1087   g_assert_cmpint (num_free_func_invocations, ==, 3);
1088
1089   num_free_func_invocations = 0;
1090   gparray = g_ptr_array_new_with_free_func (my_free_func);
1091   g_ptr_array_add (gparray, "foo");
1092   g_ptr_array_add (gparray, "bar");
1093   g_ptr_array_add (gparray, "baz");
1094   g_ptr_array_set_free_func (gparray, NULL);
1095   g_ptr_array_free (gparray, TRUE);
1096   g_assert_cmpint (num_free_func_invocations, ==, 0);
1097 }
1098
1099 static gpointer
1100 ptr_array_copy_func (gconstpointer src, gpointer userdata)
1101 {
1102   gsize *dst = g_malloc (sizeof (gsize));
1103   *dst = *((gsize *) src);
1104   return dst;
1105 }
1106
1107 /* Test the g_ptr_array_copy() function */
1108 static void
1109 pointer_array_copy (void)
1110 {
1111   GPtrArray *ptr_array, *ptr_array2;
1112   gsize i;
1113   const gsize array_size = 100;
1114   gsize *array_test = g_malloc (array_size * sizeof (gsize));
1115
1116   g_test_summary ("Check all normal behaviour of stealing elements from one "
1117                   "array to append to another, covering different array sizes "
1118                   "and element copy functions");
1119
1120   if (g_test_undefined ())
1121     {
1122       /* Testing degenerated cases */
1123       g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL,
1124                              "*assertion*!= NULL*");
1125       ptr_array = g_ptr_array_copy (NULL, NULL, NULL);
1126       g_test_assert_expected_messages ();
1127       g_assert_cmpuint ((gsize) ptr_array, ==, (gsize) NULL);
1128     }
1129
1130   /* Initializing array_test */
1131   for (i = 0; i < array_size; i++)
1132     array_test[i] = i;
1133
1134   /* Test copy an empty array */
1135   ptr_array = g_ptr_array_sized_new (0);
1136   ptr_array2 = g_ptr_array_copy (ptr_array, NULL, NULL);
1137
1138   g_assert_cmpuint (ptr_array2->len, ==, ptr_array->len);
1139
1140   g_ptr_array_unref (ptr_array);
1141   g_ptr_array_unref (ptr_array2);
1142
1143   /* Test simple copy */
1144   ptr_array = g_ptr_array_sized_new (array_size);
1145
1146   for (i = 0; i < array_size; i++)
1147     g_ptr_array_add (ptr_array, &array_test[i]);
1148
1149   ptr_array2 = g_ptr_array_copy (ptr_array, NULL, NULL);
1150
1151   g_assert_cmpuint (ptr_array2->len, ==, ptr_array->len);
1152   for (i = 0; i < array_size; i++)
1153     g_assert_cmpuint (*((gsize *) g_ptr_array_index (ptr_array2, i)), ==, i);
1154
1155   for (i = 0; i < array_size; i++)
1156     g_assert_cmpuint ((gsize) g_ptr_array_index (ptr_array, i), ==,
1157                       (gsize) g_ptr_array_index (ptr_array2, i));
1158
1159   g_ptr_array_free (ptr_array2, TRUE);
1160
1161   /* Test copy through GCopyFunc */
1162   ptr_array2 = g_ptr_array_copy (ptr_array, ptr_array_copy_func, NULL);
1163   g_ptr_array_set_free_func (ptr_array2, g_free);
1164
1165   g_assert_cmpuint (ptr_array2->len, ==, ptr_array->len);
1166   for (i = 0; i < array_size; i++)
1167     g_assert_cmpuint (*((gsize *) g_ptr_array_index (ptr_array2, i)), ==, i);
1168
1169   for (i = 0; i < array_size; i++)
1170     g_assert_cmpuint ((gsize) g_ptr_array_index (ptr_array, i), !=,
1171                       (gsize) g_ptr_array_index (ptr_array2, i));
1172
1173   g_ptr_array_free (ptr_array2, TRUE);
1174
1175   /* Final cleanup */
1176   g_ptr_array_free (ptr_array, TRUE);
1177   g_free (array_test);
1178 }
1179
1180 /* Test the g_ptr_array_extend() function */
1181 static void
1182 pointer_array_extend (void)
1183 {
1184   GPtrArray *ptr_array, *ptr_array2;
1185   gsize i;
1186   const gsize array_size = 100;
1187   gsize *array_test = g_malloc (array_size * sizeof (gsize));
1188
1189   if (g_test_undefined ())
1190     {
1191       /* Testing degenerated cases */
1192       ptr_array = g_ptr_array_sized_new (0);
1193       g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL,
1194                              "*assertion*!= NULL*");
1195       g_ptr_array_extend (NULL, ptr_array, NULL, NULL);
1196       g_test_assert_expected_messages ();
1197
1198       g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL,
1199                              "*assertion*!= NULL*");
1200       g_ptr_array_extend (ptr_array, NULL, NULL, NULL);
1201       g_test_assert_expected_messages ();
1202
1203       g_ptr_array_unref (ptr_array);
1204     }
1205
1206   /* Initializing array_test */
1207   for (i = 0; i < array_size; i++)
1208     array_test[i] = i;
1209
1210   /* Testing extend with array of size zero */
1211   ptr_array = g_ptr_array_sized_new (0);
1212   ptr_array2 = g_ptr_array_sized_new (0);
1213
1214   g_ptr_array_extend (ptr_array, ptr_array2, NULL, NULL);
1215
1216   g_assert_cmpuint (ptr_array->len, ==, 0);
1217   g_assert_cmpuint (ptr_array2->len, ==, 0);
1218
1219   g_ptr_array_unref (ptr_array);
1220   g_ptr_array_unref (ptr_array2);
1221
1222   /* Testing extend an array of size zero */
1223   ptr_array = g_ptr_array_sized_new (array_size);
1224   ptr_array2 = g_ptr_array_sized_new (0);
1225
1226   for (i = 0; i < array_size; i++)
1227     {
1228       g_ptr_array_add (ptr_array, &array_test[i]);
1229     }
1230
1231   g_ptr_array_extend (ptr_array, ptr_array2, NULL, NULL);
1232
1233   for (i = 0; i < array_size; i++)
1234     g_assert_cmpuint (*((gsize *) g_ptr_array_index (ptr_array, i)), ==, i);
1235
1236   g_ptr_array_unref (ptr_array);
1237   g_ptr_array_unref (ptr_array2);
1238
1239   /* Testing extend an array of size zero */
1240   ptr_array = g_ptr_array_sized_new (0);
1241   ptr_array2 = g_ptr_array_sized_new (array_size);
1242
1243   for (i = 0; i < array_size; i++)
1244     {
1245       g_ptr_array_add (ptr_array2, &array_test[i]);
1246     }
1247
1248   g_ptr_array_extend (ptr_array, ptr_array2, NULL, NULL);
1249
1250   for (i = 0; i < array_size; i++)
1251     g_assert_cmpuint (*((gsize *) g_ptr_array_index (ptr_array, i)), ==, i);
1252
1253   g_ptr_array_unref (ptr_array);
1254   g_ptr_array_unref (ptr_array2);
1255
1256   /* Testing simple extend */
1257   ptr_array = g_ptr_array_sized_new (array_size / 2);
1258   ptr_array2 = g_ptr_array_sized_new (array_size / 2);
1259
1260   for (i = 0; i < array_size / 2; i++)
1261     {
1262       g_ptr_array_add (ptr_array, &array_test[i]);
1263       g_ptr_array_add (ptr_array2, &array_test[i + (array_size / 2)]);
1264     }
1265
1266   g_ptr_array_extend (ptr_array, ptr_array2, NULL, NULL);
1267
1268   for (i = 0; i < array_size; i++)
1269     g_assert_cmpuint (*((gsize *) g_ptr_array_index (ptr_array, i)), ==, i);
1270
1271   g_ptr_array_unref (ptr_array);
1272   g_ptr_array_unref (ptr_array2);
1273
1274   /* Testing extend with GCopyFunc */
1275   ptr_array = g_ptr_array_sized_new (array_size / 2);
1276   ptr_array2 = g_ptr_array_sized_new (array_size / 2);
1277
1278   for (i = 0; i < array_size / 2; i++)
1279     {
1280       g_ptr_array_add (ptr_array, &array_test[i]);
1281       g_ptr_array_add (ptr_array2, &array_test[i + (array_size / 2)]);
1282     }
1283
1284   g_ptr_array_extend (ptr_array, ptr_array2, ptr_array_copy_func, NULL);
1285
1286   for (i = 0; i < array_size; i++)
1287     g_assert_cmpuint (*((gsize *) g_ptr_array_index (ptr_array, i)), ==, i);
1288
1289   /* Clean-up memory */
1290   for (i = array_size / 2; i < array_size; i++)
1291     g_free (g_ptr_array_index (ptr_array, i));
1292
1293   g_ptr_array_unref (ptr_array);
1294   g_ptr_array_unref (ptr_array2);
1295   g_free (array_test);
1296 }
1297
1298 /* Test the g_ptr_array_extend_and_steal() function */
1299 static void
1300 pointer_array_extend_and_steal (void)
1301 {
1302   GPtrArray *ptr_array, *ptr_array2, *ptr_array3;
1303   gsize i;
1304   const gsize array_size = 100;
1305   gsize *array_test = g_malloc (array_size * sizeof (gsize));
1306
1307   /* Initializing array_test */
1308   for (i = 0; i < array_size; i++)
1309     array_test[i] = i;
1310
1311   /* Testing simple extend_and_steal() */
1312   ptr_array = g_ptr_array_sized_new (array_size / 2);
1313   ptr_array2 = g_ptr_array_sized_new (array_size / 2);
1314
1315   for (i = 0; i < array_size / 2; i++)
1316     {
1317       g_ptr_array_add (ptr_array, &array_test[i]);
1318       g_ptr_array_add (ptr_array2, &array_test[i + (array_size / 2)]);
1319     }
1320
1321   g_ptr_array_extend_and_steal (ptr_array, ptr_array2);
1322
1323   for (i = 0; i < array_size; i++)
1324     g_assert_cmpuint (*((gsize *) g_ptr_array_index (ptr_array, i)), ==, i);
1325
1326   g_ptr_array_free (ptr_array, TRUE);
1327
1328   /* Testing extend_and_steal() with a pending reference to stolen array */
1329   ptr_array = g_ptr_array_sized_new (array_size / 2);
1330   ptr_array2 = g_ptr_array_sized_new (array_size / 2);
1331
1332   for (i = 0; i < array_size / 2; i++)
1333     {
1334       g_ptr_array_add (ptr_array, &array_test[i]);
1335       g_ptr_array_add (ptr_array2, &array_test[i + (array_size / 2)]);
1336     }
1337
1338   ptr_array3 = g_ptr_array_ref (ptr_array2);
1339
1340   g_ptr_array_extend_and_steal (ptr_array, ptr_array2);
1341
1342   for (i = 0; i < array_size; i++)
1343     g_assert_cmpuint (*((gsize *) g_ptr_array_index (ptr_array, i)), ==, i);
1344
1345   g_assert_cmpuint (ptr_array3->len, ==, 0);
1346   g_assert_null (ptr_array3->pdata);
1347
1348   g_ptr_array_add (ptr_array2, NULL);
1349
1350   g_ptr_array_free (ptr_array, TRUE);
1351   g_ptr_array_free (ptr_array3, TRUE);
1352
1353   /* Final memory clean-up */
1354   g_free (array_test);
1355 }
1356
1357 static gint
1358 ptr_compare (gconstpointer p1, gconstpointer p2)
1359 {
1360   gpointer i1 = *(gpointer*)p1;
1361   gpointer i2 = *(gpointer*)p2;
1362
1363   return GPOINTER_TO_INT (i1) - GPOINTER_TO_INT (i2);
1364 }
1365
1366 static gint
1367 ptr_compare_data (gconstpointer p1, gconstpointer p2, gpointer data)
1368 {
1369   gpointer i1 = *(gpointer*)p1;
1370   gpointer i2 = *(gpointer*)p2;
1371
1372   return GPOINTER_TO_INT (i1) - GPOINTER_TO_INT (i2);
1373 }
1374
1375 static void
1376 pointer_array_sort (void)
1377 {
1378   GPtrArray *gparray;
1379   gint i;
1380   gint val;
1381   gint prev, cur;
1382
1383   gparray = g_ptr_array_new ();
1384
1385   /* Sort empty array */
1386   g_ptr_array_sort (gparray, ptr_compare);
1387
1388   for (i = 0; i < 10000; i++)
1389     {
1390       val = g_random_int_range (0, 10000);
1391       g_ptr_array_add (gparray, GINT_TO_POINTER (val));
1392     }
1393
1394   g_ptr_array_sort (gparray, ptr_compare);
1395
1396   prev = -1;
1397   for (i = 0; i < 10000; i++)
1398     {
1399       cur = GPOINTER_TO_INT (g_ptr_array_index (gparray, i));
1400       g_assert_cmpint (prev, <=, cur);
1401       prev = cur;
1402     }
1403
1404   g_ptr_array_free (gparray, TRUE);
1405 }
1406
1407 /* Please keep pointer_array_sort_example() in sync with the doc-comment
1408  * of g_ptr_array_sort() */
1409
1410 typedef struct
1411 {
1412   gchar *name;
1413   gint size;
1414 } FileListEntry;
1415
1416 static void
1417 file_list_entry_free (gpointer p)
1418 {
1419   FileListEntry *entry = p;
1420
1421   g_free (entry->name);
1422   g_free (entry);
1423 }
1424
1425 static gint
1426 sort_filelist (gconstpointer a, gconstpointer b)
1427 {
1428    const FileListEntry *entry1 = *((FileListEntry **) a);
1429    const FileListEntry *entry2 = *((FileListEntry **) b);
1430
1431    return g_ascii_strcasecmp (entry1->name, entry2->name);
1432 }
1433
1434 static void
1435 pointer_array_sort_example (void)
1436 {
1437   GPtrArray *file_list = NULL;
1438   FileListEntry *entry;
1439
1440   g_test_summary ("Check that the doc-comment for g_ptr_array_sort() is correct");
1441
1442   file_list = g_ptr_array_new_with_free_func (file_list_entry_free);
1443
1444   entry = g_new0 (FileListEntry, 1);
1445   entry->name = g_strdup ("README");
1446   entry->size = 42;
1447   g_ptr_array_add (file_list, g_steal_pointer (&entry));
1448
1449   entry = g_new0 (FileListEntry, 1);
1450   entry->name = g_strdup ("empty");
1451   entry->size = 0;
1452   g_ptr_array_add (file_list, g_steal_pointer (&entry));
1453
1454   entry = g_new0 (FileListEntry, 1);
1455   entry->name = g_strdup ("aardvark");
1456   entry->size = 23;
1457   g_ptr_array_add (file_list, g_steal_pointer (&entry));
1458
1459   g_ptr_array_sort (file_list, sort_filelist);
1460
1461   g_assert_cmpuint (file_list->len, ==, 3);
1462   entry = g_ptr_array_index (file_list, 0);
1463   g_assert_cmpstr (entry->name, ==, "aardvark");
1464   entry = g_ptr_array_index (file_list, 1);
1465   g_assert_cmpstr (entry->name, ==, "empty");
1466   entry = g_ptr_array_index (file_list, 2);
1467   g_assert_cmpstr (entry->name, ==, "README");
1468
1469   g_ptr_array_unref (file_list);
1470 }
1471
1472 /* Please keep pointer_array_sort_with_data_example() in sync with the
1473  * doc-comment of g_ptr_array_sort_with_data() */
1474
1475 typedef enum { SORT_NAME, SORT_SIZE } SortMode;
1476
1477 static gint
1478 sort_filelist_how (gconstpointer a, gconstpointer b, gpointer user_data)
1479 {
1480   gint order;
1481   const SortMode sort_mode = GPOINTER_TO_INT (user_data);
1482   const FileListEntry *entry1 = *((FileListEntry **) a);
1483   const FileListEntry *entry2 = *((FileListEntry **) b);
1484
1485   switch (sort_mode)
1486     {
1487     case SORT_NAME:
1488       order = g_ascii_strcasecmp (entry1->name, entry2->name);
1489       break;
1490     case SORT_SIZE:
1491       order = entry1->size - entry2->size;
1492       break;
1493     default:
1494       order = 0;
1495       break;
1496     }
1497   return order;
1498 }
1499
1500 static void
1501 pointer_array_sort_with_data_example (void)
1502 {
1503   GPtrArray *file_list = NULL;
1504   FileListEntry *entry;
1505   SortMode sort_mode;
1506
1507   g_test_summary ("Check that the doc-comment for g_ptr_array_sort_with_data() is correct");
1508
1509   file_list = g_ptr_array_new_with_free_func (file_list_entry_free);
1510
1511   entry = g_new0 (FileListEntry, 1);
1512   entry->name = g_strdup ("README");
1513   entry->size = 42;
1514   g_ptr_array_add (file_list, g_steal_pointer (&entry));
1515
1516   entry = g_new0 (FileListEntry, 1);
1517   entry->name = g_strdup ("empty");
1518   entry->size = 0;
1519   g_ptr_array_add (file_list, g_steal_pointer (&entry));
1520
1521   entry = g_new0 (FileListEntry, 1);
1522   entry->name = g_strdup ("aardvark");
1523   entry->size = 23;
1524   g_ptr_array_add (file_list, g_steal_pointer (&entry));
1525
1526   sort_mode = SORT_NAME;
1527   g_ptr_array_sort_with_data (file_list, sort_filelist_how, GINT_TO_POINTER (sort_mode));
1528
1529   g_assert_cmpuint (file_list->len, ==, 3);
1530   entry = g_ptr_array_index (file_list, 0);
1531   g_assert_cmpstr (entry->name, ==, "aardvark");
1532   entry = g_ptr_array_index (file_list, 1);
1533   g_assert_cmpstr (entry->name, ==, "empty");
1534   entry = g_ptr_array_index (file_list, 2);
1535   g_assert_cmpstr (entry->name, ==, "README");
1536
1537   sort_mode = SORT_SIZE;
1538   g_ptr_array_sort_with_data (file_list, sort_filelist_how, GINT_TO_POINTER (sort_mode));
1539
1540   g_assert_cmpuint (file_list->len, ==, 3);
1541   entry = g_ptr_array_index (file_list, 0);
1542   g_assert_cmpstr (entry->name, ==, "empty");
1543   entry = g_ptr_array_index (file_list, 1);
1544   g_assert_cmpstr (entry->name, ==, "aardvark");
1545   entry = g_ptr_array_index (file_list, 2);
1546   g_assert_cmpstr (entry->name, ==, "README");
1547
1548   g_ptr_array_unref (file_list);
1549 }
1550
1551 static void
1552 pointer_array_sort_with_data (void)
1553 {
1554   GPtrArray *gparray;
1555   gint i;
1556   gint prev, cur;
1557
1558   gparray = g_ptr_array_new ();
1559
1560   /* Sort empty array */
1561   g_ptr_array_sort_with_data (gparray, ptr_compare_data, NULL);
1562
1563   for (i = 0; i < 10000; i++)
1564     g_ptr_array_add (gparray, GINT_TO_POINTER (g_random_int_range (0, 10000)));
1565
1566   g_ptr_array_sort_with_data (gparray, ptr_compare_data, NULL);
1567
1568   prev = -1;
1569   for (i = 0; i < 10000; i++)
1570     {
1571       cur = GPOINTER_TO_INT (g_ptr_array_index (gparray, i));
1572       g_assert_cmpint (prev, <=, cur);
1573       prev = cur;
1574     }
1575
1576   g_ptr_array_free (gparray, TRUE);
1577 }
1578
1579 static void
1580 pointer_array_find_empty (void)
1581 {
1582   GPtrArray *array;
1583   guint idx;
1584
1585   array = g_ptr_array_new ();
1586
1587   g_assert_false (g_ptr_array_find (array, "some-value", NULL));  /* NULL index */
1588   g_assert_false (g_ptr_array_find (array, "some-value", &idx));  /* non-NULL index */
1589   g_assert_false (g_ptr_array_find_with_equal_func (array, "some-value", g_str_equal, NULL));  /* NULL index */
1590   g_assert_false (g_ptr_array_find_with_equal_func (array, "some-value", g_str_equal, &idx));  /* non-NULL index */
1591
1592   g_ptr_array_free (array, TRUE);
1593 }
1594
1595 static void
1596 pointer_array_find_non_empty (void)
1597 {
1598   GPtrArray *array;
1599   guint idx;
1600   const gchar *str_pointer = "static-string";
1601
1602   array = g_ptr_array_new ();
1603
1604   g_ptr_array_add (array, "some");
1605   g_ptr_array_add (array, "random");
1606   g_ptr_array_add (array, "values");
1607   g_ptr_array_add (array, "some");
1608   g_ptr_array_add (array, "duplicated");
1609   g_ptr_array_add (array, (gpointer) str_pointer);
1610
1611   g_assert_true (g_ptr_array_find_with_equal_func (array, "random", g_str_equal, NULL));  /* NULL index */
1612   g_assert_true (g_ptr_array_find_with_equal_func (array, "random", g_str_equal, &idx));  /* non-NULL index */
1613   g_assert_cmpuint (idx, ==, 1);
1614
1615   g_assert_true (g_ptr_array_find_with_equal_func (array, "some", g_str_equal, &idx));  /* duplicate element */
1616   g_assert_cmpuint (idx, ==, 0);
1617
1618   g_assert_false (g_ptr_array_find_with_equal_func (array, "nope", g_str_equal, NULL));
1619
1620   g_assert_true (g_ptr_array_find_with_equal_func (array, str_pointer, g_str_equal, &idx));
1621   g_assert_cmpuint (idx, ==, 5);
1622   idx = G_MAXUINT;
1623   g_assert_true (g_ptr_array_find_with_equal_func (array, str_pointer, NULL, &idx));  /* NULL equal func */
1624   g_assert_cmpuint (idx, ==, 5);
1625   idx = G_MAXUINT;
1626   g_assert_true (g_ptr_array_find (array, str_pointer, &idx));  /* NULL equal func */
1627   g_assert_cmpuint (idx, ==, 5);
1628
1629   g_ptr_array_free (array, TRUE);
1630 }
1631
1632 static void
1633 steal_destroy_notify (gpointer data)
1634 {
1635   guint *counter = data;
1636   *counter = *counter + 1;
1637 }
1638
1639 /* Test that g_ptr_array_steal_index() and g_ptr_array_steal_index_fast() can
1640  * remove elements from a pointer array without the #GDestroyNotify being called. */
1641 static void
1642 pointer_array_steal_index (void)
1643 {
1644   guint i1 = 0, i2 = 0, i3 = 0, i4 = 0;
1645   gpointer out1, out2;
1646   GPtrArray *array = g_ptr_array_new_with_free_func (steal_destroy_notify);
1647
1648   g_ptr_array_add (array, &i1);
1649   g_ptr_array_add (array, &i2);
1650   g_ptr_array_add (array, &i3);
1651   g_ptr_array_add (array, &i4);
1652
1653   g_assert_cmpuint (array->len, ==, 4);
1654
1655   /* Remove a single element. */
1656   out1 = g_ptr_array_steal_index (array, 0);
1657   g_assert_true (out1 == &i1);
1658   g_assert_cmpuint (i1, ==, 0);  /* should not have been destroyed */
1659
1660   /* Following elements should have been moved down. */
1661   g_assert_cmpuint (array->len, ==, 3);
1662   g_assert_true (g_ptr_array_index (array, 0) == &i2);
1663   g_assert_true (g_ptr_array_index (array, 1) == &i3);
1664   g_assert_true (g_ptr_array_index (array, 2) == &i4);
1665
1666   /* Remove another element, quickly. */
1667   out2 = g_ptr_array_steal_index_fast (array, 0);
1668   g_assert_true (out2 == &i2);
1669   g_assert_cmpuint (i2, ==, 0);  /* should not have been destroyed */
1670
1671   /* Last element should have been swapped in place. */
1672   g_assert_cmpuint (array->len, ==, 2);
1673   g_assert_true (g_ptr_array_index (array, 0) == &i4);
1674   g_assert_true (g_ptr_array_index (array, 1) == &i3);
1675
1676   /* Check that destroying the pointer array doesn’t affect the stolen elements. */
1677   g_ptr_array_unref (array);
1678
1679   g_assert_cmpuint (i1, ==, 0);
1680   g_assert_cmpuint (i2, ==, 0);
1681   g_assert_cmpuint (i3, ==, 1);
1682   g_assert_cmpuint (i4, ==, 1);
1683 }
1684
1685 static void
1686 byte_array_new_take_overflow (void)
1687 {
1688 #if SIZE_WIDTH <= UINT_WIDTH
1689   g_test_skip ("Overflow test requires G_MAXSIZE > G_MAXUINT.");
1690 #else
1691   GByteArray* arr;
1692
1693   if (!g_test_undefined ())
1694       return;
1695
1696   /* Check for overflow should happen before data is accessed. */
1697   g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL,
1698                           "*assertion 'len <= G_MAXUINT' failed");
1699   arr = g_byte_array_new_take (NULL, (gsize)G_MAXUINT + 1);
1700   g_assert_null (arr);
1701   g_test_assert_expected_messages ();
1702 #endif
1703 }
1704
1705 static void
1706 byte_array_steal (void)
1707 {
1708   const guint array_size = 10000;
1709   GByteArray *gbarray;
1710   guint8 *bdata;
1711   guint i;
1712   gsize len, past_len;
1713
1714   gbarray = g_byte_array_new ();
1715   bdata = g_byte_array_steal (gbarray, NULL);
1716   g_assert_cmpint ((gsize) bdata, ==, (gsize) gbarray->data);
1717   g_free (bdata);
1718
1719   for (i = 0; i < array_size; i++)
1720     g_byte_array_append (gbarray, (guint8 *) "abcd", 4);
1721
1722   past_len = gbarray->len;
1723   bdata = g_byte_array_steal (gbarray, &len);
1724
1725   g_assert_cmpint (len, ==, past_len);
1726   g_assert_cmpint (gbarray->len, ==, 0);
1727
1728   g_byte_array_append (gbarray, (guint8 *) "@", 1);
1729
1730   g_assert_cmpint (bdata[0], ==, 'a');
1731   g_assert_cmpint (gbarray->data[0], ==, '@');
1732   g_assert_cmpint (gbarray->len, ==, 1);
1733
1734   g_byte_array_remove_index (gbarray, 0);
1735
1736   g_free (bdata);
1737   g_byte_array_free (gbarray, TRUE);
1738 }
1739
1740 static void
1741 byte_array_append (void)
1742 {
1743   GByteArray *gbarray;
1744   gint i;
1745   guint8 *segment;
1746
1747   gbarray = g_byte_array_sized_new (1000);
1748   for (i = 0; i < 10000; i++)
1749     g_byte_array_append (gbarray, (guint8*) "abcd", 4);
1750
1751   for (i = 0; i < 10000; i++)
1752     {
1753       g_assert (gbarray->data[4*i] == 'a');
1754       g_assert (gbarray->data[4*i+1] == 'b');
1755       g_assert (gbarray->data[4*i+2] == 'c');
1756       g_assert (gbarray->data[4*i+3] == 'd');
1757     }
1758
1759   segment = g_byte_array_free (gbarray, FALSE);
1760
1761   for (i = 0; i < 10000; i++)
1762     {
1763       g_assert (segment[4*i] == 'a');
1764       g_assert (segment[4*i+1] == 'b');
1765       g_assert (segment[4*i+2] == 'c');
1766       g_assert (segment[4*i+3] == 'd');
1767     }
1768
1769   g_free (segment);
1770 }
1771
1772 static void
1773 byte_array_prepend (void)
1774 {
1775   GByteArray *gbarray;
1776   gint i;
1777
1778   gbarray = g_byte_array_new ();
1779   g_byte_array_set_size (gbarray, 1000);
1780
1781   for (i = 0; i < 10000; i++)
1782     g_byte_array_prepend (gbarray, (guint8*) "abcd", 4);
1783
1784   for (i = 0; i < 10000; 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
1796 byte_array_ref_count (void)
1797 {
1798   GByteArray *gbarray;
1799   GByteArray *gbarray2;
1800   gint i;
1801
1802   gbarray = g_byte_array_new ();
1803   for (i = 0; i < 10000; i++)
1804     g_byte_array_append (gbarray, (guint8*) "abcd", 4);
1805
1806   gbarray2 = g_byte_array_ref (gbarray);
1807   g_assert (gbarray2 == gbarray);
1808   g_byte_array_unref (gbarray2);
1809   for (i = 0; i < 10000; i++)
1810     {
1811       g_assert (gbarray->data[4*i] == 'a');
1812       g_assert (gbarray->data[4*i+1] == 'b');
1813       g_assert (gbarray->data[4*i+2] == 'c');
1814       g_assert (gbarray->data[4*i+3] == 'd');
1815     }
1816
1817   gbarray2 = g_byte_array_ref (gbarray);
1818   g_assert (gbarray2 == gbarray);
1819   g_byte_array_free (gbarray, TRUE);
1820   g_assert_cmpint (gbarray2->len, ==, 0);
1821   g_byte_array_unref (gbarray2);
1822 }
1823
1824 static void
1825 byte_array_remove (void)
1826 {
1827   GByteArray *gbarray;
1828   gint i;
1829
1830   gbarray = g_byte_array_new ();
1831   for (i = 0; i < 100; i++)
1832     g_byte_array_append (gbarray, (guint8*) "abcd", 4);
1833
1834   g_assert_cmpint (gbarray->len, ==, 400);
1835
1836   g_byte_array_remove_index (gbarray, 4);
1837   g_byte_array_remove_index (gbarray, 4);
1838   g_byte_array_remove_index (gbarray, 4);
1839   g_byte_array_remove_index (gbarray, 4);
1840
1841   g_assert_cmpint (gbarray->len, ==, 396);
1842
1843   for (i = 0; i < 99; i++)
1844     {
1845       g_assert (gbarray->data[4*i] == 'a');
1846       g_assert (gbarray->data[4*i+1] == 'b');
1847       g_assert (gbarray->data[4*i+2] == 'c');
1848       g_assert (gbarray->data[4*i+3] == 'd');
1849     }
1850
1851   g_byte_array_free (gbarray, TRUE);
1852 }
1853
1854 static void
1855 byte_array_remove_fast (void)
1856 {
1857   GByteArray *gbarray;
1858   gint i;
1859
1860   gbarray = g_byte_array_new ();
1861   for (i = 0; i < 100; i++)
1862     g_byte_array_append (gbarray, (guint8*) "abcd", 4);
1863
1864   g_assert_cmpint (gbarray->len, ==, 400);
1865
1866   g_byte_array_remove_index_fast (gbarray, 4);
1867   g_byte_array_remove_index_fast (gbarray, 4);
1868   g_byte_array_remove_index_fast (gbarray, 4);
1869   g_byte_array_remove_index_fast (gbarray, 4);
1870
1871   g_assert_cmpint (gbarray->len, ==, 396);
1872
1873   for (i = 0; i < 99; i++)
1874     {
1875       g_assert (gbarray->data[4*i] == 'a');
1876       g_assert (gbarray->data[4*i+1] == 'b');
1877       g_assert (gbarray->data[4*i+2] == 'c');
1878       g_assert (gbarray->data[4*i+3] == 'd');
1879     }
1880
1881   g_byte_array_free (gbarray, TRUE);
1882 }
1883
1884 static void
1885 byte_array_remove_range (void)
1886 {
1887   GByteArray *gbarray;
1888   gint i;
1889
1890   gbarray = g_byte_array_new ();
1891   for (i = 0; i < 100; i++)
1892     g_byte_array_append (gbarray, (guint8*) "abcd", 4);
1893
1894   g_assert_cmpint (gbarray->len, ==, 400);
1895
1896   g_byte_array_remove_range (gbarray, 12, 4);
1897
1898   g_assert_cmpint (gbarray->len, ==, 396);
1899
1900   for (i = 0; i < 99; i++)
1901     {
1902       g_assert (gbarray->data[4*i] == 'a');
1903       g_assert (gbarray->data[4*i+1] == 'b');
1904       g_assert (gbarray->data[4*i+2] == 'c');
1905       g_assert (gbarray->data[4*i+3] == 'd');
1906     }
1907
1908   /* Ensure the entire array can be cleared, even when empty. */
1909   g_byte_array_remove_range (gbarray, 0, gbarray->len);
1910   g_byte_array_remove_range (gbarray, 0, gbarray->len);
1911
1912   g_byte_array_free (gbarray, TRUE);
1913 }
1914
1915 static int
1916 byte_compare (gconstpointer p1, gconstpointer p2)
1917 {
1918   const guint8 *i1 = p1;
1919   const guint8 *i2 = p2;
1920
1921   return *i1 - *i2;
1922 }
1923
1924 static int
1925 byte_compare_data (gconstpointer p1, gconstpointer p2, gpointer data)
1926 {
1927   const guint8 *i1 = p1;
1928   const guint8 *i2 = p2;
1929
1930   return *i1 - *i2;
1931 }
1932
1933 static void
1934 byte_array_sort (void)
1935 {
1936   GByteArray *gbarray;
1937   guint i;
1938   guint8 val;
1939   guint8 prev, cur;
1940
1941   gbarray = g_byte_array_new ();
1942   for (i = 0; i < 100; i++)
1943     {
1944       val = 'a' + g_random_int_range (0, 26);
1945       g_byte_array_append (gbarray, (guint8*) &val, 1);
1946     }
1947
1948   g_byte_array_sort (gbarray, byte_compare);
1949
1950   prev = 'a';
1951   for (i = 0; i < gbarray->len; i++)
1952     {
1953       cur = gbarray->data[i];
1954       g_assert_cmpint (prev, <=, cur);
1955       prev = cur;
1956     }
1957
1958   g_byte_array_free (gbarray, TRUE);
1959 }
1960
1961 static void
1962 byte_array_sort_with_data (void)
1963 {
1964   GByteArray *gbarray;
1965   guint i;
1966   guint8 val;
1967   guint8 prev, cur;
1968
1969   gbarray = g_byte_array_new ();
1970   for (i = 0; i < 100; i++)
1971     {
1972       val = 'a' + g_random_int_range (0, 26);
1973       g_byte_array_append (gbarray, (guint8*) &val, 1);
1974     }
1975
1976   g_byte_array_sort_with_data (gbarray, byte_compare_data, NULL);
1977
1978   prev = 'a';
1979   for (i = 0; i < gbarray->len; i++)
1980     {
1981       cur = gbarray->data[i];
1982       g_assert_cmpint (prev, <=, cur);
1983       prev = cur;
1984     }
1985
1986   g_byte_array_free (gbarray, TRUE);
1987 }
1988
1989 static void
1990 byte_array_new_take (void)
1991 {
1992   GByteArray *gbarray;
1993   guint8 *data;
1994
1995   data = g_memdup2 ("woooweeewow", 11);
1996   gbarray = g_byte_array_new_take (data, 11);
1997   g_assert (gbarray->data == data);
1998   g_assert_cmpuint (gbarray->len, ==, 11);
1999   g_byte_array_free (gbarray, TRUE);
2000 }
2001
2002 static void
2003 byte_array_free_to_bytes (void)
2004 {
2005   GByteArray *gbarray;
2006   gpointer memory;
2007   GBytes *bytes;
2008   gsize size;
2009
2010   gbarray = g_byte_array_new ();
2011   g_byte_array_append (gbarray, (guint8 *)"woooweeewow", 11);
2012   memory = gbarray->data;
2013
2014   bytes = g_byte_array_free_to_bytes (gbarray);
2015   g_assert (bytes != NULL);
2016   g_assert_cmpuint (g_bytes_get_size (bytes), ==, 11);
2017   g_assert (g_bytes_get_data (bytes, &size) == memory);
2018   g_assert_cmpuint (size, ==, 11);
2019
2020   g_bytes_unref (bytes);
2021 }
2022
2023 static void
2024 add_array_test (const gchar         *test_path,
2025                 const ArrayTestData *config,
2026                 GTestDataFunc        test_func)
2027 {
2028   gchar *test_name = NULL;
2029
2030   test_name = g_strdup_printf ("%s/%s-%s",
2031                                test_path,
2032                                config->zero_terminated ? "zero-terminated" : "non-zero-terminated",
2033                                config->clear_ ? "clear" : "no-clear");
2034   g_test_add_data_func (test_name, config, test_func);
2035   g_free (test_name);
2036 }
2037
2038 int
2039 main (int argc, char *argv[])
2040 {
2041   /* Test all possible combinations of g_array_new() parameters. */
2042   const ArrayTestData array_configurations[] =
2043     {
2044       { FALSE, FALSE },
2045       { FALSE, TRUE },
2046       { TRUE, FALSE },
2047       { TRUE, TRUE },
2048     };
2049   gsize i;
2050
2051   g_test_init (&argc, &argv, NULL);
2052
2053   /* array tests */
2054   g_test_add_func ("/array/new/zero-terminated", array_new_zero_terminated);
2055   g_test_add_func ("/array/ref-count", array_ref_count);
2056   g_test_add_func ("/array/steal", array_steal);
2057   g_test_add_func ("/array/clear-func", array_clear_func);
2058   g_test_add_func ("/array/binary-search", test_array_binary_search);
2059   g_test_add_func ("/array/copy-sized", test_array_copy_sized);
2060   g_test_add_func ("/array/overflow-append-vals", array_overflow_append_vals);
2061   g_test_add_func ("/array/overflow-set-size", array_overflow_set_size);
2062
2063   for (i = 0; i < G_N_ELEMENTS (array_configurations); i++)
2064     {
2065       add_array_test ("/array/set-size", &array_configurations[i], array_set_size);
2066       add_array_test ("/array/set-size/sized", &array_configurations[i], array_set_size_sized);
2067       add_array_test ("/array/append-val", &array_configurations[i], array_append_val);
2068       add_array_test ("/array/prepend-val", &array_configurations[i], array_prepend_val);
2069       add_array_test ("/array/prepend-vals", &array_configurations[i], array_prepend_vals);
2070       add_array_test ("/array/insert-vals", &array_configurations[i], array_insert_vals);
2071       add_array_test ("/array/remove-index", &array_configurations[i], array_remove_index);
2072       add_array_test ("/array/remove-index-fast", &array_configurations[i], array_remove_index_fast);
2073       add_array_test ("/array/remove-range", &array_configurations[i], array_remove_range);
2074       add_array_test ("/array/copy", &array_configurations[i], array_copy);
2075       add_array_test ("/array/sort", &array_configurations[i], array_sort);
2076       add_array_test ("/array/sort-with-data", &array_configurations[i], array_sort_with_data);
2077     }
2078
2079   /* pointer arrays */
2080   g_test_add_func ("/pointerarray/add", pointer_array_add);
2081   g_test_add_func ("/pointerarray/insert", pointer_array_insert);
2082   g_test_add_func ("/pointerarray/ref-count", pointer_array_ref_count);
2083   g_test_add_func ("/pointerarray/free-func", pointer_array_free_func);
2084   g_test_add_func ("/pointerarray/array_copy", pointer_array_copy);
2085   g_test_add_func ("/pointerarray/array_extend", pointer_array_extend);
2086   g_test_add_func ("/pointerarray/array_extend_and_steal", pointer_array_extend_and_steal);
2087   g_test_add_func ("/pointerarray/sort", pointer_array_sort);
2088   g_test_add_func ("/pointerarray/sort/example", pointer_array_sort_example);
2089   g_test_add_func ("/pointerarray/sort-with-data", pointer_array_sort_with_data);
2090   g_test_add_func ("/pointerarray/sort-with-data/example", pointer_array_sort_with_data_example);
2091   g_test_add_func ("/pointerarray/find/empty", pointer_array_find_empty);
2092   g_test_add_func ("/pointerarray/find/non-empty", pointer_array_find_non_empty);
2093   g_test_add_func ("/pointerarray/steal", pointer_array_steal);
2094   g_test_add_func ("/pointerarray/steal_index", pointer_array_steal_index);
2095
2096   /* byte arrays */
2097   g_test_add_func ("/bytearray/steal", byte_array_steal);
2098   g_test_add_func ("/bytearray/append", byte_array_append);
2099   g_test_add_func ("/bytearray/prepend", byte_array_prepend);
2100   g_test_add_func ("/bytearray/remove", byte_array_remove);
2101   g_test_add_func ("/bytearray/remove-fast", byte_array_remove_fast);
2102   g_test_add_func ("/bytearray/remove-range", byte_array_remove_range);
2103   g_test_add_func ("/bytearray/ref-count", byte_array_ref_count);
2104   g_test_add_func ("/bytearray/sort", byte_array_sort);
2105   g_test_add_func ("/bytearray/sort-with-data", byte_array_sort_with_data);
2106   g_test_add_func ("/bytearray/new-take", byte_array_new_take);
2107   g_test_add_func ("/bytearray/new-take-overflow", byte_array_new_take_overflow);
2108   g_test_add_func ("/bytearray/free-to-bytes", byte_array_free_to_bytes);
2109
2110   return g_test_run ();
2111 }