mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2025-03-28 02:20:04 +01:00
Merge branch 'issue-737' into 'master'
Allow calling get_property() with an uninitialized GValue Closes #737 See merge request GNOME/glib!892
This commit is contained in:
commit
2ac3cf8222
@ -2565,9 +2565,15 @@ g_object_set_property (GObject *object,
|
||||
* @property_name: the name of the property to get
|
||||
* @value: return location for the property value
|
||||
*
|
||||
* Gets a property of an object. @value must have been initialized to the
|
||||
* expected type of the property (or a type to which the expected type can be
|
||||
* transformed) using g_value_init().
|
||||
* Gets a property of an object.
|
||||
*
|
||||
* The @value can be:
|
||||
*
|
||||
* - an empty #GValue initialized by %G_VALUE_INIT, which will be
|
||||
* automatically initialized with the expected type of the property
|
||||
* - a #GValue initialized with the expected type of the property
|
||||
* - a #GValue initialized with a type to which the expected type
|
||||
* of the property can be transformed
|
||||
*
|
||||
* In general, a copy is made of the property contents and the caller is
|
||||
* responsible for freeing the memory by calling g_value_unset().
|
||||
@ -2584,7 +2590,7 @@ g_object_get_property (GObject *object,
|
||||
|
||||
g_return_if_fail (G_IS_OBJECT (object));
|
||||
g_return_if_fail (property_name != NULL);
|
||||
g_return_if_fail (G_IS_VALUE (value));
|
||||
g_return_if_fail (value != NULL);
|
||||
|
||||
g_object_ref (object);
|
||||
|
||||
@ -2597,33 +2603,38 @@ g_object_get_property (GObject *object,
|
||||
{
|
||||
GValue *prop_value, tmp_value = G_VALUE_INIT;
|
||||
|
||||
/* auto-conversion of the callers value type
|
||||
*/
|
||||
if (G_VALUE_TYPE (value) == pspec->value_type)
|
||||
{
|
||||
g_value_reset (value);
|
||||
prop_value = value;
|
||||
}
|
||||
if (G_VALUE_TYPE (value) == G_TYPE_INVALID)
|
||||
{
|
||||
/* uninitialized value */
|
||||
g_value_init (value, pspec->value_type);
|
||||
prop_value = value;
|
||||
}
|
||||
else if (G_VALUE_TYPE (value) == pspec->value_type)
|
||||
{
|
||||
/* auto-conversion of the callers value type */
|
||||
g_value_reset (value);
|
||||
prop_value = value;
|
||||
}
|
||||
else if (!g_value_type_transformable (pspec->value_type, G_VALUE_TYPE (value)))
|
||||
{
|
||||
g_warning ("%s: can't retrieve property '%s' of type '%s' as value of type '%s'",
|
||||
G_STRFUNC, pspec->name,
|
||||
g_type_name (pspec->value_type),
|
||||
G_VALUE_TYPE_NAME (value));
|
||||
g_object_unref (object);
|
||||
return;
|
||||
}
|
||||
{
|
||||
g_warning ("%s: can't retrieve property '%s' of type '%s' as value of type '%s'",
|
||||
G_STRFUNC, pspec->name,
|
||||
g_type_name (pspec->value_type),
|
||||
G_VALUE_TYPE_NAME (value));
|
||||
g_object_unref (object);
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
g_value_init (&tmp_value, pspec->value_type);
|
||||
prop_value = &tmp_value;
|
||||
}
|
||||
{
|
||||
g_value_init (&tmp_value, pspec->value_type);
|
||||
prop_value = &tmp_value;
|
||||
}
|
||||
object_get_property (object, pspec, prop_value);
|
||||
if (prop_value != value)
|
||||
{
|
||||
g_value_transform (prop_value, value);
|
||||
g_value_unset (&tmp_value);
|
||||
}
|
||||
{
|
||||
g_value_transform (prop_value, value);
|
||||
g_value_unset (&tmp_value);
|
||||
}
|
||||
}
|
||||
|
||||
g_object_unref (object);
|
||||
|
@ -541,6 +541,51 @@ properties_testv_getv (void)
|
||||
g_object_unref (test_obj);
|
||||
}
|
||||
|
||||
static void
|
||||
properties_get_property (void)
|
||||
{
|
||||
TestObject *test_obj;
|
||||
struct {
|
||||
const char *name;
|
||||
GType gtype;
|
||||
GValue value;
|
||||
} test_props[] = {
|
||||
{ "foo", G_TYPE_INT, G_VALUE_INIT },
|
||||
{ "bar", G_TYPE_INVALID, G_VALUE_INIT },
|
||||
{ "bar", G_TYPE_STRING, G_VALUE_INIT },
|
||||
};
|
||||
int i;
|
||||
|
||||
g_test_summary ("g_object_get_property() accepts uninitialized, "
|
||||
"initialized, and transformable values");
|
||||
|
||||
for (i = 0; i < G_N_ELEMENTS (test_props); i++)
|
||||
{
|
||||
if (test_props[i].gtype != G_TYPE_INVALID)
|
||||
g_value_init (&(test_props[i].value), test_props[i].gtype);
|
||||
}
|
||||
|
||||
test_obj = (TestObject *) g_object_new_with_properties (test_object_get_type (), 0, NULL, NULL);
|
||||
|
||||
g_test_message ("Test g_object_get_property with an initialized value");
|
||||
g_object_get_property (G_OBJECT (test_obj), test_props[0].name, &(test_props[0].value));
|
||||
g_assert_cmpint (g_value_get_int (&(test_props[0].value)), ==, 42);
|
||||
|
||||
g_test_message ("Test g_object_get_property with an uninitialized value");
|
||||
g_object_get_property (G_OBJECT (test_obj), test_props[1].name, &(test_props[1].value));
|
||||
g_assert_true (g_value_get_boolean (&(test_props[1].value)));
|
||||
|
||||
g_test_message ("Test g_object_get_property with a transformable value");
|
||||
g_object_get_property (G_OBJECT (test_obj), test_props[2].name, &(test_props[2].value));
|
||||
g_assert_true (G_VALUE_HOLDS_STRING (&(test_props[2].value)));
|
||||
g_assert_cmpstr (g_value_get_string (&(test_props[2].value)), ==, "TRUE");
|
||||
|
||||
for (i = 0; i < G_N_ELEMENTS (test_props); i++)
|
||||
g_value_unset (&(test_props[i].value));
|
||||
|
||||
g_object_unref (test_obj);
|
||||
}
|
||||
|
||||
static void
|
||||
properties_testv_notify_queue (void)
|
||||
{
|
||||
@ -599,6 +644,7 @@ main (int argc, char *argv[])
|
||||
g_test_add_func ("/properties/notify", properties_notify);
|
||||
g_test_add_func ("/properties/notify-queue", properties_notify_queue);
|
||||
g_test_add_func ("/properties/construct", properties_construct);
|
||||
g_test_add_func ("/properties/get-property", properties_get_property);
|
||||
|
||||
g_test_add_func ("/properties/testv_with_no_properties",
|
||||
properties_testv_with_no_properties);
|
||||
|
Loading…
x
Reference in New Issue
Block a user