[glib/gvariant: 39/39] serialiser changes WIP



commit beb3e30ef6a9b7b83e7573a3b505bf64523ce756
Author: Ryan Lortie <desrt desrt ca>
Date:   Tue Feb 2 10:21:17 2010 -0500

    serialiser changes WIP

 glib/Makefile.am           |    4 +-
 glib/gvariant-serialiser.c |  462 ++++++++++++++++++++++++++++++++++++++++----
 glib/gvariant-serialiser.h |    2 +-
 3 files changed, 426 insertions(+), 42 deletions(-)
---
diff --git a/glib/Makefile.am b/glib/Makefile.am
index 8ba739c..7699829 100644
--- a/glib/Makefile.am
+++ b/glib/Makefile.am
@@ -172,13 +172,13 @@ libglib_2_0_la_SOURCES = 	\
 	gunicodeprivate.h	\
 	gurifuncs.c 		\
 	gutils.c		\
+	gvariant-serialiser.h	\
+	gvariant-serialiser.c	\
 	gvariant-private.h	\
 	gvariant-core.c		\
 	gvariant-parser.c	\
 	gvariant-printer.c	\
 	gvariant-markup.c	\
-	gvariant-serialiser.h	\
-	gvariant-serialiser.c	\
 	gvarianttypeinfo.h	\
 	gvarianttypeinfo.c	\
 	gvarianttype.c		\
diff --git a/glib/gvariant-serialiser.c b/glib/gvariant-serialiser.c
index 57b32bb..34b5885 100644
--- a/glib/gvariant-serialiser.c
+++ b/glib/gvariant-serialiser.c
@@ -17,14 +17,398 @@
  * Boston, MA 02111-1307, USA.
  */
 
+/* Prologue {{{1 */
 #include "gvariant-serialiser.h"
 
 #include <glib/gtestutils.h>
+#include <glib/gstrfuncs.h>
 
 #include <string.h>
 
 #include "galias.h"
 
