Imported Upstream version 2.67.4
[platform/upstream/glib.git] / glib / tests / bytes.c
1 /*
2  * Copyright 2011 Collabora Ltd.
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2.1 of the License, or (at your option) any later version.
8  *
9  * See the included COPYING file for more information.
10  */
11
12 #undef G_DISABLE_ASSERT
13
14 #include <stdio.h>
15 #include <stdlib.h>
16 #include <string.h>
17 #include "glib.h"
18
19 /* Keep in sync with glib/gbytes.c */
20 struct _GBytes
21 {
22   gconstpointer data;
23   gsize size;
24   gint ref_count;
25   GDestroyNotify free_func;
26   gpointer user_data;
27 };
28
29 static const gchar *NYAN = "nyannyan";
30 static const gsize N_NYAN = 8;
31
32 static void
33 test_new (void)
34 {
35   const gchar *data;
36   GBytes *bytes;
37   gsize size;
38
39   data = "test";
40   bytes = g_bytes_new (data, 4);
41   g_assert (bytes != NULL);
42   g_assert (g_bytes_get_data (bytes, &size) != data);
43   g_assert_cmpuint (size, ==, 4);
44   g_assert_cmpuint (g_bytes_get_size (bytes), ==, 4);
45   g_assert_cmpmem (data, 4, g_bytes_get_data (bytes, NULL), g_bytes_get_size (bytes));
46
47   g_bytes_unref (bytes);
48 }
49
50 static void
51 test_new_take (void)
52 {
53   gchar *data;
54   GBytes *bytes;
55   gsize size;
56
57   data = g_strdup ("test");
58   bytes = g_bytes_new_take (data, 4);
59   g_assert (bytes != NULL);
60   g_assert (g_bytes_get_data (bytes, &size) == data);
61   g_assert_cmpuint (size, ==, 4);
62   g_assert_cmpuint (g_bytes_get_size (bytes), ==, 4);
63
64   g_bytes_unref (bytes);
65 }
66
67 static void
68 test_new_static (void)
69 {
70   const gchar *data;
71   GBytes *bytes;
72   gsize size;
73
74   data = "test";
75   bytes = g_bytes_new_static (data, 4);
76   g_assert (bytes != NULL);
77   g_assert (g_bytes_get_data (bytes, &size) == data);
78   g_assert_cmpuint (size, ==, 4);
79   g_assert_cmpuint (g_bytes_get_size (bytes), ==, 4);
80
81   g_bytes_unref (bytes);
82 }
83
84 static void
85 test_new_from_bytes (void)
86 {
87   const gchar *data = "smile and wave";
88   GBytes *bytes;
89   GBytes *sub;
90
91   bytes = g_bytes_new (data, 14);
92   sub = g_bytes_new_from_bytes (bytes, 10, 4);
93
94   g_assert (sub != NULL);
95   g_assert (g_bytes_get_data (sub, NULL) == ((gchar *)g_bytes_get_data (bytes, NULL)) + 10);
96   g_bytes_unref (bytes);
97
98   g_assert_cmpmem (g_bytes_get_data (sub, NULL), g_bytes_get_size (sub), "wave", 4);
99   g_bytes_unref (sub);
100 }
101
102 /* Verify that creating slices of GBytes reference the top-most bytes
103  * at the correct offset. Ensure that intermediate GBytes are not referenced.
104  */
105 static void
106 test_new_from_bytes_slice (void)
107 {
108   GBytes *bytes = g_bytes_new_static ("Some stupid data", strlen ("Some stupid data") + 1);
109   GBytes *bytes1 = g_bytes_new_from_bytes (bytes, 4, 13);
110   GBytes *bytes2 = g_bytes_new_from_bytes (bytes1, 1, 12);
111   GBytes *bytes3 = g_bytes_new_from_bytes (bytes2, 0, 6);
112
113   g_assert_cmpint (bytes->ref_count, ==, 4);
114   g_assert_cmpint (bytes1->ref_count, ==, 1);
115   g_assert_cmpint (bytes2->ref_count, ==, 1);
116   g_assert_cmpint (bytes3->ref_count, ==, 1);
117
118   g_assert_null (bytes->user_data);
119   g_assert (bytes1->user_data == bytes);
120   g_assert (bytes2->user_data == bytes);
121   g_assert (bytes3->user_data == bytes);
122
123   g_assert_cmpint (17, ==, g_bytes_get_size (bytes));
124   g_assert_cmpint (13, ==, g_bytes_get_size (bytes1));
125   g_assert_cmpint (12, ==, g_bytes_get_size (bytes2));
126   g_assert_cmpint (6, ==, g_bytes_get_size (bytes3));
127
128   g_assert_cmpint (0, ==, strncmp ("Some stupid data", (gchar *)bytes->data, 17));
129   g_assert_cmpint (0, ==, strncmp (" stupid data", (gchar *)bytes1->data, 13));
130   g_assert_cmpint (0, ==, strncmp ("stupid data", (gchar *)bytes2->data, 12));
131   g_assert_cmpint (0, ==, strncmp ("stupid", (gchar *)bytes3->data, 6));
132
133   g_bytes_unref (bytes);
134   g_bytes_unref (bytes1);
135   g_bytes_unref (bytes2);
136   g_bytes_unref (bytes3);
137 }
138
139 /* Ensure that referencing an entire GBytes just returns the same bytes
140  * instance (with incremented reference count) instead of a new instance.
141  */
142 static void
143 test_new_from_bytes_shared_ref (void)
144 {
145   GBytes *bytes = g_bytes_new_static ("Some data", strlen ("Some data") + 1);
146   GBytes *other = g_bytes_new_from_bytes (bytes, 0, g_bytes_get_size (bytes));
147
148   g_assert (bytes == other);
149   g_assert_cmpint (bytes->ref_count, ==, 2);
150
151   g_bytes_unref (bytes);
152   g_bytes_unref (other);
153 }
154
155 static void
156 on_destroy_increment (gpointer data)
157 {
158   gint *count = data;
159   g_assert (count != NULL);
160   (*count)++;
161 }
162
163 static void
164 test_new_with_free_func (void)
165 {
166   GBytes *bytes;
167   gchar *data;
168   gint count = 0;
169   gsize size;
170
171   data = "test";
172   bytes = g_bytes_new_with_free_func (data, 4, on_destroy_increment, &count);
173   g_assert (bytes != NULL);
174   g_assert_cmpint (count, ==, 0);
175   g_assert (g_bytes_get_data (bytes, &size) == data);
176   g_assert_cmpuint (size, ==, 4);
177   g_assert_cmpuint (g_bytes_get_size (bytes), ==, 4);
178
179   g_bytes_unref (bytes);
180   g_assert_cmpuint (count, ==, 1);
181 }
182
183 static void
184 test_hash (void)
185 {
186   GBytes *bytes1;
187   GBytes *bytes2;
188   guint hash1;
189   guint hash2;
190
191   bytes1 = g_bytes_new ("blah", 4);
192   bytes2 = g_bytes_new ("blah", 4);
193
194   hash1 = g_bytes_hash (bytes1);
195   hash2 = g_bytes_hash (bytes2);
196   g_assert (hash1 == hash2);
197
198   g_bytes_unref (bytes1);
199   g_bytes_unref (bytes2);
200 }
201
202 static void
203 test_equal (void)
204 {
205   GBytes *bytes;
206   GBytes *bytes2;
207
208   bytes = g_bytes_new ("blah", 4);
209
210   bytes2 = g_bytes_new ("blah", 4);
211   g_assert (g_bytes_equal (bytes, bytes2));
212   g_assert (g_bytes_equal (bytes2, bytes));
213   g_bytes_unref (bytes2);
214
215   bytes2 = g_bytes_new ("bla", 3);
216   g_assert (!g_bytes_equal (bytes, bytes2));
217   g_assert (!g_bytes_equal (bytes2, bytes));
218   g_bytes_unref (bytes2);
219
220   bytes2 = g_bytes_new ("true", 4);
221   g_assert (!g_bytes_equal (bytes, bytes2));
222   g_assert (!g_bytes_equal (bytes2, bytes));
223   g_bytes_unref (bytes2);
224
225   g_bytes_unref (bytes);
226 }
227
228 static void
229 test_compare (void)
230 {
231   GBytes *bytes;
232   GBytes *bytes2;
233
234   bytes = g_bytes_new ("blah", 4);
235
236   bytes2 = g_bytes_new ("blah", 4);
237   g_assert_cmpint (g_bytes_compare (bytes, bytes2), ==, 0);
238   g_bytes_unref (bytes2);
239
240   bytes2 = g_bytes_new ("bla", 3);
241   g_assert_cmpint (g_bytes_compare (bytes, bytes2), >, 0);
242   g_bytes_unref (bytes2);
243
244   bytes2 = g_bytes_new ("abcd", 4);
245   g_assert_cmpint (g_bytes_compare (bytes, bytes2), >, 0);
246   g_bytes_unref (bytes2);
247
248   bytes2 = g_bytes_new ("blahblah", 8);
249   g_assert_cmpint (g_bytes_compare (bytes, bytes2), <, 0);
250   g_bytes_unref (bytes2);
251
252   bytes2 = g_bytes_new ("zyx", 3);
253   g_assert_cmpint (g_bytes_compare (bytes, bytes2), <, 0);
254   g_bytes_unref (bytes2);
255
256   bytes2 = g_bytes_new ("zyxw", 4);
257   g_assert_cmpint (g_bytes_compare (bytes, bytes2), <, 0);
258   g_bytes_unref (bytes2);
259
260   g_bytes_unref (bytes);
261 }
262
263 static void
264 test_to_data_transferred (void)
265 {
266   gconstpointer memory;
267   gpointer data;
268   gsize size;
269   GBytes *bytes;
270
271   /* Memory transferred: one reference, and allocated with g_malloc */
272   bytes = g_bytes_new (NYAN, N_NYAN);
273   memory = g_bytes_get_data (bytes, NULL);
274   data = g_bytes_unref_to_data (bytes, &size);
275   g_assert (data == memory);
276   g_assert_cmpmem (data, size, NYAN, N_NYAN);
277   g_free (data);
278 }
279
280 static void
281 test_to_data_two_refs (void)
282 {
283   gconstpointer memory;
284   gpointer data;
285   gsize size;
286   GBytes *bytes;
287
288   /* Memory copied: two references */
289   bytes = g_bytes_new (NYAN, N_NYAN);
290   bytes = g_bytes_ref (bytes);
291   memory = g_bytes_get_data (bytes, NULL);
292   data = g_bytes_unref_to_data (bytes, &size);
293   g_assert (data != memory);
294   g_assert_cmpmem (data, size, NYAN, N_NYAN);
295   g_free (data);
296   g_assert (g_bytes_get_data (bytes, &size) == memory);
297   g_assert_cmpuint (size, ==, N_NYAN);
298   g_assert_cmpuint (g_bytes_get_size (bytes), ==, N_NYAN);
299   g_bytes_unref (bytes);
300 }
301
302 static void
303 test_to_data_non_malloc (void)
304 {
305   gpointer data;
306   gsize size;
307   GBytes *bytes;
308
309   /* Memory copied: non malloc memory */
310   bytes = g_bytes_new_static (NYAN, N_NYAN);
311   g_assert (g_bytes_get_data (bytes, NULL) == NYAN);
312   data = g_bytes_unref_to_data (bytes, &size);
313   g_assert (data != (gpointer)NYAN);
314   g_assert_cmpmem (data, size, NYAN, N_NYAN);
315   g_free (data);
316 }
317
318 static void
319 test_to_array_transferred (void)
320 {
321   gconstpointer memory;
322   GByteArray *array;
323   GBytes *bytes;
324
325   /* Memory transferred: one reference, and allocated with g_malloc */
326   bytes = g_bytes_new (NYAN, N_NYAN);
327   memory = g_bytes_get_data (bytes, NULL);
328   array = g_bytes_unref_to_array (bytes);
329   g_assert (array != NULL);
330   g_assert (array->data == memory);
331   g_assert_cmpmem (array->data, array->len, NYAN, N_NYAN);
332   g_byte_array_unref (array);
333 }
334
335 static void
336 test_to_array_transferred_oversize (void)
337 {
338   g_test_message ("g_bytes_unref_to_array() can only take GBytes up to "
339                   "G_MAXUINT in length; test that longer ones are rejected");
340
341   if (sizeof (guint) >= sizeof (gsize))
342     {
343       g_test_skip ("Skipping test as guint is not smaller than gsize");
344     }
345   else if (g_test_undefined ())
346     {
347       GByteArray *array = NULL;
348       GBytes *bytes = NULL;
349       gpointer data = g_memdup2 (NYAN, N_NYAN);
350       gsize len = ((gsize) G_MAXUINT) + 1;
351
352       bytes = g_bytes_new_take (data, len);
353       g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL,
354                              "g_byte_array_new_take: assertion 'len <= G_MAXUINT' failed");
355       array = g_bytes_unref_to_array (g_steal_pointer (&bytes));
356       g_test_assert_expected_messages ();
357       g_assert_null (array);
358
359       g_free (data);
360     }
361   else
362     {
363       g_test_skip ("Skipping test as testing undefined behaviour is disabled");
364     }
365 }
366
367 static void
368 test_to_array_two_refs (void)
369 {
370   gconstpointer memory;
371   GByteArray *array;
372   GBytes *bytes;
373   gsize size;
374
375   /* Memory copied: two references */
376   bytes = g_bytes_new (NYAN, N_NYAN);
377   bytes = g_bytes_ref (bytes);
378   memory = g_bytes_get_data (bytes, NULL);
379   array = g_bytes_unref_to_array (bytes);
380   g_assert (array != NULL);
381   g_assert (array->data != memory);
382   g_assert_cmpmem (array->data, array->len, NYAN, N_NYAN);
383   g_byte_array_unref (array);
384   g_assert (g_bytes_get_data (bytes, &size) == memory);
385   g_assert_cmpuint (size, ==, N_NYAN);
386   g_assert_cmpuint (g_bytes_get_size (bytes), ==, N_NYAN);
387   g_bytes_unref (bytes);
388 }
389
390 static void
391 test_to_array_non_malloc (void)
392 {
393   GByteArray *array;
394   GBytes *bytes;
395
396   /* Memory copied: non malloc memory */
397   bytes = g_bytes_new_static (NYAN, N_NYAN);
398   g_assert (g_bytes_get_data (bytes, NULL) == NYAN);
399   array = g_bytes_unref_to_array (bytes);
400   g_assert (array != NULL);
401   g_assert (array->data != (gpointer)NYAN);
402   g_assert_cmpmem (array->data, array->len, NYAN, N_NYAN);
403   g_byte_array_unref (array);
404 }
405
406 static void
407 test_null (void)
408 {
409   GBytes *bytes;
410   gpointer data;
411   gsize size;
412
413   bytes = g_bytes_new (NULL, 0);
414
415   data = g_bytes_unref_to_data (bytes, &size);
416
417   g_assert (data == NULL);
418   g_assert (size == 0);
419 }
420
421 int
422 main (int argc, char *argv[])
423 {
424   g_test_init (&argc, &argv, NULL);
425
426   g_test_bug_base ("https://bugzilla.gnome.org/");
427
428   g_test_add_func ("/bytes/new", test_new);
429   g_test_add_func ("/bytes/new-take", test_new_take);
430   g_test_add_func ("/bytes/new-static", test_new_static);
431   g_test_add_func ("/bytes/new-with-free-func", test_new_with_free_func);
432   g_test_add_func ("/bytes/new-from-bytes", test_new_from_bytes);
433   g_test_add_func ("/bytes/new-from-bytes-slice", test_new_from_bytes_slice);
434   g_test_add_func ("/bytes/new-from-bytes-shared-ref", test_new_from_bytes_shared_ref);
435   g_test_add_func ("/bytes/hash", test_hash);
436   g_test_add_func ("/bytes/equal", test_equal);
437   g_test_add_func ("/bytes/compare", test_compare);
438   g_test_add_func ("/bytes/to-data/transferred", test_to_data_transferred);
439   g_test_add_func ("/bytes/to-data/two-refs", test_to_data_two_refs);
440   g_test_add_func ("/bytes/to-data/non-malloc", test_to_data_non_malloc);
441   g_test_add_func ("/bytes/to-array/transferred", test_to_array_transferred);
442   g_test_add_func ("/bytes/to-array/transferred/oversize", test_to_array_transferred_oversize);
443   g_test_add_func ("/bytes/to-array/two-refs", test_to_array_two_refs);
444   g_test_add_func ("/bytes/to-array/non-malloc", test_to_array_non_malloc);
445   g_test_add_func ("/bytes/null", test_null);
446
447   return g_test_run ();
448 }