[glib] GVariant: avoid byteswapping in some cases
- From: Ryan Lortie <ryanl src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [glib] GVariant: avoid byteswapping in some cases
- Date: Mon, 4 Oct 2010 02:56:08 +0000 (UTC)
commit 2ce2d587edbeb98b355c4038c218d75a8c8f9c99
Author: Ryan Lortie <desrt desrt ca>
Date: Sun Oct 3 22:39:47 2010 -0400
GVariant: avoid byteswapping in some cases
Make g_variant_byteswap() merely return a new reference on the given
value in the event that we know that byteswapping will have no effect
(ie: types which have no alignment requirement).
This fixes a somewhat complicated interaction between GVariant,
GSettings and GVDB on big endian machines: GSettings assumes that it
can unref values returned from GVDB without losing access to the
underlying data. This only works if the underlying data is in the
mapped file -- not a freshly-allocated buffer that GVariant byteswapped
into.
glib/gvariant.c | 40 +++++++++++++++++++++++++++-------------
1 files changed, 27 insertions(+), 13 deletions(-)
---
diff --git a/glib/gvariant.c b/glib/gvariant.c
index f9eb851..e333597 100644
--- a/glib/gvariant.c
+++ b/glib/gvariant.c
@@ -4566,23 +4566,37 @@ g_variant_get_normal_form (GVariant *value)
GVariant *
g_variant_byteswap (GVariant *value)
{
- GVariantSerialised serialised;
- GVariant *trusted;
- GBuffer *buffer;
+ GVariantTypeInfo *type_info;
+ guint alignment;
GVariant *new;
- trusted = g_variant_get_normal_form (value);
- serialised.type_info = g_variant_get_type_info (trusted);
- serialised.size = g_variant_get_size (trusted);
- serialised.data = g_malloc (serialised.size);
- g_variant_store (trusted, serialised.data);
- g_variant_unref (trusted);
+ type_info = g_variant_get_type_info (value);
- g_variant_serialised_byteswap (serialised);
+ g_variant_type_info_query (type_info, &alignment, NULL);
- buffer = g_buffer_new_take_data (serialised.data, serialised.size);
- new = g_variant_new_from_buffer (g_variant_get_type (value), buffer, TRUE);
- g_buffer_unref (buffer);
+ if (alignment)
+ /* (potentially) contains multi-byte numeric data */
+ {
+ GVariantSerialised serialised;
+ GVariant *trusted;
+ GBuffer *buffer;
+
+ trusted = g_variant_get_normal_form (value);
+ serialised.type_info = g_variant_get_type_info (trusted);
+ serialised.size = g_variant_get_size (trusted);
+ serialised.data = g_malloc (serialised.size);
+ g_variant_store (trusted, serialised.data);
+ g_variant_unref (trusted);
+
+ g_variant_serialised_byteswap (serialised);
+
+ buffer = g_buffer_new_take_data (serialised.data, serialised.size);
+ new = g_variant_new_from_buffer (g_variant_get_type (value), buffer, TRUE);
+ g_buffer_unref (buffer);
+ }
+ else
+ /* contains no multi-byte data */
+ new = value;
return g_variant_ref_sink (new);
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]