gvariant: Add g_variant_get_fixed_array()

Using g_variant_new_from_data() for creating new byte arrays is non-obvious.
This patch adds a g_variant_new_fixed_array() function.

https://bugzilla.gnome.org/show_bug.cgi?id=659923
This commit is contained in:
Stef Walter 2011-09-23 10:57:55 +02:00
parent 81e395b00b
commit 5a95e19a46
5 changed files with 86 additions and 2 deletions

View File

@ -3060,6 +3060,7 @@ g_variant_new_maybe
g_variant_new_array
g_variant_new_tuple
g_variant_new_dict_entry
g_variant_new_fixed_array
<SUBSECTION>
g_variant_get_maybe

View File

@ -1460,6 +1460,7 @@ g_variant_new_int64
g_variant_new_uint64
g_variant_new_handle
g_variant_new_double
g_variant_new_fixed_array
g_variant_new_string
g_variant_new_object_path
g_variant_is_object_path

View File

@ -1114,6 +1114,71 @@ g_variant_get_fixed_array (GVariant *value,
return NULL;
}
/**
* g_variant_new_fixed_array:
* @element_type: the #GVariantType of each element
* @elements: a pointer to the fixed array of contiguous elements
* @n_elements: the number of elements
* @element_size: the size of each element
* @returns: (transfer none): a floating reference to a new array #GVariant instance
*
* Provides access to the serialised data for an array of fixed-sized
* items.
*
* @value must be an array with fixed-sized elements. Numeric types are
* fixed-size as are tuples containing only other fixed-sized types.
*
* @element_size must be the size of a single element in the array. For
* example, if calling this function for an array of 32 bit integers,
* you might say <code>sizeof (gint32)</code>. This value isn't used
* except for the purpose of a double-check that the form of the
* seralised data matches the caller's expectation.
*
* @n_elements, which must be non-%NULL is set equal to the number of
* items in the array.
*
* Since: 2.32
**/
GVariant *
g_variant_new_fixed_array (const GVariantType *element_type,
gconstpointer elements,
gsize n_elements,
gsize element_size)
{
GVariantType *array_type;
gsize array_element_size;
GVariantTypeInfo *array_info;
GVariant *value;
gpointer data;
g_return_val_if_fail (g_variant_type_is_definite (element_type), NULL);
g_return_val_if_fail (element_size > 0, NULL);
array_type = g_variant_type_new_array (element_type);
array_info = g_variant_type_info_get (array_type);
g_variant_type_info_query_element (array_info, NULL, &array_element_size);
if G_UNLIKELY (array_element_size != element_size)
{
if (array_element_size)
g_critical ("g_variant_new_fixed_array: array size %" G_GSIZE_FORMAT
" does not match given element_size %" G_GSIZE_FORMAT ".",
array_element_size, element_size);
else
g_critical ("g_variant_get_fixed_array: array does not have fixed size.");
return NULL;
}
data = g_memdup (elements, n_elements * element_size);
value = g_variant_new_from_data (array_type, data,
n_elements * element_size,
FALSE, g_free, data);
g_variant_type_free (array_type);
g_variant_type_info_unref (array_info);
return value;
}
/* String type constructor/getters/validation {{{1 */
/**
* g_variant_new_string:

View File

@ -91,7 +91,10 @@ GVariant * g_variant_new_objv (const g
GVariant * g_variant_new_bytestring (const gchar *string);
GVariant * g_variant_new_bytestring_array (const gchar * const *strv,
gssize length);
GVariant * g_variant_new_fixed_array (const GVariantType *element_type,
gconstpointer elements,
gsize num_elements,
gsize element_size);
gboolean g_variant_get_boolean (GVariant *value);
guchar g_variant_get_byte (GVariant *value);
gint16 g_variant_get_int16 (GVariant *value);

View File

@ -4078,15 +4078,29 @@ static void
test_fixed_array (void)
{
GVariant *a;
gint32 values[5];
const gint32 *elts;
gsize n_elts;
gint i;
n_elts = 0;
a = g_variant_new_parsed ("[1,2,3,4,5]");
elts = g_variant_get_fixed_array (a, &n_elts, sizeof (gint32));
g_assert (n_elts == 5);
for (i = 0; i < 5; i++)
g_assert (elts[i] == i + 1);
g_assert_cmpint (elts[i], ==, i + 1);
g_variant_unref (a);
n_elts = 0;
for (i = 0; i < 5; i++)
values[i] = i + 1;
a = g_variant_new_fixed_array (G_VARIANT_TYPE_INT32, values,
G_N_ELEMENTS (values), sizeof (values[0]));
g_assert_cmpstr (g_variant_get_type_string (a), ==, "ai");
elts = g_variant_get_fixed_array (a, &n_elts, sizeof (gint32));
g_assert (n_elts == 5);
for (i = 0; i < 5; i++)
g_assert_cmpint (elts[i], ==, i + 1);
g_variant_unref (a);
}