diff options
Diffstat (limited to 'src/H5I.c')
-rw-r--r-- | src/H5I.c | 144 |
1 files changed, 103 insertions, 41 deletions
@@ -108,6 +108,11 @@ typedef struct { H5I_id_info_t **id_list; /*pointer to an array of ptrs to IDs */ } H5I_id_type_t; +typedef struct { + H5I_search_func_t app_cb; /* Application's callback routine */ + void *app_key; /* Application's "key" (user data) */ + void *ret_obj; /* Object to return */ +} H5I_search_ud_t; /*-------------------- Locally scoped variables -----------------------------*/ @@ -127,6 +132,7 @@ H5FL_DEFINE_STATIC(H5I_id_info_t); /*--------------------- Local function prototypes ---------------------------*/ static H5I_id_info_t *H5I_find_id(hid_t id); +static int H5I_search_cb(void *obj, hid_t id, void *udata); #ifdef H5I_DEBUG_OUTPUT static herr_t H5I_debug(H5I_type_t type); #endif /* H5I_DEBUG_OUTPUT */ @@ -1905,6 +1911,40 @@ done: /*------------------------------------------------------------------------- + * Function: H5I_search_cb + * + * Purpose: Callback routine for H5Isearch, when it calls H5I_iterate. + * Calls "user" callback search function, and then sets return + * value, based on the result of that callback. + * + * Return: Success: The first object in the type for which FUNC + * returns non-zero. NULL if FUNC returned zero + * for every object in the type. + * Failure: NULL + * + * Programmer: Quincey Koziol + * Friday, March 30, 2012 + * + *------------------------------------------------------------------------- + */ +static int +H5I_search_cb(void *obj, hid_t id, void *_udata) +{ + H5I_search_ud_t *udata = (H5I_search_ud_t *)_udata; /* User data for callback */ + int ret_value; /* Callback return value */ + + FUNC_ENTER_NOAPI_NOINIT + + ret_value = (*udata->app_cb)(obj, id, udata->app_key); + if(ret_value > 0) + udata->ret_obj = obj; + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5I_search_cb() */ + + +/*------------------------------------------------------------------------- * Function: H5Isearch * * Purpose: Apply function FUNC to each member of type TYPE and return a @@ -1931,14 +1971,27 @@ done: void * H5Isearch(H5I_type_t type, H5I_search_func_t func, void *key) { - void * ret_value; /* Return value */ + H5I_search_ud_t udata; /* Context for iteration */ + void *ret_value; /* Return value */ FUNC_ENTER_API(NULL) + /* Check arguments */ if(H5I_IS_LIB_TYPE(type)) HGOTO_ERROR(H5E_ATOM, H5E_BADGROUP, NULL, "cannot call public function on library type") - ret_value = H5I_search(type, func, key, TRUE); + /* Set up udata struct */ + udata.app_cb = func; + udata.app_key = key; + udata.ret_obj = NULL; + + /* Note that H5I_iterate returns an error code. We ignore it + * here, as we can't do anything with it without revising the API. + */ + H5I_iterate(type, H5I_search_cb, &udata, TRUE); + + /* Set return value */ + ret_value = udata.ret_obj; done: FUNC_LEAVE_API(ret_value) @@ -1946,62 +1999,71 @@ done: /*------------------------------------------------------------------------- - * Function: H5I_search + * Function: H5I_iterate * - * Purpose: Apply function FUNC to each member of type TYPE and return a - * pointer to the first object for which FUNC returns non-zero. - * The FUNC should take a pointer to the object and the KEY as - * arguments and return non-zero to terminate the search (zero - * to continue). + * Purpose: Apply function FUNC to each member of type TYPE (with + * non-zero application reference count if app_ref is TRUE). + * Stop if FUNC returns a non zero value (i.e. anything + * other than H5_ITER_CONT). * - * Limitation: Currently there is no way to start searching from where a - * previous search left off. + * If FUNC returns a positive value (i.e. H5_ITER_STOP), + * return SUCCEED. * - * Return: Success: The first object in the type for which FUNC - * returns non-zero. NULL if FUNC returned zero - * for every object in the type. - * Failure: NULL + * If FUNC returns a negative value (i.e. H5_ITER_ERROR), + * return FAIL. + * + * The FUNC should take a pointer to the object and the + * udata as arguments and return non-zero to terminate + * siteration, and zero to continue. * - * Programmer: Robb Matzke - * Friday, February 19, 1999 + * Limitation: Currently there is no way to start the iteration from + * where a previous iteration left off. + * + * Return: Success: SUCCEED + * Failure: FAIL * - * Modifications: Neil Fortner - * Wednesday, October 1, 2008 - * Added app_ref parameter. When set to TRUE, the function will only - * operate on ids that have a nonzero application reference count. + * Programmer: John Mainzer + * Monday, December 6, 2011 * *------------------------------------------------------------------------- */ -void * -H5I_search(H5I_type_t type, H5I_search_func_t func, void *key, hbool_t app_ref) +herr_t +H5I_iterate(H5I_type_t type, H5I_search_func_t func, void *udata, hbool_t app_ref) { - H5I_id_type_t *type_ptr; /*ptr to the type */ - void *ret_value = NULL; /*return value */ + H5I_id_type_t *type_ptr; /*ptr to the type */ + herr_t ret_value = SUCCEED; /*return value */ - FUNC_ENTER_NOAPI(NULL) + FUNC_ENTER_NOAPI(FAIL) /* Check arguments */ if(type <= H5I_BADID || type >= H5I_next_type) - HGOTO_ERROR(H5E_ARGS, H5E_BADRANGE, NULL, "invalid type number") + HGOTO_ERROR(H5E_ARGS, H5E_BADRANGE, FAIL, "invalid type number") type_ptr = H5I_id_type_list_g[type]; - if(type_ptr == NULL || type_ptr->count <= 0) - HGOTO_ERROR(H5E_ATOM, H5E_BADGROUP, NULL, "invalid type") - /* Only iterate through hash table if there are IDs in group */ - if(type_ptr->ids > 0) { - H5I_id_info_t *id_ptr; /*ptr to the new ID */ - H5I_id_info_t *next_id; /*ptr to the next ID */ - unsigned i; /*counter */ + /* Only iterate through hash table if it is initialized and there are IDs in group */ + if(type_ptr && type_ptr->count > 0 && type_ptr->ids > 0) { + unsigned u; /* Counter */ /* Start at the beginning of the array */ - for(i = 0; i < type_ptr->hash_size; i++) { - id_ptr = type_ptr->id_list[i]; + for(u = 0; u < type_ptr->hash_size; u++) { + H5I_id_info_t *id_ptr; /* Ptr to the new ID */ + + id_ptr = type_ptr->id_list[u]; while(id_ptr) { - next_id = id_ptr->next; /* Protect against ID being deleted in callback */ - /* (Casting away const OK -QAK) */ - if((!app_ref || id_ptr->app_count) && (*func)((void *)id_ptr->obj_ptr, id_ptr->id, key)) - /* (Casting away const OK -QAK) */ - HGOTO_DONE((void *)id_ptr->obj_ptr); /*found the item*/ + H5I_id_info_t *next_id; /* Ptr to the next ID */ + + /* Protect against ID being deleted in callback */ + next_id = id_ptr->next; + if((!app_ref) || (id_ptr->app_count > 0)) { + herr_t cb_ret_val; /* Callback return value */ + + /* (Casting away const OK) */ + cb_ret_val = (*func)((void *)id_ptr->obj_ptr, id_ptr->id, udata); + if(cb_ret_val > 0) + HGOTO_DONE(SUCCEED) /* terminate iteration early */ + else if(cb_ret_val < 0) + HGOTO_ERROR(H5E_ARGS, H5E_BADRANGE, FAIL, "func failed") + } /* end if */ id_ptr = next_id; } /* end while */ } /* end for */ @@ -2009,7 +2071,7 @@ H5I_search(H5I_type_t type, H5I_search_func_t func, void *key, hbool_t app_ref) done: FUNC_LEAVE_NOAPI(ret_value) -} /* end H5I_search() */ +} /* end H5I_iterate() */ /*------------------------------------------------------------------------- |