2 * Copyright © 2010 Codethink Limited
4 * This library 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 of the licence, or (at your option) any later version.
9 * See the included COPYING file for more information.
11 * Author: Ryan Lortie <desrt@desrt.ca>
14 #include <glib/gvariant-internal.h>
19 #define BASIC "bynqiuxthdsog?"
20 #define N_BASIC (G_N_ELEMENTS (BASIC) - 1)
22 #define INVALIDS "cefjklpwz&@^$"
23 #define N_INVALIDS (G_N_ELEMENTS (INVALIDS) - 1)
26 randomly (gdouble prob)
28 return g_test_rand_double_range (0, 1) < prob;
33 append_tuple_type_string (GString *, GString *, gboolean, gint);
35 /* append a random GVariantType to a GString
36 * append a description of the type to another GString
37 * return what the type is
40 append_type_string (GString *string,
45 if (!depth-- || randomly (0.3))
47 gchar b = BASIC[g_test_rand_int_range (0, N_BASIC - definite)];
48 g_string_append_c (string, b);
49 g_string_append_c (description, b);
54 return g_variant_type_copy (G_VARIANT_TYPE_BOOLEAN);
56 return g_variant_type_copy (G_VARIANT_TYPE_BYTE);
58 return g_variant_type_copy (G_VARIANT_TYPE_INT16);
60 return g_variant_type_copy (G_VARIANT_TYPE_UINT16);
62 return g_variant_type_copy (G_VARIANT_TYPE_INT32);
64 return g_variant_type_copy (G_VARIANT_TYPE_UINT32);
66 return g_variant_type_copy (G_VARIANT_TYPE_INT64);
68 return g_variant_type_copy (G_VARIANT_TYPE_UINT64);
70 return g_variant_type_copy (G_VARIANT_TYPE_HANDLE);
72 return g_variant_type_copy (G_VARIANT_TYPE_DOUBLE);
74 return g_variant_type_copy (G_VARIANT_TYPE_STRING);
76 return g_variant_type_copy (G_VARIANT_TYPE_OBJECT_PATH);
78 return g_variant_type_copy (G_VARIANT_TYPE_SIGNATURE);
80 return g_variant_type_copy (G_VARIANT_TYPE_BASIC);
82 g_assert_not_reached ();
89 switch (g_test_rand_int_range (0, definite ? 5 : 7))
93 GVariantType *element;
95 g_string_append_c (string, 'a');
96 g_string_append (description, "a of ");
97 element = append_type_string (string, description,
99 result = g_variant_type_new_array (element);
100 g_variant_type_free (element);
103 g_assert (g_variant_type_is_array (result));
108 GVariantType *element;
110 g_string_append_c (string, 'm');
111 g_string_append (description, "m of ");
112 element = append_type_string (string, description,
114 result = g_variant_type_new_maybe (element);
115 g_variant_type_free (element);
118 g_assert (g_variant_type_is_maybe (result));
122 result = append_tuple_type_string (string, description,
125 g_assert (g_variant_type_is_tuple (result));
130 GVariantType *key, *value;
132 g_string_append_c (string, '{');
133 g_string_append (description, "e of [");
134 key = append_type_string (string, description, definite, 0);
135 g_string_append (description, ", ");
136 value = append_type_string (string, description, definite, depth);
137 g_string_append_c (description, ']');
138 g_string_append_c (string, '}');
139 result = g_variant_type_new_dict_entry (key, value);
140 g_variant_type_free (key);
141 g_variant_type_free (value);
144 g_assert (g_variant_type_is_dict_entry (result));
148 g_string_append_c (string, 'v');
149 g_string_append_c (description, 'V');
150 result = g_variant_type_copy (G_VARIANT_TYPE_VARIANT);
151 g_assert (g_variant_type_equal (result, G_VARIANT_TYPE_VARIANT));
155 g_string_append_c (string, '*');
156 g_string_append_c (description, 'S');
157 result = g_variant_type_copy (G_VARIANT_TYPE_ANY);
158 g_assert (g_variant_type_equal (result, G_VARIANT_TYPE_ANY));
162 g_string_append_c (string, 'r');
163 g_string_append_c (description, 'R');
164 result = g_variant_type_copy (G_VARIANT_TYPE_TUPLE);
165 g_assert (g_variant_type_is_tuple (result));
169 g_assert_not_reached ();
176 static GVariantType *
177 append_tuple_type_string (GString *string,
178 GString *description,
182 GVariantType *result, *other_result;
183 GVariantType **types;
187 g_string_append_c (string, '(');
188 g_string_append (description, "t of [");
190 size = g_test_rand_int_range (0, 20);
191 types = g_new (GVariantType *, size + 1);
193 for (i = 0; i < size; i++)
195 types[i] = append_type_string (string, description, definite, depth);
198 g_string_append (description, ", ");
203 g_string_append_c (description, ']');
204 g_string_append_c (string, ')');
206 result = g_variant_type_new_tuple ((gpointer) types, size);
207 other_result = g_variant_type_new_tuple ((gpointer) types, -1);
208 g_assert (g_variant_type_equal (result, other_result));
209 g_variant_type_free (other_result);
210 for (i = 0; i < size; i++)
211 g_variant_type_free (types[i]);
217 /* given a valid type string, make it invalid */
219 invalid_mutation (const gchar *type_string)
221 gboolean have_parens, have_braces;
223 /* it's valid, so '(' implies ')' and same for '{' and '}' */
224 have_parens = strchr (type_string, '(') != NULL;
225 have_braces = strchr (type_string, '{') != NULL;
227 if (have_parens && have_braces && randomly (0.3))
229 /* swap a paren and a brace */
235 new = g_strdup (type_string);
245 /* count number of parens/braces */
246 while ((pp = strchr (pp + 1, p))) np++;
247 while ((bp = strchr (bp + 1, b))) nb++;
249 /* randomly pick one of each */
250 np = g_test_rand_int_range (0, np) + 1;
251 nb = g_test_rand_int_range (0, nb) + 1;
255 while (np--) pp = strchr (pp + 1, p);
256 while (nb--) bp = strchr (bp + 1, b);
259 g_assert (*bp == b && *pp == p);
266 if ((have_parens || have_braces) && randomly (0.3))
268 /* drop a paren/brace */
275 if (randomly (0.5)) p = '('; else p = ')';
277 if (randomly (0.5)) p = '{'; else p = '}';
279 new = g_strdup (type_string);
283 while ((pp = strchr (pp + 1, p))) np++;
284 np = g_test_rand_int_range (0, np) + 1;
286 while (np--) pp = strchr (pp + 1, p);
298 /* else, perform a random mutation at a random point */
306 /* insert a paren/brace */
308 if (randomly (0.5)) p = '('; else p = ')';
310 if (randomly (0.5)) p = '{'; else p = '}';
312 else if (randomly (0.5))
315 p = INVALIDS[g_test_rand_int_range (0, N_INVALIDS)];
324 length = strlen (type_string);
325 new = g_malloc (length + 2);
326 n = g_test_rand_int_range (0, length);
327 memcpy (new, type_string, n);
329 memcpy (new + n + 1, type_string + n, length - n);
330 new[length + 1] = '\0';
336 /* describe a type using the same language as is generated
337 * while generating the type with append_type_string
340 describe_type (const GVariantType *type)
344 if (g_variant_type_is_container (type))
346 g_assert (!g_variant_type_is_basic (type));
348 if (g_variant_type_is_array (type))
350 gchar *subtype = describe_type (g_variant_type_element (type));
351 result = g_strdup_printf ("a of %s", subtype);
354 else if (g_variant_type_is_maybe (type))
356 gchar *subtype = describe_type (g_variant_type_element (type));
357 result = g_strdup_printf ("m of %s", subtype);
360 else if (g_variant_type_is_tuple (type))
362 if (!g_variant_type_equal (type, G_VARIANT_TYPE_TUPLE))
364 const GVariantType *sub;
369 string = g_string_new ("t of [");
371 length = g_variant_type_n_items (type);
372 sub = g_variant_type_first (type);
373 for (i = 0; i < length; i++)
375 gchar *subtype = describe_type (sub);
376 g_string_append (string, subtype);
379 if ((sub = g_variant_type_next (sub)))
380 g_string_append (string, ", ");
382 g_assert (sub == NULL);
383 g_string_append_c (string, ']');
385 result = g_string_free (string, FALSE);
388 result = g_strdup ("R");
390 else if (g_variant_type_is_dict_entry (type))
392 gchar *key, *value, *key2, *value2;
394 key = describe_type (g_variant_type_key (type));
395 value = describe_type (g_variant_type_value (type));
396 key2 = describe_type (g_variant_type_first (type));
397 value2 = describe_type (
398 g_variant_type_next (g_variant_type_first (type)));
399 g_assert (g_variant_type_next (g_variant_type_next (
400 g_variant_type_first (type))) == NULL);
401 g_assert_cmpstr (key, ==, key2);
402 g_assert_cmpstr (value, ==, value2);
403 result = g_strjoin ("", "e of [", key, ", ", value, "]", NULL);
409 else if (g_variant_type_equal (type, G_VARIANT_TYPE_VARIANT))
411 result = g_strdup ("V");
414 g_assert_not_reached ();
418 if (g_variant_type_is_definite (type))
420 g_assert (g_variant_type_is_basic (type));
422 if (g_variant_type_equal (type, G_VARIANT_TYPE_BOOLEAN))
423 result = g_strdup ("b");
424 else if (g_variant_type_equal (type, G_VARIANT_TYPE_BYTE))
425 result = g_strdup ("y");
426 else if (g_variant_type_equal (type, G_VARIANT_TYPE_INT16))
427 result = g_strdup ("n");
428 else if (g_variant_type_equal (type, G_VARIANT_TYPE_UINT16))
429 result = g_strdup ("q");
430 else if (g_variant_type_equal (type, G_VARIANT_TYPE_INT32))
431 result = g_strdup ("i");
432 else if (g_variant_type_equal (type, G_VARIANT_TYPE_UINT32))
433 result = g_strdup ("u");
434 else if (g_variant_type_equal (type, G_VARIANT_TYPE_INT64))
435 result = g_strdup ("x");
436 else if (g_variant_type_equal (type, G_VARIANT_TYPE_UINT64))
437 result = g_strdup ("t");
438 else if (g_variant_type_equal (type, G_VARIANT_TYPE_HANDLE))
439 result = g_strdup ("h");
440 else if (g_variant_type_equal (type, G_VARIANT_TYPE_DOUBLE))
441 result = g_strdup ("d");
442 else if (g_variant_type_equal (type, G_VARIANT_TYPE_STRING))
443 result = g_strdup ("s");
444 else if (g_variant_type_equal (type, G_VARIANT_TYPE_OBJECT_PATH))
445 result = g_strdup ("o");
446 else if (g_variant_type_equal (type, G_VARIANT_TYPE_SIGNATURE))
447 result = g_strdup ("g");
449 g_assert_not_reached ();
453 if (g_variant_type_equal (type, G_VARIANT_TYPE_ANY))
455 result = g_strdup ("S");
457 else if (g_variant_type_equal (type, G_VARIANT_TYPE_BASIC))
459 result = g_strdup ("?");
462 g_assert_not_reached ();
469 /* given a type string, replace one of the indefinite type characters in
470 * it with a matching type (possibly the same type).
473 generate_subtype (const gchar *type_string)
475 GVariantType *replacement;
476 GString *result, *junk;
477 gint length, n = 0, l;
479 result = g_string_new (NULL);
480 junk = g_string_new (NULL);
482 /* count the number of indefinite type characters */
483 for (length = 0; type_string[length]; length++)
484 n += type_string[length] == 'r' ||
485 type_string[length] == '?' ||
486 type_string[length] == '*';
487 /* length now is strlen (type_string) */
489 /* pick one at random to replace */
490 n = g_test_rand_int_range (0, n) + 1;
494 while (n--) l += strcspn (type_string + l + 1, "r?*") + 1;
495 g_assert (type_string[l] == 'r' ||
496 type_string[l] == '?' ||
497 type_string[l] == '*');
499 /* store up to that point in a GString */
500 g_string_append_len (result, type_string, l);
502 /* then store the replacement in the GString */
503 if (type_string[l] == 'r')
504 replacement = append_tuple_type_string (result, junk, FALSE, 3);
506 else if (type_string[l] == '?')
507 replacement = append_type_string (result, junk, FALSE, 0);
509 else if (type_string[l] == '*')
510 replacement = append_type_string (result, junk, FALSE, 3);
513 g_assert_not_reached ();
515 /* ensure the replacement has the proper type */
516 g_assert (g_variant_type_is_subtype_of (replacement,
517 (gpointer) &type_string[l]));
519 /* store the rest from the original type string */
520 g_string_append (result, type_string + l + 1);
522 g_variant_type_free (replacement);
523 g_string_free (junk, TRUE);
525 return g_string_free (result, FALSE);
530 const GVariantType *type;
531 struct typestack *parent;
534 /* given an indefinite type string, replace one of the indefinite
535 * characters in it with a matching type and ensure that the result is a
536 * subtype of the original. repeat.
539 subtype_check (const gchar *type_string,
540 struct typestack *parent_ts)
542 struct typestack ts, *node;
546 subtype = generate_subtype (type_string);
548 ts.type = G_VARIANT_TYPE (subtype);
549 ts.parent = parent_ts;
551 for (node = &ts; node; node = node->parent)
553 /* this type should be a subtype of each parent type */
554 g_assert (g_variant_type_is_subtype_of (ts.type, node->type));
556 /* it should only be a supertype when it is exactly equal */
557 g_assert (g_variant_type_is_subtype_of (node->type, ts.type) ==
558 g_variant_type_equal (ts.type, node->type));
563 if (!g_variant_type_is_definite (ts.type) && depth < 5)
565 /* the type is still indefinite and we haven't repeated too many
566 * times. go once more.
569 subtype_check (subtype, &ts);
576 test_gvarianttype (void)
580 for (i = 0; i < 2000; i++)
582 GString *type_string, *description;
583 GVariantType *type, *other_type;
584 const GVariantType *ctype;
588 type_string = g_string_new (NULL);
589 description = g_string_new (NULL);
591 /* generate a random type, its type string and a description
593 * exercises type constructor functions and g_variant_type_copy()
595 type = append_type_string (type_string, description, FALSE, 6);
597 /* convert the type string to a type and ensure that it is equal
598 * to the one produced with the type constructor routines
600 ctype = G_VARIANT_TYPE (type_string->str);
601 g_assert (g_variant_type_equal (ctype, type));
602 g_assert (g_variant_type_is_subtype_of (ctype, type));
603 g_assert (g_variant_type_is_subtype_of (type, ctype));
605 /* check if the type is indefinite */
606 if (!g_variant_type_is_definite (type))
608 struct typestack ts = { type, NULL };
610 /* if it is indefinite, then replace one of the indefinite
611 * characters with a matching type and ensure that the result
612 * is a subtype of the original type. repeat.
614 subtype_check (type_string->str, &ts);
617 /* ensure that no indefinite characters appear */
618 g_assert (strcspn (type_string->str, "r?*") == type_string->len);
621 /* describe the type.
623 * exercises the type iterator interface
625 desc = describe_type (type);
627 /* make sure the description matches */
628 g_assert_cmpstr (desc, ==, description->str);
631 /* make an invalid mutation to the type and make sure the type
632 * validation routines catch it */
633 invalid = invalid_mutation (type_string->str);
634 g_assert (g_variant_type_string_is_valid (type_string->str));
635 g_assert (!g_variant_type_string_is_valid (invalid));
638 /* concatenate another type to the type string and ensure that
639 * the result is recognised as being invalid
641 other_type = append_type_string (type_string, description, FALSE, 2);
643 g_string_free (description, TRUE);
644 g_string_free (type_string, TRUE);
645 g_variant_type_free (other_type);
646 g_variant_type_free (type);
650 #define ALIGNED(x, y) (((x + (y - 1)) / y) * y)
652 /* do our own calculation of the fixed_size and alignment of a type
653 * using a simple algorithm to make sure the "fancy" one in the
654 * implementation is correct.
657 calculate_type_info (const GVariantType *type,
661 if (g_variant_type_is_array (type) ||
662 g_variant_type_is_maybe (type))
664 calculate_type_info (g_variant_type_element (type), NULL, alignment);
669 else if (g_variant_type_is_tuple (type) ||
670 g_variant_type_is_dict_entry (type))
672 if (g_variant_type_n_items (type))
674 const GVariantType *sub;
683 sub = g_variant_type_first (type);
689 calculate_type_info (sub, &this_fs, &this_al);
691 al = MAX (al, this_al);
701 size = ALIGNED (size, this_al);
705 while ((sub = g_variant_type_next (sub)));
707 size = ALIGNED (size, al);
728 if (g_variant_type_equal (type, G_VARIANT_TYPE_BOOLEAN) ||
729 g_variant_type_equal (type, G_VARIANT_TYPE_BYTE))
734 else if (g_variant_type_equal (type, G_VARIANT_TYPE_INT16) ||
735 g_variant_type_equal (type, G_VARIANT_TYPE_UINT16))
740 else if (g_variant_type_equal (type, G_VARIANT_TYPE_INT32) ||
741 g_variant_type_equal (type, G_VARIANT_TYPE_UINT32) ||
742 g_variant_type_equal (type, G_VARIANT_TYPE_HANDLE))
747 else if (g_variant_type_equal (type, G_VARIANT_TYPE_INT64) ||
748 g_variant_type_equal (type, G_VARIANT_TYPE_UINT64) ||
749 g_variant_type_equal (type, G_VARIANT_TYPE_DOUBLE))
753 else if (g_variant_type_equal (type, G_VARIANT_TYPE_STRING) ||
754 g_variant_type_equal (type, G_VARIANT_TYPE_OBJECT_PATH) ||
755 g_variant_type_equal (type, G_VARIANT_TYPE_SIGNATURE))
760 else if (g_variant_type_equal (type, G_VARIANT_TYPE_VARIANT))
766 g_assert_not_reached ();
776 /* same as the describe_type() function above, but iterates over
777 * typeinfo instead of types.
780 describe_info (GVariantTypeInfo *info)
784 switch (g_variant_type_info_get_type_char (info))
786 case G_VARIANT_TYPE_INFO_CHAR_MAYBE:
790 element = describe_info (g_variant_type_info_element (info));
791 result = g_strdup_printf ("m of %s", element);
796 case G_VARIANT_TYPE_INFO_CHAR_ARRAY:
800 element = describe_info (g_variant_type_info_element (info));
801 result = g_strdup_printf ("a of %s", element);
806 case G_VARIANT_TYPE_INFO_CHAR_TUPLE:
808 const gchar *sep = "";
813 string = g_string_new ("t of [");
814 length = g_variant_type_info_n_members (info);
816 for (i = 0; i < length; i++)
818 const GVariantMemberInfo *minfo;
821 g_string_append (string, sep);
824 minfo = g_variant_type_info_member_info (info, i);
825 subtype = describe_info (minfo->type_info);
826 g_string_append (string, subtype);
830 g_string_append_c (string, ']');
832 result = g_string_free (string, FALSE);
836 case G_VARIANT_TYPE_INFO_CHAR_DICT_ENTRY:
838 const GVariantMemberInfo *keyinfo, *valueinfo;
841 g_assert_cmpint (g_variant_type_info_n_members (info), ==, 2);
842 keyinfo = g_variant_type_info_member_info (info, 0);
843 valueinfo = g_variant_type_info_member_info (info, 1);
844 key = describe_info (keyinfo->type_info);
845 value = describe_info (valueinfo->type_info);
846 result = g_strjoin ("", "e of [", key, ", ", value, "]", NULL);
852 case G_VARIANT_TYPE_INFO_CHAR_VARIANT:
853 result = g_strdup ("V");
857 result = g_strdup (g_variant_type_info_get_type_string (info));
858 g_assert_cmpint (strlen (result), ==, 1);
865 /* check that the O(1) method of calculating offsets meshes with the
866 * results of simple iteration.
869 check_offsets (GVariantTypeInfo *info,
870 const GVariantType *type)
875 length = g_variant_type_info_n_members (info);
876 g_assert_cmpint (length, ==, g_variant_type_n_items (type));
878 /* the 'flavour' is the low order bits of the ending point of
879 * variable-size items in the tuple. this lets us test that the type
880 * info is correct for various starting alignments.
882 for (flavour = 0; flavour < 8; flavour++)
884 const GVariantType *subtype;
885 gsize last_offset_index;
890 subtype = g_variant_type_first (type);
891 last_offset_index = -1;
895 /* go through the tuple, keeping track of our position */
896 for (i = 0; i < length; i++)
901 calculate_type_info (subtype, &fixed_size, &alignment);
903 position = ALIGNED (position, alignment);
905 /* compare our current aligned position (ie: the start of this
906 * item) to the start offset that would be calculated if we
910 const GVariantMemberInfo *member;
913 member = g_variant_type_info_member_info (info, i);
914 g_assert_cmpint (member->i, ==, last_offset_index);
916 /* do the calculation using the typeinfo */
922 /* did we reach the same spot? */
923 g_assert_cmpint (start, ==, position);
928 /* fixed size. add that size. */
929 position += fixed_size;
933 /* variable size. do the flavouring. */
934 while ((position & 0x7) != flavour)
937 /* and store the offset, just like it would be in the
940 last_offset = position;
945 subtype = g_variant_type_next (subtype);
948 /* make sure we used up exactly all the types */
949 g_assert (subtype == NULL);
954 test_gvarianttypeinfo (void)
958 for (i = 0; i < 2000; i++)
960 GString *type_string, *description;
961 gsize fixed_size1, fixed_size2;
962 guint alignment1, alignment2;
963 GVariantTypeInfo *info;
967 type_string = g_string_new (NULL);
968 description = g_string_new (NULL);
971 type = append_type_string (type_string, description, TRUE, 6);
973 /* create a typeinfo for it */
974 info = g_variant_type_info_get (type);
976 /* make sure the typeinfo has the right type string */
977 g_assert_cmpstr (g_variant_type_info_get_type_string (info), ==,
980 /* calculate the alignment and fixed size, compare to the
981 * typeinfo's calculations
983 calculate_type_info (type, &fixed_size1, &alignment1);
984 g_variant_type_info_query (info, &alignment2, &fixed_size2);
985 g_assert_cmpint (fixed_size1, ==, fixed_size2);
986 g_assert_cmpint (alignment1, ==, alignment2 + 1);
988 /* test the iteration functions over typeinfo structures by
989 * "describing" the typeinfo and verifying equality.
991 desc = describe_info (info);
992 g_assert_cmpstr (desc, ==, description->str);
994 /* do extra checks for containers */
995 if (g_variant_type_is_array (type) ||
996 g_variant_type_is_maybe (type))
998 const GVariantType *element;
1002 element = g_variant_type_element (type);
1003 calculate_type_info (element, &efs1, &ea1);
1004 g_variant_type_info_query_element (info, &ea2, &efs2);
1005 g_assert_cmpint (efs1, ==, efs2);
1006 g_assert_cmpint (ea1, ==, ea2 + 1);
1008 g_assert_cmpint (ea1, ==, alignment1);
1009 g_assert_cmpint (0, ==, fixed_size1);
1011 else if (g_variant_type_is_tuple (type) ||
1012 g_variant_type_is_dict_entry (type))
1014 /* make sure the "magic constants" are working */
1015 check_offsets (info, type);
1018 g_string_free (type_string, TRUE);
1019 g_string_free (description, TRUE);
1020 g_variant_type_info_unref (info);
1021 g_variant_type_free (type);
1025 g_variant_type_info_assert_no_infos ();
1028 #define MAX_FIXED_MULTIPLIER 256
1029 #define MAX_INSTANCE_SIZE 1024
1030 #define MAX_ARRAY_CHILDREN 128
1031 #define MAX_TUPLE_CHILDREN 128
1033 /* this function generates a random type such that all characteristics
1034 * that are "interesting" to the serialiser are tested.
1036 * this basically means:
1037 * - test different alignments
1038 * - test variable sized items and fixed sized items
1039 * - test different fixed sizes
1042 random_type_string (void)
1044 const guchar base_types[] = "ynix";
1047 base_type = base_types[g_test_rand_int_range (0, 4)];
1049 if (g_test_rand_bit ())
1050 /* construct a fixed-sized type */
1052 char type_string[MAX_FIXED_MULTIPLIER];
1056 multiplier = g_test_rand_int_range (1, sizeof type_string - 1);
1058 type_string[i++] = '(';
1059 while (multiplier--)
1060 type_string[i++] = base_type;
1061 type_string[i++] = ')';
1063 return g_strndup (type_string, i);
1066 /* construct a variable-sized type */
1068 char type_string[2] = { 'a', base_type };
1070 return g_strndup (type_string, 2);
1076 GVariantTypeInfo *type_info;
1079 gboolean is_fixed_sized;
1083 #define INSTANCE_MAGIC 1287582829
1087 static RandomInstance *
1088 random_instance (GVariantTypeInfo *type_info)
1090 RandomInstance *instance;
1092 instance = g_slice_new (RandomInstance);
1094 if (type_info == NULL)
1096 gchar *str = random_type_string ();
1097 instance->type_info = g_variant_type_info_get (G_VARIANT_TYPE (str));
1101 instance->type_info = g_variant_type_info_ref (type_info);
1103 instance->seed = g_test_rand_int ();
1105 g_variant_type_info_query (instance->type_info,
1106 &instance->alignment,
1109 instance->is_fixed_sized = instance->size != 0;
1111 if (!instance->is_fixed_sized)
1112 instance->size = g_test_rand_int_range (0, MAX_INSTANCE_SIZE);
1114 instance->magic = INSTANCE_MAGIC;
1120 random_instance_free (RandomInstance *instance)
1122 g_variant_type_info_unref (instance->type_info);
1123 g_slice_free (RandomInstance, instance);
1127 append_instance_size (RandomInstance *instance,
1130 *offset += (-*offset) & instance->alignment;
1131 *offset += instance->size;
1135 random_instance_write (RandomInstance *instance,
1141 g_assert_cmpint ((gsize) buffer & instance->alignment, ==, 0);
1143 rand = g_rand_new_with_seed (instance->seed);
1144 for (i = 0; i < instance->size; i++)
1145 buffer[i] = g_rand_int (rand);
1150 append_instance_data (RandomInstance *instance,
1153 while (((gsize) *buffer) & instance->alignment)
1154 *(*buffer)++ = '\0';
1156 random_instance_write (instance, *buffer);
1157 *buffer += instance->size;
1161 random_instance_assert (RandomInstance *instance,
1168 g_assert_cmpint ((gsize) buffer & instance->alignment, ==, 0);
1169 g_assert_cmpint (size, ==, instance->size);
1171 rand = g_rand_new_with_seed (instance->seed);
1172 for (i = 0; i < instance->size; i++)
1174 guchar byte = g_rand_int (rand);
1176 g_assert (buffer[i] == byte);
1180 return i == instance->size;
1184 random_instance_check (RandomInstance *instance,
1191 g_assert_cmpint ((gsize) buffer & instance->alignment, ==, 0);
1193 if (size != instance->size)
1196 rand = g_rand_new_with_seed (instance->seed);
1197 for (i = 0; i < instance->size; i++)
1198 if (buffer[i] != (guchar) g_rand_int (rand))
1202 return i == instance->size;
1206 random_instance_filler (GVariantSerialised *serialised,
1209 RandomInstance *instance = data;
1211 g_assert (instance->magic == INSTANCE_MAGIC);
1213 if (serialised->type_info == NULL)
1214 serialised->type_info = instance->type_info;
1216 if (serialised->size == 0)
1217 serialised->size = instance->size;
1219 g_assert (serialised->type_info == instance->type_info);
1220 g_assert (serialised->size == instance->size);
1222 if (serialised->data)
1223 random_instance_write (instance, serialised->data);
1227 calculate_offset_size (gsize body_size,
1233 if (body_size + n_offsets <= G_MAXUINT8)
1236 if (body_size + 2 * n_offsets <= G_MAXUINT16)
1239 if (body_size + 4 * n_offsets <= G_MAXUINT32)
1242 /* the test case won't generate anything bigger */
1243 g_assert_not_reached ();
1247 flavoured_malloc (gsize size, gsize flavour)
1249 g_assert (flavour < 8);
1254 return g_malloc (size + flavour) + flavour;
1258 flavoured_free (gpointer data)
1260 g_free ((gpointer) (((gsize) data) & ~7));
1264 append_offset (guchar **offset_ptr,
1270 guchar bytes[sizeof (gsize)];
1274 tmpvalue.integer = GSIZE_TO_LE (offset);
1275 memcpy (*offset_ptr, tmpvalue.bytes, offset_size);
1276 *offset_ptr += offset_size;
1280 prepend_offset (guchar **offset_ptr,
1286 guchar bytes[sizeof (gsize)];
1290 *offset_ptr -= offset_size;
1291 tmpvalue.integer = GSIZE_TO_LE (offset);
1292 memcpy (*offset_ptr, tmpvalue.bytes, offset_size);
1298 GVariantTypeInfo *type_info;
1299 RandomInstance *instance;
1303 instance = random_instance (NULL);
1306 const gchar *element;
1309 element = g_variant_type_info_get_type_string (instance->type_info);
1310 tmp = g_strdup_printf ("m%s", element);
1311 type_info = g_variant_type_info_get (G_VARIANT_TYPE (tmp));
1315 needed_size = g_variant_serialiser_needed_size (type_info,
1316 random_instance_filler,
1318 g_assert_cmpint (needed_size, ==, 0);
1320 needed_size = g_variant_serialiser_needed_size (type_info,
1321 random_instance_filler,
1322 (gpointer *) &instance, 1);
1324 if (instance->is_fixed_sized)
1325 g_assert_cmpint (needed_size, ==, instance->size);
1327 g_assert_cmpint (needed_size, ==, instance->size + 1);
1332 ptr = data = g_malloc (needed_size);
1333 append_instance_data (instance, &ptr);
1335 if (!instance->is_fixed_sized)
1338 g_assert_cmpint (ptr - data, ==, needed_size);
1345 alignment = instance->alignment + 1;
1347 for (flavour = 0; flavour < 8; flavour += alignment)
1349 GVariantSerialised serialised;
1350 GVariantSerialised child;
1352 serialised.type_info = type_info;
1353 serialised.data = flavoured_malloc (needed_size, flavour);
1354 serialised.size = needed_size;
1356 g_variant_serialiser_serialise (serialised,
1357 random_instance_filler,
1358 (gpointer *) &instance, 1);
1359 child = g_variant_serialised_get_child (serialised, 0);
1360 g_assert (child.type_info == instance->type_info);
1361 random_instance_assert (instance, child.data, child.size);
1362 g_variant_type_info_unref (child.type_info);
1363 flavoured_free (serialised.data);
1367 g_variant_type_info_unref (type_info);
1368 random_instance_free (instance);
1377 for (i = 0; i < 1000; i++)
1380 g_variant_type_info_assert_no_infos ();
1386 GVariantTypeInfo *element_info;
1387 GVariantTypeInfo *array_info;
1388 RandomInstance **instances;
1395 gchar *element_type, *array_type;
1397 element_type = random_type_string ();
1398 array_type = g_strdup_printf ("a%s", element_type);
1400 element_info = g_variant_type_info_get (G_VARIANT_TYPE (element_type));
1401 array_info = g_variant_type_info_get (G_VARIANT_TYPE (array_type));
1402 g_assert (g_variant_type_info_element (array_info) == element_info);
1404 g_free (element_type);
1405 g_free (array_type);
1411 n_children = g_test_rand_int_range (0, MAX_ARRAY_CHILDREN);
1412 instances = g_new (RandomInstance *, n_children);
1413 for (i = 0; i < n_children; i++)
1414 instances[i] = random_instance (element_info);
1417 needed_size = g_variant_serialiser_needed_size (array_info,
1418 random_instance_filler,
1419 (gpointer *) instances,
1423 gsize element_fixed_size;
1424 gsize body_size = 0;
1427 for (i = 0; i < n_children; i++)
1428 append_instance_size (instances[i], &body_size);
1430 g_variant_type_info_query (element_info, NULL, &element_fixed_size);
1432 if (!element_fixed_size)
1434 offset_size = calculate_offset_size (body_size, n_children);
1436 if (offset_size == 0)
1442 g_assert_cmpint (needed_size, ==, body_size + n_children * offset_size);
1446 guchar *offset_ptr, *body_ptr;
1449 body_ptr = data = g_malloc (needed_size);
1450 offset_ptr = body_ptr + needed_size - offset_size * n_children;
1452 for (i = 0; i < n_children; i++)
1454 append_instance_data (instances[i], &body_ptr);
1455 append_offset (&offset_ptr, body_ptr - data, offset_size);
1458 g_assert (body_ptr == data + needed_size - offset_size * n_children);
1459 g_assert (offset_ptr == data + needed_size);
1467 g_variant_type_info_query (array_info, &alignment, NULL);
1470 for (flavour = 0; flavour < 8; flavour += alignment)
1472 GVariantSerialised serialised;
1474 serialised.type_info = array_info;
1475 serialised.data = flavoured_malloc (needed_size, flavour);
1476 serialised.size = needed_size;
1478 g_variant_serialiser_serialise (serialised, random_instance_filler,
1479 (gpointer *) instances, n_children);
1481 g_assert (memcmp (serialised.data, data, serialised.size) == 0);
1482 g_assert (g_variant_serialised_n_children (serialised) == n_children);
1484 for (i = 0; i < n_children; i++)
1486 GVariantSerialised child;
1488 child = g_variant_serialised_get_child (serialised, i);
1489 g_assert (child.type_info == instances[i]->type_info);
1490 random_instance_assert (instances[i], child.data, child.size);
1491 g_variant_type_info_unref (child.type_info);
1494 flavoured_free (serialised.data);
1501 for (i = 0; i < n_children; i++)
1502 random_instance_free (instances[i]);
1506 g_variant_type_info_unref (element_info);
1507 g_variant_type_info_unref (array_info);
1516 for (i = 0; i < 100; i++)
1519 g_variant_type_info_assert_no_infos ();
1525 GVariantTypeInfo *type_info;
1526 RandomInstance **instances;
1527 gboolean fixed_size;
1534 n_children = g_test_rand_int_range (0, MAX_TUPLE_CHILDREN);
1535 instances = g_new (RandomInstance *, n_children);
1538 GString *type_string;
1544 type_string = g_string_new ("(");
1545 for (i = 0; i < n_children; i++)
1549 instances[i] = random_instance (NULL);
1551 alignment |= instances[i]->alignment;
1552 if (!instances[i]->is_fixed_sized)
1555 str = g_variant_type_info_get_type_string (instances[i]->type_info);
1556 g_string_append (type_string, str);
1558 g_string_append_c (type_string, ')');
1560 type_info = g_variant_type_info_get (G_VARIANT_TYPE (type_string->str));
1561 g_string_free (type_string, TRUE);
1564 needed_size = g_variant_serialiser_needed_size (type_info,
1565 random_instance_filler,
1566 (gpointer *) instances,
1569 gsize body_size = 0;
1573 for (i = 0; i < n_children; i++)
1575 append_instance_size (instances[i], &body_size);
1577 if (i != n_children - 1 && !instances[i]->is_fixed_sized)
1583 body_size += (-body_size) & alignment;
1585 g_assert ((body_size == 0) == (n_children == 0));
1586 if (n_children == 0)
1590 offset_size = calculate_offset_size (body_size, offsets);
1591 g_assert_cmpint (needed_size, ==, body_size + offsets * offset_size);
1599 body_ptr = data = g_malloc (needed_size);
1600 ofs_ptr = body_ptr + needed_size;
1602 for (i = 0; i < n_children; i++)
1604 append_instance_data (instances[i], &body_ptr);
1606 if (i != n_children - 1 && !instances[i]->is_fixed_sized)
1607 prepend_offset (&ofs_ptr, body_ptr - data, offset_size);
1612 while (((gsize) body_ptr) & alignment)
1615 g_assert ((body_ptr == data) == (n_children == 0));
1616 if (n_children == 0)
1622 g_assert (body_ptr == ofs_ptr);
1631 for (flavour = 0; flavour < 8; flavour += alignment)
1633 GVariantSerialised serialised;
1635 serialised.type_info = type_info;
1636 serialised.data = flavoured_malloc (needed_size, flavour);
1637 serialised.size = needed_size;
1639 g_variant_serialiser_serialise (serialised, random_instance_filler,
1640 (gpointer *) instances, n_children);
1642 g_assert (memcmp (serialised.data, data, serialised.size) == 0);
1643 g_assert (g_variant_serialised_n_children (serialised) == n_children);
1645 for (i = 0; i < n_children; i++)
1647 GVariantSerialised child;
1649 child = g_variant_serialised_get_child (serialised, i);
1650 g_assert (child.type_info == instances[i]->type_info);
1651 random_instance_assert (instances[i], child.data, child.size);
1652 g_variant_type_info_unref (child.type_info);
1655 flavoured_free (serialised.data);
1662 for (i = 0; i < n_children; i++)
1663 random_instance_free (instances[i]);
1667 g_variant_type_info_unref (type_info);
1676 for (i = 0; i < 100; i++)
1679 g_variant_type_info_assert_no_infos ();
1685 GVariantTypeInfo *type_info;
1686 RandomInstance *instance;
1687 const gchar *type_string;
1692 type_info = g_variant_type_info_get (G_VARIANT_TYPE_VARIANT);
1693 instance = random_instance (NULL);
1695 type_string = g_variant_type_info_get_type_string (instance->type_info);
1696 len = strlen (type_string);
1698 needed_size = g_variant_serialiser_needed_size (type_info,
1699 random_instance_filler,
1700 (gpointer *) &instance, 1);
1702 g_assert_cmpint (needed_size, ==, instance->size + 1 + len);
1707 ptr = data = g_malloc (needed_size);
1708 append_instance_data (instance, &ptr);
1710 memcpy (ptr, type_string, len);
1713 g_assert (data + needed_size == ptr);
1717 /* variants are 8-aligned, so no extra flavouring */
1718 GVariantSerialised serialised;
1719 GVariantSerialised child;
1721 serialised.type_info = type_info;
1722 serialised.data = flavoured_malloc (needed_size, 0);
1723 serialised.size = needed_size;
1725 g_variant_serialiser_serialise (serialised, random_instance_filler,
1726 (gpointer *) &instance, 1);
1728 g_assert (memcmp (serialised.data, data, serialised.size) == 0);
1729 g_assert (g_variant_serialised_n_children (serialised) == 1);
1731 child = g_variant_serialised_get_child (serialised, 0);
1732 g_assert (child.type_info == instance->type_info);
1733 random_instance_check (instance, child.data, child.size);
1735 g_variant_type_info_unref (child.type_info);
1736 flavoured_free (serialised.data);
1739 g_variant_type_info_unref (type_info);
1740 random_instance_free (instance);
1745 test_variants (void)
1749 for (i = 0; i < 100; i++)
1752 g_variant_type_info_assert_no_infos ();
1765 #define is_objpath is_string | 2
1766 #define is_sig is_string | 4
1768 { is_nval, 0, NULL },
1769 { is_string, 13, "hello world!" },
1770 { is_nval, 13, "hello world\0" },
1771 { is_nval, 13, "hello\0world!" },
1772 { is_nval, 12, "hello world!" },
1774 { is_objpath, 2, "/" },
1775 { is_objpath, 3, "/a" },
1776 { is_string, 3, "//" },
1777 { is_objpath, 11, "/some/path" },
1778 { is_string, 12, "/some/path/" },
1779 { is_nval, 11, "/some\0path" },
1780 { is_string, 11, "/some\\path" },
1781 { is_string, 12, "/some//path" },
1782 { is_string, 12, "/some-/path" },
1786 { is_sig, 5, "(si)" },
1787 { is_string, 4, "(si" },
1788 { is_string, 2, "*" },
1789 { is_sig, 3, "ai" },
1790 { is_string, 3, "mi" },
1791 { is_string, 2, "r" },
1792 { is_sig, 15, "(yyy{sv}ssiai)" },
1793 { is_string, 16, "(yyy{yv}ssiai))" },
1794 { is_string, 15, "(yyy{vv}ssiai)" },
1795 { is_string, 15, "(yyy{sv)ssiai}" }
1799 for (i = 0; i < G_N_ELEMENTS (test_cases); i++)
1803 flags = g_variant_serialiser_is_string (test_cases[i].data,
1807 flags |= g_variant_serialiser_is_object_path (test_cases[i].data,
1811 flags |= g_variant_serialiser_is_signature (test_cases[i].data,
1815 g_assert (flags == test_cases[i].flags);
1819 typedef struct _TreeInstance TreeInstance;
1820 struct _TreeInstance
1822 GVariantTypeInfo *info;
1824 TreeInstance **children;
1835 static GVariantType *
1836 make_random_definite_type (int depth)
1838 GString *description;
1839 GString *type_string;
1842 description = g_string_new (NULL);
1843 type_string = g_string_new (NULL);
1844 type = append_type_string (type_string, description, TRUE, depth);
1845 g_string_free (description, TRUE);
1846 g_string_free (type_string, TRUE);
1852 make_random_string (gchar *string,
1854 const GVariantType *type)
1858 /* create strings that are valid signature strings */
1859 #define good_chars "bynqiuxthdsog"
1861 for (i = 0; i < size - 1; i++)
1862 string[i] = good_chars[g_test_rand_int_range (0, strlen (good_chars))];
1865 /* in case we need an object path, prefix a '/' */
1866 if (*g_variant_type_peek_string (type) == 'o')
1872 static TreeInstance *
1873 tree_instance_new (const GVariantType *type,
1876 const GVariantType *child_type = NULL;
1877 GVariantType *mytype = NULL;
1878 TreeInstance *instance;
1879 gboolean is_tuple_type;
1882 type = mytype = make_random_definite_type (depth);
1884 instance = g_slice_new (TreeInstance);
1885 instance->info = g_variant_type_info_get (type);
1886 instance->children = NULL;
1887 instance->n_children = 0;
1888 instance->data_size = 0;
1890 is_tuple_type = FALSE;
1892 switch (*g_variant_type_peek_string (type))
1894 case G_VARIANT_TYPE_INFO_CHAR_MAYBE:
1895 instance->n_children = g_test_rand_int_range (0, 2);
1896 child_type = g_variant_type_element (type);
1899 case G_VARIANT_TYPE_INFO_CHAR_ARRAY:
1900 instance->n_children = g_test_rand_int_range (0, MAX_ARRAY_CHILDREN);
1901 child_type = g_variant_type_element (type);
1904 case G_VARIANT_TYPE_INFO_CHAR_DICT_ENTRY:
1905 case G_VARIANT_TYPE_INFO_CHAR_TUPLE:
1906 instance->n_children = g_variant_type_n_items (type);
1907 child_type = g_variant_type_first (type);
1908 is_tuple_type = TRUE;
1911 case G_VARIANT_TYPE_INFO_CHAR_VARIANT:
1912 instance->n_children = 1;
1917 instance->data.integer = g_test_rand_int_range (0, 2);
1918 instance->data_size = 1;
1922 instance->data.integer = g_test_rand_int ();
1923 instance->data_size = 1;
1927 instance->data.integer = g_test_rand_int ();
1928 instance->data_size = 2;
1931 case 'i': case 'u': case 'h':
1932 instance->data.integer = g_test_rand_int ();
1933 instance->data_size = 4;
1936 case 'x': case 't': case 'd':
1937 instance->data.integer = g_test_rand_int ();
1938 instance->data.integer <<= 32;
1939 instance->data.integer |= (guint32) g_test_rand_int ();
1940 instance->data_size = 8;
1943 case 's': case 'o': case 'g':
1944 instance->data_size = g_test_rand_int_range (10, 20);
1945 make_random_string (instance->data.string, instance->data_size, type);
1949 if (instance->data_size == 0)
1950 /* no data -> it is a container */
1954 instance->children = g_new (TreeInstance *, instance->n_children);
1956 for (i = 0; i < instance->n_children; i++)
1958 instance->children[i] = tree_instance_new (child_type, depth - 1);
1961 child_type = g_variant_type_next (child_type);
1964 g_assert (!is_tuple_type || child_type == NULL);
1967 g_variant_type_free (mytype);
1973 tree_instance_free (TreeInstance *instance)
1977 g_variant_type_info_unref (instance->info);
1978 for (i = 0; i < instance->n_children; i++)
1979 tree_instance_free (instance->children[i]);
1980 g_free (instance->children);
1981 g_slice_free (TreeInstance, instance);
1984 static gboolean i_am_writing_byteswapped;
1987 tree_filler (GVariantSerialised *serialised,
1990 TreeInstance *instance = data;
1992 if (serialised->type_info == NULL)
1993 serialised->type_info = instance->info;
1995 if (instance->data_size == 0)
1996 /* is a container */
1998 if (serialised->size == 0)
2000 g_variant_serialiser_needed_size (instance->info, tree_filler,
2001 (gpointer *) instance->children,
2002 instance->n_children);
2004 if (serialised->data)
2005 g_variant_serialiser_serialise (*serialised, tree_filler,
2006 (gpointer *) instance->children,
2007 instance->n_children);
2012 if (serialised->size == 0)
2013 serialised->size = instance->data_size;
2015 if (serialised->data)
2017 switch (instance->data_size)
2020 *serialised->data = instance->data.integer;
2025 guint16 value = instance->data.integer;
2027 if (i_am_writing_byteswapped)
2028 value = GUINT16_SWAP_LE_BE (value);
2030 *(guint16 *) serialised->data = value;
2036 guint32 value = instance->data.integer;
2038 if (i_am_writing_byteswapped)
2039 value = GUINT32_SWAP_LE_BE (value);
2041 *(guint32 *) serialised->data = value;
2047 guint64 value = instance->data.integer;
2049 if (i_am_writing_byteswapped)
2050 value = GUINT64_SWAP_LE_BE (value);
2052 *(guint64 *) serialised->data = value;
2057 memcpy (serialised->data,
2058 instance->data.string,
2059 instance->data_size);
2067 check_tree (TreeInstance *instance,
2068 GVariantSerialised serialised)
2070 if (instance->info != serialised.type_info)
2073 if (instance->data_size == 0)
2074 /* is a container */
2078 if (g_variant_serialised_n_children (serialised) !=
2079 instance->n_children)
2082 for (i = 0; i < instance->n_children; i++)
2084 GVariantSerialised child;
2085 gpointer data = NULL;
2088 child = g_variant_serialised_get_child (serialised, i);
2089 if (child.size && child.data == NULL)
2090 child.data = data = g_malloc0 (child.size);
2091 ok = check_tree (instance->children[i], child);
2092 g_variant_type_info_unref (child.type_info);
2104 switch (instance->data_size)
2107 g_assert (serialised.size == 1);
2108 return *(guint8 *) serialised.data ==
2109 (guint8) instance->data.integer;
2112 g_assert (serialised.size == 2);
2113 return *(guint16 *) serialised.data ==
2114 (guint16) instance->data.integer;
2117 g_assert (serialised.size == 4);
2118 return *(guint32 *) serialised.data ==
2119 (guint32) instance->data.integer;
2122 g_assert (serialised.size == 8);
2123 return *(guint64 *) serialised.data ==
2124 (guint64) instance->data.integer;
2127 if (serialised.size != instance->data_size)
2130 return memcmp (serialised.data,
2131 instance->data.string,
2132 instance->data_size) == 0;
2138 serialise_tree (TreeInstance *tree,
2139 GVariantSerialised *serialised)
2141 GVariantSerialised empty = { };
2143 *serialised = empty;
2144 tree_filler (serialised, tree);
2145 serialised->data = g_malloc (serialised->size);
2146 tree_filler (serialised, tree);
2150 test_byteswap (void)
2152 GVariantSerialised one, two;
2155 tree = tree_instance_new (NULL, 3);
2156 serialise_tree (tree, &one);
2158 i_am_writing_byteswapped = TRUE;
2159 serialise_tree (tree, &two);
2160 i_am_writing_byteswapped = FALSE;
2162 g_variant_serialised_byteswap (two);
2164 g_assert_cmpint (one.size, ==, two.size);
2165 g_assert (memcmp (one.data, two.data, one.size) == 0);
2167 tree_instance_free (tree);
2173 test_byteswaps (void)
2177 for (i = 0; i < 200; i++)
2180 g_variant_type_info_assert_no_infos ();
2184 test_fuzz (gdouble *fuzziness)
2186 GVariantSerialised serialised;
2189 /* make an instance */
2190 tree = tree_instance_new (NULL, 3);
2193 serialise_tree (tree, &serialised);
2195 g_assert (g_variant_serialised_is_normal (serialised));
2196 g_assert (check_tree (tree, serialised));
2198 if (serialised.size)
2200 gboolean fuzzed = FALSE;
2207 for (i = 0; i < serialised.size; i++)
2208 if (randomly (*fuzziness))
2210 serialised.data[i] += g_test_rand_int_range (1, 256);
2215 /* at least one byte in the serialised data has changed.
2217 * this means that at least one of the following is true:
2219 * - the serialised data now represents a different value:
2220 * check_tree() will return FALSE
2222 * - the serialised data is in non-normal form:
2223 * g_variant_serialiser_is_normal() will return FALSE
2225 * we always do both checks to increase exposure of the serialiser
2228 a = g_variant_serialised_is_normal (serialised);
2229 b = check_tree (tree, serialised);
2231 g_assert (!a || !b);
2234 tree_instance_free (tree);
2235 g_free (serialised.data);
2240 test_fuzzes (gpointer data)
2245 fuzziness = GPOINTER_TO_INT (data) / 100.;
2247 for (i = 0; i < 200; i++)
2248 test_fuzz (&fuzziness);
2250 g_variant_type_info_assert_no_infos ();
2254 tree_instance_get_gvariant (TreeInstance *tree)
2256 const GVariantType *type;
2259 type = (GVariantType *) g_variant_type_info_get_type_string (tree->info);
2261 switch (g_variant_type_info_get_type_char (tree->info))
2263 case G_VARIANT_TYPE_INFO_CHAR_MAYBE:
2265 const GVariantType *child_type;
2268 if (tree->n_children)
2269 child = tree_instance_get_gvariant (tree->children[0]);
2273 child_type = g_variant_type_element (type);
2275 if (child != NULL && randomly (0.5))
2278 result = g_variant_new_maybe (child_type, child);
2282 case G_VARIANT_TYPE_INFO_CHAR_ARRAY:
2284 const GVariantType *child_type;
2285 GVariant **children;
2288 children = g_new (GVariant *, tree->n_children);
2289 for (i = 0; i < tree->n_children; i++)
2290 children[i] = tree_instance_get_gvariant (tree->children[i]);
2292 child_type = g_variant_type_element (type);
2294 if (i > 0 && randomly (0.5))
2297 result = g_variant_new_array (child_type, children, tree->n_children);
2302 case G_VARIANT_TYPE_INFO_CHAR_TUPLE:
2304 GVariant **children;
2307 children = g_new (GVariant *, tree->n_children);
2308 for (i = 0; i < tree->n_children; i++)
2309 children[i] = tree_instance_get_gvariant (tree->children[i]);
2311 result = g_variant_new_tuple (children, tree->n_children);
2316 case G_VARIANT_TYPE_INFO_CHAR_DICT_ENTRY:
2318 GVariant *key, *val;
2320 g_assert (tree->n_children == 2);
2322 key = tree_instance_get_gvariant (tree->children[0]);
2323 val = tree_instance_get_gvariant (tree->children[1]);
2325 result = g_variant_new_dict_entry (key, val);
2329 case G_VARIANT_TYPE_INFO_CHAR_VARIANT:
2333 g_assert (tree->n_children == 1);
2335 value = tree_instance_get_gvariant (tree->children[0]);
2336 result = g_variant_new_variant (value);
2341 result = g_variant_new_boolean (tree->data.integer > 0);
2345 result = g_variant_new_byte (tree->data.integer);
2349 result = g_variant_new_int16 (tree->data.integer);
2353 result = g_variant_new_uint16 (tree->data.integer);
2357 result = g_variant_new_int32 (tree->data.integer);
2361 result = g_variant_new_uint32 (tree->data.integer);
2365 result = g_variant_new_int64 (tree->data.integer);
2369 result = g_variant_new_uint64 (tree->data.integer);
2373 result = g_variant_new_handle (tree->data.integer);
2377 result = g_variant_new_double (tree->data.floating);
2381 result = g_variant_new_string (tree->data.string);
2385 result = g_variant_new_object_path (tree->data.string);
2389 result = g_variant_new_signature (tree->data.string);
2393 g_assert_not_reached ();
2400 tree_instance_check_gvariant (TreeInstance *tree,
2403 const GVariantType *type;
2405 type = (GVariantType *) g_variant_type_info_get_type_string (tree->info);
2406 g_assert (g_variant_is_of_type (value, type));
2408 switch (g_variant_type_info_get_type_char (tree->info))
2410 case G_VARIANT_TYPE_INFO_CHAR_MAYBE:
2415 child = g_variant_get_maybe (value);
2417 if (child != NULL && tree->n_children == 1)
2418 equal = tree_instance_check_gvariant (tree->children[0], child);
2419 else if (child == NULL && tree->n_children == 0)
2425 g_variant_unref (child);
2431 case G_VARIANT_TYPE_INFO_CHAR_ARRAY:
2432 case G_VARIANT_TYPE_INFO_CHAR_TUPLE:
2433 case G_VARIANT_TYPE_INFO_CHAR_DICT_ENTRY:
2437 if (g_variant_n_children (value) != tree->n_children)
2440 for (i = 0; i < tree->n_children; i++)
2445 child = g_variant_get_child_value (value, i);
2446 equal = tree_instance_check_gvariant (tree->children[i], child);
2447 g_variant_unref (child);
2457 case G_VARIANT_TYPE_INFO_CHAR_VARIANT:
2459 const gchar *str1, *str2;
2463 child = g_variant_get_variant (value);
2464 str1 = g_variant_get_type_string (child);
2465 str2 = g_variant_type_info_get_type_string (tree->children[0]->info);
2466 /* GVariant only keeps one copy of type strings around */
2467 equal = str1 == str2 &&
2468 tree_instance_check_gvariant (tree->children[0], child);
2470 g_variant_unref (child);
2477 return g_variant_get_boolean (value) == tree->data.integer;
2480 return g_variant_get_byte (value) == (guchar) tree->data.integer;
2483 return g_variant_get_int16 (value) == (gint16) tree->data.integer;
2486 return g_variant_get_uint16 (value) == (guint16) tree->data.integer;
2489 return g_variant_get_int32 (value) == (gint32) tree->data.integer;
2492 return g_variant_get_uint32 (value) == (guint32) tree->data.integer;
2495 return g_variant_get_int64 (value) == (gint64) tree->data.integer;
2498 return g_variant_get_uint64 (value) == (guint64) tree->data.integer;
2501 return g_variant_get_handle (value) == (gint32) tree->data.integer;
2505 gdouble floating = g_variant_get_double (value);
2507 return memcmp (&floating, &tree->data.floating, sizeof floating) == 0;
2513 return strcmp (g_variant_get_string (value, NULL),
2514 tree->data.string) == 0;
2517 g_assert_not_reached ();
2522 tree_instance_build_gvariant (TreeInstance *tree,
2523 GVariantBuilder *builder,
2526 const GVariantType *type;
2528 type = (GVariantType *) g_variant_type_info_get_type_string (tree->info);
2530 if (g_variant_type_is_container (type))
2534 /* force GVariantBuilder to guess the type half the time */
2535 if (guess_ok && randomly (0.5))
2537 if (g_variant_type_is_array (type) && tree->n_children)
2538 type = G_VARIANT_TYPE_ARRAY;
2540 if (g_variant_type_is_maybe (type) && tree->n_children)
2541 type = G_VARIANT_TYPE_MAYBE;
2543 if (g_variant_type_is_tuple (type))
2544 type = G_VARIANT_TYPE_TUPLE;
2546 if (g_variant_type_is_dict_entry (type))
2547 type = G_VARIANT_TYPE_DICT_ENTRY;
2552 g_variant_builder_open (builder, type);
2554 for (i = 0; i < tree->n_children; i++)
2555 tree_instance_build_gvariant (tree->children[i], builder, guess_ok);
2557 g_variant_builder_close (builder);
2560 g_variant_builder_add_value (builder, tree_instance_get_gvariant (tree));
2565 tree_instance_check_iter (TreeInstance *tree,
2570 value = g_variant_iter_next_value (iter);
2572 if (g_variant_is_container (value))
2576 iter = g_variant_iter_new (value);
2577 g_variant_unref (value);
2579 if (g_variant_iter_n_children (iter) != tree->n_children)
2581 g_variant_iter_free (iter);
2585 for (i = 0; i < tree->n_children; i++)
2586 if (!tree_instance_check_iter (tree->children[i], iter))
2588 g_variant_iter_free (iter);
2592 g_assert (g_variant_iter_next_value (iter) == NULL);
2593 g_variant_iter_free (iter);
2602 equal = tree_instance_check_gvariant (tree, value);
2603 g_variant_unref (value);
2610 test_container (void)
2616 tree = tree_instance_new (NULL, 3);
2617 value = g_variant_ref_sink (tree_instance_get_gvariant (tree));
2619 s1 = g_variant_print (value, TRUE);
2620 g_assert (tree_instance_check_gvariant (tree, value));
2622 g_variant_get_data (value);
2624 s2 = g_variant_print (value, TRUE);
2625 g_assert (tree_instance_check_gvariant (tree, value));
2627 g_assert_cmpstr (s1, ==, s2);
2629 if (g_variant_is_container (value))
2631 GVariantBuilder builder;
2637 g_variant_builder_init (&builder, G_VARIANT_TYPE_VARIANT);
2638 tree_instance_build_gvariant (tree, &builder, TRUE);
2639 built = g_variant_builder_end (&builder);
2640 g_variant_ref_sink (built);
2641 g_variant_get_data (built);
2642 val = g_variant_get_variant (built);
2644 s3 = g_variant_print (val, TRUE);
2645 g_assert_cmpstr (s1, ==, s3);
2647 g_variant_iter_init (&iter, built);
2648 g_assert (tree_instance_check_iter (tree, &iter));
2649 g_assert (g_variant_iter_next_value (&iter) == NULL);
2651 g_variant_unref (built);
2652 g_variant_unref (val);
2656 tree_instance_free (tree);
2657 g_variant_unref (value);
2663 test_containers (void)
2667 for (i = 0; i < 100; i++)
2672 g_variant_type_info_assert_no_infos ();
2676 test_format_strings (void)
2681 g_assert (g_variant_format_string_scan ("i", NULL, &end) && *end == '\0');
2682 g_assert (g_variant_format_string_scan ("@i", NULL, &end) && *end == '\0');
2683 g_assert (g_variant_format_string_scan ("@ii", NULL, &end) && *end == 'i');
2684 g_assert (g_variant_format_string_scan ("^a&s", NULL, &end) && *end == '\0');
2685 g_assert (g_variant_format_string_scan ("(^as)", NULL, &end) &&
2687 g_assert (!g_variant_format_string_scan ("(^s)", NULL, &end));
2688 g_assert (!g_variant_format_string_scan ("(^a)", NULL, &end));
2689 g_assert (!g_variant_format_string_scan ("(z)", NULL, &end));
2690 g_assert (!g_variant_format_string_scan ("az", NULL, &end));
2691 g_assert (!g_variant_format_string_scan ("{**}", NULL, &end));
2692 g_assert (!g_variant_format_string_scan ("{@**}", NULL, &end));
2693 g_assert (g_variant_format_string_scan ("{@y*}", NULL, &end) &&
2695 g_assert (g_variant_format_string_scan ("{yv}", NULL, &end) &&
2697 g_assert (!g_variant_format_string_scan ("{vv}", NULL, &end));
2698 g_assert (!g_variant_format_string_scan ("{y}", NULL, &end));
2699 g_assert (!g_variant_format_string_scan ("{yyy}", NULL, &end));
2700 g_assert (!g_variant_format_string_scan ("{ya}", NULL, &end));
2701 g_assert (g_variant_format_string_scan ("&s", NULL, &end) && *end == '\0');
2702 g_assert (!g_variant_format_string_scan ("&as", NULL, &end));
2703 g_assert (!g_variant_format_string_scan ("@z", NULL, &end));
2704 g_assert (!g_variant_format_string_scan ("az", NULL, &end));
2705 g_assert (!g_variant_format_string_scan ("a&s", NULL, &end));
2707 type = g_variant_format_string_scan_type ("mm(@xy^a&s*?@?)", NULL, &end);
2708 g_assert (type && *end == '\0');
2709 g_assert (g_variant_type_equal (type, G_VARIANT_TYPE ("mm(xyas*?\?)")));
2710 g_variant_type_free (type);
2712 type = g_variant_format_string_scan_type ("mm(@xy^a&*?@?)", NULL, NULL);
2713 g_assert (type == NULL);
2717 exit_on_abort (int signal)
2723 do_failed_test (const gchar *pattern)
2725 if (g_test_trap_fork (1000000, G_TEST_TRAP_SILENCE_STDERR))
2727 signal (SIGABRT, exit_on_abort);
2731 g_test_trap_assert_failed ();
2732 g_test_trap_assert_stderr (pattern);
2738 test_invalid_varargs (void)
2740 if (do_failed_test ("*not a valid GVariant format string*"))
2742 g_variant_new ("z");
2746 if (do_failed_test ("*valid GVariant format string as a prefix*"))
2750 g_variant_new_va ("z", &end, NULL);
2754 if (do_failed_test ("*type of `q' but * has a type of `y'*"))
2756 g_variant_get (g_variant_new ("y", 'a'), "q");
2762 check_and_free (GVariant *value,
2765 gchar *valstr = g_variant_print (value, FALSE);
2766 g_assert_cmpstr (str, ==, valstr);
2767 g_variant_unref (value);
2775 GVariantBuilder array;
2777 g_variant_builder_init (&array, G_VARIANT_TYPE_ARRAY);
2778 g_variant_builder_add (&array, "{sv}", "size",
2779 g_variant_new ("(ii)", 800, 600));
2780 g_variant_builder_add (&array, "{sv}", "title",
2781 g_variant_new_string ("Test case"));
2782 g_variant_builder_add_value (&array,
2783 g_variant_new_dict_entry (g_variant_new_string ("temperature"),
2784 g_variant_new_variant (
2785 g_variant_new_double (37.5))));
2786 check_and_free (g_variant_new ("(ma{sv}m(a{sv})ma{sv}ii)",
2787 NULL, FALSE, NULL, &array, 7777, 8888),
2788 "(Nothing, Nothing, {'size': <(800, 600)>, "
2789 "'title': <'Test case'>, "
2790 "'temperature': <37.5>}, "
2793 check_and_free (g_variant_new ("(imimimmimmimmi)",
2800 "(123, Nothing, 123, Nothing, Just Nothing, 123)");
2802 check_and_free (g_variant_new ("(ybnixd)",
2803 'a', 1, 22, 33, (guint64) 44, 5.5),
2804 "(0x61, true, 22, 33, 44, 5.5)");
2806 check_and_free (g_variant_new ("(@y?*rv)",
2807 g_variant_new ("y", 'a'),
2808 g_variant_new ("y", 'b'),
2809 g_variant_new ("y", 'c'),
2810 g_variant_new ("(y)", 'd'),
2811 g_variant_new ("y", 'e')),
2812 "(0x61, 0x62, 0x63, (0x64,), <byte 0x65>)");
2816 GVariantBuilder array;
2823 g_variant_builder_init (&array, G_VARIANT_TYPE_ARRAY);
2824 for (i = 0; i < 100; i++)
2826 number = g_strdup_printf ("%d", i);
2827 g_variant_builder_add (&array, "s", number);
2831 value = g_variant_builder_end (&array);
2832 g_variant_iter_init (&iter, value);
2835 while (g_variant_iter_loop (&iter, "s", &number))
2837 gchar *check = g_strdup_printf ("%d", i++);
2838 g_assert_cmpstr (number, ==, check);
2841 g_assert (number == NULL);
2842 g_assert (i == 100);
2844 g_variant_unref (value);
2846 g_variant_builder_init (&array, G_VARIANT_TYPE_ARRAY);
2847 for (i = 0; i < 100; i++)
2848 g_variant_builder_add (&array, "mi", i % 2 == 0, i);
2849 value = g_variant_builder_end (&array);
2852 g_variant_iter_init (&iter, value);
2853 while (g_variant_iter_loop (&iter, "mi", NULL, &val))
2854 g_assert (val == i++ || val == 0);
2855 g_assert (i == 100);
2858 g_variant_iter_init (&iter, value);
2859 while (g_variant_iter_loop (&iter, "mi", &just, &val))
2866 g_assert (val == this);
2871 g_assert (val == 0);
2874 g_assert (i == 100);
2876 g_variant_unref (value);
2880 const gchar *strvector[] = {"/hello", "/world", NULL};
2881 const gchar *test_strs[] = {"/foo", "/bar", "/baz" };
2882 GVariantBuilder builder;
2883 GVariantIter *array;
2891 g_variant_builder_init (&builder, G_VARIANT_TYPE ("ao"));
2892 g_variant_builder_add (&builder, "o", "/foo");
2893 g_variant_builder_add (&builder, "o", "/bar");
2894 g_variant_builder_add (&builder, "o", "/baz");
2895 value = g_variant_new("(ao^ao^a&o)", &builder, strvector, strvector);
2896 g_variant_iter_init (&tuple, value);
2897 g_variant_iter_next (&tuple, "ao", &array);
2900 while (g_variant_iter_loop (array, "o", &str))
2901 g_assert_cmpstr (str, ==, test_strs[i++]);
2904 g_variant_iter_free (array);
2907 g_variant_iter_init (&tuple, value);
2908 g_variant_iter_next (&tuple, "ao", &array);
2911 while (g_variant_iter_loop (array, "&o", &str))
2912 g_assert_cmpstr (str, ==, test_strs[i++]);
2915 g_variant_iter_free (array);
2917 g_variant_iter_next (&tuple, "^a&o", &strv);
2918 g_variant_iter_next (&tuple, "^ao", &my_strv);
2920 g_assert_cmpstr (strv[0], ==, "/hello");
2921 g_assert_cmpstr (strv[1], ==, "/world");
2922 g_assert (strv[2] == NULL);
2923 g_assert_cmpstr (my_strv[0], ==, "/hello");
2924 g_assert_cmpstr (my_strv[1], ==, "/world");
2925 g_assert (my_strv[2] == NULL);
2927 g_variant_unref (value);
2928 g_strfreev (my_strv);
2933 const gchar *strvector[] = { "i", "ii", "iii", "iv", "v", "vi", NULL };
2934 GVariantBuilder builder;
2943 g_variant_builder_init (&builder, G_VARIANT_TYPE ("aag"));
2944 g_variant_builder_open (&builder, G_VARIANT_TYPE ("ag"));
2945 for (i = 0; i < 6; i++)
2947 g_variant_builder_add (&builder, "g", strvector[i]);
2949 g_variant_builder_add (&builder, "&g", strvector[i]);
2950 g_variant_builder_close (&builder);
2951 g_variant_builder_add (&builder, "^ag", strvector);
2952 g_variant_builder_add (&builder, "^ag", strvector);
2953 value = g_variant_new ("aag", &builder);
2955 g_variant_iter_init (&iter, value);
2956 while (g_variant_iter_loop (&iter, "^ag", &strv))
2957 for (i = 0; i < 6; i++)
2958 g_assert_cmpstr (strv[i], ==, strvector[i]);
2960 g_variant_iter_init (&iter, value);
2961 while (g_variant_iter_loop (&iter, "^a&g", &strv))
2962 for (i = 0; i < 6; i++)
2963 g_assert_cmpstr (strv[i], ==, strvector[i]);
2965 g_variant_iter_init (&iter, value);
2966 while (g_variant_iter_loop (&iter, "ag", &i2))
2971 while (g_variant_iter_loop (i2, "g", &str))
2972 g_assert_cmpstr (str, ==, strvector[i++]);
2976 g_variant_iter_init (&iter, value);
2977 i3 = g_variant_iter_copy (&iter);
2978 while (g_variant_iter_loop (&iter, "@ag", &sub))
2980 gchar *str = g_variant_print (sub, TRUE);
2981 g_assert_cmpstr (str, ==,
2982 "[signature 'i', 'ii', 'iii', 'iv', 'v', 'vi']");
2986 if (do_failed_test ("*NULL has already been returned*"))
2988 g_variant_iter_next_value (&iter);
2993 while (g_variant_iter_loop (i3, "*", &sub))
2995 gchar *str = g_variant_print (sub, TRUE);
2996 g_assert_cmpstr (str, ==,
2997 "[signature 'i', 'ii', 'iii', 'iv', 'v', 'vi']");
3001 g_variant_iter_free (i3);
3003 for (i = 0; i < g_variant_n_children (value); i++)
3007 g_variant_get_child (value, i, "*", &sub);
3009 for (j = 0; j < g_variant_n_children (sub); j++)
3011 const gchar *str = NULL;
3014 g_variant_get_child (sub, j, "&g", &str);
3015 g_assert_cmpstr (str, ==, strvector[j]);
3017 cval = g_variant_get_child_value (sub, j);
3018 g_variant_get (cval, "&g", &str);
3019 g_assert_cmpstr (str, ==, strvector[j]);
3020 g_variant_unref (cval);
3023 g_variant_unref (sub);
3026 g_variant_unref (value);
3045 /* test all 'Nothing' */
3046 value = g_variant_new ("(mymbmnmqmimumxmtmhmdmv)",
3049 FALSE, (gint16) 123,
3050 FALSE, (guint16) 123,
3051 FALSE, (gint32) 123,
3052 FALSE, (guint32) 123,
3053 FALSE, (gint64) 123,
3054 FALSE, (guint64) 123,
3056 FALSE, (gdouble) 37.5,
3060 g_variant_get (value, "(mymbmnmqmimumxmtmhmdmv)",
3074 memset (justs, 1, sizeof justs);
3075 g_variant_get (value, "(mymbmnmqmimumxmtmhmdmv)",
3087 g_assert (!(justs[0] || justs[1] || justs[2] || justs[3] || justs[4] ||
3088 justs[5] || justs[6] || justs[7] || justs[8] || justs[9]));
3091 memset (justs, 1, sizeof justs);
3092 byteval = i16val = u16val = i32val = u32val = i64val = u64val = hval = 88;
3096 g_variant_get (value, "(mymbmnmqmimumxmtmhmdmv)",
3097 &justs[0], &byteval,
3108 g_assert (!(justs[0] || justs[1] || justs[2] || justs[3] || justs[4] ||
3109 justs[5] || justs[6] || justs[7] || justs[8] || justs[9]));
3110 g_assert (byteval == '\0' && bval == FALSE);
3111 g_assert (i16val == 0 && u16val == 0 && i32val == 0 &&
3112 u32val == 0 && i64val == 0 && u64val == 0 &&
3113 hval == 0 && dval == 0.0);
3114 g_assert (vval == NULL);
3117 byteval = i16val = u16val = i32val = u32val = i64val = u64val = hval = 88;
3121 g_variant_get (value, "(mymbmnmqmimumxmtmhmdmv)",
3133 g_assert (byteval == '\0' && bval == FALSE);
3134 g_assert (i16val == 0 && u16val == 0 && i32val == 0 &&
3135 u32val == 0 && i64val == 0 && u64val == 0 &&
3136 hval == 0 && dval == 0.0);
3137 g_assert (vval == NULL);
3139 g_variant_unref (value);
3142 /* test all 'Just' */
3143 value = g_variant_new ("(mymbmnmqmimumxmtmhmdmv)",
3147 TRUE, (guint16) 123,
3149 TRUE, (guint32) 123,
3151 TRUE, (guint64) 123,
3153 TRUE, (gdouble) 37.5,
3154 g_variant_new ("()"));
3157 g_variant_get (value, "(mymbmnmqmimumxmtmhmdmv)",
3171 memset (justs, 0, sizeof justs);
3172 g_variant_get (value, "(mymbmnmqmimumxmtmhmdmv)",
3184 g_assert (justs[0] && justs[1] && justs[2] && justs[3] && justs[4] &&
3185 justs[5] && justs[6] && justs[7] && justs[8] && justs[9]);
3188 memset (justs, 0, sizeof justs);
3189 byteval = i16val = u16val = i32val = u32val = i64val = u64val = hval = 88;
3193 g_variant_get (value, "(mymbmnmqmimumxmtmhmdmv)",
3194 &justs[0], &byteval,
3205 g_assert (justs[0] && justs[1] && justs[2] && justs[3] && justs[4] &&
3206 justs[5] && justs[6] && justs[7] && justs[8] && justs[9]);
3207 g_assert (byteval == 'a' && bval == TRUE);
3208 g_assert (i16val == 123 && u16val == 123 && i32val == 123 &&
3209 u32val == 123 && i64val == 123 && u64val == 123 &&
3210 hval == -1 && dval == 37.5);
3211 g_assert (g_variant_is_of_type (vval, G_VARIANT_TYPE_UNIT));
3212 g_variant_unref (vval);
3215 byteval = i16val = u16val = i32val = u32val = i64val = u64val = hval = 88;
3219 g_variant_get (value, "(mymbmnmqmimumxmtmhmdmv)",
3231 g_assert (byteval == 'a' && bval == TRUE);
3232 g_assert (i16val == 123 && u16val == 123 && i32val == 123 &&
3233 u32val == 123 && i64val == 123 && u64val == 123 &&
3234 hval == -1 && dval == 37.5);
3235 g_assert (g_variant_is_of_type (vval, G_VARIANT_TYPE_UNIT));
3236 g_variant_unref (vval);
3238 g_variant_unref (value);
3241 g_variant_type_info_assert_no_infos ();
3245 hash_get (GVariant *value,
3246 const gchar *format,
3249 const gchar *endptr = NULL;
3253 hash = g_str_has_suffix (format, "#");
3255 va_start (ap, format);
3256 g_variant_get_va (value, format, hash ? &endptr : NULL, &ap);
3260 g_assert (*endptr == '#');
3264 hash_new (const gchar *format,
3267 const gchar *endptr = NULL;
3272 hash = g_str_has_suffix (format, "#");
3274 va_start (ap, format);
3275 value = g_variant_new_va (format, hash ? &endptr : NULL, &ap);
3279 g_assert (*endptr == '#');
3291 value = hash_new ("i", 234);
3292 hash_get (value, "i", &x);
3293 g_assert (x == 234);
3294 g_variant_unref (value);
3297 value = hash_new ("i#", 234);
3298 hash_get (value, "i#", &x);
3299 g_assert (x == 234);
3300 g_variant_unref (value);
3302 g_variant_type_info_assert_no_infos ();
3306 test_builder_memory (void)
3308 GVariantBuilder *hb;
3311 hb = g_variant_builder_new (G_VARIANT_TYPE_ARRAY);
3312 g_variant_builder_open (hb, G_VARIANT_TYPE_ARRAY);
3313 g_variant_builder_open (hb, G_VARIANT_TYPE_ARRAY);
3314 g_variant_builder_open (hb, G_VARIANT_TYPE_ARRAY);
3315 g_variant_builder_add (hb, "s", "some value");
3316 g_variant_builder_ref (hb);
3317 g_variant_builder_unref (hb);
3318 g_variant_builder_unref (hb);
3320 hb = g_variant_builder_new (G_VARIANT_TYPE_ARRAY);
3321 g_variant_builder_unref (hb);
3323 hb = g_variant_builder_new (G_VARIANT_TYPE_ARRAY);
3324 g_variant_builder_clear (hb);
3325 g_variant_builder_unref (hb);
3327 g_variant_builder_init (&sb, G_VARIANT_TYPE_ARRAY);
3328 g_variant_builder_open (&sb, G_VARIANT_TYPE_ARRAY);
3329 g_variant_builder_open (&sb, G_VARIANT_TYPE_ARRAY);
3330 g_variant_builder_add (&sb, "s", "some value");
3331 g_variant_builder_clear (&sb);
3333 g_variant_type_info_assert_no_infos ();
3339 const gint n_items = 4096;
3340 GVariant *items[n_items];
3344 table = g_hash_table_new_full (g_variant_hash, g_variant_equal,
3345 (GDestroyNotify ) g_variant_unref,
3348 for (i = 0; i < n_items; i++)
3354 tree = tree_instance_new (NULL, 0);
3355 items[i] = tree_instance_get_gvariant (tree);
3356 tree_instance_free (tree);
3358 for (j = 0; j < i; j++)
3359 if (g_variant_equal (items[i], items[j]))
3361 g_variant_unref (items[i]);
3365 g_hash_table_insert (table,
3366 g_variant_ref_sink (items[i]),
3367 GINT_TO_POINTER (i));
3370 for (i = 0; i < n_items; i++)
3374 result = g_hash_table_lookup (table, items[i]);
3375 g_assert_cmpint (GPOINTER_TO_INT (result), ==, i);
3378 g_hash_table_unref (table);
3380 g_variant_type_info_assert_no_infos ();
3384 main (int argc, char **argv)
3388 g_test_init (&argc, &argv, NULL);
3390 g_test_add_func ("/gvariant/type", test_gvarianttype);
3391 g_test_add_func ("/gvariant/typeinfo", test_gvarianttypeinfo);
3392 g_test_add_func ("/gvariant/serialiser/maybe", test_maybes);
3393 g_test_add_func ("/gvariant/serialiser/array", test_arrays);
3394 g_test_add_func ("/gvariant/serialiser/tuple", test_tuples);
3395 g_test_add_func ("/gvariant/serialiser/variant", test_variants);
3396 g_test_add_func ("/gvariant/serialiser/strings", test_strings);
3397 g_test_add_func ("/gvariant/serialiser/byteswap", test_byteswaps);
3399 for (i = 1; i <= 20; i += 4)
3403 testname = g_strdup_printf ("/gvariant/serialiser/fuzz/%d%%", i);
3404 g_test_add_data_func (testname, GINT_TO_POINTER (i),
3405 (gpointer) test_fuzzes);
3409 g_test_add_func ("/gvariant/containers", test_containers);
3410 g_test_add_func ("/gvariant/format-strings", test_format_strings);
3411 g_test_add_func ("/gvariant/invalid-varargs", test_invalid_varargs);
3412 g_test_add_func ("/gvariant/varargs", test_varargs);
3413 g_test_add_func ("/gvariant/valist", test_valist);
3414 g_test_add_func ("/gvariant/builder-memory", test_builder_memory);
3415 g_test_add_func ("/gvariant/hashing", test_hashing);
3417 return g_test_run ();