[glib] GDBusMessage: Optimize serializer and deserializer



commit a6d33d3a28071957e81d63ba389bdf759d29dc45
Author: David Zeuthen <davidz redhat com>
Date:   Tue Jun 14 18:11:09 2011 -0400

    GDBusMessage: Optimize serializer and deserializer
    
    ... by using a switch instead of if-then-else.
    
    Signed-off-by: David Zeuthen <davidz redhat com>

 gio/gdbusmessage.c |  763 +++++++++++++++++++++++++++-------------------------
 1 files changed, 390 insertions(+), 373 deletions(-)
---
diff --git a/gio/gdbusmessage.c b/gio/gdbusmessage.c
index b5e4ffe..f29f5d9 100644
--- a/gio/gdbusmessage.c
+++ b/gio/gdbusmessage.c
@@ -1058,6 +1058,9 @@ parse_value_from_blob (GMemoryInputStream    *mis,
   GVariant *ret;
   GError *local_error;
   gboolean is_leaf;
+  const gchar *type_string;
+
+  type_string = g_variant_type_peek_string (type);
 
 #ifdef DEBUG_SERIALIZER
   if (!just_align)
@@ -1076,8 +1079,9 @@ parse_value_from_blob (GMemoryInputStream    *mis,
 
   is_leaf = TRUE;
   local_error = NULL;
-  if (g_variant_type_equal (type, G_VARIANT_TYPE_BOOLEAN))
+  switch (type_string[0])
     {
+    case 'b': /* G_VARIANT_TYPE_BOOLEAN */
       if (!ensure_input_padding (mis, 4, &local_error))
         goto fail;
       if (!just_align)
@@ -1088,9 +1092,9 @@ parse_value_from_blob (GMemoryInputStream    *mis,
             goto fail;
           ret = g_variant_new_boolean (v);
         }
-    }
-  else if (g_variant_type_equal (type, G_VARIANT_TYPE_BYTE))
-    {
+      break;
+
+    case 'y': /* G_VARIANT_TYPE_BYTE */
       if (!just_align)
         {
           guchar v;
@@ -1099,9 +1103,9 @@ parse_value_from_blob (GMemoryInputStream    *mis,
             goto fail;
           ret = g_variant_new_byte (v);
         }
-    }
-  else if (g_variant_type_equal (type, G_VARIANT_TYPE_INT16))
-    {
+      break;
+
+    case 'n': /* G_VARIANT_TYPE_INT16 */
       if (!ensure_input_padding (mis, 2, &local_error))
         goto fail;
       if (!just_align)
@@ -1112,9 +1116,9 @@ parse_value_from_blob (GMemoryInputStream    *mis,
             goto fail;
           ret = g_variant_new_int16 (v);
         }
-    }
-  else if (g_variant_type_equal (type, G_VARIANT_TYPE_UINT16))
-    {
+      break;
+
+    case 'q': /* G_VARIANT_TYPE_UINT16 */
       if (!ensure_input_padding (mis, 2, &local_error))
         goto fail;
       if (!just_align)
@@ -1125,9 +1129,9 @@ parse_value_from_blob (GMemoryInputStream    *mis,
             goto fail;
           ret = g_variant_new_uint16 (v);
         }
-    }
-  else if (g_variant_type_equal (type, G_VARIANT_TYPE_INT32))
-    {
+      break;
+
+    case 'i': /* G_VARIANT_TYPE_INT32 */
       if (!ensure_input_padding (mis, 4, &local_error))
         goto fail;
       if (!just_align)
@@ -1138,9 +1142,9 @@ parse_value_from_blob (GMemoryInputStream    *mis,
             goto fail;
           ret = g_variant_new_int32 (v);
         }
-    }
-  else if (g_variant_type_equal (type, G_VARIANT_TYPE_UINT32))
-    {
+      break;
+
+    case 'u': /* G_VARIANT_TYPE_UINT32 */
       if (!ensure_input_padding (mis, 4, &local_error))
         goto fail;
       if (!just_align)
@@ -1151,9 +1155,9 @@ parse_value_from_blob (GMemoryInputStream    *mis,
             goto fail;
           ret = g_variant_new_uint32 (v);
         }
-    }
-  else if (g_variant_type_equal (type, G_VARIANT_TYPE_INT64))
-    {
+      break;
+
+    case 'x': /* G_VARIANT_TYPE_INT64 */
       if (!ensure_input_padding (mis, 8, &local_error))
         goto fail;
       if (!just_align)
@@ -1164,9 +1168,9 @@ parse_value_from_blob (GMemoryInputStream    *mis,
             goto fail;
           ret = g_variant_new_int64 (v);
         }
-    }
-  else if (g_variant_type_equal (type, G_VARIANT_TYPE_UINT64))
-    {
+      break;
+
+    case 't': /* G_VARIANT_TYPE_UINT64 */
       if (!ensure_input_padding (mis, 8, &local_error))
         goto fail;
       if (!just_align)
@@ -1177,9 +1181,9 @@ parse_value_from_blob (GMemoryInputStream    *mis,
             goto fail;
           ret = g_variant_new_uint64 (v);
         }
-    }
-  else if (g_variant_type_equal (type, G_VARIANT_TYPE_DOUBLE))
-    {
+      break;
+
+    case 'd': /* G_VARIANT_TYPE_DOUBLE */
       if (!ensure_input_padding (mis, 8, &local_error))
         goto fail;
       if (!just_align)
@@ -1194,9 +1198,9 @@ parse_value_from_blob (GMemoryInputStream    *mis,
             goto fail;
           ret = g_variant_new_double (u.v_double);
         }
-    }
-  else if (g_variant_type_equal (type, G_VARIANT_TYPE_STRING))
-    {
+      break;
+
+    case 's': /* G_VARIANT_TYPE_STRING */
       if (!ensure_input_padding (mis, 4, &local_error))
         goto fail;
       if (!just_align)
@@ -1212,9 +1216,9 @@ parse_value_from_blob (GMemoryInputStream    *mis,
           ret = g_variant_new_string (v);
           g_free (v);
         }
-    }
-  else if (g_variant_type_equal (type, G_VARIANT_TYPE_OBJECT_PATH))
-    {
+      break;
+
+    case 'o': /* G_VARIANT_TYPE_OBJECT_PATH */
       if (!ensure_input_padding (mis, 4, &local_error))
         goto fail;
       if (!just_align)
@@ -1240,9 +1244,9 @@ parse_value_from_blob (GMemoryInputStream    *mis,
           ret = g_variant_new_object_path (v);
           g_free (v);
         }
-    }
-  else if (g_variant_type_equal (type, G_VARIANT_TYPE_SIGNATURE))
-    {
+      break;
+
+    case 'g': /* G_VARIANT_TYPE_SIGNATURE */
       if (!just_align)
         {
           guchar len;
@@ -1266,9 +1270,9 @@ parse_value_from_blob (GMemoryInputStream    *mis,
           ret = g_variant_new_signature (v);
           g_free (v);
         }
-    }
-  else if (g_variant_type_equal (type, G_VARIANT_TYPE_HANDLE))
-    {
+      break;
+
+    case 'h': /* G_VARIANT_TYPE_HANDLE */
       if (!ensure_input_padding (mis, 4, &local_error))
         goto fail;
       if (!just_align)
@@ -1279,231 +1283,237 @@ parse_value_from_blob (GMemoryInputStream    *mis,
             goto fail;
           ret = g_variant_new_handle (v);
         }
-    }
-  else if (g_variant_type_is_array (type))
-    {
-      guint32 array_len;
-      goffset offset;
-      goffset target;
-      const GVariantType *element_type;
-      GVariantBuilder builder;
+      break;
 
-      if (!ensure_input_padding (mis, 4, &local_error))
-        goto fail;
+    case 'a': /* G_VARIANT_TYPE_ARRAY */
+      {
+        guint32 array_len;
+        goffset offset;
+        goffset target;
+        const GVariantType *element_type;
+        GVariantBuilder builder;
 
-      if (just_align)
-        {
-          array_len = 0;
-        }
-      else
+        if (!ensure_input_padding (mis, 4, &local_error))
+          goto fail;
+
+        if (just_align)
+          {
+            array_len = 0;
+          }
+        else
+          {
+            array_len = g_data_input_stream_read_uint32 (dis, NULL, &local_error);
+            if (local_error != NULL)
+              goto fail;
+
+            is_leaf = FALSE;
+#ifdef DEBUG_SERIALIZER
+            g_print (": array spans 0x%04x bytes\n", array_len);
+#endif /* DEBUG_SERIALIZER */
+
+            if (array_len > (2<<26))
+              {
+                /* G_GUINT32_FORMAT doesn't work with gettext, so use u */
+                g_set_error (&local_error,
+                             G_IO_ERROR,
+                             G_IO_ERROR_INVALID_ARGUMENT,
+                             _("Encountered array of length %u bytes. Maximum length is 2<<26 bytes (64 MiB)."),
+                             array_len);
+                goto fail;
+              }
+          }
+
+        g_variant_builder_init (&builder, type);
+        element_type = g_variant_type_element (type);
+
+        if (array_len == 0)
+          {
+            GVariant *item;
+            item = parse_value_from_blob (mis,
+                                          dis,
+                                          element_type,
+                                          TRUE,
+                                          indent + 2,
+                                          &local_error);
+            g_assert (item == NULL);
+          }
+        else
+          {
+            /* TODO: optimize array of primitive types */
+            offset = g_seekable_tell (G_SEEKABLE (mis));
+            target = offset + array_len;
+            while (offset < target)
+              {
+                GVariant *item;
+                item = parse_value_from_blob (mis,
+                                              dis,
+                                              element_type,
+                                              FALSE,
+                                              indent + 2,
+                                              &local_error);
+                if (item == NULL)
+                  {
+                    g_variant_builder_clear (&builder);
+                    goto fail;
+                  }
+                g_variant_builder_add_value (&builder, item);
+                g_variant_unref (item);
+                offset = g_seekable_tell (G_SEEKABLE (mis));
+              }
+          }
+
+        if (!just_align)
+          {
+            ret = g_variant_builder_end (&builder);
+          }
+        else
+          {
+            g_variant_builder_clear (&builder);
+          }
+      }
+      break;
+
+    default:
+      if (g_variant_type_is_dict_entry (type))
         {
-          array_len = g_data_input_stream_read_uint32 (dis, NULL, &local_error);
-          if (local_error != NULL)
+          const GVariantType *key_type;
+          const GVariantType *value_type;
+          GVariant *key;
+          GVariant *value;
+
+          if (!ensure_input_padding (mis, 8, &local_error))
             goto fail;
 
           is_leaf = FALSE;
 #ifdef DEBUG_SERIALIZER
-          g_print (": array spans 0x%04x bytes\n", array_len);
+          g_print ("\n");
 #endif /* DEBUG_SERIALIZER */
 
-          if (array_len > (2<<26))
-            {
-              /* G_GUINT32_FORMAT doesn't work with gettext, so use u */
-              g_set_error (&local_error,
-                           G_IO_ERROR,
-                           G_IO_ERROR_INVALID_ARGUMENT,
-                           _("Encountered array of length %u bytes. Maximum length is 2<<26 bytes (64 MiB)."),
-                           array_len);
-              goto fail;
-            }
-        }
-
-      g_variant_builder_init (&builder, type);
-      element_type = g_variant_type_element (type);
-
-      if (array_len == 0)
-        {
-          GVariant *item;
-          item = parse_value_from_blob (mis,
-                                        dis,
-                                        element_type,
-                                        TRUE,
-                                        indent + 2,
-                                        &local_error);
-          g_assert (item == NULL);
-        }
-      else
-        {
-          /* TODO: optimize array of primitive types */
-          offset = g_seekable_tell (G_SEEKABLE (mis));
-          target = offset + array_len;
-          while (offset < target)
+          if (!just_align)
             {
-              GVariant *item;
-              item = parse_value_from_blob (mis,
-                                            dis,
-                                            element_type,
-                                            FALSE,
-                                            indent + 2,
-                                            &local_error);
-              if (item == NULL)
+              key_type = g_variant_type_key (type);
+              key = parse_value_from_blob (mis,
+                                           dis,
+                                           key_type,
+                                           FALSE,
+                                           indent + 2,
+                                           &local_error);
+              if (key == NULL)
+                goto fail;
+              value_type = g_variant_type_value (type);
+              value = parse_value_from_blob (mis,
+                                             dis,
+                                             value_type,
+                                             FALSE,
+                                             indent + 2,
+                                             &local_error);
+              if (value == NULL)
                 {
-                  g_variant_builder_clear (&builder);
+                  g_variant_unref (key);
                   goto fail;
                 }
-              g_variant_builder_add_value (&builder, item);
-              g_variant_unref (item);
-              offset = g_seekable_tell (G_SEEKABLE (mis));
+              ret = g_variant_new_dict_entry (key, value);
+              g_variant_unref (key);
+              g_variant_unref (value);
             }
         }
-
-      if (!just_align)
-        {
-          ret = g_variant_builder_end (&builder);
-        }
-      else
+      else if (g_variant_type_is_tuple (type))
         {
-          g_variant_builder_clear (&builder);
-        }
-    }
-  else if (g_variant_type_is_dict_entry (type))
-    {
-      const GVariantType *key_type;
-      const GVariantType *value_type;
-      GVariant *key;
-      GVariant *value;
-
-      if (!ensure_input_padding (mis, 8, &local_error))
-        goto fail;
+          if (!ensure_input_padding (mis, 8, &local_error))
+            goto fail;
 
-      is_leaf = FALSE;
+          is_leaf = FALSE;
 #ifdef DEBUG_SERIALIZER
-      g_print ("\n");
+          g_print ("\n");
 #endif /* DEBUG_SERIALIZER */
 
-      if (!just_align)
-        {
-          key_type = g_variant_type_key (type);
-          key = parse_value_from_blob (mis,
-                                       dis,
-                                       key_type,
-                                       FALSE,
-                                       indent + 2,
-                                       &local_error);
-          if (key == NULL)
-            goto fail;
-          value_type = g_variant_type_value (type);
-          value = parse_value_from_blob (mis,
-                                         dis,
-                                         value_type,
-                                         FALSE,
-                                         indent + 2,
-                                         &local_error);
-          if (value == NULL)
+          if (!just_align)
             {
-              g_variant_unref (key);
-              goto fail;
+              const GVariantType *element_type;
+              GVariantBuilder builder;
+
+              g_variant_builder_init (&builder, type);
+              element_type = g_variant_type_first (type);
+              while (element_type != NULL)
+                {
+                  GVariant *item;
+                  item = parse_value_from_blob (mis,
+                                                dis,
+                                                element_type,
+                                                FALSE,
+                                                indent + 2,
+                                                &local_error);
+                  if (item == NULL)
+                    {
+                      g_variant_builder_clear (&builder);
+                      goto fail;
+                    }
+                  g_variant_builder_add_value (&builder, item);
+                  g_variant_unref (item);
+
+                  element_type = g_variant_type_next (element_type);
+                }
+              ret = g_variant_builder_end (&builder);
             }
-          ret = g_variant_new_dict_entry (key, value);
-          g_variant_unref (key);
-          g_variant_unref (value);
         }
-    }
-  else if (g_variant_type_is_tuple (type))
-    {
-      if (!ensure_input_padding (mis, 8, &local_error))
-        goto fail;
-
-      is_leaf = FALSE;
+      else if (g_variant_type_is_variant (type))
+        {
+          is_leaf = FALSE;
 #ifdef DEBUG_SERIALIZER
-      g_print ("\n");
+          g_print ("\n");
 #endif /* DEBUG_SERIALIZER */
 
-      if (!just_align)
-        {
-          const GVariantType *element_type;
-          GVariantBuilder builder;
-
-          g_variant_builder_init (&builder, type);
-          element_type = g_variant_type_first (type);
-          while (element_type != NULL)
+          if (!just_align)
             {
-              GVariant *item;
-              item = parse_value_from_blob (mis,
-                                            dis,
-                                            element_type,
-                                            FALSE,
-                                            indent + 2,
-                                            &local_error);
-              if (item == NULL)
+              guchar siglen;
+              gchar *sig;
+              GVariantType *variant_type;
+              GVariant *value;
+
+              siglen = g_data_input_stream_read_byte (dis, NULL, &local_error);
+              if (local_error != NULL)
+                goto fail;
+              sig = read_string (mis, dis, (gsize) siglen, &local_error);
+              if (sig == NULL)
+                goto fail;
+              if (!g_variant_is_signature (sig))
                 {
-                  g_variant_builder_clear (&builder);
+                  g_set_error (&local_error,
+                               G_IO_ERROR,
+                               G_IO_ERROR_INVALID_ARGUMENT,
+                               _("Parsed value `%s' for variant is not a valid D-Bus signature"),
+                               sig);
+                  g_free (sig);
                   goto fail;
                 }
-              g_variant_builder_add_value (&builder, item);
-              g_variant_unref (item);
-
-              element_type = g_variant_type_next (element_type);
+              variant_type = g_variant_type_new (sig);
+              g_free (sig);
+              value = parse_value_from_blob (mis,
+                                             dis,
+                                             variant_type,
+                                             FALSE,
+                                             indent + 2,
+                                             &local_error);
+              g_variant_type_free (variant_type);
+              if (value == NULL)
+                goto fail;
+              ret = g_variant_new_variant (value);
+              g_variant_unref (value);
             }
-          ret = g_variant_builder_end (&builder);
         }
-    }
-  else if (g_variant_type_is_variant (type))
-    {
-      is_leaf = FALSE;
-#ifdef DEBUG_SERIALIZER
-      g_print ("\n");
-#endif /* DEBUG_SERIALIZER */
-
-      if (!just_align)
+      else
         {
-          guchar siglen;
-          gchar *sig;
-          GVariantType *variant_type;
-          GVariant *value;
-
-          siglen = g_data_input_stream_read_byte (dis, NULL, &local_error);
-          if (local_error != NULL)
-            goto fail;
-          sig = read_string (mis, dis, (gsize) siglen, &local_error);
-          if (sig == NULL)
-            goto fail;
-          if (!g_variant_is_signature (sig))
-            {
-              g_set_error (&local_error,
-                           G_IO_ERROR,
-                           G_IO_ERROR_INVALID_ARGUMENT,
-                           _("Parsed value `%s' for variant is not a valid D-Bus signature"),
-                           sig);
-              g_free (sig);
-              goto fail;
-            }
-          variant_type = g_variant_type_new (sig);
-          g_free (sig);
-          value = parse_value_from_blob (mis,
-                                         dis,
-                                         variant_type,
-                                         FALSE,
-                                         indent + 2,
-                                         &local_error);
-          g_variant_type_free (variant_type);
-          if (value == NULL)
-            goto fail;
-          ret = g_variant_new_variant (value);
-          g_variant_unref (value);
+          gchar *s;
+          s = g_variant_type_dup_string (type);
+          g_set_error (&local_error,
+                       G_IO_ERROR,
+                       G_IO_ERROR_INVALID_ARGUMENT,
+                       _("Error deserializing GVariant with type string `%s' from the D-Bus wire format"),
+                       s);
+          g_free (s);
+          goto fail;
         }
-    }
-  else
-    {
-      gchar *s;
-      s = g_variant_type_dup_string (type);
-      g_set_error (&local_error,
-                   G_IO_ERROR,
-                   G_IO_ERROR_INVALID_ARGUMENT,
-                   _("Error deserializing GVariant with type string `%s' from the D-Bus wire format"),
-                   s);
-      g_free (s);
-      goto fail;
+      break;
     }
 
   g_assert ((just_align && ret == NULL) || (!just_align && ret != NULL));
@@ -1863,82 +1873,86 @@ append_value_to_blob (GVariant             *value,
                       GError              **error)
 {
   gsize padding_added;
+  const gchar *type_string;
+
+  type_string = g_variant_type_peek_string (type);
 
   padding_added = 0;
 
-  if (g_variant_type_equal (type, G_VARIANT_TYPE_BOOLEAN))
+  switch (type_string[0])
     {
+    case 'b': /* G_VARIANT_TYPE_BOOLEAN */
       padding_added = ensure_output_padding (mos, dos, 4);
       if (value != NULL)
         {
           gboolean v = g_variant_get_boolean (value);
           g_data_output_stream_put_uint32 (dos, v, NULL, NULL);
         }
-    }
-  else if (g_variant_type_equal (type, G_VARIANT_TYPE_BYTE))
-    {
+      break;
+
+    case 'y': /* G_VARIANT_TYPE_BYTE */
       if (value != NULL)
         {
           guint8 v = g_variant_get_byte (value);
           g_data_output_stream_put_byte (dos, v, NULL, NULL);
         }
-    }
-  else if (g_variant_type_equal (type, G_VARIANT_TYPE_INT16))
-    {
+      break;
+
+    case 'n': /* G_VARIANT_TYPE_INT16 */
       padding_added = ensure_output_padding (mos, dos, 2);
       if (value != NULL)
         {
           gint16 v = g_variant_get_int16 (value);
           g_data_output_stream_put_int16 (dos, v, NULL, NULL);
         }
-    }
-  else if (g_variant_type_equal (type, G_VARIANT_TYPE_UINT16))
-    {
+      break;
+
+    case 'q': /* G_VARIANT_TYPE_UINT16 */
       padding_added = ensure_output_padding (mos, dos, 2);
       if (value != NULL)
         {
           guint16 v = g_variant_get_uint16 (value);
           g_data_output_stream_put_uint16 (dos, v, NULL, NULL);
         }
-    }
-  else if (g_variant_type_equal (type, G_VARIANT_TYPE_INT32))
-    {
+      break;
+
+    case 'i': /* G_VARIANT_TYPE_INT32 */
       padding_added = ensure_output_padding (mos, dos, 4);
       if (value != NULL)
         {
           gint32 v = g_variant_get_int32 (value);
           g_data_output_stream_put_int32 (dos, v, NULL, NULL);
         }
-    }
-  else if (g_variant_type_equal (type, G_VARIANT_TYPE_UINT32))
-    {
+      break;
+
+    case 'u': /* G_VARIANT_TYPE_UINT32 */
       padding_added = ensure_output_padding (mos, dos, 4);
       if (value != NULL)
         {
           guint32 v = g_variant_get_uint32 (value);
           g_data_output_stream_put_uint32 (dos, v, NULL, NULL);
         }
-    }
-  else if (g_variant_type_equal (type, G_VARIANT_TYPE_INT64))
-    {
+      break;
+
+    case 'x': /* G_VARIANT_TYPE_INT64 */
       padding_added = ensure_output_padding (mos, dos, 8);
       if (value != NULL)
         {
           gint64 v = g_variant_get_int64 (value);
           g_data_output_stream_put_int64 (dos, v, NULL, NULL);
         }
-    }
-  else if (g_variant_type_equal (type, G_VARIANT_TYPE_UINT64))
-    {
+      break;
+
+    case 't': /* G_VARIANT_TYPE_UINT64 */
       padding_added = ensure_output_padding (mos, dos, 8);
       if (value != NULL)
         {
           guint64 v = g_variant_get_uint64 (value);
           g_data_output_stream_put_uint64 (dos, v, NULL, NULL);
         }
-    }
-  else if (g_variant_type_equal (type, G_VARIANT_TYPE_DOUBLE))
-    {
+      break;
+
+    case 'd': /* G_VARIANT_TYPE_DOUBLE */
       padding_added = ensure_output_padding (mos, dos, 8);
       if (value != NULL)
         {
@@ -1950,9 +1964,9 @@ append_value_to_blob (GVariant             *value,
           u.v_double = g_variant_get_double (value);
           g_data_output_stream_put_uint64 (dos, u.v_uint64, NULL, NULL);
         }
-    }
-  else if (g_variant_type_equal (type, G_VARIANT_TYPE_STRING))
-    {
+      break;
+
+    case 's': /* G_VARIANT_TYPE_STRING */
       padding_added = ensure_output_padding (mos, dos, 4);
       if (value != NULL)
         {
@@ -1965,9 +1979,9 @@ append_value_to_blob (GVariant             *value,
           g_data_output_stream_put_string (dos, v, NULL, NULL);
           g_data_output_stream_put_byte (dos, '\0', NULL, NULL);
         }
-    }
-  else if (g_variant_type_equal (type, G_VARIANT_TYPE_OBJECT_PATH))
-    {
+      break;
+
+    case 'o': /* G_VARIANT_TYPE_OBJECT_PATH */
       padding_added = ensure_output_padding (mos, dos, 4);
       if (value != NULL)
         {
@@ -1978,9 +1992,9 @@ append_value_to_blob (GVariant             *value,
           g_data_output_stream_put_string (dos, v, NULL, NULL);
           g_data_output_stream_put_byte (dos, '\0', NULL, NULL);
         }
-    }
-  else if (g_variant_type_equal (type, G_VARIANT_TYPE_SIGNATURE))
-    {
+      break;
+
+    case 'g': /* G_VARIANT_TYPE_SIGNATURE */
       if (value != NULL)
         {
           gsize len;
@@ -1990,155 +2004,158 @@ append_value_to_blob (GVariant             *value,
           g_data_output_stream_put_string (dos, v, NULL, NULL);
           g_data_output_stream_put_byte (dos, '\0', NULL, NULL);
         }
-    }
-  else if (g_variant_type_equal (type, G_VARIANT_TYPE_HANDLE))
-    {
+      break;
+
+    case 'h': /* G_VARIANT_TYPE_HANDLE */
       padding_added = ensure_output_padding (mos, dos, 4);
       if (value != NULL)
         {
           gint32 v = g_variant_get_handle (value);
           g_data_output_stream_put_int32 (dos, v, NULL, NULL);
         }
-    }
-  else if (g_variant_type_is_array (type))
-    {
-      GVariant *item;
-      GVariantIter iter;
-      goffset array_len_offset;
-      goffset array_payload_begin_offset;
-      goffset cur_offset;
-      gsize array_len;
+      break;
 
-      padding_added = ensure_output_padding (mos, dos, 4);
-      if (value != NULL)
+    case 'a': /* G_VARIANT_TYPE_ARRAY */
+      {
+        GVariant *item;
+        GVariantIter iter;
+        goffset array_len_offset;
+        goffset array_payload_begin_offset;
+        goffset cur_offset;
+        gsize array_len;
+
+        padding_added = ensure_output_padding (mos, dos, 4);
+        if (value != NULL)
+          {
+            /* array length - will be filled in later */
+            array_len_offset = g_memory_output_stream_get_data_size (mos);
+            g_data_output_stream_put_uint32 (dos, 0xF00DFACE, NULL, NULL);
+
+            /* From the D-Bus spec:
+             *
+             *   "A UINT32 giving the length of the array data in bytes,
+             *    followed by alignment padding to the alignment boundary of
+             *    the array element type, followed by each array element. The
+             *    array length is from the end of the alignment padding to
+             *    the end of the last element, i.e. it does not include the
+             *    padding after the length, or any padding after the last
+             *    element."
+             *
+             * Thus, we need to count how much padding the first element
+             * contributes and subtract that from the array length.
+             */
+            array_payload_begin_offset = g_memory_output_stream_get_data_size (mos);
+
+            if (g_variant_n_children (value) == 0)
+              {
+                gsize padding_added_for_item;
+                if (!append_value_to_blob (NULL,
+                                           g_variant_type_element (type),
+                                           mos,
+                                           dos,
+                                           &padding_added_for_item,
+                                           error))
+                  goto fail;
+                array_payload_begin_offset += padding_added_for_item;
+              }
+            else
+              {
+                guint n;
+                n = 0;
+                g_variant_iter_init (&iter, value);
+                while ((item = g_variant_iter_next_value (&iter)) != NULL)
+                  {
+                    gsize padding_added_for_item;
+                    if (!append_value_to_blob (item,
+                                               g_variant_get_type (item),
+                                               mos,
+                                               dos,
+                                               &padding_added_for_item,
+                                               error))
+                      {
+                        g_variant_unref (item);
+                        goto fail;
+                      }
+                    g_variant_unref (item);
+                    if (n == 0)
+                      {
+                        array_payload_begin_offset += padding_added_for_item;
+                      }
+                    n++;
+                  }
+              }
+
+            cur_offset = g_memory_output_stream_get_data_size (mos);
+            array_len = cur_offset - array_payload_begin_offset;
+            if (!g_seekable_seek (G_SEEKABLE (mos), array_len_offset, G_SEEK_SET, NULL, error))
+              goto fail;
+
+            g_data_output_stream_put_uint32 (dos, array_len, NULL, NULL);
+            if (!g_seekable_seek (G_SEEKABLE (mos), cur_offset, G_SEEK_SET, NULL, error))
+              goto fail;
+          }
+      }
+      break;
+
+    default:
+      if (g_variant_type_is_dict_entry (type) || g_variant_type_is_tuple (type))
         {
-          /* array length - will be filled in later */
-          array_len_offset = g_memory_output_stream_get_data_size (mos);
-          g_data_output_stream_put_uint32 (dos, 0xF00DFACE, NULL, NULL);
-
-          /* From the D-Bus spec:
-           *
-           *   "A UINT32 giving the length of the array data in bytes,
-           *    followed by alignment padding to the alignment boundary of
-           *    the array element type, followed by each array element. The
-           *    array length is from the end of the alignment padding to
-           *    the end of the last element, i.e. it does not include the
-           *    padding after the length, or any padding after the last
-           *    element."
-           *
-           * Thus, we need to count how much padding the first element
-           * contributes and subtract that from the array length.
-           */
-          array_payload_begin_offset = g_memory_output_stream_get_data_size (mos);
-
-          if (g_variant_n_children (value) == 0)
+          padding_added = ensure_output_padding (mos, dos, 8);
+          if (value != NULL)
             {
-              gsize padding_added_for_item;
-              if (!append_value_to_blob (NULL,
-                                         g_variant_type_element (type),
-                                         mos,
-                                         dos,
-                                         &padding_added_for_item,
-                                         error))
-                goto fail;
-              array_payload_begin_offset += padding_added_for_item;
-            }
-          else
-            {
-              guint n;
-              n = 0;
+              GVariant *item;
+              GVariantIter iter;
               g_variant_iter_init (&iter, value);
               while ((item = g_variant_iter_next_value (&iter)) != NULL)
                 {
-                  gsize padding_added_for_item;
                   if (!append_value_to_blob (item,
                                              g_variant_get_type (item),
                                              mos,
                                              dos,
-                                             &padding_added_for_item,
+                                             NULL,
                                              error))
                     {
                       g_variant_unref (item);
                       goto fail;
                     }
                   g_variant_unref (item);
-                  if (n == 0)
-                    {
-                      array_payload_begin_offset += padding_added_for_item;
-                    }
-                  n++;
                 }
             }
-
-          cur_offset = g_memory_output_stream_get_data_size (mos);
-
-          array_len = cur_offset - array_payload_begin_offset;
-
-          if (!g_seekable_seek (G_SEEKABLE (mos), array_len_offset, G_SEEK_SET, NULL, error))
-            goto fail;
-
-          g_data_output_stream_put_uint32 (dos, array_len, NULL, NULL);
-
-          if (!g_seekable_seek (G_SEEKABLE (mos), cur_offset, G_SEEK_SET, NULL, error))
-            goto fail;
         }
-    }
-  else if (g_variant_type_is_dict_entry (type) || g_variant_type_is_tuple (type))
-    {
-      padding_added = ensure_output_padding (mos, dos, 8);
-      if (value != NULL)
+      else if (g_variant_type_is_variant (type))
         {
-          GVariant *item;
-          GVariantIter iter;
-          g_variant_iter_init (&iter, value);
-          while ((item = g_variant_iter_next_value (&iter)) != NULL)
+          if (value != NULL)
             {
-              if (!append_value_to_blob (item,
-                                         g_variant_get_type (item),
+              GVariant *child;
+              const gchar *signature;
+              child = g_variant_get_child_value (value, 0);
+              signature = g_variant_get_type_string (child);
+              g_data_output_stream_put_byte (dos, strlen (signature), NULL, NULL);
+              g_data_output_stream_put_string (dos, signature, NULL, NULL);
+              g_data_output_stream_put_byte (dos, '\0', NULL, NULL);
+              if (!append_value_to_blob (child,
+                                         g_variant_get_type (child),
                                          mos,
                                          dos,
                                          NULL,
                                          error))
                 {
-                  g_variant_unref (item);
+                  g_variant_unref (child);
                   goto fail;
                 }
-              g_variant_unref (item);
+              g_variant_unref (child);
             }
         }
-    }
-  else if (g_variant_type_is_variant (type))
-    {
-      if (value != NULL)
+      else
         {
-          GVariant *child;
-          const gchar *signature;
-          child = g_variant_get_child_value (value, 0);
-          signature = g_variant_get_type_string (child);
-          g_data_output_stream_put_byte (dos, strlen (signature), NULL, NULL);
-          g_data_output_stream_put_string (dos, signature, NULL, NULL);
-          g_data_output_stream_put_byte (dos, '\0', NULL, NULL);
-          if (!append_value_to_blob (child,
-                                     g_variant_get_type (child),
-                                     mos,
-                                     dos,
-                                     NULL,
-                                     error))
-            {
-              g_variant_unref (child);
-              goto fail;
-            }
-          g_variant_unref (child);
+          g_set_error (error,
+                       G_IO_ERROR,
+                       G_IO_ERROR_INVALID_ARGUMENT,
+                       _("Error serializing GVariant with type string `%s' to the D-Bus wire format"),
+                       g_variant_get_type_string (value));
+          goto fail;
         }
-    }
-  else
-    {
-      g_set_error (error,
-                   G_IO_ERROR,
-                   G_IO_ERROR_INVALID_ARGUMENT,
-                   _("Error serializing GVariant with type string `%s' to the D-Bus wire format"),
-                   g_variant_get_type_string (value));
-      goto fail;
+      break;
     }
 
   if (out_padding_added != NULL)



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