diff --git a/legacy/ecore/src/lib/ecore/Ecore_Data.h b/legacy/ecore/src/lib/ecore/Ecore_Data.h index 7c1d6fd1a8..29a466dfd2 100644 --- a/legacy/ecore/src/lib/ecore/Ecore_Data.h +++ b/legacy/ecore/src/lib/ecore/Ecore_Data.h @@ -16,7 +16,7 @@ extern "C" { extern const unsigned int ecore_prime_table[]; - typedef void (*Ecore_For_Each) (void *value); + typedef void (*Ecore_For_Each) (void *value, void *user_data); # define ECORE_FOR_EACH(function) ((Ecore_For_Each)function) typedef void (*Ecore_Free_Cb) (void *data); @@ -163,7 +163,8 @@ extern "C" { int ecore_list_nodes(Ecore_List * list); /* Traversing the list */ - int ecore_list_for_each(Ecore_List *list, Ecore_For_Each function); + int ecore_list_for_each(Ecore_List *list, Ecore_For_Each function, + void *user_data); inline void *ecore_list_goto_first(Ecore_List * list); inline void *ecore_list_goto_last(Ecore_List * list); inline void *ecore_list_goto_index(Ecore_List * list, int index); @@ -221,8 +222,8 @@ extern "C" { void *ecore_dlist_remove_last(Ecore_DList * _e_dlist); /* Traversing the list */ -# define ecore_dlist_for_each(list, function) \ - ecore_list_for_each(ECORE_LIST(list), function) +# define ecore_dlist_for_each(list, function, user_data) \ + ecore_list_for_each(ECORE_LIST(list), function, user_data) inline void *ecore_dlist_goto_first(Ecore_DList * _e_dlist); inline void *ecore_dlist_goto_last(Ecore_DList * _e_dlist); inline void *ecore_dlist_goto_index(Ecore_DList * _e_dlist, int index); @@ -274,6 +275,9 @@ extern "C" { int size; /* An index into the table of primes to determine size */ int nodes; /* The number of nodes currently in the hash */ + + int index; /* The current index into the bucket table */ + Ecore_Hash_Node *current; /* the current node in the current bucket */ Ecore_Compare_Cb compare; /* The function used to compare node values */ Ecore_Hash_Cb hash_func; /* The function used to compare node values */ @@ -292,7 +296,12 @@ extern "C" { int ecore_hash_set_free_key(Ecore_Hash *hash, Ecore_Free_Cb function); int ecore_hash_set_free_value(Ecore_Hash *hash, Ecore_Free_Cb function); void ecore_hash_destroy(Ecore_Hash *hash); - int ecore_hash_for_each_node(Ecore_Hash *hash, Ecore_For_Each for_each_func); + + Ecore_Hash_Node *ecore_hash_goto_first(Ecore_Hash *hash); + Ecore_Hash_Node *ecore_hash_next(Ecore_Hash *hash); + int ecore_hash_for_each_node(Ecore_Hash *hash, Ecore_For_Each for_each_func, + void *user_data); + Ecore_List *ecore_hash_keys(Ecore_Hash *hash); /* Retrieve and store data into the hash */ void *ecore_hash_get(Ecore_Hash *hash, void *key); @@ -528,10 +537,12 @@ extern "C" { /* For each node in the tree perform the for_each_func function */ /* For this one pass in the node */ - int ecore_tree_for_each_node(Ecore_Tree * tree, Ecore_For_Each for_each_func); + int ecore_tree_for_each_node(Ecore_Tree * tree, Ecore_For_Each for_each_func, + void *user_data); /* And here pass in the node's value */ int ecore_tree_for_each_node_value(Ecore_Tree * tree, - Ecore_For_Each for_each_func); + Ecore_For_Each for_each_func, + void *user_data); /* Some basic node functions */ /* Initialize a node */ diff --git a/legacy/ecore/src/lib/ecore/ecore_hash.c b/legacy/ecore/src/lib/ecore/ecore_hash.c index 713ca8666c..3b2d51a24d 100644 --- a/legacy/ecore/src/lib/ecore/ecore_hash.c +++ b/legacy/ecore/src/lib/ecore/ecore_hash.c @@ -198,14 +198,79 @@ void ecore_hash_destroy(Ecore_Hash *hash) * Functions that iterate through hash tables. */ +/** + * Move the current index to the beginning of the given hash for sequential + * processing + * @param hash The given hash + * @return the topmost node on success, NULL otherwise + * @ingroup Ecore_Data_Hash_ADT_Traverse_Group + */ +Ecore_Hash_Node *ecore_hash_goto_first(Ecore_Hash *hash) +{ + CHECK_PARAM_POINTER_RETURN("hash", hash, FALSE); + + hash->index = 0; + + ECORE_READ_LOCK(hash); + + if( hash->buckets[hash->index] ) + hash->current = ecore_list_goto_first( hash->buckets[hash->index] ) + + ECORE_READ_UNLOCK(hash); + + return hash->current; +} + +/** + * Return the current node and move to the next node of the given hash + * @param hash The given hash + * @return the current node on success, NULL if end reached + * @ingroup Ecore_Data_Hash_ADT_Traverse_Group + */ +Ecore_Hash_Node *ecore_hash_next(Ecore_Hash *hash) +{ + Ecore_Hash_Node *node; + + CHECK_PARAM_POINTER_RETURN("hash", hash, FALSE); + + ECORE_READ_LOCK(hash); + + node = hash->current; + + if( hash->index < ecore_prime_table[hash->size] && + hash->buckets[hash->index] ) { + if( hash->current ) + ecore_list_goto( hash->buckets[hash->index], hash->current ); + else + ecore_list_goto_first( hash->buckets[hash->index] ); + ecore_list_next( hash->buckets[hash->index] ); + hash->current = ecore_list_current( hash->buckets[hash->index] ); + if( !hash->current ) { + hash->index++; + + ECORE_READ_UNLOCK(hash); + ecore_hash_next(hash); + ECORE_READ_LOCK(hash); + } + } else { + hash->current = NULL; + } + + ECORE_READ_UNLOCK(hash); + + return node; +} + /** * Runs the @p for_each_func function on each entry in the given hash. * @param hash The given hash. * @param for_each_func The function that each entry is passed to. + * @param user_data a pointer passed to calls of for_each_func * @return TRUE on success, FALSE otherwise. * @ingroup Ecore_Data_Hash_ADT_Traverse_Group */ -int ecore_hash_for_each_node(Ecore_Hash *hash, Ecore_For_Each for_each_func) +int ecore_hash_for_each_node(Ecore_Hash *hash, Ecore_For_Each for_each_func, + void *user_data) { int i = 0; @@ -220,7 +285,7 @@ int ecore_hash_for_each_node(Ecore_Hash *hash, Ecore_For_Each for_each_func) ecore_list_goto_first(hash->buckets[i]); while ((node = ecore_list_next(hash->buckets[i]))) { - for_each_func(node); + for_each_func(node, user_data); } } i++; @@ -231,6 +296,40 @@ int ecore_hash_for_each_node(Ecore_Hash *hash, Ecore_For_Each for_each_func) return TRUE; } +/** + * Retrieves an ecore_list of all keys in the given hash. + * @param hash The given hash. + * @return new ecore_list on success, NULL otherwise + * @ingroup Ecore_Data_Hash_ADT_Traverse_Group + */ +Ecore_List *ecore_hash_keys(Ecore_Hash *hash) +{ + int i = 0; + Ecore_List *keys; + + CHECK_PARAM_POINTER_RETURN("hash", hash, NULL); + + ECORE_READ_LOCK(hash); + + keys = ecore_list_new(); + + while (i < ecore_prime_table[hash->size]) { + if (hash->buckets[i]) { + Ecore_Hash_Node *node; + + ecore_list_goto_first(hash->buckets[i]); + while ((node = ecore_list_next(hash->buckets[i]))) { + ecore_list_append(keys, node->key); + } + } + i++; + } + + ECORE_READ_UNLOCK(hash); + + return keys; +} + /** * Prints the distribution of the given hash table for graphing. * @param hash The given hash table. diff --git a/legacy/ecore/src/lib/ecore/ecore_list.c b/legacy/ecore/src/lib/ecore/ecore_list.c index 1cb8168476..ebed0d38b1 100644 --- a/legacy/ecore/src/lib/ecore/ecore_list.c +++ b/legacy/ecore/src/lib/ecore/ecore_list.c @@ -22,7 +22,8 @@ static void *_ecore_list_goto(Ecore_List * list, void *data); static void *_ecore_list_goto_index(Ecore_List *list, int index); /* Iterative function */ -static int _ecore_list_for_each(Ecore_List *list, Ecore_For_Each function); +static int _ecore_list_for_each(Ecore_List *list, Ecore_For_Each function, + void *user_data); /* Private double linked list functions */ static void *_ecore_dlist_previous(Ecore_DList * list); @@ -916,19 +917,21 @@ int ecore_list_clear(Ecore_List * list) * @return Returns @c TRUE on success, @c FALSE on failure. * @ingroup Ecore_Data_List_Traverse_Group */ -int ecore_list_for_each(Ecore_List *list, Ecore_For_Each function) +int ecore_list_for_each(Ecore_List *list, Ecore_For_Each function, + void *user_data) { int ret; CHECK_PARAM_POINTER_RETURN("list", list, FALSE); - ret = _ecore_list_for_each(list, function); + ret = _ecore_list_for_each(list, function, user_data); return ret; } /* The real meat of executing the function for each data node */ -static int _ecore_list_for_each(Ecore_List *list, Ecore_For_Each function) +static int _ecore_list_for_each(Ecore_List *list, Ecore_For_Each function, + void *user_data) { void *value; @@ -937,7 +940,7 @@ static int _ecore_list_for_each(Ecore_List *list, Ecore_For_Each function) _ecore_list_goto_first(list); while ((value = _ecore_list_next(list)) != NULL) - function(value); + function(value, user_data); return TRUE; } diff --git a/legacy/ecore/src/lib/ecore/ecore_path.c b/legacy/ecore/src/lib/ecore/ecore_path.c index 641172167c..9202eea8d0 100644 --- a/legacy/ecore/src/lib/ecore/ecore_path.c +++ b/legacy/ecore/src/lib/ecore/ecore_path.c @@ -65,7 +65,7 @@ ecore_path_group_del(int group_id) if (group->paths) { ecore_list_for_each(group->paths, - ECORE_FOR_EACH(free)); + ECORE_FOR_EACH(free), NULL); ecore_list_destroy(group->paths); } diff --git a/legacy/ecore/src/lib/ecore/ecore_tree.c b/legacy/ecore/src/lib/ecore/ecore_tree.c index 868e346866..55322dd675 100644 --- a/legacy/ecore/src/lib/ecore/ecore_tree.c +++ b/legacy/ecore/src/lib/ecore/ecore_tree.c @@ -15,9 +15,10 @@ int tree_node_rotate_right(Ecore_Tree * tree, Ecore_Tree_Node * top_node); int tree_node_rotate_left(Ecore_Tree * tree, Ecore_Tree_Node * top_node); /* Fucntions for executing a specified function on each node of a tree */ -int tree_for_each_node(Ecore_Tree_Node * node, Ecore_For_Each for_each_func); +int tree_for_each_node(Ecore_Tree_Node * node, Ecore_For_Each for_each_func, + void *user_data); int tree_for_each_node_value(Ecore_Tree_Node * node, - Ecore_For_Each for_each_func); + Ecore_For_Each for_each_func, void *user_data); /** * @brief Allocate a new tree structure. @@ -572,10 +573,11 @@ int ecore_tree_is_empty(Ecore_Tree * tree) * @brief Execute function for each value in the tree * @param tree: the tree to traverse * @param for_each_func: the function to execute for each value in the tree + * @param user_data: data passed to each for_each_func call * @return Returns TRUE on success, FALSE on failure. */ int ecore_tree_for_each_node_value(Ecore_Tree * tree, - Ecore_For_Each for_each_func) + Ecore_For_Each for_each_func, void *user_data) { CHECK_PARAM_POINTER_RETURN("tree", tree, FALSE); CHECK_PARAM_POINTER_RETURN("for_each_func", for_each_func, FALSE); @@ -583,17 +585,18 @@ int ecore_tree_for_each_node_value(Ecore_Tree * tree, if (!tree->tree) return FALSE; - return tree_for_each_node_value(tree->tree, for_each_func); + return tree_for_each_node_value(tree->tree, for_each_func, user_data); } /** * @brief Execute the function for each node in the tree * @param tree: the tree to traverse * @param for_each_func: the function to execute for each node - * + * @param user_data: data passed to each for_each_func call * @return Returns TRUE on success, FALSE on failure. */ -int ecore_tree_for_each_node(Ecore_Tree * tree, Ecore_For_Each for_each_func) +int ecore_tree_for_each_node(Ecore_Tree * tree, Ecore_For_Each for_each_func, + void *user_data) { CHECK_PARAM_POINTER_RETURN("tree", tree, FALSE); CHECK_PARAM_POINTER_RETURN("for_each_func", for_each_func, FALSE); @@ -601,7 +604,7 @@ int ecore_tree_for_each_node(Ecore_Tree * tree, Ecore_For_Each for_each_func) if (!tree->tree) return FALSE; - return tree_for_each_node(tree->tree, for_each_func); + return tree_for_each_node(tree->tree, for_each_func, user_data); } /* Find the parent for the key */ @@ -770,19 +773,21 @@ int tree_node_rotate_left(Ecore_Tree * tree, Ecore_Tree_Node * top_node) * @brief Execute a function for each node below this point in the tree. * @param node: the highest node in the tree the function will be executed for * @param for_each_func: the function to pass the nodes as data into + * @param user_data: data passed to each for_each_func call * @return Returns FALSE if an error condition occurs, otherwise TRUE */ -int tree_for_each_node(Ecore_Tree_Node * node, Ecore_For_Each for_each_func) +int tree_for_each_node(Ecore_Tree_Node * node, Ecore_For_Each for_each_func, + void *user_data) { CHECK_PARAM_POINTER_RETURN("node", node, FALSE); if (node->right_child) - tree_for_each_node(node->right_child, for_each_func); + tree_for_each_node(node->right_child, for_each_func, user_data); if (node->left_child) - tree_for_each_node(node->left_child, for_each_func); + tree_for_each_node(node->left_child, for_each_func, user_data); - for_each_func(node); + for_each_func(node, user_data); return TRUE; } @@ -795,17 +800,17 @@ int tree_for_each_node(Ecore_Tree_Node * node, Ecore_For_Each for_each_func) * @return Returns FALSE if an error condition occurs, otherwise TRUE */ int tree_for_each_node_value(Ecore_Tree_Node * node, - Ecore_For_Each for_each_func) + Ecore_For_Each for_each_func, void *user_data) { CHECK_PARAM_POINTER_RETURN("node", node, FALSE); if (node->right_child) - tree_for_each_node_value(node->right_child, for_each_func); + tree_for_each_node_value(node->right_child, for_each_func, user_data); if (node->left_child) - tree_for_each_node_value(node->left_child, for_each_func); + tree_for_each_node_value(node->left_child, for_each_func, user_data); - for_each_func(node->value); + for_each_func(node->value, user_data); return TRUE; }