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>
16 #include <glib/gvariant-internal.h>
21 #define BASIC "bynqiuxthdsog?"
22 #define N_BASIC (G_N_ELEMENTS (BASIC) - 1)
24 #define INVALIDS "cefjklpwz&@^$"
25 #define N_INVALIDS (G_N_ELEMENTS (INVALIDS) - 1)
27 /* see comment in gvariant-serialiser.c about this madness.
29 * we use this to get testing of non-strictly-aligned GVariant instances
30 * on machines that can tolerate it. it is necessary to support this
31 * because some systems have malloc() that returns non-8-aligned
32 * pointers. it is necessary to have special support in the tests
33 * because on most machines malloc() is 8-aligned.
35 #define ALIGN_BITS (sizeof (struct { char a; union { \
36 guint64 x; void *y; gdouble z; } b; }) - 9)
39 randomly (gdouble prob
)
41 return g_test_rand_double_range (0, 1) < prob
;
46 append_tuple_type_string (GString
*, GString
*, gboolean
, gint
);
48 /* append a random GVariantType to a GString
49 * append a description of the type to another GString
50 * return what the type is
53 append_type_string (GString
*string
,
58 if (!depth
-- || randomly (0.3))
60 gchar b
= BASIC
[g_test_rand_int_range (0, N_BASIC
- definite
)];
61 g_string_append_c (string
, b
);
62 g_string_append_c (description
, b
);
67 return g_variant_type_copy (G_VARIANT_TYPE_BOOLEAN
);
69 return g_variant_type_copy (G_VARIANT_TYPE_BYTE
);
71 return g_variant_type_copy (G_VARIANT_TYPE_INT16
);
73 return g_variant_type_copy (G_VARIANT_TYPE_UINT16
);
75 return g_variant_type_copy (G_VARIANT_TYPE_INT32
);
77 return g_variant_type_copy (G_VARIANT_TYPE_UINT32
);
79 return g_variant_type_copy (G_VARIANT_TYPE_INT64
);
81 return g_variant_type_copy (G_VARIANT_TYPE_UINT64
);
83 return g_variant_type_copy (G_VARIANT_TYPE_HANDLE
);
85 return g_variant_type_copy (G_VARIANT_TYPE_DOUBLE
);
87 return g_variant_type_copy (G_VARIANT_TYPE_STRING
);
89 return g_variant_type_copy (G_VARIANT_TYPE_OBJECT_PATH
);
91 return g_variant_type_copy (G_VARIANT_TYPE_SIGNATURE
);
93 return g_variant_type_copy (G_VARIANT_TYPE_BASIC
);
95 g_assert_not_reached ();
100 GVariantType
*result
;
102 switch (g_test_rand_int_range (0, definite
? 5 : 7))
106 GVariantType
*element
;
108 g_string_append_c (string
, 'a');
109 g_string_append (description
, "a of ");
110 element
= append_type_string (string
, description
,
112 result
= g_variant_type_new_array (element
);
113 g_variant_type_free (element
);
116 g_assert (g_variant_type_is_array (result
));
121 GVariantType
*element
;
123 g_string_append_c (string
, 'm');
124 g_string_append (description
, "m of ");
125 element
= append_type_string (string
, description
,
127 result
= g_variant_type_new_maybe (element
);
128 g_variant_type_free (element
);
131 g_assert (g_variant_type_is_maybe (result
));
135 result
= append_tuple_type_string (string
, description
,
138 g_assert (g_variant_type_is_tuple (result
));
143 GVariantType
*key
, *value
;
145 g_string_append_c (string
, '{');
146 g_string_append (description
, "e of [");
147 key
= append_type_string (string
, description
, definite
, 0);
148 g_string_append (description
, ", ");
149 value
= append_type_string (string
, description
, definite
, depth
);
150 g_string_append_c (description
, ']');
151 g_string_append_c (string
, '}');
152 result
= g_variant_type_new_dict_entry (key
, value
);
153 g_variant_type_free (key
);
154 g_variant_type_free (value
);
157 g_assert (g_variant_type_is_dict_entry (result
));
161 g_string_append_c (string
, 'v');
162 g_string_append_c (description
, 'V');
163 result
= g_variant_type_copy (G_VARIANT_TYPE_VARIANT
);
164 g_assert (g_variant_type_equal (result
, G_VARIANT_TYPE_VARIANT
));
168 g_string_append_c (string
, '*');
169 g_string_append_c (description
, 'S');
170 result
= g_variant_type_copy (G_VARIANT_TYPE_ANY
);
171 g_assert (g_variant_type_equal (result
, G_VARIANT_TYPE_ANY
));
175 g_string_append_c (string
, 'r');
176 g_string_append_c (description
, 'R');
177 result
= g_variant_type_copy (G_VARIANT_TYPE_TUPLE
);
178 g_assert (g_variant_type_is_tuple (result
));
182 g_assert_not_reached ();
189 static GVariantType
*
190 append_tuple_type_string (GString
*string
,
191 GString
*description
,
195 GVariantType
*result
, *other_result
;
196 GVariantType
**types
;
200 g_string_append_c (string
, '(');
201 g_string_append (description
, "t of [");
203 size
= g_test_rand_int_range (0, 20);
204 types
= g_new (GVariantType
*, size
+ 1);
206 for (i
= 0; i
< size
; i
++)
208 types
[i
] = append_type_string (string
, description
, definite
, depth
);
211 g_string_append (description
, ", ");
216 g_string_append_c (description
, ']');
217 g_string_append_c (string
, ')');
219 result
= g_variant_type_new_tuple ((gpointer
) types
, size
);
220 other_result
= g_variant_type_new_tuple ((gpointer
) types
, -1);
221 g_assert (g_variant_type_equal (result
, other_result
));
222 g_variant_type_free (other_result
);
223 for (i
= 0; i
< size
; i
++)
224 g_variant_type_free (types
[i
]);
230 /* given a valid type string, make it invalid */
232 invalid_mutation (const gchar
*type_string
)
234 gboolean have_parens
, have_braces
;
236 /* it's valid, so '(' implies ')' and same for '{' and '}' */
237 have_parens
= strchr (type_string
, '(') != NULL
;
238 have_braces
= strchr (type_string
, '{') != NULL
;
240 if (have_parens
&& have_braces
&& randomly (0.3))
242 /* swap a paren and a brace */
248 new = g_strdup (type_string
);
258 /* count number of parens/braces */
259 while ((pp
= strchr (pp
+ 1, p
))) np
++;
260 while ((bp
= strchr (bp
+ 1, b
))) nb
++;
262 /* randomly pick one of each */
263 np
= g_test_rand_int_range (0, np
) + 1;
264 nb
= g_test_rand_int_range (0, nb
) + 1;
268 while (np
--) pp
= strchr (pp
+ 1, p
);
269 while (nb
--) bp
= strchr (bp
+ 1, b
);
272 g_assert (*bp
== b
&& *pp
== p
);
279 if ((have_parens
|| have_braces
) && randomly (0.3))
281 /* drop a paren/brace */
288 if (randomly (0.5)) p
= '('; else p
= ')';
290 if (randomly (0.5)) p
= '{'; else p
= '}';
292 new = g_strdup (type_string
);
296 while ((pp
= strchr (pp
+ 1, p
))) np
++;
297 np
= g_test_rand_int_range (0, np
) + 1;
299 while (np
--) pp
= strchr (pp
+ 1, p
);
311 /* else, perform a random mutation at a random point */
319 /* insert a paren/brace */
321 if (randomly (0.5)) p
= '('; else p
= ')';
323 if (randomly (0.5)) p
= '{'; else p
= '}';
325 else if (randomly (0.5))
328 p
= INVALIDS
[g_test_rand_int_range (0, N_INVALIDS
)];
337 length
= strlen (type_string
);
338 new = g_malloc (length
+ 2);
339 n
= g_test_rand_int_range (0, length
);
340 memcpy (new, type_string
, n
);
342 memcpy (new + n
+ 1, type_string
+ n
, length
- n
);
343 new[length
+ 1] = '\0';
349 /* describe a type using the same language as is generated
350 * while generating the type with append_type_string
353 describe_type (const GVariantType
*type
)
357 if (g_variant_type_is_container (type
))
359 g_assert (!g_variant_type_is_basic (type
));
361 if (g_variant_type_is_array (type
))
363 gchar
*subtype
= describe_type (g_variant_type_element (type
));
364 result
= g_strdup_printf ("a of %s", subtype
);
367 else if (g_variant_type_is_maybe (type
))
369 gchar
*subtype
= describe_type (g_variant_type_element (type
));
370 result
= g_strdup_printf ("m of %s", subtype
);
373 else if (g_variant_type_is_tuple (type
))
375 if (!g_variant_type_equal (type
, G_VARIANT_TYPE_TUPLE
))
377 const GVariantType
*sub
;
382 string
= g_string_new ("t of [");
384 length
= g_variant_type_n_items (type
);
385 sub
= g_variant_type_first (type
);
386 for (i
= 0; i
< length
; i
++)
388 gchar
*subtype
= describe_type (sub
);
389 g_string_append (string
, subtype
);
392 if ((sub
= g_variant_type_next (sub
)))
393 g_string_append (string
, ", ");
395 g_assert (sub
== NULL
);
396 g_string_append_c (string
, ']');
398 result
= g_string_free (string
, FALSE
);
401 result
= g_strdup ("R");
403 else if (g_variant_type_is_dict_entry (type
))
405 gchar
*key
, *value
, *key2
, *value2
;
407 key
= describe_type (g_variant_type_key (type
));
408 value
= describe_type (g_variant_type_value (type
));
409 key2
= describe_type (g_variant_type_first (type
));
410 value2
= describe_type (
411 g_variant_type_next (g_variant_type_first (type
)));
412 g_assert (g_variant_type_next (g_variant_type_next (
413 g_variant_type_first (type
))) == NULL
);
414 g_assert_cmpstr (key
, ==, key2
);
415 g_assert_cmpstr (value
, ==, value2
);
416 result
= g_strjoin ("", "e of [", key
, ", ", value
, "]", NULL
);
422 else if (g_variant_type_equal (type
, G_VARIANT_TYPE_VARIANT
))
424 result
= g_strdup ("V");
427 g_assert_not_reached ();
431 if (g_variant_type_is_definite (type
))
433 g_assert (g_variant_type_is_basic (type
));
435 if (g_variant_type_equal (type
, G_VARIANT_TYPE_BOOLEAN
))
436 result
= g_strdup ("b");
437 else if (g_variant_type_equal (type
, G_VARIANT_TYPE_BYTE
))
438 result
= g_strdup ("y");
439 else if (g_variant_type_equal (type
, G_VARIANT_TYPE_INT16
))
440 result
= g_strdup ("n");
441 else if (g_variant_type_equal (type
, G_VARIANT_TYPE_UINT16
))
442 result
= g_strdup ("q");
443 else if (g_variant_type_equal (type
, G_VARIANT_TYPE_INT32
))
444 result
= g_strdup ("i");
445 else if (g_variant_type_equal (type
, G_VARIANT_TYPE_UINT32
))
446 result
= g_strdup ("u");
447 else if (g_variant_type_equal (type
, G_VARIANT_TYPE_INT64
))
448 result
= g_strdup ("x");
449 else if (g_variant_type_equal (type
, G_VARIANT_TYPE_UINT64
))
450 result
= g_strdup ("t");
451 else if (g_variant_type_equal (type
, G_VARIANT_TYPE_HANDLE
))
452 result
= g_strdup ("h");
453 else if (g_variant_type_equal (type
, G_VARIANT_TYPE_DOUBLE
))
454 result
= g_strdup ("d");
455 else if (g_variant_type_equal (type
, G_VARIANT_TYPE_STRING
))
456 result
= g_strdup ("s");
457 else if (g_variant_type_equal (type
, G_VARIANT_TYPE_OBJECT_PATH
))
458 result
= g_strdup ("o");
459 else if (g_variant_type_equal (type
, G_VARIANT_TYPE_SIGNATURE
))
460 result
= g_strdup ("g");
462 g_assert_not_reached ();
466 if (g_variant_type_equal (type
, G_VARIANT_TYPE_ANY
))
468 result
= g_strdup ("S");
470 else if (g_variant_type_equal (type
, G_VARIANT_TYPE_BASIC
))
472 result
= g_strdup ("?");
475 g_assert_not_reached ();
482 /* given a type string, replace one of the indefinite type characters in
483 * it with a matching type (possibly the same type).
486 generate_subtype (const gchar
*type_string
)
488 GVariantType
*replacement
;
489 GString
*result
, *junk
;
490 gint length
, n
= 0, l
;
492 result
= g_string_new (NULL
);
493 junk
= g_string_new (NULL
);
495 /* count the number of indefinite type characters */
496 for (length
= 0; type_string
[length
]; length
++)
497 n
+= type_string
[length
] == 'r' ||
498 type_string
[length
] == '?' ||
499 type_string
[length
] == '*';
500 /* length now is strlen (type_string) */
502 /* pick one at random to replace */
503 n
= g_test_rand_int_range (0, n
) + 1;
507 while (n
--) l
+= strcspn (type_string
+ l
+ 1, "r?*") + 1;
508 g_assert (type_string
[l
] == 'r' ||
509 type_string
[l
] == '?' ||
510 type_string
[l
] == '*');
512 /* store up to that point in a GString */
513 g_string_append_len (result
, type_string
, l
);
515 /* then store the replacement in the GString */
516 if (type_string
[l
] == 'r')
517 replacement
= append_tuple_type_string (result
, junk
, FALSE
, 3);
519 else if (type_string
[l
] == '?')
520 replacement
= append_type_string (result
, junk
, FALSE
, 0);
522 else if (type_string
[l
] == '*')
523 replacement
= append_type_string (result
, junk
, FALSE
, 3);
526 g_assert_not_reached ();
528 /* ensure the replacement has the proper type */
529 g_assert (g_variant_type_is_subtype_of (replacement
,
530 (gpointer
) &type_string
[l
]));
532 /* store the rest from the original type string */
533 g_string_append (result
, type_string
+ l
+ 1);
535 g_variant_type_free (replacement
);
536 g_string_free (junk
, TRUE
);
538 return g_string_free (result
, FALSE
);
543 const GVariantType
*type
;
544 struct typestack
*parent
;
547 /* given an indefinite type string, replace one of the indefinite
548 * characters in it with a matching type and ensure that the result is a
549 * subtype of the original. repeat.
552 subtype_check (const gchar
*type_string
,
553 struct typestack
*parent_ts
)
555 struct typestack ts
, *node
;
559 subtype
= generate_subtype (type_string
);
561 ts
.type
= G_VARIANT_TYPE (subtype
);
562 ts
.parent
= parent_ts
;
564 for (node
= &ts
; node
; node
= node
->parent
)
566 /* this type should be a subtype of each parent type */
567 g_assert (g_variant_type_is_subtype_of (ts
.type
, node
->type
));
569 /* it should only be a supertype when it is exactly equal */
570 g_assert (g_variant_type_is_subtype_of (node
->type
, ts
.type
) ==
571 g_variant_type_equal (ts
.type
, node
->type
));
576 if (!g_variant_type_is_definite (ts
.type
) && depth
< 5)
578 /* the type is still indefinite and we haven't repeated too many
579 * times. go once more.
582 subtype_check (subtype
, &ts
);
589 test_gvarianttype (void)
593 for (i
= 0; i
< 2000; i
++)
595 GString
*type_string
, *description
;
596 GVariantType
*type
, *other_type
;
597 const GVariantType
*ctype
;
601 type_string
= g_string_new (NULL
);
602 description
= g_string_new (NULL
);
604 /* generate a random type, its type string and a description
606 * exercises type constructor functions and g_variant_type_copy()
608 type
= append_type_string (type_string
, description
, FALSE
, 6);
610 /* convert the type string to a type and ensure that it is equal
611 * to the one produced with the type constructor routines
613 ctype
= G_VARIANT_TYPE (type_string
->str
);
614 g_assert (g_variant_type_equal (ctype
, type
));
615 g_assert (g_variant_type_hash (ctype
) == g_variant_type_hash (type
));
616 g_assert (g_variant_type_is_subtype_of (ctype
, type
));
617 g_assert (g_variant_type_is_subtype_of (type
, ctype
));
619 /* check if the type is indefinite */
620 if (!g_variant_type_is_definite (type
))
622 struct typestack ts
= { type
, NULL
};
624 /* if it is indefinite, then replace one of the indefinite
625 * characters with a matching type and ensure that the result
626 * is a subtype of the original type. repeat.
628 subtype_check (type_string
->str
, &ts
);
631 /* ensure that no indefinite characters appear */
632 g_assert (strcspn (type_string
->str
, "r?*") == type_string
->len
);
635 /* describe the type.
637 * exercises the type iterator interface
639 desc
= describe_type (type
);
641 /* make sure the description matches */
642 g_assert_cmpstr (desc
, ==, description
->str
);
645 /* make an invalid mutation to the type and make sure the type
646 * validation routines catch it */
647 invalid
= invalid_mutation (type_string
->str
);
648 g_assert (g_variant_type_string_is_valid (type_string
->str
));
649 g_assert (!g_variant_type_string_is_valid (invalid
));
652 /* concatenate another type to the type string and ensure that
653 * the result is recognised as being invalid
655 other_type
= append_type_string (type_string
, description
, FALSE
, 2);
657 g_string_free (description
, TRUE
);
658 g_string_free (type_string
, TRUE
);
659 g_variant_type_free (other_type
);
660 g_variant_type_free (type
);
664 #define ALIGNED(x, y) (((x + (y - 1)) / y) * y)
666 /* do our own calculation of the fixed_size and alignment of a type
667 * using a simple algorithm to make sure the "fancy" one in the
668 * implementation is correct.
671 calculate_type_info (const GVariantType
*type
,
675 if (g_variant_type_is_array (type
) ||
676 g_variant_type_is_maybe (type
))
678 calculate_type_info (g_variant_type_element (type
), NULL
, alignment
);
683 else if (g_variant_type_is_tuple (type
) ||
684 g_variant_type_is_dict_entry (type
))
686 if (g_variant_type_n_items (type
))
688 const GVariantType
*sub
;
697 sub
= g_variant_type_first (type
);
703 calculate_type_info (sub
, &this_fs
, &this_al
);
705 al
= MAX (al
, this_al
);
715 size
= ALIGNED (size
, this_al
);
719 while ((sub
= g_variant_type_next (sub
)));
721 size
= ALIGNED (size
, al
);
742 if (g_variant_type_equal (type
, G_VARIANT_TYPE_BOOLEAN
) ||
743 g_variant_type_equal (type
, G_VARIANT_TYPE_BYTE
))
748 else if (g_variant_type_equal (type
, G_VARIANT_TYPE_INT16
) ||
749 g_variant_type_equal (type
, G_VARIANT_TYPE_UINT16
))
754 else if (g_variant_type_equal (type
, G_VARIANT_TYPE_INT32
) ||
755 g_variant_type_equal (type
, G_VARIANT_TYPE_UINT32
) ||
756 g_variant_type_equal (type
, G_VARIANT_TYPE_HANDLE
))
761 else if (g_variant_type_equal (type
, G_VARIANT_TYPE_INT64
) ||
762 g_variant_type_equal (type
, G_VARIANT_TYPE_UINT64
) ||
763 g_variant_type_equal (type
, G_VARIANT_TYPE_DOUBLE
))
767 else if (g_variant_type_equal (type
, G_VARIANT_TYPE_STRING
) ||
768 g_variant_type_equal (type
, G_VARIANT_TYPE_OBJECT_PATH
) ||
769 g_variant_type_equal (type
, G_VARIANT_TYPE_SIGNATURE
))
774 else if (g_variant_type_equal (type
, G_VARIANT_TYPE_VARIANT
))
780 g_assert_not_reached ();
790 /* same as the describe_type() function above, but iterates over
791 * typeinfo instead of types.
794 describe_info (GVariantTypeInfo
*info
)
798 switch (g_variant_type_info_get_type_char (info
))
800 case G_VARIANT_TYPE_INFO_CHAR_MAYBE
:
804 element
= describe_info (g_variant_type_info_element (info
));
805 result
= g_strdup_printf ("m of %s", element
);
810 case G_VARIANT_TYPE_INFO_CHAR_ARRAY
:
814 element
= describe_info (g_variant_type_info_element (info
));
815 result
= g_strdup_printf ("a of %s", element
);
820 case G_VARIANT_TYPE_INFO_CHAR_TUPLE
:
822 const gchar
*sep
= "";
827 string
= g_string_new ("t of [");
828 length
= g_variant_type_info_n_members (info
);
830 for (i
= 0; i
< length
; i
++)
832 const GVariantMemberInfo
*minfo
;
835 g_string_append (string
, sep
);
838 minfo
= g_variant_type_info_member_info (info
, i
);
839 subtype
= describe_info (minfo
->type_info
);
840 g_string_append (string
, subtype
);
844 g_string_append_c (string
, ']');
846 result
= g_string_free (string
, FALSE
);
850 case G_VARIANT_TYPE_INFO_CHAR_DICT_ENTRY
:
852 const GVariantMemberInfo
*keyinfo
, *valueinfo
;
855 g_assert_cmpint (g_variant_type_info_n_members (info
), ==, 2);
856 keyinfo
= g_variant_type_info_member_info (info
, 0);
857 valueinfo
= g_variant_type_info_member_info (info
, 1);
858 key
= describe_info (keyinfo
->type_info
);
859 value
= describe_info (valueinfo
->type_info
);
860 result
= g_strjoin ("", "e of [", key
, ", ", value
, "]", NULL
);
866 case G_VARIANT_TYPE_INFO_CHAR_VARIANT
:
867 result
= g_strdup ("V");
871 result
= g_strdup (g_variant_type_info_get_type_string (info
));
872 g_assert_cmpint (strlen (result
), ==, 1);
879 /* check that the O(1) method of calculating offsets meshes with the
880 * results of simple iteration.
883 check_offsets (GVariantTypeInfo
*info
,
884 const GVariantType
*type
)
889 length
= g_variant_type_info_n_members (info
);
890 g_assert_cmpint (length
, ==, g_variant_type_n_items (type
));
892 /* the 'flavour' is the low order bits of the ending point of
893 * variable-size items in the tuple. this lets us test that the type
894 * info is correct for various starting alignments.
896 for (flavour
= 0; flavour
< 8; flavour
++)
898 const GVariantType
*subtype
;
899 gsize last_offset_index
;
904 subtype
= g_variant_type_first (type
);
905 last_offset_index
= -1;
909 /* go through the tuple, keeping track of our position */
910 for (i
= 0; i
< length
; i
++)
915 calculate_type_info (subtype
, &fixed_size
, &alignment
);
917 position
= ALIGNED (position
, alignment
);
919 /* compare our current aligned position (ie: the start of this
920 * item) to the start offset that would be calculated if we
924 const GVariantMemberInfo
*member
;
927 member
= g_variant_type_info_member_info (info
, i
);
928 g_assert_cmpint (member
->i
, ==, last_offset_index
);
930 /* do the calculation using the typeinfo */
936 /* did we reach the same spot? */
937 g_assert_cmpint (start
, ==, position
);
942 /* fixed size. add that size. */
943 position
+= fixed_size
;
947 /* variable size. do the flavouring. */
948 while ((position
& 0x7) != flavour
)
951 /* and store the offset, just like it would be in the
954 last_offset
= position
;
959 subtype
= g_variant_type_next (subtype
);
962 /* make sure we used up exactly all the types */
963 g_assert (subtype
== NULL
);
968 test_gvarianttypeinfo (void)
972 for (i
= 0; i
< 2000; i
++)
974 GString
*type_string
, *description
;
975 gsize fixed_size1
, fixed_size2
;
976 guint alignment1
, alignment2
;
977 GVariantTypeInfo
*info
;
981 type_string
= g_string_new (NULL
);
982 description
= g_string_new (NULL
);
985 type
= append_type_string (type_string
, description
, TRUE
, 6);
987 /* create a typeinfo for it */
988 info
= g_variant_type_info_get (type
);
990 /* make sure the typeinfo has the right type string */
991 g_assert_cmpstr (g_variant_type_info_get_type_string (info
), ==,
994 /* calculate the alignment and fixed size, compare to the
995 * typeinfo's calculations
997 calculate_type_info (type
, &fixed_size1
, &alignment1
);
998 g_variant_type_info_query (info
, &alignment2
, &fixed_size2
);
999 g_assert_cmpint (fixed_size1
, ==, fixed_size2
);
1000 g_assert_cmpint (alignment1
, ==, alignment2
+ 1);
1002 /* test the iteration functions over typeinfo structures by
1003 * "describing" the typeinfo and verifying equality.
1005 desc
= describe_info (info
);
1006 g_assert_cmpstr (desc
, ==, description
->str
);
1008 /* do extra checks for containers */
1009 if (g_variant_type_is_array (type
) ||
1010 g_variant_type_is_maybe (type
))
1012 const GVariantType
*element
;
1016 element
= g_variant_type_element (type
);
1017 calculate_type_info (element
, &efs1
, &ea1
);
1018 g_variant_type_info_query_element (info
, &ea2
, &efs2
);
1019 g_assert_cmpint (efs1
, ==, efs2
);
1020 g_assert_cmpint (ea1
, ==, ea2
+ 1);
1022 g_assert_cmpint (ea1
, ==, alignment1
);
1023 g_assert_cmpint (0, ==, fixed_size1
);
1025 else if (g_variant_type_is_tuple (type
) ||
1026 g_variant_type_is_dict_entry (type
))
1028 /* make sure the "magic constants" are working */
1029 check_offsets (info
, type
);
1032 g_string_free (type_string
, TRUE
);
1033 g_string_free (description
, TRUE
);
1034 g_variant_type_info_unref (info
);
1035 g_variant_type_free (type
);
1039 g_variant_type_info_assert_no_infos ();
1042 #define MAX_FIXED_MULTIPLIER 256
1043 #define MAX_INSTANCE_SIZE 1024
1044 #define MAX_ARRAY_CHILDREN 128
1045 #define MAX_TUPLE_CHILDREN 128
1047 /* this function generates a random type such that all characteristics
1048 * that are "interesting" to the serialiser are tested.
1050 * this basically means:
1051 * - test different alignments
1052 * - test variable sized items and fixed sized items
1053 * - test different fixed sizes
1056 random_type_string (void)
1058 const guchar base_types
[] = "ynix";
1061 base_type
= base_types
[g_test_rand_int_range (0, 4)];
1063 if (g_test_rand_bit ())
1064 /* construct a fixed-sized type */
1066 char type_string
[MAX_FIXED_MULTIPLIER
];
1070 multiplier
= g_test_rand_int_range (1, sizeof type_string
- 1);
1072 type_string
[i
++] = '(';
1073 while (multiplier
--)
1074 type_string
[i
++] = base_type
;
1075 type_string
[i
++] = ')';
1077 return g_strndup (type_string
, i
);
1080 /* construct a variable-sized type */
1082 char type_string
[2] = { 'a', base_type
};
1084 return g_strndup (type_string
, 2);
1090 GVariantTypeInfo
*type_info
;
1093 gboolean is_fixed_sized
;
1097 #define INSTANCE_MAGIC 1287582829
1101 static RandomInstance
*
1102 random_instance (GVariantTypeInfo
*type_info
)
1104 RandomInstance
*instance
;
1106 instance
= g_slice_new (RandomInstance
);
1108 if (type_info
== NULL
)
1110 gchar
*str
= random_type_string ();
1111 instance
->type_info
= g_variant_type_info_get (G_VARIANT_TYPE (str
));
1115 instance
->type_info
= g_variant_type_info_ref (type_info
);
1117 instance
->seed
= g_test_rand_int ();
1119 g_variant_type_info_query (instance
->type_info
,
1120 &instance
->alignment
,
1123 instance
->is_fixed_sized
= instance
->size
!= 0;
1125 if (!instance
->is_fixed_sized
)
1126 instance
->size
= g_test_rand_int_range (0, MAX_INSTANCE_SIZE
);
1128 instance
->magic
= INSTANCE_MAGIC
;
1134 random_instance_free (RandomInstance
*instance
)
1136 g_variant_type_info_unref (instance
->type_info
);
1137 g_slice_free (RandomInstance
, instance
);
1141 append_instance_size (RandomInstance
*instance
,
1144 *offset
+= (-*offset
) & instance
->alignment
;
1145 *offset
+= instance
->size
;
1149 random_instance_write (RandomInstance
*instance
,
1155 g_assert_cmpint ((gsize
) buffer
& ALIGN_BITS
& instance
->alignment
, ==, 0);
1157 rand
= g_rand_new_with_seed (instance
->seed
);
1158 for (i
= 0; i
< instance
->size
; i
++)
1159 buffer
[i
] = g_rand_int (rand
);
1164 append_instance_data (RandomInstance
*instance
,
1167 while (((gsize
) *buffer
) & instance
->alignment
)
1168 *(*buffer
)++ = '\0';
1170 random_instance_write (instance
, *buffer
);
1171 *buffer
+= instance
->size
;
1175 random_instance_assert (RandomInstance
*instance
,
1182 g_assert_cmpint ((gsize
) buffer
& ALIGN_BITS
& instance
->alignment
, ==, 0);
1183 g_assert_cmpint (size
, ==, instance
->size
);
1185 rand
= g_rand_new_with_seed (instance
->seed
);
1186 for (i
= 0; i
< instance
->size
; i
++)
1188 guchar byte
= g_rand_int (rand
);
1190 g_assert (buffer
[i
] == byte
);
1194 return i
== instance
->size
;
1198 random_instance_check (RandomInstance
*instance
,
1205 g_assert_cmpint ((gsize
) buffer
& ALIGN_BITS
& instance
->alignment
, ==, 0);
1207 if (size
!= instance
->size
)
1210 rand
= g_rand_new_with_seed (instance
->seed
);
1211 for (i
= 0; i
< instance
->size
; i
++)
1212 if (buffer
[i
] != (guchar
) g_rand_int (rand
))
1216 return i
== instance
->size
;
1220 random_instance_filler (GVariantSerialised
*serialised
,
1223 RandomInstance
*instance
= data
;
1225 g_assert (instance
->magic
== INSTANCE_MAGIC
);
1227 if (serialised
->type_info
== NULL
)
1228 serialised
->type_info
= instance
->type_info
;
1230 if (serialised
->size
== 0)
1231 serialised
->size
= instance
->size
;
1233 g_assert (serialised
->type_info
== instance
->type_info
);
1234 g_assert (serialised
->size
== instance
->size
);
1236 if (serialised
->data
)
1237 random_instance_write (instance
, serialised
->data
);
1241 calculate_offset_size (gsize body_size
,
1247 if (body_size
+ n_offsets
<= G_MAXUINT8
)
1250 if (body_size
+ 2 * n_offsets
<= G_MAXUINT16
)
1253 if (body_size
+ 4 * n_offsets
<= G_MAXUINT32
)
1256 /* the test case won't generate anything bigger */
1257 g_assert_not_reached ();
1261 flavoured_malloc (gsize size
, gsize flavour
)
1263 g_assert (flavour
< 8);
1268 return ((gchar
*) g_malloc (size
+ flavour
)) + flavour
;
1272 flavoured_free (gpointer data
,
1277 g_free (((gchar
*) data
) - flavour
);
1281 align_malloc (gsize size
)
1285 #ifdef HAVE_POSIX_MEMALIGN
1286 if (posix_memalign (&mem
, 8, size
))
1287 g_error ("posix_memalign failed");
1289 /* NOTE: there may be platforms that lack posix_memalign() and also
1290 * have malloc() that returns non-8-aligned. if so, we need to try
1293 mem
= malloc (size
);
1300 align_free (gpointer mem
)
1306 append_offset (guchar
**offset_ptr
,
1312 guchar bytes
[sizeof (gsize
)];
1316 tmpvalue
.integer
= GSIZE_TO_LE (offset
);
1317 memcpy (*offset_ptr
, tmpvalue
.bytes
, offset_size
);
1318 *offset_ptr
+= offset_size
;
1322 prepend_offset (guchar
**offset_ptr
,
1328 guchar bytes
[sizeof (gsize
)];
1332 *offset_ptr
-= offset_size
;
1333 tmpvalue
.integer
= GSIZE_TO_LE (offset
);
1334 memcpy (*offset_ptr
, tmpvalue
.bytes
, offset_size
);
1340 GVariantTypeInfo
*type_info
;
1341 RandomInstance
*instance
;
1345 instance
= random_instance (NULL
);
1348 const gchar
*element
;
1351 element
= g_variant_type_info_get_type_string (instance
->type_info
);
1352 tmp
= g_strdup_printf ("m%s", element
);
1353 type_info
= g_variant_type_info_get (G_VARIANT_TYPE (tmp
));
1357 needed_size
= g_variant_serialiser_needed_size (type_info
,
1358 random_instance_filler
,
1360 g_assert_cmpint (needed_size
, ==, 0);
1362 needed_size
= g_variant_serialiser_needed_size (type_info
,
1363 random_instance_filler
,
1364 (gpointer
*) &instance
, 1);
1366 if (instance
->is_fixed_sized
)
1367 g_assert_cmpint (needed_size
, ==, instance
->size
);
1369 g_assert_cmpint (needed_size
, ==, instance
->size
+ 1);
1374 ptr
= data
= align_malloc (needed_size
);
1375 append_instance_data (instance
, &ptr
);
1377 if (!instance
->is_fixed_sized
)
1380 g_assert_cmpint (ptr
- data
, ==, needed_size
);
1387 alignment
= (instance
->alignment
& ALIGN_BITS
) + 1;
1389 for (flavour
= 0; flavour
< 8; flavour
+= alignment
)
1391 GVariantSerialised serialised
;
1392 GVariantSerialised child
;
1394 serialised
.type_info
= type_info
;
1395 serialised
.data
= flavoured_malloc (needed_size
, flavour
);
1396 serialised
.size
= needed_size
;
1398 g_variant_serialiser_serialise (serialised
,
1399 random_instance_filler
,
1400 (gpointer
*) &instance
, 1);
1401 child
= g_variant_serialised_get_child (serialised
, 0);
1402 g_assert (child
.type_info
== instance
->type_info
);
1403 random_instance_assert (instance
, child
.data
, child
.size
);
1404 g_variant_type_info_unref (child
.type_info
);
1405 flavoured_free (serialised
.data
, flavour
);
1409 g_variant_type_info_unref (type_info
);
1410 random_instance_free (instance
);
1419 for (i
= 0; i
< 1000; i
++)
1422 g_variant_type_info_assert_no_infos ();
1428 GVariantTypeInfo
*element_info
;
1429 GVariantTypeInfo
*array_info
;
1430 RandomInstance
**instances
;
1437 gchar
*element_type
, *array_type
;
1439 element_type
= random_type_string ();
1440 array_type
= g_strdup_printf ("a%s", element_type
);
1442 element_info
= g_variant_type_info_get (G_VARIANT_TYPE (element_type
));
1443 array_info
= g_variant_type_info_get (G_VARIANT_TYPE (array_type
));
1444 g_assert (g_variant_type_info_element (array_info
) == element_info
);
1446 g_free (element_type
);
1447 g_free (array_type
);
1453 n_children
= g_test_rand_int_range (0, MAX_ARRAY_CHILDREN
);
1454 instances
= g_new (RandomInstance
*, n_children
);
1455 for (i
= 0; i
< n_children
; i
++)
1456 instances
[i
] = random_instance (element_info
);
1459 needed_size
= g_variant_serialiser_needed_size (array_info
,
1460 random_instance_filler
,
1461 (gpointer
*) instances
,
1465 gsize element_fixed_size
;
1466 gsize body_size
= 0;
1469 for (i
= 0; i
< n_children
; i
++)
1470 append_instance_size (instances
[i
], &body_size
);
1472 g_variant_type_info_query (element_info
, NULL
, &element_fixed_size
);
1474 if (!element_fixed_size
)
1476 offset_size
= calculate_offset_size (body_size
, n_children
);
1478 if (offset_size
== 0)
1484 g_assert_cmpint (needed_size
, ==, body_size
+ n_children
* offset_size
);
1488 guchar
*offset_ptr
, *body_ptr
;
1491 body_ptr
= data
= align_malloc (needed_size
);
1492 offset_ptr
= body_ptr
+ needed_size
- offset_size
* n_children
;
1494 for (i
= 0; i
< n_children
; i
++)
1496 append_instance_data (instances
[i
], &body_ptr
);
1497 append_offset (&offset_ptr
, body_ptr
- data
, offset_size
);
1500 g_assert (body_ptr
== data
+ needed_size
- offset_size
* n_children
);
1501 g_assert (offset_ptr
== data
+ needed_size
);
1509 g_variant_type_info_query (array_info
, &alignment
, NULL
);
1510 alignment
= (alignment
& ALIGN_BITS
) + 1;
1512 for (flavour
= 0; flavour
< 8; flavour
+= alignment
)
1514 GVariantSerialised serialised
;
1516 serialised
.type_info
= array_info
;
1517 serialised
.data
= flavoured_malloc (needed_size
, flavour
);
1518 serialised
.size
= needed_size
;
1520 g_variant_serialiser_serialise (serialised
, random_instance_filler
,
1521 (gpointer
*) instances
, n_children
);
1523 g_assert (memcmp (serialised
.data
, data
, serialised
.size
) == 0);
1524 g_assert (g_variant_serialised_n_children (serialised
) == n_children
);
1526 for (i
= 0; i
< n_children
; i
++)
1528 GVariantSerialised child
;
1530 child
= g_variant_serialised_get_child (serialised
, i
);
1531 g_assert (child
.type_info
== instances
[i
]->type_info
);
1532 random_instance_assert (instances
[i
], child
.data
, child
.size
);
1533 g_variant_type_info_unref (child
.type_info
);
1536 flavoured_free (serialised
.data
, flavour
);
1543 for (i
= 0; i
< n_children
; i
++)
1544 random_instance_free (instances
[i
]);
1548 g_variant_type_info_unref (element_info
);
1549 g_variant_type_info_unref (array_info
);
1558 for (i
= 0; i
< 100; i
++)
1561 g_variant_type_info_assert_no_infos ();
1567 GVariantTypeInfo
*type_info
;
1568 RandomInstance
**instances
;
1569 gboolean fixed_size
;
1576 n_children
= g_test_rand_int_range (0, MAX_TUPLE_CHILDREN
);
1577 instances
= g_new (RandomInstance
*, n_children
);
1580 GString
*type_string
;
1586 type_string
= g_string_new ("(");
1587 for (i
= 0; i
< n_children
; i
++)
1591 instances
[i
] = random_instance (NULL
);
1593 alignment
|= instances
[i
]->alignment
;
1594 if (!instances
[i
]->is_fixed_sized
)
1597 str
= g_variant_type_info_get_type_string (instances
[i
]->type_info
);
1598 g_string_append (type_string
, str
);
1600 g_string_append_c (type_string
, ')');
1602 type_info
= g_variant_type_info_get (G_VARIANT_TYPE (type_string
->str
));
1603 g_string_free (type_string
, TRUE
);
1606 needed_size
= g_variant_serialiser_needed_size (type_info
,
1607 random_instance_filler
,
1608 (gpointer
*) instances
,
1611 gsize body_size
= 0;
1615 for (i
= 0; i
< n_children
; i
++)
1617 append_instance_size (instances
[i
], &body_size
);
1619 if (i
!= n_children
- 1 && !instances
[i
]->is_fixed_sized
)
1625 body_size
+= (-body_size
) & alignment
;
1627 g_assert ((body_size
== 0) == (n_children
== 0));
1628 if (n_children
== 0)
1632 offset_size
= calculate_offset_size (body_size
, offsets
);
1633 g_assert_cmpint (needed_size
, ==, body_size
+ offsets
* offset_size
);
1641 body_ptr
= data
= align_malloc (needed_size
);
1642 ofs_ptr
= body_ptr
+ needed_size
;
1644 for (i
= 0; i
< n_children
; i
++)
1646 append_instance_data (instances
[i
], &body_ptr
);
1648 if (i
!= n_children
- 1 && !instances
[i
]->is_fixed_sized
)
1649 prepend_offset (&ofs_ptr
, body_ptr
- data
, offset_size
);
1654 while (((gsize
) body_ptr
) & alignment
)
1657 g_assert ((body_ptr
== data
) == (n_children
== 0));
1658 if (n_children
== 0)
1664 g_assert (body_ptr
== ofs_ptr
);
1671 alignment
= (alignment
& ALIGN_BITS
) + 1;
1673 for (flavour
= 0; flavour
< 8; flavour
+= alignment
)
1675 GVariantSerialised serialised
;
1677 serialised
.type_info
= type_info
;
1678 serialised
.data
= flavoured_malloc (needed_size
, flavour
);
1679 serialised
.size
= needed_size
;
1681 g_variant_serialiser_serialise (serialised
, random_instance_filler
,
1682 (gpointer
*) instances
, n_children
);
1684 g_assert (memcmp (serialised
.data
, data
, serialised
.size
) == 0);
1685 g_assert (g_variant_serialised_n_children (serialised
) == n_children
);
1687 for (i
= 0; i
< n_children
; i
++)
1689 GVariantSerialised child
;
1691 child
= g_variant_serialised_get_child (serialised
, i
);
1692 g_assert (child
.type_info
== instances
[i
]->type_info
);
1693 random_instance_assert (instances
[i
], child
.data
, child
.size
);
1694 g_variant_type_info_unref (child
.type_info
);
1697 flavoured_free (serialised
.data
, flavour
);
1704 for (i
= 0; i
< n_children
; i
++)
1705 random_instance_free (instances
[i
]);
1709 g_variant_type_info_unref (type_info
);
1718 for (i
= 0; i
< 100; i
++)
1721 g_variant_type_info_assert_no_infos ();
1727 GVariantTypeInfo
*type_info
;
1728 RandomInstance
*instance
;
1729 const gchar
*type_string
;
1734 type_info
= g_variant_type_info_get (G_VARIANT_TYPE_VARIANT
);
1735 instance
= random_instance (NULL
);
1737 type_string
= g_variant_type_info_get_type_string (instance
->type_info
);
1738 len
= strlen (type_string
);
1740 needed_size
= g_variant_serialiser_needed_size (type_info
,
1741 random_instance_filler
,
1742 (gpointer
*) &instance
, 1);
1744 g_assert_cmpint (needed_size
, ==, instance
->size
+ 1 + len
);
1749 ptr
= data
= align_malloc (needed_size
);
1750 append_instance_data (instance
, &ptr
);
1752 memcpy (ptr
, type_string
, len
);
1755 g_assert (data
+ needed_size
== ptr
);
1762 /* variants are always 8-aligned */
1763 alignment
= ALIGN_BITS
+ 1;
1765 for (flavour
= 0; flavour
< 8; flavour
+= alignment
)
1767 GVariantSerialised serialised
;
1768 GVariantSerialised child
;
1770 serialised
.type_info
= type_info
;
1771 serialised
.data
= flavoured_malloc (needed_size
, flavour
);
1772 serialised
.size
= needed_size
;
1774 g_variant_serialiser_serialise (serialised
, random_instance_filler
,
1775 (gpointer
*) &instance
, 1);
1777 g_assert (memcmp (serialised
.data
, data
, serialised
.size
) == 0);
1778 g_assert (g_variant_serialised_n_children (serialised
) == 1);
1780 child
= g_variant_serialised_get_child (serialised
, 0);
1781 g_assert (child
.type_info
== instance
->type_info
);
1782 random_instance_check (instance
, child
.data
, child
.size
);
1784 g_variant_type_info_unref (child
.type_info
);
1785 flavoured_free (serialised
.data
, flavour
);
1789 g_variant_type_info_unref (type_info
);
1790 random_instance_free (instance
);
1795 test_variants (void)
1799 for (i
= 0; i
< 100; i
++)
1802 g_variant_type_info_assert_no_infos ();
1815 #define is_objpath is_string | 2
1816 #define is_sig is_string | 4
1818 { is_nval
, 0, NULL
},
1819 { is_nval
, 13, "hello\xffworld!" },
1820 { is_string
, 13, "hello world!" },
1821 { is_nval
, 13, "hello world\0" },
1822 { is_nval
, 13, "hello\0world!" },
1823 { is_nval
, 12, "hello world!" },
1825 { is_objpath
, 2, "/" },
1826 { is_objpath
, 3, "/a" },
1827 { is_string
, 3, "//" },
1828 { is_objpath
, 11, "/some/path" },
1829 { is_string
, 12, "/some/path/" },
1830 { is_nval
, 11, "/some\0path" },
1831 { is_string
, 11, "/some\\path" },
1832 { is_string
, 12, "/some//path" },
1833 { is_string
, 12, "/some-/path" },
1837 { is_sig
, 5, "(si)" },
1838 { is_string
, 4, "(si" },
1839 { is_string
, 2, "*" },
1840 { is_sig
, 3, "ai" },
1841 { is_string
, 3, "mi" },
1842 { is_string
, 2, "r" },
1843 { is_sig
, 15, "(yyy{sv}ssiai)" },
1844 { is_string
, 16, "(yyy{yv}ssiai))" },
1845 { is_string
, 15, "(yyy{vv}ssiai)" },
1846 { is_string
, 15, "(yyy{sv)ssiai}" }
1850 for (i
= 0; i
< G_N_ELEMENTS (test_cases
); i
++)
1854 flags
= g_variant_serialiser_is_string (test_cases
[i
].data
,
1858 flags
|= g_variant_serialiser_is_object_path (test_cases
[i
].data
,
1862 flags
|= g_variant_serialiser_is_signature (test_cases
[i
].data
,
1866 g_assert (flags
== test_cases
[i
].flags
);
1870 typedef struct _TreeInstance TreeInstance
;
1871 struct _TreeInstance
1873 GVariantTypeInfo
*info
;
1875 TreeInstance
**children
;
1886 static GVariantType
*
1887 make_random_definite_type (int depth
)
1889 GString
*description
;
1890 GString
*type_string
;
1893 description
= g_string_new (NULL
);
1894 type_string
= g_string_new (NULL
);
1895 type
= append_type_string (type_string
, description
, TRUE
, depth
);
1896 g_string_free (description
, TRUE
);
1897 g_string_free (type_string
, TRUE
);
1903 make_random_string (gchar
*string
,
1905 const GVariantType
*type
)
1909 /* create strings that are valid signature strings */
1910 #define good_chars "bynqiuxthdsog"
1912 for (i
= 0; i
< size
- 1; i
++)
1913 string
[i
] = good_chars
[g_test_rand_int_range (0, strlen (good_chars
))];
1916 /* in case we need an object path, prefix a '/' */
1917 if (*g_variant_type_peek_string (type
) == 'o')
1923 static TreeInstance
*
1924 tree_instance_new (const GVariantType
*type
,
1927 const GVariantType
*child_type
= NULL
;
1928 GVariantType
*mytype
= NULL
;
1929 TreeInstance
*instance
;
1930 gboolean is_tuple_type
;
1933 type
= mytype
= make_random_definite_type (depth
);
1935 instance
= g_slice_new (TreeInstance
);
1936 instance
->info
= g_variant_type_info_get (type
);
1937 instance
->children
= NULL
;
1938 instance
->n_children
= 0;
1939 instance
->data_size
= 0;
1941 is_tuple_type
= FALSE
;
1943 switch (*g_variant_type_peek_string (type
))
1945 case G_VARIANT_TYPE_INFO_CHAR_MAYBE
:
1946 instance
->n_children
= g_test_rand_int_range (0, 2);
1947 child_type
= g_variant_type_element (type
);
1950 case G_VARIANT_TYPE_INFO_CHAR_ARRAY
:
1951 instance
->n_children
= g_test_rand_int_range (0, MAX_ARRAY_CHILDREN
);
1952 child_type
= g_variant_type_element (type
);
1955 case G_VARIANT_TYPE_INFO_CHAR_DICT_ENTRY
:
1956 case G_VARIANT_TYPE_INFO_CHAR_TUPLE
:
1957 instance
->n_children
= g_variant_type_n_items (type
);
1958 child_type
= g_variant_type_first (type
);
1959 is_tuple_type
= TRUE
;
1962 case G_VARIANT_TYPE_INFO_CHAR_VARIANT
:
1963 instance
->n_children
= 1;
1968 instance
->data
.integer
= g_test_rand_int_range (0, 2);
1969 instance
->data_size
= 1;
1973 instance
->data
.integer
= g_test_rand_int ();
1974 instance
->data_size
= 1;
1978 instance
->data
.integer
= g_test_rand_int ();
1979 instance
->data_size
= 2;
1982 case 'i': case 'u': case 'h':
1983 instance
->data
.integer
= g_test_rand_int ();
1984 instance
->data_size
= 4;
1988 instance
->data
.integer
= g_test_rand_int ();
1989 instance
->data
.integer
<<= 32;
1990 instance
->data
.integer
|= (guint32
) g_test_rand_int ();
1991 instance
->data_size
= 8;
1995 instance
->data
.floating
= g_test_rand_double ();
1996 instance
->data_size
= 8;
1999 case 's': case 'o': case 'g':
2000 instance
->data_size
= g_test_rand_int_range (10, 20);
2001 make_random_string (instance
->data
.string
, instance
->data_size
, type
);
2005 if (instance
->data_size
== 0)
2006 /* no data -> it is a container */
2010 instance
->children
= g_new (TreeInstance
*, instance
->n_children
);
2012 for (i
= 0; i
< instance
->n_children
; i
++)
2014 instance
->children
[i
] = tree_instance_new (child_type
, depth
- 1);
2017 child_type
= g_variant_type_next (child_type
);
2020 g_assert (!is_tuple_type
|| child_type
== NULL
);
2023 g_variant_type_free (mytype
);
2029 tree_instance_free (TreeInstance
*instance
)
2033 g_variant_type_info_unref (instance
->info
);
2034 for (i
= 0; i
< instance
->n_children
; i
++)
2035 tree_instance_free (instance
->children
[i
]);
2036 g_free (instance
->children
);
2037 g_slice_free (TreeInstance
, instance
);
2040 static gboolean i_am_writing_byteswapped
;
2043 tree_filler (GVariantSerialised
*serialised
,
2046 TreeInstance
*instance
= data
;
2048 if (serialised
->type_info
== NULL
)
2049 serialised
->type_info
= instance
->info
;
2051 if (instance
->data_size
== 0)
2052 /* is a container */
2054 if (serialised
->size
== 0)
2056 g_variant_serialiser_needed_size (instance
->info
, tree_filler
,
2057 (gpointer
*) instance
->children
,
2058 instance
->n_children
);
2060 if (serialised
->data
)
2061 g_variant_serialiser_serialise (*serialised
, tree_filler
,
2062 (gpointer
*) instance
->children
,
2063 instance
->n_children
);
2068 if (serialised
->size
== 0)
2069 serialised
->size
= instance
->data_size
;
2071 if (serialised
->data
)
2073 switch (instance
->data_size
)
2076 *serialised
->data
= instance
->data
.integer
;
2081 guint16 value
= instance
->data
.integer
;
2083 if (i_am_writing_byteswapped
)
2084 value
= GUINT16_SWAP_LE_BE (value
);
2086 *(guint16
*) serialised
->data
= value
;
2092 guint32 value
= instance
->data
.integer
;
2094 if (i_am_writing_byteswapped
)
2095 value
= GUINT32_SWAP_LE_BE (value
);
2097 *(guint32
*) serialised
->data
= value
;
2103 guint64 value
= instance
->data
.integer
;
2105 if (i_am_writing_byteswapped
)
2106 value
= GUINT64_SWAP_LE_BE (value
);
2108 *(guint64
*) serialised
->data
= value
;
2113 memcpy (serialised
->data
,
2114 instance
->data
.string
,
2115 instance
->data_size
);
2123 check_tree (TreeInstance
*instance
,
2124 GVariantSerialised serialised
)
2126 if (instance
->info
!= serialised
.type_info
)
2129 if (instance
->data_size
== 0)
2130 /* is a container */
2134 if (g_variant_serialised_n_children (serialised
) !=
2135 instance
->n_children
)
2138 for (i
= 0; i
< instance
->n_children
; i
++)
2140 GVariantSerialised child
;
2141 gpointer data
= NULL
;
2144 child
= g_variant_serialised_get_child (serialised
, i
);
2145 if (child
.size
&& child
.data
== NULL
)
2146 child
.data
= data
= g_malloc0 (child
.size
);
2147 ok
= check_tree (instance
->children
[i
], child
);
2148 g_variant_type_info_unref (child
.type_info
);
2160 switch (instance
->data_size
)
2163 g_assert (serialised
.size
== 1);
2164 return *(guint8
*) serialised
.data
==
2165 (guint8
) instance
->data
.integer
;
2168 g_assert (serialised
.size
== 2);
2169 return *(guint16
*) serialised
.data
==
2170 (guint16
) instance
->data
.integer
;
2173 g_assert (serialised
.size
== 4);
2174 return *(guint32
*) serialised
.data
==
2175 (guint32
) instance
->data
.integer
;
2178 g_assert (serialised
.size
== 8);
2179 return *(guint64
*) serialised
.data
==
2180 (guint64
) instance
->data
.integer
;
2183 if (serialised
.size
!= instance
->data_size
)
2186 return memcmp (serialised
.data
,
2187 instance
->data
.string
,
2188 instance
->data_size
) == 0;
2194 serialise_tree (TreeInstance
*tree
,
2195 GVariantSerialised
*serialised
)
2197 GVariantSerialised empty
= { };
2199 *serialised
= empty
;
2200 tree_filler (serialised
, tree
);
2201 serialised
->data
= g_malloc (serialised
->size
);
2202 tree_filler (serialised
, tree
);
2206 test_byteswap (void)
2208 GVariantSerialised one
, two
;
2211 tree
= tree_instance_new (NULL
, 3);
2212 serialise_tree (tree
, &one
);
2214 i_am_writing_byteswapped
= TRUE
;
2215 serialise_tree (tree
, &two
);
2216 i_am_writing_byteswapped
= FALSE
;
2218 g_variant_serialised_byteswap (two
);
2220 g_assert_cmpint (one
.size
, ==, two
.size
);
2221 g_assert (memcmp (one
.data
, two
.data
, one
.size
) == 0);
2223 tree_instance_free (tree
);
2229 test_byteswaps (void)
2233 for (i
= 0; i
< 200; i
++)
2236 g_variant_type_info_assert_no_infos ();
2240 test_fuzz (gdouble
*fuzziness
)
2242 GVariantSerialised serialised
;
2245 /* make an instance */
2246 tree
= tree_instance_new (NULL
, 3);
2249 serialise_tree (tree
, &serialised
);
2251 g_assert (g_variant_serialised_is_normal (serialised
));
2252 g_assert (check_tree (tree
, serialised
));
2254 if (serialised
.size
)
2256 gboolean fuzzed
= FALSE
;
2263 for (i
= 0; i
< serialised
.size
; i
++)
2264 if (randomly (*fuzziness
))
2266 serialised
.data
[i
] += g_test_rand_int_range (1, 256);
2271 /* at least one byte in the serialised data has changed.
2273 * this means that at least one of the following is true:
2275 * - the serialised data now represents a different value:
2276 * check_tree() will return FALSE
2278 * - the serialised data is in non-normal form:
2279 * g_variant_serialiser_is_normal() will return FALSE
2281 * we always do both checks to increase exposure of the serialiser
2284 a
= g_variant_serialised_is_normal (serialised
);
2285 b
= check_tree (tree
, serialised
);
2287 g_assert (!a
|| !b
);
2290 tree_instance_free (tree
);
2291 g_free (serialised
.data
);
2296 test_fuzzes (gpointer data
)
2301 fuzziness
= GPOINTER_TO_INT (data
) / 100.;
2303 for (i
= 0; i
< 200; i
++)
2304 test_fuzz (&fuzziness
);
2306 g_variant_type_info_assert_no_infos ();
2310 tree_instance_get_gvariant (TreeInstance
*tree
)
2312 const GVariantType
*type
;
2315 type
= (GVariantType
*) g_variant_type_info_get_type_string (tree
->info
);
2317 switch (g_variant_type_info_get_type_char (tree
->info
))
2319 case G_VARIANT_TYPE_INFO_CHAR_MAYBE
:
2321 const GVariantType
*child_type
;
2324 if (tree
->n_children
)
2325 child
= tree_instance_get_gvariant (tree
->children
[0]);
2329 child_type
= g_variant_type_element (type
);
2331 if (child
!= NULL
&& randomly (0.5))
2334 result
= g_variant_new_maybe (child_type
, child
);
2338 case G_VARIANT_TYPE_INFO_CHAR_ARRAY
:
2340 const GVariantType
*child_type
;
2341 GVariant
**children
;
2344 children
= g_new (GVariant
*, tree
->n_children
);
2345 for (i
= 0; i
< tree
->n_children
; i
++)
2346 children
[i
] = tree_instance_get_gvariant (tree
->children
[i
]);
2348 child_type
= g_variant_type_element (type
);
2350 if (i
> 0 && randomly (0.5))
2353 result
= g_variant_new_array (child_type
, children
, tree
->n_children
);
2358 case G_VARIANT_TYPE_INFO_CHAR_TUPLE
:
2360 GVariant
**children
;
2363 children
= g_new (GVariant
*, tree
->n_children
);
2364 for (i
= 0; i
< tree
->n_children
; i
++)
2365 children
[i
] = tree_instance_get_gvariant (tree
->children
[i
]);
2367 result
= g_variant_new_tuple (children
, tree
->n_children
);
2372 case G_VARIANT_TYPE_INFO_CHAR_DICT_ENTRY
:
2374 GVariant
*key
, *val
;
2376 g_assert (tree
->n_children
== 2);
2378 key
= tree_instance_get_gvariant (tree
->children
[0]);
2379 val
= tree_instance_get_gvariant (tree
->children
[1]);
2381 result
= g_variant_new_dict_entry (key
, val
);
2385 case G_VARIANT_TYPE_INFO_CHAR_VARIANT
:
2389 g_assert (tree
->n_children
== 1);
2391 value
= tree_instance_get_gvariant (tree
->children
[0]);
2392 result
= g_variant_new_variant (value
);
2397 result
= g_variant_new_boolean (tree
->data
.integer
> 0);
2401 result
= g_variant_new_byte (tree
->data
.integer
);
2405 result
= g_variant_new_int16 (tree
->data
.integer
);
2409 result
= g_variant_new_uint16 (tree
->data
.integer
);
2413 result
= g_variant_new_int32 (tree
->data
.integer
);
2417 result
= g_variant_new_uint32 (tree
->data
.integer
);
2421 result
= g_variant_new_int64 (tree
->data
.integer
);
2425 result
= g_variant_new_uint64 (tree
->data
.integer
);
2429 result
= g_variant_new_handle (tree
->data
.integer
);
2433 result
= g_variant_new_double (tree
->data
.floating
);
2437 result
= g_variant_new_string (tree
->data
.string
);
2441 result
= g_variant_new_object_path (tree
->data
.string
);
2445 result
= g_variant_new_signature (tree
->data
.string
);
2449 g_assert_not_reached ();
2456 tree_instance_check_gvariant (TreeInstance
*tree
,
2459 const GVariantType
*type
;
2461 type
= (GVariantType
*) g_variant_type_info_get_type_string (tree
->info
);
2462 g_assert (g_variant_is_of_type (value
, type
));
2464 switch (g_variant_type_info_get_type_char (tree
->info
))
2466 case G_VARIANT_TYPE_INFO_CHAR_MAYBE
:
2471 child
= g_variant_get_maybe (value
);
2473 if (child
!= NULL
&& tree
->n_children
== 1)
2474 equal
= tree_instance_check_gvariant (tree
->children
[0], child
);
2475 else if (child
== NULL
&& tree
->n_children
== 0)
2481 g_variant_unref (child
);
2487 case G_VARIANT_TYPE_INFO_CHAR_ARRAY
:
2488 case G_VARIANT_TYPE_INFO_CHAR_TUPLE
:
2489 case G_VARIANT_TYPE_INFO_CHAR_DICT_ENTRY
:
2493 if (g_variant_n_children (value
) != tree
->n_children
)
2496 for (i
= 0; i
< tree
->n_children
; i
++)
2501 child
= g_variant_get_child_value (value
, i
);
2502 equal
= tree_instance_check_gvariant (tree
->children
[i
], child
);
2503 g_variant_unref (child
);
2513 case G_VARIANT_TYPE_INFO_CHAR_VARIANT
:
2515 const gchar
*str1
, *str2
;
2519 child
= g_variant_get_variant (value
);
2520 str1
= g_variant_get_type_string (child
);
2521 str2
= g_variant_type_info_get_type_string (tree
->children
[0]->info
);
2522 /* GVariant only keeps one copy of type strings around */
2523 equal
= str1
== str2
&&
2524 tree_instance_check_gvariant (tree
->children
[0], child
);
2526 g_variant_unref (child
);
2533 return g_variant_get_boolean (value
) == tree
->data
.integer
;
2536 return g_variant_get_byte (value
) == (guchar
) tree
->data
.integer
;
2539 return g_variant_get_int16 (value
) == (gint16
) tree
->data
.integer
;
2542 return g_variant_get_uint16 (value
) == (guint16
) tree
->data
.integer
;
2545 return g_variant_get_int32 (value
) == (gint32
) tree
->data
.integer
;
2548 return g_variant_get_uint32 (value
) == (guint32
) tree
->data
.integer
;
2551 return g_variant_get_int64 (value
) == (gint64
) tree
->data
.integer
;
2554 return g_variant_get_uint64 (value
) == (guint64
) tree
->data
.integer
;
2557 return g_variant_get_handle (value
) == (gint32
) tree
->data
.integer
;
2561 gdouble floating
= g_variant_get_double (value
);
2563 return memcmp (&floating
, &tree
->data
.floating
, sizeof floating
) == 0;
2569 return strcmp (g_variant_get_string (value
, NULL
),
2570 tree
->data
.string
) == 0;
2573 g_assert_not_reached ();
2578 tree_instance_build_gvariant (TreeInstance
*tree
,
2579 GVariantBuilder
*builder
,
2582 const GVariantType
*type
;
2584 type
= (GVariantType
*) g_variant_type_info_get_type_string (tree
->info
);
2586 if (g_variant_type_is_container (type
))
2590 /* force GVariantBuilder to guess the type half the time */
2591 if (guess_ok
&& randomly (0.5))
2593 if (g_variant_type_is_array (type
) && tree
->n_children
)
2594 type
= G_VARIANT_TYPE_ARRAY
;
2596 if (g_variant_type_is_maybe (type
) && tree
->n_children
)
2597 type
= G_VARIANT_TYPE_MAYBE
;
2599 if (g_variant_type_is_tuple (type
))
2600 type
= G_VARIANT_TYPE_TUPLE
;
2602 if (g_variant_type_is_dict_entry (type
))
2603 type
= G_VARIANT_TYPE_DICT_ENTRY
;
2608 g_variant_builder_open (builder
, type
);
2610 for (i
= 0; i
< tree
->n_children
; i
++)
2611 tree_instance_build_gvariant (tree
->children
[i
], builder
, guess_ok
);
2613 g_variant_builder_close (builder
);
2616 g_variant_builder_add_value (builder
, tree_instance_get_gvariant (tree
));
2621 tree_instance_check_iter (TreeInstance
*tree
,
2626 value
= g_variant_iter_next_value (iter
);
2628 if (g_variant_is_container (value
))
2632 iter
= g_variant_iter_new (value
);
2633 g_variant_unref (value
);
2635 if (g_variant_iter_n_children (iter
) != tree
->n_children
)
2637 g_variant_iter_free (iter
);
2641 for (i
= 0; i
< tree
->n_children
; i
++)
2642 if (!tree_instance_check_iter (tree
->children
[i
], iter
))
2644 g_variant_iter_free (iter
);
2648 g_assert (g_variant_iter_next_value (iter
) == NULL
);
2649 g_variant_iter_free (iter
);
2658 equal
= tree_instance_check_gvariant (tree
, value
);
2659 g_variant_unref (value
);
2666 test_container (void)
2672 tree
= tree_instance_new (NULL
, 3);
2673 value
= g_variant_ref_sink (tree_instance_get_gvariant (tree
));
2675 s1
= g_variant_print (value
, TRUE
);
2676 g_assert (tree_instance_check_gvariant (tree
, value
));
2678 g_variant_get_data (value
);
2680 s2
= g_variant_print (value
, TRUE
);
2681 g_assert (tree_instance_check_gvariant (tree
, value
));
2683 g_assert_cmpstr (s1
, ==, s2
);
2685 if (g_variant_is_container (value
))
2687 GVariantBuilder builder
;
2693 g_variant_builder_init (&builder
, G_VARIANT_TYPE_VARIANT
);
2694 tree_instance_build_gvariant (tree
, &builder
, TRUE
);
2695 built
= g_variant_builder_end (&builder
);
2696 g_variant_ref_sink (built
);
2697 g_variant_get_data (built
);
2698 val
= g_variant_get_variant (built
);
2700 s3
= g_variant_print (val
, TRUE
);
2701 g_assert_cmpstr (s1
, ==, s3
);
2703 g_variant_iter_init (&iter
, built
);
2704 g_assert (tree_instance_check_iter (tree
, &iter
));
2705 g_assert (g_variant_iter_next_value (&iter
) == NULL
);
2707 g_variant_unref (built
);
2708 g_variant_unref (val
);
2712 tree_instance_free (tree
);
2713 g_variant_unref (value
);
2721 const gchar invalid
[] = "hello\xffworld";
2724 /* ensure that the test data is not valid utf8... */
2725 g_assert (!g_utf8_validate (invalid
, -1, NULL
));
2727 /* load the data untrusted */
2728 value
= g_variant_new_from_data (G_VARIANT_TYPE_STRING
,
2729 invalid
, sizeof invalid
,
2732 /* ensure that the problem is caught and we get valid UTF-8 */
2733 g_assert (g_utf8_validate (g_variant_get_string (value
, NULL
), -1, NULL
));
2734 g_variant_unref (value
);
2737 /* now load it trusted */
2738 value
= g_variant_new_from_data (G_VARIANT_TYPE_STRING
,
2739 invalid
, sizeof invalid
,
2742 /* ensure we get the invalid data (ie: make sure that time wasn't
2743 * wasted on validating data that was marked as trusted)
2745 g_assert (g_variant_get_string (value
, NULL
) == invalid
);
2746 g_variant_unref (value
);
2750 test_containers (void)
2754 for (i
= 0; i
< 100; i
++)
2759 g_variant_type_info_assert_no_infos ();
2763 test_format_strings (void)
2768 g_assert (g_variant_format_string_scan ("i", NULL
, &end
) && *end
== '\0');
2769 g_assert (g_variant_format_string_scan ("@i", NULL
, &end
) && *end
== '\0');
2770 g_assert (g_variant_format_string_scan ("@ii", NULL
, &end
) && *end
== 'i');
2771 g_assert (g_variant_format_string_scan ("^a&s", NULL
, &end
) && *end
== '\0');
2772 g_assert (g_variant_format_string_scan ("(^as)", NULL
, &end
) &&
2774 g_assert (!g_variant_format_string_scan ("(^s)", NULL
, &end
));
2775 g_assert (!g_variant_format_string_scan ("(^a)", NULL
, &end
));
2776 g_assert (!g_variant_format_string_scan ("(z)", NULL
, &end
));
2777 g_assert (!g_variant_format_string_scan ("az", NULL
, &end
));
2778 g_assert (!g_variant_format_string_scan ("{**}", NULL
, &end
));
2779 g_assert (!g_variant_format_string_scan ("{@**}", NULL
, &end
));
2780 g_assert (g_variant_format_string_scan ("{@y*}", NULL
, &end
) &&
2782 g_assert (g_variant_format_string_scan ("{yv}", NULL
, &end
) &&
2784 g_assert (!g_variant_format_string_scan ("{&?v}", NULL
, &end
));
2785 g_assert (g_variant_format_string_scan ("{@?v}", NULL
, &end
) &&
2787 g_assert (!g_variant_format_string_scan ("{&@sv}", NULL
, &end
));
2788 g_assert (!g_variant_format_string_scan ("{@&sv}", NULL
, &end
));
2789 g_assert (g_variant_format_string_scan ("{&sv}", NULL
, &end
) &&
2791 g_assert (!g_variant_format_string_scan ("{vv}", NULL
, &end
));
2792 g_assert (!g_variant_format_string_scan ("{y}", NULL
, &end
));
2793 g_assert (!g_variant_format_string_scan ("{yyy}", NULL
, &end
));
2794 g_assert (!g_variant_format_string_scan ("{ya}", NULL
, &end
));
2795 g_assert (g_variant_format_string_scan ("&s", NULL
, &end
) && *end
== '\0');
2796 g_assert (!g_variant_format_string_scan ("&as", NULL
, &end
));
2797 g_assert (!g_variant_format_string_scan ("@z", NULL
, &end
));
2798 g_assert (!g_variant_format_string_scan ("az", NULL
, &end
));
2799 g_assert (!g_variant_format_string_scan ("a&s", NULL
, &end
));
2801 type
= g_variant_format_string_scan_type ("mm(@xy^a&s*?@?)", NULL
, &end
);
2802 g_assert (type
&& *end
== '\0');
2803 g_assert (g_variant_type_equal (type
, G_VARIANT_TYPE ("mm(xyas*?\?)")));
2804 g_variant_type_free (type
);
2806 type
= g_variant_format_string_scan_type ("mm(@xy^a&*?@?)", NULL
, NULL
);
2807 g_assert (type
== NULL
);
2811 exit_on_abort (int signal
)
2817 do_failed_test (const gchar
*pattern
)
2819 if (g_test_trap_fork (1000000, G_TEST_TRAP_SILENCE_STDERR
))
2821 signal (SIGABRT
, exit_on_abort
);
2825 g_test_trap_assert_failed ();
2826 g_test_trap_assert_stderr (pattern
);
2832 test_invalid_varargs (void)
2834 if (do_failed_test ("*GVariant format string*"))
2836 g_variant_new ("z");
2840 if (do_failed_test ("*valid GVariant format string as a prefix*"))
2844 g_variant_new_va ("z", &end
, NULL
);
2848 if (do_failed_test ("*type of `q' but * has a type of `y'*"))
2850 g_variant_get (g_variant_new ("y", 'a'), "q");
2856 check_and_free (GVariant
*value
,
2859 gchar
*valstr
= g_variant_print (value
, FALSE
);
2860 g_assert_cmpstr (str
, ==, valstr
);
2861 g_variant_unref (value
);
2869 GVariantBuilder array
;
2871 g_variant_builder_init (&array
, G_VARIANT_TYPE_ARRAY
);
2872 g_variant_builder_add_parsed (&array
, "{'size', <(%i, %i)> }", 800, 600);
2873 g_variant_builder_add (&array
, "{sv}", "title",
2874 g_variant_new_string ("Test case"));
2875 g_variant_builder_add_value (&array
,
2876 g_variant_new_dict_entry (g_variant_new_string ("temperature"),
2877 g_variant_new_variant (
2878 g_variant_new_double (37.5))));
2879 check_and_free (g_variant_new ("(ma{sv}m(a{sv})ma{sv}ii)",
2880 NULL
, FALSE
, NULL
, &array
, 7777, 8888),
2881 "(nothing, nothing, {'size': <(800, 600)>, "
2882 "'title': <'Test case'>, "
2883 "'temperature': <37.5>}, "
2886 check_and_free (g_variant_new ("(imimimmimmimmi)",
2893 "(123, nothing, 123, nothing, just nothing, 123)");
2895 check_and_free (g_variant_new ("(ybnixd)",
2896 'a', 1, 22, 33, (guint64
) 44, 5.5),
2897 "(0x61, true, 22, 33, 44, 5.5)");
2899 check_and_free (g_variant_new ("(@y?*rv)",
2900 g_variant_new ("y", 'a'),
2901 g_variant_new ("y", 'b'),
2902 g_variant_new ("y", 'c'),
2903 g_variant_new ("(y)", 'd'),
2904 g_variant_new ("y", 'e')),
2905 "(0x61, 0x62, 0x63, (0x64,), <byte 0x65>)");
2909 GVariantBuilder array
;
2916 g_variant_builder_init (&array
, G_VARIANT_TYPE_ARRAY
);
2917 for (i
= 0; i
< 100; i
++)
2919 number
= g_strdup_printf ("%d", i
);
2920 g_variant_builder_add (&array
, "s", number
);
2924 value
= g_variant_builder_end (&array
);
2925 g_variant_iter_init (&iter
, value
);
2928 while (g_variant_iter_loop (&iter
, "s", &number
))
2930 gchar
*check
= g_strdup_printf ("%d", i
++);
2931 g_assert_cmpstr (number
, ==, check
);
2934 g_assert (number
== NULL
);
2935 g_assert (i
== 100);
2937 g_variant_unref (value
);
2939 g_variant_builder_init (&array
, G_VARIANT_TYPE_ARRAY
);
2940 for (i
= 0; i
< 100; i
++)
2941 g_variant_builder_add (&array
, "mi", i
% 2 == 0, i
);
2942 value
= g_variant_builder_end (&array
);
2945 g_variant_iter_init (&iter
, value
);
2946 while (g_variant_iter_loop (&iter
, "mi", NULL
, &val
))
2947 g_assert (val
== i
++ || val
== 0);
2948 g_assert (i
== 100);
2951 g_variant_iter_init (&iter
, value
);
2952 while (g_variant_iter_loop (&iter
, "mi", &just
, &val
))
2959 g_assert (val
== this);
2964 g_assert (val
== 0);
2967 g_assert (i
== 100);
2969 g_variant_unref (value
);
2973 const gchar
*strvector
[] = {"/hello", "/world", NULL
};
2974 const gchar
*test_strs
[] = {"/foo", "/bar", "/baz" };
2975 GVariantBuilder builder
;
2976 GVariantIter
*array
;
2984 g_variant_builder_init (&builder
, G_VARIANT_TYPE ("as"));
2985 g_variant_builder_add (&builder
, "s", "/foo");
2986 g_variant_builder_add (&builder
, "s", "/bar");
2987 g_variant_builder_add (&builder
, "s", "/baz");
2988 value
= g_variant_new("(as^as^a&s)", &builder
, strvector
, strvector
);
2989 g_variant_iter_init (&tuple
, value
);
2990 g_variant_iter_next (&tuple
, "as", &array
);
2993 while (g_variant_iter_loop (array
, "s", &str
))
2994 g_assert_cmpstr (str
, ==, test_strs
[i
++]);
2997 g_variant_iter_free (array
);
3000 g_variant_iter_init (&tuple
, value
);
3001 g_variant_iter_next (&tuple
, "as", &array
);
3004 while (g_variant_iter_loop (array
, "&s", &str
))
3005 g_assert_cmpstr (str
, ==, test_strs
[i
++]);
3008 g_variant_iter_free (array
);
3010 g_variant_iter_next (&tuple
, "^a&s", &strv
);
3011 g_variant_iter_next (&tuple
, "^as", &my_strv
);
3013 g_assert_cmpstr (strv
[0], ==, "/hello");
3014 g_assert_cmpstr (strv
[1], ==, "/world");
3015 g_assert (strv
[2] == NULL
);
3016 g_assert_cmpstr (my_strv
[0], ==, "/hello");
3017 g_assert_cmpstr (my_strv
[1], ==, "/world");
3018 g_assert (my_strv
[2] == NULL
);
3020 g_variant_unref (value
);
3021 g_strfreev (my_strv
);
3026 const gchar
*strvector
[] = { "i", "ii", "iii", "iv", "v", "vi", NULL
};
3027 GVariantBuilder builder
;
3036 g_variant_builder_init (&builder
, G_VARIANT_TYPE ("aas"));
3037 g_variant_builder_open (&builder
, G_VARIANT_TYPE ("as"));
3038 for (i
= 0; i
< 6; i
++)
3040 g_variant_builder_add (&builder
, "s", strvector
[i
]);
3042 g_variant_builder_add (&builder
, "&s", strvector
[i
]);
3043 g_variant_builder_close (&builder
);
3044 g_variant_builder_add (&builder
, "^as", strvector
);
3045 g_variant_builder_add (&builder
, "^as", strvector
);
3046 value
= g_variant_new ("aas", &builder
);
3048 g_variant_iter_init (&iter
, value
);
3049 while (g_variant_iter_loop (&iter
, "^as", &strv
))
3050 for (i
= 0; i
< 6; i
++)
3051 g_assert_cmpstr (strv
[i
], ==, strvector
[i
]);
3053 g_variant_iter_init (&iter
, value
);
3054 while (g_variant_iter_loop (&iter
, "^a&s", &strv
))
3055 for (i
= 0; i
< 6; i
++)
3056 g_assert_cmpstr (strv
[i
], ==, strvector
[i
]);
3058 g_variant_iter_init (&iter
, value
);
3059 while (g_variant_iter_loop (&iter
, "as", &i2
))
3064 while (g_variant_iter_loop (i2
, "s", &str
))
3065 g_assert_cmpstr (str
, ==, strvector
[i
++]);
3069 g_variant_iter_init (&iter
, value
);
3070 i3
= g_variant_iter_copy (&iter
);
3071 while (g_variant_iter_loop (&iter
, "@as", &sub
))
3073 gchar
*str
= g_variant_print (sub
, TRUE
);
3074 g_assert_cmpstr (str
, ==,
3075 "['i', 'ii', 'iii', 'iv', 'v', 'vi']");
3079 if (do_failed_test ("*NULL has already been returned*"))
3081 g_variant_iter_next_value (&iter
);
3086 while (g_variant_iter_loop (i3
, "*", &sub
))
3088 gchar
*str
= g_variant_print (sub
, TRUE
);
3089 g_assert_cmpstr (str
, ==,
3090 "['i', 'ii', 'iii', 'iv', 'v', 'vi']");
3094 g_variant_iter_free (i3
);
3096 for (i
= 0; i
< g_variant_n_children (value
); i
++)
3100 g_variant_get_child (value
, i
, "*", &sub
);
3102 for (j
= 0; j
< g_variant_n_children (sub
); j
++)
3104 const gchar
*str
= NULL
;
3107 g_variant_get_child (sub
, j
, "&s", &str
);
3108 g_assert_cmpstr (str
, ==, strvector
[j
]);
3110 cval
= g_variant_get_child_value (sub
, j
);
3111 g_variant_get (cval
, "&s", &str
);
3112 g_assert_cmpstr (str
, ==, strvector
[j
]);
3113 g_variant_unref (cval
);
3116 g_variant_unref (sub
);
3119 g_variant_unref (value
);
3138 /* test all 'nothing' */
3139 value
= g_variant_new ("(mymbmnmqmimumxmtmhmdmv)",
3142 FALSE
, (gint16
) 123,
3143 FALSE
, (guint16
) 123,
3144 FALSE
, (gint32
) 123,
3145 FALSE
, (guint32
) 123,
3146 FALSE
, (gint64
) 123,
3147 FALSE
, (guint64
) 123,
3149 FALSE
, (gdouble
) 37.5,
3153 g_variant_get (value
, "(mymbmnmqmimumxmtmhmdmv)",
3167 memset (justs
, 1, sizeof justs
);
3168 g_variant_get (value
, "(mymbmnmqmimumxmtmhmdmv)",
3180 g_assert (!(justs
[0] || justs
[1] || justs
[2] || justs
[3] || justs
[4] ||
3181 justs
[5] || justs
[6] || justs
[7] || justs
[8] || justs
[9]));
3184 memset (justs
, 1, sizeof justs
);
3185 byteval
= i16val
= u16val
= i32val
= u32val
= i64val
= u64val
= hval
= 88;
3189 g_variant_get (value
, "(mymbmnmqmimumxmtmhmdmv)",
3190 &justs
[0], &byteval
,
3201 g_assert (!(justs
[0] || justs
[1] || justs
[2] || justs
[3] || justs
[4] ||
3202 justs
[5] || justs
[6] || justs
[7] || justs
[8] || justs
[9]));
3203 g_assert (byteval
== '\0' && bval
== FALSE
);
3204 g_assert (i16val
== 0 && u16val
== 0 && i32val
== 0 &&
3205 u32val
== 0 && i64val
== 0 && u64val
== 0 &&
3206 hval
== 0 && dval
== 0.0);
3207 g_assert (vval
== NULL
);
3210 byteval
= i16val
= u16val
= i32val
= u32val
= i64val
= u64val
= hval
= 88;
3214 g_variant_get (value
, "(mymbmnmqmimumxmtmhmdmv)",
3226 g_assert (byteval
== '\0' && bval
== FALSE
);
3227 g_assert (i16val
== 0 && u16val
== 0 && i32val
== 0 &&
3228 u32val
== 0 && i64val
== 0 && u64val
== 0 &&
3229 hval
== 0 && dval
== 0.0);
3230 g_assert (vval
== NULL
);
3232 g_variant_unref (value
);
3235 /* test all 'just' */
3236 value
= g_variant_new ("(mymbmnmqmimumxmtmhmdmv)",
3240 TRUE
, (guint16
) 123,
3242 TRUE
, (guint32
) 123,
3244 TRUE
, (guint64
) 123,
3246 TRUE
, (gdouble
) 37.5,
3247 g_variant_new ("()"));
3250 g_variant_get (value
, "(mymbmnmqmimumxmtmhmdmv)",
3264 memset (justs
, 0, sizeof justs
);
3265 g_variant_get (value
, "(mymbmnmqmimumxmtmhmdmv)",
3277 g_assert (justs
[0] && justs
[1] && justs
[2] && justs
[3] && justs
[4] &&
3278 justs
[5] && justs
[6] && justs
[7] && justs
[8] && justs
[9]);
3281 memset (justs
, 0, sizeof justs
);
3282 byteval
= i16val
= u16val
= i32val
= u32val
= i64val
= u64val
= hval
= 88;
3286 g_variant_get (value
, "(mymbmnmqmimumxmtmhmdmv)",
3287 &justs
[0], &byteval
,
3298 g_assert (justs
[0] && justs
[1] && justs
[2] && justs
[3] && justs
[4] &&
3299 justs
[5] && justs
[6] && justs
[7] && justs
[8] && justs
[9]);
3300 g_assert (byteval
== 'a' && bval
== TRUE
);
3301 g_assert (i16val
== 123 && u16val
== 123 && i32val
== 123 &&
3302 u32val
== 123 && i64val
== 123 && u64val
== 123 &&
3303 hval
== -1 && dval
== 37.5);
3304 g_assert (g_variant_is_of_type (vval
, G_VARIANT_TYPE_UNIT
));
3305 g_variant_unref (vval
);
3308 byteval
= i16val
= u16val
= i32val
= u32val
= i64val
= u64val
= hval
= 88;
3312 g_variant_get (value
, "(mymbmnmqmimumxmtmhmdmv)",
3324 g_assert (byteval
== 'a' && bval
== TRUE
);
3325 g_assert (i16val
== 123 && u16val
== 123 && i32val
== 123 &&
3326 u32val
== 123 && i64val
== 123 && u64val
== 123 &&
3327 hval
== -1 && dval
== 37.5);
3328 g_assert (g_variant_is_of_type (vval
, G_VARIANT_TYPE_UNIT
));
3329 g_variant_unref (vval
);
3331 g_variant_unref (value
);
3334 g_variant_type_info_assert_no_infos ();
3338 hash_get (GVariant
*value
,
3339 const gchar
*format
,
3342 const gchar
*endptr
= NULL
;
3346 hash
= g_str_has_suffix (format
, "#");
3348 va_start (ap
, format
);
3349 g_variant_get_va (value
, format
, hash
? &endptr
: NULL
, &ap
);
3353 g_assert (*endptr
== '#');
3357 hash_new (const gchar
*format
,
3360 const gchar
*endptr
= NULL
;
3365 hash
= g_str_has_suffix (format
, "#");
3367 va_start (ap
, format
);
3368 value
= g_variant_new_va (format
, hash
? &endptr
: NULL
, &ap
);
3372 g_assert (*endptr
== '#');
3384 value
= hash_new ("i", 234);
3385 hash_get (value
, "i", &x
);
3386 g_assert (x
== 234);
3387 g_variant_unref (value
);
3390 value
= hash_new ("i#", 234);
3391 hash_get (value
, "i#", &x
);
3392 g_assert (x
== 234);
3393 g_variant_unref (value
);
3395 g_variant_type_info_assert_no_infos ();
3399 test_builder_memory (void)
3401 GVariantBuilder
*hb
;
3404 hb
= g_variant_builder_new (G_VARIANT_TYPE_ARRAY
);
3405 g_variant_builder_open (hb
, G_VARIANT_TYPE_ARRAY
);
3406 g_variant_builder_open (hb
, G_VARIANT_TYPE_ARRAY
);
3407 g_variant_builder_open (hb
, G_VARIANT_TYPE_ARRAY
);
3408 g_variant_builder_add (hb
, "s", "some value");
3409 g_variant_builder_ref (hb
);
3410 g_variant_builder_unref (hb
);
3411 g_variant_builder_unref (hb
);
3413 hb
= g_variant_builder_new (G_VARIANT_TYPE_ARRAY
);
3414 g_variant_builder_unref (hb
);
3416 hb
= g_variant_builder_new (G_VARIANT_TYPE_ARRAY
);
3417 g_variant_builder_clear (hb
);
3418 g_variant_builder_unref (hb
);
3420 g_variant_builder_init (&sb
, G_VARIANT_TYPE_ARRAY
);
3421 g_variant_builder_open (&sb
, G_VARIANT_TYPE_ARRAY
);
3422 g_variant_builder_open (&sb
, G_VARIANT_TYPE_ARRAY
);
3423 g_variant_builder_add (&sb
, "s", "some value");
3424 g_variant_builder_clear (&sb
);
3426 g_variant_type_info_assert_no_infos ();
3432 GVariant
*items
[4096];
3436 table
= g_hash_table_new_full (g_variant_hash
, g_variant_equal
,
3437 (GDestroyNotify
) g_variant_unref
,
3440 for (i
= 0; i
< G_N_ELEMENTS (items
); i
++)
3446 tree
= tree_instance_new (NULL
, 0);
3447 items
[i
] = tree_instance_get_gvariant (tree
);
3448 tree_instance_free (tree
);
3450 for (j
= 0; j
< i
; j
++)
3451 if (g_variant_equal (items
[i
], items
[j
]))
3453 g_variant_unref (items
[i
]);
3457 g_hash_table_insert (table
,
3458 g_variant_ref_sink (items
[i
]),
3459 GINT_TO_POINTER (i
));
3462 for (i
= 0; i
< G_N_ELEMENTS (items
); i
++)
3466 result
= g_hash_table_lookup (table
, items
[i
]);
3467 g_assert_cmpint (GPOINTER_TO_INT (result
), ==, i
);
3470 g_hash_table_unref (table
);
3472 g_variant_type_info_assert_no_infos ();
3478 #if G_BYTE_ORDER == G_LITTLE_ENDIAN
3479 # define native16(x) x, 0
3480 # define swapped16(x) 0, x
3482 # define native16(x) 0, x
3483 # define swapped16(x) x, 0
3485 /* all kinds of of crazy randomised testing already performed on the
3486 * byteswapper in the /gvariant/serialiser/byteswap test and all kinds
3487 * of crazy randomised testing performed against the serialiser
3488 * normalisation functions in the /gvariant/serialiser/fuzz/ tests.
3490 * just test a few simple cases here to make sure they each work
3492 guchar valid_data
[] = { 'a', '\0', swapped16(66), 2,
3494 'b', '\0', swapped16(77), 2,
3496 guchar corrupt_data
[] = { 'a', '\0', swapped16(66), 2,
3498 'b', '\0', swapped16(77), 2,
3500 GVariant
*value
, *swapped
;
3501 gchar
*string
, *string2
;
3505 value
= g_variant_new_from_data (G_VARIANT_TYPE ("a(sn)"),
3506 valid_data
, sizeof valid_data
, TRUE
,
3508 swapped
= g_variant_byteswap (value
);
3509 g_variant_unref (value
);
3510 g_assert (g_variant_get_size (swapped
) == 13);
3511 string
= g_variant_print (swapped
, FALSE
);
3512 g_variant_unref (swapped
);
3513 g_assert_cmpstr (string
, ==, "[('a', 66), ('b', 77)]");
3516 /* untrusted but valid */
3517 value
= g_variant_new_from_data (G_VARIANT_TYPE ("a(sn)"),
3518 valid_data
, sizeof valid_data
, FALSE
,
3520 swapped
= g_variant_byteswap (value
);
3521 g_variant_unref (value
);
3522 g_assert (g_variant_get_size (swapped
) == 13);
3523 string
= g_variant_print (swapped
, FALSE
);
3524 g_variant_unref (swapped
);
3525 g_assert_cmpstr (string
, ==, "[('a', 66), ('b', 77)]");
3528 /* untrusted, invalid */
3529 value
= g_variant_new_from_data (G_VARIANT_TYPE ("a(sn)"),
3530 corrupt_data
, sizeof corrupt_data
, FALSE
,
3532 string
= g_variant_print (value
, FALSE
);
3533 swapped
= g_variant_byteswap (value
);
3534 g_variant_unref (value
);
3535 g_assert (g_variant_get_size (swapped
) == 13);
3536 value
= g_variant_byteswap (swapped
);
3537 g_variant_unref (swapped
);
3538 string2
= g_variant_print (value
, FALSE
);
3539 g_assert (g_variant_get_size (value
) == 13);
3540 g_variant_unref (value
);
3541 g_assert_cmpstr (string
, ==, string2
);
3555 tree
= tree_instance_new (NULL
, 3);
3556 value
= tree_instance_get_gvariant (tree
);
3557 tree_instance_free (tree
);
3559 pt
= g_variant_print (value
, TRUE
);
3560 p
= g_variant_print (value
, FALSE
);
3562 parsed
= g_variant_parse (NULL
, pt
, NULL
, NULL
, NULL
);
3563 res
= g_variant_print (parsed
, FALSE
);
3564 g_assert_cmpstr (p
, ==, res
);
3565 g_variant_unref (parsed
);
3568 parsed
= g_variant_parse (g_variant_get_type (value
), p
,
3570 res
= g_variant_print (parsed
, TRUE
);
3571 g_assert_cmpstr (pt
, ==, res
);
3572 g_variant_unref (parsed
);
3575 g_variant_unref (value
);
3585 for (i
= 0; i
< 100; i
++)
3592 GError
*error
= NULL
;
3597 for (i
= 0; i
< 127; i
++)
3601 val
= g_variant_new_string (str
);
3602 p
= g_variant_print (val
, FALSE
);
3603 g_variant_unref (val
);
3605 val
= g_variant_parse (NULL
, p
, NULL
, NULL
, &error
);
3606 p2
= g_variant_print (val
, FALSE
);
3608 g_assert_cmpstr (str
, ==, g_variant_get_string (val
, NULL
));
3609 g_assert_cmpstr (p
, ==, p2
);
3611 g_variant_unref (val
);
3616 /* another mini test */
3621 value
= g_variant_parse (G_VARIANT_TYPE_INT32
, "1 2 3", NULL
, &end
, NULL
);
3622 g_assert_cmpint (g_variant_get_int32 (value
), ==, 1);
3623 /* make sure endptr returning works */
3624 g_assert_cmpstr (end
, ==, " 2 3");
3625 g_variant_unref (value
);
3628 /* unicode mini test */
3631 const gchar orig
[] = "a\xc5\x82\xf0\x9d\x84\x9e \t\n";
3635 value
= g_variant_new_string (orig
);
3636 printed
= g_variant_print (value
, FALSE
);
3637 g_variant_unref (value
);
3639 g_assert_cmpstr (printed
, ==, "'a\xc5\x82\xf0\x9d\x84\x9e \\t\\n'");
3640 value
= g_variant_parse (NULL
, printed
, NULL
, NULL
, NULL
);
3641 g_assert_cmpstr (g_variant_get_string (value
, NULL
), ==, orig
);
3642 g_variant_unref (value
);
3646 g_variant_type_info_assert_no_infos ();
3650 test_parse_failures (void)
3652 const gchar
*test
[] = {
3653 "[1, 2,", "6:", "expected value",
3654 "", "0:", "expected value",
3655 "(1, 2,", "6:", "expected value",
3656 "<1", "2:", "expected `>'",
3657 "[]", "0-2:", "unable to infer",
3658 "(,", "1:", "expected value",
3659 "[4,'']", "1-2,3-5:", "common type",
3660 "[4, '', 5]", "1-2,4-6:", "common type",
3661 "['', 4, 5]", "1-3,5-6:", "common type",
3662 "[4, 5, '']", "1-2,7-9:", "common type",
3663 "[[4], [], ['']]", "1-4,10-14:", "common type",
3664 "[[], [4], ['']]", "5-8,10-14:", "common type",
3665 "just", "4:", "expected value",
3666 "nothing", "0-7:", "unable to infer",
3667 "just [4, '']", "6-7,9-11:", "common type",
3668 "[[4,'']]", "2-3,4-6:", "common type",
3669 "([4,''],)", "2-3,4-6:", "common type",
3671 "{}", "0-2:", "unable to infer",
3672 "{[1,2],[3,4]}", "0-13:", "basic types",
3673 "{[1,2]:[3,4]}", "0-13:", "basic types",
3674 "justt", "0-5:", "unknown keyword",
3675 "nothng", "0-6:", "unknown keyword",
3676 "uint33", "0-6:", "unknown keyword",
3677 "@mi just ''", "9-11:", "can not parse as",
3678 "@ai ['']", "5-7:", "can not parse as",
3679 "@(i) ('',)", "6-8:", "can not parse as",
3680 "[[], 5]", "1-3,5-6:", "common type",
3681 "[[5], 5]", "1-4,6-7:", "common type",
3682 "5 5", "2:", "expected end of input",
3683 "[5, [5, '']]", "5-6,8-10:", "common type",
3684 "@i just 5", "3-9:", "can not parse as",
3685 "@i nothing", "3-10:", "can not parse as",
3686 "@i []", "3-5:", "can not parse as",
3687 "@i ()", "3-5:", "can not parse as",
3688 "@ai (4,)", "4-8:", "can not parse as",
3689 "@(i) []", "5-7:", "can not parse as",
3690 "(5 5)", "3:", "expected `,'",
3691 "[5 5]", "3:", "expected `,' or `]'",
3692 "(5, 5 5)", "6:", "expected `,' or `)'",
3693 "[5, 5 5]", "6:", "expected `,' or `]'",
3694 "<@i []>", "4-6:", "can not parse as",
3695 "<[5 5]>", "4:", "expected `,' or `]'",
3696 "{[4,''],5}", "2-3,4-6:", "common type",
3697 "{5,[4,'']}", "4-5,6-8:", "common type",
3698 "@i {1,2}", "3-8:", "can not parse as",
3699 "{@i '', 5}", "4-6:", "can not parse as",
3700 "{5, @i ''}", "7-9:", "can not parse as",
3701 "@ai {}", "4-6:", "can not parse as",
3702 "{@i '': 5}", "4-6:", "can not parse as",
3703 "{5: @i ''}", "7-9:", "can not parse as",
3704 "{<4,5}", "3:", "expected `>'",
3705 "{4,<5}", "5:", "expected `>'",
3706 "{4,5,6}", "4:", "expected `}'",
3707 "{5 5}", "3:", "expected `:' or `,'",
3708 "{4: 5: 6}", "5:", "expected `,' or `}'",
3709 "{4:5,<6:7}", "7:", "expected `>'",
3710 "{4:5,6:<7}", "9:", "expected `>'",
3711 "{4:5,6 7}", "7:", "expected `:'",
3712 "@o 'foo'", "3-8:", "object path",
3713 "@g 'zzz'", "3-8:", "signature",
3714 "@i true", "3-7:", "can not parse as",
3715 "@z 4", "0-2:", "invalid type",
3716 "@a* []", "0-3:", "definite",
3717 "@ai [3 3]", "7:", "expected `,' or `]'",
3718 "18446744073709551616", "0-20:", "too big for any type",
3719 "-18446744073709551616", "0-21:", "too big for any type",
3720 "byte 256", "5-8:", "out of range for type",
3721 "byte -1", "5-7:", "out of range for type",
3722 "int16 32768", "6-11:", "out of range for type",
3723 "int16 -32769", "6-12:", "out of range for type",
3724 "uint16 -1", "7-9:", "out of range for type",
3725 "uint16 65536", "7-12:", "out of range for type",
3726 "2147483648", "0-10:", "out of range for type",
3727 "-2147483649", "0-11:", "out of range for type",
3728 "uint32 -1", "7-9:", "out of range for type",
3729 "uint32 4294967296", "7-17:", "out of range for type",
3730 "@x 9223372036854775808", "3-22:", "out of range for type",
3731 "@x -9223372036854775809", "3-23:", "out of range for type",
3732 "@t -1", "3-5:", "out of range for type",
3733 "@t 18446744073709551616", "3-23:", "too big for any type",
3734 "handle 2147483648", "7-17:", "out of range for type",
3735 "handle -2147483649", "7-18:", "out of range for type",
3736 "1.798e308", "0-9:", "too big for any type",
3737 "37.5a488", "4-5:", "invalid character",
3738 "0x7ffgf", "5-6:", "invalid character",
3739 "07758", "4-5:", "invalid character",
3740 "123a5", "3-4:", "invalid character",
3741 "@ai 123", "4-7:", "can not parse as",
3742 "'\"\\'", "0-4:", "unterminated string",
3743 "'\"\\'\\", "0-5:", "unterminated string",
3744 "boolean 4", "8-9:", "can not parse as",
3745 "int32 true", "6-10:", "can not parse as",
3746 "[double 5, int32 5]", "1-9,11-18:", "common type",
3747 "string 4", "7-8:", "can not parse as"
3751 for (i
= 0; i
< G_N_ELEMENTS (test
); i
+= 3)
3753 GError
*error
= NULL
;
3756 value
= g_variant_parse (NULL
, test
[i
], NULL
, NULL
, &error
);
3757 g_assert (value
== NULL
);
3759 if (!strstr (error
->message
, test
[i
+2]))
3760 g_error ("test %d: Can't find `%s' in `%s'", i
/ 3,
3761 test
[i
+2], error
->message
);
3763 if (!g_str_has_prefix (error
->message
, test
[i
+1]))
3764 g_error ("test %d: Expected location `%s' in `%s'", i
/ 3,
3765 test
[i
+1], error
->message
);
3767 g_error_free (error
);
3772 test_parse_positional (void)
3775 check_and_free (g_variant_new_parsed ("[('one', 1), (%s, 2),"
3776 " ('three', %i)]", "two", 3),
3777 "[('one', 1), ('two', 2), ('three', 3)]");
3778 value
= g_variant_new_parsed ("[('one', 1), (%s, 2),"
3779 " ('three', %u)]", "two", 3);
3780 g_assert (g_variant_is_of_type (value
, G_VARIANT_TYPE ("a(su)")));
3781 check_and_free (value
, "[('one', 1), ('two', 2), ('three', 3)]");
3782 check_and_free (g_variant_new_parsed ("{%s:%i}", "one", 1), "{'one': 1}");
3784 if (do_failed_test ("*GVariant format string*"))
3786 g_variant_new_parsed ("%z");
3790 if (do_failed_test ("*can not parse as*"))
3792 g_variant_new_parsed ("uint32 %i", 2);
3796 if (do_failed_test ("*expected GVariant of type `i'*"))
3798 g_variant_new_parsed ("%@i", g_variant_new_uint32 (2));
3804 test_floating (void)
3808 value
= g_variant_new_int32 (42);
3809 g_assert (g_variant_is_floating (value
));
3810 g_variant_ref_sink (value
);
3811 g_assert (!g_variant_is_floating (value
));
3812 g_variant_unref (value
);
3816 test_bytestring (void)
3818 const gchar
*test_string
= "foo,bar,baz,quux,\xffoooo";
3823 strv
= g_strsplit (test_string
, ",", 0);
3825 value
= g_variant_new_bytestring_array ((const gchar
**) strv
, -1);
3826 g_assert (g_variant_is_floating (value
));
3829 str
= g_variant_print (value
, FALSE
);
3830 g_variant_unref (value
);
3832 value
= g_variant_parse (NULL
, str
, NULL
, NULL
, NULL
);
3835 strv
= g_variant_dup_bytestring_array (value
, NULL
);
3836 g_variant_unref (value
);
3838 str
= g_strjoinv (",", strv
);
3841 g_assert_cmpstr (str
, ==, test_string
);
3844 strv
= g_strsplit (test_string
, ",", 0);
3845 value
= g_variant_new ("(^aay^a&ay^ay^&ay)",
3846 strv
, strv
, strv
[0], strv
[0]);
3849 g_variant_get_child (value
, 0, "^a&ay", &strv
);
3850 str
= g_strjoinv (",", strv
);
3852 g_assert_cmpstr (str
, ==, test_string
);
3855 g_variant_get_child (value
, 0, "^aay", &strv
);
3856 str
= g_strjoinv (",", strv
);
3858 g_assert_cmpstr (str
, ==, test_string
);
3861 g_variant_get_child (value
, 1, "^a&ay", &strv
);
3862 str
= g_strjoinv (",", strv
);
3864 g_assert_cmpstr (str
, ==, test_string
);
3867 g_variant_get_child (value
, 1, "^aay", &strv
);
3868 str
= g_strjoinv (",", strv
);
3870 g_assert_cmpstr (str
, ==, test_string
);
3873 g_variant_get_child (value
, 2, "^ay", &str
);
3874 g_assert_cmpstr (str
, ==, "foo");
3877 g_variant_get_child (value
, 2, "^&ay", &str
);
3878 g_assert_cmpstr (str
, ==, "foo");
3880 g_variant_get_child (value
, 3, "^ay", &str
);
3881 g_assert_cmpstr (str
, ==, "foo");
3884 g_variant_get_child (value
, 3, "^&ay", &str
);
3885 g_assert_cmpstr (str
, ==, "foo");
3886 g_variant_unref (value
);
3890 main (int argc
, char **argv
)
3894 g_test_init (&argc
, &argv
, NULL
);
3896 g_test_add_func ("/gvariant/type", test_gvarianttype
);
3897 g_test_add_func ("/gvariant/typeinfo", test_gvarianttypeinfo
);
3898 g_test_add_func ("/gvariant/serialiser/maybe", test_maybes
);
3899 g_test_add_func ("/gvariant/serialiser/array", test_arrays
);
3900 g_test_add_func ("/gvariant/serialiser/tuple", test_tuples
);
3901 g_test_add_func ("/gvariant/serialiser/variant", test_variants
);
3902 g_test_add_func ("/gvariant/serialiser/strings", test_strings
);
3903 g_test_add_func ("/gvariant/serialiser/byteswap", test_byteswaps
);
3905 for (i
= 1; i
<= 20; i
+= 4)
3909 testname
= g_strdup_printf ("/gvariant/serialiser/fuzz/%d%%", i
);
3910 g_test_add_data_func (testname
, GINT_TO_POINTER (i
),
3911 (gpointer
) test_fuzzes
);
3915 g_test_add_func ("/gvariant/utf8", test_utf8
);
3916 g_test_add_func ("/gvariant/containers", test_containers
);
3917 g_test_add_func ("/gvariant/format-strings", test_format_strings
);
3918 g_test_add_func ("/gvariant/invalid-varargs", test_invalid_varargs
);
3919 g_test_add_func ("/gvariant/varargs", test_varargs
);
3920 g_test_add_func ("/gvariant/valist", test_valist
);
3921 g_test_add_func ("/gvariant/builder-memory", test_builder_memory
);
3922 g_test_add_func ("/gvariant/hashing", test_hashing
);
3923 g_test_add_func ("/gvariant/byteswap", test_gv_byteswap
);
3924 g_test_add_func ("/gvariant/parser", test_parses
);
3925 g_test_add_func ("/gvariant/parse-failures", test_parse_failures
);
3926 g_test_add_func ("/gvariant/parse-positional", test_parse_positional
);
3927 g_test_add_func ("/gvariant/floating", test_floating
);
3928 g_test_add_func ("/gvariant/bytestring", test_bytestring
);
3930 return g_test_run ();