1#ifndef GLIB_DISABLE_DEPRECATION_WARNINGS
2#define GLIB_DISABLE_DEPRECATION_WARNINGS
3#endif
4
5#include <glib-object.h>
6
7typedef struct _MyBoxed MyBoxed;
8
9struct _MyBoxed
10{
11 gint ivalue;
12 gchar *bla;
13};
14
15static gpointer
16my_boxed_copy (gpointer orig)
17{
18 MyBoxed *a = orig;
19 MyBoxed *b;
20
21 b = g_slice_new (MyBoxed);
22 b->ivalue = a->ivalue;
23 b->bla = g_strdup (str: a->bla);
24
25 return b;
26}
27
28static gint my_boxed_free_count;
29
30static void
31my_boxed_free (gpointer orig)
32{
33 MyBoxed *a = orig;
34
35 g_free (mem: a->bla);
36 g_slice_free (MyBoxed, a);
37
38 my_boxed_free_count++;
39}
40
41static GType my_boxed_get_type (void);
42#define MY_TYPE_BOXED (my_boxed_get_type ())
43
44G_DEFINE_BOXED_TYPE (MyBoxed, my_boxed, my_boxed_copy, my_boxed_free)
45
46static void
47test_define_boxed (void)
48{
49 MyBoxed a;
50 MyBoxed *b;
51
52 a.ivalue = 20;
53 a.bla = g_strdup (str: "bla");
54
55 b = g_boxed_copy (MY_TYPE_BOXED, src_boxed: &a);
56
57 g_assert_cmpint (b->ivalue, ==, 20);
58 g_assert_cmpstr (b->bla, ==, "bla");
59
60 g_boxed_free (MY_TYPE_BOXED, boxed: b);
61
62 g_free (mem: a.bla);
63}
64
65static void
66test_boxed_ownership (void)
67{
68 GValue value = G_VALUE_INIT;
69 static MyBoxed boxed = { 10, "bla" };
70
71 g_value_init (value: &value, MY_TYPE_BOXED);
72
73 my_boxed_free_count = 0;
74
75 g_value_set_static_boxed (value: &value, v_boxed: &boxed);
76 g_value_reset (value: &value);
77
78 g_assert_cmpint (my_boxed_free_count, ==, 0);
79
80 g_value_set_boxed_take_ownership (value: &value, v_boxed: g_boxed_copy (MY_TYPE_BOXED, src_boxed: &boxed));
81 g_value_reset (value: &value);
82 g_assert_cmpint (my_boxed_free_count, ==, 1);
83
84 g_value_take_boxed (value: &value, v_boxed: g_boxed_copy (MY_TYPE_BOXED, src_boxed: &boxed));
85 g_value_reset (value: &value);
86 g_assert_cmpint (my_boxed_free_count, ==, 2);
87
88 g_value_set_boxed (value: &value, v_boxed: &boxed);
89 g_value_reset (value: &value);
90 g_assert_cmpint (my_boxed_free_count, ==, 3);
91}
92
93static void
94my_callback (gpointer user_data)
95{
96}
97
98static gint destroy_count;
99
100static void
101my_closure_notify (gpointer user_data, GClosure *closure)
102{
103 destroy_count++;
104}
105
106static void
107test_boxed_closure (void)
108{
109 GClosure *closure;
110 GClosure *closure2;
111 GValue value = G_VALUE_INIT;
112
113 g_value_init (value: &value, G_TYPE_CLOSURE);
114 g_assert (G_VALUE_HOLDS_BOXED (&value));
115
116 closure = g_cclosure_new (G_CALLBACK (my_callback), user_data: "bla", destroy_data: my_closure_notify);
117 g_value_take_boxed (value: &value, v_boxed: closure);
118
119 closure2 = g_value_get_boxed (value: &value);
120 g_assert (closure2 == closure);
121
122 closure2 = g_value_dup_boxed (value: &value);
123 g_assert (closure2 == closure); /* closures use ref/unref for copy/free */
124 g_closure_unref (closure: closure2);
125
126 g_value_unset (value: &value);
127 g_assert_cmpint (destroy_count, ==, 1);
128}
129
130static void
131test_boxed_date (void)
132{
133 GDate *date;
134 GDate *date2;
135 GValue value = G_VALUE_INIT;
136
137 g_value_init (value: &value, G_TYPE_DATE);
138 g_assert (G_VALUE_HOLDS_BOXED (&value));
139
140 date = g_date_new_dmy (day: 1, month: 3, year: 1970);
141 g_value_take_boxed (value: &value, v_boxed: date);
142
143 date2 = g_value_get_boxed (value: &value);
144 g_assert (date2 == date);
145
146 date2 = g_value_dup_boxed (value: &value);
147 g_assert (date2 != date);
148 g_assert (g_date_compare (date, date2) == 0);
149 g_date_free (date: date2);
150
151 g_value_unset (value: &value);
152}
153
154static void
155test_boxed_value (void)
156{
157 GValue value1 = G_VALUE_INIT;
158 GValue *value2;
159 GValue value = G_VALUE_INIT;
160
161 g_value_init (value: &value, G_TYPE_VALUE);
162 g_assert (G_VALUE_HOLDS_BOXED (&value));
163
164 g_value_init (value: &value1, G_TYPE_INT);
165 g_value_set_int (value: &value1, v_int: 26);
166
167 g_value_set_static_boxed (value: &value, v_boxed: &value1);
168
169 value2 = g_value_get_boxed (value: &value);
170 g_assert (value2 == &value1);
171
172 value2 = g_value_dup_boxed (value: &value);
173 g_assert (value2 != &value1);
174 g_assert (G_VALUE_HOLDS_INT (value2));
175 g_assert_cmpint (g_value_get_int (value2), ==, 26);
176 g_boxed_free (G_TYPE_VALUE, boxed: value2);
177
178 g_value_unset (value: &value);
179}
180
181static void
182test_boxed_string (void)
183{
184 GString *v;
185 GString *v2;
186 GValue value = G_VALUE_INIT;
187
188 g_value_init (value: &value, G_TYPE_GSTRING);
189 g_assert (G_VALUE_HOLDS_BOXED (&value));
190
191 v = g_string_new (init: "bla");
192 g_value_take_boxed (value: &value, v_boxed: v);
193
194 v2 = g_value_get_boxed (value: &value);
195 g_assert (v2 == v);
196
197 v2 = g_value_dup_boxed (value: &value);
198 g_assert (v2 != v);
199 g_assert (g_string_equal (v, v2));
200 g_string_free (string: v2, TRUE);
201
202 g_value_unset (value: &value);
203}
204
205static void
206test_boxed_hashtable (void)
207{
208 GHashTable *v;
209 GHashTable *v2;
210 GValue value = G_VALUE_INIT;
211
212 g_value_init (value: &value, G_TYPE_HASH_TABLE);
213 g_assert (G_VALUE_HOLDS_BOXED (&value));
214
215 v = g_hash_table_new (hash_func: g_str_hash, key_equal_func: g_str_equal);
216 g_value_take_boxed (value: &value, v_boxed: v);
217
218 v2 = g_value_get_boxed (value: &value);
219 g_assert (v2 == v);
220
221 v2 = g_value_dup_boxed (value: &value);
222 g_assert (v2 == v); /* hash tables use ref/unref for copy/free */
223 g_hash_table_unref (hash_table: v2);
224
225 g_value_unset (value: &value);
226}
227
228static void
229test_boxed_array (void)
230{
231 GArray *v;
232 GArray *v2;
233 GValue value = G_VALUE_INIT;
234
235 g_value_init (value: &value, G_TYPE_ARRAY);
236 g_assert (G_VALUE_HOLDS_BOXED (&value));
237
238 v = g_array_new (TRUE, FALSE, element_size: 1);
239 g_value_take_boxed (value: &value, v_boxed: v);
240
241 v2 = g_value_get_boxed (value: &value);
242 g_assert (v2 == v);
243
244 v2 = g_value_dup_boxed (value: &value);
245 g_assert (v2 == v); /* arrays use ref/unref for copy/free */
246 g_array_unref (array: v2);
247
248 g_value_unset (value: &value);
249}
250
251static void
252test_boxed_ptrarray (void)
253{
254 GPtrArray *v;
255 GPtrArray *v2;
256 GValue value = G_VALUE_INIT;
257
258 g_value_init (value: &value, G_TYPE_PTR_ARRAY);
259 g_assert (G_VALUE_HOLDS_BOXED (&value));
260
261 v = g_ptr_array_new ();
262 g_value_take_boxed (value: &value, v_boxed: v);
263
264 v2 = g_value_get_boxed (value: &value);
265 g_assert (v2 == v);
266
267 v2 = g_value_dup_boxed (value: &value);
268 g_assert (v2 == v); /* ptr arrays use ref/unref for copy/free */
269 g_ptr_array_unref (array: v2);
270
271 g_value_unset (value: &value);
272}
273
274static void
275test_boxed_regex (void)
276{
277 GRegex *v;
278 GRegex *v2;
279 GValue value = G_VALUE_INIT;
280
281 g_value_init (value: &value, G_TYPE_REGEX);
282 g_assert (G_VALUE_HOLDS_BOXED (&value));
283
284 v = g_regex_new (pattern: "a+b+", compile_options: 0, match_options: 0, NULL);
285 g_value_take_boxed (value: &value, v_boxed: v);
286
287 v2 = g_value_get_boxed (value: &value);
288 g_assert (v2 == v);
289
290 v2 = g_value_dup_boxed (value: &value);
291 g_assert (v2 == v); /* regexes use ref/unref for copy/free */
292 g_regex_unref (regex: v2);
293
294 g_value_unset (value: &value);
295}
296
297static void
298test_boxed_matchinfo (void)
299{
300 GRegex *r;
301 GMatchInfo *info, *info2;
302 gboolean ret;
303 GValue value = G_VALUE_INIT;
304
305 g_value_init (value: &value, G_TYPE_MATCH_INFO);
306 g_assert (G_VALUE_HOLDS_BOXED (&value));
307
308 r = g_regex_new (pattern: "ab", compile_options: 0, match_options: 0, NULL);
309 ret = g_regex_match (regex: r, string: "blabla abab bla", match_options: 0, match_info: &info);
310 g_assert (ret);
311 g_value_take_boxed (value: &value, v_boxed: info);
312
313 info2 = g_value_get_boxed (value: &value);
314 g_assert (info == info2);
315
316 info2 = g_value_dup_boxed (value: &value);
317 g_assert (info == info2); /* matchinfo uses ref/unref for copy/free */
318 g_match_info_unref (match_info: info2);
319
320 g_value_unset (value: &value);
321 g_regex_unref (regex: r);
322}
323
324static void
325test_boxed_varianttype (void)
326{
327 GVariantType *v;
328 GVariantType *v2;
329 GValue value = G_VALUE_INIT;
330
331 g_value_init (value: &value, G_TYPE_VARIANT_TYPE);
332 g_assert (G_VALUE_HOLDS_BOXED (&value));
333
334 v = g_variant_type_new (type_string: "mas");
335 g_value_take_boxed (value: &value, v_boxed: v);
336
337 v2 = g_value_get_boxed (value: &value);
338 g_assert (v2 == v);
339
340 v2 = g_value_dup_boxed (value: &value);
341 g_assert (v2 != v);
342 g_assert_cmpstr (g_variant_type_peek_string (v), ==, g_variant_type_peek_string (v2));
343 g_variant_type_free (type: v2);
344
345 g_value_unset (value: &value);
346}
347
348static void
349test_boxed_datetime (void)
350{
351 GDateTime *v;
352 GDateTime *v2;
353 GValue value = G_VALUE_INIT;
354
355 g_value_init (value: &value, G_TYPE_DATE_TIME);
356 g_assert (G_VALUE_HOLDS_BOXED (&value));
357
358 v = g_date_time_new_now_local ();
359 g_value_take_boxed (value: &value, v_boxed: v);
360
361 v2 = g_value_get_boxed (value: &value);
362 g_assert (v2 == v);
363
364 v2 = g_value_dup_boxed (value: &value);
365 g_assert (v2 == v); /* datetime uses ref/unref for copy/free */
366 g_date_time_unref (datetime: v2);
367
368 g_value_unset (value: &value);
369}
370
371static void
372test_boxed_error (void)
373{
374 GError *v;
375 GError *v2;
376 GValue value = G_VALUE_INIT;
377
378 g_value_init (value: &value, G_TYPE_ERROR);
379 g_assert (G_VALUE_HOLDS_BOXED (&value));
380
381 v = g_error_new_literal (G_VARIANT_PARSE_ERROR,
382 code: G_VARIANT_PARSE_ERROR_NUMBER_TOO_BIG,
383 message: "Too damn big");
384 g_value_take_boxed (value: &value, v_boxed: v);
385
386 v2 = g_value_get_boxed (value: &value);
387 g_assert (v2 == v);
388
389 v2 = g_value_dup_boxed (value: &value);
390 g_assert (v2 != v);
391 g_assert_cmpint (v->domain, ==, v2->domain);
392 g_assert_cmpint (v->code, ==, v2->code);
393 g_assert_cmpstr (v->message, ==, v2->message);
394 g_error_free (error: v2);
395
396 g_value_unset (value: &value);
397}
398
399static void
400test_boxed_keyfile (void)
401{
402 GKeyFile *k, *k2;
403 GValue value = G_VALUE_INIT;
404
405 g_value_init (value: &value, G_TYPE_KEY_FILE);
406 g_assert (G_VALUE_HOLDS_BOXED (&value));
407
408 k = g_key_file_new ();
409 g_value_take_boxed (value: &value, v_boxed: k);
410
411 k2 = g_value_get_boxed (value: &value);
412 g_assert (k == k2);
413
414 k2 = g_value_dup_boxed (value: &value);
415 g_assert (k == k2); /* keyfile uses ref/unref for copy/free */
416 g_key_file_unref (key_file: k2);
417
418 g_value_unset (value: &value);
419}
420
421static void
422test_boxed_mainloop (void)
423{
424 GMainLoop *l, *l2;
425 GValue value = G_VALUE_INIT;
426
427 g_value_init (value: &value, G_TYPE_MAIN_LOOP);
428 g_assert (G_VALUE_HOLDS_BOXED (&value));
429
430 l = g_main_loop_new (NULL, FALSE);
431 g_value_take_boxed (value: &value, v_boxed: l);
432
433 l2 = g_value_get_boxed (value: &value);
434 g_assert (l == l2);
435
436 l2 = g_value_dup_boxed (value: &value);
437 g_assert (l == l2); /* mainloop uses ref/unref for copy/free */
438 g_main_loop_unref (loop: l2);
439
440 g_value_unset (value: &value);
441}
442
443static void
444test_boxed_maincontext (void)
445{
446 GMainContext *c, *c2;
447 GValue value = G_VALUE_INIT;
448
449 g_value_init (value: &value, G_TYPE_MAIN_CONTEXT);
450 g_assert (G_VALUE_HOLDS_BOXED (&value));
451
452 c = g_main_context_new ();
453 g_value_take_boxed (value: &value, v_boxed: c);
454
455 c2 = g_value_get_boxed (value: &value);
456 g_assert (c == c2);
457
458 c2 = g_value_dup_boxed (value: &value);
459 g_assert (c == c2); /* maincontext uses ref/unref for copy/free */
460 g_main_context_unref (context: c2);
461
462 g_value_unset (value: &value);
463}
464
465static void
466test_boxed_source (void)
467{
468 GSource *s, *s2;
469 GValue value = G_VALUE_INIT;
470
471 g_value_init (value: &value, G_TYPE_SOURCE);
472 g_assert (G_VALUE_HOLDS_BOXED (&value));
473
474 s = g_idle_source_new ();
475 g_value_take_boxed (value: &value, v_boxed: s);
476
477 s2 = g_value_get_boxed (value: &value);
478 g_assert (s == s2);
479
480 s2 = g_value_dup_boxed (value: &value);
481 g_assert (s == s2); /* source uses ref/unref for copy/free */
482 g_source_unref (source: s2);
483
484 g_value_unset (value: &value);
485}
486
487static void
488test_boxed_variantbuilder (void)
489{
490 GVariantBuilder *v, *v2;
491 GValue value = G_VALUE_INIT;
492
493 g_value_init (value: &value, G_TYPE_VARIANT_BUILDER);
494 g_assert (G_VALUE_HOLDS_BOXED (&value));
495
496 v = g_variant_builder_new (G_VARIANT_TYPE_OBJECT_PATH_ARRAY);
497 g_value_take_boxed (value: &value, v_boxed: v);
498
499 v2 = g_value_get_boxed (value: &value);
500 g_assert (v == v2);
501
502 v2 = g_value_dup_boxed (value: &value);
503 g_assert (v == v2); /* variantbuilder uses ref/unref for copy/free */
504 g_variant_builder_unref (builder: v2);
505
506 g_value_unset (value: &value);
507}
508
509static void
510test_boxed_timezone (void)
511{
512 GTimeZone *z, *z2;
513 GValue value = G_VALUE_INIT;
514
515 g_value_init (value: &value, G_TYPE_TIME_ZONE);
516 g_assert (G_VALUE_HOLDS_BOXED (&value));
517
518 z = g_time_zone_new_utc ();
519 g_value_take_boxed (value: &value, v_boxed: z);
520
521 z2 = g_value_get_boxed (value: &value);
522 g_assert (z == z2);
523
524 z2 = g_value_dup_boxed (value: &value);
525 g_assert (z == z2); /* timezone uses ref/unref for copy/free */
526 g_time_zone_unref (tz: z2);
527
528 g_value_unset (value: &value);
529}
530
531static void
532test_boxed_pollfd (void)
533{
534 GPollFD *p, *p2;
535 GValue value = G_VALUE_INIT;
536
537 g_value_init (value: &value, G_TYPE_POLLFD);
538 g_assert (G_VALUE_HOLDS_BOXED (&value));
539
540 p = g_new (GPollFD, 1);
541 g_value_take_boxed (value: &value, v_boxed: p);
542
543 p2 = g_value_get_boxed (value: &value);
544 g_assert (p == p2);
545
546 p2 = g_value_dup_boxed (value: &value);
547 g_assert (p != p2);
548 g_free (mem: p2);
549
550 g_value_unset (value: &value);
551}
552
553static void
554test_boxed_markup (void)
555{
556 GMarkupParseContext *c, *c2;
557 const GMarkupParser parser = { 0 };
558 GValue value = G_VALUE_INIT;
559
560 g_value_init (value: &value, G_TYPE_MARKUP_PARSE_CONTEXT);
561 g_assert (G_VALUE_HOLDS_BOXED (&value));
562
563 c = g_markup_parse_context_new (parser: &parser, flags: 0, NULL, NULL);
564 g_value_take_boxed (value: &value, v_boxed: c);
565
566 c2 = g_value_get_boxed (value: &value);
567 g_assert (c == c2);
568
569 c2 = g_value_dup_boxed (value: &value);
570 g_assert (c == c2);
571 g_markup_parse_context_unref (context: c2);
572
573 g_value_unset (value: &value);
574}
575
576static void
577test_boxed_thread (void)
578{
579 GThread *t, *t2;
580 GValue value = G_VALUE_INIT;
581
582 g_value_init (value: &value, G_TYPE_THREAD);
583 g_assert (G_VALUE_HOLDS_BOXED (&value));
584
585 t = g_thread_self ();
586 g_value_set_boxed (value: &value, v_boxed: t);
587
588 t2 = g_value_get_boxed (value: &value);
589 g_assert (t == t2);
590
591 t2 = g_value_dup_boxed (value: &value);
592 g_assert (t == t2);
593 g_thread_unref (thread: t2);
594
595 g_value_unset (value: &value);
596}
597
598static void
599test_boxed_checksum (void)
600{
601 GChecksum *c, *c2;
602 GValue value = G_VALUE_INIT;
603
604 g_value_init (value: &value, G_TYPE_CHECKSUM);
605 g_assert (G_VALUE_HOLDS_BOXED (&value));
606
607 c = g_checksum_new (checksum_type: G_CHECKSUM_SHA512);
608 g_value_take_boxed (value: &value, v_boxed: c);
609
610 c2 = g_value_get_boxed (value: &value);
611 g_assert (c == c2);
612
613 c2 = g_value_dup_boxed (value: &value);
614 g_assert (c != c2);
615 g_checksum_free (checksum: c2);
616
617 g_value_unset (value: &value);
618}
619
620static gint
621treecmp (gconstpointer a, gconstpointer b)
622{
623 return (a < b) ? -1 : (a > b);
624}
625
626static void
627test_boxed_tree (void)
628{
629 GTree *t, *t2;
630 GValue value = G_VALUE_INIT;
631
632 g_value_init (value: &value, G_TYPE_TREE);
633 g_assert_true (G_VALUE_HOLDS_BOXED (&value));
634
635 t = g_tree_new (key_compare_func: treecmp);
636 g_value_take_boxed (value: &value, v_boxed: t);
637
638 t2 = g_value_get_boxed (value: &value);
639 g_assert_true (t == t2);
640
641 t2 = g_value_dup_boxed (value: &value);
642 g_assert_true (t == t2); /* trees use ref/unref for copy/free */
643 g_tree_unref (tree: t2);
644
645 g_value_unset (value: &value);
646}
647
648int
649main (int argc, char *argv[])
650{
651 g_test_init (argc: &argc, argv: &argv, NULL);
652
653 g_test_add_func (testpath: "/boxed/define", test_func: test_define_boxed);
654 g_test_add_func (testpath: "/boxed/ownership", test_func: test_boxed_ownership);
655 g_test_add_func (testpath: "/boxed/closure", test_func: test_boxed_closure);
656 g_test_add_func (testpath: "/boxed/date", test_func: test_boxed_date);
657 g_test_add_func (testpath: "/boxed/value", test_func: test_boxed_value);
658 g_test_add_func (testpath: "/boxed/string", test_func: test_boxed_string);
659 g_test_add_func (testpath: "/boxed/hashtable", test_func: test_boxed_hashtable);
660 g_test_add_func (testpath: "/boxed/array", test_func: test_boxed_array);
661 g_test_add_func (testpath: "/boxed/ptrarray", test_func: test_boxed_ptrarray);
662 g_test_add_func (testpath: "/boxed/regex", test_func: test_boxed_regex);
663 g_test_add_func (testpath: "/boxed/varianttype", test_func: test_boxed_varianttype);
664 g_test_add_func (testpath: "/boxed/error", test_func: test_boxed_error);
665 g_test_add_func (testpath: "/boxed/datetime", test_func: test_boxed_datetime);
666 g_test_add_func (testpath: "/boxed/matchinfo", test_func: test_boxed_matchinfo);
667 g_test_add_func (testpath: "/boxed/keyfile", test_func: test_boxed_keyfile);
668 g_test_add_func (testpath: "/boxed/mainloop", test_func: test_boxed_mainloop);
669 g_test_add_func (testpath: "/boxed/maincontext", test_func: test_boxed_maincontext);
670 g_test_add_func (testpath: "/boxed/source", test_func: test_boxed_source);
671 g_test_add_func (testpath: "/boxed/variantbuilder", test_func: test_boxed_variantbuilder);
672 g_test_add_func (testpath: "/boxed/timezone", test_func: test_boxed_timezone);
673 g_test_add_func (testpath: "/boxed/pollfd", test_func: test_boxed_pollfd);
674 g_test_add_func (testpath: "/boxed/markup", test_func: test_boxed_markup);
675 g_test_add_func (testpath: "/boxed/thread", test_func: test_boxed_thread);
676 g_test_add_func (testpath: "/boxed/checksum", test_func: test_boxed_checksum);
677 g_test_add_func (testpath: "/boxed/tree", test_func: test_boxed_tree);
678
679 return g_test_run ();
680}
681

source code of gtk/subprojects/glib/gobject/tests/boxed.c