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 ((gchar *) 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;
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;
1944 instance->data.floating = g_test_rand_double ();
1945 instance->data_size = 8;
1948 case 's': case 'o': case 'g':
1949 instance->data_size = g_test_rand_int_range (10, 20);
1950 make_random_string (instance->data.string, instance->data_size, type);
1954 if (instance->data_size == 0)
1955 /* no data -> it is a container */
1959 instance->children = g_new (TreeInstance *, instance->n_children);
1961 for (i = 0; i < instance->n_children; i++)
1963 instance->children[i] = tree_instance_new (child_type, depth - 1);
1966 child_type = g_variant_type_next (child_type);
1969 g_assert (!is_tuple_type || child_type == NULL);
1972 g_variant_type_free (mytype);
1978 tree_instance_free (TreeInstance *instance)
1982 g_variant_type_info_unref (instance->info);
1983 for (i = 0; i < instance->n_children; i++)
1984 tree_instance_free (instance->children[i]);
1985 g_free (instance->children);
1986 g_slice_free (TreeInstance, instance);
1989 static gboolean i_am_writing_byteswapped;
1992 tree_filler (GVariantSerialised *serialised,
1995 TreeInstance *instance = data;
1997 if (serialised->type_info == NULL)
1998 serialised->type_info = instance->info;
2000 if (instance->data_size == 0)
2001 /* is a container */
2003 if (serialised->size == 0)
2005 g_variant_serialiser_needed_size (instance->info, tree_filler,
2006 (gpointer *) instance->children,
2007 instance->n_children);
2009 if (serialised->data)
2010 g_variant_serialiser_serialise (*serialised, tree_filler,
2011 (gpointer *) instance->children,
2012 instance->n_children);
2017 if (serialised->size == 0)
2018 serialised->size = instance->data_size;
2020 if (serialised->data)
2022 switch (instance->data_size)
2025 *serialised->data = instance->data.integer;
2030 guint16 value = instance->data.integer;
2032 if (i_am_writing_byteswapped)
2033 value = GUINT16_SWAP_LE_BE (value);
2035 *(guint16 *) serialised->data = value;
2041 guint32 value = instance->data.integer;
2043 if (i_am_writing_byteswapped)
2044 value = GUINT32_SWAP_LE_BE (value);
2046 *(guint32 *) serialised->data = value;
2052 guint64 value = instance->data.integer;
2054 if (i_am_writing_byteswapped)
2055 value = GUINT64_SWAP_LE_BE (value);
2057 *(guint64 *) serialised->data = value;
2062 memcpy (serialised->data,
2063 instance->data.string,
2064 instance->data_size);
2072 check_tree (TreeInstance *instance,
2073 GVariantSerialised serialised)
2075 if (instance->info != serialised.type_info)
2078 if (instance->data_size == 0)
2079 /* is a container */
2083 if (g_variant_serialised_n_children (serialised) !=
2084 instance->n_children)
2087 for (i = 0; i < instance->n_children; i++)
2089 GVariantSerialised child;
2090 gpointer data = NULL;
2093 child = g_variant_serialised_get_child (serialised, i);
2094 if (child.size && child.data == NULL)
2095 child.data = data = g_malloc0 (child.size);
2096 ok = check_tree (instance->children[i], child);
2097 g_variant_type_info_unref (child.type_info);
2109 switch (instance->data_size)
2112 g_assert (serialised.size == 1);
2113 return *(guint8 *) serialised.data ==
2114 (guint8) instance->data.integer;
2117 g_assert (serialised.size == 2);
2118 return *(guint16 *) serialised.data ==
2119 (guint16) instance->data.integer;
2122 g_assert (serialised.size == 4);
2123 return *(guint32 *) serialised.data ==
2124 (guint32) instance->data.integer;
2127 g_assert (serialised.size == 8);
2128 return *(guint64 *) serialised.data ==
2129 (guint64) instance->data.integer;
2132 if (serialised.size != instance->data_size)
2135 return memcmp (serialised.data,
2136 instance->data.string,
2137 instance->data_size) == 0;
2143 serialise_tree (TreeInstance *tree,
2144 GVariantSerialised *serialised)
2146 GVariantSerialised empty = { };
2148 *serialised = empty;
2149 tree_filler (serialised, tree);
2150 serialised->data = g_malloc (serialised->size);
2151 tree_filler (serialised, tree);
2155 test_byteswap (void)
2157 GVariantSerialised one, two;
2160 tree = tree_instance_new (NULL, 3);
2161 serialise_tree (tree, &one);
2163 i_am_writing_byteswapped = TRUE;
2164 serialise_tree (tree, &two);
2165 i_am_writing_byteswapped = FALSE;
2167 g_variant_serialised_byteswap (two);
2169 g_assert_cmpint (one.size, ==, two.size);
2170 g_assert (memcmp (one.data, two.data, one.size) == 0);
2172 tree_instance_free (tree);
2178 test_byteswaps (void)
2182 for (i = 0; i < 200; i++)
2185 g_variant_type_info_assert_no_infos ();
2189 test_fuzz (gdouble *fuzziness)
2191 GVariantSerialised serialised;
2194 /* make an instance */
2195 tree = tree_instance_new (NULL, 3);
2198 serialise_tree (tree, &serialised);
2200 g_assert (g_variant_serialised_is_normal (serialised));
2201 g_assert (check_tree (tree, serialised));
2203 if (serialised.size)
2205 gboolean fuzzed = FALSE;
2212 for (i = 0; i < serialised.size; i++)
2213 if (randomly (*fuzziness))
2215 serialised.data[i] += g_test_rand_int_range (1, 256);
2220 /* at least one byte in the serialised data has changed.
2222 * this means that at least one of the following is true:
2224 * - the serialised data now represents a different value:
2225 * check_tree() will return FALSE
2227 * - the serialised data is in non-normal form:
2228 * g_variant_serialiser_is_normal() will return FALSE
2230 * we always do both checks to increase exposure of the serialiser
2233 a = g_variant_serialised_is_normal (serialised);
2234 b = check_tree (tree, serialised);
2236 g_assert (!a || !b);
2239 tree_instance_free (tree);
2240 g_free (serialised.data);
2245 test_fuzzes (gpointer data)
2250 fuzziness = GPOINTER_TO_INT (data) / 100.;
2252 for (i = 0; i < 200; i++)
2253 test_fuzz (&fuzziness);
2255 g_variant_type_info_assert_no_infos ();
2259 tree_instance_get_gvariant (TreeInstance *tree)
2261 const GVariantType *type;
2264 type = (GVariantType *) g_variant_type_info_get_type_string (tree->info);
2266 switch (g_variant_type_info_get_type_char (tree->info))
2268 case G_VARIANT_TYPE_INFO_CHAR_MAYBE:
2270 const GVariantType *child_type;
2273 if (tree->n_children)
2274 child = tree_instance_get_gvariant (tree->children[0]);
2278 child_type = g_variant_type_element (type);
2280 if (child != NULL && randomly (0.5))
2283 result = g_variant_new_maybe (child_type, child);
2287 case G_VARIANT_TYPE_INFO_CHAR_ARRAY:
2289 const GVariantType *child_type;
2290 GVariant **children;
2293 children = g_new (GVariant *, tree->n_children);
2294 for (i = 0; i < tree->n_children; i++)
2295 children[i] = tree_instance_get_gvariant (tree->children[i]);
2297 child_type = g_variant_type_element (type);
2299 if (i > 0 && randomly (0.5))
2302 result = g_variant_new_array (child_type, children, tree->n_children);
2307 case G_VARIANT_TYPE_INFO_CHAR_TUPLE:
2309 GVariant **children;
2312 children = g_new (GVariant *, tree->n_children);
2313 for (i = 0; i < tree->n_children; i++)
2314 children[i] = tree_instance_get_gvariant (tree->children[i]);
2316 result = g_variant_new_tuple (children, tree->n_children);
2321 case G_VARIANT_TYPE_INFO_CHAR_DICT_ENTRY:
2323 GVariant *key, *val;
2325 g_assert (tree->n_children == 2);
2327 key = tree_instance_get_gvariant (tree->children[0]);
2328 val = tree_instance_get_gvariant (tree->children[1]);
2330 result = g_variant_new_dict_entry (key, val);
2334 case G_VARIANT_TYPE_INFO_CHAR_VARIANT:
2338 g_assert (tree->n_children == 1);
2340 value = tree_instance_get_gvariant (tree->children[0]);
2341 result = g_variant_new_variant (value);
2346 result = g_variant_new_boolean (tree->data.integer > 0);
2350 result = g_variant_new_byte (tree->data.integer);
2354 result = g_variant_new_int16 (tree->data.integer);
2358 result = g_variant_new_uint16 (tree->data.integer);
2362 result = g_variant_new_int32 (tree->data.integer);
2366 result = g_variant_new_uint32 (tree->data.integer);
2370 result = g_variant_new_int64 (tree->data.integer);
2374 result = g_variant_new_uint64 (tree->data.integer);
2378 result = g_variant_new_handle (tree->data.integer);
2382 result = g_variant_new_double (tree->data.floating);
2386 result = g_variant_new_string (tree->data.string);
2390 result = g_variant_new_object_path (tree->data.string);
2394 result = g_variant_new_signature (tree->data.string);
2398 g_assert_not_reached ();
2405 tree_instance_check_gvariant (TreeInstance *tree,
2408 const GVariantType *type;
2410 type = (GVariantType *) g_variant_type_info_get_type_string (tree->info);
2411 g_assert (g_variant_is_of_type (value, type));
2413 switch (g_variant_type_info_get_type_char (tree->info))
2415 case G_VARIANT_TYPE_INFO_CHAR_MAYBE:
2420 child = g_variant_get_maybe (value);
2422 if (child != NULL && tree->n_children == 1)
2423 equal = tree_instance_check_gvariant (tree->children[0], child);
2424 else if (child == NULL && tree->n_children == 0)
2430 g_variant_unref (child);
2436 case G_VARIANT_TYPE_INFO_CHAR_ARRAY:
2437 case G_VARIANT_TYPE_INFO_CHAR_TUPLE:
2438 case G_VARIANT_TYPE_INFO_CHAR_DICT_ENTRY:
2442 if (g_variant_n_children (value) != tree->n_children)
2445 for (i = 0; i < tree->n_children; i++)
2450 child = g_variant_get_child_value (value, i);
2451 equal = tree_instance_check_gvariant (tree->children[i], child);
2452 g_variant_unref (child);
2462 case G_VARIANT_TYPE_INFO_CHAR_VARIANT:
2464 const gchar *str1, *str2;
2468 child = g_variant_get_variant (value);
2469 str1 = g_variant_get_type_string (child);
2470 str2 = g_variant_type_info_get_type_string (tree->children[0]->info);
2471 /* GVariant only keeps one copy of type strings around */
2472 equal = str1 == str2 &&
2473 tree_instance_check_gvariant (tree->children[0], child);
2475 g_variant_unref (child);
2482 return g_variant_get_boolean (value) == tree->data.integer;
2485 return g_variant_get_byte (value) == (guchar) tree->data.integer;
2488 return g_variant_get_int16 (value) == (gint16) tree->data.integer;
2491 return g_variant_get_uint16 (value) == (guint16) tree->data.integer;
2494 return g_variant_get_int32 (value) == (gint32) tree->data.integer;
2497 return g_variant_get_uint32 (value) == (guint32) tree->data.integer;
2500 return g_variant_get_int64 (value) == (gint64) tree->data.integer;
2503 return g_variant_get_uint64 (value) == (guint64) tree->data.integer;
2506 return g_variant_get_handle (value) == (gint32) tree->data.integer;
2510 gdouble floating = g_variant_get_double (value);
2512 return memcmp (&floating, &tree->data.floating, sizeof floating) == 0;
2518 return strcmp (g_variant_get_string (value, NULL),
2519 tree->data.string) == 0;
2522 g_assert_not_reached ();
2527 tree_instance_build_gvariant (TreeInstance *tree,
2528 GVariantBuilder *builder,
2531 const GVariantType *type;
2533 type = (GVariantType *) g_variant_type_info_get_type_string (tree->info);
2535 if (g_variant_type_is_container (type))
2539 /* force GVariantBuilder to guess the type half the time */
2540 if (guess_ok && randomly (0.5))
2542 if (g_variant_type_is_array (type) && tree->n_children)
2543 type = G_VARIANT_TYPE_ARRAY;
2545 if (g_variant_type_is_maybe (type) && tree->n_children)
2546 type = G_VARIANT_TYPE_MAYBE;
2548 if (g_variant_type_is_tuple (type))
2549 type = G_VARIANT_TYPE_TUPLE;
2551 if (g_variant_type_is_dict_entry (type))
2552 type = G_VARIANT_TYPE_DICT_ENTRY;
2557 g_variant_builder_open (builder, type);
2559 for (i = 0; i < tree->n_children; i++)
2560 tree_instance_build_gvariant (tree->children[i], builder, guess_ok);
2562 g_variant_builder_close (builder);
2565 g_variant_builder_add_value (builder, tree_instance_get_gvariant (tree));
2570 tree_instance_check_iter (TreeInstance *tree,
2575 value = g_variant_iter_next_value (iter);
2577 if (g_variant_is_container (value))
2581 iter = g_variant_iter_new (value);
2582 g_variant_unref (value);
2584 if (g_variant_iter_n_children (iter) != tree->n_children)
2586 g_variant_iter_free (iter);
2590 for (i = 0; i < tree->n_children; i++)
2591 if (!tree_instance_check_iter (tree->children[i], iter))
2593 g_variant_iter_free (iter);
2597 g_assert (g_variant_iter_next_value (iter) == NULL);
2598 g_variant_iter_free (iter);
2607 equal = tree_instance_check_gvariant (tree, value);
2608 g_variant_unref (value);
2615 test_container (void)
2621 tree = tree_instance_new (NULL, 3);
2622 value = g_variant_ref_sink (tree_instance_get_gvariant (tree));
2624 s1 = g_variant_print (value, TRUE);
2625 g_assert (tree_instance_check_gvariant (tree, value));
2627 g_variant_get_data (value);
2629 s2 = g_variant_print (value, TRUE);
2630 g_assert (tree_instance_check_gvariant (tree, value));
2632 g_assert_cmpstr (s1, ==, s2);
2634 if (g_variant_is_container (value))
2636 GVariantBuilder builder;
2642 g_variant_builder_init (&builder, G_VARIANT_TYPE_VARIANT);
2643 tree_instance_build_gvariant (tree, &builder, TRUE);
2644 built = g_variant_builder_end (&builder);
2645 g_variant_ref_sink (built);
2646 g_variant_get_data (built);
2647 val = g_variant_get_variant (built);
2649 s3 = g_variant_print (val, TRUE);
2650 g_assert_cmpstr (s1, ==, s3);
2652 g_variant_iter_init (&iter, built);
2653 g_assert (tree_instance_check_iter (tree, &iter));
2654 g_assert (g_variant_iter_next_value (&iter) == NULL);
2656 g_variant_unref (built);
2657 g_variant_unref (val);
2661 tree_instance_free (tree);
2662 g_variant_unref (value);
2668 test_containers (void)
2672 for (i = 0; i < 100; i++)
2677 g_variant_type_info_assert_no_infos ();
2681 test_format_strings (void)
2686 g_assert (g_variant_format_string_scan ("i", NULL, &end) && *end == '\0');
2687 g_assert (g_variant_format_string_scan ("@i", NULL, &end) && *end == '\0');
2688 g_assert (g_variant_format_string_scan ("@ii", NULL, &end) && *end == 'i');
2689 g_assert (g_variant_format_string_scan ("^a&s", NULL, &end) && *end == '\0');
2690 g_assert (g_variant_format_string_scan ("(^as)", NULL, &end) &&
2692 g_assert (!g_variant_format_string_scan ("(^s)", NULL, &end));
2693 g_assert (!g_variant_format_string_scan ("(^a)", NULL, &end));
2694 g_assert (!g_variant_format_string_scan ("(z)", NULL, &end));
2695 g_assert (!g_variant_format_string_scan ("az", NULL, &end));
2696 g_assert (!g_variant_format_string_scan ("{**}", NULL, &end));
2697 g_assert (!g_variant_format_string_scan ("{@**}", NULL, &end));
2698 g_assert (g_variant_format_string_scan ("{@y*}", NULL, &end) &&
2700 g_assert (g_variant_format_string_scan ("{yv}", NULL, &end) &&
2702 g_assert (!g_variant_format_string_scan ("{&?v}", NULL, &end));
2703 g_assert (g_variant_format_string_scan ("{@?v}", NULL, &end) &&
2705 g_assert (!g_variant_format_string_scan ("{&@sv}", NULL, &end));
2706 g_assert (!g_variant_format_string_scan ("{@&sv}", NULL, &end));
2707 g_assert (g_variant_format_string_scan ("{&sv}", NULL, &end) &&
2709 g_assert (!g_variant_format_string_scan ("{vv}", NULL, &end));
2710 g_assert (!g_variant_format_string_scan ("{y}", NULL, &end));
2711 g_assert (!g_variant_format_string_scan ("{yyy}", NULL, &end));
2712 g_assert (!g_variant_format_string_scan ("{ya}", NULL, &end));
2713 g_assert (g_variant_format_string_scan ("&s", NULL, &end) && *end == '\0');
2714 g_assert (!g_variant_format_string_scan ("&as", NULL, &end));
2715 g_assert (!g_variant_format_string_scan ("@z", NULL, &end));
2716 g_assert (!g_variant_format_string_scan ("az", NULL, &end));
2717 g_assert (!g_variant_format_string_scan ("a&s", NULL, &end));
2719 type = g_variant_format_string_scan_type ("mm(@xy^a&s*?@?)", NULL, &end);
2720 g_assert (type && *end == '\0');
2721 g_assert (g_variant_type_equal (type, G_VARIANT_TYPE ("mm(xyas*?\?)")));
2722 g_variant_type_free (type);
2724 type = g_variant_format_string_scan_type ("mm(@xy^a&*?@?)", NULL, NULL);
2725 g_assert (type == NULL);
2729 exit_on_abort (int signal)
2735 do_failed_test (const gchar *pattern)
2737 if (g_test_trap_fork (1000000, G_TEST_TRAP_SILENCE_STDERR))
2739 signal (SIGABRT, exit_on_abort);
2743 g_test_trap_assert_failed ();
2744 g_test_trap_assert_stderr (pattern);
2750 test_invalid_varargs (void)
2752 if (do_failed_test ("*GVariant format string*"))
2754 g_variant_new ("z");
2758 if (do_failed_test ("*valid GVariant format string as a prefix*"))
2762 g_variant_new_va ("z", &end, NULL);
2766 if (do_failed_test ("*type of `q' but * has a type of `y'*"))
2768 g_variant_get (g_variant_new ("y", 'a'), "q");
2774 check_and_free (GVariant *value,
2777 gchar *valstr = g_variant_print (value, FALSE);
2778 g_assert_cmpstr (str, ==, valstr);
2779 g_variant_unref (value);
2787 GVariantBuilder array;
2789 g_variant_builder_init (&array, G_VARIANT_TYPE_ARRAY);
2790 g_variant_builder_add (&array, "{sv}", "size",
2791 g_variant_new ("(ii)", 800, 600));
2792 g_variant_builder_add (&array, "{sv}", "title",
2793 g_variant_new_string ("Test case"));
2794 g_variant_builder_add_value (&array,
2795 g_variant_new_dict_entry (g_variant_new_string ("temperature"),
2796 g_variant_new_variant (
2797 g_variant_new_double (37.5))));
2798 check_and_free (g_variant_new ("(ma{sv}m(a{sv})ma{sv}ii)",
2799 NULL, FALSE, NULL, &array, 7777, 8888),
2800 "(nothing, nothing, {'size': <(800, 600)>, "
2801 "'title': <'Test case'>, "
2802 "'temperature': <37.5>}, "
2805 check_and_free (g_variant_new ("(imimimmimmimmi)",
2812 "(123, nothing, 123, nothing, just nothing, 123)");
2814 check_and_free (g_variant_new ("(ybnixd)",
2815 'a', 1, 22, 33, (guint64) 44, 5.5),
2816 "(0x61, true, 22, 33, 44, 5.5)");
2818 check_and_free (g_variant_new ("(@y?*rv)",
2819 g_variant_new ("y", 'a'),
2820 g_variant_new ("y", 'b'),
2821 g_variant_new ("y", 'c'),
2822 g_variant_new ("(y)", 'd'),
2823 g_variant_new ("y", 'e')),
2824 "(0x61, 0x62, 0x63, (0x64,), <byte 0x65>)");
2828 GVariantBuilder array;
2835 g_variant_builder_init (&array, G_VARIANT_TYPE_ARRAY);
2836 for (i = 0; i < 100; i++)
2838 number = g_strdup_printf ("%d", i);
2839 g_variant_builder_add (&array, "s", number);
2843 value = g_variant_builder_end (&array);
2844 g_variant_iter_init (&iter, value);
2847 while (g_variant_iter_loop (&iter, "s", &number))
2849 gchar *check = g_strdup_printf ("%d", i++);
2850 g_assert_cmpstr (number, ==, check);
2853 g_assert (number == NULL);
2854 g_assert (i == 100);
2856 g_variant_unref (value);
2858 g_variant_builder_init (&array, G_VARIANT_TYPE_ARRAY);
2859 for (i = 0; i < 100; i++)
2860 g_variant_builder_add (&array, "mi", i % 2 == 0, i);
2861 value = g_variant_builder_end (&array);
2864 g_variant_iter_init (&iter, value);
2865 while (g_variant_iter_loop (&iter, "mi", NULL, &val))
2866 g_assert (val == i++ || val == 0);
2867 g_assert (i == 100);
2870 g_variant_iter_init (&iter, value);
2871 while (g_variant_iter_loop (&iter, "mi", &just, &val))
2878 g_assert (val == this);
2883 g_assert (val == 0);
2886 g_assert (i == 100);
2888 g_variant_unref (value);
2892 const gchar *strvector[] = {"/hello", "/world", NULL};
2893 const gchar *test_strs[] = {"/foo", "/bar", "/baz" };
2894 GVariantBuilder builder;
2895 GVariantIter *array;
2903 g_variant_builder_init (&builder, G_VARIANT_TYPE ("ao"));
2904 g_variant_builder_add (&builder, "o", "/foo");
2905 g_variant_builder_add (&builder, "o", "/bar");
2906 g_variant_builder_add (&builder, "o", "/baz");
2907 value = g_variant_new("(ao^ao^a&o)", &builder, strvector, strvector);
2908 g_variant_iter_init (&tuple, value);
2909 g_variant_iter_next (&tuple, "ao", &array);
2912 while (g_variant_iter_loop (array, "o", &str))
2913 g_assert_cmpstr (str, ==, test_strs[i++]);
2916 g_variant_iter_free (array);
2919 g_variant_iter_init (&tuple, value);
2920 g_variant_iter_next (&tuple, "ao", &array);
2923 while (g_variant_iter_loop (array, "&o", &str))
2924 g_assert_cmpstr (str, ==, test_strs[i++]);
2927 g_variant_iter_free (array);
2929 g_variant_iter_next (&tuple, "^a&o", &strv);
2930 g_variant_iter_next (&tuple, "^ao", &my_strv);
2932 g_assert_cmpstr (strv[0], ==, "/hello");
2933 g_assert_cmpstr (strv[1], ==, "/world");
2934 g_assert (strv[2] == NULL);
2935 g_assert_cmpstr (my_strv[0], ==, "/hello");
2936 g_assert_cmpstr (my_strv[1], ==, "/world");
2937 g_assert (my_strv[2] == NULL);
2939 g_variant_unref (value);
2940 g_strfreev (my_strv);
2945 const gchar *strvector[] = { "i", "ii", "iii", "iv", "v", "vi", NULL };
2946 GVariantBuilder builder;
2955 g_variant_builder_init (&builder, G_VARIANT_TYPE ("aag"));
2956 g_variant_builder_open (&builder, G_VARIANT_TYPE ("ag"));
2957 for (i = 0; i < 6; i++)
2959 g_variant_builder_add (&builder, "g", strvector[i]);
2961 g_variant_builder_add (&builder, "&g", strvector[i]);
2962 g_variant_builder_close (&builder);
2963 g_variant_builder_add (&builder, "^ag", strvector);
2964 g_variant_builder_add (&builder, "^ag", strvector);
2965 value = g_variant_new ("aag", &builder);
2967 g_variant_iter_init (&iter, value);
2968 while (g_variant_iter_loop (&iter, "^ag", &strv))
2969 for (i = 0; i < 6; i++)
2970 g_assert_cmpstr (strv[i], ==, strvector[i]);
2972 g_variant_iter_init (&iter, value);
2973 while (g_variant_iter_loop (&iter, "^a&g", &strv))
2974 for (i = 0; i < 6; i++)
2975 g_assert_cmpstr (strv[i], ==, strvector[i]);
2977 g_variant_iter_init (&iter, value);
2978 while (g_variant_iter_loop (&iter, "ag", &i2))
2983 while (g_variant_iter_loop (i2, "g", &str))
2984 g_assert_cmpstr (str, ==, strvector[i++]);
2988 g_variant_iter_init (&iter, value);
2989 i3 = g_variant_iter_copy (&iter);
2990 while (g_variant_iter_loop (&iter, "@ag", &sub))
2992 gchar *str = g_variant_print (sub, TRUE);
2993 g_assert_cmpstr (str, ==,
2994 "[signature 'i', 'ii', 'iii', 'iv', 'v', 'vi']");
2998 if (do_failed_test ("*NULL has already been returned*"))
3000 g_variant_iter_next_value (&iter);
3005 while (g_variant_iter_loop (i3, "*", &sub))
3007 gchar *str = g_variant_print (sub, TRUE);
3008 g_assert_cmpstr (str, ==,
3009 "[signature 'i', 'ii', 'iii', 'iv', 'v', 'vi']");
3013 g_variant_iter_free (i3);
3015 for (i = 0; i < g_variant_n_children (value); i++)
3019 g_variant_get_child (value, i, "*", &sub);
3021 for (j = 0; j < g_variant_n_children (sub); j++)
3023 const gchar *str = NULL;
3026 g_variant_get_child (sub, j, "&g", &str);
3027 g_assert_cmpstr (str, ==, strvector[j]);
3029 cval = g_variant_get_child_value (sub, j);
3030 g_variant_get (cval, "&g", &str);
3031 g_assert_cmpstr (str, ==, strvector[j]);
3032 g_variant_unref (cval);
3035 g_variant_unref (sub);
3038 g_variant_unref (value);
3057 /* test all 'nothing' */
3058 value = g_variant_new ("(mymbmnmqmimumxmtmhmdmv)",
3061 FALSE, (gint16) 123,
3062 FALSE, (guint16) 123,
3063 FALSE, (gint32) 123,
3064 FALSE, (guint32) 123,
3065 FALSE, (gint64) 123,
3066 FALSE, (guint64) 123,
3068 FALSE, (gdouble) 37.5,
3072 g_variant_get (value, "(mymbmnmqmimumxmtmhmdmv)",
3086 memset (justs, 1, sizeof justs);
3087 g_variant_get (value, "(mymbmnmqmimumxmtmhmdmv)",
3099 g_assert (!(justs[0] || justs[1] || justs[2] || justs[3] || justs[4] ||
3100 justs[5] || justs[6] || justs[7] || justs[8] || justs[9]));
3103 memset (justs, 1, sizeof justs);
3104 byteval = i16val = u16val = i32val = u32val = i64val = u64val = hval = 88;
3108 g_variant_get (value, "(mymbmnmqmimumxmtmhmdmv)",
3109 &justs[0], &byteval,
3120 g_assert (!(justs[0] || justs[1] || justs[2] || justs[3] || justs[4] ||
3121 justs[5] || justs[6] || justs[7] || justs[8] || justs[9]));
3122 g_assert (byteval == '\0' && bval == FALSE);
3123 g_assert (i16val == 0 && u16val == 0 && i32val == 0 &&
3124 u32val == 0 && i64val == 0 && u64val == 0 &&
3125 hval == 0 && dval == 0.0);
3126 g_assert (vval == NULL);
3129 byteval = i16val = u16val = i32val = u32val = i64val = u64val = hval = 88;
3133 g_variant_get (value, "(mymbmnmqmimumxmtmhmdmv)",
3145 g_assert (byteval == '\0' && bval == FALSE);
3146 g_assert (i16val == 0 && u16val == 0 && i32val == 0 &&
3147 u32val == 0 && i64val == 0 && u64val == 0 &&
3148 hval == 0 && dval == 0.0);
3149 g_assert (vval == NULL);
3151 g_variant_unref (value);
3154 /* test all 'just' */
3155 value = g_variant_new ("(mymbmnmqmimumxmtmhmdmv)",
3159 TRUE, (guint16) 123,
3161 TRUE, (guint32) 123,
3163 TRUE, (guint64) 123,
3165 TRUE, (gdouble) 37.5,
3166 g_variant_new ("()"));
3169 g_variant_get (value, "(mymbmnmqmimumxmtmhmdmv)",
3183 memset (justs, 0, sizeof justs);
3184 g_variant_get (value, "(mymbmnmqmimumxmtmhmdmv)",
3196 g_assert (justs[0] && justs[1] && justs[2] && justs[3] && justs[4] &&
3197 justs[5] && justs[6] && justs[7] && justs[8] && justs[9]);
3200 memset (justs, 0, sizeof justs);
3201 byteval = i16val = u16val = i32val = u32val = i64val = u64val = hval = 88;
3205 g_variant_get (value, "(mymbmnmqmimumxmtmhmdmv)",
3206 &justs[0], &byteval,
3217 g_assert (justs[0] && justs[1] && justs[2] && justs[3] && justs[4] &&
3218 justs[5] && justs[6] && justs[7] && justs[8] && justs[9]);
3219 g_assert (byteval == 'a' && bval == TRUE);
3220 g_assert (i16val == 123 && u16val == 123 && i32val == 123 &&
3221 u32val == 123 && i64val == 123 && u64val == 123 &&
3222 hval == -1 && dval == 37.5);
3223 g_assert (g_variant_is_of_type (vval, G_VARIANT_TYPE_UNIT));
3224 g_variant_unref (vval);
3227 byteval = i16val = u16val = i32val = u32val = i64val = u64val = hval = 88;
3231 g_variant_get (value, "(mymbmnmqmimumxmtmhmdmv)",
3243 g_assert (byteval == 'a' && bval == TRUE);
3244 g_assert (i16val == 123 && u16val == 123 && i32val == 123 &&
3245 u32val == 123 && i64val == 123 && u64val == 123 &&
3246 hval == -1 && dval == 37.5);
3247 g_assert (g_variant_is_of_type (vval, G_VARIANT_TYPE_UNIT));
3248 g_variant_unref (vval);
3250 g_variant_unref (value);
3253 g_variant_type_info_assert_no_infos ();
3257 hash_get (GVariant *value,
3258 const gchar *format,
3261 const gchar *endptr = NULL;
3265 hash = g_str_has_suffix (format, "#");
3267 va_start (ap, format);
3268 g_variant_get_va (value, format, hash ? &endptr : NULL, &ap);
3272 g_assert (*endptr == '#');
3276 hash_new (const gchar *format,
3279 const gchar *endptr = NULL;
3284 hash = g_str_has_suffix (format, "#");
3286 va_start (ap, format);
3287 value = g_variant_new_va (format, hash ? &endptr : NULL, &ap);
3291 g_assert (*endptr == '#');
3303 value = hash_new ("i", 234);
3304 hash_get (value, "i", &x);
3305 g_assert (x == 234);
3306 g_variant_unref (value);
3309 value = hash_new ("i#", 234);
3310 hash_get (value, "i#", &x);
3311 g_assert (x == 234);
3312 g_variant_unref (value);
3314 g_variant_type_info_assert_no_infos ();
3318 test_builder_memory (void)
3320 GVariantBuilder *hb;
3323 hb = g_variant_builder_new (G_VARIANT_TYPE_ARRAY);
3324 g_variant_builder_open (hb, G_VARIANT_TYPE_ARRAY);
3325 g_variant_builder_open (hb, G_VARIANT_TYPE_ARRAY);
3326 g_variant_builder_open (hb, G_VARIANT_TYPE_ARRAY);
3327 g_variant_builder_add (hb, "s", "some value");
3328 g_variant_builder_ref (hb);
3329 g_variant_builder_unref (hb);
3330 g_variant_builder_unref (hb);
3332 hb = g_variant_builder_new (G_VARIANT_TYPE_ARRAY);
3333 g_variant_builder_unref (hb);
3335 hb = g_variant_builder_new (G_VARIANT_TYPE_ARRAY);
3336 g_variant_builder_clear (hb);
3337 g_variant_builder_unref (hb);
3339 g_variant_builder_init (&sb, G_VARIANT_TYPE_ARRAY);
3340 g_variant_builder_open (&sb, G_VARIANT_TYPE_ARRAY);
3341 g_variant_builder_open (&sb, G_VARIANT_TYPE_ARRAY);
3342 g_variant_builder_add (&sb, "s", "some value");
3343 g_variant_builder_clear (&sb);
3345 g_variant_type_info_assert_no_infos ();
3351 GVariant *items[4096];
3355 table = g_hash_table_new_full (g_variant_hash, g_variant_equal,
3356 (GDestroyNotify ) g_variant_unref,
3359 for (i = 0; i < G_N_ELEMENTS (items); i++)
3365 tree = tree_instance_new (NULL, 0);
3366 items[i] = tree_instance_get_gvariant (tree);
3367 tree_instance_free (tree);
3369 for (j = 0; j < i; j++)
3370 if (g_variant_equal (items[i], items[j]))
3372 g_variant_unref (items[i]);
3376 g_hash_table_insert (table,
3377 g_variant_ref_sink (items[i]),
3378 GINT_TO_POINTER (i));
3381 for (i = 0; i < G_N_ELEMENTS (items); i++)
3385 result = g_hash_table_lookup (table, items[i]);
3386 g_assert_cmpint (GPOINTER_TO_INT (result), ==, i);
3389 g_hash_table_unref (table);
3391 g_variant_type_info_assert_no_infos ();
3397 #if G_BYTE_ORDER == G_LITTLE_ENDIAN
3398 # define native16(x) x, 0
3399 # define swapped16(x) 0, x
3401 # define native16(x) 0, x
3402 # define swapped16(x) x, 0
3404 /* all kinds of of crazy randomised testing already performed on the
3405 * byteswapper in the /gvariant/serialiser/byteswap test and all kinds
3406 * of crazy randomised testing performed against the serialiser
3407 * normalisation functions in the /gvariant/serialiser/fuzz/ tests.
3409 * just test a few simple cases here to make sure they each work
3411 guchar valid_data[] = { 'a', '\0', swapped16(66), 2,
3413 'b', '\0', swapped16(77), 2,
3415 guchar corrupt_data[] = { 'a', '\0', swapped16(66), 2,
3417 'b', '\0', swapped16(77), 2,
3419 GVariant *value, *swapped;
3420 gchar *string, *string2;
3424 value = g_variant_new_from_data (G_VARIANT_TYPE ("a(sn)"),
3425 valid_data, sizeof valid_data, TRUE,
3427 swapped = g_variant_byteswap (value);
3428 g_variant_unref (value);
3429 g_assert (g_variant_get_size (swapped) == 13);
3430 string = g_variant_print (swapped, FALSE);
3431 g_variant_unref (swapped);
3432 g_assert_cmpstr (string, ==, "[('a', 66), ('b', 77)]");
3435 /* untrusted but valid */
3436 value = g_variant_new_from_data (G_VARIANT_TYPE ("a(sn)"),
3437 valid_data, sizeof valid_data, FALSE,
3439 swapped = g_variant_byteswap (value);
3440 g_variant_unref (value);
3441 g_assert (g_variant_get_size (swapped) == 13);
3442 string = g_variant_print (swapped, FALSE);
3443 g_variant_unref (swapped);
3444 g_assert_cmpstr (string, ==, "[('a', 66), ('b', 77)]");
3447 /* untrusted, invalid */
3448 value = g_variant_new_from_data (G_VARIANT_TYPE ("a(sn)"),
3449 corrupt_data, sizeof corrupt_data, FALSE,
3451 string = g_variant_print (value, FALSE);
3452 swapped = g_variant_byteswap (value);
3453 g_variant_unref (value);
3454 g_assert (g_variant_get_size (swapped) == 13);
3455 value = g_variant_byteswap (swapped);
3456 g_variant_unref (swapped);
3457 string2 = g_variant_print (value, FALSE);
3458 g_assert (g_variant_get_size (value) == 13);
3459 g_variant_unref (value);
3460 g_assert_cmpstr (string, ==, string2);
3474 tree = tree_instance_new (NULL, 3);
3475 value = tree_instance_get_gvariant (tree);
3476 tree_instance_free (tree);
3478 pt = g_variant_print (value, TRUE);
3479 p = g_variant_print (value, FALSE);
3481 parsed = g_variant_parse (NULL, pt, NULL, NULL, NULL);
3482 res = g_variant_print (parsed, FALSE);
3483 g_assert_cmpstr (p, ==, res);
3484 g_variant_unref (parsed);
3487 parsed = g_variant_parse (g_variant_get_type (value), p,
3489 res = g_variant_print (parsed, TRUE);
3490 g_assert_cmpstr (pt, ==, res);
3491 g_variant_unref (parsed);
3494 g_variant_unref (value);
3504 for (i = 0; i < 100; i++)
3515 for (i = 0; i < 256; i++)
3518 val = g_variant_new_string (str);
3519 p = g_variant_print (val, FALSE);
3520 g_variant_unref (val);
3522 val = g_variant_parse (NULL, p, NULL, NULL, NULL);
3523 p2 = g_variant_print (val, FALSE);
3525 g_assert_cmpstr (str, ==, g_variant_get_string (val, NULL));
3526 g_assert_cmpstr (p, ==, p2);
3528 g_variant_unref (val);
3533 /* another mini test */
3538 value = g_variant_parse (G_VARIANT_TYPE_INT32, "1 2 3", NULL, &end, NULL);
3539 g_assert_cmpint (g_variant_get_int32 (value), ==, 1);
3540 /* make sure endptr returning works */
3541 g_assert_cmpstr (end, ==, " 2 3");
3542 g_variant_unref (value);
3545 g_variant_type_info_assert_no_infos ();
3549 test_parse_failures (void)
3551 const gchar *test[] = {
3552 "[1, 2,", "6:", "expected value",
3553 "", "0:", "expected value",
3554 "(1, 2,", "6:", "expected value",
3555 "<1", "2:", "expected `>'",
3556 "[]", "0-2:", "unable to infer",
3557 "(,", "1:", "expected value",
3558 "[4,'']", "1-2,3-5:", "common type",
3559 "[4, '', 5]", "1-2,4-6:", "common type",
3560 "['', 4, 5]", "1-3,5-6:", "common type",
3561 "[4, 5, '']", "1-2,7-9:", "common type",
3562 "[[4], [], ['']]", "1-4,10-14:", "common type",
3563 "[[], [4], ['']]", "5-8,10-14:", "common type",
3564 "just", "4:", "expected value",
3565 "nothing", "0-7:", "unable to infer",
3566 "just [4, '']", "6-7,9-11:", "common type",
3567 "[[4,'']]", "2-3,4-6:", "common type",
3568 "([4,''],)", "2-3,4-6:", "common type",
3570 "{}", "0-2:", "unable to infer",
3571 "{[1,2],[3,4]}", "0-13:", "basic types",
3572 "{[1,2]:[3,4]}", "0-13:", "basic types",
3573 "justt", "0-5:", "unknown keyword",
3574 "nothng", "0-6:", "unknown keyword",
3575 "uint33", "0-6:", "unknown keyword",
3576 "@mi just ''", "9-11:", "can not parse as",
3577 "@ai ['']", "5-7:", "can not parse as",
3578 "@(i) ('',)", "6-8:", "can not parse as",
3579 "[[], 5]", "1-3,5-6:", "common type",
3580 "[[5], 5]", "1-4,6-7:", "common type",
3581 "5 5", "2:", "expected end of input",
3582 "[5, [5, '']]", "5-6,8-10:", "common type",
3583 "@i just 5", "3-9:", "can not parse as",
3584 "@i nothing", "3-10:", "can not parse as",
3585 "@i []", "3-5:", "can not parse as",
3586 "@i ()", "3-5:", "can not parse as",
3587 "@ai (4,)", "4-8:", "can not parse as",
3588 "@(i) []", "5-7:", "can not parse as",
3589 "(5 5)", "3:", "expected `,'",
3590 "[5 5]", "3:", "expected `,' or `]'",
3591 "(5, 5 5)", "6:", "expected `,' or `)'",
3592 "[5, 5 5]", "6:", "expected `,' or `]'",
3593 "<@i []>", "4-6:", "can not parse as",
3594 "<[5 5]>", "4:", "expected `,' or `]'",
3595 "{[4,''],5}", "2-3,4-6:", "common type",
3596 "{5,[4,'']}", "4-5,6-8:", "common type",
3597 "@i {1,2}", "3-8:", "can not parse as",
3598 "{@i '', 5}", "4-6:", "can not parse as",
3599 "{5, @i ''}", "7-9:", "can not parse as",
3600 "@ai {}", "4-6:", "can not parse as",
3601 "{@i '': 5}", "4-6:", "can not parse as",
3602 "{5: @i ''}", "7-9:", "can not parse as",
3603 "{<4,5}", "3:", "expected `>'",
3604 "{4,<5}", "5:", "expected `>'",
3605 "{4,5,6}", "4:", "expected `}'",
3606 "{5 5}", "3:", "expected `:' or `,'",
3607 "{4: 5: 6}", "5:", "expected `,' or `}'",
3608 "{4:5,<6:7}", "7:", "expected `>'",
3609 "{4:5,6:<7}", "9:", "expected `>'",
3610 "{4:5,6 7}", "7:", "expected `:'",
3611 "@o 'foo'", "3-8:", "object path",
3612 "@g 'zzz'", "3-8:", "signature",
3613 "@i true", "3-7:", "can not parse as",
3614 "@z 4", "0-2:", "invalid type",
3615 "@a* []", "0-3:", "definite",
3616 "@ai [3 3]", "7:", "expected `,' or `]'",
3617 "18446744073709551616", "0-20:", "too big for any type",
3618 "-18446744073709551616", "0-21:", "too big for any type",
3619 "byte 256", "5-8:", "out of range for type",
3620 "byte -1", "5-7:", "out of range for type",
3621 "int16 32768", "6-11:", "out of range for type",
3622 "int16 -32769", "6-12:", "out of range for type",
3623 "uint16 -1", "7-9:", "out of range for type",
3624 "uint16 65536", "7-12:", "out of range for type",
3625 "2147483648", "0-10:", "out of range for type",
3626 "-2147483649", "0-11:", "out of range for type",
3627 "uint32 -1", "7-9:", "out of range for type",
3628 "uint32 4294967296", "7-17:", "out of range for type",
3629 "@x 9223372036854775808", "3-22:", "out of range for type",
3630 "@x -9223372036854775809", "3-23:", "out of range for type",
3631 "@t -1", "3-5:", "out of range for type",
3632 "@t 18446744073709551616", "3-23:", "too big for any type",
3633 "handle 2147483648", "7-17:", "out of range for type",
3634 "handle -2147483649", "7-18:", "out of range for type",
3635 "1.798e308", "0-9:", "too big for any type",
3636 "37.5a488", "4-5:", "invalid character",
3637 "0x7ffgf", "5-6:", "invalid character",
3638 "07758", "4-5:", "invalid character",
3639 "123a5", "3-4:", "invalid character",
3640 "@ai 123", "4-7:", "can not parse as",
3641 "'\"\\'", "0-4:", "unterminated string",
3642 "'\"\\'\\", "0-5:", "unterminated string",
3643 "boolean 4", "8-9:", "can not parse as",
3644 "int32 true", "6-10:", "can not parse as",
3645 "[double 5, int32 5]", "1-9,11-18:", "common type",
3646 "string 4", "7-8:", "can not parse as"
3650 for (i = 0; i < G_N_ELEMENTS (test); i += 3)
3652 GError *error = NULL;
3655 value = g_variant_parse (NULL, test[i], NULL, NULL, &error);
3656 g_assert (value == NULL);
3658 if (!strstr (error->message, test[i+2]))
3659 g_error ("test %d: Can't find `%s' in `%s'", i / 3,
3660 test[i+2], error->message);
3662 if (!g_str_has_prefix (error->message, test[i+1]))
3663 g_error ("test %d: Expected location `%s' in `%s'", i / 3,
3664 test[i+1], error->message);
3666 g_error_free (error);
3671 test_parse_positional (void)
3674 check_and_free (g_variant_new_parsed ("[('one', 1), (%s, 2),"
3675 " ('three', %i)]", "two", 3),
3676 "[('one', 1), ('two', 2), ('three', 3)]");
3677 value = g_variant_new_parsed ("[('one', 1), (%s, 2),"
3678 " ('three', %u)]", "two", 3);
3679 g_assert (g_variant_is_of_type (value, G_VARIANT_TYPE ("a(su)")));
3680 check_and_free (value, "[('one', 1), ('two', 2), ('three', 3)]");
3681 check_and_free (g_variant_new_parsed ("{%s:%i}", "one", 1), "{'one': 1}");
3683 if (do_failed_test ("*GVariant format string*"))
3685 g_variant_new_parsed ("%z");
3689 if (do_failed_test ("*can not parse as*"))
3691 g_variant_new_parsed ("uint32 %i", 2);
3695 if (do_failed_test ("*expected GVariant of type `i'*"))
3697 g_variant_new_parsed ("%@i", g_variant_new_uint32 (2));
3703 main (int argc, char **argv)
3707 g_test_init (&argc, &argv, NULL);
3709 g_test_add_func ("/gvariant/type", test_gvarianttype);
3710 g_test_add_func ("/gvariant/typeinfo", test_gvarianttypeinfo);
3711 g_test_add_func ("/gvariant/serialiser/maybe", test_maybes);
3712 g_test_add_func ("/gvariant/serialiser/array", test_arrays);
3713 g_test_add_func ("/gvariant/serialiser/tuple", test_tuples);
3714 g_test_add_func ("/gvariant/serialiser/variant", test_variants);
3715 g_test_add_func ("/gvariant/serialiser/strings", test_strings);
3716 g_test_add_func ("/gvariant/serialiser/byteswap", test_byteswaps);
3718 for (i = 1; i <= 20; i += 4)
3722 testname = g_strdup_printf ("/gvariant/serialiser/fuzz/%d%%", i);
3723 g_test_add_data_func (testname, GINT_TO_POINTER (i),
3724 (gpointer) test_fuzzes);
3728 g_test_add_func ("/gvariant/containers", test_containers);
3729 g_test_add_func ("/gvariant/format-strings", test_format_strings);
3730 g_test_add_func ("/gvariant/invalid-varargs", test_invalid_varargs);
3731 g_test_add_func ("/gvariant/varargs", test_varargs);
3732 g_test_add_func ("/gvariant/valist", test_valist);
3733 g_test_add_func ("/gvariant/builder-memory", test_builder_memory);
3734 g_test_add_func ("/gvariant/hashing", test_hashing);
3735 g_test_add_func ("/gvariant/byteswap", test_gv_byteswap);
3736 g_test_add_func ("/gvariant/parser", test_parses);
3737 g_test_add_func ("/gvariant/parse-failures", test_parse_failures);
3738 g_test_add_func ("/gvariant/parse-positional", test_parse_positional);
3740 return g_test_run ();