/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Copyright by The HDF Group. * * All rights reserved. * * * * This file is part of HDF5. The full HDF5 copyright notice, including * * terms governing use, modification, and redistribution, is contained in * * the COPYING file, which can be found at the root of the source code * * distribution tree, or in https://www.hdfgroup.org/licenses. * * If you do not have access to either file, you may request a copy from * * help@hdfgroup.org. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* * H5I.c - Public routines for handling IDs */ /****************/ /* Module Setup */ /****************/ #include "H5Imodule.h" /* This source code file is part of the H5I module */ /***********/ /* Headers */ /***********/ #include "H5private.h" /* Generic Functions */ #include "H5Eprivate.h" /* Error handling */ #include "H5Fprivate.h" /* Files */ #include "H5Ipkg.h" /* IDs */ #include "H5MMprivate.h" /* Memory management */ #include "H5Pprivate.h" /* Property lists */ /****************/ /* Local Macros */ /****************/ /******************/ /* Local Typedefs */ /******************/ 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; typedef struct { H5I_iterate_func_t op; /* Application's callback routine */ void *op_data; /* Application's user data */ } H5I_iterate_pub_ud_t; /********************/ /* Package Typedefs */ /********************/ /********************/ /* Local Prototypes */ /********************/ static int H5I__search_cb(void *obj, hid_t id, void *_udata); static int H5I__iterate_pub_cb(void *obj, hid_t id, void *udata); /*********************/ /* Package Variables */ /*********************/ /*****************************/ /* Library Private Variables */ /*****************************/ /*******************/ /* Local Variables */ /*******************/ /*------------------------------------------------------------------------- * 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. * * Return: Success: Type ID of the new type * Failure: H5I_BADID * *------------------------------------------------------------------------- */ H5I_type_t 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 = H5I_BADID; /* New ID type value */ H5I_type_t ret_value = H5I_BADID; /* Return value */ FUNC_ENTER_API(H5I_BADID) H5TRACE3("It", "zIuIf", hash_size, reserved, free_func); /* Generate a new H5I_type_t value */ /* Increment the number of types */ if (H5I_next_type_g < H5I_MAX_NUM_TYPES) { new_type = (H5I_type_t)H5I_next_type_g; H5I_next_type_g++; } else { hbool_t done; /* Indicate that search was successful */ int i; /* Look for a free type to give out */ done = FALSE; for (i = H5I_NTYPES; i < H5I_MAX_NUM_TYPES && done == FALSE; i++) { if (NULL == H5I_type_info_array_g[i]) { /* Found a free type ID */ new_type = (H5I_type_t)i; done = TRUE; } } /* Verify that we found a type to give out */ if (done == FALSE) HGOTO_ERROR(H5E_ID, H5E_NOSPACE, H5I_BADID, "Maximum number of ID types exceeded") } /* Allocate new ID class */ if (NULL == (cls = H5MM_calloc(sizeof(H5I_class_t)))) HGOTO_ERROR(H5E_ID, H5E_CANTALLOC, H5I_BADID, "ID class allocation failed") /* Initialize class fields */ cls->type = new_type; cls->flags = H5I_CLASS_IS_APPLICATION; cls->reserved = reserved; cls->free_func = free_func; /* Register the new ID class */ if (H5I_register_type(cls) < 0) HGOTO_ERROR(H5E_ID, H5E_CANTINIT, H5I_BADID, "can't initialize ID class") /* Set return value */ ret_value = new_type; done: /* Clean up on error */ if (ret_value < 0) if (cls) cls = H5MM_xfree(cls); FUNC_LEAVE_API(ret_value) } /* end H5Iregister_type() */ /*------------------------------------------------------------------------- * Function: H5Itype_exists * * Purpose: Query function to inform the user if a given type is * currently registered with the library. * * Return: TRUE/FALSE/FAIL * *------------------------------------------------------------------------- */ htri_t H5Itype_exists(H5I_type_t type) { htri_t ret_value = TRUE; /* Return value */ FUNC_ENTER_API(FAIL) H5TRACE1("t", "It", type); /* Validate parameter */ if (H5I_IS_LIB_TYPE(type)) HGOTO_ERROR(H5E_ID, H5E_BADGROUP, FAIL, "cannot call public function on library type") if (type <= H5I_BADID || (int)type >= H5I_next_type_g) HGOTO_ERROR(H5E_ARGS, H5E_BADRANGE, FAIL, "invalid type number") if (NULL == H5I_type_info_array_g[type]) ret_value = FALSE; done: FUNC_LEAVE_API(ret_value) } /* end H5Itype_exists() */ /*------------------------------------------------------------------------- * Function: H5Inmembers * * 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: SUCCEED/FAIL * * Programmer: James Laird * Nathaniel Furrer * Friday, April 23, 2004 * *------------------------------------------------------------------------- */ herr_t H5Inmembers(H5I_type_t type, hsize_t *num_members) { herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API(FAIL) H5TRACE2("e", "It*h", type, num_members); if (H5I_IS_LIB_TYPE(type)) HGOTO_ERROR(H5E_ID, H5E_BADGROUP, FAIL, "cannot call public function on library type") /* Validate parameters. This needs to be done here, instead of letting * the private interface handle it, because the public interface throws * an error when the supplied type does not exist. */ if (type <= H5I_BADID || (int)type >= H5I_next_type_g) HGOTO_ERROR(H5E_ARGS, H5E_BADRANGE, FAIL, "invalid type number") if (NULL == H5I_type_info_array_g[type]) HGOTO_ERROR(H5E_ARGS, H5E_BADRANGE, FAIL, "supplied type does not exist") if (num_members) { int64_t members; if ((members = H5I_nmembers(type)) < 0) HGOTO_ERROR(H5E_ID, H5E_CANTCOUNT, FAIL, "can't compute number of members") H5_CHECKED_ASSIGN(*num_members, hsize_t, members, int64_t); } done: FUNC_LEAVE_API(ret_value) } /* end H5Inmembers() */ /*------------------------------------------------------------------------- * 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. * * Return: SUCCEED/FAIL * * Programmer: James Laird * Nathaniel Furrer * Friday, April 23, 2004 * *------------------------------------------------------------------------- */ herr_t H5Iclear_type(H5I_type_t type, hbool_t force) { herr_t ret_value = FAIL; /* Return value */ FUNC_ENTER_API(FAIL) H5TRACE2("e", "Itb", type, force); if (H5I_IS_LIB_TYPE(type)) HGOTO_ERROR(H5E_ID, H5E_BADGROUP, FAIL, "cannot call public function on library type") ret_value = H5I_clear_type(type, force, TRUE); done: FUNC_LEAVE_API(ret_value) } /* end H5Iclear_type() */ /*------------------------------------------------------------------------- * Function: H5Idestroy_type * * Purpose: Destroys a type along with all IDs 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: SUCCEED/FAIL * * Programmer: Nathaniel Furrer * James Laird * *------------------------------------------------------------------------- */ herr_t H5Idestroy_type(H5I_type_t type) { herr_t ret_value = FAIL; /* Return value */ FUNC_ENTER_API(FAIL) H5TRACE1("e", "It", type); if (H5I_IS_LIB_TYPE(type)) HGOTO_ERROR(H5E_ID, H5E_BADGROUP, FAIL, "cannot call public function on library type") ret_value = H5I__destroy_type(type); done: FUNC_LEAVE_API(ret_value) } /* end H5Idestroy_type() */ /*------------------------------------------------------------------------- * Function: H5Iregister * * Purpose: Register an object. * * Return: Success: New object ID * Failure: H5I_INVALID_HID * *------------------------------------------------------------------------- */ hid_t H5Iregister(H5I_type_t type, const void *object) { hid_t ret_value = H5I_INVALID_HID; /* Return value */ FUNC_ENTER_API(H5I_INVALID_HID) H5TRACE2("i", "It*x", type, object); if (H5I_IS_LIB_TYPE(type)) HGOTO_ERROR(H5E_ID, H5E_BADGROUP, H5I_INVALID_HID, "cannot call public function on library type") /* Register the object */ if ((ret_value = H5I__register(type, object, TRUE, NULL, NULL)) < 0) HGOTO_ERROR(H5E_ID, H5E_CANTREGISTER, H5I_INVALID_HID, "unable to register object") done: FUNC_LEAVE_API(ret_value) } /* end H5Iregister() */ /*------------------------------------------------------------------------- * Function: H5Iregister_future * * Purpose: Register a "future" object. * * Return: Success: New future object ID * Failure: H5I_INVALID_HID * *------------------------------------------------------------------------- */ hid_t H5Iregister_future(H5I_type_t type, const void *object, H5I_future_realize_func_t realize_cb, H5I_future_discard_func_t discard_cb) { hid_t ret_value = H5I_INVALID_HID; /* Return value */ FUNC_ENTER_API(H5I_INVALID_HID) H5TRACE4("i", "It*xIRID", type, object, realize_cb, discard_cb); /* Check arguments */ if (NULL == realize_cb) HGOTO_ERROR(H5E_ID, H5E_BADVALUE, H5I_INVALID_HID, "NULL pointer for realize_cb not allowed") if (NULL == discard_cb) HGOTO_ERROR(H5E_ID, H5E_BADVALUE, H5I_INVALID_HID, "NULL pointer for realize_cb not allowed") /* Register the future object */ if ((ret_value = H5I__register(type, object, TRUE, realize_cb, discard_cb)) < 0) HGOTO_ERROR(H5E_ID, H5E_CANTREGISTER, H5I_INVALID_HID, "unable to register object") done: FUNC_LEAVE_API(ret_value) } /* end H5Iregister_future() */ /*------------------------------------------------------------------------- * 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. * * Return: Success: Non-NULL object pointer associated with the * specified ID. * Failure: NULL * *------------------------------------------------------------------------- */ void * H5Iobject_verify(hid_t id, H5I_type_t type) { void *ret_value = NULL; /* Return value */ FUNC_ENTER_API(NULL) H5TRACE2("*x", "iIt", id, type); /* Validate parameters */ if (H5I_IS_LIB_TYPE(type)) HGOTO_ERROR(H5E_ID, H5E_BADGROUP, NULL, "cannot call public function on library type") if (type < 1 || (int)type >= H5I_next_type_g) HGOTO_ERROR(H5E_ID, H5E_BADGROUP, NULL, "identifier has invalid type") ret_value = H5I_object_verify(id, type); done: FUNC_LEAVE_API(ret_value) } /* end H5Iobject_verify() */ /*------------------------------------------------------------------------- * 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. * * 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 * *------------------------------------------------------------------------- */ H5I_type_t H5Iget_type(hid_t id) { H5I_type_t ret_value = H5I_BADID; /* Return value */ FUNC_ENTER_API(H5I_BADID) H5TRACE1("It", "i", id); ret_value = H5I_get_type(id); if (ret_value <= H5I_BADID || (int)ret_value >= H5I_next_type_g || NULL == H5I_object(id)) HGOTO_DONE(H5I_BADID); done: FUNC_LEAVE_API(ret_value) } /* end H5Iget_type() */ /*------------------------------------------------------------------------- * 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 * *------------------------------------------------------------------------- */ void * H5Iremove_verify(hid_t id, H5I_type_t type) { void *ret_value = NULL; /* Return value */ FUNC_ENTER_API(NULL) H5TRACE2("*x", "iIt", id, type); if (H5I_IS_LIB_TYPE(type)) HGOTO_ERROR(H5E_ID, H5E_BADGROUP, NULL, "cannot call public function on library type") /* Remove the id */ ret_value = H5I__remove_verify(id, type); done: FUNC_LEAVE_API(ret_value) } /* end H5Iremove_verify() */ /*------------------------------------------------------------------------- * Function: H5Idec_ref * * 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: -1 * * Programmer: Quincey Koziol * Dec 7, 2003 * *------------------------------------------------------------------------- */ int H5Idec_ref(hid_t id) { int ret_value = 0; /* Return value */ FUNC_ENTER_API((-1)) H5TRACE1("Is", "i", id); /* Check arguments */ if (id < 0) HGOTO_ERROR(H5E_ID, H5E_BADID, (-1), "invalid ID") /* Do actual decrement operation */ if ((ret_value = H5I_dec_app_ref(id)) < 0) HGOTO_ERROR(H5E_ID, H5E_CANTDEC, (-1), "can't decrement ID ref count") done: FUNC_LEAVE_API(ret_value) } /* end H5Idec_ref() */ /*------------------------------------------------------------------------- * Function: H5Iinc_ref * * Purpose: Increments the number of references outstanding for an ID. * * Return: Success: New reference count * Failure: -1 * *------------------------------------------------------------------------- */ int H5Iinc_ref(hid_t id) { int ret_value = -1; /* Return value */ FUNC_ENTER_API((-1)) H5TRACE1("Is", "i", id); /* Check arguments */ if (id < 0) HGOTO_ERROR(H5E_ID, H5E_BADID, (-1), "invalid ID") /* Do actual increment operation */ if ((ret_value = H5I_inc_ref(id, TRUE)) < 0) HGOTO_ERROR(H5E_ID, H5E_CANTINC, (-1), "can't increment ID ref count") done: FUNC_LEAVE_API(ret_value) } /* end H5Iinc_ref() */ /*------------------------------------------------------------------------- * Function: H5Iget_ref * * Purpose: Retrieves the number of references outstanding for an ID. * * Return: Success: Reference count * Failure: -1 * *------------------------------------------------------------------------- */ int H5Iget_ref(hid_t id) { int ret_value = -1; /* Return value */ FUNC_ENTER_API((-1)) H5TRACE1("Is", "i", id); /* Check arguments */ if (id < 0) HGOTO_ERROR(H5E_ID, H5E_BADID, (-1), "invalid ID") /* Do actual retrieve operation */ if ((ret_value = H5I_get_ref(id, TRUE)) < 0) HGOTO_ERROR(H5E_ID, H5E_CANTGET, (-1), "can't get ID ref count") done: FUNC_LEAVE_API(ret_value) } /* end H5Iget_ref() */ /*------------------------------------------------------------------------- * Function: H5Iinc_type_ref * * Purpose: Increments the number of references outstanding for an ID type. * * Return: Success: New reference count * Failure: -1 * *------------------------------------------------------------------------- */ int H5Iinc_type_ref(H5I_type_t type) { int ret_value = -1; /* Return value */ FUNC_ENTER_API((-1)) H5TRACE1("Is", "It", type); /* Check arguments */ if (type <= 0 || (int)type >= H5I_next_type_g) HGOTO_ERROR(H5E_ID, H5E_BADID, (-1), "invalid ID type") if (H5I_IS_LIB_TYPE(type)) HGOTO_ERROR(H5E_ID, 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_ID, H5E_CANTINC, (-1), "can't increment ID type ref count") done: FUNC_LEAVE_API(ret_value) } /* end H5Iinc_ref() */ /*------------------------------------------------------------------------- * 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 IDs 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 = 0; /* Return value */ FUNC_ENTER_API((-1)) H5TRACE1("e", "It", type); if (H5I_IS_LIB_TYPE(type)) HGOTO_ERROR(H5E_ID, H5E_BADGROUP, (-1), "cannot call public function on library type") ret_value = H5I_dec_type_ref(type); done: FUNC_LEAVE_API(ret_value) } /* end H5Idec_type_ref() */ /*------------------------------------------------------------------------- * Function: H5Iget_type_ref * * Purpose: Retrieves the number of references outstanding for a type. * * Return: Success: Reference count * Failure: -1 * *------------------------------------------------------------------------- */ int H5Iget_type_ref(H5I_type_t type) { int ret_value = -1; /* Return value */ FUNC_ENTER_API((-1)) H5TRACE1("Is", "It", type); /* Check arguments */ if (type <= 0 || (int)type >= H5I_next_type_g) HGOTO_ERROR(H5E_ID, H5E_BADID, (-1), "invalid ID type") if (H5I_IS_LIB_TYPE(type)) HGOTO_ERROR(H5E_ID, 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_ID, H5E_CANTGET, (-1), "can't get ID type ref count") done: FUNC_LEAVE_API(ret_value) } /* end H5Iget_ref() */ /*------------------------------------------------------------------------- * Function: H5Iis_valid * * 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: TRUE/FALSE/FAIL * *------------------------------------------------------------------------- */ htri_t H5Iis_valid(hid_t id) { H5I_id_info_t *info = NULL; /* Pointer to the ID info */ htri_t ret_value = TRUE; /* Return value */ FUNC_ENTER_API(FAIL) H5TRACE1("t", "i", id); /* Find the ID */ if (NULL == (info = H5I__find_id(id))) ret_value = FALSE; else if (!info->app_count) /* Check if the found id is an internal id */ ret_value = FALSE; done: FUNC_LEAVE_API(ret_value) } /* end H5Iis_valid() */ /*------------------------------------------------------------------------- * 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: 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 */ herr_t cb_ret_val; /* User callback return value */ int ret_value = H5_ITER_ERROR; /* Callback return value */ FUNC_ENTER_PACKAGE_NOERR 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. * * Limitation: Currently there is no way to start searching from where a * previous search left off. * * 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 * *------------------------------------------------------------------------- */ void * H5Isearch(H5I_type_t type, H5I_search_func_t func, void *key) { H5I_search_ud_t udata; /* Context for iteration */ void *ret_value = NULL; /* Return value */ FUNC_ENTER_API(NULL) H5TRACE3("*x", "ItIS*x", type, func, key); /* Check arguments */ if (H5I_IS_LIB_TYPE(type)) HGOTO_ERROR(H5E_ID, H5E_BADGROUP, NULL, "cannot call public function on library type") /* 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. */ (void)H5I_iterate(type, H5I__search_cb, &udata, TRUE); /* Set return value */ ret_value = udata.ret_obj; done: FUNC_LEAVE_API(ret_value) } /* end H5Isearch() */ /*------------------------------------------------------------------------- * 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 * *------------------------------------------------------------------------- */ 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 = FAIL; /* User callback return value */ int ret_value = H5_ITER_ERROR; /* Callback return value */ FUNC_ENTER_PACKAGE_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 function 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 = FAIL; /* Return value */ FUNC_ENTER_API(FAIL) H5TRACE3("e", "ItII*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_ID, H5E_BADITER, FAIL, "can't iterate over ids") done: FUNC_LEAVE_API(ret_value) } /* end H5Iiterate() */ /*------------------------------------------------------------------------- * Function: H5Iget_file_id * * Purpose: Obtains the file ID given an object ID. The user has to * close this ID. * * Return: Success: The file ID associated with the object * * Failure: H5I_INVALID_HID * *------------------------------------------------------------------------- */ hid_t H5Iget_file_id(hid_t obj_id) { H5I_type_t type; /* ID type */ hid_t ret_value = H5I_INVALID_HID; /* Return value */ FUNC_ENTER_API(H5I_INVALID_HID) H5TRACE1("i", "i", obj_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_ID, 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_ID, H5E_CANTGET, H5I_INVALID_HID, "can't retrieve file ID") } else HGOTO_ERROR(H5E_ARGS, H5E_BADRANGE, H5I_INVALID_HID, "not an ID of a file object") done: FUNC_LEAVE_API(ret_value) } /* end H5Iget_file_id() */ /*------------------------------------------------------------------------- * Function: H5Iget_name * * Purpose: Gets a name of an object from its ID. * * Return: Success: The length of the name * * Failure: -1 * * Notes: * 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, * 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) * 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. * *------------------------------------------------------------------------- */ ssize_t H5Iget_name(hid_t id, char *name /*out*/, size_t size) { H5VL_object_t *vol_obj = NULL; /* Object stored in ID */ H5VL_object_get_args_t vol_cb_args; /* Arguments to VOL callback */ H5VL_loc_params_t loc_params; size_t obj_name_len = 0; /* Length of object's name */ ssize_t ret_value = -1; /* Return value */ FUNC_ENTER_API((-1)) H5TRACE3("Zs", "ixz", id, name, size); /* Get the object pointer */ if (NULL == (vol_obj = H5VL_vol_object(id))) HGOTO_ERROR(H5E_ID, H5E_BADTYPE, (-1), "invalid identifier") /* Set location parameters */ loc_params.type = H5VL_OBJECT_BY_SELF; loc_params.obj_type = H5I_get_type(id); /* Set up VOL callback arguments */ vol_cb_args.op_type = H5VL_OBJECT_GET_NAME; vol_cb_args.args.get_name.buf_size = size; vol_cb_args.args.get_name.buf = name; vol_cb_args.args.get_name.name_len = &obj_name_len; /* Retrieve object's name */ if (H5VL_object_get(vol_obj, &loc_params, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0) HGOTO_ERROR(H5E_ID, H5E_CANTGET, (-1), "can't retrieve object name") /* Set return value */ ret_value = (ssize_t)obj_name_len; done: FUNC_LEAVE_API(ret_value) } /* end H5Iget_name() */