1 /* Fo
2 * fo-hashtable.c: HashTable hashtable
3 *
4 * Copyright (C) 2001 Sun Microsystems
5 * Copyright (C) 2007-2010 Menteith Consulting Ltd
6 *
7 * See COPYING for the status of this software.
8 */
9
10 #include <math.h>
11 #include "fo-utils.h"
12 #include "fo-hash-table.h"
13
14 struct _FoHashTable
15 {
16 FoObject parent_instance;
17
18 GHashTable *hash_table;
19 };
20
21 struct _FoHashTableClass
22 {
23 FoObjectClass parent_class;
24 };
25
26 static void _init (FoHashTable *hash_table);
27 static void _class_init (FoHashTableClass *klass);
28 static void _finalize (GObject *object);
29
30 static guint _hash_func (gconstpointer key);
31 static gboolean _key_equal_func (gconstpointer a,
32 gconstpointer b);
33 static void _destroy_func (gpointer data);
34
35 static gpointer parent_class;
36
37 /**
38 * fo_hash_table_get_type:
39 *
40 * Register the #FoHashTable object type.
41 *
42 * Return value: #GType value of the #FoHashTable object type.
43 **/
44 GType
fo_hash_table_get_type(void)45 fo_hash_table_get_type (void)
46 {
47 static GType object_type = 0;
48
49 if (!object_type)
50 {
51 static const GTypeInfo object_info =
52 {
53 sizeof (FoHashTableClass),
54 (GBaseInitFunc) NULL,
55 (GBaseFinalizeFunc) NULL,
56 (GClassInitFunc) _class_init,
57 NULL, /* class_finalize */
58 NULL, /* class_data */
59 sizeof (FoHashTable),
60 0, /* n_preallocs */
61 (GInstanceInitFunc) _init,
62 NULL /* value_table */
63 };
64
65 object_type = g_type_register_static (FO_TYPE_OBJECT,
66 "FoHashTable",
67 &object_info,
68 0);
69 }
70
71 return object_type;
72 }
73
74 /**
75 * _init:
76 * @hash_table: #FoHash_Table object to initialise
77 *
78 * Implements #GInstanceInitFunc for #FoHashTable
79 **/
80 static void
_init(FoHashTable * hash_table)81 _init (FoHashTable *hash_table)
82 {
83 hash_table->hash_table = g_hash_table_new_full(_hash_func,
84 _key_equal_func,
85 _destroy_func,
86 _destroy_func);
87 }
88
89 /**
90 * _class_init:
91 * @klass: #FoHashTableClass object to initialise.
92 *
93 * Implements #GClassInitFunc for #FoHashTableClass.
94 **/
95 static void
_class_init(FoHashTableClass * klass)96 _class_init (FoHashTableClass *klass)
97 {
98 GObjectClass *object_class = G_OBJECT_CLASS (klass);
99
100 parent_class = g_type_class_peek_parent (klass);
101
102 object_class->finalize = _finalize;
103 }
104
105 /**
106 * _finalize:
107 * @object: #FoHashTable object to finalize.
108 *
109 * Implements #GObjectFinalizeFunc for #FoHashTable.
110 **/
111 static void
_finalize(GObject * object)112 _finalize (GObject *object)
113 {
114 FoHashTable *fo_hash_table;
115
116 fo_hash_table = FO_HASH_TABLE (object);
117
118 g_hash_table_destroy (fo_hash_table->hash_table);
119
120 G_OBJECT_CLASS (parent_class)->finalize (object);
121 }
122
123 /**
124 * fo_hash_table_new:
125 *
126 * Creates a new #FoHashTable initialized to default value.
127 *
128 * Return value: the new #FoHashTable
129 **/
130 FoHashTable *
fo_hash_table_new(void)131 fo_hash_table_new (void)
132 {
133 return FO_HASH_TABLE (g_object_new (fo_hash_table_get_type (),
134 NULL));
135 }
136
137 /**
138 * _destroy_func:
139 * @data: Data to be destroyed.
140 *
141 * #GDestroyNotify function called when a key or value is removed from
142 * a #FoHashTable.
143 **/
144 static void
_destroy_func(gpointer data)145 _destroy_func (gpointer data)
146 {
147 if ((data != NULL) &&
148 FO_IS_OBJECT (data))
149 {
150 g_object_unref (data);
151 }
152 }
153
154 /**
155 * _hash_func:
156 * @key: Key to hash.
157 *
158 * Creates the hash code for @key using the 'hash' function for the
159 * #FoObject class type of @key.
160 *
161 * Return value: Hash code for @key.
162 **/
163 static guint
_hash_func(gconstpointer key)164 _hash_func (gconstpointer key)
165 {
166 guint result = 0;
167
168 if ((key != NULL) &&
169 (FO_IS_OBJECT (key)))
170 {
171 result = FO_OBJECT_GET_CLASS (key)->hash_func (key);
172 }
173
174 return result;
175 }
176
177 /**
178 * _key_equal_func:
179 * @a: First key to compare.
180 * @b: Second key to compare.
181 *
182 * Compares @a and @b using the 'equal' function of the #FoObject
183 * class type of @a.
184 *
185 * Return value: %TRUE if @a and @b are equal.
186 **/
187 static gboolean
_key_equal_func(gconstpointer a,gconstpointer b)188 _key_equal_func (gconstpointer a,
189 gconstpointer b)
190 {
191 return FO_OBJECT_GET_CLASS (a)->equal_func (a, b);
192 }
193
194 /**
195 * fo_hash_table_insert:
196 * @fo_hash_table: #FoHashTable in which to insert.
197 * @key: Key at which to insert.
198 * @value: Value to insert.
199 * @error: #GError with information about error that occurred.
200 *
201 * Inserts @value as the value corresponding to @key in
202 * @fo_hash_table.
203 **/
204 void
fo_hash_table_insert(FoHashTable * fo_hash_table,FoObject * key,FoObject * value,GError ** error G_GNUC_UNUSED)205 fo_hash_table_insert (FoHashTable *fo_hash_table,
206 FoObject *key,
207 FoObject *value,
208 GError **error G_GNUC_UNUSED)
209 {
210 g_return_if_fail (fo_hash_table != NULL);
211 g_return_if_fail (FO_IS_HASH_TABLE (fo_hash_table));
212 g_return_if_fail (key != NULL);
213 g_return_if_fail (FO_IS_OBJECT (value));
214
215 g_hash_table_insert (fo_hash_table->hash_table,
216 g_object_ref (key),
217 g_object_ref (value));
218 }
219
220 /**
221 * fo_hash_table_replace:
222 * @fo_hash_table: #FoHashTable in which to replace.
223 * @key: Key of key-value pair to replace.
224 * @value: New value.
225 * @error: #GError with information about error that occurred.
226 *
227 * Replaces the key-value pair in @fo_hash_table that has a key
228 * matching @key.
229 **/
230 void
fo_hash_table_replace(FoHashTable * fo_hash_table,FoObject * key,FoObject * value,GError ** error G_GNUC_UNUSED)231 fo_hash_table_replace (FoHashTable *fo_hash_table,
232 FoObject *key,
233 FoObject *value,
234 GError **error G_GNUC_UNUSED)
235 {
236 g_return_if_fail (fo_hash_table != NULL);
237 g_return_if_fail (FO_IS_HASH_TABLE (fo_hash_table));
238 g_return_if_fail (key != NULL);
239 g_return_if_fail (FO_IS_OBJECT (key));
240
241 g_hash_table_replace (fo_hash_table->hash_table,
242 g_object_ref(key),
243 g_object_ref(value));
244 }
245
246 /**
247 * fo_hash_table_remove:
248 * @fo_hash_table: #FoHashTable from which to remove a key-value pair.
249 * @key: Key of pair to remove.
250 * @error: #GError with information about error that occurred.
251 *
252 * Removes the key-value pair with key matching @key from
253 * @fo_hash_table.
254 *
255 * Return value: %TRUE is successful.
256 **/
257 gboolean
fo_hash_table_remove(FoHashTable * fo_hash_table,FoObject * key,GError ** error G_GNUC_UNUSED)258 fo_hash_table_remove (FoHashTable *fo_hash_table,
259 FoObject *key,
260 GError **error G_GNUC_UNUSED)
261 {
262 g_return_val_if_fail (fo_hash_table != NULL, FALSE);
263 g_return_val_if_fail (FO_IS_HASH_TABLE (fo_hash_table), FALSE);
264 g_return_val_if_fail (key != NULL, FALSE);
265 g_return_val_if_fail (FO_IS_OBJECT (key), FALSE);
266
267 return g_hash_table_remove (fo_hash_table->hash_table,
268 g_object_ref(key));
269 }
270
271 /**
272 * fo_hash_table_lookup:
273 * @fo_hash_table: #FoHashTable in which to look.
274 * @key: Key value against which to compare.
275 * @error: #GError with information about error that occurred.
276 *
277 * Gets the value associated with @key in @fo_hash_table.
278 *
279 * Return value: The value, or %NULL if no matching key.
280 **/
281 FoObject *
fo_hash_table_lookup(FoHashTable * fo_hash_table,FoObject * key,GError ** error G_GNUC_UNUSED)282 fo_hash_table_lookup (FoHashTable *fo_hash_table,
283 FoObject *key,
284 GError **error G_GNUC_UNUSED)
285 {
286 g_return_val_if_fail (fo_hash_table != NULL, NULL);
287 g_return_val_if_fail (FO_IS_HASH_TABLE (fo_hash_table), NULL);
288 g_return_val_if_fail (key != NULL, NULL);
289 g_return_val_if_fail (FO_IS_OBJECT (key), NULL);
290
291 return g_hash_table_lookup (fo_hash_table->hash_table,
292 key);
293 }
294
295 /**
296 * fo_hash_table_size:
297 * @fo_hash_table: #FoHashTable for which to get size.
298 *
299 * Gets the number of key-value pairs in @fo_hash_table.
300 *
301 * Return value: Number of key-value pairs.
302 **/
303 guint
fo_hash_table_size(FoHashTable * fo_hash_table)304 fo_hash_table_size (FoHashTable *fo_hash_table)
305 {
306 return g_hash_table_size (fo_hash_table->hash_table);
307 }
308
309 /**
310 * fo_hash_table_error_quark:
311 *
312 * Get the error quark for #FoHashTable.
313 *
314 * If the quark does not yet exist, create it.
315 *
316 * Return value: Quark associated with #FoHashTable errors.
317 **/
318 GQuark
fo_hash_table_error_quark(void)319 fo_hash_table_error_quark (void)
320 {
321 static GQuark quark = 0;
322 if (quark == 0)
323 quark = g_quark_from_static_string ("FoHashTable error");
324 return quark;
325 }
326
327 const char *fo_hash_table_error_messages [] = {
328 N_("Invalid hash_table for context."),
329 };
330