[glib] gvariant: Add g_variant_get_fixed_array()



commit 5a95e19a462712010fece9c71079d5c311c77304
Author: Stef Walter <stefw collabora co uk>
Date:   Fri Sep 23 10:57:55 2011 +0200

    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

 docs/reference/glib/glib-sections.txt |    1 +
 glib/glib.symbols                     |    1 +
 glib/gvariant.c                       |   65 +++++++++++++++++++++++++++++++++
 glib/gvariant.h                       |    5 ++-
 glib/tests/gvariant.c                 |   16 ++++++++-
 5 files changed, 86 insertions(+), 2 deletions(-)
---
diff --git a/docs/reference/glib/glib-sections.txt b/docs/reference/glib/glib-sections.txt
index b5b30b2..046e955 100644
--- a/docs/reference/glib/glib-sections.txt
+++ b/docs/reference/glib/glib-sections.txt
@@ -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
diff --git a/glib/glib.symbols b/glib/glib.symbols
index 6c19c22..879da03 100644
--- a/glib/glib.symbols
+++ b/glib/glib.symbols
@@ -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
diff --git a/glib/gvariant.c b/glib/gvariant.c
index 571d29c..94383ae 100644
--- a/glib/gvariant.c
+++ b/glib/gvariant.c
@@ -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:
diff --git a/glib/gvariant.h b/glib/gvariant.h
index 7f3af98..bd24ef6 100644
--- a/glib/gvariant.h
+++ b/glib/gvariant.h
@@ -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);
diff --git a/glib/tests/gvariant.c b/glib/tests/gvariant.c
index e943bb2..29ca17b 100644
--- a/glib/tests/gvariant.c
+++ b/glib/tests/gvariant.c
@@ -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);
 }
 



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]