diff --git a/legacy/ecore/src/lib/ecore/Ecore_Data.h b/legacy/ecore/src/lib/ecore/Ecore_Data.h index c21655ca21..e1c895b802 100644 --- a/legacy/ecore/src/lib/ecore/Ecore_Data.h +++ b/legacy/ecore/src/lib/ecore/Ecore_Data.h @@ -252,10 +252,10 @@ extern "C" { int index; /* The current index into the bucket table */ Ecore_Compare_Cb compare; /* The function used to compare node values */ - Ecore_Hash_Cb hash_func; /* The function used to compare node values */ + Ecore_Hash_Cb hash_func; /* The callback function to determine hash */ Ecore_Free_Cb free_key; /* The callback function to free key */ - Ecore_Free_Cb free_value; /* The callback function to determine hash */ + Ecore_Free_Cb free_value; /* The callback function to free value */ }; /* Create and initialize a hash */ @@ -398,7 +398,7 @@ extern "C" { struct _Ecore_Tree_Node { /* The actual data for each node */ - const void *key; + void *key; void *value; /* Pointers to surrounding nodes */ @@ -421,7 +421,9 @@ extern "C" { Ecore_Compare_Cb compare_func; /* Callback for freeing node data, default is NULL */ - Ecore_Free_Cb free_func; + Ecore_Free_Cb free_value; + /* Callback for freeing node key, default is NULL */ + Ecore_Free_Cb free_key; }; /* Some basic tree functions */ @@ -444,7 +446,7 @@ extern "C" { EAPI void *ecore_tree_get_closest_smaller(Ecore_Tree * tree, const void *key); /* Set the value associated with key to value */ - EAPI int ecore_tree_set(Ecore_Tree * tree, const void *key, void *value); + EAPI int ecore_tree_set(Ecore_Tree * tree, void *key, void *value); /* Remove the key from the tree */ EAPI int ecore_tree_remove(Ecore_Tree * tree, const void *key); @@ -468,12 +470,13 @@ extern "C" { /* Allocate and initialize a new node */ EAPI Ecore_Tree_Node *ecore_tree_node_new(void); /* Free the desired node */ - EAPI int ecore_tree_node_destroy(Ecore_Tree_Node * node, Ecore_Free_Cb free_data); + EAPI int ecore_tree_node_destroy(Ecore_Tree_Node * node, + Ecore_Free_Cb free_value, Ecore_Free_Cb free_key); /* Set the node's key to key */ - EAPI int ecore_tree_node_key_set(Ecore_Tree_Node * node, const void *key); + EAPI int ecore_tree_node_key_set(Ecore_Tree_Node * node, void *key); /* Retrieve the key in node */ - EAPI const void *ecore_tree_node_key_get(Ecore_Tree_Node * node); + EAPI void *ecore_tree_node_key_get(Ecore_Tree_Node * node); /* Set the node's value to value */ EAPI int ecore_tree_node_value_set(Ecore_Tree_Node * node, void *value); @@ -481,7 +484,9 @@ extern "C" { EAPI void *ecore_tree_node_value_get(Ecore_Tree_Node * node); /* Add a function to free the data stored in nodes */ - EAPI int ecore_tree_set_free_cb(Ecore_Tree * tree, Ecore_Free_Cb free_func); + EAPI int ecore_tree_set_free_value(Ecore_Tree * tree, Ecore_Free_Cb free_value); + /* Add a function to free the keys stored in nodes */ + EAPI int ecore_tree_set_free_key(Ecore_Tree * tree, Ecore_Free_Cb free_key); EAPI Ecore_Strbuf * ecore_strbuf_new(void); diff --git a/legacy/ecore/src/lib/ecore/ecore_tree.c b/legacy/ecore/src/lib/ecore/ecore_tree.c index 99cbcc12a3..c726bb7147 100644 --- a/legacy/ecore/src/lib/ecore/ecore_tree.c +++ b/legacy/ecore/src/lib/ecore/ecore_tree.c @@ -73,11 +73,27 @@ ecore_tree_init(Ecore_Tree *new_tree, Ecore_Compare_Cb compare_func) * @return Returns TRUE on successful set, FALSE otherwise. */ EAPI int -ecore_tree_set_free_cb(Ecore_Tree *tree, Ecore_Free_Cb free_func) +ecore_tree_set_free_value(Ecore_Tree *tree, Ecore_Free_Cb free_value) { CHECK_PARAM_POINTER_RETURN("tree", tree, FALSE); - tree->free_func = free_func; + tree->free_value = free_value; + + return TRUE; +} + +/* + * @brief Add a function to be called at node destroy time + * @param tree: the tree that will use this function when nodes are destroyed + * @param free_key: the function that will be passed the node being freed + * @return Returns TRUE on successful set, FALSE otherwise. + */ +EAPI int +ecore_tree_set_free_key(Ecore_Tree *tree, Ecore_Free_Cb free_key) +{ + CHECK_PARAM_POINTER_RETURN("tree", tree, FALSE); + + tree->free_key = free_key; return TRUE; } @@ -134,12 +150,14 @@ ecore_tree_node_new() * If you don't want the children free'd then you need to remove the node first. */ EAPI int -ecore_tree_node_destroy(Ecore_Tree_Node *node, Ecore_Free_Cb data_free) +ecore_tree_node_destroy(Ecore_Tree_Node *node, Ecore_Free_Cb value_free, Ecore_Free_Cb key_free) { CHECK_PARAM_POINTER_RETURN("node", node, FALSE); - if (data_free) - data_free(node->value); + if (key_free) + key_free(node->key); + if (value_free) + value_free(node->value); FREE(node); @@ -185,7 +203,7 @@ ecore_tree_node_value_get(Ecore_Tree_Node *node) * @return Returns TRUE if the node is set successfully, FALSE if not. */ EAPI int -ecore_tree_node_key_set(Ecore_Tree_Node *node, const void *key) +ecore_tree_node_key_set(Ecore_Tree_Node *node, void *key) { CHECK_PARAM_POINTER_RETURN("node", node, FALSE); @@ -200,10 +218,10 @@ ecore_tree_node_key_set(Ecore_Tree_Node *node, const void *key) * * @return Returns NULL if an error occurs, otherwise the key is returned */ -EAPI const void * +EAPI void * ecore_tree_node_key_get(Ecore_Tree_Node *node) { - const void *ret; + void *ret; CHECK_PARAM_POINTER_RETURN("node", node, NULL); ret = node->key; @@ -227,7 +245,7 @@ ecore_tree_destroy(Ecore_Tree *tree) while ((node = tree->tree)) { ecore_tree_remove_node(tree, node); - ecore_tree_node_destroy(node, tree->free_func); + ecore_tree_node_destroy(node, tree->free_value, tree->free_key); } FREE(tree); @@ -334,7 +352,7 @@ ecore_tree_get_closest_smaller(Ecore_Tree *tree, const void *key) * @return TRUE if successful, FALSE if not. */ EAPI int -ecore_tree_set(Ecore_Tree *tree, const void *key, void *value) +ecore_tree_set(Ecore_Tree *tree, void *key, void *value) { Ecore_Tree_Node *node = NULL; @@ -348,6 +366,14 @@ ecore_tree_set(Ecore_Tree *tree, const void *key, void *value) if (!ecore_tree_add_node(tree, node)) return FALSE; } + else + { + if (tree->free_key) + tree->free_key(key); + if (node->value && tree->free_value) + tree->free_value(node->value); + } + ecore_tree_node_value_set(node, value); for (; node; node = node->parent) @@ -537,7 +563,7 @@ ecore_tree_remove(Ecore_Tree *tree, const void *key) if (!ecore_tree_remove_node(tree, node)) return FALSE; - ecore_tree_node_destroy(node, tree->free_func); + ecore_tree_node_destroy(node, tree->free_value, tree->free_key); return TRUE; }