1 /* GObject - GLib Type, Object, Parameter and Signal Library
2 * Copyright (C) 1997, 1998, 1999, 2000 Tim Janik and Red Hat, Inc.
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General
15 * Public License along with this library; if not, write to the
16 * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
17 * Boston, MA 02111-1307, USA.
22 /* --- typedefs & structures --- */
32 /* --- variables --- */
33 static GHashTable *param_exchange_ht = NULL;
36 /* --- functions --- */
38 g_value_init (GValue *value,
41 GTypeValueTable *value_table = g_type_value_table_peek (g_type);
43 g_return_if_fail (value != NULL);
44 g_return_if_fail (G_VALUE_TYPE (value) == 0);
48 memset (value, 0, sizeof (*value));
49 value->g_type = g_type;
50 value_table->value_init (value);
53 g_warning (G_STRLOC ": cannot initialize value of type `%s' which has no GTypeValueTable",
54 g_type_name (g_type));
58 g_value_copy (const GValue *src_value,
61 GTypeValueTable *value_table = g_type_value_table_peek (G_VALUE_TYPE (dest_value));
63 g_return_if_fail (G_IS_VALUE (src_value));
64 g_return_if_fail (G_IS_VALUE (dest_value));
65 g_return_if_fail (g_type_is_a (G_VALUE_TYPE (src_value), G_VALUE_TYPE (dest_value)));
67 g_return_if_fail (g_type_value_table_peek (G_VALUE_TYPE (dest_value)) != NULL);
69 if (src_value != dest_value)
71 /* make sure dest_value's value is free()d and zero initialized */
72 g_value_reset (dest_value);
74 value_table->value_copy (src_value, dest_value);
79 g_value_unset (GValue *value)
81 GTypeValueTable *value_table = g_type_value_table_peek (G_VALUE_TYPE (value));
83 g_return_if_fail (G_IS_VALUE (value));
85 g_return_if_fail (g_type_value_table_peek (G_VALUE_TYPE (value)) != NULL);
87 if (value_table->value_free)
88 value_table->value_free (value);
89 memset (value, 0, sizeof (*value));
93 g_value_reset (GValue *value)
95 GTypeValueTable *value_table = g_type_value_table_peek (G_VALUE_TYPE (value));
98 g_return_if_fail (G_IS_VALUE (value));
100 g_type = G_VALUE_TYPE (value);
102 if (value_table->value_free)
103 value_table->value_free (value);
104 memset (value, 0, sizeof (*value));
106 value->g_type = g_type;
107 value_table->value_init (value);
111 exchange_entries_equal (gconstpointer v1,
114 const ExchangeEntry *entry1 = v1;
115 const ExchangeEntry *entry2 = v2;
117 return (entry1->value_type1 == entry2->value_type1 &&
118 entry1->value_type2 == entry2->value_type2);
122 exchange_entry_hash (gconstpointer key)
124 const ExchangeEntry *entry = key;
126 return entry->value_type1 ^ entry->value_type2;
130 value_exchange_memcpy (GValue *value1,
135 memcpy (&tmp_value.data, &value1->data, sizeof (value1->data));
136 memcpy (&value1->data, &value2->data, sizeof (value1->data));
137 memcpy (&value2->data, &tmp_value.data, sizeof (value2->data));
140 static inline GValueExchange
141 exchange_func_lookup (GType value_type1,
145 if (value_type1 == value_type2)
146 return value_exchange_memcpy;
149 GType type1 = value_type1;
153 GType type2 = value_type2;
157 ExchangeEntry entry, *ret;
159 entry.value_type1 = MIN (type1, type2);
160 entry.value_type2 = MAX (type1, type2);
161 ret = g_hash_table_lookup (param_exchange_ht, &entry);
165 *need_swap = ret->first_type == type2;
170 type2 = g_type_parent (type2);
174 type1 = g_type_parent (type1);
183 g_value_register_exchange_func (GType value_type1,
189 g_return_if_fail (G_TYPE_IS_VALUE (value_type1));
190 g_return_if_fail (G_TYPE_IS_VALUE (value_type2));
191 g_return_if_fail (func != NULL);
193 entry.value_type1 = MIN (value_type1, value_type2);
194 entry.value_type2 = MAX (value_type1, value_type2);
195 if (param_exchange_ht && g_hash_table_lookup (param_exchange_ht, &entry))
196 g_warning (G_STRLOC ": cannot re-register param value exchange function "
198 g_type_name (value_type1),
199 g_type_name (value_type2));
202 ExchangeEntry *entry = g_new (ExchangeEntry, 1);
204 if (!param_exchange_ht)
205 param_exchange_ht = g_hash_table_new (exchange_entry_hash, exchange_entries_equal);
206 entry->value_type1 = MIN (value_type1, value_type2);
207 entry->value_type2 = MAX (value_type1, value_type2);
209 entry->first_type = value_type1;
210 g_hash_table_insert (param_exchange_ht, entry, entry);
215 g_value_types_exchangable (GType value_type1,
218 g_return_val_if_fail (G_TYPE_IS_VALUE (value_type1), FALSE);
219 g_return_val_if_fail (G_TYPE_IS_VALUE (value_type2), FALSE);
221 return exchange_func_lookup (value_type1, value_type2, NULL) != NULL;
225 g_values_exchange (GValue *value1,
228 g_return_val_if_fail (G_IS_VALUE (value1), FALSE);
229 g_return_val_if_fail (G_IS_VALUE (value2), FALSE);
231 if (value1 != value2)
234 GValueExchange value_exchange = exchange_func_lookup (G_VALUE_TYPE (value1),
235 G_VALUE_TYPE (value2),
240 value_exchange (value2, value1);
242 value_exchange (value1, value2);
245 return value_exchange != NULL;
252 g_value_convert (const GValue *src_value,
255 gboolean success = TRUE;
257 g_return_val_if_fail (G_IS_VALUE (src_value), FALSE);
258 g_return_val_if_fail (G_IS_VALUE (dest_value), FALSE);
260 if (src_value != dest_value)
262 GValue tmp_value = { 0, };
264 g_value_init (&tmp_value, G_VALUE_TYPE (src_value));
265 g_value_copy (src_value, &tmp_value);
267 success = g_values_exchange (&tmp_value, dest_value);
268 g_value_unset (&tmp_value);