Branch data Line data Source code
1 : : /* GLIB - Library of useful routines for C programming
2 : : * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
3 : : *
4 : : * SPDX-License-Identifier: LGPL-2.1-or-later
5 : : *
6 : : * This library is free software; you can redistribute it and/or
7 : : * modify it under the terms of the GNU Lesser General Public
8 : : * License as published by the Free Software Foundation; either
9 : : * version 2.1 of the License, or (at your option) any later version.
10 : : *
11 : : * This library is distributed in the hope that it will be useful,
12 : : * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 : : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 : : * Lesser General Public License for more details.
15 : : *
16 : : * You should have received a copy of the GNU Lesser General Public
17 : : * License along with this library; if not, see <http://www.gnu.org/licenses/>.
18 : : */
19 : :
20 : : /*
21 : : * Modified by the GLib Team and others 1997-2000. See the AUTHORS
22 : : * file for a list of people on the GLib Team. See the ChangeLog
23 : : * files for a list of changes. These files are distributed with
24 : : * GLib at ftp://ftp.gtk.org/pub/gtk/.
25 : : */
26 : :
27 : : #undef G_DISABLE_ASSERT
28 : :
29 : : #include <stdio.h>
30 : : #include <stdlib.h>
31 : : #include <string.h>
32 : : #include "glib.h"
33 : :
34 : : /* Test data to be passed to any function which calls g_array_new(), providing
35 : : * the parameters for that call. Most #GArray tests should be repeated for all
36 : : * possible values of #ArrayTestData. */
37 : : typedef struct
38 : : {
39 : : gboolean zero_terminated;
40 : : gboolean clear_;
41 : : } ArrayTestData;
42 : :
43 : : /* Assert that @garray contains @n_expected_elements as given in @expected_data.
44 : : * @garray must contain #gint elements. */
45 : : static void
46 : 44 : assert_int_array_equal (GArray *garray,
47 : : const gint *expected_data,
48 : : gsize n_expected_elements)
49 : : {
50 : : gsize i;
51 : :
52 : 44 : g_assert_cmpuint (garray->len, ==, n_expected_elements);
53 [ + + ]: 240 : for (i = 0; i < garray->len; i++)
54 : 196 : g_assert_cmpint (g_array_index (garray, gint, i), ==, expected_data[i]);
55 : 44 : }
56 : :
57 : : /* Iff config->zero_terminated is %TRUE, assert that the final element of
58 : : * @garray is zero. @garray must contain #gint elements. */
59 : : static void
60 : 128 : assert_int_array_zero_terminated (const ArrayTestData *config,
61 : : GArray *garray)
62 : : {
63 [ + + ]: 128 : if (config->zero_terminated)
64 : : {
65 : 64 : gint *data = (gint *) garray->data;
66 : 64 : g_assert_cmpint (data[garray->len], ==, 0);
67 : : }
68 : 128 : }
69 : :
70 : : static void
71 : 40000 : sum_up (gpointer data,
72 : : gpointer user_data)
73 : : {
74 : 40000 : gint *sum = (gint *)user_data;
75 : :
76 : 40000 : *sum += GPOINTER_TO_INT (data);
77 : 40000 : }
78 : :
79 : : /* Check that expanding an array with g_array_set_size() clears the new elements
80 : : * if @clear_ was specified during construction. */
81 : : static void
82 : 4 : array_set_size (gconstpointer test_data)
83 : : {
84 : 4 : const ArrayTestData *config = test_data;
85 : : GArray *garray;
86 : : gsize i;
87 : :
88 : 4 : garray = g_array_new (config->zero_terminated, config->clear_, sizeof (gint));
89 : 4 : g_assert_cmpuint (garray->len, ==, 0);
90 : 4 : assert_int_array_zero_terminated (config, garray);
91 : :
92 : 4 : g_array_set_size (garray, 5);
93 : 4 : g_assert_cmpuint (garray->len, ==, 5);
94 : 4 : assert_int_array_zero_terminated (config, garray);
95 : :
96 [ + + ]: 4 : if (config->clear_)
97 [ + + ]: 12 : for (i = 0; i < 5; i++)
98 : 10 : g_assert_cmpint (g_array_index (garray, gint, i), ==, 0);
99 : :
100 : 4 : g_array_unref (garray);
101 : 4 : }
102 : :
103 : : /* As with array_set_size(), but with a sized array. */
104 : : static void
105 : 4 : array_set_size_sized (gconstpointer test_data)
106 : : {
107 : 4 : const ArrayTestData *config = test_data;
108 : : GArray *garray;
109 : : gsize i;
110 : :
111 : 4 : garray = g_array_sized_new (config->zero_terminated, config->clear_, sizeof (gint), 10);
112 : 4 : g_assert_cmpuint (garray->len, ==, 0);
113 : 4 : assert_int_array_zero_terminated (config, garray);
114 : :
115 : 4 : g_array_set_size (garray, 5);
116 : 4 : g_assert_cmpuint (garray->len, ==, 5);
117 : 4 : assert_int_array_zero_terminated (config, garray);
118 : :
119 [ + + ]: 4 : if (config->clear_)
120 [ + + ]: 12 : for (i = 0; i < 5; i++)
121 : 10 : g_assert_cmpint (g_array_index (garray, gint, i), ==, 0);
122 : :
123 : 4 : g_array_unref (garray);
124 : 4 : }
125 : :
126 : : /* Check that a zero-terminated array does actually have a zero terminator. */
127 : : static void
128 : 1 : array_new_zero_terminated (void)
129 : : {
130 : : GArray *garray;
131 : 1 : gchar *out_str = NULL;
132 : :
133 : 1 : garray = g_array_new (TRUE, FALSE, sizeof (gchar));
134 : 1 : g_assert_cmpuint (garray->len, ==, 0);
135 : :
136 : 1 : g_array_append_vals (garray, "hello", strlen ("hello"));
137 : 1 : g_assert_cmpuint (garray->len, ==, 5);
138 : 1 : g_assert_cmpstr (garray->data, ==, "hello");
139 : :
140 : 1 : out_str = g_array_free (garray, FALSE);
141 : 1 : g_assert_cmpstr (out_str, ==, "hello");
142 : 1 : g_free (out_str);
143 : 1 : }
144 : :
145 : : static void
146 : 1 : array_new_take (void)
147 : : {
148 : 1 : const size_t array_size = 10000;
149 : : GArray *garray;
150 : : gpointer *data;
151 : : gpointer *old_data_copy;
152 : : gsize len;
153 : :
154 : 1 : garray = g_array_new (FALSE, FALSE, sizeof (size_t));
155 [ + + ]: 10001 : for (size_t i = 0; i < array_size; i++)
156 : 10000 : g_array_append_val (garray, i);
157 : :
158 : 1 : data = g_array_steal (garray, &len);
159 : 1 : g_assert_cmpuint (array_size, ==, len);
160 : 1 : g_assert_nonnull (data);
161 : 1 : g_clear_pointer (&garray, g_array_unref);
162 : :
163 : 1 : old_data_copy = g_memdup2 (data, len * sizeof (size_t));
164 : 1 : garray = g_array_new_take (g_steal_pointer (&data), len, FALSE, sizeof (size_t));
165 : 1 : g_assert_cmpuint (garray->len, ==, array_size);
166 : :
167 : 1 : g_assert_cmpuint (g_array_index (garray, size_t, 0), ==, 0);
168 : 1 : g_assert_cmpuint (g_array_index (garray, size_t, 10), ==, 10);
169 : :
170 : 1 : g_assert_cmpmem (old_data_copy, array_size * sizeof (size_t),
171 : : garray->data, array_size * sizeof (size_t));
172 : :
173 : 1 : size_t val = 55;
174 : 1 : g_array_append_val (garray, val);
175 : 1 : val = 33;
176 : 1 : g_array_prepend_val (garray, val);
177 : :
178 : 1 : g_assert_cmpuint (garray->len, ==, array_size + 2);
179 : 1 : g_assert_cmpuint (g_array_index (garray, size_t, 0), ==, 33);
180 : 1 : g_assert_cmpuint (g_array_index (garray, size_t, garray->len - 1), ==, 55);
181 : :
182 : 1 : g_array_remove_index (garray, 0);
183 : 1 : g_assert_cmpuint (garray->len, ==, array_size + 1);
184 : 1 : g_array_remove_index (garray, garray->len - 1);
185 : 1 : g_assert_cmpuint (garray->len, ==, array_size);
186 : :
187 : 1 : g_assert_cmpmem (old_data_copy, array_size * sizeof (size_t),
188 : : garray->data, array_size * sizeof (size_t));
189 : :
190 : 1 : g_array_unref (garray);
191 : 1 : g_free (old_data_copy);
192 : 1 : }
193 : :
194 : : static void
195 : 1 : array_new_take_empty (void)
196 : : {
197 : : GArray *garray;
198 : 1 : size_t empty_array[] = {0};
199 : :
200 : 1 : garray = g_array_new_take (
201 : : g_memdup2 (&empty_array, sizeof (size_t)), 0, FALSE, sizeof (size_t));
202 : 1 : g_assert_cmpuint (garray->len, ==, 0);
203 : :
204 : 1 : g_clear_pointer (&garray, g_array_unref);
205 : :
206 : 1 : garray = g_array_new_take (NULL, 0, FALSE, sizeof (size_t));
207 : 1 : g_assert_cmpuint (garray->len, ==, 0);
208 : :
209 : 1 : g_clear_pointer (&garray, g_array_unref);
210 : 1 : }
211 : :
212 : : static void
213 : 1 : array_new_take_zero_terminated (void)
214 : : {
215 : 1 : size_t array_size = 10000;
216 : : GArray *garray;
217 : : gpointer *data;
218 : : gpointer *old_data_copy;
219 : : gsize len;
220 : :
221 : 1 : garray = g_array_new (TRUE, FALSE, sizeof (size_t));
222 [ + + ]: 10001 : for (size_t i = 1; i <= array_size; i++)
223 : 10000 : g_array_append_val (garray, i);
224 : :
225 : 1 : data = g_array_steal (garray, &len);
226 : 1 : g_assert_cmpuint (array_size, ==, len);
227 : 1 : g_assert_nonnull (data);
228 : 1 : g_clear_pointer (&garray, g_array_unref);
229 : :
230 : 1 : old_data_copy = g_memdup2 (data, len * sizeof (size_t));
231 : 1 : garray = g_array_new_take_zero_terminated (
232 : : g_steal_pointer (&data), FALSE, sizeof (size_t));
233 : 1 : g_assert_cmpuint (garray->len, ==, array_size);
234 : 1 : g_assert_cmpuint (g_array_index (garray, size_t, garray->len), ==, 0);
235 : :
236 : 1 : g_assert_cmpuint (g_array_index (garray, size_t, 0), ==, 1);
237 : 1 : g_assert_cmpuint (g_array_index (garray, size_t, 10), ==, 11);
238 : :
239 : 1 : g_assert_cmpmem (old_data_copy, array_size * sizeof (size_t),
240 : : garray->data, array_size * sizeof (size_t));
241 : :
242 : 1 : size_t val = 55;
243 : 1 : g_array_append_val (garray, val);
244 : 1 : val = 33;
245 : 1 : g_array_prepend_val (garray, val);
246 : :
247 : 1 : g_assert_cmpuint (garray->len, ==, array_size + 2);
248 : 1 : g_assert_cmpuint (g_array_index (garray, size_t, 0), ==, 33);
249 : 1 : g_assert_cmpuint (g_array_index (garray, size_t, garray->len - 1), ==, 55);
250 : :
251 : 1 : g_array_remove_index (garray, 0);
252 : 1 : g_assert_cmpuint (garray->len, ==, array_size + 1);
253 : 1 : g_array_remove_index (garray, garray->len - 1);
254 : 1 : g_assert_cmpuint (garray->len, ==, array_size);
255 : 1 : g_assert_cmpuint (g_array_index (garray, size_t, garray->len), ==, 0);
256 : :
257 : 1 : g_assert_cmpmem (old_data_copy, array_size * sizeof (size_t),
258 : : garray->data, array_size * sizeof (size_t));
259 : :
260 : 1 : g_clear_pointer (&garray, g_array_unref);
261 : 1 : g_clear_pointer (&old_data_copy, g_free);
262 : :
263 : 1 : array_size = G_MAXUINT8;
264 : 1 : garray = g_array_new (TRUE, FALSE, sizeof (guint8));
265 [ + + ]: 255 : for (guint8 i = 1; i < array_size; i++)
266 : 254 : g_array_append_val (garray, i);
267 : :
268 : 1 : guint8 byte_val = G_MAXUINT8 / 2;
269 : 1 : g_array_append_val (garray, byte_val);
270 : :
271 : 1 : data = g_array_steal (garray, &len);
272 : 1 : g_assert_cmpuint (array_size, ==, len);
273 : 1 : g_assert_nonnull (data);
274 : 1 : g_clear_pointer (&garray, g_array_unref);
275 : :
276 : 1 : old_data_copy = g_memdup2 (data, len * sizeof (guint8));
277 : 1 : garray = g_array_new_take_zero_terminated (
278 : : g_steal_pointer (&data), FALSE, sizeof (guint8));
279 : 1 : g_assert_cmpuint (garray->len, ==, array_size);
280 : 1 : g_assert_cmpuint (g_array_index (garray, guint8, garray->len), ==, 0);
281 : :
282 : 1 : g_assert_cmpuint (g_array_index (garray, guint8, 0), ==, 1);
283 : 1 : g_assert_cmpuint (g_array_index (garray, guint8, 10), ==, 11);
284 : :
285 : 1 : g_assert_cmpmem (old_data_copy, array_size * sizeof (guint8),
286 : : garray->data, array_size * sizeof (guint8));
287 : :
288 : 1 : byte_val = 55;
289 : 1 : g_array_append_val (garray, byte_val);
290 : 1 : byte_val = 33;
291 : 1 : g_array_prepend_val (garray, byte_val);
292 : :
293 : 1 : g_assert_cmpuint (garray->len, ==, array_size + 2);
294 : 1 : g_assert_cmpuint (g_array_index (garray, guint8, 0), ==, 33);
295 : 1 : g_assert_cmpuint (g_array_index (garray, guint8, garray->len - 1), ==, 55);
296 : :
297 : 1 : g_array_remove_index (garray, 0);
298 : 1 : g_assert_cmpuint (garray->len, ==, array_size + 1);
299 : 1 : g_array_remove_index (garray, garray->len - 1);
300 : 1 : g_assert_cmpuint (garray->len, ==, array_size);
301 : 1 : g_assert_cmpuint (g_array_index (garray, guint8, garray->len), ==, 0);
302 : :
303 : 1 : g_assert_cmpmem (old_data_copy, array_size * sizeof (guint8),
304 : : garray->data, array_size * sizeof (guint8));
305 : :
306 : 1 : g_clear_pointer (&garray, g_array_unref);
307 : 1 : g_clear_pointer (&old_data_copy, g_free);
308 : 1 : }
309 : :
310 : : static void
311 : 1 : array_new_take_overflow (void)
312 : : {
313 : : #if SIZE_WIDTH <= UINT_WIDTH
314 : 1 : g_test_skip ("Overflow test requires UINT_WIDTH > SIZE_WIDTH.");
315 : : #else
316 : : if (!g_test_undefined ())
317 : : return;
318 : :
319 : : /* Check for overflow should happen before data is accessed. */
320 : : g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL,
321 : : "*assertion 'len <= G_MAXUINT' failed");
322 : : g_assert_null (
323 : : g_array_new_take (
324 : : (gpointer) (int []) { 0 }, (gsize) G_MAXUINT + 1, FALSE, sizeof (int)));
325 : : g_test_assert_expected_messages ();
326 : :
327 : : g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL,
328 : : "*assertion 'element_size <= G_MAXUINT' failed");
329 : : g_assert_null (
330 : : g_array_new_take (NULL, 0, FALSE, (gsize) G_MAXUINT + 1));
331 : : g_test_assert_expected_messages ();
332 : : #endif
333 : 1 : }
334 : :
335 : : /* Check g_array_steal() function */
336 : : static void
337 : 1 : array_steal (void)
338 : : {
339 : 1 : const guint array_size = 10000;
340 : : GArray *garray;
341 : : gint *adata;
342 : : guint i;
343 : : gsize len, past_len;
344 : :
345 : 1 : garray = g_array_new (FALSE, FALSE, sizeof (gint));
346 : 1 : adata = (gint *) g_array_steal (garray, NULL);
347 : 1 : g_assert_null (adata);
348 : :
349 : 1 : adata = (gint *) g_array_steal (garray, &len);
350 : 1 : g_assert_null (adata);
351 : 1 : g_assert_cmpint (len, ==, 0);
352 : :
353 [ + + ]: 10001 : for (i = 0; i < array_size; i++)
354 : 10000 : g_array_append_val (garray, i);
355 : :
356 [ + + ]: 10001 : for (i = 0; i < array_size; i++)
357 : 10000 : g_assert_cmpint (g_array_index (garray, gint, i), ==, i);
358 : :
359 : :
360 : 1 : past_len = garray->len;
361 : 1 : adata = (gint *) g_array_steal (garray, &len);
362 [ + + ]: 10001 : for (i = 0; i < array_size; i++)
363 : 10000 : g_assert_cmpint (adata[i], ==, i);
364 : :
365 : 1 : g_assert_cmpint (past_len, ==, len);
366 : 1 : g_assert_cmpint (garray->len, ==, 0);
367 : :
368 : 1 : g_array_append_val (garray, i);
369 : :
370 : 1 : g_assert_cmpint (adata[0], ==, 0);
371 : 1 : g_assert_cmpint (g_array_index (garray, gint, 0), ==, array_size);
372 : 1 : g_assert_cmpint (garray->len, ==, 1);
373 : :
374 : 1 : g_array_remove_index (garray, 0);
375 : :
376 [ + + ]: 10001 : for (i = 0; i < array_size; i++)
377 : 10000 : g_array_append_val (garray, i);
378 : :
379 : 1 : g_assert_cmpint (garray->len, ==, array_size);
380 : 1 : g_assert_cmpmem (adata, array_size * sizeof (gint),
381 : : garray->data, array_size * sizeof (gint));
382 : 1 : g_free (adata);
383 : 1 : g_array_free (garray, TRUE);
384 : 1 : }
385 : :
386 : : /* Check that g_array_append_val() works correctly for various #GArray
387 : : * configurations. */
388 : : static void
389 : 4 : array_append_val (gconstpointer test_data)
390 : : {
391 : 4 : const ArrayTestData *config = test_data;
392 : : GArray *garray;
393 : : gint i;
394 : : gint *segment;
395 : :
396 : 4 : garray = g_array_new (config->zero_terminated, config->clear_, sizeof (gint));
397 [ + + ]: 40004 : for (i = 0; i < 10000; i++)
398 : 40000 : g_array_append_val (garray, i);
399 : 4 : assert_int_array_zero_terminated (config, garray);
400 : :
401 [ + + ]: 40004 : for (i = 0; i < 10000; i++)
402 : 40000 : g_assert_cmpint (g_array_index (garray, gint, i), ==, i);
403 : :
404 : 4 : segment = (gint*)g_array_free (garray, FALSE);
405 [ + + ]: 40004 : for (i = 0; i < 10000; i++)
406 : 40000 : g_assert_cmpint (segment[i], ==, i);
407 [ + + ]: 4 : if (config->zero_terminated)
408 : 2 : g_assert_cmpint (segment[10000], ==, 0);
409 : :
410 : 4 : g_free (segment);
411 : 4 : }
412 : :
413 : : /* Check that g_array_prepend_val() works correctly for various #GArray
414 : : * configurations. */
415 : : static void
416 : 4 : array_prepend_val (gconstpointer test_data)
417 : : {
418 : 4 : const ArrayTestData *config = test_data;
419 : : GArray *garray;
420 : : gint i;
421 : :
422 : 4 : garray = g_array_new (config->zero_terminated, config->clear_, sizeof (gint));
423 [ + + ]: 404 : for (i = 0; i < 100; i++)
424 : 400 : g_array_prepend_val (garray, i);
425 : 4 : assert_int_array_zero_terminated (config, garray);
426 : :
427 [ + + ]: 404 : for (i = 0; i < 100; i++)
428 : 400 : g_assert_cmpint (g_array_index (garray, gint, i), ==, (100 - i - 1));
429 : :
430 : 4 : g_array_free (garray, TRUE);
431 : 4 : }
432 : :
433 : : /* Test that g_array_prepend_vals() works correctly with various array
434 : : * configurations. */
435 : : static void
436 : 4 : array_prepend_vals (gconstpointer test_data)
437 : : {
438 : 4 : const ArrayTestData *config = test_data;
439 : : GArray *garray, *garray_out;
440 : 4 : const gint vals[] = { 0, 1, 2, 3, 4 };
441 : 4 : const gint expected_vals1[] = { 0, 1 };
442 : 4 : const gint expected_vals2[] = { 2, 0, 1 };
443 : 4 : const gint expected_vals3[] = { 3, 4, 2, 0, 1 };
444 : :
445 : : /* Set up an array. */
446 : 4 : garray = g_array_new (config->zero_terminated, config->clear_, sizeof (gint));
447 : 4 : assert_int_array_zero_terminated (config, garray);
448 : :
449 : : /* Prepend several values to an empty array. */
450 : 4 : garray_out = g_array_prepend_vals (garray, vals, 2);
451 : 4 : g_assert_true (garray == garray_out);
452 : 4 : assert_int_array_equal (garray, expected_vals1, G_N_ELEMENTS (expected_vals1));
453 : 4 : assert_int_array_zero_terminated (config, garray);
454 : :
455 : : /* Prepend a single value. */
456 : 4 : garray_out = g_array_prepend_vals (garray, vals + 2, 1);
457 : 4 : g_assert_true (garray == garray_out);
458 : 4 : assert_int_array_equal (garray, expected_vals2, G_N_ELEMENTS (expected_vals2));
459 : 4 : assert_int_array_zero_terminated (config, garray);
460 : :
461 : : /* Prepend several values to a non-empty array. */
462 : 4 : garray_out = g_array_prepend_vals (garray, vals + 3, 2);
463 : 4 : g_assert_true (garray == garray_out);
464 : 4 : assert_int_array_equal (garray, expected_vals3, G_N_ELEMENTS (expected_vals3));
465 : 4 : assert_int_array_zero_terminated (config, garray);
466 : :
467 : : /* Prepend no values. */
468 : 4 : garray_out = g_array_prepend_vals (garray, vals, 0);
469 : 4 : g_assert_true (garray == garray_out);
470 : 4 : assert_int_array_equal (garray, expected_vals3, G_N_ELEMENTS (expected_vals3));
471 : 4 : assert_int_array_zero_terminated (config, garray);
472 : :
473 : : /* Prepend no values with %NULL data. */
474 : 4 : garray_out = g_array_prepend_vals (garray, NULL, 0);
475 : 4 : g_assert_true (garray == garray_out);
476 : 4 : assert_int_array_equal (garray, expected_vals3, G_N_ELEMENTS (expected_vals3));
477 : 4 : assert_int_array_zero_terminated (config, garray);
478 : :
479 : 4 : g_array_free (garray, TRUE);
480 : 4 : }
481 : :
482 : : /* Test that g_array_insert_vals() works correctly with various array
483 : : * configurations. */
484 : : static void
485 : 4 : array_insert_vals (gconstpointer test_data)
486 : : {
487 : 4 : const ArrayTestData *config = test_data;
488 : : GArray *garray, *garray_out;
489 : : gsize i;
490 : 4 : const gint vals[] = { 0, 1, 2, 3, 4, 5, 6, 7 };
491 : 4 : const gint expected_vals1[] = { 0, 1 };
492 : 4 : const gint expected_vals2[] = { 0, 2, 3, 1 };
493 : 4 : const gint expected_vals3[] = { 0, 2, 3, 1, 4 };
494 : 4 : const gint expected_vals4[] = { 5, 0, 2, 3, 1, 4 };
495 : 4 : const gint expected_vals5[] = { 5, 0, 2, 3, 1, 4, 0, 0, 0, 0, 6, 7 };
496 : :
497 : : /* Set up an array. */
498 : 4 : garray = g_array_new (config->zero_terminated, config->clear_, sizeof (gint));
499 : 4 : assert_int_array_zero_terminated (config, garray);
500 : :
501 : : /* Insert several values at the beginning. */
502 : 4 : garray_out = g_array_insert_vals (garray, 0, vals, 2);
503 : 4 : g_assert_true (garray == garray_out);
504 : 4 : assert_int_array_equal (garray, expected_vals1, G_N_ELEMENTS (expected_vals1));
505 : 4 : assert_int_array_zero_terminated (config, garray);
506 : :
507 : : /* Insert some more part-way through. */
508 : 4 : garray_out = g_array_insert_vals (garray, 1, vals + 2, 2);
509 : 4 : g_assert_true (garray == garray_out);
510 : 4 : assert_int_array_equal (garray, expected_vals2, G_N_ELEMENTS (expected_vals2));
511 : 4 : assert_int_array_zero_terminated (config, garray);
512 : :
513 : : /* And at the end. */
514 : 4 : garray_out = g_array_insert_vals (garray, garray->len, vals + 4, 1);
515 : 4 : g_assert_true (garray == garray_out);
516 : 4 : assert_int_array_equal (garray, expected_vals3, G_N_ELEMENTS (expected_vals3));
517 : 4 : assert_int_array_zero_terminated (config, garray);
518 : :
519 : : /* Then back at the beginning again. */
520 : 4 : garray_out = g_array_insert_vals (garray, 0, vals + 5, 1);
521 : 4 : g_assert_true (garray == garray_out);
522 : 4 : assert_int_array_equal (garray, expected_vals4, G_N_ELEMENTS (expected_vals4));
523 : 4 : assert_int_array_zero_terminated (config, garray);
524 : :
525 : : /* Insert zero elements. */
526 : 4 : garray_out = g_array_insert_vals (garray, 0, vals, 0);
527 : 4 : g_assert_true (garray == garray_out);
528 : 4 : assert_int_array_equal (garray, expected_vals4, G_N_ELEMENTS (expected_vals4));
529 : 4 : assert_int_array_zero_terminated (config, garray);
530 : :
531 : : /* Insert zero elements with a %NULL pointer. */
532 : 4 : garray_out = g_array_insert_vals (garray, 0, NULL, 0);
533 : 4 : g_assert_true (garray == garray_out);
534 : 4 : assert_int_array_equal (garray, expected_vals4, G_N_ELEMENTS (expected_vals4));
535 : 4 : assert_int_array_zero_terminated (config, garray);
536 : :
537 : : /* Insert some elements off the end of the array. The behaviour here depends
538 : : * on whether the array clears entries. */
539 : 4 : garray_out = g_array_insert_vals (garray, garray->len + 4, vals + 6, 2);
540 : 4 : g_assert_true (garray == garray_out);
541 : :
542 : 4 : g_assert_cmpuint (garray->len, ==, G_N_ELEMENTS (expected_vals5));
543 [ + + ]: 52 : for (i = 0; i < G_N_ELEMENTS (expected_vals5); i++)
544 : : {
545 [ + + + + : 48 : if (config->clear_ || i < 6 || i > 9)
+ + ]
546 : 40 : g_assert_cmpint (g_array_index (garray, gint, i), ==, expected_vals5[i]);
547 : : }
548 : :
549 : 4 : assert_int_array_zero_terminated (config, garray);
550 : :
551 : 4 : g_array_free (garray, TRUE);
552 : 4 : }
553 : :
554 : : /* Check that g_array_remove_index() works correctly for various #GArray
555 : : * configurations. */
556 : : static void
557 : 4 : array_remove_index (gconstpointer test_data)
558 : : {
559 : 4 : const ArrayTestData *config = test_data;
560 : : GArray *garray;
561 : : guint i;
562 : : gint prev, cur;
563 : :
564 : 4 : garray = g_array_new (config->zero_terminated, config->clear_, sizeof (gint));
565 [ + + ]: 404 : for (i = 0; i < 100; i++)
566 : 400 : g_array_append_val (garray, i);
567 : 4 : assert_int_array_zero_terminated (config, garray);
568 : :
569 : 4 : g_assert_cmpint (garray->len, ==, 100);
570 : :
571 : 4 : g_array_remove_index (garray, 1);
572 : 4 : g_array_remove_index (garray, 3);
573 : 4 : g_array_remove_index (garray, 21);
574 : 4 : g_array_remove_index (garray, 57);
575 : :
576 : 4 : g_assert_cmpint (garray->len, ==, 96);
577 : 4 : assert_int_array_zero_terminated (config, garray);
578 : :
579 : 4 : prev = -1;
580 [ + + ]: 388 : for (i = 0; i < garray->len; i++)
581 : : {
582 : 384 : cur = g_array_index (garray, gint, i);
583 : 384 : g_assert (cur != 1 && cur != 4 && cur != 23 && cur != 60);
584 : 384 : g_assert_cmpint (prev, <, cur);
585 : 384 : prev = cur;
586 : : }
587 : :
588 : 4 : g_array_free (garray, TRUE);
589 : 4 : }
590 : :
591 : : /* Check that g_array_remove_index_fast() works correctly for various #GArray
592 : : * configurations. */
593 : : static void
594 : 4 : array_remove_index_fast (gconstpointer test_data)
595 : : {
596 : 4 : const ArrayTestData *config = test_data;
597 : : GArray *garray;
598 : : guint i;
599 : : gint prev, cur;
600 : :
601 : 4 : garray = g_array_new (config->zero_terminated, config->clear_, sizeof (gint));
602 [ + + ]: 404 : for (i = 0; i < 100; i++)
603 : 400 : g_array_append_val (garray, i);
604 : :
605 : 4 : g_assert_cmpint (garray->len, ==, 100);
606 : 4 : assert_int_array_zero_terminated (config, garray);
607 : :
608 : 4 : g_array_remove_index_fast (garray, 1);
609 : 4 : g_array_remove_index_fast (garray, 3);
610 : 4 : g_array_remove_index_fast (garray, 21);
611 : 4 : g_array_remove_index_fast (garray, 57);
612 : :
613 : 4 : g_assert_cmpint (garray->len, ==, 96);
614 : 4 : assert_int_array_zero_terminated (config, garray);
615 : :
616 : 4 : prev = -1;
617 [ + + ]: 388 : for (i = 0; i < garray->len; i++)
618 : : {
619 : 384 : cur = g_array_index (garray, gint, i);
620 : 384 : g_assert (cur != 1 && cur != 3 && cur != 21 && cur != 57);
621 [ + + ]: 384 : if (cur < 96)
622 : : {
623 : 368 : g_assert_cmpint (prev, <, cur);
624 : 368 : prev = cur;
625 : : }
626 : : }
627 : :
628 : 4 : g_array_free (garray, TRUE);
629 : 4 : }
630 : :
631 : : /* Check that g_array_remove_range() works correctly for various #GArray
632 : : * configurations. */
633 : : static void
634 : 4 : array_remove_range (gconstpointer test_data)
635 : : {
636 : 4 : const ArrayTestData *config = test_data;
637 : : GArray *garray;
638 : : guint i;
639 : : gint prev, cur;
640 : :
641 : 4 : garray = g_array_new (config->zero_terminated, config->clear_, sizeof (gint));
642 [ + + ]: 404 : for (i = 0; i < 100; i++)
643 : 400 : g_array_append_val (garray, i);
644 : :
645 : 4 : g_assert_cmpint (garray->len, ==, 100);
646 : 4 : assert_int_array_zero_terminated (config, garray);
647 : :
648 : 4 : g_array_remove_range (garray, 31, 4);
649 : :
650 : 4 : g_assert_cmpint (garray->len, ==, 96);
651 : 4 : assert_int_array_zero_terminated (config, garray);
652 : :
653 : 4 : prev = -1;
654 [ + + ]: 388 : for (i = 0; i < garray->len; i++)
655 : : {
656 : 384 : cur = g_array_index (garray, gint, i);
657 : 384 : g_assert (cur < 31 || cur > 34);
658 : 384 : g_assert_cmpint (prev, <, cur);
659 : 384 : prev = cur;
660 : : }
661 : :
662 : : /* Ensure the entire array can be cleared, even when empty. */
663 : 4 : g_array_remove_range (garray, 0, garray->len);
664 : :
665 : 4 : g_assert_cmpint (garray->len, ==, 0);
666 : 4 : assert_int_array_zero_terminated (config, garray);
667 : :
668 : 4 : g_array_remove_range (garray, 0, garray->len);
669 : :
670 : 4 : g_assert_cmpint (garray->len, ==, 0);
671 : 4 : assert_int_array_zero_terminated (config, garray);
672 : :
673 : 4 : g_array_free (garray, TRUE);
674 : 4 : }
675 : :
676 : : static void
677 : 1 : array_ref_count (void)
678 : : {
679 : : GArray *garray;
680 : : GArray *garray2;
681 : : gint i;
682 : :
683 : 1 : garray = g_array_new (FALSE, FALSE, sizeof (gint));
684 : 1 : g_assert_cmpint (g_array_get_element_size (garray), ==, sizeof (gint));
685 [ + + ]: 101 : for (i = 0; i < 100; i++)
686 : 100 : g_array_prepend_val (garray, i);
687 : :
688 : : /* check we can ref, unref and still access the array */
689 : 1 : garray2 = g_array_ref (garray);
690 : 1 : g_assert (garray == garray2);
691 : 1 : g_array_unref (garray2);
692 [ + + ]: 101 : for (i = 0; i < 100; i++)
693 : 100 : g_assert_cmpint (g_array_index (garray, gint, i), ==, (100 - i - 1));
694 : :
695 : : /* garray2 should be an empty valid GArray wrapper */
696 : 1 : garray2 = g_array_ref (garray);
697 : 1 : g_array_free (garray, TRUE);
698 : :
699 : 1 : g_assert_cmpint (garray2->len, ==, 0);
700 : 1 : g_array_unref (garray2);
701 : 1 : }
702 : :
703 : : static int
704 : 481665 : int_compare (gconstpointer p1, gconstpointer p2)
705 : : {
706 : 481665 : const gint *i1 = p1;
707 : 481665 : const gint *i2 = p2;
708 : :
709 : 481665 : return *i1 - *i2;
710 : : }
711 : :
712 : : static void
713 : 4 : array_copy (gconstpointer test_data)
714 : : {
715 : : GArray *array, *array_copy;
716 : : gsize i;
717 : 4 : const ArrayTestData *config = test_data;
718 : 4 : const gsize array_size = 100;
719 : :
720 : : /* Testing degenerated cases */
721 [ + - ]: 4 : if (g_test_undefined ())
722 : : {
723 : 4 : g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL,
724 : : "*assertion*!= NULL*");
725 : 4 : array = g_array_copy (NULL);
726 : 4 : g_test_assert_expected_messages ();
727 : :
728 : 4 : g_assert_null (array);
729 : : }
730 : :
731 : : /* Testing simple copy */
732 : 4 : array = g_array_new (config->zero_terminated, config->clear_, sizeof (gint));
733 : :
734 [ + + ]: 404 : for (i = 0; i < array_size; i++)
735 : 400 : g_array_append_val (array, i);
736 : :
737 : 4 : array_copy = g_array_copy (array);
738 : :
739 : : /* Check internal data */
740 [ + + ]: 404 : for (i = 0; i < array_size; i++)
741 : 400 : g_assert_cmpuint (g_array_index (array, gint, i), ==,
742 : : g_array_index (array_copy, gint, i));
743 : :
744 : : /* Check internal parameters ('zero_terminated' flag) */
745 [ + + ]: 4 : if (config->zero_terminated)
746 : : {
747 : 2 : const gint *data = (const gint *) array_copy->data;
748 : 2 : g_assert_cmpint (data[array_copy->len], ==, 0);
749 : : }
750 : :
751 : : /* Check internal parameters ('clear' flag) */
752 [ + + ]: 4 : if (config->clear_)
753 : : {
754 : 2 : guint old_length = array_copy->len;
755 : 2 : g_array_set_size (array_copy, old_length + 5);
756 [ + + ]: 12 : for (i = old_length; i < old_length + 5; i++)
757 : 10 : g_assert_cmpint (g_array_index (array_copy, gint, i), ==, 0);
758 : : }
759 : :
760 : : /* Clean-up */
761 : 4 : g_array_unref (array);
762 : 4 : g_array_unref (array_copy);
763 : 4 : }
764 : :
765 : : static int
766 : 481584 : int_compare_data (gconstpointer p1, gconstpointer p2, gpointer data)
767 : : {
768 : 481584 : const gint *i1 = p1;
769 : 481584 : const gint *i2 = p2;
770 : :
771 : 481584 : return *i1 - *i2;
772 : : }
773 : :
774 : : /* Check that g_array_sort() works correctly for various #GArray
775 : : * configurations. */
776 : : static void
777 : 4 : array_sort (gconstpointer test_data)
778 : : {
779 : 4 : const ArrayTestData *config = test_data;
780 : : GArray *garray;
781 : : guint i;
782 : : gint prev, cur;
783 : :
784 : 4 : garray = g_array_new (config->zero_terminated, config->clear_, sizeof (gint));
785 : :
786 : : /* Sort empty array */
787 : 4 : g_array_sort (garray, int_compare);
788 : :
789 [ + + ]: 40004 : for (i = 0; i < 10000; i++)
790 : : {
791 : 40000 : cur = g_random_int_range (0, 10000);
792 : 40000 : g_array_append_val (garray, cur);
793 : : }
794 : 4 : assert_int_array_zero_terminated (config, garray);
795 : :
796 : 4 : g_array_sort (garray, int_compare);
797 : 4 : assert_int_array_zero_terminated (config, garray);
798 : :
799 : 4 : prev = -1;
800 [ + + ]: 40004 : for (i = 0; i < garray->len; i++)
801 : : {
802 : 40000 : cur = g_array_index (garray, gint, i);
803 : 40000 : g_assert_cmpint (prev, <=, cur);
804 : 40000 : prev = cur;
805 : : }
806 : :
807 : 4 : g_array_free (garray, TRUE);
808 : 4 : }
809 : :
810 : : /* Check that g_array_sort_with_data() works correctly for various #GArray
811 : : * configurations. */
812 : : static void
813 : 4 : array_sort_with_data (gconstpointer test_data)
814 : : {
815 : 4 : const ArrayTestData *config = test_data;
816 : : GArray *garray;
817 : : guint i;
818 : : gint prev, cur;
819 : :
820 : 4 : garray = g_array_new (config->zero_terminated, config->clear_, sizeof (gint));
821 : :
822 : : /* Sort empty array */
823 : 4 : g_array_sort_with_data (garray, int_compare_data, NULL);
824 : :
825 [ + + ]: 40004 : for (i = 0; i < 10000; i++)
826 : : {
827 : 40000 : cur = g_random_int_range (0, 10000);
828 : 40000 : g_array_append_val (garray, cur);
829 : : }
830 : 4 : assert_int_array_zero_terminated (config, garray);
831 : :
832 : 4 : g_array_sort_with_data (garray, int_compare_data, NULL);
833 : 4 : assert_int_array_zero_terminated (config, garray);
834 : :
835 : 4 : prev = -1;
836 [ + + ]: 40004 : for (i = 0; i < garray->len; i++)
837 : : {
838 : 40000 : cur = g_array_index (garray, gint, i);
839 : 40000 : g_assert_cmpint (prev, <=, cur);
840 : 40000 : prev = cur;
841 : : }
842 : :
843 : 4 : g_array_free (garray, TRUE);
844 : 4 : }
845 : :
846 : : static gint num_clear_func_invocations = 0;
847 : :
848 : : static void
849 : 10 : my_clear_func (gpointer data)
850 : : {
851 : 10 : num_clear_func_invocations += 1;
852 : 10 : }
853 : :
854 : : static void
855 : 1 : array_clear_func (void)
856 : : {
857 : : GArray *garray;
858 : : gint i;
859 : : gint cur;
860 : :
861 : 1 : garray = g_array_new (FALSE, FALSE, sizeof (gint));
862 : 1 : g_array_set_clear_func (garray, my_clear_func);
863 : :
864 [ + + ]: 11 : for (i = 0; i < 10; i++)
865 : : {
866 : 10 : cur = g_random_int_range (0, 100);
867 : 10 : g_array_append_val (garray, cur);
868 : : }
869 : :
870 : 1 : g_array_remove_index (garray, 9);
871 : 1 : g_assert_cmpint (num_clear_func_invocations, ==, 1);
872 : :
873 : 1 : g_array_remove_range (garray, 5, 3);
874 : 1 : g_assert_cmpint (num_clear_func_invocations, ==, 4);
875 : :
876 : 1 : g_array_remove_index_fast (garray, 4);
877 : 1 : g_assert_cmpint (num_clear_func_invocations, ==, 5);
878 : :
879 : 1 : g_array_free (garray, TRUE);
880 : 1 : g_assert_cmpint (num_clear_func_invocations, ==, 10);
881 : 1 : }
882 : :
883 : : /* Defining a comparison function for testing g_array_binary_search() */
884 : : static gint
885 : 247342 : cmpint (gconstpointer a, gconstpointer b)
886 : : {
887 : 247342 : const gint *_a = a;
888 : 247342 : const gint *_b = b;
889 : :
890 : 247342 : return *_a - *_b;
891 : : }
892 : :
893 : : /* Testing g_array_binary_search() function */
894 : : static void
895 : 1 : test_array_binary_search (void)
896 : : {
897 : : GArray *garray;
898 : : guint i, matched_index;
899 : :
900 [ + - ]: 1 : if (g_test_undefined ())
901 : : {
902 : : /* Testing degenerated cases */
903 : 1 : garray = g_array_sized_new (FALSE, FALSE, sizeof (guint), 0);
904 : 1 : g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL,
905 : : "*assertion*!= NULL*");
906 : 1 : g_assert_false (g_array_binary_search (NULL, &i, cmpint, NULL));
907 : 1 : g_test_assert_expected_messages ();
908 : :
909 : 1 : g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL,
910 : : "*assertion*!= NULL*");
911 : 1 : g_assert_false (g_array_binary_search (garray, &i, NULL, NULL));
912 : 1 : g_test_assert_expected_messages ();
913 : 1 : g_array_free (garray, TRUE);
914 : : }
915 : :
916 : : /* Testing array of size 0 */
917 : 1 : garray = g_array_sized_new (FALSE, FALSE, sizeof (guint), 0);
918 : :
919 : 1 : i = 1;
920 : 1 : g_assert_false (g_array_binary_search (garray, &i, cmpint, NULL));
921 : :
922 : 1 : g_array_free (garray, TRUE);
923 : :
924 : : /* Testing array of size 1 */
925 : 1 : garray = g_array_sized_new (FALSE, FALSE, sizeof (guint), 1);
926 : 1 : i = 1;
927 : 1 : g_array_append_val (garray, i);
928 : :
929 : 1 : g_assert_true (g_array_binary_search (garray, &i, cmpint, NULL));
930 : :
931 : 1 : i = 0;
932 : 1 : g_assert_false (g_array_binary_search (garray, &i, cmpint, NULL));
933 : :
934 : 1 : i = 2;
935 : 1 : g_assert_false (g_array_binary_search (garray, &i, cmpint, NULL));
936 : :
937 : 1 : g_array_free (garray, TRUE);
938 : :
939 : : /* Testing array of size 2 */
940 : 1 : garray = g_array_sized_new (FALSE, FALSE, sizeof (guint), 2);
941 [ + + ]: 3 : for (i = 1; i < 3; i++)
942 : 2 : g_array_append_val (garray, i);
943 : :
944 [ + + ]: 3 : for (i = 1; i < 3; i++)
945 : 2 : g_assert_true (g_array_binary_search (garray, &i, cmpint, NULL));
946 : :
947 : 1 : i = 0;
948 : 1 : g_assert_false (g_array_binary_search (garray, &i, cmpint, NULL));
949 : :
950 : 1 : i = 4;
951 : 1 : g_assert_false (g_array_binary_search (garray, &i, cmpint, NULL));
952 : :
953 : 1 : g_array_free (garray, TRUE);
954 : :
955 : : /* Testing array of size 3 */
956 : 1 : garray = g_array_sized_new (FALSE, FALSE, sizeof (guint), 3);
957 [ + + ]: 4 : for (i = 1; i < 4; i++)
958 : 3 : g_array_append_val (garray, i);
959 : :
960 [ + + ]: 4 : for (i = 1; i < 4; i++)
961 : 3 : g_assert_true (g_array_binary_search (garray, &i, cmpint, NULL));
962 : :
963 : 1 : i = 0;
964 : 1 : g_assert_false (g_array_binary_search (garray, &i, cmpint, NULL));
965 : :
966 : 1 : i = 5;
967 : 1 : g_assert_false (g_array_binary_search (garray, &i, cmpint, NULL));
968 : :
969 : 1 : g_array_free (garray, TRUE);
970 : :
971 : : /* Testing array of size 10000 */
972 : 1 : garray = g_array_sized_new (FALSE, FALSE, sizeof (guint), 10000);
973 : :
974 [ + + ]: 10001 : for (i = 1; i < 10001; i++)
975 : 10000 : g_array_append_val (garray, i);
976 : :
977 [ + + ]: 10001 : for (i = 1; i < 10001; i++)
978 : 10000 : g_assert_true (g_array_binary_search (garray, &i, cmpint, NULL));
979 : :
980 [ + + ]: 10001 : for (i = 1; i < 10001; i++)
981 : : {
982 : 10000 : g_assert_true (g_array_binary_search (garray, &i, cmpint, &matched_index));
983 : 10000 : g_assert_cmpint (i, ==, matched_index + 1);
984 : : }
985 : :
986 : : /* Testing negative result */
987 : 1 : i = 0;
988 : 1 : g_assert_false (g_array_binary_search (garray, &i, cmpint, NULL));
989 : 1 : g_assert_false (g_array_binary_search (garray, &i, cmpint, &matched_index));
990 : :
991 : 1 : i = 10002;
992 : 1 : g_assert_false (g_array_binary_search (garray, &i, cmpint, NULL));
993 : 1 : g_assert_false (g_array_binary_search (garray, &i, cmpint, &matched_index));
994 : :
995 : 1 : g_array_free (garray, TRUE);
996 : :
997 : : /* Test for a not-found element in the middle of the array. */
998 : 1 : garray = g_array_sized_new (FALSE, FALSE, sizeof (guint), 3);
999 [ + + ]: 6 : for (i = 1; i < 10; i += 2)
1000 : 5 : g_array_append_val (garray, i);
1001 : :
1002 : 1 : i = 0;
1003 : 1 : g_assert_false (g_array_binary_search (garray, &i, cmpint, NULL));
1004 : :
1005 : 1 : i = 2;
1006 : 1 : g_assert_false (g_array_binary_search (garray, &i, cmpint, NULL));
1007 : :
1008 : 1 : i = 10;
1009 : 1 : g_assert_false (g_array_binary_search (garray, &i, cmpint, NULL));
1010 : :
1011 : 1 : g_array_free (garray, TRUE);
1012 : 1 : }
1013 : :
1014 : : static void
1015 : 1 : test_array_copy_sized (void)
1016 : : {
1017 : 1 : GArray *array1 = NULL, *array2 = NULL, *array3 = NULL;
1018 : 1 : int val = 5;
1019 : :
1020 : 1 : g_test_summary ("Test that copying a newly-allocated sized array works.");
1021 : :
1022 : 1 : array1 = g_array_sized_new (FALSE, FALSE, sizeof (int), 1);
1023 : 1 : array2 = g_array_copy (array1);
1024 : :
1025 : 1 : g_assert_cmpuint (array2->len, ==, array1->len);
1026 : :
1027 : 1 : g_array_append_val (array1, val);
1028 : 1 : array3 = g_array_copy (array1);
1029 : :
1030 : 1 : g_assert_cmpuint (array3->len, ==, array1->len);
1031 : 1 : g_assert_cmpuint (g_array_index (array3, int, 0), ==, g_array_index (array1, int, 0));
1032 : 1 : g_assert_cmpuint (array3->len, ==, 1);
1033 : 1 : g_assert_cmpuint (g_array_index (array3, int, 0), ==, val);
1034 : :
1035 : 1 : g_array_unref (array3);
1036 : 1 : g_array_unref (array2);
1037 : 1 : g_array_unref (array1);
1038 : 1 : }
1039 : :
1040 : : static void
1041 : 1 : array_overflow_append_vals (void)
1042 : : {
1043 [ - + ]: 1 : if (!g_test_undefined ())
1044 : 0 : return;
1045 : :
1046 [ - + ]: 1 : if (g_test_subprocess ())
1047 : : {
1048 : 0 : GArray *array = g_array_new (TRUE, FALSE, 1);
1049 : : /* Check for overflow should happen before data is accessed. */
1050 : 0 : g_array_append_vals (array, NULL, G_MAXUINT);
1051 : : }
1052 : : else
1053 : : {
1054 : 1 : g_test_trap_subprocess (NULL, 0, G_TEST_SUBPROCESS_DEFAULT);
1055 : 1 : g_test_trap_assert_failed ();
1056 : 1 : g_test_trap_assert_stderr ("*adding 4294967295 to array would overflow*");
1057 : : }
1058 : : }
1059 : :
1060 : : static void
1061 : 1 : array_overflow_set_size (void)
1062 : : {
1063 [ - + ]: 1 : if (!g_test_undefined ())
1064 : 0 : return;
1065 : :
1066 [ - + ]: 1 : if (g_test_subprocess ())
1067 : : {
1068 : 0 : GArray *array = g_array_new (TRUE, FALSE, 1);
1069 : 0 : g_array_set_size (array, G_MAXUINT);
1070 : : }
1071 : : else
1072 : : {
1073 : 1 : g_test_trap_subprocess (NULL, 0, G_TEST_SUBPROCESS_DEFAULT);
1074 : 1 : g_test_trap_assert_failed ();
1075 : 1 : g_test_trap_assert_stderr ("*adding 4294967295 to array would overflow*");
1076 : : }
1077 : : }
1078 : :
1079 : : static void
1080 : 20075 : assert_ptr_array_null_terminated (GPtrArray *array, gboolean null_terminated)
1081 : : {
1082 : 20075 : g_assert_cmpint (null_terminated, ==, g_ptr_array_is_null_terminated (array));
1083 [ + + ]: 20075 : if (array->pdata)
1084 : : {
1085 [ + + ]: 20055 : if (null_terminated)
1086 : 10039 : g_assert_null (array->pdata[array->len]);
1087 : : }
1088 : : else
1089 : 20 : g_assert_cmpint (array->len, ==, 0);
1090 : 20075 : }
1091 : :
1092 : : /* Check g_ptr_array_steal() function */
1093 : : static void
1094 : 1 : pointer_array_steal (void)
1095 : : {
1096 : 1 : const guint array_size = 10000;
1097 : : GPtrArray *gparray;
1098 : : gpointer *pdata;
1099 : : guint i;
1100 : : gsize len, past_len;
1101 : :
1102 : 1 : gparray = g_ptr_array_new ();
1103 : 1 : pdata = g_ptr_array_steal (gparray, NULL);
1104 : 1 : g_assert_null (pdata);
1105 : :
1106 : 1 : pdata = g_ptr_array_steal (gparray, &len);
1107 : 1 : g_assert_null (pdata);
1108 : 1 : g_assert_cmpint (len, ==, 0);
1109 : :
1110 [ + + ]: 10001 : for (i = 0; i < array_size; i++)
1111 : 10000 : g_ptr_array_add (gparray, GINT_TO_POINTER (i));
1112 : :
1113 : 1 : past_len = gparray->len;
1114 : 1 : pdata = g_ptr_array_steal (gparray, &len);
1115 : 1 : g_assert_cmpint (gparray->len, ==, 0);
1116 : 1 : g_assert_cmpint (past_len, ==, len);
1117 : 1 : g_ptr_array_add (gparray, GINT_TO_POINTER (10));
1118 : :
1119 : 1 : g_assert_cmpint ((gsize) pdata[0], ==, (gsize) GINT_TO_POINTER (0));
1120 : 1 : g_assert_cmpint ((gsize) g_ptr_array_index (gparray, 0), ==,
1121 : : (gsize) GINT_TO_POINTER (10));
1122 : 1 : g_assert_cmpint (gparray->len, ==, 1);
1123 : :
1124 : 1 : g_ptr_array_remove_index (gparray, 0);
1125 : :
1126 [ + + ]: 10001 : for (i = 0; i < array_size; i++)
1127 : 10000 : g_ptr_array_add (gparray, GINT_TO_POINTER (i));
1128 : 1 : g_assert_cmpmem (pdata, array_size * sizeof (gpointer),
1129 : : gparray->pdata, array_size * sizeof (gpointer));
1130 : 1 : g_free (pdata);
1131 : :
1132 : 1 : g_ptr_array_free (gparray, TRUE);
1133 : :
1134 : 1 : gparray = g_ptr_array_new_null_terminated (0, NULL, TRUE);
1135 : 1 : pdata = g_ptr_array_steal (gparray, NULL);
1136 : 1 : g_assert_null (pdata);
1137 : 1 : g_ptr_array_unref (gparray);
1138 : 1 : }
1139 : :
1140 : : static void
1141 : 1 : pointer_array_free_null_terminated (void)
1142 : : {
1143 : 1 : GPtrArray *parray = NULL;
1144 : : gpointer *segment;
1145 : :
1146 : 1 : g_test_summary ("Check that g_ptr_array_free() on an empty array returns a NULL-terminated empty array");
1147 : :
1148 : 1 : parray = g_ptr_array_new_null_terminated (0, NULL, TRUE);
1149 : 1 : g_assert_nonnull (parray);
1150 : 1 : assert_ptr_array_null_terminated (parray, TRUE);
1151 : :
1152 : 1 : segment = g_ptr_array_free (parray, FALSE);
1153 : 1 : g_assert_nonnull (segment);
1154 : 1 : g_assert_null (segment[0]);
1155 : :
1156 : 1 : g_free (segment);
1157 : 1 : }
1158 : :
1159 : : static void
1160 : 1 : pointer_array_add (void)
1161 : : {
1162 : : GPtrArray *gparray;
1163 : : gint i;
1164 : 1 : gint sum = 0;
1165 : : gpointer *segment;
1166 : :
1167 : 1 : gparray = g_ptr_array_sized_new (1000);
1168 : :
1169 [ + + ]: 10001 : for (i = 0; i < 10000; i++)
1170 : 10000 : g_ptr_array_add (gparray, GINT_TO_POINTER (i));
1171 : :
1172 [ + + ]: 10001 : for (i = 0; i < 10000; i++)
1173 : 10000 : g_assert (g_ptr_array_index (gparray, i) == GINT_TO_POINTER (i));
1174 : :
1175 : 1 : g_ptr_array_foreach (gparray, sum_up, &sum);
1176 : 1 : g_assert (sum == 49995000);
1177 : :
1178 : 1 : segment = g_ptr_array_free (gparray, FALSE);
1179 [ + + ]: 10001 : for (i = 0; i < 10000; i++)
1180 : 10000 : g_assert (segment[i] == GINT_TO_POINTER (i));
1181 : 1 : g_free (segment);
1182 : 1 : }
1183 : :
1184 : : static void
1185 : 1 : pointer_array_insert (void)
1186 : : {
1187 : : GPtrArray *gparray;
1188 : : gint i;
1189 : 1 : gint sum = 0;
1190 : : gint index;
1191 : :
1192 : 1 : gparray = g_ptr_array_sized_new (1000);
1193 : :
1194 [ + + ]: 10001 : for (i = 0; i < 10000; i++)
1195 : : {
1196 : 10000 : index = g_random_int_range (-1, i + 1);
1197 : 10000 : g_ptr_array_insert (gparray, index, GINT_TO_POINTER (i));
1198 : : }
1199 : :
1200 : 1 : g_ptr_array_foreach (gparray, sum_up, &sum);
1201 : 1 : g_assert (sum == 49995000);
1202 : :
1203 : 1 : g_ptr_array_free (gparray, TRUE);
1204 : 1 : }
1205 : :
1206 : : static void
1207 : 1 : pointer_array_new_take (void)
1208 : : {
1209 : 1 : const size_t array_size = 10000;
1210 : : GPtrArray *gparray;
1211 : : gpointer *pdata;
1212 : : gpointer *old_pdata_copy;
1213 : : gsize len;
1214 : :
1215 : 1 : gparray = g_ptr_array_new ();
1216 [ + + ]: 10001 : for (size_t i = 0; i < array_size; i++)
1217 : 10000 : g_ptr_array_add (gparray, GUINT_TO_POINTER (i));
1218 : :
1219 : 1 : pdata = g_ptr_array_steal (gparray, &len);
1220 : 1 : g_assert_cmpuint (array_size, ==, len);
1221 : 1 : g_assert_nonnull (pdata);
1222 : 1 : g_clear_pointer (&gparray, g_ptr_array_unref);
1223 : :
1224 : 1 : old_pdata_copy = g_memdup2 (pdata, len * sizeof (gpointer));
1225 : 1 : gparray = g_ptr_array_new_take (g_steal_pointer (&pdata), len, NULL);
1226 : 1 : g_assert_false (g_ptr_array_is_null_terminated (gparray));
1227 : 1 : g_assert_cmpuint (gparray->len, ==, array_size);
1228 : :
1229 : 1 : g_assert_cmpuint (GPOINTER_TO_UINT (g_ptr_array_index (gparray, 0)), ==, 0);
1230 : 1 : g_assert_cmpuint (GPOINTER_TO_UINT (g_ptr_array_index (gparray, 10)), ==, 10);
1231 : :
1232 : 1 : g_assert_cmpmem (old_pdata_copy, array_size * sizeof (gpointer),
1233 : : gparray->pdata, array_size * sizeof (gpointer));
1234 : :
1235 : 1 : g_ptr_array_add (gparray, GUINT_TO_POINTER (55));
1236 : 1 : g_ptr_array_insert (gparray, 0, GUINT_TO_POINTER (33));
1237 : :
1238 : 1 : g_assert_cmpuint (gparray->len, ==, array_size + 2);
1239 : 1 : g_assert_cmpuint (GPOINTER_TO_UINT (g_ptr_array_index (gparray, 0)), ==, 33);
1240 : 1 : g_assert_cmpuint (
1241 : : GPOINTER_TO_UINT (g_ptr_array_index (gparray, gparray->len - 1)), ==, 55);
1242 : :
1243 : 1 : g_ptr_array_remove_index (gparray, 0);
1244 : 1 : g_assert_cmpuint (gparray->len, ==, array_size + 1);
1245 : 1 : g_ptr_array_remove_index (gparray, gparray->len - 1);
1246 : 1 : g_assert_cmpuint (gparray->len, ==, array_size);
1247 : :
1248 : 1 : g_assert_cmpmem (old_pdata_copy, array_size * sizeof (gpointer),
1249 : : gparray->pdata, array_size * sizeof (gpointer));
1250 : :
1251 : 1 : g_ptr_array_unref (gparray);
1252 : 1 : g_free (old_pdata_copy);
1253 : 1 : }
1254 : :
1255 : : static void
1256 : 1 : pointer_array_new_take_empty (void)
1257 : : {
1258 : : GPtrArray *gparray;
1259 : 1 : gpointer empty_array[] = {0};
1260 : :
1261 : 1 : gparray = g_ptr_array_new_take (
1262 : 1 : g_memdup2 (&empty_array, sizeof (gpointer)), 0, NULL);
1263 : 1 : g_assert_false (g_ptr_array_is_null_terminated (gparray));
1264 : 1 : g_assert_cmpuint (gparray->len, ==, 0);
1265 : :
1266 : 1 : g_clear_pointer (&gparray, g_ptr_array_unref);
1267 : :
1268 : 1 : gparray = g_ptr_array_new_take (NULL, 0, NULL);
1269 : 1 : g_assert_false (g_ptr_array_is_null_terminated (gparray));
1270 : 1 : g_assert_cmpuint (gparray->len, ==, 0);
1271 : :
1272 : 1 : g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL,
1273 : : "*data*!=*NULL*||*len*==*0*");
1274 : 1 : g_assert_null (g_ptr_array_new_take (NULL, 10, NULL));
1275 : 1 : g_test_assert_expected_messages ();
1276 : :
1277 : 1 : g_clear_pointer (&gparray, g_ptr_array_unref);
1278 : 1 : }
1279 : :
1280 : : static void
1281 : 1 : pointer_array_new_take_overflow (void)
1282 : : {
1283 : : #if SIZE_WIDTH <= UINT_WIDTH
1284 : 1 : g_test_skip ("Overflow test requires UINT_WIDTH > SIZE_WIDTH.");
1285 : : #else
1286 : : if (!g_test_undefined ())
1287 : : return;
1288 : :
1289 : : /* Check for overflow should happen before data is accessed. */
1290 : : g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL,
1291 : : "*assertion 'len <= G_MAXUINT' failed");
1292 : : g_assert_null (g_ptr_array_new_take (
1293 : : (gpointer []) { NULL }, (gsize) G_MAXUINT + 1, NULL));
1294 : : g_test_assert_expected_messages ();
1295 : : #endif
1296 : 1 : }
1297 : :
1298 : : static void
1299 : 1 : pointer_array_new_take_with_free_func (void)
1300 : : {
1301 : 1 : const size_t array_size = 10000;
1302 : : GPtrArray *gparray;
1303 : : gpointer *pdata;
1304 : : gpointer *old_pdata_copy;
1305 : : gsize len;
1306 : :
1307 : 1 : gparray = g_ptr_array_new_with_free_func (g_free);
1308 [ + + ]: 10001 : for (size_t i = 0; i < array_size; i++)
1309 : 10000 : g_ptr_array_add (gparray, g_strdup_printf ("%" G_GSIZE_FORMAT, i));
1310 : :
1311 : 1 : pdata = g_ptr_array_steal (gparray, &len);
1312 : 1 : g_assert_cmpuint (array_size, ==, len);
1313 : 1 : g_assert_nonnull (pdata);
1314 : 1 : g_clear_pointer (&gparray, g_ptr_array_unref);
1315 : :
1316 : 1 : old_pdata_copy = g_memdup2 (pdata, len * sizeof (gpointer));
1317 : 1 : gparray = g_ptr_array_new_take (g_steal_pointer (&pdata), len, g_free);
1318 : 1 : g_assert_false (g_ptr_array_is_null_terminated (gparray));
1319 : 1 : g_assert_cmpuint (gparray->len, ==, array_size);
1320 : :
1321 : 1 : g_assert_cmpstr ((const char *) g_ptr_array_index (gparray, 0), ==, "0");
1322 : 1 : g_assert_cmpstr ((const char *) g_ptr_array_index (gparray, 101), ==, "101");
1323 : :
1324 : 1 : g_assert_cmpmem (old_pdata_copy, array_size * sizeof (gpointer),
1325 : : gparray->pdata, array_size * sizeof (gpointer));
1326 : :
1327 : 1 : g_ptr_array_add (gparray, g_strdup_printf ("%d", 55));
1328 : 1 : g_ptr_array_insert (gparray, 0, g_strdup_printf ("%d", 33));
1329 : :
1330 : 1 : g_assert_cmpuint (gparray->len, ==, array_size + 2);
1331 : 1 : g_assert_cmpstr ((const char *) g_ptr_array_index (gparray, 0), ==, "33");
1332 : 1 : g_assert_cmpstr (
1333 : : (const char *) g_ptr_array_index (gparray, gparray->len - 1), ==, "55");
1334 : :
1335 : 1 : g_ptr_array_remove_index (gparray, 0);
1336 : 1 : g_assert_cmpuint (gparray->len, ==, array_size + 1);
1337 : 1 : g_ptr_array_remove_index (gparray, gparray->len - 1);
1338 : 1 : g_assert_cmpuint (gparray->len, ==, array_size);
1339 : :
1340 : 1 : g_assert_cmpmem (old_pdata_copy, array_size * sizeof (gpointer),
1341 : : gparray->pdata, array_size * sizeof (gpointer));
1342 : :
1343 : 1 : g_ptr_array_unref (gparray);
1344 : 1 : g_free (old_pdata_copy);
1345 : 1 : }
1346 : :
1347 : : static void
1348 : 1 : pointer_array_new_take_null_terminated (void)
1349 : : {
1350 : 1 : const size_t array_size = 10000;
1351 : : GPtrArray *gparray;
1352 : : gpointer *pdata;
1353 : : gpointer *old_pdata_copy;
1354 : : gsize len;
1355 : :
1356 : 1 : gparray = g_ptr_array_new_null_terminated (array_size, NULL, TRUE);
1357 : 1 : g_assert_true (g_ptr_array_is_null_terminated (gparray));
1358 : :
1359 [ + + ]: 10001 : for (size_t i = 0; i < array_size; i++)
1360 : 10000 : g_ptr_array_add (gparray, GUINT_TO_POINTER (i + 1));
1361 : :
1362 : 1 : assert_ptr_array_null_terminated (gparray, TRUE);
1363 : 1 : pdata = g_ptr_array_steal (gparray, &len);
1364 : 1 : g_assert_cmpuint (array_size, ==, len);
1365 : 1 : g_assert_nonnull (pdata);
1366 : 1 : g_clear_pointer (&gparray, g_ptr_array_unref);
1367 : :
1368 : 1 : old_pdata_copy = g_memdup2 (pdata, len * sizeof (gpointer));
1369 : 1 : gparray = g_ptr_array_new_take_null_terminated (g_steal_pointer (&pdata), NULL);
1370 : 1 : g_assert_true (g_ptr_array_is_null_terminated (gparray));
1371 : 1 : assert_ptr_array_null_terminated (gparray, TRUE);
1372 : 1 : g_assert_cmpuint (gparray->len, ==, array_size);
1373 : :
1374 : 1 : g_assert_cmpuint (GPOINTER_TO_UINT (g_ptr_array_index (gparray, 0)), ==, 1);
1375 : 1 : g_assert_cmpuint (GPOINTER_TO_UINT (g_ptr_array_index (gparray, 10)), ==, 11);
1376 : :
1377 : 1 : g_assert_cmpmem (old_pdata_copy, array_size * sizeof (gpointer),
1378 : : gparray->pdata, array_size * sizeof (gpointer));
1379 : :
1380 : 1 : g_ptr_array_add (gparray, GUINT_TO_POINTER (55));
1381 : 1 : assert_ptr_array_null_terminated (gparray, TRUE);
1382 : :
1383 : 1 : g_ptr_array_insert (gparray, 0, GUINT_TO_POINTER (33));
1384 : 1 : assert_ptr_array_null_terminated (gparray, TRUE);
1385 : :
1386 : 1 : g_assert_cmpuint (gparray->len, ==, array_size + 2);
1387 : 1 : g_assert_cmpuint (GPOINTER_TO_UINT (g_ptr_array_index (gparray, 0)), ==, 33);
1388 : 1 : g_assert_cmpuint (
1389 : : GPOINTER_TO_UINT (g_ptr_array_index (gparray, gparray->len - 1)), ==, 55);
1390 : :
1391 : 1 : g_ptr_array_remove_index (gparray, 0);
1392 : 1 : g_assert_cmpuint (gparray->len, ==, array_size + 1);
1393 : 1 : assert_ptr_array_null_terminated (gparray, TRUE);
1394 : :
1395 : 1 : g_ptr_array_remove_index (gparray, gparray->len - 1);
1396 : 1 : g_assert_cmpuint (gparray->len, ==, array_size);
1397 : 1 : assert_ptr_array_null_terminated (gparray, TRUE);
1398 : :
1399 : 1 : g_assert_cmpmem (old_pdata_copy, array_size * sizeof (gpointer),
1400 : : gparray->pdata, array_size * sizeof (gpointer));
1401 : :
1402 : 1 : g_ptr_array_unref (gparray);
1403 : 1 : g_free (old_pdata_copy);
1404 : 1 : }
1405 : :
1406 : : static void
1407 : 1 : pointer_array_new_take_null_terminated_empty (void)
1408 : : {
1409 : : GPtrArray *gparray;
1410 : 1 : const gpointer *data = (gpointer []) { NULL };
1411 : :
1412 : 1 : gparray = g_ptr_array_new_take_null_terminated (
1413 : 1 : g_memdup2 (data, sizeof (gpointer)), NULL);
1414 : 1 : g_assert_true (g_ptr_array_is_null_terminated (gparray));
1415 : 1 : assert_ptr_array_null_terminated (gparray, TRUE);
1416 : 1 : g_assert_cmpuint (gparray->len, ==, 0);
1417 : :
1418 : 1 : g_clear_pointer (&gparray, g_ptr_array_unref);
1419 : :
1420 : 1 : gparray = g_ptr_array_new_take_null_terminated (NULL, NULL);
1421 : 1 : g_assert_true (g_ptr_array_is_null_terminated (gparray));
1422 : 1 : assert_ptr_array_null_terminated (gparray, TRUE);
1423 : 1 : g_assert_cmpuint (gparray->len, ==, 0);
1424 : :
1425 : 1 : g_clear_pointer (&gparray, g_ptr_array_unref);
1426 : 1 : }
1427 : :
1428 : : static void
1429 : 1 : pointer_array_new_take_null_terminated_with_free_func (void)
1430 : : {
1431 : 1 : const size_t array_size = 10000;
1432 : : GPtrArray *gparray;
1433 : : gpointer *pdata;
1434 : : gpointer *old_pdata_copy;
1435 : : gsize len;
1436 : :
1437 : 1 : gparray = g_ptr_array_new_null_terminated (array_size, g_free, TRUE);
1438 : 1 : g_assert_true (g_ptr_array_is_null_terminated (gparray));
1439 : :
1440 [ + + ]: 10001 : for (size_t i = 0; i < array_size; i++)
1441 : 10000 : g_ptr_array_add (gparray, g_strdup_printf ("%" G_GSIZE_FORMAT, i));
1442 : :
1443 : 1 : assert_ptr_array_null_terminated (gparray, TRUE);
1444 : :
1445 : 1 : pdata = g_ptr_array_steal (gparray, &len);
1446 : 1 : g_assert_cmpuint (array_size, ==, len);
1447 : 1 : g_assert_nonnull (pdata);
1448 : 1 : g_clear_pointer (&gparray, g_ptr_array_unref);
1449 : :
1450 : 1 : old_pdata_copy = g_memdup2 (pdata, len * sizeof (gpointer));
1451 : 1 : gparray = g_ptr_array_new_take_null_terminated (g_steal_pointer (&pdata), g_free);
1452 : 1 : g_assert_true (g_ptr_array_is_null_terminated (gparray));
1453 : 1 : assert_ptr_array_null_terminated (gparray, TRUE);
1454 : 1 : g_assert_cmpuint (gparray->len, ==, array_size);
1455 : :
1456 : 1 : g_assert_cmpstr ((const char *) g_ptr_array_index (gparray, 0), ==, "0");
1457 : 1 : g_assert_cmpstr ((const char *) g_ptr_array_index (gparray, 101), ==, "101");
1458 : :
1459 : 1 : g_assert_cmpmem (old_pdata_copy, array_size * sizeof (gpointer),
1460 : : gparray->pdata, array_size * sizeof (gpointer));
1461 : :
1462 : 1 : g_ptr_array_add (gparray, g_strdup_printf ("%d", 55));
1463 : 1 : assert_ptr_array_null_terminated (gparray, TRUE);
1464 : :
1465 : 1 : g_ptr_array_insert (gparray, 0, g_strdup_printf ("%d", 33));
1466 : 1 : assert_ptr_array_null_terminated (gparray, TRUE);
1467 : :
1468 : 1 : g_assert_cmpuint (gparray->len, ==, array_size + 2);
1469 : 1 : g_assert_cmpstr ((const char *) g_ptr_array_index (gparray, 0), ==, "33");
1470 : 1 : g_assert_cmpstr (
1471 : : (const char *) g_ptr_array_index (gparray, gparray->len - 1), ==, "55");
1472 : :
1473 : 1 : g_ptr_array_remove_index (gparray, 0);
1474 : 1 : g_assert_cmpuint (gparray->len, ==, array_size + 1);
1475 : 1 : assert_ptr_array_null_terminated (gparray, TRUE);
1476 : :
1477 : 1 : g_ptr_array_remove_index (gparray, gparray->len - 1);
1478 : 1 : g_assert_cmpuint (gparray->len, ==, array_size);
1479 : 1 : assert_ptr_array_null_terminated (gparray, TRUE);
1480 : :
1481 : 1 : g_assert_cmpmem (old_pdata_copy, array_size * sizeof (gpointer),
1482 : : gparray->pdata, array_size * sizeof (gpointer));
1483 : :
1484 : 1 : g_ptr_array_unref (gparray);
1485 : 1 : g_free (old_pdata_copy);
1486 : 1 : }
1487 : :
1488 : : static void
1489 : 1 : pointer_array_new_take_null_terminated_from_gstrv (void)
1490 : : {
1491 : : GPtrArray *gparray;
1492 : : char *joined;
1493 : :
1494 : 1 : gparray = g_ptr_array_new_take_null_terminated (
1495 : 1 : (gpointer) g_strsplit ("A.dot.separated.string", ".", -1), g_free);
1496 : :
1497 : 1 : g_assert_cmpstr (
1498 : : (const char *) g_ptr_array_index (gparray, 0), ==, "A");
1499 : 1 : g_assert_cmpstr (
1500 : : (const char *) g_ptr_array_index (gparray, 1), ==, "dot");
1501 : 1 : g_assert_cmpstr (
1502 : : (const char *) g_ptr_array_index (gparray, 2), ==, "separated");
1503 : 1 : g_assert_cmpstr (
1504 : : (const char *) g_ptr_array_index (gparray, 3), ==, "string");
1505 : :
1506 : 1 : g_assert_null (g_ptr_array_index (gparray, 4));
1507 : :
1508 : 1 : joined = g_strjoinv (".", (char **) gparray->pdata);
1509 : 1 : g_assert_cmpstr (joined, ==, "A.dot.separated.string");
1510 : :
1511 : 1 : g_ptr_array_unref (gparray);
1512 : 1 : g_free (joined);
1513 : 1 : }
1514 : :
1515 : : static void
1516 : 1 : pointer_array_new_from_array (void)
1517 : : {
1518 : 1 : const size_t array_size = 10000;
1519 : : GPtrArray *source_array;
1520 : : GPtrArray *gparray;
1521 : : gpointer *old_pdata_copy;
1522 : :
1523 : 1 : source_array = g_ptr_array_new ();
1524 [ + + ]: 10001 : for (size_t i = 0; i < array_size; i++)
1525 : 10000 : g_ptr_array_add (source_array, GUINT_TO_POINTER (i));
1526 : :
1527 : 1 : g_assert_cmpuint (array_size, ==, source_array->len);
1528 : 1 : g_assert_nonnull (source_array->pdata);
1529 : :
1530 : 1 : gparray = g_ptr_array_new_from_array (source_array->pdata, source_array->len,
1531 : : NULL, NULL, NULL);
1532 : :
1533 : : old_pdata_copy =
1534 : 1 : g_memdup2 (source_array->pdata, source_array->len * sizeof (gpointer));
1535 : 1 : g_assert_nonnull (old_pdata_copy);
1536 : 1 : g_clear_pointer (&source_array, g_ptr_array_unref);
1537 : :
1538 : 1 : g_assert_false (g_ptr_array_is_null_terminated (gparray));
1539 : 1 : g_assert_cmpuint (gparray->len, ==, array_size);
1540 : :
1541 : 1 : g_assert_cmpuint (GPOINTER_TO_UINT (g_ptr_array_index (gparray, 0)), ==, 0);
1542 : 1 : g_assert_cmpuint (GPOINTER_TO_UINT (g_ptr_array_index (gparray, 10)), ==, 10);
1543 : :
1544 : 1 : g_assert_cmpmem (old_pdata_copy, array_size * sizeof (gpointer),
1545 : : gparray->pdata, array_size * sizeof (gpointer));
1546 : :
1547 : 1 : g_ptr_array_add (gparray, GUINT_TO_POINTER (55));
1548 : 1 : g_ptr_array_insert (gparray, 0, GUINT_TO_POINTER (33));
1549 : :
1550 : 1 : g_assert_cmpuint (gparray->len, ==, array_size + 2);
1551 : 1 : g_assert_cmpuint (GPOINTER_TO_UINT (g_ptr_array_index (gparray, 0)), ==, 33);
1552 : 1 : g_assert_cmpuint (
1553 : : GPOINTER_TO_UINT (g_ptr_array_index (gparray, gparray->len - 1)), ==, 55);
1554 : :
1555 : 1 : g_ptr_array_remove_index (gparray, 0);
1556 : 1 : g_assert_cmpuint (gparray->len, ==, array_size + 1);
1557 : 1 : g_ptr_array_remove_index (gparray, gparray->len - 1);
1558 : 1 : g_assert_cmpuint (gparray->len, ==, array_size);
1559 : :
1560 : 1 : g_assert_cmpmem (old_pdata_copy, array_size * sizeof (gpointer),
1561 : : gparray->pdata, array_size * sizeof (gpointer));
1562 : :
1563 : 1 : g_ptr_array_unref (gparray);
1564 : 1 : g_free (old_pdata_copy);
1565 : 1 : }
1566 : :
1567 : : static void
1568 : 1 : pointer_array_new_from_array_empty (void)
1569 : : {
1570 : : GPtrArray *gparray;
1571 : 1 : gpointer empty_array[] = {0};
1572 : :
1573 : 1 : gparray = g_ptr_array_new_from_array (empty_array, 0, NULL, NULL, NULL);
1574 : 1 : g_assert_false (g_ptr_array_is_null_terminated (gparray));
1575 : 1 : g_assert_cmpuint (gparray->len, ==, 0);
1576 : :
1577 : 1 : g_clear_pointer (&gparray, g_ptr_array_unref);
1578 : :
1579 : 1 : g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL,
1580 : : "*data*!=*NULL*||*len*==*0*");
1581 : 1 : g_assert_null (g_ptr_array_new_from_array (NULL, 10, NULL, NULL, NULL));
1582 : 1 : g_test_assert_expected_messages ();
1583 : 1 : }
1584 : :
1585 : : static void
1586 : 1 : pointer_array_new_from_array_overflow (void)
1587 : : {
1588 : : #if SIZE_WIDTH <= UINT_WIDTH
1589 : 1 : g_test_skip ("Overflow test requires UINT_WIDTH > SIZE_WIDTH.");
1590 : : #else
1591 : : if (!g_test_undefined ())
1592 : : return;
1593 : :
1594 : : /* Check for overflow should happen before data is accessed. */
1595 : : g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL,
1596 : : "*assertion 'len <= G_MAXUINT' failed");
1597 : : g_assert_null (g_ptr_array_new_from_array (
1598 : : (gpointer []) { NULL }, (gsize) G_MAXUINT + 1, NULL, NULL, NULL));
1599 : : g_test_assert_expected_messages ();
1600 : : #endif
1601 : 1 : }
1602 : :
1603 : : static void
1604 : 1 : pointer_array_new_from_array_with_copy_and_free_func (void)
1605 : : {
1606 : 1 : const size_t array_size = 10000;
1607 : : GPtrArray *source_array;
1608 : : GPtrArray *gparray;
1609 : : gpointer *old_pdata_copy;
1610 : :
1611 : 1 : source_array = g_ptr_array_new_with_free_func (g_free);
1612 [ + + ]: 10001 : for (size_t i = 0; i < array_size; i++)
1613 : 10000 : g_ptr_array_add (source_array, g_strdup_printf ("%" G_GSIZE_FORMAT, i));
1614 : :
1615 : 1 : g_assert_cmpuint (array_size, ==, source_array->len);
1616 : 1 : g_assert_nonnull (source_array->pdata);
1617 : :
1618 : 1 : gparray = g_ptr_array_new_from_array (source_array->pdata, source_array->len,
1619 : : (GCopyFunc) g_strdup, NULL, g_free);
1620 : :
1621 : : old_pdata_copy =
1622 : 1 : g_memdup2 (source_array->pdata, source_array->len * sizeof (gpointer));
1623 : 1 : g_assert_nonnull (old_pdata_copy);
1624 : :
1625 [ + + ]: 10001 : for (size_t i = 0; i < gparray->len; i++)
1626 : : {
1627 : 10000 : g_assert_cmpstr ((const char *) g_ptr_array_index (gparray, i), ==,
1628 : : (const char *) old_pdata_copy[i]);
1629 : : }
1630 : :
1631 : 1 : g_clear_pointer (&source_array, g_ptr_array_unref);
1632 : :
1633 : 1 : g_assert_cmpstr ((const char *) g_ptr_array_index (gparray, 0), ==, "0");
1634 : 1 : g_assert_cmpstr ((const char *) g_ptr_array_index (gparray, 101), ==, "101");
1635 : :
1636 : 1 : g_ptr_array_add (gparray, g_strdup_printf ("%d", 55));
1637 : 1 : g_ptr_array_insert (gparray, 0, g_strdup_printf ("%d", 33));
1638 : :
1639 : 1 : g_assert_cmpuint (gparray->len, ==, array_size + 2);
1640 : 1 : g_assert_cmpstr ((const char *) g_ptr_array_index (gparray, 0), ==, "33");
1641 : 1 : g_assert_cmpstr (
1642 : : (const char *) g_ptr_array_index (gparray, gparray->len - 1), ==, "55");
1643 : :
1644 : 1 : g_ptr_array_remove_index (gparray, 0);
1645 : 1 : g_assert_cmpuint (gparray->len, ==, array_size + 1);
1646 : 1 : g_ptr_array_remove_index (gparray, gparray->len - 1);
1647 : 1 : g_assert_cmpuint (gparray->len, ==, array_size);
1648 : :
1649 : 1 : g_ptr_array_unref (gparray);
1650 : 1 : g_free (old_pdata_copy);
1651 : 1 : }
1652 : :
1653 : : static void
1654 : 1 : pointer_array_new_from_null_terminated_array (void)
1655 : : {
1656 : 1 : const size_t array_size = 10000;
1657 : : GPtrArray *source_array;
1658 : : GPtrArray *gparray;
1659 : : gpointer *old_pdata_copy;
1660 : :
1661 : 1 : source_array = g_ptr_array_new_null_terminated (array_size, NULL, TRUE);
1662 : 1 : g_assert_true (g_ptr_array_is_null_terminated (source_array));
1663 : :
1664 [ + + ]: 10001 : for (size_t i = 0; i < array_size; i++)
1665 : 10000 : g_ptr_array_add (source_array, GUINT_TO_POINTER (i + 1));
1666 : :
1667 : 1 : g_assert_cmpuint (array_size, ==, source_array->len);
1668 : 1 : g_assert_nonnull (source_array->pdata);
1669 : :
1670 : : old_pdata_copy =
1671 : 1 : g_memdup2 (source_array->pdata, source_array->len * sizeof (gpointer));
1672 : 1 : g_assert_nonnull (old_pdata_copy);
1673 : :
1674 : 1 : gparray = g_ptr_array_new_from_null_terminated_array (source_array->pdata,
1675 : : NULL, NULL, NULL);
1676 : 1 : g_assert_true (g_ptr_array_is_null_terminated (source_array));
1677 : 1 : assert_ptr_array_null_terminated (gparray, TRUE);
1678 : :
1679 : 1 : g_clear_pointer (&source_array, g_ptr_array_unref);
1680 : :
1681 : 1 : g_assert_true (g_ptr_array_is_null_terminated (gparray));
1682 : 1 : g_assert_cmpuint (gparray->len, ==, array_size);
1683 : :
1684 : 1 : g_assert_cmpuint (GPOINTER_TO_UINT (g_ptr_array_index (gparray, 0)), ==, 1);
1685 : 1 : g_assert_cmpuint (GPOINTER_TO_UINT (g_ptr_array_index (gparray, 10)), ==, 11);
1686 : :
1687 : 1 : g_assert_cmpmem (old_pdata_copy, array_size * sizeof (gpointer),
1688 : : gparray->pdata, array_size * sizeof (gpointer));
1689 : :
1690 : 1 : g_ptr_array_add (gparray, GUINT_TO_POINTER (55));
1691 : 1 : assert_ptr_array_null_terminated (gparray, TRUE);
1692 : :
1693 : 1 : g_ptr_array_insert (gparray, 0, GUINT_TO_POINTER (33));
1694 : 1 : assert_ptr_array_null_terminated (gparray, TRUE);
1695 : :
1696 : 1 : g_assert_cmpuint (gparray->len, ==, array_size + 2);
1697 : 1 : g_assert_cmpuint (GPOINTER_TO_UINT (g_ptr_array_index (gparray, 0)), ==, 33);
1698 : 1 : g_assert_cmpuint (
1699 : : GPOINTER_TO_UINT (g_ptr_array_index (gparray, gparray->len - 1)), ==, 55);
1700 : :
1701 : 1 : g_ptr_array_remove_index (gparray, 0);
1702 : 1 : g_assert_cmpuint (gparray->len, ==, array_size + 1);
1703 : 1 : assert_ptr_array_null_terminated (gparray, TRUE);
1704 : :
1705 : 1 : g_ptr_array_remove_index (gparray, gparray->len - 1);
1706 : 1 : g_assert_cmpuint (gparray->len, ==, array_size);
1707 : 1 : assert_ptr_array_null_terminated (gparray, TRUE);
1708 : :
1709 : 1 : g_assert_cmpmem (old_pdata_copy, array_size * sizeof (gpointer),
1710 : : gparray->pdata, array_size * sizeof (gpointer));
1711 : :
1712 : 1 : g_ptr_array_unref (gparray);
1713 : 1 : g_free (old_pdata_copy);
1714 : 1 : }
1715 : :
1716 : : static void
1717 : 1 : pointer_array_new_from_null_terminated_array_empty (void)
1718 : : {
1719 : : GPtrArray *gparray;
1720 : :
1721 : 2 : gparray = g_ptr_array_new_from_null_terminated_array (
1722 : 1 : (gpointer []) { NULL }, NULL, NULL, NULL);
1723 : 1 : g_assert_true (g_ptr_array_is_null_terminated (gparray));
1724 : 1 : assert_ptr_array_null_terminated (gparray, TRUE);
1725 : 1 : g_assert_cmpuint (gparray->len, ==, 0);
1726 : :
1727 : 1 : g_clear_pointer (&gparray, g_ptr_array_unref);
1728 : :
1729 : 1 : gparray = g_ptr_array_new_from_null_terminated_array (
1730 : : NULL, NULL, NULL, NULL);
1731 : 1 : g_assert_true (g_ptr_array_is_null_terminated (gparray));
1732 : 1 : assert_ptr_array_null_terminated (gparray, TRUE);
1733 : 1 : g_assert_cmpuint (gparray->len, ==, 0);
1734 : :
1735 : 1 : g_clear_pointer (&gparray, g_ptr_array_unref);
1736 : 1 : }
1737 : :
1738 : : static void
1739 : 1 : pointer_array_new_from_null_terminated_array_with_copy_and_free_func (void)
1740 : : {
1741 : 1 : const size_t array_size = 10000;
1742 : : GPtrArray *source_array;
1743 : : GPtrArray *gparray;
1744 : : GStrv old_pdata_copy;
1745 : :
1746 : 1 : source_array = g_ptr_array_new_null_terminated (array_size, g_free, TRUE);
1747 : 1 : g_assert_true (g_ptr_array_is_null_terminated (source_array));
1748 : :
1749 [ + + ]: 10001 : for (size_t i = 0; i < array_size; i++)
1750 : 10000 : g_ptr_array_add (source_array, g_strdup_printf ("%" G_GSIZE_FORMAT, i));
1751 : :
1752 : 1 : g_assert_cmpuint (array_size, ==, source_array->len);
1753 : 1 : g_assert_nonnull (source_array->pdata);
1754 : :
1755 : 1 : old_pdata_copy = g_strdupv ((char **) source_array->pdata);
1756 : 1 : g_assert_cmpuint (g_strv_length (old_pdata_copy), ==, array_size);
1757 : 1 : g_assert_nonnull (old_pdata_copy);
1758 : 1 : g_clear_pointer (&source_array, g_ptr_array_unref);
1759 : :
1760 : 1 : gparray = g_ptr_array_new_from_null_terminated_array (
1761 : : (gpointer* ) old_pdata_copy, (GCopyFunc) g_strdup, NULL, g_free);
1762 : 1 : g_assert_true (g_ptr_array_is_null_terminated (gparray));
1763 : 1 : assert_ptr_array_null_terminated (gparray, TRUE);
1764 : :
1765 [ + + ]: 10001 : for (size_t i = 0; i < gparray->len; i++)
1766 : : {
1767 : 10000 : g_assert_cmpstr ((const char *) g_ptr_array_index (gparray, i), ==,
1768 : : (const char *) old_pdata_copy[i]);
1769 : : }
1770 : :
1771 : 1 : g_assert_cmpstr ((const char *) g_ptr_array_index (gparray, 0), ==, "0");
1772 : 1 : g_assert_cmpstr ((const char *) g_ptr_array_index (gparray, 101), ==, "101");
1773 : :
1774 : 1 : g_ptr_array_add (gparray, g_strdup_printf ("%d", 55));
1775 : 1 : assert_ptr_array_null_terminated (gparray, TRUE);
1776 : :
1777 : 1 : g_ptr_array_insert (gparray, 0, g_strdup_printf ("%d", 33));
1778 : 1 : assert_ptr_array_null_terminated (gparray, TRUE);
1779 : :
1780 : 1 : g_assert_cmpuint (gparray->len, ==, array_size + 2);
1781 : 1 : g_assert_cmpstr ((const char *) g_ptr_array_index (gparray, 0), ==, "33");
1782 : 1 : g_assert_cmpstr (
1783 : : (const char *) g_ptr_array_index (gparray, gparray->len - 1), ==, "55");
1784 : :
1785 : 1 : g_ptr_array_remove_index (gparray, 0);
1786 : 1 : assert_ptr_array_null_terminated (gparray, TRUE);
1787 : 1 : g_assert_cmpuint (gparray->len, ==, array_size + 1);
1788 : :
1789 : 1 : g_ptr_array_remove_index (gparray, gparray->len - 1);
1790 : 1 : assert_ptr_array_null_terminated (gparray, TRUE);
1791 : 1 : g_assert_cmpuint (gparray->len, ==, array_size);
1792 : :
1793 [ + + ]: 10001 : for (size_t i = 0; i < gparray->len; i++)
1794 : : {
1795 : 10000 : g_assert_cmpstr ((const char *) g_ptr_array_index (gparray, i), ==,
1796 : : (const char *) old_pdata_copy[i]);
1797 : : }
1798 : :
1799 : 1 : g_ptr_array_unref (gparray);
1800 : 1 : g_strfreev (old_pdata_copy);
1801 : 1 : }
1802 : :
1803 : : static void
1804 : 1 : pointer_array_new_from_null_terminated_array_from_gstrv (void)
1805 : : {
1806 : : GPtrArray *gparray;
1807 : : GStrv strv;
1808 : : char *joined;
1809 : :
1810 : 1 : strv = g_strsplit ("A.dot.separated.string", ".", -1);
1811 : 1 : gparray = g_ptr_array_new_from_null_terminated_array (
1812 : : (gpointer) strv, NULL, NULL, NULL);
1813 : :
1814 : 1 : g_assert_cmpstr (
1815 : : (const char *) g_ptr_array_index (gparray, 0), ==, "A");
1816 : 1 : g_assert_true (g_ptr_array_index (gparray, 0) == strv[0]);
1817 : 1 : g_assert_cmpstr (
1818 : : (const char *) g_ptr_array_index (gparray, 1), ==, "dot");
1819 : 1 : g_assert_true (g_ptr_array_index (gparray, 1) == strv[1]);
1820 : 1 : g_assert_cmpstr (
1821 : : (const char *) g_ptr_array_index (gparray, 2), ==, "separated");
1822 : 1 : g_assert_true (g_ptr_array_index (gparray, 2) == strv[2]);
1823 : 1 : g_assert_cmpstr (
1824 : : (const char *) g_ptr_array_index (gparray, 3), ==, "string");
1825 : 1 : g_assert_true (g_ptr_array_index (gparray, 3) == strv[3]);
1826 : :
1827 : 1 : g_assert_null (strv[4]);
1828 : 1 : g_assert_null (g_ptr_array_index (gparray, 4));
1829 : :
1830 : 1 : joined = g_strjoinv (".", (char **) gparray->pdata);
1831 : 1 : g_assert_cmpstr (joined, ==, "A.dot.separated.string");
1832 : :
1833 : 1 : g_ptr_array_unref (gparray);
1834 : 1 : g_strfreev (strv);
1835 : 1 : g_free (joined);
1836 : 1 : }
1837 : :
1838 : : static void
1839 : 2 : pointer_array_ref_count (gconstpointer test_data)
1840 : : {
1841 : 2 : const gboolean null_terminated = GPOINTER_TO_INT (test_data);
1842 : : GPtrArray *gparray;
1843 : : GPtrArray *gparray2;
1844 : : gint i;
1845 : 2 : gint sum = 0;
1846 : :
1847 [ + + ]: 2 : if (null_terminated)
1848 : 1 : gparray = g_ptr_array_new_null_terminated (0, NULL, null_terminated);
1849 : : else
1850 : 1 : gparray = g_ptr_array_new ();
1851 : :
1852 : 2 : assert_ptr_array_null_terminated (gparray, null_terminated);
1853 : :
1854 [ + + ]: 20002 : for (i = 0; i < 10000; i++)
1855 : : {
1856 : 20000 : g_ptr_array_add (gparray, GINT_TO_POINTER (i));
1857 : 20000 : assert_ptr_array_null_terminated (gparray, null_terminated);
1858 : : }
1859 : :
1860 : : /* check we can ref, unref and still access the array */
1861 : 2 : gparray2 = g_ptr_array_ref (gparray);
1862 : 2 : g_assert (gparray == gparray2);
1863 : 2 : g_ptr_array_unref (gparray2);
1864 [ + + ]: 20002 : for (i = 0; i < 10000; i++)
1865 : 20000 : g_assert (g_ptr_array_index (gparray, i) == GINT_TO_POINTER (i));
1866 : :
1867 : 2 : assert_ptr_array_null_terminated (gparray, null_terminated);
1868 : :
1869 : 2 : g_ptr_array_foreach (gparray, sum_up, &sum);
1870 : 2 : g_assert (sum == 49995000);
1871 : :
1872 : : /* gparray2 should be an empty valid GPtrArray wrapper */
1873 : 2 : gparray2 = g_ptr_array_ref (gparray);
1874 : 2 : g_ptr_array_free (gparray, TRUE);
1875 : :
1876 : 2 : g_assert_cmpint (gparray2->len, ==, 0);
1877 : 2 : assert_ptr_array_null_terminated (gparray, null_terminated);
1878 : :
1879 : 2 : g_ptr_array_unref (gparray2);
1880 : 2 : }
1881 : :
1882 : : static gint num_free_func_invocations = 0;
1883 : :
1884 : : static void
1885 : 11 : my_free_func (gpointer data)
1886 : : {
1887 : 11 : num_free_func_invocations++;
1888 : 11 : g_free (data);
1889 : 11 : }
1890 : :
1891 : : static void
1892 : 1 : pointer_array_free_func (void)
1893 : : {
1894 : : GPtrArray *gparray;
1895 : : GPtrArray *gparray2;
1896 : : gchar **strv;
1897 : : gchar *s;
1898 : :
1899 : 1 : num_free_func_invocations = 0;
1900 : 1 : gparray = g_ptr_array_new_with_free_func (my_free_func);
1901 : 1 : g_ptr_array_unref (gparray);
1902 : 1 : g_assert_cmpint (num_free_func_invocations, ==, 0);
1903 : :
1904 : 1 : gparray = g_ptr_array_new_with_free_func (my_free_func);
1905 : 1 : g_ptr_array_free (gparray, TRUE);
1906 : 1 : g_assert_cmpint (num_free_func_invocations, ==, 0);
1907 : :
1908 : 1 : num_free_func_invocations = 0;
1909 : 1 : gparray = g_ptr_array_new_with_free_func (my_free_func);
1910 : 1 : g_ptr_array_add (gparray, g_strdup ("foo"));
1911 : 1 : g_ptr_array_add (gparray, g_strdup ("bar"));
1912 : 1 : g_ptr_array_add (gparray, g_strdup ("baz"));
1913 : 1 : g_ptr_array_remove_index (gparray, 0);
1914 : 1 : g_assert_cmpint (num_free_func_invocations, ==, 1);
1915 : 1 : g_ptr_array_remove_index_fast (gparray, 1);
1916 : 1 : g_assert_cmpint (num_free_func_invocations, ==, 2);
1917 : 1 : s = g_strdup ("frob");
1918 : 1 : g_ptr_array_add (gparray, s);
1919 : 1 : g_assert (g_ptr_array_remove (gparray, s));
1920 : 1 : g_assert (!g_ptr_array_remove (gparray, "nuun"));
1921 : 1 : g_assert (!g_ptr_array_remove_fast (gparray, "mlo"));
1922 : 1 : g_assert_cmpint (num_free_func_invocations, ==, 3);
1923 : 1 : s = g_strdup ("frob");
1924 : 1 : g_ptr_array_add (gparray, s);
1925 : 1 : g_ptr_array_set_size (gparray, 1);
1926 : 1 : g_assert_cmpint (num_free_func_invocations, ==, 4);
1927 : 1 : g_ptr_array_ref (gparray);
1928 : 1 : g_ptr_array_unref (gparray);
1929 : 1 : g_assert_cmpint (num_free_func_invocations, ==, 4);
1930 : 1 : g_ptr_array_unref (gparray);
1931 : 1 : g_assert_cmpint (num_free_func_invocations, ==, 5);
1932 : :
1933 : 1 : num_free_func_invocations = 0;
1934 : 1 : gparray = g_ptr_array_new_full (10, my_free_func);
1935 : 1 : g_ptr_array_add (gparray, g_strdup ("foo"));
1936 : 1 : g_ptr_array_add (gparray, g_strdup ("bar"));
1937 : 1 : g_ptr_array_add (gparray, g_strdup ("baz"));
1938 : 1 : g_ptr_array_set_size (gparray, 20);
1939 : 1 : g_ptr_array_add (gparray, NULL);
1940 : 1 : gparray2 = g_ptr_array_ref (gparray);
1941 : 1 : strv = (gchar **) g_ptr_array_free (gparray, FALSE);
1942 : 1 : g_assert_cmpint (num_free_func_invocations, ==, 0);
1943 : 1 : g_strfreev (strv);
1944 : 1 : g_ptr_array_unref (gparray2);
1945 : 1 : g_assert_cmpint (num_free_func_invocations, ==, 0);
1946 : :
1947 : 1 : num_free_func_invocations = 0;
1948 : 1 : gparray = g_ptr_array_new_with_free_func (my_free_func);
1949 : 1 : g_ptr_array_add (gparray, g_strdup ("foo"));
1950 : 1 : g_ptr_array_add (gparray, g_strdup ("bar"));
1951 : 1 : g_ptr_array_add (gparray, g_strdup ("baz"));
1952 : 1 : g_ptr_array_remove_range (gparray, 1, 1);
1953 : 1 : g_ptr_array_unref (gparray);
1954 : 1 : g_assert_cmpint (num_free_func_invocations, ==, 3);
1955 : :
1956 : 1 : num_free_func_invocations = 0;
1957 : 1 : gparray = g_ptr_array_new_with_free_func (my_free_func);
1958 : 1 : g_ptr_array_add (gparray, g_strdup ("foo"));
1959 : 1 : g_ptr_array_add (gparray, g_strdup ("bar"));
1960 : 1 : g_ptr_array_add (gparray, g_strdup ("baz"));
1961 : 1 : g_ptr_array_free (gparray, TRUE);
1962 : 1 : g_assert_cmpint (num_free_func_invocations, ==, 3);
1963 : :
1964 : 1 : num_free_func_invocations = 0;
1965 : 1 : gparray = g_ptr_array_new_with_free_func (my_free_func);
1966 : 1 : g_ptr_array_add (gparray, "foo");
1967 : 1 : g_ptr_array_add (gparray, "bar");
1968 : 1 : g_ptr_array_add (gparray, "baz");
1969 : 1 : g_ptr_array_set_free_func (gparray, NULL);
1970 : 1 : g_ptr_array_free (gparray, TRUE);
1971 : 1 : g_assert_cmpint (num_free_func_invocations, ==, 0);
1972 : 1 : }
1973 : :
1974 : : static gpointer
1975 : 300 : ptr_array_copy_func (gconstpointer src, gpointer userdata)
1976 : : {
1977 : 300 : gsize *dst = g_malloc (sizeof (gsize));
1978 : 300 : *dst = *((gsize *) src);
1979 : 300 : return dst;
1980 : : }
1981 : :
1982 : : /* Test the g_ptr_array_copy() function */
1983 : : static void
1984 : 2 : pointer_array_copy (gconstpointer test_data)
1985 : : {
1986 : 2 : const gboolean null_terminated = GPOINTER_TO_INT (test_data);
1987 : : GPtrArray *ptr_array, *ptr_array2;
1988 : : gsize i;
1989 : 2 : const gsize array_size = 100;
1990 : 2 : gsize *array_test = g_malloc (array_size * sizeof (gsize));
1991 : :
1992 : 2 : g_test_summary ("Check all normal behaviour of stealing elements from one "
1993 : : "array to append to another, covering different array sizes "
1994 : : "and element copy functions");
1995 : :
1996 [ + - ]: 2 : if (g_test_undefined ())
1997 : : {
1998 : : /* Testing degenerated cases */
1999 : 2 : g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL,
2000 : : "*assertion*!= NULL*");
2001 : 2 : ptr_array = g_ptr_array_copy (NULL, NULL, NULL);
2002 : 2 : g_test_assert_expected_messages ();
2003 : 2 : g_assert_cmpuint ((gsize) ptr_array, ==, (gsize) NULL);
2004 : : }
2005 : :
2006 : : /* Initializing array_test */
2007 [ + + ]: 202 : for (i = 0; i < array_size; i++)
2008 : 200 : array_test[i] = i;
2009 : :
2010 : : /* Test copy an empty array */
2011 : 2 : ptr_array = g_ptr_array_new_null_terminated (0, NULL, null_terminated);
2012 : 2 : ptr_array2 = g_ptr_array_copy (ptr_array, NULL, NULL);
2013 : :
2014 : 2 : g_assert_cmpuint (ptr_array2->len, ==, ptr_array->len);
2015 : 2 : assert_ptr_array_null_terminated (ptr_array, null_terminated);
2016 : 2 : assert_ptr_array_null_terminated (ptr_array2, null_terminated);
2017 : :
2018 : 2 : g_ptr_array_unref (ptr_array);
2019 : 2 : g_ptr_array_unref (ptr_array2);
2020 : :
2021 : : /* Test simple copy */
2022 : 2 : ptr_array = g_ptr_array_new_null_terminated (array_size, NULL, null_terminated);
2023 : :
2024 [ + + ]: 202 : for (i = 0; i < array_size; i++)
2025 : 200 : g_ptr_array_add (ptr_array, &array_test[i]);
2026 : :
2027 : 2 : ptr_array2 = g_ptr_array_copy (ptr_array, NULL, NULL);
2028 : :
2029 : 2 : g_assert_cmpuint (ptr_array2->len, ==, ptr_array->len);
2030 [ + + ]: 202 : for (i = 0; i < array_size; i++)
2031 : 200 : g_assert_cmpuint (*((gsize *) g_ptr_array_index (ptr_array2, i)), ==, i);
2032 : :
2033 [ + + ]: 202 : for (i = 0; i < array_size; i++)
2034 : 200 : g_assert_cmpuint ((gsize) g_ptr_array_index (ptr_array, i), ==,
2035 : : (gsize) g_ptr_array_index (ptr_array2, i));
2036 : :
2037 : 2 : assert_ptr_array_null_terminated (ptr_array, null_terminated);
2038 : 2 : assert_ptr_array_null_terminated (ptr_array2, null_terminated);
2039 : :
2040 : 2 : g_ptr_array_free (ptr_array2, TRUE);
2041 : :
2042 : : /* Test copy through GCopyFunc */
2043 : 2 : ptr_array2 = g_ptr_array_copy (ptr_array, ptr_array_copy_func, NULL);
2044 : 2 : g_ptr_array_set_free_func (ptr_array2, g_free);
2045 : :
2046 : 2 : g_assert_cmpuint (ptr_array2->len, ==, ptr_array->len);
2047 [ + + ]: 202 : for (i = 0; i < array_size; i++)
2048 : 200 : g_assert_cmpuint (*((gsize *) g_ptr_array_index (ptr_array2, i)), ==, i);
2049 : :
2050 [ + + ]: 202 : for (i = 0; i < array_size; i++)
2051 : 200 : g_assert_cmpuint ((gsize) g_ptr_array_index (ptr_array, i), !=,
2052 : : (gsize) g_ptr_array_index (ptr_array2, i));
2053 : :
2054 : 2 : assert_ptr_array_null_terminated (ptr_array, null_terminated);
2055 : 2 : assert_ptr_array_null_terminated (ptr_array2, null_terminated);
2056 : :
2057 : 2 : g_ptr_array_free (ptr_array2, TRUE);
2058 : :
2059 : : /* Final cleanup */
2060 : 2 : g_ptr_array_free (ptr_array, TRUE);
2061 : 2 : g_free (array_test);
2062 : 2 : }
2063 : :
2064 : : /* Test the g_ptr_array_extend() function */
2065 : : static void
2066 : 2 : pointer_array_extend (gconstpointer test_data)
2067 : : {
2068 : 2 : gboolean null_terminated = GPOINTER_TO_INT (test_data);
2069 : : GPtrArray *ptr_array, *ptr_array2;
2070 : : gsize i;
2071 : 2 : const gsize array_size = 100;
2072 : 2 : gsize *array_test = g_malloc (array_size * sizeof (gsize));
2073 : :
2074 [ + - ]: 2 : if (g_test_undefined ())
2075 : : {
2076 : : /* Testing degenerated cases */
2077 : 2 : ptr_array = g_ptr_array_sized_new (0);
2078 : 2 : g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL,
2079 : : "*assertion*!= NULL*");
2080 : 2 : g_ptr_array_extend (NULL, ptr_array, NULL, NULL);
2081 : 2 : g_test_assert_expected_messages ();
2082 : :
2083 : 2 : g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL,
2084 : : "*assertion*!= NULL*");
2085 : 2 : g_ptr_array_extend (ptr_array, NULL, NULL, NULL);
2086 : 2 : g_test_assert_expected_messages ();
2087 : :
2088 : 2 : g_ptr_array_unref (ptr_array);
2089 : : }
2090 : :
2091 : : /* Initializing array_test */
2092 [ + + ]: 202 : for (i = 0; i < array_size; i++)
2093 : 200 : array_test[i] = i;
2094 : :
2095 : : /* Testing extend with array of size zero */
2096 : 2 : ptr_array = g_ptr_array_new_null_terminated (0, NULL, null_terminated);
2097 : 2 : ptr_array2 = g_ptr_array_new_null_terminated (0, NULL, null_terminated);
2098 : :
2099 : 2 : g_ptr_array_extend (ptr_array, ptr_array2, NULL, NULL);
2100 : :
2101 : 2 : g_assert_cmpuint (ptr_array->len, ==, 0);
2102 : 2 : g_assert_cmpuint (ptr_array2->len, ==, 0);
2103 : :
2104 : 2 : assert_ptr_array_null_terminated (ptr_array, null_terminated);
2105 : 2 : assert_ptr_array_null_terminated (ptr_array2, null_terminated);
2106 : :
2107 : 2 : g_ptr_array_unref (ptr_array);
2108 : 2 : g_ptr_array_unref (ptr_array2);
2109 : :
2110 : : /* Testing extend an array of size zero */
2111 : 2 : ptr_array = g_ptr_array_new_null_terminated (array_size, NULL, null_terminated);
2112 : 2 : ptr_array2 = g_ptr_array_new_null_terminated (0, NULL, null_terminated);
2113 : :
2114 [ + + ]: 202 : for (i = 0; i < array_size; i++)
2115 : : {
2116 : 200 : g_ptr_array_add (ptr_array, &array_test[i]);
2117 : : }
2118 : :
2119 : 2 : g_ptr_array_extend (ptr_array, ptr_array2, NULL, NULL);
2120 : :
2121 [ + + ]: 202 : for (i = 0; i < array_size; i++)
2122 : 200 : g_assert_cmpuint (*((gsize *) g_ptr_array_index (ptr_array, i)), ==, i);
2123 : :
2124 : 2 : assert_ptr_array_null_terminated (ptr_array, null_terminated);
2125 : 2 : assert_ptr_array_null_terminated (ptr_array2, null_terminated);
2126 : :
2127 : 2 : g_ptr_array_unref (ptr_array);
2128 : 2 : g_ptr_array_unref (ptr_array2);
2129 : :
2130 : : /* Testing extend an array of size zero */
2131 : 2 : ptr_array = g_ptr_array_new_null_terminated (0, NULL, null_terminated);
2132 : 2 : ptr_array2 = g_ptr_array_new_null_terminated (array_size, NULL, null_terminated);
2133 : :
2134 [ + + ]: 202 : for (i = 0; i < array_size; i++)
2135 : : {
2136 : 200 : g_ptr_array_add (ptr_array2, &array_test[i]);
2137 : : }
2138 : :
2139 : 2 : g_ptr_array_extend (ptr_array, ptr_array2, NULL, NULL);
2140 : :
2141 [ + + ]: 202 : for (i = 0; i < array_size; i++)
2142 : 200 : g_assert_cmpuint (*((gsize *) g_ptr_array_index (ptr_array, i)), ==, i);
2143 : :
2144 : 2 : assert_ptr_array_null_terminated (ptr_array, null_terminated);
2145 : 2 : assert_ptr_array_null_terminated (ptr_array2, null_terminated);
2146 : :
2147 : 2 : g_ptr_array_unref (ptr_array);
2148 : 2 : g_ptr_array_unref (ptr_array2);
2149 : :
2150 : : /* Testing simple extend */
2151 : 2 : ptr_array = g_ptr_array_new_null_terminated (array_size / 2, NULL, null_terminated);
2152 : 2 : ptr_array2 = g_ptr_array_new_null_terminated (array_size / 2, NULL, null_terminated);
2153 : :
2154 [ + + ]: 102 : for (i = 0; i < array_size / 2; i++)
2155 : : {
2156 : 100 : g_ptr_array_add (ptr_array, &array_test[i]);
2157 : 100 : g_ptr_array_add (ptr_array2, &array_test[i + (array_size / 2)]);
2158 : : }
2159 : :
2160 : 2 : g_ptr_array_extend (ptr_array, ptr_array2, NULL, NULL);
2161 : :
2162 [ + + ]: 202 : for (i = 0; i < array_size; i++)
2163 : 200 : g_assert_cmpuint (*((gsize *) g_ptr_array_index (ptr_array, i)), ==, i);
2164 : :
2165 : 2 : assert_ptr_array_null_terminated (ptr_array, null_terminated);
2166 : 2 : assert_ptr_array_null_terminated (ptr_array2, null_terminated);
2167 : :
2168 : 2 : g_ptr_array_unref (ptr_array);
2169 : 2 : g_ptr_array_unref (ptr_array2);
2170 : :
2171 : : /* Testing extend with GCopyFunc */
2172 : 2 : ptr_array = g_ptr_array_new_null_terminated (array_size / 2, NULL, null_terminated);
2173 : 2 : ptr_array2 = g_ptr_array_new_null_terminated (array_size / 2, NULL, null_terminated);
2174 : :
2175 [ + + ]: 102 : for (i = 0; i < array_size / 2; i++)
2176 : : {
2177 : 100 : g_ptr_array_add (ptr_array, &array_test[i]);
2178 : 100 : g_ptr_array_add (ptr_array2, &array_test[i + (array_size / 2)]);
2179 : : }
2180 : :
2181 : 2 : g_ptr_array_extend (ptr_array, ptr_array2, ptr_array_copy_func, NULL);
2182 : :
2183 [ + + ]: 202 : for (i = 0; i < array_size; i++)
2184 : 200 : g_assert_cmpuint (*((gsize *) g_ptr_array_index (ptr_array, i)), ==, i);
2185 : :
2186 : 2 : assert_ptr_array_null_terminated (ptr_array, null_terminated);
2187 : 2 : assert_ptr_array_null_terminated (ptr_array2, null_terminated);
2188 : :
2189 : : /* Clean-up memory */
2190 [ + + ]: 102 : for (i = array_size / 2; i < array_size; i++)
2191 : 100 : g_free (g_ptr_array_index (ptr_array, i));
2192 : :
2193 : 2 : g_ptr_array_unref (ptr_array);
2194 : 2 : g_ptr_array_unref (ptr_array2);
2195 : 2 : g_free (array_test);
2196 : 2 : }
2197 : :
2198 : : /* Test the g_ptr_array_extend_and_steal() function */
2199 : : static void
2200 : 1 : pointer_array_extend_and_steal (void)
2201 : : {
2202 : : GPtrArray *ptr_array, *ptr_array2, *ptr_array3;
2203 : : gsize i;
2204 : 1 : const gsize array_size = 100;
2205 : 1 : guintptr *array_test = g_malloc (array_size * sizeof (guintptr));
2206 : :
2207 : : /* Initializing array_test */
2208 [ + + ]: 101 : for (i = 0; i < array_size; i++)
2209 : 100 : array_test[i] = i;
2210 : :
2211 : : /* Testing simple extend_and_steal() */
2212 : 1 : ptr_array = g_ptr_array_sized_new (array_size / 2);
2213 : 1 : ptr_array2 = g_ptr_array_sized_new (array_size / 2);
2214 : :
2215 [ + + ]: 51 : for (i = 0; i < array_size / 2; i++)
2216 : : {
2217 : 50 : g_ptr_array_add (ptr_array, &array_test[i]);
2218 : 50 : g_ptr_array_add (ptr_array2, &array_test[i + (array_size / 2)]);
2219 : : }
2220 : :
2221 : 1 : g_ptr_array_extend_and_steal (ptr_array, ptr_array2);
2222 : :
2223 [ + + ]: 101 : for (i = 0; i < array_size; i++)
2224 : 100 : g_assert_cmpuint (*((guintptr *) g_ptr_array_index (ptr_array, i)), ==, i);
2225 : :
2226 : 1 : g_ptr_array_free (ptr_array, TRUE);
2227 : :
2228 : : /* Testing extend_and_steal() with a pending reference to stolen array */
2229 : 1 : ptr_array = g_ptr_array_sized_new (array_size / 2);
2230 : 1 : ptr_array2 = g_ptr_array_sized_new (array_size / 2);
2231 : :
2232 [ + + ]: 51 : for (i = 0; i < array_size / 2; i++)
2233 : : {
2234 : 50 : g_ptr_array_add (ptr_array, &array_test[i]);
2235 : 50 : g_ptr_array_add (ptr_array2, &array_test[i + (array_size / 2)]);
2236 : : }
2237 : :
2238 : 1 : ptr_array3 = g_ptr_array_ref (ptr_array2);
2239 : :
2240 : 1 : g_ptr_array_extend_and_steal (ptr_array, ptr_array2);
2241 : :
2242 [ + + ]: 101 : for (i = 0; i < array_size; i++)
2243 : 100 : g_assert_cmpuint (*((guintptr *) g_ptr_array_index (ptr_array, i)), ==, i);
2244 : :
2245 : 1 : g_assert_cmpuint (ptr_array3->len, ==, 0);
2246 : 1 : g_assert_null (ptr_array3->pdata);
2247 : :
2248 : 1 : g_ptr_array_add (ptr_array2, NULL);
2249 : :
2250 : 1 : g_ptr_array_free (ptr_array, TRUE);
2251 : 1 : g_ptr_array_free (ptr_array3, TRUE);
2252 : :
2253 : : /* Final memory clean-up */
2254 : 1 : g_free (array_test);
2255 : 1 : }
2256 : :
2257 : : static gint
2258 : 240954 : ptr_compare_values (gconstpointer p1, gconstpointer p2)
2259 : : {
2260 : 240954 : return GPOINTER_TO_INT (p1) - GPOINTER_TO_INT (p2);
2261 : : }
2262 : :
2263 : : static gint
2264 : 120515 : ptr_compare (gconstpointer p1, gconstpointer p2)
2265 : : {
2266 : 120515 : gpointer i1 = *(gpointer*)p1;
2267 : 120515 : gpointer i2 = *(gpointer*)p2;
2268 : :
2269 : 120515 : return ptr_compare_values (i1, i2);
2270 : : }
2271 : :
2272 : : static gint
2273 : 240875 : ptr_compare_values_data (gconstpointer p1, gconstpointer p2, gpointer data)
2274 : : {
2275 : 240875 : return GPOINTER_TO_INT (p1) - GPOINTER_TO_INT (p2);
2276 : : }
2277 : :
2278 : : static gint
2279 : 120489 : ptr_compare_data (gconstpointer p1, gconstpointer p2, gpointer data)
2280 : : {
2281 : 120489 : gpointer i1 = *(gpointer*)p1;
2282 : 120489 : gpointer i2 = *(gpointer*)p2;
2283 : :
2284 : 120489 : return ptr_compare_values_data (i1, i2, data);
2285 : : }
2286 : :
2287 : : static void
2288 : 1 : pointer_array_sort (void)
2289 : : {
2290 : : GPtrArray *gparray;
2291 : : gint i;
2292 : : gint val;
2293 : : gint prev, cur;
2294 : :
2295 : 1 : gparray = g_ptr_array_new ();
2296 : :
2297 : : /* Sort empty array */
2298 : 1 : g_ptr_array_sort (gparray, ptr_compare);
2299 : :
2300 [ + + ]: 10001 : for (i = 0; i < 10000; i++)
2301 : : {
2302 : 10000 : val = g_random_int_range (0, 10000);
2303 : 10000 : g_ptr_array_add (gparray, GINT_TO_POINTER (val));
2304 : : }
2305 : :
2306 : 1 : g_ptr_array_sort (gparray, ptr_compare);
2307 : :
2308 : 1 : prev = -1;
2309 [ + + ]: 10001 : for (i = 0; i < 10000; i++)
2310 : : {
2311 : 10000 : cur = GPOINTER_TO_INT (g_ptr_array_index (gparray, i));
2312 : 10000 : g_assert_cmpint (prev, <=, cur);
2313 : 10000 : prev = cur;
2314 : : }
2315 : :
2316 : 1 : g_ptr_array_free (gparray, TRUE);
2317 : 1 : }
2318 : :
2319 : : /* Please keep pointer_array_sort_example() in sync with the doc-comment
2320 : : * of g_ptr_array_sort() */
2321 : :
2322 : : typedef struct
2323 : : {
2324 : : gchar *name;
2325 : : gint size;
2326 : : } FileListEntry;
2327 : :
2328 : : static void
2329 : 12 : file_list_entry_free (gpointer p)
2330 : : {
2331 : 12 : FileListEntry *entry = p;
2332 : :
2333 : 12 : g_free (entry->name);
2334 : 12 : g_free (entry);
2335 : 12 : }
2336 : :
2337 : : static gint
2338 : 3 : sort_filelist (gconstpointer a, gconstpointer b)
2339 : : {
2340 : 3 : const FileListEntry *entry1 = *((FileListEntry **) a);
2341 : 3 : const FileListEntry *entry2 = *((FileListEntry **) b);
2342 : :
2343 : 3 : return g_ascii_strcasecmp (entry1->name, entry2->name);
2344 : : }
2345 : :
2346 : : static void
2347 : 1 : pointer_array_sort_example (void)
2348 : : {
2349 : 1 : GPtrArray *file_list = NULL;
2350 : : FileListEntry *entry;
2351 : :
2352 : 1 : g_test_summary ("Check that the doc-comment for g_ptr_array_sort() is correct");
2353 : :
2354 : 1 : file_list = g_ptr_array_new_with_free_func (file_list_entry_free);
2355 : :
2356 : 1 : entry = g_new0 (FileListEntry, 1);
2357 : 1 : entry->name = g_strdup ("README");
2358 : 1 : entry->size = 42;
2359 : 1 : g_ptr_array_add (file_list, g_steal_pointer (&entry));
2360 : :
2361 : 1 : entry = g_new0 (FileListEntry, 1);
2362 : 1 : entry->name = g_strdup ("empty");
2363 : 1 : entry->size = 0;
2364 : 1 : g_ptr_array_add (file_list, g_steal_pointer (&entry));
2365 : :
2366 : 1 : entry = g_new0 (FileListEntry, 1);
2367 : 1 : entry->name = g_strdup ("aardvark");
2368 : 1 : entry->size = 23;
2369 : 1 : g_ptr_array_add (file_list, g_steal_pointer (&entry));
2370 : :
2371 : 1 : g_ptr_array_sort (file_list, sort_filelist);
2372 : :
2373 : 1 : g_assert_cmpuint (file_list->len, ==, 3);
2374 : 1 : entry = g_ptr_array_index (file_list, 0);
2375 : 1 : g_assert_cmpstr (entry->name, ==, "aardvark");
2376 : 1 : entry = g_ptr_array_index (file_list, 1);
2377 : 1 : g_assert_cmpstr (entry->name, ==, "empty");
2378 : 1 : entry = g_ptr_array_index (file_list, 2);
2379 : 1 : g_assert_cmpstr (entry->name, ==, "README");
2380 : :
2381 : 1 : g_ptr_array_unref (file_list);
2382 : 1 : }
2383 : :
2384 : : /* Please keep pointer_array_sort_with_data_example() in sync with the
2385 : : * doc-comment of g_ptr_array_sort_with_data() */
2386 : :
2387 : : typedef enum { SORT_NAME, SORT_SIZE } SortMode;
2388 : :
2389 : : static gint
2390 : 6 : sort_filelist_how (gconstpointer a, gconstpointer b, gpointer user_data)
2391 : : {
2392 : : gint order;
2393 : 6 : const SortMode sort_mode = GPOINTER_TO_INT (user_data);
2394 : 6 : const FileListEntry *entry1 = *((FileListEntry **) a);
2395 : 6 : const FileListEntry *entry2 = *((FileListEntry **) b);
2396 : :
2397 [ + + - ]: 6 : switch (sort_mode)
2398 : : {
2399 : 3 : case SORT_NAME:
2400 : 3 : order = g_ascii_strcasecmp (entry1->name, entry2->name);
2401 : 3 : break;
2402 : 3 : case SORT_SIZE:
2403 : 3 : order = entry1->size - entry2->size;
2404 : 3 : break;
2405 : 0 : default:
2406 : 0 : order = 0;
2407 : 0 : break;
2408 : : }
2409 : 6 : return order;
2410 : : }
2411 : :
2412 : : static void
2413 : 1 : pointer_array_sort_with_data_example (void)
2414 : : {
2415 : 1 : GPtrArray *file_list = NULL;
2416 : : FileListEntry *entry;
2417 : : SortMode sort_mode;
2418 : :
2419 : 1 : g_test_summary ("Check that the doc-comment for g_ptr_array_sort_with_data() is correct");
2420 : :
2421 : 1 : file_list = g_ptr_array_new_with_free_func (file_list_entry_free);
2422 : :
2423 : 1 : entry = g_new0 (FileListEntry, 1);
2424 : 1 : entry->name = g_strdup ("README");
2425 : 1 : entry->size = 42;
2426 : 1 : g_ptr_array_add (file_list, g_steal_pointer (&entry));
2427 : :
2428 : 1 : entry = g_new0 (FileListEntry, 1);
2429 : 1 : entry->name = g_strdup ("empty");
2430 : 1 : entry->size = 0;
2431 : 1 : g_ptr_array_add (file_list, g_steal_pointer (&entry));
2432 : :
2433 : 1 : entry = g_new0 (FileListEntry, 1);
2434 : 1 : entry->name = g_strdup ("aardvark");
2435 : 1 : entry->size = 23;
2436 : 1 : g_ptr_array_add (file_list, g_steal_pointer (&entry));
2437 : :
2438 : 1 : sort_mode = SORT_NAME;
2439 : 1 : g_ptr_array_sort_with_data (file_list, sort_filelist_how, GINT_TO_POINTER (sort_mode));
2440 : :
2441 : 1 : g_assert_cmpuint (file_list->len, ==, 3);
2442 : 1 : entry = g_ptr_array_index (file_list, 0);
2443 : 1 : g_assert_cmpstr (entry->name, ==, "aardvark");
2444 : 1 : entry = g_ptr_array_index (file_list, 1);
2445 : 1 : g_assert_cmpstr (entry->name, ==, "empty");
2446 : 1 : entry = g_ptr_array_index (file_list, 2);
2447 : 1 : g_assert_cmpstr (entry->name, ==, "README");
2448 : :
2449 : 1 : sort_mode = SORT_SIZE;
2450 : 1 : g_ptr_array_sort_with_data (file_list, sort_filelist_how, GINT_TO_POINTER (sort_mode));
2451 : :
2452 : 1 : g_assert_cmpuint (file_list->len, ==, 3);
2453 : 1 : entry = g_ptr_array_index (file_list, 0);
2454 : 1 : g_assert_cmpstr (entry->name, ==, "empty");
2455 : 1 : entry = g_ptr_array_index (file_list, 1);
2456 : 1 : g_assert_cmpstr (entry->name, ==, "aardvark");
2457 : 1 : entry = g_ptr_array_index (file_list, 2);
2458 : 1 : g_assert_cmpstr (entry->name, ==, "README");
2459 : :
2460 : 1 : g_ptr_array_unref (file_list);
2461 : 1 : }
2462 : :
2463 : : static void
2464 : 1 : pointer_array_sort_with_data (void)
2465 : : {
2466 : : GPtrArray *gparray;
2467 : : gint i;
2468 : : gint prev, cur;
2469 : :
2470 : 1 : gparray = g_ptr_array_new ();
2471 : :
2472 : : /* Sort empty array */
2473 : 1 : g_ptr_array_sort_with_data (gparray, ptr_compare_data, NULL);
2474 : :
2475 [ + + ]: 10001 : for (i = 0; i < 10000; i++)
2476 : 10000 : g_ptr_array_add (gparray, GINT_TO_POINTER (g_random_int_range (0, 10000)));
2477 : :
2478 : 1 : g_ptr_array_sort_with_data (gparray, ptr_compare_data, NULL);
2479 : :
2480 : 1 : prev = -1;
2481 [ + + ]: 10001 : for (i = 0; i < 10000; i++)
2482 : : {
2483 : 10000 : cur = GPOINTER_TO_INT (g_ptr_array_index (gparray, i));
2484 : 10000 : g_assert_cmpint (prev, <=, cur);
2485 : 10000 : prev = cur;
2486 : : }
2487 : :
2488 : 1 : g_ptr_array_free (gparray, TRUE);
2489 : 1 : }
2490 : :
2491 : : static void
2492 : 1 : pointer_array_sort_values (void)
2493 : : {
2494 : : GPtrArray *gparray;
2495 : : gint i;
2496 : : gint val;
2497 : : gint prev, cur;
2498 : :
2499 : 1 : gparray = g_ptr_array_new ();
2500 : :
2501 : : /* Sort empty array */
2502 : 1 : g_ptr_array_sort_values (gparray, ptr_compare_values);
2503 : :
2504 [ + + ]: 10001 : for (i = 0; i < 10000; i++)
2505 : : {
2506 : 10000 : val = g_random_int_range (0, 10000);
2507 : 10000 : g_ptr_array_add (gparray, GINT_TO_POINTER (val));
2508 : : }
2509 : :
2510 : 1 : g_ptr_array_sort_values (gparray, ptr_compare_values);
2511 : :
2512 : 1 : prev = -1;
2513 [ + + ]: 10001 : for (i = 0; i < 10000; i++)
2514 : : {
2515 : 10000 : cur = GPOINTER_TO_INT (g_ptr_array_index (gparray, i));
2516 : 10000 : g_assert_cmpint (prev, <=, cur);
2517 : 10000 : prev = cur;
2518 : : }
2519 : :
2520 : 1 : g_clear_pointer (&gparray, g_ptr_array_unref);
2521 : :
2522 : 1 : gparray = g_ptr_array_new ();
2523 : :
2524 : 1 : g_ptr_array_add (gparray, "dddd");
2525 : 1 : g_ptr_array_add (gparray, "cccc");
2526 : 1 : g_ptr_array_add (gparray, NULL);
2527 : 1 : g_ptr_array_add (gparray, "bbbb");
2528 : 1 : g_ptr_array_add (gparray, "aaaa");
2529 : :
2530 : 1 : g_ptr_array_sort_values (gparray, (GCompareFunc) g_strcmp0);
2531 : :
2532 : 1 : i = 0;
2533 : 1 : g_assert_cmpstr (g_ptr_array_index (gparray, i++), ==, NULL);
2534 : 1 : g_assert_cmpstr (g_ptr_array_index (gparray, i++), ==, "aaaa");
2535 : 1 : g_assert_cmpstr (g_ptr_array_index (gparray, i++), ==, "bbbb");
2536 : 1 : g_assert_cmpstr (g_ptr_array_index (gparray, i++), ==, "cccc");
2537 : 1 : g_assert_cmpstr (g_ptr_array_index (gparray, i++), ==, "dddd");
2538 : :
2539 : 1 : g_clear_pointer (&gparray, g_ptr_array_unref);
2540 : 1 : }
2541 : :
2542 : : static gint
2543 : 3 : sort_filelist_values (gconstpointer a, gconstpointer b)
2544 : : {
2545 : 3 : const FileListEntry *entry1 = a;
2546 : 3 : const FileListEntry *entry2 = b;
2547 : :
2548 : 3 : return g_ascii_strcasecmp (entry1->name, entry2->name);
2549 : : }
2550 : :
2551 : : static void
2552 : 1 : pointer_array_sort_values_example (void)
2553 : : {
2554 : 1 : GPtrArray *file_list = NULL;
2555 : : FileListEntry *entry;
2556 : :
2557 : 1 : file_list = g_ptr_array_new_with_free_func (file_list_entry_free);
2558 : :
2559 : 1 : entry = g_new0 (FileListEntry, 1);
2560 : 1 : entry->name = g_strdup ("README");
2561 : 1 : entry->size = 42;
2562 : 1 : g_ptr_array_add (file_list, g_steal_pointer (&entry));
2563 : :
2564 : 1 : entry = g_new0 (FileListEntry, 1);
2565 : 1 : entry->name = g_strdup ("empty");
2566 : 1 : entry->size = 0;
2567 : 1 : g_ptr_array_add (file_list, g_steal_pointer (&entry));
2568 : :
2569 : 1 : entry = g_new0 (FileListEntry, 1);
2570 : 1 : entry->name = g_strdup ("aardvark");
2571 : 1 : entry->size = 23;
2572 : 1 : g_ptr_array_add (file_list, g_steal_pointer (&entry));
2573 : :
2574 : 1 : g_ptr_array_sort_values (file_list, sort_filelist_values);
2575 : :
2576 : 1 : g_assert_cmpuint (file_list->len, ==, 3);
2577 : 1 : entry = g_ptr_array_index (file_list, 0);
2578 : 1 : g_assert_cmpstr (entry->name, ==, "aardvark");
2579 : 1 : entry = g_ptr_array_index (file_list, 1);
2580 : 1 : g_assert_cmpstr (entry->name, ==, "empty");
2581 : 1 : entry = g_ptr_array_index (file_list, 2);
2582 : 1 : g_assert_cmpstr (entry->name, ==, "README");
2583 : :
2584 : 1 : g_ptr_array_unref (file_list);
2585 : 1 : }
2586 : :
2587 : : static gint
2588 : 6 : sort_filelist_how_values (gconstpointer a, gconstpointer b, gpointer user_data)
2589 : : {
2590 : : gint order;
2591 : 6 : const SortMode sort_mode = GPOINTER_TO_INT (user_data);
2592 : 6 : const FileListEntry *entry1 = a;
2593 : 6 : const FileListEntry *entry2 = b;
2594 : :
2595 [ + + - ]: 6 : switch (sort_mode)
2596 : : {
2597 : 3 : case SORT_NAME:
2598 : 3 : order = g_ascii_strcasecmp (entry1->name, entry2->name);
2599 : 3 : break;
2600 : 3 : case SORT_SIZE:
2601 : 3 : order = entry1->size - entry2->size;
2602 : 3 : break;
2603 : 0 : default:
2604 : 0 : order = 0;
2605 : 0 : break;
2606 : : }
2607 : 6 : return order;
2608 : : }
2609 : :
2610 : : static void
2611 : 1 : pointer_array_sort_values_with_data_example (void)
2612 : : {
2613 : 1 : GPtrArray *file_list = NULL;
2614 : : FileListEntry *entry;
2615 : : SortMode sort_mode;
2616 : :
2617 : 1 : file_list = g_ptr_array_new_with_free_func (file_list_entry_free);
2618 : :
2619 : 1 : entry = g_new0 (FileListEntry, 1);
2620 : 1 : entry->name = g_strdup ("README");
2621 : 1 : entry->size = 42;
2622 : 1 : g_ptr_array_add (file_list, g_steal_pointer (&entry));
2623 : :
2624 : 1 : entry = g_new0 (FileListEntry, 1);
2625 : 1 : entry->name = g_strdup ("empty");
2626 : 1 : entry->size = 0;
2627 : 1 : g_ptr_array_add (file_list, g_steal_pointer (&entry));
2628 : :
2629 : 1 : entry = g_new0 (FileListEntry, 1);
2630 : 1 : entry->name = g_strdup ("aardvark");
2631 : 1 : entry->size = 23;
2632 : 1 : g_ptr_array_add (file_list, g_steal_pointer (&entry));
2633 : :
2634 : 1 : sort_mode = SORT_NAME;
2635 : 1 : g_ptr_array_sort_values_with_data (file_list, sort_filelist_how_values,
2636 : 1 : GINT_TO_POINTER (sort_mode));
2637 : :
2638 : 1 : g_assert_cmpuint (file_list->len, ==, 3);
2639 : 1 : entry = g_ptr_array_index (file_list, 0);
2640 : 1 : g_assert_cmpstr (entry->name, ==, "aardvark");
2641 : 1 : entry = g_ptr_array_index (file_list, 1);
2642 : 1 : g_assert_cmpstr (entry->name, ==, "empty");
2643 : 1 : entry = g_ptr_array_index (file_list, 2);
2644 : 1 : g_assert_cmpstr (entry->name, ==, "README");
2645 : :
2646 : 1 : sort_mode = SORT_SIZE;
2647 : 1 : g_ptr_array_sort_values_with_data (file_list, sort_filelist_how_values,
2648 : 1 : GINT_TO_POINTER (sort_mode));
2649 : :
2650 : 1 : g_assert_cmpuint (file_list->len, ==, 3);
2651 : 1 : entry = g_ptr_array_index (file_list, 0);
2652 : 1 : g_assert_cmpstr (entry->name, ==, "empty");
2653 : 1 : entry = g_ptr_array_index (file_list, 1);
2654 : 1 : g_assert_cmpstr (entry->name, ==, "aardvark");
2655 : 1 : entry = g_ptr_array_index (file_list, 2);
2656 : 1 : g_assert_cmpstr (entry->name, ==, "README");
2657 : :
2658 : 1 : g_ptr_array_unref (file_list);
2659 : 1 : }
2660 : :
2661 : : static void
2662 : 1 : pointer_array_sort_values_with_data (void)
2663 : : {
2664 : : GPtrArray *gparray;
2665 : : gint i;
2666 : : gint prev, cur;
2667 : :
2668 : 1 : gparray = g_ptr_array_new ();
2669 : :
2670 : : /* Sort empty array */
2671 : 1 : g_ptr_array_sort_values_with_data (gparray, ptr_compare_values_data, NULL);
2672 : :
2673 [ + + ]: 10001 : for (i = 0; i < 10000; i++)
2674 : 10000 : g_ptr_array_add (gparray, GINT_TO_POINTER (g_random_int_range (0, 10000)));
2675 : :
2676 : 1 : g_ptr_array_sort_values_with_data (gparray, ptr_compare_values_data, NULL);
2677 : :
2678 : 1 : prev = -1;
2679 [ + + ]: 10001 : for (i = 0; i < 10000; i++)
2680 : : {
2681 : 10000 : cur = GPOINTER_TO_INT (g_ptr_array_index (gparray, i));
2682 : 10000 : g_assert_cmpint (prev, <=, cur);
2683 : 10000 : prev = cur;
2684 : : }
2685 : :
2686 : 1 : g_ptr_array_free (gparray, TRUE);
2687 : 1 : }
2688 : :
2689 : : static void
2690 : 1 : pointer_array_find_empty (void)
2691 : : {
2692 : : GPtrArray *array;
2693 : : guint idx;
2694 : :
2695 : 1 : array = g_ptr_array_new ();
2696 : :
2697 : 1 : g_assert_false (g_ptr_array_find (array, "some-value", NULL)); /* NULL index */
2698 : 1 : g_assert_false (g_ptr_array_find (array, "some-value", &idx)); /* non-NULL index */
2699 : 1 : g_assert_false (g_ptr_array_find_with_equal_func (array, "some-value", g_str_equal, NULL)); /* NULL index */
2700 : 1 : g_assert_false (g_ptr_array_find_with_equal_func (array, "some-value", g_str_equal, &idx)); /* non-NULL index */
2701 : :
2702 : 1 : g_ptr_array_free (array, TRUE);
2703 : 1 : }
2704 : :
2705 : : static void
2706 : 1 : pointer_array_find_non_empty (void)
2707 : : {
2708 : : GPtrArray *array;
2709 : : guint idx;
2710 : 1 : const gchar *str_pointer = "static-string";
2711 : :
2712 : 1 : array = g_ptr_array_new ();
2713 : :
2714 : 1 : g_ptr_array_add (array, "some");
2715 : 1 : g_ptr_array_add (array, "random");
2716 : 1 : g_ptr_array_add (array, "values");
2717 : 1 : g_ptr_array_add (array, "some");
2718 : 1 : g_ptr_array_add (array, "duplicated");
2719 : 1 : g_ptr_array_add (array, (gpointer) str_pointer);
2720 : :
2721 : 1 : g_assert_true (g_ptr_array_find_with_equal_func (array, "random", g_str_equal, NULL)); /* NULL index */
2722 : 1 : g_assert_true (g_ptr_array_find_with_equal_func (array, "random", g_str_equal, &idx)); /* non-NULL index */
2723 : 1 : g_assert_cmpuint (idx, ==, 1);
2724 : :
2725 : 1 : g_assert_true (g_ptr_array_find_with_equal_func (array, "some", g_str_equal, &idx)); /* duplicate element */
2726 : 1 : g_assert_cmpuint (idx, ==, 0);
2727 : :
2728 : 1 : g_assert_false (g_ptr_array_find_with_equal_func (array, "nope", g_str_equal, NULL));
2729 : :
2730 : 1 : g_assert_true (g_ptr_array_find_with_equal_func (array, str_pointer, g_str_equal, &idx));
2731 : 1 : g_assert_cmpuint (idx, ==, 5);
2732 : 1 : idx = G_MAXUINT;
2733 : 1 : g_assert_true (g_ptr_array_find_with_equal_func (array, str_pointer, NULL, &idx)); /* NULL equal func */
2734 : 1 : g_assert_cmpuint (idx, ==, 5);
2735 : 1 : idx = G_MAXUINT;
2736 : 1 : g_assert_true (g_ptr_array_find (array, str_pointer, &idx)); /* NULL equal func */
2737 : 1 : g_assert_cmpuint (idx, ==, 5);
2738 : :
2739 : 1 : g_ptr_array_free (array, TRUE);
2740 : 1 : }
2741 : :
2742 : : static void
2743 : 1 : pointer_array_remove_range (void)
2744 : : {
2745 : 1 : GPtrArray *parray = NULL;
2746 : :
2747 : : /* Try removing an empty range. */
2748 : 1 : parray = g_ptr_array_new ();
2749 : 1 : g_ptr_array_remove_range (parray, 0, 0);
2750 : 1 : g_ptr_array_unref (parray);
2751 : 1 : }
2752 : :
2753 : : static void
2754 : 4 : steal_destroy_notify (gpointer data)
2755 : : {
2756 : 4 : guint *counter = data;
2757 : 4 : *counter = *counter + 1;
2758 : 4 : }
2759 : :
2760 : : /* Test that g_ptr_array_steal_index() and g_ptr_array_steal_index_fast() can
2761 : : * remove elements from a pointer array without the #GDestroyNotify being called. */
2762 : : static void
2763 : 2 : pointer_array_steal_index (gconstpointer test_data)
2764 : : {
2765 : 2 : const gboolean null_terminated = GPOINTER_TO_INT (test_data);
2766 : 2 : guint i1 = 0, i2 = 0, i3 = 0, i4 = 0;
2767 : : gpointer out1, out2;
2768 : : GPtrArray *array;
2769 : :
2770 [ + + ]: 2 : if (null_terminated)
2771 : 1 : array = g_ptr_array_new_null_terminated (0, steal_destroy_notify, null_terminated);
2772 : : else
2773 : 1 : array = g_ptr_array_new_with_free_func (steal_destroy_notify);
2774 : :
2775 : 2 : assert_ptr_array_null_terminated (array, null_terminated);
2776 : :
2777 : 2 : g_ptr_array_add (array, &i1);
2778 : 2 : g_ptr_array_add (array, &i2);
2779 : :
2780 : 2 : assert_ptr_array_null_terminated (array, null_terminated);
2781 : :
2782 : 2 : g_ptr_array_add (array, &i3);
2783 : 2 : g_ptr_array_add (array, &i4);
2784 : :
2785 : 2 : g_assert_cmpuint (array->len, ==, 4);
2786 : :
2787 : 2 : assert_ptr_array_null_terminated (array, null_terminated);
2788 : :
2789 : : /* Remove a single element. */
2790 : 2 : out1 = g_ptr_array_steal_index (array, 0);
2791 : 2 : g_assert_true (out1 == &i1);
2792 : 2 : g_assert_cmpuint (i1, ==, 0); /* should not have been destroyed */
2793 : :
2794 : : /* Following elements should have been moved down. */
2795 : 2 : g_assert_cmpuint (array->len, ==, 3);
2796 : 2 : g_assert_true (g_ptr_array_index (array, 0) == &i2);
2797 : 2 : g_assert_true (g_ptr_array_index (array, 1) == &i3);
2798 : 2 : g_assert_true (g_ptr_array_index (array, 2) == &i4);
2799 : :
2800 : 2 : assert_ptr_array_null_terminated (array, null_terminated);
2801 : :
2802 : : /* Remove another element, quickly. */
2803 : 2 : out2 = g_ptr_array_steal_index_fast (array, 0);
2804 : 2 : g_assert_true (out2 == &i2);
2805 : 2 : g_assert_cmpuint (i2, ==, 0); /* should not have been destroyed */
2806 : :
2807 : : /* Last element should have been swapped in place. */
2808 : 2 : g_assert_cmpuint (array->len, ==, 2);
2809 : 2 : g_assert_true (g_ptr_array_index (array, 0) == &i4);
2810 : 2 : g_assert_true (g_ptr_array_index (array, 1) == &i3);
2811 : :
2812 : 2 : assert_ptr_array_null_terminated (array, null_terminated);
2813 : :
2814 : : /* Check that destroying the pointer array doesn’t affect the stolen elements. */
2815 : 2 : g_ptr_array_unref (array);
2816 : :
2817 : 2 : g_assert_cmpuint (i1, ==, 0);
2818 : 2 : g_assert_cmpuint (i2, ==, 0);
2819 : 2 : g_assert_cmpuint (i3, ==, 1);
2820 : 2 : g_assert_cmpuint (i4, ==, 1);
2821 : 2 : }
2822 : :
2823 : : static void
2824 : 1 : byte_array_new_take_overflow (void)
2825 : : {
2826 : : #if SIZE_WIDTH <= UINT_WIDTH
2827 : 1 : g_test_skip ("Overflow test requires G_MAXSIZE > G_MAXUINT.");
2828 : : #else
2829 : : GByteArray* arr;
2830 : :
2831 : : if (!g_test_undefined ())
2832 : : return;
2833 : :
2834 : : /* Check for overflow should happen before data is accessed. */
2835 : : g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL,
2836 : : "*assertion 'len <= G_MAXUINT' failed");
2837 : : arr = g_byte_array_new_take (NULL, (gsize)G_MAXUINT + 1);
2838 : : g_assert_null (arr);
2839 : : g_test_assert_expected_messages ();
2840 : : #endif
2841 : 1 : }
2842 : :
2843 : : static void
2844 : 1 : byte_array_steal (void)
2845 : : {
2846 : 1 : const guint array_size = 10000;
2847 : : GByteArray *gbarray;
2848 : : guint8 *bdata;
2849 : : guint i;
2850 : : gsize len, past_len;
2851 : :
2852 : 1 : gbarray = g_byte_array_new ();
2853 : 1 : bdata = g_byte_array_steal (gbarray, NULL);
2854 : 1 : g_assert_cmpint ((gsize) bdata, ==, (gsize) gbarray->data);
2855 : 1 : g_free (bdata);
2856 : :
2857 [ + + ]: 10001 : for (i = 0; i < array_size; i++)
2858 : 10000 : g_byte_array_append (gbarray, (guint8 *) "abcd", 4);
2859 : :
2860 : 1 : past_len = gbarray->len;
2861 : 1 : bdata = g_byte_array_steal (gbarray, &len);
2862 : :
2863 : 1 : g_assert_cmpint (len, ==, past_len);
2864 : 1 : g_assert_cmpint (gbarray->len, ==, 0);
2865 : :
2866 : 1 : g_byte_array_append (gbarray, (guint8 *) "@", 1);
2867 : :
2868 : 1 : g_assert_cmpint (bdata[0], ==, 'a');
2869 : 1 : g_assert_cmpint (gbarray->data[0], ==, '@');
2870 : 1 : g_assert_cmpint (gbarray->len, ==, 1);
2871 : :
2872 : 1 : g_byte_array_remove_index (gbarray, 0);
2873 : :
2874 : 1 : g_free (bdata);
2875 : 1 : g_byte_array_free (gbarray, TRUE);
2876 : 1 : }
2877 : :
2878 : : static void
2879 : 1 : byte_array_append (void)
2880 : : {
2881 : : GByteArray *gbarray;
2882 : : gint i;
2883 : : guint8 *segment;
2884 : :
2885 : 1 : gbarray = g_byte_array_sized_new (1000);
2886 [ + + ]: 10001 : for (i = 0; i < 10000; i++)
2887 : 10000 : g_byte_array_append (gbarray, (guint8*) "abcd", 4);
2888 : :
2889 [ + + ]: 10001 : for (i = 0; i < 10000; i++)
2890 : : {
2891 : 10000 : g_assert (gbarray->data[4*i] == 'a');
2892 : 10000 : g_assert (gbarray->data[4*i+1] == 'b');
2893 : 10000 : g_assert (gbarray->data[4*i+2] == 'c');
2894 : 10000 : g_assert (gbarray->data[4*i+3] == 'd');
2895 : : }
2896 : :
2897 : 1 : segment = g_byte_array_free (gbarray, FALSE);
2898 : :
2899 [ + + ]: 10001 : for (i = 0; i < 10000; i++)
2900 : : {
2901 : 10000 : g_assert (segment[4*i] == 'a');
2902 : 10000 : g_assert (segment[4*i+1] == 'b');
2903 : 10000 : g_assert (segment[4*i+2] == 'c');
2904 : 10000 : g_assert (segment[4*i+3] == 'd');
2905 : : }
2906 : :
2907 : 1 : g_free (segment);
2908 : 1 : }
2909 : :
2910 : : static void
2911 : 1 : byte_array_prepend (void)
2912 : : {
2913 : : GByteArray *gbarray;
2914 : : gint i;
2915 : :
2916 : 1 : gbarray = g_byte_array_new ();
2917 : 1 : g_byte_array_set_size (gbarray, 1000);
2918 : :
2919 [ + + ]: 10001 : for (i = 0; i < 10000; i++)
2920 : 10000 : g_byte_array_prepend (gbarray, (guint8*) "abcd", 4);
2921 : :
2922 [ + + ]: 10001 : for (i = 0; i < 10000; i++)
2923 : : {
2924 : 10000 : g_assert (gbarray->data[4*i] == 'a');
2925 : 10000 : g_assert (gbarray->data[4*i+1] == 'b');
2926 : 10000 : g_assert (gbarray->data[4*i+2] == 'c');
2927 : 10000 : g_assert (gbarray->data[4*i+3] == 'd');
2928 : : }
2929 : :
2930 : 1 : g_byte_array_free (gbarray, TRUE);
2931 : 1 : }
2932 : :
2933 : : static void
2934 : 1 : byte_array_ref_count (void)
2935 : : {
2936 : : GByteArray *gbarray;
2937 : : GByteArray *gbarray2;
2938 : : gint i;
2939 : :
2940 : 1 : gbarray = g_byte_array_new ();
2941 [ + + ]: 10001 : for (i = 0; i < 10000; i++)
2942 : 10000 : g_byte_array_append (gbarray, (guint8*) "abcd", 4);
2943 : :
2944 : 1 : gbarray2 = g_byte_array_ref (gbarray);
2945 : 1 : g_assert (gbarray2 == gbarray);
2946 : 1 : g_byte_array_unref (gbarray2);
2947 [ + + ]: 10001 : for (i = 0; i < 10000; i++)
2948 : : {
2949 : 10000 : g_assert (gbarray->data[4*i] == 'a');
2950 : 10000 : g_assert (gbarray->data[4*i+1] == 'b');
2951 : 10000 : g_assert (gbarray->data[4*i+2] == 'c');
2952 : 10000 : g_assert (gbarray->data[4*i+3] == 'd');
2953 : : }
2954 : :
2955 : 1 : gbarray2 = g_byte_array_ref (gbarray);
2956 : 1 : g_assert (gbarray2 == gbarray);
2957 : 1 : g_byte_array_free (gbarray, TRUE);
2958 : 1 : g_assert_cmpint (gbarray2->len, ==, 0);
2959 : 1 : g_byte_array_unref (gbarray2);
2960 : 1 : }
2961 : :
2962 : : static void
2963 : 1 : byte_array_remove (void)
2964 : : {
2965 : : GByteArray *gbarray;
2966 : : gint i;
2967 : :
2968 : 1 : gbarray = g_byte_array_new ();
2969 [ + + ]: 101 : for (i = 0; i < 100; i++)
2970 : 100 : g_byte_array_append (gbarray, (guint8*) "abcd", 4);
2971 : :
2972 : 1 : g_assert_cmpint (gbarray->len, ==, 400);
2973 : :
2974 : 1 : g_byte_array_remove_index (gbarray, 4);
2975 : 1 : g_byte_array_remove_index (gbarray, 4);
2976 : 1 : g_byte_array_remove_index (gbarray, 4);
2977 : 1 : g_byte_array_remove_index (gbarray, 4);
2978 : :
2979 : 1 : g_assert_cmpint (gbarray->len, ==, 396);
2980 : :
2981 [ + + ]: 100 : for (i = 0; i < 99; i++)
2982 : : {
2983 : 99 : g_assert (gbarray->data[4*i] == 'a');
2984 : 99 : g_assert (gbarray->data[4*i+1] == 'b');
2985 : 99 : g_assert (gbarray->data[4*i+2] == 'c');
2986 : 99 : g_assert (gbarray->data[4*i+3] == 'd');
2987 : : }
2988 : :
2989 : 1 : g_byte_array_free (gbarray, TRUE);
2990 : 1 : }
2991 : :
2992 : : static void
2993 : 1 : byte_array_remove_fast (void)
2994 : : {
2995 : : GByteArray *gbarray;
2996 : : gint i;
2997 : :
2998 : 1 : gbarray = g_byte_array_new ();
2999 [ + + ]: 101 : for (i = 0; i < 100; i++)
3000 : 100 : g_byte_array_append (gbarray, (guint8*) "abcd", 4);
3001 : :
3002 : 1 : g_assert_cmpint (gbarray->len, ==, 400);
3003 : :
3004 : 1 : g_byte_array_remove_index_fast (gbarray, 4);
3005 : 1 : g_byte_array_remove_index_fast (gbarray, 4);
3006 : 1 : g_byte_array_remove_index_fast (gbarray, 4);
3007 : 1 : g_byte_array_remove_index_fast (gbarray, 4);
3008 : :
3009 : 1 : g_assert_cmpint (gbarray->len, ==, 396);
3010 : :
3011 [ + + ]: 100 : for (i = 0; i < 99; i++)
3012 : : {
3013 : 99 : g_assert (gbarray->data[4*i] == 'a');
3014 : 99 : g_assert (gbarray->data[4*i+1] == 'b');
3015 : 99 : g_assert (gbarray->data[4*i+2] == 'c');
3016 : 99 : g_assert (gbarray->data[4*i+3] == 'd');
3017 : : }
3018 : :
3019 : 1 : g_byte_array_free (gbarray, TRUE);
3020 : 1 : }
3021 : :
3022 : : static void
3023 : 1 : byte_array_remove_range (void)
3024 : : {
3025 : : GByteArray *gbarray;
3026 : : gint i;
3027 : :
3028 : 1 : gbarray = g_byte_array_new ();
3029 [ + + ]: 101 : for (i = 0; i < 100; i++)
3030 : 100 : g_byte_array_append (gbarray, (guint8*) "abcd", 4);
3031 : :
3032 : 1 : g_assert_cmpint (gbarray->len, ==, 400);
3033 : :
3034 : 1 : g_byte_array_remove_range (gbarray, 12, 4);
3035 : :
3036 : 1 : g_assert_cmpint (gbarray->len, ==, 396);
3037 : :
3038 [ + + ]: 100 : for (i = 0; i < 99; i++)
3039 : : {
3040 : 99 : g_assert (gbarray->data[4*i] == 'a');
3041 : 99 : g_assert (gbarray->data[4*i+1] == 'b');
3042 : 99 : g_assert (gbarray->data[4*i+2] == 'c');
3043 : 99 : g_assert (gbarray->data[4*i+3] == 'd');
3044 : : }
3045 : :
3046 : : /* Ensure the entire array can be cleared, even when empty. */
3047 : 1 : g_byte_array_remove_range (gbarray, 0, gbarray->len);
3048 : 1 : g_byte_array_remove_range (gbarray, 0, gbarray->len);
3049 : :
3050 : 1 : g_byte_array_free (gbarray, TRUE);
3051 : 1 : }
3052 : :
3053 : : static int
3054 : 543 : byte_compare (gconstpointer p1, gconstpointer p2)
3055 : : {
3056 : 543 : const guint8 *i1 = p1;
3057 : 543 : const guint8 *i2 = p2;
3058 : :
3059 : 543 : return *i1 - *i2;
3060 : : }
3061 : :
3062 : : static int
3063 : 533 : byte_compare_data (gconstpointer p1, gconstpointer p2, gpointer data)
3064 : : {
3065 : 533 : const guint8 *i1 = p1;
3066 : 533 : const guint8 *i2 = p2;
3067 : :
3068 : 533 : return *i1 - *i2;
3069 : : }
3070 : :
3071 : : static void
3072 : 1 : byte_array_sort (void)
3073 : : {
3074 : : GByteArray *gbarray;
3075 : : guint i;
3076 : : guint8 val;
3077 : : guint8 prev, cur;
3078 : :
3079 : 1 : gbarray = g_byte_array_new ();
3080 [ + + ]: 101 : for (i = 0; i < 100; i++)
3081 : : {
3082 : 100 : val = 'a' + g_random_int_range (0, 26);
3083 : 100 : g_byte_array_append (gbarray, (guint8*) &val, 1);
3084 : : }
3085 : :
3086 : 1 : g_byte_array_sort (gbarray, byte_compare);
3087 : :
3088 : 1 : prev = 'a';
3089 [ + + ]: 101 : for (i = 0; i < gbarray->len; i++)
3090 : : {
3091 : 100 : cur = gbarray->data[i];
3092 : 100 : g_assert_cmpint (prev, <=, cur);
3093 : 100 : prev = cur;
3094 : : }
3095 : :
3096 : 1 : g_byte_array_free (gbarray, TRUE);
3097 : 1 : }
3098 : :
3099 : : static void
3100 : 1 : byte_array_sort_with_data (void)
3101 : : {
3102 : : GByteArray *gbarray;
3103 : : guint i;
3104 : : guint8 val;
3105 : : guint8 prev, cur;
3106 : :
3107 : 1 : gbarray = g_byte_array_new ();
3108 [ + + ]: 101 : for (i = 0; i < 100; i++)
3109 : : {
3110 : 100 : val = 'a' + g_random_int_range (0, 26);
3111 : 100 : g_byte_array_append (gbarray, (guint8*) &val, 1);
3112 : : }
3113 : :
3114 : 1 : g_byte_array_sort_with_data (gbarray, byte_compare_data, NULL);
3115 : :
3116 : 1 : prev = 'a';
3117 [ + + ]: 101 : for (i = 0; i < gbarray->len; i++)
3118 : : {
3119 : 100 : cur = gbarray->data[i];
3120 : 100 : g_assert_cmpint (prev, <=, cur);
3121 : 100 : prev = cur;
3122 : : }
3123 : :
3124 : 1 : g_byte_array_free (gbarray, TRUE);
3125 : 1 : }
3126 : :
3127 : : static void
3128 : 1 : byte_array_new_take (void)
3129 : : {
3130 : : GByteArray *gbarray;
3131 : : guint8 *data;
3132 : :
3133 : 1 : data = g_memdup2 ("woooweeewow", 11);
3134 : 1 : gbarray = g_byte_array_new_take (data, 11);
3135 : 1 : g_assert (gbarray->data == data);
3136 : 1 : g_assert_cmpuint (gbarray->len, ==, 11);
3137 : 1 : g_byte_array_free (gbarray, TRUE);
3138 : 1 : }
3139 : :
3140 : : static void
3141 : 1 : byte_array_free_to_bytes (void)
3142 : : {
3143 : : GByteArray *gbarray;
3144 : : gpointer memory;
3145 : : GBytes *bytes;
3146 : : gsize size;
3147 : :
3148 : 1 : gbarray = g_byte_array_new ();
3149 : 1 : g_byte_array_append (gbarray, (guint8 *)"woooweeewow", 11);
3150 : 1 : memory = gbarray->data;
3151 : :
3152 : 1 : bytes = g_byte_array_free_to_bytes (gbarray);
3153 : 1 : g_assert (bytes != NULL);
3154 : 1 : g_assert_cmpuint (g_bytes_get_size (bytes), ==, 11);
3155 : 1 : g_assert (g_bytes_get_data (bytes, &size) == memory);
3156 : 1 : g_assert_cmpuint (size, ==, 11);
3157 : :
3158 : 1 : g_bytes_unref (bytes);
3159 : 1 : }
3160 : :
3161 : : static void
3162 : 48 : add_array_test (const gchar *test_path,
3163 : : const ArrayTestData *config,
3164 : : GTestDataFunc test_func)
3165 : : {
3166 : 48 : gchar *test_name = NULL;
3167 : :
3168 : 96 : test_name = g_strdup_printf ("%s/%s-%s",
3169 : : test_path,
3170 [ + + ]: 48 : config->zero_terminated ? "zero-terminated" : "non-zero-terminated",
3171 [ + + ]: 48 : config->clear_ ? "clear" : "no-clear");
3172 : 48 : g_test_add_data_func (test_name, config, test_func);
3173 : 48 : g_free (test_name);
3174 : 48 : }
3175 : :
3176 : : int
3177 : 1 : main (int argc, char *argv[])
3178 : : {
3179 : : /* Test all possible combinations of g_array_new() parameters. */
3180 : 1 : const ArrayTestData array_configurations[] =
3181 : : {
3182 : : { FALSE, FALSE },
3183 : : { FALSE, TRUE },
3184 : : { TRUE, FALSE },
3185 : : { TRUE, TRUE },
3186 : : };
3187 : : gsize i;
3188 : :
3189 : 1 : g_test_init (&argc, &argv, NULL);
3190 : :
3191 : : /* array tests */
3192 : 1 : g_test_add_func ("/array/new/zero-terminated", array_new_zero_terminated);
3193 : 1 : g_test_add_func ("/array/new/take", array_new_take);
3194 : 1 : g_test_add_func ("/array/new/take/empty", array_new_take_empty);
3195 : 1 : g_test_add_func ("/array/new/take/overflow", array_new_take_overflow);
3196 : 1 : g_test_add_func ("/array/new/take-zero-terminated", array_new_take_zero_terminated);
3197 : 1 : g_test_add_func ("/array/ref-count", array_ref_count);
3198 : 1 : g_test_add_func ("/array/steal", array_steal);
3199 : 1 : g_test_add_func ("/array/clear-func", array_clear_func);
3200 : 1 : g_test_add_func ("/array/binary-search", test_array_binary_search);
3201 : 1 : g_test_add_func ("/array/copy-sized", test_array_copy_sized);
3202 : 1 : g_test_add_func ("/array/overflow-append-vals", array_overflow_append_vals);
3203 : 1 : g_test_add_func ("/array/overflow-set-size", array_overflow_set_size);
3204 : :
3205 [ + + ]: 5 : for (i = 0; i < G_N_ELEMENTS (array_configurations); i++)
3206 : : {
3207 : 4 : add_array_test ("/array/set-size", &array_configurations[i], array_set_size);
3208 : 4 : add_array_test ("/array/set-size/sized", &array_configurations[i], array_set_size_sized);
3209 : 4 : add_array_test ("/array/append-val", &array_configurations[i], array_append_val);
3210 : 4 : add_array_test ("/array/prepend-val", &array_configurations[i], array_prepend_val);
3211 : 4 : add_array_test ("/array/prepend-vals", &array_configurations[i], array_prepend_vals);
3212 : 4 : add_array_test ("/array/insert-vals", &array_configurations[i], array_insert_vals);
3213 : 4 : add_array_test ("/array/remove-index", &array_configurations[i], array_remove_index);
3214 : 4 : add_array_test ("/array/remove-index-fast", &array_configurations[i], array_remove_index_fast);
3215 : 4 : add_array_test ("/array/remove-range", &array_configurations[i], array_remove_range);
3216 : 4 : add_array_test ("/array/copy", &array_configurations[i], array_copy);
3217 : 4 : add_array_test ("/array/sort", &array_configurations[i], array_sort);
3218 : 4 : add_array_test ("/array/sort-with-data", &array_configurations[i], array_sort_with_data);
3219 : : }
3220 : :
3221 : : /* pointer arrays */
3222 : 1 : g_test_add_func ("/pointerarray/free/null-terminated", pointer_array_free_null_terminated);
3223 : 1 : g_test_add_func ("/pointerarray/add", pointer_array_add);
3224 : 1 : g_test_add_func ("/pointerarray/insert", pointer_array_insert);
3225 : 1 : g_test_add_func ("/pointerarray/new-take", pointer_array_new_take);
3226 : 1 : g_test_add_func ("/pointerarray/new-take/empty", pointer_array_new_take_empty);
3227 : 1 : g_test_add_func ("/pointerarray/new-take/overflow", pointer_array_new_take_overflow);
3228 : 1 : g_test_add_func ("/pointerarray/new-take/with-free-func", pointer_array_new_take_with_free_func);
3229 : 1 : g_test_add_func ("/pointerarray/new-take-null-terminated", pointer_array_new_take_null_terminated);
3230 : 1 : g_test_add_func ("/pointerarray/new-take-null-terminated/empty", pointer_array_new_take_null_terminated_empty);
3231 : 1 : g_test_add_func ("/pointerarray/new-take-null-terminated/with-free-func", pointer_array_new_take_null_terminated_with_free_func);
3232 : 1 : g_test_add_func ("/pointerarray/new-take-null-terminated/from-gstrv", pointer_array_new_take_null_terminated_from_gstrv);
3233 : 1 : g_test_add_func ("/pointerarray/new-from-array", pointer_array_new_from_array);
3234 : 1 : g_test_add_func ("/pointerarray/new-from-array/empty", pointer_array_new_from_array_empty);
3235 : 1 : g_test_add_func ("/pointerarray/new-from-array/overflow", pointer_array_new_from_array_overflow);
3236 : 1 : g_test_add_func ("/pointerarray/new-from-array/with-copy-and-free-func", pointer_array_new_from_array_with_copy_and_free_func);
3237 : 1 : g_test_add_func ("/pointerarray/new-from-null-terminated-array", pointer_array_new_from_null_terminated_array);
3238 : 1 : g_test_add_func ("/pointerarray/new-from-null-terminated-array/empty", pointer_array_new_from_null_terminated_array_empty);
3239 : 1 : g_test_add_func ("/pointerarray/new-from-null-terminated-array/with-copy-and-free-func", pointer_array_new_from_null_terminated_array_with_copy_and_free_func);
3240 : 1 : g_test_add_func ("/pointerarray/new-from-null-terminated-array/from-gstrv", pointer_array_new_from_null_terminated_array_from_gstrv);
3241 : 1 : g_test_add_data_func ("/pointerarray/ref-count/not-null-terminated", GINT_TO_POINTER (0), pointer_array_ref_count);
3242 : 1 : g_test_add_data_func ("/pointerarray/ref-count/null-terminated", GINT_TO_POINTER (1), pointer_array_ref_count);
3243 : 1 : g_test_add_func ("/pointerarray/free-func", pointer_array_free_func);
3244 : 1 : g_test_add_data_func ("/pointerarray/array_copy/not-null-terminated", GINT_TO_POINTER (0), pointer_array_copy);
3245 : 1 : g_test_add_data_func ("/pointerarray/array_copy/null-terminated", GINT_TO_POINTER (1), pointer_array_copy);
3246 : 1 : g_test_add_data_func ("/pointerarray/array_extend/not-null-terminated", GINT_TO_POINTER (0), pointer_array_extend);
3247 : 1 : g_test_add_data_func ("/pointerarray/array_extend/null-terminated", GINT_TO_POINTER (1), pointer_array_extend);
3248 : 1 : g_test_add_func ("/pointerarray/array_extend_and_steal", pointer_array_extend_and_steal);
3249 : 1 : g_test_add_func ("/pointerarray/sort", pointer_array_sort);
3250 : 1 : g_test_add_func ("/pointerarray/sort/example", pointer_array_sort_example);
3251 : 1 : g_test_add_func ("/pointerarray/sort-with-data", pointer_array_sort_with_data);
3252 : 1 : g_test_add_func ("/pointerarray/sort-with-data/example", pointer_array_sort_with_data_example);
3253 : 1 : g_test_add_func ("/pointerarray/sort-values", pointer_array_sort_values);
3254 : 1 : g_test_add_func ("/pointerarray/sort-values/example", pointer_array_sort_values_example);
3255 : 1 : g_test_add_func ("/pointerarray/sort-values-with-data", pointer_array_sort_values_with_data);
3256 : 1 : g_test_add_func ("/pointerarray/sort-values-with-data/example", pointer_array_sort_values_with_data_example);
3257 : 1 : g_test_add_func ("/pointerarray/find/empty", pointer_array_find_empty);
3258 : 1 : g_test_add_func ("/pointerarray/find/non-empty", pointer_array_find_non_empty);
3259 : 1 : g_test_add_func ("/pointerarray/remove-range", pointer_array_remove_range);
3260 : 1 : g_test_add_func ("/pointerarray/steal", pointer_array_steal);
3261 : 1 : g_test_add_data_func ("/pointerarray/steal_index/not-null-terminated", GINT_TO_POINTER (0), pointer_array_steal_index);
3262 : 1 : g_test_add_data_func ("/pointerarray/steal_index/null-terminated", GINT_TO_POINTER (1), pointer_array_steal_index);
3263 : :
3264 : : /* byte arrays */
3265 : 1 : g_test_add_func ("/bytearray/steal", byte_array_steal);
3266 : 1 : g_test_add_func ("/bytearray/append", byte_array_append);
3267 : 1 : g_test_add_func ("/bytearray/prepend", byte_array_prepend);
3268 : 1 : g_test_add_func ("/bytearray/remove", byte_array_remove);
3269 : 1 : g_test_add_func ("/bytearray/remove-fast", byte_array_remove_fast);
3270 : 1 : g_test_add_func ("/bytearray/remove-range", byte_array_remove_range);
3271 : 1 : g_test_add_func ("/bytearray/ref-count", byte_array_ref_count);
3272 : 1 : g_test_add_func ("/bytearray/sort", byte_array_sort);
3273 : 1 : g_test_add_func ("/bytearray/sort-with-data", byte_array_sort_with_data);
3274 : 1 : g_test_add_func ("/bytearray/new-take", byte_array_new_take);
3275 : 1 : g_test_add_func ("/bytearray/new-take-overflow", byte_array_new_take_overflow);
3276 : 1 : g_test_add_func ("/bytearray/free-to-bytes", byte_array_free_to_bytes);
3277 : :
3278 : 1 : return g_test_run ();
3279 : : }
|