diff options
Diffstat (limited to 'src/H5I.c')
-rw-r--r-- | src/H5I.c | 1620 |
1 files changed, 922 insertions, 698 deletions
@@ -12,49 +12,38 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* - * FILE: H5I.c - Internal storage routines for handling "IDs" + * FILE: H5I.c - Internal storage routines for handling "IDs" * - * REMARKS: ID's which allow objects (void *'s currently) to be bundled - * into "types" for more general storage. + * REMARKS: IDs which allow objects (void * currently) to be bundled + * into "types" for more general storage. * - * DESIGN: The types are stored in an array of pointers to store each - * type in an element. Each "type" node contains a link to a - * hash table to manage the IDs in each type. Allowed types are - * values within the range 1 to H5I_MAX_NUM_TYPES and are given out - * at run-time. Types used by the library are stored in global - * variables defined in H5Ipublic.h. - * - * AUTHOR: Quincey Koziol - * - * MODIFICATIONS: - * 1/3/96 - Starting writing specs & coding prototype - * 1/7/96 - Finished coding prototype - * 6/10/97 - Moved into HDF5 library - * 5/18/04 - Expanded to allow registration of new types at run-time + * DESIGN: The types are stored in an array of pointers to store each + * type in an element. Each "type" node contains a link to a + * hash table to manage the IDs in each type. Allowed types are + * values within the range 1 to H5I_MAX_NUM_TYPES and are given out + * at run-time. Types used by the library are stored in global + * variables defined in H5Ipublic.h. */ #include "H5Imodule.h" /* This source code file is part of the H5I module */ +#define H5T_FRIEND /* Suppress error about including H5Tpkg */ + +#include "H5private.h" /* Generic Functions */ +#include "H5ACprivate.h" /* Metadata cache */ +#include "H5CXprivate.h" /* API Contexts */ +#include "H5Dprivate.h" /* Datasets */ +#include "H5Eprivate.h" /* Error handling */ +#include "H5Fprivate.h" /* File access */ +#include "H5FLprivate.h" /* Free Lists */ +#include "H5Gprivate.h" /* Groups */ +#include "H5Ipkg.h" /* IDs */ +#include "H5MMprivate.h" /* Memory management */ +#include "H5Oprivate.h" /* Object headers */ +#include "H5SLprivate.h" /* Skip Lists */ +#include "H5Tpkg.h" /* Datatypes */ +#include "H5VLprivate.h" /* Virtual Object Layer */ -#include "H5private.h" /* Generic Functions */ -#include "H5ACprivate.h" /* Metadata cache */ -#include "H5Eprivate.h" /* Error handling */ -#include "H5FLprivate.h" /* Free Lists */ -#include "H5Ipkg.h" /* IDs */ -#include "H5MMprivate.h" /* Memory management */ -#include "H5Oprivate.h" /* Object headers */ -#include "H5SLprivate.h" /* Skip Lists */ - -/* Define this to compile in support for dumping ID information */ -/* #define H5I_DEBUG_OUTPUT */ -#ifndef H5I_DEBUG_OUTPUT -#include "H5Gprivate.h" /* Groups */ -#else /* H5I_DEBUG_OUTPUT */ -#define H5G_FRIEND /*suppress error about including H5Gpkg */ -#include "H5Gpkg.h" /* Groups */ -#include "H5Dprivate.h" /* Datasets */ -#include "H5Tprivate.h" /* Datatypes */ -#endif /* H5I_DEBUG_OUTPUT */ /* Local Macros */ @@ -78,20 +67,34 @@ typedef struct { unsigned init_count; /* # of times this type has been initialized*/ uint64_t id_count; /* Current number of IDs held */ uint64_t nextid; /* ID to use for the next atom */ + H5I_id_info_t *last_info; /* Info for most recent ID looked up */ H5SL_t *ids; /* Pointer to skip list that stores 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_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; +typedef struct { + H5I_iterate_func_t op; /* Application's callback routine */ + void *op_data; /* Application's user data */ +} H5I_iterate_pub_ud_t; + +/* User data for iterator callback for retrieving an ID corresponding to an object pointer */ +typedef struct { + const void *object; /* object pointer to search for */ + H5I_type_t obj_type; /* type of object we are searching for */ + hid_t ret_id; /* ID returned */ +} H5I_get_id_ud_t; + /* User data for iterator callback for ID iteration */ typedef struct { - H5I_search_func_t user_func; /* 'User' function to invoke */ - void *user_udata; /* User data to pass to 'user' function */ - hbool_t app_ref; /* Whether this is an appl. ref. call */ + H5I_search_func_t user_func; /* 'User' function to invoke */ + void *user_udata; /* User data to pass to 'user' function */ + hbool_t app_ref; /* Whether this is an appl. ref. call */ + H5I_type_t obj_type; /* Type of object we are iterating over */ } H5I_iterate_ud_t; /* User data for H5I__clear_type_cb */ @@ -115,7 +118,7 @@ static H5I_id_type_t *H5I_id_type_list_g[H5I_MAX_NUM_TYPES]; /* Starts at 1 instead of 0 because it makes trace output look nicer. If more */ /* types (or IDs within a type) are needed, adjust TYPE_BITS in H5Ipkg.h */ /* and/or increase size of hid_t */ -static H5I_type_t H5I_next_type = (H5I_type_t) H5I_NTYPES; +static int H5I_next_type = (int)H5I_NTYPES; /* Declare a free list to manage the H5I_id_info_t struct */ H5FL_DEFINE_STATIC(H5I_id_info_t); @@ -126,32 +129,34 @@ H5FL_DEFINE_STATIC(H5I_id_type_t); /* Declare a free list to manage the H5I_class_t struct */ H5FL_DEFINE_STATIC(H5I_class_t); +H5FL_EXTERN(H5VL_object_t); + /*--------------------- Local function prototypes ---------------------------*/ +static void *H5I__unwrap(void *obj_ptr, H5I_type_t type); static htri_t H5I__clear_type_cb(void *_id, void *key, void *udata); static int H5I__destroy_type(H5I_type_t type); static void *H5I__remove_verify(hid_t id, H5I_type_t id_type); static void *H5I__remove_common(H5I_id_type_t *type_ptr, hid_t id); static int H5I__inc_type_ref(H5I_type_t type); static int H5I__get_type_ref(H5I_type_t type); +static int H5I__search_cb(void *obj, hid_t id, void *_udata); static H5I_id_info_t *H5I__find_id(hid_t id); -#ifdef H5I_DEBUG_OUTPUT -static herr_t H5I__debug(H5I_type_t type); -#endif /* H5I_DEBUG_OUTPUT */ +static int H5I__iterate_pub_cb(void *obj, hid_t id, void *udata); +static int H5I__find_id_cb(void *_item, void *_key, void *_udata); +static int H5I__id_dump_cb(void *_item, void *_key, void *_udata); /*------------------------------------------------------------------------- - * Function: H5I_term_package + * Function: H5I_term_package * - * Purpose: Terminate the H5I interface: release all memory, reset all - * global variables to initial values. This only happens if all - * types have been destroyed from other interfaces. + * Purpose: Terminate the H5I interface: release all memory, reset all + * global variables to initial values. This only happens if all + * types have been destroyed from other interfaces. * - * Return: Success: Positive if any action was taken that might - * affect some other interface; zero otherwise. + * Return: Success: Positive if any action was taken that might + * affect some other interface; zero otherwise. * - * Failure: Negative. - * - * Programmer: Unknown + * Failure: Negative * *------------------------------------------------------------------------- */ @@ -164,16 +169,16 @@ H5I_term_package(void) if(H5_PKG_INIT_VAR) { H5I_id_type_t *type_ptr; /* Pointer to ID type */ - H5I_type_t type; /* Type of ID */ + int type; /* Type of ID */ /* How many types are still being used? */ - for(type = (H5I_type_t)0; type < H5I_next_type; H5_INC_ENUM(H5I_type_t, type)) + for(type = 0; type < H5I_next_type; type++) if((type_ptr = H5I_id_type_list_g[type]) && type_ptr->ids) n++; /* If no types are used then clean up */ if(0 == n) { - for(type = (H5I_type_t)0; type < H5I_next_type; H5_INC_ENUM(H5I_type_t,type)) { + for(type = 0; type < H5I_next_type; type++) { type_ptr = H5I_id_type_list_g[type]; if(type_ptr) { HDassert(NULL == type_ptr->ids); @@ -194,28 +199,25 @@ H5I_term_package(void) /*------------------------------------------------------------------------- - * Function: H5Iregister_type + * Function: H5Iregister_type * - * Purpose: Public interface to H5I_register_type. Creates a new type - * of ID's to give out. A specific number (RESERVED) of type - * entries may be reserved to enable "constant" values to be handed - * out which are valid IDs in the type, but which do not map to any - * data structures and are not allocated dynamically later. HASH_SIZE is - * the minimum hash table size to use for the type. FREE_FUNC is - * called with an object pointer when the object is removed from - * the type. + * Purpose: Public interface to H5I_register_type. Creates a new type + * of ID's to give out. A specific number (RESERVED) of type + * entries may be reserved to enable "constant" values to be handed + * out which are valid IDs in the type, but which do not map to any + * data structures and are not allocated dynamically later. HASH_SIZE is + * the minimum hash table size to use for the type. FREE_FUNC is + * called with an object pointer when the object is removed from + * the type. * - * Return: Success: Type ID of the new type - * Failure: H5I_BADID - * - * Programmers: Nathaniel Furrer - * James Laird - * Friday, April 30, 2004 + * Return: Success: Type ID of the new type + * Failure: H5I_BADID * *------------------------------------------------------------------------- */ H5I_type_t -H5Iregister_type(size_t hash_size, unsigned reserved, H5I_free_t free_func) +H5Iregister_type(size_t H5_ATTR_DEBUG_API_USED hash_size, unsigned reserved, + H5I_free_t free_func) { H5I_class_t *cls = NULL; /* New ID class */ H5I_type_t new_type; /* New ID type value */ @@ -226,10 +228,10 @@ H5Iregister_type(size_t hash_size, unsigned reserved, H5I_free_t free_func) /* Generate a new H5I_type_t value */ - /* Increment the number of types*/ + /* Increment the number of types */ if(H5I_next_type < H5I_MAX_NUM_TYPES) { - new_type = H5I_next_type; - H5_INC_ENUM(H5I_type_t, H5I_next_type); + new_type = (H5I_type_t)H5I_next_type; + H5I_next_type++; } /* end if */ else { hbool_t done; /* Indicate that search was successful */ @@ -247,11 +249,11 @@ H5Iregister_type(size_t hash_size, unsigned reserved, H5I_free_t free_func) /* Verify that we found a type to give out */ if(done == FALSE) - HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, H5I_BADID, "Maximum number of ID types exceeded.") + HGOTO_ERROR(H5E_ATOM, H5E_NOSPACE, H5I_BADID, "Maximum number of ID types exceeded") } /* end else */ /* Allocate new ID class */ - if(NULL == (cls = H5FL_MALLOC(H5I_class_t))) + if(NULL == (cls = H5FL_CALLOC(H5I_class_t))) HGOTO_ERROR(H5E_ATOM, H5E_CANTALLOC, H5I_BADID, "ID class allocation failed") /* Initialize class fields */ @@ -278,18 +280,13 @@ done: /*------------------------------------------------------------------------- - * Function: H5I_register_type + * Function: H5I_register_type * - * Purpose: Creates a new type of ID's to give out. - * The class is initialized or its reference count is incremented + * Purpose: Creates a new type of ID's to give out. + * The class is initialized or its reference count is incremented * (if it is already initialized). * - * Return: Success: Type ID of the new type - * Failure: H5I_BADID - * - * Programmers: Nathaniel Furrer - * James Laird - * Friday, April 30, 2004 + * Return: SUCCEED/FAIL * *------------------------------------------------------------------------- */ @@ -303,7 +300,7 @@ H5I_register_type(const H5I_class_t *cls) /* Sanity check */ HDassert(cls); - HDassert(cls->type_id > 0 && cls->type_id < H5I_MAX_NUM_TYPES); + HDassert(cls->type_id > 0 && (int)cls->type_id < H5I_MAX_NUM_TYPES); /* Initialize the type */ if(NULL == H5I_id_type_list_g[cls->type_id]) { @@ -322,6 +319,7 @@ H5I_register_type(const H5I_class_t *cls) type_ptr->cls = cls; type_ptr->id_count = 0; type_ptr->nextid = cls->reserved; + type_ptr->last_info = NULL; if(NULL == (type_ptr->ids = H5SL_create(H5SL_TYPE_HID, NULL))) HGOTO_ERROR(H5E_ATOM, H5E_CANTCREATE, FAIL, "skip list creation failed") } /* end if */ @@ -343,17 +341,12 @@ done: /*------------------------------------------------------------------------- - * Function: H5Itype_exists + * Function: H5Itype_exists * * Purpose: Query function to inform the user if a given type is * currently registered with the library. * - * Return: Success: 1 if the type is registered, 0 if it is not - * Failure: Negative - * - * Programmer: James Laird - * Nathaniel Furrer - * Tuesday, June 29, 2004 + * Return: TRUE/FALSE/FAIL * *------------------------------------------------------------------------- */ @@ -365,8 +358,11 @@ H5Itype_exists(H5I_type_t type) FUNC_ENTER_API(FAIL) H5TRACE1("t", "It", type); - if(type <= H5I_BADID || type >= H5I_next_type) - HGOTO_ERROR(H5E_ARGS, H5E_BADRANGE, FAIL, "invalid type number") + /* Validate parameter */ + if(H5I_IS_LIB_TYPE(type)) + HGOTO_ERROR(H5E_ATOM, H5E_BADGROUP, FAIL, "cannot call public function on library type") + if(type <= H5I_BADID || (int)type >= H5I_next_type) + HGOTO_ERROR(H5E_ARGS, H5E_BADRANGE, FAIL, "invalid type number") if(NULL == H5I_id_type_list_g[type]) ret_value = FALSE; @@ -377,15 +373,14 @@ done: /*------------------------------------------------------------------------- - * Function: H5Inmembers + * Function: H5Inmembers * - * Purpose: Returns the number of members in a type. Public interface to - * H5I_nmembers. The public interface throws an error if the + * Purpose: Returns the number of members in a type. Public interface to + * H5I_nmembers. The public interface throws an error if the * supplied type does not exist. This is different than the * private interface, which will just return 0. * - * Return: Success: Zero - * Failure: Negative + * Return: SUCCEED/FAIL * * Programmer: James Laird * Nathaniel Furrer @@ -408,10 +403,10 @@ H5Inmembers(H5I_type_t type, hsize_t *num_members) * the private interface handle it, because the public interface throws * an error when the supplied type does not exist. */ - if(type <= H5I_BADID || type >= H5I_next_type) - HGOTO_ERROR(H5E_ARGS, H5E_BADRANGE, FAIL, "invalid type number") + if(type <= H5I_BADID || (int)type >= H5I_next_type) + HGOTO_ERROR(H5E_ARGS, H5E_BADRANGE, FAIL, "invalid type number") if(NULL == H5I_id_type_list_g[type]) - HGOTO_ERROR(H5E_ARGS, H5E_BADRANGE, FAIL, "supplied type does not exist") + HGOTO_ERROR(H5E_ARGS, H5E_BADRANGE, FAIL, "supplied type does not exist") if(num_members) { int64_t members; @@ -428,14 +423,14 @@ done: /*------------------------------------------------------------------------- - * Function: H5I_nmembers + * Function: H5I_nmembers * - * Purpose: Returns the number of members in a type. + * Purpose: Returns the number of members in a type. * - * Return: Success: Number of members; zero if the type is empty - * or has been deleted. + * Return: Success: Number of members; zero if the type is empty + * or has been deleted. * - * Failure: Negative + * Failure: Negative * * Programmer: Robb Matzke * Wednesday, March 24, 1999 @@ -450,7 +445,8 @@ H5I_nmembers(H5I_type_t type) FUNC_ENTER_NOAPI(FAIL) - if(type <= H5I_BADID || type >= H5I_next_type) + /* Validate parameter */ + if(type <= H5I_BADID || (int)type >= H5I_next_type) HGOTO_ERROR(H5E_ARGS, H5E_BADRANGE, FAIL, "invalid type number") if(NULL == (type_ptr = H5I_id_type_list_g[type]) || type_ptr->init_count <= 0) HGOTO_DONE(0); @@ -464,14 +460,57 @@ done: /*------------------------------------------------------------------------- - * Function: H5Iclear_type + * Function: H5I__unwrap + * + * Purpose: Unwraps the object pointer for the 'item' that corresponds + * to an ID. + * + * Return: Pointer to the unwrapped pointer (can't fail) + * + * Programmer: Quincey Koziol + * Friday, October 19, 2018 + * + *------------------------------------------------------------------------- + */ +static void * +H5I__unwrap(void *obj_ptr, H5I_type_t type) +{ + void *ret_value = NULL; /* Return value */ + + FUNC_ENTER_STATIC_NOERR + + /* Sanity checks */ + HDassert(obj_ptr); + + /* The stored object pointer might be an H5VL_object_t, in which + * case we'll need to get the wrapped object struct (H5F_t *, etc.). + */ + if(H5I_FILE == type || H5I_GROUP == type || H5I_DATASET == type || H5I_ATTR == type) { + const H5VL_object_t *vol_obj; + + vol_obj = (const H5VL_object_t *)obj_ptr; + ret_value = H5VL_object_data(vol_obj); + } /* end if */ + else if(H5I_DATATYPE == type) { + H5T_t *dt = (H5T_t *)obj_ptr; + + ret_value = (void *)H5T_get_actual_type(dt); + } /* end if */ + else + ret_value = obj_ptr; + + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5I__unwrap() */ + + +/*------------------------------------------------------------------------- + * Function: H5Iclear_type * - * Purpose: Removes all objects from the type, calling the free - * function for each object regardless of the reference count. - * Public interface to H5I_clear_type. + * Purpose: Removes all objects from the type, calling the free + * function for each object regardless of the reference count. + * Public interface to H5I_clear_type. * - * Return: Success: Non-negative - * Failure: negative + * Return: SUCCEED/FAIL * * Programmer: James Laird * Nathaniel Furrer @@ -498,13 +537,12 @@ done: /*------------------------------------------------------------------------- - * Function: H5I_clear_type + * Function: H5I_clear_type * - * Purpose: Removes all objects from the type, calling the free - * function for each object regardless of the reference count. + * Purpose: Removes all objects from the type, calling the free + * function for each object regardless of the reference count. * - * Return: Success: Non-negative - * Failure: negative + * Return: SUCCEED/FAIL * * Programmer: Robb Matzke * Wednesday, March 24, 1999 @@ -519,7 +557,8 @@ H5I_clear_type(H5I_type_t type, hbool_t force, hbool_t app_ref) FUNC_ENTER_NOAPI(FAIL) - if(type <= H5I_BADID || type >= H5I_next_type) + /* Validate parameters */ + if(type <= H5I_BADID || (int)type >= H5I_next_type) HGOTO_ERROR(H5E_ARGS, H5E_BADRANGE, FAIL, "invalid type number") udata.type_ptr = H5I_id_type_list_g[type]; @@ -542,11 +581,10 @@ done: /*------------------------------------------------------------------------- * Function: H5I__clear_type_cb * - * Purpose: Attempts to free the specified ID , calling the free + * Purpose: Attempts to free the specified ID, calling the free * function for the object. * - * Return: Success: Non-negative - * Failure: negative + * Return: TRUE/FALSE/FAIL * * Programmer: Neil Fortner * Friday, July 10, 2015 @@ -562,22 +600,21 @@ H5I__clear_type_cb(void *_id, void H5_ATTR_UNUSED *key, void *_udata) FUNC_ENTER_STATIC_NOERR + /* Sanity checks */ HDassert(id); HDassert(udata); HDassert(udata->type_ptr); - /* - * Do nothing to the object if the reference count is larger than + /* Do nothing to the object if the reference count is larger than * one and forcing is off. */ if(udata->force || (id->count - (!udata->app_ref * id->app_count)) <= 1) { /* Check for a 'free' function and call it, if it exists */ - /* (Casting away const OK -QAK) */ - if(udata->type_ptr->cls->free_func && (udata->type_ptr->cls->free_func)((void *)id->obj_ptr) < 0) { + if(udata->type_ptr->cls->free_func && (udata->type_ptr->cls->free_func)((void *)id->obj_ptr) < 0) { /* (Casting away const OK -QAK) */ if(udata->force) { #ifdef H5I_DEBUG if(H5DEBUG(I)) { - fprintf(H5DEBUG(I), "H5I: free type=%d obj=0x%08lx " + HDfprintf(H5DEBUG(I), "H5I: free type=%d obj=0x%08lx " "failure ignored\n", (int)udata->type_ptr->cls->type_id, (unsigned long)(id->obj_ptr)); @@ -608,15 +645,15 @@ H5I__clear_type_cb(void *_id, void H5_ATTR_UNUSED *key, void *_udata) /*------------------------------------------------------------------------- - * Function: H5Idestroy_type + * Function: H5Idestroy_type * - * Purpose: Destroys a type along with all atoms in that type - * regardless of their reference counts. Destroying IDs - * involves calling the free-func for each ID's object and - * then adding the ID struct to the ID free list. Public - * interface to H5I__destroy_type. + * Purpose: Destroys a type along with all atoms in that type + * regardless of their reference counts. Destroying IDs + * involves calling the free-func for each ID's object and + * then adding the ID struct to the ID free list. Public + * interface to H5I__destroy_type. * - * Return: Zero on success/Negative on failure + * Return: SUCCEED/FAIL * * Programmer: Nathaniel Furrer * James Laird @@ -642,14 +679,14 @@ done: /*------------------------------------------------------------------------- - * Function: H5I__destroy_type + * Function: H5I__destroy_type * - * Purpose: Destroys a type along with all atoms in that type - * regardless of their reference counts. Destroying IDs - * involves calling the free-func for each ID's object and - * then adding the ID struct to the ID free list. + * Purpose: Destroys a type along with all atoms in that type + * regardless of their reference counts. Destroying IDs + * involves calling the free-func for each ID's object and + * then adding the ID struct to the ID free list. * - * Return: Zero on success/Negative on failure + * Return: SUCCEED/FAIL * * Programmer: Nathaniel Furrer * James Laird @@ -664,7 +701,8 @@ H5I__destroy_type(H5I_type_t type) FUNC_ENTER_STATIC - if(type <= H5I_BADID || type >= H5I_next_type) + /* Validate parameter */ + if(type <= H5I_BADID || (int)type >= H5I_next_type) HGOTO_ERROR(H5E_ARGS, H5E_BADRANGE, FAIL, "invalid type number") type_ptr = H5I_id_type_list_g[type]; @@ -693,15 +731,12 @@ done: /*------------------------------------------------------------------------- - * Function: H5Iregister + * Function: H5Iregister * - * Purpose: Public interface to H5I_register. + * Purpose: Public interface to H5I_register. * - * Return: Success: New object id. - * Failure: Negative - * - * Programmer: Nathaniel Furrer - * James Laird + * Return: Success: New object ID + * Failure: H5I_INVALID_HID * *------------------------------------------------------------------------- */ @@ -724,60 +759,59 @@ done: /*------------------------------------------------------------------------- - * Function: H5I_register + * Function: H5I_register * - * Purpose: Registers an OBJECT in a TYPE and returns an ID for it. - * This routine does _not_ check for unique-ness of the objects, - * if you register an object twice, you will get two different - * IDs for it. This routine does make certain that each ID in a - * type is unique. IDs are created by getting a unique number - * for the type the ID is in and incorporating the type into - * the ID which is returned to the user. + * Purpose: Registers an OBJECT in a TYPE and returns an ID for it. + * This routine does _not_ check for unique-ness of the objects, + * if you register an object twice, you will get two different + * IDs for it. This routine does make certain that each ID in a + * type is unique. IDs are created by getting a unique number + * for the type the ID is in and incorporating the type into + * the ID which is returned to the user. * - * Return: Success: New object id. - * Failure: Negative - * - * Programmer: Unknown + * Return: Success: New object ID + * Failure: H5I_INVALID_HID * *------------------------------------------------------------------------- */ hid_t H5I_register(H5I_type_t type, const void *object, hbool_t app_ref) { - H5I_id_type_t *type_ptr; /*ptr to the type */ - H5I_id_info_t *id_ptr; /*ptr to the new ID information */ - hid_t new_id; /*new ID */ - hid_t ret_value = SUCCEED; /*return value */ + H5I_id_type_t *type_ptr = NULL; /* ptr to the type */ + H5I_id_info_t *id_ptr = NULL; /* ptr to the new ID information */ + hid_t new_id = -1; /* new ID */ + hid_t ret_value = H5I_INVALID_HID; /* return value */ FUNC_ENTER_NOAPI(FAIL) /* Check arguments */ - if(type <= H5I_BADID || type >= H5I_next_type) - HGOTO_ERROR(H5E_ARGS, H5E_BADRANGE, FAIL, "invalid type number") + if (type <= H5I_BADID || (int)type >= H5I_next_type) + HGOTO_ERROR(H5E_ARGS, H5E_BADRANGE, H5I_INVALID_HID, "invalid type number") type_ptr = H5I_id_type_list_g[type]; - if(NULL == type_ptr || type_ptr->init_count <= 0) - HGOTO_ERROR(H5E_ATOM, H5E_BADGROUP, FAIL, "invalid type") - if(NULL == (id_ptr = H5FL_MALLOC(H5I_id_info_t))) - HGOTO_ERROR(H5E_ATOM, H5E_NOSPACE, FAIL, "memory allocation failed") + if ((NULL == type_ptr) || (type_ptr->init_count <= 0)) + HGOTO_ERROR(H5E_ATOM, H5E_BADGROUP, H5I_INVALID_HID, "invalid type") + if (NULL == (id_ptr = H5FL_MALLOC(H5I_id_info_t))) + HGOTO_ERROR(H5E_ATOM, H5E_NOSPACE, H5I_INVALID_HID, "memory allocation failed") - /* Create the struct & it's ID */ + /* Create the struct & its ID */ new_id = H5I_MAKE(type, type_ptr->nextid); - id_ptr->id = new_id; - id_ptr->count = 1; /*initial reference count*/ - id_ptr->app_count = !!app_ref; - id_ptr->obj_ptr = object; + id_ptr->id = new_id; + id_ptr->count = 1; /* initial reference count */ + id_ptr->app_count = !!app_ref; + id_ptr->obj_ptr = object; /* Insert into the type */ - if(H5SL_insert(type_ptr->ids, id_ptr, &id_ptr->id) < 0) - HGOTO_ERROR(H5E_ATOM, H5E_CANTINSERT, FAIL, "can't insert ID node into skip list") + if (H5SL_insert(type_ptr->ids, id_ptr, &id_ptr->id) < 0) + HGOTO_ERROR(H5E_ATOM, H5E_CANTINSERT, H5I_INVALID_HID, "can't insert ID node into skip list") type_ptr->id_count++; type_ptr->nextid++; - /* - * Sanity check for the 'nextid' getting too large and wrapping around. - */ + /* Sanity check for the 'nextid' getting too large and wrapping around */ HDassert(type_ptr->nextid <= ID_MASK); + /* Set the most recent ID to this object */ + type_ptr->last_info = id_ptr; + /* Set return value */ ret_value = new_id; @@ -787,40 +821,41 @@ done: /*------------------------------------------------------------------------- - * Function: H5I_register_with_id + * Function: H5I_register_using_existing_id * - * Purpose: Registers an OBJECT in a TYPE with the supplied ID for it. - * This routine will check to ensure the supplied ID is not already - * in use, and ensure that it is a valid ID for the given type, - * but will NOT check to ensure the OBJECT is not already - * registered (thus, it is possible to register one object under - * multiple IDs). + * Purpose: Registers an OBJECT in a TYPE with the supplied ID for it. + * This routine will check to ensure the supplied ID is not already + * in use, and ensure that it is a valid ID for the given type, + * but will NOT check to ensure the OBJECT is not already + * registered (thus, it is possible to register one object under + * multiple IDs). * - * Return: Success: 0 - * Failure: -1 + * NOTE: Intended for use in refresh calls, where we have to close + * and re-open the underlying data, then hook the object back + * up to the original ID. * - * Programmer: Mike McGreevy - * Wednesday, July 21, 2010 + * Return: SUCCEED/FAIL * *------------------------------------------------------------------------- */ herr_t -H5I_register_with_id(H5I_type_t type, const void *object, hbool_t app_ref, hid_t id) +H5I_register_using_existing_id(H5I_type_t type, void *object, hbool_t app_ref, hid_t existing_id) { - H5I_id_type_t *type_ptr; /*ptr to the type */ - H5I_id_info_t *id_ptr; /*ptr to the new ID information */ - herr_t ret_value = SUCCEED; /*return value */ + H5I_id_type_t *type_ptr; /* ptr to the type */ + H5I_id_info_t *id_ptr; /* ptr to the new ID information */ + herr_t ret_value = SUCCEED; /* return value */ FUNC_ENTER_NOAPI(FAIL) /* Check arguments */ + HDassert(object); /* Make sure ID is not already in use */ - if(NULL != (id_ptr = H5I__find_id(id))) - HGOTO_ERROR(H5E_ATOM, H5E_BADRANGE, FAIL, "ID already in use?!") + if(NULL != (id_ptr = H5I__find_id(existing_id))) + HGOTO_ERROR(H5E_ATOM, H5E_BADRANGE, FAIL, "ID already in use") /* Make sure type number is valid */ - if(type <= H5I_BADID || type >= H5I_next_type) + if(type <= H5I_BADID || (int)type >= H5I_next_type) HGOTO_ERROR(H5E_ARGS, H5E_BADRANGE, FAIL, "invalid type number") /* Get type pointer from list of types */ @@ -830,7 +865,7 @@ H5I_register_with_id(H5I_type_t type, const void *object, hbool_t app_ref, hid_t HGOTO_ERROR(H5E_ATOM, H5E_BADGROUP, FAIL, "invalid type") /* Make sure requested ID belongs to object's type */ - if(H5I_TYPE(id) != type) + if(H5I_TYPE(existing_id) != type) HGOTO_ERROR(H5E_ATOM, H5E_BADRANGE, FAIL, "invalid type for provided ID") /* Allocate new structure to house this ID */ @@ -838,29 +873,32 @@ H5I_register_with_id(H5I_type_t type, const void *object, hbool_t app_ref, hid_t HGOTO_ERROR(H5E_ATOM, H5E_NOSPACE, FAIL, "memory allocation failed") /* Create the struct & insert requested ID */ - id_ptr->id = id; - id_ptr->count = 1; /*initial reference count*/ - id_ptr->app_count = !!app_ref; - id_ptr->obj_ptr = object; + id_ptr->id = existing_id; + id_ptr->count = 1; /* initial reference count*/ + id_ptr->app_count = !!app_ref; + id_ptr->obj_ptr = object; /* Insert into the type */ if(H5SL_insert(type_ptr->ids, id_ptr, &id_ptr->id) < 0) HGOTO_ERROR(H5E_ATOM, H5E_CANTINSERT, FAIL, "can't insert ID node into skip list") type_ptr->id_count++; + /* Set the most recent ID to this object */ + type_ptr->last_info = id_ptr; + done: FUNC_LEAVE_NOAPI(ret_value) -} /* end H5I_register_with_id() */ +} /* end H5I_register_using_existing_id() */ /*------------------------------------------------------------------------- - * Function: H5I_subst + * Function: H5I_subst * - * Purpose: Substitute a new object pointer for the specified ID. + * Purpose: Substitute a new object pointer for the specified ID. * - * Return: Success: Non-null previous object pointer associated - * with the specified ID. - * Failure: NULL + * Return: Success: Non-NULL previous object pointer associated + * with the specified ID. + * Failure: NULL * * Programmer: Quincey Koziol * Saturday, February 27, 2010 @@ -880,8 +918,7 @@ H5I_subst(hid_t id, const void *new_object) HGOTO_ERROR(H5E_ATOM, H5E_NOTFOUND, NULL, "can't get ID ref count") /* Get the old object pointer to return */ - /* (Casting away const OK -QAK) */ - ret_value = (void *)id_ptr->obj_ptr; + ret_value = (void *)id_ptr->obj_ptr; /* (Casting away const OK -QAK) */ /* Set the new object pointer for the ID */ id_ptr->obj_ptr = new_object; @@ -892,51 +929,45 @@ done: /*------------------------------------------------------------------------- - * Function: H5I_object + * Function: H5I_object * - * Purpose: Find an object pointer for the specified ID. + * Purpose: Find an object pointer for the specified ID. * - * Return: Success: Non-null object pointer associated with the - * specified ID. - * Failure: NULL + * Return: Success: Non-NULL object pointer associated with the + * specified ID * - * Programmer: Unknown + * Failure: NULL * *------------------------------------------------------------------------- */ void * H5I_object(hid_t id) { - H5I_id_info_t *id_ptr; /*ptr to the new atom */ - void *ret_value = NULL; /*return value */ + H5I_id_info_t *id_ptr; /* Pointer to the new atom */ + void *ret_value = NULL; /* Return value */ FUNC_ENTER_NOAPI_NOERR /* General lookup of the ID */ if(NULL != (id_ptr = H5I__find_id(id))) { /* Get the object pointer to return */ - /* (Casting away const OK -QAK) */ - ret_value = (void *)id_ptr->obj_ptr; - } /* end if */ + ret_value = (void *)id_ptr->obj_ptr; /* (Casting away const OK -QAK) */ + } FUNC_LEAVE_NOAPI(ret_value) } /* end H5I_object() */ /*------------------------------------------------------------------------- - * Function: H5Iobject_verify + * Function: H5Iobject_verify * - * Purpose: Find an object pointer for the specified ID, verifying that - * its in a particular type. Public interface to - * H5I_object_verify. + * Purpose: Find an object pointer for the specified ID, verifying that + * its in a particular type. Public interface to + * H5I_object_verify. * - * Return: Success: Non-null object pointer associated with the - * specified ID. - * Failure: NULL - * - * Programmer: Nathaniel Furrer - * James Laird - * Friday, April 23, 2004 + * Return: Success: Non-NULL object pointer associated with the + * specified ID. + * Failure: NULL * *------------------------------------------------------------------------- */ @@ -948,10 +979,10 @@ H5Iobject_verify(hid_t id, H5I_type_t id_type) FUNC_ENTER_API(NULL) H5TRACE2("*x", "iIt", id, id_type); + /* Validate parameters */ if(H5I_IS_LIB_TYPE(id_type)) HGOTO_ERROR(H5E_ATOM, H5E_BADGROUP, NULL, "cannot call public function on library type") - - if(id_type < 1 || id_type >= H5I_next_type) + if(id_type < 1 || (int)id_type >= H5I_next_type) HGOTO_ERROR(H5E_ATOM, H5E_BADGROUP, NULL, "identifier has invalid type") ret_value = H5I_object_verify(id, id_type); @@ -962,14 +993,14 @@ done: /*------------------------------------------------------------------------- - * Function: H5I_object_verify + * Function: H5I_object_verify * - * Purpose: Find an object pointer for the specified ID, verifying that - * its in a particular type. + * Purpose: Find an object pointer for the specified ID, verifying that + * its in a particular type. * - * Return: Success: Non-null object pointer associated with the - * specified ID. - * Failure: NULL + * Return: Success: Non-NULL object pointer associated with the + * specified ID. + * Failure: NULL * * Programmer: Quincey Koziol * Wednesday, July 31, 2002 @@ -979,34 +1010,35 @@ done: void * H5I_object_verify(hid_t id, H5I_type_t id_type) { - H5I_id_info_t *id_ptr = NULL; /*ptr to the new atom */ - void *ret_value = NULL; /*return value */ + H5I_id_info_t *id_ptr = NULL; /* Pointer to the new atom */ + void *ret_value = NULL; /* Return value */ FUNC_ENTER_NOAPI_NOERR - HDassert(id_type >= 1 && id_type < H5I_next_type); + HDassert(id_type >= 1 && (int)id_type < H5I_next_type); /* Verify that the type of the ID is correct & lookup the ID */ if(id_type == H5I_TYPE(id) && NULL != (id_ptr = H5I__find_id(id))) { /* Get the object pointer to return */ - /* (Casting away const OK -QAK) */ - ret_value = (void *)id_ptr->obj_ptr; - } /* end if */ + ret_value = (void *)id_ptr->obj_ptr; /* (Casting away const OK -QAK) */ + } FUNC_LEAVE_NOAPI(ret_value) } /* H5I_object_verify() */ /*------------------------------------------------------------------------- - * Function: H5I_get_type + * Function: H5I_get_type * - * Purpose: Given an object ID return the type to which it - * belongs. The ID need not be the ID of an object which - * currently exists because the type number is encoded - * in the object ID. + * Purpose: Given an object ID return the type to which it + * belongs. The ID need not be the ID of an object which + * currently exists because the type number is encoded + * in the object ID. * - * Return: Success: A valid type number - * Failure: H5I_BADID, a negative value. + * Return: Success: A positive integer (corresponding to an H5I_type_t + * enum value for library ID types, but not for user + * ID types). + * Failure: H5I_BADID * * Programmer: Robb Matzke * Friday, February 19, 1999 @@ -1023,24 +1055,24 @@ H5I_get_type(hid_t id) if(id > 0) ret_value = H5I_TYPE(id); - HDassert(ret_value >= H5I_BADID && ret_value < H5I_next_type); + HDassert(ret_value >= H5I_BADID && (int)ret_value < H5I_next_type); FUNC_LEAVE_NOAPI(ret_value) } /* end H5I_get_type() */ /*------------------------------------------------------------------------- - * Function: H5Iget_type + * Function: H5Iget_type * - * Purpose: The public version of H5I_get_type(), obtains a type number - * when given an ID. The ID need not be the ID of an - * object which currently exists because the type number is - * encoded as part of the ID. + * Purpose: The public version of H5I_get_type(), obtains a type number + * when given an ID. The ID need not be the ID of an + * object which currently exists because the type number is + * encoded as part of the ID. * - * Return: Success: Type number - * Failure: H5I_BADID, a negative value - * - * Programmer: Unknown + * Return: Success: A positive integer (corresponding to an H5I_type_t + * enum value for library ID types, but not for user + * ID types). + * Failure: H5I_BADID * *------------------------------------------------------------------------- */ @@ -1054,7 +1086,7 @@ H5Iget_type(hid_t id) ret_value = H5I_get_type(id); - if(ret_value <= H5I_BADID || ret_value >= H5I_next_type || NULL == H5I_object(id)) + if(ret_value <= H5I_BADID || (int)ret_value >= H5I_next_type || NULL == H5I_object(id)) HGOTO_DONE(H5I_BADID); done: @@ -1063,16 +1095,67 @@ done: /*------------------------------------------------------------------------- - * Function: H5Iremove_verify + * Function: H5I_is_file_object + * + * Purpose: Convenience function to determine if an ID represents + * a file object. * - * Purpose: Removes the specified ID from its type, first checking that the - * type of the ID and the type type are the same. Public interface to - * H5I__remove_verify. + * In H5O calls, you can't use object_verify to ensure + * the ID was of the correct class since there's no + * H5I_OBJECT ID class. * - * Return: Success: A pointer to the object that was removed, the - * same pointer which would have been found by - * calling H5I_object(). - * Failure: NULL + * Return: Success: TRUE/FALSE + * Failure: FAIL + * + *------------------------------------------------------------------------- + */ +htri_t +H5I_is_file_object(hid_t id) +{ + H5I_type_t id_type = H5I_get_type(id); + htri_t ret_value = FAIL; + + FUNC_ENTER_NOAPI(FAIL); + + /* Fail if the ID type is out of range */ + if (id_type < 1 || id_type >= H5I_NTYPES) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "ID type out of range"); + + /* Return TRUE if the ID is a file object (dataset, group, map, or committed + * datatype), FALSE otherwise. + */ + if (H5I_DATASET == id_type || H5I_GROUP == id_type || H5I_MAP == id_type) { + ret_value = TRUE; + } + else if (H5I_DATATYPE == id_type) { + + H5T_t *dt = NULL; + + if(NULL == (dt = (H5T_t *)H5I_object(id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "unable to get underlying datatype struct"); + + ret_value = H5T_is_named(dt); + } + else { + ret_value = FALSE; + } + +done: + FUNC_LEAVE_NOAPI(ret_value); +} /* H5I_is_file_object() */ + + +/*------------------------------------------------------------------------- + * Function: H5Iremove_verify + * + * Purpose: Removes the specified ID from its type, first checking that the + * type of the ID and the type type are the same. Public interface to + * H5I__remove_verify. + * + * Return: Success: A pointer to the object that was removed, the + * same pointer which would have been found by + * calling H5I_object(). + * Failure: NULL * * Programmer: James Laird * Nathaniel Furrer @@ -1099,22 +1182,22 @@ done: /*------------------------------------------------------------------------- - * Function: H5I__remove_verify + * Function: H5I__remove_verify * - * Purpose: Removes the specified ID from its type, first checking that - * the ID's type is the same as the ID type supplied as an argument + * Purpose: Removes the specified ID from its type, first checking that + * the ID's type is the same as the ID type supplied as an argument * - * Return: Success: A pointer to the object that was removed, the - * same pointer which would have been found by - * calling H5I_object(). - * Failure: NULL + * Return: Success: A pointer to the object that was removed, the + * same pointer which would have been found by + * calling H5I_object(). + * Failure: NULL * * Programmer: James Laird * Nat Furrer * *------------------------------------------------------------------------- */ -void * +static void * H5I__remove_verify(hid_t id, H5I_type_t id_type) { void * ret_value = NULL; /*return value */ @@ -1132,14 +1215,14 @@ H5I__remove_verify(hid_t id, H5I_type_t id_type) /*------------------------------------------------------------------------- - * Function: H5I__remove_common + * Function: H5I__remove_common * - * Purpose: Common code to remove a specified ID from its type. + * Purpose: Common code to remove a specified ID from its type. * - * Return: Success: A pointer to the object that was removed, the - * same pointer which would have been found by - * calling H5I_object(). - * Failure: NULL + * Return: Success: A pointer to the object that was removed, the + * same pointer which would have been found by + * calling H5I_object(). + * Failure: NULL * * Programmer: Quincey Koziol * October 3, 2013 @@ -1161,8 +1244,11 @@ H5I__remove_common(H5I_id_type_t *type_ptr, hid_t id) if(NULL == (curr_id = (H5I_id_info_t *)H5SL_remove(type_ptr->ids, &id))) HGOTO_ERROR(H5E_ATOM, H5E_CANTDELETE, NULL, "can't remove ID node from skip list") - /* (Casting away const OK -QAK) */ - ret_value = (void *)curr_id->obj_ptr; + /* Check if this ID was the last one accessed */ + if(type_ptr->last_info == curr_id) + type_ptr->last_info = NULL; + + ret_value = (void *)curr_id->obj_ptr; /* (Casting away const OK -QAK) */ curr_id = H5FL_FREE(H5I_id_info_t, curr_id); /* Decrement the number of IDs in the type */ @@ -1174,14 +1260,14 @@ done: /*------------------------------------------------------------------------- - * Function: H5I_remove + * Function: H5I_remove * - * Purpose: Removes the specified ID from its type. + * Purpose: Removes the specified ID from its type. * - * Return: Success: A pointer to the object that was removed, the - * same pointer which would have been found by - * calling H5I_object(). - * Failure: NULL + * Return: Success: A pointer to the object that was removed, the + * same pointer which would have been found by + * calling H5I_object(). + * Failure: NULL * * Programmer: Unknown * @@ -1198,11 +1284,11 @@ H5I_remove(hid_t id) /* Check arguments */ type = H5I_TYPE(id); - if(type <= H5I_BADID || type >= H5I_next_type) - HGOTO_ERROR(H5E_ARGS, H5E_BADRANGE, NULL, "invalid type number") + if(type <= H5I_BADID || (int)type >= H5I_next_type) + HGOTO_ERROR(H5E_ARGS, H5E_BADRANGE, NULL, "invalid type number") type_ptr = H5I_id_type_list_g[type]; if(type_ptr == NULL || type_ptr->init_count <= 0) - HGOTO_ERROR(H5E_ATOM, H5E_BADGROUP, NULL, "invalid type") + HGOTO_ERROR(H5E_ATOM, H5E_BADGROUP, NULL, "invalid type") /* Remove the node from the type */ if(NULL == (ret_value = H5I__remove_common(type_ptr, id))) @@ -1214,14 +1300,14 @@ done: /*------------------------------------------------------------------------- - * Function: H5Idec_ref + * Function: H5Idec_ref * - * Purpose: Decrements the number of references outstanding for an ID. + * Purpose: Decrements the number of references outstanding for an ID. * If the reference count for an ID reaches zero, the object * will be closed. * - * Return: Success: New reference count - * Failure: Negative + * Return: Success: New reference count + * Failure: -1 * * Programmer: Quincey Koziol * Dec 7, 2003 @@ -1233,16 +1319,16 @@ H5Idec_ref(hid_t id) { int ret_value = 0; /* Return value */ - FUNC_ENTER_API(FAIL) + FUNC_ENTER_API((-1)) H5TRACE1("Is", "i", id); /* Check arguments */ if(id < 0) - HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "invalid ID") + HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, (-1), "invalid ID") /* Do actual decrement operation */ if((ret_value = H5I_dec_app_ref(id)) < 0) - HGOTO_ERROR(H5E_ATOM, H5E_CANTDEC, FAIL, "can't decrement ID ref count") + HGOTO_ERROR(H5E_ATOM, H5E_CANTDEC, (-1), "can't decrement ID ref count") done: FUNC_LEAVE_API(ret_value) @@ -1250,19 +1336,17 @@ done: /*------------------------------------------------------------------------- - * Function: H5I_dec_ref + * Function: H5I_dec_ref * - * Purpose: Decrements the number of references outstanding for an ID. - * This will fail if the type is not a reference counted type. - * The ID type's 'free' function will be called for the ID - * if the reference count for the ID reaches 0 and a free - * function has been defined at type creation time. + * Purpose: Decrements the number of references outstanding for an ID. + * This will fail if the type is not a reference counted type. + * The ID type's 'free' function will be called for the ID + * if the reference count for the ID reaches 0 and a free + * function has been defined at type creation time. * - * Return: Success: New reference count. + * Return: Success: New reference count * - * Failure: Negative - * - * Programmer: Unknown + * Failure: -1 * *------------------------------------------------------------------------- */ @@ -1272,17 +1356,16 @@ H5I_dec_ref(hid_t id) H5I_id_info_t *id_ptr; /* Pointer to the new ID */ int ret_value = 0; /* Return value */ - FUNC_ENTER_NOAPI(FAIL) + FUNC_ENTER_NOAPI((-1)) /* Sanity check */ HDassert(id >= 0); /* General lookup of the ID */ if(NULL == (id_ptr = H5I__find_id(id))) - HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't locate ID") + HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, (-1), "can't locate ID") - /* - * If this is the last reference to the object then invoke the type's + /* If this is the last reference to the object then invoke the type's * free method on the object. If the free method is undefined or * successful then remove the object from the type; otherwise leave * the object in the type without decrementing the reference @@ -1290,10 +1373,10 @@ H5I_dec_ref(hid_t id) * reference count without calling the free method. * * Beware: the free method may call other H5I functions. - * - * If an object is closing, we can remove the ID even though the free + * + * If an object is closing, we can remove the ID even though the free * method might fail. This can happen when a mandatory filter fails to - * write when a dataset is closed and the chunk cache is flushed to the + * write when a dataset is closed and the chunk cache is flushed to the * file. We have to close the dataset anyway. (SLU - 2010/9/7) */ if(1 == id_ptr->count) { @@ -1306,11 +1389,11 @@ H5I_dec_ref(hid_t id) if(!type_ptr->cls->free_func || (type_ptr->cls->free_func)((void *)id_ptr->obj_ptr) >= 0) { /* Remove the node from the type */ if(NULL == H5I__remove_common(type_ptr, id)) - HGOTO_ERROR(H5E_ATOM, H5E_CANTDELETE, FAIL, "can't remove ID node") + HGOTO_ERROR(H5E_ATOM, H5E_CANTDELETE, (-1), "can't remove ID node") ret_value = 0; } /* end if */ else - ret_value = FAIL; + ret_value = -1; } /* end if */ else { --(id_ptr->count); @@ -1323,13 +1406,13 @@ done: /*------------------------------------------------------------------------- - * Function: H5I_dec_app_ref + * Function: H5I_dec_app_ref * - * Purpose: H5I_dec_ref wrapper for case of modifying the application ref. - * count for an ID as well as normal reference count. + * Purpose: H5I_dec_ref wrapper for case of modifying the application ref. + * count for an ID as well as normal reference count. * - * Return: Success: New app. reference count. - * Failure: Negative + * Return: Success: New app. reference count + * Failure: -1 * * Programmer: Quincey Koziol * Sept 16, 2010 @@ -1342,20 +1425,20 @@ H5I_dec_app_ref(hid_t id) H5I_id_info_t *id_ptr; /* Pointer to the new ID */ int ret_value = 0; /* Return value */ - FUNC_ENTER_NOAPI(FAIL) + FUNC_ENTER_NOAPI((-1)) /* Sanity check */ HDassert(id >= 0); /* Call regular decrement reference count routine */ if((ret_value = H5I_dec_ref(id)) < 0) - HGOTO_ERROR(H5E_ATOM, H5E_CANTDEC, FAIL, "can't decrement ID ref count") + HGOTO_ERROR(H5E_ATOM, H5E_CANTDEC, (-1), "can't decrement ID ref count") /* Check if the ID still exists */ if(ret_value > 0) { /* General lookup of the ID */ if(NULL == (id_ptr = H5I__find_id(id))) - HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't locate ID") + HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, (-1), "can't locate ID") /* Adjust app_ref */ --(id_ptr->app_count); @@ -1371,16 +1454,13 @@ done: /*------------------------------------------------------------------------- - * Function: H5I_dec_app_ref_always_close + * Function: H5I_dec_app_ref_always_close * - * Purpose: H5I_dec_app_ref wrapper for case of always closing the ID, - * even when the free routine fails + * Purpose: H5I_dec_app_ref wrapper for case of always closing the ID, + * even when the free routine fails * - * Return: Success: New app. reference count. - * Failure: Negative - * - * Programmer: Quincey Koziol - * Sept 16, 2010 + * Return: Success: New app. reference count + * Failure: -1 * *------------------------------------------------------------------------- */ @@ -1389,7 +1469,7 @@ H5I_dec_app_ref_always_close(hid_t id) { int ret_value = 0; /* Return value */ - FUNC_ENTER_NOAPI(FAIL) + FUNC_ENTER_NOAPI((-1)) /* Sanity check */ HDassert(id >= 0); @@ -1398,17 +1478,17 @@ H5I_dec_app_ref_always_close(hid_t id) ret_value = H5I_dec_app_ref(id); /* Check for failure */ - if(ret_value < 0) { + if (ret_value < 0) { /* - * If an object is closing, we can remove the ID even though the free + * If an object is closing, we can remove the ID even though the free * method might fail. This can happen when a mandatory filter fails to - * write when a dataset is closed and the chunk cache is flushed to the + * write when a dataset is closed and the chunk cache is flushed to the * file. We have to close the dataset anyway. (SLU - 2010/9/7) */ H5I_remove(id); - HGOTO_ERROR(H5E_ATOM, H5E_CANTDEC, FAIL, "can't decrement ID ref count") - } /* end if */ + HGOTO_ERROR(H5E_ATOM, H5E_CANTDEC, (-1), "can't decrement ID ref count") + } done: FUNC_LEAVE_NOAPI(ret_value) @@ -1416,15 +1496,12 @@ done: /*------------------------------------------------------------------------- - * Function: H5Iinc_ref + * Function: H5Iinc_ref * - * Purpose: Increments the number of references outstanding for an ID. + * Purpose: Increments the number of references outstanding for an ID. * - * Return: Success: New reference count - * Failure: Negative - * - * Programmer: Quincey Koziol - * Dec 7, 2003 + * Return: Success: New reference count + * Failure: -1 * *------------------------------------------------------------------------- */ @@ -1433,16 +1510,16 @@ H5Iinc_ref(hid_t id) { int ret_value; /* Return value */ - FUNC_ENTER_API(FAIL) + FUNC_ENTER_API((-1)) H5TRACE1("Is", "i", id); /* Check arguments */ - if(id < 0) - HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "invalid ID") + if (id < 0) + HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, (-1), "invalid ID") /* Do actual increment operation */ - if((ret_value = H5I_inc_ref(id, TRUE)) < 0) - HGOTO_ERROR(H5E_ATOM, H5E_CANTINC, FAIL, "can't increment ID ref count") + if ((ret_value = H5I_inc_ref(id, TRUE)) < 0) + HGOTO_ERROR(H5E_ATOM, H5E_CANTINC, (-1), "can't increment ID ref count") done: FUNC_LEAVE_API(ret_value) @@ -1450,15 +1527,12 @@ done: /*------------------------------------------------------------------------- - * Function: H5I_inc_ref - * - * Purpose: Increment the reference count for an object. + * Function: H5I_inc_ref * - * Return: Success: The new reference count. - * Failure: Negative + * Purpose: Increment the reference count for an object. * - * Programmer: Robb Matzke - * Thursday, July 29, 1999 + * Return: Success: The new reference count + * Failure: -1 * *------------------------------------------------------------------------- */ @@ -1468,14 +1542,14 @@ H5I_inc_ref(hid_t id, hbool_t app_ref) H5I_id_info_t *id_ptr; /* Pointer to the ID */ int ret_value = 0; /* Return value */ - FUNC_ENTER_NOAPI(FAIL) + FUNC_ENTER_NOAPI((-1)) /* Sanity check */ HDassert(id >= 0); /* General lookup of the ID */ - if(NULL == (id_ptr = H5I__find_id(id))) - HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't locate ID") + if (NULL == (id_ptr = H5I__find_id(id))) + HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, (-1), "can't locate ID") /* Adjust reference counts */ ++(id_ptr->count); @@ -1491,15 +1565,12 @@ done: /*------------------------------------------------------------------------- - * Function: H5Iget_ref - * - * Purpose: Retrieves the number of references outstanding for an ID. + * Function: H5Iget_ref * - * Return: Success: Reference count - * Failure: Negative + * Purpose: Retrieves the number of references outstanding for an ID. * - * Programmer: Quincey Koziol - * Dec 7, 2003 + * Return: Success: Reference count + * Failure: -1 * *------------------------------------------------------------------------- */ @@ -1508,16 +1579,16 @@ H5Iget_ref(hid_t id) { int ret_value; /* Return value */ - FUNC_ENTER_API(FAIL) + FUNC_ENTER_API((-1)) H5TRACE1("Is", "i", id); /* Check arguments */ - if(id < 0) - HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "invalid ID") + if (id < 0) + HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, (-1), "invalid ID") /* Do actual retrieve operation */ - if((ret_value = H5I_get_ref(id, TRUE)) < 0) - HGOTO_ERROR(H5E_ATOM, H5E_CANTGET, FAIL, "can't get ID ref count") + if ((ret_value = H5I_get_ref(id, TRUE)) < 0) + HGOTO_ERROR(H5E_ATOM, H5E_CANTGET, (-1), "can't get ID ref count") done: FUNC_LEAVE_API(ret_value) @@ -1525,15 +1596,12 @@ done: /*------------------------------------------------------------------------- - * Function: H5I_get_ref + * Function: H5I_get_ref * - * Purpose: Retrieve the reference count for an object. + * Purpose: Retrieve the reference count for an object. * - * Return: Success: The reference count. - * Failure: Negative - * - * Programmer: Quincey Koziol - * Saturday, Decemeber 6, 2003 + * Return: Success: The reference count + * Failure: -1 * *------------------------------------------------------------------------- */ @@ -1543,14 +1611,14 @@ H5I_get_ref(hid_t id, hbool_t app_ref) H5I_id_info_t *id_ptr; /* Pointer to the ID */ int ret_value = 0; /* Return value */ - FUNC_ENTER_NOAPI(FAIL) + FUNC_ENTER_NOAPI((-1)) /* Sanity check */ HDassert(id >= 0); /* General lookup of the ID */ - if(NULL == (id_ptr = H5I__find_id(id))) - HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't locate ID") + if (NULL == (id_ptr = H5I__find_id(id))) + HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, (-1), "can't locate ID") /* Set return value */ ret_value = (int)(app_ref ? id_ptr->app_count : id_ptr->count); @@ -1561,16 +1629,12 @@ done: /*------------------------------------------------------------------------- - * Function: H5Iinc_type_ref + * Function: H5Iinc_type_ref * - * Purpose: Increments the number of references outstanding for an ID type. + * Purpose: Increments the number of references outstanding for an ID type. * - * Return: Success: New reference count - * Failure: Negative - * - * Programmer: Nat Furrer - * James Laird - * April 30, 2004 + * Return: Success: New reference count + * Failure: -1 * *------------------------------------------------------------------------- */ @@ -1579,19 +1643,18 @@ H5Iinc_type_ref(H5I_type_t type) { int ret_value; /* Return value */ - FUNC_ENTER_API(FAIL) + FUNC_ENTER_API((-1)) H5TRACE1("Is", "It", type); /* Check arguments */ - if(type <= 0 || type >= H5I_next_type) - HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "invalid ID type") - + if(type <= 0 || (int)type >= H5I_next_type) + HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, (-1), "invalid ID type") if(H5I_IS_LIB_TYPE(type)) - HGOTO_ERROR(H5E_ATOM, H5E_BADGROUP, FAIL, "cannot call public function on library type") + HGOTO_ERROR(H5E_ATOM, H5E_BADGROUP, (-1), "cannot call public function on library type") /* Do actual increment operation */ if((ret_value = H5I__inc_type_ref(type)) < 0) - HGOTO_ERROR(H5E_ATOM, H5E_CANTINC, FAIL, "can't increment ID type ref count") + HGOTO_ERROR(H5E_ATOM, H5E_CANTINC, (-1), "can't increment ID type ref count") done: FUNC_LEAVE_API(ret_value) @@ -1599,16 +1662,12 @@ done: /*------------------------------------------------------------------------- - * Function: H5I__inc_type_ref + * Function: H5I__inc_type_ref * - * Purpose: Increment the reference count for an ID type. + * Purpose: Increment the reference count for an ID type. * - * Return: Success: The new reference count. - * Failure: Negative - * - * Programmer: James Laird - * Nat Furrer - * Friday, April 30, 2004 + * Return: Success: The new reference count + * Failure: -1 * *------------------------------------------------------------------------- */ @@ -1621,12 +1680,12 @@ H5I__inc_type_ref(H5I_type_t type) FUNC_ENTER_STATIC /* Sanity check */ - HDassert(type > 0 && type < H5I_next_type); + HDassert(type > 0 && (int)type < H5I_next_type); /* Check arguments */ type_ptr = H5I_id_type_list_g[type]; - if(!type_ptr) - HGOTO_ERROR(H5E_ATOM, H5E_BADGROUP, FAIL, "invalid type") + if(NULL == type_ptr) + HGOTO_ERROR(H5E_ATOM, H5E_BADGROUP, (-1), "invalid type") /* Set return value */ ret_value = (int)(++(type_ptr->init_count)); @@ -1637,37 +1696,39 @@ done: /*------------------------------------------------------------------------- - * Function: H5Idec_type_ref - * - * Purpose: Decrements the reference count on an entire type of IDs. - * If the type reference count becomes zero then the type is - * destroyed along with all atoms in that type regardless of - * their reference counts. Destroying IDs involves calling - * the free-func for each ID's object and then adding the ID - * struct to the ID free list. Public interface to - * H5I_dec_type_ref. - * Returns the number of references to the type on success; a - * return value of 0 means that the type will have to be - * re-initialized before it can be used again (and should probably - * be set to H5I_UNINIT). - * - * Return: Number of references to type on success/Negative on failure - * - * Programmer: Nathaniel Furrer - * James Laird + * Function: H5Idec_type_ref + * + * Purpose: Decrements the reference count on an entire type of IDs. + * If the type reference count becomes zero then the type is + * destroyed along with all atoms in that type regardless of + * their reference counts. Destroying IDs involves calling + * the free-func for each ID's object and then adding the ID + * struct to the ID free list. Public interface to + * H5I_dec_type_ref. + * Returns the number of references to the type on success; a + * return value of 0 means that the type will have to be + * re-initialized before it can be used again (and should probably + * be set to H5I_UNINIT). + * + * NOTE: Using an error type to also represent a count is semantially + * incorrect. We should consider fixing this in a future major + * release (DER). + * + * Return: Success: Number of references to type + * Failure: -1 * *------------------------------------------------------------------------- */ herr_t H5Idec_type_ref(H5I_type_t type) { - herr_t ret_value; /* Return value */ + herr_t ret_value = 0; /* Return value */ - FUNC_ENTER_API(FAIL) + FUNC_ENTER_API((-1)) H5TRACE1("e", "It", type); - if(H5I_IS_LIB_TYPE(type)) - HGOTO_ERROR(H5E_ATOM, H5E_BADGROUP, FAIL, "cannot call public function on library type") + if (H5I_IS_LIB_TYPE(type)) + HGOTO_ERROR(H5E_ATOM, H5E_BADGROUP, (-1), "cannot call public function on library type") ret_value = H5I_dec_type_ref(type); @@ -1677,42 +1738,40 @@ done: /*------------------------------------------------------------------------- - * Function: H5I_dec_type_ref - * - * Purpose: Decrements the reference count on an entire type of IDs. - * If the type reference count becomes zero then the type is - * destroyed along with all atoms in that type regardless of - * their reference counts. Destroying IDs involves calling - * the free-func for each ID's object and then adding the ID - * struct to the ID free list. - * Returns the number of references to the type on success; a - * return value of 0 means that the type will have to be - * re-initialized before it can be used again (and should probably - * be set to H5I_UNINIT). - * - * Return: Number of references to type on success/Negative on failure - * - * Programmer: Unknown + * Function: H5I_dec_type_ref + * + * Purpose: Decrements the reference count on an entire type of IDs. + * If the type reference count becomes zero then the type is + * destroyed along with all atoms in that type regardless of + * their reference counts. Destroying IDs involves calling + * the free-func for each ID's object and then adding the ID + * struct to the ID free list. + * Returns the number of references to the type on success; a + * return value of 0 means that the type will have to be + * re-initialized before it can be used again (and should probably + * be set to H5I_UNINIT). + * + * Return: Success: Number of references to type + * Failure: -1 * *------------------------------------------------------------------------- */ -herr_t +int H5I_dec_type_ref(H5I_type_t type) { H5I_id_type_t *type_ptr; /* Pointer to the ID type */ - herr_t ret_value = SUCCEED; /* Return value */ + herr_t ret_value = 0; /* Return value */ - FUNC_ENTER_NOAPI(FAIL) + FUNC_ENTER_NOAPI((-1)) - if(type <= H5I_BADID || type >= H5I_next_type) - HGOTO_ERROR(H5E_ARGS, H5E_BADRANGE, FAIL, "invalid type number") + if(type <= H5I_BADID || (int)type >= H5I_next_type) + HGOTO_ERROR(H5E_ARGS, H5E_BADRANGE, (-1), "invalid type number") type_ptr = H5I_id_type_list_g[type]; if(type_ptr == NULL || type_ptr->init_count <= 0) - HGOTO_ERROR(H5E_ATOM, H5E_BADGROUP, FAIL, "invalid type") + HGOTO_ERROR(H5E_ATOM, H5E_BADGROUP, (-1), "invalid type") - /* - * Decrement the number of users of the atomic type. If this is the + /* Decrement the number of users of the atomic type. If this is the * last user of the type then release all atoms from the type and * free all memory it used. The free function is invoked for each atom * being freed. @@ -1732,16 +1791,12 @@ done: /*------------------------------------------------------------------------- - * Function: H5Iget_type_ref + * Function: H5Iget_type_ref * - * Purpose: Retrieves the number of references outstanding for a type. + * Purpose: Retrieves the number of references outstanding for a type. * - * Return: Success: Reference count - * Failure: Negative - * - * Programmer: Nat Furrer - * James Laird - * April 30, 2004 + * Return: Success: Reference count + * Failure: -1 * *------------------------------------------------------------------------- */ @@ -1750,19 +1805,18 @@ H5Iget_type_ref(H5I_type_t type) { int ret_value; /* Return value */ - FUNC_ENTER_API(FAIL) + FUNC_ENTER_API((-1)) H5TRACE1("Is", "It", type); /* Check arguments */ - if(type <= 0 || type >= H5I_next_type) - HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "invalid ID type") - + if(type <= 0 || (int)type >= H5I_next_type) + HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, (-1), "invalid ID type") if(H5I_IS_LIB_TYPE(type)) - HGOTO_ERROR(H5E_ATOM, H5E_BADGROUP, FAIL, "cannot call public function on library type") + HGOTO_ERROR(H5E_ATOM, H5E_BADGROUP, (-1), "cannot call public function on library type") /* Do actual retrieve operation */ if((ret_value = H5I__get_type_ref(type)) < 0) - HGOTO_ERROR(H5E_ATOM, H5E_CANTGET, FAIL, "can't get ID type ref count") + HGOTO_ERROR(H5E_ATOM, H5E_CANTGET, (-1), "can't get ID type ref count") done: FUNC_LEAVE_API(ret_value) @@ -1770,25 +1824,21 @@ done: /*------------------------------------------------------------------------- - * Function: H5I__get_type_ref + * Function: H5I__get_type_ref * - * Purpose: Retrieve the reference count for an ID type. + * Purpose: Retrieve the reference count for an ID type. * - * Return: Success: The reference count. + * Return: Success: The reference count * - * Failure: Negative - * - * Programmer: Nat Furrer - * James Laird - * April 30, 2004 + * Failure: -1 * *------------------------------------------------------------------------- */ static int H5I__get_type_ref(H5I_type_t type) { - H5I_id_type_t *type_ptr; /*ptr to the type */ - int ret_value = -1; /* Return value */ + H5I_id_type_t *type_ptr; /* Pointer to the type */ + int ret_value = -1; /* Return value */ FUNC_ENTER_STATIC @@ -1797,7 +1847,7 @@ H5I__get_type_ref(H5I_type_t type) /* Check arguments */ type_ptr = H5I_id_type_list_g[type]; - if(!type_ptr) + if (!type_ptr) HGOTO_ERROR(H5E_ATOM, H5E_BADGROUP, FAIL, "invalid type") /* Set return value */ @@ -1809,17 +1859,12 @@ done: /*------------------------------------------------------------------------- - * Function: H5Iis_valid + * Function: H5Iis_valid * - * Purpose: Check if the given id is valid. An id is valid if it is in + * Purpose: Check if the given id is valid. An id is valid if it is in * use and has an application reference count of at least 1. * - * Return: Success: TRUE if the id is valid, FALSE otherwise. - * - * Failure: Negative (never fails currently) - * - * Programmer: Neil Fortner - * Friday, October 31, 2008 (boo) + * Return: TRUE/FALSE/FAIL * *------------------------------------------------------------------------- */ @@ -1835,9 +1880,7 @@ H5Iis_valid(hid_t id) /* Find the ID */ if (NULL == (id_ptr = H5I__find_id(id))) ret_value = FALSE; - - /* Check if the found id is an internal id */ - else if (!id_ptr->app_count) + else if (!id_ptr->app_count) /* Check if the found id is an internal id */ ret_value = FALSE; done: @@ -1846,59 +1889,57 @@ done: /*------------------------------------------------------------------------- - * Function: H5I__search_cb + * 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. + * 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 + * Return: Success: H5_ITER_CONT (0) or H5_ITER_STOP (1) + * Failure: H5_ITER_ERROR (-1) * *------------------------------------------------------------------------- */ 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 = -1; /* Callback return value */ + H5I_search_ud_t *udata = (H5I_search_ud_t *)_udata; /* User data for callback */ + herr_t cb_ret_val; /* User callback return value */ + int ret_value = H5_ITER_ERROR; /* Callback return value */ FUNC_ENTER_STATIC_NOERR - ret_value = (*udata->app_cb)(obj, id, udata->app_key); - if(ret_value > 0) - udata->ret_obj = obj; + cb_ret_val = (*udata->app_cb)(obj, id, udata->app_key); + + /* Set the return value based on the callback's return value */ + if(cb_ret_val > 0) { + ret_value = H5_ITER_STOP; /* terminate iteration early */ + udata->ret_obj = obj; /* also set out parameter */ + } + else if(cb_ret_val < 0) + ret_value = H5_ITER_ERROR; /* indicate failure (which terminates iteration) */ FUNC_LEAVE_NOAPI(ret_value) } /* end H5I__search_cb() */ /*------------------------------------------------------------------------- - * Function: H5Isearch - * - * 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). Public interface to H5I_search. + * Function: H5Isearch * - * Limitation: Currently there is no way to start searching from where a - * previous search left off. + * 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). Public interface to H5I_search. * - * 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. + * Limitation: Currently there is no way to start searching from where a + * previous search left off. * - * Failure: NULL + * 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. * - * Programmer: James Laird - * Nathaniel Furrer - * Friday, April 23, 2004 + * Failure: NULL * *------------------------------------------------------------------------- */ @@ -1912,7 +1953,7 @@ H5Isearch(H5I_type_t type, H5I_search_func_t func, void *key) H5TRACE3("*x", "Itx*x", type, func, key); /* Check arguments */ - if(H5I_IS_LIB_TYPE(type)) + if (H5I_IS_LIB_TYPE(type)) HGOTO_ERROR(H5E_ATOM, H5E_BADGROUP, NULL, "cannot call public function on library type") /* Set up udata struct */ @@ -1920,7 +1961,7 @@ H5Isearch(H5I_type_t type, H5I_search_func_t func, void *key) udata.app_key = key; udata.ret_obj = NULL; - /* Note that H5I_iterate returns an error code. We ignore it + /* Note that H5I_iterate returns an error code. We ignore it * here, as we can't do anything with it without revising the API. */ (void)H5I_iterate(type, H5I__search_cb, &udata, TRUE); @@ -1934,17 +1975,101 @@ done: /*------------------------------------------------------------------------- - * Function: H5I__iterate_cb + * Function: H5I__iterate_pub_cb + * + * Purpose: Callback routine for H5Iiterate, when it calls + * H5I_iterate. Calls "user" callback search function, and + * then sets return value, based on the result of that + * callback. + * + * Return: Success: H5_ITER_CONT (0) or H5_ITER_STOP (1) + * Failure: H5_ITER_ERROR (-1) + * + * Programmer: Neil Fortner + * Friday, October 11, 2013 * - * Purpose: Callback routine for H5I_iterate, invokes "user" callback + *------------------------------------------------------------------------- + */ +static int +H5I__iterate_pub_cb(void H5_ATTR_UNUSED *obj, hid_t id, void *_udata) +{ + H5I_iterate_pub_ud_t *udata = (H5I_iterate_pub_ud_t *)_udata; /* User data for callback */ + herr_t cb_ret_val; /* User callback return value */ + int ret_value = H5_ITER_ERROR; /* Callback return value */ + + FUNC_ENTER_STATIC_NOERR + + /* Invoke the callback */ + cb_ret_val = (*udata->op)(id, udata->op_data); + + /* Set the return value based on the callback's return value */ + if(cb_ret_val > 0) + ret_value = H5_ITER_STOP; /* terminate iteration early */ + else if(cb_ret_val < 0) + ret_value = H5_ITER_ERROR; /* indicate failure (which terminates iteration) */ + else + ret_value = H5_ITER_CONT; /* continue iteration */ + + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5I__iterate_pub_cb() */ + + +/*------------------------------------------------------------------------- + * Function: H5Iiterate + * + * Purpose: Call the callback funciton op for each member of the id + * type type. op takes as parameters the id and a + * passthrough of op_data, and returns an herr_t. A positive + * return from op will cause the iteration to stop and + * H5Iiterate will return the value returned by op. A + * negative return from op will cause the iteration to stop + * and H5Iiterate will return failure. A zero return from op + * will allow iteration to continue, as long as there are + * other ids remaining in type. + * + * Limitation: Currently there is no way to start searching from where a + * previous search left off. + * + * Return: The last value returned by op + * + * Programmer: Neil Fortner + * Friday, October 11, 2013 + * + *------------------------------------------------------------------------- + */ +herr_t +H5Iiterate(H5I_type_t type, H5I_iterate_func_t op, void *op_data) +{ + H5I_iterate_pub_ud_t int_udata; /* Internal user data */ + herr_t ret_value; /* Return value */ + + FUNC_ENTER_API(FAIL) + H5TRACE3("e", "Itx*x", type, op, op_data); + + /* Set up udata struct */ + int_udata.op = op; + int_udata.op_data = op_data; + + /* Note that H5I_iterate returns an error code. We ignore it + * here, as we can't do anything with it without revising the API. + */ + if ((ret_value = H5I_iterate(type, H5I__iterate_pub_cb, &int_udata, TRUE)) < 0) + HGOTO_ERROR(H5E_ATOM, H5E_BADITER, FAIL, "can't iterate over ids") + +done: + FUNC_LEAVE_API(ret_value) +} /* end H5Iiterate() */ + + +/*------------------------------------------------------------------------- + * Function: H5I__iterate_cb + * + * Purpose: Callback routine for H5I_iterate, invokes "user" callback * function, and then sets return value, based on the result of * that callback. * - * Return: Success: Non-negative on success - * Failure: Negative - * - * Programmer: Quincey Koziol - * Thursday, October 3, 2013 + * Return: Success: H5_ITER_CONT (0) or H5_ITER_STOP (1) + * Failure: H5_ITER_ERROR (-1) * *------------------------------------------------------------------------- */ @@ -1957,12 +2082,23 @@ H5I__iterate_cb(void *_item, void H5_ATTR_UNUSED *_key, void *_udata) FUNC_ENTER_STATIC_NOERR - /* Don't make callback if app_ref is set and the appl. ref count is 0 */ + /* Only invoke the callback function if this ID is visible externally and + * its reference count is positive. + */ if((!udata->app_ref) || (item->app_count > 0)) { - herr_t cb_ret_val; + H5I_type_t type = udata->obj_type; + void *obj_ptr; + herr_t cb_ret_val; + + /* The stored object pointer might be an H5VL_object_t, in which + * case we'll need to get the wrapped object struct (H5F_t *, etc.). + */ + obj_ptr = H5I__unwrap((void *)item->obj_ptr, type); - /* (Casting away const OK) */ - cb_ret_val = (*udata->user_func)((void *)item->obj_ptr, item->id, udata->user_udata); + /* Invoke callback function */ + cb_ret_val = (*udata->user_func)((void *)obj_ptr, item->id, udata->user_udata); /* (Casting away const OK) */ + + /* Set the return value based on the callback's return value */ if(cb_ret_val > 0) ret_value = H5_ITER_STOP; /* terminate iteration early */ else if(cb_ret_val < 0) @@ -1976,43 +2112,39 @@ H5I__iterate_cb(void *_item, void H5_ATTR_UNUSED *_key, void *_udata) /*------------------------------------------------------------------------- * Function: H5I_iterate * - * 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). + * 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). * - * If FUNC returns a positive value (i.e. H5_ITER_STOP), - * return SUCCEED. + * If FUNC returns a positive value (i.e. H5_ITER_STOP), + * return SUCCEED. * - * 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. + * If FUNC returns a negative value (i.e. H5_ITER_ERROR), + * return FAIL. * - * Limitation: Currently there is no way to start the iteration from - * where a previous iteration left off. + * 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. * - * Return: Success: SUCCEED - * Failure: FAIL + * Limitation: Currently there is no way to start the iteration from + * where a previous iteration left off. * - * Programmer: John Mainzer - * Monday, December 6, 2011 + * Return: SUCCEED/FAIL * *------------------------------------------------------------------------- */ 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 */ - herr_t ret_value = SUCCEED; /*return value */ + H5I_id_type_t *type_ptr; /* Pointer to the type */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI(FAIL) /* Check arguments */ - if(type <= H5I_BADID || type >= H5I_next_type) - HGOTO_ERROR(H5E_ARGS, H5E_BADRANGE, FAIL, "invalid type number") + if(type <= H5I_BADID || (int)type >= H5I_next_type) + HGOTO_ERROR(H5E_ARGS, H5E_BADRANGE, FAIL, "invalid type number") type_ptr = H5I_id_type_list_g[type]; /* Only iterate through ID list if it is initialized and there are IDs in type */ @@ -2021,9 +2153,10 @@ H5I_iterate(H5I_type_t type, H5I_search_func_t func, void *udata, hbool_t app_re herr_t iter_status; /* Iteration status */ /* Set up iterator user data */ - iter_udata.user_func = func; - iter_udata.user_udata = udata; - iter_udata.app_ref = app_ref; + iter_udata.user_func = func; + iter_udata.user_udata = udata; + iter_udata.app_ref = app_ref; + iter_udata.obj_type = type; /* Iterate over IDs */ if((iter_status = H5SL_iterate(type_ptr->ids, H5I__iterate_cb, &iter_udata)) < 0) @@ -2036,16 +2169,14 @@ done: /*------------------------------------------------------------------------- - * Function: H5I__find_id + * Function: H5I__find_id * - * Purpose: Given an object ID find the info struct that describes the - * object. + * Purpose: Given an object ID find the info struct that describes the + * object. * - * Return: Success: Ptr to the object's info struct. + * Return: Success: A pointer to the object's info struct. * - * Failure: NULL - * - * Programmer: Unknown + * Failure: NULL * *------------------------------------------------------------------------- */ @@ -2060,15 +2191,22 @@ H5I__find_id(hid_t id) /* Check arguments */ type = H5I_TYPE(id); - if(type <= H5I_BADID || type >= H5I_next_type) - HGOTO_DONE(NULL) - + if(type <= H5I_BADID || (int)type >= H5I_next_type) + HGOTO_DONE(NULL) type_ptr = H5I_id_type_list_g[type]; if(!type_ptr || type_ptr->init_count <= 0) - HGOTO_DONE(NULL) + HGOTO_DONE(NULL) + + /* Check for same ID as we have looked up last time */ + if(type_ptr->last_info && type_ptr->last_info->id == id) + ret_value = type_ptr->last_info; + else { + /* Locate the ID node for the ID */ + ret_value = (H5I_id_info_t *)H5SL_search(type_ptr->ids, &id); - /* Locate the ID node for the ID */ - ret_value = (H5I_id_info_t *)H5SL_search(type_ptr->ids, &id); + /* Remember this ID */ + type_ptr->last_info = ret_value; + } /* end else */ done: FUNC_LEAVE_NOAPI(ret_value) @@ -2076,24 +2214,23 @@ done: /*------------------------------------------------------------------------- - * Function: H5Iget_name - * - * Purpose: Gets a name of an object from its ID. + * Function: H5Iget_name * - * Return: Success: The length of name. + * Purpose: Gets a name of an object from its ID. * - * Failure: -1 + * Return: Success: The length of the name * - * Programmer: Pedro Vicente, pvn@ncsa.uiuc.edu + * Failure: -1 * - * Date: July 26, 2002 + * NOTE: Not safe for arbitrary VOL connectors as it relies on + * private H5G calls. * * Comments: Public function - * If `name' is non-NULL then write up to `size' bytes into that + * If 'name' is non-NULL then write up to 'size' bytes into that * buffer and always return the length of the entry name. - * Otherwise `size' is ignored and the function does not store the name, + * Otherwise 'size' is ignored and the function does not store the name, * just returning the number of characters required to store the name. - * If an error occurs then the buffer pointed to by `name' (NULL or non-NULL) + * If an error occurs then the buffer pointed to by 'name' (NULL or non-NULL) * is unchanged and the function returns a negative value. * If a zero is returned for the name's length, then there is no name * associated with the ID. @@ -2103,19 +2240,24 @@ done: ssize_t H5Iget_name(hid_t id, char *name/*out*/, size_t size) { - H5G_loc_t loc; /* Object location */ + H5VL_object_t *vol_obj; /* Object of loc_id */ + H5VL_loc_params_t loc_params; ssize_t ret_value; /* Return value */ - FUNC_ENTER_API(FAIL) + FUNC_ENTER_API((-1)) H5TRACE3("Zs", "ixz", id, name, size); - /* Get object location */ - if(H5G_loc(id, &loc) < 0) - HGOTO_ERROR(H5E_ATOM, H5E_CANTGET, FAIL, "can't retrieve object location") + /* Get the object pointer */ + if(NULL == (vol_obj = H5VL_vol_object(id))) + HGOTO_ERROR(H5E_ATOM, H5E_BADTYPE, (-1), "invalid identifier") + + /* Set location parameters */ + loc_params.type = H5VL_OBJECT_BY_SELF; + loc_params.obj_type = H5I_get_type(id); - /* Call internal group routine to retrieve object's name */ - if((ret_value = H5G_get_name(&loc, name, size, NULL, H5P_DEFAULT, H5AC_ind_read_dxpl_id)) < 0) - HGOTO_ERROR(H5E_ATOM, H5E_CANTGET, FAIL, "can't retrieve object name") + /* Retrieve object's name */ + if(H5VL_object_get(vol_obj, &loc_params, H5VL_OBJECT_GET_NAME, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL, &ret_value, name, size) < 0) + HGOTO_ERROR(H5E_ATOM, H5E_CANTGET, (-1), "can't retrieve object name") done: FUNC_LEAVE_API(ret_value) @@ -2123,30 +2265,43 @@ done: /*------------------------------------------------------------------------- - * Function: H5Iget_file_id + * Function: H5Iget_file_id * - * Purpose: The public version of H5I_get_file_id(), obtains the file - * ID given an object ID. User has to close this ID. + * Purpose: Obtains the file ID given an object ID. The user has to + * close this ID. * - * Return: Success: file ID + * Return: Success: The file ID associated with the object * - * Failure: a negative value - * - * Programmer: Raymond Lu - * Oct 27, 2003 + * Failure: H5I_INVALID_HID * *------------------------------------------------------------------------- */ hid_t H5Iget_file_id(hid_t obj_id) { - hid_t ret_value; /* Return value */ + H5I_type_t type; /* ID type */ + hid_t ret_value = H5I_INVALID_HID; /* Return value */ FUNC_ENTER_API(FAIL) H5TRACE1("i", "i", obj_id); - if((ret_value = H5I_get_file_id(obj_id, TRUE)) < 0) - HGOTO_ERROR(H5E_ATOM, H5E_CANTGET, FAIL, "can't retrieve file ID") + /* Get object type */ + type = H5I_TYPE(obj_id); + + /* Call internal function */ + if(H5I_FILE == type || H5I_DATATYPE == type || H5I_GROUP == type || H5I_DATASET == type || H5I_ATTR == type) { + H5VL_object_t *vol_obj; /* Object of obj_id */ + + /* Get the VOL object */ + if(NULL == (vol_obj = H5VL_vol_object(obj_id))) + HGOTO_ERROR(H5E_ATOM, H5E_BADTYPE, H5I_INVALID_HID, "invalid location identifier") + + /* Get the file ID */ + if((ret_value = H5F_get_file_id(vol_obj, type, TRUE)) < 0) + HGOTO_ERROR(H5E_ATOM, H5E_CANTGET, H5I_INVALID_HID, "can't retrieve file ID") + } /* end if */ + else + HGOTO_ERROR(H5E_ARGS, H5E_BADRANGE, H5I_INVALID_HID, "not an ID of a file object") done: FUNC_LEAVE_API(ret_value) @@ -2154,147 +2309,216 @@ done: /*------------------------------------------------------------------------- - * Function: H5I_get_file_id + * Function: H5I__find_id_cb * - * Purpose: The private version of H5Iget_file_id(), obtains the file - * ID given an object ID. + * Purpose: Callback for searching for an ID with a specific pointer * - * Return: Success: file ID - * Failure: a negative value - * - * Programmer: Raymond Lu - * Oct 27, 2003 + * Return: Success: H5_ITER_CONT (0) or H5_ITER_STOP (1) + * Failure: H5_ITER_ERROR (-1) * *------------------------------------------------------------------------- */ -hid_t -H5I_get_file_id(hid_t obj_id, hbool_t app_ref) +static int +H5I__find_id_cb(void *_item, void H5_ATTR_UNUSED *_key, void *_udata) { - H5I_type_t type; /* ID type */ - hid_t ret_value = H5I_INVALID_HID; /* Return value */ + H5I_id_info_t *item = (H5I_id_info_t *)_item; /* Pointer to the ID node */ + H5I_get_id_ud_t *udata = (H5I_get_id_ud_t *)_udata; /* Pointer to user data */ + H5I_type_t type = udata->obj_type; + const void *obj_ptr = NULL; + int ret_value = H5_ITER_CONT; /* Return value */ - FUNC_ENTER_NOAPI_NOINIT + FUNC_ENTER_STATIC_NOERR - /* Get object type */ - type = H5I_TYPE(obj_id); - if(type == H5I_FILE) { - /* Increment reference count on file ID */ - if(H5I_inc_ref(obj_id, app_ref) < 0) - HGOTO_ERROR(H5E_ATOM, H5E_CANTSET, FAIL, "incrementing file ID failed") + /* Sanity check */ + HDassert(item); + HDassert(udata); - /* Set return value */ - ret_value = obj_id; + /* Get a pointer to the VOL connector's data */ + obj_ptr = H5I__unwrap(item->obj_ptr, type); + + /* Check for a match */ + if (obj_ptr == udata->object) { + udata->ret_id = item->id; + ret_value = H5_ITER_STOP; } /* end if */ - else if(type == H5I_DATATYPE || type == H5I_GROUP || type == H5I_DATASET || type == H5I_ATTR) { - H5G_loc_t loc; /* Location of object */ - /* Get the object location information */ - if(H5G_loc(obj_id, &loc) < 0) - HGOTO_ERROR(H5E_ATOM, H5E_CANTGET, FAIL, "can't get object location") + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5I__find_id_cb() */ + + +/*------------------------------------------------------------------------- + * Function: H5I_find_id + * + * Purpose: Return the ID of an object by searching through the ID list + * for the type. + * + * Return: SUCCEED/FAIL + * (id will be set to H5I_INVALID_HID on errors or not found) + * + *------------------------------------------------------------------------- + */ +herr_t +H5I_find_id(const void *object, H5I_type_t type, hid_t *id) +{ + H5I_id_type_t *type_ptr; /* Pointer to the type */ + herr_t ret_value = SUCCEED; /* Return value */ - /* Get the file ID for the object */ - if((ret_value = H5F_get_id(loc.oloc->file, app_ref)) < 0) - HGOTO_ERROR(H5E_ATOM, H5E_CANTGET, FAIL, "can't get file ID") + FUNC_ENTER_NOAPI(FAIL) + + HDassert(id); + + *id = H5I_INVALID_HID; + + type_ptr = H5I_id_type_list_g[type]; + if (!type_ptr || type_ptr->init_count <= 0) + HGOTO_ERROR(H5E_ATOM, H5E_BADGROUP, FAIL, "invalid type") + + /* Only iterate through ID list if it is initialized and there are IDs in type */ + if (type_ptr->init_count > 0 && type_ptr->id_count > 0) { + H5I_get_id_ud_t udata; /* User data */ + herr_t iter_status; /* Iteration status */ + + /* Set up iterator user data */ + udata.object = object; + udata.obj_type = type; + udata.ret_id = H5I_INVALID_HID; + + /* Iterate over IDs for the ID type */ + if ((iter_status = H5SL_iterate(type_ptr->ids, H5I__find_id_cb, &udata)) < 0) + HGOTO_ERROR(H5E_ATOM, H5E_BADITER, FAIL, "iteration failed") + + *id = udata.ret_id; } /* end if */ - else - HGOTO_ERROR(H5E_ARGS, H5E_BADRANGE, FAIL, "invalid object ID") done: FUNC_LEAVE_NOAPI(ret_value) -} /* end H5I_get_file_id() */ +} /* end H5I_find_id() */ -#ifdef H5I_DEBUG_OUTPUT /*------------------------------------------------------------------------- - * Function: H5I__debug_cb + * Function: H5I__id_dump_cb * - * Purpose: Dump the contents of an ID to stderr for debugging. + * Purpose: Dump the contents of an ID to stderr for debugging. * - * Return: Success: Non-negative - * Failure: Negative - * - * Programmer: Robb Matzke - * Friday, February 19, 1999 + * Return: H5_ITER_CONT (always) * *------------------------------------------------------------------------- */ -static herr_t -H5I__debug_cb(void *_item, void H5_ATTR_UNUSED *_key, void *_udata) +static int +H5I__id_dump_cb(void *_item, void H5_ATTR_UNUSED *_key, void *_udata) { - H5I_id_info_t *item = (H5I_id_info_t *)_item; /* Pointer to the ID node */ - H5I_type_t type = *(H5I_type_t *)_udata; /* User data */ - H5G_name_t *path = NULL; - int ret_value = H5_ITER_CONT; /* Return value */ + H5I_id_info_t *item = (H5I_id_info_t *)_item; /* Pointer to the ID node */ + H5I_type_t type = *(H5I_type_t *)_udata; /* User data */ + H5G_name_t *path = NULL; /* Path to file object */ + const void *obj_ptr = NULL; /* Pointer to VOL connector object */ FUNC_ENTER_STATIC_NOERR - fprintf(stderr, " id = %lu\n", (unsigned long)(item->id)); - fprintf(stderr, " count = %u\n", item->count); - fprintf(stderr, " obj = 0x%08lx\n", (unsigned long)(item->obj_ptr)); + HDfprintf(stderr, " id = %lu\n", (unsigned long)(item->id)); + HDfprintf(stderr, " count = %u\n", item->count); + HDfprintf(stderr, " obj = 0x%08lx\n", (unsigned long)(item->obj_ptr)); /* Get the group location, so we get get the name */ - switch(type) { + switch (type) { case H5I_GROUP: - path = H5G_nameof((H5G_t*)item->obj_ptr); + { + const H5VL_object_t *vol_obj = (const H5VL_object_t *)item->obj_ptr; + + obj_ptr = H5VL_object_data(vol_obj); + if(H5_VOL_NATIVE == vol_obj->connector->cls->value) + path = H5G_nameof((const H5G_t *)obj_ptr); break; + } case H5I_DATASET: - path = H5D_nameof((H5D_t*)item->obj_ptr); + { + const H5VL_object_t *vol_obj = (const H5VL_object_t *)item->obj_ptr; + + obj_ptr = H5VL_object_data(vol_obj); + if(H5_VOL_NATIVE == vol_obj->connector->cls->value) + path = H5D_nameof((const H5D_t *)obj_ptr); break; + } case H5I_DATATYPE: - path = H5T_nameof((H5T_t*)item->obj_ptr); + { + const H5T_t *dt = (const H5T_t *)item->obj_ptr; + + obj_ptr = (void *)H5T_get_actual_type((H5T_t *)dt); /* Casting away const OK - QAK */ + path = H5T_nameof((const H5T_t *)obj_ptr); break; + } + /* TODO: Maps will have to be added when they are supported in the + * native VOL connector. + */ + case H5I_MAP: + + case H5I_UNINIT: + case H5I_BADID: + case H5I_FILE: + case H5I_DATASPACE: + case H5I_ATTR: + case H5I_VFL: + case H5I_VOL: + case H5I_GENPROP_CLS: + case H5I_GENPROP_LST: + case H5I_ERROR_CLASS: + case H5I_ERROR_MSG: + case H5I_ERROR_STACK: + case H5I_SPACE_SEL_ITER: + case H5I_NTYPES: default: break; /* Other types of IDs are not stored in files */ - } /* end switch*/ + } - if(path) { - if(path->user_path_r) - fprintf(stderr, " user_path = %s\n", H5RS_get_str(path->user_path_r)); - if(path->full_path_r) - fprintf(stderr, " full_path = %s\n", H5RS_get_str(path->full_path_r)); - } /* end if */ + if (path) { + if (path->user_path_r) + HDfprintf(stderr, " user_path = %s\n", H5RS_get_str(path->user_path_r)); + if (path->full_path_r) + HDfprintf(stderr, " full_path = %s\n", H5RS_get_str(path->full_path_r)); + } - FUNC_LEAVE_NOAPI(SUCCEED) -} /* end H5I__debug_cb() */ + FUNC_LEAVE_NOAPI(H5_ITER_CONT) +} /* end H5I__id_dump_cb() */ /*------------------------------------------------------------------------- - * Function: H5I__debug + * Function: H5I_dump_ids_for_type * - * Purpose: Dump the contents of a type to stderr for debugging. + * Purpose: Dump the contents of a type to stderr for debugging. * - * Return: Success: Non-negative - * Failure: Negative - * - * Programmer: Robb Matzke - * Friday, February 19, 1999 + * Return: SUCCEED/FAIL * *------------------------------------------------------------------------- */ -static herr_t -H5I__debug(H5I_type_t type) +herr_t +H5I_dump_ids_for_type(H5I_type_t type) { - H5I_id_type_t *type_ptr; + H5I_id_type_t *type_ptr = NULL; - FUNC_ENTER_STATIC_NOERR + FUNC_ENTER_NOAPI_NOERR - fprintf(stderr, "Dumping ID type %d\n", (int)type); + HDfprintf(stderr, "Dumping ID type %d\n", (int)type); type_ptr = H5I_id_type_list_g[type]; - /* Header */ - fprintf(stderr, " init_count = %u\n", type_ptr->init_count); - fprintf(stderr, " reserved = %u\n", type_ptr->cls->reserved); - fprintf(stderr, " id_count = %llu\n", (unsigned long long)type_ptr->id_count); - fprintf(stderr, " nextid = %llu\n", (unsigned long long)type_ptr->nextid); + if(type_ptr) { - /* List */ - fprintf(stderr, " List:\n"); - H5SL_iterate(type_ptr->ids, H5I__debug_cb, &type); + /* Header */ + HDfprintf(stderr, " init_count = %u\n", type_ptr->init_count); + HDfprintf(stderr, " reserved = %u\n", type_ptr->cls->reserved); + HDfprintf(stderr, " id_count = %llu\n", (unsigned long long)type_ptr->id_count); + HDfprintf(stderr, " nextid = %llu\n", (unsigned long long)type_ptr->nextid); + + /* List */ + if(type_ptr->id_count > 0) { + HDfprintf(stderr, " List:\n"); + H5SL_iterate(type_ptr->ids, H5I__id_dump_cb, &type); + } + } + else + HDfprintf(stderr, "Global type info/tracking pointer for that type is NULL\n"); FUNC_LEAVE_NOAPI(SUCCEED) -} /* end H5I__debug() */ -#endif /* H5I_DEBUG_OUTPUT */ +} /* end H5I_dump_ids_for_type() */ |