+/* Maybe {{{1
+ *
+ * Maybe types are handled depending on if the element type of the maybe
+ * type is a fixed-sized or variable-sized type.  Although all maybe
+ * types themselves are variable-sized types, herein, a maybe value with
+ * a fixed-sized element type is called a "fixed-sized maybe" for
+ * convenience and a maybe value with a variable-sized element type is
+ * called a "variable-sized maybe".
+ */
+
+/* Fixed-sized Maybe {{{2
+ *
+ * The size of a maybe value with a fixed-sized element type is either 0
+ * or equal to the fixed size of its element type.  The case where the
+ * size of the maybe value is zero corresponds to the "Nothing" case and
+ * the case where the size of the maybe value is equal to the fixed size
+ * of the element type corresponds to the "Just" case; in that case, the
+ * serialised data of the child value forms the entire serialised data
+ * of the maybe value.
+ *
+ * In the event that a fixed-sized maybe value is presented with a size
+ * that is not equal to the fixed size of the element type then the
+ * value must be taken to be "Nothing".
+ */
+
+static inline gsize
+gvs_fixed_sized_maybe_n_children (GVariantSerialised value)
+{
+  gsize element_fixed_size;
+
+  g_variant_type_info_query_element (value.type_info, NULL,
+                                     &element_fixed_size);
+
+  return (element_fixed_size == value.size) ? 1 : 0;
+}
+
+static inline GVariantSerialised
+gvs_fixed_sized_maybe_get_child (GVariantSerialised value,
+                                 gsize              index_)
+{
+  /* the child has the same bounds as the
+   * container, so just update the type.
+   */
+  value.type_info = g_variant_type_info_element (value.type_info);
+
+  return value;
+}
+
+static inline gsize
+gvs_fixed_sized_maybe_needed_size (GVariantTypeInfo         *type_info,
+                                   GVariantSerialisedFiller  gvs_filler,
+                                   const gpointer           *children,
+                                   gsize                     n_children)
+{
+  if (n_children)
+    {
+      gsize element_fixed_size;
+
+      g_variant_type_info_query_element (type_info, NULL,
+                                         &element_fixed_size);
+
+      return element_fixed_size;
+    }
+  else
+    return 0;
+}
+
+static inline void
+gvs_fixed_sized_maybe_serialise (GVariantSerialised        value,
+                                 GVariantSerialisedFiller  gvs_filler,
+                                 const gpointer           *children,
+                                 gsize                     n_children)
+{
+  if (n_children)
+    {
+      GVariantSerialised child = { NULL, value.data, value.size };
+
+      gvs_filler (&child, children[0]);
+    }
+}
+
+static inline gboolean
+gvs_fixed_sized_maybe_is_normal (GVariantSerialised value)
+{
+  if (value.size > 0)
+    {
+      gsize element_fixed_size;
+
+      g_variant_type_info_query_element (value.type_info,
+                                         NULL, &element_fixed_size);
+
+      if (value.size != element_fixed_size)
+        return FALSE;
+
+      /* proper element size: "Just".  recurse to the child. */
+      value = gvs_fixed_sized_maybe_get_child (value, 0);
+
+      return g_variant_serialiser_is_normal (value);
+    }
+
+  /* size of 0: "Nothing" */
+  return TRUE;
+}
+
+/* Variable-sized Maybe
+ *
+ * The size of a maybe value with a variable-sized element type is
+ * either 0 or strictly greater than 0.  The case where the size of the
+ * maybe value is zero corresponds to the "Nothing" case and the case
+ * where the size of the maybe value is greater than zero corresponds to
+ * the "Just" case; in that case, the serialised data of the child value
+ * forms the first part of the serialised data of the maybe value and is
+ * followed by a single zero byte.  This zero byte is always appended,
+ * regardless of any zero bytes that may already be at the end of the
+ * serialised ata of the child value.
+ */
+
+static inline gsize
+gvs_variable_sized_maybe_n_children (GVariantSerialised value)
+{
+  return (value.size > 0) ? 1 : 0;
+}
+
+static inline GVariantSerialised
+gvs_variable_sized_maybe_get_child (GVariantSerialised value,
+                                    gsize              index_)
+{
+  /* remove the padding byte and update the type. */
+  value.type_info = g_variant_type_info_element (value.type_info);
+  value.size--;
+
+  return value;
+}
+
+static inline gsize
+gvs_variable_sized_maybe_needed_size (GVariantTypeInfo         *type_info,
+                                      GVariantSerialisedFiller  gvs_filler,
+                                      const gpointer           *children,
+                                      gsize                     n_children)
+{
+  if (n_children)
+    {
+      GVariantSerialised child = {  };
+
+      gvs_filler (&child, children[0]);
+
+      return child.size + 1;
+    }
+  else
+    return 0;
+}
+
+static inline void
+gvs_variable_sized_maybe_serialise (GVariantSerialised        value,
+                                    GVariantSerialisedFiller  gvs_filler,
+                                    const gpointer           *children,
+                                    gsize                     n_children)
+{
+  if (n_children)
+    {
+      GVariantSerialised child = { NULL, value.data, value.size - 1 };
+
+      /* write the data for the child.  */
+      gvs_filler (&child, children[0]);
+      value.data[child.size] = '\0';
+    }
+}
+
+static inline gboolean
+gvs_variable_sized_maybe_is_normal (GVariantSerialised value)
+{
+         /* Nothing */        /* Just */
+  return (value.size == 0) || (value.data[value.size - 1] == '\0');
+}
+
+/* Arrays {{{1
+ *
+ * Just as with maybe types, array types are handled depending on if the
+ * element type of the array type is a fixed-sized or variable-sized
+ * type.  Similar to maybe types, for convenience, an array value with a
+ * fixed-sized element type is called a "fixed-sized array" and an array
+ * value with a variable-sized element type is called a "variable sized
+ * array".
+ */
+
+/* Fixed-sized Array {{{2 */
+
+static inline gsize
+gvs_fixed_sized_array_n_children (GVariantSerialised value)
+{
+  gsize element_fixed_size;
+
+  g_variant_type_info_query_element (value.type_info, NULL,
+                                     &element_fixed_size);
+
+  if (value.size % element_fixed_size == 0)
+    return value.size / element_fixed_size;
+
+  return 0;
+}
+
+static inline GVariantSerialised
+gvs_fixed_sized_array_get_child (GVariantSerialised value,
+                                 gsize              index_)
+{
+  GVariantSerialised child = {  };
+
+  child.type_info = g_variant_type_info_element (value.type_info);
+  g_variant_type_info_query (child.type_info, NULL, &child.size);
+  child.data = value.data + (child.size * index_);
+
+  return child;
+}
+
+static inline gsize
+gvs_fixed_sized_array_needed_size (GVariantTypeInfo         *type_info,
+                                   GVariantSerialisedFiller  gvs_filler,
+                                   const gpointer           *children,
+                                   gsize                     n_children)
+{
+  gsize element_fixed_size;
+
+  g_variant_type_info_query_element (value.type_info, NULL,
+                                     &element_fixed_size);
+
+  return element_fixed_size * n_children;
+}
+
+static inline void
+gvs_fixed_sized_array_serialise (GVariantSerialised        value,
+                                 GVariantSerialisedFiller  gvs_filler,
+                                 const gpointer           *children,
+                                 gsize                     n_children)
+{
+  GVariantSerialised child = {  };
+  gsize i;
+
+  child.type_info = g_variant_type_info_element (value.type_info);
+  g_variant_type_info_query (child.type_info, NULL, &child.size);
+  child.data = value.data;
+
+  for (i = 0; i < n_children; i++)
+    {
+      gvs_filler (&child, children[i]);
+      child_data += element_fixed_size;
+    }
+}
+
+static inline gboolean
+gvs_fixed_sized_array_is_normal (GVariantSerialised value)
+{
+  GVariantSerialised child = {  };
+
+  child.type_info = g_variant_type_info_element (value.type_info);
+  g_variant_type_info_query (child.type_info, NULL, &child.size);
+
+  if (value.size % child.size != 0)
+    return FALSE;
+
+  for (child.data = value.data;
+       child.data < value.data + value.size;
+       child.data += child.size)
+    {
+      if (!g_variant_serialiser_is_normal (child))
+        return FALSE;
+    }
+
+  return TRUE;
+}
+
+/* Variable-sized Array {{{2 */
+
+static inline gsize
+gvs_variable_sized_array_n_children (GVariantSerialised value)
+{
+}
+
+static inline GVariantSerialised
+gvs_variable_sized_array_get_child (GVariantSerialised value,
+                                    gsize              index_)
+{
+}
+
+static inline gsize
+gvs_variable_sized_array_needed_size (GVariantTypeInfo         *type_info,
+                                      GVariantSerialisedFiller  gvs_filler,
+                                      const gpointer           *children,
+                                      gsize                     n_children)
+{
+}
+
+static inline void
+gvs_variable_sized_array_serialise (GVariantSerialised        value,
+                                    GVariantSerialisedFiller  gvs_filler,
+                                    const gpointer           *children,
+                                    gsize                     n_children)
+{
+}
+
+static inline gboolean
+gvs_variable_sized_array_is_normal (GVariantSerialised value)
+{
+}
+
+variable size array stuff
+
+/* Tuples {{{1 */
+
+static inline gsize
+gvs_fixed_sized_maybe_n_children (GVariantSerialised value)
+{
+}
+
+static inline GVariantSerialised
+gvs_fixed_sized_maybe_get_child (GVariantSerialised value,
+                                 gsize              index_)
+{
+}
+
+static inline gsize
+gvs_fixed_sized_maybe_needed_size (GVariantTypeInfo         *type_info,
+                                   GVariantSerialisedFiller  gvs_filler,
+                                   const gpointer           *children,
+                                   gsize                     n_children)
+{
+}
+
+static inline void
+gvs_fixed_sized_maybe_serialise (GVariantSerialised        value,
+                                 GVariantSerialisedFiller  gvs_filler,
+                                 const gpointer           *children,
+                                 gsize                     n_children)
+{
+}
+
+static inline gboolean
+gvs_fixed_sized_maybe_is_normal (GVariantSerialised value)
+{
+}
+
+tuple stuff
+
+/* Variants {{{1 */
+
+static inline gsize
+gvs_fixed_sized_maybe_n_children (GVariantSerialised value)
+{
+}
+
+static inline GVariantSerialised
+gvs_fixed_sized_maybe_get_child (GVariantSerialised value,
+                                 gsize              index_)
+{
+}
+
+static inline gsize
+gvs_fixed_sized_maybe_needed_size (GVariantTypeInfo         *type_info,
+                                   GVariantSerialisedFiller  gvs_filler,
+                                   const gpointer           *children,
+                                   gsize                     n_children)
+{
+}
+
+static inline void
+gvs_fixed_sized_maybe_serialise (GVariantSerialised        value,
+                                 GVariantSerialisedFiller  gvs_filler,
+                                 const gpointer           *children,
+                                 gsize                     n_children)
+{
+}
+
+static inline gboolean
+gvs_fixed_sized_maybe_is_normal (GVariantSerialised value)
+{
+}
+
+
+variants
+
+/* Unsorted {{{1 */
+
+
 static gsize
 g_variant_serialiser_determine_size (gsize    content_end,
                                      gsize    offsets,
@@ -148,17 +532,17 @@ g_variant_serialised_n_children (GVariantSerialised container)
   g_variant_serialised_assert_invariant (container);
 
   switch (g_variant_type_info_get_type_char (container.type))
-  {
-    case G_VARIANT_CLASS_VARIANT:
+    {
+    case G_VARIANT_TYPE_INFO_CHAR_VARIANT:
       return 1;
 
-    case G_VARIANT_CLASS_TUPLE:
+    case G_VARIANT_TYPE_INFO_CHAR_TUPLE:
       return g_variant_type_info_n_members (container.type);
 
-    case G_VARIANT_CLASS_DICT_ENTRY:
+    case G_VARIANT_TYPE_INFO_CHAR_DICT_ENTRY:
       return 2;
 
-    case G_VARIANT_CLASS_MAYBE:
+    case G_VARIANT_TYPE_INFO_CHAR_MAYBE:
       {
         gsize size;
 
@@ -173,7 +557,7 @@ g_variant_serialised_n_children (GVariantSerialised container)
         return 1;
       }
 
-    case G_VARIANT_CLASS_ARRAY:
+    case G_VARIANT_TYPE_INFO_CHAR_ARRAY:
       {
         gsize fixed_size;
 
@@ -238,7 +622,7 @@ g_variant_serialised_get_child (GVariantSerialised container,
 
   switch (g_variant_type_info_get_type_char (container.type))
   {
-    case G_VARIANT_CLASS_VARIANT:
+    case G_VARIANT_TYPE_INFO_CHAR_VARIANT:
       {
         GVariantSerialised child = { NULL, container.data, container.size };
 
@@ -301,7 +685,7 @@ g_variant_serialised_get_child (GVariantSerialised container,
         return child;
       }
 
-    case G_VARIANT_CLASS_MAYBE:
+    case G_VARIANT_TYPE_INFO_CHAR_MAYBE:
       {
         GVariantSerialised child;
         gsize fixed_size;
@@ -333,7 +717,7 @@ g_variant_serialised_get_child (GVariantSerialised container,
         return child;
       }
 
-    case G_VARIANT_CLASS_ARRAY:
+    case G_VARIANT_TYPE_INFO_CHAR_ARRAY:
       {
         GVariantSerialised child;
         gsize fixed_size;
@@ -402,8 +786,8 @@ g_variant_serialised_get_child (GVariantSerialised container,
         return child;
       }
 
-    case G_VARIANT_CLASS_TUPLE:
-    case G_VARIANT_CLASS_DICT_ENTRY:
+    case G_VARIANT_TYPE_INFO_CHAR_TUPLE:
+    case G_VARIANT_TYPE_INFO_CHAR_DICT_ENTRY:
       {
         const GVariantMemberInfo *info;
         GVariantSerialised child;
@@ -483,7 +867,7 @@ g_variant_serialiser_serialise (GVariantSerialised        container,
 {
   switch (g_variant_type_info_get_type_char (container.type))
   {
-    case G_VARIANT_CLASS_VARIANT:
+    case G_VARIANT_TYPE_INFO_CHAR_VARIANT:
       {
         GVariantSerialised child = { NULL, container.data, 0 };
         const gchar *type_string;
@@ -511,7 +895,7 @@ g_variant_serialiser_serialise (GVariantSerialised        container,
         return;
       }
 
-    case G_VARIANT_CLASS_MAYBE:
+    case G_VARIANT_TYPE_INFO_CHAR_MAYBE:
       {
         g_assert_cmpint (n_children, ==, (container.size > 0));
 
@@ -542,7 +926,7 @@ g_variant_serialiser_serialise (GVariantSerialised        container,
         return;
       }
 
-    case G_VARIANT_CLASS_ARRAY:
+    case G_VARIANT_TYPE_INFO_CHAR_ARRAY:
       {
         g_assert_cmpint ((n_children > 0), ==, (container.size > 0));
 
@@ -590,8 +974,8 @@ g_variant_serialiser_serialise (GVariantSerialised        container,
         return;
       }
 
-    case G_VARIANT_CLASS_TUPLE:
-    case G_VARIANT_CLASS_DICT_ENTRY:
+    case G_VARIANT_TYPE_INFO_CHAR_TUPLE:
+    case G_VARIANT_TYPE_INFO_CHAR_DICT_ENTRY:
       {
         if (n_children)
           {
@@ -675,7 +1059,7 @@ g_variant_serialiser_needed_size (GVariantTypeInfo         *type,
 {
   switch (g_variant_type_info_get_type_char (type))
   {
-    case G_VARIANT_CLASS_VARIANT:
+    case G_VARIANT_TYPE_INFO_CHAR_VARIANT:
       {
         GVariantSerialised child = {};
         const gchar *type_string;
@@ -688,7 +1072,7 @@ g_variant_serialiser_needed_size (GVariantTypeInfo         *type,
         return child.size + 1 + strlen (type_string);
       }
 
-    case G_VARIANT_CLASS_MAYBE:
+    case G_VARIANT_TYPE_INFO_CHAR_MAYBE:
       {
         GVariantSerialised child = { g_variant_type_info_element (type) };
         gsize fixed_size;
@@ -711,7 +1095,7 @@ g_variant_serialiser_needed_size (GVariantTypeInfo         *type,
         return child.size;
       }
 
-    case G_VARIANT_CLASS_ARRAY:
+    case G_VARIANT_TYPE_INFO_CHAR_ARRAY:
       {
         GVariantTypeInfo *elem_type;
         gsize fixed_size;
@@ -750,8 +1134,8 @@ g_variant_serialiser_needed_size (GVariantTypeInfo         *type,
           return fixed_size * n_children;
       }
 
-    case G_VARIANT_CLASS_TUPLE:
-    case G_VARIANT_CLASS_DICT_ENTRY:
+    case G_VARIANT_TYPE_INFO_CHAR_TUPLE:
+    case G_VARIANT_TYPE_INFO_CHAR_DICT_ENTRY:
       {
         gsize n_offsets;
         gsize offset;
@@ -912,24 +1296,24 @@ g_variant_serialised_is_normal (GVariantSerialised value)
 //#define fail g_assert_not_reached ()
   switch (g_variant_type_info_get_type_char (value.type))
   {
-    case G_VARIANT_CLASS_BYTE:
-    case G_VARIANT_CLASS_INT16:
-    case G_VARIANT_CLASS_UINT16:
-    case G_VARIANT_CLASS_INT32:
-    case G_VARIANT_CLASS_HANDLE:
-    case G_VARIANT_CLASS_UINT32:
-    case G_VARIANT_CLASS_INT64:
-    case G_VARIANT_CLASS_UINT64:
-    case G_VARIANT_CLASS_DOUBLE:
+    case G_VARIANT_TYPE_INFO_CHAR_BYTE:
+    case G_VARIANT_TYPE_INFO_CHAR_INT16:
+    case G_VARIANT_TYPE_INFO_CHAR_UINT16:
+    case G_VARIANT_TYPE_INFO_CHAR_INT32:
+    case G_VARIANT_TYPE_INFO_CHAR_HANDLE:
+    case G_VARIANT_TYPE_INFO_CHAR_UINT32:
+    case G_VARIANT_TYPE_INFO_CHAR_INT64:
+    case G_VARIANT_TYPE_INFO_CHAR_UINT64:
+    case G_VARIANT_TYPE_INFO_CHAR_DOUBLE:
       return TRUE;
 
-    case G_VARIANT_CLASS_BOOLEAN:
+    case G_VARIANT_TYPE_INFO_CHAR_BOOLEAN:
       if (value.data[0] > 1)
         fail;
 
       return TRUE;
 
-    case G_VARIANT_CLASS_STRING:
+    case G_VARIANT_TYPE_INFO_CHAR_STRING:
       /* XXX this is not safe if the data changes... */
       if (value.size == 0 || value.data[value.size - 1] != '\0' ||
           strlen ((const char *) value.data) + 1 != value.size)
@@ -937,7 +1321,7 @@ g_variant_serialised_is_normal (GVariantSerialised value)
 
       return TRUE;
 
-    case G_VARIANT_CLASS_VARIANT:
+    case G_VARIANT_TYPE_INFO_CHAR_VARIANT:
       {
         GVariantSerialised child = { NULL, value.data, value.size };
 
@@ -992,7 +1376,7 @@ g_variant_serialised_is_normal (GVariantSerialised value)
         return g_variant_serialised_is_normal (child);
       }
 
-    case G_VARIANT_CLASS_MAYBE:
+    case G_VARIANT_TYPE_INFO_CHAR_MAYBE:
       {
         gsize fixed_size;
 
@@ -1024,7 +1408,7 @@ g_variant_serialised_is_normal (GVariantSerialised value)
         return g_variant_serialised_is_normal (value);
       }
 
-    case G_VARIANT_CLASS_ARRAY:
+    case G_VARIANT_TYPE_INFO_CHAR_ARRAY:
       {
         GVariantSerialised child = { g_variant_type_info_element (value.type),
                                      value.data,
@@ -1122,8 +1506,8 @@ g_variant_serialised_is_normal (GVariantSerialised value)
         return TRUE;
       }
 
-    case G_VARIANT_CLASS_TUPLE:
-    case G_VARIANT_CLASS_DICT_ENTRY:
+    case G_VARIANT_TYPE_INFO_CHAR_TUPLE:
+    case G_VARIANT_TYPE_INFO_CHAR_DICT_ENTRY:
       {
         const GVariantMemberInfo *info;
         guint offset_size;
@@ -1241,8 +1625,8 @@ g_variant_serialised_is_normal (GVariantSerialised value)
         return TRUE;
       }
 
-    case G_VARIANT_CLASS_SIGNATURE:
-    case G_VARIANT_CLASS_OBJECT_PATH:
+    case G_VARIANT_TYPE_INFO_CHAR_SIGNATURE:
+    case G_VARIANT_TYPE_INFO_CHAR_OBJECT_PATH:
       return TRUE; /* XXX */
 
     default:
diff --git a/glib/gvariant-serialiser.h b/glib/gvariant-serialiser.h
index 3201da1..293918e 100644
--- a/glib/gvariant-serialiser.h
+++ b/glib/gvariant-serialiser.h
@@ -24,7 +24,7 @@
 
 typedef struct
 {
-  GVariantTypeInfo *type;
+  GVariantTypeInfo *type_info;
   guchar           *data;
   gsize             size;
 } GVariantSerialised;



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