2 * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2
12 #include "Evas_Data.h"
14 typedef struct _Evas_Hash_El Evas_Hash_El;
18 Evas_Object_List _list_data;
23 static inline int _evas_hash_gen(const char *key);
25 static int _evas_hash_alloc_error = 0;
28 _evas_hash_gen(const char *key)
30 unsigned int hash_num = 5381;
31 const unsigned char *ptr;
34 for (ptr = (unsigned char *)key; *ptr; ptr++)
35 hash_num = (hash_num * 33) ^ *ptr;
42 * @defgroup Evas_Hash_Data Hash Data Functions
44 * Functions that add, access or remove data from hashes.
46 * The following example shows how to add and then access data in a
49 * Evas_Hash *hash = NULL;
50 * extern void *my_data;
52 * hash = evas_hash_add(hash, "My Data", my_data);
53 * if (evas_hash_alloc_error())
55 * fprintf(stderr, "ERROR: Memory is low. Hash allocation failed.\n");
58 * if (evas_hash_find(hash, "My Data") == my_data)
60 * printf("My Data inserted and successfully found.\n");
64 * What follows is another example, showing how the @ref evas_hash_del
67 * extern Evas_Hash *hash;
70 * printf("Insert some data...\n");
71 * hash = evas_hash_add(hash, "My Data", my_data);
72 * printf("Removing by key...\n");
73 * hash = evas_hash_del(hash, "My Data", NULL);
74 * printf("Insert some more data as a NULL key...\n");
75 * hash = evas_hash_add(hash, NULL, my_data);
76 * printf("Removing by data as a NULL key...\n");
77 * hash = evas_hash_del(hash, NULL, my_data);
82 * Adds an entry to the given hash table.
84 * @p key is expected to be a unique string within the hash table.
85 * Otherwise, you cannot be sure which inserted data pointer will be
86 * accessed with @ref evas_hash_find , and removed with
87 * @ref evas_hash_del .
89 * Key strings are case sensitive.
91 * @ref evas_hash_alloc_error should be used to determine if an
92 * allocation error occurred during this function.
94 * @param hash The given hash table. Can be @c NULL, in which case a
95 * new hash table is allocated and returned.
96 * @param key A unique string. Can be @c NULL.
97 * @param data Data to associate with the string given by @p key.
98 * @return Either the given hash table, or if the given value for @p
99 * hash is @c NULL, then a new one. @c NULL will be returned
100 * if memory could not be allocated for a new table.
101 * @ingroup Evas_Hash_Data
104 evas_hash_add(Evas_Hash *hash, const char *key, const void *data)
109 if ((!key) || (!data)) return hash;
110 _evas_hash_alloc_error = 0;
113 hash = calloc(1, sizeof(struct _Evas_Hash));
116 _evas_hash_alloc_error = 1;
120 if (!(el = malloc(sizeof(struct _Evas_Hash_El) + strlen(key) + 1)))
122 if (hash->population <= 0)
127 _evas_hash_alloc_error = 1;
130 el->key = ((char *)el) + sizeof(struct _Evas_Hash_El);
131 strcpy((char *) el->key, key);
132 el->data = (void *)data;
133 hash_num = _evas_hash_gen(key);
134 hash->buckets[hash_num] = evas_object_list_prepend(hash->buckets[hash_num], el);
140 * Adds an entry to the given hash table and does not duplicate the string key.
142 * @p key is expected to be a unique string within the hash table.
143 * Otherwise, you cannot be sure which inserted data pointer will be
144 * accessed with @ref evas_hash_find , and removed with
145 * @ref evas_hash_del . This call does not make a copy of the key so it must
146 * be a string constant or stored elsewhere (in the object being added) etc.
148 * Key strings are case sensitive.
150 * @ref evas_hash_alloc_error should be used to determine if an
151 * allocation error occurred during this function.
153 * @param hash The given hash table. Can be @c NULL, in which case a
154 * new hash table is allocated and returned.
155 * @param key A unique string. Can be @c NULL.
156 * @param data Data to associate with the string given by @p key.
157 * @return Either the given hash table, or if the given value for @p
158 * hash is @c NULL, then a new one. @c NULL will be returned
159 * if memory could not be allocated for a new table.
160 * @ingroup Evas_Hash_Data
163 evas_hash_direct_add(Evas_Hash *hash, const char *key, const void *data)
168 if ((!key) || (!data)) return hash;
169 _evas_hash_alloc_error = 0;
172 hash = calloc(1, sizeof(struct _Evas_Hash));
175 _evas_hash_alloc_error = 1;
179 if (!(el = malloc(sizeof(struct _Evas_Hash_El))))
181 if (hash->population <= 0)
186 _evas_hash_alloc_error = 1;
190 el->data = (void *)data;
191 hash_num = _evas_hash_gen(key);
192 hash->buckets[hash_num] = evas_object_list_prepend(hash->buckets[hash_num], el);
198 * Removes the entry identified by @p key or @p data from the given
201 * If @p key is @c NULL, then @p data is used to find a match to
204 * @param hash The given hash table.
205 * @param key The key string. Can be @c NULL.
206 * @param data The data pointer to remove if @p key is @c NULL.
207 * Otherwise, not required and can be @c NULL.
208 * @return The modified hash table. If there are no entries left, the
209 * hash table will be freed and @c NULL will be returned.
210 * @ingroup Evas_Hash_Data
213 evas_hash_del(Evas_Hash *hash, const char *key, const void *data)
219 if (!hash) return NULL;
224 for (hash_num = 0; hash_num < 256; hash_num++)
226 for (l = hash->buckets[hash_num]; l; l = l->next)
228 el = (Evas_Hash_El *)l;
229 if (el->data == data)
231 hash->buckets[hash_num] = evas_object_list_remove(hash->buckets[hash_num], el);
234 if (hash->population <= 0)
246 hash_num = _evas_hash_gen(key);
247 for (l = hash->buckets[hash_num]; l; l = l->next)
249 el = (Evas_Hash_El *)l;
250 if (!strcmp(el->key, key))
252 hash->buckets[hash_num] = evas_object_list_remove(hash->buckets[hash_num], el);
255 if (hash->population <= 0)
268 * Retrieves a specific entry in the given hash table.
269 * @param hash The given hash table.
270 * @param key The key string of the entry to find.
271 * @return The data pointer for the stored entry, or @c NULL if not
273 * @ingroup Evas_Hash_Data
276 evas_hash_find(const Evas_Hash *hash, const char *key)
282 _evas_hash_alloc_error = 0;
283 if ((!hash) || (!key)) return NULL;
284 hash_num = _evas_hash_gen(key);
285 for (l = hash->buckets[hash_num]; l; l = l->next)
287 el = (Evas_Hash_El *)l;
288 if (!strcmp(el->key, key))
290 if (l != hash->buckets[hash_num])
292 Evas_Object_List *bucket;
294 bucket = hash->buckets[hash_num];
295 bucket = evas_object_list_remove(bucket, el);
296 bucket = evas_object_list_prepend(bucket, el);
297 ((Evas_Hash *)hash)->buckets[hash_num] = bucket;
306 * Modifies the entry pointer at the specified key and returns the old entry
307 * @param hash The given hash table.
308 * @param key The key string of the entry to modify.
309 * @param data The data to replace the old entry, if it exists.
310 * @return The data pointer for the old stored entry, or @c NULL if not
311 * found. If an existing entry is not found, nothing is added to the
313 * @ingroup Evas_Hash_Data
316 evas_hash_modify(Evas_Hash *hash, const char *key, const void *data)
322 _evas_hash_alloc_error = 0;
323 if (!hash) return NULL;
324 hash_num = _evas_hash_gen(key);
325 for (l = hash->buckets[hash_num]; l; l = l->next)
327 el = (Evas_Hash_El *)l;
328 if ((key) && (!strcmp(el->key, key)))
332 if (l != hash->buckets[hash_num])
334 hash->buckets[hash_num] = evas_object_list_remove(hash->buckets[hash_num], el);
335 hash->buckets[hash_num] = evas_object_list_prepend(hash->buckets[hash_num], el);
338 el->data = (void *) data;
346 * @defgroup Evas_Hash_General_Group Hash General Functions
348 * Miscellaneous functions that operate on hash objects.
352 * Retrieves the number of buckets available in the given hash table.
353 * @param hash The given hash table.
354 * @return @c 256 if @p hash is not @c NULL. @c 0 otherwise.
355 * @ingroup Evas_Hash_General_Group
358 evas_hash_size(const Evas_Hash *hash)
365 * @todo Complete polishing documentation for evas_hash.c. The
366 * functions' docs may be grouped, but they need some simplification.
370 * Free an entire hash table
371 * @param hash The hash table to be freed
373 * This function frees up all the memory allocated to storing the specified
374 * hash tale pointed to by @p hash. Any entries in the table that the program
375 * has no more pointers for elsewhere may now be lost, so this should only be
376 * called if the program has lready freed any allocated data in the hash table
377 * or has the pointers for data in teh table stored elswehere as well.
381 * extern Evas_Hash *hash;
383 * evas_hash_free(hash);
386 * @ingroup Evas_Hash_General_Group
389 evas_hash_free(Evas_Hash *hash)
394 size = evas_hash_size(hash);
395 for (i = 0; i < size; i++)
397 while (hash->buckets[i])
401 el = (Evas_Hash_El *)hash->buckets[i];
402 hash->buckets[i] = evas_object_list_remove(hash->buckets[i], el);
410 * Call a function on every member stored in the hash table
411 * @param hash The hash table whose members will be walked
412 * @param func The function to call on each parameter
413 * @param fdata The data pointer to pass to the function being called
415 * This function goes through every entry in the hash table @p hash and calls
416 * the function @p func on each member. The function should NOT modify the
417 * hash table contents if it returns 1. IF the hash table contents are
418 * modified by this function or the function wishes to stop processing it must
419 * return 0, otherwise return 1 to keep processing.
423 * extern Evas_Hash *hash;
425 * Evas_Bool hash_fn(Evas_Hash *hash, const char *key, void *data, void *fdata)
427 * printf("Func data: %s, Hash entry: %s / %p\n", fdata, key, data);
431 * int main(int argc, char **argv)
433 * char *hash_fn_data;
435 * hash_fn_data = strdup("Hello World");
436 * evas_hash_foreach(hash, hash_fn, hash_fn_data);
437 * free(hash_fn_data);
440 * @ingroup Evas_Hash_General_Group
443 evas_hash_foreach(const Evas_Hash *hash, Evas_Bool (*func) (const Evas_Hash *hash, const char *key, void *data, void *fdata), const void *fdata)
448 size = evas_hash_size(hash);
449 for (i = 0; i < size; i++)
451 Evas_Object_List *l, *next_l;
453 for (l = hash->buckets[i]; l;)
458 el = (Evas_Hash_El *)l;
459 if (!func(hash, el->key, el->data, (void *)fdata)) return;
466 * Return memory allocation failure flag after an function requiring allocation
467 * @return The state of the allocation flag
469 * This function returns the state of the memory allocation flag. This flag is
470 * set if memory allocations fail during evas_hash_add() calls. If they do, 1
471 * will be returned, otherwise 0 will be returned. The flag will remain in its
472 * current state until the next call that requires allocation is called, and
477 * Evas_Hash *hash = NULL;
478 * extern void *my_data;
480 * hash = evas_hash_add(hash, "My Data", my_data);
481 * if (evas_hash_alloc_error())
483 * fprintf(stderr, "ERROR: Memory is low. Hash allocation failed.\n");
486 * if (evas_hash_find(hash, "My Data") == my_data)
488 * printf("My Data inserted and successfully found.\n");
491 * @ingroup Evas_Hash_General_Group
494 evas_hash_alloc_error(void)
496 return _evas_hash_alloc_error;