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.
27 #include "gvaluecollector.h"
30 /* --- typedefs & structures --- */
40 /* --- variables --- */
41 static GHashTable *param_exchange_ht = NULL;
44 /* --- functions --- */
46 g_value_init (GValue *value,
49 GTypeValueTable *value_table = g_type_value_table_peek (g_type);
51 g_return_if_fail (value != NULL);
52 g_return_if_fail (G_VALUE_TYPE (value) == 0);
56 memset (value, 0, sizeof (*value));
57 value->g_type = g_type;
58 value_table->value_init (value);
61 g_warning (G_STRLOC ": cannot initialize value of type `%s' which has no GTypeValueTable",
62 g_type_name (g_type));
66 g_value_copy (const GValue *src_value,
69 GTypeValueTable *value_table;
71 g_return_if_fail (G_IS_VALUE (src_value));
72 g_return_if_fail (G_IS_VALUE (dest_value));
73 g_return_if_fail (g_type_is_a (G_VALUE_TYPE (src_value), G_VALUE_TYPE (dest_value)));
75 value_table = g_type_value_table_peek (G_VALUE_TYPE (dest_value));
77 g_return_if_fail (g_type_value_table_peek (G_VALUE_TYPE (dest_value)) != NULL);
79 if (src_value != dest_value)
81 /* make sure dest_value's value is free()d and zero initialized */
82 g_value_reset (dest_value);
84 value_table->value_copy (src_value, dest_value);
89 g_value_fits_pointer (const GValue *value)
91 GTypeValueTable *value_table;
93 g_return_val_if_fail (G_IS_VALUE (value), FALSE);
95 value_table = g_type_value_table_peek (G_VALUE_TYPE (value));
97 g_return_val_if_fail (g_type_value_table_peek (G_VALUE_TYPE (value)) != NULL, FALSE);
99 return value_table->value_peek_pointer != NULL;
103 g_value_get_as_pointer (const GValue *value)
105 GTypeValueTable *value_table;
107 g_return_val_if_fail (G_IS_VALUE (value), NULL);
109 value_table = g_type_value_table_peek (G_VALUE_TYPE (value));
111 g_return_val_if_fail (g_type_value_table_peek (G_VALUE_TYPE (value)) != NULL, NULL);
112 if (!value_table->value_peek_pointer)
113 g_return_val_if_fail (g_value_fits_pointer (value) == TRUE, NULL);
115 return value_table->value_peek_pointer (value);
119 g_value_set_instance (GValue *value,
122 g_return_if_fail (G_IS_VALUE (value));
124 g_value_reset (value);
127 GType g_type = G_VALUE_TYPE (value);
128 GTypeValueTable *value_table = g_type_value_table_peek (g_type);
129 GTypeCValue cvalue = { 0, };
131 guint collect_type = value_table->collect_type;
134 g_return_if_fail (G_TYPE_CHECK_INSTANCE (instance));
135 g_return_if_fail (g_type_is_a (G_TYPE_FROM_INSTANCE (instance), G_VALUE_TYPE (value)));
136 g_return_if_fail (value_table->collect_type == G_VALUE_COLLECT_POINTER);
138 cvalue.v_pointer = instance;
139 error_msg = value_table->collect_value (value, nth_value++, &collect_type, &cvalue);
141 /* this shouldn't be triggered, instance types should collect just one pointer,
142 * but since we have to follow the calling conventions for collect_value(),
143 * we can attempt to feed them with 0s if they insist on extra args.
145 while (collect_type && !error_msg)
147 memset (&cvalue, 0, sizeof (cvalue));
148 error_msg = value_table->collect_value (value, nth_value++, &collect_type, &cvalue);
153 g_warning ("%s: %s", G_STRLOC, error_msg);
156 /* we purposely leak the value here, it might not be
157 * in a sane state if an error condition occoured
159 memset (value, 0, sizeof (*value));
160 value->g_type = g_type;
161 value_table->value_init (value);
167 g_value_unset (GValue *value)
169 GTypeValueTable *value_table = g_type_value_table_peek (G_VALUE_TYPE (value));
171 g_return_if_fail (G_IS_VALUE (value));
173 g_return_if_fail (g_type_value_table_peek (G_VALUE_TYPE (value)) != NULL);
175 if (value_table->value_free)
176 value_table->value_free (value);
177 memset (value, 0, sizeof (*value));
181 g_value_reset (GValue *value)
183 GTypeValueTable *value_table;
186 g_return_if_fail (G_IS_VALUE (value));
188 value_table = g_type_value_table_peek (G_VALUE_TYPE (value));
189 g_type = G_VALUE_TYPE (value);
191 if (value_table->value_free)
192 value_table->value_free (value);
193 memset (value, 0, sizeof (*value));
195 value->g_type = g_type;
196 value_table->value_init (value);
200 exchange_entries_equal (gconstpointer v1,
203 const ExchangeEntry *entry1 = v1;
204 const ExchangeEntry *entry2 = v2;
206 return (entry1->value_type1 == entry2->value_type1 &&
207 entry1->value_type2 == entry2->value_type2);
211 exchange_entry_hash (gconstpointer key)
213 const ExchangeEntry *entry = key;
215 return entry->value_type1 ^ entry->value_type2;
219 value_exchange_memcpy (GValue *value1,
224 memcpy (&tmp_value.data, &value1->data, sizeof (value1->data));
225 memcpy (&value1->data, &value2->data, sizeof (value1->data));
226 memcpy (&value2->data, &tmp_value.data, sizeof (value2->data));
229 static inline GValueExchange
230 exchange_func_lookup (GType value_type1,
234 if (value_type1 == value_type2)
235 return value_exchange_memcpy;
238 GType type1 = value_type1;
242 GType type2 = value_type2;
246 ExchangeEntry entry, *ret;
248 entry.value_type1 = MIN (type1, type2);
249 entry.value_type2 = MAX (type1, type2);
250 ret = g_hash_table_lookup (param_exchange_ht, &entry);
254 *need_swap = ret->first_type == type2;
259 type2 = g_type_parent (type2);
263 type1 = g_type_parent (type1);
272 g_value_register_exchange_func (GType value_type1,
278 g_return_if_fail (g_type_name (value_type1) != NULL);
279 g_return_if_fail (g_type_name (value_type2) != NULL);
280 g_return_if_fail (func != NULL);
282 entry.value_type1 = MIN (value_type1, value_type2);
283 entry.value_type2 = MAX (value_type1, value_type2);
284 if (param_exchange_ht && g_hash_table_lookup (param_exchange_ht, &entry))
285 g_warning (G_STRLOC ": cannot re-register param value exchange function "
287 g_type_name (value_type1),
288 g_type_name (value_type2));
291 ExchangeEntry *entry = g_new (ExchangeEntry, 1);
293 if (!param_exchange_ht)
294 param_exchange_ht = g_hash_table_new (exchange_entry_hash, exchange_entries_equal);
295 entry->value_type1 = MIN (value_type1, value_type2);
296 entry->value_type2 = MAX (value_type1, value_type2);
298 entry->first_type = value_type1;
299 g_hash_table_insert (param_exchange_ht, entry, entry);
304 g_value_types_exchangable (GType value_type1,
307 g_return_val_if_fail (G_TYPE_IS_VALUE (value_type1), FALSE); /* these might bite us, think G_TYPE_ENUM */
308 g_return_val_if_fail (G_TYPE_IS_VALUE (value_type2), FALSE);
310 return exchange_func_lookup (value_type1, value_type2, NULL) != NULL;
314 g_values_exchange (GValue *value1,
317 g_return_val_if_fail (G_IS_VALUE (value1), FALSE);
318 g_return_val_if_fail (G_IS_VALUE (value2), FALSE);
320 if (value1 != value2)
323 GValueExchange value_exchange = exchange_func_lookup (G_VALUE_TYPE (value1),
324 G_VALUE_TYPE (value2),
329 value_exchange (value2, value1);
331 value_exchange (value1, value2);
334 return value_exchange != NULL;
341 g_value_convert (const GValue *src_value,
344 gboolean success = TRUE;
346 g_return_val_if_fail (G_IS_VALUE (src_value), FALSE);
347 g_return_val_if_fail (G_IS_VALUE (dest_value), FALSE);
349 if (src_value != dest_value)
351 GValue tmp_value = { 0, };
353 g_value_init (&tmp_value, G_VALUE_TYPE (src_value));
354 g_value_copy (src_value, &tmp_value);
356 success = g_values_exchange (&tmp_value, dest_value);
357 g_value_unset (&tmp_value);