Skip to content
This repository has been archived by the owner on Nov 17, 2020. It is now read-only.

Commit

Permalink
GVariant: support NULL for empty arrays in varargs
Browse files Browse the repository at this point in the history
g_variant_new("as", NULL); now gives an empty array of strings, for
example.

This was documented as working already, but was never actually
implemented (due to the fact that it muddies the water when considering
maybe types).  It's being implemented now because its convenience to
programmers exceeds any damage done to the conceptual purity of the API.
  • Loading branch information
allisonkarlitskaya committed Feb 11, 2011
1 parent d25dca2 commit b1d02f9
Show file tree
Hide file tree
Showing 3 changed files with 55 additions and 18 deletions.
5 changes: 5 additions & 0 deletions docs/reference/glib/gvariant-varargs.xml
Expand Up @@ -681,6 +681,11 @@ g_variant_unref (value);]]></programlisting></informalexample>
prefixed with an '<literal>m</literal>', the type of arguments that are collected does not change in any way, but
<link linkend='NULL--CAPS'><literal>NULL</literal></link> becomes a permissable value, to indicate the Nothing case.
</para>
<para>
Note that the "special exception" introduced in the array section for constructing empty arrays is ignored
here. Using a <literal>NULL</literal> pointer with the format string '<literal>mas</literal>' constructs
the Nothing value -- not an empty array.
</para>
<para>
The second way is used with all other format strings. For
<link linkend='g-variant-new'><function>g_variant_new()</function></link> an additional
Expand Down
52 changes: 34 additions & 18 deletions glib/gvariant.c
Expand Up @@ -3643,30 +3643,46 @@ g_variant_valist_new_nnp (const gchar **str,
switch (*(*str)++)
{
case 'a':
{
const GVariantType *type;
GVariant *value;
if (ptr != NULL)
{
const GVariantType *type;
GVariant *value;

value = g_variant_builder_end (ptr);
type = g_variant_get_type (value);
value = g_variant_builder_end (ptr);
type = g_variant_get_type (value);

if G_UNLIKELY (!g_variant_type_is_array (type))
g_error ("g_variant_new: expected array GVariantBuilder but "
"the built value has type `%s'",
g_variant_get_type_string (value));
if G_UNLIKELY (!g_variant_type_is_array (type))
g_error ("g_variant_new: expected array GVariantBuilder but "
"the built value has type `%s'",
g_variant_get_type_string (value));

type = g_variant_type_element (type);
type = g_variant_type_element (type);

if G_UNLIKELY (!g_variant_type_is_subtype_of (type, (GVariantType *) *str))
g_error ("g_variant_new: expected GVariantBuilder array element "
"type `%s' but the built value has element type `%s'",
g_variant_type_dup_string ((GVariantType *) *str),
g_variant_get_type_string (value) + 1);
if G_UNLIKELY (!g_variant_type_is_subtype_of (type, (GVariantType *) *str))
g_error ("g_variant_new: expected GVariantBuilder array element "
"type `%s' but the built value has element type `%s'",
g_variant_type_dup_string ((GVariantType *) *str),
g_variant_get_type_string (value) + 1);

g_variant_type_string_scan (*str, NULL, str);
g_variant_type_string_scan (*str, NULL, str);

return value;
}
return value;
}
else

/* special case: NULL pointer for empty array */
{
const GVariantType *type = (GVariantType *) *str;

g_variant_type_string_scan (*str, NULL, str);

if G_UNLIKELY (!g_variant_type_is_definite (type))
g_error ("g_variant_new: NULL pointer given with indefinite "
"array type; unable to determine which type of empty "
"array to construct.");

return g_variant_new_array (type, NULL, 0);
}

case 's':
return g_variant_new_string (ptr);
Expand Down
16 changes: 16 additions & 0 deletions glib/tests/gvariant.c
Expand Up @@ -3331,6 +3331,22 @@ test_varargs (void)
g_variant_unref (value);
}

{
GVariant *value;
gchar *str;

value = g_variant_new ("(masas)", NULL, NULL);
g_variant_ref_sink (value);

str = g_variant_print (value, TRUE);
g_assert_cmpstr (str, ==, "(@mas nothing, @as [])");
g_variant_unref (value);
g_free (str);

if (do_failed_test ("*which type of empty array*"))
g_variant_new ("(a{s*})", NULL);
}

g_variant_type_info_assert_no_infos ();
}

Expand Down

0 comments on commit b1d02f9

Please sign in to comment.