[glib] GDBusMessage: Optimize serializer and deserializer
- From: David Zeuthen <davidz src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [glib] GDBusMessage: Optimize serializer and deserializer
- Date: Tue, 14 Jun 2011 22:12:31 +0000 (UTC)
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]