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