mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2025-01-11 23:16:14 +01:00
GVariant: better support for object path arrays
Add G_VARIANT_TYPE_OBJECT_PATH_ARRAY along with accessor functions g_variant_new_objv, g_variant_get_objv and g_variant_dup_objv. Also add support for '^ao' and '^a&o' format strings for g_variant_new() and g_variant_get(). https://bugzilla.gnome.org/show_bug.cgi?id=654955
This commit is contained in:
parent
c841c2ce3f
commit
19878998bc
@ -2940,6 +2940,7 @@ G_VARIANT_TYPE_UNIT
|
|||||||
G_VARIANT_TYPE_DICT_ENTRY
|
G_VARIANT_TYPE_DICT_ENTRY
|
||||||
G_VARIANT_TYPE_DICTIONARY
|
G_VARIANT_TYPE_DICTIONARY
|
||||||
G_VARIANT_TYPE_STRING_ARRAY
|
G_VARIANT_TYPE_STRING_ARRAY
|
||||||
|
G_VARIANT_TYPE_OBJECT_PATH_ARRAY
|
||||||
G_VARIANT_TYPE_BYTESTRING
|
G_VARIANT_TYPE_BYTESTRING
|
||||||
G_VARIANT_TYPE_BYTESTRING_ARRAY
|
G_VARIANT_TYPE_BYTESTRING_ARRAY
|
||||||
G_VARIANT_TYPE_VARDICT
|
G_VARIANT_TYPE_VARDICT
|
||||||
@ -3030,6 +3031,7 @@ g_variant_new_signature
|
|||||||
g_variant_is_signature
|
g_variant_is_signature
|
||||||
g_variant_new_variant
|
g_variant_new_variant
|
||||||
g_variant_new_strv
|
g_variant_new_strv
|
||||||
|
g_variant_new_objv
|
||||||
g_variant_new_bytestring
|
g_variant_new_bytestring
|
||||||
g_variant_new_bytestring_array
|
g_variant_new_bytestring_array
|
||||||
|
|
||||||
@ -3049,6 +3051,8 @@ g_variant_dup_string
|
|||||||
g_variant_get_variant
|
g_variant_get_variant
|
||||||
g_variant_get_strv
|
g_variant_get_strv
|
||||||
g_variant_dup_strv
|
g_variant_dup_strv
|
||||||
|
g_variant_get_objv
|
||||||
|
g_variant_dup_objv
|
||||||
g_variant_get_bytestring
|
g_variant_get_bytestring
|
||||||
g_variant_dup_bytestring
|
g_variant_dup_bytestring
|
||||||
g_variant_get_bytestring_array
|
g_variant_get_bytestring_array
|
||||||
|
@ -46,8 +46,8 @@
|
|||||||
<listitem>
|
<listitem>
|
||||||
<para>
|
<para>
|
||||||
'<literal>&s</literal>' '<literal>&o</literal>', '<literal>&g</literal>', '<literal>^as</literal>',
|
'<literal>&s</literal>' '<literal>&o</literal>', '<literal>&g</literal>', '<literal>^as</literal>',
|
||||||
'<literal>^a&s</literal>', '<literal>^ay</literal>', '<literal>^&ay</literal>', '<literal>^aay</literal>'
|
'<literal>^a&s</literal>', '<literal>^ao</literal>', '<literal>^a&o</literal>','<literal>^ay</literal>',
|
||||||
or '<literal>^a&ay</literal>'.
|
'<literal>^&ay</literal>', '<literal>^aay</literal>' or '<literal>^a&ay</literal>'.
|
||||||
</para>
|
</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
<listitem>
|
<listitem>
|
||||||
@ -1018,6 +1018,41 @@ value2 = g_variant_new ("(@(iii)*)", value1, g_variant_new_string ("foo"));
|
|||||||
</entry>
|
</entry>
|
||||||
</row>
|
</row>
|
||||||
|
|
||||||
|
<row rowsep='1'>
|
||||||
|
<entry colsep='1' rowsep='1'>
|
||||||
|
<para>
|
||||||
|
<emphasis role='strong'>
|
||||||
|
<literal>^ao</literal>
|
||||||
|
</emphasis>
|
||||||
|
</para>
|
||||||
|
</entry>
|
||||||
|
<entry colsep='1' rowsep='1' morerows='1'>
|
||||||
|
<para>
|
||||||
|
equivalent to <link linkend='g-variant-new-objv'><function>g_variant_new_objv()</function></link>
|
||||||
|
</para>
|
||||||
|
</entry>
|
||||||
|
<entry colsep='1' rowsep='1'>
|
||||||
|
<para>
|
||||||
|
equivalent to <link linkend='g-variant-dup-objv'><function>g_variant_dup_objv()</function></link>
|
||||||
|
</para>
|
||||||
|
</entry>
|
||||||
|
</row>
|
||||||
|
|
||||||
|
<row rowsep='1'>
|
||||||
|
<entry colsep='1' rowsep='1'>
|
||||||
|
<para>
|
||||||
|
<emphasis role='strong'>
|
||||||
|
<literal>^a&o</literal>
|
||||||
|
</emphasis>
|
||||||
|
</para>
|
||||||
|
</entry>
|
||||||
|
<entry colsep='1' rowsep='1'>
|
||||||
|
<para>
|
||||||
|
equivalent to <link linkend='g-variant-get-objv'><function>g_variant_get_objv()</function></link>
|
||||||
|
</para>
|
||||||
|
</entry>
|
||||||
|
</row>
|
||||||
|
|
||||||
<row rowsep='1'>
|
<row rowsep='1'>
|
||||||
<entry colsep='1' rowsep='1'>
|
<entry colsep='1' rowsep='1'>
|
||||||
<para>
|
<para>
|
||||||
|
@ -1447,6 +1447,7 @@ g_variant_new_signature
|
|||||||
g_variant_is_signature
|
g_variant_is_signature
|
||||||
g_variant_new_variant
|
g_variant_new_variant
|
||||||
g_variant_new_strv
|
g_variant_new_strv
|
||||||
|
g_variant_new_objv
|
||||||
g_variant_new_bytestring
|
g_variant_new_bytestring
|
||||||
g_variant_new_bytestring_array
|
g_variant_new_bytestring_array
|
||||||
g_variant_get_boolean
|
g_variant_get_boolean
|
||||||
@ -1464,6 +1465,8 @@ g_variant_dup_string
|
|||||||
g_variant_get_variant
|
g_variant_get_variant
|
||||||
g_variant_get_strv
|
g_variant_get_strv
|
||||||
g_variant_dup_strv
|
g_variant_dup_strv
|
||||||
|
g_variant_get_objv
|
||||||
|
g_variant_dup_objv
|
||||||
g_variant_get_bytestring
|
g_variant_get_bytestring
|
||||||
g_variant_dup_bytestring
|
g_variant_dup_bytestring
|
||||||
g_variant_get_bytestring_array
|
g_variant_get_bytestring_array
|
||||||
|
168
glib/gvariant.c
168
glib/gvariant.c
@ -1452,6 +1452,141 @@ g_variant_dup_strv (GVariant *value,
|
|||||||
return strv;
|
return strv;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* g_variant_new_objv:
|
||||||
|
* @strv: (array length=length) (element-type utf8): an array of strings
|
||||||
|
* @length: the length of @strv, or -1
|
||||||
|
* @returns: (transfer none): a new floating #GVariant instance
|
||||||
|
*
|
||||||
|
* Constructs an array of object paths #GVariant from the given array of
|
||||||
|
* strings.
|
||||||
|
*
|
||||||
|
* Each string must be a valid #GVariant object path; see
|
||||||
|
* g_variant_is_object_path().
|
||||||
|
*
|
||||||
|
* If @length is -1 then @strv is %NULL-terminated.
|
||||||
|
*
|
||||||
|
* Since: 2.30
|
||||||
|
**/
|
||||||
|
GVariant *
|
||||||
|
g_variant_new_objv (const gchar * const *strv,
|
||||||
|
gssize length)
|
||||||
|
{
|
||||||
|
GVariant **strings;
|
||||||
|
gsize i;
|
||||||
|
|
||||||
|
g_return_val_if_fail (length == 0 || strv != NULL, NULL);
|
||||||
|
|
||||||
|
if (length < 0)
|
||||||
|
length = g_strv_length ((gchar **) strv);
|
||||||
|
|
||||||
|
strings = g_new (GVariant *, length);
|
||||||
|
for (i = 0; i < length; i++)
|
||||||
|
strings[i] = g_variant_ref_sink (g_variant_new_object_path (strv[i]));
|
||||||
|
|
||||||
|
return g_variant_new_from_children (G_VARIANT_TYPE_OBJECT_PATH_ARRAY,
|
||||||
|
strings, length, TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* g_variant_get_objv:
|
||||||
|
* @value: an array of object paths #GVariant
|
||||||
|
* @length: (out) (allow-none): the length of the result, or %NULL
|
||||||
|
* @returns: (array length=length zero-terminated=1) (transfer container): an array of constant
|
||||||
|
* strings
|
||||||
|
*
|
||||||
|
* Gets the contents of an array of object paths #GVariant. This call
|
||||||
|
* makes a shallow copy; the return result should be released with
|
||||||
|
* g_free(), but the individual strings must not be modified.
|
||||||
|
*
|
||||||
|
* If @length is non-%NULL then the number of elements in the result
|
||||||
|
* is stored there. In any case, the resulting array will be
|
||||||
|
* %NULL-terminated.
|
||||||
|
*
|
||||||
|
* For an empty array, @length will be set to 0 and a pointer to a
|
||||||
|
* %NULL pointer will be returned.
|
||||||
|
*
|
||||||
|
* Since: 2.30
|
||||||
|
**/
|
||||||
|
const gchar **
|
||||||
|
g_variant_get_objv (GVariant *value,
|
||||||
|
gsize *length)
|
||||||
|
{
|
||||||
|
const gchar **strv;
|
||||||
|
gsize n;
|
||||||
|
gsize i;
|
||||||
|
|
||||||
|
TYPE_CHECK (value, G_VARIANT_TYPE_OBJECT_PATH_ARRAY, NULL);
|
||||||
|
|
||||||
|
g_variant_get_data (value);
|
||||||
|
n = g_variant_n_children (value);
|
||||||
|
strv = g_new (const gchar *, n + 1);
|
||||||
|
|
||||||
|
for (i = 0; i < n; i++)
|
||||||
|
{
|
||||||
|
GVariant *string;
|
||||||
|
|
||||||
|
string = g_variant_get_child_value (value, i);
|
||||||
|
strv[i] = g_variant_get_string (string, NULL);
|
||||||
|
g_variant_unref (string);
|
||||||
|
}
|
||||||
|
strv[i] = NULL;
|
||||||
|
|
||||||
|
if (length)
|
||||||
|
*length = n;
|
||||||
|
|
||||||
|
return strv;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* g_variant_dup_objv:
|
||||||
|
* @value: an array of object paths #GVariant
|
||||||
|
* @length: (out) (allow-none): the length of the result, or %NULL
|
||||||
|
* @returns: (array length=length zero-terminated=1) (transfer full): an array of strings
|
||||||
|
*
|
||||||
|
* Gets the contents of an array of object paths #GVariant. This call
|
||||||
|
* makes a deep copy; the return result should be released with
|
||||||
|
* g_strfreev().
|
||||||
|
*
|
||||||
|
* If @length is non-%NULL then the number of elements in the result
|
||||||
|
* is stored there. In any case, the resulting array will be
|
||||||
|
* %NULL-terminated.
|
||||||
|
*
|
||||||
|
* For an empty array, @length will be set to 0 and a pointer to a
|
||||||
|
* %NULL pointer will be returned.
|
||||||
|
*
|
||||||
|
* Since: 2.30
|
||||||
|
**/
|
||||||
|
gchar **
|
||||||
|
g_variant_dup_objv (GVariant *value,
|
||||||
|
gsize *length)
|
||||||
|
{
|
||||||
|
gchar **strv;
|
||||||
|
gsize n;
|
||||||
|
gsize i;
|
||||||
|
|
||||||
|
TYPE_CHECK (value, G_VARIANT_TYPE_OBJECT_PATH_ARRAY, NULL);
|
||||||
|
|
||||||
|
n = g_variant_n_children (value);
|
||||||
|
strv = g_new (gchar *, n + 1);
|
||||||
|
|
||||||
|
for (i = 0; i < n; i++)
|
||||||
|
{
|
||||||
|
GVariant *string;
|
||||||
|
|
||||||
|
string = g_variant_get_child_value (value, i);
|
||||||
|
strv[i] = g_variant_dup_string (string, NULL);
|
||||||
|
g_variant_unref (string);
|
||||||
|
}
|
||||||
|
strv[i] = NULL;
|
||||||
|
|
||||||
|
if (length)
|
||||||
|
*length = n;
|
||||||
|
|
||||||
|
return strv;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* g_variant_new_bytestring:
|
* g_variant_new_bytestring:
|
||||||
* @string: (array zero-terminated=1): a normal nul-terminated string in no particular encoding
|
* @string: (array zero-terminated=1): a normal nul-terminated string in no particular encoding
|
||||||
@ -3373,8 +3508,8 @@ g_variant_format_string_scan (const gchar *string,
|
|||||||
break; /* '^a&ay' */
|
break; /* '^a&ay' */
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (c == 's')
|
else if (c == 's' || c == 'o')
|
||||||
break; /* '^a&s' */
|
break; /* '^a&s', '^a&o' */
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (c == 'a')
|
else if (c == 'a')
|
||||||
@ -3383,8 +3518,8 @@ g_variant_format_string_scan (const gchar *string,
|
|||||||
break; /* '^aay' */
|
break; /* '^aay' */
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (c == 's')
|
else if (c == 's' || c == 'o')
|
||||||
break; /* '^as' */
|
break; /* '^as', '^ao' */
|
||||||
|
|
||||||
else if (c == 'y')
|
else if (c == 'y')
|
||||||
break; /* '^ay' */
|
break; /* '^ay' */
|
||||||
@ -3586,9 +3721,9 @@ g_variant_valist_free_nnp (const gchar *str,
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case '^':
|
case '^':
|
||||||
if (str[2] != '&') /* '^as' */
|
if (str[2] != '&') /* '^as', '^ao' */
|
||||||
g_strfreev (ptr);
|
g_strfreev (ptr);
|
||||||
else /* '^a&s' */
|
else /* '^a&s', '^a&o' */
|
||||||
g_free (ptr);
|
g_free (ptr);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -3709,10 +3844,16 @@ g_variant_valist_new_nnp (const gchar **str,
|
|||||||
{
|
{
|
||||||
gboolean constant;
|
gboolean constant;
|
||||||
guint arrays;
|
guint arrays;
|
||||||
|
gchar type;
|
||||||
|
|
||||||
if (g_variant_scan_convenience (str, &constant, &arrays) == 's')
|
type = g_variant_scan_convenience (str, &constant, &arrays);
|
||||||
|
|
||||||
|
if (type == 's')
|
||||||
return g_variant_new_strv (ptr, -1);
|
return g_variant_new_strv (ptr, -1);
|
||||||
|
|
||||||
|
if (type == 'o')
|
||||||
|
return g_variant_new_objv (ptr, -1);
|
||||||
|
|
||||||
if (arrays > 1)
|
if (arrays > 1)
|
||||||
return g_variant_new_bytestring_array (ptr, -1);
|
return g_variant_new_bytestring_array (ptr, -1);
|
||||||
|
|
||||||
@ -3780,8 +3921,11 @@ g_variant_valist_get_nnp (const gchar **str,
|
|||||||
{
|
{
|
||||||
gboolean constant;
|
gboolean constant;
|
||||||
guint arrays;
|
guint arrays;
|
||||||
|
gchar type;
|
||||||
|
|
||||||
if (g_variant_scan_convenience (str, &constant, &arrays) == 's')
|
type = g_variant_scan_convenience (str, &constant, &arrays);
|
||||||
|
|
||||||
|
if (type == 's')
|
||||||
{
|
{
|
||||||
if (constant)
|
if (constant)
|
||||||
return g_variant_get_strv (value, NULL);
|
return g_variant_get_strv (value, NULL);
|
||||||
@ -3789,6 +3933,14 @@ g_variant_valist_get_nnp (const gchar **str,
|
|||||||
return g_variant_dup_strv (value, NULL);
|
return g_variant_dup_strv (value, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
else if (type == 'o')
|
||||||
|
{
|
||||||
|
if (constant)
|
||||||
|
return g_variant_get_objv (value, NULL);
|
||||||
|
else
|
||||||
|
return g_variant_dup_objv (value, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
else if (arrays > 1)
|
else if (arrays > 1)
|
||||||
{
|
{
|
||||||
if (constant)
|
if (constant)
|
||||||
|
@ -86,6 +86,8 @@ gboolean g_variant_is_signature (const g
|
|||||||
GVariant * g_variant_new_variant (GVariant *value);
|
GVariant * g_variant_new_variant (GVariant *value);
|
||||||
GVariant * g_variant_new_strv (const gchar * const *strv,
|
GVariant * g_variant_new_strv (const gchar * const *strv,
|
||||||
gssize length);
|
gssize length);
|
||||||
|
GVariant * g_variant_new_objv (const gchar * const *strv,
|
||||||
|
gssize length);
|
||||||
GVariant * g_variant_new_bytestring (const gchar *string);
|
GVariant * g_variant_new_bytestring (const gchar *string);
|
||||||
GVariant * g_variant_new_bytestring_array (const gchar * const *strv,
|
GVariant * g_variant_new_bytestring_array (const gchar * const *strv,
|
||||||
gssize length);
|
gssize length);
|
||||||
@ -109,6 +111,10 @@ const gchar ** g_variant_get_strv (GVarian
|
|||||||
gsize *length);
|
gsize *length);
|
||||||
gchar ** g_variant_dup_strv (GVariant *value,
|
gchar ** g_variant_dup_strv (GVariant *value,
|
||||||
gsize *length);
|
gsize *length);
|
||||||
|
const gchar ** g_variant_get_objv (GVariant *value,
|
||||||
|
gsize *length);
|
||||||
|
gchar ** g_variant_dup_objv (GVariant *value,
|
||||||
|
gsize *length);
|
||||||
const gchar * g_variant_get_bytestring (GVariant *value);
|
const gchar * g_variant_get_bytestring (GVariant *value);
|
||||||
gchar * g_variant_dup_bytestring (GVariant *value,
|
gchar * g_variant_dup_bytestring (GVariant *value,
|
||||||
gsize *length);
|
gsize *length);
|
||||||
|
@ -238,6 +238,13 @@ typedef struct _GVariantType GVariantType;
|
|||||||
**/
|
**/
|
||||||
#define G_VARIANT_TYPE_STRING_ARRAY ((const GVariantType *) "as")
|
#define G_VARIANT_TYPE_STRING_ARRAY ((const GVariantType *) "as")
|
||||||
|
|
||||||
|
/**
|
||||||
|
* G_VARIANT_TYPE_OBJECT_PATH_ARRAY:
|
||||||
|
*
|
||||||
|
* The type of an array of object paths.
|
||||||
|
**/
|
||||||
|
#define G_VARIANT_TYPE_OBJECT_PATH_ARRAY ((const GVariantType *) "ao")
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* G_VARIANT_TYPE_BYTESTRING:
|
* G_VARIANT_TYPE_BYTESTRING:
|
||||||
*
|
*
|
||||||
|
@ -3022,6 +3022,59 @@ test_varargs (void)
|
|||||||
g_free (strv);
|
g_free (strv);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
const gchar *strvector[] = {"/hello", "/world", NULL};
|
||||||
|
const gchar *test_strs[] = {"/foo", "/bar", "/baz" };
|
||||||
|
GVariantBuilder builder;
|
||||||
|
GVariantIter *array;
|
||||||
|
GVariantIter tuple;
|
||||||
|
const gchar **strv;
|
||||||
|
gchar **my_strv;
|
||||||
|
GVariant *value;
|
||||||
|
gchar *str;
|
||||||
|
gint i;
|
||||||
|
|
||||||
|
g_variant_builder_init (&builder, G_VARIANT_TYPE_OBJECT_PATH_ARRAY);
|
||||||
|
g_variant_builder_add (&builder, "o", "/foo");
|
||||||
|
g_variant_builder_add (&builder, "o", "/bar");
|
||||||
|
g_variant_builder_add (&builder, "o", "/baz");
|
||||||
|
value = g_variant_new("(ao^ao^a&o)", &builder, strvector, strvector);
|
||||||
|
g_variant_iter_init (&tuple, value);
|
||||||
|
g_variant_iter_next (&tuple, "ao", &array);
|
||||||
|
|
||||||
|
i = 0;
|
||||||
|
while (g_variant_iter_loop (array, "o", &str))
|
||||||
|
g_assert_cmpstr (str, ==, test_strs[i++]);
|
||||||
|
g_assert (i == 3);
|
||||||
|
|
||||||
|
g_variant_iter_free (array);
|
||||||
|
|
||||||
|
/* start over */
|
||||||
|
g_variant_iter_init (&tuple, value);
|
||||||
|
g_variant_iter_next (&tuple, "ao", &array);
|
||||||
|
|
||||||
|
i = 0;
|
||||||
|
while (g_variant_iter_loop (array, "&o", &str))
|
||||||
|
g_assert_cmpstr (str, ==, test_strs[i++]);
|
||||||
|
g_assert (i == 3);
|
||||||
|
|
||||||
|
g_variant_iter_free (array);
|
||||||
|
|
||||||
|
g_variant_iter_next (&tuple, "^a&o", &strv);
|
||||||
|
g_variant_iter_next (&tuple, "^ao", &my_strv);
|
||||||
|
|
||||||
|
g_assert_cmpstr (strv[0], ==, "/hello");
|
||||||
|
g_assert_cmpstr (strv[1], ==, "/world");
|
||||||
|
g_assert (strv[2] == NULL);
|
||||||
|
g_assert_cmpstr (my_strv[0], ==, "/hello");
|
||||||
|
g_assert_cmpstr (my_strv[1], ==, "/world");
|
||||||
|
g_assert (my_strv[2] == NULL);
|
||||||
|
|
||||||
|
g_variant_unref (value);
|
||||||
|
g_strfreev (my_strv);
|
||||||
|
g_free (strv);
|
||||||
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
const gchar *strvector[] = { "i", "ii", "iii", "iv", "v", "vi", NULL };
|
const gchar *strvector[] = { "i", "ii", "iii", "iv", "v", "vi", NULL };
|
||||||
GVariantBuilder builder;
|
GVariantBuilder builder;
|
||||||
|
Loading…
Reference in New Issue
Block a user