X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=gobject%2Fgvalue.c;h=5277b777ec0b6a828f9b54315af55773acb84928;hb=9da85c7262325478e8730ae9f3e76bd0528a9a8c;hp=56d30c62b495148217570a1b94ffffde2a41fa0a;hpb=078dbda148a81af1b3a76fbda72f089b963087f1;p=platform%2Fupstream%2Fglib.git diff --git a/gobject/gvalue.c b/gobject/gvalue.c index 56d30c6..5277b77 100644 --- a/gobject/gvalue.c +++ b/gobject/gvalue.c @@ -35,9 +35,9 @@ * other type * @see_also: The fundamental types which all support #GValue * operations and thus can be used as a type initializer for - * g_value_init() are defined by a separate interface. See the Standard - * Values API for details. + * g_value_init() are defined by a separate interface. See the + * [standard values API][gobject-Standard-Parameter-and-Value-Types] + * for details * @title: Generic values * * The #GValue structure is basically a variable container that consists @@ -55,8 +55,8 @@ * The code in the example program below demonstrates #GValue's * features. * - * |[ - * #include <glib-object.h> + * |[ + * #include * * static void * int2string (const GValue *src_value, @@ -72,40 +72,40 @@ * main (int argc, * char *argv[]) * { - * /* GValues must be initialized */ + * // GValues must be initialized * GValue a = G_VALUE_INIT; * GValue b = G_VALUE_INIT; * const gchar *message; * - * /* The GValue starts empty */ - * g_assert (!G_VALUE_HOLDS_STRING (&a)); + * // The GValue starts empty + * g_assert (!G_VALUE_HOLDS_STRING (&a)); * - * /* Put a string in it */ - * g_value_init (&a, G_TYPE_STRING); - * g_assert (G_VALUE_HOLDS_STRING (&a)); - * g_value_set_static_string (&a, "Hello, world!"); - * g_printf ("%s\n", g_value_get_string (&a)); + * // Put a string in it + * g_value_init (&a, G_TYPE_STRING); + * g_assert (G_VALUE_HOLDS_STRING (&a)); + * g_value_set_static_string (&a, "Hello, world!"); + * g_printf ("%s\n", g_value_get_string (&a)); * - * /* Reset it to its pristine state */ - * g_value_unset (&a); + * // Reset it to its pristine state + * g_value_unset (&a); * - * /* It can then be reused for another type */ - * g_value_init (&a, G_TYPE_INT); - * g_value_set_int (&a, 42); + * // It can then be reused for another type + * g_value_init (&a, G_TYPE_INT); + * g_value_set_int (&a, 42); * - * /* Attempt to transform it into a GValue of type STRING */ - * g_value_init (&b, G_TYPE_STRING); + * // Attempt to transform it into a GValue of type STRING + * g_value_init (&b, G_TYPE_STRING); * - * /* An INT is transformable to a STRING */ + * // An INT is transformable to a STRING * g_assert (g_value_type_transformable (G_TYPE_INT, G_TYPE_STRING)); * - * g_value_transform (&a, &b); - * g_printf ("%s\n", g_value_get_string (&b)); + * g_value_transform (&a, &b); + * g_printf ("%s\n", g_value_get_string (&b)); * - * /* Attempt to transform it again using a custom transform function */ + * // Attempt to transform it again using a custom transform function * g_value_register_transform_func (G_TYPE_INT, G_TYPE_STRING, int2string); - * g_value_transform (&a, &b); - * g_printf ("%s\n", g_value_get_string (&b)); + * g_value_transform (&a, &b); + * g_printf ("%s\n", g_value_get_string (&b)); * return 0; * } * ]| @@ -296,12 +296,13 @@ g_value_fits_pointer (const GValue *value) /** * g_value_peek_pointer: - * @value: An initialized #GValue structure. + * @value: An initialized #GValue structure + * + * Returns the value contents as pointer. This function asserts that + * g_value_fits_pointer() returned %TRUE for the passed in value. + * This is an internal function introduced mainly for C marshallers. * - * Returns: (transfer none): the value contents as pointer. This - * function asserts that g_value_fits_pointer() returned %TRUE for the - * passed in value. This is an internal function introduced mainly - * for C marshallers. + * Returns: (transfer none): the value contents as pointer */ gpointer g_value_peek_pointer (const GValue *value) @@ -372,6 +373,71 @@ g_value_set_instance (GValue *value, } } +/** + * g_value_init_from_instance: + * @value: An uninitialized #GValue structure. + * @instance: the instance + * + * Initializes and sets @value from an instantiatable type via the + * value_table's collect_value() function. + * + * Note: The @value will be initialised with the exact type of + * @instance. If you wish to set the @value's type to a different GType + * (such as a parent class GType), you need to manually call + * g_value_init() and g_value_set_instance(). + * + * Since: 2.42 + */ +void +g_value_init_from_instance (GValue *value, + gpointer instance) +{ + g_return_if_fail (value != NULL && G_VALUE_TYPE(value) == 0); + + if (G_IS_OBJECT (instance)) + { + /* Fast-path. + * If G_IS_OBJECT() succeeds we know: + * * that instance is present and valid + * * that it is a GObject, and therefore we can directly + * use the collect implementation (g_object_ref) */ + value_meminit (value, G_TYPE_FROM_INSTANCE (instance)); + value->data[0].v_pointer = g_object_ref (instance); + } + else + { + GType g_type; + GTypeValueTable *value_table; + GTypeCValue cvalue; + gchar *error_msg; + + g_return_if_fail (G_TYPE_CHECK_INSTANCE (instance)); + + g_type = G_TYPE_FROM_INSTANCE (instance); + value_table = g_type_value_table_peek (g_type); + g_return_if_fail (strcmp (value_table->collect_format, "p") == 0); + + memset (&cvalue, 0, sizeof (cvalue)); + cvalue.v_pointer = instance; + + /* setup and collect */ + value_meminit (value, g_type); + value_table->value_init (value); + error_msg = value_table->collect_value (value, 1, &cvalue, 0); + if (error_msg) + { + g_warning ("%s: %s", G_STRLOC, error_msg); + g_free (error_msg); + + /* we purposely leak the value here, it might not be + * in a sane state if an error condition occoured + */ + value_meminit (value, g_type); + value_table->value_init (value); + } + } +} + static GValueTransform transform_func_lookup (GType src_type, GType dest_type)