Update German translation
[glib.git] / gobject / tests / reference.c
blobaefa1e89474128de8134b4ef1429bbd9a4f40ab1
1 #include <glib-object.h>
3 static void
4 test_fundamentals (void)
6 g_assert (G_TYPE_IS_FUNDAMENTAL (G_TYPE_NONE));
7 g_assert (G_TYPE_IS_FUNDAMENTAL (G_TYPE_INTERFACE));
8 g_assert (G_TYPE_IS_FUNDAMENTAL (G_TYPE_CHAR));
9 g_assert (G_TYPE_IS_FUNDAMENTAL (G_TYPE_UCHAR));
10 g_assert (G_TYPE_IS_FUNDAMENTAL (G_TYPE_BOOLEAN));
11 g_assert (G_TYPE_IS_FUNDAMENTAL (G_TYPE_INT));
12 g_assert (G_TYPE_IS_FUNDAMENTAL (G_TYPE_UINT));
13 g_assert (G_TYPE_IS_FUNDAMENTAL (G_TYPE_LONG));
14 g_assert (G_TYPE_IS_FUNDAMENTAL (G_TYPE_ULONG));
15 g_assert (G_TYPE_IS_FUNDAMENTAL (G_TYPE_INT64));
16 g_assert (G_TYPE_IS_FUNDAMENTAL (G_TYPE_UINT64));
17 g_assert (G_TYPE_IS_FUNDAMENTAL (G_TYPE_ENUM));
18 g_assert (G_TYPE_IS_FUNDAMENTAL (G_TYPE_FLAGS));
19 g_assert (G_TYPE_IS_FUNDAMENTAL (G_TYPE_FLOAT));
20 g_assert (G_TYPE_IS_FUNDAMENTAL (G_TYPE_DOUBLE));
21 g_assert (G_TYPE_IS_FUNDAMENTAL (G_TYPE_STRING));
22 g_assert (G_TYPE_IS_FUNDAMENTAL (G_TYPE_POINTER));
23 g_assert (G_TYPE_IS_FUNDAMENTAL (G_TYPE_BOXED));
24 g_assert (G_TYPE_IS_FUNDAMENTAL (G_TYPE_PARAM));
25 g_assert (G_TYPE_IS_FUNDAMENTAL (G_TYPE_OBJECT));
26 g_assert (G_TYPE_OBJECT == g_object_get_type ());
27 g_assert (G_TYPE_IS_FUNDAMENTAL (G_TYPE_VARIANT));
28 g_assert (G_TYPE_IS_DERIVED (G_TYPE_INITIALLY_UNOWNED));
30 g_assert (g_type_fundamental_next () == G_TYPE_MAKE_FUNDAMENTAL (G_TYPE_RESERVED_USER_FIRST));
33 static void
34 test_type_qdata (void)
36 gchar *data;
38 g_type_set_qdata (G_TYPE_ENUM, g_quark_from_string ("bla"), "bla");
39 data = g_type_get_qdata (G_TYPE_ENUM, g_quark_from_string ("bla"));
40 g_assert_cmpstr (data, ==, "bla");
43 static void
44 test_type_query (void)
46 GTypeQuery query;
48 g_type_query (G_TYPE_ENUM, &query);
49 g_assert_cmpint (query.type, ==, G_TYPE_ENUM);
50 g_assert_cmpstr (query.type_name, ==, "GEnum");
51 g_assert_cmpint (query.class_size, ==, sizeof (GEnumClass));
52 g_assert_cmpint (query.instance_size, ==, 0);
55 typedef struct _MyObject MyObject;
56 typedef struct _MyObjectClass MyObjectClass;
57 typedef struct _MyObjectClassPrivate MyObjectClassPrivate;
59 struct _MyObject
61 GObject parent_instance;
63 gint count;
66 struct _MyObjectClass
68 GObjectClass parent_class;
71 struct _MyObjectClassPrivate
73 gint secret_class_count;
76 static GType my_object_get_type (void);
77 G_DEFINE_TYPE_WITH_CODE (MyObject, my_object, G_TYPE_OBJECT,
78 g_type_add_class_private (g_define_type_id, sizeof (MyObjectClassPrivate)) );
80 static void
81 my_object_init (MyObject *obj)
83 obj->count = 42;
86 static void
87 my_object_class_init (MyObjectClass *klass)
91 static void
92 test_class_private (void)
94 GObject *obj;
95 MyObjectClass *class;
96 MyObjectClassPrivate *priv;
98 obj = g_object_new (my_object_get_type (), NULL);
100 class = g_type_class_ref (my_object_get_type ());
101 priv = G_TYPE_CLASS_GET_PRIVATE (class, my_object_get_type (), MyObjectClassPrivate);
102 priv->secret_class_count = 13;
103 g_type_class_unref (class);
105 g_object_unref (obj);
107 g_assert_cmpint (g_type_qname (my_object_get_type ()), ==, g_quark_from_string ("MyObject"));
110 static void
111 test_clear (void)
113 GObject *o = NULL;
114 GObject *tmp;
116 g_clear_object (&o);
117 g_assert (o == NULL);
119 tmp = g_object_new (G_TYPE_OBJECT, NULL);
120 g_assert_cmpint (tmp->ref_count, ==, 1);
121 o = g_object_ref (tmp);
122 g_assert (o != NULL);
124 g_assert_cmpint (tmp->ref_count, ==, 2);
125 g_clear_object (&o);
126 g_assert_cmpint (tmp->ref_count, ==, 1);
127 g_assert (o == NULL);
129 g_object_unref (tmp);
132 static void
133 test_clear_function (void)
135 volatile GObject *o = NULL;
136 GObject *tmp;
138 (g_clear_object) (&o);
139 g_assert (o == NULL);
141 tmp = g_object_new (G_TYPE_OBJECT, NULL);
142 g_assert_cmpint (tmp->ref_count, ==, 1);
143 o = g_object_ref (tmp);
144 g_assert (o != NULL);
146 g_assert_cmpint (tmp->ref_count, ==, 2);
147 (g_clear_object) (&o);
148 g_assert_cmpint (tmp->ref_count, ==, 1);
149 g_assert (o == NULL);
151 g_object_unref (tmp);
154 static void
155 test_set (void)
157 GObject *o = NULL;
158 GObject *tmp;
160 g_assert (!g_set_object (&o, NULL));
161 g_assert (o == NULL);
163 tmp = g_object_new (G_TYPE_OBJECT, NULL);
164 g_assert_cmpint (tmp->ref_count, ==, 1);
166 g_assert (g_set_object (&o, tmp));
167 g_assert (o == tmp);
168 g_assert_cmpint (tmp->ref_count, ==, 2);
170 g_object_unref (tmp);
171 g_assert_cmpint (tmp->ref_count, ==, 1);
173 /* Setting it again shouldn’t cause finalisation. */
174 g_assert (!g_set_object (&o, tmp));
175 g_assert (o == tmp);
176 g_assert_cmpint (tmp->ref_count, ==, 1);
178 g_assert (g_set_object (&o, NULL));
179 g_assert (o == NULL);
180 g_assert (!G_IS_OBJECT (tmp)); /* finalised */
183 static void
184 test_set_function (void)
186 GObject *o = NULL;
187 GObject *tmp;
189 g_assert (!(g_set_object) (&o, NULL));
190 g_assert (o == NULL);
192 tmp = g_object_new (G_TYPE_OBJECT, NULL);
193 g_assert_cmpint (tmp->ref_count, ==, 1);
195 g_assert ((g_set_object) (&o, tmp));
196 g_assert (o == tmp);
197 g_assert_cmpint (tmp->ref_count, ==, 2);
199 g_object_unref (tmp);
200 g_assert_cmpint (tmp->ref_count, ==, 1);
202 /* Setting it again shouldn’t cause finalisation. */
203 g_assert (!(g_set_object) (&o, tmp));
204 g_assert (o == tmp);
205 g_assert_cmpint (tmp->ref_count, ==, 1);
207 g_assert ((g_set_object) (&o, NULL));
208 g_assert (o == NULL);
209 g_assert (!G_IS_OBJECT (tmp)); /* finalised */
212 static void
213 toggle_cb (gpointer data, GObject *obj, gboolean is_last)
215 gboolean *b = data;
217 *b = TRUE;
220 static void
221 test_object_value (void)
223 GObject *v;
224 GObject *v2;
225 GValue value = G_VALUE_INIT;
226 gboolean toggled = FALSE;
228 g_value_init (&value, G_TYPE_OBJECT);
230 v = g_object_new (G_TYPE_OBJECT, NULL);
231 g_object_add_toggle_ref (v, toggle_cb, &toggled);
233 g_value_take_object (&value, v);
235 v2 = g_value_get_object (&value);
236 g_assert (v2 == v);
238 v2 = g_value_dup_object (&value);
239 g_assert (v2 == v); /* objects use ref/unref for copy/free */
240 g_object_unref (v2);
242 g_assert (!toggled);
243 g_value_unset (&value);
244 g_assert (toggled);
246 /* test the deprecated variant too */
247 g_value_init (&value, G_TYPE_OBJECT);
248 /* get a new reference */
249 g_object_ref (v);
251 G_GNUC_BEGIN_IGNORE_DEPRECATIONS
252 g_value_set_object_take_ownership (&value, v);
253 G_GNUC_END_IGNORE_DEPRECATIONS
255 toggled = FALSE;
256 g_value_unset (&value);
257 g_assert (toggled);
259 g_object_remove_toggle_ref (v, toggle_cb, &toggled);
262 static void
263 test_initially_unowned (void)
265 GObject *obj;
267 obj = g_object_new (G_TYPE_INITIALLY_UNOWNED, NULL);
268 g_assert (g_object_is_floating (obj));
269 g_assert_cmpint (obj->ref_count, ==, 1);
271 g_object_ref_sink (obj);
272 g_assert (!g_object_is_floating (obj));
273 g_assert_cmpint (obj->ref_count, ==, 1);
275 g_object_ref_sink (obj);
276 g_assert (!g_object_is_floating (obj));
277 g_assert_cmpint (obj->ref_count, ==, 2);
279 g_object_unref (obj);
280 g_assert_cmpint (obj->ref_count, ==, 1);
282 g_object_force_floating (obj);
283 g_assert (g_object_is_floating (obj));
284 g_assert_cmpint (obj->ref_count, ==, 1);
286 g_object_ref_sink (obj);
287 g_object_unref (obj);
290 static void
291 test_weak_pointer (void)
293 GObject *obj;
294 gpointer weak;
295 gpointer weak2;
297 weak = weak2 = obj = g_object_new (G_TYPE_OBJECT, NULL);
298 g_assert_cmpint (obj->ref_count, ==, 1);
300 g_object_add_weak_pointer (obj, &weak);
301 g_object_add_weak_pointer (obj, &weak2);
302 g_assert_cmpint (obj->ref_count, ==, 1);
303 g_assert (weak == obj);
304 g_assert (weak2 == obj);
306 g_object_remove_weak_pointer (obj, &weak2);
307 g_assert_cmpint (obj->ref_count, ==, 1);
308 g_assert (weak == obj);
309 g_assert (weak2 == obj);
311 g_object_unref (obj);
312 g_assert (weak == NULL);
313 g_assert (weak2 == obj);
316 /* See gobject/tests/threadtests.c for the threaded version */
317 static void
318 test_weak_ref (void)
320 GObject *obj;
321 GObject *obj2;
322 GObject *tmp;
323 GWeakRef weak = { { GUINT_TO_POINTER (0xDEADBEEFU) } };
324 GWeakRef weak2 = { { GUINT_TO_POINTER (0xDEADBEEFU) } };
325 GWeakRef weak3 = { { GUINT_TO_POINTER (0xDEADBEEFU) } };
326 GWeakRef *dynamic_weak = g_new (GWeakRef, 1);
328 /* you can initialize to empty like this... */
329 g_weak_ref_init (&weak2, NULL);
330 g_assert (g_weak_ref_get (&weak2) == NULL);
332 /* ... or via an initializer */
333 g_weak_ref_init (&weak3, NULL);
334 g_assert (g_weak_ref_get (&weak3) == NULL);
336 obj = g_object_new (G_TYPE_OBJECT, NULL);
337 g_assert_cmpint (obj->ref_count, ==, 1);
339 obj2 = g_object_new (G_TYPE_OBJECT, NULL);
340 g_assert_cmpint (obj2->ref_count, ==, 1);
342 /* you can init with an object (even if uninitialized) */
343 g_weak_ref_init (&weak, obj);
344 g_weak_ref_init (dynamic_weak, obj);
345 /* or set to point at an object, if initialized (maybe to 0) */
346 g_weak_ref_set (&weak2, obj);
347 g_weak_ref_set (&weak3, obj);
348 /* none of this affects its refcount */
349 g_assert_cmpint (obj->ref_count, ==, 1);
351 /* getting the value takes a ref */
352 tmp = g_weak_ref_get (&weak);
353 g_assert (tmp == obj);
354 g_assert_cmpint (obj->ref_count, ==, 2);
355 g_object_unref (tmp);
356 g_assert_cmpint (obj->ref_count, ==, 1);
358 tmp = g_weak_ref_get (&weak2);
359 g_assert (tmp == obj);
360 g_assert_cmpint (obj->ref_count, ==, 2);
361 g_object_unref (tmp);
362 g_assert_cmpint (obj->ref_count, ==, 1);
364 tmp = g_weak_ref_get (&weak3);
365 g_assert (tmp == obj);
366 g_assert_cmpint (obj->ref_count, ==, 2);
367 g_object_unref (tmp);
368 g_assert_cmpint (obj->ref_count, ==, 1);
370 tmp = g_weak_ref_get (dynamic_weak);
371 g_assert (tmp == obj);
372 g_assert_cmpint (obj->ref_count, ==, 2);
373 g_object_unref (tmp);
374 g_assert_cmpint (obj->ref_count, ==, 1);
376 /* clearing a weak ref stops tracking */
377 g_weak_ref_clear (&weak);
379 /* setting a weak ref to NULL stops tracking too */
380 g_weak_ref_set (&weak2, NULL);
381 g_assert (g_weak_ref_get (&weak2) == NULL);
382 g_weak_ref_clear (&weak2);
384 /* setting a weak ref to a new object stops tracking the old one */
385 g_weak_ref_set (dynamic_weak, obj2);
386 tmp = g_weak_ref_get (dynamic_weak);
387 g_assert (tmp == obj2);
388 g_assert_cmpint (obj2->ref_count, ==, 2);
389 g_object_unref (tmp);
390 g_assert_cmpint (obj2->ref_count, ==, 1);
392 g_assert_cmpint (obj->ref_count, ==, 1);
394 /* free the object: weak3 is the only one left pointing there */
395 g_object_unref (obj);
396 g_assert (g_weak_ref_get (&weak3) == NULL);
398 /* setting a weak ref to a new object stops tracking the old one */
399 g_weak_ref_set (dynamic_weak, obj2);
400 tmp = g_weak_ref_get (dynamic_weak);
401 g_assert (tmp == obj2);
402 g_assert_cmpint (obj2->ref_count, ==, 2);
403 g_object_unref (tmp);
404 g_assert_cmpint (obj2->ref_count, ==, 1);
406 g_weak_ref_clear (&weak3);
408 /* clear and free dynamic_weak... */
409 g_weak_ref_clear (dynamic_weak);
411 /* ... to prove that doing so stops this from being a use-after-free */
412 g_object_unref (obj2);
413 g_free (dynamic_weak);
416 typedef struct
418 gboolean should_be_last;
419 gint count;
420 } Count;
422 static void
423 toggle_notify (gpointer data,
424 GObject *obj,
425 gboolean is_last)
427 Count *c = data;
429 g_assert (is_last == c->should_be_last);
431 c->count++;
434 static void
435 test_toggle_ref (void)
437 GObject *obj;
438 Count c, c2;
440 obj = g_object_new (G_TYPE_OBJECT, NULL);
442 g_object_add_toggle_ref (obj, toggle_notify, &c);
443 g_object_add_toggle_ref (obj, toggle_notify, &c2);
445 c.should_be_last = c2.should_be_last = TRUE;
446 c.count = c2.count = 0;
448 g_object_unref (obj);
450 g_assert_cmpint (c.count, ==, 0);
451 g_assert_cmpint (c2.count, ==, 0);
453 g_object_ref (obj);
455 g_assert_cmpint (c.count, ==, 0);
456 g_assert_cmpint (c2.count, ==, 0);
458 g_object_remove_toggle_ref (obj, toggle_notify, &c2);
460 g_object_unref (obj);
462 g_assert_cmpint (c.count, ==, 1);
464 c.should_be_last = FALSE;
466 g_object_ref (obj);
468 g_assert_cmpint (c.count, ==, 2);
470 c.should_be_last = TRUE;
472 g_object_unref (obj);
474 g_assert_cmpint (c.count, ==, 3);
476 g_object_remove_toggle_ref (obj, toggle_notify, &c);
479 static gboolean destroyed;
480 static gint value;
482 static void
483 data_destroy (gpointer data)
485 g_assert_cmpint (GPOINTER_TO_INT (data), ==, value);
487 destroyed = TRUE;
490 static void
491 test_object_qdata (void)
493 GObject *obj;
494 gpointer v;
495 GQuark quark;
497 obj = g_object_new (G_TYPE_OBJECT, NULL);
499 value = 1;
500 destroyed = FALSE;
501 g_object_set_data_full (obj, "test", GINT_TO_POINTER (1), data_destroy);
502 v = g_object_get_data (obj, "test");
503 g_assert_cmpint (GPOINTER_TO_INT (v), ==, 1);
504 g_object_set_data_full (obj, "test", GINT_TO_POINTER (2), data_destroy);
505 g_assert (destroyed);
506 value = 2;
507 destroyed = FALSE;
508 v = g_object_steal_data (obj, "test");
509 g_assert_cmpint (GPOINTER_TO_INT (v), ==, 2);
510 g_assert (!destroyed);
512 value = 1;
513 destroyed = FALSE;
514 quark = g_quark_from_string ("test");
515 g_object_set_qdata_full (obj, quark, GINT_TO_POINTER (1), data_destroy);
516 v = g_object_get_qdata (obj, quark);
517 g_assert_cmpint (GPOINTER_TO_INT (v), ==, 1);
518 g_object_set_qdata_full (obj, quark, GINT_TO_POINTER (2), data_destroy);
519 g_assert (destroyed);
520 value = 2;
521 destroyed = FALSE;
522 v = g_object_steal_qdata (obj, quark);
523 g_assert_cmpint (GPOINTER_TO_INT (v), ==, 2);
524 g_assert (!destroyed);
526 g_object_set_qdata_full (obj, quark, GINT_TO_POINTER (3), data_destroy);
527 value = 3;
528 destroyed = FALSE;
529 g_object_unref (obj);
531 g_assert (destroyed);
534 typedef struct {
535 const gchar *value;
536 gint refcount;
537 } Value;
539 static gpointer
540 ref_value (gpointer value, gpointer user_data)
542 Value *v = value;
543 Value **old_value_p = user_data;
545 if (old_value_p)
546 *old_value_p = v;
548 if (v)
549 v->refcount += 1;
551 return value;
554 static void
555 unref_value (gpointer value)
557 Value *v = value;
559 v->refcount -= 1;
560 if (v->refcount == 0)
561 g_free (value);
564 static
565 Value *
566 new_value (const gchar *s)
568 Value *v;
570 v = g_new (Value, 1);
571 v->value = s;
572 v->refcount = 1;
574 return v;
577 static void
578 test_object_qdata2 (void)
580 GObject *obj;
581 Value *v, *v1, *v2, *v3, *old_val;
582 GDestroyNotify old_destroy;
583 gboolean res;
585 obj = g_object_new (G_TYPE_OBJECT, NULL);
587 v1 = new_value ("bla");
589 g_object_set_data_full (obj, "test", v1, unref_value);
591 v = g_object_get_data (obj, "test");
592 g_assert_cmpstr (v->value, ==, "bla");
593 g_assert_cmpint (v->refcount, ==, 1);
595 v = g_object_dup_data (obj, "test", ref_value, &old_val);
596 g_assert (old_val == v1);
597 g_assert_cmpstr (v->value, ==, "bla");
598 g_assert_cmpint (v->refcount, ==, 2);
599 unref_value (v);
601 v = g_object_dup_data (obj, "nono", ref_value, &old_val);
602 g_assert (old_val == NULL);
603 g_assert (v == NULL);
605 v2 = new_value ("not");
607 res = g_object_replace_data (obj, "test", v1, v2, unref_value, &old_destroy);
608 g_assert (res == TRUE);
609 g_assert (old_destroy == unref_value);
610 g_assert_cmpstr (v1->value, ==, "bla");
611 g_assert_cmpint (v1->refcount, ==, 1);
613 v = g_object_get_data (obj, "test");
614 g_assert_cmpstr (v->value, ==, "not");
615 g_assert_cmpint (v->refcount, ==, 1);
617 v3 = new_value ("xyz");
618 res = g_object_replace_data (obj, "test", v1, v3, unref_value, &old_destroy);
619 g_assert (res == FALSE);
620 g_assert_cmpstr (v2->value, ==, "not");
621 g_assert_cmpint (v2->refcount, ==, 1);
623 unref_value (v1);
625 res = g_object_replace_data (obj, "test", NULL, v3, unref_value, &old_destroy);
626 g_assert (res == FALSE);
627 g_assert_cmpstr (v2->value, ==, "not");
628 g_assert_cmpint (v2->refcount, ==, 1);
630 res = g_object_replace_data (obj, "test", v2, NULL, unref_value, &old_destroy);
631 g_assert (res == TRUE);
632 g_assert (old_destroy == unref_value);
633 g_assert_cmpstr (v2->value, ==, "not");
634 g_assert_cmpint (v2->refcount, ==, 1);
636 unref_value (v2);
638 v = g_object_get_data (obj, "test");
639 g_assert (v == NULL);
641 res = g_object_replace_data (obj, "test", NULL, v3, unref_value, &old_destroy);
642 g_assert (res == TRUE);
644 v = g_object_get_data (obj, "test");
645 g_assert (v == v3);
647 ref_value (v3, NULL);
648 g_assert_cmpint (v3->refcount, ==, 2);
649 g_object_unref (obj);
650 g_assert_cmpint (v3->refcount, ==, 1);
651 unref_value (v3);
655 main (int argc, char **argv)
657 g_test_init (&argc, &argv, NULL);
659 g_test_add_func ("/type/fundamentals", test_fundamentals);
660 g_test_add_func ("/type/qdata", test_type_qdata);
661 g_test_add_func ("/type/query", test_type_query);
662 g_test_add_func ("/type/class-private", test_class_private);
663 g_test_add_func ("/object/clear", test_clear);
664 g_test_add_func ("/object/clear-function", test_clear_function);
665 g_test_add_func ("/object/set", test_set);
666 g_test_add_func ("/object/set-function", test_set_function);
667 g_test_add_func ("/object/value", test_object_value);
668 g_test_add_func ("/object/initially-unowned", test_initially_unowned);
669 g_test_add_func ("/object/weak-pointer", test_weak_pointer);
670 g_test_add_func ("/object/weak-ref", test_weak_ref);
671 g_test_add_func ("/object/toggle-ref", test_toggle_ref);
672 g_test_add_func ("/object/qdata", test_object_qdata);
673 g_test_add_func ("/object/qdata2", test_object_qdata2);
675 return g_test_run ();