mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2025-08-22 08:58:54 +02:00
Add g_value_take_variant
Turns out we do need g_value_take_variant(), so we can correctly implement VARIANT:* marshalers. Bug #621947.
This commit is contained in:
@@ -58,6 +58,8 @@ struct _TestObjectClass
|
||||
gint param);
|
||||
gboolean (*test_signal2) (TestObject *tobject,
|
||||
gint param);
|
||||
GVariant* (*test_signal3) (TestObject *tobject,
|
||||
gboolean *weak_ptr);
|
||||
};
|
||||
|
||||
static GType test_object_get_type (void);
|
||||
@@ -155,11 +157,70 @@ test_object_signal2_callback_after (TestObject *tobject,
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
test_signal3_accumulator (GSignalInvocationHint *ihint,
|
||||
GValue *return_accu,
|
||||
const GValue *handler_return,
|
||||
gpointer data)
|
||||
{
|
||||
GVariant *variant;
|
||||
|
||||
variant = g_value_get_variant (handler_return);
|
||||
g_assert (!g_variant_is_floating (variant));
|
||||
|
||||
g_value_set_variant (return_accu, variant);
|
||||
|
||||
return variant == NULL;
|
||||
}
|
||||
|
||||
/* To be notified when the variant is finalised, we construct
|
||||
* it from data with a custom GDestroyNotify.
|
||||
*/
|
||||
|
||||
typedef struct {
|
||||
char *mem;
|
||||
gsize n;
|
||||
gboolean *weak_ptr;
|
||||
} VariantData;
|
||||
|
||||
static void
|
||||
free_data (VariantData *data)
|
||||
{
|
||||
*(data->weak_ptr) = TRUE;
|
||||
g_free (data->mem);
|
||||
g_slice_free (VariantData, data);
|
||||
}
|
||||
|
||||
static GVariant *
|
||||
test_object_real_signal3 (TestObject *tobject,
|
||||
gboolean *weak_ptr)
|
||||
{
|
||||
GVariant *variant;
|
||||
VariantData *data;
|
||||
|
||||
variant = g_variant_ref_sink (g_variant_new_uint32 (42));
|
||||
data = g_slice_new (VariantData);
|
||||
data->weak_ptr = weak_ptr;
|
||||
data->n = g_variant_get_size (variant);
|
||||
data->mem = g_malloc (data->n);
|
||||
g_variant_store (variant, data->mem);
|
||||
g_variant_unref (variant);
|
||||
|
||||
variant = g_variant_new_from_data (G_VARIANT_TYPE ("u"),
|
||||
data->mem,
|
||||
data->n,
|
||||
TRUE,
|
||||
(GDestroyNotify) free_data,
|
||||
data);
|
||||
return g_variant_ref_sink (variant);
|
||||
}
|
||||
|
||||
static void
|
||||
test_object_class_init (TestObjectClass *class)
|
||||
{
|
||||
class->test_signal1 = test_object_real_signal1;
|
||||
class->test_signal2 = test_object_real_signal2;
|
||||
class->test_signal3 = test_object_real_signal3;
|
||||
|
||||
g_signal_new ("test-signal1",
|
||||
G_OBJECT_CLASS_TYPE (class),
|
||||
@@ -175,6 +236,13 @@ test_object_class_init (TestObjectClass *class)
|
||||
g_signal_accumulator_true_handled, NULL,
|
||||
test_marshal_BOOLEAN__INT,
|
||||
G_TYPE_BOOLEAN, 1, G_TYPE_INT);
|
||||
g_signal_new ("test-signal3",
|
||||
G_OBJECT_CLASS_TYPE (class),
|
||||
G_SIGNAL_RUN_LAST,
|
||||
G_STRUCT_OFFSET (TestObjectClass, test_signal3),
|
||||
test_signal3_accumulator, NULL,
|
||||
test_marshal_VARIANT__POINTER,
|
||||
G_TYPE_VARIANT, 1, G_TYPE_POINTER);
|
||||
}
|
||||
|
||||
static DEFINE_TYPE(TestObject, test_object,
|
||||
@@ -188,6 +256,8 @@ main (int argc,
|
||||
TestObject *object;
|
||||
gchar *string_result;
|
||||
gboolean bool_result;
|
||||
gboolean variant_finalised;
|
||||
GVariant *variant_result;
|
||||
|
||||
g_log_set_always_fatal (g_log_set_always_fatal (G_LOG_FATAL_MASK) |
|
||||
G_LOG_LEVEL_WARNING |
|
||||
@@ -223,5 +293,16 @@ main (int argc,
|
||||
g_signal_emit_by_name (object, "test-signal2", 4, &bool_result);
|
||||
g_assert (bool_result == FALSE);
|
||||
|
||||
variant_finalised = FALSE;
|
||||
variant_result = NULL;
|
||||
g_signal_emit_by_name (object, "test-signal3", &variant_finalised, &variant_result);
|
||||
g_assert (variant_result != NULL);
|
||||
g_assert (!g_variant_is_floating (variant_result));
|
||||
|
||||
/* Test that variant_result had refcount 1 */
|
||||
g_assert (!variant_finalised);
|
||||
g_variant_unref (variant_result);
|
||||
g_assert (variant_finalised);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@@ -1,4 +1,4 @@
|
||||
# Marshallers used in tests
|
||||
BOOLEAN:INT
|
||||
STRING:INT
|
||||
|
||||
VARIANT:POINTER
|
||||
|
Reference in New Issue
Block a user