Imported Upstream version 2.57.1
[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 #undef G_LOG_DOMAIN
27
28 #include <stdio.h>
29 #include <stdlib.h>
30 #include <string.h>
31 #include "glib.h"
32
33 static void
34 sum_up (gpointer data,
35         gpointer user_data)
36 {
37   gint *sum = (gint *)user_data;
38
39   *sum += GPOINTER_TO_INT (data);
40 }
41
42 /* Check that expanding an array with g_array_set_size() clears the new elements
43  * if @clear_ was specified during construction. */
44 static void
45 array_new_cleared (void)
46 {
47   GArray *garray;
48   gsize i;
49
50   garray = g_array_new (FALSE, TRUE, sizeof (gint));
51   g_assert_cmpuint (garray->len, ==, 0);
52
53   g_array_set_size (garray, 5);
54   g_assert_cmpuint (garray->len, ==, 5);
55
56   for (i = 0; i < 5; i++)
57     g_assert_cmpint (g_array_index (garray, gint, i), ==, 0);
58
59   g_array_unref (garray);
60 }
61
62 /* As with array_new_cleared(), but with a sized array. */
63 static void
64 array_new_sized_cleared (void)
65 {
66   GArray *garray;
67   gsize i;
68
69   garray = g_array_sized_new (FALSE, TRUE, sizeof (gint), 10);
70   g_assert_cmpuint (garray->len, ==, 0);
71
72   g_array_set_size (garray, 5);
73   g_assert_cmpuint (garray->len, ==, 5);
74
75   for (i = 0; i < 5; i++)
76     g_assert_cmpint (g_array_index (garray, gint, i), ==, 0);
77
78   g_array_unref (garray);
79 }
80
81 /* Check that a zero-terminated array does actually have a zero terminator. */
82 static void
83 array_new_zero_terminated (void)
84 {
85   GArray *garray;
86   gchar *out_str = NULL;
87
88   garray = g_array_new (TRUE, FALSE, sizeof (gchar));
89   g_assert_cmpuint (garray->len, ==, 0);
90
91   g_array_append_vals (garray, "hello", strlen ("hello"));
92   g_assert_cmpuint (garray->len, ==, 5);
93   g_assert_cmpstr (garray->data, ==, "hello");
94
95   out_str = g_array_free (garray, FALSE);
96   g_assert_cmpstr (out_str, ==, "hello");
97   g_free (out_str);
98 }
99
100 static void
101 array_append (void)
102 {
103   GArray *garray;
104   gint i;
105   gint *segment;
106
107   garray = g_array_new (FALSE, FALSE, sizeof (gint));
108   for (i = 0; i < 10000; i++)
109     g_array_append_val (garray, i);
110
111   for (i = 0; i < 10000; i++)
112     g_assert_cmpint (g_array_index (garray, gint, i), ==, i);
113
114   segment = (gint*)g_array_free (garray, FALSE);
115   for (i = 0; i < 10000; i++)
116     g_assert_cmpint (segment[i], ==, i);
117   g_free (segment);
118 }
119
120 static void
121 array_prepend (void)
122 {
123   GArray *garray;
124   gint i;
125
126   garray = g_array_new (FALSE, FALSE, sizeof (gint));
127   for (i = 0; i < 100; i++)
128     g_array_prepend_val (garray, i);
129
130   for (i = 0; i < 100; i++)
131     g_assert_cmpint (g_array_index (garray, gint, i), ==, (100 - i - 1));
132
133   g_array_free (garray, TRUE);
134 }
135
136 static void
137 array_remove (void)
138 {
139   GArray *garray;
140   gint i;
141   gint prev, cur;
142
143   garray = g_array_new (FALSE, FALSE, sizeof (gint));
144   for (i = 0; i < 100; i++)
145     g_array_append_val (garray, i);
146
147   g_assert_cmpint (garray->len, ==, 100);
148
149   g_array_remove_index (garray, 1);
150   g_array_remove_index (garray, 3);
151   g_array_remove_index (garray, 21);
152   g_array_remove_index (garray, 57);
153
154   g_assert_cmpint (garray->len, ==, 96);
155
156   prev = -1;
157   for (i = 0; i < garray->len; i++)
158     {
159       cur = g_array_index (garray, gint, i);
160       g_assert (cur != 1 &&  cur != 4 && cur != 23 && cur != 60);
161       g_assert_cmpint (prev, <, cur);
162       prev = cur;
163     }
164
165   g_array_free (garray, TRUE);
166 }
167
168 static void
169 array_remove_fast (void)
170 {
171   GArray *garray;
172   gint i;
173   gint prev, cur;
174
175   garray = g_array_new (FALSE, FALSE, sizeof (gint));
176   for (i = 0; i < 100; i++)
177     g_array_append_val (garray, i);
178
179   g_assert_cmpint (garray->len, ==, 100);
180
181   g_array_remove_index_fast (garray, 1);
182   g_array_remove_index_fast (garray, 3);
183   g_array_remove_index_fast (garray, 21);
184   g_array_remove_index_fast (garray, 57);
185
186   g_assert_cmpint (garray->len, ==, 96);
187
188   prev = -1;
189   for (i = 0; i < garray->len; i++)
190     {
191       cur = g_array_index (garray, gint, i);
192       g_assert (cur != 1 &&  cur != 3 && cur != 21 && cur != 57);
193       if (cur < 96)
194         {
195           g_assert_cmpint (prev, <, cur);
196           prev = cur;
197         }
198     }
199
200   g_array_free (garray, TRUE);
201 }
202
203 static void
204 array_remove_range (void)
205 {
206   GArray *garray;
207   gint i;
208   gint prev, cur;
209
210   garray = g_array_new (FALSE, FALSE, sizeof (gint));
211   for (i = 0; i < 100; i++)
212     g_array_append_val (garray, i);
213
214   g_assert_cmpint (garray->len, ==, 100);
215
216   g_array_remove_range (garray, 31, 4);
217
218   g_assert_cmpint (garray->len, ==, 96);
219
220   prev = -1;
221   for (i = 0; i < garray->len; i++)
222     {
223       cur = g_array_index (garray, gint, i);
224       g_assert (cur < 31 || cur > 34);
225       g_assert_cmpint (prev, <, cur);
226       prev = cur;
227     }
228
229   /* Ensure the entire array can be cleared, even when empty. */
230   g_array_remove_range (garray, 0, garray->len);
231   g_array_remove_range (garray, 0, garray->len);
232
233   g_array_free (garray, TRUE);
234 }
235
236 static void
237 array_ref_count (void)
238 {
239   GArray *garray;
240   GArray *garray2;
241   gint i;
242
243   garray = g_array_new (FALSE, FALSE, sizeof (gint));
244   g_assert_cmpint (g_array_get_element_size (garray), ==, sizeof (gint));
245   for (i = 0; i < 100; i++)
246     g_array_prepend_val (garray, i);
247
248   /* check we can ref, unref and still access the array */
249   garray2 = g_array_ref (garray);
250   g_assert (garray == garray2);
251   g_array_unref (garray2);
252   for (i = 0; i < 100; i++)
253     g_assert_cmpint (g_array_index (garray, gint, i), ==, (100 - i - 1));
254
255   /* garray2 should be an empty valid GArray wrapper */
256   garray2 = g_array_ref (garray);
257   g_array_free (garray, TRUE);
258
259   g_assert_cmpint (garray2->len, ==, 0);
260   g_array_unref (garray2);
261 }
262
263 static int
264 int_compare (gconstpointer p1, gconstpointer p2)
265 {
266   const gint *i1 = p1;
267   const gint *i2 = p2;
268
269   return *i1 - *i2;
270 }
271
272 static int
273 int_compare_data (gconstpointer p1, gconstpointer p2, gpointer data)
274 {
275   const gint *i1 = p1;
276   const gint *i2 = p2;
277
278   return *i1 - *i2;
279 }
280 static void
281 array_sort (void)
282 {
283   GArray *garray;
284   gint i;
285   gint prev, cur;
286
287   garray = g_array_new (FALSE, FALSE, sizeof (gint));
288   for (i = 0; i < 10000; i++)
289     {
290       cur = g_random_int_range (0, 10000);
291       g_array_append_val (garray, cur);
292     }
293   g_array_sort (garray,  int_compare);
294
295   prev = -1;
296   for (i = 0; i < garray->len; i++)
297     {
298       cur = g_array_index (garray, gint, i);
299       g_assert_cmpint (prev, <=, cur);
300       prev = cur;
301     }
302
303   g_array_free (garray, TRUE);
304 }
305
306 static void
307 array_sort_with_data (void)
308 {
309   GArray *garray;
310   gint i;
311   gint prev, cur;
312
313   garray = g_array_new (FALSE, FALSE, sizeof (gint));
314   for (i = 0; i < 10000; i++)
315     {
316       cur = g_random_int_range (0, 10000);
317       g_array_append_val (garray, cur);
318     }
319   g_array_sort_with_data (garray, int_compare_data, NULL);
320
321   prev = -1;
322   for (i = 0; i < garray->len; i++)
323     {
324       cur = g_array_index (garray, gint, i);
325       g_assert_cmpint (prev, <=, cur);
326       prev = cur;
327     }
328
329   g_array_free (garray, TRUE);
330 }
331
332 static gint num_clear_func_invocations = 0;
333
334 static void
335 my_clear_func (gpointer data)
336 {
337   num_clear_func_invocations += 1;
338 }
339
340 static void
341 array_clear_func (void)
342 {
343   GArray *garray;
344   gint i;
345   gint cur;
346
347   garray = g_array_new (FALSE, FALSE, sizeof (gint));
348   g_array_set_clear_func (garray, my_clear_func);
349
350   for (i = 0; i < 10; i++)
351     {
352       cur = g_random_int_range (0, 100);
353       g_array_append_val (garray, cur);
354     }
355
356   g_array_remove_index (garray, 9);
357   g_assert_cmpint (num_clear_func_invocations, ==, 1);
358
359   g_array_remove_range (garray, 5, 3);
360   g_assert_cmpint (num_clear_func_invocations, ==, 4);
361
362   g_array_remove_index_fast (garray, 4);
363   g_assert_cmpint (num_clear_func_invocations, ==, 5);
364
365   g_array_free (garray, TRUE);
366   g_assert_cmpint (num_clear_func_invocations, ==, 10);
367 }
368
369 static void
370 pointer_array_add (void)
371 {
372   GPtrArray *gparray;
373   gint i;
374   gint sum = 0;
375   gpointer *segment;
376
377   gparray = g_ptr_array_sized_new (1000);
378
379   for (i = 0; i < 10000; i++)
380     g_ptr_array_add (gparray, GINT_TO_POINTER (i));
381
382   for (i = 0; i < 10000; i++)
383     g_assert (g_ptr_array_index (gparray, i) == GINT_TO_POINTER (i));
384   
385   g_ptr_array_foreach (gparray, sum_up, &sum);
386   g_assert (sum == 49995000);
387
388   segment = g_ptr_array_free (gparray, FALSE);
389   for (i = 0; i < 10000; i++)
390     g_assert (segment[i] == GINT_TO_POINTER (i));
391   g_free (segment);
392 }
393
394 static void
395 pointer_array_insert (void)
396 {
397   GPtrArray *gparray;
398   gint i;
399   gint sum = 0;
400   gint index;
401
402   gparray = g_ptr_array_sized_new (1000);
403
404   for (i = 0; i < 10000; i++)
405     {
406       index = g_random_int_range (-1, i + 1);
407       g_ptr_array_insert (gparray, index, GINT_TO_POINTER (i));
408     }
409
410   g_ptr_array_foreach (gparray, sum_up, &sum);
411   g_assert (sum == 49995000);
412
413   g_ptr_array_free (gparray, TRUE);
414 }
415
416 static void
417 pointer_array_ref_count (void)
418 {
419   GPtrArray *gparray;
420   GPtrArray *gparray2;
421   gint i;
422   gint sum = 0;
423
424   gparray = g_ptr_array_new ();
425   for (i = 0; i < 10000; i++)
426     g_ptr_array_add (gparray, GINT_TO_POINTER (i));
427
428   /* check we can ref, unref and still access the array */
429   gparray2 = g_ptr_array_ref (gparray);
430   g_assert (gparray == gparray2);
431   g_ptr_array_unref (gparray2);
432   for (i = 0; i < 10000; i++)
433     g_assert (g_ptr_array_index (gparray, i) == GINT_TO_POINTER (i));
434
435   g_ptr_array_foreach (gparray, sum_up, &sum);
436   g_assert (sum == 49995000);
437
438   /* gparray2 should be an empty valid GPtrArray wrapper */
439   gparray2 = g_ptr_array_ref (gparray);
440   g_ptr_array_free (gparray, TRUE);
441
442   g_assert_cmpint (gparray2->len, ==, 0);
443   g_ptr_array_unref (gparray2);
444 }
445
446 static gint num_free_func_invocations = 0;
447
448 static void
449 my_free_func (gpointer data)
450 {
451   num_free_func_invocations++;
452   g_free (data);
453 }
454
455 static void
456 pointer_array_free_func (void)
457 {
458   GPtrArray *gparray;
459   GPtrArray *gparray2;
460   gchar **strv;
461   gchar *s;
462
463   num_free_func_invocations = 0;
464   gparray = g_ptr_array_new_with_free_func (my_free_func);
465   g_ptr_array_unref (gparray);
466   g_assert_cmpint (num_free_func_invocations, ==, 0);
467
468   gparray = g_ptr_array_new_with_free_func (my_free_func);
469   g_ptr_array_free (gparray, TRUE);
470   g_assert_cmpint (num_free_func_invocations, ==, 0);
471
472   num_free_func_invocations = 0;
473   gparray = g_ptr_array_new_with_free_func (my_free_func);
474   g_ptr_array_add (gparray, g_strdup ("foo"));
475   g_ptr_array_add (gparray, g_strdup ("bar"));
476   g_ptr_array_add (gparray, g_strdup ("baz"));
477   g_ptr_array_remove_index (gparray, 0);
478   g_assert_cmpint (num_free_func_invocations, ==, 1);
479   g_ptr_array_remove_index_fast (gparray, 1);
480   g_assert_cmpint (num_free_func_invocations, ==, 2);
481   s = g_strdup ("frob");
482   g_ptr_array_add (gparray, s);
483   g_assert (g_ptr_array_remove (gparray, s));
484   g_assert (!g_ptr_array_remove (gparray, "nuun"));
485   g_assert (!g_ptr_array_remove_fast (gparray, "mlo"));
486   g_assert_cmpint (num_free_func_invocations, ==, 3);
487   s = g_strdup ("frob");
488   g_ptr_array_add (gparray, s);
489   g_ptr_array_set_size (gparray, 1);
490   g_assert_cmpint (num_free_func_invocations, ==, 4);
491   g_ptr_array_ref (gparray);
492   g_ptr_array_unref (gparray);
493   g_assert_cmpint (num_free_func_invocations, ==, 4);
494   g_ptr_array_unref (gparray);
495   g_assert_cmpint (num_free_func_invocations, ==, 5);
496
497   num_free_func_invocations = 0;
498   gparray = g_ptr_array_new_full (10, my_free_func);
499   g_ptr_array_add (gparray, g_strdup ("foo"));
500   g_ptr_array_add (gparray, g_strdup ("bar"));
501   g_ptr_array_add (gparray, g_strdup ("baz"));
502   g_ptr_array_set_size (gparray, 20);
503   g_ptr_array_add (gparray, NULL);
504   gparray2 = g_ptr_array_ref (gparray);
505   strv = (gchar **) g_ptr_array_free (gparray, FALSE);
506   g_assert_cmpint (num_free_func_invocations, ==, 0);
507   g_strfreev (strv);
508   g_ptr_array_unref (gparray2);
509   g_assert_cmpint (num_free_func_invocations, ==, 0);
510
511   num_free_func_invocations = 0;
512   gparray = g_ptr_array_new_with_free_func (my_free_func);
513   g_ptr_array_add (gparray, g_strdup ("foo"));
514   g_ptr_array_add (gparray, g_strdup ("bar"));
515   g_ptr_array_add (gparray, g_strdup ("baz"));
516   g_ptr_array_remove_range (gparray, 1, 1);
517   g_ptr_array_unref (gparray);
518   g_assert_cmpint (num_free_func_invocations, ==, 3);
519
520   num_free_func_invocations = 0;
521   gparray = g_ptr_array_new_with_free_func (my_free_func);
522   g_ptr_array_add (gparray, g_strdup ("foo"));
523   g_ptr_array_add (gparray, g_strdup ("bar"));
524   g_ptr_array_add (gparray, g_strdup ("baz"));
525   g_ptr_array_free (gparray, TRUE);
526   g_assert_cmpint (num_free_func_invocations, ==, 3);
527
528   num_free_func_invocations = 0;
529   gparray = g_ptr_array_new_with_free_func (my_free_func);
530   g_ptr_array_add (gparray, "foo");
531   g_ptr_array_add (gparray, "bar");
532   g_ptr_array_add (gparray, "baz");
533   g_ptr_array_set_free_func (gparray, NULL);
534   g_ptr_array_free (gparray, TRUE);
535   g_assert_cmpint (num_free_func_invocations, ==, 0);
536 }
537
538 static gint
539 ptr_compare (gconstpointer p1, gconstpointer p2)
540 {
541   gpointer i1 = *(gpointer*)p1;
542   gpointer i2 = *(gpointer*)p2;
543
544   return GPOINTER_TO_INT (i1) - GPOINTER_TO_INT (i2);
545 }
546
547 static gint
548 ptr_compare_data (gconstpointer p1, gconstpointer p2, gpointer data)
549 {
550   gpointer i1 = *(gpointer*)p1;
551   gpointer i2 = *(gpointer*)p2;
552
553   return GPOINTER_TO_INT (i1) - GPOINTER_TO_INT (i2);
554 }
555
556 static void
557 pointer_array_sort (void)
558 {
559   GPtrArray *gparray;
560   gint i;
561   gint val;
562   gint prev, cur;
563
564   gparray = g_ptr_array_new ();
565   for (i = 0; i < 10000; i++)
566     {
567       val = g_random_int_range (0, 10000);
568       g_ptr_array_add (gparray, GINT_TO_POINTER (val));
569     }
570
571   g_ptr_array_sort (gparray, ptr_compare);
572
573   prev = -1;
574   for (i = 0; i < 10000; i++)
575     {
576       cur = GPOINTER_TO_INT (g_ptr_array_index (gparray, i));
577       g_assert_cmpint (prev, <=, cur);
578       prev = cur;
579     }
580
581   g_ptr_array_free (gparray, TRUE);
582 }
583
584 static void
585 pointer_array_sort_with_data (void)
586 {
587   GPtrArray *gparray;
588   gint i;
589   gint prev, cur;
590
591   gparray = g_ptr_array_new ();
592   for (i = 0; i < 10000; i++)
593     g_ptr_array_add (gparray, GINT_TO_POINTER (g_random_int_range (0, 10000)));
594
595   g_ptr_array_sort_with_data (gparray, ptr_compare_data, NULL);
596
597   prev = -1;
598   for (i = 0; i < 10000; i++)
599     {
600       cur = GPOINTER_TO_INT (g_ptr_array_index (gparray, i));
601       g_assert_cmpint (prev, <=, cur);
602       prev = cur;
603     }
604
605   g_ptr_array_free (gparray, TRUE);
606 }
607
608 static void
609 pointer_array_find_empty (void)
610 {
611   GPtrArray *array;
612   guint idx;
613
614   array = g_ptr_array_new ();
615
616   g_assert_false (g_ptr_array_find (array, "some-value", NULL));  /* NULL index */
617   g_assert_false (g_ptr_array_find (array, "some-value", &idx));  /* non-NULL index */
618   g_assert_false (g_ptr_array_find_with_equal_func (array, "some-value", g_str_equal, NULL));  /* NULL index */
619   g_assert_false (g_ptr_array_find_with_equal_func (array, "some-value", g_str_equal, &idx));  /* non-NULL index */
620
621   g_ptr_array_free (array, TRUE);
622 }
623
624 static void
625 pointer_array_find_non_empty (void)
626 {
627   GPtrArray *array;
628   guint idx;
629   const gchar *str_pointer = "static-string";
630
631   array = g_ptr_array_new ();
632
633   g_ptr_array_add (array, "some");
634   g_ptr_array_add (array, "random");
635   g_ptr_array_add (array, "values");
636   g_ptr_array_add (array, "some");
637   g_ptr_array_add (array, "duplicated");
638   g_ptr_array_add (array, (gpointer) str_pointer);
639
640   g_assert_true (g_ptr_array_find_with_equal_func (array, "random", g_str_equal, NULL));  /* NULL index */
641   g_assert_true (g_ptr_array_find_with_equal_func (array, "random", g_str_equal, &idx));  /* non-NULL index */
642   g_assert_cmpuint (idx, ==, 1);
643
644   g_assert_true (g_ptr_array_find_with_equal_func (array, "some", g_str_equal, &idx));  /* duplicate element */
645   g_assert_cmpuint (idx, ==, 0);
646
647   g_assert_false (g_ptr_array_find_with_equal_func (array, "nope", g_str_equal, NULL));
648
649   g_assert_true (g_ptr_array_find_with_equal_func (array, str_pointer, g_str_equal, &idx));
650   g_assert_cmpuint (idx, ==, 5);
651   idx = G_MAXUINT;
652   g_assert_true (g_ptr_array_find_with_equal_func (array, str_pointer, NULL, &idx));  /* NULL equal func */
653   g_assert_cmpuint (idx, ==, 5);
654   idx = G_MAXUINT;
655   g_assert_true (g_ptr_array_find (array, str_pointer, &idx));  /* NULL equal func */
656   g_assert_cmpuint (idx, ==, 5);
657
658   g_ptr_array_free (array, TRUE);
659 }
660
661 static void
662 steal_destroy_notify (gpointer data)
663 {
664   guint *counter = data;
665   *counter = *counter + 1;
666 }
667
668 /* Test that g_ptr_array_steal_index() and g_ptr_array_steal_index_fast() can
669  * remove elements from a pointer array without the #GDestroyNotify being called. */
670 static void
671 pointer_array_steal (void)
672 {
673   guint i1 = 0, i2 = 0, i3 = 0, i4 = 0;
674   gpointer out1, out2;
675   GPtrArray *array = g_ptr_array_new_with_free_func (steal_destroy_notify);
676
677   g_ptr_array_add (array, &i1);
678   g_ptr_array_add (array, &i2);
679   g_ptr_array_add (array, &i3);
680   g_ptr_array_add (array, &i4);
681
682   g_assert_cmpuint (array->len, ==, 4);
683
684   /* Remove a single element. */
685   out1 = g_ptr_array_steal_index (array, 0);
686   g_assert_true (out1 == &i1);
687   g_assert_cmpuint (i1, ==, 0);  /* should not have been destroyed */
688
689   /* Following elements should have been moved down. */
690   g_assert_cmpuint (array->len, ==, 3);
691   g_assert_true (g_ptr_array_index (array, 0) == &i2);
692   g_assert_true (g_ptr_array_index (array, 1) == &i3);
693   g_assert_true (g_ptr_array_index (array, 2) == &i4);
694
695   /* Remove another element, quickly. */
696   out2 = g_ptr_array_steal_index_fast (array, 0);
697   g_assert_true (out2 == &i2);
698   g_assert_cmpuint (i2, ==, 0);  /* should not have been destroyed */
699
700   /* Last element should have been swapped in place. */
701   g_assert_cmpuint (array->len, ==, 2);
702   g_assert_true (g_ptr_array_index (array, 0) == &i4);
703   g_assert_true (g_ptr_array_index (array, 1) == &i3);
704
705   /* Check that destroying the pointer array doesn’t affect the stolen elements. */
706   g_ptr_array_unref (array);
707
708   g_assert_cmpuint (i1, ==, 0);
709   g_assert_cmpuint (i2, ==, 0);
710   g_assert_cmpuint (i3, ==, 1);
711   g_assert_cmpuint (i4, ==, 1);
712 }
713
714 static void
715 byte_array_append (void)
716 {
717   GByteArray *gbarray;
718   gint i;
719   guint8 *segment;
720
721   gbarray = g_byte_array_sized_new (1000);
722   for (i = 0; i < 10000; i++)
723     g_byte_array_append (gbarray, (guint8*) "abcd", 4);
724
725   for (i = 0; i < 10000; i++)
726     {
727       g_assert (gbarray->data[4*i] == 'a');
728       g_assert (gbarray->data[4*i+1] == 'b');
729       g_assert (gbarray->data[4*i+2] == 'c');
730       g_assert (gbarray->data[4*i+3] == 'd');
731     }
732
733   segment = g_byte_array_free (gbarray, FALSE);
734
735   for (i = 0; i < 10000; i++)
736     {
737       g_assert (segment[4*i] == 'a');
738       g_assert (segment[4*i+1] == 'b');
739       g_assert (segment[4*i+2] == 'c');
740       g_assert (segment[4*i+3] == 'd');
741     }
742
743   g_free (segment);
744 }
745
746 static void
747 byte_array_prepend (void)
748 {
749   GByteArray *gbarray;
750   gint i;
751
752   gbarray = g_byte_array_new ();
753   g_byte_array_set_size (gbarray, 1000);
754
755   for (i = 0; i < 10000; i++)
756     g_byte_array_prepend (gbarray, (guint8*) "abcd", 4);
757
758   for (i = 0; i < 10000; i++)
759     {
760       g_assert (gbarray->data[4*i] == 'a');
761       g_assert (gbarray->data[4*i+1] == 'b');
762       g_assert (gbarray->data[4*i+2] == 'c');
763       g_assert (gbarray->data[4*i+3] == 'd');
764     }
765
766   g_byte_array_free (gbarray, TRUE);
767 }
768
769 static void
770 byte_array_ref_count (void)
771 {
772   GByteArray *gbarray;
773   GByteArray *gbarray2;
774   gint i;
775
776   gbarray = g_byte_array_new ();
777   for (i = 0; i < 10000; i++)
778     g_byte_array_append (gbarray, (guint8*) "abcd", 4);
779
780   gbarray2 = g_byte_array_ref (gbarray);
781   g_assert (gbarray2 == gbarray);
782   g_byte_array_unref (gbarray2);
783   for (i = 0; i < 10000; i++)
784     {
785       g_assert (gbarray->data[4*i] == 'a');
786       g_assert (gbarray->data[4*i+1] == 'b');
787       g_assert (gbarray->data[4*i+2] == 'c');
788       g_assert (gbarray->data[4*i+3] == 'd');
789     }
790
791   gbarray2 = g_byte_array_ref (gbarray);
792   g_assert (gbarray2 == gbarray);
793   g_byte_array_free (gbarray, TRUE);
794   g_assert_cmpint (gbarray2->len, ==, 0);
795   g_byte_array_unref (gbarray2);
796 }
797
798 static void
799 byte_array_remove (void)
800 {
801   GByteArray *gbarray;
802   gint i;
803
804   gbarray = g_byte_array_new ();
805   for (i = 0; i < 100; i++)
806     g_byte_array_append (gbarray, (guint8*) "abcd", 4);
807
808   g_assert_cmpint (gbarray->len, ==, 400);
809
810   g_byte_array_remove_index (gbarray, 4);
811   g_byte_array_remove_index (gbarray, 4);
812   g_byte_array_remove_index (gbarray, 4);
813   g_byte_array_remove_index (gbarray, 4);
814
815   g_assert_cmpint (gbarray->len, ==, 396);
816
817   for (i = 0; i < 99; i++)
818     {
819       g_assert (gbarray->data[4*i] == 'a');
820       g_assert (gbarray->data[4*i+1] == 'b');
821       g_assert (gbarray->data[4*i+2] == 'c');
822       g_assert (gbarray->data[4*i+3] == 'd');
823     }
824
825   g_byte_array_free (gbarray, TRUE);
826 }
827
828 static void
829 byte_array_remove_fast (void)
830 {
831   GByteArray *gbarray;
832   gint i;
833
834   gbarray = g_byte_array_new ();
835   for (i = 0; i < 100; i++)
836     g_byte_array_append (gbarray, (guint8*) "abcd", 4);
837
838   g_assert_cmpint (gbarray->len, ==, 400);
839
840   g_byte_array_remove_index_fast (gbarray, 4);
841   g_byte_array_remove_index_fast (gbarray, 4);
842   g_byte_array_remove_index_fast (gbarray, 4);
843   g_byte_array_remove_index_fast (gbarray, 4);
844
845   g_assert_cmpint (gbarray->len, ==, 396);
846
847   for (i = 0; i < 99; i++)
848     {
849       g_assert (gbarray->data[4*i] == 'a');
850       g_assert (gbarray->data[4*i+1] == 'b');
851       g_assert (gbarray->data[4*i+2] == 'c');
852       g_assert (gbarray->data[4*i+3] == 'd');
853     }
854
855   g_byte_array_free (gbarray, TRUE);
856 }
857
858 static void
859 byte_array_remove_range (void)
860 {
861   GByteArray *gbarray;
862   gint i;
863
864   gbarray = g_byte_array_new ();
865   for (i = 0; i < 100; i++)
866     g_byte_array_append (gbarray, (guint8*) "abcd", 4);
867
868   g_assert_cmpint (gbarray->len, ==, 400);
869
870   g_byte_array_remove_range (gbarray, 12, 4);
871
872   g_assert_cmpint (gbarray->len, ==, 396);
873
874   for (i = 0; i < 99; i++)
875     {
876       g_assert (gbarray->data[4*i] == 'a');
877       g_assert (gbarray->data[4*i+1] == 'b');
878       g_assert (gbarray->data[4*i+2] == 'c');
879       g_assert (gbarray->data[4*i+3] == 'd');
880     }
881
882   /* Ensure the entire array can be cleared, even when empty. */
883   g_byte_array_remove_range (gbarray, 0, gbarray->len);
884   g_byte_array_remove_range (gbarray, 0, gbarray->len);
885
886   g_byte_array_free (gbarray, TRUE);
887 }
888
889 static int
890 byte_compare (gconstpointer p1, gconstpointer p2)
891 {
892   const guint8 *i1 = p1;
893   const guint8 *i2 = p2;
894
895   return *i1 - *i2;
896 }
897
898 static int
899 byte_compare_data (gconstpointer p1, gconstpointer p2, gpointer data)
900 {
901   const guint8 *i1 = p1;
902   const guint8 *i2 = p2;
903
904   return *i1 - *i2;
905 }
906
907 static void
908 byte_array_sort (void)
909 {
910   GByteArray *gbarray;
911   gint i;
912   guint8 val;
913   guint8 prev, cur;
914
915   gbarray = g_byte_array_new ();
916   for (i = 0; i < 100; i++)
917     {
918       val = 'a' + g_random_int_range (0, 26);
919       g_byte_array_append (gbarray, (guint8*) &val, 1);
920     }
921
922   g_byte_array_sort (gbarray, byte_compare);
923
924   prev = 'a';
925   for (i = 0; i < gbarray->len; i++)
926     {
927       cur = gbarray->data[i];
928       g_assert_cmpint (prev, <=, cur);
929       prev = cur;
930     }
931
932   g_byte_array_free (gbarray, TRUE);
933 }
934
935 static void
936 byte_array_sort_with_data (void)
937 {
938   GByteArray *gbarray;
939   gint i;
940   guint8 val;
941   guint8 prev, cur;
942
943   gbarray = g_byte_array_new ();
944   for (i = 0; i < 100; i++)
945     {
946       val = 'a' + g_random_int_range (0, 26);
947       g_byte_array_append (gbarray, (guint8*) &val, 1);
948     }
949
950   g_byte_array_sort_with_data (gbarray, byte_compare_data, NULL);
951
952   prev = 'a';
953   for (i = 0; i < gbarray->len; i++)
954     {
955       cur = gbarray->data[i];
956       g_assert_cmpint (prev, <=, cur);
957       prev = cur;
958     }
959
960   g_byte_array_free (gbarray, TRUE);
961 }
962
963 static void
964 byte_array_new_take (void)
965 {
966   GByteArray *gbarray;
967   guint8 *data;
968
969   data = g_memdup ("woooweeewow", 11);
970   gbarray = g_byte_array_new_take (data, 11);
971   g_assert (gbarray->data == data);
972   g_assert_cmpuint (gbarray->len, ==, 11);
973   g_byte_array_free (gbarray, TRUE);
974 }
975
976 static void
977 byte_array_free_to_bytes (void)
978 {
979   GByteArray *gbarray;
980   gpointer memory;
981   GBytes *bytes;
982   gsize size;
983
984   gbarray = g_byte_array_new ();
985   g_byte_array_append (gbarray, (guint8 *)"woooweeewow", 11);
986   memory = gbarray->data;
987
988   bytes = g_byte_array_free_to_bytes (gbarray);
989   g_assert (bytes != NULL);
990   g_assert_cmpuint (g_bytes_get_size (bytes), ==, 11);
991   g_assert (g_bytes_get_data (bytes, &size) == memory);
992   g_assert_cmpuint (size, ==, 11);
993
994   g_bytes_unref (bytes);
995 }
996 int
997 main (int argc, char *argv[])
998 {
999   g_test_init (&argc, &argv, NULL);
1000
1001   g_test_bug_base ("https://bugzilla.gnome.org/");
1002
1003   /* array tests */
1004   g_test_add_func ("/array/new/cleared", array_new_cleared);
1005   g_test_add_func ("/array/new/sized-cleared", array_new_sized_cleared);
1006   g_test_add_func ("/array/new/zero-terminated", array_new_zero_terminated);
1007   g_test_add_func ("/array/append", array_append);
1008   g_test_add_func ("/array/prepend", array_prepend);
1009   g_test_add_func ("/array/remove", array_remove);
1010   g_test_add_func ("/array/remove-fast", array_remove_fast);
1011   g_test_add_func ("/array/remove-range", array_remove_range);
1012   g_test_add_func ("/array/ref-count", array_ref_count);
1013   g_test_add_func ("/array/sort", array_sort);
1014   g_test_add_func ("/array/sort-with-data", array_sort_with_data);
1015   g_test_add_func ("/array/clear-func", array_clear_func);
1016
1017   /* pointer arrays */
1018   g_test_add_func ("/pointerarray/add", pointer_array_add);
1019   g_test_add_func ("/pointerarray/insert", pointer_array_insert);
1020   g_test_add_func ("/pointerarray/ref-count", pointer_array_ref_count);
1021   g_test_add_func ("/pointerarray/free-func", pointer_array_free_func);
1022   g_test_add_func ("/pointerarray/sort", pointer_array_sort);
1023   g_test_add_func ("/pointerarray/sort-with-data", pointer_array_sort_with_data);
1024   g_test_add_func ("/pointerarray/find/empty", pointer_array_find_empty);
1025   g_test_add_func ("/pointerarray/find/non-empty", pointer_array_find_non_empty);
1026   g_test_add_func ("/pointerarray/steal", pointer_array_steal);
1027
1028   /* byte arrays */
1029   g_test_add_func ("/bytearray/append", byte_array_append);
1030   g_test_add_func ("/bytearray/prepend", byte_array_prepend);
1031   g_test_add_func ("/bytearray/remove", byte_array_remove);
1032   g_test_add_func ("/bytearray/remove-fast", byte_array_remove_fast);
1033   g_test_add_func ("/bytearray/remove-range", byte_array_remove_range);
1034   g_test_add_func ("/bytearray/ref-count", byte_array_ref_count);
1035   g_test_add_func ("/bytearray/sort", byte_array_sort);
1036   g_test_add_func ("/bytearray/sort-with-data", byte_array_sort_with_data);
1037   g_test_add_func ("/bytearray/new-take", byte_array_new_take);
1038   g_test_add_func ("/bytearray/free-to-bytes", byte_array_free_to_bytes);
1039
1040   return g_test_run ();
1041 }
1042