mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2025-02-24 03:02:10 +01:00
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.
This commit is contained in:
parent
63adeda086
commit
2ce2d587ed
@ -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);
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user