From f4d858c069f06e7060a0bb067c29f5bffb7869ee Mon Sep 17 00:00:00 2001 From: Aurelien Jarno Date: Wed, 31 Aug 2016 22:16:06 +0200 Subject: Fix list/hashtable enum <-> hash conversion on 64-bit big endian glist and ghashtable objects both store pointers. Complex objects are stored as pointers to the objects, but simpler objects like an integer value are stored directly as a pointer, using for example the GINT_TO_POINTER and GPOINTER_TO_INT macros. This is done in pygobject with the _pygi_hash_pointer_to_arg and _pygi_arg_to_hash_pointer functions. These functions handle the various type of objects. However they consider that an enum, represented with the GI_TYPE_TAG_INTERFACE type (extended interface object), are always a pointer. This is wrong as it is often a 32-bit value. Therefore on 64-bit big endian machines, the value is handle with the 2 32-bit parts swapped. This patches fixes that by changing the second argument of both functions from GITypeTag to GITypeInfo. This way the interface can be determined, and the underlying storage type can also be determined. This currently only handles enum and flags, leaving other types as pointers. The patch also adds two tests in the testsuite, one for each direction. https://bugzilla.gnome.org/show_bug.cgi?id=770608 --- tests/gimarshallingtestsextra.c | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) (limited to 'tests/gimarshallingtestsextra.c') diff --git a/tests/gimarshallingtestsextra.c b/tests/gimarshallingtestsextra.c index 9624077d..56b0113a 100644 --- a/tests/gimarshallingtestsextra.c +++ b/tests/gimarshallingtestsextra.c @@ -35,3 +35,36 @@ gi_marshalling_tests_compare_two_gerrors_in_gvalue (GValue *v, GValue *v1) g_assert_cmpint (error->code, ==, error1->code); g_assert_cmpstr (error->message, ==, error1->message); } + +/** + * gi_marshalling_tests_ghashtable_enum_none_in: + * @hash_table: (element-type gint GIMarshallingTestsExtraEnum) (transfer none): + */ +void +gi_marshalling_tests_ghashtable_enum_none_in (GHashTable *hash_table) +{ + g_assert_cmpint (GPOINTER_TO_INT (g_hash_table_lookup (hash_table, GINT_TO_POINTER (1))), ==, GI_MARSHALLING_TESTS_EXTRA_ENUM_VALUE1); + g_assert_cmpint (GPOINTER_TO_INT (g_hash_table_lookup (hash_table, GINT_TO_POINTER (2))), ==, GI_MARSHALLING_TESTS_EXTRA_ENUM_VALUE2); + g_assert_cmpint (GPOINTER_TO_INT (g_hash_table_lookup (hash_table, GINT_TO_POINTER (3))), ==, GI_MARSHALLING_TESTS_EXTRA_ENUM_VALUE3); +} + +/** + * gi_marshalling_tests_ghashtable_enum_none_return: + * + * Returns: (element-type gint GIMarshallingTestsExtraEnum) (transfer none): + */ +GHashTable * +gi_marshalling_tests_ghashtable_enum_none_return (void) +{ + static GHashTable *hash_table = NULL; + + if (hash_table == NULL) + { + hash_table = g_hash_table_new (NULL, NULL); + g_hash_table_insert (hash_table, GINT_TO_POINTER (1), GINT_TO_POINTER (GI_MARSHALLING_TESTS_EXTRA_ENUM_VALUE1)); + g_hash_table_insert (hash_table, GINT_TO_POINTER (2), GINT_TO_POINTER (GI_MARSHALLING_TESTS_EXTRA_ENUM_VALUE2)); + g_hash_table_insert (hash_table, GINT_TO_POINTER (3), GINT_TO_POINTER (GI_MARSHALLING_TESTS_EXTRA_ENUM_VALUE3)); + } + + return hash_table; +} -- cgit v1.2.1