From 2893de11973c4912f4c2a3d40f09ef0823a3f091 Mon Sep 17 00:00:00 2001 From: Dmitri Pal Date: Fri, 23 Jul 2010 14:33:56 -0400 Subject: Allow destroying collection with a callback Addresses ticket #572 Bumps the library and interface version. Updates the docs. [COLLECTION] Changed callback signature --- collection/collection.c | 57 ++++++++++++++++++++++++++++++++------- collection/collection.h | 63 +++++++++++++++++++++++++++++++++++++++---- collection/collection_queue.h | 3 +++ collection/collection_stack.h | 3 +++ collection/collection_tools.h | 4 +++ collection/collection_ut.c | 18 ++++++++++++- contrib/ding-libs.spec.in | 6 ++--- 7 files changed, 135 insertions(+), 19 deletions(-) diff --git a/collection/collection.c b/collection/collection.c index 87ac321..f24102b 100644 --- a/collection/collection.c +++ b/collection/collection.c @@ -172,8 +172,11 @@ static int col_validate_property(const char *property) return invalid; } -/* Function that cleans the item */ -void col_delete_item(struct collection_item *item) + +/* Function that cleans the item with callback */ +static void col_delete_item_with_cb(struct collection_item *item, + col_item_cleanup_fn cb, + void *custom_data) { struct collection_item *other_collection; @@ -189,9 +192,17 @@ void col_delete_item(struct collection_item *item) /* Our data is a pointer to a whole external collection so dereference * it or delete */ other_collection = *((struct collection_item **)(item->data)); - col_destroy_collection(other_collection); + col_destroy_collection_with_cb(other_collection, cb, custom_data); } + /* Call the callback */ + if (cb) cb(item->property, + item->property_len, + item->type, + item->data, + item->length, + custom_data); + TRACE_INFO_STRING("Deleting property:", item->property); TRACE_INFO_NUMBER("Type:", item->type); @@ -203,6 +214,18 @@ void col_delete_item(struct collection_item *item) TRACE_FLOW_STRING("col_delete_item","Exit."); } +/* Function that cleans the item */ +void col_delete_item(struct collection_item *item) +{ + TRACE_FLOW_STRING("col_delete_item","Entry point."); + + col_delete_item_with_cb(item, NULL, NULL); + + TRACE_FLOW_STRING("col_delete_item","Exit."); +} + + + /* A generic function to allocate a property item */ int col_allocate_item(struct collection_item **ci, const char *property, const void *item_data, int length, int type) @@ -1164,7 +1187,9 @@ static int col_get_subcollection(const char *property, /* Cleans the collection tree including current item. */ /* The passed in variable should not be used after the call * as memory is freed!!! */ -static void col_delete_collection(struct collection_item *ci) +static void col_delete_collection(struct collection_item *ci, + col_item_cleanup_fn cb, + void *custom_data) { TRACE_FLOW_STRING("col_delete_collection", "Entry."); @@ -1177,10 +1202,10 @@ static void col_delete_collection(struct collection_item *ci) TRACE_INFO_STRING("Property", ci->property); TRACE_INFO_NUMBER("Next item", ci->next); - col_delete_collection(ci->next); + col_delete_collection(ci->next, cb, custom_data); /* Delete this item */ - col_delete_item(ci); + col_delete_item_with_cb(ci, cb, custom_data); TRACE_FLOW_STRING("col_delete_collection", "Exit."); } @@ -2235,11 +2260,13 @@ int col_create_collection(struct collection_item **ci, const char *name, /* DESTROY */ /* Function that destroys a collection */ -void col_destroy_collection(struct collection_item *ci) +void col_destroy_collection_with_cb(struct collection_item *ci, + col_item_cleanup_fn cb, + void *custom_data) { struct collection_header *header; - TRACE_FLOW_STRING("col_destroy_collection", "Entry."); + TRACE_FLOW_STRING("col_destroy_collection_with_cb", "Entry."); /* Do not try to delete NULL */ if (ci == NULL) return; @@ -2263,13 +2290,23 @@ void col_destroy_collection(struct collection_item *ci) header->reference_count); } else { - col_delete_collection(ci); + col_delete_collection(ci, cb, custom_data); } - TRACE_FLOW_STRING("col_destroy_collection", "Exit."); + TRACE_FLOW_STRING("col_destroy_collection_with_cb", "Exit."); } +/* Function that destroys a collection */ +void col_destroy_collection(struct collection_item *ci) +{ + TRACE_FLOW_STRING("col_destroy_collection", "Entry."); + + col_destroy_collection_with_cb(ci, NULL, NULL); + + TRACE_FLOW_STRING("col_destroy_collection", "Exit."); +} + /* COPY */ /* Wrapper around a more advanced function */ diff --git a/collection/collection.h b/collection/collection.h index b656ebb..2ec81bd 100644 --- a/collection/collection.h +++ b/collection/collection.h @@ -483,6 +483,60 @@ int col_create_collection(struct collection_item **ci, */ void col_destroy_collection(struct collection_item *ci); +/** + * @brief Cleanup Callback + * + * Signature of the callback that needs to be used when + * the collection is destroyed and a special cleanup operation + * is required for items in the collection. + * + * @param[in] property The name of the property will + * be passed in this parameter. + * @param[in] property_len Length of the property name + * will be passed in this parameter. + * @param[in] type Type of the data will be passed + * in this parameter. + * @param[in] data Pointer to the data will be passed + * in this parameter. + * @param[in] length Length of data will be passed in + * this parameter. + * @param[in] custom_data Custom data will be passed in + * this parameter. + * @return No return value. + */ + +typedef void (*col_item_cleanup_fn)(const char *property, + int property_len, + int type, + void *data, + int length, + void *custom_data); + +/** + * @brief Destroy a collection with callback + * + * Execute a provided callback for each item + * in the collection or subcollection immediately + * before freeing item. The callback is executed for each + * element including the collection header. + * It is the responsibility of the callback implementor + * to properly handle gifferent collection elements + * depending upon whether it is a header, reference to + * an embedded or external collection or a normal data + * element. + * + * The function will destroy a collection. + * + * @param[in] ci Collection object. + * @param[in] cb Cleanup callback. + * @param[in] custom_data Application data passed into + * the cleanup callback. + * + */ +void col_destroy_collection_with_cb(struct collection_item *ci, + col_item_cleanup_fn cb, + void *custom_data); + /** * @brief Copy item callback. * @@ -618,7 +672,7 @@ int col_add_collection_to_collection(struct collection_item *ci, * in this parameter. * @param[in] length Length of data will be passed in * this parameter. - * @param[in] custom_dat Custom data will be passed in + * @param[in] custom_data Custom data will be passed in * this parameter. * @param[out] stop Pointer to a variable where the handler * can put nonzero to stop traversing @@ -633,10 +687,9 @@ typedef int (*col_item_fn)(const char *property, int type, void *data, int length, - void *custom_dat, + void *custom_data, int *stop); - /** * @brief Traverse collection * @@ -2366,9 +2419,9 @@ int col_get_item_type(struct collection_item *ci); int col_get_item_length(struct collection_item *ci); /** - * @brief Get property value from the item. + * @brief Get value from the item. * - * Get property value from the item. + * Get value from the item. * * @param[in] ci Item to get value from. * If item is invalid the function diff --git a/collection/collection_queue.h b/collection/collection_queue.h index 86c3925..21350be 100644 --- a/collection/collection_queue.h +++ b/collection/collection_queue.h @@ -319,5 +319,8 @@ int col_enqueue_item(struct collection_item *queue, int col_dequeue_item(struct collection_item *queue, struct collection_item **item); +/** + * @} + */ #endif diff --git a/collection/collection_stack.h b/collection/collection_stack.h index f9b0130..1a7c470 100644 --- a/collection/collection_stack.h +++ b/collection/collection_stack.h @@ -322,4 +322,7 @@ int col_push_item(struct collection_item *stack, int col_pop_item(struct collection_item *stack, struct collection_item **item); +/** + * @} + */ #endif diff --git a/collection/collection_tools.h b/collection/collection_tools.h index eec91ca..586eef1 100644 --- a/collection/collection_tools.h +++ b/collection/collection_tools.h @@ -265,4 +265,8 @@ char **col_collection_to_list(struct collection_item *handle, */ void col_free_property_list(char **str_list); +/** + * @} + */ + #endif diff --git a/collection/collection_ut.c b/collection/collection_ut.c index 92d9d0c..2e4ead5 100644 --- a/collection/collection_ut.c +++ b/collection/collection_ut.c @@ -1497,11 +1497,27 @@ int insert_extract_test(void) return EOK; } +/* Cleanup collback */ +void cb(const char *property, + int property_len, + int type, + void *data, + int length, + void *ext_data) +{ + COLOUT(printf("%s\n", *((const char **)ext_data))); + COLOUT(printf("Property: %s\n", property)); + COLOUT(printf("Length: %d\n", property_len)); + COLOUT(printf("Type: %d\n", type)); + COLOUT(printf("Data len: %d\n", length)); +} + int delete_test(void) { struct collection_item *col; int error = EOK; + const char *str = "Cleanup Callback Test"; COLOUT(printf("\n\n==== DELETION TEST 1====\n\n")); @@ -1550,7 +1566,7 @@ int delete_test(void) COLOUT(printf("\n\n==== DELETION TEST 2 END ====\n\n")); - col_destroy_collection(col); + col_destroy_collection_with_cb(col, cb, (void *)(&str)); return error; } diff --git a/contrib/ding-libs.spec.in b/contrib/ding-libs.spec.in index 1c20074..d7b3561 100644 --- a/contrib/ding-libs.spec.in +++ b/contrib/ding-libs.spec.in @@ -10,7 +10,7 @@ BuildRoot: %(mktemp -ud %{_tmppath}/%{name}-%{version}-%{release}-XXXXXX) %global path_utils_version 0.2.1 %global dhash_version 0.4.1 -%global collection_version 0.5.1 +%global collection_version 0.6.0 %global ref_array_version 0.1.1 %global basicobjecs_vesion 0.1.0 %global ini_config_version 0.6.1 @@ -171,8 +171,8 @@ and serialization %defattr(-,root,root,-) %doc COPYING %doc COPYING.LESSER -%{_libdir}/libcollection.so.2 -%{_libdir}/libcollection.so.2.0.0 +%{_libdir}/libcollection.so.3 +%{_libdir}/libcollection.so.3.0.0 %files -n libcollection-devel %defattr(-,root,root,-) -- cgit