/** * g_value_init: * @value: A zero-filled (uninitialized) #GValue structure. * @g_type: Type the #GValue should hold values of. * * Initializes @value with the default value of @type. * * Returns: (transfer none): the #GValue structure that has been passed in */ GValue* g_value_init (GValue *value, GType g_type) { /* g_return_val_if_fail (G_TYPE_IS_VALUE (g_type), NULL); be more elaborate below */ g_return_val_if_fail (value != NULL, NULL); /* g_return_val_if_fail (G_VALUE_TYPE (value) == 0, NULL); be more elaborate below */ if (G_TYPE_IS_VALUE (g_type) && G_VALUE_TYPE (value) == 0) { GTypeValueTable *value_table = g_type_value_table_peek (g_type); /* setup and init */ value_meminit (value, g_type); value_table->value_init (value); } else if (G_VALUE_TYPE (value)) g_warning ("%s: cannot initialize GValue with type '%s', the value has already been initialized as '%s'", G_STRLOC, g_type_name (g_type), g_type_name (G_VALUE_TYPE (value))); else /* !G_TYPE_IS_VALUE (g_type) */ g_warning ("%s: cannot initialize GValue with type '%s', %s", G_STRLOC, g_type_name (g_type), g_type_value_table_peek (g_type) ? "this type is abstract with regards to GValue use, use a more specific (derived) type" : "this type has no GTypeValueTable implementation"); return value; }
static GValueTransform transform_func_lookup (GType src_type, GType dest_type) { TransformEntry entry; entry.src_type = src_type; do { entry.dest_type = dest_type; do { TransformEntry *e; e = g_bsearch_array_lookup (transform_array, &transform_bconfig, &entry); if (e) { /* need to check that there hasn't been a change in value handling */ if (g_type_value_table_peek (entry.dest_type) == g_type_value_table_peek (dest_type) && g_type_value_table_peek (entry.src_type) == g_type_value_table_peek (src_type)) return e->func; } entry.dest_type = g_type_parent (entry.dest_type); } while (entry.dest_type); entry.src_type = g_type_parent (entry.src_type); } while (entry.src_type); return NULL; }
/** * g_value_type_compatible: * @src_type: source type to be copied. * @dest_type: destination type for copying. * * Returns whether a #GValue of type @src_type can be copied into * a #GValue of type @dest_type. * * Returns: %TRUE if g_value_copy() is possible with @src_type and @dest_type. */ gboolean g_value_type_compatible (GType src_type, GType dest_type) { g_return_val_if_fail (G_TYPE_IS_VALUE (src_type), FALSE); g_return_val_if_fail (G_TYPE_IS_VALUE (dest_type), FALSE); return (g_type_is_a (src_type, dest_type) && g_type_value_table_peek (dest_type) == g_type_value_table_peek (src_type)); }
/** * g_boxed_free: * @boxed_type: The type of @boxed. * @boxed: The boxed structure to be freed. * * Free the boxed structure @boxed which is of type @boxed_type. */ void g_boxed_free (GType boxed_type, gpointer boxed) { GTypeValueTable *value_table; g_return_if_fail (G_TYPE_IS_BOXED (boxed_type)); g_return_if_fail (G_TYPE_IS_ABSTRACT (boxed_type) == FALSE); g_return_if_fail (boxed != NULL); value_table = g_type_value_table_peek (boxed_type); if (!value_table) g_return_if_fail (G_TYPE_IS_VALUE_TYPE (boxed_type)); /* check if our proxying implementation is used, we can short-cut here */ if (value_table->value_free == boxed_proxy_value_free) { BoxedNode key, *node; key.type = boxed_type; node = g_bsearch_array_lookup (boxed_bsa, &boxed_bconfig, &key); node->free (boxed); } else { GValue value; /* see g_boxed_copy() on why we think we can do this */ value_meminit (&value, boxed_type); value.data[0].v_pointer = boxed; value_table->value_free (&value); } }
gpointer g_boxed_copy (GType boxed_type, gconstpointer src_boxed) { GTypeValueTable *value_table; gpointer dest_boxed; g_return_val_if_fail (G_TYPE_IS_BOXED (boxed_type), NULL); g_return_val_if_fail (G_TYPE_IS_ABSTRACT (boxed_type) == FALSE, NULL); g_return_val_if_fail (src_boxed != NULL, NULL); value_table = g_type_value_table_peek (boxed_type); if (!value_table) g_return_val_if_fail (G_TYPE_IS_VALUE_TYPE (boxed_type), NULL); /* check if our proxying implementation is used, we can short-cut here */ if (value_table->value_copy == boxed_proxy_value_copy) { BoxedNode key, *node; key.type = boxed_type; node = g_bsearch_array_lookup (boxed_bsa, &boxed_bconfig, &key); dest_boxed = node->copy ((gpointer) src_boxed); } else { GValue src_value, dest_value; /* we heavil rely on third-party boxed type value vtable * implementations to follow normal boxed value storage * (data[0].v_pointer is the boxed struct, and * data[1].v_uint holds the G_VALUE_NOCOPY_CONTENTS flag, * rest zero). * but then, we can expect that since we layed out the * g_boxed_*() API. * data[1].v_uint&G_VALUE_NOCOPY_CONTENTS shouldn't be set * after a copy. */ /* equiv. to g_value_set_static_boxed() */ value_meminit (&src_value, boxed_type); src_value.data[0].v_pointer = (gpointer) src_boxed; src_value.data[1].v_uint = G_VALUE_NOCOPY_CONTENTS; /* call third-party code copy fucntion, fingers-crossed */ value_meminit (&dest_value, boxed_type); value_table->value_copy (&src_value, &dest_value); /* double check and grouse if things went wrong */ if (dest_value.data[1].v_ulong || dest_value.data[2].v_ulong) g_warning ("the copy_value() implementation of type `%s' seems to make use of reserved GValue fields", g_type_name (boxed_type)); dest_boxed = dest_value.data[0].v_pointer; } return dest_boxed; }
/** * g_value_fits_pointer: * @value: An initialized #GValue structure. * * Determines if @value will fit inside the size of a pointer value. * This is an internal function introduced mainly for C marshallers. * * Returns: %TRUE if @value will fit inside a pointer value. */ gboolean g_value_fits_pointer (const GValue *value) { GTypeValueTable *value_table; g_return_val_if_fail (G_IS_VALUE (value), FALSE); value_table = g_type_value_table_peek (G_VALUE_TYPE (value)); return value_table->value_peek_pointer != NULL; }
/** * g_value_unset: * @value: An initialized #GValue structure. * * Clears the current value in @value and "unsets" the type, * this releases all resources associated with this GValue. * An unset value is the same as an uninitialized (zero-filled) * #GValue structure. */ void g_value_unset (GValue *value) { GTypeValueTable *value_table; g_return_if_fail (G_IS_VALUE (value)); value_table = g_type_value_table_peek (G_VALUE_TYPE (value)); if (value_table->value_free) value_table->value_free (value); memset (value, 0, sizeof (*value)); }
/** * g_value_init_from_instance: * @value: An uninitialized #GValue structure. * @instance: (type GObject.TypeInstance): 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); } } }
/** * g_value_peek_pointer: * @value: An initialized #GValue structure. * * 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. */ gpointer g_value_peek_pointer (const GValue *value) { GTypeValueTable *value_table; g_return_val_if_fail (G_IS_VALUE (value), NULL); value_table = g_type_value_table_peek (G_VALUE_TYPE (value)); if (!value_table->value_peek_pointer) { g_return_val_if_fail (g_value_fits_pointer (value) == TRUE, NULL); return NULL; } return value_table->value_peek_pointer (value); }
/** * g_value_set_instance: * @value: An initialized #GValue structure. * @instance: (allow-none): the instance * * Sets @value from an instantiatable type via the * value_table's collect_value() function. */ void g_value_set_instance (GValue *value, gpointer instance) { GType g_type; GTypeValueTable *value_table; GTypeCValue cvalue; gchar *error_msg; g_return_if_fail (G_IS_VALUE (value)); if (instance) { g_return_if_fail (G_TYPE_CHECK_INSTANCE (instance)); g_return_if_fail (g_value_type_compatible (G_TYPE_FROM_INSTANCE (instance), G_VALUE_TYPE (value))); } g_type = G_VALUE_TYPE (value); 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; /* make sure value's value is free()d */ if (value_table->value_free) value_table->value_free (value); /* setup and collect */ value_meminit (value, g_type); 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); } }
/** * g_value_reset: * @value: An initialized #GValue structure. * * Clears the current value in @value and resets it to the default value * (as if the value had just been initialized). * * Returns: the #GValue structure that has been passed in */ GValue* g_value_reset (GValue *value) { GTypeValueTable *value_table; GType g_type; g_return_val_if_fail (G_IS_VALUE (value), NULL); g_type = G_VALUE_TYPE (value); value_table = g_type_value_table_peek (g_type); /* make sure value's value is free()d */ if (value_table->value_free) value_table->value_free (value); /* setup and init */ value_meminit (value, g_type); value_table->value_init (value); return value; }
/** * g_value_copy: * @src_value: An initialized #GValue structure. * @dest_value: An initialized #GValue structure of the same type as @src_value. * * Copies the value of @src_value into @dest_value. */ void g_value_copy (const GValue *src_value, GValue *dest_value) { g_return_if_fail (G_IS_VALUE (src_value)); g_return_if_fail (G_IS_VALUE (dest_value)); g_return_if_fail (g_value_type_compatible (G_VALUE_TYPE (src_value), G_VALUE_TYPE (dest_value))); if (src_value != dest_value) { GType dest_type = G_VALUE_TYPE (dest_value); GTypeValueTable *value_table = g_type_value_table_peek (dest_type); /* make sure dest_value's value is free()d */ if (value_table->value_free) value_table->value_free (dest_value); /* setup and copy */ value_meminit (dest_value, dest_type); value_table->value_copy (src_value, dest_value); } }