gboolean g_value_compare(GValue * a, GValue * b) { if (a == NULL && b == NULL) return TRUE; if (a == NULL || b == NULL) return FALSE; if (G_VALUE_TYPE(a) != G_VALUE_TYPE(b)) return FALSE; if (g_value_fits_pointer(a) && g_value_fits_pointer(b)) { return g_value_peek_pointer(a) == g_value_peek_pointer(b); } else { /* Since there is no builtin comparison function, we resort to comparing serialized strings. Yuck. */ char * a_str; char * b_str; gboolean rval; a_str = g_strdup_value_contents(a); b_str = g_strdup_value_contents(b); rval = (0 == strcmp(a_str, b_str)); amfree(a_str); amfree(b_str); return rval; } g_assert_not_reached(); }
static gpointer value_as_pointer (GValue *value) { if (g_value_fits_pointer (value)) return g_value_peek_pointer (value); if (G_VALUE_HOLDS_BOOLEAN (value)) return (void*) g_value_get_boolean (value); if (G_VALUE_HOLDS_CHAR (value)) return (void*) (gssize) g_value_get_char (value); if (G_VALUE_HOLDS_UCHAR (value)) return (void*) (gsize) g_value_get_uchar (value); if (G_VALUE_HOLDS_INT (value)) return (void*) g_value_get_int (value); if (G_VALUE_HOLDS_UINT (value)) return (void*) g_value_get_uint (value); if (G_VALUE_HOLDS_LONG (value)) return (void*) g_value_get_long (value); if (G_VALUE_HOLDS_ULONG (value)) return (void*) g_value_get_ulong (value); if (G_VALUE_HOLDS_FLOAT (value)) return (void*) (gssize) g_value_get_float (value); if (G_VALUE_HOLDS_DOUBLE (value)) return (void*) (gssize) g_value_get_double (value); if (G_VALUE_HOLDS_ENUM (value)) return (void*) (gssize) g_value_get_enum (value); if (G_VALUE_HOLDS_FLAGS (value)) return (void*) (gsize) g_value_get_flags (value); return (void*) 0x1373babe; }
/** * 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_strdup_value_contents: * @value: #GValue which contents are to be described. * * Return a newly allocated string, which describes the contents of a * #GValue. The main purpose of this function is to describe #GValue * contents for debugging output, the way in which the contents are * described may change between different GLib versions. * * Returns: Newly allocated string. */ gchar* g_strdup_value_contents (const GValue *value) { const gchar *src; gchar *contents; g_return_val_if_fail (G_IS_VALUE (value), NULL); if (G_VALUE_HOLDS_STRING (value)) { src = g_value_get_string (value); if (!src) contents = g_strdup ("NULL"); else { gchar *s = g_strescape (src, NULL); contents = g_strdup_printf ("\"%s\"", s); g_free (s); } } else if (g_value_type_transformable (G_VALUE_TYPE (value), G_TYPE_STRING)) { GValue tmp_value = { 0, }; gchar *s; g_value_init (&tmp_value, G_TYPE_STRING); g_value_transform (value, &tmp_value); s = g_strescape (g_value_get_string (&tmp_value), NULL); g_value_unset (&tmp_value); if (G_VALUE_HOLDS_ENUM (value) || G_VALUE_HOLDS_FLAGS (value)) contents = g_strdup_printf ("((%s) %s)", g_type_name (G_VALUE_TYPE (value)), s); else contents = g_strdup (s ? s : "NULL"); g_free (s); } else if (g_value_fits_pointer (value)) { gpointer p = g_value_peek_pointer (value); if (!p) contents = g_strdup ("NULL"); else if (G_VALUE_HOLDS_OBJECT (value)) contents = g_strdup_printf ("((%s*) %p)", G_OBJECT_TYPE_NAME (p), p); else if (G_VALUE_HOLDS_PARAM (value)) contents = g_strdup_printf ("((%s*) %p)", G_PARAM_SPEC_TYPE_NAME (p), p); else if (G_VALUE_HOLDS (value, G_TYPE_STRV)) { GStrv strv = g_value_get_boxed (value); GString *tmp = g_string_new ("["); while (*strv != NULL) { gchar *escaped = g_strescape (*strv, NULL); g_string_append_printf (tmp, "\"%s\"", escaped); g_free (escaped); if (*++strv != NULL) g_string_append (tmp, ", "); } g_string_append (tmp, "]"); contents = g_string_free (tmp, FALSE); } else if (G_VALUE_HOLDS_BOXED (value)) contents = g_strdup_printf ("((%s*) %p)", g_type_name (G_VALUE_TYPE (value)), p); else if (G_VALUE_HOLDS_POINTER (value)) contents = g_strdup_printf ("((gpointer) %p)", p); else contents = g_strdup ("???"); } else contents = g_strdup ("???"); return contents; }