diff options
Diffstat (limited to 'src')
150 files changed, 34606 insertions, 6356 deletions
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index fa42d6d..79b695f 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -174,6 +174,10 @@ IDE_GENERATED_PROPERTIES ("H5EA" "${H5EA_HDRS}" "${H5EA_SOURCES}" ) set (H5ES_SOURCES + ${HDF5_SRC_DIR}/H5ES.c + ${HDF5_SRC_DIR}/H5ESevent.c + ${HDF5_SRC_DIR}/H5ESint.c + ${HDF5_SRC_DIR}/H5ESlist.c ) set (H5ES_HDRS ${HDF5_SRC_DIR}/H5ESpublic.h @@ -732,6 +736,7 @@ set (H5_MODULE_HEADERS ${HDF5_SRC_DIR}/H5Dmodule.h ${HDF5_SRC_DIR}/H5Emodule.h ${HDF5_SRC_DIR}/H5EAmodule.h + ${HDF5_SRC_DIR}/H5ESmodule.h ${HDF5_SRC_DIR}/H5Fmodule.h ${HDF5_SRC_DIR}/H5FAmodule.h ${HDF5_SRC_DIR}/H5FDdrvr_module.h @@ -773,6 +778,7 @@ set (common_SRCS ${H5D_SOURCES} ${H5E_SOURCES} ${H5EA_SOURCES} + ${H5ES_SOURCES} ${H5F_SOURCES} ${H5FA_SOURCES} ${H5FD_SOURCES} @@ -885,6 +891,9 @@ set (H5_PRIVATE_HEADERS ${HDF5_SRC_DIR}/H5EApkg.h ${HDF5_SRC_DIR}/H5EAprivate.h + ${HDF5_SRC_DIR}/H5ESpkg.h + ${HDF5_SRC_DIR}/H5ESprivate.h + ${HDF5_SRC_DIR}/H5Fpkg.h ${HDF5_SRC_DIR}/H5Fprivate.h @@ -1355,11 +1364,11 @@ set (_PKG_CONFIG_REQUIRES_PRIVATE) configure_file ( ${HDF_CONFIG_DIR}/libhdf5.pc.in - ${HDF5_BINARY_DIR}/CMakeFiles/${HDF5_LIB_CORENAME}-${HDF5_PACKAGE_VERSION}.pc + ${HDF5_BINARY_DIR}/CMakeFiles/${HDF5_LIB_CORENAME}.pc @ONLY ) install ( - FILES ${HDF5_BINARY_DIR}/CMakeFiles/${HDF5_LIB_CORENAME}-${HDF5_PACKAGE_VERSION}.pc + FILES ${HDF5_BINARY_DIR}/CMakeFiles/${HDF5_LIB_CORENAME}.pc DESTINATION ${HDF5_INSTALL_LIB_DIR}/pkgconfig COMPONENT libraries ) @@ -366,6 +366,11 @@ H5_term_library(void) * down before "lower" level components that they might rely on. -QAK */ + /* Close the event sets first, so that all asynchronous operations + * complete before anything else attempts to shut down. + */ + pending += DOWN(ES); + /* Close down the user-facing interfaces, after the event sets */ if (pending == 0) { /* Close the interfaces dependent on others */ @@ -25,6 +25,7 @@ #include "H5Apkg.h" /* Attributes */ #include "H5CXprivate.h" /* API Contexts */ #include "H5Eprivate.h" /* Error handling */ +#include "H5ESprivate.h" /* Event Sets */ #include "H5FLprivate.h" /* Free Lists */ #include "H5Iprivate.h" /* IDs */ #include "H5MMprivate.h" /* Memory management */ @@ -40,13 +41,6 @@ /* Local Typedefs */ /******************/ -/* Object header iterator callbacks */ -/* Data structure for callback for locating the index by name */ -typedef struct H5A_iter_cb1 { - const char *name; - int idx; -} H5A_iter_cb1; - /********************/ /* Package Typedefs */ /********************/ @@ -55,13 +49,49 @@ typedef struct H5A_iter_cb1 { /* Local Prototypes */ /********************/ +/* Helper routines for sync/async API calls */ +static hid_t H5A__create_common(H5VL_object_t *vol_obj, H5VL_loc_params_t *loc_params, const char *attr_name, + hid_t type_id, hid_t space_id, hid_t acpl_id, hid_t aapl_id, + void **token_ptr); +static hid_t H5A__create_api_common(hid_t loc_id, const char *attr_name, hid_t type_id, hid_t space_id, + hid_t acpl_id, hid_t aapl_id, void **token_ptr, + H5VL_object_t **_vol_obj_ptr); +static hid_t H5A__create_by_name_api_common(hid_t loc_id, const char *obj_name, const char *attr_name, + hid_t type_id, hid_t space_id, hid_t acpl_id, hid_t aapl_id, + hid_t lapl_id, void **token_ptr, H5VL_object_t **_vol_obj_ptr); +static hid_t H5A__open_common(H5VL_object_t *vol_obj, H5VL_loc_params_t *loc_params, const char *attr_name, + hid_t aapl_id, void **token_ptr); +static hid_t H5A__open_api_common(hid_t loc_id, const char *attr_name, hid_t aapl_id, void **token_ptr, + H5VL_object_t **_vol_obj_ptr); +static hid_t H5A__open_by_name_api_common(hid_t loc_id, const char *obj_name, const char *attr_name, + hid_t aapl_id, hid_t lapl_id, void **token_ptr, + H5VL_object_t **_vol_obj_ptr); +static hid_t H5A__open_by_idx_api_common(hid_t loc_id, const char *obj_name, H5_index_t idx_type, + H5_iter_order_t order, hsize_t n, hid_t aapl_id, hid_t lapl_id, + void **token_ptr, H5VL_object_t **_vol_obj_ptr); +static herr_t H5A__write_api_common(hid_t attr_id, hid_t type_id, const void *buf, void **token_ptr, + H5VL_object_t **_vol_obj_ptr); +static herr_t H5A__read_api_common(hid_t attr_id, hid_t dtype_id, void *buf, void **token_ptr, + H5VL_object_t **_vol_obj_ptr); +static herr_t H5A__rename_common(H5VL_object_t *vol_obj, H5VL_loc_params_t *loc_params, const char *old_name, + const char *new_name, void **token_ptr); +static herr_t H5A__rename_api_common(hid_t loc_id, const char *old_name, const char *new_name, + void **token_ptr, H5VL_object_t **_vol_obj_ptr); +static herr_t H5A__rename_by_name_api_common(hid_t loc_id, const char *obj_name, const char *old_attr_name, + const char *new_attr_name, hid_t lapl_id, void **token_ptr, + H5VL_object_t **_vol_obj_ptr); +static herr_t H5A__exists_common(H5VL_object_t *vol_obj, H5VL_loc_params_t *loc_params, const char *attr_name, + hbool_t *attr_exists, void **token_ptr); +static herr_t H5A__exists_api_common(hid_t obj_id, const char *attr_name, hbool_t *attr_exists, + void **token_ptr, H5VL_object_t **_vol_obj_ptr); +static herr_t H5A__exists_by_name_api_common(hid_t obj_id, const char *obj_name, const char *attr_name, + hbool_t *attr_exists, hid_t lapl_id, void **token_ptr, + H5VL_object_t **_vol_obj_ptr); + /*********************/ /* Package Variables */ /*********************/ -/* Package initialization variable */ -hbool_t H5_PKG_INIT_VAR = FALSE; - /*****************************/ /* Library Private Variables */ /*****************************/ @@ -70,159 +100,94 @@ hbool_t H5_PKG_INIT_VAR = FALSE; /* Local Variables */ /*******************/ -/* Declare the free lists of H5A_t */ -H5FL_DEFINE(H5A_t); - -/* Declare the free lists for H5A_shared_t's */ -H5FL_DEFINE(H5A_shared_t); - -/* Declare a free list to manage blocks of type conversion data */ -H5FL_BLK_DEFINE(attr_buf); - -/* Attribute ID class */ -static const H5I_class_t H5I_ATTR_CLS[1] = {{ - H5I_ATTR, /* ID class value */ - 0, /* Class flags */ - 0, /* # of reserved IDs for class */ - (H5I_free_t)H5A__close_cb /* Callback routine for closing objects of this class */ -}}; - -/* Flag indicating "top" of interface has been initialized */ -static hbool_t H5A_top_package_initialize_s = FALSE; - -/*------------------------------------------------------------------------- - * Function: H5A_init +/*-------------------------------------------------------------------------- + * Function: H5A__create_common * - * Purpose: Initialize the interface from some other layer. + * Purpose: This is the common function for creating HDF5 datasets. * - * Return: Success: non-negative + * Return: Success: A attribute ID + * Failure: H5I_INVALID_HID * - * Failure: negative *------------------------------------------------------------------------- */ -herr_t -H5A_init(void) +static hid_t +H5A__create_common(H5VL_object_t *vol_obj, H5VL_loc_params_t *loc_params, const char *attr_name, + hid_t type_id, hid_t space_id, hid_t acpl_id, hid_t aapl_id, void **token_ptr) { - herr_t ret_value = SUCCEED; /* Return value */ - - FUNC_ENTER_NOAPI(FAIL) - /* FUNC_ENTER() does all the work */ + void *attr = NULL; /* Attribute created */ + hid_t ret_value = H5I_INVALID_HID; /* Return value */ -done: - FUNC_LEAVE_NOAPI(ret_value) -} /* end H5A_init() */ + FUNC_ENTER_STATIC -/*-------------------------------------------------------------------------- -NAME - H5A__init_package -- Initialize interface-specific information -USAGE - herr_t H5A__init_package() + /* Sanity checks */ + HDassert(vol_obj); + HDassert(loc_params); + HDassert(attr_name); -RETURNS - Non-negative on success/Negative on failure -DESCRIPTION - Initializes any interface-specific data or routines. - ---------------------------------------------------------------------------*/ -herr_t -H5A__init_package(void) -{ - herr_t ret_value = SUCCEED; /* Return value */ - - FUNC_ENTER_PACKAGE - - /* - * Create attribute ID type. - */ - if (H5I_register_type(H5I_ATTR_CLS) < 0) - HGOTO_ERROR(H5E_ATTR, H5E_CANTINIT, FAIL, "unable to initialize interface") + /* Create the attribute */ + if (NULL == (attr = H5VL_attr_create(vol_obj, loc_params, attr_name, type_id, space_id, acpl_id, aapl_id, + H5P_DATASET_XFER_DEFAULT, token_ptr))) + HGOTO_ERROR(H5E_ATTR, H5E_CANTINIT, H5I_INVALID_HID, "unable to create attribute") - /* Mark "top" of interface as initialized, too */ - H5A_top_package_initialize_s = TRUE; + /* Register the new attribute and get an ID for it */ + if ((ret_value = H5VL_register(H5I_ATTR, attr, vol_obj->connector, TRUE)) < 0) + HGOTO_ERROR(H5E_ATTR, H5E_CANTREGISTER, H5I_INVALID_HID, "unable to register attribute for ID") done: + /* Cleanup on failure */ + if (H5I_INVALID_HID == ret_value) + if (attr && H5VL_attr_close(vol_obj, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0) + HDONE_ERROR(H5E_ATTR, H5E_CLOSEERROR, H5I_INVALID_HID, "can't close attribute") + FUNC_LEAVE_NOAPI(ret_value) -} /* end H5A__init_package() */ +} /* H5A__create_common() */ /*-------------------------------------------------------------------------- - NAME - H5A_top_term_package - PURPOSE - Terminate various H5A objects - USAGE - void H5A_top_term_package() - RETURNS - DESCRIPTION - Release IDs for the atom group, deferring full interface shutdown - until later (in H5A_term_package). - GLOBAL VARIABLES - COMMENTS, BUGS, ASSUMPTIONS - Can't report errors... - EXAMPLES - REVISION LOG ---------------------------------------------------------------------------*/ -int -H5A_top_term_package(void) + * Function: H5A__create_api_common + * + * Purpose: This is the common function for creating HDF5 attributes + * + * Return: Success: A attribute ID + * Failure: H5I_INVALID_HID + * + *------------------------------------------------------------------------- + */ +static hid_t +H5A__create_api_common(hid_t loc_id, const char *attr_name, hid_t type_id, hid_t space_id, hid_t acpl_id, + hid_t aapl_id, void **token_ptr, H5VL_object_t **_vol_obj_ptr) { - int n = 0; - - FUNC_ENTER_NOAPI_NOINIT_NOERR + H5VL_object_t * tmp_vol_obj = NULL; /* Object for loc_id */ + H5VL_object_t **vol_obj_ptr = + (_vol_obj_ptr ? _vol_obj_ptr : &tmp_vol_obj); /* Ptr to object ptr for loc_id */ + H5VL_loc_params_t loc_params; /* Location parameters for object access */ + hid_t ret_value = H5I_INVALID_HID; /* Return value */ - if (H5A_top_package_initialize_s) { - if (H5I_nmembers(H5I_ATTR) > 0) { - (void)H5I_clear_type(H5I_ATTR, FALSE, FALSE); - n++; /*H5I*/ - } /* end if */ + FUNC_ENTER_STATIC - /* Mark closed */ - if (0 == n) - H5A_top_package_initialize_s = FALSE; - } /* end if */ - - FUNC_LEAVE_NOAPI(n) -} /* H5A_top_term_package() */ - -/*-------------------------------------------------------------------------- - NAME - H5A_term_package - PURPOSE - Terminate various H5A objects - USAGE - void H5A_term_package() - RETURNS - DESCRIPTION - Release any other resources allocated. - GLOBAL VARIABLES - COMMENTS, BUGS, ASSUMPTIONS - Can't report errors... - - Finishes shutting down the interface, after H5A_top_term_package() - is called - EXAMPLES - REVISION LOG ---------------------------------------------------------------------------*/ -int -H5A_term_package(void) -{ - int n = 0; - - FUNC_ENTER_NOAPI_NOINIT_NOERR + /* Check arguments */ + if (H5I_ATTR == H5I_get_type(loc_id)) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5I_INVALID_HID, "location is not valid for an attribute") + if (!attr_name) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, H5I_INVALID_HID, "attr_name parameter cannot be NULL") + if (!*attr_name) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, H5I_INVALID_HID, "attr_name parameter cannot be an empty string") - if (H5_PKG_INIT_VAR) { - /* Sanity checks */ - HDassert(0 == H5I_nmembers(H5I_ATTR)); - HDassert(FALSE == H5A_top_package_initialize_s); + /* Set up object access arguments */ + if (H5VL_setup_acc_args(loc_id, H5P_CLS_AACC, TRUE, &aapl_id, vol_obj_ptr, &loc_params) < 0) + HGOTO_ERROR(H5E_ATTR, H5E_CANTSET, H5I_INVALID_HID, "can't set object access arguments") - /* Destroy the attribute object id group */ - n += (H5I_dec_type_ref(H5I_ATTR) > 0); + /* Get correct property list */ + if (H5P_DEFAULT == acpl_id) + acpl_id = H5P_ATTRIBUTE_CREATE_DEFAULT; - /* Mark closed */ - if (0 == n) - H5_PKG_INIT_VAR = FALSE; - } /* end if */ + /* Create the attribute */ + if ((ret_value = H5A__create_common(*vol_obj_ptr, &loc_params, attr_name, type_id, space_id, acpl_id, + aapl_id, token_ptr)) < 0) + HGOTO_ERROR(H5E_ATTR, H5E_CANTCREATE, H5I_INVALID_HID, "unable to create attribute") - FUNC_LEAVE_NOAPI(n) -} /* H5A_term_package() */ +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* H5A__create_api_common() */ /*-------------------------------------------------------------------------- * Function: H5Acreate2 @@ -260,14 +225,91 @@ H5A_term_package(void) hid_t H5Acreate2(hid_t loc_id, const char *attr_name, hid_t type_id, hid_t space_id, hid_t acpl_id, hid_t aapl_id) { - void * attr = NULL; /* Attribute created */ - H5VL_object_t * vol_obj = NULL; /* Object of loc_id */ - H5VL_loc_params_t loc_params; - hid_t ret_value = H5I_INVALID_HID; /* Return value */ + hid_t ret_value = H5I_INVALID_HID; /* Return value */ FUNC_ENTER_API(H5I_INVALID_HID) H5TRACE6("i", "i*siiii", loc_id, attr_name, type_id, space_id, acpl_id, aapl_id); + /* Create the attribute synchronously */ + if ((ret_value = + H5A__create_api_common(loc_id, attr_name, type_id, space_id, acpl_id, aapl_id, NULL, NULL)) < 0) + HGOTO_ERROR(H5E_ATTR, H5E_CANTCREATE, H5I_INVALID_HID, "unable to synchronously create attribute") + +done: + FUNC_LEAVE_API(ret_value) +} /* H5Acreate2() */ + +/*-------------------------------------------------------------------------- + * Function: H5Acreate_sync + * + * Purpose: Asynchronous version of H5Acreate + * + * Return: Success: A attribute ID + * Failure: H5I_INVALID_HID + * + *------------------------------------------------------------------------- + */ +hid_t +H5Acreate_async(const char *app_file, const char *app_func, unsigned app_line, hid_t loc_id, + const char *attr_name, hid_t type_id, hid_t space_id, hid_t acpl_id, hid_t aapl_id, + hid_t es_id) +{ + H5VL_object_t *vol_obj = NULL; /* Object for loc_id */ + void * token = NULL; /* Request token for async operation */ + void ** token_ptr = H5_REQUEST_NULL; /* Pointer to request token for async operation */ + hid_t ret_value = H5I_INVALID_HID; /* Return value */ + + FUNC_ENTER_API(H5I_INVALID_HID) + H5TRACE10("i", "*s*sIui*siiiii", app_file, app_func, app_line, loc_id, attr_name, type_id, space_id, + acpl_id, aapl_id, es_id); + + /* Set up request token pointer for asynchronous operation */ + if (H5ES_NONE != es_id) + token_ptr = &token; /* Point at token for VOL connector to set up */ + + /* Create the attribute asynchronously */ + if ((ret_value = H5A__create_api_common(loc_id, attr_name, type_id, space_id, acpl_id, aapl_id, token_ptr, + &vol_obj)) < 0) + HGOTO_ERROR(H5E_ATTR, H5E_CANTCREATE, H5I_INVALID_HID, "unable to asynchronously create attribute") + + /* If a token was created, add the token to the event set */ + if (NULL != token) + /* clang-format off */ + if (H5ES_insert(es_id, vol_obj->connector, token, + H5ARG_TRACE10(FUNC, "*s*sIui*siiiii", app_file, app_func, app_line, loc_id, attr_name, type_id, space_id, acpl_id, aapl_id, es_id)) < 0) { + /* clang-format on */ + if (H5I_dec_app_ref(ret_value) < 0) + HDONE_ERROR(H5E_ATTR, H5E_CANTDEC, H5I_INVALID_HID, "can't decrement count on attribute ID") + HGOTO_ERROR(H5E_ATTR, H5E_CANTINSERT, H5I_INVALID_HID, "can't insert token into event set") + } /* end if */ + +done: + FUNC_LEAVE_API(ret_value) +} /* H5Acreate_async() */ + +/*-------------------------------------------------------------------------- + * Function: H5A__create_by_name_api_common + * + * Purpose: This is the common function for creating HDF5 attributes by name + * + * Return: Success: A attribute ID + * Failure: H5I_INVALID_HID + * + *------------------------------------------------------------------------- + */ +static hid_t +H5A__create_by_name_api_common(hid_t loc_id, const char *obj_name, const char *attr_name, hid_t type_id, + hid_t space_id, hid_t acpl_id, hid_t aapl_id, hid_t lapl_id, void **token_ptr, + H5VL_object_t **_vol_obj_ptr) +{ + H5VL_object_t * tmp_vol_obj = NULL; /* Object for loc_id */ + H5VL_object_t **vol_obj_ptr = + (_vol_obj_ptr ? _vol_obj_ptr : &tmp_vol_obj); /* Ptr to object ptr for loc_id */ + H5VL_loc_params_t loc_params; /* Location parameters for object access */ + hid_t ret_value = H5I_INVALID_HID; /* Return value */ + + FUNC_ENTER_STATIC + /* Check arguments */ if (H5I_ATTR == H5I_get_type(loc_id)) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5I_INVALID_HID, "location is not valid for an attribute") @@ -276,39 +318,27 @@ H5Acreate2(hid_t loc_id, const char *attr_name, hid_t type_id, hid_t space_id, h if (!*attr_name) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, H5I_INVALID_HID, "attr_name parameter cannot be an empty string") - /* Get correct property list */ - if (H5P_DEFAULT == acpl_id) - acpl_id = H5P_ATTRIBUTE_CREATE_DEFAULT; + /* obj_name is verified in H5VL_setup_name_args() */ + /* Set up object access arguments */ + if (H5VL_setup_name_args(loc_id, obj_name, H5P_CLS_LACC, TRUE, lapl_id, vol_obj_ptr, &loc_params) < 0) + HGOTO_ERROR(H5E_ATTR, H5E_CANTSET, H5I_INVALID_HID, "can't set object access arguments") /* Verify access property list and set up collective metadata if appropriate */ if (H5CX_set_apl(&aapl_id, H5P_CLS_AACC, loc_id, TRUE) < 0) - HGOTO_ERROR(H5E_ATTR, H5E_CANTSET, H5I_INVALID_HID, "can't set access property list info") - - /* Get the location object */ - if (NULL == (vol_obj = H5VL_vol_object(loc_id))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5I_INVALID_HID, "invalid location identifier") + HGOTO_ERROR(H5E_ATTR, H5E_CANTSET, H5I_INVALID_HID, "can't set attribute access property list info") - /* Set location parameters */ - loc_params.type = H5VL_OBJECT_BY_SELF; - loc_params.obj_type = H5I_get_type(loc_id); + /* Get correct property list */ + if (H5P_DEFAULT == acpl_id) + acpl_id = H5P_ATTRIBUTE_CREATE_DEFAULT; /* Create the attribute */ - if (NULL == (attr = H5VL_attr_create(vol_obj, &loc_params, attr_name, type_id, space_id, acpl_id, aapl_id, - H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL))) - HGOTO_ERROR(H5E_ATTR, H5E_CANTINIT, H5I_INVALID_HID, "unable to create attribute") - - /* Register the new attribute and get an ID for it */ - if ((ret_value = H5VL_register(H5I_ATTR, attr, vol_obj->connector, TRUE)) < 0) - HGOTO_ERROR(H5E_ATTR, H5E_CANTREGISTER, H5I_INVALID_HID, "unable to atomize attribute handle") + if ((ret_value = H5A__create_common(*vol_obj_ptr, &loc_params, attr_name, type_id, space_id, acpl_id, + aapl_id, token_ptr)) < 0) + HGOTO_ERROR(H5E_ATTR, H5E_CANTCREATE, H5I_INVALID_HID, "unable to create attribute") done: - /* Cleanup on failure */ - if (H5I_INVALID_HID == ret_value) - if (attr && H5VL_attr_close(vol_obj, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0) - HDONE_ERROR(H5E_ATTR, H5E_CLOSEERROR, H5I_INVALID_HID, "can't close attribute") - - FUNC_LEAVE_API(ret_value) -} /* H5Acreate2() */ + FUNC_LEAVE_NOAPI(ret_value) +} /* H5A__create_by_name_api_common() */ /*-------------------------------------------------------------------------- NAME @@ -344,50 +374,99 @@ hid_t H5Acreate_by_name(hid_t loc_id, const char *obj_name, const char *attr_name, hid_t type_id, hid_t space_id, hid_t acpl_id, hid_t aapl_id, hid_t lapl_id) { - void * attr = NULL; /* attr object from VOL connector */ - H5VL_object_t * vol_obj = NULL; /* object of loc_id */ - H5VL_loc_params_t loc_params; - hid_t ret_value = H5I_INVALID_HID; /* Return value */ + hid_t ret_value = H5I_INVALID_HID; /* Return value */ FUNC_ENTER_API(H5I_INVALID_HID) H5TRACE8("i", "i*s*siiiii", loc_id, obj_name, attr_name, type_id, space_id, acpl_id, aapl_id, lapl_id); - /* Check arguments */ - if (H5I_ATTR == H5I_get_type(loc_id)) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5I_INVALID_HID, "location is not valid for an attribute") - if (!obj_name || !*obj_name) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, H5I_INVALID_HID, "no object name") - if (!attr_name || !*attr_name) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, H5I_INVALID_HID, "no attribute name") + /* Create the attribute synchronously */ + if ((ret_value = H5A__create_by_name_api_common(loc_id, obj_name, attr_name, type_id, space_id, acpl_id, + aapl_id, lapl_id, NULL, NULL)) < 0) + HGOTO_ERROR(H5E_ATTR, H5E_CANTCREATE, H5I_INVALID_HID, "unable to synchronously create attribute") - /* Get correct property list */ - if (H5P_DEFAULT == acpl_id) - acpl_id = H5P_ATTRIBUTE_CREATE_DEFAULT; +done: + FUNC_LEAVE_API(ret_value) +} /* H5Acreate_by_name() */ - /* Verify access property list and set up collective metadata if appropriate */ - if (H5CX_set_apl(&aapl_id, H5P_CLS_AACC, loc_id, TRUE) < 0) - HGOTO_ERROR(H5E_ATTR, H5E_CANTSET, H5I_INVALID_HID, "can't set attribute access property list info") - if (H5CX_set_apl(&lapl_id, H5P_CLS_LACC, loc_id, TRUE) < 0) - HGOTO_ERROR(H5E_ATTR, H5E_CANTSET, H5I_INVALID_HID, "can't set link access property list info") +/*-------------------------------------------------------------------------- + * Function: H5Acreate_by_name_async + * + * Purpose: Asynchronous version of H5Acreate_by_name + * + * Return: Success: A attribute ID + * Failure: H5I_INVALID_HID + * + *------------------------------------------------------------------------- + */ +hid_t +H5Acreate_by_name_async(const char *app_file, const char *app_func, unsigned app_line, hid_t loc_id, + const char *obj_name, const char *attr_name, hid_t type_id, hid_t space_id, + hid_t acpl_id, hid_t aapl_id, hid_t lapl_id, hid_t es_id) +{ + H5VL_object_t *vol_obj = NULL; /* Object for loc_id */ + void * token = NULL; /* Request token for async operation */ + void ** token_ptr = H5_REQUEST_NULL; /* Pointer to request token for async operation */ + hid_t ret_value = H5I_INVALID_HID; /* Return value */ - /* Set up location struct */ - loc_params.type = H5VL_OBJECT_BY_NAME; - loc_params.obj_type = H5I_get_type(loc_id); - loc_params.loc_data.loc_by_name.name = obj_name; - loc_params.loc_data.loc_by_name.lapl_id = lapl_id; + FUNC_ENTER_API(H5I_INVALID_HID) + H5TRACE12("i", "*s*sIui*s*siiiiii", app_file, app_func, app_line, loc_id, obj_name, attr_name, type_id, + space_id, acpl_id, aapl_id, lapl_id, es_id); + + /* Set up request token pointer for asynchronous operation */ + if (H5ES_NONE != es_id) + token_ptr = &token; /* Point at token for VOL connector to set up */ + + /* Create the attribute asynchronously */ + if ((ret_value = H5A__create_by_name_api_common(loc_id, obj_name, attr_name, type_id, space_id, acpl_id, + aapl_id, lapl_id, token_ptr, &vol_obj)) < 0) + HGOTO_ERROR(H5E_ATTR, H5E_CANTCREATE, H5I_INVALID_HID, "unable to asynchronously create attribute") + + /* If a token was created, add the token to the event set */ + if (NULL != token) + /* clang-format off */ + if (H5ES_insert(es_id, vol_obj->connector, token, + H5ARG_TRACE12(FUNC, "*s*sIui*s*siiiiii", app_file, app_func, app_line, loc_id, obj_name, attr_name, type_id, space_id, acpl_id, aapl_id, lapl_id, es_id)) < 0) { + /* clang-format on */ + if (H5I_dec_app_ref(ret_value) < 0) + HDONE_ERROR(H5E_ATTR, H5E_CANTDEC, H5I_INVALID_HID, "can't decrement count on attribute ID") + HGOTO_ERROR(H5E_ATTR, H5E_CANTINSERT, H5I_INVALID_HID, "can't insert token into event set") + } /* end if */ - /* Get the location object */ - if (NULL == (vol_obj = H5VL_vol_object(loc_id))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5I_INVALID_HID, "invalid location identifier") +done: + FUNC_LEAVE_API(ret_value) +} /* H5Acreate_by_name_async() */ - /* Create the attribute */ - if (NULL == (attr = H5VL_attr_create(vol_obj, &loc_params, attr_name, type_id, space_id, acpl_id, aapl_id, - H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL))) - HGOTO_ERROR(H5E_ATTR, H5E_CANTINIT, H5I_INVALID_HID, "unable to create attribute") +/*------------------------------------------------------------------------- + * Function: H5A__open_common + * + * Purpose: This is the common function for opening an attribute + * + * Return: Success: A group ID + * Failure: H5I_INVALID_HID + * + *------------------------------------------------------------------------- + */ +static hid_t +H5A__open_common(H5VL_object_t *vol_obj, H5VL_loc_params_t *loc_params, const char *attr_name, hid_t aapl_id, + void **token_ptr) +{ + void *attr = NULL; /* attr object from VOL connector */ + hid_t ret_value = H5I_INVALID_HID; - /* Register the new attribute and get an ID for it */ + FUNC_ENTER_STATIC + + /* Sanity checks */ + HDassert(vol_obj); + HDassert(loc_params); + + /* Open the attribute */ + if (NULL == + (attr = H5VL_attr_open(vol_obj, loc_params, attr_name, aapl_id, H5P_DATASET_XFER_DEFAULT, token_ptr))) + HGOTO_ERROR(H5E_ATTR, H5E_CANTOPENOBJ, H5I_INVALID_HID, "unable to open attribute: '%s'", attr_name) + + /* Register the attribute and get an ID for it */ if ((ret_value = H5VL_register(H5I_ATTR, attr, vol_obj->connector, TRUE)) < 0) - HGOTO_ERROR(H5E_ATTR, H5E_CANTREGISTER, H5I_INVALID_HID, "unable to atomize attribute handle") + HGOTO_ERROR(H5E_ATTR, H5E_CANTREGISTER, H5I_INVALID_HID, "unable to register attribute for ID") done: /* Cleanup on failure */ @@ -395,8 +474,50 @@ done: if (attr && H5VL_attr_close(vol_obj, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0) HDONE_ERROR(H5E_ATTR, H5E_CLOSEERROR, H5I_INVALID_HID, "can't close attribute") - FUNC_LEAVE_API(ret_value) -} /* H5Acreate_by_name() */ + FUNC_LEAVE_NOAPI(ret_value) +} /* H5A__open_common() */ + +/*------------------------------------------------------------------------- + * Function: H5A__open_api_common + * + * Purpose: This is the common function for opening an attribute + * + * Return: Success: A group ID + * Failure: H5I_INVALID_HID + * + *------------------------------------------------------------------------- + */ +static hid_t +H5A__open_api_common(hid_t loc_id, const char *attr_name, hid_t aapl_id, void **token_ptr, + H5VL_object_t **_vol_obj_ptr) +{ + H5VL_object_t * tmp_vol_obj = NULL; /* Object for loc_id */ + H5VL_object_t **vol_obj_ptr = + (_vol_obj_ptr ? _vol_obj_ptr : &tmp_vol_obj); /* Ptr to object ptr for loc_id */ + H5VL_loc_params_t loc_params; /* Location parameters for object access */ + hid_t ret_value = H5I_INVALID_HID; /* Return value */ + + FUNC_ENTER_STATIC + + /* Check arguments */ + if (H5I_ATTR == H5I_get_type(loc_id)) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5I_INVALID_HID, "location is not valid for an attribute") + if (!attr_name) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, H5I_INVALID_HID, "name parameter cannot be NULL") + if (!*attr_name) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, H5I_INVALID_HID, "name parameter cannot be an empty string") + + /* Set up object access arguments */ + if (H5VL_setup_acc_args(loc_id, H5P_CLS_AACC, FALSE, &aapl_id, vol_obj_ptr, &loc_params) < 0) + HGOTO_ERROR(H5E_ATTR, H5E_CANTSET, H5I_INVALID_HID, "can't set object access arguments") + + /* Open the attribute */ + if ((ret_value = H5A__open_common(*vol_obj_ptr, &loc_params, attr_name, aapl_id, token_ptr)) < 0) + HGOTO_ERROR(H5E_ATTR, H5E_CANTOPENOBJ, H5I_INVALID_HID, "unable to open attribute: '%s'", attr_name) + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* H5A__open_api_common() */ /*-------------------------------------------------------------------------- NAME @@ -420,51 +541,109 @@ done: hid_t H5Aopen(hid_t loc_id, const char *attr_name, hid_t aapl_id) { - void * attr = NULL; /* attr object from VOL connector */ - H5VL_object_t * vol_obj = NULL; /* object of loc_id */ - H5VL_loc_params_t loc_params; - hid_t ret_value = H5I_INVALID_HID; + hid_t ret_value = H5I_INVALID_HID; FUNC_ENTER_API(H5I_INVALID_HID) H5TRACE3("i", "i*si", loc_id, attr_name, aapl_id); + /* Open the attribute synchronously */ + if ((ret_value = H5A__open_api_common(loc_id, attr_name, aapl_id, NULL, NULL)) < 0) + HGOTO_ERROR(H5E_ATTR, H5E_CANTCREATE, H5I_INVALID_HID, "unable to synchronously open attribute") + +done: + FUNC_LEAVE_API(ret_value) +} /* H5Aopen() */ + +/*-------------------------------------------------------------------------- + * NAME + * H5Aopen_async + * PURPOSE + * Asynchronous version of H5Aopen + * + * RETURNS + * ID of attribute on success, H5I_INVALID_HID on failure + * + *--------------------------------------------------------------------------*/ +hid_t +H5Aopen_async(const char *app_file, const char *app_func, unsigned app_line, hid_t loc_id, + const char *attr_name, hid_t aapl_id, hid_t es_id) +{ + H5VL_object_t *vol_obj = NULL; /* Object for loc_id */ + void * token = NULL; /* Request token for async operation */ + void ** token_ptr = H5_REQUEST_NULL; /* Pointer to request token for async operation */ + hid_t ret_value = H5I_INVALID_HID; /* Return value */ + + FUNC_ENTER_API(H5I_INVALID_HID) + H5TRACE7("i", "*s*sIui*sii", app_file, app_func, app_line, loc_id, attr_name, aapl_id, es_id); + + /* Set up request token pointer for asynchronous operation */ + if (H5ES_NONE != es_id) + token_ptr = &token; /* Point at token for VOL connector to set up */ + + /* Open the attribute asynchronously */ + if ((ret_value = H5A__open_api_common(loc_id, attr_name, aapl_id, token_ptr, &vol_obj)) < 0) + HGOTO_ERROR(H5E_ATTR, H5E_CANTCREATE, H5I_INVALID_HID, "unable to asynchronously open attribute") + + /* If a token was created, add the token to the event set */ + if (NULL != token) + /* clang-format off */ + if (H5ES_insert(es_id, vol_obj->connector, token, + H5ARG_TRACE7(FUNC, "*s*sIui*sii", app_file, app_func, app_line, loc_id, attr_name, aapl_id, es_id)) < 0) { + /* clang-format on */ + if (H5I_dec_app_ref(ret_value) < 0) + HDONE_ERROR(H5E_ATTR, H5E_CANTDEC, H5I_INVALID_HID, "can't decrement count on attribute ID") + HGOTO_ERROR(H5E_ATTR, H5E_CANTINSERT, H5I_INVALID_HID, "can't insert token into event set") + } /* end if */ + +done: + FUNC_LEAVE_API(ret_value) +} /* H5Aopen_async() */ + +/*------------------------------------------------------------------------- + * Function: H5A__open_by_name_api_common + * + * Purpose: This is the common function for opening an attribute + * + * Return: Success: A group ID + * Failure: H5I_INVALID_HID + * + *------------------------------------------------------------------------- + */ +static hid_t +H5A__open_by_name_api_common(hid_t loc_id, const char *obj_name, const char *attr_name, hid_t aapl_id, + hid_t lapl_id, void **token_ptr, H5VL_object_t **_vol_obj_ptr) +{ + H5VL_object_t * tmp_vol_obj = NULL; /* Object for loc_id */ + H5VL_object_t **vol_obj_ptr = + (_vol_obj_ptr ? _vol_obj_ptr : &tmp_vol_obj); /* Ptr to object ptr for loc_id */ + H5VL_loc_params_t loc_params; /* Location parameters for object access */ + hid_t ret_value = H5I_INVALID_HID; + + FUNC_ENTER_STATIC + /* Check arguments */ if (H5I_ATTR == H5I_get_type(loc_id)) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5I_INVALID_HID, "location is not valid for an attribute") - if (!attr_name) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, H5I_INVALID_HID, "name parameter cannot be NULL") - if (!*attr_name) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, H5I_INVALID_HID, "name parameter cannot be an empty string") - /* Verify access property list and set up collective metadata if appropriate */ - if (H5CX_set_apl(&aapl_id, H5P_CLS_AACC, loc_id, FALSE) < 0) - HGOTO_ERROR(H5E_ATTR, H5E_CANTSET, H5I_INVALID_HID, "can't set access property list info") + if (!attr_name || !*attr_name) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, H5I_INVALID_HID, "no attribute name") - /* Set location struct fields */ - loc_params.type = H5VL_OBJECT_BY_SELF; - loc_params.obj_type = H5I_get_type(loc_id); + /* obj_name is verified in H5VL_setup_name_args() */ + /* Set up object access arguments */ + if (H5VL_setup_name_args(loc_id, obj_name, H5P_CLS_LACC, FALSE, lapl_id, vol_obj_ptr, &loc_params) < 0) + HGOTO_ERROR(H5E_ATTR, H5E_CANTSET, H5I_INVALID_HID, "can't set object access arguments") - /* Get the location object */ - if (NULL == (vol_obj = H5VL_vol_object(loc_id))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5I_INVALID_HID, "invalid location identifier") + /* Verify access property list and set up collective metadata if appropriate */ + if (H5CX_set_apl(&aapl_id, H5P_CLS_AACC, loc_id, FALSE) < 0) + HGOTO_ERROR(H5E_ATTR, H5E_CANTSET, H5I_INVALID_HID, "can't set attribute access property list info") /* Open the attribute */ - if (NULL == (attr = H5VL_attr_open(vol_obj, &loc_params, attr_name, aapl_id, H5P_DATASET_XFER_DEFAULT, - H5_REQUEST_NULL))) + if ((ret_value = H5A__open_common(*vol_obj_ptr, &loc_params, attr_name, aapl_id, token_ptr)) < 0) HGOTO_ERROR(H5E_ATTR, H5E_CANTOPENOBJ, H5I_INVALID_HID, "unable to open attribute: '%s'", attr_name) - /* Register the attribute and get an ID for it */ - if ((ret_value = H5VL_register(H5I_ATTR, attr, vol_obj->connector, TRUE)) < 0) - HGOTO_ERROR(H5E_ATTR, H5E_CANTREGISTER, H5I_INVALID_HID, "unable to atomize attribute handle") - done: - /* Cleanup on failure */ - if (H5I_INVALID_HID == ret_value) - if (attr && H5VL_attr_close(vol_obj, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0) - HDONE_ERROR(H5E_ATTR, H5E_CLOSEERROR, H5I_INVALID_HID, "can't close attribute") - - FUNC_LEAVE_API(ret_value) -} /* H5Aopen() */ + FUNC_LEAVE_NOAPI(ret_value) +} /* H5A__open_by_name_api_common() */ /*-------------------------------------------------------------------------- NAME @@ -490,55 +669,116 @@ done: hid_t H5Aopen_by_name(hid_t loc_id, const char *obj_name, const char *attr_name, hid_t aapl_id, hid_t lapl_id) { - void * attr = NULL; /* attr object from VOL connector */ - H5VL_object_t * vol_obj = NULL; /* object of loc_id */ - H5VL_loc_params_t loc_params; - hid_t ret_value = H5I_INVALID_HID; + hid_t ret_value = H5I_INVALID_HID; FUNC_ENTER_API(H5I_INVALID_HID) H5TRACE5("i", "i*s*sii", loc_id, obj_name, attr_name, aapl_id, lapl_id); + /* Open the attribute by name asynchronously */ + if ((ret_value = + H5A__open_by_name_api_common(loc_id, obj_name, attr_name, aapl_id, lapl_id, NULL, NULL)) < 0) + HGOTO_ERROR(H5E_ATTR, H5E_CANTOPENOBJ, H5I_INVALID_HID, "unable to synchronously open attribute") + +done: + FUNC_LEAVE_API(ret_value) +} /* end H5Aopen_by_name() */ + +/*-------------------------------------------------------------------------- + * NAME + * H5Aopen_by_name_async + * PURPOSE + * Asynchronous version of H5Aopen_by_name + * + * RETURNS + * ID of attribute on success, H5I_INVALID_HID on failure + * + *--------------------------------------------------------------------------*/ +hid_t +H5Aopen_by_name_async(const char *app_file, const char *app_func, unsigned app_line, hid_t loc_id, + const char *obj_name, const char *attr_name, hid_t aapl_id, hid_t lapl_id, hid_t es_id) +{ + H5VL_object_t *vol_obj = NULL; /* Object for loc_id */ + void * token = NULL; /* Request token for async operation */ + void ** token_ptr = H5_REQUEST_NULL; /* Pointer to request token for async operation */ + hid_t ret_value = H5I_INVALID_HID; + + FUNC_ENTER_API(H5I_INVALID_HID) + H5TRACE9("i", "*s*sIui*s*siii", app_file, app_func, app_line, loc_id, obj_name, attr_name, aapl_id, + lapl_id, es_id); + + /* Set up request token pointer for asynchronous operation */ + if (H5ES_NONE != es_id) + token_ptr = &token; /* Point at token for VOL connector to set up */ + + /* Open the attribute by name asynchronously */ + if ((ret_value = H5A__open_by_name_api_common(loc_id, obj_name, attr_name, aapl_id, lapl_id, token_ptr, + &vol_obj)) < 0) + HGOTO_ERROR(H5E_ATTR, H5E_CANTOPENOBJ, H5I_INVALID_HID, "unable to asynchronously open attribute") + + /* If a token was created, add the token to the event set */ + if (NULL != token) + /* clang-format off */ + if (H5ES_insert(es_id, vol_obj->connector, token, + H5ARG_TRACE9(FUNC, "*s*sIui*s*siii", app_file, app_func, app_line, loc_id, obj_name, attr_name, aapl_id, lapl_id, es_id)) < 0) { + /* clang-format on */ + if (H5I_dec_app_ref(ret_value) < 0) + HDONE_ERROR(H5E_ATTR, H5E_CANTDEC, H5I_INVALID_HID, "can't decrement count on attribute ID") + HGOTO_ERROR(H5E_ATTR, H5E_CANTINSERT, H5I_INVALID_HID, "can't insert token into event set") + } /* end if */ + +done: + FUNC_LEAVE_API(ret_value) +} /* end H5Aopen_by_name_async() */ + +/*------------------------------------------------------------------------- + * Function: H5A__open_by_idx_api_common + * + * Purpose: This is the common function for opening an attribute + * + * Return: Success: A group ID + * Failure: H5I_INVALID_HID + * + *------------------------------------------------------------------------- + */ +static hid_t +H5A__open_by_idx_api_common(hid_t loc_id, const char *obj_name, H5_index_t idx_type, H5_iter_order_t order, + hsize_t n, hid_t aapl_id, hid_t lapl_id, void **token_ptr, + H5VL_object_t **_vol_obj_ptr) +{ + H5VL_object_t * tmp_vol_obj = NULL; /* Object for loc_id */ + H5VL_object_t **vol_obj_ptr = + (_vol_obj_ptr ? _vol_obj_ptr : &tmp_vol_obj); /* Ptr to object ptr for loc_id */ + H5VL_loc_params_t loc_params; /* Location parameters for object access */ + hid_t ret_value = H5I_INVALID_HID; + + FUNC_ENTER_STATIC + /* Check arguments */ if (H5I_ATTR == H5I_get_type(loc_id)) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5I_INVALID_HID, "location is not valid for an attribute") if (!obj_name || !*obj_name) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, H5I_INVALID_HID, "no object name") - if (!attr_name || !*attr_name) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, H5I_INVALID_HID, "no attribute name") + if (idx_type <= H5_INDEX_UNKNOWN || idx_type >= H5_INDEX_N) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, H5I_INVALID_HID, "invalid index type specified") + if (order <= H5_ITER_UNKNOWN || order >= H5_ITER_N) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, H5I_INVALID_HID, "invalid iteration order specified") + + /* Set up object access arguments */ + if (H5VL_setup_idx_args(loc_id, obj_name, idx_type, order, n, H5P_CLS_LACC, FALSE, lapl_id, vol_obj_ptr, + &loc_params) < 0) + HGOTO_ERROR(H5E_ATTR, H5E_CANTSET, H5I_INVALID_HID, "can't set object access arguments") /* Verify access property list and set up collective metadata if appropriate */ if (H5CX_set_apl(&aapl_id, H5P_CLS_AACC, loc_id, FALSE) < 0) HGOTO_ERROR(H5E_ATTR, H5E_CANTSET, H5I_INVALID_HID, "can't set attribute access property list info") - if (H5CX_set_apl(&lapl_id, H5P_CLS_LACC, loc_id, FALSE) < 0) - HGOTO_ERROR(H5E_ATTR, H5E_CANTSET, H5I_INVALID_HID, "can't set link access property list info") - - /* Fill in location struct fields */ - loc_params.type = H5VL_OBJECT_BY_NAME; - loc_params.loc_data.loc_by_name.name = obj_name; - loc_params.loc_data.loc_by_name.lapl_id = lapl_id; - loc_params.obj_type = H5I_get_type(loc_id); - - /* Get the location object */ - if (NULL == (vol_obj = H5VL_vol_object(loc_id))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5I_INVALID_HID, "invalid location identifier") /* Open the attribute */ - if (NULL == (attr = H5VL_attr_open(vol_obj, &loc_params, attr_name, aapl_id, H5P_DATASET_XFER_DEFAULT, - H5_REQUEST_NULL))) - HGOTO_ERROR(H5E_ATTR, H5E_CANTOPENOBJ, H5I_INVALID_HID, "can't open attribute") - - /* Register the attribute and get an ID for it */ - if ((ret_value = H5VL_register(H5I_ATTR, attr, vol_obj->connector, TRUE)) < 0) - HGOTO_ERROR(H5E_ATTR, H5E_CANTREGISTER, H5I_INVALID_HID, "unable to atomize attribute handle") + if ((ret_value = H5A__open_common(*vol_obj_ptr, &loc_params, NULL, aapl_id, token_ptr)) < 0) + HGOTO_ERROR(H5E_ATTR, H5E_CANTOPENOBJ, H5I_INVALID_HID, "unable to open attribute") done: - /* Cleanup on failure */ - if (H5I_INVALID_HID == ret_value) - if (attr && H5VL_attr_close(vol_obj, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0) - HDONE_ERROR(H5E_ATTR, H5E_CLOSEERROR, H5I_INVALID_HID, "can't close attribute") - - FUNC_LEAVE_API(ret_value) -} /* end H5Aopen_by_name() */ + FUNC_LEAVE_NOAPI(ret_value) +} /* H5A__open_by_idx_api_common() */ /*-------------------------------------------------------------------------- NAME @@ -568,60 +808,104 @@ hid_t H5Aopen_by_idx(hid_t loc_id, const char *obj_name, H5_index_t idx_type, H5_iter_order_t order, hsize_t n, hid_t aapl_id, hid_t lapl_id) { - void * attr = NULL; /* Attribute opened */ - H5VL_object_t * vol_obj = NULL; /* object of loc_id */ - H5VL_loc_params_t loc_params; - hid_t ret_value = H5I_INVALID_HID; /* Return value */ + hid_t ret_value = H5I_INVALID_HID; /* Return value */ FUNC_ENTER_API(H5I_INVALID_HID) H5TRACE7("i", "i*sIiIohii", loc_id, obj_name, idx_type, order, n, aapl_id, lapl_id); - /* Check arguments */ - if (H5I_ATTR == H5I_get_type(loc_id)) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5I_INVALID_HID, "location is not valid for an attribute") - if (!obj_name || !*obj_name) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, H5I_INVALID_HID, "no object name") - if (idx_type <= H5_INDEX_UNKNOWN || idx_type >= H5_INDEX_N) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, H5I_INVALID_HID, "invalid index type specified") - if (order <= H5_ITER_UNKNOWN || order >= H5_ITER_N) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, H5I_INVALID_HID, "invalid iteration order specified") + /* Open the attribute by idx synchronously */ + if ((ret_value = H5A__open_by_idx_api_common(loc_id, obj_name, idx_type, order, n, aapl_id, lapl_id, NULL, + NULL)) < 0) + HGOTO_ERROR(H5E_ATTR, H5E_CANTCREATE, H5I_INVALID_HID, "unable to synchronously open attribute") - /* Verify access property list and set up collective metadata if appropriate */ - if (H5CX_set_apl(&aapl_id, H5P_CLS_AACC, loc_id, FALSE) < 0) - HGOTO_ERROR(H5E_ATTR, H5E_CANTSET, H5I_INVALID_HID, "can't set attribute access property list info") - if (H5CX_set_apl(&lapl_id, H5P_CLS_LACC, loc_id, FALSE) < 0) - HGOTO_ERROR(H5E_ATTR, H5E_CANTSET, H5I_INVALID_HID, "can't set link access property list info") +done: + FUNC_LEAVE_API(ret_value) +} /* H5Aopen_by_idx() */ - /* Fill in location struct parameters */ - loc_params.type = H5VL_OBJECT_BY_IDX; - loc_params.loc_data.loc_by_idx.name = obj_name; - loc_params.loc_data.loc_by_idx.idx_type = idx_type; - loc_params.loc_data.loc_by_idx.order = order; - loc_params.loc_data.loc_by_idx.n = n; - loc_params.loc_data.loc_by_idx.lapl_id = lapl_id; - loc_params.obj_type = H5I_get_type(loc_id); +/*-------------------------------------------------------------------------- + * NAME + * H5Aopen_by_idx_async + * PURPOSE + * Asynchronous version of H5Aopen_by_idx + * + * RETURNS + * ID of attribute on success, H5I_INVALID_HID on failure + * + *--------------------------------------------------------------------------*/ +hid_t +H5Aopen_by_idx_async(const char *app_file, const char *app_func, unsigned app_line, hid_t loc_id, + const char *obj_name, H5_index_t idx_type, H5_iter_order_t order, hsize_t n, + hid_t aapl_id, hid_t lapl_id, hid_t es_id) +{ + H5VL_object_t *vol_obj = NULL; /* Object for loc_id */ + void * token = NULL; /* Request token for async operation */ + void ** token_ptr = H5_REQUEST_NULL; /* Pointer to request token for async operation */ + hid_t ret_value = H5I_INVALID_HID; - /* Get the location object */ - if (NULL == (vol_obj = H5VL_vol_object(loc_id))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5I_INVALID_HID, "invalid location identifier") + FUNC_ENTER_API(H5I_INVALID_HID) + H5TRACE11("i", "*s*sIui*sIiIohiii", app_file, app_func, app_line, loc_id, obj_name, idx_type, order, n, + aapl_id, lapl_id, es_id); + + /* Set up request token pointer for asynchronous operation */ + if (H5ES_NONE != es_id) + token_ptr = &token; /* Point at token for VOL connector to set up */ + + /* Open the attribute by idx asynchronously */ + if ((ret_value = H5A__open_by_idx_api_common(loc_id, obj_name, idx_type, order, n, aapl_id, lapl_id, + token_ptr, &vol_obj)) < 0) + HGOTO_ERROR(H5E_ATTR, H5E_CANTCREATE, H5I_INVALID_HID, "unable to asynchronously open attribute") + + /* If a token was created, add the token to the event set */ + if (NULL != token) + /* clang-format off */ + if (H5ES_insert(es_id, vol_obj->connector, token, + H5ARG_TRACE11(FUNC, "*s*sIui*sIiIohiii", app_file, app_func, app_line, loc_id, obj_name, idx_type, order, n, aapl_id, lapl_id, es_id)) < 0) { + /* clang-format on */ + if (H5I_dec_app_ref(ret_value) < 0) + HDONE_ERROR(H5E_ATTR, H5E_CANTDEC, H5I_INVALID_HID, "can't decrement count on attribute ID") + HGOTO_ERROR(H5E_ATTR, H5E_CANTINSERT, H5I_INVALID_HID, "can't insert token into event set") + } /* end if */ - /* Open the attribute */ - if (NULL == (attr = H5VL_attr_open(vol_obj, &loc_params, NULL, aapl_id, H5P_DATASET_XFER_DEFAULT, - H5_REQUEST_NULL))) - HGOTO_ERROR(H5E_ATTR, H5E_CANTOPENOBJ, H5I_INVALID_HID, "unable to open attribute") +done: + FUNC_LEAVE_API(ret_value) +} /* end H5Aopen_by_idx_async() */ - /* Register the attribute and get an ID for it */ - if ((ret_value = H5VL_register(H5I_ATTR, attr, vol_obj->connector, TRUE)) < 0) - HGOTO_ERROR(H5E_ATTR, H5E_CANTREGISTER, H5I_INVALID_HID, "unable to atomize attribute handle") +/*-------------------------------------------------------------------------- + NAME + H5A__write_api_common + PURPOSE + Common helper routine for sync/async dataset write operations. + RETURNS + Non-negative on success/Negative on failure +--------------------------------------------------------------------------*/ +static herr_t +H5A__write_api_common(hid_t attr_id, hid_t type_id, const void *buf, void **token_ptr, + H5VL_object_t **_vol_obj_ptr) +{ + H5VL_object_t * tmp_vol_obj = NULL; /* Object for loc_id */ + H5VL_object_t **vol_obj_ptr = + (_vol_obj_ptr ? _vol_obj_ptr : &tmp_vol_obj); /* Ptr to object ptr for loc_id */ + herr_t ret_value = SUCCEED; /* Return value */ -done: - /* Cleanup on failure */ - if (H5I_INVALID_HID == ret_value) - if (attr && H5VL_attr_close(vol_obj, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0) - HDONE_ERROR(H5E_ATTR, H5E_CLOSEERROR, H5I_INVALID_HID, "can't close attribute") + FUNC_ENTER_STATIC - FUNC_LEAVE_API(ret_value) -} /* H5Aopen_by_idx() */ + /* Check arguments */ + if (H5I_DATATYPE != H5I_get_type(type_id)) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a datatype") + if (NULL == buf) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "buf parameter can't be NULL") + + /* Get attribute pointer */ + if (H5VL_setup_args(attr_id, H5I_ATTR, vol_obj_ptr) < 0) + HGOTO_ERROR(H5E_ATTR, H5E_CANTGET, FAIL, "can't get VOL object for attribute") + + /* Write the attribute data */ + if (H5VL_attr_write(*vol_obj_ptr, type_id, buf, H5P_DATASET_XFER_DEFAULT, token_ptr) < 0) + HGOTO_ERROR(H5E_ATTR, H5E_WRITEERROR, FAIL, "unable to write attribute") + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* H5A__write_api_common() */ /*-------------------------------------------------------------------------- NAME @@ -642,31 +926,94 @@ done: herr_t H5Awrite(hid_t attr_id, hid_t dtype_id, const void *buf) { - H5VL_object_t *vol_obj; /* Attribute object for ID */ - herr_t ret_value; /* Return value */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API(FAIL) H5TRACE3("e", "ii*x", attr_id, dtype_id, buf); + /* Synchronously write the data */ + if (H5A__write_api_common(attr_id, dtype_id, buf, NULL, NULL) < 0) + HGOTO_ERROR(H5E_ATTR, H5E_WRITEERROR, FAIL, "can't synchronously write data") + +done: + FUNC_LEAVE_API(ret_value) +} /* H5Awrite() */ + +/*-------------------------------------------------------------------------- + NAME + H5Awrite_async + PURPOSE + Asynchronous version of H5Awrite + RETURNS + Non-negative on success/Negative on failure +--------------------------------------------------------------------------*/ +herr_t +H5Awrite_async(const char *app_file, const char *app_func, unsigned app_line, hid_t attr_id, hid_t dtype_id, + const void *buf, hid_t es_id) +{ + H5VL_object_t *vol_obj = NULL; /* Object for attr_id */ + void * token = NULL; /* Request token for async operation */ + void ** token_ptr = H5_REQUEST_NULL; /* Pointer to request token for async operation */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_API(FAIL) + H5TRACE7("e", "*s*sIuii*xi", app_file, app_func, app_line, attr_id, dtype_id, buf, es_id); + + /* Set up request token pointer for asynchronous operation */ + if (H5ES_NONE != es_id) + token_ptr = &token; /* Point at token for VOL connector to set up */ + + /* Asynchronously write the data */ + if (H5A__write_api_common(attr_id, dtype_id, buf, token_ptr, &vol_obj) < 0) + HGOTO_ERROR(H5E_ATTR, H5E_WRITEERROR, FAIL, "can't asynchronously write data") + + /* If a token was created, add the token to the event set */ + if (NULL != token) + /* clang-format off */ + if (H5ES_insert(es_id, vol_obj->connector, token, + H5ARG_TRACE7(FUNC, "*s*sIuii*xi", app_file, app_func, app_line, attr_id, dtype_id, buf, es_id)) < 0) + /* clang-format on */ + HGOTO_ERROR(H5E_ATTR, H5E_CANTINSERT, FAIL, "can't insert token into event set") + +done: + FUNC_LEAVE_API(ret_value) +} /* H5Awrite_async() */ + +/*-------------------------------------------------------------------------- + * NAME + * H5A__read_api_common + * PURPOSE + * Common helper routine for sync/async attribute read operations. + * RETURNS + * Non-negative on success/Negative on failure + *--------------------------------------------------------------------------*/ +static herr_t +H5A__read_api_common(hid_t attr_id, hid_t dtype_id, void *buf, void **token_ptr, H5VL_object_t **_vol_obj_ptr) +{ + H5VL_object_t * tmp_vol_obj = NULL; /* Object for loc_id */ + H5VL_object_t **vol_obj_ptr = + (_vol_obj_ptr ? _vol_obj_ptr : &tmp_vol_obj); /* Ptr to object ptr for loc_id */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_STATIC + /* Check arguments */ - if (NULL == (vol_obj = (H5VL_object_t *)H5I_object_verify(attr_id, H5I_ATTR))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not an attribute") if (H5I_DATATYPE != H5I_get_type(dtype_id)) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a datatype") if (NULL == buf) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "buf parameter can't be NULL") - /* Set up collective metadata if appropriate */ - if (H5CX_set_loc(attr_id) < 0) - HGOTO_ERROR(H5E_ATTR, H5E_CANTSET, FAIL, "can't set collective metadata read") + /* Get attribute object pointer */ + if (NULL == (*vol_obj_ptr = (H5VL_object_t *)H5I_object_verify(attr_id, H5I_ATTR))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not an attribute") - /* Write the attribute data */ - if ((ret_value = H5VL_attr_write(vol_obj, dtype_id, buf, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL)) < 0) - HGOTO_ERROR(H5E_ATTR, H5E_WRITEERROR, FAIL, "unable to write attribute") + /* Read the attribute data */ + if (H5VL_attr_read(*vol_obj_ptr, dtype_id, buf, H5P_DATASET_XFER_DEFAULT, token_ptr) < 0) + HGOTO_ERROR(H5E_ATTR, H5E_READERROR, FAIL, "unable to read attribute") done: - FUNC_LEAVE_API(ret_value) -} /* H5Awrite() */ + FUNC_LEAVE_NOAPI(ret_value) +} /* H5A__read_api_common() */ /*-------------------------------------------------------------------------- NAME @@ -685,31 +1032,62 @@ done: This function reads a complete attribute from disk. --------------------------------------------------------------------------*/ herr_t -H5Aread(hid_t attr_id, hid_t dtype_id, void *buf) +H5Aread(hid_t attr_id, hid_t dtype_id, void *buf /*out*/) { - H5VL_object_t *vol_obj; /* Attribute object for ID */ - herr_t ret_value; /* Return value */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API(FAIL) - H5TRACE3("e", "ii*x", attr_id, dtype_id, buf); - - /* Check arguments */ - if (NULL == (vol_obj = (H5VL_object_t *)H5I_object_verify(attr_id, H5I_ATTR))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not an attribute") - if (H5I_DATATYPE != H5I_get_type(dtype_id)) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a datatype") - if (NULL == buf) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "buf parameter can't be NULL") + H5TRACE3("e", "iix", attr_id, dtype_id, buf); - /* Read the attribute data */ - if ((ret_value = H5VL_attr_read(vol_obj, dtype_id, buf, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL)) < 0) - HGOTO_ERROR(H5E_ATTR, H5E_READERROR, FAIL, "unable to read attribute") + /* Synchronously read the data */ + if (H5A__read_api_common(attr_id, dtype_id, buf, NULL, NULL) < 0) + HGOTO_ERROR(H5E_ATTR, H5E_READERROR, FAIL, "can't synchronously read data") done: FUNC_LEAVE_API(ret_value) } /* H5Aread() */ /*-------------------------------------------------------------------------- + * NAME + * H5Aread_async + * PURPOSE + * Asynchronous version of H5Aread + * RETURNS + * Non-negative on success/Negative on failure + *--------------------------------------------------------------------------*/ +herr_t +H5Aread_async(const char *app_file, const char *app_func, unsigned app_line, hid_t attr_id, hid_t dtype_id, + void *buf, hid_t es_id) +{ + H5VL_object_t *vol_obj = NULL; /* Object for attr_id */ + void * token = NULL; /* Request token for async operation */ + void ** token_ptr = H5_REQUEST_NULL; /* Pointer to request token for async operation */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_API(FAIL) + H5TRACE7("e", "*s*sIuii*xi", app_file, app_func, app_line, attr_id, dtype_id, buf, es_id); + + /* Set up request token pointer for asynchronous operation */ + if (H5ES_NONE != es_id) + token_ptr = &token; /* Point at token for VOL connector to set up */ + + /* Asynchronously read the data */ + if (H5A__read_api_common(attr_id, dtype_id, buf, token_ptr, &vol_obj) < 0) + HGOTO_ERROR(H5E_ATTR, H5E_READERROR, FAIL, "can't asynchronously read data") + + /* If a token was created, add the token to the event set */ + if (NULL != token) + /* clang-format off */ + if (H5ES_insert(es_id, vol_obj->connector, token, + H5ARG_TRACE7(FUNC, "*s*sIuii*xi", app_file, app_func, app_line, attr_id, dtype_id, buf, es_id)) < 0) + /* clang-format on */ + HGOTO_ERROR(H5E_ATTR, H5E_CANTINSERT, FAIL, "can't insert token into event set") + +done: + FUNC_LEAVE_API(ret_value) +} /* H5Aread_async() */ + +/*-------------------------------------------------------------------------- NAME H5Aget_space PURPOSE @@ -849,14 +1227,14 @@ done: properly terminate the string. --------------------------------------------------------------------------*/ ssize_t -H5Aget_name(hid_t attr_id, size_t buf_size, char *buf) +H5Aget_name(hid_t attr_id, size_t buf_size, char *buf /*out*/) { H5VL_object_t * vol_obj = NULL; /* Attribute object for ID */ H5VL_loc_params_t loc_params; ssize_t ret_value = -1; FUNC_ENTER_API((-1)) - H5TRACE3("Zs", "iz*s", attr_id, buf_size, buf); + H5TRACE3("Zs", "izx", attr_id, buf_size, buf); /* check arguments */ if (NULL == (vol_obj = (H5VL_object_t *)H5I_object_verify(attr_id, H5I_ATTR))) @@ -995,16 +1373,16 @@ done: *------------------------------------------------------------------------- */ herr_t -H5Aget_info(hid_t attr_id, H5A_info_t *ainfo) +H5Aget_info(hid_t attr_id, H5A_info_t *ainfo /*out*/) { H5VL_object_t * vol_obj; H5VL_loc_params_t loc_params; herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API(FAIL) - H5TRACE2("e", "i*Ai", attr_id, ainfo); + H5TRACE2("e", "ix", attr_id, ainfo); - /* Check arguments */ + /* Check args */ if (NULL == (vol_obj = (H5VL_object_t *)H5I_object_verify(attr_id, H5I_ATTR))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not an attribute") if (!ainfo) @@ -1036,7 +1414,7 @@ done: *------------------------------------------------------------------------- */ herr_t -H5Aget_info_by_name(hid_t loc_id, const char *obj_name, const char *attr_name, H5A_info_t *ainfo, +H5Aget_info_by_name(hid_t loc_id, const char *obj_name, const char *attr_name, H5A_info_t *ainfo /*out*/, hid_t lapl_id) { H5VL_object_t * vol_obj; @@ -1044,7 +1422,7 @@ H5Aget_info_by_name(hid_t loc_id, const char *obj_name, const char *attr_name, H herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API(FAIL) - H5TRACE5("e", "i*s*s*Aii", loc_id, obj_name, attr_name, ainfo, lapl_id); + H5TRACE5("e", "i*s*sxi", loc_id, obj_name, attr_name, ainfo, lapl_id); /* Check args */ if (H5I_ATTR == H5I_get_type(loc_id)) @@ -1094,14 +1472,14 @@ done: */ herr_t H5Aget_info_by_idx(hid_t loc_id, const char *obj_name, H5_index_t idx_type, H5_iter_order_t order, hsize_t n, - H5A_info_t *ainfo, hid_t lapl_id) + H5A_info_t *ainfo /*out*/, hid_t lapl_id) { H5VL_object_t * vol_obj; H5VL_loc_params_t loc_params; herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API(FAIL) - H5TRACE7("e", "i*sIiIoh*Aii", loc_id, obj_name, idx_type, order, n, ainfo, lapl_id); + H5TRACE7("e", "i*sIiIohxi", loc_id, obj_name, idx_type, order, n, ainfo, lapl_id); /* Check args */ if (H5I_ATTR == H5I_get_type(loc_id)) @@ -1140,12 +1518,91 @@ done: FUNC_LEAVE_API(ret_value) } /* end H5Aget_info_by_idx() */ +/*-------------------------------------------------------------------------- + NAME + H5A__rename_common + PURPOSE + Common helper routine for sync/async attribute rename operations + RETURNS + Non-negative on success/Negative on failure +--------------------------------------------------------------------------*/ +static herr_t +H5A__rename_common(H5VL_object_t *vol_obj, H5VL_loc_params_t *loc_params, const char *old_name, + const char *new_name, void **token_ptr) +{ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_STATIC + + /* Sanity checks */ + HDassert(vol_obj); + HDassert(loc_params); + HDassert(old_name); + HDassert(new_name); + + /* Avoid thrashing things if the names are the same */ + if (HDstrcmp(old_name, new_name) != 0) + /* Rename the attribute */ + if (H5VL_attr_specific(vol_obj, loc_params, H5VL_ATTR_RENAME, H5P_DATASET_XFER_DEFAULT, token_ptr, + old_name, new_name) < 0) + HGOTO_ERROR(H5E_ATTR, H5E_CANTRENAME, FAIL, "can't rename attribute from '%s' to '%s'", old_name, + new_name) + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* H5A__rename_common() */ + +/*-------------------------------------------------------------------------- + NAME + H5A__rename_api_common + PURPOSE + Common helper routine for sync/async attribute rename operations + RETURNS + Non-negative on success/Negative on failure +--------------------------------------------------------------------------*/ +static herr_t +H5A__rename_api_common(hid_t loc_id, const char *old_name, const char *new_name, void **token_ptr, + H5VL_object_t **_vol_obj_ptr) +{ + H5VL_object_t * tmp_vol_obj = NULL; /* Object for loc_id */ + H5VL_object_t **vol_obj_ptr = + (_vol_obj_ptr ? _vol_obj_ptr : &tmp_vol_obj); /* Ptr to object ptr for loc_id */ + H5VL_loc_params_t loc_params; /* Location parameters for object access */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_STATIC + + /* Check arguments */ + if (H5I_ATTR == H5I_get_type(loc_id)) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "location is not valid for an attribute") + if (!old_name) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "old attribute name cannot be NULL") + if (!*old_name) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "old attribute name cannot be an empty string") + if (!new_name) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "new attribute name cannot be NULL") + if (!*new_name) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "new attribute name cannot be an empty string") + + /* Set up object access arguments */ + if (H5VL_setup_loc_args(loc_id, vol_obj_ptr, &loc_params) < 0) + HGOTO_ERROR(H5E_ATTR, H5E_CANTSET, FAIL, "can't set object access arguments") + + /* Rename the attribute */ + if (H5A__rename_common(*vol_obj_ptr, &loc_params, old_name, new_name, token_ptr) < 0) + HGOTO_ERROR(H5E_ATTR, H5E_CANTRENAME, FAIL, "can't rename attribute") + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* H5A__rename_api_common() */ + /*------------------------------------------------------------------------- * Function: H5Arename * * Purpose: Rename an attribute * - * Return: SUCCEED/FAIL + * Return: Success: Non-negative + * Failure: Negative * * Programmer: Raymond Lu * October 23, 2002 @@ -1160,9 +1617,78 @@ H5Arename(hid_t loc_id, const char *old_name, const char *new_name) FUNC_ENTER_API(FAIL) H5TRACE3("e", "i*s*s", loc_id, old_name, new_name); - /* check arguments */ + /* Synchronously rename the attribute */ + if (H5A__rename_api_common(loc_id, old_name, new_name, NULL, NULL) < 0) + HGOTO_ERROR(H5E_ATTR, H5E_CANTRENAME, FAIL, "can't synchronously rename attribute") + +done: + FUNC_LEAVE_API(ret_value) +} /* H5Arename() */ + +/*-------------------------------------------------------------------------- + * NAME + * H5Arename_async + * PURPOSE + * Asynchronous version of H5Arename + * RETURNS + * Non-negative on success/Negative on failure + *--------------------------------------------------------------------------*/ +herr_t +H5Arename_async(const char *app_file, const char *app_func, unsigned app_line, hid_t loc_id, + const char *old_name, const char *new_name, hid_t es_id) +{ + H5VL_object_t *vol_obj = NULL; /* Object for loc_id */ + void * token = NULL; /* Request token for async operation */ + void ** token_ptr = H5_REQUEST_NULL; /* Pointer to request token for async operation */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_API(FAIL) + H5TRACE7("e", "*s*sIui*s*si", app_file, app_func, app_line, loc_id, old_name, new_name, es_id); + + /* Set up request token pointer for asynchronous operation */ + if (H5ES_NONE != es_id) + token_ptr = &token; /* Point at token for VOL connector to set up */ + + /* Asynchronously rename the attribute */ + if (H5A__rename_api_common(loc_id, old_name, new_name, token_ptr, &vol_obj) < 0) + HGOTO_ERROR(H5E_ATTR, H5E_CANTRENAME, FAIL, "can't asynchronously rename attribute") + + /* If a token was created, add the token to the event set */ + if (NULL != token) + /* clang-format off */ + if (H5ES_insert(es_id, vol_obj->connector, token, + H5ARG_TRACE7(FUNC, "*s*sIui*s*si", app_file, app_func, app_line, loc_id, old_name, new_name, es_id)) < 0) + /* clang-format on */ + HGOTO_ERROR(H5E_ATTR, H5E_CANTINSERT, FAIL, "can't insert token into event set") + +done: + FUNC_LEAVE_API(ret_value) +} /* H5Arename_async() */ + +/*-------------------------------------------------------------------------- + NAME + H5A__rename_by_name_api_common + PURPOSE + Common helper routine for sync/async attribute rename operations + RETURNS + Non-negative on success/Negative on failure +--------------------------------------------------------------------------*/ +static herr_t +H5A__rename_by_name_api_common(hid_t loc_id, const char *obj_name, const char *old_name, const char *new_name, + hid_t lapl_id, void **token_ptr, H5VL_object_t **_vol_obj_ptr) +{ + H5VL_object_t * tmp_vol_obj = NULL; /* Object for loc_id */ + H5VL_object_t **vol_obj_ptr = + (_vol_obj_ptr ? _vol_obj_ptr : &tmp_vol_obj); /* Ptr to object ptr for loc_id */ + H5VL_loc_params_t loc_params; /* Location parameters for object access */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_STATIC + + /* Check arguments */ if (H5I_ATTR == H5I_get_type(loc_id)) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "location is not valid for an attribute") + if (!old_name) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "old attribute name cannot be NULL") if (!*old_name) @@ -1172,38 +1698,26 @@ H5Arename(hid_t loc_id, const char *old_name, const char *new_name) if (!*new_name) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "new attribute name cannot be an empty string") - /* Avoid thrashing things if the names are the same */ - if (HDstrcmp(old_name, new_name)) { - H5VL_object_t * vol_obj; - H5VL_loc_params_t loc_params; - - loc_params.type = H5VL_OBJECT_BY_SELF; - loc_params.obj_type = H5I_get_type(loc_id); - - /* Get the location object */ - if (NULL == (vol_obj = H5VL_vol_object(loc_id))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid location identifier") + /* obj_name is verified in H5VL_setup_name_args() */ + /* Set up object access arguments */ + if (H5VL_setup_name_args(loc_id, obj_name, H5P_CLS_LACC, TRUE, lapl_id, vol_obj_ptr, &loc_params) < 0) + HGOTO_ERROR(H5E_ATTR, H5E_CANTSET, FAIL, "can't set object access arguments") - /* Set up collective metadata if appropriate */ - if (H5CX_set_loc(loc_id) < 0) - HGOTO_ERROR(H5E_ATTR, H5E_CANTSET, FAIL, "can't set collective metadata read") - - /* Rename the attribute */ - if (H5VL_attr_specific(vol_obj, &loc_params, H5VL_ATTR_RENAME, H5P_DATASET_XFER_DEFAULT, - H5_REQUEST_NULL, old_name, new_name) < 0) - HGOTO_ERROR(H5E_ATTR, H5E_CANTRENAME, FAIL, "can't rename attribute") - } /* end if */ + /* Rename the attribute */ + if (H5A__rename_common(*vol_obj_ptr, &loc_params, old_name, new_name, token_ptr) < 0) + HGOTO_ERROR(H5E_ATTR, H5E_CANTRENAME, FAIL, "can't rename attribute") done: - FUNC_LEAVE_API(ret_value) -} /* H5Arename() */ + FUNC_LEAVE_NOAPI(ret_value) +} /* H5A__rename_by_name_api_common() */ /*------------------------------------------------------------------------- * Function: H5Arename_by_name * * Purpose: Rename an attribute * - * Return: SUCCEED/FAIL + * Return: Success: Non-negative + * Failure: Negative * * Programmer: Quincey Koziol * February 20, 2007 @@ -1219,43 +1733,57 @@ H5Arename_by_name(hid_t loc_id, const char *obj_name, const char *old_attr_name, FUNC_ENTER_API(FAIL) H5TRACE5("e", "i*s*s*si", loc_id, obj_name, old_attr_name, new_attr_name, lapl_id); - /* check arguments */ - if (H5I_ATTR == H5I_get_type(loc_id)) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "location is not valid for an attribute") - if (!obj_name || !*obj_name) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no object name") - if (!old_attr_name || !*old_attr_name) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no old attribute name") - if (!new_attr_name || !*new_attr_name) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no new attribute name") - - /* Avoid thrashing things if the names are the same */ - if (HDstrcmp(old_attr_name, new_attr_name)) { - H5VL_object_t * vol_obj; - H5VL_loc_params_t loc_params; - - /* Verify access property list and set up collective metadata if appropriate */ - if (H5CX_set_apl(&lapl_id, H5P_CLS_LACC, loc_id, TRUE) < 0) - HGOTO_ERROR(H5E_ATTR, H5E_CANTSET, FAIL, "can't set access property list info") + /* Synchronously rename the attribute */ + if (H5A__rename_by_name_api_common(loc_id, obj_name, old_attr_name, new_attr_name, lapl_id, NULL, NULL) < + 0) + HGOTO_ERROR(H5E_ATTR, H5E_CANTRENAME, FAIL, "can't synchronously rename attribute") - loc_params.type = H5VL_OBJECT_BY_NAME; - loc_params.loc_data.loc_by_name.name = obj_name; - loc_params.loc_data.loc_by_name.lapl_id = lapl_id; - loc_params.obj_type = H5I_get_type(loc_id); +done: + FUNC_LEAVE_API(ret_value) +} /* H5Arename_by_name() */ - /* Get the location object */ - if (NULL == (vol_obj = H5VL_vol_object(loc_id))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid location identifier") +/*-------------------------------------------------------------------------- + * NAME + * H5Arename_by_name_async + * PURPOSE + * Asynchronous version of H5Arename_by_name + * RETURNS + * Non-negative on success/Negative on failure + *--------------------------------------------------------------------------*/ +herr_t +H5Arename_by_name_async(const char *app_file, const char *app_func, unsigned app_line, hid_t loc_id, + const char *obj_name, const char *old_attr_name, const char *new_attr_name, + hid_t lapl_id, hid_t es_id) +{ + H5VL_object_t *vol_obj = NULL; /* Object for loc_id */ + void * token = NULL; /* Request token for async operation */ + void ** token_ptr = H5_REQUEST_NULL; /* Pointer to request token for async operation */ + herr_t ret_value = SUCCEED; /* Return value */ - /* Rename the attribute */ - if (H5VL_attr_specific(vol_obj, &loc_params, H5VL_ATTR_RENAME, H5P_DATASET_XFER_DEFAULT, - H5_REQUEST_NULL, old_attr_name, new_attr_name) < 0) - HGOTO_ERROR(H5E_ATTR, H5E_CANTRENAME, FAIL, "can't rename attribute") - } /* end if */ + FUNC_ENTER_API(FAIL) + H5TRACE9("e", "*s*sIui*s*s*sii", app_file, app_func, app_line, loc_id, obj_name, old_attr_name, + new_attr_name, lapl_id, es_id); + + /* Set up request token pointer for asynchronous operation */ + if (H5ES_NONE != es_id) + token_ptr = &token; /* Point at token for VOL connector to set up */ + + /* Asynchronously rename the attribute */ + if (H5A__rename_by_name_api_common(loc_id, obj_name, old_attr_name, new_attr_name, lapl_id, token_ptr, + &vol_obj) < 0) + HGOTO_ERROR(H5E_ATTR, H5E_CANTRENAME, FAIL, "can't synchronously rename attribute") + + /* If a token was created, add the token to the event set */ + if (NULL != token) + /* clang-format off */ + if (H5ES_insert(es_id, vol_obj->connector, token, + H5ARG_TRACE9(FUNC, "*s*sIui*s*s*sii", app_file, app_func, app_line, loc_id, obj_name, old_attr_name, new_attr_name, lapl_id, es_id)) < 0) + /* clang-format on */ + HGOTO_ERROR(H5E_ATTR, H5E_CANTINSERT, FAIL, "can't insert token into event set") done: FUNC_LEAVE_API(ret_value) -} /* H5Arename_by_name() */ +} /* H5Arename_by_name_async() */ /*-------------------------------------------------------------------------- NAME @@ -1299,8 +1827,8 @@ done: attribute. --------------------------------------------------------------------------*/ herr_t -H5Aiterate2(hid_t loc_id, H5_index_t idx_type, H5_iter_order_t order, hsize_t *idx, H5A_operator2_t op, - void *op_data) +H5Aiterate2(hid_t loc_id, H5_index_t idx_type, H5_iter_order_t order, hsize_t *idx /*in,out */, + H5A_operator2_t op, void *op_data) { H5VL_object_t * vol_obj = NULL; /* object of loc_id */ H5VL_loc_params_t loc_params; @@ -1378,16 +1906,16 @@ done: --------------------------------------------------------------------------*/ herr_t H5Aiterate_by_name(hid_t loc_id, const char *obj_name, H5_index_t idx_type, H5_iter_order_t order, - hsize_t *idx, H5A_operator2_t op, void *op_data, hid_t lapl_id) + hsize_t *idx /*in,out */, H5A_operator2_t op, void *op_data, hid_t lapl_id) { - H5VL_object_t * vol_obj = NULL; /* object of loc_id */ + H5VL_object_t * vol_obj = NULL; /* Object location */ H5VL_loc_params_t loc_params; herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API(FAIL) H5TRACE8("e", "i*sIiIo*hAO*xi", loc_id, obj_name, idx_type, order, idx, op, op_data, lapl_id); - /* check arguments */ + /* Check arguments */ if (H5I_ATTR == H5I_get_type(loc_id)) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "location is not valid for an attribute") if (!obj_name || !*obj_name) @@ -1590,7 +2118,7 @@ H5Adelete_by_idx(hid_t loc_id, const char *obj_name, H5_index_t idx_type, H5_ite if (NULL == (vol_obj = H5VL_vol_object(loc_id))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid object identifier") - /* Delete the attribute through the VOL */ + /* Delete the attribute */ if (H5VL_attr_specific(vol_obj, &loc_params, H5VL_ATTR_DELETE, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL, NULL) < 0) HGOTO_ERROR(H5E_ATTR, H5E_CANTDELETE, FAIL, "unable to delete attribute") @@ -1619,18 +2147,154 @@ H5Aclose(hid_t attr_id) H5TRACE1("e", "i", attr_id); /* Check arguments */ - if (NULL == H5I_object_verify(attr_id, H5I_ATTR)) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not an attribute") + if (H5I_ATTR != H5I_get_type(attr_id)) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not an attribute ID") - /* Decrement references to that atom (and close it) */ + /* Decrement the counter on the attribute ID. It will be freed if the count + * reaches zero. + */ if (H5I_dec_app_ref(attr_id) < 0) - HGOTO_ERROR(H5E_ATTR, H5E_CANTDEC, FAIL, "can't close attribute") + HGOTO_ERROR(H5E_ATTR, H5E_CANTDEC, FAIL, "decrementing attribute ID failed") done: FUNC_LEAVE_API(ret_value) } /* H5Aclose() */ /*------------------------------------------------------------------------- + * Function: H5Aclose_async + * + * Purpose: Asynchronous version of H5Aclose + * + * Return: SUCCEED/FAIL + * + *------------------------------------------------------------------------- + */ +herr_t +H5Aclose_async(const char *app_file, const char *app_func, unsigned app_line, hid_t attr_id, hid_t es_id) +{ + H5VL_object_t *vol_obj = NULL; /* Object for loc_id */ + H5VL_t * connector = NULL; /* VOL connector */ + void * token = NULL; /* Request token for async operation */ + void ** token_ptr = H5_REQUEST_NULL; /* Pointer to request token for async operation */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_API(FAIL) + H5TRACE5("e", "*s*sIuii", app_file, app_func, app_line, attr_id, es_id); + + /* Check arguments */ + if (H5I_ATTR != H5I_get_type(attr_id)) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a attribute ID") + + /* Prepare for possible asynchronous operation */ + if (H5ES_NONE != es_id) { + /* Get attribute object's connector */ + if (NULL == (vol_obj = H5VL_vol_object(attr_id))) + HGOTO_ERROR(H5E_ATTR, H5E_CANTGET, FAIL, "can't get VOL object for attribute") + + /* Increase connector's refcount, so it doesn't get closed if closing + * the attribute closes the file */ + connector = vol_obj->connector; + H5VL_conn_inc_rc(connector); + + /* Point at token for operation to set up */ + token_ptr = &token; + } /* end if */ + + /* Decrement the counter on the attribute ID. It will be freed if the count + * reaches zero. + */ + if (H5I_dec_app_ref_async(attr_id, token_ptr) < 0) + HGOTO_ERROR(H5E_ATTR, H5E_CANTDEC, FAIL, "decrementing attribute ID failed") + + /* If a token was created, add the token to the event set */ + if (NULL != token) + /* clang-format off */ + if (H5ES_insert(es_id, vol_obj->connector, token, + H5ARG_TRACE5(FUNC, "*s*sIuii", app_file, app_func, app_line, attr_id, es_id)) < 0) + /* clang-format on */ + HGOTO_ERROR(H5E_ATTR, H5E_CANTINSERT, FAIL, "can't insert token into event set") + +done: + if (connector && H5VL_conn_dec_rc(connector) < 0) + HDONE_ERROR(H5E_ATTR, H5E_CANTDEC, FAIL, "can't decrement ref count on connector") + + FUNC_LEAVE_API(ret_value) +} /* H5Aclose_async() */ + +/*-------------------------------------------------------------------------- + * NAME + * H5A__exists_common + * PURPOSE + * Common helper routine for sync/async check if an attribute exists + * RETURNS + * Non-negative on success/Negative on failure + *--------------------------------------------------------------------------*/ +static herr_t +H5A__exists_common(H5VL_object_t *vol_obj, H5VL_loc_params_t *loc_params, const char *attr_name, + hbool_t *attr_exists, void **token_ptr) +{ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_STATIC + + /* Sanity checks */ + HDassert(vol_obj); + HDassert(loc_params); + + /* Check arguments */ + if (!attr_name || !*attr_name) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no attribute name") + + /* Check if the attribute exists */ + if (H5VL_attr_specific(vol_obj, loc_params, H5VL_ATTR_EXISTS, H5P_DATASET_XFER_DEFAULT, token_ptr, + attr_name, attr_exists) < 0) + HGOTO_ERROR(H5E_ATTR, H5E_CANTGET, FAIL, "unable to determine if attribute exists") + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* H5A__exists_common() */ + +/*-------------------------------------------------------------------------- + * NAME + * H5A__exists_api_common + * PURPOSE + * Common helper routine for sync/async check if an attribute exists + * RETURNS + * Non-negative on success/Negative on failure + *--------------------------------------------------------------------------*/ +static herr_t +H5A__exists_api_common(hid_t obj_id, const char *attr_name, hbool_t *attr_exists, void **token_ptr, + H5VL_object_t **_vol_obj_ptr) +{ + H5VL_object_t * tmp_vol_obj = NULL; /* Object for loc_id */ + H5VL_object_t **vol_obj_ptr = + (_vol_obj_ptr ? _vol_obj_ptr : &tmp_vol_obj); /* Ptr to object ptr for loc_id */ + H5VL_loc_params_t loc_params; /* Location parameters for object access */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_STATIC + + /* Check arguments */ + if (H5I_ATTR == H5I_get_type(obj_id)) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "location is not valid for an attribute") + if (!attr_name || !*attr_name) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no attribute name") + if (NULL == attr_exists) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid pointer for attribute existence") + + /* Set up object access arguments */ + if (H5VL_setup_self_args(obj_id, vol_obj_ptr, &loc_params) < 0) + HGOTO_ERROR(H5E_ATTR, H5E_CANTSET, FAIL, "can't set object access arguments") + + /* Check if the attribute exists */ + if (H5A__exists_common(*vol_obj_ptr, &loc_params, attr_name, attr_exists, token_ptr) < 0) + HGOTO_ERROR(H5E_ATTR, H5E_CANTGET, FAIL, "unable to determine if attribute exists") + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* H5A__exists_api_common() */ + +/*------------------------------------------------------------------------- * Function: H5Aexists * * Purpose: Checks if an attribute with a given name exists on an opened @@ -1647,34 +2311,105 @@ done: htri_t H5Aexists(hid_t obj_id, const char *attr_name) { - H5VL_object_t * vol_obj; - H5VL_loc_params_t loc_params; - htri_t ret_value; /* Return value */ + hbool_t exists; /* Flag for attribute existance */ + htri_t ret_value = FAIL; /* Return value */ FUNC_ENTER_API(FAIL) H5TRACE2("t", "i*s", obj_id, attr_name); + /* Synchronously check if an attribute exists */ + exists = FALSE; + if (H5A__exists_api_common(obj_id, attr_name, &exists, NULL, NULL) < 0) + HGOTO_ERROR(H5E_ATTR, H5E_CANTRENAME, FAIL, "can't synchronously rename attribute") + + /* Set return value */ + ret_value = (htri_t)exists; + +done: + FUNC_LEAVE_API(ret_value) +} /* H5Aexists() */ + +/*-------------------------------------------------------------------------- + * NAME + * H5Aexists_async + * PURPOSE + * Asynchronous version of H5Aexists + * RETURNS + * Non-negative on success/Negative on failure + *--------------------------------------------------------------------------*/ +herr_t +H5Aexists_async(const char *app_file, const char *app_func, unsigned app_line, hid_t obj_id, + const char *attr_name, hbool_t *attr_exists, hid_t es_id) +{ + H5VL_object_t *vol_obj = NULL; /* Object for loc_id */ + void * token = NULL; /* Request token for async operation */ + void ** token_ptr = H5_REQUEST_NULL; /* Pointer to request token for async operation */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_API(FAIL) + H5TRACE7("e", "*s*sIui*s*bi", app_file, app_func, app_line, obj_id, attr_name, attr_exists, es_id); + + /* Set up request token pointer for asynchronous operation */ + if (H5ES_NONE != es_id) + token_ptr = &token; /* Point at token for VOL connector to set up */ + + /* Asynchronously check if an attribute exists */ + if (H5A__exists_api_common(obj_id, attr_name, attr_exists, token_ptr, &vol_obj) < 0) + HGOTO_ERROR(H5E_ATTR, H5E_CANTRENAME, FAIL, "can't asynchronously check if attribute exists") + + /* If a token was created, add the token to the event set */ + if (NULL != token) + /* clang-format off */ + if (H5ES_insert(es_id, vol_obj->connector, token, + H5ARG_TRACE7(FUNC, "*s*sIui*s*bi", app_file, app_func, app_line, obj_id, attr_name, attr_exists, es_id)) < 0) + /* clang-format on */ + HGOTO_ERROR(H5E_ATTR, H5E_CANTINSERT, FAIL, "can't insert token into event set") + +done: + FUNC_LEAVE_API(ret_value) +} /* H5Aexists_async() */ + +/*-------------------------------------------------------------------------- + * NAME + * H5A__exists_by_name_api_common + * PURPOSE + * Common helper routine for sync/async check if an attribute exists + * RETURNS + * Non-negative on success/Negative on failure + *--------------------------------------------------------------------------*/ +static herr_t +H5A__exists_by_name_api_common(hid_t loc_id, const char *obj_name, const char *attr_name, + hbool_t *attr_exists, hid_t lapl_id, void **token_ptr, + H5VL_object_t **_vol_obj_ptr) +{ + H5VL_object_t * tmp_vol_obj = NULL; /* Object for loc_id */ + H5VL_object_t **vol_obj_ptr = + (_vol_obj_ptr ? _vol_obj_ptr : &tmp_vol_obj); /* Ptr to object ptr for loc_id */ + H5VL_loc_params_t loc_params; /* Location parameters for object access */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_STATIC + /* Check arguments */ - if (H5I_ATTR == H5I_get_type(obj_id)) + if (H5I_ATTR == H5I_get_type(loc_id)) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "location is not valid for an attribute") if (!attr_name || !*attr_name) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no attribute name") + if (NULL == attr_exists) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid pointer for attribute existence") - /* get the object */ - if (NULL == (vol_obj = H5VL_vol_object(obj_id))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid object identifier") - - loc_params.type = H5VL_OBJECT_BY_SELF; - loc_params.obj_type = H5I_get_type(obj_id); + /* obj_name is verified in H5VL_setup_name_args() */ + /* Set up object access arguments */ + if (H5VL_setup_name_args(loc_id, obj_name, H5P_CLS_LACC, FALSE, lapl_id, vol_obj_ptr, &loc_params) < 0) + HGOTO_ERROR(H5E_ATTR, H5E_CANTSET, FAIL, "can't set object access arguments") /* Check if the attribute exists */ - if (H5VL_attr_specific(vol_obj, &loc_params, H5VL_ATTR_EXISTS, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL, - attr_name, &ret_value) < 0) + if (H5A__exists_common(*vol_obj_ptr, &loc_params, attr_name, attr_exists, token_ptr) < 0) HGOTO_ERROR(H5E_ATTR, H5E_CANTGET, FAIL, "unable to determine if attribute exists") done: - FUNC_LEAVE_API(ret_value) -} /* H5Aexists() */ + FUNC_LEAVE_NOAPI(ret_value) +} /* H5A__exists_by_name_api_common() */ /*------------------------------------------------------------------------- * Function: H5Aexists_by_name @@ -1682,7 +2417,7 @@ done: * Purpose: Checks if an attribute with a given name exists on an object. * * Return: Success: TRUE/FALSE - * Failure: Negative + * Failure: Negative * * Programmer: Quincey Koziol * Thursday, November 1, 2007 @@ -1692,39 +2427,63 @@ done: htri_t H5Aexists_by_name(hid_t loc_id, const char *obj_name, const char *attr_name, hid_t lapl_id) { - H5VL_object_t * vol_obj; - H5VL_loc_params_t loc_params; - htri_t ret_value; /* Return value */ + hbool_t exists; /* Flag for attribute existance */ + htri_t ret_value = FAIL; /* Return value */ FUNC_ENTER_API(FAIL) H5TRACE4("t", "i*s*si", loc_id, obj_name, attr_name, lapl_id); - /* check arguments */ - if (H5I_ATTR == H5I_get_type(loc_id)) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "location is not valid for an attribute") - if (!obj_name || !*obj_name) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no object name") - if (!attr_name || !*attr_name) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no attribute name") + /* Synchronously check if an attribute exists */ + exists = FALSE; + if (H5A__exists_by_name_api_common(loc_id, obj_name, attr_name, &exists, lapl_id, NULL, NULL) < 0) + HGOTO_ERROR(H5E_ATTR, H5E_CANTRENAME, FAIL, "can't synchronously rename attribute") - /* Verify access property list and set up collective metadata if appropriate */ - if (H5CX_set_apl(&lapl_id, H5P_CLS_LACC, loc_id, FALSE) < 0) - HGOTO_ERROR(H5E_ATTR, H5E_CANTSET, FAIL, "can't set access property list info") + /* Set return value */ + ret_value = (htri_t)exists; - /* get the object */ - if (NULL == (vol_obj = H5VL_vol_object(loc_id))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid object identifier") +done: + FUNC_LEAVE_API(ret_value) +} /* H5Aexists_by_name() */ - loc_params.type = H5VL_OBJECT_BY_NAME; - loc_params.loc_data.loc_by_name.name = obj_name; - loc_params.loc_data.loc_by_name.lapl_id = lapl_id; - loc_params.obj_type = H5I_get_type(loc_id); +/*-------------------------------------------------------------------------- + * NAME + * H5Aexists_by_name_async + * PURPOSE + * Asynchronous version of H5Aexists_by_name + * RETURNS + * Non-negative on success/Negative on failure + *--------------------------------------------------------------------------*/ +herr_t +H5Aexists_by_name_async(const char *app_file, const char *app_func, unsigned app_line, hid_t loc_id, + const char *obj_name, const char *attr_name, hbool_t *attr_exists, hid_t lapl_id, + hid_t es_id) +{ + H5VL_object_t *vol_obj = NULL; /* Object for loc_id */ + void * token = NULL; /* Request token for async operation */ + void ** token_ptr = H5_REQUEST_NULL; /* Pointer to request token for async operation */ + herr_t ret_value = SUCCEED; /* Return value */ - /* Check existence of attribute */ - if (H5VL_attr_specific(vol_obj, &loc_params, H5VL_ATTR_EXISTS, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL, - attr_name, &ret_value) < 0) - HGOTO_ERROR(H5E_ATTR, H5E_CANTGET, FAIL, "unable to determine if attribute exists") + FUNC_ENTER_API(FAIL) + H5TRACE9("e", "*s*sIui*s*s*bii", app_file, app_func, app_line, loc_id, obj_name, attr_name, attr_exists, + lapl_id, es_id); + + /* Set up request token pointer for asynchronous operation */ + if (H5ES_NONE != es_id) + token_ptr = &token; /* Point at token for VOL connector to set up */ + + /* Asynchronously check if an attribute exists */ + if (H5A__exists_by_name_api_common(loc_id, obj_name, attr_name, attr_exists, lapl_id, token_ptr, + &vol_obj) < 0) + HGOTO_ERROR(H5E_ATTR, H5E_CANTRENAME, FAIL, "can't asynchronously rename attribute") + + /* If a token was created, add the token to the event set */ + if (NULL != token) + /* clang-format off */ + if (H5ES_insert(es_id, vol_obj->connector, token, + H5ARG_TRACE9(FUNC, "*s*sIui*s*s*bii", app_file, app_func, app_line, loc_id, obj_name, attr_name, attr_exists, lapl_id, es_id)) < 0) + /* clang-format on */ + HGOTO_ERROR(H5E_ATTR, H5E_CANTINSERT, FAIL, "can't insert token into event set") done: FUNC_LEAVE_API(ret_value) -} /* H5Aexists_by_name() */ +} /* H5Aexists_by_name_async() */ diff --git a/src/H5ACprivate.h b/src/H5ACprivate.h index e320f72..e85f90c 100644 --- a/src/H5ACprivate.h +++ b/src/H5ACprivate.h @@ -222,80 +222,89 @@ typedef struct H5AC_proxy_entry_t { /* Default cache configuration. */ #define H5AC__DEFAULT_METADATA_WRITE_STRATEGY H5AC_METADATA_WRITE_STRATEGY__DISTRIBUTED +/* clang-format off */ #ifdef H5_HAVE_PARALLEL -#define H5AC__DEFAULT_CACHE_CONFIG \ - { \ - /* int version = */ H5AC__CURR_CACHE_CONFIG_VERSION, \ - /* hbool_t rpt_fcn_enabled = */ FALSE, \ - /* hbool_t open_trace_file = */ FALSE, \ - /* hbool_t close_trace_file = */ FALSE, /* char trace_file_name[] = */ "", \ - /* hbool_t evictions_enabled = */ TRUE, \ - /* hbool_t set_initial_size = */ TRUE, \ - /* size_t initial_size = */ (2 * 1024 * 1024), \ - /* double min_clean_fraction = */ 0.3f, \ - /* size_t max_size = */ (32 * 1024 * 1024), \ - /* size_t min_size = */ (1 * 1024 * 1024), \ - /* long int epoch_length = */ 50000, \ - /* enum H5C_cache_incr_mode incr_mode = */ H5C_incr__threshold, \ - /* double lower_hr_threshold = */ 0.9f, \ - /* double increment = */ 2.0f, \ - /* hbool_t apply_max_increment = */ TRUE, \ - /* size_t max_increment = */ (4 * 1024 * 1024), /* enum H5C_cache_flash_incr_mode \ - */ \ - /* flash_incr_mode = */ H5C_flash_incr__add_space, \ - /* double flash_multiple = */ 1.0f, \ - /* double flash_threshold = */ 0.25f, \ - /* enum H5C_cache_decr_mode decr_mode = */ H5C_decr__age_out_with_threshold, \ - /* double upper_hr_threshold = */ 0.999f, \ - /* double decrement = */ 0.9f, \ - /* hbool_t apply_max_decrement = */ TRUE, \ - /* size_t max_decrement = */ (1 * 1024 * 1024), \ - /* int epochs_before_eviction = */ 3, /* hbool_t apply_empty_reserve = */ TRUE, \ - /* double empty_reserve = */ 0.1f, \ - /* size_t dirty_bytes_threshold = */ (256 * 1024), /* int metadata_write_strategy = */ \ - H5AC__DEFAULT_METADATA_WRITE_STRATEGY \ - } +#define H5AC__DEFAULT_CACHE_CONFIG \ +{ \ + /* int version = */ H5AC__CURR_CACHE_CONFIG_VERSION, \ + /* hbool_t rpt_fcn_enabled = */ FALSE, \ + /* hbool_t open_trace_file = */ FALSE, \ + /* hbool_t close_trace_file = */ FALSE, \ + /* char trace_file_name[] = */ "", \ + /* hbool_t evictions_enabled = */ TRUE, \ + /* hbool_t set_initial_size = */ TRUE, \ + /* size_t initial_size = */ ( 2 * 1024 * 1024), \ + /* double min_clean_fraction = */ 0.3f, \ + /* size_t max_size = */ (32 * 1024 * 1024), \ + /* size_t min_size = */ (1 * 1024 * 1024), \ + /* long int epoch_length = */ 50000, \ + /* enum H5C_cache_incr_mode incr_mode = */ H5C_incr__threshold, \ + /* double lower_hr_threshold = */ 0.9f, \ + /* double increment = */ 2.0f, \ + /* hbool_t apply_max_increment = */ TRUE, \ + /* size_t max_increment = */ (4 * 1024 * 1024), \ + /* enum H5C_cache_flash_incr_mode */ \ + /* flash_incr_mode = */ H5C_flash_incr__add_space, \ + /* double flash_multiple = */ 1.0f, \ + /* double flash_threshold = */ 0.25f, \ + /* enum H5C_cache_decr_mode decr_mode = */ H5C_decr__age_out_with_threshold, \ + /* double upper_hr_threshold = */ 0.999f, \ + /* double decrement = */ 0.9f, \ + /* hbool_t apply_max_decrement = */ TRUE, \ + /* size_t max_decrement = */ (1 * 1024 * 1024), \ + /* int epochs_before_eviction = */ 3, \ + /* hbool_t apply_empty_reserve = */ TRUE, \ + /* double empty_reserve = */ 0.1f, \ + /* size_t dirty_bytes_threshold = */ (256 * 1024), \ + /* int metadata_write_strategy = */ \ + H5AC__DEFAULT_METADATA_WRITE_STRATEGY \ +} #else /* H5_HAVE_PARALLEL */ -#define H5AC__DEFAULT_CACHE_CONFIG \ - { \ - /* int version = */ H5C__CURR_AUTO_SIZE_CTL_VER, \ - /* hbool_t rpt_fcn_enabled = */ FALSE, \ - /* hbool_t open_trace_file = */ FALSE, \ - /* hbool_t close_trace_file = */ FALSE, /* char trace_file_name[] = */ "", \ - /* hbool_t evictions_enabled = */ TRUE, \ - /* hbool_t set_initial_size = */ TRUE, \ - /* size_t initial_size = */ (2 * 1024 * 1024), \ - /* double min_clean_fraction = */ 0.01f, \ - /* size_t max_size = */ (32 * 1024 * 1024), \ - /* size_t min_size = */ (1 * 1024 * 1024), \ - /* long int epoch_length = */ 50000, \ - /* enum H5C_cache_incr_mode incr_mode = */ H5C_incr__threshold, \ - /* double lower_hr_threshold = */ 0.9f, \ - /* double increment = */ 2.0f, \ - /* hbool_t apply_max_increment = */ TRUE, \ - /* size_t max_increment = */ (4 * 1024 * 1024), /* enum H5C_cache_flash_incr_mode \ - */ \ - /* flash_incr_mode = */ H5C_flash_incr__add_space, \ - /* double flash_multiple = */ 1.4f, \ - /* double flash_threshold = */ 0.25f, \ - /* enum H5C_cache_decr_mode decr_mode = */ H5C_decr__age_out_with_threshold, \ - /* double upper_hr_threshold = */ 0.999f, \ - /* double decrement = */ 0.9f, \ - /* hbool_t apply_max_decrement = */ TRUE, \ - /* size_t max_decrement = */ (1 * 1024 * 1024), \ - /* int epochs_before_eviction = */ 3, /* hbool_t apply_empty_reserve = */ TRUE, \ - /* double empty_reserve = */ 0.1f, \ - /* size_t dirty_bytes_threshold = */ (256 * 1024), /* int metadata_write_strategy = */ \ - H5AC__DEFAULT_METADATA_WRITE_STRATEGY \ - } +#define H5AC__DEFAULT_CACHE_CONFIG \ +{ \ + /* int version = */ H5C__CURR_AUTO_SIZE_CTL_VER, \ + /* hbool_t rpt_fcn_enabled = */ FALSE, \ + /* hbool_t open_trace_file = */ FALSE, \ + /* hbool_t close_trace_file = */ FALSE, \ + /* char trace_file_name[] = */ "", \ + /* hbool_t evictions_enabled = */ TRUE, \ + /* hbool_t set_initial_size = */ TRUE, \ + /* size_t initial_size = */ ( 2 * 1024 * 1024), \ + /* double min_clean_fraction = */ 0.01f, \ + /* size_t max_size = */ (32 * 1024 * 1024), \ + /* size_t min_size = */ ( 1 * 1024 * 1024), \ + /* long int epoch_length = */ 50000, \ + /* enum H5C_cache_incr_mode incr_mode = */ H5C_incr__threshold, \ + /* double lower_hr_threshold = */ 0.9f, \ + /* double increment = */ 2.0f, \ + /* hbool_t apply_max_increment = */ TRUE, \ + /* size_t max_increment = */ (4 * 1024 * 1024), \ + /* enum H5C_cache_flash_incr_mode */ \ + /* flash_incr_mode = */ H5C_flash_incr__add_space, \ + /* double flash_multiple = */ 1.4f, \ + /* double flash_threshold = */ 0.25f, \ + /* enum H5C_cache_decr_mode decr_mode = */ H5C_decr__age_out_with_threshold,\ + /* double upper_hr_threshold = */ 0.999f, \ + /* double decrement = */ 0.9f, \ + /* hbool_t apply_max_decrement = */ TRUE, \ + /* size_t max_decrement = */ (1 * 1024 * 1024), \ + /* int epochs_before_eviction = */ 3, \ + /* hbool_t apply_empty_reserve = */ TRUE, \ + /* double empty_reserve = */ 0.1f, \ + /* size_t dirty_bytes_threshold = */ (256 * 1024), \ + /* int metadata_write_strategy = */ \ + H5AC__DEFAULT_METADATA_WRITE_STRATEGY \ +} #endif /* H5_HAVE_PARALLEL */ -#define H5AC__DEFAULT_CACHE_IMAGE_CONFIG \ - { \ - /* int32_t version = */ H5AC__CURR_CACHE_IMAGE_CONFIG_VERSION, \ - /* hbool_t generate_image = */ FALSE, /* hbool_t save_resize_status = */ FALSE, \ - /* int32_t entry_ageout = */ H5AC__CACHE_IMAGE__ENTRY_AGEOUT__NONE \ - } +#define H5AC__DEFAULT_CACHE_IMAGE_CONFIG \ +{ \ + /* int32_t version = */ H5AC__CURR_CACHE_IMAGE_CONFIG_VERSION, \ + /* hbool_t generate_image = */ FALSE, \ + /* hbool_t save_resize_status = */ FALSE, \ + /* int32_t entry_ageout = */ H5AC__CACHE_IMAGE__ENTRY_AGEOUT__NONE \ +} +/* clang-format on */ /* * Library prototypes. */ diff --git a/src/H5ACpublic.h b/src/H5ACpublic.h index e6cebff..f8f4f28 100644 --- a/src/H5ACpublic.h +++ b/src/H5ACpublic.h @@ -442,124 +442,347 @@ extern "C" { #define H5AC_METADATA_WRITE_STRATEGY__PROCESS_0_ONLY 0 #define H5AC_METADATA_WRITE_STRATEGY__DISTRIBUTED 1 +/** + * H5AC_cache_config_t is a public structure intended for use in public APIs. + * At least in its initial incarnation, it is basically a copy of \c struct + * \c H5C_auto_size_ctl_t, minus the \c report_fcn field, and plus the + * \c dirty_bytes_threshold field. + * + * The \c report_fcn field is omitted, as including it would require us to make + * \c H5C_t structure public. + * + * The \c dirty_bytes_threshold field does not appear in \c H5C_auto_size_ctl_t, + * as synchronization between caches on different processes is handled at the \c + * H5AC level, not at the level of \c H5C. Note however that there is + * considerable interaction between this value and the other fields in this + * structure. + * + * Similarly, the \c open_trace_file, \c close_trace_file, and \c + * trace_file_name fields do not appear in \c H5C_auto_size_ctl_t, as most trace + * file issues are handled at the \c H5AC level. The one exception is storage + * of the pointer to the trace file, which is handled by \c H5C. + * + * The structure is in H5ACpublic.h as we may wish to allow different + * configuration options for metadata and raw data caches. + */ + +//! <!-- [H5AC_cache_config_t_snip] --> typedef struct H5AC_cache_config_t { /* general configuration fields: */ + //! <!-- [H5AC_cache_config_t_general_snip] --> int version; + /**< Integer field indicating the the version of the H5AC_cache_config_t + * in use. This field should be set to #H5AC__CURR_CACHE_CONFIG_VERSION + * (defined in H5ACpublic.h). */ hbool_t rpt_fcn_enabled; + /**< Boolean flag indicating whether the adaptive cache resize report + * function is enabled. This field should almost always be set to disabled + * (0). Since resize algorithm activity is reported via stdout, it MUST be + * set to disabled (0) on Windows machines.\n + * The report function is not supported code, and can be expected to change + * between versions of the library. Use it at your own risk. */ hbool_t open_trace_file; + /**< Boolean field indicating whether the + * \ref H5AC_cache_config_t.trace_file_name "trace_file_name" + * field should be used to open a trace file for the cache.\n + * The trace file is a debugging feature that allows the capture + * of top level metadata cache requests for purposes of debugging + * and/or optimization. This field should normally be set to 0, as + * trace file collection imposes considerable overhead.\n + * This field should only be set to 1 when the + * \ref H5AC_cache_config_t.trace_file_name "trace_file_name" + * contains the full path of the desired trace file, and either + * there is no open trace file on the cache, or the + * \ref H5AC_cache_config_t.close_trace_file "close_trace_file" + * field is also 1.\n + * The trace file feature is unsupported unless used at the + * direction of The HDF Group. It is intended to allow The HDF + * Group to collect a trace of cache activity in cases of occult + * failures and/or poor performance seen in the field, so as to aid + * in reproduction in the lab. If you use it absent the direction + * of The HDF Group, you are on your own. */ + hbool_t close_trace_file; - char trace_file_name[H5AC__MAX_TRACE_FILE_NAME_LEN + 1]; + /**< Boolean field indicating whether the current trace file + *(if any) should be closed.\n + * See the above comments on the \ref H5AC_cache_config_t.open_trace_file + * "open_trace_file" field. This field should be set to 0 unless there is + * an open trace file on the cache that you wish to close.\n + * The trace file feature is unsupported unless used at the direction of + * The HDF Group. It is intended to allow The HDF Group to collect a trace + * of cache activity in cases of occult failures and/or poor performance + * seen in the field, so as to aid in reproduction in the lab. If you use + * it absent the direction of The HDF Group, you are on your own. */ + + char trace_file_name[H5AC__MAX_TRACE_FILE_NAME_LEN + 1]; + /**< Full path of the trace file to be opened if the + * \ref H5AC_cache_config_t.open_trace_file "open_trace_file" field is set + * to 1.\n + * In the parallel case, an ascii representation of the MPI rank of the + * process will be appended to the file name to yield a unique trace file + * name for each process.\n + * The length of the path must not exceed #H5AC__MAX_TRACE_FILE_NAME_LEN + * characters.\n + * The trace file feature is unsupported unless used at the direction of + * The HDF Group. It is intended to allow The HDF Group to collect a trace + * of cache activity in cases of occult failures and/or poor performance + * seen in the field, so as to aid in reproduction in the lab. If you use + * it absent the direction of The HDF Group, you are on your own. */ hbool_t evictions_enabled; + /**< A boolean flag indicating whether evictions from the metadata cache + * are enabled. This flag is initially set to enabled (1).\n + * In rare circumstances, the raw data throughput quirements may be so high + * that the user wishes to postpone metadata writes so as to reserve I/O + * throughput for raw data. The \p evictions_enabled field exists to allow + * this. However, this is an extreme step, and you have no business doing + * it unless you have read the User Guide section on metadata caching, and + * have considered all other options carefully.\n + * The \p evictions_enabled field may not be set to disabled (0) + * unless all adaptive cache resizing code is disabled via the + * \ref H5AC_cache_config_t.incr_mode "incr_mode", + * \ref H5AC_cache_config_t.flash_incr_mode "flash_incr_mode", + * \ref H5AC_cache_config_t.decr_mode "decr_mode" fields.\n + * When this flag is set to disabled (\c 0), the metadata cache will not + * attempt to evict entries to make space for new entries, and thus will + * grow without bound.\n + * Evictions will be re-enabled when this field is set back to \c 1. + * This should be done as soon as possible. */ hbool_t set_initial_size; - size_t initial_size; + /**< Boolean flag indicating whether the cache should be created + * with a user specified initial size. */ + + size_t initial_size; + /**< If \ref H5AC_cache_config_t.set_initial_size "set_initial_size" + * is set to 1, \p initial_size must contain he desired initial size in + * bytes. This value must lie in the closed interval + * [ \p min_size, \p max_size ]. (see below) */ double min_clean_fraction; + /**< This field specifies the minimum fraction of the cache + * that must be kept either clean or empty.\n + * The value must lie in the interval [0.0, 1.0]. 0.01 is a good place to + * start in the serial case. In the parallel case, a larger value is needed + * -- see the overview of the metadata cache in the + * “Metadata Caching in HDF5” section of the -- <em>HDF5 User’s Guide</em> + * for details. */ size_t max_size; + /**< Upper bound (in bytes) on the range of values that the + * adaptive cache resize code can select as the maximum cache size. */ + size_t min_size; + /**< Lower bound (in bytes) on the range of values that the + * adaptive cache resize code can select as the mininum cache * size. */ long int epoch_length; + /**< Number of cache accesses between runs of the adaptive cache resize + * code. 50,000 is a good starting number. */ + //! <!-- [H5AC_cache_config_t_general_snip] --> /* size increase control fields: */ + //! <!-- [H5AC_cache_config_t_incr_snip] --> enum H5C_cache_incr_mode incr_mode; + /**< Enumerated value indicating the operational mode of the automatic + * cache size increase code. At present, only two values listed in + * #H5C_cache_incr_mode are legal. */ double lower_hr_threshold; + /**< Hit rate threshold used by the hit rate threshold cache size + * increment algorithm.\n + * When the hit rate over an epoch is below this threshold and the cache + * is full, the maximum size of the cache is multiplied by increment + * (below), and then clipped as necessary to stay within \p max_size, and + * possibly \p max_increment.\n + * This field must lie in the interval [0.0, 1.0]. 0.8 or 0.9 is a good + * place to start. */ double increment; + /**< Factor by which the hit rate threshold cache size increment + * algorithm multiplies the current cache max size to obtain a tentative + * new cache size.\n + * The actual cache size increase will be clipped to satisfy the \p max_size + * specified in the general configuration, and possibly max_increment + * below.\n + * The parameter must be greater than or equal to 1.0 -- 2.0 is a reasonable + * value.\n + * If you set it to 1.0, you will effectively disable cache size increases. + */ hbool_t apply_max_increment; - size_t max_increment; + /**< Boolean flag indicating whether an upper limit should be applied to + * the size of cache size increases. */ + + size_t max_increment; + /**< Maximum number of bytes by which cache size can be increased in a + * single step -- if applicable. */ enum H5C_cache_flash_incr_mode flash_incr_mode; - double flash_multiple; - double flash_threshold; + /**< Enumerated value indicating the operational mode of the flash cache + * size increase code. At present, only two listed values in + * #H5C_cache_flash_incr_mode are legal.*/ + + double flash_multiple; + /**< The factor by which the size of the triggering entry / entry size + * increase is multiplied to obtain the initial cache size increment. This + * increment may be reduced to reflect existing free space in the cache and + * the \p max_size field above.\n + * The parameter must lie in the interval [0.0, 1.0]. 0.1 or 0.05 is a good + * place to start.\n + * At present, this field must lie in the range [0.1, 10.0]. */ + + double flash_threshold; + /**< The factor by which the current maximum cache size is multiplied to + * obtain the minimum size entry / entry size increase which may trigger a + * flash cache size increase. \n + * At present, this value must lie in the range [0.1, 1.0]. */ + //! <!-- [H5AC_cache_config_t_incr_snip] --> /* size decrease control fields: */ + //! <!-- [H5AC_cache_config_t_decr_snip] --> enum H5C_cache_decr_mode decr_mode; + /**< Enumerated value indicating the operational mode of the tomatic + * cache size decrease code. At present, the values listed in + * #H5C_cache_decr_mode are legal.*/ double upper_hr_threshold; + /**< Hit rate threshold for the hit rate threshold and ageout with hit + * rate threshold cache size decrement algorithms.\n + * When \p decr_mode is #H5C_decr__threshold, and the hit rate over a given + * epoch exceeds the supplied threshold, the current maximum cache + * size is multiplied by decrement to obtain a tentative new (and smaller) + * maximum cache size.\n + * When \p decr_mode is #H5C_decr__age_out_with_threshold, there is + * no attempt to find and evict aged out entries unless the hit rate in + * the previous epoch exceeded the supplied threshold.\n + * This field must lie in the interval [0.0, 1.0].\n + * For #H5C_incr__threshold, .9995 or .99995 is a good place to start.\n + * For #H5C_decr__age_out_with_threshold, .999 might be more useful.*/ double decrement; + /**< In the hit rate threshold cache size decrease algorithm, this + * parameter contains the factor by which the current max cache size is + * multiplied to produce a tentative new cache size.\n + * The actual cache size decrease will be clipped to satisfy the + * \ref H5AC_cache_config_t.min_size "min_size" specified in the general + * configuration, and possibly \ref H5AC_cache_config_t.max_decrement + * "max_decrement".\n + * The parameter must be be in the interval [0.0, 1.0].\n + * If you set it to 1.0, you will effectively + * disable cache size decreases. 0.9 is a reasonable starting point. */ hbool_t apply_max_decrement; - size_t max_decrement; + /**< Boolean flag indicating ether an upper limit should be applied to + * the size of cache size decreases. */ + + size_t max_decrement; + /**< Maximum number of bytes by which the maximum cache size can be + * decreased in any single step -- if applicable.*/ int epochs_before_eviction; + /**< In the ageout based cache size reduction algorithms, this field + * contains the minimum number of epochs an entry must remain unaccessed in + * cache before the cache size reduction algorithm tries to evict it. 3 is a + * reasonable value. */ hbool_t apply_empty_reserve; - double empty_reserve; + /**< Boolean flag indicating whether the ageout based decrement + * algorithms will maintain a empty reserve when decreasing cache size. */ + + double empty_reserve; + /**< Empty reserve as a fraction maximum cache size if applicable.\n When + * so directed, the ageout based algorithms will not decrease the maximum + * cache size unless the empty reserve can be met.\n The parameter must lie + * in the interval [0.0, 1.0]. 0.1 or 0.05 is a good place to start. */ + //! <!-- [H5AC_cache_config_t_decr_snip] --> /* parallel configuration fields: */ + //! <!-- [H5AC_cache_config_t_parallel_snip] --> size_t dirty_bytes_threshold; - int metadata_write_strategy; - + /**< Threshold number of bytes of dirty metadata generation for + * triggering synchronizations of the metadata caches serving the target + * file in the parallel case.\n Synchronization occurs whenever the number + * of bytes of dirty metadata created since the last synchronization exceeds + * this limit.\n This field only applies to the parallel case. While it is + * ignored elsewhere, it can still draw a value out of bounds error.\n It + * must be consistant across all caches on any given file.\n By default, + * this field is set to 256 KB. It shouldn't be more than half the current + * max cache size times the min clean fraction. */ + + int metadata_write_strategy; + /**< Desired metadata write strategy. The valid values for this field + * are:\n #H5AC_METADATA_WRITE_STRATEGY__PROCESS_0_ONLY: Specifies tha only + * process zero is allowed to write dirty metadata to disk.\n + * #H5AC_METADATA_WRITE_STRATEGY__DISTRIBUTED: Specifies that process zero + * still makes the decisions as to what entries should be flushed, but the + * actual flushes are distributed across the processes in the computation to + * the extent possible.\n The src/H5ACpublic.h include file in the HDF5 + * library has detailed information on each strategy. */ + //! <!-- [H5AC_cache_config_t_parallel_snip] --> } H5AC_cache_config_t; - -/**************************************************************************** - * - * structure H5AC_cache_image_config_t - * - * H5AC_cache_image_ctl_t is a public structure intended for use in public - * APIs. At least in its initial incarnation, it is a copy of struct - * H5C_cache_image_ctl_t. - * - * The fields of the structure are discussed individually below: - * - * version: Integer field containing the version number of this version - * of the H5C_image_ctl_t structure. Any instance of - * H5C_image_ctl_t passed to the cache must have a known - * version number, or an error will be flagged. - * - * generate_image: Boolean flag indicating whether a cache image should - * be created on file close. - * - * save_resize_status: Boolean flag indicating whether the cache image - * should include the adaptive cache resize configuration and status. - * Note that this field is ignored at present. - * - * entry_ageout: Integer field indicating the maximum number of - * times a prefetched entry can appear in subsequent cache images. - * This field exists to allow the user to avoid the buildup of - * infrequently used entries in long sequences of cache images. - * - * The value of this field must lie in the range - * H5AC__CACHE_IMAGE__ENTRY_AGEOUT__NONE (-1) to - * H5AC__CACHE_IMAGE__ENTRY_AGEOUT__MAX (100). - * - * H5AC__CACHE_IMAGE__ENTRY_AGEOUT__NONE means that no limit - * is imposed on number of times a prefeteched entry can appear - * in subsequent cache images. - * - * A value of 0 prevents prefetched entries from being included - * in cache images. - * - * Positive integers restrict prefetched entries to the specified - * number of appearances. - * - * Note that the number of subsequent cache images that a prefetched - * entry has appeared in is tracked in an 8 bit field. Thus, while - * H5AC__CACHE_IMAGE__ENTRY_AGEOUT__MAX can be increased from its - * current value, any value in excess of 255 will be the functional - * equivalent of H5AC__CACHE_IMAGE__ENTRY_AGEOUT__NONE. - * - ****************************************************************************/ +//! <!-- [H5AC_cache_config_t_snip] --> #define H5AC__CURR_CACHE_IMAGE_CONFIG_VERSION 1 #define H5AC__CACHE_IMAGE__ENTRY_AGEOUT__NONE -1 #define H5AC__CACHE_IMAGE__ENTRY_AGEOUT__MAX 100 +//! <!-- [H5AC_cache_image_config_t_snip] --> +/** + * H5AC_cache_image_config_t is a public structure intended for use in public + * APIs. At least in its initial incarnation, it is a copy of \c struct \c + * H5C_cache_image_ctl_t. + */ + typedef struct H5AC_cache_image_config_t { - int version; + int version; + /**< Integer field containing the version number of this version of the \c + * H5C_image_ctl_t structure. Any instance of \c H5C_image_ctl_t passed + * to the cache must have a known version number, or an error will be + * flagged. + */ hbool_t generate_image; + /**< Boolean flag indicating whether a cache image should be created on file + * close. + */ hbool_t save_resize_status; - int entry_ageout; + /**< Boolean flag indicating whether the cache image should include the + * adaptive cache resize configuration and status. Note that this field + * is ignored at present. + */ + int entry_ageout; + /**< Integer field indicating the maximum number of times a + * prefetched entry can appear in subsequent cache images. This field + * exists to allow the user to avoid the buildup of infrequently used + * entries in long sequences of cache images. + * + * The value of this field must lie in the range \ref + * H5AC__CACHE_IMAGE__ENTRY_AGEOUT__NONE (-1) to \ref + * H5AC__CACHE_IMAGE__ENTRY_AGEOUT__MAX (100). + * + * \ref H5AC__CACHE_IMAGE__ENTRY_AGEOUT__NONE means that no limit is + * imposed on number of times a prefeteched entry can appear in subsequent + * cache images. + * + * A value of 0 prevents prefetched entries from being included in cache + * images. + * + * Positive integers restrict prefetched entries to the specified number + * of appearances. + * + * Note that the number of subsequent cache images that a prefetched entry + * has appeared in is tracked in an 8 bit field. Thus, while \ref + * H5AC__CACHE_IMAGE__ENTRY_AGEOUT__MAX can be increased from its current + * value, any value in excess of 255 will be the functional equivalent of + * \ref H5AC__CACHE_IMAGE__ENTRY_AGEOUT__NONE. + */ } H5AC_cache_image_config_t; +//! <!-- [H5AC_cache_image_config_t_snip] --> + #ifdef __cplusplus } #endif diff --git a/src/H5Adense.c b/src/H5Adense.c index 1575f3c..b0d793c 100644 --- a/src/H5Adense.c +++ b/src/H5Adense.c @@ -338,7 +338,7 @@ H5A__dense_open(H5F_t *f, const H5O_ainfo_t *ainfo, const char *name) H5HF_t * shared_fheap = NULL; /* Fractal heap handle for shared header messages */ H5B2_t * bt2_name = NULL; /* v2 B-tree handle for name index */ htri_t attr_sharable; /* Flag indicating attributes are sharable */ - htri_t attr_exists; /* Attribute exists in v2 B-tree */ + hbool_t attr_exists; /* Attribute exists in v2 B-tree */ H5A_t * ret_value = NULL; /* Return value */ FUNC_ENTER_PACKAGE @@ -388,9 +388,10 @@ H5A__dense_open(H5F_t *f, const H5O_ainfo_t *ainfo, const char *name) udata.found_op_data = &ret_value; /* Find & copy the attribute in the 'name' index */ - if ((attr_exists = H5B2_find(bt2_name, &udata, NULL, NULL)) < 0) + attr_exists = FALSE; + if (H5B2_find(bt2_name, &udata, &attr_exists, NULL, NULL) < 0) HGOTO_ERROR(H5E_ATTR, H5E_NOTFOUND, NULL, "can't search for attribute in name index") - else if (attr_exists == FALSE) + if (attr_exists == FALSE) HGOTO_ERROR(H5E_ATTR, H5E_NOTFOUND, NULL, "can't locate attribute in name index") done: @@ -866,7 +867,7 @@ H5A__dense_rename(H5F_t *f, const H5O_ainfo_t *ainfo, const char *old_name, cons H5A_t * attr_copy = NULL; /* Copy of attribute to rename */ htri_t attr_sharable; /* Flag indicating attributes are sharable */ htri_t shared_mesg; /* Should this message be stored in the Shared Message table? */ - htri_t attr_exists; /* Attribute exists in v2 B-tree */ + hbool_t attr_exists; /* Attribute exists in v2 B-tree */ herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_PACKAGE @@ -917,9 +918,10 @@ H5A__dense_rename(H5F_t *f, const H5O_ainfo_t *ainfo, const char *old_name, cons udata.found_op_data = &attr_copy; /* Get copy of attribute through 'name' tracking v2 B-tree */ - if ((attr_exists = H5B2_find(bt2_name, &udata, NULL, NULL)) < 0) + attr_exists = FALSE; + if (H5B2_find(bt2_name, &udata, &attr_exists, NULL, NULL) < 0) HGOTO_ERROR(H5E_ATTR, H5E_NOTFOUND, FAIL, "can't search for attribute in name index") - else if (attr_exists == FALSE) + if (attr_exists == FALSE) HGOTO_ERROR(H5E_ATTR, H5E_NOTFOUND, FAIL, "can't locate attribute in name index") HDassert(attr_copy); @@ -942,7 +944,7 @@ H5A__dense_rename(H5F_t *f, const H5O_ainfo_t *ainfo, const char *old_name, cons /* Need to remove the attribute from the creation order index v2 B-tree */ if (ainfo->index_corder) { - htri_t corder_attr_exists; /* Attribute exists in v2 B-tree */ + hbool_t corder_attr_exists; /* Attribute exists in v2 B-tree */ /* Open the creation order index v2 B-tree */ HDassert(H5F_addr_defined(ainfo->corder_bt2_addr)); @@ -952,7 +954,8 @@ H5A__dense_rename(H5F_t *f, const H5O_ainfo_t *ainfo, const char *old_name, cons /* Set up the creation order to search for */ udata.corder = attr_copy->shared->crt_idx; - if ((corder_attr_exists = H5B2_find(bt2_corder, &udata, NULL, NULL)) < 0) + corder_attr_exists = FALSE; + if (H5B2_find(bt2_corder, &udata, &corder_attr_exists, NULL, NULL) < 0) HGOTO_ERROR(H5E_ATTR, H5E_NOTFOUND, FAIL, "can't search for attribute in name index") if (corder_attr_exists) { @@ -1665,15 +1668,15 @@ done: * *------------------------------------------------------------------------- */ -htri_t -H5A__dense_exists(H5F_t *f, const H5O_ainfo_t *ainfo, const char *name) +herr_t +H5A__dense_exists(H5F_t *f, const H5O_ainfo_t *ainfo, const char *name, hbool_t *attr_exists) { H5A_bt2_ud_common_t udata; /* User data for v2 B-tree modify */ H5HF_t * fheap = NULL; /* Fractal heap handle */ H5HF_t * shared_fheap = NULL; /* Fractal heap handle for shared header messages */ H5B2_t * bt2_name = NULL; /* v2 B-tree handle for name index */ htri_t attr_sharable; /* Flag indicating attributes are sharable */ - htri_t ret_value = TRUE; /* Return value */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_PACKAGE @@ -1681,6 +1684,7 @@ H5A__dense_exists(H5F_t *f, const H5O_ainfo_t *ainfo, const char *name) HDassert(f); HDassert(ainfo); HDassert(name); + HDassert(attr_exists); /* Open the fractal heap */ if (NULL == (fheap = H5HF_open(f, ainfo->fheap_addr))) @@ -1722,7 +1726,7 @@ H5A__dense_exists(H5F_t *f, const H5O_ainfo_t *ainfo, const char *name) udata.found_op_data = NULL; /* Find the attribute in the 'name' index */ - if ((ret_value = H5B2_find(bt2_name, &udata, NULL, NULL)) < 0) + if (H5B2_find(bt2_name, &udata, attr_exists, NULL, NULL) < 0) HGOTO_ERROR(H5E_ATTR, H5E_NOTFOUND, FAIL, "can't search for attribute in name index") done: diff --git a/src/H5Aint.c b/src/H5Aint.c index 9bbf031..8ec5463 100644 --- a/src/H5Aint.c +++ b/src/H5Aint.c @@ -83,6 +83,7 @@ typedef struct { /* Local Prototypes */ /********************/ +static herr_t H5A__close_cb(H5VL_object_t *attr_vol_obj, void **request); static herr_t H5A__compact_build_table_cb(H5O_t *oh, H5O_mesg_t *mesg /*in,out*/, unsigned sequence, unsigned *oh_flags_ptr, void *_udata /*in,out*/); static herr_t H5A__dense_build_table_cb(const H5A_t *attr, void *_udata); @@ -98,6 +99,9 @@ static herr_t H5A__iterate_common(hid_t loc_id, H5_index_t idx_type, H5_iter_ord /* Package Variables */ /*********************/ +/* Package initialization variable */ +hbool_t H5_PKG_INIT_VAR = FALSE; + /* Format version bounds for attribute */ const unsigned H5O_attr_ver_bounds[] = { H5O_ATTR_VERSION_1, /* H5F_LIBVER_EARLIEST */ @@ -115,8 +119,162 @@ const unsigned H5O_attr_ver_bounds[] = { /* Local Variables */ /*******************/ +/* Declare the free lists of H5A_t */ +H5FL_DEFINE(H5A_t); + +/* Declare the free lists for H5A_shared_t's */ +H5FL_DEFINE(H5A_shared_t); + +/* Declare a free list to manage blocks of type conversion data */ +H5FL_BLK_DEFINE(attr_buf); + typedef H5A_t *H5A_t_ptr; -H5FL_SEQ_DEFINE(H5A_t_ptr); +H5FL_SEQ_DEFINE_STATIC(H5A_t_ptr); + +/* Attribute ID class */ +static const H5I_class_t H5I_ATTR_CLS[1] = {{ + H5I_ATTR, /* ID class value */ + 0, /* Class flags */ + 0, /* # of reserved IDs for class */ + (H5I_free_t)H5A__close_cb /* Callback routine for closing objects of this class */ +}}; + +/* Flag indicating "top" of interface has been initialized */ +static hbool_t H5A_top_package_initialize_s = FALSE; + +/*------------------------------------------------------------------------- + * Function: H5A_init + * + * Purpose: Initialize the interface from some other layer. + * + * Return: Success: non-negative + * + * Failure: negative + *------------------------------------------------------------------------- + */ +herr_t +H5A_init(void) +{ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI(FAIL) + /* FUNC_ENTER() does all the work */ + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5A_init() */ + +/*-------------------------------------------------------------------------- +NAME + H5A__init_package -- Initialize interface-specific information +USAGE + herr_t H5A__init_package() + +RETURNS + Non-negative on success/Negative on failure +DESCRIPTION + Initializes any interface-specific data or routines. + +--------------------------------------------------------------------------*/ +herr_t +H5A__init_package(void) +{ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_PACKAGE + + /* + * Create attribute ID type. + */ + if (H5I_register_type(H5I_ATTR_CLS) < 0) + HGOTO_ERROR(H5E_ATTR, H5E_CANTINIT, FAIL, "unable to initialize interface") + + /* Mark "top" of interface as initialized, too */ + H5A_top_package_initialize_s = TRUE; + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5A__init_package() */ + +/*-------------------------------------------------------------------------- + NAME + H5A_top_term_package + PURPOSE + Terminate various H5A objects + USAGE + void H5A_top_term_package() + RETURNS + DESCRIPTION + Release IDs for the atom group, deferring full interface shutdown + until later (in H5A_term_package). + GLOBAL VARIABLES + COMMENTS, BUGS, ASSUMPTIONS + Can't report errors... + EXAMPLES + REVISION LOG +--------------------------------------------------------------------------*/ +int +H5A_top_term_package(void) +{ + int n = 0; + + FUNC_ENTER_NOAPI_NOINIT_NOERR + + if (H5A_top_package_initialize_s) { + if (H5I_nmembers(H5I_ATTR) > 0) { + (void)H5I_clear_type(H5I_ATTR, FALSE, FALSE); + n++; /*H5I*/ + } /* end if */ + + /* Mark closed */ + if (0 == n) + H5A_top_package_initialize_s = FALSE; + } /* end if */ + + FUNC_LEAVE_NOAPI(n) +} /* H5A_top_term_package() */ + +/*-------------------------------------------------------------------------- + NAME + H5A_term_package + PURPOSE + Terminate various H5A objects + USAGE + void H5A_term_package() + RETURNS + DESCRIPTION + Release any other resources allocated. + GLOBAL VARIABLES + COMMENTS, BUGS, ASSUMPTIONS + Can't report errors... + + Finishes shutting down the interface, after H5A_top_term_package() + is called + EXAMPLES + REVISION LOG +--------------------------------------------------------------------------*/ +int +H5A_term_package(void) +{ + int n = 0; + + FUNC_ENTER_NOAPI_NOINIT_NOERR + + if (H5_PKG_INIT_VAR) { + /* Sanity checks */ + HDassert(0 == H5I_nmembers(H5I_ATTR)); + HDassert(FALSE == H5A_top_package_initialize_s); + + /* Destroy the attribute object id group */ + n += (H5I_dec_type_ref(H5I_ATTR) > 0); + + /* Mark closed */ + if (0 == n) + H5_PKG_INIT_VAR = FALSE; + } /* end if */ + + FUNC_LEAVE_NOAPI(n) +} /* H5A_term_package() */ /*------------------------------------------------------------------------- * Function: H5A__create @@ -136,7 +294,7 @@ H5A__create(const H5G_loc_t *loc, const char *attr_name, const H5T_t *type, cons H5A_t * attr = NULL; /* Attribute created */ hssize_t snelmts; /* elements in attribute */ size_t nelmts; /* elements in attribute */ - htri_t exists; /* Whether attribute exists */ + hbool_t exists; /* Whether attribute exists */ H5A_t * ret_value = NULL; /* Return value */ FUNC_ENTER_PACKAGE_TAG(loc->oloc->addr) @@ -152,9 +310,10 @@ H5A__create(const H5G_loc_t *loc, const char *attr_name, const H5T_t *type, cons * name, but it's going to be hard to unwind all the special cases on * failure, so just check first, for now - QAK) */ - if ((exists = H5O__attr_exists(loc->oloc, attr_name)) < 0) + exists = FALSE; + if (H5O__attr_exists(loc->oloc, attr_name, &exists) < 0) HGOTO_ERROR(H5E_ATTR, H5E_NOTFOUND, NULL, "error checking attributes") - else if (exists > 0) + if (exists) HGOTO_ERROR(H5E_ATTR, H5E_ALREADYEXISTS, NULL, "attribute already exists") /* Check if the dataspace has an extent set (or is NULL) */ @@ -356,12 +515,12 @@ done: * *------------------------------------------------------------------------- */ -herr_t +static herr_t H5A__open_common(const H5G_loc_t *loc, H5A_t *attr) { herr_t ret_value = SUCCEED; /* Return value */ - FUNC_ENTER_PACKAGE + FUNC_ENTER_STATIC /* check args */ HDassert(loc); @@ -1134,18 +1293,18 @@ H5A__shared_free(H5A_t *attr) * *------------------------------------------------------------------------- */ -herr_t -H5A__close_cb(H5VL_object_t *attr_vol_obj) +static herr_t +H5A__close_cb(H5VL_object_t *attr_vol_obj, void **request) { herr_t ret_value = SUCCEED; /* Return value */ - FUNC_ENTER_PACKAGE + FUNC_ENTER_STATIC /* Sanity check */ HDassert(attr_vol_obj); /* Close the attribute */ - if ((ret_value = H5VL_attr_close(attr_vol_obj, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL)) < 0) + if ((ret_value = H5VL_attr_close(attr_vol_obj, H5P_DATASET_XFER_DEFAULT, request)) < 0) HGOTO_ERROR(H5E_ATTR, H5E_CLOSEERROR, FAIL, "problem closing attribute") /* Free the VOL object */ @@ -1309,17 +1468,22 @@ done: * *------------------------------------------------------------------------- */ -htri_t -H5A__exists_by_name(H5G_loc_t loc, const char *obj_name, const char *attr_name) +herr_t +H5A__exists_by_name(H5G_loc_t loc, const char *obj_name, const char *attr_name, hbool_t *attr_exists) { - H5G_loc_t obj_loc; /* Location used to open group */ - H5G_name_t obj_path; /* Opened object group hier. path */ - H5O_loc_t obj_oloc; /* Opened object object location */ - hbool_t loc_found = FALSE; /* Entry at 'obj_name' found */ - htri_t ret_value = FAIL; /* Return value */ + H5G_loc_t obj_loc; /* Location used to open group */ + H5G_name_t obj_path; /* Opened object group hier. path */ + H5O_loc_t obj_oloc; /* Opened object object location */ + hbool_t loc_found = FALSE; /* Entry at 'obj_name' found */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_PACKAGE + /* Sanity check */ + HDassert(obj_name); + HDassert(attr_name); + HDassert(attr_exists); + /* Set up opened group location to fill in */ obj_loc.oloc = &obj_oloc; obj_loc.path = &obj_path; @@ -1331,7 +1495,7 @@ H5A__exists_by_name(H5G_loc_t loc, const char *obj_name, const char *attr_name) loc_found = TRUE; /* Check if the attribute exists */ - if ((ret_value = H5O__attr_exists(obj_loc.oloc, attr_name)) < 0) + if (H5O__attr_exists(obj_loc.oloc, attr_name, attr_exists) < 0) HGOTO_ERROR(H5E_ATTR, H5E_CANTGET, FAIL, "unable to determine if attribute exists") done: diff --git a/src/H5Apkg.h b/src/H5Apkg.h index da6eb0a..a349f9f 100644 --- a/src/H5Apkg.h +++ b/src/H5Apkg.h @@ -185,14 +185,12 @@ H5_DLL H5A_t *H5A__open(const H5G_loc_t *loc, const char *attr_name); H5_DLL H5A_t *H5A__open_by_name(const H5G_loc_t *loc, const char *obj_name, const char *attr_name); H5_DLL H5A_t *H5A__open_by_idx(const H5G_loc_t *loc, const char *obj_name, H5_index_t idx_type, H5_iter_order_t order, hsize_t n); -H5_DLL herr_t H5A__open_common(const H5G_loc_t *loc, H5A_t *attr); H5_DLL H5A_t *H5A__copy(H5A_t *new_attr, const H5A_t *old_attr); H5_DLL hid_t H5A__get_type(H5A_t *attr); H5_DLL herr_t H5A__get_info(const H5A_t *attr, H5A_info_t *ainfo); H5_DLL hid_t H5A__get_create_plist(H5A_t *attr); H5_DLL herr_t H5A__shared_free(H5A_t *attr); H5_DLL herr_t H5A__close(H5A_t *attr); -H5_DLL herr_t H5A__close_cb(H5VL_object_t *attr_vol_obj); H5_DLL htri_t H5A__get_ainfo(H5F_t *f, H5O_t *oh, H5O_ainfo_t *ainfo); H5_DLL herr_t H5A__set_version(const H5F_t *f, H5A_t *attr); H5_DLL herr_t H5A__rename_by_name(H5G_loc_t loc, const char *obj_name, const char *old_attr_name, @@ -205,7 +203,8 @@ H5_DLL herr_t H5A__iterate_old(hid_t loc_id, unsigned *attr_num, H5A_operator1_t H5_DLL herr_t H5A__delete_by_name(const H5G_loc_t *loc, const char *obj_name, const char *attr_name); H5_DLL herr_t H5A__delete_by_idx(const H5G_loc_t *loc, const char *obj_name, H5_index_t idx_type, H5_iter_order_t order, hsize_t n); -H5_DLL htri_t H5A__exists_by_name(H5G_loc_t loc, const char *obj_name, const char *attr_name); +H5_DLL herr_t H5A__exists_by_name(H5G_loc_t loc, const char *obj_name, const char *attr_name, + hbool_t *attr_exists); H5_DLL herr_t H5A__write(H5A_t *attr, const H5T_t *mem_type, const void *buf); H5_DLL herr_t H5A__read(const H5A_t *attr, const H5T_t *mem_type, void *buf); H5_DLL ssize_t H5A__get_name(H5A_t *attr, size_t buf_size, char *buf); @@ -223,7 +222,7 @@ H5_DLL herr_t H5A__dense_iterate(H5F_t *f, hid_t loc_id, const H5O_ainfo_t *ainf H5_DLL herr_t H5A__dense_remove(H5F_t *f, const H5O_ainfo_t *ainfo, const char *name); H5_DLL herr_t H5A__dense_remove_by_idx(H5F_t *f, const H5O_ainfo_t *ainfo, H5_index_t idx_type, H5_iter_order_t order, hsize_t n); -H5_DLL htri_t H5A__dense_exists(H5F_t *f, const H5O_ainfo_t *ainfo, const char *name); +H5_DLL herr_t H5A__dense_exists(H5F_t *f, const H5O_ainfo_t *ainfo, const char *name, hbool_t *attr_exists); H5_DLL herr_t H5A__dense_delete(H5F_t *f, H5O_ainfo_t *ainfo); /* Attribute table operations */ @@ -248,10 +247,7 @@ H5_DLL herr_t H5O__attr_iterate(hid_t loc_id, H5_index_t idx_type, H5_iter_order H5_DLL herr_t H5O__attr_remove(const H5O_loc_t *loc, const char *name); H5_DLL herr_t H5O__attr_remove_by_idx(const H5O_loc_t *loc, H5_index_t idx_type, H5_iter_order_t order, hsize_t n); -H5_DLL htri_t H5O__attr_exists(const H5O_loc_t *loc, const char *name); -#ifndef H5_NO_DEPRECATED_SYMBOLS -H5_DLL int H5O__attr_count(const H5O_loc_t *loc); -#endif /* H5_NO_DEPRECATED_SYMBOLS */ +H5_DLL herr_t H5O__attr_exists(const H5O_loc_t *loc, const char *name, hbool_t *attr_exists); H5_DLL H5A_t *H5A__attr_copy_file(const H5A_t *attr_src, H5F_t *file_dst, hbool_t *recompute_size, H5O_copy_t *cpy_info); H5_DLL herr_t H5A__attr_post_copy_file(const H5O_loc_t *src_oloc, const H5A_t *mesg_src, H5O_loc_t *dst_oloc, diff --git a/src/H5Apublic.h b/src/H5Apublic.h index 6ec9144..b3da77f 100644 --- a/src/H5Apublic.h +++ b/src/H5Apublic.h @@ -68,45 +68,1071 @@ typedef herr_t (*H5A_operator2_t)(hid_t location_id /*in*/, const char *attr_nam extern "C" { #endif -H5_DLL hid_t H5Acreate2(hid_t loc_id, const char *attr_name, hid_t type_id, hid_t space_id, hid_t acpl_id, - hid_t aapl_id); -H5_DLL hid_t H5Acreate_by_name(hid_t loc_id, const char *obj_name, const char *attr_name, hid_t type_id, - hid_t space_id, hid_t acpl_id, hid_t aapl_id, hid_t lapl_id); -H5_DLL hid_t H5Aopen(hid_t obj_id, const char *attr_name, hid_t aapl_id); -H5_DLL hid_t H5Aopen_by_name(hid_t loc_id, const char *obj_name, const char *attr_name, hid_t aapl_id, - hid_t lapl_id); -H5_DLL hid_t H5Aopen_by_idx(hid_t loc_id, const char *obj_name, H5_index_t idx_type, H5_iter_order_t order, - hsize_t n, hid_t aapl_id, hid_t lapl_id); -H5_DLL herr_t H5Awrite(hid_t attr_id, hid_t type_id, const void *buf); -H5_DLL herr_t H5Aread(hid_t attr_id, hid_t type_id, void *buf); -H5_DLL herr_t H5Aclose(hid_t attr_id); -H5_DLL hid_t H5Aget_space(hid_t attr_id); -H5_DLL hid_t H5Aget_type(hid_t attr_id); -H5_DLL hid_t H5Aget_create_plist(hid_t attr_id); +/*-------------------------------------------------------------------------*/ +/** + * \ingroup H5A + * + * \brief Closes the specified attribute + * + * \attr_id + * + * \return \herr_t + * + * \details H5Aclose() terminates access to the attribute specified by + * \p attr_id by releasing the identifier. + * + * \attention Further use of a released attribute identifier is illegal; a + * function using such an identifier will generate an error. + * + * \since 1.0.0 + * + * \see H5Acreate(), H5Aopen() + */ +H5_DLL herr_t H5Aclose(hid_t attr_id); +/*--------------------------------------------------------------------------*/ +/** + * \ingroup ASYNC + * \async_variant_of{H5Aclose} + */ +H5_DLL herr_t H5Aclose_async(const char *app_file, const char *app_func, unsigned app_line, hid_t attr_id, + hid_t es_id); +/* --------------------------------------------------------------------------*/ +/** + * \ingroup H5A + * + * \brief Creates an attribute attached to a specified object + * + * \fgdt_loc_id + * \param[in] attr_name Name of attribute + * \param[in] type_id Attribute datatype identifier + * \space_id + * \acpl_id + * \aapl_id + * + * \return \hid_tv{attribute} + * + * \details H5Acreate2() creates an attribute, \p attr_name, which is attached + * to the object specified by the identifier \p loc_id. + * + * The attribute name, \p attr_name, must be unique for the object. + * + * The attribute is created with the specified datatype and dataspace, + * \p type_id and \p space_id, which are created with the H5T and + * H5S interfaces, respectively. + * + * If \p type_id is either a fixed-length or variable-length string, + * it is important to set the string length when defining the + * datatype. String datatypes are derived from #H5T_C_S1 (or + * #H5T_FORTRAN_S1 for Fortran), which defaults to 1 character in + * size. See H5Tset_size() and Creating variable-length string + * datatypes. + * + * The access property list is currently unused, but will be used in + * the future. This property list should currently be #H5P_DEFAULT. + * + * The attribute identifier returned by this function must be released + * with H5Aclose() resource leaks will develop. + * + * \note The \p aapl parameter is currently not used; specify #H5P_DEFAULT. + * + * \note If \p loc_id is a file identifier, the attribute will be attached + * that file’s root group. + * + * \since 1.8.0 + * + * \see H5Aclose() + * + */ +H5_DLL hid_t H5Acreate2(hid_t loc_id, const char *attr_name, hid_t type_id, hid_t space_id, hid_t acpl_id, + hid_t aapl_id); +/*--------------------------------------------------------------------------*/ +/** + * \ingroup ASYNC + * \async_variant_of{H5Acreate} + */ +H5_DLL hid_t H5Acreate_async(const char *app_file, const char *app_func, unsigned app_line, hid_t loc_id, + const char *attr_name, hid_t type_id, hid_t space_id, hid_t acpl_id, + hid_t aapl_id, hid_t es_id); +/*--------------------------------------------------------------------------*/ +/** + * \ingroup H5A + * + * \brief Creates an attribute attached to a specified object + * + * \fgdt_loc_id + * \param[in] obj_name Name, relative to \p loc_id, of object that + * attribute is to be attached to + * \param[in] attr_name Attribute name + * \param[in] type_id Attribute datatype identifier + * \space_id + * \acpl_id + * \aapl_id + * \lapl_id + * + * \return \hid_tv{attribute} + * + * \details H5Acreate_by_name() creates an attribute, \p attr_name, which is + * attached to the object specified by \p loc_id and \p obj_name. + * + * \p loc_id is a location identifier; \p obj_name is the object + * name relative to \p loc_id. If \p loc_id fully specifies the + * object to which the attribute is to be attached, \p obj_name + * should be '.' (a dot). + * + * The attribute name, \p attr_name, must be unique for the object. + * + * The attribute is created with the specified datatype and + * dataspace, \p type_id and \p space_id, which are created with + * the H5T and H5S interfaces respectively. + * + * The attribute creation and access property lists are currently + * unused, but will be used in the future for optional attribute + * creation and access properties. These property lists should + * currently be #H5P_DEFAULT. + * + * The link access property list, \p lapl_id, may provide + * information regarding the properties of links required to access + * the object, \p obj_name. + * + * The attribute identifier returned by this function must be + * released with H5close() or resource leaks will develop. + * + * \since 1.8.0 + * + */ +H5_DLL hid_t H5Acreate_by_name(hid_t loc_id, const char *obj_name, const char *attr_name, hid_t type_id, + hid_t space_id, hid_t acpl_id, hid_t aapl_id, hid_t lapl_id); +/*--------------------------------------------------------------------------*/ +/** + * \ingroup ASYNC + * \async_variant_of{H5Acreate_by_name} + */ +H5_DLL hid_t H5Acreate_by_name_async(const char *app_file, const char *app_func, unsigned app_line, + hid_t loc_id, const char *obj_name, const char *attr_name, hid_t type_id, + hid_t space_id, hid_t acpl_id, hid_t aapl_id, hid_t lapl_id, + hid_t es_id); +/*-------------------------------------------------------------------------*/ +/** + * \ingroup H5A + * + * \brief Deletes an attribute from a specified location + * + * \fgdt_loc_id + * \param[in] attr_name Name of the attribute to delete + * + * \return \herr_t + * + * \details H5Adelete() removes the attribute specified by its name, + * \p attr_name, from a file, dataset, group, or named datatype. + * This function should not be used when attribute identifiers + * are open on \p loc_id as it may cause the internal indexes of + * the attributes to change and future writes to the open + * attributes to produce incorrect results. + * + * \since 1.0.0 + * + */ +H5_DLL herr_t H5Adelete(hid_t loc_id, const char *attr_name); +/*-------------------------------------------------------------------------*/ +/** + * \ingroup H5A + * + * \brief Deletes an attribute from an object according to index order + * + * \fgdt_loc_id + * \param[in] obj_name Name of object, relative to location, from which + * attribute is to be removed + * \param[in] idx_type Type of index + * \param[in] order Order in which to iterate over index + * \param[in] n Offset within index + * \lapl_id + * + * \return \herr_t + * + * \details H5Adelete_by_idx() removes an attribute, specified by its + * location in an index, from an object. + * + * The object from which the attribute is to be removed is + * specified by a location identifier and name, \p loc_id and + * \p obj_name, respectively. If \p loc_id fully specifies the + * object from which the attribute is to be removed, \p obj_name + * should be '.' (a dot). + * + * The attribute to be removed is specified by a position in an + * index, \p n. The type of index is specified by \p idx_type and + * may be #H5_INDEX_NAME, for an alpha-numeric index by name, or + * #H5_INDEX_CRT_ORDER, for an index by creation order. The order + * in which the index is to be traversed is specified by \p order + * and may be #H5_ITER_INC (increment) for top-down iteration, + * #H5_ITER_DEC (decrement) for bottom-up iteration, or + * #H5_ITER_NATIVE, in which case HDF5 will iterate in the + * fastest-available order. For example, if \p idx_type, \p order, + * and \p n are set to #H5_INDEX_NAME, #H5_ITER_INC, and 5, + * respectively, the fifth attribute by alpha-numeric order of + * attribute names will be removed. + * + * For a discussion of \p idx_type and \p order, the valid values + * of those parameters, and the use of \p n, see the description + * of H5Aiterate2(). + * + * The link access property list, \p lapl_id, may provide + * information regarding the properties of links required to access + * the object, \p obj_name. + + * \since 1.8.0 + * + */ +H5_DLL herr_t H5Adelete_by_idx(hid_t loc_id, const char *obj_name, H5_index_t idx_type, H5_iter_order_t order, + hsize_t n, hid_t lapl_id); +/*-------------------------------------------------------------------------*/ +/** + * \ingroup H5A + * + * \brief Removes an attribute from a specified location + * + * \fgdt_loc_id + * \param[in] obj_name Name of object, relative to location, from which + * attribute is to be removed + * \param[in] attr_name Name of attribute to delete + * \lapl_id + * + * \return \herr_t + * + * \details H5Adelete_by_name() removes the attribute \p attr_name + * from an object specified by location and name, \p loc_id and + * \p obj_name, respectively. + * + * If \p loc_id fully specifies the object from which the + * attribute is to be removed, \p obj_name should be '.' (a dot). + * + * The link access property list, \p lapl_id, may provide + * information regarding the properties of links required to + * access the object, \p obj_name. + * + * \since 1.8.0 + * + */ +H5_DLL herr_t H5Adelete_by_name(hid_t loc_id, const char *obj_name, const char *attr_name, hid_t lapl_id); +/*-------------------------------------------------------------------------*/ +/** + * \ingroup H5A + * + * \brief Determines whether an attribute with a given name exists on an + * object + * + * \fgdt_loc_id{obj_id} + * \param[in] attr_name Attribute name + * + * \return \htri_t + * + * \details H5Aexists() determines whether the attribute \p attr_name + * exists on the object specified by \p obj_id. + * + * \since 1.8.0 + * + */ +H5_DLL htri_t H5Aexists(hid_t obj_id, const char *attr_name); +/*--------------------------------------------------------------------------*/ +/** + * \ingroup ASYNC + * \async_variant_of{H5Aexists} + */ +H5_DLL herr_t H5Aexists_async(const char *app_file, const char *app_func, unsigned app_line, hid_t obj_id, + const char *attr_name, hbool_t *exists, hid_t es_id); +/*-------------------------------------------------------------------------*/ +/** + * \ingroup H5A + * + * \brief Determines whether an attribute with a given name exists on an + * object + * + * \fgdt_loc_id{obj_id} + * \param[in] obj_name Object name + * \param[in] attr_name Attribute name + * \lapl_id + * + * \return \htri_t + * + * \details H5Aexists_by_name() determines whether the attribute + * \p attr_name exists on an object. That object is specified by + * its location and name, \p loc_id and \p obj_name, respectively. + * + * \p loc_id specifies a location in the file containing the object. + * \p obj_name is the name of the object to which the attribute is + * attached and can be a relative name, relative to \p loc_id, + * or an absolute name, based in the root group of the file. If + * \p loc_id fully specifies the object, \p obj_name should be '.' + * (a dot). + * + * The link access property list, \p lapl_id, may provide + * information regarding the properties of links required to access + * \p obj_name. + * + * \since 1.8.0 + * + */ +H5_DLL htri_t H5Aexists_by_name(hid_t obj_id, const char *obj_name, const char *attr_name, hid_t lapl_id); +/*--------------------------------------------------------------------------*/ +/** + * \ingroup ASYNC + * \async_variant_of{H5Aexists_by_name} + */ +H5_DLL herr_t H5Aexists_by_name_async(const char *app_file, const char *app_func, unsigned app_line, + hid_t loc_id, const char *obj_name, const char *attr_name, + hbool_t *exists, hid_t lapl_id, hid_t es_id); +/*-------------------------------------------------------------------------*/ +/** + * \ingroup H5A + * + * \brief Gets an attribute creation property list identifier + * + * \attr_id + * + * \return \hid_tv{attribute's creation property list} + * + * \details H5Aget_create_plist() returns an identifier for the attribute + * creation property list associated with the attribute specified + * by \p attr_id. + * + * The creation property list identifier should be released with + * H5Pclose(). + * + * \since 1.8.0 + * + */ +H5_DLL hid_t H5Aget_create_plist(hid_t attr_id); +/*-------------------------------------------------------------------------*/ +/** + * \ingroup H5A + * + * \brief Retrieves attribute information, by attribute identifier + * + * \attr_id + * \param[out] ainfo Attribute information struct + * + * \return \herr_t + * + * \details H5Aget_info() retrieves attribute information, locating the + * attribute with an attribute identifier, \p attr_id, which is + * the identifier returned by H5Aopen() or H5Aopen_by_idx(). The + * attribute information is returned in the \p ainfo struct. + * + * The \p ainfo struct is defined as follows: + * \snippet this H5A_info_t_snip + * + * \p corder_valid indicates whether the creation order data is + * valid for this attribute. Note that if creation order is not + * being tracked, no creation order data will be valid. Valid + * values are \c TRUE and \c FALSE. + * + * \p corder is a positive integer containing the creation + * order of the attribute. This value is 0-based, so, for + * example, the third attribute created will have a \p corder + * value of 2. + * + * \p cset indicates the character set used for the attribute’s + * name; valid values are defined in H5Tpublic.h and include + * the following: + * \csets + * This value is set with H5Pset_char_encoding(). + * + * \p data_size indicates the size, in the number of characters, + * of the attribute. + * + * \since 1.8.0 + * + */ +H5_DLL herr_t H5Aget_info(hid_t attr_id, H5A_info_t *ainfo /*out*/); +/*-------------------------------------------------------------------------*/ +/** + * \ingroup H5A + * + * \brief Retrieves attribute information by attribute index position + * + * \fgdt_loc_id + * \param[in] obj_name Name of object to which attribute is attached, + * relative to location + * \param[in] idx_type Type of index + * \param[in] order Index traversal order + * \param[in] n Attribute’s position in index + * \param[out] ainfo Struct containing returned attribute information + * \lapl_id + * + * \return \herr_t + * + * \details H5Aget_info_by_idx() retrieves information for an attribute + * that is attached to an object, which is specified by its + * location and name, \p loc_id and \p obj_name, respectively. + * The attribute is located by its index position and the attribute + * information is returned in the \p ainfo struct. + * + * If \p loc_id fully specifies the object to which the attribute + * is attached, \p obj_name should be '.' (a dot). + * + * The attribute is located by means of an index type, an index + * traversal order, and a position in the index, \p idx_type, + * \p order and \p n, respectively. These parameters and their + * valid values are discussed in the description of H5Aiterate2(). + * + * The \p ainfo struct, which will contain the returned attribute + * information, is described in H5Aget_info(). + * + * The link access property list, \p lapl_id, may provide + * information regarding the properties of links required to access + * the object, \p obj_name. + * + * \since 1.8.0 + * + */ +H5_DLL herr_t H5Aget_info_by_idx(hid_t loc_id, const char *obj_name, H5_index_t idx_type, + H5_iter_order_t order, hsize_t n, H5A_info_t *ainfo /*out*/, hid_t lapl_id); +/*-------------------------------------------------------------------------*/ +/** + * \ingroup H5A + * + * \brief Retrieves attribute information, by attribute name + * + * \fgdt_loc_id + * + * \param[in] obj_name Name of object to which attribute is attached, + * relative to location + * \param[in] attr_name Attribute name + * \param[out] ainfo Struct containing returned attribute information + * \lapl_id + * + * \return \herr_t + * + * \details H5Aget_info_by_name() retrieves information for an attribute, + * \p attr_name, that is attached to an object specified by its + * location and name, \p loc_id and \p obj_name, respectively. + * The attribute information is returned in the \p ainfo struct. + * + * If \p loc_id fully specifies the object to which the attribute + * is attached, \p obj_name should be '.' (a dot). + * + * The \p ainfo struct is described in H5Aget_info(). + * + * The link access property list, \p lapl_id, may provide + * information regarding the properties of links required to + * access the object, \p obj_name. + * + * \since 1.8.0 + * + */ +H5_DLL herr_t H5Aget_info_by_name(hid_t loc_id, const char *obj_name, const char *attr_name, + H5A_info_t *ainfo /*out*/, hid_t lapl_id); +/*-------------------------------------------------------------------------*/ +/** + * \ingroup H5A + * + * \brief Gets an attribute name + * + * \attr_id + * \param[in] buf_size The size of the buffer to store the name in + * \param[out] buf Buffer to store name in + * + * \return Returns the length of the attribute's name, which may be longer + * than \p buf_size, if successful. Otherwise returns a negative + * value. + * + * \details H5Aget_name() retrieves the name of an attribute specified by + * the identifier, \p attr_id. Up to \p buf_size characters are + * stored in \p buf followed by a \0 string terminator. If the + * name of the attribute is longer than (\p buf_size -1), the + * string terminator is stored in the last position of the buffer + * to properly terminate the string. + * + * If the user only wants to find out the size of this name, the + * values 0 and NULL can be passed in for the parameters + * \p bufsize and \p buf. + * + * \since 1.0.0 + * + */ H5_DLL ssize_t H5Aget_name(hid_t attr_id, size_t buf_size, char *buf); +/*-------------------------------------------------------------------------*/ +/** + * \ingroup H5A + * + * \brief Gets an attribute name, by attribute index position + * + * \fgdt_loc_id + * \param[in] obj_name Name of object to which attribute is attached, + * relative to location + * \param[in] idx_type Type of index + * \param[in] order Index traversal order + * \param[in] n Attribute’s position in index + * \param[out] name Attribute name + * \param[in] size Size, in bytes, of attribute name + * \lapl_id + * + * \return Returns attribute name size, in bytes, if successful; + * otherwise returns a negative value. + * + * \details H5Aget_name_by_idx() retrieves the name of an attribute that is + * attached to an object, which is specified by its location and + * name, \p loc_id and \p obj_name, respectively. The attribute is + * located by its index position, the size of the name is specified + * in \p size, and the attribute name is returned in \p name. + * + * If \p loc_id fully specifies the object to which the attribute + * is attached, \p obj_name should be '.' (a dot). + * + * The attribute is located by means of an index type, an index + * traversal order, and a position in the index, \p idx_type, + * \p order and \p n, respectively. These parameters and their + * valid values are discussed in the description of H5Aiterate2(). + * + * If the attribute name’s size is unknown, the values 0 and NULL + * can be passed in for the parameters \p size and \p name. The + * function’s return value will provide the correct value for + * \p size. + * + * The link access property list, \p lapl_id, may provide + * information regarding the properties of links required to access + * the object, \p obj_name. + * + * \since 1.8.0 + * + */ H5_DLL ssize_t H5Aget_name_by_idx(hid_t loc_id, const char *obj_name, H5_index_t idx_type, H5_iter_order_t order, hsize_t n, char *name /*out*/, size_t size, hid_t lapl_id); +/*-------------------------------------------------------------------------*/ +/** + * \ingroup H5A + * + * \brief Gets a copy of the dataspace for an attribute + * + * \attr_id + * + * \return \hid_tv{attribute dataspace} + * + * \details H5Aget_space() retrieves a copy of the dataspace for an + * attribute. The dataspace identifier returned from this + * function must be released with H5Sclose() or resource leaks + * will develop. + * + * \since 1.0.0 + * + */ +H5_DLL hid_t H5Aget_space(hid_t attr_id); +/*-------------------------------------------------------------------------*/ +/** + * \ingroup H5A + * + * \brief Returns the amount of storage required for an attribute + * + * \attr_id + * + * \return Returns the amount of storage size allocated for the attribute; + * otherwise returns 0 (zero). + * + * \details H5Aget_storage_size() returns the amount of storage that is + * required for the specified attribute, \p attr_id. + * + * \since 1.6.0 + * + */ H5_DLL hsize_t H5Aget_storage_size(hid_t attr_id); -H5_DLL herr_t H5Aget_info(hid_t attr_id, H5A_info_t *ainfo /*out*/); -H5_DLL herr_t H5Aget_info_by_name(hid_t loc_id, const char *obj_name, const char *attr_name, - H5A_info_t *ainfo /*out*/, hid_t lapl_id); -H5_DLL herr_t H5Aget_info_by_idx(hid_t loc_id, const char *obj_name, H5_index_t idx_type, - H5_iter_order_t order, hsize_t n, H5A_info_t *ainfo /*out*/, hid_t lapl_id); -H5_DLL herr_t H5Arename(hid_t loc_id, const char *old_name, const char *new_name); -H5_DLL herr_t H5Arename_by_name(hid_t loc_id, const char *obj_name, const char *old_attr_name, - const char *new_attr_name, hid_t lapl_id); -H5_DLL herr_t H5Aiterate2(hid_t loc_id, H5_index_t idx_type, H5_iter_order_t order, hsize_t *idx, - H5A_operator2_t op, void *op_data); -H5_DLL herr_t H5Aiterate_by_name(hid_t loc_id, const char *obj_name, H5_index_t idx_type, - H5_iter_order_t order, hsize_t *idx, H5A_operator2_t op, void *op_data, - hid_t lapd_id); -H5_DLL herr_t H5Adelete(hid_t loc_id, const char *name); -H5_DLL herr_t H5Adelete_by_name(hid_t loc_id, const char *obj_name, const char *attr_name, hid_t lapl_id); -H5_DLL herr_t H5Adelete_by_idx(hid_t loc_id, const char *obj_name, H5_index_t idx_type, H5_iter_order_t order, - hsize_t n, hid_t lapl_id); -H5_DLL htri_t H5Aexists(hid_t obj_id, const char *attr_name); -H5_DLL htri_t H5Aexists_by_name(hid_t obj_id, const char *obj_name, const char *attr_name, hid_t lapl_id); +/*-------------------------------------------------------------------------*/ +/** + * \ingroup H5A + * + * \brief Gets an attribute datatype + * + * \attr_id + * + * \return \hid_t{datatype} + * + * \details H5Aget_type() retrieves a copy of the datatype for an attribute. + * The datatype is reopened if it is a named type before returning + * it to the application. The datatypes returned by this function + * are always read-only. If an error occurs when atomizing the + * return datatype, then the datatype is closed. + * + * The datatype identifier returned from this function must be + * released with H5Tclose() or resource leaks will develop. + * + * \since 1.0.0 + * + */ +H5_DLL hid_t H5Aget_type(hid_t attr_id); +/*-------------------------------------------------------------------------*/ +/** + * \ingroup H5A + * + * \brief Calls user-defined function for each attribute on an object + * + * \fgdt_loc_id + * \param[in] idx_type Type of index + * \param[in] order Order in which to iterate over index + * \param[in,out] idx Initial and returned offset within index + * \param[in] op User-defined function to pass each attribute to + * \param[in,out] op_data User data to pass through to and to be returned + * by iterator operator function + * + * \return \herr_t + * Further note that this function returns the return value of the + * last operator if it was non-zero, which can be a negative value, + * zero if all attributes were processed, or a positive value + * indicating short-circuit success. + * + * \details H5Aiterate2() iterates over the attributes attached to a + * dataset, named datatype, or group, as specified by \p loc_id. + * For each attribute, user-provided data, \p op_data, with + * additional information as defined below, is passed to a + * user-defined function, \p op, which operates on that + * attribute. + * + * The order of the iteration and the attributes iterated over + * are specified by three parameters: the index type, + * \p idx_type; the order in which the index is to be traversed, + * \p order; and the attribute’s position in the index, \p idx. + * + * The type of index specified by \p idx_type can be one of the + * following: + * + * \indexes + * + * The order in which the index is to be traversed, as specified + * by \p order, can be one of the following: + * + * \orders + * + * The next attribute to be operated on is specified by \p idx, + * a position in the index. + * + * For example, if \p idx_type, \p order, and \p idx are set to + * #H5_INDEX_NAME, #H5_ITER_INC, and 5, respectively, the attribute + * in question is the fifth attribute from the beginning of the + * alpha-numeric index of attribute names. If \p order were set to + * #H5_ITER_DEC, it would be the fifth attribute from the end of + * the index. + * + * The parameter \p idx is passed in on an H5Aiterate2() call with + * one value and may be returned with another value. The value + * passed in identifies the parameter to be operated on first; + * the value returned identifies the parameter to be operated on + * in the next step of the iteration. + * + * \p op is a user-defined function whose prototype is defined + * as follows: + * \snippet this H5A_operator2_t_snip + * \click4more + * + * \note This function is also available through the H5Aiterate() macro. + * + * \since 1.8.0 + * + */ +H5_DLL herr_t H5Aiterate2(hid_t loc_id, H5_index_t idx_type, H5_iter_order_t order, hsize_t *idx, + H5A_operator2_t op, void *op_data); +/*--------------------------------------------------------------------------*/ +/** + * \ingroup H5A + * + * \brief Calls user-defined function for each attribute on an object + * + * \fgdt_loc_id + * \param[in] obj_name Name of object, relative to location + * \param[in] idx_type Type of index + * \param[in] order Order in which to iterate over index + * \param[in,out] idx Initial and returned offset within index + * \param[in] op User-defined function to pass each attribute to + * \param[in,out] op_data User data to pass through to and to be returned + * by iterator operator function + * \lapl_id + * + * \return \herr_t + * Further note that this function returns the return value of + * the last operator if it was non-zero, which can be a negative + * value, zero if all attributes were processed, or a positive value + * indicating short-circuit success. + * + * \details H5Aiterate_by_name() iterates over the attributes attached + * to the dataset or group specified with \p loc_id and \p obj_name. + * For each attribute, user-provided data, \p op_data, with + * additional information as defined below, is passed to a + * user-defined function, \p op, which operates on that attribute. + * + * If \p loc_id fully specifies the object to which these + * attributes are attached, \p obj_name should be '.' (a dot). + * + * The order of the iteration and the attributes iterated over + * are specified by three parameters: the index type, \p idx_type; + * the order in which the index is to be traversed, \p order; + * and the attribute’s position in the index, \p idx. + * + * The type of index specified by \p idx_type can be one of the + * following: + * + * \indexes + * + * The order in which the index is to be traversed, as specified + * by \p order, can be one of the following: + * + * \orders + * + * The next attribute to be operated on is specified by \p idx, + * a position in the index. + * + * For example, if \p idx_type, \p order, and \p idx are set to + * #H5_INDEX_NAME, #H5_ITER_INC, and 5, respectively, the attribute + * in question is the fifth attribute from the beginning of the + * alpha-numeric index of attribute names. If \p order were set to + * #H5_ITER_DEC, it would be the fifth attribute from the end of + * the index. + * + * The parameter \p idx is passed in on an H5Aiterate_by_name() + * call with one value and may be returned with another value. The + * value passed in identifies the parameter to be operated on first; + * the value returned identifies the parameter to be operated on in + * the next step of the iteration. + * + * \p op is a user-defined function whose prototype is defined + * as follows: + * \snippet this H5A_operator2_t_snip + * \click4more + * + * Valid return values from an operator and the resulting + * H5Aiterate_by_name() and \p op behavior are as follows: + * + * \li Zero causes the iterator to continue, returning zero when + * all attributes have been processed. + * \li A positive value causes the iterator to immediately return + * that positive value, indicating short-circuit success. + * The iterator can be restarted at the next attribute, as + * indicated by the return value of \p idx. + * \li A negative value causes the iterator to immediately return + * that value, indicating failure. The iterator can be + * restarted at the next attribute, as indicated by the return + * value of \p idx. + * + * The link access property list, \p lapl_id, may provide + * information regarding the properties of links required to access + * the object, \p obj_name. + * + * \since 1.8.0 + * + */ +H5_DLL herr_t H5Aiterate_by_name(hid_t loc_id, const char *obj_name, H5_index_t idx_type, + H5_iter_order_t order, hsize_t *idx, H5A_operator2_t op, void *op_data, + hid_t lapl_id); +/*--------------------------------------------------------------------------*/ +/** + * \ingroup H5A + * + * \brief Opens an attribute for an object specified by object identifier and + * attribute name + * + * \fgdt_loc_id{obj_id} + * \param[in] attr_name Name of attribute to open + * \aapl_id + * + * \return \hid_tv{attribute} + * + * \details H5Aopen() opens an existing attribute, \p attr_name, that is + * attached to object specified by an object identifier, \p obj_id. + * + * The attribute access property list, \p aapl_id, is currently unused + * and should be #H5P_DEFAULT. + * + * This function, H5Aopen_by_idx() or H5Aopen_by_name() must be called + * before the attribute can be accessed for any further purpose, + * including reading, writing, or any modification. + * + * The attribute identifier returned by this function must be released + * with H5Aclose() or resource leaks will develop. + * + * \since 1.8.0 + * + * \see H5Aclose(), H5Acreate() + */ +H5_DLL hid_t H5Aopen(hid_t obj_id, const char *attr_name, hid_t aapl_id); +/*--------------------------------------------------------------------------*/ +/** + * \ingroup ASYNC + * \async_variant_of{H5Aopen} + */ +H5_DLL hid_t H5Aopen_async(const char *app_file, const char *app_func, unsigned app_line, hid_t obj_id, + const char *attr_name, hid_t aapl_id, hid_t es_id); +/*--------------------------------------------------------------------------*/ +/** + * \ingroup H5A + * + * \brief Opens the nth attribute attached to an object + * + * \loc_id + * \param[in] obj_name Name of object to which attribute is attached, + * relative to location + * \param[in] idx_type Type of index + * \param[in] order Index traversal order + * \param[in] n Attribute’s position in index + * \aapl_id + * \lapl_id + * + * \return \hid_tv{attribute} + * + * \details H5Aopen_by_idx() opens an existing attribute that is attached + * to an object specified by location and name, \p loc_id and + * \p obj_name, respectively. If \p loc_id fully specifies the + * object to which the attribute is attached, \p obj_name, should + * be '.' (a dot). + * + * The attribute is identified by an index type, an index traversal + * order, and a position in the index, \p idx_type, \p order and + * \p n, respectively. These parameters and their valid values are + * discussed in the description of H5Aiterate2(). + * + * The attribute access property list, \p aapl_id, is currently + * unused and should currently be #H5P_DEFAULT. + * + * The link access property list, \p lapl_id, may provide + * information regarding the properties of links required to access + * the object, \p obj_name. + * + * This function, H5Aopen(), or H5Aopen_by_name() must be called + * before an attribute can be accessed for any further purpose, + * including reading, writing, or any modification. + * + * The attribute identifier returned by this function must be + * released with H5Aclose() or resource leaks will develop. + * + * \since 1.8.0 + * + */ +H5_DLL hid_t H5Aopen_by_idx(hid_t loc_id, const char *obj_name, H5_index_t idx_type, H5_iter_order_t order, + hsize_t n, hid_t aapl_id, hid_t lapl_id); +/*--------------------------------------------------------------------------*/ +/** + * \ingroup ASYNC + * \async_variant_of{H5Aopen_by_idx} + */ +H5_DLL hid_t H5Aopen_by_idx_async(const char *app_file, const char *app_func, unsigned app_line, hid_t loc_id, + const char *obj_name, H5_index_t idx_type, H5_iter_order_t order, hsize_t n, + hid_t aapl_id, hid_t lapl_id, hid_t es_id); +/*--------------------------------------------------------------------------*/ +/** + * \ingroup H5A + * + * \brief Opens an attribute for an object by object name and attribute name + * + * \fgdt_loc_id + * \param[in] obj_name Name of object to which attribute is attached, + * relative to \p loc_id + * \param[in] attr_name Name of attribute to open + * \aapl_id + * \lapl_id + * + * \return \hid_tv{attribute} + * + * \details H5Aopen_by_name() opens an existing attribute, \p attr_name, + * that is attached to an object specified by location and name, + * \p loc_id and \p obj_name, respectively. + * + * \p loc_id specifies a location from which the target object can + * be located and \p obj_name is an object name relative to + * \p loc_id. If \p loc_id fully specifies the object to which the + * attribute is attached, \p obj_name should be '.' (a dot). + * + * The attribute access property list, \p aapl_id, is currently + * unused and should currently be #H5P_DEFAULT. + * + * The link access property list, \p lapl_id, may provide + * information regarding the properties of links required to access + * the object, \p obj_name. + * + * This function, H5Aopen(), or H5Aopen_by_idx() must be called + * before an attribute can be accessed for any further purpose, + * including reading, writing, or any modification. + * + * The attribute identifier returned by this function must be + * released with H5Aclose() or resource leaks will develop. + * + * \since 1.8.0 + * + */ +H5_DLL hid_t H5Aopen_by_name(hid_t loc_id, const char *obj_name, const char *attr_name, hid_t aapl_id, + hid_t lapl_id); +/*--------------------------------------------------------------------------*/ +/** + * \ingroup ASYNC + * \async_variant_of{H5Aopen_by_name} + */ +H5_DLL hid_t H5Aopen_by_name_async(const char *app_file, const char *app_func, unsigned app_line, + hid_t loc_id, const char *obj_name, const char *attr_name, hid_t aapl_id, + hid_t lapl_id, hid_t es_id); +/*-------------------------------------------------------------------------- */ +/** + * \ingroup H5A + * + * \brief Reads the value of an attribute + * + * \attr_id + * \mem_type_id{type_id} + * \param[out] buf Buffer for data to be read + * + * \return \herr_t + * + * \details H5Aread() reads an attribute, specified with \p attr_id. The + * attribute's in-memory datatype is specified with \p type_id. The + * entire attribute is read into \p buf from the file. + * + * Datatype conversion takes place at the time of a read or write and + * is automatic. + * + * \version 1.8.8 Fortran updated to Fortran2003. + * \version 1.4.2 The \p dims parameter was added to the Fortran API in this + * release. + * \since 1.0.0 + * + * \see H5Awrite() + * + */ +H5_DLL herr_t H5Aread(hid_t attr_id, hid_t type_id, void *buf); +/*--------------------------------------------------------------------------*/ +/** + * \ingroup ASYNC + * \async_variant_of{H5Aread} + */ +H5_DLL herr_t H5Aread_async(const char *app_file, const char *app_func, unsigned app_line, hid_t attr_id, + hid_t dtype_id, void *buf, hid_t es_id); +/*-------------------------------------------------------------------------*/ +/** + * \ingroup H5A + * + * \brief Renames an attribute + * + * \fgdt_loc_id + * \param[in] old_name Name of the attribute to be changed + * \param[in] new_name New name for the attribute + * + * \return \herr_t + * + * \details H5Arename() changes the name of the attribute located at + * \p loc_id. + * + * The old name, \p old_name, is changed to the new name, + * \p new_name. + * + * \since 1.6.0 + * + */ +H5_DLL herr_t H5Arename(hid_t loc_id, const char *old_name, const char *new_name); +/*--------------------------------------------------------------------------*/ +/** + * \ingroup ASYNC + * \async_variant_of{H5Arename} + */ +H5_DLL herr_t H5Arename_async(const char *app_file, const char *app_func, unsigned app_line, hid_t loc_id, + const char *old_name, const char *new_name, hid_t es_id); +/*--------------------------------------------------------------------------*/ +/** + * \ingroup ASYNC + * \async_variant_of{H5Arename_by_name} + */ +H5_DLL herr_t H5Arename_by_name_async(const char *app_file, const char *app_func, unsigned app_line, + hid_t loc_id, const char *obj_name, const char *old_attr_name, + const char *new_attr_name, hid_t lapl_id, hid_t es_id); +/*--------------------------------------------------------------------------*/ +/** + * \ingroup H5A + * + * \brief Writes data to an attribute + * + * \attr_id + * \mem_type_id{type_id} + * \param[out] buf Data to be written + * + * \return \herr_t + * + * \details H5Awrite() writes an attribute, specified with \p attr_id. The + * attribute's in-memory datatype is specified with \p type_id. + * The entire attribute is written from \p buf to the file. + * + * If \p type_id is either a fixed-length or variable-length string, + * it is important to set the string length when defining the datatype. + * String datatypes are derived from #H5T_C_S1 (or #H5T_FORTRAN_S1 for + * Fortran codes), which defaults to 1 character in size. + * See H5Tset_size() and Creating variable-length string datatypes. + * + * Datatype conversion takes place at the time of a read or write and + * is automatic. + * + * \version 1.8.8 Fortran updated to Fortran2003. + * \version 1.4.2 Fortran \p dims parameter added in this release + * \since 1.0.0 + * \see H5Aread() + * + */ +H5_DLL herr_t H5Awrite(hid_t attr_id, hid_t type_id, const void *buf); +/*--------------------------------------------------------------------------*/ +/** + * \ingroup ASYNC + * \async_variant_of{H5Awrite} + */ +H5_DLL herr_t H5Awrite_async(const char *app_file, const char *app_func, unsigned app_line, hid_t attr_id, + hid_t type_id, const void *buf, hid_t es_id); +/*-------------------------------------------------------------------------*/ +/** + * \ingroup H5A + * + * \fgdt_loc_id + * \param[in] obj_name Name of object, relative to location, whose + * attribute is to be renamed + * \param[in] old_attr_name Prior attribute name + * \param[in] new_attr_name New attribute name + * \lapl_id + * + * \details H5Arename_by_name() changes the name of attribute that is + * attached to the object specified by \p loc_id and \p obj_name. + * The attribute named \p old_attr_name is renamed + * \p new_attr_name. + * + * The link access property list, \p lapl_id, may provide + * information regarding the properties of links required to + * access the object, \p obj_name. + * + * \since 1.8.0 + * + */ +H5_DLL herr_t H5Arename_by_name(hid_t loc_id, const char *obj_name, const char *old_attr_name, + const char *new_attr_name, hid_t lapl_id); + +/* API Wrappers for async routines */ +/* (Must be defined _after_ the function prototype) */ +/* (And must only defined when included in application code, not the library) */ +#ifndef H5A_MODULE +#define H5Acreate_async(...) H5Acreate_async(__FILE__, __func__, __LINE__, __VA_ARGS__) +#define H5Acreate_by_name_async(...) H5Acreate_by_name_async(__FILE__, __func__, __LINE__, __VA_ARGS__) +#define H5Aopen_async(...) H5Aopen_async(__FILE__, __func__, __LINE__, __VA_ARGS__) +#define H5Aopen_by_name_async(...) H5Aopen_by_name_async(__FILE__, __func__, __LINE__, __VA_ARGS__) +#define H5Aopen_by_idx_async(...) H5Aopen_by_idx_async(__FILE__, __func__, __LINE__, __VA_ARGS__) +#define H5Awrite_async(...) H5Awrite_async(__FILE__, __func__, __LINE__, __VA_ARGS__) +#define H5Aread_async(...) H5Aread_async(__FILE__, __func__, __LINE__, __VA_ARGS__) +#define H5Arename_async(...) H5Arename_async(__FILE__, __func__, __LINE__, __VA_ARGS__) +#define H5Arename_by_name_async(...) H5Arename_by_name_async(__FILE__, __func__, __LINE__, __VA_ARGS__) +#define H5Aexists_async(...) H5Aexists_async(__FILE__, __func__, __LINE__, __VA_ARGS__) +#define H5Aexists_by_name_async(...) H5Aexists_by_name_async(__FILE__, __func__, __LINE__, __VA_ARGS__) +#define H5Aclose_async(...) H5Aclose_async(__FILE__, __func__, __LINE__, __VA_ARGS__) + +/* Define "wrapper" versions of function calls, to allow compile-time values to + * be passed in by language wrapper or library layer on top of HDF5. + */ +#define H5Acreate_async_wrap H5_NO_EXPAND(H5Acreate_async) +#define H5Acreate_by_name_async_wrap H5_NO_EXPAND(H5Acreate_by_name_async) +#define H5Aopen_async_wrap H5_NO_EXPAND(H5Aopen_async) +#define H5Aopen_by_name_async_wrap H5_NO_EXPAND(H5Aopen_by_name_async) +#define H5Aopen_by_idx_async_wrap H5_NO_EXPAND(H5Aopen_by_idx_async) +#define H5Awrite_async_wrap H5_NO_EXPAND(H5Awrite_async) +#define H5Aread_async_wrap H5_NO_EXPAND(H5Aread_async) +#define H5Arename_async_wrap H5_NO_EXPAND(H5Arename_async) +#define H5Arename_by_name_async_wrap H5_NO_EXPAND(H5Arename_by_name_async) +#define H5Aexists_async_wrap H5_NO_EXPAND(H5Aexists_async) +#define H5Aexists_by_name_async_wrap H5_NO_EXPAND(H5Aexists_by_name_async) +#define H5Aclose_async_wrap H5_NO_EXPAND(H5Aclose_async) +#endif /* H5A_MODULE */ /* Symbols defined for compatibility with previous versions of the HDF5 API. * @@ -142,11 +1168,162 @@ typedef herr_t (*H5A_operator1_t)(hid_t location_id /*in*/, const char *attr_nam //! <!-- [H5A_operator1_t_snip] --> /* Function prototypes */ -H5_DLL hid_t H5Acreate1(hid_t loc_id, const char *name, hid_t type_id, hid_t space_id, hid_t acpl_id); -H5_DLL hid_t H5Aopen_name(hid_t loc_id, const char *name); -H5_DLL hid_t H5Aopen_idx(hid_t loc_id, unsigned idx); -H5_DLL int H5Aget_num_attrs(hid_t loc_id); -H5_DLL herr_t H5Aiterate1(hid_t loc_id, unsigned *attr_num, H5A_operator1_t op, void *op_data); +/* --------------------------------------------------------------------------*/ +/** + * \ingroup H5A + * + * \brief Creates an attribute attached to a specified object + * + * \fgdt_loc_id + * \param[in] name Name of attribute to locate and open + * \param[in] type_id Identifier of attribute datatype + * \space_id + * \acpl_id + * + * \return \hid_tv{attribute} + * + * \note The \p acpl parameters is currently not used; specify #H5P_DEFAULT. + * + * \deprecated Deprecated in favor of H5Acreate2() + * + * \details H5Acreate1() creates an attribute, \p name, which is attached + * to the object specified by the identifier \p loc_id. + * + * The attribute name, \p name, must be unique for the object. + * + * The attribute is created with the specified datatype and dataspace, + * \p type_id and \p space_id, which are created with the H5T and + * H5S interfaces, respectively. + * + * If \p type_id is either a fixed-length or variable-length string, + * it is important to set the string length when defining the + * datatype. String datatypes are derived from #H5T_C_S1 (or + * #H5T_FORTRAN_S1 for Fortran), which defaults to 1 character in + * size. See H5Tset_size() and Creating variable-length string + * datatypes. + * + * The attribute identifier returned by this function must be released + * with H5Aclose() resource leaks will develop. + * + * \since 1.8.0 + * + * \version 1.8.0 The function H5Acreate() was renamed to H5Acreate1() and + * deprecated in this release. + * + * \see H5Aclose() + * + */ +H5_DLL hid_t H5Acreate1(hid_t loc_id, const char *name, hid_t type_id, hid_t space_id, hid_t acpl_id); +/* --------------------------------------------------------------------------*/ +/** + * \ingroup H5A + * + * \brief Determines the number of attributes attached to an object + * + * \fgdt_loc_id + * + * \return Returns the number of attributes if successful; otherwise returns + * a negative value. + * + * \deprecated This function is deprecated in favor of the functions + * H5Oget_info(), H5Oget_info_by_name(), and H5Oget_info_by_idx(). + * + * \details H5Aget_num_attrs() returns the number of attributes attached to + * the object specified by its identifier, \p loc_id. + * + * \since 1.0.0 + * + */ +H5_DLL int H5Aget_num_attrs(hid_t loc_id); +/* --------------------------------------------------------------------------*/ +/** + * \ingroup H5A + * + * \brief Calls a user’s function for each attribute on an object + * + * \loc_id + * \param[in,out] idx Starting (in) and ending (out) attribute index + * \param[in] op User's function to pass each attribute to + * \param[in,out] op_data User's data to pass through to iterator operator + * function + * + * \return \herr_t + * + * \deprecated This function is deprecated in favor of the function + * H5Aiterate2(). + * + * \details H5Aiterate1() iterates over the attributes of the object + * specified by its identifier, \p loc_id. The object can be a + * group, dataset, or named datatype. For each attribute of the + * object, the \p op_data and some additional information specified + * below are passed to the operator function \p op. The iteration + * begins with the attribute specified by its index, \p idx; the + * index for the next attribute to be processed by the operator, + * \p op, is returned in \p idx. If \p idx is the null pointer, + * then all attributes are processed. + * + * \p op is a user-defined function whose prototype is defined as follows: + * \snippet this H5A_operator1_t_snip + * \click4more + * + * \version 1.8.0 The function \p H5Aiterate was renamed to H5Aiterate1() + * and deprecated in this release. + * \since 1.0.0 + * + */ +H5_DLL herr_t H5Aiterate1(hid_t loc_id, unsigned *idx, H5A_operator1_t op, void *op_data); +/* --------------------------------------------------------------------------*/ +/** + * \ingroup H5A + * + * \brief Opens the attribute specified by its index + * + * \loc_id + * \param[in] idx Index of the attribute to open + * + * \return \hid_tv{attribute} + * + * \deprecated This function is deprecated in favor of the function + * H5Aopen_by_idx(). + * + * \details H5Aopen_idx() opens an attribute which is attached to the + * object specified with \p loc_id . The location object may be + * either a group, dataset, or named datatype, all of which may + * have any sort of attribute. The attribute specified by the index, + * \p idx , indicates the attribute to access. The value of \p idx + * is a 0-based, non-negative integer. The attribute identifier + * returned from this function must be released with H5Aclose() + * or resource leaks will develop. + * + * \since 1.0.0 + * + */ +H5_DLL hid_t H5Aopen_idx(hid_t loc_id, unsigned idx); +/* --------------------------------------------------------------------------*/ +/** + * \ingroup H5A + * + * \brief Opens an attribute specified by name + * + * \loc_id + * \param[in] name Attribute name + * + * \return \hid_tv{attribute} + * + * \deprecated This function is deprecated in favor of the function + * H5Aopen_by_name(). + * + * \details H5Aopen_name() opens an attribute specified by its name, + * \p name, which is attached to the object specified with + * \p loc_id. The location object may be either a group, dataset, + * or named datatype, which may have any sort of attribute. The + * attribute identifier returned from this function must be + * released with H5Aclose() or resource leaks will develop. + * + * \since 1.0.0 + * + */ +H5_DLL hid_t H5Aopen_name(hid_t loc_id, const char *name); #endif /* H5_NO_DEPRECATED_SYMBOLS */ @@ -286,8 +286,8 @@ done: * *------------------------------------------------------------------------- */ -htri_t -H5B_find(H5F_t *f, const H5B_class_t *type, haddr_t addr, void *udata) +herr_t +H5B_find(H5F_t *f, const H5B_class_t *type, haddr_t addr, hbool_t *found, void *udata) { H5B_t * bt = NULL; H5UC_t * rc_shared; /* Ref-counted shared info */ @@ -295,7 +295,7 @@ H5B_find(H5F_t *f, const H5B_class_t *type, haddr_t addr, void *udata) H5B_cache_ud_t cache_udata; /* User-data for metadata cache callback */ unsigned idx = 0, lt = 0, rt; /* Final, left & right key indices */ int cmp = 1; /* Key comparison value */ - htri_t ret_value = FAIL; /* Return value */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI(FAIL) @@ -337,21 +337,22 @@ H5B_find(H5F_t *f, const H5B_class_t *type, haddr_t addr, void *udata) /* Check if not found */ if (cmp) - HGOTO_DONE(FALSE) - - /* - * Follow the link to the subtree or to the data node. - */ - HDassert(idx < bt->nchildren); - - if (bt->level > 0) { - if ((ret_value = H5B_find(f, type, bt->child[idx], udata)) < 0) - HGOTO_ERROR(H5E_BTREE, H5E_NOTFOUND, FAIL, "can't lookup key in subtree") - } /* end if */ + *found = FALSE; else { - if ((ret_value = (type->found)(f, bt->child[idx], H5B_NKEY(bt, shared, idx), udata)) < 0) - HGOTO_ERROR(H5E_BTREE, H5E_NOTFOUND, FAIL, "can't lookup key in leaf node") - } /* end else */ + /* + * Follow the link to the subtree or to the data node. + */ + HDassert(idx < bt->nchildren); + + if (bt->level > 0) { + if ((ret_value = H5B_find(f, type, bt->child[idx], found, udata)) < 0) + HGOTO_ERROR(H5E_BTREE, H5E_NOTFOUND, FAIL, "can't lookup key in subtree") + } /* end if */ + else { + if ((ret_value = (type->found)(f, bt->child[idx], H5B_NKEY(bt, shared, idx), found, udata)) < 0) + HGOTO_ERROR(H5E_BTREE, H5E_NOTFOUND, FAIL, "can't lookup key in leaf node") + } /* end else */ + } /* end else */ done: if (bt && H5AC_unprotect(f, H5AC_BT, addr, bt, H5AC__NO_FLAGS_SET) < 0) @@ -445,29 +445,30 @@ H5B2_iterate(H5B2_t *bt2, H5B2_operator_t op, void *op_data) * If 'OP' is NULL, then this routine just returns "TRUE" when * a record is present in the B-tree. * - * Return: Non-negative (TRUE/FALSE) on success, negative on failure. + * Return: SUCCEED/FAIL * * Programmer: Quincey Koziol * Feb 23 2005 * *------------------------------------------------------------------------- */ -htri_t -H5B2_find(H5B2_t *bt2, void *udata, H5B2_found_t op, void *op_data) +herr_t +H5B2_find(H5B2_t *bt2, void *udata, hbool_t *found, H5B2_found_t op, void *op_data) { - H5B2_hdr_t * hdr; /* Pointer to the B-tree header */ - H5B2_node_ptr_t curr_node_ptr; /* Node pointer info for current node */ - void * parent = NULL; /* Parent of current node */ - uint16_t depth; /* Current depth of the tree */ - int cmp; /* Comparison value of records */ - unsigned idx; /* Location of record which matches key */ - H5B2_nodepos_t curr_pos; /* Position of the current node */ - htri_t ret_value = TRUE; /* Return value */ + H5B2_hdr_t * hdr; /* Pointer to the B-tree header */ + H5B2_node_ptr_t curr_node_ptr; /* Node pointer info for current node */ + void * parent = NULL; /* Parent of current node */ + uint16_t depth; /* Current depth of the tree */ + int cmp; /* Comparison value of records */ + unsigned idx; /* Location of record which matches key */ + H5B2_nodepos_t curr_pos; /* Position of the current node */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI(FAIL) /* Check arguments. */ HDassert(bt2); + HDassert(found); /* Set the shared v2 B-tree header's file context for this operation */ bt2->hdr->f = bt2->f; @@ -479,8 +480,10 @@ H5B2_find(H5B2_t *bt2, void *udata, H5B2_found_t op, void *op_data) curr_node_ptr = hdr->root; /* Check for empty tree */ - if (curr_node_ptr.node_nrec == 0) - HGOTO_DONE(FALSE) + if (curr_node_ptr.node_nrec == 0) { + *found = FALSE; + HGOTO_DONE(SUCCEED) + } /* Check record against min & max records in tree, to attempt to quickly * find candidates or avoid further searching. @@ -488,25 +491,31 @@ H5B2_find(H5B2_t *bt2, void *udata, H5B2_found_t op, void *op_data) if (hdr->min_native_rec != NULL) { if ((hdr->cls->compare)(udata, hdr->min_native_rec, &cmp) < 0) HGOTO_ERROR(H5E_BTREE, H5E_CANTCOMPARE, FAIL, "can't compare btree2 records") - if (cmp < 0) - HGOTO_DONE(FALSE) /* Less than the least record--not found */ - else if (cmp == 0) { /* Record is found */ + if (cmp < 0) { + *found = FALSE; /* Less than the least record--not found */ + HGOTO_DONE(SUCCEED) + } + else if (cmp == 0) { /* Record is found */ if (op && (op)(hdr->min_native_rec, op_data) < 0) HGOTO_ERROR(H5E_BTREE, H5E_NOTFOUND, FAIL, "'found' callback failed for B-tree find operation") - HGOTO_DONE(TRUE) + *found = TRUE; + HGOTO_DONE(SUCCEED) } /* end if */ } /* end if */ if (hdr->max_native_rec != NULL) { if ((hdr->cls->compare)(udata, hdr->max_native_rec, &cmp) < 0) HGOTO_ERROR(H5E_BTREE, H5E_CANTCOMPARE, FAIL, "can't compare btree2 records") - if (cmp > 0) - HGOTO_DONE(FALSE) /* Less than the least record--not found */ - else if (cmp == 0) { /* Record is found */ + if (cmp > 0) { + *found = FALSE; /* Greater than the largest record--not found */ + HGOTO_DONE(SUCCEED) + } + else if (cmp == 0) { /* Record is found */ if (op && (op)(hdr->max_native_rec, op_data) < 0) HGOTO_ERROR(H5E_BTREE, H5E_NOTFOUND, FAIL, "'found' callback failed for B-tree find operation") - HGOTO_DONE(TRUE) + *found = TRUE; + HGOTO_DONE(SUCCEED) } /* end if */ } /* end if */ @@ -597,7 +606,8 @@ H5B2_find(H5B2_t *bt2, void *udata, H5B2_found_t op, void *op_data) HGOTO_ERROR(H5E_BTREE, H5E_CANTUNPROTECT, FAIL, "unable to release B-tree node") /* Indicate record found */ - HGOTO_DONE(TRUE) + *found = TRUE; + HGOTO_DONE(SUCCEED) } /* end else */ /* Decrement depth we're at in B-tree */ @@ -632,7 +642,8 @@ H5B2_find(H5B2_t *bt2, void *udata, H5B2_found_t op, void *op_data) HGOTO_ERROR(H5E_BTREE, H5E_CANTUNPROTECT, FAIL, "unable to release B-tree node") /* Record not found */ - HGOTO_DONE(FALSE) + *found = FALSE; + HGOTO_DONE(SUCCEED) } /* end if */ else { /* Make callback for current record */ @@ -672,6 +683,9 @@ H5B2_find(H5B2_t *bt2, void *udata, H5B2_found_t op, void *op_data) /* Unlock current node */ if (H5AC_unprotect(hdr->f, H5AC_BT2_LEAF, curr_node_ptr.addr, leaf, H5AC__NO_FLAGS_SET) < 0) HGOTO_ERROR(H5E_BTREE, H5E_CANTUNPROTECT, FAIL, "unable to release B-tree node") + + /* Indicate record found */ + *found = TRUE; } /* end block */ done: diff --git a/src/H5B2private.h b/src/H5B2private.h index 21ea823..a65a533 100644 --- a/src/H5B2private.h +++ b/src/H5B2private.h @@ -131,7 +131,7 @@ H5_DLL H5B2_t *H5B2_open(H5F_t *f, haddr_t addr, void *ctx_udata); H5_DLL herr_t H5B2_get_addr(const H5B2_t *bt2, haddr_t *addr /*out*/); H5_DLL herr_t H5B2_insert(H5B2_t *bt2, void *udata); H5_DLL herr_t H5B2_iterate(H5B2_t *bt2, H5B2_operator_t op, void *op_data); -H5_DLL htri_t H5B2_find(H5B2_t *bt2, void *udata, H5B2_found_t op, void *op_data); +H5_DLL herr_t H5B2_find(H5B2_t *bt2, void *udata, hbool_t *found, H5B2_found_t op, void *op_data); H5_DLL herr_t H5B2_index(H5B2_t *bt2, H5_iter_order_t order, hsize_t idx, H5B2_found_t op, void *op_data); H5_DLL herr_t H5B2_neighbor(H5B2_t *bt2, H5B2_compare_t range, void *udata, H5B2_found_t op, void *op_data); H5_DLL herr_t H5B2_modify(H5B2_t *bt2, void *udata, H5B2_modify_t op, void *op_data); diff --git a/src/H5Bprivate.h b/src/H5Bprivate.h index 265b6c6..2203ebd 100644 --- a/src/H5Bprivate.h +++ b/src/H5Bprivate.h @@ -110,7 +110,7 @@ typedef struct H5B_class_t { herr_t (*new_node)(H5F_t *, H5B_ins_t, void *, void *, void *, haddr_t *); int (*cmp2)(void *, void *, void *); /*compare 2 keys */ int (*cmp3)(void *, void *, void *); /*compare 3 keys */ - htri_t (*found)(H5F_t *, haddr_t, const void *, void *); + htri_t (*found)(H5F_t *, haddr_t, const void *, hbool_t *, void *); /* insert new data */ H5B_ins_t (*insert)(H5F_t *, haddr_t, void *, hbool_t *, void *, void *, void *, hbool_t *, haddr_t *); @@ -145,7 +145,7 @@ typedef struct H5B_info_t { /* Library-private Function Prototypes */ /***************************************/ H5_DLL herr_t H5B_create(H5F_t *f, const H5B_class_t *type, void *udata, haddr_t *addr_p /*out*/); -H5_DLL herr_t H5B_find(H5F_t *f, const H5B_class_t *type, haddr_t addr, void *udata); +H5_DLL herr_t H5B_find(H5F_t *f, const H5B_class_t *type, haddr_t addr, hbool_t *found, void *udata); H5_DLL herr_t H5B_insert(H5F_t *f, const H5B_class_t *type, haddr_t addr, void *udata); H5_DLL herr_t H5B_iterate(H5F_t *f, const H5B_class_t *type, haddr_t addr, H5B_operator_t op, void *udata); H5_DLL herr_t H5B_get_info(H5F_t *f, const H5B_class_t *type, haddr_t addr, H5B_info_t *bt_info, @@ -3037,7 +3037,7 @@ H5C_set_cache_auto_resize_config(H5C_t *cache_ptr, H5C_auto_size_ctl_t *config_p break; case H5C_incr__threshold: - if ((config_ptr->lower_hr_threshold <= (double)0.0f) || (config_ptr->increment <= (double)1.0f) || + if ((config_ptr->lower_hr_threshold <= 0.0) || (config_ptr->increment <= 1.0) || ((config_ptr->apply_max_increment) && (config_ptr->max_increment <= 0))) cache_ptr->size_increase_possible = FALSE; break; @@ -3057,21 +3057,21 @@ H5C_set_cache_auto_resize_config(H5C_t *cache_ptr, H5C_auto_size_ctl_t *config_p break; case H5C_decr__threshold: - if ((config_ptr->upper_hr_threshold >= (double)1.0f) || (config_ptr->decrement >= (double)1.0f) || + if ((config_ptr->upper_hr_threshold >= 1.0) || (config_ptr->decrement >= 1.0) || ((config_ptr->apply_max_decrement) && (config_ptr->max_decrement <= 0))) cache_ptr->size_decrease_possible = FALSE; break; case H5C_decr__age_out: - if (((config_ptr->apply_empty_reserve) && (config_ptr->empty_reserve >= (double)1.0f)) || + if (((config_ptr->apply_empty_reserve) && (config_ptr->empty_reserve >= 1.0)) || ((config_ptr->apply_max_decrement) && (config_ptr->max_decrement <= 0))) cache_ptr->size_decrease_possible = FALSE; break; case H5C_decr__age_out_with_threshold: - if (((config_ptr->apply_empty_reserve) && (config_ptr->empty_reserve >= (double)1.0f)) || + if (((config_ptr->apply_empty_reserve) && (config_ptr->empty_reserve >= 1.0)) || ((config_ptr->apply_max_decrement) && (config_ptr->max_decrement <= 0)) || - (config_ptr->upper_hr_threshold >= (double)1.0f)) + (config_ptr->upper_hr_threshold >= 1.0)) cache_ptr->size_decrease_possible = FALSE; break; @@ -3793,8 +3793,7 @@ done: HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "initial_size must be in the interval [min_size, max_size]") - if ((config_ptr->min_clean_fraction < (double)0.0f) || - (config_ptr->min_clean_fraction > (double)1.0f)) + if ((config_ptr->min_clean_fraction < 0.0) || (config_ptr->min_clean_fraction > 1.0)) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "min_clean_fraction must be in the interval [0.0, 1.0]") @@ -3810,12 +3809,11 @@ done: HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "Invalid incr_mode") if (config_ptr->incr_mode == H5C_incr__threshold) { - if ((config_ptr->lower_hr_threshold < (double)0.0f) || - (config_ptr->lower_hr_threshold > (double)1.0f)) + if ((config_ptr->lower_hr_threshold < 0.0) || (config_ptr->lower_hr_threshold > 1.0)) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "lower_hr_threshold must be in the range [0.0, 1.0]") - if (config_ptr->increment < (double)1.0f) + if (config_ptr->increment < 1.0) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "increment must be greater than or equal to 1.0") @@ -3830,12 +3828,10 @@ done: break; case H5C_flash_incr__add_space: - if ((config_ptr->flash_multiple < (double)0.1f) || - (config_ptr->flash_multiple > (double)10.0f)) + if ((config_ptr->flash_multiple < 0.1) || (config_ptr->flash_multiple > 10.0)) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "flash_multiple must be in the range [0.1, 10.0]") - if ((config_ptr->flash_threshold < (double)0.1f) || - (config_ptr->flash_threshold > (double)1.0f)) + if ((config_ptr->flash_threshold < 0.1) || (config_ptr->flash_threshold > 1.0)) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "flash_threshold must be in the range [0.1, 1.0]") break; @@ -3856,10 +3852,10 @@ done: } if (config_ptr->decr_mode == H5C_decr__threshold) { - if (config_ptr->upper_hr_threshold > (double)1.0f) + if (config_ptr->upper_hr_threshold > 1.0) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "upper_hr_threshold must be <= 1.0") - if ((config_ptr->decrement > (double)1.0f) || (config_ptr->decrement < (double)0.0f)) + if ((config_ptr->decrement > 1.0) || (config_ptr->decrement < 0.0)) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "decrement must be in the interval [0.0, 1.0]") /* no need to check max_decrement as it is a size_t @@ -3875,8 +3871,8 @@ done: if (config_ptr->epochs_before_eviction > H5C__MAX_EPOCH_MARKERS) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "epochs_before_eviction too big") - if ((config_ptr->apply_empty_reserve) && ((config_ptr->empty_reserve > (double)1.0f) || - (config_ptr->empty_reserve < (double)0.0f))) + if ((config_ptr->apply_empty_reserve) && + ((config_ptr->empty_reserve > 1.0) || (config_ptr->empty_reserve < 0.0))) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "empty_reserve must be in the interval [0.0, 1.0]") @@ -3886,8 +3882,7 @@ done: } /* H5C_decr__age_out || H5C_decr__age_out_with_threshold */ if (config_ptr->decr_mode == H5C_decr__age_out_with_threshold) { - if ((config_ptr->upper_hr_threshold > (double)1.0f) || - (config_ptr->upper_hr_threshold < (double)0.0f)) + if ((config_ptr->upper_hr_threshold > 1.0) || (config_ptr->upper_hr_threshold < 0.0)) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "upper_hr_threshold must be in the interval [0.0, 1.0]") } /* H5C_decr__age_out_with_threshold */ @@ -4352,8 +4347,8 @@ done: HDassert(cache_ptr); HDassert(cache_ptr->magic == H5C__H5C_T_MAGIC); HDassert(cache_ptr->cache_accesses >= (cache_ptr->resize_ctl).epoch_length); - HDassert((double)0.0f <= (cache_ptr->resize_ctl).min_clean_fraction); - HDassert((cache_ptr->resize_ctl).min_clean_fraction <= (double)100.0f); + HDassert(0.0 <= (cache_ptr->resize_ctl).min_clean_fraction); + HDassert((cache_ptr->resize_ctl).min_clean_fraction <= 100.0); /* check to see if cache_ptr->resize_in_progress is TRUE. If it, this * is a re-entrant call via a client callback called in the resize @@ -4376,7 +4371,7 @@ done: if (H5C_get_cache_hit_rate(cache_ptr, &hit_rate) != SUCCEED) HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "Can't get hit rate") - HDassert(((double)0.0f <= hit_rate) && (hit_rate <= (double)1.0f)); + HDassert((0.0 <= hit_rate) && (hit_rate <= 1.0)); switch ((cache_ptr->resize_ctl).incr_mode) { case H5C_incr__off: @@ -122,8 +122,6 @@ H5CS__get_stack(void) * Programmer: Quincey Koziol * Thursday, February 6, 2003 * - * Modifications: - * *------------------------------------------------------------------------- */ herr_t @@ -211,8 +209,6 @@ H5CS_push(const char *func_name) * Programmer: Quincey Koziol * Thursday, February 6, 2003 * - * Modifications: - * *------------------------------------------------------------------------- */ herr_t diff --git a/src/H5Cdbg.c b/src/H5Cdbg.c index 87b81dc..7de25d4 100644 --- a/src/H5Cdbg.c +++ b/src/H5Cdbg.c @@ -517,11 +517,11 @@ H5C_stats(H5C_t *cache_ptr, const char *cache_name, int32_t aggregate_max_pins = 0; double hit_rate; double prefetch_use_rate; - double average_successful_search_depth = 0.0f; - double average_failed_search_depth = 0.0f; - double average_entries_skipped_per_calls_to_msic = 0.0f; - double average_dirty_pf_entries_skipped_per_call_to_msic = 0.0f; - double average_entries_scanned_per_calls_to_msic = 0.0f; + double average_successful_search_depth = 0.0; + double average_failed_search_depth = 0.0; + double average_entries_skipped_per_calls_to_msic = 0.0; + double average_dirty_pf_entries_skipped_per_call_to_msic = 0.0; + double average_entries_scanned_per_calls_to_msic = 0.0; #endif /* H5C_COLLECT_CACHE_STATS */ herr_t ret_value = SUCCEED; /* Return value */ @@ -580,9 +580,9 @@ H5C_stats(H5C_t *cache_ptr, const char *cache_name, } /* end for */ if ((total_hits > 0) || (total_misses > 0)) - hit_rate = (double)100.0f * ((double)(total_hits)) / ((double)(total_hits + total_misses)); + hit_rate = 100.0 * ((double)(total_hits)) / ((double)(total_hits + total_misses)); else - hit_rate = 0.0f; + hit_rate = 0.0; if (cache_ptr->successful_ht_searches > 0) average_successful_search_depth = ((double)(cache_ptr->total_successful_ht_search_depth)) / @@ -718,10 +718,9 @@ H5C_stats(H5C_t *cache_ptr, const char *cache_name, (long long)(cache_ptr->evictions[H5AC_PREFETCHED_ENTRY_ID])); if (cache_ptr->prefetches > 0) - prefetch_use_rate = - (double)100.0f * ((double)(cache_ptr->prefetch_hits)) / ((double)(cache_ptr->prefetches)); + prefetch_use_rate = 100.0 * ((double)(cache_ptr->prefetch_hits)) / ((double)(cache_ptr->prefetches)); else - prefetch_use_rate = 0.0f; + prefetch_use_rate = 0.0; HDfprintf(stdout, "%s prefetched entry use rate = %lf\n", cache_ptr->prefix, prefetch_use_rate); @@ -746,10 +745,10 @@ H5C_stats(H5C_t *cache_ptr, const char *cache_name, ((cache_ptr->class_table_ptr))[i]->name); if ((cache_ptr->hits[i] > 0) || (cache_ptr->misses[i] > 0)) - hit_rate = (double)100.0f * ((double)(cache_ptr->hits[i])) / + hit_rate = 100.0 * ((double)(cache_ptr->hits[i])) / ((double)(cache_ptr->hits[i] + cache_ptr->misses[i])); else - hit_rate = 0.0f; + hit_rate = 0.0; HDfprintf(stdout, "%s hits / misses / hit_rate = %ld / %ld / %f\n", cache_ptr->prefix, (long)(cache_ptr->hits[i]), (long)(cache_ptr->misses[i]), hit_rate); diff --git a/src/H5Cimage.c b/src/H5Cimage.c index 91d23c4..d56aafc 100644 --- a/src/H5Cimage.c +++ b/src/H5Cimage.c @@ -971,15 +971,14 @@ H5C_image_stats(H5C_t *cache_ptr, hbool_t H5_ATTR_UNUSED print_header) } /* end for */ if ((total_hits > 0) || (total_misses > 0)) - hit_rate = (double)100.0f * ((double)(total_hits)) / ((double)(total_hits + total_misses)); + hit_rate = 100.0 * ((double)(total_hits)) / ((double)(total_hits + total_misses)); else - hit_rate = 0.0f; + hit_rate = 0.0; if (cache_ptr->prefetches > 0) - prefetch_use_rate = - (double)100.0f * ((double)(cache_ptr->prefetch_hits)) / ((double)(cache_ptr->prefetches)); + prefetch_use_rate = 100.0 * ((double)(cache_ptr->prefetch_hits)) / ((double)(cache_ptr->prefetches)); else - prefetch_use_rate = 0.0f; + prefetch_use_rate = 0.0; if (print_header) { HDfprintf(stdout, "\nhit prefetches prefetch image pf hit\n"); diff --git a/src/H5Clog.h b/src/H5Clog.h index bd5c413..790a073 100644 --- a/src/H5Clog.h +++ b/src/H5Clog.h @@ -79,10 +79,10 @@ typedef struct H5C_log_class_t { /* Logging information */ struct H5C_log_info_t { - hbool_t enabled; /* Was the logging set up? */ - hbool_t logging; /* Are we currently logging? */ - H5C_log_class_t *cls; /* Callbacks for writing log messages */ - void * udata; /* Log-specific data */ + hbool_t enabled; /* Was the logging set up? */ + hbool_t logging; /* Are we currently logging? */ + const H5C_log_class_t *cls; /* Callbacks for writing log messages */ + void * udata; /* Log-specific data */ }; /*****************************/ diff --git a/src/H5Clog_json.c b/src/H5Clog_json.c index 731d741..18323ca 100644 --- a/src/H5Clog_json.c +++ b/src/H5Clog_json.c @@ -118,32 +118,32 @@ static herr_t H5C__json_write_remove_entry_log_msg(void *udata, const H5C_cache_ /* Note that there's no cache set up call since that's the * place where this struct is wired into the cache. */ -static H5C_log_class_t H5C_json_log_class_g = {"json", - H5C__json_tear_down_logging, - NULL, /* start logging */ - NULL, /* stop logging */ - H5C__json_write_start_log_msg, - H5C__json_write_stop_log_msg, - H5C__json_write_create_cache_log_msg, - H5C__json_write_destroy_cache_log_msg, - H5C__json_write_evict_cache_log_msg, - H5C__json_write_expunge_entry_log_msg, - H5C__json_write_flush_cache_log_msg, - H5C__json_write_insert_entry_log_msg, - H5C__json_write_mark_entry_dirty_log_msg, - H5C__json_write_mark_entry_clean_log_msg, - H5C__json_write_mark_unserialized_entry_log_msg, - H5C__json_write_mark_serialized_entry_log_msg, - H5C__json_write_move_entry_log_msg, - H5C__json_write_pin_entry_log_msg, - H5C__json_write_create_fd_log_msg, - H5C__json_write_protect_entry_log_msg, - H5C__json_write_resize_entry_log_msg, - H5C__json_write_unpin_entry_log_msg, - H5C__json_write_destroy_fd_log_msg, - H5C__json_write_unprotect_entry_log_msg, - H5C__json_write_set_cache_config_log_msg, - H5C__json_write_remove_entry_log_msg}; +static const H5C_log_class_t H5C_json_log_class_g = {"json", + H5C__json_tear_down_logging, + NULL, /* start logging */ + NULL, /* stop logging */ + H5C__json_write_start_log_msg, + H5C__json_write_stop_log_msg, + H5C__json_write_create_cache_log_msg, + H5C__json_write_destroy_cache_log_msg, + H5C__json_write_evict_cache_log_msg, + H5C__json_write_expunge_entry_log_msg, + H5C__json_write_flush_cache_log_msg, + H5C__json_write_insert_entry_log_msg, + H5C__json_write_mark_entry_dirty_log_msg, + H5C__json_write_mark_entry_clean_log_msg, + H5C__json_write_mark_unserialized_entry_log_msg, + H5C__json_write_mark_serialized_entry_log_msg, + H5C__json_write_move_entry_log_msg, + H5C__json_write_pin_entry_log_msg, + H5C__json_write_create_fd_log_msg, + H5C__json_write_protect_entry_log_msg, + H5C__json_write_resize_entry_log_msg, + H5C__json_write_unpin_entry_log_msg, + H5C__json_write_destroy_fd_log_msg, + H5C__json_write_unprotect_entry_log_msg, + H5C__json_write_set_cache_config_log_msg, + H5C__json_write_remove_entry_log_msg}; /*------------------------------------------------------------------------- * Function: H5C__json_write_log_message diff --git a/src/H5Clog_trace.c b/src/H5Clog_trace.c index c30f79e..d33d1b0 100644 --- a/src/H5Clog_trace.c +++ b/src/H5Clog_trace.c @@ -113,32 +113,32 @@ static herr_t H5C__trace_write_remove_entry_log_msg(void *udata, const H5C_cache /* Note that there's no cache set up call since that's the * place where this struct is wired into the cache. */ -static H5C_log_class_t H5C_trace_log_class_g = {"trace", - H5C__trace_tear_down_logging, - NULL, /* start logging */ - NULL, /* stop logging */ - NULL, /* write start message */ - NULL, /* write stop message */ - NULL, /* write create cache message */ - NULL, /* write destroy cache message */ - NULL, /* write evict cache message */ - H5C__trace_write_expunge_entry_log_msg, - H5C__trace_write_flush_cache_log_msg, - H5C__trace_write_insert_entry_log_msg, - H5C__trace_write_mark_entry_dirty_log_msg, - H5C__trace_write_mark_entry_clean_log_msg, - H5C__trace_write_mark_unserialized_entry_log_msg, - H5C__trace_write_mark_serialized_entry_log_msg, - H5C__trace_write_move_entry_log_msg, - H5C__trace_write_pin_entry_log_msg, - H5C__trace_write_create_fd_log_msg, - H5C__trace_write_protect_entry_log_msg, - H5C__trace_write_resize_entry_log_msg, - H5C__trace_write_unpin_entry_log_msg, - H5C__trace_write_destroy_fd_log_msg, - H5C__trace_write_unprotect_entry_log_msg, - H5C__trace_write_set_cache_config_log_msg, - H5C__trace_write_remove_entry_log_msg}; +static const H5C_log_class_t H5C_trace_log_class_g = {"trace", + H5C__trace_tear_down_logging, + NULL, /* start logging */ + NULL, /* stop logging */ + NULL, /* write start message */ + NULL, /* write stop message */ + NULL, /* write create cache message */ + NULL, /* write destroy cache message */ + NULL, /* write evict cache message */ + H5C__trace_write_expunge_entry_log_msg, + H5C__trace_write_flush_cache_log_msg, + H5C__trace_write_insert_entry_log_msg, + H5C__trace_write_mark_entry_dirty_log_msg, + H5C__trace_write_mark_entry_clean_log_msg, + H5C__trace_write_mark_unserialized_entry_log_msg, + H5C__trace_write_mark_serialized_entry_log_msg, + H5C__trace_write_move_entry_log_msg, + H5C__trace_write_pin_entry_log_msg, + H5C__trace_write_create_fd_log_msg, + H5C__trace_write_protect_entry_log_msg, + H5C__trace_write_resize_entry_log_msg, + H5C__trace_write_unpin_entry_log_msg, + H5C__trace_write_destroy_fd_log_msg, + H5C__trace_write_unprotect_entry_log_msg, + H5C__trace_write_set_cache_config_log_msg, + H5C__trace_write_remove_entry_log_msg}; /*------------------------------------------------------------------------- * Function: H5C__trace_write_log_message diff --git a/src/H5Cprivate.h b/src/H5Cprivate.h index 0c827c6..8ac78ae 100644 --- a/src/H5Cprivate.h +++ b/src/H5Cprivate.h @@ -109,20 +109,20 @@ #define H5C__CURR_CACHE_IMAGE_CTL_VER 1 /* Default configuration settings */ -#define H5C__DEF_AR_UPPER_THRESHHOLD 0.9999f -#define H5C__DEF_AR_LOWER_THRESHHOLD 0.9f +#define H5C__DEF_AR_UPPER_THRESHHOLD 0.9999 +#define H5C__DEF_AR_LOWER_THRESHHOLD 0.9 #define H5C__DEF_AR_MAX_SIZE ((size_t)(16 * 1024 * 1024)) #define H5C__DEF_AR_INIT_SIZE ((size_t)(1 * 1024 * 1024)) #define H5C__DEF_AR_MIN_SIZE ((size_t)(1 * 1024 * 1024)) -#define H5C__DEF_AR_MIN_CLEAN_FRAC 0.5f -#define H5C__DEF_AR_INCREMENT 2.0f +#define H5C__DEF_AR_MIN_CLEAN_FRAC 0.5 +#define H5C__DEF_AR_INCREMENT 2.0 #define H5C__DEF_AR_MAX_INCREMENT ((size_t)(2 * 1024 * 1024)) -#define H5C__DEF_AR_FLASH_MULTIPLE 1.0f -#define H5C__DEV_AR_FLASH_THRESHOLD 0.25f -#define H5C__DEF_AR_DECREMENT 0.9f +#define H5C__DEF_AR_FLASH_MULTIPLE 1.0 +#define H5C__DEV_AR_FLASH_THRESHOLD 0.25 +#define H5C__DEF_AR_DECREMENT 0.9 #define H5C__DEF_AR_MAX_DECREMENT ((size_t)(1 * 1024 * 1024)) #define H5C__DEF_AR_EPCHS_B4_EVICT 3 -#define H5C__DEF_AR_EMPTY_RESERVE 0.05f +#define H5C__DEF_AR_EMPTY_RESERVE 0.05 #define H5C__MIN_AR_EPOCH_LENGTH 100 #define H5C__DEF_AR_EPOCH_LENGTH 50000 #define H5C__MAX_AR_EPOCH_LENGTH 1000000 @@ -24,6 +24,7 @@ #include "H5CXprivate.h" /* API Contexts */ #include "H5Dpkg.h" /* Datasets */ #include "H5Eprivate.h" /* Error handling */ +#include "H5ESprivate.h" /* Event Sets */ #include "H5FLprivate.h" /* Free lists */ #include "H5Iprivate.h" /* IDs */ #include "H5VLprivate.h" /* Virtual Object Layer */ @@ -42,6 +43,21 @@ /* Local Prototypes */ /********************/ +/* Helper routines for sync/async API calls */ +static hid_t H5D__create_api_common(hid_t loc_id, const char *name, hid_t type_id, hid_t space_id, + hid_t lcpl_id, hid_t dcpl_id, hid_t dapl_id, void **token_ptr, + H5VL_object_t **_vol_obj_ptr); +static hid_t H5D__open_api_common(hid_t loc_id, const char *name, hid_t dapl_id, void **token_ptr, + H5VL_object_t **_vol_obj_ptr); +static hid_t H5D__get_space_api_common(hid_t dset_id, void **token_ptr, H5VL_object_t **_vol_obj_ptr); +static herr_t H5D__read_api_common(hid_t dset_id, hid_t mem_type_id, hid_t mem_space_id, hid_t file_space_id, + hid_t dxpl_id, void *buf, void **token_ptr, H5VL_object_t **_vol_obj_ptr); +static herr_t H5D__write_api_common(hid_t dset_id, hid_t mem_type_id, hid_t mem_space_id, hid_t file_space_id, + hid_t dxpl_id, const void *buf, void **token_ptr, + H5VL_object_t **_vol_obj_ptr); +static herr_t H5D__set_extent_api_common(hid_t dset_id, const hsize_t size[], void **token_ptr, + H5VL_object_t **_vol_obj_ptr); + /*********************/ /* Package Variables */ /*********************/ @@ -64,42 +80,27 @@ H5FL_BLK_EXTERN(type_conv); /*******************/ /*------------------------------------------------------------------------- - * Function: H5Dcreate2 - * - * Purpose: Creates a new dataset named NAME at LOC_ID, opens the - * dataset for access, and associates with that dataset constant - * and initial persistent properties including the type of each - * datapoint as stored in the file (TYPE_ID), the size of the - * dataset (SPACE_ID), and other initial miscellaneous - * properties (DCPL_ID). + * Function: H5D__create_api_common * - * All arguments are copied into the dataset, so the caller is - * allowed to derive new types, dataspaces, and creation - * parameters from the old ones and reuse them in calls to - * create other datasets. - * - * Return: Success: The object ID of the new dataset. At this - * point, the dataset is ready to receive its - * raw data. Attempting to read raw data from - * the dataset will probably return the fill - * value. The dataset should be closed when the - * caller is no longer interested in it. + * Purpose: This is the common function for creating HDF5 datasets. * + * Return: Success: A dataset ID * Failure: H5I_INVALID_HID * *------------------------------------------------------------------------- */ -hid_t -H5Dcreate2(hid_t loc_id, const char *name, hid_t type_id, hid_t space_id, hid_t lcpl_id, hid_t dcpl_id, - hid_t dapl_id) +static hid_t +H5D__create_api_common(hid_t loc_id, const char *name, hid_t type_id, hid_t space_id, hid_t lcpl_id, + hid_t dcpl_id, hid_t dapl_id, void **token_ptr, H5VL_object_t **_vol_obj_ptr) { - void * dset = NULL; /* New dataset's info */ - H5VL_object_t * vol_obj = NULL; /* object of loc_id */ - H5VL_loc_params_t loc_params; - hid_t ret_value = H5I_INVALID_HID; /* Return value */ + void * dset = NULL; /* New dataset's info */ + H5VL_object_t * tmp_vol_obj = NULL; /* Object for loc_id */ + H5VL_object_t **vol_obj_ptr = + (_vol_obj_ptr ? _vol_obj_ptr : &tmp_vol_obj); /* Ptr to object ptr for loc_id */ + H5VL_loc_params_t loc_params; /* Location parameters for object access */ + hid_t ret_value = H5I_INVALID_HID; /* Return value */ - FUNC_ENTER_API(H5I_INVALID_HID) - H5TRACE7("i", "i*siiiii", loc_id, name, type_id, space_id, lcpl_id, dcpl_id, dapl_id); + FUNC_ENTER_STATIC /* Check arguments */ if (!name) @@ -107,6 +108,10 @@ H5Dcreate2(hid_t loc_id, const char *name, hid_t type_id, hid_t space_id, hid_t if (!*name) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, H5I_INVALID_HID, "name parameter cannot be an empty string") + /* Set up object access arguments */ + if (H5VL_setup_acc_args(loc_id, H5P_CLS_DACC, TRUE, &dapl_id, vol_obj_ptr, &loc_params) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTSET, H5I_INVALID_HID, "can't set object access arguments") + /* Get link creation property list */ if (H5P_DEFAULT == lcpl_id) lcpl_id = H5P_LINK_CREATE_DEFAULT; @@ -126,36 +131,115 @@ H5Dcreate2(hid_t loc_id, const char *name, hid_t type_id, hid_t space_id, hid_t /* Set the LCPL for the API context */ H5CX_set_lcpl(lcpl_id); - /* Verify access property list and set up collective metadata if appropriate */ - if (H5CX_set_apl(&dapl_id, H5P_CLS_DACC, loc_id, TRUE) < 0) - HGOTO_ERROR(H5E_DATASET, H5E_CANTSET, H5I_INVALID_HID, "can't set access property list info") - - /* Get the location object */ - if (NULL == (vol_obj = (H5VL_object_t *)H5I_object(loc_id))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5I_INVALID_HID, "invalid location identifier") - - /* Set location parameters */ - loc_params.type = H5VL_OBJECT_BY_SELF; - loc_params.obj_type = H5I_get_type(loc_id); - /* Create the dataset */ - if (NULL == (dset = H5VL_dataset_create(vol_obj, &loc_params, name, lcpl_id, type_id, space_id, dcpl_id, - dapl_id, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL))) + if (NULL == (dset = H5VL_dataset_create(*vol_obj_ptr, &loc_params, name, lcpl_id, type_id, space_id, + dcpl_id, dapl_id, H5P_DATASET_XFER_DEFAULT, token_ptr))) HGOTO_ERROR(H5E_DATASET, H5E_CANTCREATE, H5I_INVALID_HID, "unable to create dataset") /* Get an ID for the dataset */ - if ((ret_value = H5VL_register(H5I_DATASET, dset, vol_obj->connector, TRUE)) < 0) + if ((ret_value = H5VL_register(H5I_DATASET, dset, (*vol_obj_ptr)->connector, TRUE)) < 0) HGOTO_ERROR(H5E_DATASET, H5E_CANTREGISTER, H5I_INVALID_HID, "unable to register dataset") done: if (H5I_INVALID_HID == ret_value) - if (dset && H5VL_dataset_close(vol_obj, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0) + if (dset && H5VL_dataset_close(*vol_obj_ptr, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0) HDONE_ERROR(H5E_DATASET, H5E_CLOSEERROR, H5I_INVALID_HID, "unable to release dataset") + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5D__create_api_common() */ + +/*------------------------------------------------------------------------- + * Function: H5Dcreate2 + * + * Purpose: Creates a new dataset named NAME at LOC_ID, opens the + * dataset for access, and associates with that dataset constant + * and initial persistent properties including the type of each + * datapoint as stored in the file (TYPE_ID), the size of the + * dataset (SPACE_ID), and other initial miscellaneous + * properties (DCPL_ID). + * + * All arguments are copied into the dataset, so the caller is + * allowed to derive new types, dataspaces, and creation + * parameters from the old ones and reuse them in calls to + * create other datasets. + * + * Return: Success: The object ID of the new dataset. At this + * point, the dataset is ready to receive its + * raw data. Attempting to read raw data from + * the dataset will probably return the fill + * value. The dataset should be closed when the + * caller is no longer interested in it. + * + * Failure: H5I_INVALID_HID + * + *------------------------------------------------------------------------- + */ +hid_t +H5Dcreate2(hid_t loc_id, const char *name, hid_t type_id, hid_t space_id, hid_t lcpl_id, hid_t dcpl_id, + hid_t dapl_id) +{ + hid_t ret_value = H5I_INVALID_HID; /* Return value */ + + FUNC_ENTER_API(H5I_INVALID_HID) + H5TRACE7("i", "i*siiiii", loc_id, name, type_id, space_id, lcpl_id, dcpl_id, dapl_id); + + /* Create the dataset synchronously */ + if ((ret_value = H5D__create_api_common(loc_id, name, type_id, space_id, lcpl_id, dcpl_id, dapl_id, NULL, + NULL)) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTCREATE, H5I_INVALID_HID, "unable to synchronously create dataset") + +done: FUNC_LEAVE_API(ret_value) } /* end H5Dcreate2() */ /*------------------------------------------------------------------------- + * Function: H5Dcreate_async + * + * Purpose: Asynchronous version of H5Dcreate + * + * Return: Success: A dataset ID + * Failure: H5I_INVALID_HID + * + *------------------------------------------------------------------------- + */ +hid_t +H5Dcreate_async(const char *app_file, const char *app_func, unsigned app_line, hid_t loc_id, const char *name, + hid_t type_id, hid_t space_id, hid_t lcpl_id, hid_t dcpl_id, hid_t dapl_id, hid_t es_id) +{ + H5VL_object_t *vol_obj = NULL; /* Object for loc_id */ + void * token = NULL; /* Request token for async operation */ + void ** token_ptr = H5_REQUEST_NULL; /* Pointer to request token for async operation */ + hid_t ret_value = H5I_INVALID_HID; /* Return value */ + + FUNC_ENTER_API(H5I_INVALID_HID) + H5TRACE11("i", "*s*sIui*siiiiii", app_file, app_func, app_line, loc_id, name, type_id, space_id, lcpl_id, + dcpl_id, dapl_id, es_id); + + /* Set up request token pointer for asynchronous operation */ + if (H5ES_NONE != es_id) + token_ptr = &token; /* Point at token for VOL connector to set up */ + + /* Create the dataset asynchronously */ + if ((ret_value = H5D__create_api_common(loc_id, name, type_id, space_id, lcpl_id, dcpl_id, dapl_id, + token_ptr, &vol_obj)) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTCREATE, H5I_INVALID_HID, "unable to asynchronously create dataset") + + /* If a token was created, add the token to the event set */ + if (NULL != token) + /* clang-format off */ + if (H5ES_insert(es_id, vol_obj->connector, token, + H5ARG_TRACE11(FUNC, "*s*sIui*siiiiii", app_file, app_func, app_line, loc_id, name, type_id, space_id, lcpl_id, dcpl_id, dapl_id, es_id)) < 0) { + /* clang-format on */ + if (H5I_dec_app_ref_always_close(ret_value) < 0) + HDONE_ERROR(H5E_DATASET, H5E_CANTDEC, H5I_INVALID_HID, "can't decrement count on dataset ID") + HGOTO_ERROR(H5E_DATASET, H5E_CANTINSERT, H5I_INVALID_HID, "can't insert token into event set") + } /* end if */ + +done: + FUNC_LEAVE_API(ret_value) +} /* end H5Dcreate_async() */ + +/*------------------------------------------------------------------------- * Function: H5Dcreate_anon * * Purpose: Creates a new dataset named NAME at LOC_ID, opens the @@ -239,30 +323,27 @@ done: } /* end H5Dcreate_anon() */ /*------------------------------------------------------------------------- - * Function: H5Dopen2 - * - * Purpose: Finds a dataset named NAME at LOC_ID, opens it, and returns - * its ID. The dataset should be close when the caller is no - * longer interested in it. + * Function: H5D__open_api_common * - * Takes a dataset access property list + * Purpose: This is the common function for opening a dataset * * Return: Success: Object ID of the dataset - * * Failure: H5I_INVALID_HID * *------------------------------------------------------------------------- */ -hid_t -H5Dopen2(hid_t loc_id, const char *name, hid_t dapl_id) +static hid_t +H5D__open_api_common(hid_t loc_id, const char *name, hid_t dapl_id, void **token_ptr, + H5VL_object_t **_vol_obj_ptr) { - void * dset = NULL; /* dset object from VOL connector */ - H5VL_object_t * vol_obj = NULL; /* object of loc_id */ - H5VL_loc_params_t loc_params; - hid_t ret_value = H5I_INVALID_HID; /* Return value */ + void * dset = NULL; /* dset object from VOL connector */ + H5VL_object_t * tmp_vol_obj = NULL; /* Object for loc_id */ + H5VL_object_t **vol_obj_ptr = + (_vol_obj_ptr ? _vol_obj_ptr : &tmp_vol_obj); /* Ptr to object ptr for loc_id */ + H5VL_loc_params_t loc_params; /* Location parameters for object access */ + hid_t ret_value = H5I_INVALID_HID; /* Return value */ - FUNC_ENTER_API(H5I_INVALID_HID) - H5TRACE3("i", "i*si", loc_id, name, dapl_id); + FUNC_ENTER_STATIC /* Check args */ if (!name) @@ -270,36 +351,104 @@ H5Dopen2(hid_t loc_id, const char *name, hid_t dapl_id) if (!*name) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, H5I_INVALID_HID, "name parameter cannot be an empty string") - /* Verify access property list and set up collective metadata if appropriate */ - if (H5CX_set_apl(&dapl_id, H5P_CLS_DACC, loc_id, FALSE) < 0) - HGOTO_ERROR(H5E_DATASET, H5E_CANTSET, H5I_INVALID_HID, "can't set access property list info") - - /* get the location object */ - if (NULL == (vol_obj = (H5VL_object_t *)H5I_object(loc_id))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5I_INVALID_HID, "invalid location identifier") - - /* Set the location parameters */ - loc_params.type = H5VL_OBJECT_BY_SELF; - loc_params.obj_type = H5I_get_type(loc_id); + /* Set up object access arguments */ + if (H5VL_setup_acc_args(loc_id, H5P_CLS_DACC, FALSE, &dapl_id, vol_obj_ptr, &loc_params) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTSET, H5I_INVALID_HID, "can't set object access arguments") /* Open the dataset */ - if (NULL == (dset = H5VL_dataset_open(vol_obj, &loc_params, name, dapl_id, H5P_DATASET_XFER_DEFAULT, - H5_REQUEST_NULL))) + if (NULL == (dset = H5VL_dataset_open(*vol_obj_ptr, &loc_params, name, dapl_id, H5P_DATASET_XFER_DEFAULT, + token_ptr))) HGOTO_ERROR(H5E_DATASET, H5E_CANTOPENOBJ, H5I_INVALID_HID, "unable to open dataset") /* Register an atom for the dataset */ - if ((ret_value = H5VL_register(H5I_DATASET, dset, vol_obj->connector, TRUE)) < 0) - HGOTO_ERROR(H5E_DATASET, H5E_CANTREGISTER, H5I_INVALID_HID, "can't register dataset atom") + if ((ret_value = H5VL_register(H5I_DATASET, dset, (*vol_obj_ptr)->connector, TRUE)) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTREGISTER, H5I_INVALID_HID, "can't register dataset ID") done: if (H5I_INVALID_HID == ret_value) - if (dset && H5VL_dataset_close(vol_obj, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0) + if (dset && H5VL_dataset_close(*vol_obj_ptr, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0) HDONE_ERROR(H5E_DATASET, H5E_CLOSEERROR, H5I_INVALID_HID, "unable to release dataset") + FUNC_LEAVE_NOAPI(ret_value) +} /* H5D__open_api_common() */ + +/*------------------------------------------------------------------------- + * Function: H5Dopen2 + * + * Purpose: Finds a dataset named NAME at LOC_ID, opens it, and returns + * its ID. The dataset should be close when the caller is no + * longer interested in it. + * + * Takes a dataset access property list + * + * Return: Success: Object ID of the dataset + * + * Failure: H5I_INVALID_HID + * + *------------------------------------------------------------------------- + */ +hid_t +H5Dopen2(hid_t loc_id, const char *name, hid_t dapl_id) +{ + hid_t ret_value = H5I_INVALID_HID; /* Return value */ + + FUNC_ENTER_API(H5I_INVALID_HID) + H5TRACE3("i", "i*si", loc_id, name, dapl_id); + + /* Open the dataset synchronously */ + if ((ret_value = H5D__open_api_common(loc_id, name, dapl_id, NULL, NULL)) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTOPENOBJ, H5I_INVALID_HID, "unable to synchronously open dataset") + +done: FUNC_LEAVE_API(ret_value) } /* end H5Dopen2() */ /*------------------------------------------------------------------------- + * Function: H5Dopen_async + * + * Purpose: Asynchronous version of H5Dopen2 + * + * Return: Success: A group ID + * Failure: H5I_INVALID_HID + * + *------------------------------------------------------------------------- + */ +hid_t +H5Dopen_async(const char *app_file, const char *app_func, unsigned app_line, hid_t loc_id, const char *name, + hid_t dapl_id, hid_t es_id) +{ + H5VL_object_t *vol_obj = NULL; /* Object for loc_id */ + void * token = NULL; /* Request token for async operation */ + void ** token_ptr = H5_REQUEST_NULL; /* Pointer to request token for async operation */ + hid_t ret_value = H5I_INVALID_HID; /* Return value */ + + FUNC_ENTER_API(H5I_INVALID_HID) + H5TRACE7("i", "*s*sIui*sii", app_file, app_func, app_line, loc_id, name, dapl_id, es_id); + + /* Set up request token pointer for asynchronous operation */ + if (H5ES_NONE != es_id) + token_ptr = &token; /* Point at token for VOL connector to set up */ + + /* Open the dataset asynchronously */ + if ((ret_value = H5D__open_api_common(loc_id, name, dapl_id, token_ptr, &vol_obj)) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTOPENOBJ, H5I_INVALID_HID, "unable to asynchronously open dataset") + + /* If a token was created, add the token to the event set */ + if (NULL != token) + /* clang-format off */ + if (H5ES_insert(es_id, vol_obj->connector, token, + H5ARG_TRACE7(FUNC, "*s*sIui*sii", app_file, app_func, app_line, loc_id, name, dapl_id, es_id)) < 0) { + /* clang-format on */ + if (H5I_dec_app_ref_always_close(ret_value) < 0) + HDONE_ERROR(H5E_DATASET, H5E_CANTDEC, H5I_INVALID_HID, "can't decrement count on dataset ID") + HGOTO_ERROR(H5E_DATASET, H5E_CANTINSERT, H5I_INVALID_HID, "can't insert token into event set") + } /* end if */ + +done: + FUNC_LEAVE_API(ret_value) +} /* end H5Dopen_async() */ + +/*------------------------------------------------------------------------- * Function: H5Dclose * * Purpose: Closes access to a dataset and releases resources used by @@ -333,6 +482,100 @@ done: } /* end H5Dclose() */ /*------------------------------------------------------------------------- + * Function: H5Dclose_async + * + * Purpose: Asynchronous version of H5Dclose + * + * Return: Non-negative on success/Negative on failure + * + *------------------------------------------------------------------------- + */ +herr_t +H5Dclose_async(const char *app_file, const char *app_func, unsigned app_line, hid_t dset_id, hid_t es_id) +{ + void * token = NULL; /* Request token for async operation */ + void ** token_ptr = H5_REQUEST_NULL; /* Pointer to request token for async operation */ + H5VL_object_t *vol_obj = NULL; /* VOL object of dset_id */ + H5VL_t * connector = NULL; /* VOL connector */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_API(FAIL) + H5TRACE5("e", "*s*sIuii", app_file, app_func, app_line, dset_id, es_id); + + /* Check args */ + if (H5I_DATASET != H5I_get_type(dset_id)) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a dataset ID") + + /* Get dataset object's connector */ + if (NULL == (vol_obj = H5VL_vol_object(dset_id))) + HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't get VOL object for dataset") + + /* Prepare for possible asynchronous operation */ + if (H5ES_NONE != es_id) { + /* Increase connector's refcount, so it doesn't get closed if closing + * the dataset closes the file */ + connector = vol_obj->connector; + H5VL_conn_inc_rc(connector); + + /* Point at token for operation to set up */ + token_ptr = &token; + } /* end if */ + + /* Decrement the counter on the dataset. It will be freed if the count + * reaches zero. + */ + if (H5I_dec_app_ref_always_close_async(dset_id, token_ptr) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTDEC, FAIL, "can't decrement count on dataset ID") + + /* If a token was created, add the token to the event set */ + if (NULL != token) + /* clang-format off */ + if (H5ES_insert(es_id, vol_obj->connector, token, + H5ARG_TRACE5(FUNC, "*s*sIuii", app_file, app_func, app_line, dset_id, es_id)) < 0) + /* clang-format on */ + HGOTO_ERROR(H5E_DATASET, H5E_CANTINSERT, FAIL, "can't insert token into event set") + +done: + if (connector && H5VL_conn_dec_rc(connector) < 0) + HDONE_ERROR(H5E_DATASET, H5E_CANTDEC, FAIL, "can't decrement ref count on connector") + + FUNC_LEAVE_API(ret_value) +} /* end H5Dclose_async() */ + +/*------------------------------------------------------------------------- + * Function: H5D__get_space_api_common + * + * Purpose: This is the common function for getting a dataset's dataspace + * + * Return: Success: ID for a copy of the dataspace. + * Failure: H5I_INVALID_HID + * + *------------------------------------------------------------------------- + */ +static hid_t +H5D__get_space_api_common(hid_t dset_id, void **token_ptr, H5VL_object_t **_vol_obj_ptr) +{ + H5VL_object_t * tmp_vol_obj = NULL; /* Object for loc_id */ + H5VL_object_t **vol_obj_ptr = + (_vol_obj_ptr ? _vol_obj_ptr : &tmp_vol_obj); /* Ptr to object ptr for loc_id */ + hid_t ret_value = H5I_INVALID_HID; /* Return value */ + + FUNC_ENTER_STATIC + + /* Check args */ + if (NULL == (*vol_obj_ptr = (H5VL_object_t *)H5I_object_verify(dset_id, H5I_DATASET))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5I_INVALID_HID, "invalid dataset identifier") + + /* Get the dataspace */ + if (H5VL_dataset_get(*vol_obj_ptr, H5VL_DATASET_GET_SPACE, H5P_DATASET_XFER_DEFAULT, token_ptr, + &ret_value) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, H5I_INVALID_HID, "unable to get dataspace") + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* H5D__get_space_api_common() */ + +/*------------------------------------------------------------------------- * Function: H5Dget_space * * Purpose: Returns a copy of the file dataspace for a dataset. @@ -348,26 +591,68 @@ done: hid_t H5Dget_space(hid_t dset_id) { - H5VL_object_t *vol_obj = NULL; /* Dataset structure */ - hid_t ret_value = H5I_INVALID_HID; /* Return value */ + hid_t ret_value = H5I_INVALID_HID; /* Return value */ FUNC_ENTER_API(H5I_INVALID_HID) H5TRACE1("i", "i", dset_id); - /* Check args */ - if (NULL == (vol_obj = (H5VL_object_t *)H5I_object_verify(dset_id, H5I_DATASET))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5I_INVALID_HID, "invalid dataset identifier") - - /* Get the dataspace */ - if (H5VL_dataset_get(vol_obj, H5VL_DATASET_GET_SPACE, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL, - &ret_value) < 0) - HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, H5I_INVALID_HID, "unable to get dataspace") + /* Get the dataset's dataspace synchronously */ + if ((ret_value = H5D__get_space_api_common(dset_id, NULL, NULL)) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, H5I_INVALID_HID, "unable to synchronously get dataspace") done: FUNC_LEAVE_API(ret_value) } /* end H5Dget_space() */ /*------------------------------------------------------------------------- + * Function: H5Dget_space_async + * + * Purpose: Asynchronous version of H5Dget_space + * + * Return: Success: ID for a copy of the dataspace. The data + * space should be released by calling + * H5Sclose(). + * + * Failure: H5I_INVALID_HID + * + *------------------------------------------------------------------------- + */ +hid_t +H5Dget_space_async(const char *app_file, const char *app_func, unsigned app_line, hid_t dset_id, hid_t es_id) +{ + H5VL_object_t *vol_obj = NULL; /* Object for loc_id */ + void * token = NULL; /* Request token for async operation */ + void ** token_ptr = H5_REQUEST_NULL; /* Pointer to request token for async operation */ + hid_t ret_value = H5I_INVALID_HID; /* Return value */ + + FUNC_ENTER_API(H5I_INVALID_HID) + H5TRACE5("i", "*s*sIuii", app_file, app_func, app_line, dset_id, es_id); + + /* Set up request token pointer for asynchronous operation */ + if (H5ES_NONE != es_id) + token_ptr = &token; /* Point at token for VOL connector to set up */ + + /* Get the dataset's dataspace asynchronously */ + if ((ret_value = H5D__get_space_api_common(dset_id, token_ptr, &vol_obj)) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, H5I_INVALID_HID, "unable to asynchronously get dataspace") + + /* If a token was created, add the token to the event set */ + if (NULL != token) + /* clang-format off */ + if (H5ES_insert(es_id, vol_obj->connector, token, + H5ARG_TRACE5(FUNC, "*s*sIuii", app_file, app_func, app_line, dset_id, es_id)) < 0) { + /* clang-format on */ + if (H5I_dec_app_ref(ret_value) < 0) + HDONE_ERROR(H5E_DATASET, H5E_CANTDEC, H5I_INVALID_HID, + "can't decrement count on dataspace ID") + HGOTO_ERROR(H5E_DATASET, H5E_CANTINSERT, H5I_INVALID_HID, "can't insert token into event set") + } /* end if */ + +done: + FUNC_LEAVE_API(ret_value) +} /* end H5Dget_space_async() */ + +/*------------------------------------------------------------------------- * Function: H5Dget_space_status * * Purpose: Returns the status of dataspace allocation. @@ -597,6 +882,384 @@ done: } /* end H5Dget_offset() */ /*------------------------------------------------------------------------- + * Function: H5D__read_api_common + * + * Purpose: Common helper routine for sync/async dataset read operations. + * + * Return: SUCCEED/FAIL + * + *------------------------------------------------------------------------- + */ +static herr_t +H5D__read_api_common(hid_t dset_id, hid_t mem_type_id, hid_t mem_space_id, hid_t file_space_id, hid_t dxpl_id, + void *buf, void **token_ptr, H5VL_object_t **_vol_obj_ptr) +{ + H5VL_object_t * tmp_vol_obj = NULL; /* Object for loc_id */ + H5VL_object_t **vol_obj_ptr = + (_vol_obj_ptr ? _vol_obj_ptr : &tmp_vol_obj); /* Ptr to object ptr for loc_id */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_STATIC + + /* Check arguments */ + if (mem_space_id < 0) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid memory dataspace ID") + if (file_space_id < 0) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid file dataspace ID") + + /* Get dataset pointer */ + if (NULL == (*vol_obj_ptr = (H5VL_object_t *)H5I_object_verify(dset_id, H5I_DATASET))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "dset_id is not a dataset ID") + + /* Get the default dataset transfer property list if the user didn't provide one */ + if (H5P_DEFAULT == dxpl_id) + dxpl_id = H5P_DATASET_XFER_DEFAULT; + else if (TRUE != H5P_isa_class(dxpl_id, H5P_DATASET_XFER)) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not xfer parms") + + /* Read the data */ + if (H5VL_dataset_read(*vol_obj_ptr, mem_type_id, mem_space_id, file_space_id, dxpl_id, buf, token_ptr) < + 0) + HGOTO_ERROR(H5E_DATASET, H5E_READERROR, FAIL, "can't read data") + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5D__read_api_common() */ + +/*------------------------------------------------------------------------- + * Function: H5Dread + * + * Purpose: Reads (part of) a DSET from the file into application + * memory BUF. The part of the dataset to read is defined with + * MEM_SPACE_ID and FILE_SPACE_ID. The data points are + * converted from their file type to the MEM_TYPE_ID specified. + * Additional miscellaneous data transfer properties can be + * passed to this function with the PLIST_ID argument. + * + * The FILE_SPACE_ID can be the constant H5S_ALL which indicates + * that the entire file dataspace is to be referenced. + * + * The MEM_SPACE_ID can be the constant H5S_ALL in which case + * the memory dataspace is the same as the file dataspace + * defined when the dataset was created. + * + * The number of elements in the memory dataspace must match + * the number of elements in the file dataspace. + * + * The PLIST_ID can be the constant H5P_DEFAULT in which + * case the default data transfer properties are used. + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Robb Matzke + * Thursday, December 4, 1997 + * + *------------------------------------------------------------------------- + */ +herr_t +H5Dread(hid_t dset_id, hid_t mem_type_id, hid_t mem_space_id, hid_t file_space_id, hid_t dxpl_id, + void *buf /*out*/) +{ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_API(FAIL) + H5TRACE6("e", "iiiiix", dset_id, mem_type_id, mem_space_id, file_space_id, dxpl_id, buf); + + /* Read the data */ + if (H5D__read_api_common(dset_id, mem_type_id, mem_space_id, file_space_id, dxpl_id, buf, NULL, NULL) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_READERROR, FAIL, "can't synchronously read data") + +done: + FUNC_LEAVE_API(ret_value) +} /* end H5Dread() */ + +/*------------------------------------------------------------------------- + * Function: H5Dread_async + * + * Purpose: Asynchronously read dataset elements. + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Houjun Tang + * Oct 15, 2019 + * + *------------------------------------------------------------------------- + */ +herr_t +H5Dread_async(const char *app_file, const char *app_func, unsigned app_line, hid_t dset_id, hid_t mem_type_id, + hid_t mem_space_id, hid_t file_space_id, hid_t dxpl_id, void *buf /*out*/, hid_t es_id) +{ + H5VL_object_t *vol_obj = NULL; /* Dataset VOL object */ + void * token = NULL; /* Request token for async operation */ + void ** token_ptr = H5_REQUEST_NULL; /* Pointer to request token for async operation */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_API(FAIL) + H5TRACE10("e", "*s*sIuiiiiixi", app_file, app_func, app_line, dset_id, mem_type_id, mem_space_id, + file_space_id, dxpl_id, buf, es_id); + + /* Set up request token pointer for asynchronous operation */ + if (H5ES_NONE != es_id) + token_ptr = &token; /* Point at token for VOL connector to set up */ + + /* Read the data */ + if (H5D__read_api_common(dset_id, mem_type_id, mem_space_id, file_space_id, dxpl_id, buf, token_ptr, + &vol_obj) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_READERROR, FAIL, "can't asynchronously read data") + + /* If a token was created, add the token to the event set */ + if (NULL != token) + /* clang-format off */ + if (H5ES_insert(es_id, vol_obj->connector, token, + H5ARG_TRACE10(FUNC, "*s*sIuiiiiixi", app_file, app_func, app_line, dset_id, mem_type_id, mem_space_id, file_space_id, dxpl_id, buf, es_id)) < 0) + /* clang-format on */ + HGOTO_ERROR(H5E_DATASET, H5E_CANTINSERT, FAIL, "can't insert token into event set") + +done: + FUNC_LEAVE_API(ret_value) +} /* end H5Dread_async() */ + +/*------------------------------------------------------------------------- + * Function: H5Dread_chunk + * + * Purpose: Reads an entire chunk from the file directly. + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Matthew Strong (GE Healthcare) + * 14 February 2016 + * + *--------------------------------------------------------------------------- + */ +herr_t +H5Dread_chunk(hid_t dset_id, hid_t dxpl_id, const hsize_t *offset, uint32_t *filters, void *buf) +{ + H5VL_object_t *vol_obj = NULL; + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_API(FAIL) + H5TRACE5("e", "ii*h*Iu*x", dset_id, dxpl_id, offset, filters, buf); + + /* Check arguments */ + if (NULL == (vol_obj = (H5VL_object_t *)H5I_object_verify(dset_id, H5I_DATASET))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "dset_id is not a dataset ID") + if (!buf) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "buf cannot be NULL") + if (!offset) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "offset cannot be NULL") + if (!filters) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "filters cannot be NULL") + + /* Get the default dataset transfer property list if the user didn't provide one */ + if (H5P_DEFAULT == dxpl_id) + dxpl_id = H5P_DATASET_XFER_DEFAULT; + else if (TRUE != H5P_isa_class(dxpl_id, H5P_DATASET_XFER)) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "dxpl_id is not a dataset transfer property list ID") + + /* Read the raw chunk */ + if (H5VL_dataset_optional(vol_obj, H5VL_NATIVE_DATASET_CHUNK_READ, dxpl_id, H5_REQUEST_NULL, offset, + filters, buf) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_READERROR, FAIL, "can't read unprocessed chunk data") + +done: + FUNC_LEAVE_API(ret_value) +} /* end H5Dread_chunk() */ + +/*------------------------------------------------------------------------- + * Function: H5D__write_api_common + * + * Purpose: Common helper routine for sync/async dataset write operations. + * + * Return: SUCCEED/FAIL + * + *------------------------------------------------------------------------- + */ +static herr_t +H5D__write_api_common(hid_t dset_id, hid_t mem_type_id, hid_t mem_space_id, hid_t file_space_id, + hid_t dxpl_id, const void *buf, void **token_ptr, H5VL_object_t **_vol_obj_ptr) +{ + H5VL_object_t * tmp_vol_obj = NULL; /* Object for loc_id */ + H5VL_object_t **vol_obj_ptr = + (_vol_obj_ptr ? _vol_obj_ptr : &tmp_vol_obj); /* Ptr to object ptr for loc_id */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_STATIC + + /* Check arguments */ + if (mem_space_id < 0) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid memory dataspace ID") + if (file_space_id < 0) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid file dataspace ID") + + /* Get dataset pointer */ + if (NULL == (*vol_obj_ptr = (H5VL_object_t *)H5I_object_verify(dset_id, H5I_DATASET))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "dset_id is not a dataset ID") + + /* Get the default dataset transfer property list if the user didn't provide one */ + if (H5P_DEFAULT == dxpl_id) + dxpl_id = H5P_DATASET_XFER_DEFAULT; + else if (TRUE != H5P_isa_class(dxpl_id, H5P_DATASET_XFER)) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not xfer parms") + + /* Write the data */ + if (H5VL_dataset_write(*vol_obj_ptr, mem_type_id, mem_space_id, file_space_id, dxpl_id, buf, token_ptr) < + 0) + HGOTO_ERROR(H5E_DATASET, H5E_WRITEERROR, FAIL, "can't write data") + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5D__write_api_common() */ + +/*------------------------------------------------------------------------- + * Function: H5Dwrite + * + * Purpose: Writes (part of) a DSET from application memory BUF to the + * file. The part of the dataset to write is defined with the + * MEM_SPACE_ID and FILE_SPACE_ID arguments. The data points + * are converted from their current type (MEM_TYPE_ID) to their + * file datatype. Additional miscellaneous data transfer + * properties can be passed to this function with the + * PLIST_ID argument. + * + * The FILE_SPACE_ID can be the constant H5S_ALL which indicates + * that the entire file dataspace is to be referenced. + * + * The MEM_SPACE_ID can be the constant H5S_ALL in which case + * the memory dataspace is the same as the file dataspace + * defined when the dataset was created. + * + * The number of elements in the memory dataspace must match + * the number of elements in the file dataspace. + * + * The PLIST_ID can be the constant H5P_DEFAULT in which + * case the default data transfer properties are used. + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Robb Matzke + * Thursday, December 4, 1997 + * + *------------------------------------------------------------------------- + */ +herr_t +H5Dwrite(hid_t dset_id, hid_t mem_type_id, hid_t mem_space_id, hid_t file_space_id, hid_t dxpl_id, + const void *buf) +{ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_API(FAIL) + H5TRACE6("e", "iiiii*x", dset_id, mem_type_id, mem_space_id, file_space_id, dxpl_id, buf); + + /* Write the data */ + if (H5D__write_api_common(dset_id, mem_type_id, mem_space_id, file_space_id, dxpl_id, buf, NULL, NULL) < + 0) + HGOTO_ERROR(H5E_DATASET, H5E_WRITEERROR, FAIL, "can't synchronously write data") + +done: + FUNC_LEAVE_API(ret_value) +} /* end H5Dwrite() */ + +/*------------------------------------------------------------------------- + * Function: H5Dwrite_async + * + * Purpose: For asynchronous VOL with request token + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Houjun Tang + * Oct 15, 2019 + * + *------------------------------------------------------------------------- + */ +herr_t +H5Dwrite_async(const char *app_file, const char *app_func, unsigned app_line, hid_t dset_id, + hid_t mem_type_id, hid_t mem_space_id, hid_t file_space_id, hid_t dxpl_id, const void *buf, + hid_t es_id) +{ + H5VL_object_t *vol_obj = NULL; /* Dataset VOL object */ + void * token = NULL; /* Request token for async operation */ + void ** token_ptr = H5_REQUEST_NULL; /* Pointer to request token for async operation */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_API(FAIL) + H5TRACE10("e", "*s*sIuiiiii*xi", app_file, app_func, app_line, dset_id, mem_type_id, mem_space_id, + file_space_id, dxpl_id, buf, es_id); + + /* Set up request token pointer for asynchronous operation */ + if (H5ES_NONE != es_id) + token_ptr = &token; /* Point at token for VOL connector to set up */ + + /* Write the data */ + if (H5D__write_api_common(dset_id, mem_type_id, mem_space_id, file_space_id, dxpl_id, buf, token_ptr, + &vol_obj) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_WRITEERROR, FAIL, "can't asynchronously write data") + + /* If a token was created, add the token to the event set */ + if (NULL != token) + /* clang-format off */ + if (H5ES_insert(es_id, vol_obj->connector, token, + H5ARG_TRACE10(FUNC, "*s*sIuiiiii*xi", app_file, app_func, app_line, dset_id, mem_type_id, mem_space_id, file_space_id, dxpl_id, buf, es_id)) < 0) + /* clang-format on */ + HGOTO_ERROR(H5E_DATASET, H5E_CANTINSERT, FAIL, "can't insert token into event set") + +done: + FUNC_LEAVE_API(ret_value) +} /* end H5Dwrite_async() */ + +/*------------------------------------------------------------------------- + * Function: H5Dwrite_chunk + * + * Purpose: Writes an entire chunk to the file directly. + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Raymond Lu + * 30 July 2012 + * + *------------------------------------------------------------------------- + */ +herr_t +H5Dwrite_chunk(hid_t dset_id, hid_t dxpl_id, uint32_t filters, const hsize_t *offset, size_t data_size, + const void *buf) +{ + H5VL_object_t *vol_obj = NULL; + uint32_t data_size_32; /* Chunk data size (limited to 32-bits currently) */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_API(FAIL) + H5TRACE6("e", "iiIu*hz*x", dset_id, dxpl_id, filters, offset, data_size, buf); + + /* Check arguments */ + if (NULL == (vol_obj = (H5VL_object_t *)H5I_object_verify(dset_id, H5I_DATASET))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid dataset ID") + if (!buf) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "buf cannot be NULL") + if (!offset) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "offset cannot be NULL") + if (0 == data_size) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "data_size cannot be zero") + + /* Make sure data size is less than 4 GiB */ + data_size_32 = (uint32_t)data_size; + if (data_size != (size_t)data_size_32) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid data_size - chunks cannot be > 4 GiB") + + /* Get the default dataset transfer property list if the user didn't provide one */ + if (H5P_DEFAULT == dxpl_id) + dxpl_id = H5P_DATASET_XFER_DEFAULT; + else if (TRUE != H5P_isa_class(dxpl_id, H5P_DATASET_XFER)) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "dxpl_id is not a dataset transfer property list ID") + + /* Write chunk */ + if (H5VL_dataset_optional(vol_obj, H5VL_NATIVE_DATASET_CHUNK_WRITE, dxpl_id, H5_REQUEST_NULL, filters, + offset, data_size_32, buf) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_WRITEERROR, FAIL, "can't write unprocessed chunk data") + +done: + FUNC_LEAVE_API(ret_value) +} /* end H5Dwrite_chunk() */ + +/*------------------------------------------------------------------------- * Function: H5Dscatter * * Purpose: Scatters data provided by the callback op to the @@ -957,7 +1620,7 @@ herr_t H5Dvlen_get_buf_size(hid_t dataset_id, hid_t type_id, hid_t space_id, hsize_t *size /*out*/) { H5VL_object_t *vol_obj; /* Dataset for this operation */ - hbool_t supported; /* Whether 'get vlen buf size' operation is supported by VOL connector */ + uint64_t supported; /* Whether 'get vlen buf size' operation is supported by VOL connector */ herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API(FAIL) @@ -974,11 +1637,11 @@ H5Dvlen_get_buf_size(hid_t dataset_id, hid_t type_id, hid_t space_id, hsize_t *s HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid 'size' pointer") /* Check if the 'get_vlen_buf_size' callback is supported */ - supported = FALSE; + supported = 0; if (H5VL_introspect_opt_query(vol_obj, H5VL_SUBCLS_DATASET, H5VL_NATIVE_DATASET_GET_VLEN_BUF_SIZE, &supported) < 0) HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't check for 'get vlen buf size' operation") - if (supported) { + if (supported & H5VL_OPT_QUERY_SUPPORTED) { /* Make the 'get_vlen_buf_size' callback */ if (H5VL_dataset_optional(vol_obj, H5VL_NATIVE_DATASET_GET_VLEN_BUF_SIZE, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL, type_id, space_id, size) < 0) @@ -995,27 +1658,28 @@ done: } /* end H5Dvlen_get_buf_size() */ /*------------------------------------------------------------------------- - * Function: H5Dset_extent + * Function: H5D__set_extent_api_common * - * Purpose: Modifies the dimensions of a dataset. - * Can change to a smaller dimension. + * Purpose: This is the common function for changing a dataset's dimensions * - * Return: Non-negative on success, negative on failure + * Return: Non-negative on success, negative on failure * *------------------------------------------------------------------------- */ -herr_t -H5Dset_extent(hid_t dset_id, const hsize_t size[]) +static herr_t +H5D__set_extent_api_common(hid_t dset_id, const hsize_t size[], void **token_ptr, + H5VL_object_t **_vol_obj_ptr) { - H5VL_object_t *vol_obj; /* Dataset for this operation */ - herr_t ret_value = SUCCEED; /* Return value */ + H5VL_object_t * tmp_vol_obj = NULL; /* Object for loc_id */ + H5VL_object_t **vol_obj_ptr = + (_vol_obj_ptr ? _vol_obj_ptr : &tmp_vol_obj); /* Ptr to object ptr for loc_id */ + herr_t ret_value = SUCCEED; /* Return value */ - FUNC_ENTER_API(FAIL) - H5TRACE2("e", "i*h", dset_id, size); + FUNC_ENTER_STATIC /* Check args */ - if (NULL == (vol_obj = (H5VL_object_t *)H5I_object_verify(dset_id, H5I_DATASET))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "dset_id parameter is not a valid dataset identifier") + if (NULL == (*vol_obj_ptr = (H5VL_object_t *)H5I_object_verify(dset_id, H5I_DATASET))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid dataset identifier") if (!size) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "size array cannot be NULL") @@ -1024,15 +1688,82 @@ H5Dset_extent(hid_t dset_id, const hsize_t size[]) HGOTO_ERROR(H5E_DATASET, H5E_CANTSET, FAIL, "can't set collective metadata read info") /* Set the extent */ - if ((ret_value = H5VL_dataset_specific(vol_obj, H5VL_DATASET_SET_EXTENT, H5P_DATASET_XFER_DEFAULT, - H5_REQUEST_NULL, size)) < 0) + if ((ret_value = H5VL_dataset_specific(*vol_obj_ptr, H5VL_DATASET_SET_EXTENT, H5P_DATASET_XFER_DEFAULT, + token_ptr, size)) < 0) HGOTO_ERROR(H5E_DATASET, H5E_CANTSET, FAIL, "unable to set dataset extent") done: + FUNC_LEAVE_NOAPI(ret_value) +} /* H5D__set_extent_api_common() */ + +/*------------------------------------------------------------------------- + * Function: H5Dset_extent + * + * Purpose: Modifies the dimensions of a dataset. + * Can change to a smaller dimension. + * + * Return: Non-negative on success, negative on failure + * + *------------------------------------------------------------------------- + */ +herr_t +H5Dset_extent(hid_t dset_id, const hsize_t size[]) +{ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_API(FAIL) + H5TRACE2("e", "i*h", dset_id, size); + + /* Change a datset's dimenions synchronously */ + if ((ret_value = H5D__set_extent_api_common(dset_id, size, NULL, NULL)) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTSET, FAIL, "unable to synchronously change a dataset's dimensions") + +done: FUNC_LEAVE_API(ret_value) } /* end H5Dset_extent() */ /*------------------------------------------------------------------------- + * Function: H5Dset_extent_async + * + * Purpose: Asynchronous version of H5Dset_extent + * + * Return: Non-negative on success, negative on failure + * + *------------------------------------------------------------------------- + */ +herr_t +H5Dset_extent_async(const char *app_file, const char *app_func, unsigned app_line, hid_t dset_id, + const hsize_t size[], hid_t es_id) +{ + H5VL_object_t *vol_obj = NULL; /* Object for loc_id */ + void * token = NULL; /* Request token for async operation */ + void ** token_ptr = H5_REQUEST_NULL; /* Pointer to request token for async operation */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_API(FAIL) + H5TRACE6("e", "*s*sIui*hi", app_file, app_func, app_line, dset_id, size, es_id); + + /* Set up request token pointer for asynchronous operation */ + if (H5ES_NONE != es_id) + token_ptr = &token; /* Point at token for VOL connector to set up */ + + /* Change a datset's dimenions asynchronously */ + if (H5D__set_extent_api_common(dset_id, size, token_ptr, &vol_obj) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTSET, FAIL, "unable to asynchronously change a dataset's dimensions") + + /* If a token was created, add the token to the event set */ + if (NULL != token) + /* clang-format off */ + if (H5ES_insert(es_id, vol_obj->connector, token, + H5ARG_TRACE6(FUNC, "*s*sIui*hi", app_file, app_func, app_line, dset_id, size, es_id)) < 0) + /* clang-format on */ + HGOTO_ERROR(H5E_DATASET, H5E_CANTINSERT, FAIL, "can't insert token into event set") + +done: + FUNC_LEAVE_API(ret_value) +} /* H5Dset_extent_async() */ + +/*------------------------------------------------------------------------- * Function: H5Dflush * * Purpose: Flushes all buffers associated with a dataset. @@ -1071,6 +1802,41 @@ done: } /* H5Dflush */ /*------------------------------------------------------------------------- + * Function: H5Dwait + * + * Purpose: Wait for all operations on a dataset. + * Tang: added for async + * + * Return: Non-negative on success/Negative on failure + * + *------------------------------------------------------------------------- + */ +herr_t +H5Dwait(hid_t dset_id) +{ + H5VL_object_t *vol_obj; /* Dataset for this operation */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_API(FAIL) + H5TRACE1("e", "i", dset_id); + + /* Check args */ + if (NULL == (vol_obj = (H5VL_object_t *)H5I_object_verify(dset_id, H5I_DATASET))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "dset_id parameter is not a valid dataset identifier") + + /* Set up collective metadata if appropriate */ + if (H5CX_set_loc(dset_id) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTSET, FAIL, "can't set collective metadata read info") + + if ((ret_value = H5VL_dataset_specific(vol_obj, H5VL_DATASET_WAIT, H5P_DATASET_XFER_DEFAULT, + H5_REQUEST_NULL, dset_id)) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTOPERATE, FAIL, "unable to wait dataset") + +done: + FUNC_LEAVE_API(ret_value) +} /* H5Dwait*/ + +/*------------------------------------------------------------------------- * Function: H5Drefresh * * Purpose: Refreshes all buffers associated with a dataset. @@ -1247,13 +2013,13 @@ done: *------------------------------------------------------------------------- */ herr_t -H5Dget_num_chunks(hid_t dset_id, hid_t fspace_id, hsize_t *nchunks) +H5Dget_num_chunks(hid_t dset_id, hid_t fspace_id, hsize_t *nchunks /*out*/) { H5VL_object_t *vol_obj = NULL; /* Dataset for this operation */ herr_t ret_value = SUCCEED; FUNC_ENTER_API(FAIL) - H5TRACE3("e", "ii*h", dset_id, fspace_id, nchunks); + H5TRACE3("e", "iix", dset_id, fspace_id, nchunks); /* Check arguments */ if (NULL == (vol_obj = (H5VL_object_t *)H5I_object_verify(dset_id, H5I_DATASET))) @@ -1376,3 +2142,68 @@ H5Dget_chunk_info_by_coord(hid_t dset_id, const hsize_t *offset, unsigned *filte done: FUNC_LEAVE_API(ret_value) } /* end H5Dget_chunk_info_by_coord() */ + +/*------------------------------------------------------------------------- + * Function: H5Dchunk_iter + * + * Purpose: Iterates over all chunks in dataset with given callback and user data. + * + * Parameters: + * hid_t dset_id; IN: Chunked dataset ID + * H5D_chunk_iter_op_t cb IN: User callback function, called for every chunk. + * void *op_data IN/OUT: Optional user data passed on to user callback. + * + * Callback information: + * H5D_chunk_iter_op_t is defined as: + * + * typedef int (*H5D_chunk_iter_op_t)( + * const hsize_t *offset, + * uint32_t filter_mask, + * haddr_t addr, + * uint32_t nbytes, + * void *op_data); + * + * H5D_chunk_iter_op_t parameters: + * hsize_t *offset; IN/OUT: Array of starting logical coordinates of chunk. + * uint32_t filter_mask; IN: Filter mask of chunk. + * haddr_t addr; IN: Offset in file of chunk data. + * uint32_t nbytes; IN: Size in number of bytes of chunk data in file. + * void *op_data; IN/OUT: Pointer to any user-defined data + * associated with the operation. + * + * The return values from an operator are: + * Zero (H5_ITER_CONT) causes the iterator to continue, returning zero when all + * elements have been processed. + * Positive (H5_ITER_STOP) causes the iterator to immediately return that positive + * value, indicating short-circuit success. + * Negative (H5_ITER_ERROR) causes the iterator to immediately return that value, + * indicating failure. + * + * Return: Non-negative on success, negative on failure + * + * Programmer: Gaute Hope + * August 2020 + * + *------------------------------------------------------------------------- + */ +herr_t +H5Dchunk_iter(hid_t dset_id, H5D_chunk_iter_op_t cb, void *op_data) +{ + H5VL_object_t *vol_obj = NULL; /* Dataset for this operation */ + herr_t ret_value = SUCCEED; + + FUNC_ENTER_API(FAIL) + H5TRACE3("e", "ix*x", dset_id, cb, op_data); + + /* Check arguments */ + if (NULL == (vol_obj = (H5VL_object_t *)H5I_object_verify(dset_id, H5I_DATASET))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid dataset identifier") + + /* Call private function to get the chunk info given the chunk's index */ + if (H5VL_dataset_specific(vol_obj, H5VL_DATASET_CHUNK_ITER, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL, cb, + op_data) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "Can't iterate over chunks") + +done: + FUNC_LEAVE_API(ret_value) +} /* end H5Dchunk_iter() */ diff --git a/src/H5Dbtree.c b/src/H5Dbtree.c index 75bc23f..f495bd4 100644 --- a/src/H5Dbtree.c +++ b/src/H5Dbtree.c @@ -102,7 +102,7 @@ static herr_t H5D__btree_new_node(H5F_t *f, H5B_ins_t, void *_lt_key, void *_ haddr_t *addr_p /*out*/); static int H5D__btree_cmp2(void *_lt_key, void *_udata, void *_rt_key); static int H5D__btree_cmp3(void *_lt_key, void *_udata, void *_rt_key); -static htri_t H5D__btree_found(H5F_t *f, haddr_t addr, const void *_lt_key, void *_udata); +static htri_t H5D__btree_found(H5F_t *f, haddr_t addr, const void *_lt_key, hbool_t *found, void *_udata); static H5B_ins_t H5D__btree_insert(H5F_t *f, haddr_t addr, void *_lt_key, hbool_t *lt_key_changed, void *_md_key, void *_udata, void *_rt_key, hbool_t *rt_key_changed, haddr_t *new_node /*out*/); @@ -408,8 +408,9 @@ H5D__btree_cmp3(void *_lt_key, void *_udata, void *_rt_key) * called with the maximum stored chunk indices less than the * requested chunk indices. * - * Return: Non-negative (TRUE/FALSE) on success with information about the - * chunk returned through the UDATA argument. Negative on failure. + * Return: Non-negative on success with information about the + * chunk returned through the UDATA argument, if *FOUND is true. + * Negative on failure. * * Programmer: Robb Matzke * Thursday, October 9, 1997 @@ -417,31 +418,35 @@ H5D__btree_cmp3(void *_lt_key, void *_udata, void *_rt_key) *------------------------------------------------------------------------- */ static htri_t -H5D__btree_found(H5F_t H5_ATTR_UNUSED *f, haddr_t addr, const void *_lt_key, void *_udata) +H5D__btree_found(H5F_t H5_ATTR_UNUSED *f, haddr_t addr, const void *_lt_key, hbool_t *found, void *_udata) { H5D_chunk_ud_t * udata = (H5D_chunk_ud_t *)_udata; const H5D_btree_key_t *lt_key = (const H5D_btree_key_t *)_lt_key; unsigned u; - htri_t ret_value = TRUE; /* Return value */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_STATIC_NOERR /* Check arguments */ HDassert(f); HDassert(H5F_addr_defined(addr)); - HDassert(udata); HDassert(lt_key); + HDassert(found); + HDassert(udata); /* Is this *really* the requested chunk? */ for (u = 0; u < udata->common.layout->ndims; u++) - if (udata->common.scaled[u] >= (lt_key->scaled[u] + 1)) - HGOTO_DONE(FALSE) + if (udata->common.scaled[u] >= (lt_key->scaled[u] + 1)) { + *found = FALSE; + HGOTO_DONE(SUCCEED) + } /* Initialize return values */ HDassert(lt_key->nbytes > 0); udata->chunk_block.offset = addr; udata->chunk_block.length = lt_key->nbytes; udata->filter_mask = lt_key->filter_mask; + *found = TRUE; done: FUNC_LEAVE_NOAPI(ret_value) @@ -991,7 +996,8 @@ done: static herr_t H5D__btree_idx_get_addr(const H5D_chk_idx_info_t *idx_info, H5D_chunk_ud_t *udata) { - herr_t ret_value = SUCCEED; /* Return value */ + hbool_t found; /* Whether chunk was found */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_STATIC @@ -1005,8 +1011,9 @@ H5D__btree_idx_get_addr(const H5D_chk_idx_info_t *idx_info, H5D_chunk_ud_t *udat HDassert(udata); /* Go get the chunk information from the B-tree */ - if (H5B_find(idx_info->f, H5B_BTREE, idx_info->storage->idx_addr, udata) < 0) - HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't get chunk info") + found = FALSE; + if (H5B_find(idx_info->f, H5B_BTREE, idx_info->storage->idx_addr, &found, udata) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTFIND, FAIL, "can't check for chunk in B-tree") done: FUNC_LEAVE_NOAPI(ret_value) diff --git a/src/H5Dbtree2.c b/src/H5Dbtree2.c index 529f735..12cd513 100644 --- a/src/H5Dbtree2.c +++ b/src/H5Dbtree2.c @@ -970,6 +970,7 @@ H5D__bt2_idx_get_addr(const H5D_chk_idx_info_t *idx_info, H5D_chunk_ud_t *udata) H5D_bt2_ud_t bt2_udata; /* User data for v2 B-tree calls */ H5D_chunk_rec_t found_rec; /* Record found from searching for object */ unsigned u; /* Local index variable */ + hbool_t found; /* Whether chunk was found */ herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_STATIC @@ -1011,17 +1012,18 @@ H5D__bt2_idx_get_addr(const H5D_chk_idx_info_t *idx_info, H5D_chunk_ud_t *udata) bt2_udata.rec.scaled[u] = udata->common.scaled[u]; /* Go get chunk information from v2 B-tree */ - if (H5B2_find(bt2, &bt2_udata, H5D__bt2_found_cb, &found_rec) < 0) - HGOTO_ERROR(H5E_HEAP, H5E_NOTFOUND, FAIL, "can't find object in v2 B-tree") + found = FALSE; + if (H5B2_find(bt2, &bt2_udata, &found, H5D__bt2_found_cb, &found_rec) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTFIND, FAIL, "can't check for chunk in v2 B-tree") - /* Set common info for the chunk */ - udata->chunk_block.offset = found_rec.chunk_addr; - - /* Check for setting other info */ - if (H5F_addr_defined(udata->chunk_block.offset)) { + /* Check if chunk was found */ + if (found) { /* Sanity check */ HDassert(0 != found_rec.nbytes); + /* Set common info for the chunk */ + udata->chunk_block.offset = found_rec.chunk_addr; + /* Set other info for the chunk */ if (idx_info->pline->nused > 0) { /* filtered chunk */ udata->chunk_block.length = found_rec.nbytes; @@ -1033,6 +1035,7 @@ H5D__bt2_idx_get_addr(const H5D_chk_idx_info_t *idx_info, H5D_chunk_ud_t *udata) } /* end else */ } /* end if */ else { + udata->chunk_block.offset = HADDR_UNDEF; udata->chunk_block.length = 0; udata->filter_mask = 0; } /* end else */ diff --git a/src/H5Dchunk.c b/src/H5Dchunk.c index 5380644..d6eb715 100644 --- a/src/H5Dchunk.c +++ b/src/H5Dchunk.c @@ -245,6 +245,11 @@ typedef struct H5D_chunk_coll_info_t { } H5D_chunk_coll_info_t; #endif /* H5_HAVE_PARALLEL */ +typedef struct H5D_chunk_iter_cb_data_t { + H5D_chunk_iter_op_t cb; /* User defined callback */ + void * op_data; /* User data for user defined callback */ +} H5D_chunk_iter_cb_data_t; + /********************/ /* Local Prototypes */ /********************/ @@ -271,6 +276,7 @@ static herr_t H5D__chunk_index_close(const H5D_t *, bool); static int H5D__get_num_chunks_cb(const H5D_chunk_rec_t *chunk_rec, void *_udata); static int H5D__get_chunk_info_cb(const H5D_chunk_rec_t *chunk_rec, void *_udata); static int H5D__get_chunk_info_by_coord_cb(const H5D_chunk_rec_t *chunk_rec, void *_udata); +static int H5D__chunk_iter_cb(const H5D_chunk_rec_t *chunk_rec, void *udata); /* "Nonexistent" layout operation callback */ static ssize_t H5D__nonexistent_readvv(const H5D_io_info_t *io_info, size_t chunk_max_nseq, @@ -713,10 +719,8 @@ H5D__chunk_set_info_real(H5O_layout_chunk_t *layout, unsigned ndims, const hsize } /* end for */ /* Get the "down" sizes for each dimension */ - if (H5VM_array_down(ndims, layout->chunks, layout->down_chunks) < 0) - HGOTO_ERROR(H5E_DATASET, H5E_CANTSET, FAIL, "can't compute 'down' chunk size value") - if (H5VM_array_down(ndims, layout->max_chunks, layout->max_down_chunks) < 0) - HGOTO_ERROR(H5E_DATASET, H5E_CANTSET, FAIL, "can't compute 'down' chunk size value") + H5VM_array_down(ndims, layout->chunks, layout->down_chunks); + H5VM_array_down(ndims, layout->max_chunks, layout->max_down_chunks); done: FUNC_LEAVE_NOAPI(ret_value) @@ -2985,7 +2989,7 @@ done: static herr_t H5D__chunk_cinfo_cache_reset(H5D_chunk_cached_t *last) { - FUNC_ENTER_PACKAGE_NOERR + FUNC_ENTER_STATIC_NOERR /* Sanity check */ HDassert(last); @@ -3191,9 +3195,9 @@ H5D__chunk_hash_val(const H5D_shared_t *shared, const hsize_t *scaled) herr_t H5D__chunk_lookup(const H5D_t *dset, const hsize_t *scaled, H5D_chunk_ud_t *udata) { - H5D_rdcc_ent_t * ent = NULL; /* Cache entry */ - H5O_storage_chunk_t *sc = &(dset->shared->layout.storage.u.chunk); - unsigned idx; /* Index of chunk in cache, if present */ + H5D_rdcc_ent_t * ent = NULL; /* Cache entry */ + H5O_storage_chunk_t *sc = &(dset->shared->layout.storage.u.chunk); + unsigned idx = 0; /* Index of chunk in cache, if present */ hbool_t found = FALSE; /* In cache? */ herr_t ret_value = SUCCEED; /* Return value */ @@ -4298,7 +4302,7 @@ done: *------------------------------------------------------------------------- */ herr_t -H5D__chunk_allocate(const H5D_io_info_t *io_info, hbool_t full_overwrite, hsize_t old_dim[]) +H5D__chunk_allocate(const H5D_io_info_t *io_info, hbool_t full_overwrite, const hsize_t old_dim[]) { const H5D_t * dset = io_info->dset; /* the dataset pointer */ H5D_chk_idx_info_t idx_info; /* Chunked index info */ @@ -4307,18 +4311,18 @@ H5D__chunk_allocate(const H5D_io_info_t *io_info, hbool_t full_overwrite, hsize_ coordinates) */ hsize_t max_unalloc[H5O_LAYOUT_NDIMS]; /* Last chunk in each dimension that is unallocated (in scaled coordinates) */ - hsize_t scaled[H5O_LAYOUT_NDIMS]; /* Offset of current chunk (in scaled coordinates) */ - size_t orig_chunk_size; /* Original size of chunk in bytes */ - size_t chunk_size; /* Actual size of chunk in bytes, possibly filtered */ - unsigned filter_mask = 0; /* Filter mask for chunks that have them */ - const H5O_layout_t *layout = &(dset->shared->layout); /* Dataset layout */ - const H5O_pline_t * pline = &(dset->shared->dcpl_cache.pline); /* I/O pipeline info */ - const H5O_pline_t def_pline = H5O_CRT_PIPELINE_DEF; /* Default pipeline */ - const H5O_fill_t * fill = &(dset->shared->dcpl_cache.fill); /* Fill value info */ - H5D_fill_value_t fill_status; /* The fill value status */ - hbool_t should_fill = FALSE; /* Whether fill values should be written */ - void * unfilt_fill_buf = NULL; /* Unfiltered fill value buffer */ - void ** fill_buf = NULL; /* Pointer to the fill buffer to use for a chunk */ + hsize_t scaled[H5O_LAYOUT_NDIMS]; /* Offset of current chunk (in scaled coordinates) */ + size_t orig_chunk_size; /* Original size of chunk in bytes */ + size_t chunk_size; /* Actual size of chunk in bytes, possibly filtered */ + unsigned filter_mask = 0; /* Filter mask for chunks that have them */ + H5O_layout_t * layout = &(dset->shared->layout); /* Dataset layout */ + const H5O_pline_t *pline = &(dset->shared->dcpl_cache.pline); /* I/O pipeline info */ + const H5O_pline_t def_pline = H5O_CRT_PIPELINE_DEF; /* Default pipeline */ + const H5O_fill_t * fill = &(dset->shared->dcpl_cache.fill); /* Fill value info */ + H5D_fill_value_t fill_status; /* The fill value status */ + hbool_t should_fill = FALSE; /* Whether fill values should be written */ + void * unfilt_fill_buf = NULL; /* Unfiltered fill value buffer */ + void ** fill_buf = NULL; /* Pointer to the fill buffer to use for a chunk */ #ifdef H5_HAVE_PARALLEL hbool_t blocks_written = FALSE; /* Flag to indicate that chunk was actually written */ hbool_t using_mpi = @@ -4337,9 +4341,9 @@ H5D__chunk_allocate(const H5D_io_info_t *io_info, hbool_t full_overwrite, hsize_ of each dimension */ hsize_t edge_chunk_scaled[H5O_LAYOUT_NDIMS]; /* Offset of the unfiltered edge chunks at the edge of each dimension */ - unsigned nunfilt_edge_chunk_dims = 0; /* Number of dimensions on an edge */ - const H5O_storage_chunk_t *sc = &(layout->storage.u.chunk); - herr_t ret_value = SUCCEED; /* Return value */ + unsigned nunfilt_edge_chunk_dims = 0; /* Number of dimensions on an edge */ + H5O_storage_chunk_t *sc = &(layout->storage.u.chunk); /* Convenience variable */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_PACKAGE @@ -7493,3 +7497,95 @@ H5D__get_chunk_info_by_coord(const H5D_t *dset, const hsize_t *offset, unsigned done: FUNC_LEAVE_NOAPI_TAG(ret_value) } /* end H5D__get_chunk_info_by_coord() */ + +/*------------------------------------------------------------------------- + * Function: H5D__chunk_iter + * + * Purpose: Iterate over all the chunks in the dataset with given callbak. + * + * Return: Success: Non-negative + * Failure: Negative + * + * Programmer: Gaute Hope + * August 2020 + * + *------------------------------------------------------------------------- + */ +herr_t +H5D__chunk_iter(const H5D_t *dset, H5D_chunk_iter_op_t cb, void *op_data) +{ + const H5O_layout_t *layout = NULL; /* Dataset layout */ + const H5D_rdcc_t * rdcc = NULL; /* Raw data chunk cache */ + H5D_rdcc_ent_t * ent; /* Cache entry index */ + H5D_chk_idx_info_t idx_info; /* Chunked index info */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_PACKAGE_TAG(dset->oloc.addr) + + /* Check args */ + HDassert(dset); + HDassert(dset->shared); + + /* Get dataset layout and raw data chunk cache */ + layout = &(dset->shared->layout); + rdcc = &(dset->shared->cache.chunk); + HDassert(layout); + HDassert(rdcc); + HDassert(H5D_CHUNKED == layout->type); + + /* Search for cached chunks that haven't been written out */ + for (ent = rdcc->head; ent; ent = ent->next) + /* Flush the chunk out to disk, to make certain the size is correct later */ + if (H5D__chunk_flush_entry(dset, ent, FALSE) < 0) + HGOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "cannot flush indexed storage buffer") + + /* Compose chunked index info struct */ + idx_info.f = dset->oloc.file; + idx_info.pline = &dset->shared->dcpl_cache.pline; + idx_info.layout = &dset->shared->layout.u.chunk; + idx_info.storage = &dset->shared->layout.storage.u.chunk; + + /* If the dataset is not written, return without errors */ + if (H5F_addr_defined(idx_info.storage->idx_addr)) { + H5D_chunk_iter_cb_data_t data; + data.cb = cb; + data.op_data = op_data; + + /* Iterate over the allocated chunks calling the iterator callback */ + if ((dset->shared->layout.storage.u.chunk.ops->iterate)(&idx_info, H5D__chunk_iter_cb, &data) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "unable to iterate over chunks.") + } /* end if H5F_addr_defined */ + +done: + FUNC_LEAVE_NOAPI_TAG(ret_value) +} /* end H5D__chunk_iter() */ + +/*------------------------------------------------------------------------- + * Function: H5D__chunk_iter_cb + * + * Purpose: Call the user-defined function with the chunk data. The iterator continues if + * the user-defined function returns H5_ITER_CONT, and stops if H5_ITER_STOP is + * returned. + * + * Return: Success: H5_ITER_CONT or H5_ITER_STOP + * Failure: Negative (H5_ITER_ERROR) + * + * Programmer: Gaute Hope + * August 2020 + * + *------------------------------------------------------------------------- + */ +static int +H5D__chunk_iter_cb(const H5D_chunk_rec_t *chunk_rec, void *udata) +{ + int ret_value = 0; + + FUNC_ENTER_STATIC_NOERR + + const H5D_chunk_iter_cb_data_t *data = (H5D_chunk_iter_cb_data_t *)udata; + + ret_value = (data->cb)(chunk_rec->scaled, chunk_rec->filter_mask, chunk_rec->chunk_addr, + chunk_rec->nbytes, data->op_data); + + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5D__chunk_iter_cb */ diff --git a/src/H5Dearray.c b/src/H5Dearray.c index db77a4c..bef453d 100644 --- a/src/H5Dearray.c +++ b/src/H5Dearray.c @@ -1161,9 +1161,7 @@ done: static herr_t H5D__earray_idx_resize(H5O_layout_chunk_t *layout) { - herr_t ret_value = SUCCEED; /* Return value */ - - FUNC_ENTER_STATIC + FUNC_ENTER_STATIC_NOERR /* Check args */ HDassert(layout); @@ -1183,8 +1181,7 @@ H5D__earray_idx_resize(H5O_layout_chunk_t *layout) H5VM_swizzle_coords(hsize_t, swizzled_chunks, layout->u.earray.unlim_dim); /* Get the swizzled "down" sizes for each dimension */ - if (H5VM_array_down((layout->ndims - 1), swizzled_chunks, layout->u.earray.swizzled_down_chunks) < 0) - HGOTO_ERROR(H5E_DATASET, H5E_CANTSET, FAIL, "can't compute swizzled 'down' chunk size value") + H5VM_array_down((layout->ndims - 1), swizzled_chunks, layout->u.earray.swizzled_down_chunks); /* Get the swizzled max number of chunks in each dimension */ H5MM_memcpy(swizzled_max_chunks, layout->max_chunks, @@ -1192,13 +1189,10 @@ H5D__earray_idx_resize(H5O_layout_chunk_t *layout) H5VM_swizzle_coords(hsize_t, swizzled_max_chunks, layout->u.earray.unlim_dim); /* Get the swizzled max "down" sizes for each dimension */ - if (H5VM_array_down((layout->ndims - 1), swizzled_max_chunks, - layout->u.earray.swizzled_max_down_chunks) < 0) - HGOTO_ERROR(H5E_DATASET, H5E_CANTSET, FAIL, "can't compute swizzled 'down' chunk size value") - } /* end if */ + H5VM_array_down((layout->ndims - 1), swizzled_max_chunks, layout->u.earray.swizzled_max_down_chunks); + } -done: - FUNC_LEAVE_NOAPI(ret_value) + FUNC_LEAVE_NOAPI(SUCCEED) } /* end H5D__earray_idx_resize() */ /*------------------------------------------------------------------------- diff --git a/src/H5Dint.c b/src/H5Dint.c index d0c1ba2..5e709db 100644 --- a/src/H5Dint.c +++ b/src/H5Dint.c @@ -83,7 +83,7 @@ static herr_t H5D__build_file_prefix(const H5D_t *dset, H5F_prefix_open_t prefix static herr_t H5D__open_oid(H5D_t *dataset, hid_t dapl_id); static herr_t H5D__init_storage(const H5D_io_info_t *io_info, hbool_t full_overwrite, hsize_t old_dim[]); static herr_t H5D__append_flush_setup(H5D_t *dset, hid_t dapl_id); -static herr_t H5D__close_cb(H5VL_object_t *dset_vol_obj); +static herr_t H5D__close_cb(H5VL_object_t *dset_vol_obj, void **request); static herr_t H5D__use_minimized_dset_headers(H5F_t *file, hbool_t *minimize); static herr_t H5D__prepare_minimized_oh(H5F_t *file, H5D_t *dset, H5O_loc_t *oloc); static size_t H5D__calculate_minimum_header_size(H5F_t *file, H5D_t *dset, H5O_t *ohdr); @@ -330,7 +330,7 @@ H5D_term_package(void) *------------------------------------------------------------------------- */ static herr_t -H5D__close_cb(H5VL_object_t *dset_vol_obj) +H5D__close_cb(H5VL_object_t *dset_vol_obj, void **request) { herr_t ret_value = SUCCEED; /* Return value */ @@ -340,7 +340,7 @@ H5D__close_cb(H5VL_object_t *dset_vol_obj) HDassert(dset_vol_obj); /* Close the dataset */ - if (H5VL_dataset_close(dset_vol_obj, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0) + if (H5VL_dataset_close(dset_vol_obj, H5P_DATASET_XFER_DEFAULT, request) < 0) HGOTO_ERROR(H5E_DATASET, H5E_CLOSEERROR, FAIL, "unable to close dataset"); done: @@ -885,7 +885,7 @@ H5D__prepare_minimized_oh(H5F_t *file, H5D_t *dset, H5O_loc_t *oloc) HDassert(dset); HDassert(oloc); - oh = H5O__create_ohdr(file, dset->shared->dcpl_id); + oh = H5O_create_ohdr(file, dset->shared->dcpl_id); if (NULL == oh) HGOTO_ERROR(H5E_OHDR, H5E_BADVALUE, FAIL, "can't instantiate object header") @@ -894,7 +894,7 @@ H5D__prepare_minimized_oh(H5F_t *file, H5D_t *dset, H5O_loc_t *oloc) HGOTO_ERROR(H5E_OHDR, H5E_BADVALUE, FAIL, "computed header size is invalid") /* Special allocation of space for compact datsets is handled by the call here. */ - if (H5O__apply_ohdr(file, oh, dset->shared->dcpl_id, ohdr_size, (size_t)1, oloc) == FAIL) + if (H5O_apply_ohdr(file, oh, dset->shared->dcpl_id, ohdr_size, (size_t)1, oloc) == FAIL) HGOTO_ERROR(H5E_OHDR, H5E_BADVALUE, FAIL, "can't apply object header to file") done: diff --git a/src/H5Dio.c b/src/H5Dio.c index e28da8c..03400cf 100644 --- a/src/H5Dio.c +++ b/src/H5Dio.c @@ -118,248 +118,6 @@ done: } /* end H5D__get_offset_copy() */ /*------------------------------------------------------------------------- - * Function: H5Dread - * - * Purpose: Reads (part of) a DSET from the file into application - * memory BUF. The part of the dataset to read is defined with - * MEM_SPACE_ID and FILE_SPACE_ID. The data points are - * converted from their file type to the MEM_TYPE_ID specified. - * Additional miscellaneous data transfer properties can be - * passed to this function with the PLIST_ID argument. - * - * The FILE_SPACE_ID can be the constant H5S_ALL which indicates - * that the entire file dataspace is to be referenced. - * - * The MEM_SPACE_ID can be the constant H5S_ALL in which case - * the memory dataspace is the same as the file dataspace - * defined when the dataset was created. - * - * The number of elements in the memory dataspace must match - * the number of elements in the file dataspace. - * - * The PLIST_ID can be the constant H5P_DEFAULT in which - * case the default data transfer properties are used. - * - * Return: Non-negative on success/Negative on failure - * - * Programmer: Robb Matzke - * Thursday, December 4, 1997 - * - *------------------------------------------------------------------------- - */ -herr_t -H5Dread(hid_t dset_id, hid_t mem_type_id, hid_t mem_space_id, hid_t file_space_id, hid_t dxpl_id, - void *buf /*out*/) -{ - H5VL_object_t *vol_obj = NULL; - herr_t ret_value = SUCCEED; /* Return value */ - - FUNC_ENTER_API(FAIL) - H5TRACE6("e", "iiiiix", dset_id, mem_type_id, mem_space_id, file_space_id, dxpl_id, buf); - - /* Check arguments */ - if (mem_space_id < 0) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid memory dataspace ID") - if (file_space_id < 0) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid file dataspace ID") - - /* Get dataset pointer */ - if (NULL == (vol_obj = (H5VL_object_t *)H5I_object_verify(dset_id, H5I_DATASET))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "dset_id is not a dataset ID") - - /* Get the default dataset transfer property list if the user didn't provide one */ - if (H5P_DEFAULT == dxpl_id) - dxpl_id = H5P_DATASET_XFER_DEFAULT; - else if (TRUE != H5P_isa_class(dxpl_id, H5P_DATASET_XFER)) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not xfer parms") - - /* Set DXPL for operation */ - H5CX_set_dxpl(dxpl_id); - - /* Read the data */ - if ((ret_value = H5VL_dataset_read(vol_obj, mem_type_id, mem_space_id, file_space_id, dxpl_id, buf, - H5_REQUEST_NULL)) < 0) - HGOTO_ERROR(H5E_DATASET, H5E_READERROR, FAIL, "can't read data") - -done: - FUNC_LEAVE_API(ret_value) -} /* end H5Dread() */ - -/*------------------------------------------------------------------------- - * Function: H5Dread_chunk - * - * Purpose: Reads an entire chunk from the file directly. - * - * Return: Non-negative on success/Negative on failure - * - * Programmer: Matthew Strong (GE Healthcare) - * 14 February 2016 - * - *--------------------------------------------------------------------------- - */ -herr_t -H5Dread_chunk(hid_t dset_id, hid_t dxpl_id, const hsize_t *offset, uint32_t *filters, void *buf) -{ - H5VL_object_t *vol_obj = NULL; - herr_t ret_value = SUCCEED; /* Return value */ - - FUNC_ENTER_API(FAIL) - H5TRACE5("e", "ii*h*Iu*x", dset_id, dxpl_id, offset, filters, buf); - - /* Check arguments */ - if (NULL == (vol_obj = (H5VL_object_t *)H5I_object_verify(dset_id, H5I_DATASET))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "dset_id is not a dataset ID") - if (!buf) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "buf cannot be NULL") - if (!offset) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "offset cannot be NULL") - if (!filters) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "filters cannot be NULL") - - /* Get the default dataset transfer property list if the user didn't provide one */ - if (H5P_DEFAULT == dxpl_id) - dxpl_id = H5P_DATASET_XFER_DEFAULT; - else if (TRUE != H5P_isa_class(dxpl_id, H5P_DATASET_XFER)) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "dxpl_id is not a dataset transfer property list ID") - - /* Set DXPL for operation */ - H5CX_set_dxpl(dxpl_id); - - /* Read the raw chunk */ - if (H5VL_dataset_optional(vol_obj, H5VL_NATIVE_DATASET_CHUNK_READ, dxpl_id, H5_REQUEST_NULL, offset, - filters, buf) < 0) - HGOTO_ERROR(H5E_DATASET, H5E_READERROR, FAIL, "can't read unprocessed chunk data") - -done: - FUNC_LEAVE_API(ret_value) -} /* end H5Dread_chunk() */ - -/*------------------------------------------------------------------------- - * Function: H5Dwrite - * - * Purpose: Writes (part of) a DSET from application memory BUF to the - * file. The part of the dataset to write is defined with the - * MEM_SPACE_ID and FILE_SPACE_ID arguments. The data points - * are converted from their current type (MEM_TYPE_ID) to their - * file datatype. Additional miscellaneous data transfer - * properties can be passed to this function with the - * PLIST_ID argument. - * - * The FILE_SPACE_ID can be the constant H5S_ALL which indicates - * that the entire file dataspace is to be referenced. - * - * The MEM_SPACE_ID can be the constant H5S_ALL in which case - * the memory dataspace is the same as the file dataspace - * defined when the dataset was created. - * - * The number of elements in the memory dataspace must match - * the number of elements in the file dataspace. - * - * The PLIST_ID can be the constant H5P_DEFAULT in which - * case the default data transfer properties are used. - * - * Return: Non-negative on success/Negative on failure - * - * Programmer: Robb Matzke - * Thursday, December 4, 1997 - * - *------------------------------------------------------------------------- - */ -herr_t -H5Dwrite(hid_t dset_id, hid_t mem_type_id, hid_t mem_space_id, hid_t file_space_id, hid_t dxpl_id, - const void *buf) -{ - H5VL_object_t *vol_obj = NULL; - herr_t ret_value = SUCCEED; /* Return value */ - - FUNC_ENTER_API(FAIL) - H5TRACE6("e", "iiiii*x", dset_id, mem_type_id, mem_space_id, file_space_id, dxpl_id, buf); - - /* Check arguments */ - if (mem_space_id < 0) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid memory dataspace ID") - if (file_space_id < 0) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid file dataspace ID") - - /* Get dataset pointer */ - if (NULL == (vol_obj = (H5VL_object_t *)H5I_object_verify(dset_id, H5I_DATASET))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "dset_id is not a dataset ID") - - /* Get the default dataset transfer property list if the user didn't provide one */ - if (H5P_DEFAULT == dxpl_id) - dxpl_id = H5P_DATASET_XFER_DEFAULT; - else if (TRUE != H5P_isa_class(dxpl_id, H5P_DATASET_XFER)) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not xfer parms") - - /* Set DXPL for operation */ - H5CX_set_dxpl(dxpl_id); - - /* Write the data */ - if ((ret_value = H5VL_dataset_write(vol_obj, mem_type_id, mem_space_id, file_space_id, dxpl_id, buf, - H5_REQUEST_NULL)) < 0) - HGOTO_ERROR(H5E_DATASET, H5E_WRITEERROR, FAIL, "can't write data") - -done: - FUNC_LEAVE_API(ret_value) -} /* end H5Dwrite() */ - -/*------------------------------------------------------------------------- - * Function: H5Dwrite_chunk - * - * Purpose: Writes an entire chunk to the file directly. - * - * Return: Non-negative on success/Negative on failure - * - * Programmer: Raymond Lu - * 30 July 2012 - * - *------------------------------------------------------------------------- - */ -herr_t -H5Dwrite_chunk(hid_t dset_id, hid_t dxpl_id, uint32_t filters, const hsize_t *offset, size_t data_size, - const void *buf) -{ - H5VL_object_t *vol_obj = NULL; - uint32_t data_size_32; /* Chunk data size (limited to 32-bits currently) */ - herr_t ret_value = SUCCEED; /* Return value */ - - FUNC_ENTER_API(FAIL) - H5TRACE6("e", "iiIu*hz*x", dset_id, dxpl_id, filters, offset, data_size, buf); - - /* Check arguments */ - if (NULL == (vol_obj = (H5VL_object_t *)H5I_object_verify(dset_id, H5I_DATASET))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid dataset ID") - if (!buf) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "buf cannot be NULL") - if (!offset) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "offset cannot be NULL") - if (0 == data_size) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "data_size cannot be zero") - - /* Make sure data size is less than 4 GiB */ - data_size_32 = (uint32_t)data_size; - if (data_size != (size_t)data_size_32) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid data_size - chunks cannot be > 4 GiB") - - /* Get the default dataset transfer property list if the user didn't provide one */ - if (H5P_DEFAULT == dxpl_id) - dxpl_id = H5P_DATASET_XFER_DEFAULT; - else if (TRUE != H5P_isa_class(dxpl_id, H5P_DATASET_XFER)) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "dxpl_id is not a dataset transfer property list ID") - - /* Set DXPL for operation */ - H5CX_set_dxpl(dxpl_id); - - /* Write chunk */ - if (H5VL_dataset_optional(vol_obj, H5VL_NATIVE_DATASET_CHUNK_WRITE, dxpl_id, H5_REQUEST_NULL, filters, - offset, data_size_32, buf) < 0) - HGOTO_ERROR(H5E_DATASET, H5E_WRITEERROR, FAIL, "can't write unprocessed chunk data") - -done: - FUNC_LEAVE_API(ret_value) -} /* end H5Dwrite_chunk() */ - -/*------------------------------------------------------------------------- * Function: H5D__read * * Purpose: Reads (part of) a DATASET into application memory BUF. See diff --git a/src/H5Dlayout.c b/src/H5Dlayout.c index 86c0bf6..6c4fc12 100644 --- a/src/H5Dlayout.c +++ b/src/H5Dlayout.c @@ -504,6 +504,7 @@ H5D__layout_oh_create(H5F_t *file, H5O_t *oh, H5D_t *dset, hid_t dapl_id) H5HL_t * heap; /* Pointer to local heap for EFL file names */ size_t heap_size = H5HL_ALIGN(1); size_t u; + size_t name_offset; /* Determine size of heap needed to stored the file names */ for (u = 0; u < efl->nused; ++u) @@ -518,24 +519,22 @@ H5D__layout_oh_create(H5F_t *file, H5O_t *oh, H5D_t *dset, hid_t dapl_id) HGOTO_ERROR(H5E_DATASET, H5E_CANTPROTECT, FAIL, "unable to protect EFL file name heap") /* Insert "empty" name first */ - if (UFAIL == H5HL_insert(file, heap, (size_t)1, "")) { + if (H5HL_insert(file, heap, (size_t)1, "", &name_offset) < 0) { H5HL_unprotect(heap); HGOTO_ERROR(H5E_DATASET, H5E_CANTINSERT, FAIL, "unable to insert file name into heap") - } /* end if */ + } for (u = 0; u < efl->nused; ++u) { - size_t offset; /* Offset of file name in heap */ - /* Insert file name into heap */ - if (UFAIL == - (offset = H5HL_insert(file, heap, HDstrlen(efl->slot[u].name) + 1, efl->slot[u].name))) { + if (H5HL_insert(file, heap, HDstrlen(efl->slot[u].name) + 1, efl->slot[u].name, &name_offset) < + 0) { H5HL_unprotect(heap); HGOTO_ERROR(H5E_DATASET, H5E_CANTINSERT, FAIL, "unable to insert file name into heap") - } /* end if */ + } /* Store EFL file name offset */ - efl->slot[u].name_offset = offset; - } /* end for */ + efl->slot[u].name_offset = name_offset; + } /* Release the heap */ if (H5HL_unprotect(heap) < 0) diff --git a/src/H5Dpkg.h b/src/H5Dpkg.h index 954b108..972a67b 100644 --- a/src/H5Dpkg.h +++ b/src/H5Dpkg.h @@ -566,6 +566,7 @@ H5_DLL herr_t H5D__get_chunk_info(const H5D_t *dset, const H5S_t *space, hsize_ unsigned *filter_mask, haddr_t *offset, hsize_t *size); H5_DLL herr_t H5D__get_chunk_info_by_coord(const H5D_t *dset, const hsize_t *coord, unsigned *filter_mask, haddr_t *addr, hsize_t *size); +H5_DLL herr_t H5D__chunk_iter(const H5D_t *dset, H5D_chunk_iter_op_t cb, void *op_data); H5_DLL haddr_t H5D__get_offset(const H5D_t *dset); H5_DLL herr_t H5D__vlen_get_buf_size(H5D_t *dset, hid_t type_id, hid_t space_id, hsize_t *size); H5_DLL herr_t H5D__vlen_get_buf_size_gen(H5VL_object_t *vol_obj, hid_t type_id, hid_t space_id, @@ -632,7 +633,8 @@ H5_DLL hbool_t H5D__chunk_is_space_alloc(const H5O_storage_t *storage); H5_DLL hbool_t H5D__chunk_is_data_cached(const H5D_shared_t *shared_dset); H5_DLL herr_t H5D__chunk_lookup(const H5D_t *dset, const hsize_t *scaled, H5D_chunk_ud_t *udata); H5_DLL herr_t H5D__chunk_allocated(const H5D_t *dset, hsize_t *nbytes); -H5_DLL herr_t H5D__chunk_allocate(const H5D_io_info_t *io_info, hbool_t full_overwrite, hsize_t old_dim[]); +H5_DLL herr_t H5D__chunk_allocate(const H5D_io_info_t *io_info, hbool_t full_overwrite, + const hsize_t old_dim[]); H5_DLL herr_t H5D__chunk_file_alloc(const H5D_chk_idx_info_t *idx_info, const H5F_block_t *old_chunk, H5F_block_t *new_chunk, hbool_t *need_insert, const hsize_t *scaled); H5_DLL herr_t H5D__chunk_update_old_edge_chunks(H5D_t *dset, hsize_t old_dim[]); diff --git a/src/H5Dpublic.h b/src/H5Dpublic.h index c52bef3..0b5fac6 100644 --- a/src/H5Dpublic.h +++ b/src/H5Dpublic.h @@ -28,9 +28,9 @@ /*****************/ /* Macros used to "unset" chunk cache configuration parameters */ -#define H5D_CHUNK_CACHE_NSLOTS_DEFAULT ((size_t)-1) -#define H5D_CHUNK_CACHE_NBYTES_DEFAULT ((size_t)-1) -#define H5D_CHUNK_CACHE_W0_DEFAULT (-1.0f) +#define H5D_CHUNK_CACHE_NSLOTS_DEFAULT SIZE_MAX +#define H5D_CHUNK_CACHE_NBYTES_DEFAULT SIZE_MAX +#define H5D_CHUNK_CACHE_W0_DEFAULT (-1.0) /* Bit flags for the H5Pset_chunk_opts() and H5Pget_chunk_opts() */ #define H5D_CHUNK_DONT_FILTER_PARTIAL_CHUNKS (0x0002u) @@ -46,11 +46,11 @@ typedef enum H5D_layout_t { H5D_LAYOUT_ERROR = -1, - H5D_COMPACT = 0, /**< raw data is very small */ - H5D_CONTIGUOUS = 1, /**< the default */ - H5D_CHUNKED = 2, /**< slow and fancy */ - H5D_VIRTUAL = 3, /**< actual data is stored in other datasets */ - H5D_NLAYOUTS = 4 /**< this one must be last! */ + H5D_COMPACT = 0, /**< raw data is very small */ + H5D_CONTIGUOUS = 1, /**< the default */ + H5D_CHUNKED = 2, /**< slow and fancy */ + H5D_VIRTUAL = 3, /**< actual data is stored in other datasets */ + H5D_NLAYOUTS = 4 /**< this one must be last! */ } H5D_layout_t; //! <!-- [H5D_layout_t_snip] --> @@ -160,6 +160,14 @@ typedef herr_t (*H5D_scatter_func_t)(const void **src_buf /*out*/, size_t *src_b typedef herr_t (*H5D_gather_func_t)(const void *dst_buf, size_t dst_buf_bytes_used, void *op_data); //! <!-- [H5D_gather_func_t_snip] --> +//! <!-- [H5D_chunk_iter_op_t_snip] --> +/** + * Define the operator function pointer for H5Dchunk_iter() + */ +//! <!-- [H5D_chunk_iter_op_t_snip] --> +typedef int (*H5D_chunk_iter_op_t)(const hsize_t *offset, uint32_t filter_mask, haddr_t addr, uint32_t nbytes, + void *op_data); + /********************/ /* Public Variables */ /********************/ @@ -241,6 +249,15 @@ H5_DLL hid_t H5Dcreate2(hid_t loc_id, const char *name, hid_t type_id, hid_t spa /** * -------------------------------------------------------------------------- + * \ingroup ASYNC + * \async_variant_of{H5Dcreate} + */ +H5_DLL hid_t H5Dcreate_async(const char *app_file, const char *app_func, unsigned app_line, hid_t loc_id, + const char *name, hid_t type_id, hid_t space_id, hid_t lcpl_id, hid_t dcpl_id, + hid_t dapl_id, hid_t es_id); + +/** + * -------------------------------------------------------------------------- * \ingroup H5D * * \brief Creates a dataset in a file without linking it into the file @@ -336,6 +353,14 @@ H5_DLL hid_t H5Dopen2(hid_t loc_id, const char *name, hid_t dapl_id); /** * -------------------------------------------------------------------------- + * \ingroup ASYNC + * \async_variant_of{H5Dopen} + */ +H5_DLL hid_t H5Dopen_async(const char *app_file, const char *app_func, unsigned app_line, hid_t loc_id, + const char *name, hid_t dapl_id, hid_t es_id); + +/** + * -------------------------------------------------------------------------- *\ingroup H5D * * \brief Returns an identifier for a copy of the dataspace for a dataset @@ -359,6 +384,14 @@ H5_DLL hid_t H5Dget_space(hid_t dset_id); /** * -------------------------------------------------------------------------- + * \ingroup ASYNC + * \async_variant_of{H5Dget_space} + */ +H5_DLL hid_t H5Dget_space_async(const char *app_file, const char *app_func, unsigned app_line, hid_t dset_id, + hid_t es_id); + +/** + * -------------------------------------------------------------------------- * \ingroup H5D * \todo Document this function! */ @@ -605,6 +638,51 @@ H5_DLL herr_t H5Dget_chunk_info_by_coord(hid_t dset_id, const hsize_t *offset, u * -------------------------------------------------------------------------- * \ingroup H5D * + * \brief Iterate over all chunks + * + * \dset_id + * \param[in] cb User callback function, called for every chunk. + * \param[in] op_data User-defined pointer to data required by op + * + * \return \herr_t + * + * \details H5Dget_chunk_iter iterates over all chunks in the dataset, calling the + * user supplied callback with the details of the chunk and the supplied + * \p op_data. + * + * Callback information: + * H5D_chunk_iter_op_t is defined as: + * + * typedef int (*H5D_chunk_iter_op_t)( + * const hsize_t *offset, + * uint32_t filter_mask, + * haddr_t addr, + * uint32_t nbytes, + * void *op_data); + * + * H5D_chunk_iter_op_t parameters: + * hsize_t *offset; IN/OUT: Array of starting logical coordinates of chunk. + * uint32_t filter_mask; IN: Filter mask of chunk. + * haddr_t addr; IN: Offset in file of chunk data. + * uint32_t nbytes; IN: Size in number of bytes of chunk data in file. + * void *op_data; IN/OUT: Pointer to any user-defined data + * associated with the operation. + * + * The return values from an operator are: + * Zero (H5_ITER_CONT) causes the iterator to continue, returning zero when all + * elements have been processed. + * Positive (H5_ITER_STOP) causes the iterator to immediately return that positive + * value, indicating short-circuit success. + * Negative (H5_ITER_ERROR) causes the iterator to immediately return that value, + * indicating failure. + * + */ +H5_DLL herr_t H5Dchunk_iter(hid_t dset_id, H5D_chunk_iter_op_t cb, void *op_data); + +/** + * -------------------------------------------------------------------------- + * \ingroup H5D + * * \brief Retrieves information about a chunk specified by its index * * \dset_id @@ -766,6 +844,16 @@ H5_DLL haddr_t H5Dget_offset(hid_t dset_id); */ H5_DLL herr_t H5Dread(hid_t dset_id, hid_t mem_type_id, hid_t mem_space_id, hid_t file_space_id, hid_t dxpl_id, void *buf /*out*/); + +/** + * -------------------------------------------------------------------------- + * \ingroup ASYNC + * \async_variant_of{H5Dread} + */ +H5_DLL herr_t H5Dread_async(const char *app_file, const char *app_func, unsigned app_line, hid_t dset_id, + hid_t mem_type_id, hid_t mem_space_id, hid_t file_space_id, hid_t dxpl_id, + void *buf /*out*/, hid_t es_id); + /** * -------------------------------------------------------------------------- * \ingroup H5D @@ -879,6 +967,15 @@ H5_DLL herr_t H5Dwrite(hid_t dset_id, hid_t mem_type_id, hid_t mem_space_id, hid /** * -------------------------------------------------------------------------- + * \ingroup ASYNC + * \async_variant_of{H5Dwrite} + */ +H5_DLL herr_t H5Dwrite_async(const char *app_file, const char *app_func, unsigned app_line, hid_t dset_id, + hid_t mem_type_id, hid_t mem_space_id, hid_t file_space_id, hid_t dxpl_id, + const void *buf, hid_t es_id); + +/** + * -------------------------------------------------------------------------- * \ingroup H5D * * \brief Writes a raw data chunk from a buffer directly to a dataset in a file @@ -1213,6 +1310,14 @@ H5_DLL herr_t H5Dset_extent(hid_t dset_id, const hsize_t size[]); /** * -------------------------------------------------------------------------- + * \ingroup ASYNC + * \async_variant_of{H5Dset_extent} + */ +H5_DLL herr_t H5Dset_extent_async(const char *app_file, const char *app_func, unsigned app_line, + hid_t dset_id, const hsize_t size[], hid_t es_id); + +/** + * -------------------------------------------------------------------------- * \ingroup H5D * * \brief Flushes all buffers associated with a dataset to disk @@ -1234,6 +1339,8 @@ H5_DLL herr_t H5Dset_extent(hid_t dset_id, const hsize_t size[]); */ H5_DLL herr_t H5Dflush(hid_t dset_id); +H5_DLL herr_t H5Dwait(hid_t dset_id); + /** * -------------------------------------------------------------------------- * \ingroup H5D @@ -1431,11 +1538,43 @@ H5_DLL herr_t H5Dgather(hid_t src_space_id, const void *src_buf, hid_t type_id, */ H5_DLL herr_t H5Dclose(hid_t dset_id); +/** + * -------------------------------------------------------------------------- + * \ingroup ASYNC + * \async_variant_of{H5Dclose} + */ +H5_DLL herr_t H5Dclose_async(const char *app_file, const char *app_func, unsigned app_line, hid_t dset_id, + hid_t es_id); + /* Internal API routines */ H5_DLL herr_t H5Ddebug(hid_t dset_id); H5_DLL herr_t H5Dformat_convert(hid_t dset_id); H5_DLL herr_t H5Dget_chunk_index_type(hid_t did, H5D_chunk_index_t *idx_type); +/* API Wrappers for async routines */ +/* (Must be defined _after_ the function prototype) */ +/* (And must only defined when included in application code, not the library) */ +#ifndef H5D_MODULE +#define H5Dcreate_async(...) H5Dcreate_async(__FILE__, __func__, __LINE__, __VA_ARGS__) +#define H5Dopen_async(...) H5Dopen_async(__FILE__, __func__, __LINE__, __VA_ARGS__) +#define H5Dget_space_async(...) H5Dget_space_async(__FILE__, __func__, __LINE__, __VA_ARGS__) +#define H5Dread_async(...) H5Dread_async(__FILE__, __func__, __LINE__, __VA_ARGS__) +#define H5Dwrite_async(...) H5Dwrite_async(__FILE__, __func__, __LINE__, __VA_ARGS__) +#define H5Dset_extent_async(...) H5Dset_extent_async(__FILE__, __func__, __LINE__, __VA_ARGS__) +#define H5Dclose_async(...) H5Dclose_async(__FILE__, __func__, __LINE__, __VA_ARGS__) + +/* Define "wrapper" versions of function calls, to allow compile-time values to + * be passed in by language wrapper or library layer on top of HDF5. + */ +#define H5Dcreate_async_wrap H5_NO_EXPAND(H5Dcreate_async) +#define H5Dopen_async_wrap H5_NO_EXPAND(H5Dopen_async) +#define H5Dget_space_async_wrap H5_NO_EXPAND(H5Dget_space_async) +#define H5Dread_async_wrap H5_NO_EXPAND(H5Dread_async) +#define H5Dwrite_async_wrap H5_NO_EXPAND(H5Dwrite_async) +#define H5Dset_extent_async_wrap H5_NO_EXPAND(H5Dset_extent_async) +#define H5Dclose_async_wrap H5_NO_EXPAND(H5Dclose_async) +#endif /* H5D_MODULE */ + /* Symbols defined for compatibility with previous versions of the HDF5 API. * * Use of these symbols is deprecated. @@ -76,15 +76,16 @@ /* Static function declarations */ static herr_t H5E__set_default_auto(H5E_t *stk); static H5E_cls_t *H5E__register_class(const char *cls_name, const char *lib_name, const char *version); -static herr_t H5E__unregister_class(H5E_cls_t *cls); +static herr_t H5E__unregister_class(H5E_cls_t *cls, void **request); static ssize_t H5E__get_class_name(const H5E_cls_t *cls, char *name, size_t size); static int H5E__close_msg_cb(void *obj_ptr, hid_t obj_id, void *udata); -static herr_t H5E__close_msg(H5E_msg_t *err); +static herr_t H5E__close_msg(H5E_msg_t *err, void **request); static H5E_msg_t *H5E__create_msg(H5E_cls_t *cls, H5E_type_t msg_type, const char *msg); static H5E_t * H5E__get_current_stack(void); static herr_t H5E__set_current_stack(H5E_t *estack); -static herr_t H5E__close_stack(H5E_t *err_stack); +static herr_t H5E__close_stack(H5E_t *err_stack, void **request); static ssize_t H5E__get_num(const H5E_t *err_stack); +static herr_t H5E__print2(hid_t err_stack, FILE *stream); static herr_t H5E__append_stack(H5E_t *dst_estack, const H5E_t *src_stack); /*********************/ @@ -245,6 +246,20 @@ H5E_term_package(void) nstk = H5I_nmembers(H5I_ERROR_STACK); if ((ncls + nmsg + nstk) > 0) { + /* Clear the default error stack. Note that + * the following H5I_clear_type calls do not + * force the clears and will not be able to + * clear any error message IDs that are still + * in use by the default error stack unless we + * clear that stack manually. + * + * Error message IDs will typically still be + * in use by the default error stack when the + * application does H5E_BEGIN/END_TRY cleanup + * at the very end. + */ + H5E_clear_stack(NULL); + /* Clear any outstanding error stacks */ if (nstk > 0) (void)H5I_clear_type(H5I_ERROR_STACK, FALSE, FALSE); @@ -312,10 +327,10 @@ H5E__set_default_auto(H5E_t *stk) #endif /* H5_USE_16_API_DEFAULT */ stk->auto_op.func1 = stk->auto_op.func1_default = (H5E_auto1_t)H5Eprint1; - stk->auto_op.func2 = stk->auto_op.func2_default = (H5E_auto2_t)H5Eprint2; + stk->auto_op.func2 = stk->auto_op.func2_default = (H5E_auto2_t)H5E__print2; stk->auto_op.is_default = TRUE; #else /* H5_NO_DEPRECATED_SYMBOLS */ - stk->auto_op.func2 = (H5E_auto2_t)H5Eprint2; + stk->auto_op.func2 = (H5E_auto2_t)H5E__print2; #endif /* H5_NO_DEPRECATED_SYMBOLS */ stk->auto_data = NULL; @@ -541,7 +556,7 @@ done: *------------------------------------------------------------------------- */ static herr_t -H5E__unregister_class(H5E_cls_t *cls) +H5E__unregister_class(H5E_cls_t *cls, void H5_ATTR_UNUSED **request) { herr_t ret_value = SUCCEED; /* Return value */ @@ -661,7 +676,7 @@ H5E__close_msg_cb(void *obj_ptr, hid_t obj_id, void *udata) /* Close the message if it is in the class being closed */ if (err_msg->cls == cls) { - if (H5E__close_msg(err_msg) < 0) + if (H5E__close_msg(err_msg, NULL) < 0) HGOTO_ERROR(H5E_ERROR, H5E_CANTCLOSEOBJ, H5_ITER_ERROR, "unable to close error message") if (NULL == H5I_remove(obj_id)) HGOTO_ERROR(H5E_ERROR, H5E_CANTREMOVE, H5_ITER_ERROR, "unable to remove error message") @@ -716,7 +731,7 @@ done: *------------------------------------------------------------------------- */ static herr_t -H5E__close_msg(H5E_msg_t *err) +H5E__close_msg(H5E_msg_t *err, void H5_ATTR_UNUSED **request) { FUNC_ENTER_STATIC_NOERR @@ -817,7 +832,7 @@ H5E__create_msg(H5E_cls_t *cls, H5E_type_t msg_type, const char *msg_str) done: if (!ret_value) - if (msg && H5E__close_msg(msg) < 0) + if (msg && H5E__close_msg(msg, NULL) < 0) HDONE_ERROR(H5E_ERROR, H5E_CANTCLOSEOBJ, NULL, "unable to close error message") FUNC_LEAVE_NOAPI(ret_value) @@ -1164,7 +1179,7 @@ done: *------------------------------------------------------------------------- */ static herr_t -H5E__close_stack(H5E_t *estack) +H5E__close_stack(H5E_t *estack, void H5_ATTR_UNUSED **request) { FUNC_ENTER_STATIC_NOERR @@ -1433,13 +1448,37 @@ done: herr_t H5Eprint2(hid_t err_stack, FILE *stream) { - H5E_t *estack; /* Error stack to operate on */ herr_t ret_value = SUCCEED; /* Return value */ /* Don't clear the error stack! :-) */ FUNC_ENTER_API_NOCLEAR(FAIL) /*NO TRACE*/ + /* Print error stack */ + if ((ret_value = H5E__print2(err_stack, stream)) < 0) + HGOTO_ERROR(H5E_ERROR, H5E_CANTLIST, FAIL, "can't display error stack") + +done: + FUNC_LEAVE_API(ret_value) +} /* end H5Eprint2() */ + +/*------------------------------------------------------------------------- + * Function: H5E__print2 + * + * Purpose: Internal helper routine for H5Eprint2. + * + * Return: Non-negative on success/Negative on failure + * + *------------------------------------------------------------------------- + */ +static herr_t +H5E__print2(hid_t err_stack, FILE *stream) +{ + H5E_t *estack; /* Error stack to operate on */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_STATIC + /* Need to check for errors */ if (err_stack == H5E_DEFAULT) { if (NULL == (estack = H5E__get_my_stack())) /*lint !e506 !e774 Make lint 'constant value Boolean' in @@ -1459,8 +1498,8 @@ H5Eprint2(hid_t err_stack, FILE *stream) HGOTO_ERROR(H5E_ERROR, H5E_CANTLIST, FAIL, "can't display error stack") done: - FUNC_LEAVE_API(ret_value) -} /* end H5Eprint2() */ + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5E__print2() */ /*------------------------------------------------------------------------- * Function: H5Ewalk2 @@ -1532,7 +1571,8 @@ H5Eget_auto2(hid_t estack_id, H5E_auto2_t *func /*out*/, void **client_data /*ou H5E_auto_op_t op; /* Error stack function */ herr_t ret_value = SUCCEED; /* Return value */ - FUNC_ENTER_API(FAIL) + /* Don't clear the error stack! :-) */ + FUNC_ENTER_API_NOCLEAR(FAIL) H5TRACE3("e", "ixx", estack_id, func, client_data); if (estack_id == H5E_DEFAULT) { @@ -1540,8 +1580,13 @@ H5Eget_auto2(hid_t estack_id, H5E_auto2_t *func /*out*/, void **client_data /*ou non-threaded case */ HGOTO_ERROR(H5E_ERROR, H5E_CANTGET, FAIL, "can't get current error stack") } /* end if */ - else if (NULL == (estack = (H5E_t *)H5I_object_verify(estack_id, H5I_ERROR_STACK))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a error stack ID") + else { + /* Only clear the error stack if it's not the default stack */ + H5E_clear_stack(NULL); + + if (NULL == (estack = (H5E_t *)H5I_object_verify(estack_id, H5I_ERROR_STACK))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a error stack ID") + } /* end else */ /* Get the automatic error reporting information */ if (H5E__get_auto(estack, &op, client_data) < 0) @@ -1598,8 +1643,13 @@ H5Eset_auto2(hid_t estack_id, H5E_auto2_t func, void *client_data) non-threaded case */ HGOTO_ERROR(H5E_ERROR, H5E_CANTGET, FAIL, "can't get current error stack") } /* end if */ - else if (NULL == (estack = (H5E_t *)H5I_object_verify(estack_id, H5I_ERROR_STACK))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a error stack ID") + else { + /* Only clear the error stack if it's not the default stack */ + H5E_clear_stack(NULL); + + if (NULL == (estack = (H5E_t *)H5I_object_verify(estack_id, H5I_ERROR_STACK))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a error stack ID") + } /* end else */ #ifndef H5_NO_DEPRECATED_SYMBOLS /* Get the automatic error reporting information */ @@ -1646,7 +1696,8 @@ H5Eauto_is_v2(hid_t estack_id, unsigned *is_stack) H5E_t *estack; /* Error stack to operate on */ herr_t ret_value = SUCCEED; /* Return value */ - FUNC_ENTER_API(FAIL) + /* Don't clear the error stack! :-) */ + FUNC_ENTER_API_NOCLEAR(FAIL) H5TRACE2("e", "i*Iu", estack_id, is_stack); if (estack_id == H5E_DEFAULT) { @@ -1654,8 +1705,13 @@ H5Eauto_is_v2(hid_t estack_id, unsigned *is_stack) non-threaded case */ HGOTO_ERROR(H5E_ERROR, H5E_CANTGET, FAIL, "can't get current error stack") } /* end if */ - else if (NULL == (estack = (H5E_t *)H5I_object_verify(estack_id, H5I_ERROR_STACK))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a error stack ID") + else { + /* Only clear the error stack if it's not the default stack */ + H5E_clear_stack(NULL); + + if (NULL == (estack = (H5E_t *)H5I_object_verify(estack_id, H5I_ERROR_STACK))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a error stack ID") + } /* end else */ /* Check if the error stack reporting function is the "newer" stack type */ if (is_stack) diff --git a/src/H5ES.c b/src/H5ES.c new file mode 100644 index 0000000..2ba8a72 --- /dev/null +++ b/src/H5ES.c @@ -0,0 +1,378 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * 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. * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +/*------------------------------------------------------------------------- + * + * Created: H5ES.c + * Apr 6 2020 + * Quincey Koziol + * + * Purpose: Implements an "event set" for managing asynchronous + * operations. + * + * Please see the asynchronous I/O RFC document + * for a full description of how they work, etc. + * + *------------------------------------------------------------------------- + */ + +/****************/ +/* Module Setup */ +/****************/ + +#include "H5ESmodule.h" /* This source code file is part of the H5ES module */ + +/***********/ +/* Headers */ +/***********/ +#include "H5private.h" /* Generic Functions */ +#include "H5Eprivate.h" /* Error handling */ +#include "H5ESpkg.h" /* Event Sets */ +#include "H5FLprivate.h" /* Free Lists */ +#include "H5Iprivate.h" /* IDs */ + +/****************/ +/* Local Macros */ +/****************/ + +/******************/ +/* Local Typedefs */ +/******************/ + +/********************/ +/* Package Typedefs */ +/********************/ + +/********************/ +/* Local Prototypes */ +/********************/ + +/*********************/ +/* Package Variables */ +/*********************/ + +/*****************************/ +/* Library Private Variables */ +/*****************************/ + +/*******************/ +/* Local Variables */ +/*******************/ + +/*------------------------------------------------------------------------- + * Function: H5EScreate + * + * Purpose: Creates an event set. + * + * Return: Success: An ID for the event set + * Failure: H5I_INVALID_HID + * + * Programmer: Quincey Koziol + * Wednesday, April 8, 2020 + * + *------------------------------------------------------------------------- + */ +hid_t +H5EScreate(void) +{ + H5ES_t *es; /* Pointer to event set object */ + hid_t ret_value = H5I_INVALID_HID; /* Return value */ + + FUNC_ENTER_API(H5I_INVALID_HID) + H5TRACE0("i", ""); + + /* Create the new event set object */ + if (NULL == (es = H5ES__create())) + HGOTO_ERROR(H5E_EVENTSET, H5E_CANTCREATE, H5I_INVALID_HID, "can't create event set") + + /* Register the new event set to get an ID for it */ + if ((ret_value = H5I_register(H5I_EVENTSET, es, TRUE)) < 0) + HGOTO_ERROR(H5E_EVENTSET, H5E_CANTREGISTER, H5I_INVALID_HID, "can't register event set") + +done: + FUNC_LEAVE_API(ret_value) +} /* end H5EScreate() */ + +/*------------------------------------------------------------------------- + * Function: H5ESget_count + * + * Purpose: Retrieve the # of events in an event set + * + * Return: SUCCEED / FAIL + * + * Programmer: Quincey Koziol + * Wednesday, April 8, 2020 + * + *------------------------------------------------------------------------- + */ +herr_t +H5ESget_count(hid_t es_id, size_t *count /*out*/) +{ + H5ES_t *es; /* Event set */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_API(FAIL) + H5TRACE2("e", "ix", es_id, count); + + /* Check arguments */ + if (NULL == (es = H5I_object_verify(es_id, H5I_EVENTSET))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid event set identifier") + + /* Retrieve the count, if non-NULL */ + if (count) + *count = H5ES__list_count(&es->active); + +done: + FUNC_LEAVE_API(ret_value) +} /* end H5ESget_count() */ + +/*------------------------------------------------------------------------- + * Function: H5ESget_op_counter + * + * Purpose: Retrieve the counter that will be assigned to the next operation + * inserted into the event set. + * + * Note: This is designed for wrapper libraries mainly, to use as a + * mechanism for matching operations inserted into the event + * set with [possible] errors that occur. + * + * Return: SUCCEED / FAIL + * + * Programmer: Quincey Koziol + * Fiiday, November 6, 2020 + * + *------------------------------------------------------------------------- + */ +herr_t +H5ESget_op_counter(hid_t es_id, uint64_t *op_counter /*out*/) +{ + H5ES_t *es; /* Event set */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_API(FAIL) + H5TRACE2("e", "ix", es_id, op_counter); + + /* Check arguments */ + if (NULL == (es = H5I_object_verify(es_id, H5I_EVENTSET))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid event set identifier") + + /* Retrieve the operation counter, if non-NULL */ + if (op_counter) + *op_counter = es->op_counter; + +done: + FUNC_LEAVE_API(ret_value) +} /* end H5ESget_op_counter() */ + +/*------------------------------------------------------------------------- + * Function: H5ESwait + * + * Purpose: Wait (with timeout) for operations in event set to complete + * + * Note: Timeout value is in ns, and is for the H5ESwait call, not each + * individual operation. For example: if '10' is passed as + * a timeout value and the event set waited 4ns for the first + * operation to complete, the remaining operations would be + * allowed to wait for at most 6ns more. i.e. the timeout value + * is "used up" across all operations, until it reaches 0, then + * any remaining operations are only checked for completion, not + * waited on. + * + * Note: This call will stop waiting on operations and will return + * immediately if an operation fails. If a failure occurs, the + * value returned for the # of operations in progress may be + * inaccurate. + * + * Return: SUCCEED / FAIL + * + * Programmer: Quincey Koziol + * Monday, July 13, 2020 + * + *------------------------------------------------------------------------- + */ +herr_t +H5ESwait(hid_t es_id, uint64_t timeout, size_t *num_in_progress /*out*/, hbool_t *op_failed /*out*/) +{ + H5ES_t *es; /* Event set */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_API(FAIL) + H5TRACE4("e", "iULxx", es_id, timeout, num_in_progress, op_failed); + + /* Check arguments */ + if (NULL == (es = H5I_object_verify(es_id, H5I_EVENTSET))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid event set identifier") + if (NULL == num_in_progress) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "NULL num_in_progress pointer") + if (NULL == op_failed) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "NULL op_failed pointer") + + /* Wait for operations */ + if (H5ES__wait(es, timeout, num_in_progress, op_failed) < 0) + HGOTO_ERROR(H5E_EVENTSET, H5E_CANTWAIT, FAIL, "can't wait on operations") + +done: + FUNC_LEAVE_API(ret_value) +} /* end H5ESwait() */ + +/*------------------------------------------------------------------------- + * Function: H5ESget_err_status + * + * Purpose: Check if event set has failed operations + * + * Return: SUCCEED / FAIL + * + * Programmer: Quincey Koziol + * Thursday, October 15, 2020 + * + *------------------------------------------------------------------------- + */ +herr_t +H5ESget_err_status(hid_t es_id, hbool_t *err_status /*out*/) +{ + H5ES_t *es; /* Event set */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_API(FAIL) + H5TRACE2("e", "ix", es_id, err_status); + + /* Check arguments */ + if (NULL == (es = H5I_object_verify(es_id, H5I_EVENTSET))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid event set identifier") + + /* Retrieve the error flag, if non-NULL */ + if (err_status) + *err_status = es->err_occurred; + +done: + FUNC_LEAVE_API(ret_value) +} /* end H5ESget_err_status() */ + +/*------------------------------------------------------------------------- + * Function: H5ESget_err_count + * + * Purpose: Retrieve # of failed operations + * + * Note: Does not wait for active operations to complete, so count may + * not include all failures. + * + * Return: SUCCEED / FAIL + * + * Programmer: Quincey Koziol + * Thursday, October 15, 2020 + * + *------------------------------------------------------------------------- + */ +herr_t +H5ESget_err_count(hid_t es_id, size_t *num_errs /*out*/) +{ + H5ES_t *es; /* Event set */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_API(FAIL) + H5TRACE2("e", "ix", es_id, num_errs); + + /* Check arguments */ + if (NULL == (es = H5I_object_verify(es_id, H5I_EVENTSET))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid event set identifier") + + /* Retrieve the error flag, if non-NULL */ + if (num_errs) { + if (es->err_occurred) + *num_errs = H5ES__list_count(&es->failed); + else + *num_errs = 0; + } /* end if */ + +done: + FUNC_LEAVE_API(ret_value) +} /* end H5ESget_err_count() */ + +/*------------------------------------------------------------------------- + * Function: H5ESget_err_info + * + * Purpose: Retrieve information about failed operations + * + * Note: The strings retrieved for each error info must be released + * by calling H5free_memory(). + * + * Return: SUCCEED / FAIL + * + * Programmer: Quincey Koziol + * Friday, November 6, 2020 + * + *------------------------------------------------------------------------- + */ +herr_t +H5ESget_err_info(hid_t es_id, size_t num_err_info, H5ES_err_info_t err_info[] /*out*/, + size_t *num_cleared /*out*/) +{ + H5ES_t *es; /* Event set */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_API(FAIL) + H5TRACE4("e", "izxx", es_id, num_err_info, err_info, num_cleared); + + /* Check arguments */ + if (NULL == (es = H5I_object_verify(es_id, H5I_EVENTSET))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid event set identifier") + if (0 == num_err_info) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "err_info array size is 0") + if (NULL == err_info) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "NULL err_info array pointer") + if (NULL == num_cleared) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "NULL errors cleared pointer") + + /* Retrieve the error information */ + if (H5ES__get_err_info(es, num_err_info, err_info, num_cleared) < 0) + HGOTO_ERROR(H5E_EVENTSET, H5E_CANTGET, FAIL, "can't retrieve error info for failed operation(s)") + +done: + FUNC_LEAVE_API(ret_value) +} /* end H5ESget_err_info() */ + +/*------------------------------------------------------------------------- + * Function: H5ESclose + * + * Purpose: Closes an event set. + * + * Note: Fails if active operations are present. + * + * Return: SUCCEED / FAIL + * + * Programmer: Quincey Koziol + * Wednesday, April 8, 2020 + * + *------------------------------------------------------------------------- + */ +herr_t +H5ESclose(hid_t es_id) +{ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_API(FAIL) + H5TRACE1("e", "i", es_id); + + /* Check arguments */ + if (H5I_EVENTSET != H5I_get_type(es_id)) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not an event set") + + /* + * Decrement the counter on the object. It will be freed if the count + * reaches zero. + */ + if (H5I_dec_app_ref(es_id) < 0) + HGOTO_ERROR(H5E_EVENTSET, H5E_CANTDEC, FAIL, "unable to decrement ref count on event set") + +done: + FUNC_LEAVE_API(ret_value) +} /* end H5ESclose() */ diff --git a/src/H5ESevent.c b/src/H5ESevent.c new file mode 100644 index 0000000..b0c3578 --- /dev/null +++ b/src/H5ESevent.c @@ -0,0 +1,197 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * 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. * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +/*------------------------------------------------------------------------- + * + * Created: H5ESevent.c + * Nov 7 2020 + * Quincey Koziol + * + * Purpose: Operations on "events" for managing asynchronous + * operations. + * + * Please see the asynchronous I/O RFC document + * for a full description of how they work, etc. + * + *------------------------------------------------------------------------- + */ + +/****************/ +/* Module Setup */ +/****************/ + +#include "H5ESmodule.h" /* This source code file is part of the H5ES module */ + +/***********/ +/* Headers */ +/***********/ +#include "H5private.h" /* Generic Functions */ +#include "H5Eprivate.h" /* Error handling */ +#include "H5ESpkg.h" /* Event Sets */ +#include "H5FLprivate.h" /* Free Lists */ +#include "H5MMprivate.h" /* Memory management */ + +/****************/ +/* Local Macros */ +/****************/ + +/******************/ +/* Local Typedefs */ +/******************/ + +/********************/ +/* Package Typedefs */ +/********************/ + +/********************/ +/* Local Prototypes */ +/********************/ + +/*********************/ +/* Package Variables */ +/*********************/ + +/*****************************/ +/* Library Private Variables */ +/*****************************/ + +/*******************/ +/* Local Variables */ +/*******************/ + +/* Declare a static free list to manage H5ES_event_t structs */ +H5FL_DEFINE_STATIC(H5ES_event_t); + +/*------------------------------------------------------------------------- + * Function: H5ES__event_new + * + * Purpose: Allocate and initialize a new event + * + * Return: Non-NULL pointer to new event on success, NULL on failure + * + * Programmer: Quincey Koziol + * Saturday, November 7, 2020 + * + *------------------------------------------------------------------------- + */ +H5ES_event_t * +H5ES__event_new(H5VL_t *connector, void *token) +{ + H5ES_event_t * ev = NULL; /* New event */ + H5VL_object_t *request = NULL; /* Async request token VOL object */ + H5ES_event_t * ret_value = NULL; /* Return value */ + + FUNC_ENTER_PACKAGE + + /* Sanity check */ + HDassert(connector); + HDassert(token); + + /* Create vol object for token */ + if (NULL == (request = H5VL_create_object(token, connector))) { + if (H5VL_request_free(token) < 0) + HDONE_ERROR(H5E_EVENTSET, H5E_CANTFREE, NULL, "can't free request") + HGOTO_ERROR(H5E_EVENTSET, H5E_CANTINIT, NULL, "can't create vol object for request token") + } /* end if */ + + /* Allocate space for new event */ + if (NULL == (ev = H5FL_CALLOC(H5ES_event_t))) + HGOTO_ERROR(H5E_EVENTSET, H5E_CANTALLOC, NULL, "can't allocate event object") + + /* Set request for event */ + ev->request = request; + + /* Set return value */ + ret_value = ev; + +done: + FUNC_LEAVE_NOAPI(ret_value); +} /* end H5ES__event_new() */ + +/*------------------------------------------------------------------------- + * Function: H5ES__event_free + * + * Purpose: Free an event + * + * Return: SUCCEED / FAIL + * + * Programmer: Quincey Koziol + * Saturday, November 7, 2020 + * + *------------------------------------------------------------------------- + */ +herr_t +H5ES__event_free(H5ES_event_t *ev) +{ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_PACKAGE + + /* Sanity check */ + HDassert(ev); + + if (ev->api_name) + H5MM_xfree_const(ev->api_name); + if (ev->api_args) + H5MM_xfree_const(ev->api_args); + if (ev->app_file) + H5MM_xfree_const(ev->app_file); + if (ev->app_func) + H5MM_xfree_const(ev->app_func); + if (ev->request) { + /* Free the request */ + if (H5VL_request_free(ev->request) < 0) + HGOTO_ERROR(H5E_EVENTSET, H5E_CANTFREE, FAIL, "unable to free request") + + /* Free the VOL object for the request */ + if (H5VL_free_object(ev->request) < 0) + HGOTO_ERROR(H5E_EVENTSET, H5E_CANTRELEASE, FAIL, "can't free VOL request object") + } /* end if */ + + H5FL_FREE(H5ES_event_t, ev); + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5ES__event_free() */ + +/*------------------------------------------------------------------------- + * Function: H5ES__event_completed + * + * Purpose: Handle a completed event + * + * Return: SUCCEED / FAIL + * + * Programmer: Quincey Koziol + * Sunday, November 8, 2020 + * + *------------------------------------------------------------------------- + */ +herr_t +H5ES__event_completed(H5ES_event_t *ev, H5ES_event_list_t *el) +{ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_PACKAGE + + /* Sanity check */ + HDassert(ev); + + /* Remove the event from the event list */ + H5ES__list_remove(el, ev); + + /* Free the event */ + if (H5ES__event_free(ev) < 0) + HGOTO_ERROR(H5E_EVENTSET, H5E_CANTFREE, FAIL, "unable to free event") + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5ES__event_completed() */ diff --git a/src/H5ESint.c b/src/H5ESint.c new file mode 100644 index 0000000..da3f779 --- /dev/null +++ b/src/H5ESint.c @@ -0,0 +1,666 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * 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. * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +/*------------------------------------------------------------------------- + * + * Created: H5ESint.c + * Apr 8 2020 + * Quincey Koziol + * + * Purpose: Internal "event set" routines for managing asynchronous + * operations. + * + * Please see the asynchronous I/O RFC document + * for a full description of how they work, etc. + * + *------------------------------------------------------------------------- + */ + +/****************/ +/* Module Setup */ +/****************/ + +#include "H5ESmodule.h" /* This source code file is part of the H5ES module */ + +/***********/ +/* Headers */ +/***********/ +#include "H5private.h" /* Generic Functions */ +#include "H5Eprivate.h" /* Error handling */ +#include "H5ESpkg.h" /* Event Sets */ +#include "H5FLprivate.h" /* Free Lists */ +#include "H5Iprivate.h" /* IDs */ +#include "H5MMprivate.h" /* Memory management */ +#include "H5RSprivate.h" /* Reference-counted strings */ + +/****************/ +/* Local Macros */ +/****************/ + +/******************/ +/* Local Typedefs */ +/******************/ + +/* Callback context for wait operations */ +typedef struct H5ES_wait_ctx_t { + H5ES_t * es; /* Event set being operated on */ + uint64_t timeout; /* Timeout for wait operation */ + size_t * num_in_progress; /* Count of # of operations that have not completed */ + hbool_t *op_failed; /* Flag to indicate an operation failed */ +} H5ES_wait_ctx_t; + +/* Callback context for get error info (gei) operations */ +typedef struct H5ES_gei_ctx_t { + H5ES_t * es; /* Event set being operated on */ + size_t num_err_info; /* # of elements in err_info[] array */ + size_t curr_err; /* Index of current error in array */ + H5ES_err_info_t *curr_err_info; /* Pointer to current element in err_info[] array */ +} H5ES_gei_ctx_t; + +/********************/ +/* Package Typedefs */ +/********************/ + +/********************/ +/* Local Prototypes */ +/********************/ +static herr_t H5ES__close_cb(void *es, void **request_token); +static herr_t H5ES__handle_fail(H5ES_t *es, H5ES_event_t *ev); +static int H5ES__wait_cb(H5ES_event_t *ev, void *_ctx); +static int H5ES__get_err_info_cb(H5ES_event_t *ev, void *_ctx); +static int H5ES__close_failed_cb(H5ES_event_t *ev, void *_ctx); + +/*********************/ +/* Package Variables */ +/*********************/ + +/* Package initialization variable */ +hbool_t H5_PKG_INIT_VAR = FALSE; + +/*****************************/ +/* Library Private Variables */ +/*****************************/ + +/*******************/ +/* Local Variables */ +/*******************/ + +/* Event Set ID class */ +static const H5I_class_t H5I_EVENTSET_CLS[1] = {{ + H5I_EVENTSET, /* ID class value */ + 0, /* Class flags */ + 0, /* # of reserved IDs for class */ + (H5I_free_t)H5ES__close_cb /* Callback routine for closing objects of this class */ +}}; + +/* Declare a static free list to manage H5ES_t structs */ +H5FL_DEFINE_STATIC(H5ES_t); + +/*------------------------------------------------------------------------- + * Function: H5ES__init_package + * + * Purpose: Initializes any interface-specific data or routines. + * + * Return: Non-negative on success / Negative on failure + * + * Programmer: Quincey Koziol + * Monday, April 6, 2020 + * + *------------------------------------------------------------------------- + */ +herr_t +H5ES__init_package(void) +{ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_PACKAGE + + /* Initialize the ID group for the event set IDs */ + if (H5I_register_type(H5I_EVENTSET_CLS) < 0) + HGOTO_ERROR(H5E_EVENTSET, H5E_CANTINIT, FAIL, "unable to initialize interface") + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5ES__init_package() */ + +/*------------------------------------------------------------------------- + * Function: H5ES_term_package + * + * Purpose: Terminate this interface. + * + * Return: Success: Positive if anything is done that might + * affect other interfaces; zero otherwise. + * Failure: Negative + * + * Programmer: Quincey Koziol + * Monday, April 6, 2020 + * + *------------------------------------------------------------------------- + */ +int +H5ES_term_package(void) +{ + int n = 0; + + FUNC_ENTER_NOAPI_NOINIT_NOERR + + if (H5_PKG_INIT_VAR) { + /* Destroy the event set ID group */ + n += (H5I_dec_type_ref(H5I_EVENTSET) > 0); + + /* Mark closed */ + if (0 == n) + H5_PKG_INIT_VAR = FALSE; + } /* end if */ + + FUNC_LEAVE_NOAPI(n) +} /* end H5ES_term_package() */ + +/*------------------------------------------------------------------------- + * Function: H5ES__close_cb + * + * Purpose: Called when the ref count reaches zero on an event set's ID + * + * Return: SUCCEED / FAIL + * + * Programmer: Quincey Koziol + * Monday, April 6, 2020 + * + *------------------------------------------------------------------------- + */ +static herr_t +H5ES__close_cb(void *_es, void H5_ATTR_UNUSED **rt) +{ + H5ES_t *es = (H5ES_t *)_es; /* The event set to close */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_STATIC + + /* Sanity check */ + HDassert(es); + + /* Close the event set object */ + if (H5ES__close(es) < 0) + HGOTO_ERROR(H5E_EVENTSET, H5E_CLOSEERROR, FAIL, "unable to close event set"); + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5ES__close_cb() */ + +/*------------------------------------------------------------------------- + * Function: H5ES__create + * + * Purpose: Private function to create an event set object + * + * Return: Success: Pointer to an event set struct + * Failure: NULL + * + * Programmer: Quincey Koziol + * Wednesday, April 8, 2020 + * + *------------------------------------------------------------------------- + */ +H5ES_t * +H5ES__create(void) +{ + H5ES_t *es = NULL; /* Pointer to event set */ + H5ES_t *ret_value = NULL; /* Return value */ + + FUNC_ENTER_PACKAGE + + /* Allocate space for new event set */ + if (NULL == (es = H5FL_CALLOC(H5ES_t))) + HGOTO_ERROR(H5E_EVENTSET, H5E_CANTALLOC, NULL, "can't allocate event set object") + + /* Set the return value */ + ret_value = es; + +done: + if (!ret_value) + if (es && H5ES__close(es) < 0) + HDONE_ERROR(H5E_EVENTSET, H5E_CANTRELEASE, NULL, "unable to free event set") + + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5ES__create() */ + +/*------------------------------------------------------------------------- + * Function: H5ES_insert + * + * Purpose: Insert a request token into an event set + * + * Return: SUCCEED / FAIL + * + * Programmer: Quincey Koziol + * Wednesday, April 8, 2020 + * + *------------------------------------------------------------------------- + */ +herr_t +H5ES_insert(hid_t es_id, H5VL_t *connector, void *token, const char *caller, const char *caller_args, ...) +{ + H5ES_t * es = NULL; /* Event set for the operation */ + H5ES_event_t *ev = NULL; /* Event for request */ + H5RS_str_t * rs = NULL; /* Ref-counted string to compose formatted argument string in */ + const char * app_file; /* Application source file name */ + const char * app_func; /* Application source function name */ + const char * s; /* Pointer to internal string from ref-counted string */ + va_list ap; /* Varargs for caller */ + hbool_t arg_started = FALSE; /* Whether the va_list has been started */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI(FAIL) + + /* Sanity check */ + HDassert(connector); + HDassert(token); + HDassert(caller); + HDassert(caller_args); + + /* Get event set */ + if (NULL == (es = (H5ES_t *)H5I_object_verify(es_id, H5I_EVENTSET))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not an event set") + + /* Check for errors in event set */ + if (es->err_occurred) + HGOTO_ERROR(H5E_EVENTSET, H5E_CANTINSERT, FAIL, "event set has failed operations") + + /* Create new event */ + if (NULL == (ev = H5ES__event_new(connector, token))) + HGOTO_ERROR(H5E_EVENTSET, H5E_CANTCREATE, FAIL, "can't create event object") + + /* Start working on the API routines arguments */ + HDva_start(ap, caller_args); + arg_started = TRUE; + + /* Copy the app source information */ + (void)HDva_arg(ap, char *); /* Toss the 'app_file' parameter name */ + app_file = HDva_arg(ap, char *); + if (NULL == (ev->app_file = H5MM_strdup(app_file))) + HGOTO_ERROR(H5E_EVENTSET, H5E_CANTALLOC, FAIL, "can't copy app source file name") + (void)HDva_arg(ap, char *); /* Toss the 'app_func' parameter name */ + app_func = HDva_arg(ap, char *); + if (NULL == (ev->app_func = H5MM_strdup(app_func))) + HGOTO_ERROR(H5E_EVENTSET, H5E_CANTALLOC, FAIL, "can't copy app source function name") + (void)HDva_arg(ap, char *); /* Toss the 'app_line' parameter name */ + ev->app_line = HDva_arg(ap, unsigned); + + /* Set the event's operation counter */ + ev->ev_count = es->op_counter++; + + /* Set the event's timestamp */ + ev->ev_time = H5_now_usec(); + + /* Copy the API routine's name */ + if (NULL == (ev->api_name = H5MM_strdup(caller))) + HGOTO_ERROR(H5E_EVENTSET, H5E_CANTALLOC, FAIL, "can't copy API routine name") + + /* Create the string for the API routine's arguments */ + if (NULL == (rs = H5RS_create(NULL))) + HGOTO_ERROR(H5E_EVENTSET, H5E_CANTALLOC, FAIL, "can't allocate ref-counted string") + + /* Copy the string for the API routine's arguments */ + /* (skip the six characters from the app's file, function and line # arguments) */ + HDassert(0 == HDstrncmp(caller_args, "*s*sIu", 6)); + if (H5_trace_args(rs, caller_args + 6, ap) < 0) + HGOTO_ERROR(H5E_EVENTSET, H5E_CANTSET, FAIL, "can't create formatted API arguments") + if (NULL == (s = H5RS_get_str(rs))) + HGOTO_ERROR(H5E_EVENTSET, H5E_CANTGET, FAIL, "can't get pointer to formatted API arguments") + if (NULL == (ev->api_args = H5MM_strdup(s))) + HGOTO_ERROR(H5E_EVENTSET, H5E_CANTALLOC, FAIL, "can't copy API routine arguments") + + /* Append fully initialized event onto the event set's 'active' list */ + H5ES__list_append(&es->active, ev); + +done: + /* Clean up */ + if (arg_started) + HDva_end(ap); + if (rs) + H5RS_decr(rs); + + /* Release resources on error */ + if (ret_value < 0) + if (ev && H5ES__event_free(ev) < 0) + HDONE_ERROR(H5E_EVENTSET, H5E_CANTRELEASE, FAIL, "unable to release event") + + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5ES_insert() */ + +/*------------------------------------------------------------------------- + * Function: H5ES__handle_fail + * + * Purpose: Handle a failed event + * + * Return: SUCCEED / FAIL + * + * Programmer: Quincey Koziol + * Thursday, October 15, 2020 + * + *------------------------------------------------------------------------- + */ +static herr_t +H5ES__handle_fail(H5ES_t *es, H5ES_event_t *ev) +{ + FUNC_ENTER_STATIC_NOERR + + /* Sanity check */ + HDassert(es); + HDassert(es->active.head); + HDassert(ev); + + /* Set error flag for event set */ + es->err_occurred = TRUE; + + /* Remove event from normal list */ + H5ES__list_remove(&es->active, ev); + + /* Append event onto the event set's error list */ + H5ES__list_append(&es->failed, ev); + + FUNC_LEAVE_NOAPI(SUCCEED) +} /* end H5ES__handle_fail() */ + +/*------------------------------------------------------------------------- + * Function: H5ES__wait_cb + * + * Purpose: Common routine for testing / waiting on an operation + * + * Return: SUCCEED / FAIL + * + * Programmer: Quincey Koziol + * Sunday, November 7, 2020 + * + *------------------------------------------------------------------------- + */ +static int +H5ES__wait_cb(H5ES_event_t *ev, void *_ctx) +{ + H5ES_wait_ctx_t * ctx = (H5ES_wait_ctx_t *)_ctx; /* Callback context */ + H5VL_request_status_t ev_status = H5VL_REQUEST_STATUS_SUCCEED; /* Status from event's operation */ + uint64_t start_time = 0, elapsed_time = 0; /* Start and elapsed times for waiting on an operation */ + int ret_value = H5_ITER_CONT; /* Return value */ + + FUNC_ENTER_STATIC + + /* Sanity check */ + HDassert(ev); + HDassert(ctx); + + /* Wait on the request */ + if (ctx->timeout != H5ES_WAIT_NONE && ctx->timeout != H5ES_WAIT_FOREVER) + start_time = H5_now_usec(); + if (H5VL_request_wait(ev->request, ctx->timeout, &ev_status) < 0) + HGOTO_ERROR(H5E_EVENTSET, H5E_CANTWAIT, H5_ITER_ERROR, "unable to test operation") + if (ctx->timeout != H5ES_WAIT_NONE && ctx->timeout != H5ES_WAIT_FOREVER) + elapsed_time = H5_now_usec() - start_time; + + /* Check for status values that indicate we should break out of the loop */ + if (ev_status == H5VL_REQUEST_STATUS_FAIL) { + /* Handle failure */ + if (H5ES__handle_fail(ctx->es, ev) < 0) + HGOTO_ERROR(H5E_EVENTSET, H5E_CANTSET, H5_ITER_ERROR, "unable to handle failed event") + + /* Record the error */ + *ctx->op_failed = TRUE; + + /* Exit from the iteration */ + ret_value = H5_ITER_STOP; + } /* end if */ + else if (ev_status == H5VL_REQUEST_STATUS_SUCCEED) { + if (H5ES__event_completed(ev, &ctx->es->active) < 0) + HGOTO_ERROR(H5E_EVENTSET, H5E_CANTRELEASE, H5_ITER_ERROR, "unable to release completed event") + } /* end else-if */ + else if (ev_status == H5VL_REQUEST_STATUS_CANCELED) + /* Should never get a status of 'cancel' back from test / wait operation */ + HGOTO_ERROR(H5E_EVENTSET, H5E_BADVALUE, H5_ITER_ERROR, "received 'cancel' status for operation") + else { + /* Sanity check */ + HDassert(ev_status == H5VL_REQUEST_STATUS_IN_PROGRESS); + + /* Increment "in progress operation" counter */ + (*ctx->num_in_progress)++; + } /* end if */ + + /* Check for updateable timeout */ + if (ctx->timeout != H5ES_WAIT_NONE && ctx->timeout != H5ES_WAIT_FOREVER) { + /* Update timeout for next operation */ + if ((elapsed_time * 1000) > ctx->timeout) + ctx->timeout = H5ES_WAIT_NONE; + else + ctx->timeout -= (elapsed_time * 1000); /* Convert us to ns */ + } /* end if */ + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5ES__wait_cb() */ + +/*------------------------------------------------------------------------- + * Function: H5ES__wait + * + * Purpose: Wait for operations in event set to complete + * + * Note: Timeout value is in ns, and is for H5ES__wait itself. + * + * Return: SUCCEED / FAIL + * + * Programmer: Quincey Koziol + * Monday, July 13, 2020 + * + *------------------------------------------------------------------------- + */ +herr_t +H5ES__wait(H5ES_t *es, uint64_t timeout, size_t *num_in_progress, hbool_t *op_failed) +{ + H5ES_wait_ctx_t ctx; /* Iterator callback context info */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_PACKAGE + + /* Sanity check */ + HDassert(es); + HDassert(num_in_progress); + HDassert(op_failed); + + /* Set user's parameters to known values */ + *num_in_progress = 0; + *op_failed = FALSE; + + /* Set up context for iterator callbacks */ + ctx.es = es; + ctx.timeout = timeout; + ctx.num_in_progress = num_in_progress; + ctx.op_failed = op_failed; + + /* Iterate over the events in the set, waiting for them to complete */ + if (H5ES__list_iterate(&es->active, H5ES__wait_cb, &ctx) < 0) + HGOTO_ERROR(H5E_EVENTSET, H5E_BADITER, FAIL, "iteration failed") + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5ES__wait() */ + +/*------------------------------------------------------------------------- + * Function: H5ES__get_err_info_cb + * + * Purpose: Retrieve information about a failed operation + * + * Return: SUCCEED / FAIL + * + * Programmer: Quincey Koziol + * Monday, November 11, 2020 + * + *------------------------------------------------------------------------- + */ +static int +H5ES__get_err_info_cb(H5ES_event_t *ev, void *_ctx) +{ + H5ES_gei_ctx_t *ctx = (H5ES_gei_ctx_t *)_ctx; /* Callback context */ + int ret_value = H5_ITER_CONT; /* Return value */ + + FUNC_ENTER_STATIC + + /* Sanity check */ + HDassert(ev); + HDassert(ctx); + + /* Copy operation info for event */ + if (NULL == (ctx->curr_err_info->api_name = H5MM_strdup(ev->api_name))) + HGOTO_ERROR(H5E_EVENTSET, H5E_CANTALLOC, H5_ITER_ERROR, "can't copy HDF5 API name") + if (NULL == (ctx->curr_err_info->api_args = H5MM_strdup(ev->api_args))) + HGOTO_ERROR(H5E_EVENTSET, H5E_CANTALLOC, H5_ITER_ERROR, "can't copy HDF5 API routine arguments") + if (NULL == (ctx->curr_err_info->app_file_name = H5MM_strdup(ev->app_file))) + HGOTO_ERROR(H5E_EVENTSET, H5E_CANTALLOC, H5_ITER_ERROR, "can't copy app source file name") + if (NULL == (ctx->curr_err_info->app_func_name = H5MM_strdup(ev->app_func))) + HGOTO_ERROR(H5E_EVENTSET, H5E_CANTALLOC, H5_ITER_ERROR, "can't copy app function name") + ctx->curr_err_info->app_line_num = ev->app_line; + ctx->curr_err_info->op_ins_count = ev->ev_count; + ctx->curr_err_info->op_ins_ts = ev->ev_time; + + /* Get error stack for event */ + if (H5VL_request_specific(ev->request, H5VL_REQUEST_GET_ERR_STACK, &ctx->curr_err_info->err_stack_id) < 0) + HGOTO_ERROR(H5E_EVENTSET, H5E_CANTGET, H5_ITER_ERROR, "unable to retrieve error stack for operation") + + /* Remove event from event set's failed list */ + H5ES__list_remove(&ctx->es->failed, ev); + + /* Free event node */ + if (H5ES__event_free(ev) < 0) + HGOTO_ERROR(H5E_EVENTSET, H5E_CANTRELEASE, H5_ITER_ERROR, "unable to release failed event") + + /* Advance to next element of err_info[] array */ + ctx->curr_err++; + ctx->curr_err_info++; + + /* Stop iteration if err_info[] array is full */ + if (ctx->curr_err == ctx->num_err_info) + ret_value = H5_ITER_STOP; + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5ES__get_err_info_cb() */ + +/*------------------------------------------------------------------------- + * Function: H5ES__get_err_info + * + * Purpose: Retrieve information about failed operations + * + * Return: SUCCEED / FAIL + * + * Programmer: Quincey Koziol + * Friday, November 6, 2020 + * + *------------------------------------------------------------------------- + */ +herr_t +H5ES__get_err_info(H5ES_t *es, size_t num_err_info, H5ES_err_info_t err_info[], size_t *num_cleared) +{ + H5ES_gei_ctx_t ctx; /* Iterator callback context info */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_PACKAGE + + /* Sanity check */ + HDassert(es); + HDassert(num_err_info); + HDassert(err_info); + HDassert(num_cleared); + + /* Set up context for iterator callbacks */ + ctx.es = es; + ctx.num_err_info = num_err_info; + ctx.curr_err = 0; + ctx.curr_err_info = &err_info[0]; + + /* Iterate over the failed events in the set, copying their error info */ + if (H5ES__list_iterate(&es->failed, H5ES__get_err_info_cb, &ctx) < 0) + HGOTO_ERROR(H5E_EVENTSET, H5E_BADITER, FAIL, "iteration failed") + + /* Set # of failed events cleared from event set's failed list */ + *num_cleared = ctx.curr_err; + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5ES__get_err_info() */ + +/*------------------------------------------------------------------------- + * Function: H5ES__close_failed_cb + * + * Purpose: Release a failed event + * + * Return: SUCCEED / FAIL + * + * Programmer: Quincey Koziol + * Monday, November 11, 2020 + * + *------------------------------------------------------------------------- + */ +static int +H5ES__close_failed_cb(H5ES_event_t *ev, void *_ctx) +{ + H5ES_t *es = (H5ES_t *)_ctx; /* Callback context */ + int ret_value = H5_ITER_CONT; /* Return value */ + + FUNC_ENTER_PACKAGE + + /* Sanity check */ + HDassert(ev); + HDassert(es); + + /* Remove event from event set's failed list */ + H5ES__list_remove(&es->failed, ev); + + /* Free event node */ + if (H5ES__event_free(ev) < 0) + HGOTO_ERROR(H5E_EVENTSET, H5E_CANTRELEASE, H5_ITER_ERROR, "unable to release failed event") + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5ES__close_failed_cb() */ + +/*------------------------------------------------------------------------- + * Function: H5ES__close + * + * Purpose: Destroy an event set object + * + * Return: SUCCEED / FAIL + * + * Programmer: Quincey Koziol + * Monday, April 6, 2020 + * + *------------------------------------------------------------------------- + */ +herr_t +H5ES__close(H5ES_t *es) +{ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_PACKAGE + + /* Sanity check */ + HDassert(es); + + /* Fail if active operations still present */ + if (H5ES__list_count(&es->active) > 0) + HGOTO_ERROR( + H5E_EVENTSET, H5E_CANTCLOSEOBJ, FAIL, + "can't close event set while unfinished operations are present (i.e. wait on event set first)") + + /* Iterate over the failed events in the set, releasing them */ + if (H5ES__list_iterate(&es->failed, H5ES__close_failed_cb, (void *)es) < 0) + HGOTO_ERROR(H5E_EVENTSET, H5E_BADITER, FAIL, "iteration failed") + + /* Release the event set */ + es = H5FL_FREE(H5ES_t, es); + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5ES__close() */ diff --git a/src/H5ESlist.c b/src/H5ESlist.c new file mode 100644 index 0000000..c0e24cc --- /dev/null +++ b/src/H5ESlist.c @@ -0,0 +1,215 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * 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. * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +/*------------------------------------------------------------------------- + * + * Created: H5ESlist.c + * Nov 7 2020 + * Quincey Koziol + * + * Purpose: Operations on "event lists" for managing asynchronous + * operations. + * + * Please see the asynchronous I/O RFC document + * for a full description of how they work, etc. + * + *------------------------------------------------------------------------- + */ + +/****************/ +/* Module Setup */ +/****************/ + +#include "H5ESmodule.h" /* This source code file is part of the H5ES module */ + +/***********/ +/* Headers */ +/***********/ +#include "H5private.h" /* Generic Functions */ +#include "H5Eprivate.h" /* Error handling */ +#include "H5ESpkg.h" /* Event Sets */ +#include "H5FLprivate.h" /* Free Lists */ + +/****************/ +/* Local Macros */ +/****************/ + +/******************/ +/* Local Typedefs */ +/******************/ + +/********************/ +/* Package Typedefs */ +/********************/ + +/********************/ +/* Local Prototypes */ +/********************/ + +/*********************/ +/* Package Variables */ +/*********************/ + +/*****************************/ +/* Library Private Variables */ +/*****************************/ + +/*******************/ +/* Local Variables */ +/*******************/ + +/*------------------------------------------------------------------------- + * Function: H5ES__list_insert + * + * Purpose: Append an event into an event list + * + * Return: SUCCEED / FAIL + * + * Programmer: Quincey Koziol + * Saturday, November 7, 2020 + * + *------------------------------------------------------------------------- + */ +void +H5ES__list_append(H5ES_event_list_t *el, H5ES_event_t *ev) +{ + FUNC_ENTER_PACKAGE_NOERR + + /* Sanity check */ + HDassert(el); + HDassert(ev); + + /* Append event onto the event list */ + if (NULL == el->tail) + el->head = el->tail = ev; + else { + ev->prev = el->tail; + el->tail->next = ev; + el->tail = ev; + } /* end else */ + + /* Increment the # of events in list */ + el->count++; + + FUNC_LEAVE_NOAPI_VOID +} /* end H5ES__list_append() */ + +/*------------------------------------------------------------------------- + * Function: H5ES__list_count + * + * Purpose: Retrieve # of events in an event list + * + * Return: SUCCEED / FAIL + * + * Programmer: Quincey Koziol + * Saturday, November 7, 2020 + * + *------------------------------------------------------------------------- + */ +H5_ATTR_PURE size_t +H5ES__list_count(const H5ES_event_list_t *el) +{ + FUNC_ENTER_PACKAGE_NOERR + + /* Sanity check */ + HDassert(el); + + FUNC_LEAVE_NOAPI(el->count) +} /* end H5ES__list_count() */ + +/*------------------------------------------------------------------------- + * Function: H5ES__list_iterate + * + * Purpose: Iterate over events in a list, calling callback for + * each event. + * + * Note: Iteration is safe for deleting the current event. Modifying + * the list in other ways is likely unsafe. + * + * Return: SUCCEED / FAIL + * + * Programmer: Quincey Koziol + * Saturday, November 7, 2020 + * + *------------------------------------------------------------------------- + */ +int +H5ES__list_iterate(H5ES_event_list_t *el, H5ES_list_iter_func_t cb, void *ctx) +{ + H5ES_event_t *ev; /* Event in list */ + int ret_value = H5_ITER_CONT; /* Return value */ + + FUNC_ENTER_PACKAGE_NOERR + + /* Sanity check */ + HDassert(el); + HDassert(cb); + + /* Iterate over events in list */ + ev = el->head; + while (ev) { + H5ES_event_t *tmp; /* Temporary event */ + + /* Get pointer to next node, so it's safe if this one is removed */ + tmp = ev->next; + + /* Perform iterator callback */ + if ((ret_value = (*cb)(ev, ctx)) != H5_ITER_CONT) { + if (ret_value < 0) + HERROR(H5E_EVENTSET, H5E_CANTNEXT, "iteration operator failed"); + break; + } /* end if */ + + /* Advance to next node */ + ev = tmp; + } /* end while */ + + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5ES__list_iterate() */ + +/*------------------------------------------------------------------------- + * Function: H5ES__list_remove + * + * Purpose: Remove an event from an event list + * + * Return: SUCCEED / FAIL + * + * Programmer: Houjun Tang + * Thursday, July 30, 2020 + * + *------------------------------------------------------------------------- + */ +void +H5ES__list_remove(H5ES_event_list_t *el, const H5ES_event_t *ev) +{ + FUNC_ENTER_PACKAGE_NOERR + + /* Sanity check */ + HDassert(el); + HDassert(el->head); + HDassert(ev); + + /* Stitch event out of list */ + if (ev == el->head) + el->head = ev->next; + if (NULL != ev->next) + ev->next->prev = ev->prev; + if (NULL != ev->prev) + ev->prev->next = ev->next; + if (NULL == el->head) + el->tail = NULL; + + /* Decrement the # of events in list */ + el->count--; + + FUNC_LEAVE_NOAPI_VOID +} /* end H5ES__list_remove() */ diff --git a/src/H5ESmodule.h b/src/H5ESmodule.h new file mode 100644 index 0000000..cbc812e --- /dev/null +++ b/src/H5ESmodule.h @@ -0,0 +1,65 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * 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. * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +/* + * Programmer: Quincey Koziol + * Monday, April 6, 2020 + * + * Purpose: This file contains declarations which define macros for the + * H5ES package. Including this header means that the source file + * is part of the H5ES package. + */ +#ifndef H5ESmodule_H +#define H5ESmodule_H + +/* Define the proper control macros for the generic FUNC_ENTER/LEAVE and error + * reporting macros. + */ +#define H5ES_MODULE +#define H5_MY_PKG H5ES +#define H5_MY_PKG_ERR H5E_EVENTSET +#define H5_MY_PKG_INIT YES + +/** + * \defgroup H5ES H5ES + * \brief Event Set Interface + * + * \details \Bold{This interface can be only used with the HDF5 VOL connectors that + * enable the asynchronous feature in HDF5.} The native HDF5 library has + * only synchronous operations. + * + * HDF5 VOL connectors with support for asynchronous operations: + * - ASYNC + * - DAOS + * + * \par Example: + * \code + * fid = H5Fopen(..); + * gid = H5Gopen(fid, ..); //Starts when H5Fopen completes + * did = H5Dopen(gid, ..); //Starts when H5Gopen completes + * + * es_id = H5EScreate(); // Create event set for tracking async operations + * status = H5Dwrite_async(did, .., es_id); //Asynchronous, starts when H5Dopen completes, + * // may run concurrently with other H5Dwrite_async + * // in event set. + * status = H5Dwrite_async(did, .., es_id); //Asynchronous, starts when H5Dopen completes, + * // may run concurrently with other H5Dwrite_async + * // in event set.... + * <other user code> + * ... + * H5ESwait(es_id); // Wait for operations in event set to complete, buffers + * // used for H5Dwrite_async must only be changed after wait + * // returns. + * \endcode + */ + +#endif /* H5ESmodule_H */ diff --git a/src/H5ESpkg.h b/src/H5ESpkg.h new file mode 100644 index 0000000..339ce1d --- /dev/null +++ b/src/H5ESpkg.h @@ -0,0 +1,101 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * 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. * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +/* + * Programmer: Quincey Koziol + * Wednesday, April 8, 2020 + * + * Purpose: This file contains declarations which are visible only within + * the H5ES package. Source files outside the H5ES package should + * include H5ESprivate.h instead. + */ +#if !(defined H5ES_FRIEND || defined H5ES_MODULE) +#error "Do not include this file outside the H5ES package!" +#endif + +#ifndef H5ESpkg_H +#define H5ESpkg_H + +/* Get package's private header */ +#include "H5ESprivate.h" + +/* Other private headers needed by this file */ + +/**************************/ +/* Package Private Macros */ +/**************************/ + +/****************************/ +/* Package Private Typedefs */ +/****************************/ + +/* Typedef for event nodes */ +typedef struct H5ES_event_t { + H5VL_object_t * request; /* Request token for event */ + struct H5ES_event_t *prev, *next; /* Previous and next event nodes */ + + /* Useful info for debugging and error reporting */ + const char *api_name; /* Name of API routine for event */ + const char *api_args; /* Arguments to API routine */ + const char *app_file; /* Name of source file from application */ + const char *app_func; /* Name of source function from application */ + unsigned app_line; /* Line # of source file from application */ + uint64_t ev_count; /* This event is the n'th operation in the event set */ + uint64_t ev_time; /* Timestamp for this event (in ms from UNIX epoch) */ +} H5ES_event_t; + +/* Typedef for lists of event set operations */ +typedef struct H5ES_event_list_t { + size_t count; /* # of events in list */ + H5ES_event_t *head, *tail; /* Head & tail of events in list */ +} H5ES_event_list_t; + +/* Typedef for event set objects */ +struct H5ES_t { + uint64_t op_counter; /* Count of operations inserted into this set */ + + /* Active events */ + H5ES_event_list_t active; /* List of active events in set */ + + /* Failed events */ + hbool_t err_occurred; /* Flag for error from an operation */ + H5ES_event_list_t failed; /* List of failed events in set */ +}; + +/* Event list iterator callback function */ +typedef int (*H5ES_list_iter_func_t)(H5ES_event_t *ev, void *ctx); + +/*****************************/ +/* Package Private Variables */ +/*****************************/ + +/******************************/ +/* Package Private Prototypes */ +/******************************/ +H5_DLL H5ES_t *H5ES__create(void); +H5_DLL herr_t H5ES__wait(H5ES_t *es, uint64_t timeout, size_t *num_in_progress, hbool_t *op_failed); +H5_DLL herr_t H5ES__get_err_info(H5ES_t *es, size_t num_err_info, H5ES_err_info_t err_info[], + size_t *num_cleared); +H5_DLL herr_t H5ES__close(H5ES_t *es); + +/* Event list operations */ +H5_DLL void H5ES__list_append(H5ES_event_list_t *el, H5ES_event_t *ev); +H5_DLL size_t H5ES__list_count(const H5ES_event_list_t *el); +H5_DLL int H5ES__list_iterate(H5ES_event_list_t *el, H5ES_list_iter_func_t cb, void *ctx); +H5_DLL void H5ES__list_remove(H5ES_event_list_t *el, const H5ES_event_t *ev); + +/* Event operations */ +H5_DLL H5ES_event_t *H5ES__event_new(H5VL_t *connector, void *token); +H5_DLL herr_t H5ES__event_free(H5ES_event_t *ev); +H5_DLL herr_t H5ES__event_completed(H5ES_event_t *ev, H5ES_event_list_t *el); + +#endif /* H5ESpkg_H */ diff --git a/src/H5ESprivate.h b/src/H5ESprivate.h new file mode 100644 index 0000000..4f843ba --- /dev/null +++ b/src/H5ESprivate.h @@ -0,0 +1,54 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * 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. * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +/*------------------------------------------------------------------------- + * + * Created: H5ESprivate.h + * Apr 6 2020 + * Quincey Koziol + * + * Purpose: Private header for library accessible event set routines. + * + *------------------------------------------------------------------------- + */ + +#ifndef H5ESprivate_H +#define H5ESprivate_H + +/* Include package's public header */ +#include "H5ESpublic.h" /* Event Sets */ + +/* Private headers needed by this file */ +#include "H5VLprivate.h" /* Virtual Object Layer */ + +/**************************/ +/* Library Private Macros */ +/**************************/ + +/****************************/ +/* Library Private Typedefs */ +/****************************/ + +/* Typedef for event set objects */ +typedef struct H5ES_t H5ES_t; + +/*****************************/ +/* Library-private Variables */ +/*****************************/ + +/***************************************/ +/* Library-private Function Prototypes */ +/***************************************/ +herr_t H5ES_insert(hid_t es_id, H5VL_t *connector, void *token, const char *caller, const char *caller_args, + ...); + +#endif /* H5ESprivate_H */ diff --git a/src/H5ESpublic.h b/src/H5ESpublic.h index 9cc800a..409282c 100644 --- a/src/H5ESpublic.h +++ b/src/H5ESpublic.h @@ -25,7 +25,7 @@ /*****************/ /* Default value for "no event set" / synchronous execution */ -#define H5ES_NONE (hid_t)0 +#define H5ES_NONE 0 /* (hid_t) */ /* Special "wait" timeout values */ #define H5ES_WAIT_FOREVER (UINT64_MAX) /* Wait until all operations complete */ @@ -123,6 +123,159 @@ How to Trace Async Operations? extern "C" { #endif +/** + * \ingroup H5ES + * + * \brief Creates an event set + * + * \returns \hid_ti{event set} + * + * \details H5EScreate() creates a new event set and returns a corresponding + * event set identifier. + * + * \since 1.13.0 + * + */ +H5_DLL hid_t H5EScreate(void); + +/** + * \ingroup H5ES + * + * \brief Waits for operations in event set to complete + * + * \es_id + * \param[in] timeout Total time in nanoseconds to wait for all operations in + * the event set to complete + * \param[out] num_in_progress The number of operations still in progress + * \param[out] err_occurred Flag if an operation in the event set failed + * \returns \herr_t + * + * \details H5ESwait() waits for operations in an event set \p es_id to wait + * with \p timeout. + * + * Timeout value is in nanoseconds, and is for the H5ESwait() call and + * not for each individual operation in the event set. For example, if + * "10" is passed as a timeout value and the event set waited 4 + * nanoseconds for the first operation to complete, the remaining + * operations would be allowed to wait for at most 6 nanoseconds more, + * i.e., the timeout value used across all operations in the event set + * until it reaches 0, then any remaining operations are only checked + * for completion, not waited on. + * + * This call will stop waiting on operations and will return + * immediately if an operation fails. If a failure occurs, the value + * returned for the number of operations in progress may be inaccurate. + * + * \since 1.13.0 + * + */ +H5_DLL herr_t H5ESwait(hid_t es_id, uint64_t timeout, size_t *num_in_progress, hbool_t *err_occurred); + +/** + * \ingroup H5ES + * + * \brief Retrieves number of events in an event set + * + * \es_id + * \param[out] count The number of events in the event set + * \returns \herr_t + * + * \details H5ESget_count() retrieves number of events in an event set specified + * by \p es_id. + * + * \since 1.13.0 + * + */ +H5_DLL herr_t H5ESget_count(hid_t es_id, size_t *count); + +/** + * \ingroup H5ES + * + * \todo Fill in the blanks! + * + * \since 1.13.0 + * + */ +H5_DLL herr_t H5ESget_op_counter(hid_t es_id, uint64_t *counter); + +/** + * \ingroup H5ES + * + * \brief Checks for failed operations + * + * \es_id + * \param[out] err_occurred Status indicating if error is present in the event + * set + * \returns \herr_t + * + * \details H5ESget_err_status() checks if event set specified by es_id has + * failed operations. + * + * \since 1.13.0 + * + */ +H5_DLL herr_t H5ESget_err_status(hid_t es_id, hbool_t *err_occurred); + +/** + * \ingroup H5ES + * + * \brief Retrieves the number of failed operations + * + * \es_id + * \param[out] num_errs Number of errors + * \returns \herr_t + * + * \details H5ESget_err_count() retrieves the number of failed operations in an + * event set specified by \p es_id. + * + * The function does not wait for active operations to complete, so + * count may not include all failures. + * + * \since 1.13.0 + * + */ +H5_DLL herr_t H5ESget_err_count(hid_t es_id, size_t *num_errs); + +/** + * \ingroup H5ES + * + * \brief Retrieves information about failed operations + * + * \es_id + * \param[in] num_err_info The number of elements in \p err_info array + * \param[out] err_info Array of structures + * \param[out] err_cleared Number of cleared errors + * \returns \herr_t + * + * \details H5ESget_err_info() retrieves information about failed operations in + * an event set specified by \p es_id. The strings retrieved for each + * error info must be released by calling H5free_memory(). + * + * Below is the description of the \ref H5ES_err_info_t structure: + * \snippet this H5ES_err_info_t_snip + * \click4more + * + * \since 1.13.0 + * + */ +H5_DLL herr_t H5ESget_err_info(hid_t es_id, size_t num_err_info, H5ES_err_info_t err_info[], + size_t *err_cleared); + +/** + * \ingroup H5ES + * + * \brief Terminates access to an event set + * + * \es_id + * \returns \herr_t + * + * \details H5ESclose() terminates access to an event set specified by \p es_id. + * + * \since 1.13.0 + * + */ +H5_DLL herr_t H5ESclose(hid_t es_id); + #ifdef __cplusplus } #endif diff --git a/src/H5Epublic.h b/src/H5Epublic.h index ace7700..0294023 100644 --- a/src/H5Epublic.h +++ b/src/H5Epublic.h @@ -24,7 +24,7 @@ #include "H5Ipublic.h" /* Value for the default error stack */ -#define H5E_DEFAULT (hid_t)0 +#define H5E_DEFAULT 0 /* (hid_t) */ /** * Different kinds of error information @@ -21,20 +21,14 @@ /* Headers */ /***********/ #include "H5private.h" /* Generic Functions */ -#include "H5Aprivate.h" /* Attributes */ #include "H5ACprivate.h" /* Metadata cache */ #include "H5CXprivate.h" /* API Contexts */ -#include "H5Dprivate.h" /* Datasets */ #include "H5Eprivate.h" /* Error handling */ +#include "H5ESprivate.h" /* Event Sets */ #include "H5Fpkg.h" /* File access */ -#include "H5FDprivate.h" /* File drivers */ #include "H5FLprivate.h" /* Free lists */ -#include "H5Gprivate.h" /* Groups */ #include "H5Iprivate.h" /* IDs */ -#include "H5MFprivate.h" /* File memory management */ -#include "H5MMprivate.h" /* Memory management */ #include "H5Pprivate.h" /* Property lists */ -#include "H5Tprivate.h" /* Datatypes */ #include "H5VLprivate.h" /* Virtual Object Layer */ #include "H5VLnative_private.h" /* Native VOL connector */ @@ -74,6 +68,15 @@ static int H5F__get_all_count_cb(void H5_ATTR_UNUSED *obj_ptr, hid_t H5_ATTR_UNU /* Callback for getting IDs for open objects in a file */ static int H5F__get_all_ids_cb(void H5_ATTR_UNUSED *obj_ptr, hid_t obj_id, void *key); +/* Helper routines for sync/async API calls */ +static herr_t H5F__post_open_api_common(H5VL_object_t *vol_obj, void **token_ptr); +static hid_t H5F__create_api_common(const char *filename, unsigned flags, hid_t fcpl_id, hid_t fapl_id, + void **token_ptr); +static hid_t H5F__open_api_common(const char *filename, unsigned flags, hid_t fapl_id, void **token_ptr); +static hid_t H5F__reopen_api_common(hid_t file_id, void **token_ptr); +static herr_t H5F__flush_api_common(hid_t object_id, H5F_scope_t scope, void **token_ptr, + H5VL_object_t **_vol_obj_ptr); + /*********************/ /* Package Variables */ /*********************/ @@ -454,40 +457,53 @@ done: } /* end H5Fis_accessible() */ /*------------------------------------------------------------------------- - * Function: H5Fcreate + * Function: H5F__post_open_api_common * - * Purpose: This is the primary function for creating HDF5 files . The - * flags parameter determines whether an existing file will be - * overwritten or not. All newly created files are opened for - * both reading and writing. All flags may be combined with the - * bit-wise OR operator (`|') to change the behavior of the file - * create call. + * Purpose: This is the common function for 'post open' operations * - * The more complex behaviors of a file's creation and access - * are controlled through the file-creation and file-access - * property lists. The value of H5P_DEFAULT for a template - * value indicates that the library should use the default - * values for the appropriate template. + * Return: SUCCEED/FAIL * - * See also: H5Fpublic.h for the list of supported flags. H5Ppublic.h for - * the list of file creation and file access properties. + *------------------------------------------------------------------------- + */ +static herr_t +H5F__post_open_api_common(H5VL_object_t *vol_obj, void **token_ptr) +{ + uint64_t supported; /* Whether 'post open' operation is supported by VOL connector */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_STATIC + + /* Check for 'post open' callback */ + supported = 0; + if (H5VL_introspect_opt_query(vol_obj, H5VL_SUBCLS_FILE, H5VL_NATIVE_FILE_POST_OPEN, &supported) < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "can't check for 'post open' operation") + if (supported & H5VL_OPT_QUERY_SUPPORTED) + /* Make the 'post open' callback */ + if (H5VL_file_optional(vol_obj, H5VL_NATIVE_FILE_POST_OPEN, H5P_DATASET_XFER_DEFAULT, token_ptr) < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, FAIL, "unable to make file 'post open' callback") + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5F__post_open_api_common() */ + +/*------------------------------------------------------------------------- + * Function: H5F__create_api_common + * + * Purpose: This is the common function for creating new HDF5 files. * * Return: Success: A file ID * Failure: H5I_INVALID_HID *------------------------------------------------------------------------- */ -hid_t -H5Fcreate(const char *filename, unsigned flags, hid_t fcpl_id, hid_t fapl_id) +static hid_t +H5F__create_api_common(const char *filename, unsigned flags, hid_t fcpl_id, hid_t fapl_id, void **token_ptr) { - H5F_t * new_file = NULL; /* File struct for new file */ - H5P_genplist_t * plist; /* Property list pointer */ - H5VL_connector_prop_t connector_prop; /* Property for VOL connector ID & info */ - H5VL_object_t * vol_obj = NULL; /* VOL object for file */ - hbool_t supported; /* Whether 'post open' operation is supported by VOL connector */ - hid_t ret_value; /* return value */ + void * new_file = NULL; /* File struct for new file */ + H5P_genplist_t * plist; /* Property list pointer */ + H5VL_connector_prop_t connector_prop; /* Property for VOL connector ID & info */ + hid_t ret_value = H5I_INVALID_HID; /* Return value */ - FUNC_ENTER_API(H5I_INVALID_HID) - H5TRACE4("i", "*sIuii", filename, flags, fcpl_id, fapl_id); + FUNC_ENTER_STATIC /* Check/fix arguments */ if (!filename || !*filename) @@ -534,41 +550,72 @@ H5Fcreate(const char *filename, unsigned flags, hid_t fcpl_id, hid_t fapl_id) flags |= H5F_ACC_RDWR | H5F_ACC_CREAT; /* Create a new file or truncate an existing file through the VOL */ - if (NULL == (new_file = (H5F_t *)H5VL_file_create(&connector_prop, filename, flags, fcpl_id, fapl_id, - H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL))) + if (NULL == (new_file = H5VL_file_create(&connector_prop, filename, flags, fcpl_id, fapl_id, + H5P_DATASET_XFER_DEFAULT, token_ptr))) HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, H5I_INVALID_HID, "unable to create file") - /* Get an atom for the file */ + /* Get an ID for the file */ if ((ret_value = H5VL_register_using_vol_id(H5I_FILE, new_file, connector_prop.connector_id, TRUE)) < 0) - HGOTO_ERROR(H5E_FILE, H5E_CANTREGISTER, H5I_INVALID_HID, "unable to atomize file handle") + HGOTO_ERROR(H5E_FILE, H5E_CANTREGISTER, H5I_INVALID_HID, "unable to register file handle") + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5F__create_api_common() */ + +/*------------------------------------------------------------------------- + * Function: H5Fcreate + * + * Purpose: This is the primary function for creating HDF5 files . The + * flags parameter determines whether an existing file will be + * overwritten or not. All newly created files are opened for + * both reading and writing. All flags may be combined with the + * bit-wise OR operator (`|') to change the behavior of the file + * create call. + * + * The more complex behaviors of a file's creation and access + * are controlled through the file-creation and file-access + * property lists. The value of H5P_DEFAULT for a template + * value indicates that the library should use the default + * values for the appropriate template. + * + * See also: H5Fpublic.h for the list of supported flags. H5Ppublic.h for + * the list of file creation and file access properties. + * + * Return: Success: A file ID + * + * Failure: H5I_INVALID_HID + * + *------------------------------------------------------------------------- + */ +hid_t +H5Fcreate(const char *filename, unsigned flags, hid_t fcpl_id, hid_t fapl_id) +{ + H5VL_object_t *vol_obj = NULL; /* File object */ + hid_t ret_value = H5I_INVALID_HID; /* Return value */ + + FUNC_ENTER_API(H5I_INVALID_HID) + H5TRACE4("i", "*sIuii", filename, flags, fcpl_id, fapl_id); + + /* Create the file synchronously */ + if ((ret_value = H5F__create_api_common(filename, flags, fcpl_id, fapl_id, NULL)) < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTCREATE, H5I_INVALID_HID, "unable to synchronously create file") /* Get the file object */ if (NULL == (vol_obj = H5VL_vol_object(ret_value))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5I_INVALID_HID, "invalid object identifier") + HGOTO_ERROR(H5E_FILE, H5E_BADTYPE, H5I_INVALID_HID, "invalid object identifier") - /* Make the 'post open' callback */ - supported = FALSE; - if (H5VL_introspect_opt_query(vol_obj, H5VL_SUBCLS_FILE, H5VL_NATIVE_FILE_POST_OPEN, &supported) < 0) - HGOTO_ERROR(H5E_FILE, H5E_CANTGET, H5I_INVALID_HID, "can't check for 'post open' operation") - if (supported) - if (H5VL_file_optional(vol_obj, H5VL_NATIVE_FILE_POST_OPEN, H5P_DATASET_XFER_DEFAULT, - H5_REQUEST_NULL) < 0) - HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, H5I_INVALID_HID, "unable to make file 'post open' callback") + /* Perform 'post open' operation */ + if (H5F__post_open_api_common(vol_obj, NULL) < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, H5I_INVALID_HID, "'post open' operation failed") done: FUNC_LEAVE_API(ret_value) } /* end H5Fcreate() */ /*------------------------------------------------------------------------- - * Function: H5Fopen + * Function: H5Fcreate_async * - * Purpose: This is the primary function for accessing existing HDF5 - * files. The FLAGS argument determines whether writing to an - * existing file will be allowed or not. All flags may be - * combined with the bit-wise OR operator (`|') to change the - * behavior of the file open call. The more complex behaviors - * of a file's access are controlled through the file-access - * property list. + * Purpose: Asynchronous version of H5Fcreate * * See Also: H5Fpublic.h for a list of possible values for FLAGS. * @@ -577,17 +624,80 @@ done: *------------------------------------------------------------------------- */ hid_t -H5Fopen(const char *filename, unsigned flags, hid_t fapl_id) +H5Fcreate_async(const char *app_file, const char *app_func, unsigned app_line, const char *filename, + unsigned flags, hid_t fcpl_id, hid_t fapl_id, hid_t es_id) { - H5F_t * new_file = NULL; /* File struct for new file */ - H5P_genplist_t * plist; /* Property list pointer */ - H5VL_connector_prop_t connector_prop; /* Property for VOL connector ID & info */ - H5VL_object_t * vol_obj = NULL; /* VOL object for file */ - hbool_t supported; /* Whether 'post open' operation is supported by VOL connector */ - hid_t ret_value; /* Return value */ + H5VL_object_t *vol_obj = NULL; /* File object */ + void * token = NULL; /* Request token for async operation */ + void ** token_ptr = H5_REQUEST_NULL; /* Pointer to request token for async operation */ + hid_t ret_value = H5I_INVALID_HID; /* Return value */ FUNC_ENTER_API(H5I_INVALID_HID) - H5TRACE3("i", "*sIui", filename, flags, fapl_id); + H5TRACE8("i", "*s*sIu*sIuiii", app_file, app_func, app_line, filename, flags, fcpl_id, fapl_id, es_id); + + /* Set up request token pointer for asynchronous operation */ + if (H5ES_NONE != es_id) + token_ptr = &token; /* Point at token for VOL connector to set up */ + + /* Create the file, possibly asynchronously */ + if ((ret_value = H5F__create_api_common(filename, flags, fcpl_id, fapl_id, token_ptr)) < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTCREATE, H5I_INVALID_HID, "unable to asynchronously create file") + + /* Get the file object */ + if (NULL == (vol_obj = H5VL_vol_object(ret_value))) + HGOTO_ERROR(H5E_FILE, H5E_BADTYPE, H5I_INVALID_HID, "invalid object identifier") + + /* If a token was created, add the token to the event set */ + if (NULL != token) + /* clang-format off */ + if (H5ES_insert(es_id, vol_obj->connector, token, + H5ARG_TRACE8(FUNC, "*s*sIu*sIuiii", app_file, app_func, app_line, filename, flags, fcpl_id, fapl_id, es_id)) < 0) { + /* clang-format on */ + if (H5I_dec_app_ref(ret_value) < 0) + HDONE_ERROR(H5E_FILE, H5E_CANTDEC, H5I_INVALID_HID, "can't decrement count on file ID") + HGOTO_ERROR(H5E_FILE, H5E_CANTINSERT, H5I_INVALID_HID, "can't insert token into event set") + } /* end if */ + + /* Reset token for 'post open' operation */ + /* (Unnecessary if create operation didn't change it, but not worth checking -QAK) */ + token = NULL; + + /* Perform 'post open' operation */ + if (H5F__post_open_api_common(vol_obj, token_ptr) < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, H5I_INVALID_HID, "'post open' operation failed") + + /* If a token was created, add the token to the event set */ + if (NULL != token) + /* clang-format off */ + if (H5ES_insert(es_id, vol_obj->connector, token, + H5ARG_TRACE8(FUNC, "*s*sIu*sIuiii", app_file, app_func, app_line, filename, flags, fcpl_id, fapl_id, es_id)) < 0) + /* clang-format on */ + HGOTO_ERROR(H5E_FILE, H5E_CANTINSERT, H5I_INVALID_HID, "can't insert token into event set") + +done: + FUNC_LEAVE_API(ret_value) +} /* end H5Fcreate_async() */ + +/*------------------------------------------------------------------------- + * Function: H5F__open_api_common + * + * Purpose: This is the common function for accessing existing HDF5 + * files. + * + * Return: Success: A file ID + * Failure: H5I_INVALID_HID + * + *------------------------------------------------------------------------- + */ +static hid_t +H5F__open_api_common(const char *filename, unsigned flags, hid_t fapl_id, void **token_ptr) +{ + void * new_file = NULL; /* File struct for new file */ + H5P_genplist_t * plist; /* Property list pointer */ + H5VL_connector_prop_t connector_prop; /* Property for VOL connector ID & info */ + hid_t ret_value = H5I_INVALID_HID; /* Return value */ + + FUNC_ENTER_STATIC /* Check arguments */ if (!filename || !*filename) @@ -622,51 +732,148 @@ H5Fopen(const char *filename, unsigned flags, hid_t fapl_id) HGOTO_ERROR(H5E_FILE, H5E_CANTSET, H5I_INVALID_HID, "can't set VOL connector info in API context") /* Open the file through the VOL layer */ - if (NULL == (new_file = (H5F_t *)H5VL_file_open(&connector_prop, filename, flags, fapl_id, - H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL))) + if (NULL == (new_file = H5VL_file_open(&connector_prop, filename, flags, fapl_id, + H5P_DATASET_XFER_DEFAULT, token_ptr))) HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, H5I_INVALID_HID, "unable to open file") /* Get an ID for the file */ if ((ret_value = H5VL_register_using_vol_id(H5I_FILE, new_file, connector_prop.connector_id, TRUE)) < 0) - HGOTO_ERROR(H5E_FILE, H5E_CANTREGISTER, H5I_INVALID_HID, "unable to atomize file handle") + HGOTO_ERROR(H5E_FILE, H5E_CANTREGISTER, H5I_INVALID_HID, "unable to register file handle") + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5F__open_api_common() */ + +/*------------------------------------------------------------------------- + * Function: H5Fopen + * + * Purpose: This is the primary function for accessing existing HDF5 + * files. The FLAGS argument determines whether writing to an + * existing file will be allowed or not. All flags may be + * combined with the bit-wise OR operator (`|') to change the + * behavior of the file open call. The more complex behaviors + * of a file's access are controlled through the file-access + * property list. + * + * See Also: H5Fpublic.h for a list of possible values for FLAGS. + * + * Return: Success: A file ID + * + * Failure: H5I_INVALID_HID + * + *------------------------------------------------------------------------- + */ +hid_t +H5Fopen(const char *filename, unsigned flags, hid_t fapl_id) +{ + H5VL_object_t *vol_obj = NULL; /* File object */ + hid_t ret_value = H5I_INVALID_HID; /* Return value */ + + FUNC_ENTER_API(H5I_INVALID_HID) + H5TRACE3("i", "*sIui", filename, flags, fapl_id); + + /* Open the file synchronously */ + if ((ret_value = H5F__open_api_common(filename, flags, fapl_id, NULL)) < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, H5I_INVALID_HID, "unable to synchronously open file") /* Get the file object */ if (NULL == (vol_obj = H5VL_vol_object(ret_value))) - HGOTO_ERROR(H5E_FILE, H5E_CANTGET, H5I_INVALID_HID, "invalid object identifier") + HGOTO_ERROR(H5E_FILE, H5E_BADTYPE, H5I_INVALID_HID, "invalid object identifier") - /* Make the 'post open' callback */ - supported = FALSE; - if (H5VL_introspect_opt_query(vol_obj, H5VL_SUBCLS_FILE, H5VL_NATIVE_FILE_POST_OPEN, &supported) < 0) - HGOTO_ERROR(H5E_FILE, H5E_CANTGET, H5I_INVALID_HID, "can't check for 'post open' operation") - if (supported) - if (H5VL_file_optional(vol_obj, H5VL_NATIVE_FILE_POST_OPEN, H5P_DATASET_XFER_DEFAULT, - H5_REQUEST_NULL) < 0) - HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, H5I_INVALID_HID, "unable to make file 'post open' callback") + /* Perform 'post open' operation */ + if (H5F__post_open_api_common(vol_obj, NULL) < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, H5I_INVALID_HID, "'post open' operation failed") done: FUNC_LEAVE_API(ret_value) } /* end H5Fopen() */ /*------------------------------------------------------------------------- - * Function: H5Fflush + * Function: H5Fopen_async * - * Purpose: Flushes all outstanding buffers of a file to disk but does - * not remove them from the cache. The OBJECT_ID can be a file, - * dataset, group, attribute, or named data type. + * Purpose: Asynchronous version of H5Fopen + * + * See Also: H5Fpublic.h for a list of possible values for FLAGS. + * + * Return: Success: A file ID + * Failure: H5I_INVALID_HID * - * Return: Success: Non-negative - * Failure: Negative *------------------------------------------------------------------------- */ -herr_t -H5Fflush(hid_t object_id, H5F_scope_t scope) +hid_t +H5Fopen_async(const char *app_file, const char *app_func, unsigned app_line, const char *filename, + unsigned flags, hid_t fapl_id, hid_t es_id) { - H5VL_object_t *vol_obj = NULL; /* Object info */ - H5I_type_t obj_type; /* Type of object */ - herr_t ret_value = SUCCEED; /* Return value */ + H5VL_object_t *vol_obj = NULL; /* File object */ + void * token = NULL; /* Request token for async operation */ + void ** token_ptr = H5_REQUEST_NULL; /* Pointer to request token for async operation */ + hid_t ret_value = H5I_INVALID_HID; /* Return value */ - FUNC_ENTER_API(FAIL) - H5TRACE2("e", "iFs", object_id, scope); + FUNC_ENTER_API(H5I_INVALID_HID) + H5TRACE7("i", "*s*sIu*sIuii", app_file, app_func, app_line, filename, flags, fapl_id, es_id); + + /* Set up request token pointer for asynchronous operation */ + if (H5ES_NONE != es_id) + token_ptr = &token; /* Point at token for VOL connector to set up */ + + /* Open the file, possibly asynchronously */ + if ((ret_value = H5F__open_api_common(filename, flags, fapl_id, token_ptr)) < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, H5I_INVALID_HID, "unable to asynchronously open file") + + /* Get the file object */ + if (NULL == (vol_obj = H5VL_vol_object(ret_value))) + HGOTO_ERROR(H5E_FILE, H5E_BADTYPE, H5I_INVALID_HID, "invalid object identifier") + + /* If a token was created, add the token to the event set */ + if (NULL != token) + /* clang-format off */ + if (H5ES_insert(es_id, vol_obj->connector, token, + H5ARG_TRACE7(FUNC, "*s*sIu*sIuii", app_file, app_func, app_line, filename, flags, fapl_id, es_id)) < 0) { + /* clang-format on */ + if (H5I_dec_app_ref(ret_value) < 0) + HDONE_ERROR(H5E_FILE, H5E_CANTDEC, H5I_INVALID_HID, "can't decrement count on file ID") + HGOTO_ERROR(H5E_FILE, H5E_CANTINSERT, H5I_INVALID_HID, "can't insert token into event set") + } /* end if */ + + /* Reset token for 'post open' operation */ + /* (Unnecessary if create operation didn't change it, but not worth checking -QAK) */ + token = NULL; + + /* Perform 'post open' operation */ + if (H5F__post_open_api_common(vol_obj, token_ptr) < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, H5I_INVALID_HID, "'post open' operation failed") + + /* If a token was created, add the token to the event set */ + if (NULL != token) + /* clang-format off */ + if (H5ES_insert(es_id, vol_obj->connector, token, + H5ARG_TRACE7(FUNC, "*s*sIu*sIuii", app_file, app_func, app_line, filename, flags, fapl_id, es_id)) < 0) + /* clang-format on */ + HGOTO_ERROR(H5E_FILE, H5E_CANTINSERT, H5I_INVALID_HID, "can't insert token into event set") + +done: + FUNC_LEAVE_API(ret_value) +} /* end H5Fopen_async() */ + +/*------------------------------------------------------------------------- + * Function: H5F__flush_api_common + * + * Purpose: This is the common function for flushing an HDF5 file. + * + * Return: SUCCEED/FAIL + * + *------------------------------------------------------------------------- + */ +static herr_t +H5F__flush_api_common(hid_t object_id, H5F_scope_t scope, void **token_ptr, H5VL_object_t **_vol_obj_ptr) +{ + H5VL_object_t * tmp_vol_obj = NULL; /* Object for loc_id */ + H5VL_object_t **vol_obj_ptr = + (_vol_obj_ptr ? _vol_obj_ptr : &tmp_vol_obj); /* Ptr to object ptr for loc_id */ + H5I_type_t obj_type; /* Type of object to use */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_STATIC /* Get the type of object we're flushing + sanity check */ obj_type = H5I_get_type(object_id); @@ -674,20 +881,89 @@ H5Fflush(hid_t object_id, H5F_scope_t scope) H5I_DATASET != obj_type && H5I_ATTR != obj_type) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file or file object") - /* get the file object */ - if (NULL == (vol_obj = H5VL_vol_object(object_id))) + /* Get the file object */ + if (NULL == (*vol_obj_ptr = H5VL_vol_object(object_id))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid object identifier") /* Flush the object */ - if (H5VL_file_specific(vol_obj, H5VL_FILE_FLUSH, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL, (int)obj_type, + if (H5VL_file_specific(*vol_obj_ptr, H5VL_FILE_FLUSH, H5P_DATASET_XFER_DEFAULT, token_ptr, (int)obj_type, (int)scope) < 0) HGOTO_ERROR(H5E_FILE, H5E_CANTFLUSH, FAIL, "unable to flush file") done: + FUNC_LEAVE_NOAPI(ret_value) +} /* H5F__flush_api_common() */ + +/*------------------------------------------------------------------------- + * Function: H5Fflush + * + * Purpose: Flushes all outstanding buffers of a file to disk but does + * not remove them from the cache. The OBJECT_ID can be a file, + * dataset, group, attribute, or named data type. + * + * Return: Success: Non-negative + * Failure: Negative + *------------------------------------------------------------------------- + */ +herr_t +H5Fflush(hid_t object_id, H5F_scope_t scope) +{ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_API(FAIL) + H5TRACE2("e", "iFs", object_id, scope); + + /* Flush the file synchronously */ + if (H5F__flush_api_common(object_id, scope, NULL, NULL) < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTFLUSH, FAIL, "unable to synchronously flush file") + +done: FUNC_LEAVE_API(ret_value) } /* end H5Fflush() */ /*------------------------------------------------------------------------- + * Function: H5Fflush_async + * + * Purpose: Asynchronous version of H5Fflush + * + * Return: Success: Non-negative + * Failure: Negative + * + *------------------------------------------------------------------------- + */ +herr_t +H5Fflush_async(const char *app_file, const char *app_func, unsigned app_line, hid_t object_id, + H5F_scope_t scope, hid_t es_id) +{ + H5VL_object_t *vol_obj = NULL; /* Object for loc_id */ + void * token = NULL; /* Request token for async operation */ + void ** token_ptr = H5_REQUEST_NULL; /* Pointer to request token for async operation */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_API(FAIL) + H5TRACE6("e", "*s*sIuiFsi", app_file, app_func, app_line, object_id, scope, es_id); + + /* Set up request token pointer for asynchronous operation */ + if (H5ES_NONE != es_id) + token_ptr = &token; /* Point at token for VOL connector to set up */ + + /* Flush the file asynchronously */ + if (H5F__flush_api_common(object_id, scope, token_ptr, &vol_obj) < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTFLUSH, FAIL, "unable to asynchronously flush file") + + /* If a token was created, add the token to the event set */ + if (NULL != token) + /* clang-format off */ + if (H5ES_insert(es_id, vol_obj->connector, token, + H5ARG_TRACE6(FUNC, "*s*sIuiFsi", app_file, app_func, app_line, object_id, scope, es_id)) < 0) + /* clang-format on */ + HGOTO_ERROR(H5E_FILE, H5E_CANTINSERT, FAIL, "can't insert token into event set") + +done: + FUNC_LEAVE_API(ret_value) +} /* end H5Fflush_async() */ + +/*------------------------------------------------------------------------- * Function: H5Fclose * * Purpose: This function closes the file specified by FILE_ID by @@ -713,7 +989,9 @@ H5Fclose(hid_t file_id) if (H5I_FILE != H5I_get_type(file_id)) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file ID") - /* Close the file */ + /* Synchronously decrement reference count on ID. + * When it reaches zero the file will be closed. + */ if (H5I_dec_app_ref(file_id) < 0) HGOTO_ERROR(H5E_FILE, H5E_CANTCLOSEFILE, FAIL, "decrementing file ID failed") @@ -722,6 +1000,67 @@ done: } /* end H5Fclose() */ /*------------------------------------------------------------------------- + * Function: H5Fclose_async + * + * Purpose: Asynchronous version of H5Fclose + * + * Return: SUCCEED/FAIL + * + *------------------------------------------------------------------------- + */ +herr_t +H5Fclose_async(const char *app_file, const char *app_func, unsigned app_line, hid_t file_id, hid_t es_id) +{ + H5VL_object_t *vol_obj = NULL; /* Object for loc_id */ + H5VL_t * connector = NULL; /* VOL connector */ + void * token = NULL; /* Request token for async operation */ + void ** token_ptr = H5_REQUEST_NULL; /* Pointer to request token for async operation */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_API(FAIL) + H5TRACE5("e", "*s*sIuii", app_file, app_func, app_line, file_id, es_id); + + /* Check arguments */ + if (H5I_FILE != H5I_get_type(file_id)) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file ID") + + /* Prepare for possible asynchronous operation */ + if (H5ES_NONE != es_id) { + /* Get file object's connector */ + if (NULL == (vol_obj = H5VL_vol_object(file_id))) + HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "can't get VOL object for file") + + /* Increase connector's refcount, so it doesn't get closed if closing + * this file ID closes the file */ + connector = vol_obj->connector; + H5VL_conn_inc_rc(connector); + + /* Point at token for operation to set up */ + token_ptr = &token; + } /* end if */ + + /* Asynchronously decrement reference count on ID. + * When it reaches zero the file will be closed. + */ + if (H5I_dec_app_ref_async(file_id, token_ptr) < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTCLOSEFILE, FAIL, "decrementing file ID failed") + + /* If a token was created, add the token to the event set */ + if (NULL != token) + /* clang-format off */ + if (H5ES_insert(es_id, vol_obj->connector, token, + H5ARG_TRACE5(FUNC, "*s*sIuii", app_file, app_func, app_line, file_id, es_id)) < 0) + /* clang-format on */ + HGOTO_ERROR(H5E_FILE, H5E_CANTINSERT, FAIL, "can't insert token into event set") + +done: + if (connector && H5VL_conn_dec_rc(connector) < 0) + HDONE_ERROR(H5E_FILE, H5E_CANTDEC, FAIL, "can't decrement ref count on connector") + + FUNC_LEAVE_API(ret_value) +} /* end H5Fclose_async() */ + +/*------------------------------------------------------------------------- * Function: H5Fdelete * * Purpose: Deletes an HDF5 file. @@ -893,6 +1232,46 @@ done: } /* end H5Funmount() */ /*------------------------------------------------------------------------- + * Function: H5F__reopen_api_common + * + * Purpose: This is the common function for reopening an HDF5 file + * files. + * + * Return: Success: A file ID + * Failure: H5I_INVALID_HID + * + *------------------------------------------------------------------------- + */ +static hid_t +H5F__reopen_api_common(hid_t file_id, void **token_ptr) +{ + void * file = NULL; /* File struct for new file */ + H5VL_object_t *vol_obj = NULL; /* Object for loc_id */ + hid_t ret_value = H5I_INVALID_HID; /* Return value */ + + FUNC_ENTER_STATIC + + /* Get the file object */ + if (NULL == (vol_obj = (H5VL_object_t *)H5I_object_verify(file_id, H5I_FILE))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5I_INVALID_HID, "invalid file identifier") + + /* Reopen the file */ + if (H5VL_file_specific(vol_obj, H5VL_FILE_REOPEN, H5P_DATASET_XFER_DEFAULT, token_ptr, &file) < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, H5I_INVALID_HID, "unable to reopen file via the VOL connector") + + /* Make sure that worked */ + if (NULL == file) + HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, H5I_INVALID_HID, "unable to reopen file") + + /* Get an ID for the file */ + if ((ret_value = H5VL_register(H5I_FILE, file, vol_obj->connector, TRUE)) < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTREGISTER, H5I_INVALID_HID, "unable to register file handle") + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5F__reopen_api_common() */ + +/*------------------------------------------------------------------------- * Function: H5Freopen * * Purpose: Reopen a file. The new file handle which is returned points @@ -910,47 +1289,94 @@ done: hid_t H5Freopen(hid_t file_id) { - void * file = NULL; /* File struct for new file */ - H5VL_object_t *vol_obj = NULL; /* VOL object for file */ - hbool_t supported; /* Whether 'post open' operation is supported by VOL connector */ + H5VL_object_t *vol_obj = NULL; /* File object */ hid_t ret_value = H5I_INVALID_HID; /* Return value */ FUNC_ENTER_API(H5I_INVALID_HID) H5TRACE1("i", "i", file_id); + /* Reopen the file synchronously */ + if ((ret_value = H5F__reopen_api_common(file_id, NULL)) < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, H5I_INVALID_HID, "unable to synchronously reopen file") + /* Get the file object */ - if (NULL == (vol_obj = (H5VL_object_t *)H5I_object_verify(file_id, H5I_FILE))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5I_INVALID_HID, "invalid file identifier") + if (NULL == (vol_obj = H5VL_vol_object(ret_value))) + HGOTO_ERROR(H5E_FILE, H5E_CANTGET, H5I_INVALID_HID, "can't get handle for re-opened file") - /* Reopen the file */ - if (H5VL_file_specific(vol_obj, H5VL_FILE_REOPEN, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL, &file) < 0) - HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, H5I_INVALID_HID, "unable to reopen file via the VOL connector") + /* Perform 'post open' operation */ + if (H5F__post_open_api_common(vol_obj, NULL) < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, H5I_INVALID_HID, "'post open' operation failed") - /* Make sure that worked */ - if (NULL == file) - HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, H5I_INVALID_HID, "unable to reopen file") +done: + /* XXX (VOL MERGE): If registration fails, file will not be closed */ + FUNC_LEAVE_API(ret_value) +} /* end H5Freopen() */ - /* Get an atom for the file */ - if ((ret_value = H5VL_register(H5I_FILE, file, vol_obj->connector, TRUE)) < 0) - HGOTO_ERROR(H5E_FILE, H5E_CANTREGISTER, H5I_INVALID_HID, "unable to atomize file handle") +/*------------------------------------------------------------------------- + * Function: H5Freopen_async + * + * Purpose: Asynchronous version of H5Freopen + * + * See Also: H5Fpublic.h for a list of possible values for FLAGS. + * + * Return: Success: A file ID + * Failure: H5I_INVALID_HID + * + *------------------------------------------------------------------------- + */ +hid_t +H5Freopen_async(const char *app_file, const char *app_func, unsigned app_line, hid_t file_id, hid_t es_id) +{ + H5VL_object_t *vol_obj = NULL; /* Object for loc_id */ + void * token = NULL; /* Request token for async operation */ + void ** token_ptr = H5_REQUEST_NULL; /* Pointer to request token for async operation */ + hid_t ret_value; /* Return value */ + + FUNC_ENTER_API(H5I_INVALID_HID) + H5TRACE5("i", "*s*sIuii", app_file, app_func, app_line, file_id, es_id); + + /* Set up request token pointer for asynchronous operation */ + if (H5ES_NONE != es_id) + token_ptr = &token; /* Point at token for VOL connector to set up */ + + /* Reopen the file, possibly asynchronously */ + if ((ret_value = H5F__reopen_api_common(file_id, token_ptr)) < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, H5I_INVALID_HID, "unable to asynchronously reopen file") /* Get the file object */ if (NULL == (vol_obj = H5VL_vol_object(ret_value))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5I_INVALID_HID, "invalid object identifier") - - /* Make the 'post open' callback */ - supported = FALSE; - if (H5VL_introspect_opt_query(vol_obj, H5VL_SUBCLS_FILE, H5VL_NATIVE_FILE_POST_OPEN, &supported) < 0) - HGOTO_ERROR(H5E_FILE, H5E_CANTGET, H5I_INVALID_HID, "can't check for 'post open' operation") - if (supported) - if (H5VL_file_optional(vol_obj, H5VL_NATIVE_FILE_POST_OPEN, H5P_DATASET_XFER_DEFAULT, - H5_REQUEST_NULL) < 0) - HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, H5I_INVALID_HID, "unable to make file 'post open' callback") + HGOTO_ERROR(H5E_FILE, H5E_CANTGET, H5I_INVALID_HID, "can't get handle for re-opened file") + + /* If a token was created, add the token to the event set */ + if (NULL != token) + /* clang-format off */ + if (H5ES_insert(es_id, vol_obj->connector, token, + H5ARG_TRACE5(FUNC, "*s*sIuii", app_file, app_func, app_line, file_id, es_id)) < 0) { + /* clang-format on */ + if (H5I_dec_app_ref(ret_value) < 0) + HDONE_ERROR(H5E_FILE, H5E_CANTDEC, H5I_INVALID_HID, "can't decrement count on file ID") + HGOTO_ERROR(H5E_FILE, H5E_CANTINSERT, H5I_INVALID_HID, "can't insert token into event set") + } /* end if */ + + /* Reset token for 'post open' operation */ + /* (Unnecessary if create operation didn't change it, but not worth checking -QAK) */ + token = NULL; + + /* Perform 'post open' operation */ + if (H5F__post_open_api_common(vol_obj, token_ptr) < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, H5I_INVALID_HID, "'post open' operation failed") + + /* If a token was created, add the token to the event set */ + if (NULL != token) + /* clang-format off */ + if (H5ES_insert(es_id, vol_obj->connector, token, + H5ARG_TRACE5(FUNC, "*s*sIuii", app_file, app_func, app_line, file_id, es_id)) < 0) + /* clang-format on */ + HGOTO_ERROR(H5E_FILE, H5E_CANTINSERT, H5I_INVALID_HID, "can't insert token into event set") done: - /* XXX (VOL MERGE): If registration fails, file will not be closed */ FUNC_LEAVE_API(ret_value) -} /* end H5Freopen() */ +} /* end H5Freopen_async() */ /*------------------------------------------------------------------------- * Function: H5Fget_intent @@ -1998,6 +2424,43 @@ done: } /* H5Fset_dset_no_attrs_hint */ /*------------------------------------------------------------------------- + * Function: H5Fwait + * + * Purpose: Wait for all operations on a dataset. + * Tang: added for async + * + * Return: SUCCEED/FAIL + * + *------------------------------------------------------------------------- + */ +herr_t +H5Fwait(hid_t file_id) +{ + H5VL_object_t *vol_obj; /* File for this operation */ + H5I_type_t obj_type; /* Type of object */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_API(FAIL) + H5TRACE1("e", "i", file_id); + + /* Get the type of object we're flushing + sanity check */ + obj_type = H5I_get_type(file_id); + if (H5I_FILE != obj_type && H5I_GROUP != obj_type && H5I_DATATYPE != obj_type && + H5I_DATASET != obj_type && H5I_ATTR != obj_type) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file or file object") + + if (NULL == (vol_obj = (H5VL_object_t *)H5I_object_verify(file_id, H5I_FILE))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "file_id parameter is not a valid file identifier") + + if ((ret_value = H5VL_file_specific(vol_obj, H5VL_FILE_WAIT, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL, + file_id)) < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTOPERATE, FAIL, "unable to wait file") + +done: + FUNC_LEAVE_API(ret_value) +} /* H5Fwait() */ + +/*------------------------------------------------------------------------- * Function: H5Fvfd_swmr_end_tick() * * Purpose: To trigger end of tick processing diff --git a/src/H5Fint.c b/src/H5Fint.c index f5dc85d..e1b63b2 100644 --- a/src/H5Fint.c +++ b/src/H5Fint.c @@ -699,6 +699,7 @@ H5F__get_objects_cb(void *obj_ptr, hid_t obj_id, void *key) case H5I_ERROR_MSG: case H5I_ERROR_STACK: case H5I_SPACE_SEL_ITER: + case H5I_EVENTSET: case H5I_NTYPES: default: HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5_ITER_ERROR, "unknown or invalid data object") @@ -1353,6 +1354,8 @@ H5F__new(H5F_shared_t *shared, unsigned flags, hid_t fcpl_id, hid_t fapl_id, H5F done: if (!ret_value && f) { + HDassert(NULL == f->vol_obj); + if (!shared) { /* Attempt to clean up some of the shared file structures */ if (f->shared->efc) @@ -1365,11 +1368,6 @@ done: f->shared = H5FL_FREE(H5F_shared_t, f->shared); } - /* Free VOL object */ - if (f->vol_obj) - if (H5VL_free_object(f->vol_obj) < 0) - HDONE_ERROR(H5E_FILE, H5E_CANTDEC, NULL, "unable to free VOL object") - f = H5FL_FREE(H5F_t, f); } @@ -1674,9 +1672,21 @@ H5F__dest(H5F_t *f, hbool_t flush) /* Free the non-shared part of the file */ f->open_name = (char *)H5MM_xfree(f->open_name); f->actual_name = (char *)H5MM_xfree(f->actual_name); - if (f->vol_obj && H5VL_free_object(f->vol_obj) < 0) - HDONE_ERROR(H5E_FILE, H5E_CANTDEC, FAIL, "unable to free VOL object") - f->vol_obj = NULL; + if (f->vol_obj) { + void *vol_wrap_ctx = NULL; + + /* If a VOL wrapping context is available, retrieve it + * and unwrap file VOL object + */ + if (H5CX_get_vol_wrap_ctx((void **)&vol_wrap_ctx) < 0) + HDONE_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "can't get VOL object wrap context") + if (vol_wrap_ctx && (NULL == H5VL_object_unwrap(f->vol_obj))) + HDONE_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "can't unwrap VOL object") + + if (H5VL_free_object(f->vol_obj) < 0) + HDONE_ERROR(H5E_FILE, H5E_CANTDEC, FAIL, "unable to free VOL object") + f->vol_obj = NULL; + } if (H5FO_top_dest(f) < 0) HDONE_ERROR(H5E_FILE, H5E_CANTINIT, FAIL, "problems closing file") f->shared = NULL; @@ -1850,7 +1860,7 @@ H5F_open(const char *name, unsigned flags, hid_t fcpl_id, hid_t fapl_id) } /* - * If the driver has a `cmp' method then the driver is capable of + * If the driver has a 'cmp' method then the driver is capable of * determining when two file handles refer to the same file and the * library can insure that when the application opens a file twice * that the two handles coordinate their operations appropriately. @@ -1905,8 +1915,8 @@ H5F_open(const char *name, unsigned flags, hid_t fcpl_id, hid_t fapl_id) /* Is the file already open? */ if ((shared = H5F__sfile_search(lf)) != NULL) { /* - * The file is already open, so use the corresponding H5F_shared_t. - * We only allow one H5FD_t* per file so one doesn't + * The file is already open, so use that one instead of the one we + * just opened. We only one one H5FD_t* per file so one doesn't * confuse the other. But fail if this request was to truncate the * file (since we can't do that while the file is open), or if the * request was to create a non-existent file (since the file already diff --git a/src/H5Fpublic.h b/src/H5Fpublic.h index 1350382..48bfaaa 100644 --- a/src/H5Fpublic.h +++ b/src/H5Fpublic.h @@ -47,50 +47,47 @@ * We're assuming that these constants are used rather early in the hdf5 * session. */ -#define H5F_ACC_RDONLY (H5CHECK H5OPEN 0x0000u) /*absence of rdwr => rd-only */ -#define H5F_ACC_RDWR (H5CHECK H5OPEN 0x0001u) /*open for read and write */ -#define H5F_ACC_TRUNC (H5CHECK H5OPEN 0x0002u) /*overwrite existing files */ -#define H5F_ACC_EXCL (H5CHECK H5OPEN 0x0004u) /*fail if file already exists*/ +#define H5F_ACC_RDONLY (H5CHECK H5OPEN 0x0000u) /**< Absence of RDWR: read-only */ +#define H5F_ACC_RDWR (H5CHECK H5OPEN 0x0001u) /**< Open for read and write */ +#define H5F_ACC_TRUNC (H5CHECK H5OPEN 0x0002u) /**< Overwrite existing files */ +#define H5F_ACC_EXCL (H5CHECK H5OPEN 0x0004u) /**< Fail if file already exists*/ /* NOTE: 0x0008u was H5F_ACC_DEBUG, now deprecated */ -#define H5F_ACC_CREAT (H5CHECK H5OPEN 0x0010u) /*create non-existing files */ +#define H5F_ACC_CREAT (H5CHECK H5OPEN 0x0010u) /**< Create non-existing files */ #define H5F_ACC_SWMR_WRITE \ - (H5CHECK 0x0020u) /*indicate that this file is \ - * open for writing in a \ - * single-writer/multi-reader (SWMR) \ - * scenario. Note that the \ - * process(es) opening the file \ - * for reading must open the file \ - * with RDONLY access, and use \ - * the special "SWMR_READ" access \ - * flag. */ + (H5CHECK 0x0020u) /**< Indicate that this file is open for writing in a \ + * single-writer/multi-reader (SWMR) scenario. \ + * Note that the process(es) opening the file for reading \ + * must open the file with #H5F_ACC_RDONLY and use the \ + * #H5F_ACC_SWMR_READ access flag. */ #define H5F_ACC_SWMR_READ \ - (H5CHECK 0x0040u) /*indicate that this file is \ - * open for reading in a \ - * single-writer/multi-reader (SWMR) \ - * scenario. Note that the \ - * process(es) opening the file \ - * for SWMR reading must also \ - * open the file with the RDONLY \ - * flag. */ - -/* Value passed to H5Pset_elink_acc_flags to cause flags to be taken from the - * parent file. */ -#define H5F_ACC_DEFAULT (H5CHECK H5OPEN 0xffffu) /*ignore setting on lapl */ + (H5CHECK 0x0040u) /**< Indicate that this file is open for reading in a \ + * single-writer/multi-reader (SWMR) scenario. Note that \ + * the process(es) opening the file for SWMR reading must \ + * also open the file with the #H5F_ACC_RDONLY flag. */ + +/** + * Default property list identifier + * + * \internal Value passed to H5Pset_elink_acc_flags to cause flags to be taken from the parent file. + * \internal ignore setting on lapl + */ +#define H5F_ACC_DEFAULT (H5CHECK H5OPEN 0xffffu) /* Flags for H5Fget_obj_count() & H5Fget_obj_ids() calls */ -#define H5F_OBJ_FILE (0x0001u) /* File objects */ -#define H5F_OBJ_DATASET (0x0002u) /* Dataset objects */ -#define H5F_OBJ_GROUP (0x0004u) /* Group objects */ -#define H5F_OBJ_DATATYPE (0x0008u) /* Named datatype objects */ -#define H5F_OBJ_ATTR (0x0010u) /* Attribute objects */ +#define H5F_OBJ_FILE (0x0001u) /**< File objects */ +#define H5F_OBJ_DATASET (0x0002u) /**< Dataset objects */ +#define H5F_OBJ_GROUP (0x0004u) /**< Group objects */ +#define H5F_OBJ_DATATYPE (0x0008u) /**< Named datatype objects */ +#define H5F_OBJ_ATTR (0x0010u) /**< Attribute objects */ #define H5F_OBJ_ALL (H5F_OBJ_FILE | H5F_OBJ_DATASET | H5F_OBJ_GROUP | H5F_OBJ_DATATYPE | H5F_OBJ_ATTR) -#define H5F_OBJ_LOCAL (0x0020u) /* Restrict search to objects opened through current file ID */ -/* (as opposed to objects opened through any file ID accessing this file) */ +#define H5F_OBJ_LOCAL \ + (0x0020u) /**< Restrict search to objects opened through current file ID \ + (as opposed to objects opened through any file ID accessing this file) */ -#define H5F_FAMILY_DEFAULT (hsize_t)0 +#define H5F_FAMILY_DEFAULT 0 /* (hsize_t) */ #ifdef H5_HAVE_PARALLEL -/* +/** * Use this constant string as the MPI_Info key to set H5Fmpio debug flags. * To turn on H5Fmpio debug flags, set the MPI_Info value with this key to * have the value of a string consisting of the characters that turn on the @@ -99,128 +96,151 @@ #define H5F_MPIO_DEBUG_KEY "H5F_mpio_debug_key" #endif /* H5_HAVE_PARALLEL */ -/* The difference between a single file and a set of mounted files */ +/** + * The scope of an operation such as H5Fflush(), e.g., + * a single file vs. a set of mounted files + */ typedef enum H5F_scope_t { - H5F_SCOPE_LOCAL = 0, /*specified file handle only */ - H5F_SCOPE_GLOBAL = 1 /*entire virtual file */ + H5F_SCOPE_LOCAL = 0, /**< The specified file handle only */ + H5F_SCOPE_GLOBAL = 1 /**< The entire virtual file */ } H5F_scope_t; -/* Unlimited file size for H5Pset_external() */ -#define H5F_UNLIMITED ((hsize_t)(-1L)) +/** + * Unlimited file size for H5Pset_external() + */ +#define H5F_UNLIMITED HSIZE_UNDEF -/* How does file close behave? - * H5F_CLOSE_DEFAULT - Use the degree pre-defined by underlining VFL - * H5F_CLOSE_WEAK - file closes only after all opened objects are closed - * H5F_CLOSE_SEMI - if no opened objects, file is close; otherwise, file - close fails - * H5F_CLOSE_STRONG - if there are opened objects, close them first, then - close file +/** + * How does file close behave? */ typedef enum H5F_close_degree_t { - H5F_CLOSE_DEFAULT = 0, - H5F_CLOSE_WEAK = 1, - H5F_CLOSE_SEMI = 2, - H5F_CLOSE_STRONG = 3 + H5F_CLOSE_DEFAULT = 0, /**< Use the degree pre-defined by underlying VFD */ + H5F_CLOSE_WEAK = 1, /**< File closes only after all opened objects are closed */ + H5F_CLOSE_SEMI = 2, /**< If no opened objects, file is closed; otherwise, file close fails */ + H5F_CLOSE_STRONG = 3 /**< If there are opened objects, close them first, then close file */ } H5F_close_degree_t; -/* Current "global" information about file */ +/** + * Current "global" information about file + */ +//! <!-- [H5F_info2_t_snip] --> typedef struct H5F_info2_t { struct { - unsigned version; /* Superblock version # */ - hsize_t super_size; /* Superblock size */ - hsize_t super_ext_size; /* Superblock extension size */ + unsigned version; /**< Superblock version # */ + hsize_t super_size; /**< Superblock size */ + hsize_t super_ext_size; /**< Superblock extension size */ } super; struct { - unsigned version; /* Version # of file free space management */ - hsize_t meta_size; /* Free space manager metadata size */ - hsize_t tot_space; /* Amount of free space in the file */ + unsigned version; /**< Version # of file free space management */ + hsize_t meta_size; /**< Free space manager metadata size */ + hsize_t tot_space; /**< Amount of free space in the file */ } free; struct { - unsigned version; /* Version # of shared object header info */ - hsize_t hdr_size; /* Shared object header message header size */ - H5_ih_info_t msgs_info; /* Shared object header message index & heap size */ + unsigned version; /**< Version # of shared object header info */ + hsize_t hdr_size; /**< Shared object header message header size */ + H5_ih_info_t msgs_info; /**< Shared object header message index & heap size */ } sohm; } H5F_info2_t; +//! <!-- [H5F_info2_t_snip] --> -/* - * Types of allocation requests. The values larger than H5FD_MEM_DEFAULT +/** + * Types of allocation requests. The values larger than #H5FD_MEM_DEFAULT * should not change other than adding new types to the end. These numbers * might appear in files. * - * Note: please change the log VFD flavors array if you change this - * enumeration. + * \internal Please change the log VFD flavors array if you change this + * enumeration. */ typedef enum H5F_mem_t { - H5FD_MEM_NOLIST = -1, /* Data should not appear in the free list. + H5FD_MEM_NOLIST = -1, /**< Data should not appear in the free list. * Must be negative. */ - H5FD_MEM_DEFAULT = 0, /* Value not yet set. Can also be the + H5FD_MEM_DEFAULT = 0, /**< Value not yet set. Can also be the * datatype set in a larger allocation * that will be suballocated by the library. * Must be zero. */ - H5FD_MEM_SUPER = 1, /* Superblock data */ - H5FD_MEM_BTREE = 2, /* B-tree data */ - H5FD_MEM_DRAW = 3, /* Raw data (content of datasets, etc.) */ - H5FD_MEM_GHEAP = 4, /* Global heap data */ - H5FD_MEM_LHEAP = 5, /* Local heap data */ - H5FD_MEM_OHDR = 6, /* Object header data */ - - H5FD_MEM_NTYPES /* Sentinel value - must be last */ + H5FD_MEM_SUPER = 1, /**< Superblock data */ + H5FD_MEM_BTREE = 2, /**< B-tree data */ + H5FD_MEM_DRAW = 3, /**< Raw data (content of datasets, etc.) */ + H5FD_MEM_GHEAP = 4, /**< Global heap data */ + H5FD_MEM_LHEAP = 5, /**< Local heap data */ + H5FD_MEM_OHDR = 6, /**< Object header data */ + + H5FD_MEM_NTYPES /**< Sentinel value - must be last */ } H5F_mem_t; -/* Free space section information */ +/** + * Free space section information + */ +//! <!-- [H5F_sect_info_t_snip] --> typedef struct H5F_sect_info_t { - haddr_t addr; /* Address of free space section */ - hsize_t size; /* Size of free space section */ + haddr_t addr; /**< Address of free space section */ + hsize_t size; /**< Size of free space section */ } H5F_sect_info_t; +//! <!-- [H5F_sect_info_t_snip] --> -/* Library's format versions */ +/** + * Library's format versions + */ typedef enum H5F_libver_t { H5F_LIBVER_ERROR = -1, - H5F_LIBVER_EARLIEST = 0, /* Use the earliest possible format for storing objects */ - H5F_LIBVER_V18 = 1, /* Use the latest v18 format for storing objects */ - H5F_LIBVER_V110 = 2, /* Use the latest v110 format for storing objects */ - H5F_LIBVER_V112 = 3, /* Use the latest v112 format for storing objects */ - H5F_LIBVER_V114 = 4, /* Use the latest v114 format for storing objects */ - H5F_LIBVER_NBOUNDS + H5F_LIBVER_EARLIEST = 0, /**< Use the earliest possible format for storing objects */ + H5F_LIBVER_V18 = 1, /**< Use the latest v18 format for storing objects */ + H5F_LIBVER_V110 = 2, /**< Use the latest v110 format for storing objects */ + H5F_LIBVER_V112 = 3, /**< Use the latest v112 format for storing objects */ + H5F_LIBVER_V114 = 4, /**< Use the latest v114 format for storing objects */ + H5F_LIBVER_NBOUNDS /**< Sentinel */ } H5F_libver_t; #define H5F_LIBVER_LATEST H5F_LIBVER_V114 -/* File space handling strategy */ +/** + * File space handling strategy + */ +//! <!-- [H5F_fspace_strategy_t_snip] --> typedef enum H5F_fspace_strategy_t { - H5F_FSPACE_STRATEGY_FSM_AGGR = - 0, /* Mechanisms: free-space managers, aggregators, and virtual file drivers */ - /* This is the library default when not set */ + H5F_FSPACE_STRATEGY_FSM_AGGR = 0, /**< Mechanisms: free-space managers, aggregators, and virtual file + drivers This is the library default when not set */ H5F_FSPACE_STRATEGY_PAGE = - 1, /* Mechanisms: free-space managers with embedded paged aggregation and virtual file drivers */ - H5F_FSPACE_STRATEGY_AGGR = 2, /* Mechanisms: aggregators and virtual file drivers */ - H5F_FSPACE_STRATEGY_NONE = 3, /* Mechanisms: virtual file drivers */ - H5F_FSPACE_STRATEGY_NTYPES /* must be last */ + 1, /**< Mechanisms: free-space managers with embedded paged aggregation and virtual file drivers */ + H5F_FSPACE_STRATEGY_AGGR = 2, /**< Mechanisms: aggregators and virtual file drivers */ + H5F_FSPACE_STRATEGY_NONE = 3, /**< Mechanisms: virtual file drivers */ + H5F_FSPACE_STRATEGY_NTYPES /**< Sentinel */ } H5F_fspace_strategy_t; +//! <!-- [H5F_fspace_strategy_t_snip] --> -/* Deprecated: File space handling strategy for release 1.10.0 */ -/* They are mapped to H5F_fspace_strategy_t as defined above from release 1.10.1 onwards */ +/** + * File space handling strategy for release 1.10.0 + * + * \deprecated 1.10.1 + */ typedef enum H5F_file_space_type_t { - H5F_FILE_SPACE_DEFAULT = 0, /* Default (or current) free space strategy setting */ - H5F_FILE_SPACE_ALL_PERSIST = 1, /* Persistent free space managers, aggregators, virtual file driver */ - H5F_FILE_SPACE_ALL = 2, /* Non-persistent free space managers, aggregators, virtual file driver */ - /* This is the library default */ - H5F_FILE_SPACE_AGGR_VFD = 3, /* Aggregators, Virtual file driver */ - H5F_FILE_SPACE_VFD = 4, /* Virtual file driver */ - H5F_FILE_SPACE_NTYPES /* must be last */ + H5F_FILE_SPACE_DEFAULT = 0, /**< Default (or current) free space strategy setting */ + H5F_FILE_SPACE_ALL_PERSIST = 1, /**< Persistent free space managers, aggregators, virtual file driver */ + H5F_FILE_SPACE_ALL = 2, /**< Non-persistent free space managers, aggregators, virtual file driver + This is the library default */ + H5F_FILE_SPACE_AGGR_VFD = 3, /**< Aggregators, Virtual file driver */ + H5F_FILE_SPACE_VFD = 4, /**< Virtual file driver */ + H5F_FILE_SPACE_NTYPES /**< Sentinel */ } H5F_file_space_type_t; -/* Data structure to report the collection of read retries for metadata items with checksum */ -/* Used by public routine H5Fget_metadata_read_retry_info() */ +//! <!-- [H5F_retry_info_t_snip] --> #define H5F_NUM_METADATA_READ_RETRY_TYPES 21 + +/** + * Data structure to report the collection of read retries for metadata items with checksum as + * used by H5Fget_metadata_read_retry_info() + */ typedef struct H5F_retry_info_t { unsigned nbins; uint32_t *retries[H5F_NUM_METADATA_READ_RETRY_TYPES]; } H5F_retry_info_t; +//! <!-- [H5F_retry_info_t_snip] --> -/* Callback for H5Pset_object_flush_cb() in a file access property list */ +/** + * Callback for H5Pset_object_flush_cb() in a file access property list + */ typedef herr_t (*H5F_flush_cb_t)(hid_t object_id, void *udata); /* VFD SWMR configuration data used by H5Pset/get_vfd_swmr_config */ @@ -318,66 +338,1576 @@ typedef struct H5F_vfd_swmr_config_t { extern "C" { #endif -H5_DLL htri_t H5Fis_accessible(const char *container_name, hid_t fapl_id); -H5_DLL hid_t H5Fcreate(const char *filename, unsigned flags, hid_t create_plist, hid_t access_plist); -H5_DLL hid_t H5Fopen(const char *filename, unsigned flags, hid_t access_plist); -H5_DLL hid_t H5Freopen(hid_t file_id); -H5_DLL herr_t H5Fflush(hid_t object_id, H5F_scope_t scope); -H5_DLL herr_t H5Fclose(hid_t file_id); -H5_DLL herr_t H5Fdelete(const char *filename, hid_t fapl_id); -H5_DLL hid_t H5Fget_create_plist(hid_t file_id); -H5_DLL hid_t H5Fget_access_plist(hid_t file_id); -H5_DLL herr_t H5Fget_intent(hid_t file_id, unsigned *intent); -H5_DLL herr_t H5Fget_fileno(hid_t file_id, unsigned long *fileno); -H5_DLL ssize_t H5Fget_obj_count(hid_t file_id, unsigned types); -H5_DLL ssize_t H5Fget_obj_ids(hid_t file_id, unsigned types, size_t max_objs, hid_t *obj_id_list); -H5_DLL herr_t H5Fget_vfd_handle(hid_t file_id, hid_t fapl, void **file_handle); -H5_DLL herr_t H5Fmount(hid_t loc, const char *name, hid_t child, hid_t plist); -H5_DLL herr_t H5Funmount(hid_t loc, const char *name); +/** + * \ingroup H5F + * + * \brief Checks if a file can be opened with a given file access property + * list + * + * \param[in] container_name Name of a file + * \fapl_id + * + * \return \htri_t + * + * \details H5Fis_accessible() checks if the file specified by \p + * container_name can be opened with the file access property list + * \p fapl_id. + * + * \note The H5Fis_accessible() function enables files to be checked with a + * given file access property list, unlike H5Fis_hdf5(), which only uses + * the default file driver when opening a file. + * + * \since 1.12.0 + * + */ +H5_DLL htri_t H5Fis_accessible(const char *container_name, hid_t fapl_id); +/** + * \ingroup H5F + * + * \brief Creates an HDF5 file + * + * \param[in] filename Name of the file to create + * \param[in] flags File access flags. Allowable values are: + * - #H5F_ACC_TRUNC: Truncate file, if it already exists, + * erasing all data previously stored in the file + * - #H5F_ACC_EXCL: Fail if file already exists + * \fcpl_id + * \fapl_id + * \return \hid_t{file} + * + * \details H5Fcreate() is the primary function for creating HDF5 files; it + * creates a new HDF5 file with the specified name and property lists. + * + * The \p filename parameter specifies the name of the new file. + * + * The \p flags parameter specifies whether an existing file is to be + * overwritten. It should be set to either #H5F_ACC_TRUNC to overwrite + * an existing file or #H5F_ACC_EXCL, instructing the function to fail + * if the file already exists. + * + * New files are always created in read-write mode, so the read-write + * and read-only flags, #H5F_ACC_RDWR and #H5F_ACC_RDONLY, + * respectively, are not relevant in this function. Further note that + * a specification of #H5F_ACC_RDONLY will be ignored; the file will + * be created in read-write mode, regardless. + * + * More complex behaviors of file creation and access are controlled + * through the file creation and file access property lists, + * \p fcpl_id and \p fapl_id, respectively. The value of #H5P_DEFAULT + * for any property list value indicates that the library should use + * the default values for that appropriate property list. + * + * The return value is a file identifier for the newly-created file; + * this file identifier should be closed by calling H5Fclose() when + * it is no longer needed. + * + * \par Example + * \snippet H5F_examples.c minimal + * + * \note #H5F_ACC_TRUNC and #H5F_ACC_EXCL are mutually exclusive; use + * exactly one. + * + * \note An additional flag, #H5F_ACC_DEBUG, prints debug information. This + * flag can be combined with one of the above values using the bit-wise + * OR operator (\c |), but it is used only by HDF5 library developers; + * \Emph{it is neither tested nor supported for use in applications}. + * + * \attention \Bold{Special case — File creation in the case of an already-open file:} + * If a file being created is already opened, by either a previous + * H5Fopen() or H5Fcreate() call, the HDF5 library may or may not + * detect that the open file and the new file are the same physical + * file. (See H5Fopen() regarding the limitations in detecting the + * re-opening of an already-open file.)\n + * If the library detects that the file is already opened, + * H5Fcreate() will return a failure, regardless of the use of + * #H5F_ACC_TRUNC.\n + * If the library does not detect that the file is already opened + * and #H5F_ACC_TRUNC is not used, H5Fcreate() will return a failure + * because the file already exists. Note that this is correct + * behavior.\n + * But if the library does not detect that the file is already + * opened and #H5F_ACC_TRUNC is used, H5Fcreate() will truncate the + * existing file and return a valid file identifier. Such a + * truncation of a currently-opened file will almost certainly + * result in errors. While unlikely, the HDF5 library may not be + * able to detect, and thus report, such errors.\n + * Applications should avoid calling H5Fcreate() with an already + * opened file. + * + * \since 1.0.0 + * + * \see H5Fopen(), H5Fclose() + * + */ +H5_DLL hid_t H5Fcreate(const char *filename, unsigned flags, hid_t fcpl_id, hid_t fapl_id); +/** + * -------------------------------------------------------------------------- + * \ingroup ASYNC + * \async_variant_of{H5Fcreate} + */ +H5_DLL hid_t H5Fcreate_async(const char *app_file, const char *app_func, unsigned app_line, + const char *filename, unsigned flags, hid_t fcpl_id, hid_t fapl_id, hid_t es_id); +/** + * \ingroup H5F + * + * \brief Opens an existing HDF5 file + * + * \param[in] filename Name of the file to be opened + * \param[in] flags File access flags. Allowable values are: + * - #H5F_ACC_RDWR: Allows read and write access to file + * - #H5F_ACC_RDONLY: Allows read-only access to file + * - #H5F_ACC_RDWR \c | #H5F_ACC_SWMR_WRITE: Indicates that + * the file is open for writing in a + * single-writer/multi-writer (SWMR) scenario. + * - #H5F_ACC_RDONLY \c | #H5F_ACC_SWMR_READ: Indicates + * that the file is open for reading in a + * single-writer/multi-reader (SWMR) scenario. + * - An additional flag, #H5F_ACC_DEBUG, prints debug + * information. This flag can be combined with one of the + * above values using the bit-wise OR operator (\c |), but + * it is used only by HDF5 library developers; + * \Emph{it is neither tested nor supported} for use in + * applications. + * \fapl_id + * \return \hid_t{file} + * + * \details H5Fopen() is the primary function for accessing existing HDF5 files. + * This function opens the named file in the specified access mode and + * with the specified access property list. + * + * Note that H5Fopen() does not create a file if it does not already + * exist; see H5Fcreate(). + * + * The \p filename parameter specifies the name of the file to be + * opened. + * + * The \p fapl_id parameter specifies the file access property list. + * Use of #H5P_DEFAULT specifies that default I/O access properties + * are to be used. + * + * The \p flags parameter specifies whether the file will be opened in + * read-write or read-only mode, #H5F_ACC_RDWR or #H5F_ACC_RDONLY, + * respectively. More complex behaviors of file access are controlled + * through the file-access property list. + * + * The return value is a file identifier for the open file; this file + * identifier should be closed by calling H5Fclose() when it is no + * longer needed. + * + * \par Example + * \snippet H5F_examples.c open + * + * \note #H5F_ACC_RDWR and #H5F_ACC_RDONLY are mutually exclusive; use + * exactly one. + * + * \attention \Bold{Special cases — Multiple opens:} A file can often be opened + * with a new H5Fopen() call without closing an already-open + * identifier established in a previous H5Fopen() or H5Fcreate() + * call. Each such H5Fopen() call will return a unique identifier + * and the file can be accessed through any of these identifiers as + * long as the identifier remains valid. In such multiply-opened + * cases, the open calls must use the same flags argument and the + * file access property lists must use the same file close degree + * property setting (see the external link discussion below and + * H5Pset_fclose_degree()).\n + * In some cases, such as files on a local Unix file system, the + * HDF5 library can detect that a file is multiply opened and will + * maintain coherent access among the file identifiers.\n + * But in many other cases, such as parallel file systems or + * networked file systems, it is not always possible to detect + * multiple opens of the same physical file. In such cases, HDF5 + * will treat the file identifiers as though they are accessing + * different files and will be unable to maintain coherent access. + * Errors are likely to result in these cases. While unlikely, the + * HDF5 library may not be able to detect, and thus report, + * such errors.\n + * It is generally recommended that applications avoid multiple + * opens of the same file. + * + * \attention \Bold{Special restriction on multiple opens of a file first + * opened by means of an external link:} When an external link is + * followed, the external file is always opened with the weak file + * close degree property setting, #H5F_CLOSE_WEAK (see + * H5Lcreate_external() and H5Pset_fclose_degree()). If the file is + * reopened with H5Fopen while it remains held open from such an + * external link call, the file access property list used in the + * open call must include the file close degree setting + * #H5F_CLOSE_WEAK or the open will fail. + * + * \version 1.10.0 The #H5F_ACC_SWMR_WRITE and #H5F_ACC_SWMR_READ flags were added. + * + * \see H5Fclose() + * + */ +H5_DLL hid_t H5Fopen(const char *filename, unsigned flags, hid_t fapl_id); +/** + * -------------------------------------------------------------------------- + * \ingroup ASYNC + * \async_variant_of{H5Fopen} + */ +H5_DLL hid_t H5Fopen_async(const char *app_file, const char *app_func, unsigned app_line, + const char *filename, unsigned flags, hid_t access_plist, hid_t es_id); +/** + * \ingroup H5F + * + * \brief Returns a new identifier for a previously-opened HDF5 file + * + * \param[in] file_id Identifier of a file for which an additional identifier + * is required + * + * \return \hid_t{file} + * + * \details H5Freopen() returns a new file identifier for an already-open HDF5 + * file, as specified by \p file_id. Both identifiers share caches and + * other information. The only difference between the identifiers is + * that the new identifier is not mounted anywhere and no files are + * mounted on it. + * + * The new file identifier should be closed by calling H5Fclose() when + * it is no longer needed. + * + * \note Note that there is no circumstance under which H5Freopen() can + * actually open a closed file; the file must already be open and have an + * active \p file_id. E.g., one cannot close a file with H5Fclose() on + * \p file_id then use H5Freopen() on \p file_id to reopen it. + * + */ +H5_DLL hid_t H5Freopen(hid_t file_id); +/** + * -------------------------------------------------------------------------- + * \ingroup ASYNC + * \async_variant_of{H5Freopen} + */ +H5_DLL hid_t H5Freopen_async(const char *app_file, const char *app_func, unsigned app_line, hid_t file_id, + hid_t es_id); +/** + * \ingroup H5F + * + * \brief Flushes all buffers associated with a file to storage + * + * \loc_id{object_id} + * \param[in] scope The scope of the flush action + * + * \return \herr_t + * + * \details H5Fflush() causes all buffers associated with a file to be + * immediately flushed to storage without removing the data from the + * cache. + * + * \p object_id can be any object associated with the file, including + * the file itself, a dataset, a group, an attribute, or a named + * datatype. + * + * \p scope specifies whether the scope of the flush action is + * global or local. Valid values are as follows: + * \scopes + * + * \par Example + * \snippet H5F_examples.c flush + * + * \attention HDF5 does not possess full control over buffering. H5Fflush() + * flushes the internal HDF5 buffers then asks the operating system + * (the OS) to flush the system buffers for the open files. After + * that, the OS is responsible for ensuring that the data is + * actually flushed to disk. + * + */ +H5_DLL herr_t H5Fflush(hid_t object_id, H5F_scope_t scope); +/** + * -------------------------------------------------------------------------- + * \ingroup ASYNC + * \async_variant_of{H5Fflush} + */ +H5_DLL herr_t H5Fflush_async(const char *app_file, const char *app_func, unsigned app_line, hid_t object_id, + H5F_scope_t scope, hid_t es_id); +/** + * \ingroup H5F + * + * \brief Terminates access to an HDF5 file + * + * \file_id + * \return \herr_t + * + * \details H5Fclose() terminates access to an HDF5 file (specified by + * \p file_id) by flushing all data to storage. + * + * If this is the last file identifier open for the file and no other + * access identifier is open (e.g., a dataset identifier, group + * identifier, or shared datatype identifier), the file will be fully + * closed and access will end. + * + * \par Example + * \snippet H5F_examples.c minimal + * + * \note \Bold{Delayed close:} Note the following deviation from the + * above-described behavior. If H5Fclose() is called for a file but one + * or more objects within the file remain open, those objects will remain + * accessible until they are individually closed. Thus, if the dataset + * \c data_sample is open when H5Fclose() is called for the file + * containing it, \c data_sample will remain open and accessible + * (including writable) until it is explicitly closed. The file will be + * automatically closed once all objects in the file have been closed.\n + * Be warned, however, that there are circumstances where it is not + * possible to delay closing a file. For example, an MPI-IO file close is + * a collective call; all of the processes that opened the file must + * close it collectively. The file cannot be closed at some time in the + * future by each process in an independent fashion. Another example is + * that an application using an AFS token-based file access privilege may + * destroy its AFS token after H5Fclose() has returned successfully. This + * would make any future access to the file, or any object within it, + * illegal.\n + * In such situations, applications must close all open objects in a file + * before calling H5Fclose. It is generally recommended to do so in all + * cases. + * + * \see H5Fopen() + * + */ +H5_DLL herr_t H5Fclose(hid_t file_id); +/** + * -------------------------------------------------------------------------- + * \ingroup ASYNC + * \async_variant_of{H5Fclose} + */ +H5_DLL herr_t H5Fclose_async(const char *app_file, const char *app_func, unsigned app_line, hid_t file_id, + hid_t es_id); +/** + * \ingroup H5F + * + * \brief Deletes an HDF5 file + * + * \param[in] filename Name of the file to delete + * \fapl_id + * + * \return \herr_t + * + * \details H5Fdelete() deletes an HDF5 file \p filename with a file access + * property list \p fapl_id. The \p fapl_id should be configured with + * the same VOL connector or VFD that was used to open the file. + * + * This API was introduced for use with the Virtual Object Layer + * (VOL). With the VOL, HDF5 "files" can map to arbitrary storage + * schemes such as object stores and relational database tables. The + * data created by these implementations may be inconvenient for a + * user to remove without a detailed knowledge of the storage scheme. + * H5Fdelete() gives VOL connector authors the ability to add + * connector-specific delete code to their connectors so that users + * can remove these "files" without detailed knowledge of the storage + * scheme. + * + * For a VOL connector, H5Fdelete() deletes the file in a way that + * makes sense for the specified VOL connector. + * + * For the native HDF5 connector, HDF5 files will be deleted via the + * VFDs, each of which will have to be modified to delete the files it + * creates. + * + * For all implementations, H5Fdelete() will first check if the file + * is an HDF5 file via H5Fis_accessible(). This is done to ensure that + * H5Fdelete() cannot be used as an arbitrary file deletion call. + * + * \since 1.12.0 + * + */ +H5_DLL herr_t H5Fdelete(const char *filename, hid_t fapl_id); +/** + * \ingroup H5F + * + * \brief Returns a file creation property list identifier + * + * \file_id + * \return \hid_t{file creation property list} + * + * \details H5Fget_create_plist() returns the file creation property list + * identifier identifying the creation properties used to create this + * file. This function is useful for duplicating properties when + * creating another file. + * + * The creation property list identifier should be released with + * H5Pclose(). + * + */ +H5_DLL hid_t H5Fget_create_plist(hid_t file_id); +/** + * \ingroup H5F + * + * \brief Returns a file access property list identifier + * + * \file_id + * \return \hid_t{file access property list} + * + * \details H5Fget_access_plist() returns the file access property list + * identifier of the specified file. + * + */ +H5_DLL hid_t H5Fget_access_plist(hid_t file_id); +/** + * \ingroup H5F + * + * \brief Determines the read/write or read-only status of a file + * + * \file_id + * \param[out] intent Access mode flag as originally passed with H5Fopen() + * + * \return \herr_t + * + * \details Given the identifier of an open file, \p file_id, H5Fget_intent() + * retrieves the intended access mode" flag passed with H5Fopen() when + * the file was opened. + * + * The value of the flag is returned in \p intent. Valid values are as + * follows: + * \file_access + * + * \note The function will not return an error if intent is NULL; it will + * simply do nothing. + * + * \version 1.10.0 Function enhanced to work with SWMR functionality. + * + * \since 1.8.0 + * + */ +H5_DLL herr_t H5Fget_intent(hid_t file_id, unsigned *intent); +/** + * \ingroup H5F + * + * \brief Retrieves a file's file number that uniquely identifies an open file + * + * \file_id + * \param[out] fileno A buffer to hold the file number + * + * \return \herr_t + * + * \details H5Fget_fileno() retrieves a file number for a file specified by the + * file identifier \p file_id and the pointer \p fnumber to the file + * number. + * + * \since 1.12.0 + * + */ +H5_DLL herr_t H5Fget_fileno(hid_t file_id, unsigned long *fileno); +/** + * \ingroup H5F + * + * \brief Returns the number of open object identifiers for an open file + * + * \file_id or #H5F_OBJ_ALL for all currently-open HDF5 files + * \param[in] types Type of object for which identifiers are to be returned + * + * \return Returns the number of open objects if successful; otherwise returns + * a negative value. + * + * \details Given the identifier of an open file, file_id, and the desired + * object types, types, H5Fget_obj_count() returns the number of open + * object identifiers for the file. + * + * To retrieve a count of open identifiers for open objects in all + * HDF5 application files that are currently open, pass the value + * #H5F_OBJ_ALL in \p file_id. + * + * The types of objects to be counted are specified in types as + * follows: + * \obj_types + * + * Multiple object types can be combined with the + * logical \c OR operator (|). For example, the expression + * \c (#H5F_OBJ_DATASET|#H5F_OBJ_GROUP) would call for datasets and + * groups. + * + * \version 1.6.8, 1.8.2 Function return type changed to \c ssize_t. + * \version 1.6.5 #H5F_OBJ_LOCAL has been added as a qualifier on the types + * of objects to be counted. #H5F_OBJ_LOCAL restricts the + * search to objects opened through current file identifier. + * + */ +H5_DLL ssize_t H5Fget_obj_count(hid_t file_id, unsigned types); +/** + *------------------------------------------------------------------------- + * \ingroup H5F + * + * \brief Returns a list of open object identifiers + * + * \file_id or #H5F_OBJ_ALL for all currently-open HDF5 files + * \param[in] types Type of object for which identifiers are to be returned + * \param[in] max_objs Maximum number of object identifiers to place into + * \p obj_id_list + * \param[out] obj_id_list Pointer to the returned buffer of open object + * identifiers + * + * \return Returns number of objects placed into \p obj_id_list if successful; + * otherwise returns a negative value. + * + * \details Given the file identifier \p file_id and the type of objects to be + * identified, types, H5Fget_obj_ids() returns the list of identifiers + * for all open HDF5 objects fitting the specified criteria. + * + * To retrieve identifiers for open objects in all HDF5 application + * files that are currently open, pass the value #H5F_OBJ_ALL in + * \p file_id. + * + * The types of object identifiers to be retrieved are specified in + * types using the codes listed for the same parameter in + * H5Fget_obj_count(). + * + * To retrieve a count of open objects, use the H5Fget_obj_count() + * function. This count can be used to set the \p max_objs parameter. + * + * \version 1.8.2 Function return type changed to \c ssize_t and \p + * max_objs parameter datatype changed to \c size_t. + * \version 1.6.8 Function return type changed to \c ssize_t and \p + * max_objs parameter datatype changed to \c size_t. + * \since 1.6.0 + * + */ +H5_DLL ssize_t H5Fget_obj_ids(hid_t file_id, unsigned types, size_t max_objs, hid_t *obj_id_list); +/** + * \ingroup H5F + * + * \brief Returns pointer to the file handle from the virtual file driver + * + * \file_id + * \fapl_id{fapl} + * \param[out] file_handle Pointer to the file handle being used by the + * low-level virtual file driver + * + * \return \herr_t + * + * \details Given the file identifier \p file_id and the file access property + * list \p fapl_id, H5Fget_vfd_handle() returns a pointer to the file + * handle from the low-level file driver currently being used by the + * HDF5 library for file I/O. + * + * \note For most drivers, the value of \p fapl_id will be #H5P_DEFAULT. For + * the \c FAMILY or \c MULTI drivers, this value should be defined + * through the property list functions: H5Pset_family_offset() for the + * \c FAMILY driver and H5Pset_multi_type() for the \c MULTI driver + * + * \since 1.6.0 + * + */ +H5_DLL herr_t H5Fget_vfd_handle(hid_t file_id, hid_t fapl, void **file_handle); +/** + * \ingroup H5F + * + * \brief Mounts an HDF5 file + * + * \loc_id{loc} + * \param[in] name Name of the group onto which the file specified by \p child + * is to be mounted + * \file_id{child} + * \param[in] plist File mount property list identifier. Pass #H5P_DEFAULT! + * + * \return \herr_t + * + * \details H5Fmount() mounts the file specified by \p child onto the object + * specified by \p loc and \p name using the mount properties \p plist + * If the object specified by \p loc is a dataset, named datatype or + * attribute, then the file will be mounted at the location where the + * attribute, dataset, or named datatype is attached. + * + * \par Example + * \snippet H5F_examples.c mount + * + * \note To date, no file mount properties have been defined in HDF5. The + * proper value to pass for \p plist is #H5P_DEFAULT, indicating the + * default file mount property list. + * + */ +H5_DLL herr_t H5Fmount(hid_t loc, const char *name, hid_t child, hid_t plist); +/** + * \ingroup H5F + * + * \brief Unounts an HDF5 file + * + * \loc_id{loc} + * \param[in] name Name of the mount point + * + * \return \herr_t + * + * \details Given a mount point, H5Funmount() dissociates the mount point's + * file from the file mounted there. This function does not close + * either file. + * + * The mount point can be either the group in the parent or the root + * group of the mounted file (both groups have the same name). If the + * mount point was opened before the mount then it is the group in the + * parent; if it was opened after the mount then it is the root group + * of the child. + * + */ +H5_DLL herr_t H5Funmount(hid_t loc, const char *name); +/** + * \ingroup H5F + * + * \brief Returns the amount of free space in a file (in bytes) + * + * \file_id + * + * \return Returns the amount of free space in the file if successful; + * otherwise returns a negative value. + * + * \details Given the identifier of an open file, \p file_id, + * H5Fget_freespace() returns the amount of space that is unused by + * any objects in the file. + * + * The interpretation of this number depends on the configured free space + * management strategy. For example, if the HDF5 library only tracks free + * space in a file from a file open or create until that file is closed, + * then this routine will report the free space that has been created + * during that interval. + * + * \since 1.6.1 + * + */ H5_DLL hssize_t H5Fget_freespace(hid_t file_id); -H5_DLL herr_t H5Fget_filesize(hid_t file_id, hsize_t *size); -H5_DLL herr_t H5Fget_eoa(hid_t file_id, haddr_t *eoa); -H5_DLL herr_t H5Fincrement_filesize(hid_t file_id, hsize_t increment); -H5_DLL ssize_t H5Fget_file_image(hid_t file_id, void *buf_ptr, size_t buf_len); -H5_DLL herr_t H5Fget_mdc_config(hid_t file_id, H5AC_cache_config_t *config_ptr); -H5_DLL herr_t H5Fset_mdc_config(hid_t file_id, H5AC_cache_config_t *config_ptr); -H5_DLL herr_t H5Fget_mdc_hit_rate(hid_t file_id, double *hit_rate_ptr); -H5_DLL herr_t H5Fget_mdc_size(hid_t file_id, size_t *max_size_ptr, size_t *min_clean_size_ptr, - size_t *cur_size_ptr, int *cur_num_entries_ptr); -H5_DLL herr_t H5Freset_mdc_hit_rate_stats(hid_t file_id); -H5_DLL ssize_t H5Fget_name(hid_t obj_id, char *name, size_t size); -H5_DLL herr_t H5Fget_info2(hid_t obj_id, H5F_info2_t *finfo); -H5_DLL herr_t H5Fget_metadata_read_retry_info(hid_t file_id, H5F_retry_info_t *info); -H5_DLL herr_t H5Fstart_swmr_write(hid_t file_id); -H5_DLL ssize_t H5Fget_free_sections(hid_t file_id, H5F_mem_t type, size_t nsects, - H5F_sect_info_t *sect_info /*out*/); -H5_DLL herr_t H5Fclear_elink_file_cache(hid_t file_id); -H5_DLL herr_t H5Fset_libver_bounds(hid_t file_id, H5F_libver_t low, H5F_libver_t high); -H5_DLL herr_t H5Fstart_mdc_logging(hid_t file_id); -H5_DLL herr_t H5Fstop_mdc_logging(hid_t file_id); -H5_DLL herr_t H5Fget_mdc_logging_status(hid_t file_id, - /*OUT*/ hbool_t *is_enabled, - /*OUT*/ hbool_t *is_currently_logging); -H5_DLL herr_t H5Fformat_convert(hid_t fid); -H5_DLL herr_t H5Freset_page_buffering_stats(hid_t file_id); -H5_DLL herr_t H5Fget_page_buffering_stats(hid_t file_id, unsigned accesses[2], unsigned hits[2], - unsigned misses[2], unsigned evictions[2], unsigned bypasses[2]); -H5_DLL herr_t H5Fget_mdc_image_info(hid_t file_id, haddr_t *image_addr, hsize_t *image_size); -H5_DLL herr_t H5Fget_dset_no_attrs_hint(hid_t file_id, hbool_t *minimize); -H5_DLL herr_t H5Fset_dset_no_attrs_hint(hid_t file_id, hbool_t minimize); +/** + * \ingroup H5F + * + * \brief Returns the size of an HDF5 file (in bytes) + * + * \file_id + * \param[out] size Size of the file, in bytes + * + * \return \herr_t + * + * \details H5Fget_filesize() returns the size of the HDF5 file specified by + * \p file_id. + * + * The returned size is that of the entire file, as opposed to only + * the HDF5 portion of the file. I.e., size includes the user block, + * if any, the HDF5 portion of the file, and any data that may have + * been appended beyond the data written through the HDF5 library. + * + * \since 1.6.3 + * + */ +H5_DLL herr_t H5Fget_filesize(hid_t file_id, hsize_t *size); +/** + * \ingroup H5F + * + * \brief Retrieves the file's end-of-allocation (EOA) + * + * \file_id + * \param[out] eoa The file's EOA + * + * \return \herr_t + * + * \details H5Fget_eoa() retrieves the file's EOA and returns it in the + * parameter eoa. + * + * \since 1.10.2 + * + */ +H5_DLL herr_t H5Fget_eoa(hid_t file_id, haddr_t *eoa); +/** + * \ingroup H5F + * + * \brief Sets the file' EOA to the maximum of (EOA, EOF) + increment + * + * \file_id + * \param[in] increment The number of bytes to be added to the maximum of + * (EOA, EOF) + * + * \return \herr_t + * + * \details H5Fincrement_filesize() sets the file's EOA to the maximum of (EOA, + * EOF) + \p increment. The EOA is the end-of-file address stored in + * the file's superblock while EOF is the file's actual end-of-file. + * + * \since 1.10.2 + * + */ +H5_DLL herr_t H5Fincrement_filesize(hid_t file_id, hsize_t increment); +/** + * \ingroup H5F + * + * \brief Retrieves a copy of the image of an existing, open file + * + * \file_id + * \param[out] buf_ptr Pointer to the buffer into which the image of the + * HDF5 file is to be copied. If \p buf_ptr is NULL, + * no data will be copied but the function’s return value + * will still indicate the buffer size required (or a + * negative value on error). + * \param[out] buf_len Size of the supplied buffer + * + * \return ssize_t + * + * \details H5Fget_file_image() retrieves a copy of the image of an existing, + * open file. This routine can be used with files opened using the + * SEC2 (or POSIX), STDIO, and Core (or Memory) virtual file drivers + * (VFDs). + * + * If the return value of H5Fget_file_image() is a positive value, it + * will be the length in bytes of the buffer required to store the + * file image. So if the file size is unknown, it can be safely + * determined with an initial H5Fget_file_image() call with buf_ptr + * set to NULL. The file image can then be retrieved with a second + * H5Fget_file_image() call with \p buf_len set to the initial call’s + * return value. + * + * While the current file size can also be retrieved with + * H5Fget_filesize(), that call may produce a larger value than is + * needed. The value returned by H5Fget_filesize() includes the user + * block, if it exists, and any unallocated space at the end of the + * file. It is safe in all situations to get the file size with + * H5Fget_file_image() and it often produces a value that is more + * appropriate for the size of a file image buffer. + * + * \note \Bold{Recommended Reading:} This function is part of the file image + * operations feature set. It is highly recommended to study the guide + * \ref_file_image_ops before using this feature set. + * + * \attention H5Pget_file_image() will fail, returning a negative value, if the + * file is too large for the supplied buffer. + * + * \see H5LTopen_file_image(), H5Pset_file_image(), H5Pget_file_image(), + * H5Pset_file_image_callbacks(), H5Pget_file_image_callbacks() + * + * \since 1.8.0 + * + */ +H5_DLL ssize_t H5Fget_file_image(hid_t file_id, void *buf_ptr, size_t buf_len); +/** + * \ingroup MDC + * + * \brief Obtains current metadata cache configuration for target file + * + * \file_id + * \param[in,out] config_ptr Pointer to the H5AC_cache_config_t instance in which + * the current metadata cache configuration is to be + * reported. The fields of this structure are discussed + * \ref H5AC-cache-config-t "here". + * \return \herr_t + * + * \note The \c in direction applies only to the H5AC_cache_config_t::version + * field. All other fields are out parameters. + * + * \details H5Fget_mdc_config() loads the current metadata cache configuration + * into the instance of H5AC_cache_config_t pointed to by the \p config_ptr + * parameter.\n + * The fields of the H5AC_cache_config_t structure are shown below: + * \snippet H5ACpublic.h H5AC_cache_config_t_snip + * \click4more + * + * \since 1.8.0 + * + */ +H5_DLL herr_t H5Fget_mdc_config(hid_t file_id, H5AC_cache_config_t *config_ptr); +/** + * \ingroup MDC + * + * \brief Attempts to configure metadata cache of target file + * + * \file_id + * \param[in,out] config_ptr Pointer to the H5AC_cache_config_t instance + * containing the desired configuration. + * The fields of this structure are discussed + * \ref H5AC-cache-config-t "here". + * \return \herr_t + * + * \details H5Fset_mdc_config() attempts to configure the file's metadata cache + * according configuration supplied in \p config_ptr. + * \snippet H5ACpublic.h H5AC_cache_config_t_snip + * \click4more + * + * \since 1.8.0 + * + */ +H5_DLL herr_t H5Fset_mdc_config(hid_t file_id, H5AC_cache_config_t *config_ptr); +/** + * \ingroup MDC + * + * \brief Obtains target file's metadata cache hit rate + * + * \file_id + * \param[out] hit_rate_ptr Pointer to the double in which the hit rate is returned. Note that + * \p hit_rate_ptr is undefined if the API call fails + * \return \herr_t + * + * \details H5Fget_mdc_hit_rate() queries the metadata cache of the target file to obtain its hit rate + * \Code{(cache hits / (cache hits + cache misses))} since the last time hit rate statistics + * were reset. If the cache has not been accessed since the last time the hit rate stats were + * reset, the hit rate is defined to be 0.0. + * + * The hit rate stats can be reset either manually (via H5Freset_mdc_hit_rate_stats()), or + * automatically. If the cache's adaptive resize code is enabled, the hit rate stats will be + * reset once per epoch. If they are reset manually as well, the cache may behave oddly. + * + * See the overview of the metadata cache in the special topics section of the user manual for + * details on the metadata cache and its adaptive resize algorithms. + * + */ +H5_DLL herr_t H5Fget_mdc_hit_rate(hid_t file_id, double *hit_rate_ptr); +/** + * \ingroup MDC + * + * \brief Obtains current metadata cache size data for specified file + * + * \file_id + * \param[out] max_size_ptr Pointer to the location in which the current cache maximum size is to be + * returned, or NULL if this datum is not desired + * \param[out] min_clean_size_ptr Pointer to the location in which the current cache minimum clean + * size is to be returned, or NULL if that datum is not desired + * \param[out] cur_size_ptr Pointer to the location in which the current cache size is to be returned, + * or NULL if that datum is not desired + * \param[out] cur_num_entries_ptr Pointer to the location in which the current number of entries in + * the cache is to be returned, or NULL if that datum is not desired + * \returns \herr_t + * + * \details H5Fget_mdc_size() queries the metadata cache of the target file for the desired size + * information, and returns this information in the locations indicated by the pointer + * parameters. If any pointer parameter is NULL, the associated data is not returned. + * + * If the API call fails, the values returned via the pointer parameters are undefined. + * + * If adaptive cache resizing is enabled, the cache maximum size and minimum clean size + * may change at the end of each epoch. Current size and current number of entries can + * change on each cache access. + * + * Current size can exceed maximum size under certain conditions. See the overview of the + * metadata cache in the special topics section of the user manual for a discussion of this. + * + */ +H5_DLL herr_t H5Fget_mdc_size(hid_t file_id, size_t *max_size_ptr, size_t *min_clean_size_ptr, + size_t *cur_size_ptr, int *cur_num_entries_ptr); +/** + * \ingroup MDC + * + * \brief Resets hit rate statistics counters for the target file + * + * \file_id + * \returns \herr_t + * + * \details + * \parblock + * H5Freset_mdc_hit_rate_stats() resets the hit rate statistics counters in the metadata cache + * associated with the specified file. + * + * If the adaptive cache resizing code is enabled, the hit rate statistics are reset at the beginning + * of each epoch. This API call allows you to do the same thing from your program. + * + * The adaptive cache resizing code may behave oddly if you use this call when adaptive cache resizing + * is enabled. However, the call should be useful if you choose to control metadata cache size from your + * program. + * + * See \ref_mdc_in_hdf5 for details about the metadata cache and the adaptive cache resizing + * algorithms. If you have not read, understood, and thought about the material covered in that + * documentation, + * you should not be using this API call. + * \endparblock + * + */ +H5_DLL herr_t H5Freset_mdc_hit_rate_stats(hid_t file_id); +/** + * \ingroup H5F + * + * \brief Retrieves name of file to which object belongs + * + * \obj_id + * \param[out] name Buffer for the file name + * \param[in] size Size, in bytes, of the \p name buffer + * + * \return Returns the length of the file name if successful; otherwise returns + * a negative value. + * + * \details H5Fget_name() retrieves the name of the file to which the object \p + * obj_id belongs. The object can be a file, group, dataset, + * attribute, or named datatype. + * + * Up to \p size characters of the file name are returned in \p name; + * additional characters, if any, are not returned to the user + * application. + * + * If the length of the name, which determines the required value of + * size, is unknown, a preliminary H5Fget_name() call can be made by + * setting \p name to NULL. The return value of this call will be the + * size of the file name; that value plus one (1) can then be assigned + * to size for a second H5Fget_name() call, which will retrieve the + * actual name. (The value passed in with the parameter \p size must + * be one greater than size in bytes of the actual name in order to + * accommodate the null terminator; if \p size is set to the exact + * size of the name, the last byte passed back will contain the null + * terminator and the last character will be missing from the name + * passed back to the calling application.) + * + * If an error occurs, the buffer pointed to by \p name is unchanged + * and the function returns a negative value. + * + * \since 1.6.3 + * + */ +H5_DLL ssize_t H5Fget_name(hid_t obj_id, char *name, size_t size); +/** + * \ingroup H5F + * + * \brief Retrieves name of file to which object belongs + * + * \fgdta_obj_id + * \param[out] file_info Buffer for global file information + * + * \return \herr_t + * + * \details H5Fget_info2() returns global information for the file associated + * with the object identifier \p obj_id in the H5F_info2_t \c struct + * named \p file_info. + * + * \p obj_id is an identifier for any object in the file of interest. + * + * H5F_info2_t struct is defined in H5Fpublic.h as follows: + * \snippet this H5F_info2_t_snip + * + * The \c super sub-struct contains the following information: + * \li \c vers is the version number of the superblock. + * \li \c super_size is the size of the superblock. + * \li \c super_ext_size is the size of the superblock extension. + * + * The \c free sub-struct contains the following information: + * \li vers is the version number of the free-space manager. + * \li \c hdr_size is the size of the free-space manager header. + * \li \c tot_space is the total amount of free space in the file. + * + * The \c sohm sub-struct contains shared object header message + * information as follows: + * \li \c vers is the version number of the shared object header information. + * \li \c hdr_size is the size of the shared object header message. + * \li \c msgs_info is an H5_ih_info_t struct defined in H5public.h as + * follows: \snippet H5public.h H5_ih_info_t_snip + * \li \p index_size is the summed size of all the shared object + * header indexes. Each index might be either a B-tree or + * a list. + * \li \p heap_size is the size of the heap. + * + * + * \since 1.10.0 + * + */ +H5_DLL herr_t H5Fget_info2(hid_t obj_id, H5F_info2_t *file_info); +/** + * \ingroup SWMR + * + * \brief Retrieves the collection of read retries for metadata entries with checksum + * + * \file_id + * \param[out] info Struct containing the collection of read retries for metadata + * entries with checksum + * \return \herr_t\n + * + * \details \Bold{Failure Modes:} + * \li When the input identifier is not a file identifier. + * \li When the pointer to the output structure is NULL. + * \li When the memory allocation for \p retries failed. + * + * \details H5Fget_metadata_read_retry_info() retrieves information regarding the number + * of read retries for metadata entries with checksum for the file \p file_id. + * This information is reported in the H5F_retry_info_t struct defined in + * H5Fpublic.h as follows: + * \snippet this H5F_retry_info_t_snip + * \c nbins is the number of bins for each \c retries[i] of metadata entry \c i. + * It is calculated based on the current number of read attempts used in the + * library and logarithmic base 10. + * + * If read retries are incurred for a metadata entry \c i, the library will + * allocate memory for \Code{retries[i] (nbins * sizeof(uint32_t)} and store + * the collection of retries there. If there are no retries for a metadata entry + * \c i, \Code{retries[i]} will be NULL. After a call to this routine, users should + * free each \Code{retries[i]} that is non-NULL, otherwise resource leak will occur. + * + * For the library default read attempts of 100 for SWMR access, nbins will be 2 + * as depicted below: + * \li \Code{retries[i][0]} is the number of 1 to 9 read retries. + * \li \Code{retries[i][1]} is the number of 10 to 99 read retries. + * For the library default read attempts of 1 for non-SWMR access, \c nbins will + * be 0 and each \Code{retries[i]} will be NULL. + * + * The following table lists the 21 metadata entries of \Code{retries[]}: + * <table> + * <tr> + * <th>Index for \Code{retries[]}</th> + * <th>Metadata entries<sup>*</sup></th> + * </tr> + * <tr><td>0</td><td>Object header (version 2)</td></tr> + * <tr><td>1</td><td>Object header chunk (version 2)</td></tr> + * <tr><td>2</td><td>B-tree header (version 2)</td></tr> + * <tr><td>3</td><td>B-tree internal node (version 2)</td></tr> + * <tr><td>4</td><td>B-tree leaf node (version 2)</td></tr> + * <tr><td>5</td><td>Fractal heap header</td></tr> + * <tr><td>6</td><td>Fractal heap direct block (optional checksum)</td></tr> + * <tr><td>7</td><td>Fractal heap indirect block</td></tr> + * <tr><td>8</td><td>Free-space header</td></tr> + * <tr><td>9</td><td>Free-space sections</td></tr> + * <tr><td>10</td><td>Shared object header message table</td></tr> + * <tr><td>11</td><td>Shared message record list</td></tr> + * <tr><td>12</td><td>Extensive array header</td></tr> + * <tr><td>13</td><td>Extensive array index block</td></tr> + * <tr><td>14</td><td>Extensive array super block</td></tr> + * <tr><td>15</td><td>Extensive array data block</td></tr> + * <tr><td>16</td><td>Extensive array data block page</td></tr> + * <tr><td>17</td><td>Fixed array super block</td></tr> + * <tr><td>18</td><td>Fixed array data block</td></tr> + * <tr><td>19</td><td>Fixed array data block page</td></tr> + * <tr><td>20</td><td>File's superblock (version 2)</td></tr> + * <tr><td colspan=2><sup>*</sup> All entries are of version 0 (zero) unless indicated + * otherwise.</td></tr> + * </table> + * + * \note On a system that is not atomic, the library might possibly read inconsistent + * metadata with checksum when performing single-writer/multiple-reader (SWMR) + * operations for an HDF5 file. Upon encountering such situations, the library + * will try reading the metadata again for a set number of times to attempt to + * obtain consistent data. The maximum number of read attempts used by the library + * will be either the value set via H5Pset_metadata_read_attempts() or the library + * default value when a value is not set.\n + * When the current number of metadata read attempts used in the library is unable + * to remedy the reading of inconsistent metadata on a system, the user can assess + * the information obtained via this routine to derive a different maximum value. + * The information can also be helpful for debugging purposes to identify potential + * issues with metadata flush dependencies and SWMR implementation in general. + * + * \since 1.10.0 + * + */ +H5_DLL herr_t H5Fget_metadata_read_retry_info(hid_t file_id, H5F_retry_info_t *info); +/** + * \ingroup SWMR + * + * \brief Retrieves free-space section information for a file + * + * \file_id + * + * \return \herr_t + * + * \details H5Fstart_swmr_write() will activate SWMR writing mode for a file + * associated with \p file_id. This routine will prepare and ensure + * the file is safe for SWMR writing as follows: + * \li Check that the file is opened with write access (#H5F_ACC_RDWR). + * \li Check that the file is opened with the latest library format to + * ensure data structures with check-summed metadata are used. + * \li Check that the file is not already marked in SWMR writing mode. + * \li Enable reading retries for check-summed metadata to remedy + * possible checksum failures from reading inconsistent metadata + * on a system that is not atomic. + * \li Turn off usage of the library's accumulator to avoid possible + * ordering problem on a system that is not atomic. + * \li Perform a flush of the file’s data buffers and metadata to set + * a consistent state for starting SWMR write operations. + * + * Library objects are groups, datasets, and committed datatypes. For + * the current implementation, groups and datasets can remain open when + * activating SWMR writing mode, but not committed datatypes. Attributes + * attached to objects cannot remain open either. + * + * \since 1.10.0 + * + */ +H5_DLL herr_t H5Fstart_swmr_write(hid_t file_id); +/** + * \ingroup H5F + * + * \brief Retrieves free-space section information for a file + * + * \file_id + * \param[in] type The file memory allocation type + * \param[in] nsects The number of free-space sections + * \param[out] sect_info Array of instances of H5F_sect_info_t in which + * the free-space section information is to be returned + * + * \return Returns the number of free-space sections for the specified + * free-space manager in the file; otherwise returns a negative value. + * + * \details H5Fget_free_sections() retrieves free-space section information for + * the free-space manager with type that is associated with file + * \p file_id. If type is #H5FD_MEM_DEFAULT, this routine retrieves + * free-space section information for all the free-space managers in + * the file. + * + * Valid values for \p type are the following: + * \mem_types + * + * H5F_sect_info_t is defined as follows (in H5Fpublic.h): + * \snippet this H5F_sect_info_t_snip + * + * This routine retrieves free-space section information for \p nsects + * sections or at most the maximum number of sections in the specified + * free-space manager. If the number of sections is not known, a + * preliminary H5Fget_free_sections() call can be made by setting \p + * sect_info to NULL and the total number of free-space sections for + * the specified free-space manager will be returned. Users can then + * allocate space for entries in \p sect_info, each of which is + * defined as an H5F_sect_info_t \c struct. + * + * \attention \Bold{Failure Modes:} This routine will fail when the following + * is true: + * \li The library fails to retrieve the file creation property list + * associated with \p file_id. + * \li If the parameter \p sect_info is non-null, but the parameter + * \p nsects is equal to 0. + * \li The library fails to retrieve free-space section information + * for the file. + * + * \since 1.10.0 + * + */ +H5_DLL ssize_t H5Fget_free_sections(hid_t file_id, H5F_mem_t type, size_t nsects, + H5F_sect_info_t *sect_info /*out*/); +/** + * \ingroup H5F + * + * \brief Clears the external link open file cache + * + * \file_id + * \return \herr_t + * + * \details H5Fclear_elink_file_cache() evicts all the cached child files in + * the specified file’s external file cache, causing them to be closed + * if there is nothing else holding them open. + * + * H5Fclear_elink_file_cache() does not close the cache itself; + * subsequent external link traversals from the parent file will again + * cache the target file. See H5Pset_elink_file_cache_size() for + * information on closing the file cache. + * + * \see H5Pset_elink_file_cache_size(), H5Pget_elink_file_cache_size() + * + * \since 1.8.7 + * + */ +H5_DLL herr_t H5Fclear_elink_file_cache(hid_t file_id); +/** + * \ingroup H5F + * + * \brief Enables the switch of version bounds setting for a file + * + * \file_id + * \param[in] low The earliest version of the library that will be used for + * writing objects + * \param[in] high The latest version of the library that will be used for + * writing objects + * + * \return \herr_t + * + * \details H5Fset_libver_bounds() enables the switch of version bounds setting + * for an open file associated with \p file_id. + * + * For the parameters \p low and \p high, see the description for + * H5Pset_libver_bounds(). + * + * \par Example + * \snippet H5F_examples.c libver_bounds + * + * \since 1.10.2 + * + */ +H5_DLL herr_t H5Fset_libver_bounds(hid_t file_id, H5F_libver_t low, H5F_libver_t high); +/** + * \ingroup MDC + * + * \brief Starts logging metadata cache events if logging was previously enabled + * + * \file_id + * + * \return \herr_t + * + * \details The metadata cache is a central part of the HDF5 library through + * which all \Emph{file metadata} reads and writes take place. File + * metadata is normally invisible to the user and is used by the + * library for purposes such as locating and indexing data. File + * metadata should not be confused with user metadata, which consists + * of attributes created by users and attached to HDF5 objects such + * as datasets via H5A API calls. + * + * Due to the complexity of the cache, a trace/logging feature has been + * created that can be used by HDF5 developers for debugging and performance + * analysis. The functions that control this functionality will normally be + * of use to a very limited number of developers outside of The HDF Group. + * The functions have been documented to help users create logs that can + * be sent with bug reports. + * + * Control of the log functionality is straightforward. Logging is enabled + * via the H5Pset_mdc_log_options() function, which will modify the file + * access property list used to open or create a file. This function has + * a flag that determines whether logging begins at file open or starts + * in a paused state. Log messages can then be controlled via the + * H5Fstart_mdc_logging() and H5Fstop_mdc_logging() functions. + * H5Pget_mdc_log_options() can be used to examine a file access property + * list, and H5Fget_mdc_logging_status() will return the current state of + * the logging flags. + * + * The log format is described in the \ref_mdc_logging document. + * + * \note Logging can only be started or stopped if metadata cache logging was enabled + * via H5Pset_mdc_log_options().\n + * When enabled and currently logging, the overhead of the logging feature will + * almost certainly be significant.\n + * The log file is opened when the HDF5 file is opened or created and not when + * this function is called for the first time.\n + * This function opens the log file and starts logging metadata cache operations + * for a particular file. Calling this function when logging has already been + * enabled will be considered an error. + * + * \since 1.10.0 + * + */ +H5_DLL herr_t H5Fstart_mdc_logging(hid_t file_id); +/** + * \ingroup MDC + * + * \brief Stops logging metadata cache events if logging was previously enabled and is currently ongoing + * + * \file_id + * + * \return \herr_t + * + * \details The metadata cache is a central part of the HDF5 library through + * which all \Emph{file metadata} reads and writes take place. File + * metadata is normally invisible to the user and is used by the + * library for purposes such as locating and indexing data. File + * metadata should not be confused with user metadata, which consists + * of attributes created by users and attached to HDF5 objects such + * as datasets via H5A API calls. + * + * Due to the complexity of the cache, a trace/logging feature has been + * created that can be used by HDF5 developers for debugging and performance + * analysis. The functions that control this functionality will normally be + * of use to a very limited number of developers outside of The HDF Group. + * The functions have been documented to help users create logs that can + * be sent with bug reports. + * + * Control of the log functionality is straightforward. Logging is enabled + * via the H5Pset_mdc_log_options() function, which will modify the file + * access property list used to open or create a file. This function has + * a flag that determines whether logging begins at file open or starts + * in a paused state. Log messages can then be controlled via the + * H5Fstart_mdc_logging() and H5Fstop_mdc_logging() functions. + * H5Pget_mdc_log_options() can be used to examine a file access property + * list, and H5Fget_mdc_logging_status() will return the current state of + * the logging flags. + * + * The log format is described in the \ref_mdc_logging document. + * + * \note Logging can only be started or stopped if metadata cache logging was enabled + * via H5Pset_mdc_log_options().\n + * This function only suspends the logging operations. The log file will remain + * open and will not be closed until the HDF5 file is closed. + * + * \since 1.10.0 + * + */ +H5_DLL herr_t H5Fstop_mdc_logging(hid_t file_id); +/** + * \ingroup MDC + * + * \brief Gets the current metadata cache logging status + * + * \file_id + * \param[out] is_enabled Whether logging is enabled + * \param[out] is_currently_logging Whether events are currently being logged + * \return \herr_t + * + * \details The metadata cache is a central part of the HDF5 library through + * which all \Emph{file metadata} reads and writes take place. File + * metadata is normally invisible to the user and is used by the + * library for purposes such as locating and indexing data. File + * metadata should not be confused with user metadata, which consists + * of attributes created by users and attached to HDF5 objects such + * as datasets via H5A API calls. + * + * Due to the complexity of the cache, a trace/logging feature has been + * created that can be used by HDF5 developers for debugging and performance + * analysis. The functions that control this functionality will normally be + * of use to a very limited number of developers outside of The HDF Group. + * The functions have been documented to help users create logs that can + * be sent with bug reports. + * + * Control of the log functionality is straightforward. Logging is enabled + * via the H5Pset_mdc_log_options() function, which will modify the file + * access property list used to open or create a file. This function has + * a flag that determines whether logging begins at file open or starts + * in a paused state. Log messages can then be controlled via the + * H5Fstart_mdc_logging() and H5Fstop_mdc_logging() functions. + * H5Pget_mdc_log_options() can be used to examine a file access property + * list, and H5Fget_mdc_logging_status() will return the current state of + * the logging flags. + * + * The log format is described in the \ref_mdc_logging document. + * + * \note Unlike H5Fstart_mdc_logging() and H5Fstop_mdc_logging(), this function can + * be called on any open file identifier. + * + * \since 1.10.0 + */ +H5_DLL herr_t H5Fget_mdc_logging_status(hid_t file_id, hbool_t *is_enabled, hbool_t *is_currently_logging); +/** + * \ingroup SWMR + * + * \todo UFO? + */ +H5_DLL herr_t H5Fformat_convert(hid_t fid); +/** + * \ingroup H5F + * + * \brief Resets the page buffer statistics + * + * \file_id + * + * \return \herr_t + * + * \details H5Freset_page_buffering_stats() resets the page buffer statistics + * for a specified file identifier \p file_id. + * + * \since 1.10.1 + * + */ +H5_DLL herr_t H5Freset_page_buffering_stats(hid_t file_id); +/** + * \ingroup H5F + * + * \brief Retrieves statistics about page access when it is enabled + * + * \file_id + * \param[out] accesses Two integer array for the number of metadata and raw + * data accesses to the page buffer + * \param[out] hits Two integer array for the number of metadata and raw data + * hits in the page buffer + * \param[out] misses Two integer array for the number of metadata and raw data + * misses in the page buffer + * \param[out] evictions Two integer array for the number of metadata and raw + * data evictions from the page buffer + * \param[out] bypasses Two integer array for the number of metadata and raw + * data accesses that bypass the page buffer + * + * \return \herr_t + * + * \details H5Fget_page_buffering_stats() retrieves page buffering statistics + * such as the number of metadata and raw data accesses (\p accesses), + * hits (\p hits), misses (\p misses), evictions (\p evictions), and + * accesses that bypass the page buffer (\p bypasses). + * + * \since 1.10.1 + * + */ +H5_DLL herr_t H5Fget_page_buffering_stats(hid_t file_id, unsigned accesses[2], unsigned hits[2], + unsigned misses[2], unsigned evictions[2], unsigned bypasses[2]); +/** + * \ingroup MDC + * + * \brief Obtains information about a cache image if it exists + * + * \file_id + * \param[out] image_addr Offset of the cache image if it exists, or \c HADDR_UNDEF if it does not + * \param[out] image_size Length of the cache image if it exists, or 0 if it does not + * \returns \herr_t + * + * \details + * \parblock + * H5Fget_mdc_image_info() returns information about a cache image if it exists. + * + * When an HDF5 file is opened in Read/Write mode, any metadata cache image will + * be read and deleted from the file on the first metadata cache access (or, if + * persistent free space managers are enabled, on the first file space + * allocation / deallocation, or read of free space manager status, whichever + * comes first). + * + * Thus, if the file is opened Read/Write, H5Fget_mdc_image_info() should be called + * immediately after file open and before any other operation. If H5Fget_mdc_image_info() + * is called after the cache image is loaded, it will correctly report that no cache image + * exists, as the image will have already been read and deleted from the file. In the Read Only + * case, the function may be called at any time, as any cache image will not be deleted + * from the file. + * \endparblock + * + * \since 1.10.1 + */ +H5_DLL herr_t H5Fget_mdc_image_info(hid_t file_id, haddr_t *image_addr, hsize_t *image_size); +/** + * \ingroup H5F + * + * \brief Retrieves the setting for whether or not a file will create minimized + * dataset object headers + * + * \file_id + * \param[out] minimize Flag indicating whether the library will or will not + * create minimized dataset object headers + * + * \return \herr_t + * + * \details H5Fget_dset_no_attrs_hint() retrieves the no dataset attributes + * hint setting for the file specified by the file identifier \p + * file_id. This setting is used to inform the library to create + * minimized dataset object headers when \c TRUE. + * + * The setting's value is returned in the boolean pointer minimize. + * + * \since 1.10.5 + * + */ +H5_DLL herr_t H5Fget_dset_no_attrs_hint(hid_t file_id, hbool_t *minimize); +/** + * \ingroup H5F + * + * \brief Sets the flag to create minimized dataset object headers + * + * \file_id + * \param[in] minimize Flag indicating whether the library will or will not + * create minimized dataset object headers + * + * \return \herr_t + * + * \details H5Fset_dset_no_attrs_hint() sets the no dataset attributes hint + * setting for the file specified by the file identifier \p file_id. + * If the boolean flag \p minimize is set to \c TRUE, then the library + * will create minimized dataset object headers in the file. + * \Bold{All} files that refer to the same file-on-disk will be + * affected by the most recent setting, regardless of the file + * identifier/handle (e.g., as returned by H5Fopen()). By setting the + * \p minimize flag to \c TRUE, the library expects that no attributes + * will be added to the dataset - attributes can be added, but they + * are appended with a continuation message, which can reduce + * performance. + * + * \attention This setting interacts with H5Pset_dset_no_attrs_hint(): if + * either is set to \c TRUE, then the created dataset's object header + * will be minimized. + * + * \since 1.10.5 + * + */ +H5_DLL herr_t H5Fset_dset_no_attrs_hint(hid_t file_id, hbool_t minimize); +H5_DLL herr_t H5Fwait(hid_t file_id); /* VFD SWMR */ +/** + * \todo Add missing documentation + */ H5_DLL herr_t H5Fvfd_swmr_end_tick(hid_t file_id); +/** + * \todo Add missing documentation + */ H5_DLL herr_t H5Fvfd_swmr_disable_end_of_tick(hid_t file_id); +/** + * \todo Add missing documentation + */ H5_DLL herr_t H5Fvfd_swmr_enable_end_of_tick(hid_t file_id); -H5_DLL bool vfd_swmr_writer_may_increase_tick_to(uint64_t, bool); -H5_DLL void vfd_swmr_reader_did_increase_tick_to(uint64_t); +/** + * \todo Add missing documentation + */ +H5_DLL bool vfd_swmr_writer_may_increase_tick_to(uint64_t, bool); +/** + * \todo Add missing documentation + */ +H5_DLL void vfd_swmr_reader_did_increase_tick_to(uint64_t); #ifdef H5_HAVE_PARALLEL +/** + * \ingroup PH5F + * + * \brief Sets the MPI atomicity mode + * + * \file_id + * \param[in] flag Logical flag for atomicity setting. Valid values are: + * \li \c 1 -- Sets MPI file access to atomic mode. + * \li \c 0 -- Sets MPI file access to nonatomic mode. + * \returns \herr_t + * + * \par Motivation + * H5Fset_mpi_atomicity() is applicable only in parallel environments using MPI I/O. + * The function is one of the tools used to ensure sequential consistency. This means + * that a set of operations will behave as though they were performed in a serial + * order consistent with the program order. + * + * \details + * \parblock + * H5Fset_mpi_atomicity() sets MPI consistency semantics for data access to the file, + * \p file_id. + * + * If \p flag is set to \c 1, all file access operations will appear atomic, guaranteeing + * sequential consistency. If \p flag is set to \c 0, enforcement of atomic file access + * will be turned off. + * + * H5Fset_mpi_atomicity() is a collective function and all participating processes must + * pass the same values for \p file_id and \p flag. + * + * This function is available only when the HDF5 library is configured with parallel support + * (\Code{--enable-parallel}). It is useful only when used with the #H5FD_MPIO driver + * (see H5Pset_fapl_mpio()). + * \endparblock + * + * \attention + * \parblock + * H5Fset_mpi_atomicity() calls \Code{MPI_File_set_atomicity} underneath and is not supported + * if the execution platform does not support \Code{MPI_File_set_atomicity}. When it is + * supported and used, the performance of data access operations may drop significantly. + * + * In certain scenarios, even when \Code{MPI_File_set_atomicity} is supported, setting + * atomicity with H5Fset_mpi_atomicity() and \p flag set to 1 does not always yield + * strictly atomic updates. For example, some H5Dwrite() calls translate to multiple + * \Code{MPI_File_write_at} calls. This happens in all cases where the high-level file + * access routine translates to multiple lower level file access routines. + * The following scenarios will raise this issue: + * \li Non-contiguous file access using independent I/O + * \li Partial collective I/O using chunked access + * \li Collective I/O using filters or when data conversion is required + * + * This issue arises because MPI atomicity is a matter of MPI file access operations rather + * than HDF5 access operations. But the user is normally seeking atomicity at the HDF5 level. + * To accomplish this, the application must set a barrier after a write, H5Dwrite(), but before + * the next read, H5Dread(), in addition to calling H5Fset_mpi_atomicity().The barrier will + * guarantee that all underlying write operations execute atomically before the read + * operations starts. This ensures additional ordering semantics and will normally produce + * the desired behavior. + * \endparblock + * + * \see \ref_cons_semantics + * + * \since 1.8.9 + * + */ H5_DLL herr_t H5Fset_mpi_atomicity(hid_t file_id, hbool_t flag); +/** + * \ingroup PH5F + * + * \brief Retrieves the atomicity mode in use + * + * \file_id + * \param[out] flag Logical flag for atomicity setting. Valid values are: + * \li 1 -- MPI file access is set to atomic mode. + * \li 0 -- MPI file access is set to nonatomic mode. + * \returns \herr_t + * + * \details H5Fget_mpi_atomicity() retrieves the current consistency semantics mode for + * data access for the file \p file_id. + * + * Upon successful return, \p flag will be set to \c 1 if file access is set + * to atomic mode and \c 0 if file access is set to nonatomic mode. + * + * \see \ref_cons_semantics + * + * \since 1.8.9 + * + */ H5_DLL herr_t H5Fget_mpi_atomicity(hid_t file_id, hbool_t *flag); #endif /* H5_HAVE_PARALLEL */ +/* API Wrappers for async routines */ +/* (Must be defined _after_ the function prototype) */ +/* (And must only defined when included in application code, not the library) */ +#ifndef H5F_MODULE +#define H5Fcreate_async(...) H5Fcreate_async(__FILE__, __func__, __LINE__, __VA_ARGS__) +#define H5Fopen_async(...) H5Fopen_async(__FILE__, __func__, __LINE__, __VA_ARGS__) +#define H5Freopen_async(...) H5Freopen_async(__FILE__, __func__, __LINE__, __VA_ARGS__) +#define H5Fflush_async(...) H5Fflush_async(__FILE__, __func__, __LINE__, __VA_ARGS__) +#define H5Fclose_async(...) H5Fclose_async(__FILE__, __func__, __LINE__, __VA_ARGS__) + +/* Define "wrapper" versions of function calls, to allow compile-time values to + * be passed in by language wrapper or library layer on top of HDF5. + */ +#define H5Fcreate_async_wrap H5_NO_EXPAND(H5Fcreate_async) +#define H5Fopen_async_wrap H5_NO_EXPAND(H5Fopen_async) +#define H5Freopen_async_wrap H5_NO_EXPAND(H5Freopen_async) +#define H5Fflush_async_wrap H5_NO_EXPAND(H5Fflush_async) +#define H5Fclose_async_wrap H5_NO_EXPAND(H5Fclose_async) +#endif /* H5F_MODULE */ + /* Symbols defined for compatibility with previous versions of the HDF5 API. * * Use of these symbols is deprecated. @@ -385,23 +1915,99 @@ H5_DLL herr_t H5Fget_mpi_atomicity(hid_t file_id, hbool_t *flag); #ifndef H5_NO_DEPRECATED_SYMBOLS /* Macros */ -#define H5F_ACC_DEBUG (H5CHECK H5OPEN 0x0000u) /*print debug info (deprecated)*/ +#define H5F_ACC_DEBUG (H5CHECK H5OPEN 0x0000u) /**< Print debug info \deprecated In which version? */ /* Typedefs */ -/* Current "global" information about file */ +/** + * Current "global" information about file + */ +//! <!-- [H5F_info1_t_snip] --> typedef struct H5F_info1_t { - hsize_t super_ext_size; /* Superblock extension size */ + hsize_t super_ext_size; /**< Superblock extension size */ struct { - hsize_t hdr_size; /* Shared object header message header size */ - H5_ih_info_t msgs_info; /* Shared object header message index & heap size */ + hsize_t hdr_size; /**< Shared object header message header size */ + H5_ih_info_t msgs_info; /**< Shared object header message index & heap size */ } sohm; } H5F_info1_t; +//! <!-- [H5F_info1_t_snip] --> /* Function prototypes */ -H5_DLL herr_t H5Fget_info1(hid_t obj_id, H5F_info1_t *finfo); +/** + * \ingroup H5F + * + * \brief Retrieves name of file to which object belongs + * + * \fgdta_obj_id + * \param[out] file_info Buffer for global file information + * + * \return \herr_t + * + * \deprecated This function has been renamed from H5Fget_info() and is + * deprecated in favor of the macro #H5Fget_info or the function + * H5Fget_info2(). + * + * \details H5Fget_info1() returns global information for the file associated + * with the object identifier \p obj_id in the H5F_info1_t \c struct + * named \p file_info. + * + * \p obj_id is an identifier for any object in the file of interest. + * + * H5F_info1_t struct is defined in H5Fpublic.h as follows: + * \snippet this H5F_info1_t_snip + * + * \c super_ext_size is the size of the superblock extension. + * + * The \c sohm sub-struct contains shared object header message + * information as follows: + * \li \c hdr_size is the size of the shared object header message. + * \li \c msgs_info is an H5_ih_info_t struct defined in H5public.h as + * follows: \snippet H5public.h H5_ih_info_t_snip + * + * \li \p index_size is the summed size of all the shared object + * header indexes. Each index might be either a B-tree or + * a list. + * + * \version 1.10.0 Function H5Fget_info() renamed to H5Fget_info1() and + * deprecated in this release. + * + * \since 1.8.0 + * + */ +H5_DLL herr_t H5Fget_info1(hid_t obj_id, H5F_info1_t *file_info); +/** + * \ingroup H5F + * + * \brief Sets thelatest version of the library to be used for writing objects + * + * \file_id + * \param[in] latest_format Latest format flag + * + * \return \herr_t + * + * \deprecated When? + * + * \todo In which version was this function deprecated? + * + */ H5_DLL herr_t H5Fset_latest_format(hid_t file_id, hbool_t latest_format); -H5_DLL htri_t H5Fis_hdf5(const char *filename); +/** + * \ingroup H5F + * + * \brief Determines whether a file is in the HDF5 format + * + * \param[in] file_name File name + * + * \return \htri_t + * + * \deprecated When? + * + * \details H5Fis_hdf5() determines whether a file is in the HDF5 format. + * + * \todo In which version was this function deprecated? + * + */ +H5_DLL htri_t H5Fis_hdf5(const char *file_name); #endif /* H5_NO_DEPRECATED_SYMBOLS */ @@ -83,6 +83,7 @@ #include "H5private.h" /* Generic Functions */ #include "H5CXprivate.h" /* API Contexts */ #include "H5Eprivate.h" /* Error handling */ +#include "H5ESprivate.h" /* Event Sets */ #include "H5Gpkg.h" /* Groups */ #include "H5Iprivate.h" /* IDs */ #include "H5Pprivate.h" /* Property lists */ @@ -104,16 +105,24 @@ /* Local Prototypes */ /********************/ -/* Group close callback */ -static herr_t H5G__close_cb(H5VL_object_t *grp_vol_obj); +/* Helper routines for sync/async API calls */ +static hid_t H5G__create_api_common(hid_t loc_id, const char *name, hid_t lcpl_id, hid_t gcpl_id, + hid_t gapl_id, void **token_ptr, H5VL_object_t **_vol_obj_ptr); +static hid_t H5G__open_api_common(hid_t loc_id, const char *name, hid_t gapl_id, void **token_ptr, + H5VL_object_t **_vol_obj_ptr); +static herr_t H5G__get_info_api_common(hid_t loc_id, H5G_info_t *group_info /*out*/, void **token_ptr, + H5VL_object_t **_vol_obj_ptr); +static herr_t H5G__get_info_by_name_api_common(hid_t loc_id, const char *name, H5G_info_t *group_info /*out*/, + hid_t lapl_id, void **token_ptr, H5VL_object_t **_vol_obj_ptr); +static herr_t H5G__get_info_by_idx_api_common(hid_t loc_id, const char *group_name, H5_index_t idx_type, + H5_iter_order_t order, hsize_t n, + H5G_info_t *group_info /*out*/, hid_t lapl_id, void **token_ptr, + H5VL_object_t **_vol_obj_ptr); /*********************/ /* Package Variables */ /*********************/ -/* Package initialization variable */ -hbool_t H5_PKG_INIT_VAR = FALSE; - /*****************************/ /* Library Private Variables */ /*****************************/ @@ -122,181 +131,70 @@ hbool_t H5_PKG_INIT_VAR = FALSE; /* Local Variables */ /*******************/ -/* Group ID class */ -static const H5I_class_t H5I_GROUP_CLS[1] = {{ - H5I_GROUP, /* ID class value */ - 0, /* Class flags */ - 0, /* # of reserved IDs for class */ - (H5I_free_t)H5G__close_cb /* Callback routine for closing objects of this class */ -}}; - -/* Flag indicating "top" of interface has been initialized */ -static hbool_t H5G_top_package_initialize_s = FALSE; - -/*------------------------------------------------------------------------- - * Function: H5G_init - * - * Purpose: Initialize the interface from some other layer. - * - * Return: Success: non-negative - * - * Failure: negative - *------------------------------------------------------------------------- - */ -herr_t -H5G_init(void) -{ - herr_t ret_value = SUCCEED; /* Return value */ - - FUNC_ENTER_NOAPI(FAIL) - /* FUNC_ENTER() does all the work */ - -done: - FUNC_LEAVE_NOAPI(ret_value) -} /* end H5G_init() */ - /*------------------------------------------------------------------------- - * Function: H5G__init_package - * - * Purpose: Initializes the H5G interface. + * Function: H5G__create_api_common * - * Return: Non-negative on success/Negative on failure + * Purpose: This is the common function for creating HDF5 groups. * - * Programmer: Robb Matzke - * Monday, January 5, 1998 - * - * Notes: The group creation properties are registered in the property - * list interface initialization routine (H5P_init_package) - * so that the file creation property class can inherit from it - * correctly. (Which allows the file creation property list to - * control the group creation properties of the root group of - * a file) QAK - 24/10/2005 - * - *------------------------------------------------------------------------- - */ -herr_t -H5G__init_package(void) -{ - herr_t ret_value = SUCCEED; /* Return value */ - - FUNC_ENTER_PACKAGE - - /* Initialize the atom group for the group IDs */ - if (H5I_register_type(H5I_GROUP_CLS) < 0) - HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to initialize interface") - - /* Mark "top" of interface as initialized, too */ - H5G_top_package_initialize_s = TRUE; - -done: - FUNC_LEAVE_NOAPI(ret_value) -} /* end H5G__init_package() */ - -/*------------------------------------------------------------------------- - * Function: H5G_top_term_package - * - * Purpose: Close the "top" of the interface, releasing IDs, etc. - * - * Return: Success: Positive if anything is done that might - * affect other interfaces; zero otherwise. - * Failure: Negative. - * - * Programmer: Quincey Koziol - * Sunday, September 13, 2015 - * - *------------------------------------------------------------------------- - */ -int -H5G_top_term_package(void) -{ - int n = 0; - - FUNC_ENTER_NOAPI_NOINIT_NOERR - - if (H5G_top_package_initialize_s) { - if (H5I_nmembers(H5I_GROUP) > 0) { - (void)H5I_clear_type(H5I_GROUP, FALSE, FALSE); - n++; /*H5I*/ - } /* end if */ - - /* Mark closed */ - if (0 == n) - H5G_top_package_initialize_s = FALSE; - } /* end if */ - - FUNC_LEAVE_NOAPI(n) -} /* end H5G_top_term_package() */ - -/*------------------------------------------------------------------------- - * Function: H5G_term_package - * - * Purpose: Terminates the H5G interface - * - * Note: Finishes shutting down the interface, after - * H5G_top_term_package() is called - * - * Return: Success: Positive if anything is done that might - * affect other interfaces; zero otherwise. - * Failure: Negative. - * - * Programmer: Robb Matzke - * Monday, January 5, 1998 + * Return: Success: A group ID + * Failure: H5I_INVALID_HID * *------------------------------------------------------------------------- */ -int -H5G_term_package(void) +static hid_t +H5G__create_api_common(hid_t loc_id, const char *name, hid_t lcpl_id, hid_t gcpl_id, hid_t gapl_id, + void **token_ptr, H5VL_object_t **_vol_obj_ptr) { - int n = 0; - - FUNC_ENTER_NOAPI_NOINIT_NOERR + void * grp = NULL; /* Structure for new group */ + H5VL_object_t * tmp_vol_obj = NULL; /* Object for loc_id */ + H5VL_object_t **vol_obj_ptr = + (_vol_obj_ptr ? _vol_obj_ptr : &tmp_vol_obj); /* Ptr to object ptr for loc_id */ + H5VL_loc_params_t loc_params; /* Location parameters for object access */ + hid_t ret_value = H5I_INVALID_HID; /* Return value */ - if (H5_PKG_INIT_VAR) { - /* Sanity checks */ - HDassert(0 == H5I_nmembers(H5I_GROUP)); - HDassert(FALSE == H5G_top_package_initialize_s); - - /* Destroy the group object id group */ - n += (H5I_dec_type_ref(H5I_GROUP) > 0); + FUNC_ENTER_STATIC - /* Mark closed */ - if (0 == n) - H5_PKG_INIT_VAR = FALSE; - } /* end if */ + /* Check arguments */ + if (!name) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, H5I_INVALID_HID, "name parameter cannot be NULL") + if (!*name) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, H5I_INVALID_HID, "name parameter cannot be an empty string") - FUNC_LEAVE_NOAPI(n) -} /* end H5G_term_package() */ + /* Set up object access arguments */ + if (H5VL_setup_acc_args(loc_id, H5P_CLS_GACC, TRUE, &gapl_id, vol_obj_ptr, &loc_params) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTSET, H5I_INVALID_HID, "can't set object access arguments") -/*------------------------------------------------------------------------- - * Function: H5G__close_cb - * - * Purpose: Called when the ref count reaches zero on the group's ID - * - * Return: SUCCEED/FAIL - * - *------------------------------------------------------------------------- - */ -static herr_t -H5G__close_cb(H5VL_object_t *grp_vol_obj) -{ - herr_t ret_value = SUCCEED; /* Return value */ + /* Check link creation property list */ + if (H5P_DEFAULT == lcpl_id) + lcpl_id = H5P_LINK_CREATE_DEFAULT; + else if (TRUE != H5P_isa_class(lcpl_id, H5P_LINK_CREATE)) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5I_INVALID_HID, "not a link creation property list") - FUNC_ENTER_STATIC + /* Check group creation property list */ + if (H5P_DEFAULT == gcpl_id) + gcpl_id = H5P_GROUP_CREATE_DEFAULT; + else if (TRUE != H5P_isa_class(gcpl_id, H5P_GROUP_CREATE)) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5I_INVALID_HID, "not a group creation property list") - /* Sanity check */ - HDassert(grp_vol_obj); + /* Set the LCPL for the API context */ + H5CX_set_lcpl(lcpl_id); - /* Close the group */ - if (H5VL_group_close(grp_vol_obj, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0) - HGOTO_ERROR(H5E_SYM, H5E_CLOSEERROR, FAIL, "unable to close group") + /* Create the group */ + if (NULL == (grp = H5VL_group_create(*vol_obj_ptr, &loc_params, name, lcpl_id, gcpl_id, gapl_id, + H5P_DATASET_XFER_DEFAULT, token_ptr))) + HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, H5I_INVALID_HID, "unable to create group") - /* Free the VOL object */ - if (H5VL_free_object(grp_vol_obj) < 0) - HGOTO_ERROR(H5E_SYM, H5E_CANTDEC, FAIL, "unable to free VOL object") + /* Get an ID for the group */ + if ((ret_value = H5VL_register(H5I_GROUP, grp, (*vol_obj_ptr)->connector, TRUE)) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTREGISTER, H5I_INVALID_HID, "unable to get ID for group handle") done: + if (H5I_INVALID_HID == ret_value) + if (grp && H5VL_group_close(*vol_obj_ptr, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0) + HDONE_ERROR(H5E_SYM, H5E_CLOSEERROR, H5I_INVALID_HID, "unable to release group") + FUNC_LEAVE_NOAPI(ret_value) -} /* end H5G__close_cb() */ +} /* end H5G__create_api_common() */ /*------------------------------------------------------------------------- * Function: H5Gcreate2 @@ -324,63 +222,65 @@ done: hid_t H5Gcreate2(hid_t loc_id, const char *name, hid_t lcpl_id, hid_t gcpl_id, hid_t gapl_id) { - void * grp = NULL; /* Structure for new group */ - H5VL_object_t * vol_obj = NULL; /* object of loc_id */ - H5VL_loc_params_t loc_params; - hid_t ret_value = H5I_INVALID_HID; /* Return value */ + hid_t ret_value = H5I_INVALID_HID; /* Return value */ FUNC_ENTER_API(H5I_INVALID_HID) H5TRACE5("i", "i*siii", loc_id, name, lcpl_id, gcpl_id, gapl_id); - /* Check arguments */ - if (!name) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, H5I_INVALID_HID, "name parameter cannot be NULL") - if (!*name) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, H5I_INVALID_HID, "name parameter cannot be an empty string") - - /* Check link creation property list */ - if (H5P_DEFAULT == lcpl_id) - lcpl_id = H5P_LINK_CREATE_DEFAULT; - else if (TRUE != H5P_isa_class(lcpl_id, H5P_LINK_CREATE)) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5I_INVALID_HID, "not a link creation property list") - - /* Check group creation property list */ - if (H5P_DEFAULT == gcpl_id) - gcpl_id = H5P_GROUP_CREATE_DEFAULT; - else if (TRUE != H5P_isa_class(gcpl_id, H5P_GROUP_CREATE)) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5I_INVALID_HID, "not a group creation property list") - - /* Set the LCPL for the API context */ - H5CX_set_lcpl(lcpl_id); + /* Create the group synchronously */ + if ((ret_value = H5G__create_api_common(loc_id, name, lcpl_id, gcpl_id, gapl_id, NULL, NULL)) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTCREATE, H5I_INVALID_HID, "unable to synchronously create group") - /* Verify access property list and set up collective metadata if appropriate */ - if (H5CX_set_apl(&gapl_id, H5P_CLS_GACC, loc_id, TRUE) < 0) - HGOTO_ERROR(H5E_SYM, H5E_CANTSET, H5I_INVALID_HID, "can't set access property list info") +done: + FUNC_LEAVE_API(ret_value) +} /* end H5Gcreate2() */ - /* Get the location object */ - if (NULL == (vol_obj = (H5VL_object_t *)H5I_object(loc_id))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5I_INVALID_HID, "invalid location identifier") +/*------------------------------------------------------------------------- + * Function: H5Gcreate_async + * + * Purpose: Asynchronous version of H5Gcreate + * + * Return: Success: A group ID + * Failure: H5I_INVALID_HID + * + *------------------------------------------------------------------------- + */ +hid_t +H5Gcreate_async(const char *app_file, const char *app_func, unsigned app_line, hid_t loc_id, const char *name, + hid_t lcpl_id, hid_t gcpl_id, hid_t gapl_id, hid_t es_id) +{ + H5VL_object_t *vol_obj = NULL; /* Object for loc_id */ + void * token = NULL; /* Request token for async operation */ + void ** token_ptr = H5_REQUEST_NULL; /* Pointer to request token for async operation */ + hid_t ret_value = H5I_INVALID_HID; /* Return value */ - /* Set the location parameters */ - loc_params.type = H5VL_OBJECT_BY_SELF; - loc_params.obj_type = H5I_get_type(loc_id); + FUNC_ENTER_API(H5I_INVALID_HID) + H5TRACE9("i", "*s*sIui*siiii", app_file, app_func, app_line, loc_id, name, lcpl_id, gcpl_id, gapl_id, + es_id); - /* Create the group */ - if (NULL == (grp = H5VL_group_create(vol_obj, &loc_params, name, lcpl_id, gcpl_id, gapl_id, - H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL))) - HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, H5I_INVALID_HID, "unable to create group") + /* Set up request token pointer for asynchronous operation */ + if (H5ES_NONE != es_id) + token_ptr = &token; /* Point at token for VOL connector to set up */ - /* Get an atom for the group */ - if ((ret_value = H5VL_register(H5I_GROUP, grp, vol_obj->connector, TRUE)) < 0) - HGOTO_ERROR(H5E_SYM, H5E_CANTREGISTER, H5I_INVALID_HID, "unable to atomize group handle") + /* Create the group asynchronously */ + if ((ret_value = H5G__create_api_common(loc_id, name, lcpl_id, gcpl_id, gapl_id, token_ptr, &vol_obj)) < + 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTCREATE, H5I_INVALID_HID, "unable to asynchronously create group") + + /* If a token was created, add the token to the event set */ + if (NULL != token) + /* clang-format off */ + if (H5ES_insert(es_id, vol_obj->connector, token, + H5ARG_TRACE9(FUNC, "*s*sIui*siiii", app_file, app_func, app_line, loc_id, name, lcpl_id, gcpl_id, gapl_id, es_id)) < 0) { + /* clang-format on */ + if (H5I_dec_app_ref_always_close(ret_value) < 0) + HDONE_ERROR(H5E_SYM, H5E_CANTDEC, H5I_INVALID_HID, "can't decrement count on group ID") + HGOTO_ERROR(H5E_SYM, H5E_CANTINSERT, H5I_INVALID_HID, "can't insert token into event set") + } /* end if */ done: - if (H5I_INVALID_HID == ret_value) - if (grp && H5VL_group_close(vol_obj, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0) - HDONE_ERROR(H5E_SYM, H5E_CLOSEERROR, H5I_INVALID_HID, "unable to release group") - FUNC_LEAVE_API(ret_value) -} /* end H5Gcreate2() */ +} /* end H5Gcreate_async() */ /*------------------------------------------------------------------------- * Function: H5Gcreate_anon @@ -417,9 +317,9 @@ done: hid_t H5Gcreate_anon(hid_t loc_id, hid_t gcpl_id, hid_t gapl_id) { - void * grp = NULL; /* Structure for new group */ - H5VL_object_t * vol_obj = NULL; /* Object for loc_id */ - H5VL_loc_params_t loc_params; + void * grp = NULL; /* Structure for new group */ + H5VL_object_t * vol_obj = NULL; /* Object for loc_id */ + H5VL_loc_params_t loc_params; /* Location parameters for object access */ hid_t ret_value = H5I_INVALID_HID; /* Return value */ FUNC_ENTER_API(H5I_INVALID_HID) @@ -448,9 +348,9 @@ H5Gcreate_anon(hid_t loc_id, hid_t gcpl_id, hid_t gapl_id) gapl_id, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL))) HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, H5I_INVALID_HID, "unable to create group") - /* Get an atom for the group */ + /* Get an ID for the group */ if ((ret_value = H5VL_register(H5I_GROUP, grp, vol_obj->connector, TRUE)) < 0) - HGOTO_ERROR(H5E_SYM, H5E_CANTREGISTER, H5I_INVALID_HID, "unable to atomize group handle") + HGOTO_ERROR(H5E_SYM, H5E_CANTREGISTER, H5I_INVALID_HID, "unable to get ID for group handle") done: /* Cleanup on failure */ @@ -462,30 +362,27 @@ done: } /* end H5Gcreate_anon() */ /*------------------------------------------------------------------------- - * Function: H5Gopen2 - * - * Purpose: Opens an existing group for modification. When finished, - * call H5Gclose() to close it and release resources. - * - * This function allows the user the pass in a Group Access - * Property List, which H5Gopen1() does not. + * Function: H5G__open_api_common * - * Return: Success: Object ID of the group + * Purpose: This is the common function for opening HDF5 groups. * + * Return: Success: A group ID * Failure: H5I_INVALID_HID * *------------------------------------------------------------------------- */ -hid_t -H5Gopen2(hid_t loc_id, const char *name, hid_t gapl_id) +static hid_t +H5G__open_api_common(hid_t loc_id, const char *name, hid_t gapl_id, void **token_ptr, + H5VL_object_t **_vol_obj_ptr) { - void * grp = NULL; /* Group opened */ - H5VL_object_t * vol_obj = NULL; /* object of loc_id */ - H5VL_loc_params_t loc_params; - hid_t ret_value = H5I_INVALID_HID; /* Return value */ + void * grp = NULL; /* Group opened */ + H5VL_object_t * tmp_vol_obj = NULL; /* Object for loc_id */ + H5VL_object_t **vol_obj_ptr = + (_vol_obj_ptr ? _vol_obj_ptr : &tmp_vol_obj); /* Ptr to object ptr for loc_id */ + H5VL_loc_params_t loc_params; /* Location parameters for object access */ + hid_t ret_value = H5I_INVALID_HID; /* Return value */ - FUNC_ENTER_API(H5I_INVALID_HID) - H5TRACE3("i", "i*si", loc_id, name, gapl_id); + FUNC_ENTER_STATIC /* Check args */ if (!name) @@ -493,35 +390,103 @@ H5Gopen2(hid_t loc_id, const char *name, hid_t gapl_id) if (!*name) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, H5I_INVALID_HID, "name parameter cannot be an empty string") - /* Verify access property list and set up collective metadata if appropriate */ - if (H5CX_set_apl(&gapl_id, H5P_CLS_GACC, loc_id, FALSE) < 0) - HGOTO_ERROR(H5E_SYM, H5E_CANTSET, H5I_INVALID_HID, "can't set access property list info") - - /* Get the location object */ - if (NULL == (vol_obj = (H5VL_object_t *)H5I_object(loc_id))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5I_INVALID_HID, "invalid location identifier") - - /* Open the group */ - loc_params.type = H5VL_OBJECT_BY_SELF; - loc_params.obj_type = H5I_get_type(loc_id); + /* Set up object access arguments */ + if (H5VL_setup_acc_args(loc_id, H5P_CLS_GACC, FALSE, &gapl_id, vol_obj_ptr, &loc_params) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTSET, H5I_INVALID_HID, "can't set object access arguments") - if (NULL == (grp = H5VL_group_open(vol_obj, &loc_params, name, gapl_id, H5P_DATASET_XFER_DEFAULT, - H5_REQUEST_NULL))) + if (NULL == (grp = H5VL_group_open(*vol_obj_ptr, &loc_params, name, gapl_id, H5P_DATASET_XFER_DEFAULT, + token_ptr))) HGOTO_ERROR(H5E_SYM, H5E_CANTOPENOBJ, H5I_INVALID_HID, "unable to open group") /* Register an ID for the group */ - if ((ret_value = H5VL_register(H5I_GROUP, grp, vol_obj->connector, TRUE)) < 0) + if ((ret_value = H5VL_register(H5I_GROUP, grp, (*vol_obj_ptr)->connector, TRUE)) < 0) HGOTO_ERROR(H5E_SYM, H5E_CANTREGISTER, H5I_INVALID_HID, "unable to register group") done: if (H5I_INVALID_HID == ret_value) - if (grp && H5VL_group_close(vol_obj, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0) + if (grp && H5VL_group_close(*vol_obj_ptr, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0) HDONE_ERROR(H5E_SYM, H5E_CLOSEERROR, H5I_INVALID_HID, "unable to release group") + FUNC_LEAVE_NOAPI(ret_value) +} /* H5G__open_api_common() */ + +/*------------------------------------------------------------------------- + * Function: H5Gopen2 + * + * Purpose: Opens an existing group for modification. When finished, + * call H5Gclose() to close it and release resources. + * + * This function allows the user the pass in a Group Access + * Property List, which H5Gopen1() does not. + * + * Return: Success: Object ID of the group + * + * Failure: H5I_INVALID_HID + * + *------------------------------------------------------------------------- + */ +hid_t +H5Gopen2(hid_t loc_id, const char *name, hid_t gapl_id) +{ + hid_t ret_value = H5I_INVALID_HID; /* Return value */ + + FUNC_ENTER_API(H5I_INVALID_HID) + H5TRACE3("i", "i*si", loc_id, name, gapl_id); + + /* Open the group synchronously */ + if ((ret_value = H5G__open_api_common(loc_id, name, gapl_id, NULL, NULL)) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTCREATE, H5I_INVALID_HID, "unable to synchronously open group") + +done: FUNC_LEAVE_API(ret_value) } /* end H5Gopen2() */ /*------------------------------------------------------------------------- + * Function: H5Gopen_async + * + * Purpose: Asynchronous version of H5Gopen2 + * + * Return: Success: A group ID + * Failure: H5I_INVALID_HID + * + *------------------------------------------------------------------------- + */ +hid_t +H5Gopen_async(const char *app_file, const char *app_func, unsigned app_line, hid_t loc_id, const char *name, + hid_t gapl_id, hid_t es_id) +{ + H5VL_object_t *vol_obj = NULL; /* Object for loc_id */ + void * token = NULL; /* Request token for async operation */ + void ** token_ptr = H5_REQUEST_NULL; /* Pointer to request token for async operation */ + hid_t ret_value = H5I_INVALID_HID; /* Return value */ + + FUNC_ENTER_API(H5I_INVALID_HID) + H5TRACE7("i", "*s*sIui*sii", app_file, app_func, app_line, loc_id, name, gapl_id, es_id); + + /* Set up request token pointer for asynchronous operation */ + if (H5ES_NONE != es_id) + token_ptr = &token; /* Point at token for VOL connector to set up */ + + /* Open the group asynchronously */ + if ((ret_value = H5G__open_api_common(loc_id, name, gapl_id, token_ptr, &vol_obj)) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTCREATE, H5I_INVALID_HID, "unable to asynchronously open group") + + /* If a token was created, add the token to the event set */ + if (NULL != token) + /* clang-format off */ + if (H5ES_insert(es_id, vol_obj->connector, token, + H5ARG_TRACE7(FUNC, "*s*sIui*sii", app_file, app_func, app_line, loc_id, name, gapl_id, es_id)) < 0) { + /* clang-format on */ + if (H5I_dec_app_ref_always_close(ret_value) < 0) + HDONE_ERROR(H5E_SYM, H5E_CANTDEC, H5I_INVALID_HID, "can't decrement count on group ID") + HGOTO_ERROR(H5E_SYM, H5E_CANTINSERT, H5I_INVALID_HID, "can't insert token into event set") + } /* end if */ + +done: + FUNC_LEAVE_API(ret_value) +} /* end H5Gopen_async() */ + +/*------------------------------------------------------------------------- * Function: H5Gget_create_plist * * Purpose: Returns a copy of the group creation property list. @@ -557,24 +522,27 @@ done: } /* end H5Gget_create_plist() */ /*------------------------------------------------------------------------- - * Function: H5Gget_info + * Function: H5G__get_info_api_common * - * Purpose: Retrieve information about a group. + * Purpose: This is the common function for retrieving information + * about a group. * * Return: SUCCEED/FAIL * *------------------------------------------------------------------------- */ -herr_t -H5Gget_info(hid_t loc_id, H5G_info_t *group_info) +static herr_t +H5G__get_info_api_common(hid_t loc_id, H5G_info_t *group_info /*out*/, void **token_ptr, + H5VL_object_t **_vol_obj_ptr) { - H5VL_object_t * vol_obj; - H5I_type_t id_type; /* Type of ID */ - H5VL_loc_params_t loc_params; - herr_t ret_value = SUCCEED; /* Return value */ + H5VL_object_t * tmp_vol_obj = NULL; /* Object for loc_id */ + H5VL_object_t **vol_obj_ptr = + (_vol_obj_ptr ? _vol_obj_ptr : &tmp_vol_obj); /* Ptr to object ptr for loc_id */ + H5VL_loc_params_t loc_params; /* Location parameters for object access */ + H5I_type_t id_type; /* Type of ID */ + herr_t ret_value = SUCCEED; /* Return value */ - FUNC_ENTER_API(FAIL) - H5TRACE2("e", "i*!", loc_id, group_info); + FUNC_ENTER_STATIC /* Check args */ id_type = H5I_get_type(loc_id); @@ -583,132 +551,305 @@ H5Gget_info(hid_t loc_id, H5G_info_t *group_info) if (!group_info) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "group_info parameter cannot be NULL") - /* Get group location */ - if (NULL == (vol_obj = (H5VL_object_t *)H5I_object(loc_id))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid location identifier") + /* Set up object access arguments */ + if (H5VL_setup_self_args(loc_id, vol_obj_ptr, &loc_params) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTSET, FAIL, "can't set object access arguments") - /* Retrieve the group's information */ - loc_params.type = H5VL_OBJECT_BY_SELF; - loc_params.obj_type = id_type; - if (H5VL_group_get(vol_obj, H5VL_GROUP_GET_INFO, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL, &loc_params, + /* Retrieve group information */ + if (H5VL_group_get(*vol_obj_ptr, H5VL_GROUP_GET_INFO, H5P_DATASET_XFER_DEFAULT, token_ptr, &loc_params, group_info) < 0) HGOTO_ERROR(H5E_SYM, H5E_CANTGET, FAIL, "unable to get group info") done: + FUNC_LEAVE_NOAPI(ret_value) +} /* H5G__get_info_api_common() */ + +/*------------------------------------------------------------------------- + * Function: H5Gget_info + * + * Purpose: Retrieve information about a group. + * + * Return: SUCCEED/FAIL + * + *------------------------------------------------------------------------- + */ +herr_t +H5Gget_info(hid_t loc_id, H5G_info_t *group_info /*out*/) +{ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_API(FAIL) + H5TRACE2("e", "ix", loc_id, group_info); + + /* Retrieve group information synchronously */ + if (H5G__get_info_api_common(loc_id, group_info, NULL, NULL) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTGET, FAIL, "unable to synchronously get group info") + +done: FUNC_LEAVE_API(ret_value) } /* end H5Gget_info() */ /*------------------------------------------------------------------------- - * Function: H5Gget_info_by_name + * Function: H5Gget_info_async * - * Purpose: Retrieve information about a group, where the group is - * identified by name instead of ID. + * Purpose: Asynchronous version of H5Gget_info * * Return: SUCCEED/FAIL * *------------------------------------------------------------------------- */ herr_t -H5Gget_info_by_name(hid_t loc_id, const char *name, H5G_info_t *group_info, hid_t lapl_id) +H5Gget_info_async(const char *app_file, const char *app_func, unsigned app_line, hid_t loc_id, + H5G_info_t *group_info /*out*/, hid_t es_id) { - H5VL_object_t * vol_obj; - H5VL_loc_params_t loc_params; - herr_t ret_value = SUCCEED; /* Return value */ + H5VL_object_t *vol_obj = NULL; /* Object for loc_id */ + void * token = NULL; /* Request token for async operation */ + void ** token_ptr = H5_REQUEST_NULL; /* Pointer to request token for async operation */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API(FAIL) - H5TRACE4("e", "i*s*!i", loc_id, name, group_info, lapl_id); + H5TRACE6("e", "*s*sIuixi", app_file, app_func, app_line, loc_id, group_info, es_id); + + /* Set up request token pointer for asynchronous operation */ + if (H5ES_NONE != es_id) + token_ptr = &token; /* Point at token for VOL connector to set up */ + + /* Retrieve group information asynchronously */ + if (H5G__get_info_api_common(loc_id, group_info, token_ptr, &vol_obj) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTGET, FAIL, "unable to asynchronously get group info") + + /* If a token was created, add the token to the event set */ + if (NULL != token) + /* clang-format off */ + if (H5ES_insert(es_id, vol_obj->connector, token, + H5ARG_TRACE6(FUNC, "*s*sIuixi", app_file, app_func, app_line, loc_id, group_info, es_id)) < 0) + /* clang-format on */ + HGOTO_ERROR(H5E_SYM, H5E_CANTINSERT, FAIL, "can't insert token into event set") + +done: + FUNC_LEAVE_API(ret_value) +} /* H5Gget_info_async() */ + +/*------------------------------------------------------------------------- + * Function: H5G__get_info_by_name_api_common + * + * Purpose: This is the common function for retrieving information + * about a group. + * + * Return: SUCCEED/FAIL + * + *------------------------------------------------------------------------- + */ +static herr_t +H5G__get_info_by_name_api_common(hid_t loc_id, const char *name, H5G_info_t *group_info /*out*/, + hid_t lapl_id, void **token_ptr, H5VL_object_t **_vol_obj_ptr) +{ + H5VL_object_t * tmp_vol_obj = NULL; /* Object for loc_id */ + H5VL_object_t **vol_obj_ptr = + (_vol_obj_ptr ? _vol_obj_ptr : &tmp_vol_obj); /* Ptr to object ptr for loc_id */ + H5VL_loc_params_t loc_params; /* Location parameters for object access */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_STATIC /* Check args */ - if (!name) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "name parameter cannot be NULL") - if (!*name) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "name parameter cannot be an empty string") if (!group_info) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "group_info parameter cannot be NULL") - /* Verify access property list and set up collective metadata if appropriate */ - if (H5CX_set_apl(&lapl_id, H5P_CLS_LACC, loc_id, FALSE) < 0) - HGOTO_ERROR(H5E_SYM, H5E_CANTSET, FAIL, "can't set access property list info") + /* Set up object access arguments */ + if (H5VL_setup_name_args(loc_id, name, H5P_CLS_LACC, FALSE, lapl_id, vol_obj_ptr, &loc_params) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTSET, FAIL, "can't set object access arguments") - /* Get the location object */ - if (NULL == (vol_obj = (H5VL_object_t *)H5I_object(loc_id))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid location identifier") + /* Retrieve group information */ + if (H5VL_group_get(*vol_obj_ptr, H5VL_GROUP_GET_INFO, H5P_DATASET_XFER_DEFAULT, token_ptr, &loc_params, + group_info) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTGET, FAIL, "unable to get group info") - /* Set up location parameters */ - loc_params.type = H5VL_OBJECT_BY_NAME; - loc_params.loc_data.loc_by_name.name = name; - loc_params.loc_data.loc_by_name.lapl_id = lapl_id; - loc_params.obj_type = H5I_get_type(loc_id); +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* H5G__get_info_by_name_api_common() */ - /* Retrieve the group's information */ - if (H5VL_group_get(vol_obj, H5VL_GROUP_GET_INFO, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL, &loc_params, - group_info) < 0) - HGOTO_ERROR(H5E_SYM, H5E_CANTGET, FAIL, "can't retrieve group info") +/*------------------------------------------------------------------------- + * Function: H5Gget_info_by_name + * + * Purpose: Retrieve information about a group, where the group is + * identified by name instead of ID. + * + * Return: SUCCEED/FAIL + * + *------------------------------------------------------------------------- + */ +herr_t +H5Gget_info_by_name(hid_t loc_id, const char *name, H5G_info_t *group_info /*out*/, hid_t lapl_id) +{ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_API(FAIL) + H5TRACE4("e", "i*sxi", loc_id, name, group_info, lapl_id); + + /* Retrieve group information synchronously */ + if (H5G__get_info_by_name_api_common(loc_id, name, group_info, lapl_id, NULL, NULL) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTGET, FAIL, "can't synchronously retrieve group info") done: FUNC_LEAVE_API(ret_value) } /* end H5Gget_info_by_name() */ /*------------------------------------------------------------------------- - * Function: H5Gget_info_by_idx + * Function: H5Gget_info_by_name_async * - * Purpose: Retrieve information about a group, according to the order - * of an index. + * Purpose: Asynchronous version of H5Gget_info_by_name * * Return: SUCCEED/FAIL * *------------------------------------------------------------------------- */ herr_t -H5Gget_info_by_idx(hid_t loc_id, const char *group_name, H5_index_t idx_type, H5_iter_order_t order, - hsize_t n, H5G_info_t *group_info, hid_t lapl_id) +H5Gget_info_by_name_async(const char *app_file, const char *app_func, unsigned app_line, hid_t loc_id, + const char *name, H5G_info_t *group_info /*out*/, hid_t lapl_id, hid_t es_id) { - H5VL_object_t * vol_obj; - H5VL_loc_params_t loc_params; - herr_t ret_value = SUCCEED; /* Return value */ + H5VL_object_t *vol_obj = NULL; /* Object for loc_id */ + void * token = NULL; /* Request token for async operation */ + void ** token_ptr = H5_REQUEST_NULL; /* Pointer to request token for async operation */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API(FAIL) - H5TRACE7("e", "i*sIiIoh*!i", loc_id, group_name, idx_type, order, n, group_info, lapl_id); + H5TRACE8("e", "*s*sIui*sxii", app_file, app_func, app_line, loc_id, name, group_info, lapl_id, es_id); + + /* Set up request token pointer for asynchronous operation */ + if (H5ES_NONE != es_id) + token_ptr = &token; /* Point at token for VOL connector to set up */ + + /* Retrieve group information asynchronously */ + if (H5G__get_info_by_name_api_common(loc_id, name, group_info, lapl_id, token_ptr, &vol_obj) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTGET, FAIL, "can't asynchronously retrieve group info") + + /* If a token was created, add the token to the event set */ + if (NULL != token) + /* clang-format off */ + if (H5ES_insert(es_id, vol_obj->connector, token, + H5ARG_TRACE8(FUNC, "*s*sIui*sxii", app_file, app_func, app_line, loc_id, name, group_info, lapl_id, es_id)) < 0) + /* clang-format on */ + HGOTO_ERROR(H5E_SYM, H5E_CANTINSERT, FAIL, "can't insert token into event set") + +done: + FUNC_LEAVE_API(ret_value) +} /* H5Gget_info_by_name_async() */ + +/*------------------------------------------------------------------------- + * Function: H5G__get_info_by_idx_api_common + * + * Purpose: This is the common function for retrieving information + * about a group. + * + * Return: SUCCEED/FAIL + * + *------------------------------------------------------------------------- + */ +static herr_t +H5G__get_info_by_idx_api_common(hid_t loc_id, const char *group_name, H5_index_t idx_type, + H5_iter_order_t order, hsize_t n, H5G_info_t *group_info /*out*/, + hid_t lapl_id, void **token_ptr, H5VL_object_t **_vol_obj_ptr) +{ + H5VL_object_t * tmp_vol_obj = NULL; /* Object for loc_id */ + H5VL_object_t **vol_obj_ptr = + (_vol_obj_ptr ? _vol_obj_ptr : &tmp_vol_obj); /* Ptr to object ptr for loc_id */ + H5VL_loc_params_t loc_params; /* Location parameters for object access */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_STATIC /* Check args */ - if (!group_name) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "group_name parameter cannot be NULL") - if (!*group_name) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "group_name parameter cannot be an empty string") - if (idx_type <= H5_INDEX_UNKNOWN || idx_type >= H5_INDEX_N) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid index type specified") - if (order <= H5_ITER_UNKNOWN || order >= H5_ITER_N) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid iteration order specified") if (!group_info) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "group_info parameter cannot be NULL") - /* Verify access property list and set up collective metadata if appropriate */ - if (H5CX_set_apl(&lapl_id, H5P_CLS_LACC, loc_id, FALSE) < 0) - HGOTO_ERROR(H5E_SYM, H5E_CANTSET, FAIL, "can't set access property list info") + /* Set up object access arguments */ + if (H5VL_setup_idx_args(loc_id, group_name, idx_type, order, n, H5P_CLS_LACC, FALSE, lapl_id, vol_obj_ptr, + &loc_params) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTSET, FAIL, "can't set object access arguments") - /* Get the location object */ - if (NULL == (vol_obj = (H5VL_object_t *)H5I_object(loc_id))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid location identifier") - - /* Set location parameters */ - loc_params.type = H5VL_OBJECT_BY_IDX; - loc_params.loc_data.loc_by_idx.name = group_name; - loc_params.loc_data.loc_by_idx.idx_type = idx_type; - loc_params.loc_data.loc_by_idx.order = order; - loc_params.loc_data.loc_by_idx.n = n; - loc_params.loc_data.loc_by_idx.lapl_id = lapl_id; - loc_params.obj_type = H5I_get_type(loc_id); - - /* Retrieve the group's information */ - if (H5VL_group_get(vol_obj, H5VL_GROUP_GET_INFO, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL, &loc_params, + /* Retrieve group information */ + if (H5VL_group_get(*vol_obj_ptr, H5VL_GROUP_GET_INFO, H5P_DATASET_XFER_DEFAULT, token_ptr, &loc_params, group_info) < 0) - HGOTO_ERROR(H5E_SYM, H5E_CANTGET, FAIL, "can't retrieve group info") + HGOTO_ERROR(H5E_SYM, H5E_CANTGET, FAIL, "unable to get group info") + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* H5G__get_info_by_idx_api_common() */ + +/*------------------------------------------------------------------------- + * Function: H5Gget_info_by_idx + * + * Purpose: Retrieve information about a group, according to the order + * of an index. + * + * Return: SUCCEED/FAIL + * + *------------------------------------------------------------------------- + */ +herr_t +H5Gget_info_by_idx(hid_t loc_id, const char *group_name, H5_index_t idx_type, H5_iter_order_t order, + hsize_t n, H5G_info_t *group_info /*out*/, hid_t lapl_id) +{ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_API(FAIL) + H5TRACE7("e", "i*sIiIohxi", loc_id, group_name, idx_type, order, n, group_info, lapl_id); + + /* Retrieve group information synchronously */ + if (H5G__get_info_by_idx_api_common(loc_id, group_name, idx_type, order, n, group_info, lapl_id, NULL, + NULL) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTGET, FAIL, "can't synchronously retrieve group info") done: FUNC_LEAVE_API(ret_value) } /* end H5Gget_info_by_idx() */ /*------------------------------------------------------------------------- + * Function: H5Gget_info_by_idx_async + * + * Purpose: Asynchronous version of H5Gget_info_by_idx + * + * Return: SUCCEED/FAIL + * + *------------------------------------------------------------------------- + */ +herr_t +H5Gget_info_by_idx_async(const char *app_file, const char *app_func, unsigned app_line, hid_t loc_id, + const char *group_name, H5_index_t idx_type, H5_iter_order_t order, hsize_t n, + H5G_info_t *group_info /*out*/, hid_t lapl_id, hid_t es_id) +{ + H5VL_object_t *vol_obj = NULL; /* Object for loc_id */ + void * token = NULL; /* Request token for async operation */ + void ** token_ptr = H5_REQUEST_NULL; /* Pointer to request token for async operation */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_API(FAIL) + H5TRACE11("e", "*s*sIui*sIiIohxii", app_file, app_func, app_line, loc_id, group_name, idx_type, order, n, + group_info, lapl_id, es_id); + + /* Set up request token pointer for asynchronous operation */ + if (H5ES_NONE != es_id) + token_ptr = &token; /* Point at token for VOL connector to set up */ + + /* Retrieve group information asynchronously */ + if (H5G__get_info_by_idx_api_common(loc_id, group_name, idx_type, order, n, group_info, lapl_id, + token_ptr, &vol_obj) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTGET, FAIL, "can't asynchronously retrieve group info") + + /* If a token was created, add the token to the event set */ + if (NULL != token) + /* clang-format off */ + if (H5ES_insert(es_id, vol_obj->connector, token, + H5ARG_TRACE11(FUNC, "*s*sIui*sIiIohxii", app_file, app_func, app_line, loc_id, group_name, idx_type, order, n, group_info, lapl_id, es_id)) < 0) + /* clang-format on */ + HGOTO_ERROR(H5E_SYM, H5E_CANTINSERT, FAIL, "can't insert token into event set") + +done: + FUNC_LEAVE_API(ret_value) +} /* H5Gget_info_by_idx_async() */ + +/*------------------------------------------------------------------------- * Function: H5Gclose * * Purpose: Closes the specified group. The group ID will no longer be @@ -726,21 +867,82 @@ H5Gclose(hid_t group_id) FUNC_ENTER_API(FAIL) H5TRACE1("e", "i", group_id); - /* Check args */ - if (NULL == H5I_object_verify(group_id, H5I_GROUP)) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a group") + /* Check arguments */ + if (H5I_GROUP != H5I_get_type(group_id)) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a group ID") - /* Decrement the counter on the group atom. It will be freed if the count + /* Decrement the counter on the group ID. It will be freed if the count * reaches zero. */ if (H5I_dec_app_ref(group_id) < 0) - HGOTO_ERROR(H5E_SYM, H5E_CANTRELEASE, FAIL, "unable to close group") + HGOTO_ERROR(H5E_SYM, H5E_CANTDEC, FAIL, "decrementing group ID failed") done: FUNC_LEAVE_API(ret_value) } /* end H5Gclose() */ /*------------------------------------------------------------------------- + * Function: H5Gclose_async + * + * Purpose: Asynchronous version of H5Gclose + * + * Return: SUCCEED/FAIL + * + *------------------------------------------------------------------------- + */ +herr_t +H5Gclose_async(const char *app_file, const char *app_func, unsigned app_line, hid_t group_id, hid_t es_id) +{ + H5VL_object_t *vol_obj = NULL; /* Object for loc_id */ + H5VL_t * connector = NULL; /* VOL connector */ + void * token = NULL; /* Request token for async operation */ + void ** token_ptr = H5_REQUEST_NULL; /* Pointer to request token for async operation */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_API(FAIL) + H5TRACE5("e", "*s*sIuii", app_file, app_func, app_line, group_id, es_id); + + /* Check arguments */ + if (H5I_GROUP != H5I_get_type(group_id)) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a group ID") + + /* Prepare for possible asynchronous operation */ + if (H5ES_NONE != es_id) { + /* Get group object's connector */ + if (NULL == (vol_obj = H5VL_vol_object(group_id))) + HGOTO_ERROR(H5E_SYM, H5E_CANTGET, FAIL, "can't get VOL object for group") + + /* Increase connector's refcount, so it doesn't get closed if closing + * the group closes the file */ + connector = vol_obj->connector; + H5VL_conn_inc_rc(connector); + + /* Point at token for operation to set up */ + token_ptr = &token; + } /* end if */ + + /* Decrement the counter on the group ID. It will be freed if the count + * reaches zero. + */ + if (H5I_dec_app_ref_async(group_id, token_ptr) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTDEC, FAIL, "decrementing group ID failed") + + /* If a token was created, add the token to the event set */ + if (NULL != token) + /* clang-format off */ + if (H5ES_insert(es_id, vol_obj->connector, token, + H5ARG_TRACE5(FUNC, "*s*sIuii", app_file, app_func, app_line, group_id, es_id)) < 0) + /* clang-format on */ + HGOTO_ERROR(H5E_SYM, H5E_CANTINSERT, FAIL, "can't insert token into event set") + +done: + if (connector && H5VL_conn_dec_rc(connector) < 0) + HDONE_ERROR(H5E_SYM, H5E_CANTDEC, FAIL, "can't decrement ref count on connector") + + FUNC_LEAVE_API(ret_value) +} /* end H5Gclose_async() */ + +/*------------------------------------------------------------------------- * Function: H5Gflush * * Purpose: Flushes all buffers associated with a group to disk. diff --git a/src/H5Gcache.c b/src/H5Gcache.c index e2b3e21..df9943f 100644 --- a/src/H5Gcache.c +++ b/src/H5Gcache.c @@ -15,7 +15,7 @@ * * Created: H5Gcache.c * Feb 5 2008 - * Quincey Koziol <koziol@hdfgroup.org> + * Quincey Koziol * * Purpose: Implement group metadata cache methods. * @@ -177,7 +177,7 @@ H5G__cache_node_deserialize(const void *_image, size_t len, void *_udata, hbool_ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed") /* magic */ - if (HDmemcmp(image, H5G_NODE_MAGIC, (size_t)H5_SIZEOF_MAGIC)) + if (HDmemcmp(image, H5G_NODE_MAGIC, (size_t)H5_SIZEOF_MAGIC) != 0) HGOTO_ERROR(H5E_SYM, H5E_BADVALUE, NULL, "bad symbol table node signature") image += H5_SIZEOF_MAGIC; diff --git a/src/H5Gcompact.c b/src/H5Gcompact.c index af188d8..a621f6e 100644 --- a/src/H5Gcompact.c +++ b/src/H5Gcompact.c @@ -52,7 +52,7 @@ typedef struct { /* upward */ H5O_link_t *lnk; /* Link struct to fill in */ - hbool_t found; /* Flag to indicate that the object was found */ + hbool_t * found; /* Pointer to flag to indicate that the object was found */ } H5G_iter_lkp_t; /* Private macros */ @@ -450,7 +450,7 @@ H5G__compact_lookup_cb(const void *_mesg, unsigned H5_ATTR_UNUSED idx, void *_ud } /* end if */ /* Indicate that the correct link was found */ - udata->found = TRUE; + *udata->found = TRUE; /* Stop iteration now */ HGOTO_DONE(H5_ITER_STOP) @@ -472,23 +472,24 @@ done: * *------------------------------------------------------------------------- */ -htri_t -H5G__compact_lookup(const H5O_loc_t *oloc, const char *name, H5O_link_t *lnk) +herr_t +H5G__compact_lookup(const H5O_loc_t *oloc, const char *name, hbool_t *found, H5O_link_t *lnk) { - H5G_iter_lkp_t udata; /* User data for iteration callback */ - H5O_mesg_operator_t op; /* Message operator */ - htri_t ret_value = FAIL; /* Return value */ + H5G_iter_lkp_t udata; /* User data for iteration callback */ + H5O_mesg_operator_t op; /* Message operator */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_PACKAGE /* check arguments */ - HDassert(lnk && oloc->file); HDassert(name && *name); + HDassert(found); + HDassert(lnk && oloc->file); /* Set up user data for iteration */ udata.name = name; udata.lnk = lnk; - udata.found = FALSE; + udata.found = found; /* Iterate through the link messages, adding them to the table */ op.op_type = H5O_MESG_OP_APP; @@ -496,9 +497,6 @@ H5G__compact_lookup(const H5O_loc_t *oloc, const char *name, H5O_link_t *lnk) if (H5O_msg_iterate(oloc, H5O_LINK_ID, &op, &udata) < 0) HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "error iterating over link messages") - /* Determine if we found the link we were looking for */ - ret_value = (htri_t)udata.found; - done: FUNC_LEAVE_NOAPI(ret_value) } /* end H5G__compact_lookup() */ diff --git a/src/H5Gdense.c b/src/H5Gdense.c index 171df9e..ec5cb71 100644 --- a/src/H5Gdense.c +++ b/src/H5Gdense.c @@ -486,13 +486,13 @@ done: * *------------------------------------------------------------------------- */ -htri_t -H5G__dense_lookup(H5F_t *f, const H5O_linfo_t *linfo, const char *name, H5O_link_t *lnk) +herr_t +H5G__dense_lookup(H5F_t *f, const H5O_linfo_t *linfo, const char *name, hbool_t *found, H5O_link_t *lnk) { - H5G_bt2_ud_common_t udata; /* User data for v2 B-tree link lookup */ - H5HF_t * fheap = NULL; /* Fractal heap handle */ - H5B2_t * bt2_name = NULL; /* v2 B-tree handle for name index */ - htri_t ret_value = FAIL; /* Return value */ + H5G_bt2_ud_common_t udata; /* User data for v2 B-tree link lookup */ + H5HF_t * fheap = NULL; /* Fractal heap handle */ + H5B2_t * bt2_name = NULL; /* v2 B-tree handle for name index */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_PACKAGE @@ -502,6 +502,7 @@ H5G__dense_lookup(H5F_t *f, const H5O_linfo_t *linfo, const char *name, H5O_link HDassert(f); HDassert(linfo); HDassert(name && *name); + HDassert(found); HDassert(lnk); /* Open the fractal heap */ @@ -521,7 +522,7 @@ H5G__dense_lookup(H5F_t *f, const H5O_linfo_t *linfo, const char *name, H5O_link udata.found_op_data = lnk; /* Find & copy the named link in the 'name' index */ - if ((ret_value = H5B2_find(bt2_name, &udata, NULL, NULL)) < 0) + if (H5B2_find(bt2_name, &udata, found, NULL, NULL) < 0) HGOTO_ERROR(H5E_SYM, H5E_CANTINSERT, FAIL, "unable to locate link in name index") done: diff --git a/src/H5Gent.c b/src/H5Gent.c index b26e308..2f1a2b4 100644 --- a/src/H5Gent.c +++ b/src/H5Gent.c @@ -384,11 +384,8 @@ H5G__ent_convert(H5F_t *f, H5HL_t *heap, const char *name, const H5O_link_t *lnk /* Reset the new entry */ H5G__ent_reset(ent); - /* - * Add the new name to the heap. - */ - name_offset = H5HL_insert(f, heap, HDstrlen(name) + 1, name); - if (0 == name_offset || UFAIL == name_offset) + /* Add the new name to the heap */ + if (H5HL_insert(f, heap, HDstrlen(name) + 1, name, &name_offset) < 0) HGOTO_ERROR(H5E_SYM, H5E_CANTINSERT, FAIL, "unable to insert symbol name into heap") ent->name_off = name_offset; @@ -476,14 +473,12 @@ H5G__ent_convert(H5F_t *f, H5HL_t *heap, const char *name, const H5O_link_t *lnk size_t lnk_offset; /* Offset to sym-link value */ /* Insert link value into local heap */ - if (UFAIL == - (lnk_offset = H5HL_insert(f, heap, HDstrlen(lnk->u.soft.name) + 1, lnk->u.soft.name))) + if (H5HL_insert(f, heap, HDstrlen(lnk->u.soft.name) + 1, lnk->u.soft.name, &lnk_offset) < 0) HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to write link value to local heap") ent->type = H5G_CACHED_SLINK; ent->cache.slink.lval_offset = lnk_offset; - } /* end case */ - break; + } break; case H5L_TYPE_ERROR: case H5L_TYPE_EXTERNAL: diff --git a/src/H5Gint.c b/src/H5Gint.c index 57a6144..dab7a54 100644 --- a/src/H5Gint.c +++ b/src/H5Gint.c @@ -83,11 +83,16 @@ typedef struct { /********************/ static herr_t H5G__open_oid(H5G_t *grp); +static herr_t H5G__visit_cb(const H5O_link_t *lnk, void *_udata); +static herr_t H5G__close_cb(H5VL_object_t *grp_vol_obj, void **request); /*********************/ /* Package Variables */ /*********************/ +/* Package initialization variable */ +hbool_t H5_PKG_INIT_VAR = FALSE; + /* Declare a free list to manage the H5G_t struct */ H5FL_DEFINE(H5G_t); H5FL_DEFINE(H5G_shared_t); @@ -103,6 +108,182 @@ H5FL_DEFINE(H5_obj_t); /* Local Variables */ /*******************/ +/* Group ID class */ +static const H5I_class_t H5I_GROUP_CLS[1] = {{ + H5I_GROUP, /* ID class value */ + 0, /* Class flags */ + 0, /* # of reserved IDs for class */ + (H5I_free_t)H5G__close_cb /* Callback routine for closing objects of this class */ +}}; + +/* Flag indicating "top" of interface has been initialized */ +static hbool_t H5G_top_package_initialize_s = FALSE; + +/*------------------------------------------------------------------------- + * Function: H5G_init + * + * Purpose: Initialize the interface from some other layer. + * + * Return: Success: non-negative + * + * Failure: negative + *------------------------------------------------------------------------- + */ +herr_t +H5G_init(void) +{ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI(FAIL) + /* FUNC_ENTER() does all the work */ + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5G_init() */ + +/*------------------------------------------------------------------------- + * Function: H5G__init_package + * + * Purpose: Initializes the H5G interface. + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Robb Matzke + * Monday, January 5, 1998 + * + * Notes: The group creation properties are registered in the property + * list interface initialization routine (H5P_init_package) + * so that the file creation property class can inherit from it + * correctly. (Which allows the file creation property list to + * control the group creation properties of the root group of + * a file) QAK - 24/10/2005 + * + *------------------------------------------------------------------------- + */ +herr_t +H5G__init_package(void) +{ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_PACKAGE + + /* Initialize the ID group for the group IDs */ + if (H5I_register_type(H5I_GROUP_CLS) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to initialize interface") + + /* Mark "top" of interface as initialized, too */ + H5G_top_package_initialize_s = TRUE; + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5G__init_package() */ + +/*------------------------------------------------------------------------- + * Function: H5G_top_term_package + * + * Purpose: Close the "top" of the interface, releasing IDs, etc. + * + * Return: Success: Positive if anything is done that might + * affect other interfaces; zero otherwise. + * Failure: Negative. + * + * Programmer: Quincey Koziol + * Sunday, September 13, 2015 + * + *------------------------------------------------------------------------- + */ +int +H5G_top_term_package(void) +{ + int n = 0; + + FUNC_ENTER_NOAPI_NOINIT_NOERR + + if (H5G_top_package_initialize_s) { + if (H5I_nmembers(H5I_GROUP) > 0) { + (void)H5I_clear_type(H5I_GROUP, FALSE, FALSE); + n++; /*H5I*/ + } /* end if */ + + /* Mark closed */ + if (0 == n) + H5G_top_package_initialize_s = FALSE; + } /* end if */ + + FUNC_LEAVE_NOAPI(n) +} /* end H5G_top_term_package() */ + +/*------------------------------------------------------------------------- + * Function: H5G_term_package + * + * Purpose: Terminates the H5G interface + * + * Note: Finishes shutting down the interface, after + * H5G_top_term_package() is called + * + * Return: Success: Positive if anything is done that might + * affect other interfaces; zero otherwise. + * Failure: Negative. + * + * Programmer: Robb Matzke + * Monday, January 5, 1998 + * + *------------------------------------------------------------------------- + */ +int +H5G_term_package(void) +{ + int n = 0; + + FUNC_ENTER_NOAPI_NOINIT_NOERR + + if (H5_PKG_INIT_VAR) { + /* Sanity checks */ + HDassert(0 == H5I_nmembers(H5I_GROUP)); + HDassert(FALSE == H5G_top_package_initialize_s); + + /* Destroy the group object id group */ + n += (H5I_dec_type_ref(H5I_GROUP) > 0); + + /* Mark closed */ + if (0 == n) + H5_PKG_INIT_VAR = FALSE; + } /* end if */ + + FUNC_LEAVE_NOAPI(n) +} /* end H5G_term_package() */ + +/*------------------------------------------------------------------------- + * Function: H5G__close_cb + * + * Purpose: Called when the ref count reaches zero on the group's ID + * + * Return: SUCCEED/FAIL + * + *------------------------------------------------------------------------- + */ +static herr_t +H5G__close_cb(H5VL_object_t *grp_vol_obj, void **request) +{ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_STATIC + + /* Sanity check */ + HDassert(grp_vol_obj); + + /* Close the group */ + if (H5VL_group_close(grp_vol_obj, H5P_DATASET_XFER_DEFAULT, request) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CLOSEERROR, FAIL, "unable to close group") + + /* Free the VOL object */ + if (H5VL_free_object(grp_vol_obj) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTDEC, FAIL, "unable to free VOL object") + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5G__close_cb() */ + /*------------------------------------------------------------------------- * Function: H5G__create_named * @@ -695,7 +876,7 @@ H5G_unmount(H5G_t *grp) } /* end H5G_unmount() */ /*------------------------------------------------------------------------- - * Function: H5G_iterate_cb + * Function: H5G__iterate_cb * * Purpose: Callback function for iterating over links in a group * @@ -708,12 +889,12 @@ H5G_unmount(H5G_t *grp) *------------------------------------------------------------------------- */ static herr_t -H5G_iterate_cb(const H5O_link_t *lnk, void *_udata) +H5G__iterate_cb(const H5O_link_t *lnk, void *_udata) { H5G_iter_appcall_ud_t *udata = (H5G_iter_appcall_ud_t *)_udata; /* User data for callback */ herr_t ret_value = H5_ITER_ERROR; /* Return value */ - FUNC_ENTER_NOAPI_NOINIT + FUNC_ENTER_STATIC /* Sanity check */ HDassert(lnk); @@ -744,7 +925,7 @@ H5G_iterate_cb(const H5O_link_t *lnk, void *_udata) done: FUNC_LEAVE_NOAPI(ret_value) -} /* end H5G_iterate_cb() */ +} /* end H5G__iterate_cb() */ /*------------------------------------------------------------------------- * Function: H5G_iterate @@ -791,7 +972,7 @@ H5G_iterate(H5G_loc_t *loc, const char *group_name, H5_index_t idx_type, H5_iter /* Call the real group iteration routine */ if ((ret_value = - H5G__obj_iterate(&(grp->oloc), idx_type, order, skip, last_lnk, H5G_iterate_cb, &udata)) < 0) + H5G__obj_iterate(&(grp->oloc), idx_type, order, skip, last_lnk, H5G__iterate_cb, &udata)) < 0) HGOTO_ERROR(H5E_SYM, H5E_BADITER, FAIL, "error iterating over links") done: @@ -807,7 +988,7 @@ done: } /* end H5G_iterate() */ /*------------------------------------------------------------------------- - * Function: H5G_free_visit_visited + * Function: H5G__free_visit_visited * * Purpose: Free the key for an object visited during a group traversal * @@ -819,17 +1000,17 @@ done: *------------------------------------------------------------------------- */ static herr_t -H5G_free_visit_visited(void *item, void H5_ATTR_UNUSED *key, void H5_ATTR_UNUSED *operator_data /*in,out*/) +H5G__free_visit_visited(void *item, void H5_ATTR_UNUSED *key, void H5_ATTR_UNUSED *operator_data /*in,out*/) { - FUNC_ENTER_NOAPI_NOINIT_NOERR + FUNC_ENTER_STATIC_NOERR item = H5FL_FREE(H5_obj_t, item); FUNC_LEAVE_NOAPI(SUCCEED) -} /* end H5G_free_visit_visited() */ +} /* end H5G__free_visit_visited() */ /*------------------------------------------------------------------------- - * Function: H5G_visit_cb + * Function: H5G__visit_cb * * Purpose: Callback function for recursively visiting links from a group * @@ -842,7 +1023,7 @@ H5G_free_visit_visited(void *item, void H5_ATTR_UNUSED *key, void H5_ATTR_UNUSED *------------------------------------------------------------------------- */ static herr_t -H5G_visit_cb(const H5O_link_t *lnk, void *_udata) +H5G__visit_cb(const H5O_link_t *lnk, void *_udata) { H5G_iter_visit_ud_t *udata = (H5G_iter_visit_ud_t *)_udata; /* User data for callback */ H5L_info2_t info; /* Link info */ @@ -855,7 +1036,7 @@ H5G_visit_cb(const H5O_link_t *lnk, void *_udata) size_t len_needed; /* Length of path string needed */ herr_t ret_value = H5_ITER_CONT; /* Return value */ - FUNC_ENTER_NOAPI_NOINIT + FUNC_ENTER_STATIC /* Sanity check */ HDassert(lnk); @@ -971,7 +1152,7 @@ H5G_visit_cb(const H5O_link_t *lnk, void *_udata) /* Iterate over links in group */ ret_value = H5G__obj_iterate(&obj_oloc, idx_type, udata->order, (hsize_t)0, NULL, - H5G_visit_cb, udata); + H5G__visit_cb, udata); /* Restore location */ udata->curr_loc = old_loc; @@ -989,7 +1170,7 @@ done: HDONE_ERROR(H5E_SYM, H5E_CANTRELEASE, H5_ITER_ERROR, "can't free location") FUNC_LEAVE_NOAPI(ret_value) -} /* end H5G_visit_cb() */ +} /* end H5G__visit_cb() */ /*------------------------------------------------------------------------- * Function: H5G_visit @@ -1113,14 +1294,14 @@ H5G_visit(H5G_loc_t *loc, const char *group_name, H5_index_t idx_type, H5_iter_o /* Call the link iteration routine */ if ((ret_value = - H5G__obj_iterate(&(grp->oloc), idx_type, order, (hsize_t)0, NULL, H5G_visit_cb, &udata)) < 0) + H5G__obj_iterate(&(grp->oloc), idx_type, order, (hsize_t)0, NULL, H5G__visit_cb, &udata)) < 0) HGOTO_ERROR(H5E_SYM, H5E_BADITER, FAIL, "can't visit links") done: /* Release user data resources */ H5MM_xfree(udata.path); if (udata.visited) - H5SL_destroy(udata.visited, H5G_free_visit_visited, NULL); + H5SL_destroy(udata.visited, H5G__free_visit_visited, NULL); /* Release the group opened */ if (gid != H5I_INVALID_HID) { diff --git a/src/H5Gnode.c b/src/H5Gnode.c index 9a7da0f..ba29b78 100644 --- a/src/H5Gnode.c +++ b/src/H5Gnode.c @@ -75,7 +75,7 @@ static herr_t H5G__node_create(H5F_t *f, H5B_ins_t op, void *_lt_key, void *_ haddr_t *addr_p /*out*/); static int H5G__node_cmp2(void *_lt_key, void *_udata, void *_rt_key); static int H5G__node_cmp3(void *_lt_key, void *_udata, void *_rt_key); -static htri_t H5G__node_found(H5F_t *f, haddr_t addr, const void *_lt_key, void *_udata); +static herr_t H5G__node_found(H5F_t *f, haddr_t addr, const void *_lt_key, hbool_t *found, void *_udata); static H5B_ins_t H5G__node_insert(H5F_t *f, haddr_t addr, void *_lt_key, hbool_t *lt_key_changed, void *_md_key, void *_udata, void *_rt_key, hbool_t *rt_key_changed, haddr_t *new_node_p /*out*/); @@ -463,8 +463,7 @@ done: * UDATA entry field to the symbol table. * * Return: Success: Non-negative (TRUE/FALSE) if found and data - * returned through the UDATA pointer. - * + * returned through the UDATA pointer, if *FOUND is true. * Failure: Negative if not found. * * Programmer: Robb Matzke @@ -472,15 +471,15 @@ done: * *------------------------------------------------------------------------- */ -static htri_t -H5G__node_found(H5F_t *f, haddr_t addr, const void H5_ATTR_UNUSED *_lt_key, void *_udata) +static herr_t +H5G__node_found(H5F_t *f, haddr_t addr, const void H5_ATTR_UNUSED *_lt_key, hbool_t *found, void *_udata) { H5G_bt_lkp_t *udata = (H5G_bt_lkp_t *)_udata; H5G_node_t * sn = NULL; unsigned lt = 0, idx = 0, rt; int cmp = 1; const char * s; - htri_t ret_value = TRUE; /* Return value */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_STATIC @@ -489,6 +488,7 @@ H5G__node_found(H5F_t *f, haddr_t addr, const void H5_ATTR_UNUSED *_lt_key, void */ HDassert(f); HDassert(H5F_addr_defined(addr)); + HDassert(found); HDassert(udata && udata->common.heap); /* @@ -515,11 +515,15 @@ H5G__node_found(H5F_t *f, haddr_t addr, const void H5_ATTR_UNUSED *_lt_key, void } /* end while */ if (cmp) - HGOTO_DONE(FALSE) + *found = FALSE; + else { + /* Set the 'found it' flag */ + *found = TRUE; - /* Call user's callback operator */ - if ((udata->op)(&sn->entry[idx], udata->op_data) < 0) - HGOTO_ERROR(H5E_SYM, H5E_BADITER, FAIL, "iterator callback failed") + /* Call user's callback operator */ + if ((udata->op)(&sn->entry[idx], udata->op_data) < 0) + HGOTO_ERROR(H5E_SYM, H5E_BADITER, FAIL, "iterator callback failed") + } /* end else */ done: if (sn && H5AC_unprotect(f, H5AC_SNODE, addr, sn, H5AC__NO_FLAGS_SET) < 0) diff --git a/src/H5Gobj.c b/src/H5Gobj.c index 3b6ebe6..1ca6b14 100644 --- a/src/H5Gobj.c +++ b/src/H5Gobj.c @@ -15,7 +15,7 @@ * * Created: H5Gobj.c * Sep 5 2005 - * Quincey Koziol <koziol@ncsa.uiuc.edu> + * Quincey Koziol * * Purpose: Functions for abstract handling of objects in groups. * @@ -80,7 +80,7 @@ typedef struct { /********************/ /* Local Prototypes */ /********************/ -static herr_t H5G_obj_compact_to_dense_cb(const void *_mesg, unsigned idx, void *_udata); +static herr_t H5G__obj_compact_to_dense_cb(const void *_mesg, unsigned idx, void *_udata); static herr_t H5G__obj_remove_update_linfo(const H5O_loc_t *oloc, H5O_linfo_t *linfo); /*********************/ @@ -103,7 +103,6 @@ static herr_t H5G__obj_remove_update_linfo(const H5O_loc_t *oloc, H5O_linfo_t *l * Return: Non-negative on success/Negative on failure * * Programmer: Quincey Koziol - * koziol@ncsa.uiuc.edu * Sep 29 2005 * *------------------------------------------------------------------------- @@ -157,7 +156,6 @@ done: * Return: Non-negative on success/Negative on failure * * Programmer: Quincey Koziol - * koziol@ncsa.uiuc.edu * Sep 29 2005 * *------------------------------------------------------------------------- @@ -287,7 +285,6 @@ done: * Failure: FAIL if error occurred * * Programmer: Quincey Koziol - * koziol@hdfgroup.org * Mar 11 2007 * *------------------------------------------------------------------------- @@ -342,7 +339,7 @@ done: } /* end H5G__obj_get_linfo() */ /*------------------------------------------------------------------------- - * Function: H5G_obj_compact_to_dense_cb + * Function: H5G__obj_compact_to_dense_cb * * Purpose: Callback routine for converting "compact" to "dense" * link storage form. @@ -350,19 +347,18 @@ done: * Return: Non-negative on success/Negative on failure * * Programmer: Quincey Koziol - * koziol@ncsa.uiuc.edu * Aug 30 2005 * *------------------------------------------------------------------------- */ static herr_t -H5G_obj_compact_to_dense_cb(const void *_mesg, unsigned H5_ATTR_UNUSED idx, void *_udata) +H5G__obj_compact_to_dense_cb(const void *_mesg, unsigned H5_ATTR_UNUSED idx, void *_udata) { const H5O_link_t * lnk = (const H5O_link_t *)_mesg; /* Pointer to link */ H5G_obj_oh_it_ud1_t *udata = (H5G_obj_oh_it_ud1_t *)_udata; /* 'User data' passed in */ herr_t ret_value = H5_ITER_CONT; /* Return value */ - FUNC_ENTER_NOAPI_NOINIT_TAG(udata->oh_addr) + FUNC_ENTER_STATIC /* check arguments */ HDassert(lnk); @@ -373,11 +369,11 @@ H5G_obj_compact_to_dense_cb(const void *_mesg, unsigned H5_ATTR_UNUSED idx, void HGOTO_ERROR(H5E_SYM, H5E_CANTINSERT, FAIL, "unable to insert link into dense storage") done: - FUNC_LEAVE_NOAPI_TAG(ret_value) -} /* end H5G_obj_compact_to_dense_cb() */ + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5G__obj_compact_to_dense_cb() */ /*------------------------------------------------------------------------- - * Function: H5G_obj_stab_to_new_cb + * Function: H5G__obj_stab_to_new_cb * * Purpose: Callback routine for converting "symbol table" link storage to * "new format" storage (either "compact" or "dense" storage). @@ -385,18 +381,17 @@ done: * Return: Non-negative on success/Negative on failure * * Programmer: Quincey Koziol - * koziol@hdfgroup.org * Sept 16 2006 * *------------------------------------------------------------------------- */ static herr_t -H5G_obj_stab_to_new_cb(const H5O_link_t *lnk, void *_udata) +H5G__obj_stab_to_new_cb(const H5O_link_t *lnk, void *_udata) { H5G_obj_stab_it_ud1_t *udata = (H5G_obj_stab_it_ud1_t *)_udata; /* 'User data' passed in */ herr_t ret_value = H5_ITER_CONT; /* Return value */ - FUNC_ENTER_NOAPI_NOINIT + FUNC_ENTER_STATIC /* check arguments */ HDassert(lnk); @@ -409,7 +404,7 @@ H5G_obj_stab_to_new_cb(const H5O_link_t *lnk, void *_udata) done: FUNC_LEAVE_NOAPI(ret_value) -} /* end H5G_obj_stab_to_new_cb() */ +} /* end H5G__obj_stab_to_new_cb() */ /*------------------------------------------------------------------------- * Function: H5G_obj_insert @@ -423,7 +418,6 @@ done: * Return: Non-negative on success/Negative on failure * * Programmer: Quincey Koziol - * koziol@ncsa.uiuc.edu * Sep 6 2005 * *------------------------------------------------------------------------- @@ -509,7 +503,7 @@ H5G_obj_insert(const H5O_loc_t *grp_oloc, const char *name, H5O_link_t *obj_lnk, /* Iterate over the 'link' messages, inserting them into the dense link storage */ op.op_type = H5O_MESG_OP_APP; - op.u.app_op = H5G_obj_compact_to_dense_cb; + op.u.app_op = H5G__obj_compact_to_dense_cb; if (H5O_msg_iterate(grp_oloc, H5O_LINK_ID, &op, &udata) < 0) HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "error iterating over links") @@ -542,7 +536,7 @@ H5G_obj_insert(const H5O_loc_t *grp_oloc, const char *name, H5O_link_t *obj_lnk, udata.grp_oloc = grp_oloc; /* Iterate through all links in "old format" group and insert them into new format */ - if (H5G__stab_iterate(grp_oloc, H5_ITER_NATIVE, (hsize_t)0, NULL, H5G_obj_stab_to_new_cb, + if (H5G__stab_iterate(grp_oloc, H5_ITER_NATIVE, (hsize_t)0, NULL, H5G__obj_stab_to_new_cb, &udata) < 0) HGOTO_ERROR(H5E_SYM, H5E_CANTNEXT, FAIL, "error iterating over old format links") @@ -691,7 +685,6 @@ done: * Return: Non-negative on success/Negative on failure * * Programmer: Quincey Koziol - * koziol@hdfgroup.org * Nov 27 2006 * *------------------------------------------------------------------------- @@ -1021,7 +1014,7 @@ H5G_obj_remove_by_idx(const H5O_loc_t *grp_oloc, H5RS_str_t *grp_full_path_r, H5 hbool_t use_old_format; /* Whether to use 'old format' (symbol table) for deletion or not */ herr_t ret_value = SUCCEED; /* Return value */ - FUNC_ENTER_NOAPI_TAG(grp_oloc->addr, FAIL) + FUNC_ENTER_NOAPI(FAIL) /* Sanity check */ HDassert(grp_oloc && grp_oloc->file); @@ -1071,7 +1064,7 @@ H5G_obj_remove_by_idx(const H5O_loc_t *grp_oloc, H5RS_str_t *grp_full_path_r, H5 HGOTO_ERROR(H5E_SYM, H5E_CANTUPDATE, FAIL, "unable to update link info") done: - FUNC_LEAVE_NOAPI_TAG(ret_value) + FUNC_LEAVE_NOAPI(ret_value) } /* end H5G_obj_remove() */ /*------------------------------------------------------------------------- @@ -1082,17 +1075,16 @@ done: * Return: Non-negative on success/Negative on failure * * Programmer: Quincey Koziol - * koziol@ncsa.uiuc.edu * Sep 26 2005 * *------------------------------------------------------------------------- */ -htri_t -H5G__obj_lookup(const H5O_loc_t *grp_oloc, const char *name, H5O_link_t *lnk) +herr_t +H5G__obj_lookup(const H5O_loc_t *grp_oloc, const char *name, hbool_t *found, H5O_link_t *lnk) { - H5O_linfo_t linfo; /* Link info message */ - htri_t linfo_exists; /* Whether the link info message exists */ - htri_t ret_value = FALSE; /* Return value */ + H5O_linfo_t linfo; /* Link info message */ + htri_t linfo_exists; /* Whether the link info message exists */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_PACKAGE_TAG(grp_oloc->addr) @@ -1107,18 +1099,18 @@ H5G__obj_lookup(const H5O_loc_t *grp_oloc, const char *name, H5O_link_t *lnk) /* Check for dense link storage */ if (H5F_addr_defined(linfo.fheap_addr)) { /* Get the object's info from the dense link storage */ - if ((ret_value = H5G__dense_lookup(grp_oloc->file, &linfo, name, lnk)) < 0) + if (H5G__dense_lookup(grp_oloc->file, &linfo, name, found, lnk) < 0) HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "can't locate object") } /* end if */ else { /* Get the object's info from the link messages */ - if ((ret_value = H5G__compact_lookup(grp_oloc, name, lnk)) < 0) + if (H5G__compact_lookup(grp_oloc, name, found, lnk) < 0) HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "can't locate object") } /* end else */ } /* end if */ else /* Get the object's info from the symbol table */ - if ((ret_value = H5G__stab_lookup(grp_oloc, name, lnk)) < 0) + if (H5G__stab_lookup(grp_oloc, name, found, lnk) < 0) HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "can't locate object") done: @@ -1134,7 +1126,6 @@ done: * Return: Non-negative on success/Negative on failure * * Programmer: Quincey Koziol - * koziol@hdfgroup.org * Nov 6 2006 * *------------------------------------------------------------------------- diff --git a/src/H5Goh.c b/src/H5Goh.c index ada4887..013ea3c 100644 --- a/src/H5Goh.c +++ b/src/H5Goh.c @@ -323,7 +323,7 @@ H5O__group_bh_info(const H5O_loc_t *loc, H5O_t *oh, H5_ih_info_t *bh_info) H5B2_t *bt2_corder = NULL; /* v2 B-tree handle for creation order index */ herr_t ret_value = SUCCEED; /* Return value */ - FUNC_ENTER_STATIC_TAG(oh->cache_info.addr) + FUNC_ENTER_STATIC /* Sanity check */ HDassert(loc); @@ -398,5 +398,5 @@ done: if (bt2_corder && H5B2_close(bt2_corder) < 0) HDONE_ERROR(H5E_SYM, H5E_CANTCLOSEOBJ, FAIL, "can't close v2 B-tree for creation order index") - FUNC_LEAVE_NOAPI_TAG(ret_value) + FUNC_LEAVE_NOAPI(ret_value) } /* end H5O__group_bh_info() */ diff --git a/src/H5Gpkg.h b/src/H5Gpkg.h index 38fb603..86b6e1b 100644 --- a/src/H5Gpkg.h +++ b/src/H5Gpkg.h @@ -30,12 +30,12 @@ #include "H5Gprivate.h" /* Other private headers needed by this file */ -#include "H5B2private.h" /* v2 B-trees */ +#include "H5B2private.h" /* v2 B-trees */ #include "H5FLprivate.h" /* Free Lists */ -#include "H5HFprivate.h" /* Fractal heaps */ -#include "H5HLprivate.h" /* Local Heaps */ -#include "H5Oprivate.h" /* Object headers */ -#include "H5SLprivate.h" /* Skip lists */ +#include "H5HFprivate.h" /* Fractal heaps */ +#include "H5HLprivate.h" /* Local Heaps */ +#include "H5Oprivate.h" /* Object headers */ +#include "H5SLprivate.h" /* Skip lists */ /**************************/ /* Package Private Macros */ @@ -46,10 +46,11 @@ /* Size of a symbol table node on disk */ #define H5G_NODE_SIZE(f) \ - ( /* General metadata fields */ \ - H5_SIZEOF_MAGIC + 1 /* Version */ \ - + 1 /* Reserved */ \ - + 2 /* Number of symbols */ \ + ( /* General metadata fields */ \ + H5_SIZEOF_MAGIC /*magic number */ \ + + 1 /* Version */ \ + + 1 /* Reserved */ \ + + 2 /* Number of symbols */ \ \ /* Entries */ \ + ((2 * H5F_SYM_LEAF_K(f)) * (unsigned)H5G_SIZEOF_ENTRY_FILE(f))) @@ -65,10 +66,10 @@ * symbol table entry. */ typedef enum H5G_cache_type_t { - H5G_CACHED_ERROR = -1, /*force enum to be signed */ + H5G_CACHED_ERROR = -1, /*force enum to be signed */ H5G_NOTHING_CACHED = 0, /*nothing is cached, must be 0 */ H5G_CACHED_STAB = 1, /*symbol table, `stab' */ - H5G_CACHED_SLINK = 2, /*symbolic link */ + H5G_CACHED_SLINK = 2, /*symbolic link */ H5G_NCACHED /*THIS MUST BE LAST */ } H5G_cache_type_t; @@ -87,7 +88,7 @@ typedef union H5G_cache_t { } stab; struct { - size_t lval_offset; /*link value offset */ + size_t lval_offset; /*link value offset */ } slink; } H5G_cache_t; @@ -156,7 +157,7 @@ typedef struct { typedef struct H5G_bt_common_t { /* downward */ const char *name; /*points to temporary memory */ - H5HL_t * heap; /*symbol table heap */ + H5HL_t * heap; /*symbol table heap */ } H5G_bt_common_t; /* @@ -203,10 +204,10 @@ typedef struct H5G_bt_lkp_t { */ typedef struct H5G_bt_it_it_t { /* downward */ - H5HL_t * heap; /*symbol table heap */ - hsize_t skip; /*initial entries to skip */ - H5G_lib_iterate_t op; /*iteration operator */ - void * op_data; /*user-defined operator data */ + H5HL_t * heap; /*symbol table heap */ + hsize_t skip; /*initial entries to skip */ + H5G_lib_iterate_t op; /*iteration operator */ + void * op_data; /*user-defined operator data */ /* upward */ hsize_t *final_ent; /*final entry looked at */ @@ -363,7 +364,7 @@ H5_DLL ssize_t H5G__stab_get_name_by_idx(const H5O_loc_t *oloc, H5_iter_order_t H5_DLL herr_t H5G__stab_remove(const H5O_loc_t *oloc, H5RS_str_t *grp_full_path_r, const char *name); H5_DLL herr_t H5G__stab_remove_by_idx(const H5O_loc_t *oloc, H5RS_str_t *grp_full_path_r, H5_iter_order_t order, hsize_t n); -H5_DLL herr_t H5G__stab_lookup(const H5O_loc_t *grp_oloc, const char *name, H5O_link_t *lnk); +H5_DLL herr_t H5G__stab_lookup(const H5O_loc_t *grp_oloc, const char *name, hbool_t *found, H5O_link_t *lnk); H5_DLL herr_t H5G__stab_lookup_by_idx(const H5O_loc_t *grp_oloc, H5_iter_order_t order, hsize_t n, H5O_link_t *lnk); #ifndef H5_STRICT_FORMAT_CHECKS @@ -416,7 +417,8 @@ H5_DLL herr_t H5G__compact_remove_by_idx(const H5O_loc_t *oloc, const H5O_linfo H5_DLL herr_t H5G__compact_iterate(const H5O_loc_t *oloc, const H5O_linfo_t *linfo, H5_index_t idx_type, H5_iter_order_t order, hsize_t skip, hsize_t *last_lnk, H5G_lib_iterate_t op, void *op_data); -H5_DLL htri_t H5G__compact_lookup(const H5O_loc_t *grp_oloc, const char *name, H5O_link_t *lnk); +H5_DLL herr_t H5G__compact_lookup(const H5O_loc_t *grp_oloc, const char *name, hbool_t *found, + H5O_link_t *lnk); H5_DLL herr_t H5G__compact_lookup_by_idx(const H5O_loc_t *oloc, const H5O_linfo_t *linfo, H5_index_t idx_type, H5_iter_order_t order, hsize_t n, H5O_link_t *lnk); @@ -425,7 +427,8 @@ H5_DLL herr_t H5G__dense_build_table(H5F_t *f, const H5O_linfo_t *linfo, H5_ind H5_iter_order_t order, H5G_link_table_t *ltable); H5_DLL herr_t H5G__dense_create(H5F_t *f, H5O_linfo_t *linfo, const H5O_pline_t *pline); H5_DLL herr_t H5G__dense_insert(H5F_t *f, const H5O_linfo_t *linfo, const H5O_link_t *lnk); -H5_DLL htri_t H5G__dense_lookup(H5F_t *f, const H5O_linfo_t *linfo, const char *name, H5O_link_t *lnk); +H5_DLL herr_t H5G__dense_lookup(H5F_t *f, const H5O_linfo_t *linfo, const char *name, hbool_t *found, + H5O_link_t *lnk); H5_DLL herr_t H5G__dense_lookup_by_idx(H5F_t *f, const H5O_linfo_t *linfo, H5_index_t idx_type, H5_iter_order_t order, hsize_t n, H5O_link_t *lnk); H5_DLL herr_t H5G__dense_iterate(H5F_t *f, const H5O_linfo_t *linfo, H5_index_t idx_type, @@ -448,7 +451,7 @@ H5_DLL htri_t H5G__obj_get_linfo(const H5O_loc_t *grp_oloc, H5O_linfo_t *linfo); H5_DLL herr_t H5G__obj_iterate(const H5O_loc_t *grp_oloc, H5_index_t idx_type, H5_iter_order_t order, hsize_t skip, hsize_t *last_lnk, H5G_lib_iterate_t op, void *op_data); H5_DLL herr_t H5G__obj_info(const H5O_loc_t *oloc, H5G_info_t *grp_info); -H5_DLL htri_t H5G__obj_lookup(const H5O_loc_t *grp_oloc, const char *name, H5O_link_t *lnk); +H5_DLL herr_t H5G__obj_lookup(const H5O_loc_t *grp_oloc, const char *name, hbool_t *found, H5O_link_t *lnk); #ifndef H5_NO_DEPRECATED_SYMBOLS H5_DLL herr_t H5G__get_objinfo(const H5G_loc_t *loc, const char *name, hbool_t follow_link, H5G_stat_t *statbuf /*out*/); diff --git a/src/H5Gprivate.h b/src/H5Gprivate.h index f2d38d5..409d790 100644 --- a/src/H5Gprivate.h +++ b/src/H5Gprivate.h @@ -29,9 +29,9 @@ #include "H5Gpublic.h" /* Private headers needed by this file */ -#include "H5private.h" /* Generic Functions */ -#include "H5Bprivate.h" /* B-trees */ -#include "H5Fprivate.h" /* File access */ +#include "H5private.h" /* Generic Functions */ +#include "H5Bprivate.h" /* B-trees */ +#include "H5Fprivate.h" /* File access */ #include "H5RSprivate.h" /* Reference-counted strings */ /* @@ -42,7 +42,7 @@ ((sizeof_size) + /*offset of name into heap */ \ (sizeof_addr) + /*address of object header */ \ 4 + /*entry type */ \ - 4 + /*reserved */ \ + 4 + /*reserved */ \ H5G_SIZEOF_SCRATCH) /*scratch pad space */ #define H5G_SIZEOF_ENTRY_FILE(F) H5G_SIZEOF_ENTRY(H5F_SIZEOF_ADDR(F), H5F_SIZEOF_SIZE(F)) @@ -60,12 +60,16 @@ /* Definitions for link info settings */ #define H5G_CRT_LINK_INFO_NAME "link info" #define H5G_CRT_LINK_INFO_SIZE sizeof(H5O_linfo_t) -#define H5G_CRT_LINK_INFO_DEF \ - { \ - H5G_CRT_LINFO_TRACK_CORDER, H5G_CRT_LINFO_INDEX_CORDER, H5G_CRT_LINFO_MAX_CORDER, \ - H5G_CRT_LINFO_CORDER_BT2_ADDR, H5G_CRT_LINFO_NLINKS, H5G_CRT_LINFO_LINK_FHEAP_ADDR, \ - H5G_CRT_LINFO_NAME_BT2_ADDR \ - } +/* clang-format off */ +#define H5G_CRT_LINK_INFO_DEF {H5G_CRT_LINFO_TRACK_CORDER, \ + H5G_CRT_LINFO_INDEX_CORDER, \ + H5G_CRT_LINFO_MAX_CORDER, \ + H5G_CRT_LINFO_CORDER_BT2_ADDR, \ + H5G_CRT_LINFO_NLINKS, \ + H5G_CRT_LINFO_LINK_FHEAP_ADDR, \ + H5G_CRT_LINFO_NAME_BT2_ADDR \ + } +/* clang-format on */ /* Defaults for group info values */ #define H5G_CRT_GINFO_LHEAP_SIZE_HINT 0 @@ -79,12 +83,16 @@ /* Definitions for group info settings */ #define H5G_CRT_GROUP_INFO_NAME "group info" #define H5G_CRT_GROUP_INFO_SIZE sizeof(H5O_ginfo_t) -#define H5G_CRT_GROUP_INFO_DEF \ - { \ - H5G_CRT_GINFO_LHEAP_SIZE_HINT, H5G_CRT_GINFO_STORE_LINK_PHASE_CHANGE, H5G_CRT_GINFO_MAX_COMPACT, \ - H5G_CRT_GINFO_MIN_DENSE, H5G_CRT_GINFO_STORE_EST_ENTRY_INFO, H5G_CRT_GINFO_EST_NUM_ENTRIES, \ - H5G_CRT_GINFO_EST_NAME_LEN \ - } +/* clang-format off */ +#define H5G_CRT_GROUP_INFO_DEF {H5G_CRT_GINFO_LHEAP_SIZE_HINT, \ + H5G_CRT_GINFO_STORE_LINK_PHASE_CHANGE, \ + H5G_CRT_GINFO_MAX_COMPACT, \ + H5G_CRT_GINFO_MIN_DENSE, \ + H5G_CRT_GINFO_STORE_EST_ENTRY_INFO, \ + H5G_CRT_GINFO_EST_NUM_ENTRIES, \ + H5G_CRT_GINFO_EST_NAME_LEN \ + } +/* clang-format on */ /* If the module using this macro is allowed access to the private variables, access them directly */ #ifdef H5G_MODULE diff --git a/src/H5Gpublic.h b/src/H5Gpublic.h index 99134f8..b009d41 100644 --- a/src/H5Gpublic.h +++ b/src/H5Gpublic.h @@ -41,22 +41,31 @@ /* Public Typedefs */ /*******************/ -/* Types of link storage for groups */ +//! <!-- [H5G_storage_t_snip] --> +/** + * Types of link storage for groups + */ typedef enum H5G_storage_type_t { - H5G_STORAGE_TYPE_UNKNOWN = -1, /* Unknown link storage type */ - H5G_STORAGE_TYPE_SYMBOL_TABLE, /* Links in group are stored with a "symbol table" */ - /* (this is sometimes called "old-style" groups) */ - H5G_STORAGE_TYPE_COMPACT, /* Links are stored in object header */ - H5G_STORAGE_TYPE_DENSE /* Links are stored in fractal heap & indexed with v2 B-tree */ + H5G_STORAGE_TYPE_UNKNOWN = -1, /**< Unknown link storage type */ + H5G_STORAGE_TYPE_SYMBOL_TABLE, /**< Links in group are stored with a "symbol table" */ + /**< (this is sometimes called "old-style" groups) */ + H5G_STORAGE_TYPE_COMPACT, /**< Links are stored in object header */ + H5G_STORAGE_TYPE_DENSE /**< Links are stored in fractal heap & indexed with v2 B-tree */ } H5G_storage_type_t; +//! <!-- [H5G_storage_t_snip] --> -/* Information struct for group (for H5Gget_info/H5Gget_info_by_name/H5Gget_info_by_idx) */ +//! <!-- [H5G_info_t_snip] --> +/** + * Information struct for group for + * H5Gget_info(), H5Gget_info_by_name(), and H5Gget_info_by_idx() + */ typedef struct H5G_info_t { - H5G_storage_type_t storage_type; /* Type of storage for links in group */ - hsize_t nlinks; /* Number of links in group */ - int64_t max_corder; /* Current max. creation order value for group */ - hbool_t mounted; /* Whether group has a file mounted on it */ + H5G_storage_type_t storage_type; /**< Type of storage for links in group */ + hsize_t nlinks; /**< Number of links in group */ + int64_t max_corder; /**< Current max. creation order value for group */ + hbool_t mounted; /**< Whether group has a file mounted on it */ } H5G_info_t; +//! <!-- [H5G_info_t_snip] --> /********************/ /* Public Variables */ @@ -69,18 +78,417 @@ typedef struct H5G_info_t { extern "C" { #endif -H5_DLL hid_t H5Gcreate2(hid_t loc_id, const char *name, hid_t lcpl_id, hid_t gcpl_id, hid_t gapl_id); -H5_DLL hid_t H5Gcreate_anon(hid_t loc_id, hid_t gcpl_id, hid_t gapl_id); -H5_DLL hid_t H5Gopen2(hid_t loc_id, const char *name, hid_t gapl_id); -H5_DLL hid_t H5Gget_create_plist(hid_t group_id); +/** + *------------------------------------------------------------------------- + * \ingroup H5G + * + * \brief Creates a new group and links it into the file + * + * \fgdta_loc_id + * \param[in] name Name of the group to create + * \lcpl_id + * \gcpl_id + * \gapl_id + * + * \return \hid_t{group} + * + * \details H5Gcreate2() creates a new group in a file. After a + * group has been created, links to datasets and to other groups + * can be added. + * + * The \p loc_id and \p name parameters specify where the group + * is located. \p loc_id may be a file, group, dataset, named + * datatype or attribute in the file. If an attribute, dataset, + * or named datatype is specified for \p loc_id then the group + * will be created at the location where the attribute, dataset, + * or named datatype is attached. \p name is the link to the group; + * \p name may be either an absolute path in the file (the links + * from the root group to the new group) or a relative path from + * \p loc_id (the link(s) from the group specified by \p loc_id + * to the new group). + * + * \p lcpl_id, \p gcpl_id, and \p gapl_id are property list + * identifiers. These property lists govern how the link to the + * group is created, how the group is created, and how the group + * can be accessed in the future, respectively. #H5P_DEFAULT can + * be passed in if the default properties are appropriate for + * these property lists. Currently, there are no APIs for the + * group access property list; use #H5P_DEFAULT. + * + * The group identifier should be closed by H5Gclose() when access + * is no longer required to prevent resource leaks. + * + * \since 1.8.0 + * + * \see H5Gopen2(), H5Gclose() + * + */ +H5_DLL hid_t H5Gcreate2(hid_t loc_id, const char *name, hid_t lcpl_id, hid_t gcpl_id, hid_t gapl_id); + +/** + * -------------------------------------------------------------------------- + * \ingroup ASYNC + * \async_variant_of{H5Gcreate} + */ +H5_DLL hid_t H5Gcreate_async(const char *app_file, const char *app_func, unsigned app_line, hid_t loc_id, + const char *name, hid_t lcpl_id, hid_t gcpl_id, hid_t gapl_id, hid_t es_id); + +/** + *------------------------------------------------------------------------- + * \ingroup H5G + * + * \brief Creates a new empty group without linking it into the file structure + * + * \fgdta_loc_id + * \gcpl_id + * \gapl_id + * + * \return \hid_t{group} + * + * \details H5Gcreate_anon() creates a new empty group in the file + * specified by \p loc_id. With default settings, H5Gcreate_anon() + * provides similar functionality to that provided by + * H5Gcreate1(), with the differences described in the list below. + * + * The new group’s creation and access properties are specified + * in \p gcpl_id and \p gapl_id, respectively. + * + * H5Gcreate_anon() returns a new group identifier. This identifier + * must be linked into the HDF5 file structure with H5Olink() + * or it will be deleted from the file when the file is closed. + * + * The differences between this function and H5Gcreate1() are + * as follows: + * + * \li H5Gcreate1() does not provide for the use of custom property + * lists; H5Gcreate1() always uses default properties. + * \li H5Gcreate_anon() neither provides the new group’s name + * nor links it into the HDF5 file structure; those actions + * must be performed separately through a call to H5Olink(), + * which offers greater control over linking. + * \li H5Gcreate_anon() does not directly provide a hint mechanism + * for the group’s heap size. Comparable information can be + * included in the group creation property list \p gcpl_id through + * a H5Pset_local_heap_size_hint() call. + * + * A group created with this function should be closed with + * H5Gclose() when the group is no longer needed so that resource + * leaks will not develop. + * + * \see H5Olink(), H5Dcreate(), Using Identifiers + * + * \since 1.8.0 + * + */ +H5_DLL hid_t H5Gcreate_anon(hid_t loc_id, hid_t gcpl_id, hid_t gapl_id); + +/** + *------------------------------------------------------------------------- + * \ingroup H5G + * + * \brief Opens an existing group in a file + * + * \fgdta_loc_id + * \param[in] name Name of the group to open + * \gapl_id + * + * \return \hid_t{group} + * + * \details H5Gopen2() opens an existing group, \p name, at the location + * specified by \p loc_id. + * + * With default settings, H5Gopen2() provides similar functionality + * to that provided by H5Gopen(). The only difference is that + * H5Gopen2() can provide a group access property list, \p gapl_id. + * + * H5Gopen2() returns a group identifier for the group that was + * opened. This group identifier should be released by H5Gclose() + * when it is no longer needed to prevent resource leaks. + * + * \since 1.8.0 + * + * \see H5Gcreate2(), H5Gclose() + * + */ +H5_DLL hid_t H5Gopen2(hid_t loc_id, const char *name, hid_t gapl_id); + +/** + * -------------------------------------------------------------------------- + * \ingroup ASYNC + * \async_variant_of{H5Gopen} + */ +H5_DLL hid_t H5Gopen_async(const char *app_file, const char *app_func, unsigned app_line, hid_t loc_id, + const char *name, hid_t gapl_id, hid_t es_id); + +/** + *------------------------------------------------------------------------- + * \ingroup H5G + * + * \brief Gets a group creation property list identifier + * + * \group_id + * + * \return \hid_t{creation property list} + * + * \details H5Gget_create_plist() returns an identifier for the group creation + * property list associated with the group specified by \p group_id. + * + * The creation property list identifier should be released with + * H5Gclose() to prevent resource leaks. + * + * \since 1.8.0 + * + * \see H5Gcreate2(), H5Gclose() + * + */ +H5_DLL hid_t H5Gget_create_plist(hid_t group_id); + +/** + *------------------------------------------------------------------------- + * \ingroup H5G + * + * \brief Retrieves information about a group + * + * \fgdta_loc_id + * \param[out] ginfo Struct in which group information is returned + * + * \return \hid_t{group} + * + * \details H5Gget_info() retrieves information about the group at location + * specified by \p loc_id. The information is returned in the \p ginfo. + * + * \p ginfo is an H5G_info_t struct and is defined (in H5Gpublic.h) + * as follows: + * + * \snippet this H5G_info_t_snip + * Possible values of \p storage_type are: + * \storage_type + * + * \since 1.8.0 + * + * \see H5Gcreate2(), H5Gclose() + * + */ H5_DLL herr_t H5Gget_info(hid_t loc_id, H5G_info_t *ginfo); + +/** + * -------------------------------------------------------------------------- + * \ingroup ASYNC + * \async_variant_of{H5Gget_info} + */ +H5_DLL herr_t H5Gget_info_async(const char *app_file, const char *app_func, unsigned app_line, hid_t loc_id, + H5G_info_t *ginfo /*out*/, hid_t es_id); + +/** + *------------------------------------------------------------------------- + * \ingroup H5G + * + * \brief Retrieves information about a group by its name + * + * \fgdta_loc_id + * \param[in] name Name of the group to query + * \param[out] ginfo Struct in which group information is returned + * \lapl_id + * + * \return \herr_t + * + * \details H5Gget_info_by_name() retrieves information about the group \p name + * at location specified by \p loc_id. The information is returned in + * the \p ginfo struct. + * + * If \p loc_id specifies the group for which information is queried, + * then the group's \p name can be a dot (.). + * + * \p ginfo is an H5G_info_t struct and is defined (in H5Gpublic.h) + * as follows: + * + * \snippet this H5G_info_t_snip + * Possible values of \p storage_type are: + * \storage_type + * + * \since 1.8.0 + * + * \see H5Gcreate2(), H5Gclose() + * + */ H5_DLL herr_t H5Gget_info_by_name(hid_t loc_id, const char *name, H5G_info_t *ginfo, hid_t lapl_id); + +/** + * -------------------------------------------------------------------------- + * \ingroup ASYNC + * \async_variant_of{H5Gget_info_by_name} + */ +H5_DLL herr_t H5Gget_info_by_name_async(const char *app_file, const char *app_func, unsigned app_line, + hid_t loc_id, const char *name, H5G_info_t *ginfo /*out*/, + hid_t lapl_id, hid_t es_id); + +/** + *------------------------------------------------------------------------- + * \ingroup H5G + * + * \brief Retrieves information about a group, according to the group’s + * position within an index + * + * \fgdta_loc_id + * \param[in] group_name Name of the group to query + * \param[in] idx_type Transient index identifying object + * \param[in] order Transient index identifying object + * \param[in] n Position in the index of the group to query + * \param[out] ginfo Struct in which group information is returned + * \lapl_id + * + * \return Returns + * \li The size of the object name if successful, or + * \li 0 if no name is associated with the group identifier, or + * \li negative value, if failure occurred + * + * \details H5Gget_info_by_idx() retrieves the same information + * about a group as retrieved by the function H5Gget_info(), + * but the means of identifying the group differs; the group is + * identified by position in an index rather than by name. + * + * \p loc_id and \p group_name specify the group containing + * the group for which information is sought. The groups in \p + * group_name are indexed by \p idx_type; the group for which + * information is retrieved is identified in that index by index + * order, \p order, and index position, \p n. + * + * If \p loc_id specifies the group containing the group for + * which information is queried, \p group_name can be a dot (.). + * + * Valid values for \p index_type are as follows: + * \indexes + * The order in which the index is to be examined, as specified + * by \p order, can be one of the following: + * \orders + * + * \since 1.8.0 + * + * \see H5Gcreate2(), H5Gclose() + * + */ H5_DLL herr_t H5Gget_info_by_idx(hid_t loc_id, const char *group_name, H5_index_t idx_type, H5_iter_order_t order, hsize_t n, H5G_info_t *ginfo, hid_t lapl_id); -H5_DLL herr_t H5Gclose(hid_t group_id); + +/** + * -------------------------------------------------------------------------- + * \ingroup ASYNC + * \async_variant_of{H5Gget_info_by_idx} + */ +H5_DLL herr_t H5Gget_info_by_idx_async(const char *app_file, const char *app_func, unsigned app_line, + hid_t loc_id, const char *group_name, H5_index_t idx_type, + H5_iter_order_t order, hsize_t n, H5G_info_t *ginfo /*out*/, + hid_t lapl_id, hid_t es_id); + +/** + *------------------------------------------------------------------------- + * \ingroup H5G + * + * \brief Flushes all buffers associated with a group to disk + * + * \group_id + * + * \return \herr_t + * + * \details H5Gflush() causes all buffers associated with a group to be + * immediately flushed to disk without removing the data from + * the cache. + * + * \attention + * HDF5 does not possess full control over buffering. H5G_FLUSH + * flushes the internal HDF5 buffers and then asks the operating + * system (the OS) to flush the system buffers for the open + * files. After that, the OS is responsible for ensuring that + * the data is actually flushed to disk. + * + * \since 1.8.0 + * + * \see H5Gcreate2(), H5Gclose() + * + */ H5_DLL herr_t H5Gflush(hid_t group_id); + +/** + *------------------------------------------------------------------------- + * \ingroup H5G + * + * \brief Refreshes all buffers associated with a group + * + * \group_id + * + * \return \herr_t + * + * \details H5Grefresh() causes all buffers associated with a group to be + * cleared and immediately re-loaded with updated contents from disk. + * + * This function essentially closes the group, evicts all + * metadata associated with it from the cache, and then re-opens + * the group. The reopened group is automatically re-registered + * with the same identifier. + * + * \since 1.8.0 + * + * \see H5Gcreate2(), H5Gclose() + * + */ H5_DLL herr_t H5Grefresh(hid_t group_id); +/** + *------------------------------------------------------------------------- + * \ingroup H5G + * + * \brief Closes the specified group + * + * \group_id + * + * \return \herr_t + * + * \details H5Gclose() releases resources used by a group which was + * opened by H5Gcreate() or H5Gopen(). After closing a group, + * \p group_id cannot be used again until another H5Gcreate() + * or H5Gopen() is called on it. + * + * Failure to release a group with this call will result in + * resource leaks. + * + * \par Example + * \snippet H5F_examples.c mount + * + * \since 1.0.0 + * + */ +H5_DLL herr_t H5Gclose(hid_t group_id); + +/** + * -------------------------------------------------------------------------- + * \ingroup ASYNC + * \async_variant_of{H5Gclose} + */ +H5_DLL herr_t H5Gclose_async(const char *app_file, const char *app_func, unsigned app_line, hid_t group_id, + hid_t es_id); + +/* API Wrappers for async routines */ +/* (Must be defined _after_ the function prototype) */ +/* (And must only defined when included in application code, not the library) */ +#ifndef H5G_MODULE +#define H5Gcreate_async(...) H5Gcreate_async(__FILE__, __func__, __LINE__, __VA_ARGS__) +#define H5Gopen_async(...) H5Gopen_async(__FILE__, __func__, __LINE__, __VA_ARGS__) +#define H5Gget_info_async(...) H5Gget_info_async(__FILE__, __func__, __LINE__, __VA_ARGS__) +#define H5Gget_info_by_name_async(...) H5Gget_info_by_name_async(__FILE__, __func__, __LINE__, __VA_ARGS__) +#define H5Gget_info_by_idx_async(...) H5Gget_info_by_idx_async(__FILE__, __func__, __LINE__, __VA_ARGS__) +#define H5Gclose_async(...) H5Gclose_async(__FILE__, __func__, __LINE__, __VA_ARGS__) + +/* Define "wrapper" versions of function calls, to allow compile-time values to + * be passed in by language wrapper or library layer on top of HDF5. + */ +#define H5Gcreate_async_wrap H5_NO_EXPAND(H5Gcreate_async) +#define H5Gopen_async_wrap H5_NO_EXPAND(H5Gopen_async) +#define H5Gget_info_async_wrap H5_NO_EXPAND(H5Gget_info_async) +#define H5Gget_info_by_name_async_wrap H5_NO_EXPAND(H5Gget_info_by_name_async) +#define H5Gget_info_by_idx_async_wrap H5_NO_EXPAND(H5Gget_info_by_idx_async) +#define H5Gclose_async_wrap H5_NO_EXPAND(H5Gclose_async) +#endif /* H5G_MODULE */ + /* Symbols defined for compatibility with previous versions of the HDF5 API. * * Use of these symbols is deprecated. @@ -104,56 +512,647 @@ H5_DLL herr_t H5Grefresh(hid_t group_id); /* Typedefs */ -/* +//! <!-- [H5G_obj_t_snip] --> +/** * An object has a certain type. The first few numbers are reserved for use * internally by HDF5. Users may add their own types with higher values. The - * values are never stored in the file -- they only exist while an - * application is running. An object may satisfy the `isa' function for more - * than one type. + * values are never stored in the file -- they only exist while an application + * is running. An object may satisfy the `isa' function for more than one type. + * + * \deprecated */ typedef enum H5G_obj_t { - H5G_UNKNOWN = -1, /* Unknown object type */ - H5G_GROUP, /* Object is a group */ - H5G_DATASET, /* Object is a dataset */ - H5G_TYPE, /* Object is a named data type */ - H5G_LINK, /* Object is a symbolic link */ - H5G_UDLINK, /* Object is a user-defined link */ - H5G_RESERVED_5, /* Reserved for future use */ - H5G_RESERVED_6, /* Reserved for future use */ - H5G_RESERVED_7 /* Reserved for future use */ + H5G_UNKNOWN = -1, /**< Unknown object type */ + H5G_GROUP, /**< Object is a group */ + H5G_DATASET, /**< Object is a dataset */ + H5G_TYPE, /**< Object is a named data type */ + H5G_LINK, /**< Object is a symbolic link */ + H5G_UDLINK, /**< Object is a user-defined link */ + H5G_RESERVED_5, /**< Reserved for future use */ + H5G_RESERVED_6, /**< Reserved for future use */ + H5G_RESERVED_7 /**< Reserved for future use */ } H5G_obj_t; +//! <!-- [H5G_obj_t_snip] --> -/* Prototype for H5Giterate() operator */ +//! <!-- [H5G_iterate_t_snip] --> +/** + * Callback for H5Giterate() + * + * \deprecated + */ typedef herr_t (*H5G_iterate_t)(hid_t group, const char *name, void *op_data); +//! <!-- [H5G_iterate_t_snip] --> -/* Information about an object */ +//! <!-- [H5G_stat_t_snip] --> +/** + * Information about an object + * + * \deprecated + */ typedef struct H5G_stat_t { - unsigned long fileno[2]; /*file number */ - unsigned long objno[2]; /*object number */ - unsigned nlink; /*number of hard links to object*/ - H5G_obj_t type; /*basic object type */ - time_t mtime; /*modification time */ - size_t linklen; /*symbolic link value length */ - H5O_stat_t ohdr; /* Object header information */ + unsigned long fileno[2]; /**< file number */ + unsigned long objno[2]; /**< object number */ + unsigned nlink; /**< number of hard links to object*/ + H5G_obj_t type; /**< basic object type */ + time_t mtime; /**< modification time */ + size_t linklen; /**< symbolic link value length */ + H5O_stat_t ohdr; /**< Object header information */ } H5G_stat_t; +//! <!-- [H5G_stat_t_snip] --> /* Function prototypes */ -H5_DLL hid_t H5Gcreate1(hid_t loc_id, const char *name, size_t size_hint); -H5_DLL hid_t H5Gopen1(hid_t loc_id, const char *name); -H5_DLL herr_t H5Glink(hid_t cur_loc_id, H5G_link_t type, const char *cur_name, const char *new_name); -H5_DLL herr_t H5Glink2(hid_t cur_loc_id, const char *cur_name, H5G_link_t type, hid_t new_loc_id, - const char *new_name); -H5_DLL herr_t H5Gmove(hid_t src_loc_id, const char *src_name, const char *dst_name); -H5_DLL herr_t H5Gmove2(hid_t src_loc_id, const char *src_name, hid_t dst_loc_id, const char *dst_name); -H5_DLL herr_t H5Gunlink(hid_t loc_id, const char *name); -H5_DLL herr_t H5Gget_linkval(hid_t loc_id, const char *name, size_t size, char *buf /*out*/); -H5_DLL herr_t H5Gset_comment(hid_t loc_id, const char *name, const char *comment); -H5_DLL int H5Gget_comment(hid_t loc_id, const char *name, size_t bufsize, char *buf); -H5_DLL herr_t H5Giterate(hid_t loc_id, const char *name, int *idx, H5G_iterate_t op, void *op_data); -H5_DLL herr_t H5Gget_num_objs(hid_t loc_id, hsize_t *num_objs); -H5_DLL herr_t H5Gget_objinfo(hid_t loc_id, const char *name, hbool_t follow_link, - H5G_stat_t *statbuf /*out*/); -H5_DLL ssize_t H5Gget_objname_by_idx(hid_t loc_id, hsize_t idx, char *name, size_t size); +/** + *------------------------------------------------------------------------- + * \ingroup H5G + * + * \brief Creates a new group and links it into the file + * + * \fgdta_loc_id + * \param[in] name Name of the group to create + * \param[in] size_hint The number of bytes to reserve for the names + * that will appear in the group + * + * \return \hid_t{group} + * + * \deprecated This function is deprecated in favor of H5Gcreate2(). + * + * \details H5Gcreate1() creates a new group with the specified name at the + * specified location, \p loc_id. \p loc_id may be a file, group, + * dataset, named datatype or attribute. If an attribute, dataset, or + * named datatype is specified for \p loc_id then the group will be + * created at the location where the attribute, dataset, or named + * datatype is attached. The name, name, must not already be taken by + * some other object and all parent groups must already exist. + * + * \p name can be a relative path based at \p loc_id or an absolute + * path from the root of the file. Use of this function requires that + * any intermediate groups specified in the path already exist. + * + * The length of a group name, or of the name of any object within a + * group, is not limited. + * + * \p size_hint is a hint for the number of bytes to reserve to store + * the names which will be eventually added to the new group. This + * value must be between 0 and UINT32_MAX (inclusive). If this + * parameter is zero, a default value will be used. + * + * The return value is a group identifier for the open group. This + * group identifier should be closed by calling H5Gclose() when it is + * no longer needed. + * + * See H5Gcreate_anon() for a discussion of the differences between + * H5Gcreate1() and H5Gcreate_anon(). + * + * \par Example + * \snippet H5F_examples.c mount + * + * \version 1.8.0 Function H5Gcreate() renamed to H5Gcreate1() and deprecated + * in this release. + * \since 1.0.0 + * + */ +H5_DLL hid_t H5Gcreate1(hid_t loc_id, const char *name, size_t size_hint); +/** + *------------------------------------------------------------------------- + * \ingroup H5G + * + * \brief Opens an existing group for modification and returns a group + * identifier for that group + * + * \fgdta_loc_id + * \param[in] name Name of the group to open + * + * \return \hid_t{group} + * + * \deprecated This function is deprecated in favor of H5Gopen2(). + * + * \details H5Gopen1() opens an existing group, \p name, at the location + * specified by \p loc_id. + * + * H5Gopen1() returns a group identifier for the group that was + * opened. This group identifier should be released by calling + * H5Gclose() when it is no longer needed. + * + * \version 1.8.0 The function H5Gopen() was renamed to H5Gopen1() + * and deprecated in this release. + * \since 1.0.0 + * + */ +H5_DLL hid_t H5Gopen1(hid_t loc_id, const char *name); +/** + *------------------------------------------------------------------------- + * \ingroup H5G + * + * \brief Creates a link of the specified type from \p new_name to \p + * cur_name + * + * \fg_loc_id{cur_loc_id} + * \param[in] type Link type + * \param[in] cur_name Name of the existing object + * \param[in] new_name New name for the object + * + * \return \herr_t + * + * \deprecated This function is deprecated. + * + * \details H5Glink() creates a new name for an object that has some current + * name, possibly one of many names it currently has. + * + * If \p link_type is #H5G_LINK_HARD, then \p cur_name must specify + * the name of an existing object and both names are interpreted + * relative to \p cur_loc_id, which is either a file identifier or a + * group identifier. + * + * If \p link_type is #H5G_LINK_SOFT, then \p cur_name can be anything + * and is interpreted at lookup time relative to the group which + * contains the final component of \p new_name. For instance, if \p + * cur_name is \Code{./foo}, \p new_name is \Code{./x/y/bar}, and a + * request is made for \Code{./x/y/bar}, then the actual object looked + * up is \Code{./x/y/./foo}. + + * \version 1.8.0 Function deprecated in this release. + * + */ +H5_DLL herr_t H5Glink(hid_t cur_loc_id, H5G_link_t type, const char *cur_name, const char *new_name); +/** + *------------------------------------------------------------------------- + * \ingroup H5G + * + * \brief Creates a link of the specified type from \p cur_name to \p + * new_name + * + * \fg_loc_id{cur_loc_id} + * \param[in] cur_name Name of the existing object + * \param[in] type Link type + * \fg_loc_id{new_loc_id} + * \param[in] new_name New name for the object + * + * \return \herr_t + * + * \deprecated This function is deprecated. + * + * \details H5Glink2() creates a new name for an object that has some current + * name, possibly one of many names it currently has. + * + * If \p link_type is #H5G_LINK_HARD, then \p cur_name must specify the + * name of an existing object and both names are interpreted relative + * to \p cur_loc_id and \p new_loc_id, respectively, which are either + * file identifiers or group identifiers. + * + * If \p link_type is #H5G_LINK_SOFT, then \p cur_name can be anything + * and is interpreted at lookup time relative to the group which + * contains the final component of \p new_name. For instance, if \p + * current_name is \Code{./foo}, \p new_name is \Code{./x/y/bar}, and a + * request is made for \Code{./x/y/bar}, then the actual object looked + * up is \Code{./x/y/./foo}. + + * \version 1.8.0 Function deprecated in this release. + * + */ +H5_DLL herr_t H5Glink2(hid_t cur_loc_id, const char *cur_name, H5G_link_t type, hid_t new_loc_id, + const char *new_name); +/** + *------------------------------------------------------------------------- + * \ingroup H5G + * + * \brief Renames an object within an HDF5 file + * + * \fg_loc_id{src_loc_id} + * \param[in] src_name Object's original name + * \param[in] dst_name Object's new name + * + * \return \herr_t + * + * \deprecated This function is deprecated. + * + * \details H5Gmove() renames an object within an HDF5 file. The original name, + * \p src_name, is unlinked from the group graph and the new name, \p + * dst_name, is inserted as an atomic operation. Both names are + * interpreted relative to \p loc_id, which is either a file or a group + * identifier. + * + * \attention Exercise care in moving groups as it is possible to render data in + * a file inaccessible with H5Gmove(). See The Group Interface in the + * HDF5 User's Guide. + * + * \version 1.8.0 Function deprecated in this release. + * + */ +H5_DLL herr_t H5Gmove(hid_t src_loc_id, const char *src_name, const char *dst_name); +/** + *------------------------------------------------------------------------- + * \ingroup H5G + * + * \brief Renames an object within an HDF5 file + * + * \fg_loc_id{src_loc_id} + * \param[in] src_name Object's original name + * \fg_loc_id{dst_loc_id} + * \param[in] dst_name Object's new name + * + * \return \herr_t + * + * \deprecated This function is deprecated. + * + * \details H5Gmove2() renames an object within an HDF5 file. The original name, + * \p src_name, is unlinked from the group graph and the new name, \p + * dst_name, is inserted as an atomic operation. + * + * \p src_name and \p dst_name are interpreted relative to \p + * src_loc_id and \p dst_loc_id, respectively, which are either file or + * group identifiers. + * + * \attention Exercise care in moving groups as it is possible to render data in + * a file inaccessible with H5Gmove2(). See The Group Interface in the + * HDF5 User's Guide. + * + * \version 1.8.0 Function deprecated in this release. + * + */ +H5_DLL herr_t H5Gmove2(hid_t src_loc_id, const char *src_name, hid_t dst_loc_id, const char *dst_name); +/** + *------------------------------------------------------------------------- + * \ingroup H5G + * + * \brief Removes the link to an object from a group + * + * \fg_loc_id{loc_id} + * \param[in] name Name of the object to unlink + * + * \return \herr_t + * + * \deprecated This function is deprecated in favor of the function H5Ldelete(). + * + * \details H5Gunlink() removes the object specified by \p name from the group + * graph and decrements the link count for the object to which \p name + * points. This action eliminates any association between name and the + * object to which name pointed. + * + * Object headers keep track of how many hard links refer to an object; + * when the link count reaches zero, the object can be removed from the + * file. Objects which are open are not removed until all identifiers + * to the object are closed. + * + * If the link count reaches zero, all file space associated with the + * object will be released, i.e., identified in memory as freespace. If + * any object identifier is open for the object, the space will not be + * released until after the object identifier is closed. + * + * Note that space identified as freespace is available for re-use only + * as long as the file remains open; once a file has been closed, the + * HDF5 library loses track of freespace. See “Freespace Management” in + * the HDF5 User's Guide for further details. + * + * \attention Exercise care in moving groups as it is possible to render data in + * a file inaccessible with H5Gunlink(). See The Group Interface in the + * HDF5 User's Guide. + * + * \version 1.8.0 Function deprecated in this release. + * + */ +H5_DLL herr_t H5Gunlink(hid_t loc_id, const char *name); +/** + *------------------------------------------------------------------------- + * \ingroup H5G + * + * \brief Returns the name of the object that the symbolic link points to + * + * \fg_loc_id{loc_id} + * \param[in] name Symbolic link to the object whose name is to be returned + * \param[in] size Maximum number of characters of value to be returned + * \param[out] buf A buffer to hold the name of the object being sought + * + * \return \herr_t + * + * \deprecated This function is deprecated in favor of the function H5Lget_val(). + * + * \details H5Gget_linkval() returns up to size characters of the name of the + * object that the symbolic link name points to. + * + * The parameter \p loc_id is a file or group identifier. + * + * The parameter \p name must be a symbolic link pointing to the + * desired object and must be defined relative to \p loc_id. + * + * If size is smaller than the size of the returned object name, then + * the name stored in the buffer value will not be \c NULL terminated. + * + * This function fails if \p name is not a symbolic link. The presence + * of a symbolic link can be tested by passing zero for \p size and \p + * NULL for value. + * + * This function should be used only after H5Lget_info1() (or the + * deprecated function H5Gget_objinfo()) has been called to verify that + * name is a symbolic link. + * + * \version 1.8.0 Function deprecated in this release. + * + */ +H5_DLL herr_t H5Gget_linkval(hid_t loc_id, const char *name, size_t size, char *buf /*out*/); +/** + *------------------------------------------------------------------------- + * \ingroup H5G + * + * \brief Sets comment for specified object + * + * \fgdt_loc_id + * \param[in] name Name of the object whose comment is to be set or reset + * name must be \Code{'.'} (dot) if \p loc_id fully specifies + * the object for which the comment is to be set. + * \param[in] comment The new comment + * + * \return \herr_t + * + * \deprecated This function is deprecated in favor of the function + * H5Oset_comment(). + * + * \details H5Gset_comment() sets the comment for the object specified by \p + * loc_id and name to comment. Any previously existing comment is + * overwritten. + * + * \p loc_id can specify any object in the file. name can be one of the + * following: + * \li The name of the object relative to \p loc_id + * \li An absolute name of the object, starting from \c /, the file’s + * root group + * \li A dot (\c .), if \p loc_id fully specifies the object + * + * If \p comment is the empty string or a null pointer, the comment + * message is removed from the object. + * + * Comments should be relatively short, null-terminated, ASCII strings. + * + * Comments can be attached to any object that has an object header, + * e.g., datasets, groups, and named datatypes, but not symbolic links. + * + * \version 1.8.0 Function deprecated in this release. + * + */ +H5_DLL herr_t H5Gset_comment(hid_t loc_id, const char *name, const char *comment); +/** + *------------------------------------------------------------------------- + * \ingroup H5G + * + * \brief Retrieves comment for specified object + * + * \fgdt_loc_id + * \param[in] name Name of the object whose comment is to be set or reset + * name must be \Code{'.'} (dot) if \p loc_id fully specifies + * the object for which the comment is to be set. + * \param[in] bufsize Maximum number of comment characters to be returned in \p buf. + * \param[in] buf The comment + * + * \return Returns the number of characters in the comment, counting the \c NULL + * terminator, if successful; the value returned may be larger than + * \p bufsize. Otherwise returns a negative value. + * + * \deprecated This function is deprecated in favor of the function + * H5Oget_comment(). + * + * \details H5Gget_comment() retrieves the comment for the the object specified + * by \p loc_id and \p name. The comment is returned in the buffer \p + * buf. + * + * \p loc_id can specify any object in the file. name can be one of the + * following: + * \li The name of the object relative to \p loc_id + * \li An absolute name of the object, starting from \c /, the file’s + * root group + * \li A dot (\c .), if \p loc_id fully specifies the object + * + * At most bufsize characters, including a null-terminator, are + * returned in \p buf. The returned value is not null-terminated if the + * comment is longer than the supplied buffer. If the size of the + * comment is unknown, a preliminary \p H5Gget_comment() call will + * return the size of the comment, including space for the + * null-terminator. + * + * If an object does not have a comment, the empty string is returned + * in comment. + * + * \version 1.8.0 Function deprecated in this release. + * + */ +H5_DLL int H5Gget_comment(hid_t loc_id, const char *name, size_t bufsize, char *buf); +/** + *------------------------------------------------------------------------- + * \ingroup H5G + * + * \brief Iterates over the entries of a group invoking a callback for each + * entry encountered + * + * \fg_loc_id + * \param[in] name Group over which the iteration is performed + * \param[in,out] idx Location at which to begin the iteration + * \param[in] op Operation to be performed on an object at each step of the + * iteration + * \param[in,out] op_data Data associated with the operation + * + * \return \herr_t + * + * \deprecated This function is deprecated in favor of the function + * H5Literate1(). + * + * \details H5Giterate() iterates over the members of name in the file or group + * specified with \p loc_id. For each object in the group, the \p + * op_data and some additional information, specified below, are passed + * to the operator function. The iteration begins with the \p idx + * object in the group and the next element to be processed by the + * operator is returned in \p idx. If \p idx is NULL, then the iterator + * starts at the first group member; since no stopping point is + * returned in this case, the iterator cannot be restarted if one of + * the calls to its operator returns non-zero. H5Giterate() does not + * recursively follow links into subgroups of the specified group. + * + * The prototype for \ref H5G_iterate_t is: + * \snippet this H5G_iterate_t_snip + * + * The operation receives the group identifier for the group being + * iterated over, \p group, the name of the current object within + * the group, \p name, and the pointer to the operator data + * passed in to H5Giterate(), \p op_data. + * + * The return values from an operator are: + * \li Zero causes the iterator to continue, returning zero when all + * group members have been processed. + * \li Positive causes the iterator to immediately return that positive + * value, indicating short-circuit success. The iterator can be + * restarted at the next group member. + * \li Negative causes the iterator to immediately return that value, + * indicating failure. The iterator can be restarted at the next + * group member. + * + * H5Giterate() assumes that the membership of the group identified by + * \p name remains unchanged through the iteration. If the membership + * changes during the iteration, the function's behavior is undefined. + * + * H5Giterate() is not recursive. In particular, if a member of \p name + * is found to be a group, call it \c subgroup_a, H5Giterate() does not + * examine the members of \c subgroup_a. When recursive iteration is + * required, the application must handle the recursion, explicitly + * calling H5Giterate() on discovered subgroups. + + * \version 1.8.0 Function deprecated in this release. + * + */ +H5_DLL herr_t H5Giterate(hid_t loc_id, const char *name, int *idx, H5G_iterate_t op, void *op_data); +/** + *------------------------------------------------------------------------- + * \ingroup H5G + * + * \brief Returns number of objects in the group specified by its identifier + * + * \fg_loc_id + * \param[out] num_objs Number of objects in the group + * + * \return \herr_t + * + * \deprecated This function is deprecated in favor of the function H5Gget_info(). + * + * \details H5Gget_num_objs() returns number of objects in a group. Group is + * specified by its identifier \p loc_id. If a file identifier is + * passed in, then the number of objects in the root group is returned. + * + * \version 1.8.0 Function deprecated in this release. + * + */ +H5_DLL herr_t H5Gget_num_objs(hid_t loc_id, hsize_t *num_objs); +/** + *------------------------------------------------------------------------- + * \ingroup H5G + * + * \brief Returns information about an object. + * + * \fgdt_loc_id + * \param[in] name Name of the object for which status is being sought + * \param[in] follow_link Link flag + * \param[out] statbuf Buffer in which to return information about the object + * + * \return \herr_t + * + * \deprecated This function is deprecated in favor of the functions H5Oget_info() + * and H5Lget_info1(). + * + * \details H5Gget_objinfo() returns information about the specified object + * through the \p statbuf argument. + * + * A file or group identifier, \p loc_id, and an object name, \p name, + * relative to \p loc_id, are commonly used to specify the + * object. However, if the object identifier is already known to the + * application, an alternative approach is to use that identifier, \c + * obj_id, in place of \p loc_id, and a dot (\c .) in place of \p + * name. Thus, the alternative versions of the first portion of an + * H5Gget_objinfo() call would be as follows: + * \code + * H5Gget_objinfo (loc_id name ...) + * H5Gget_objinfo (obj_id . ...) + * \endcode + * + * If the object is a symbolic link and follow_link is zero (0), then + * the information returned describes the link itself; otherwise the + * link is followed and the information returned describes the object + * to which the link points. If \p follow_link is non-zero but the + * final symbolic link is dangling (does not point to anything), then + * an error is returned. The \p statbuf fields are undefined for an + * error. The existence of an object can be tested by calling this + * function with a \c NULL \p statbuf. + * + * H5Gget_objinfo() fills in the following data structure (defined in + * H5Gpublic.h): + * \snippet this H5G_stat_t_snip + * + * where \ref H5O_stat_t (defined in H5Opublic.h) is: + * \snippet H5Opublic.h H5O_stat_t_snip + * + * \attention Some systems will be able to record the time accurately but unable + * to retrieve the correct time; such systems (e.g., Irix64) will + * report an \c mtime value of 0 (zero). + * + * \version 1.8.0 Function deprecated in this release. + * \version 1.6.1 Two new fields were added to the \ref H5G_stat_t struct in + * this release. + * + */ +H5_DLL herr_t H5Gget_objinfo(hid_t loc_id, const char *name, hbool_t follow_link, + H5G_stat_t *statbuf /*out*/); +/** + *------------------------------------------------------------------------- + * \ingroup H5G + * + * \brief Returns a name of an object specified by an index + * + * \fg_loc_id + * \param[in] idx Transient index identifying object + * \param[in,out] name Pointer to user-provided buffer the object name + * \param[in] size Name length + * + * \return Returns the size of the object name if successful, or 0 if no name is + * associated with the group identifier. Otherwise returns a negative + * value. + * + * \deprecated This function is deprecated in favor of the function H5Lget_name_by_idx(). + * + * \details H5Gget_objname_by_idx() returns a name of the object specified by + * the index \p idx in the group \p loc_id. + * + * The group is specified by a group identifier \p loc_id. If + * preferred, a file identifier may be passed in \p loc_id; that file's + * root group will be assumed. + * + * \p idx is the transient index used to iterate through the objects in + * the group. The value of \p idx is any nonnegative number less than + * the total number of objects in the group, which is returned by the + * function H5Gget_num_objs(). Note that this is a transient index; an + * object may have a different index each time a group is opened. + * + * The object name is returned in the user-specified buffer \p name. + * + * If the size of the provided buffer \p name is less or equal the + * actual object name length, the object name is truncated to + * \Code{max_size - 1} characters. + * + * Note that if the size of the object's name is unkown, a preliminary + * call to H5Gget_objname_by_idx() with \p name set to \c NULL will + * return the length of the object's name. A second call to + * H5Gget_objname_by_idx() can then be used to retrieve the actual + * name. + * + * \version 1.8.0 Function deprecated in this release. + * \since 1.6.0 + * + */ +H5_DLL ssize_t H5Gget_objname_by_idx(hid_t loc_id, hsize_t idx, char *name, size_t size); +/** + *------------------------------------------------------------------------- + * \ingroup H5G + * + * \brief Returns the type of an object specified by an index + * + * \fg_loc_id + * \param[in] idx Transient index identifying object + * + * \return Returns the type of the object if successful. Otherwise returns a + * negative value. + * + * \deprecated This function is deprecated in favor of the function H5Oget_info(). + * + * \details H5Gget_objtype_by_idx() returns the type of the object specified by + * the index \p idx in the group \p loc_id. + * + * The group is specified by a group identifier \p loc_id. If + * preferred, a file identifier may be passed in \p loc_id; that file's + * root group will be assumed. + * + * \p idx is the transient index used to iterate through the objects in + * the group. This parameter is described in more detail in the + * discussion of H5Gget_objname_by_idx(). + * + * \version 1.8.0 Function deprecated in this release. + * \version 1.6.0 The function return type changed from \c int to the enumerated + * type \ref H5G_obj_t. + * \since 1.6.0 + * + */ H5_DLL H5G_obj_t H5Gget_objtype_by_idx(hid_t loc_id, hsize_t idx); #endif /* H5_NO_DEPRECATED_SYMBOLS */ diff --git a/src/H5Gstab.c b/src/H5Gstab.c index 78981be..bf4b417 100644 --- a/src/H5Gstab.c +++ b/src/H5Gstab.c @@ -150,11 +150,10 @@ H5G__stab_create_components(H5F_t *f, H5O_stab_t *stab, size_t size_hint) HGOTO_ERROR(H5E_SYM, H5E_PROTECT, FAIL, "unable to protect symbol table heap") /* Insert name into the heap */ - if (UFAIL == (name_offset = H5HL_insert(f, heap, (size_t)1, ""))) + if (H5HL_insert(f, heap, (size_t)1, "", &name_offset) < 0) HGOTO_ERROR(H5E_SYM, H5E_CANTINSERT, FAIL, "can't insert name into heap") - /* - * B-tree's won't work if the first name isn't at the beginning + /* B-trees won't work if the first name isn't at the beginning * of the heap. */ HDassert(0 == name_offset); @@ -302,7 +301,7 @@ H5G__stab_insert(const H5O_loc_t *grp_oloc, const char *name, H5O_link_t *obj_ln H5O_stab_t stab; /* Symbol table message */ herr_t ret_value = SUCCEED; /* Return value */ - FUNC_ENTER_PACKAGE_TAG(grp_oloc->addr) + FUNC_ENTER_PACKAGE /* check arguments */ HDassert(grp_oloc && grp_oloc->file); @@ -317,7 +316,7 @@ H5G__stab_insert(const H5O_loc_t *grp_oloc, const char *name, H5O_link_t *obj_ln HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, H5_ITER_ERROR, "unable to insert the name") done: - FUNC_LEAVE_NOAPI_TAG(ret_value) + FUNC_LEAVE_NOAPI(ret_value) } /* end H5G__stab_insert() */ /*------------------------------------------------------------------------- @@ -507,7 +506,7 @@ H5G__stab_iterate(const H5O_loc_t *oloc, H5_iter_order_t order, hsize_t skip, hs H5G_link_table_t ltable = {0, NULL}; /* Link table */ herr_t ret_value = FAIL; /* Return value */ - FUNC_ENTER_PACKAGE_TAG(oloc->addr) + FUNC_ENTER_PACKAGE /* Sanity check */ HDassert(oloc); @@ -574,7 +573,7 @@ done: if (ltable.lnks && H5G__link_release_table(<able) < 0) HDONE_ERROR(H5E_SYM, H5E_CANTFREE, FAIL, "unable to release link table") - FUNC_LEAVE_NOAPI_TAG(ret_value) + FUNC_LEAVE_NOAPI(ret_value) } /* end H5G__stab_iterate() */ /*------------------------------------------------------------------------- @@ -833,20 +832,21 @@ done: * *------------------------------------------------------------------------- */ -htri_t -H5G__stab_lookup(const H5O_loc_t *grp_oloc, const char *name, H5O_link_t *lnk) +herr_t +H5G__stab_lookup(const H5O_loc_t *grp_oloc, const char *name, hbool_t *found, H5O_link_t *lnk) { - H5HL_t * heap = NULL; /* Pointer to local heap */ - H5G_bt_lkp_t bt_udata; /* Data to pass through B-tree */ - H5G_stab_fnd_ud_t udata; /* 'User data' to give to callback */ - H5O_stab_t stab; /* Symbol table message */ - htri_t ret_value = FAIL; /* Return value */ + H5HL_t * heap = NULL; /* Pointer to local heap */ + H5G_bt_lkp_t bt_udata; /* Data to pass through B-tree */ + H5G_stab_fnd_ud_t udata; /* 'User data' to give to callback */ + H5O_stab_t stab; /* Symbol table message */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_PACKAGE /* check arguments */ HDassert(grp_oloc && grp_oloc->file); HDassert(name && *name); + HDassert(found); HDassert(lnk); /* Retrieve the symbol table message for the group */ @@ -869,7 +869,7 @@ H5G__stab_lookup(const H5O_loc_t *grp_oloc, const char *name, H5O_link_t *lnk) bt_udata.op_data = &udata; /* Search the B-tree */ - if ((ret_value = H5B_find(grp_oloc->file, H5B_SNODE, stab.btree_addr, &bt_udata)) < 0) + if (H5B_find(grp_oloc->file, H5B_SNODE, stab.btree_addr, found, &bt_udata) < 0) HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "not found") done: diff --git a/src/H5Gtraverse.c b/src/H5Gtraverse.c index bbd8973..af29614 100644 --- a/src/H5Gtraverse.c +++ b/src/H5Gtraverse.c @@ -535,7 +535,7 @@ H5G__traverse_real(const H5G_loc_t *_loc, const char *name, unsigned target, H5G /* Traverse the path */ while ((name = H5G__component(name, &nchars)) && *name) { const char *s; /* Temporary string pointer */ - htri_t lookup_status; /* Status from object lookup */ + hbool_t lookup_status; /* Status from object lookup */ hbool_t obj_exists; /* Whether the object exists */ /* @@ -564,7 +564,8 @@ H5G__traverse_real(const H5G_loc_t *_loc, const char *name, unsigned target, H5G } /* end if */ /* Get information for object in current group */ - if ((lookup_status = H5G__obj_lookup(grp_loc.oloc, comp, &lnk /*out*/)) < 0) + lookup_status = FALSE; + if (H5G__obj_lookup(grp_loc.oloc, comp, &lookup_status, &lnk /*out*/) < 0) HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "can't look up component") obj_exists = FALSE; diff --git a/src/H5HFdbg.c b/src/H5HFdbg.c index cc61aa1..a244035 100644 --- a/src/H5HFdbg.c +++ b/src/H5HFdbg.c @@ -543,7 +543,7 @@ H5HF_dblock_debug(H5F_t *f, haddr_t addr, FILE *stream, int indent, int fwidth, amount_free = 0; HDfprintf(stream, "%*s%-*s %.2f%%\n", indent, "", fwidth, "Percent of available space for data used:", - ((double)100.0f * (double)((dblock->size - blk_prefix_size) - amount_free) / + (100.0 * (double)((dblock->size - blk_prefix_size) - amount_free) / (double)(dblock->size - blk_prefix_size))); /* diff --git a/src/H5HFhuge.c b/src/H5HFhuge.c index b1043a6..83a61ec 100644 --- a/src/H5HFhuge.c +++ b/src/H5HFhuge.c @@ -508,6 +508,8 @@ H5HF__huge_get_obj_len(H5HF_hdr_t *hdr, const uint8_t *id, size_t *obj_len_p) } /* end else */ } /* end if */ else { + hbool_t found = FALSE; /* Whether entry was found */ + /* Check if v2 B-tree is open yet */ if (NULL == hdr->huge_bt2) { /* Open existing v2 B-tree */ @@ -524,8 +526,11 @@ H5HF__huge_get_obj_len(H5HF_hdr_t *hdr, const uint8_t *id, size_t *obj_len_p) UINT64DECODE_VAR(id, search_rec.id, hdr->huge_id_size) /* Look up object in v2 B-tree */ - if (H5B2_find(hdr->huge_bt2, &search_rec, H5HF__huge_bt2_filt_indir_found, &found_rec) != TRUE) - HGOTO_ERROR(H5E_HEAP, H5E_NOTFOUND, FAIL, "can't find object in B-tree") + if (H5B2_find(hdr->huge_bt2, &search_rec, &found, H5HF__huge_bt2_filt_indir_found, &found_rec) < + 0) + HGOTO_ERROR(H5E_HEAP, H5E_CANTFIND, FAIL, "can't check for object in v2 B-tree") + if (!found) + HGOTO_ERROR(H5E_HEAP, H5E_NOTFOUND, FAIL, "can't find object in v2 B-tree") /* Retrieve the object's length */ *obj_len_p = (size_t)found_rec.obj_size; @@ -538,8 +543,10 @@ H5HF__huge_get_obj_len(H5HF_hdr_t *hdr, const uint8_t *id, size_t *obj_len_p) UINT64DECODE_VAR(id, search_rec.id, hdr->huge_id_size) /* Look up object in v2 B-tree */ - if (H5B2_find(hdr->huge_bt2, &search_rec, H5HF__huge_bt2_indir_found, &found_rec) != TRUE) - HGOTO_ERROR(H5E_HEAP, H5E_NOTFOUND, FAIL, "can't find object in B-tree") + if (H5B2_find(hdr->huge_bt2, &search_rec, &found, H5HF__huge_bt2_indir_found, &found_rec) < 0) + HGOTO_ERROR(H5E_HEAP, H5E_CANTFIND, FAIL, "can't check for object in v2 B-tree") + if (!found) + HGOTO_ERROR(H5E_HEAP, H5E_NOTFOUND, FAIL, "can't find object in v2 B-tree") /* Retrieve the object's length */ *obj_len_p = (size_t)found_rec.len; @@ -587,6 +594,8 @@ H5HF__huge_get_obj_off(H5HF_hdr_t *hdr, const uint8_t *id, hsize_t *obj_off_p) H5F_addr_decode(hdr->f, &id, &obj_addr); } /* end if */ else { + hbool_t found = FALSE; /* Whether entry was found */ + /* Sanity check */ HDassert(H5F_addr_defined(hdr->huge_bt2_addr)); @@ -606,8 +615,11 @@ H5HF__huge_get_obj_off(H5HF_hdr_t *hdr, const uint8_t *id, hsize_t *obj_off_p) UINT64DECODE_VAR(id, search_rec.id, hdr->huge_id_size) /* Look up object in v2 B-tree */ - if (H5B2_find(hdr->huge_bt2, &search_rec, H5HF__huge_bt2_filt_indir_found, &found_rec) != TRUE) - HGOTO_ERROR(H5E_HEAP, H5E_NOTFOUND, FAIL, "can't find object in B-tree") + if (H5B2_find(hdr->huge_bt2, &search_rec, &found, H5HF__huge_bt2_filt_indir_found, &found_rec) < + 0) + HGOTO_ERROR(H5E_HEAP, H5E_CANTFIND, FAIL, "can't check for object in v2 B-tree") + if (!found) + HGOTO_ERROR(H5E_HEAP, H5E_NOTFOUND, FAIL, "can't find object in v2 B-tree") /* Retrieve the object's address & length */ obj_addr = found_rec.addr; @@ -620,8 +632,10 @@ H5HF__huge_get_obj_off(H5HF_hdr_t *hdr, const uint8_t *id, hsize_t *obj_off_p) UINT64DECODE_VAR(id, search_rec.id, hdr->huge_id_size) /* Look up object in v2 B-tree */ - if (H5B2_find(hdr->huge_bt2, &search_rec, H5HF__huge_bt2_indir_found, &found_rec) != TRUE) - HGOTO_ERROR(H5E_HEAP, H5E_NOTFOUND, FAIL, "can't find object in B-tree") + if (H5B2_find(hdr->huge_bt2, &search_rec, &found, H5HF__huge_bt2_indir_found, &found_rec) < 0) + HGOTO_ERROR(H5E_HEAP, H5E_CANTFIND, FAIL, "can't check for object in v2 B-tree") + if (!found) + HGOTO_ERROR(H5E_HEAP, H5E_NOTFOUND, FAIL, "can't find object in v2 B-tree") /* Retrieve the object's address & length */ obj_addr = found_rec.addr; @@ -679,6 +693,8 @@ H5HF__huge_op_real(H5HF_hdr_t *hdr, const uint8_t *id, hbool_t is_read, H5HF_ope UINT32DECODE(id, filter_mask); } /* end if */ else { + hbool_t found = FALSE; /* Whether entry was found */ + /* Sanity check */ HDassert(H5F_addr_defined(hdr->huge_bt2_addr)); @@ -698,8 +714,11 @@ H5HF__huge_op_real(H5HF_hdr_t *hdr, const uint8_t *id, hbool_t is_read, H5HF_ope UINT64DECODE_VAR(id, search_rec.id, hdr->huge_id_size) /* Look up object in v2 B-tree */ - if (H5B2_find(hdr->huge_bt2, &search_rec, H5HF__huge_bt2_filt_indir_found, &found_rec) != TRUE) - HGOTO_ERROR(H5E_HEAP, H5E_NOTFOUND, FAIL, "can't find object in B-tree") + if (H5B2_find(hdr->huge_bt2, &search_rec, &found, H5HF__huge_bt2_filt_indir_found, &found_rec) < + 0) + HGOTO_ERROR(H5E_HEAP, H5E_CANTFIND, FAIL, "can't check for object in v2 B-tree") + if (!found) + HGOTO_ERROR(H5E_HEAP, H5E_NOTFOUND, FAIL, "can't find object in v2 B-tree") /* Retrieve the object's address & length */ obj_addr = found_rec.addr; @@ -714,8 +733,10 @@ H5HF__huge_op_real(H5HF_hdr_t *hdr, const uint8_t *id, hbool_t is_read, H5HF_ope UINT64DECODE_VAR(id, search_rec.id, hdr->huge_id_size) /* Look up object in v2 B-tree */ - if (H5B2_find(hdr->huge_bt2, &search_rec, H5HF__huge_bt2_indir_found, &found_rec) != TRUE) - HGOTO_ERROR(H5E_HEAP, H5E_NOTFOUND, FAIL, "can't find object in B-tree") + if (H5B2_find(hdr->huge_bt2, &search_rec, &found, H5HF__huge_bt2_indir_found, &found_rec) < 0) + HGOTO_ERROR(H5E_HEAP, H5E_CANTFIND, FAIL, "can't check for object in v2 B-tree") + if (!found) + HGOTO_ERROR(H5E_HEAP, H5E_NOTFOUND, FAIL, "can't find object in v2 B-tree") /* Retrieve the object's address & length */ obj_addr = found_rec.addr; @@ -827,8 +848,9 @@ H5HF__huge_write(H5HF_hdr_t *hdr, const uint8_t *id, const void *obj) H5F_DECODE_LENGTH(hdr->f, id, obj_size); } /* end if */ else { - H5HF_huge_bt2_indir_rec_t found_rec; /* Record found from tracking object */ - H5HF_huge_bt2_indir_rec_t search_rec; /* Record for searching for object */ + H5HF_huge_bt2_indir_rec_t found_rec; /* Record found from tracking object */ + H5HF_huge_bt2_indir_rec_t search_rec; /* Record for searching for object */ + hbool_t found = FALSE; /* Whether entry was found */ /* Sanity check */ HDassert(H5F_addr_defined(hdr->huge_bt2_addr)); @@ -845,8 +867,10 @@ H5HF__huge_write(H5HF_hdr_t *hdr, const uint8_t *id, const void *obj) UINT64DECODE_VAR(id, search_rec.id, hdr->huge_id_size) /* Look up object in v2 B-tree */ - if (H5B2_find(hdr->huge_bt2, &search_rec, H5HF__huge_bt2_indir_found, &found_rec) != TRUE) - HGOTO_ERROR(H5E_HEAP, H5E_NOTFOUND, FAIL, "can't find object in B-tree") + if (H5B2_find(hdr->huge_bt2, &search_rec, &found, H5HF__huge_bt2_indir_found, &found_rec) < 0) + HGOTO_ERROR(H5E_HEAP, H5E_CANTFIND, FAIL, "can't check for object in v2 B-tree") + if (!found) + HGOTO_ERROR(H5E_HEAP, H5E_NOTFOUND, FAIL, "can't find object in v2 B-tree") /* Retrieve the object's address & length */ obj_addr = found_rec.addr; @@ -508,27 +508,31 @@ END_FUNC(STATIC) /* end H5HL__dirty() */ * * Purpose: Inserts a new item into the heap. * - * Return: Success: Offset of new item within heap. - * Failure: UFAIL + * Return: Success: SUCCEED + * Offset set to location of new item within heap + * + * Failure: FAIL + * Offset set to SIZE_MAX * * Programmer: Robb Matzke * Jul 17 1997 * *------------------------------------------------------------------------- */ -BEGIN_FUNC(PRIV, ERR, size_t, UFAIL, UFAIL, - H5HL_insert(H5F_t *f, H5HL_t *heap, size_t buf_size, const void *buf)) +BEGIN_FUNC(PRIV, ERR, herr_t, SUCCEED, FAIL, + H5HL_insert(H5F_t *f, H5HL_t *heap, size_t buf_size, const void *buf, size_t *offset_out)) H5HL_free_t *fl = NULL, *last_fl = NULL; - size_t offset = 0; size_t need_size; + size_t offset = 0; hbool_t found; - /* check arguments */ + /* Check arguments */ HDassert(f); HDassert(heap); HDassert(buf_size > 0); HDassert(buf); + HDassert(offset_out); /* Mark heap as dirty in cache */ /* (A bit early in the process, but it's difficult to determine in the @@ -539,20 +543,18 @@ BEGIN_FUNC(PRIV, ERR, size_t, UFAIL, UFAIL, if (FAIL == H5HL__dirty(heap)) H5E_THROW(H5E_CANTMARKDIRTY, "unable to mark heap as dirty"); - /* - * In order to keep the free list descriptors aligned on word boundaries, + /* In order to keep the free list descriptors aligned on word boundaries, * whatever that might mean, we round the size up to the next multiple of * a word. */ need_size = H5HL_ALIGN(buf_size); - /* - * Look for a free slot large enough for this object and which would + /* Look for a free slot large enough for this object and which would * leave zero or at least H5G_SIZEOF_FREE bytes left over. */ for (fl = heap->freelist, found = FALSE; fl; fl = fl->next) { if (fl->size > need_size && fl->size - need_size >= H5HL_SIZEOF_FREE(f)) { - /* a big enough free block was found */ + /* A big enough free block was found */ offset = fl->offset; fl->offset += need_size; fl->size -= need_size; @@ -562,20 +564,19 @@ BEGIN_FUNC(PRIV, ERR, size_t, UFAIL, UFAIL, break; } else if (fl->size == need_size) { - /* free block of exact size found */ + /* Free block of exact size found */ offset = fl->offset; fl = H5HL__remove_free(heap, fl); found = TRUE; break; } else if (!last_fl || last_fl->offset < fl->offset) { - /* track free space that's closest to end of heap */ + /* Track free space that's closest to end of heap */ last_fl = fl; } } /* end for */ - /* - * If no free chunk was large enough, then allocate more space and + /* If no free chunk was large enough, then allocate more space and * add it to the free list. If the heap ends with a free chunk, we * can extend that free chunk. Otherwise we'll have to make another * free chunk. If the heap must expand, we double its size. @@ -587,7 +588,8 @@ BEGIN_FUNC(PRIV, ERR, size_t, UFAIL, UFAIL, htri_t was_extended; /* Whether the local heap's data segment on disk was extended */ /* At least double the heap's size, making certain there's enough room - * for the new object */ + * for the new object + */ need_more = MAX(need_size, heap->dblk_size); /* If there is no last free block or it's not at the end of the heap, @@ -657,8 +659,7 @@ BEGIN_FUNC(PRIV, ERR, size_t, UFAIL, UFAIL, } } /* end if */ else { - /* - * Create a new free list element large enough that we can + /* Create a new free list element large enough that we can * take some space out of it right away. */ offset = old_dblk_size; @@ -700,11 +701,10 @@ BEGIN_FUNC(PRIV, ERR, size_t, UFAIL, UFAIL, /* Copy the data into the heap */ H5MM_memcpy(heap->dblk_image + offset, buf, buf_size); - /* Set return value */ - ret_value = offset; + *offset_out = offset; CATCH - /* No special processing on errors */ + /* No special processing on exit */ END_FUNC(PRIV) /* H5HL_insert() */ diff --git a/src/H5HLdbg.c b/src/H5HLdbg.c index d0cfa96..76e4ec0 100644 --- a/src/H5HLdbg.c +++ b/src/H5HLdbg.c @@ -102,7 +102,7 @@ BEGIN_FUNC(PRIV, ERR, herr_t, SUCCEED, FAIL, if (h->dblk_size) HDfprintf(stream, "%*s%-*s %.2f%%\n", indent, "", fwidth, "Percent of heap used:", - ((double)100.0f * (double)(h->dblk_size - amount_free) / (double)h->dblk_size)); + (100.0 * (double)(h->dblk_size - amount_free) / (double)h->dblk_size)); /* Print the data in a VMS-style octal dump */ H5_buffer_dump(stream, indent, h->dblk_image, marker, (size_t)0, h->dblk_size); diff --git a/src/H5HLprivate.h b/src/H5HLprivate.h index 739e761..5c98846 100644 --- a/src/H5HLprivate.h +++ b/src/H5HLprivate.h @@ -57,7 +57,7 @@ H5_DLL herr_t H5HL_create(H5F_t *f, size_t size_hint, haddr_t *addr /*out*/); H5_DLL herr_t H5HL_delete(H5F_t *f, haddr_t addr); H5_DLL herr_t H5HL_get_size(H5F_t *f, haddr_t addr, size_t *size); H5_DLL herr_t H5HL_heapsize(H5F_t *f, haddr_t addr, hsize_t *heap_size); -H5_DLL size_t H5HL_insert(H5F_t *f, H5HL_t *heap, size_t size, const void *buf); +H5_DLL herr_t H5HL_insert(H5F_t *f, H5HL_t *heap, size_t size, const void *buf, size_t *offset); H5_DLL void * H5HL_offset_into(const H5HL_t *heap, size_t offset); H5_DLL H5HL_t *H5HL_protect(H5F_t *f, haddr_t addr, unsigned flags); H5_DLL herr_t H5HL_remove(H5F_t *f, H5HL_t *heap, size_t offset, size_t size); @@ -25,6 +25,7 @@ #include "H5CXprivate.h" /* API Contexts */ #include "H5Dprivate.h" /* Datasets */ #include "H5Eprivate.h" /* Error handling */ +#include "H5ESprivate.h" /* Event Sets */ #include "H5Fprivate.h" /* File access */ #include "H5Gprivate.h" /* Groups */ #include "H5Iprivate.h" /* IDs */ @@ -82,7 +83,7 @@ typedef struct { char *sep; /* Pointer to next separator in the string */ /* Up */ - hbool_t exists; /* Whether the link exists or not */ + hbool_t *exists; /* Whether the link exists or not */ } H5L_trav_le_t; /* User data for path traversal routine for getting link value */ @@ -95,7 +96,7 @@ typedef struct { /* Local Prototypes */ /********************/ -static int H5L_find_class_idx(H5L_type_t id); +static int H5L__find_class_idx(H5L_type_t id); static herr_t H5L__link_cb(H5G_loc_t *grp_loc /*in*/, const char *name, const H5O_link_t *lnk, H5G_loc_t *obj_loc, void *_udata /*in,out*/, H5G_own_loc_t *own_loc /*out*/); static herr_t H5L__create_real(const H5G_loc_t *link_loc, const char *link_name, H5G_name_t *obj_path, @@ -129,6 +130,22 @@ static herr_t H5L__get_info_by_idx_cb(H5G_loc_t *grp_loc /*in*/, const char *nam static herr_t H5L__get_name_by_idx_cb(H5G_loc_t *grp_loc /*in*/, const char *name, const H5O_link_t *lnk, H5G_loc_t *obj_loc, void *_udata /*in,out*/, H5G_own_loc_t *own_loc /*out*/); +static herr_t H5L__create_soft_api_common(const char *link_target, hid_t link_loc_id, const char *link_name, + hid_t lcpl_id, hid_t lapl_id, void **token_ptr, + H5VL_object_t **_vol_obj_ptr); +static herr_t H5L__create_hard_api_common(hid_t cur_loc_id, const char *cur_name, hid_t new_loc_id, + const char *new_name, hid_t lcpl_id, hid_t lapl_id, + void **token_ptr, H5VL_object_t **_vol_obj_ptr); +static herr_t H5L__delete_api_common(hid_t loc_id, const char *name, hid_t lapl_id, void **token_ptr, + H5VL_object_t **_vol_obj_ptr); +static herr_t H5L__delete_by_idx_api_common(hid_t loc_id, const char *group_name, H5_index_t idx_type, + H5_iter_order_t order, hsize_t n, hid_t lapl_id, void **token_ptr, + H5VL_object_t **_vol_obj_ptr); +static herr_t H5L__exists_api_common(hid_t loc_id, const char *name, hbool_t *exists, hid_t lapl_id, + void **token_ptr, H5VL_object_t **_vol_obj_ptr); +static herr_t H5L__iterate_api_common(hid_t group_id, H5_index_t idx_type, H5_iter_order_t order, + hsize_t *idx_p, H5L_iterate2_t op, void *op_data, void **token_ptr, + H5VL_object_t **_vol_obj_ptr); /*********************/ /* Package Variables */ @@ -422,33 +439,25 @@ done: } /* end H5Lcopy() */ /*------------------------------------------------------------------------- - * Function: H5Lcreate_soft - * - * Purpose: Creates a soft link from LINK_NAME to LINK_TARGET. + * Function: H5L__create_soft_api_common * - * LINK_TARGET can be anything and is interpreted at lookup - * time relative to the group which contains the final component - * of LINK_NAME. For instance, if LINK_TARGET is `./foo' and - * LINK_NAME is `./x/y/bar' and a request is made for `./x/y/bar' - * then the actual object looked up is `./x/y/./foo'. + * Purpose: This is the common function for creating a soft link * * Return: Non-negative on success/Negative on failure * - * Programmer: Robb Matzke - * Monday, April 6, 1998 - * *------------------------------------------------------------------------- */ -herr_t -H5Lcreate_soft(const char *link_target, hid_t link_loc_id, const char *link_name, hid_t lcpl_id, - hid_t lapl_id) +static herr_t +H5L__create_soft_api_common(const char *link_target, hid_t link_loc_id, const char *link_name, hid_t lcpl_id, + hid_t lapl_id, void **token_ptr, H5VL_object_t **_vol_obj_ptr) { - H5VL_object_t * vol_obj = NULL; /* object of loc_id */ - H5VL_loc_params_t loc_params; - herr_t ret_value = SUCCEED; /* Return value */ + H5VL_object_t * tmp_vol_obj = NULL; /* Object for loc_id */ + H5VL_object_t **vol_obj_ptr = + (_vol_obj_ptr ? _vol_obj_ptr : &tmp_vol_obj); /* Ptr to object ptr for loc_id */ + H5VL_loc_params_t loc_params; /* Location parameters for object access */ + herr_t ret_value = SUCCEED; /* Return value */ - FUNC_ENTER_API(FAIL) - H5TRACE5("e", "*si*sii", link_target, link_loc_id, link_name, lcpl_id, lapl_id); + FUNC_ENTER_STATIC /* Check arguments */ if (link_loc_id == H5L_SAME_LOC) @@ -457,10 +466,6 @@ H5Lcreate_soft(const char *link_target, hid_t link_loc_id, const char *link_name HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "link_target parameter cannot be NULL") if (!*link_target) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "link_target parameter cannot be an empty string") - if (!link_name) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "link_name parameter cannot be NULL") - if (!*link_name) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "link_name parameter cannot be an empty string") if (lcpl_id != H5P_DEFAULT && (TRUE != H5P_isa_class(lcpl_id, H5P_LINK_CREATE))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a link creation property list") @@ -475,54 +480,123 @@ H5Lcreate_soft(const char *link_target, hid_t link_loc_id, const char *link_name if (H5CX_set_apl(&lapl_id, H5P_CLS_LACC, link_loc_id, TRUE) < 0) HGOTO_ERROR(H5E_LINK, H5E_CANTSET, FAIL, "can't set access property list info") - /* Set location fields */ - loc_params.type = H5VL_OBJECT_BY_NAME; - loc_params.loc_data.loc_by_name.name = link_name; - loc_params.loc_data.loc_by_name.lapl_id = lapl_id; - loc_params.obj_type = H5I_get_type(link_loc_id); - - /* get the location object */ - if (NULL == (vol_obj = (H5VL_object_t *)H5VL_vol_object(link_loc_id))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid location identifier") + /* link_name is verified in H5VL_setup_name_args() */ + /* Set up object access arguments */ + if (H5VL_setup_name_args(link_loc_id, link_name, H5P_CLS_LACC, TRUE, lapl_id, vol_obj_ptr, &loc_params) < + 0) + HGOTO_ERROR(H5E_LINK, H5E_CANTSET, FAIL, "can't set object access arguments") /* Create the link */ - if (H5VL_link_create(H5VL_LINK_CREATE_SOFT, vol_obj, &loc_params, lcpl_id, lapl_id, - H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL, link_target) < 0) + if (H5VL_link_create(H5VL_LINK_CREATE_SOFT, *vol_obj_ptr, &loc_params, lcpl_id, lapl_id, + H5P_DATASET_XFER_DEFAULT, token_ptr, link_target) < 0) HGOTO_ERROR(H5E_LINK, H5E_CANTCREATE, FAIL, "unable to create soft link") done: - FUNC_LEAVE_API(ret_value) -} /* end H5Lcreate_soft() */ + FUNC_LEAVE_NOAPI(ret_value) +} /* H5L__create_soft_api_common() */ /*------------------------------------------------------------------------- - * Function: H5Lcreate_hard + * Function: H5Lcreate_soft * - * Purpose: Creates a hard link from NEW_NAME to CUR_NAME. + * Purpose: Creates a soft link from LINK_NAME to LINK_TARGET. * - * CUR_NAME must name an existing object. CUR_NAME and - * NEW_NAME are interpreted relative to CUR_LOC_ID and - * NEW_LOC_ID, which are either file IDs or group IDs. + * LINK_TARGET can be anything and is interpreted at lookup + * time relative to the group which contains the final component + * of LINK_NAME. For instance, if LINK_TARGET is `./foo' and + * LINK_NAME is `./x/y/bar' and a request is made for `./x/y/bar' + * then the actual object looked up is `./x/y/./foo'. * * Return: Non-negative on success/Negative on failure * - * Programmer: Robb Matzke + * Programmer: Robb Matzke * Monday, April 6, 1998 * *------------------------------------------------------------------------- */ herr_t -H5Lcreate_hard(hid_t cur_loc_id, const char *cur_name, hid_t new_loc_id, const char *new_name, hid_t lcpl_id, +H5Lcreate_soft(const char *link_target, hid_t link_loc_id, const char *link_name, hid_t lcpl_id, hid_t lapl_id) { - H5VL_object_t * vol_obj1 = NULL; /* Object of cur_loc_id */ - H5VL_object_t * vol_obj2 = NULL; /* Object of new_loc_id */ - H5VL_object_t tmp_vol_obj; /* Temporary object */ - H5VL_loc_params_t loc_params1; - H5VL_loc_params_t loc_params2; - herr_t ret_value = SUCCEED; /* Return value */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API(FAIL) - H5TRACE6("e", "i*si*sii", cur_loc_id, cur_name, new_loc_id, new_name, lcpl_id, lapl_id); + H5TRACE5("e", "*si*sii", link_target, link_loc_id, link_name, lcpl_id, lapl_id); + + /* Creates a soft link synchronously */ + if (H5L__create_soft_api_common(link_target, link_loc_id, link_name, lcpl_id, lapl_id, NULL, NULL) < 0) + HGOTO_ERROR(H5E_LINK, H5E_CANTCREATE, FAIL, "unable to synchronously create soft link") + +done: + FUNC_LEAVE_API(ret_value) +} /* end H5Lcreate_soft() */ + +/*------------------------------------------------------------------------- + * Function: H5Lcreate_soft_async + * + * Purpose: Asynchronous version of H5Lcreate_soft + * + * Return: Non-negative on success/Negative on failure + * + *------------------------------------------------------------------------- + */ +herr_t +H5Lcreate_soft_async(const char *app_file, const char *app_func, unsigned app_line, const char *link_target, + hid_t link_loc_id, const char *link_name, hid_t lcpl_id, hid_t lapl_id, hid_t es_id) +{ + H5VL_object_t *vol_obj = NULL; /* Object for loc_id */ + void * token = NULL; /* Request token for async operation */ + void ** token_ptr = H5_REQUEST_NULL; /* Pointer to request token for async operation */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_API(FAIL) + H5TRACE9("e", "*s*sIu*si*siii", app_file, app_func, app_line, link_target, link_loc_id, link_name, + lcpl_id, lapl_id, es_id); + + /* Set up request token pointer for asynchronous operation */ + if (H5ES_NONE != es_id) + token_ptr = &token; /* Point at token for VOL connector to set up */ + + /* Creates a soft link asynchronously */ + if (H5L__create_soft_api_common(link_target, link_loc_id, link_name, lcpl_id, lapl_id, token_ptr, + &vol_obj) < 0) + HGOTO_ERROR(H5E_LINK, H5E_CANTCREATE, FAIL, "unable to asynchronously create soft link") + + /* If a token was created, add the token to the event set */ + if (NULL != token) + /* clang-format off */ + if (H5ES_insert(es_id, vol_obj->connector, token, + H5ARG_TRACE9(FUNC, "*s*sIu*si*siii", app_file, app_func, app_line, link_target, link_loc_id, link_name, lcpl_id, lapl_id, es_id)) < 0) + /* clang-format on */ + HGOTO_ERROR(H5E_LINK, H5E_CANTINSERT, FAIL, "can't insert token into event set") + +done: + FUNC_LEAVE_API(ret_value) +} /* H5Lcreate_soft_async() */ + +/*------------------------------------------------------------------------- + * Function: H5L__create_hard_api_common + * + * Purpose: This is the common function for creating a hard link + * + * Return: Non-negative on success/Negative on failure + * + *------------------------------------------------------------------------- + */ +static herr_t +H5L__create_hard_api_common(hid_t cur_loc_id, const char *cur_name, hid_t new_loc_id, const char *new_name, + hid_t lcpl_id, hid_t lapl_id, void **token_ptr, H5VL_object_t **_vol_obj_ptr) +{ + H5VL_object_t * vol_obj1 = NULL; /* Object of cur_loc_id */ + H5VL_object_t * vol_obj2 = NULL; /* Object of new_loc_id */ + H5VL_object_t tmp_vol_obj; /* Temporary object */ + H5VL_object_t * tmp_vol_obj_ptr = &tmp_vol_obj; /* Ptr to temporary object */ + H5VL_object_t **tmp_vol_obj_ptr_ptr = + (_vol_obj_ptr ? _vol_obj_ptr : &tmp_vol_obj_ptr); /* Ptr to ptr to temporary object */ + H5VL_loc_params_t loc_params1; /* Location parameters for cur_loc_id object access */ + H5VL_loc_params_t loc_params2; /* Location parameters for new_loc_id object access */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_STATIC /* Check arguments */ if (cur_loc_id == H5L_SAME_LOC && new_loc_id == H5L_SAME_LOC) @@ -576,20 +650,202 @@ H5Lcreate_hard(hid_t cur_loc_id, const char *cur_name, hid_t new_loc_id, const c "Objects are accessed through different VOL connectors and can't be linked") /* Construct a temporary VOL object */ - tmp_vol_obj.data = (vol_obj2 ? (vol_obj2->data) : NULL); - tmp_vol_obj.connector = (vol_obj1 != NULL ? vol_obj1->connector : vol_obj2->connector); + (*tmp_vol_obj_ptr_ptr)->data = (vol_obj2 ? (vol_obj2->data) : NULL); + (*tmp_vol_obj_ptr_ptr)->connector = (vol_obj1 != NULL ? vol_obj1->connector : vol_obj2->connector); /* Create the link */ - if (H5VL_link_create(H5VL_LINK_CREATE_HARD, &tmp_vol_obj, &loc_params2, lcpl_id, lapl_id, - H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL, (vol_obj1 ? vol_obj1->data : NULL), + if (H5VL_link_create(H5VL_LINK_CREATE_HARD, *tmp_vol_obj_ptr_ptr, &loc_params2, lcpl_id, lapl_id, + H5P_DATASET_XFER_DEFAULT, token_ptr, (vol_obj1 ? vol_obj1->data : NULL), &loc_params1) < 0) HGOTO_ERROR(H5E_LINK, H5E_CANTCREATE, FAIL, "unable to create hard link") done: + FUNC_LEAVE_NOAPI(ret_value) +} /* H5L__create_hard_api_common() */ + +/*------------------------------------------------------------------------- + * Function: H5Lcreate_hard + * + * Purpose: Creates a hard link from NEW_NAME to CUR_NAME. + * + * CUR_NAME must name an existing object. CUR_NAME and + * NEW_NAME are interpreted relative to CUR_LOC_ID and + * NEW_LOC_ID, which are either file IDs or group IDs. + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Robb Matzke + * Monday, April 6, 1998 + * + *------------------------------------------------------------------------- + */ +herr_t +H5Lcreate_hard(hid_t cur_loc_id, const char *cur_name, hid_t new_loc_id, const char *new_name, hid_t lcpl_id, + hid_t lapl_id) +{ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_API(FAIL) + H5TRACE6("e", "i*si*sii", cur_loc_id, cur_name, new_loc_id, new_name, lcpl_id, lapl_id); + + /* Creates a hard link synchronously */ + if (H5L__create_hard_api_common(cur_loc_id, cur_name, new_loc_id, new_name, lcpl_id, lapl_id, NULL, + NULL) < 0) + HGOTO_ERROR(H5E_LINK, H5E_CANTCREATE, FAIL, "unable to synchronously create hard link") + +done: FUNC_LEAVE_API(ret_value) } /* end H5Lcreate_hard() */ /*------------------------------------------------------------------------- + * Function: H5Lcreate_hard_async + * + * Purpose: Asynchronous version of H5Lcreate_hard + * + * Note: The implementation for this routine is different from other + * _async operations, as the 'api_common' routine needs a "real" + * H5VL_object_t to point at, which is usually provided by the + * loc_id, but isn't here. + * + * Return: Non-negative on success/Negative on failure + * + *------------------------------------------------------------------------- + */ +herr_t +H5Lcreate_hard_async(const char *app_file, const char *app_func, unsigned app_line, hid_t cur_loc_id, + const char *cur_name, hid_t new_loc_id, const char *new_name, hid_t lcpl_id, + hid_t lapl_id, hid_t es_id) +{ + H5VL_object_t vol_obj; /* Object for loc_id */ + H5VL_object_t * vol_obj_ptr = &vol_obj; /* Pointer to object for loc_id */ + H5VL_object_t **vol_obj_ptr_ptr = &vol_obj_ptr; /* Pointer to object pointer */ + void * token = NULL; /* Request token for async operation */ + void ** token_ptr = H5_REQUEST_NULL; /* Pointer to request token for async operation */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_API(FAIL) + H5TRACE10("e", "*s*sIui*si*siii", app_file, app_func, app_line, cur_loc_id, cur_name, new_loc_id, + new_name, lcpl_id, lapl_id, es_id); + + /* Set up request token pointer for asynchronous operation */ + if (H5ES_NONE != es_id) + token_ptr = &token; /* Point at token for VOL connector to set up */ + + /* Creates a hard link asynchronously */ + if (H5L__create_hard_api_common(cur_loc_id, cur_name, new_loc_id, new_name, lcpl_id, lapl_id, token_ptr, + vol_obj_ptr_ptr) < 0) + HGOTO_ERROR(H5E_LINK, H5E_CANTCREATE, FAIL, "unable to asynchronously create hard link") + + /* If a token was created, add the token to the event set */ + if (NULL != token) + /* clang-format off */ + if (H5ES_insert(es_id, vol_obj_ptr->connector, token, + H5ARG_TRACE10(FUNC, "*s*sIui*si*siii", app_file, app_func, app_line, cur_loc_id, cur_name, new_loc_id, new_name, lcpl_id, lapl_id, es_id)) < 0) + /* clang-format on */ + HGOTO_ERROR(H5E_LINK, H5E_CANTINSERT, FAIL, "can't insert token into event set") + +done: + FUNC_LEAVE_API(ret_value) +} /* H5Lcreate_hard_async() */ + +/*------------------------------------------------------------------------- + * Function: H5Lcreate_external + * + * Purpose: Creates an external link from LINK_NAME to OBJ_NAME. + * + * External links are links to objects in other HDF5 files. They + * are allowed to "dangle" like soft links internal to a file. + * FILE_NAME is the name of the file that OBJ_NAME is is contained + * within. If OBJ_NAME is given as a relative path name, the + * path will be relative to the root group of FILE_NAME. + * LINK_NAME is interpreted relative to LINK_LOC_ID, which is + * either a file ID or a group ID. + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Quincey Koziol + * Wednesday, May 18, 2005 + * + *------------------------------------------------------------------------- + */ +herr_t +H5Lcreate_external(const char *file_name, const char *obj_name, hid_t link_loc_id, const char *link_name, + hid_t lcpl_id, hid_t lapl_id) +{ + H5VL_object_t * vol_obj = NULL; /* Object of loc_id */ + H5VL_loc_params_t loc_params; + char * norm_obj_name = NULL; /* Pointer to normalized current name */ + void * ext_link_buf = NULL; /* Buffer to contain external link */ + size_t buf_size; /* Size of buffer to hold external link */ + size_t file_name_len; /* Length of file name string */ + size_t norm_obj_name_len; /* Length of normalized object name string */ + uint8_t * p; /* Pointer into external link buffer */ + H5L_type_t link_type = H5L_TYPE_EXTERNAL; + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_API(FAIL) + H5TRACE6("e", "*s*si*sii", file_name, obj_name, link_loc_id, link_name, lcpl_id, lapl_id); + + /* Check arguments */ + if (!file_name || !*file_name) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no file name specified") + if (!obj_name || !*obj_name) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no object name specified") + if (!link_name || !*link_name) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no link name specified") + + /* Get the link creation property list */ + if (H5P_DEFAULT == lcpl_id) + lcpl_id = H5P_LINK_CREATE_DEFAULT; + + /* Set the LCPL for the API context */ + H5CX_set_lcpl(lcpl_id); + + /* Verify access property list and set up collective metadata if appropriate */ + if (H5CX_set_apl(&lapl_id, H5P_CLS_LACC, link_loc_id, TRUE) < 0) + HGOTO_ERROR(H5E_LINK, H5E_CANTSET, FAIL, "can't set access property list info") + + /* Get normalized copy of the link target */ + if (NULL == (norm_obj_name = H5G_normalize(obj_name))) + HGOTO_ERROR(H5E_LINK, H5E_BADVALUE, FAIL, "can't normalize object name") + + /* Combine the filename and link name into a single buffer to give to the UD link */ + file_name_len = HDstrlen(file_name) + 1; + norm_obj_name_len = HDstrlen(norm_obj_name) + 1; + buf_size = 1 + file_name_len + norm_obj_name_len; + if (NULL == (ext_link_buf = H5MM_malloc(buf_size))) + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "unable to allocate udata buffer") + + /* Encode the external link information */ + p = (uint8_t *)ext_link_buf; + *p++ = (H5L_EXT_VERSION << 4) | H5L_EXT_FLAGS_ALL; /* External link version & flags */ + HDstrncpy((char *)p, file_name, buf_size - 1); /* Name of file containing external link's object */ + p += file_name_len; + HDstrncpy((char *)p, norm_obj_name, buf_size - (file_name_len + 1)); /* External link's object */ + + loc_params.type = H5VL_OBJECT_BY_NAME; + loc_params.loc_data.loc_by_name.name = link_name; + loc_params.loc_data.loc_by_name.lapl_id = lapl_id; + loc_params.obj_type = H5I_get_type(link_loc_id); + + /* get the location object */ + if (NULL == (vol_obj = (H5VL_object_t *)H5I_object(link_loc_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid object identifier") + + /* Create an external link */ + if (H5VL_link_create(H5VL_LINK_CREATE_UD, vol_obj, &loc_params, lcpl_id, lapl_id, + H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL, (int)link_type, ext_link_buf, + buf_size) < 0) + HGOTO_ERROR(H5E_LINK, H5E_CANTINIT, FAIL, "unable to create external link") + +done: + H5MM_xfree(ext_link_buf); + H5MM_xfree(norm_obj_name); + + FUNC_LEAVE_API(ret_value) +} /* end H5Lcreate_external() */ + +/*------------------------------------------------------------------------- * Function: H5Lcreate_ud * * Purpose: Creates a user-defined link of type LINK_TYPE named LINK_NAME @@ -662,6 +918,43 @@ done: } /* end H5Lcreate_ud() */ /*------------------------------------------------------------------------- + * Function: H5L__delete_api_common + * + * Purpose: This is the common function for deleting a link + * + * Return: Non-negative on success/Negative on failure + * + *------------------------------------------------------------------------- + */ +static herr_t +H5L__delete_api_common(hid_t loc_id, const char *name, hid_t lapl_id, void **token_ptr, + H5VL_object_t **_vol_obj_ptr) +{ + H5VL_object_t * tmp_vol_obj = NULL; /* Object for loc_id */ + H5VL_object_t **vol_obj_ptr = + (_vol_obj_ptr ? _vol_obj_ptr : &tmp_vol_obj); /* Ptr to object ptr for loc_id */ + H5VL_loc_params_t loc_params; /* Location parameters for object access */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_STATIC + + /* Check arguments */ + /* name is verified in H5VL_setup_name_args() */ + + /* Set up object access arguments */ + if (H5VL_setup_name_args(loc_id, name, H5P_CLS_LACC, TRUE, lapl_id, vol_obj_ptr, &loc_params) < 0) + HGOTO_ERROR(H5E_LINK, H5E_CANTSET, FAIL, "can't set object access arguments") + + /* Unlink */ + if (H5VL_link_specific(*vol_obj_ptr, &loc_params, H5VL_LINK_DELETE, H5P_DATASET_XFER_DEFAULT, token_ptr) < + 0) + HGOTO_ERROR(H5E_LINK, H5E_CANTDELETE, FAIL, "unable to delete link") + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* H5L__delete_api_common() */ + +/*------------------------------------------------------------------------- * Function: H5Ldelete * * Purpose: Removes the specified NAME from the group graph and @@ -681,39 +974,104 @@ done: herr_t H5Ldelete(hid_t loc_id, const char *name, hid_t lapl_id) { - H5VL_object_t * vol_obj = NULL; /* Object of loc_id */ - H5VL_loc_params_t loc_params; - herr_t ret_value = SUCCEED; /* Return value */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API(FAIL) H5TRACE3("e", "i*si", loc_id, name, lapl_id); - /* Check arguments */ - if (!name || !*name) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no name") + /* Delete a link synchronously */ + if (H5L__delete_api_common(loc_id, name, lapl_id, NULL, NULL) < 0) + HGOTO_ERROR(H5E_LINK, H5E_CANTDELETE, FAIL, "unable to synchronously delete link") - /* Verify access property list and set up collective metadata if appropriate */ - if (H5CX_set_apl(&lapl_id, H5P_CLS_LACC, loc_id, TRUE) < 0) - HGOTO_ERROR(H5E_LINK, H5E_CANTSET, FAIL, "can't set access property list info") +done: + FUNC_LEAVE_API(ret_value) +} /* end H5Ldelete() */ - /* Fill in the location struct fields */ - loc_params.type = H5VL_OBJECT_BY_NAME; - loc_params.obj_type = H5I_get_type(loc_id); - loc_params.loc_data.loc_by_name.name = name; - loc_params.loc_data.loc_by_name.lapl_id = lapl_id; +/*------------------------------------------------------------------------- + * Function: H5Ldelete_async + * + * Purpose: Asynchronous version of H5Ldelete + * + * Return: Non-negative on success/Negative on failure + * + *------------------------------------------------------------------------- + */ +herr_t +H5Ldelete_async(const char *app_file, const char *app_func, unsigned app_line, hid_t loc_id, const char *name, + hid_t lapl_id, hid_t es_id) +{ + H5VL_object_t *vol_obj = NULL; /* Object for loc_id */ + void * token = NULL; /* Request token for async operation */ + void ** token_ptr = H5_REQUEST_NULL; /* Pointer to request token for async operation */ + herr_t ret_value = SUCCEED; /* Return value */ - /* get the location object */ - if (NULL == (vol_obj = (H5VL_object_t *)H5I_object(loc_id))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid location identifier") + FUNC_ENTER_API(FAIL) + H5TRACE7("e", "*s*sIui*sii", app_file, app_func, app_line, loc_id, name, lapl_id, es_id); - /* Unlink */ - if (H5VL_link_specific(vol_obj, &loc_params, H5VL_LINK_DELETE, H5P_DATASET_XFER_DEFAULT, - H5_REQUEST_NULL) < 0) - HGOTO_ERROR(H5E_LINK, H5E_CANTDELETE, FAIL, "unable to delete link") + /* Set up request token pointer for asynchronous operation */ + if (H5ES_NONE != es_id) + token_ptr = &token; /* Point at token for VOL connector to set up */ + + /* Delete a link asynchronously */ + if (H5L__delete_api_common(loc_id, name, lapl_id, token_ptr, &vol_obj) < 0) + HGOTO_ERROR(H5E_LINK, H5E_CANTDELETE, FAIL, "unable to asynchronously delete link") + + /* If a token was created, add the token to the event set */ + if (NULL != token) + /* clang-format off */ + if (H5ES_insert(es_id, vol_obj->connector, token, + H5ARG_TRACE7(FUNC, "*s*sIui*sii", app_file, app_func, app_line, loc_id, name, lapl_id, es_id)) < 0) + /* clang-format on */ + HGOTO_ERROR(H5E_LINK, H5E_CANTINSERT, FAIL, "can't insert token into event set") done: FUNC_LEAVE_API(ret_value) -} /* end H5Ldelete() */ +} /* H5Ldelete_async() */ + +/*------------------------------------------------------------------------- + * Function: H5L__delete_by_idx_api_common + * + * Purpose: This is the common function for deleting a link + * according to the order within an index. + * + * Return: Non-negative on success/Negative on failure + * + *------------------------------------------------------------------------- + */ +static herr_t +H5L__delete_by_idx_api_common(hid_t loc_id, const char *group_name, H5_index_t idx_type, + H5_iter_order_t order, hsize_t n, hid_t lapl_id, void **token_ptr, + H5VL_object_t **_vol_obj_ptr) +{ + H5VL_object_t * tmp_vol_obj = NULL; /* Object for loc_id */ + H5VL_object_t **vol_obj_ptr = + (_vol_obj_ptr ? _vol_obj_ptr : &tmp_vol_obj); /* Ptr to object ptr for loc_id */ + H5VL_loc_params_t loc_params; /* Location parameters for object access */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_STATIC + + /* Check arguments */ + if (!group_name || !*group_name) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no name specified") + if (idx_type <= H5_INDEX_UNKNOWN || idx_type >= H5_INDEX_N) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid index type specified") + if (order <= H5_ITER_UNKNOWN || order >= H5_ITER_N) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid iteration order specified") + + /* Set up object access arguments */ + if (H5VL_setup_idx_args(loc_id, group_name, idx_type, order, n, H5P_CLS_LACC, TRUE, lapl_id, vol_obj_ptr, + &loc_params) < 0) + HGOTO_ERROR(H5E_LINK, H5E_CANTSET, FAIL, "can't set object access arguments") + + /* Delete the link */ + if (H5VL_link_specific(*vol_obj_ptr, &loc_params, H5VL_LINK_DELETE, H5P_DATASET_XFER_DEFAULT, token_ptr) < + 0) + HGOTO_ERROR(H5E_LINK, H5E_CANTDELETE, FAIL, "unable to delete link") + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* H5L__delete_by_idx_api_common() */ /*------------------------------------------------------------------------- * Function: H5Ldelete_by_idx @@ -738,45 +1096,62 @@ herr_t H5Ldelete_by_idx(hid_t loc_id, const char *group_name, H5_index_t idx_type, H5_iter_order_t order, hsize_t n, hid_t lapl_id) { - H5VL_object_t * vol_obj = NULL; /* object of loc_id */ - H5VL_loc_params_t loc_params; - herr_t ret_value = SUCCEED; /* Return value */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API(FAIL) H5TRACE6("e", "i*sIiIohi", loc_id, group_name, idx_type, order, n, lapl_id); - /* Check arguments */ - if (!group_name || !*group_name) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no name specified") - if (idx_type <= H5_INDEX_UNKNOWN || idx_type >= H5_INDEX_N) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid index type specified") - if (order <= H5_ITER_UNKNOWN || order >= H5_ITER_N) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid iteration order specified") + /* Delete a link synchronously */ + if (H5L__delete_by_idx_api_common(loc_id, group_name, idx_type, order, n, lapl_id, NULL, NULL) < 0) + HGOTO_ERROR(H5E_LINK, H5E_CANTDELETE, FAIL, "unable to synchronously delete link") - /* Verify access property list and set up collective metadata if appropriate */ - if (H5CX_set_apl(&lapl_id, H5P_CLS_LACC, loc_id, TRUE) < 0) - HGOTO_ERROR(H5E_LINK, H5E_CANTSET, FAIL, "can't set access property list info") +done: + FUNC_LEAVE_API(ret_value) +} /* end H5Ldelete_by_idx() */ - loc_params.type = H5VL_OBJECT_BY_IDX; - loc_params.loc_data.loc_by_idx.name = group_name; - loc_params.loc_data.loc_by_idx.idx_type = idx_type; - loc_params.loc_data.loc_by_idx.order = order; - loc_params.loc_data.loc_by_idx.n = n; - loc_params.loc_data.loc_by_idx.lapl_id = lapl_id; - loc_params.obj_type = H5I_get_type(loc_id); +/*------------------------------------------------------------------------- + * Function: H5Ldelete_by_idx_async + * + * Purpose: Asynchronous version of H5Ldelete_by_idx + * + * Return: Non-negative on success/Negative on failure + * + *------------------------------------------------------------------------- + */ +herr_t +H5Ldelete_by_idx_async(const char *app_file, const char *app_func, unsigned app_line, hid_t loc_id, + const char *group_name, H5_index_t idx_type, H5_iter_order_t order, hsize_t n, + hid_t lapl_id, hid_t es_id) +{ + H5VL_object_t *vol_obj = NULL; /* Object for loc_id */ + void * token = NULL; /* Request token for async operation */ + void ** token_ptr = H5_REQUEST_NULL; /* Pointer to request token for async operation */ + herr_t ret_value = SUCCEED; /* Return value */ - /* Get the location object */ - if (NULL == (vol_obj = (H5VL_object_t *)H5I_object(loc_id))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid location identifier") + FUNC_ENTER_API(FAIL) + H5TRACE10("e", "*s*sIui*sIiIohii", app_file, app_func, app_line, loc_id, group_name, idx_type, order, n, + lapl_id, es_id); - /* Delete the link */ - if (H5VL_link_specific(vol_obj, &loc_params, H5VL_LINK_DELETE, H5P_DATASET_XFER_DEFAULT, - H5_REQUEST_NULL) < 0) - HGOTO_ERROR(H5E_LINK, H5E_CANTDELETE, FAIL, "unable to delete link") + /* Set up request token pointer for asynchronous operation */ + if (H5ES_NONE != es_id) + token_ptr = &token; /* Point at token for VOL connector to set up */ + + /* Delete a link asynchronously */ + if (H5L__delete_by_idx_api_common(loc_id, group_name, idx_type, order, n, lapl_id, token_ptr, &vol_obj) < + 0) + HGOTO_ERROR(H5E_LINK, H5E_CANTDELETE, FAIL, "unable to asynchronously delete link") + + /* If a token was created, add the token to the event set */ + if (NULL != token) + /* clang-format off */ + if (H5ES_insert(es_id, vol_obj->connector, token, + H5ARG_TRACE10(FUNC, "*s*sIui*sIiIohii", app_file, app_func, app_line, loc_id, group_name, idx_type, order, n, lapl_id, es_id)) < 0) + /* clang-format on */ + HGOTO_ERROR(H5E_LINK, H5E_CANTINSERT, FAIL, "can't insert token into event set") done: FUNC_LEAVE_API(ret_value) -} /* end H5Ldelete_by_idx() */ +} /* H5Ldelete_by_idx_async() */ /*------------------------------------------------------------------------- * Function: H5Lget_val @@ -895,6 +1270,45 @@ done: FUNC_LEAVE_API(ret_value) } /* end H5Lget_val_by_idx() */ +/*-------------------------------------------------------------------------- + * NAME + * H5L__exists_api_common + * PURPOSE + * Common helper routine for sync/async check if an attribute exists + * RETURNS + * Non-negative on success/Negative on failure + * + *--------------------------------------------------------------------------*/ +static herr_t +H5L__exists_api_common(hid_t loc_id, const char *name, hbool_t *exists, hid_t lapl_id, void **token_ptr, + H5VL_object_t **_vol_obj_ptr) +{ + H5VL_object_t * tmp_vol_obj = NULL; /* Object for loc_id */ + H5VL_object_t **vol_obj_ptr = + (_vol_obj_ptr ? _vol_obj_ptr : &tmp_vol_obj); /* Ptr to object ptr for loc_id */ + H5VL_loc_params_t loc_params; /* Location parameters for object access */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_STATIC + + /* Check arguments */ + /* name is verified in H5VL_setup_name_args() */ + if (NULL == exists) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid pointer for link existence") + + /* Set up object access arguments */ + if (H5VL_setup_name_args(loc_id, name, H5P_CLS_LACC, FALSE, lapl_id, vol_obj_ptr, &loc_params) < 0) + HGOTO_ERROR(H5E_LINK, H5E_CANTSET, FAIL, "can't set object access arguments") + + /* Check for the existence of the link */ + if (H5VL_link_specific(*vol_obj_ptr, &loc_params, H5VL_LINK_EXISTS, H5P_DATASET_XFER_DEFAULT, token_ptr, + exists) < 0) + HGOTO_ERROR(H5E_LINK, H5E_CANTGET, FAIL, "unable to get link info") + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* H5L__exists_api_common() */ + /*------------------------------------------------------------------------- * Function: H5Lexists * @@ -910,41 +1324,63 @@ done: htri_t H5Lexists(hid_t loc_id, const char *name, hid_t lapl_id) { - H5VL_object_t * vol_obj = NULL; /* object of loc_id */ - H5VL_loc_params_t loc_params; - htri_t ret_value = FAIL; /* Return value */ + hbool_t exists; /* Flag to indicate if link exists */ + htri_t ret_value = FAIL; /* Return value */ FUNC_ENTER_API(FAIL) H5TRACE3("t", "i*si", loc_id, name, lapl_id); - /* Check arguments */ - if (!name) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "name parameter cannot be NULL") - if (!*name) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "name parameter cannot be an empty string") + /* Synchronously check if a link exists */ + exists = FALSE; + if (H5L__exists_api_common(loc_id, name, &exists, lapl_id, NULL, NULL) < 0) + HGOTO_ERROR(H5E_LINK, H5E_CANTGET, FAIL, "unable to synchronously check link existence") - /* Verify access property list and set up collective metadata if appropriate */ - if (H5CX_set_apl(&lapl_id, H5P_CLS_LACC, loc_id, FALSE) < 0) - HGOTO_ERROR(H5E_LINK, H5E_CANTSET, FAIL, "can't set access property list info") + /* Set return value */ + ret_value = (htri_t)exists; - /* Set location struct fields */ - loc_params.type = H5VL_OBJECT_BY_NAME; - loc_params.obj_type = H5I_get_type(loc_id); - loc_params.loc_data.loc_by_name.name = name; - loc_params.loc_data.loc_by_name.lapl_id = lapl_id; +done: + FUNC_LEAVE_API(ret_value) +} /* end H5Lexists() */ - /* Get the location object */ - if (NULL == (vol_obj = (H5VL_object_t *)H5I_object(loc_id))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid location identifier") +/*-------------------------------------------------------------------------- + * Function: H5Lexists_async + * + * Purpose: Asynchronous version of H5Lexists + * + * Return: Success: TRUE/FALSE/FAIL + * + *--------------------------------------------------------------------------*/ +herr_t +H5Lexists_async(const char *app_file, const char *app_func, unsigned app_line, hid_t loc_id, const char *name, + hbool_t *exists, hid_t lapl_id, hid_t es_id) +{ + H5VL_object_t *vol_obj = NULL; /* Object for loc_id */ + void * token = NULL; /* Request token for async operation */ + void ** token_ptr = H5_REQUEST_NULL; /* Pointer to request token for async operation */ + herr_t ret_value = SUCCEED; /* Return value */ - /* Check for the existence of the link */ - if (H5VL_link_specific(vol_obj, &loc_params, H5VL_LINK_EXISTS, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL, - &ret_value) < 0) - HGOTO_ERROR(H5E_LINK, H5E_CANTGET, FAIL, "unable to get link info") + FUNC_ENTER_API(FAIL) + H5TRACE8("e", "*s*sIui*s*bii", app_file, app_func, app_line, loc_id, name, exists, lapl_id, es_id); + + /* Set up request token pointer for asynchronous operation */ + if (H5ES_NONE != es_id) + token_ptr = &token; /* Point at token for VOL connector to set up */ + + /* Asynchronously check if a link exists */ + if (H5L__exists_api_common(loc_id, name, exists, lapl_id, token_ptr, &vol_obj) < 0) + HGOTO_ERROR(H5E_LINK, H5E_CANTGET, FAIL, "unable to asynchronously check link existence") + + /* If a token was created, add the token to the event set */ + if (NULL != token) + if (H5ES_insert(es_id, vol_obj->connector, token, + /* clang-format off */ + H5ARG_TRACE8(FUNC, "*s*sIui*s*bii", app_file, app_func, app_line, loc_id, name, exists, lapl_id, es_id)) < 0) + /* clang-format on */ + HGOTO_ERROR(H5E_LINK, H5E_CANTINSERT, FAIL, "can't insert token into event set") done: FUNC_LEAVE_API(ret_value) -} /* end H5Lexists() */ +} /* H5Lexists_async() */ /*------------------------------------------------------------------------- * Function: H5Lget_info2 @@ -1252,6 +1688,53 @@ done: } /* end H5Lget_name_by_idx() */ /*------------------------------------------------------------------------- + * Function: H5L__iterate_api_common + * + * Purpose: This is the common function for iterating over links + * + * Return: Non-negative on success/Negative on failure + * + *------------------------------------------------------------------------- + */ +static herr_t +H5L__iterate_api_common(hid_t group_id, H5_index_t idx_type, H5_iter_order_t order, hsize_t *idx_p, + H5L_iterate2_t op, void *op_data, void **token_ptr, H5VL_object_t **_vol_obj_ptr) +{ + H5VL_object_t * tmp_vol_obj = NULL; /* Object for loc_id */ + H5VL_object_t **vol_obj_ptr = + (_vol_obj_ptr ? _vol_obj_ptr : &tmp_vol_obj); /* Ptr to object ptr for loc_id */ + H5VL_loc_params_t loc_params; /* Location parameters for object access */ + H5I_type_t id_type; /* Type of ID */ + herr_t ret_value = H5_ITER_CONT; /* Return value */ + + FUNC_ENTER_STATIC + + /* Check arguments */ + id_type = H5I_get_type(group_id); + if (!(H5I_GROUP == id_type || H5I_FILE == id_type)) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid argument") + if (idx_type <= H5_INDEX_UNKNOWN || idx_type >= H5_INDEX_N) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid index type specified") + if (order <= H5_ITER_UNKNOWN || order >= H5_ITER_N) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid iteration order specified") + if (!op) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no operator specified") + + /* Set up object access arguments */ + if (H5VL_setup_self_args(group_id, vol_obj_ptr, &loc_params) < 0) + HGOTO_ERROR(H5E_LINK, H5E_CANTSET, FAIL, "can't set object access arguments") + + /* Iterate over the links */ + if ((ret_value = H5VL_link_specific(*vol_obj_ptr, &loc_params, H5VL_LINK_ITER, H5P_DATASET_XFER_DEFAULT, + token_ptr, (unsigned)FALSE, (int)idx_type, (int)order, idx_p, op, + op_data)) < 0) + HGOTO_ERROR(H5E_LINK, H5E_BADITER, FAIL, "link iteration failed") + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* H5L__iterate_api_common() */ + +/*------------------------------------------------------------------------- * Function: H5Literate2 * * Purpose: Iterates over links in a group, with user callback routine, @@ -1273,42 +1756,69 @@ herr_t H5Literate2(hid_t group_id, H5_index_t idx_type, H5_iter_order_t order, hsize_t *idx_p, H5L_iterate2_t op, void *op_data) { - H5VL_object_t * vol_obj = NULL; /* Object of loc_id */ - H5VL_loc_params_t loc_params; - H5I_type_t id_type; /* Type of ID */ - herr_t ret_value; /* Return value */ + herr_t ret_value; /* Return value */ FUNC_ENTER_API(FAIL) H5TRACE6("e", "iIiIo*hLI*x", group_id, idx_type, order, idx_p, op, op_data); - /* Check arguments */ - id_type = H5I_get_type(group_id); - if (!(H5I_GROUP == id_type || H5I_FILE == id_type)) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid argument") - if (idx_type <= H5_INDEX_UNKNOWN || idx_type >= H5_INDEX_N) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid index type specified") - if (order <= H5_ITER_UNKNOWN || order >= H5_ITER_N) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid iteration order specified") - if (!op) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no operator specified") + /* Iterate over links synchronously */ + if ((ret_value = H5L__iterate_api_common(group_id, idx_type, order, idx_p, op, op_data, NULL, NULL)) < 0) + HGOTO_ERROR(H5E_LINK, H5E_BADITER, FAIL, "synchronous link iteration failed") - /* Get the location object */ - if (NULL == (vol_obj = (H5VL_object_t *)H5I_object(group_id))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid location identifier") +done: + FUNC_LEAVE_API(ret_value) +} /* end H5Literate2() */ - /* Set location struct fields */ - loc_params.type = H5VL_OBJECT_BY_SELF; - loc_params.obj_type = H5I_get_type(group_id); +/*------------------------------------------------------------------------- + * Function: H5Literate_async + * + * Purpose: Asynchronous version of H5Literate2 + * + * Return: Success: The return value of the first operator that + * returns non-zero, or zero if all members were + * processed with no operator returning non-zero. + * + * Failure: Negative if something goes wrong within the + * library, or the negative value returned by one + * of the operators. + * + * + *------------------------------------------------------------------------- + */ +herr_t +H5Literate_async(const char *app_file, const char *app_func, unsigned app_line, hid_t group_id, + H5_index_t idx_type, H5_iter_order_t order, hsize_t *idx_p, H5L_iterate2_t op, void *op_data, + hid_t es_id) +{ + H5VL_object_t *vol_obj = NULL; /* Object for loc_id */ + void * token = NULL; /* Request token for async operation */ + void ** token_ptr = H5_REQUEST_NULL; /* Pointer to request token for async operation */ + herr_t ret_value; /* Return value */ - /* Iterate over the links */ - if ((ret_value = H5VL_link_specific(vol_obj, &loc_params, H5VL_LINK_ITER, H5P_DATASET_XFER_DEFAULT, - H5_REQUEST_NULL, (unsigned)FALSE, (int)idx_type, (int)order, idx_p, - op, op_data)) < 0) - HGOTO_ERROR(H5E_LINK, H5E_BADITER, FAIL, "link iteration failed") + FUNC_ENTER_API(FAIL) + H5TRACE10("e", "*s*sIuiIiIo*hLI*xi", app_file, app_func, app_line, group_id, idx_type, order, idx_p, op, + op_data, es_id); + + /* Set up request token pointer for asynchronous operation */ + if (H5ES_NONE != es_id) + token_ptr = &token; /* Point at token for VOL connector to set up */ + + /* Iterate over links asynchronously */ + if ((ret_value = + H5L__iterate_api_common(group_id, idx_type, order, idx_p, op, op_data, token_ptr, &vol_obj)) < 0) + HGOTO_ERROR(H5E_LINK, H5E_BADITER, FAIL, "asynchronous link iteration failed") + + /* If a token was created, add the token to the event set */ + if (NULL != token) + /* clang-format off */ + if (H5ES_insert(es_id, vol_obj->connector, token, + H5ARG_TRACE10(FUNC, "*s*sIuiIiIo*hLI*xi", app_file, app_func, app_line, group_id, idx_type, order, idx_p, op, op_data, es_id)) < 0) + /* clang-format on */ + HGOTO_ERROR(H5E_LINK, H5E_CANTINSERT, FAIL, "can't insert token into event set") done: FUNC_LEAVE_API(ret_value) -} /* end H5Literate2() */ +} /* H5Literate_async() */ /*------------------------------------------------------------------------- * Function: H5Literate_by_name2 @@ -1519,6 +2029,88 @@ done: FUNC_LEAVE_API(ret_value) } /* end H5Lvisit_by_name2() */ +/*------------------------------------------------------------------------- + * Function: H5Lunpack_elink_val + * + * Purpose: Given a buffer holding the "link value" from an external link, + * gets pointers to the information within the link value buffer. + * + * External link link values contain some flags and + * two NULL-terminated strings, one after the other. + * + * The FLAGS value will be filled in and FILENAME and + * OBJ_PATH will be set to pointers within ext_linkval (unless + * any of these values is NULL). + * + * Using this function on strings that aren't external link + * udata buffers can result in segmentation faults. + * + * Return: Non-negative on success/ Negative on failure + * + * Programmer: James Laird + * Monday, July 17, 2006 + * + *------------------------------------------------------------------------- + */ +herr_t +H5Lunpack_elink_val(const void *_ext_linkval, size_t link_size, unsigned *flags, const char **filename, + const char **obj_path) +{ + const uint8_t *ext_linkval = (const uint8_t *)_ext_linkval; /* Pointer to the link value */ + unsigned lnk_version; /* External link format version */ + unsigned lnk_flags; /* External link flags */ + size_t len; /* Length of the filename in the linkval*/ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_API(FAIL) + H5TRACE5("e", "*xz*Iu**s**s", _ext_linkval, link_size, flags, filename, obj_path); + + /* Sanity check external link buffer */ + if (ext_linkval == NULL) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "not an external link linkval buffer") + lnk_version = (*ext_linkval >> 4) & 0x0F; + lnk_flags = *ext_linkval & 0x0F; + if (lnk_version > H5L_EXT_VERSION) + HGOTO_ERROR(H5E_LINK, H5E_CANTDECODE, FAIL, "bad version number for external link") + if (lnk_flags & (unsigned)~H5L_EXT_FLAGS_ALL) + HGOTO_ERROR(H5E_LINK, H5E_CANTDECODE, FAIL, "bad flags for external link") + if (link_size <= 2) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "not a valid external link buffer") + + /* Try to do some error checking. If the last character in the linkval + * (the last character of obj_path) isn't NULL, then something's wrong. + */ + if (ext_linkval[link_size - 1] != '\0') + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "linkval buffer is not NULL-terminated") + + /* We're now guaranteed that HDstrlen won't segfault, since the buffer has + * at least one NULL in it. + */ + len = HDstrlen((const char *)ext_linkval + 1); + + /* If the first NULL we found was at the very end of the buffer, then + * this external link value has no object name and is invalid. + */ + if ((len + 1) >= (link_size - 1)) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "linkval buffer doesn't contain an object path") + + /* If we got here then the buffer contains (at least) two strings packed + * in the correct way. Assume it's correct and return pointers to the + * filename and object path. + */ + if (filename) + *filename = (const char *)ext_linkval + 1; + if (obj_path) + *obj_path = ((const char *)ext_linkval + 1) + len + 1; /* Add one for NULL terminator */ + + /* Set the flags to return */ + if (flags) + *flags = lnk_flags; + +done: + FUNC_LEAVE_API(ret_value) +} /* end H5Lunpack_elink_val() */ + /* *------------------------------------------------------------------------- *------------------------------------------------------------------------- @@ -1528,7 +2120,7 @@ done: */ /*------------------------------------------------------------------------- - * Function: H5L_find_class_idx + * Function: H5L__find_class_idx * * Purpose: Given a link class ID, return the offset in the global array * that holds all the registered link classes. @@ -1543,12 +2135,12 @@ done: *------------------------------------------------------------------------- */ static int -H5L_find_class_idx(H5L_type_t id) +H5L__find_class_idx(H5L_type_t id) { size_t i; /* Local index variable */ int ret_value = FAIL; /* Return value */ - FUNC_ENTER_NOAPI_NOINIT_NOERR + FUNC_ENTER_STATIC_NOERR for (i = 0; i < H5L_table_used_g; i++) if (H5L_table_g[i].id == id) @@ -1556,7 +2148,7 @@ H5L_find_class_idx(H5L_type_t id) done: FUNC_LEAVE_NOAPI(ret_value) -} /* end H5L_find_class_idx */ +} /* end H5L__find_class_idx */ /*------------------------------------------------------------------------- * Function: H5L_find_class @@ -1581,7 +2173,7 @@ H5L_find_class(H5L_type_t id) FUNC_ENTER_NOAPI(NULL) /* Get the index in the global table */ - if ((idx = H5L_find_class_idx(id)) < 0) + if ((idx = H5L__find_class_idx(id)) < 0) HGOTO_ERROR(H5E_LINK, H5E_NOTREGISTERED, NULL, "unable to find link class") /* Set return value */ @@ -1913,7 +2505,7 @@ done: /* Close the location given to the user callback if it was created */ if (grp_id >= 0) { if (H5I_dec_app_ref(grp_id) < 0) - HDONE_ERROR(H5E_LINK, H5E_CANTRELEASE, FAIL, "unable to close atom from UD callback") + HDONE_ERROR(H5E_LINK, H5E_CANTRELEASE, FAIL, "unable to close ID from UD callback") } /* end if */ else if (grp != NULL) { if (H5G_close(grp) < 0) @@ -2017,7 +2609,7 @@ done: } /* end H5L__create_real() */ /*------------------------------------------------------------------------- - * Function: H5L_create_hard + * Function: H5L__create_hard * * Purpose: Creates a hard link from NEW_NAME to CUR_NAME. * @@ -2029,8 +2621,8 @@ done: *------------------------------------------------------------------------- */ herr_t -H5L_create_hard(H5G_loc_t *cur_loc, const char *cur_name, const H5G_loc_t *link_loc, const char *link_name, - hid_t lcpl_id) +H5L__create_hard(H5G_loc_t *cur_loc, const char *cur_name, const H5G_loc_t *link_loc, const char *link_name, + hid_t lcpl_id) { char * norm_cur_name = NULL; /* Pointer to normalized current name */ H5F_t * link_file = NULL; /* Pointer to file to link to */ @@ -2041,7 +2633,7 @@ H5L_create_hard(H5G_loc_t *cur_loc, const char *cur_name, const H5G_loc_t *link_ hbool_t loc_valid = FALSE; herr_t ret_value = SUCCEED; /* Return value */ - FUNC_ENTER_NOAPI(FAIL) + FUNC_ENTER_PACKAGE /* Check args */ HDassert(cur_loc); @@ -2086,10 +2678,10 @@ done: H5MM_xfree(norm_cur_name); FUNC_LEAVE_NOAPI(ret_value) -} /* end H5L_create_hard() */ +} /* end H5L__create_hard() */ /*------------------------------------------------------------------------- - * Function: H5L_create_soft + * Function: H5L__create_soft * * Purpose: Creates a soft link from LINK_NAME to TARGET_PATH. * @@ -2101,13 +2693,13 @@ done: *------------------------------------------------------------------------- */ herr_t -H5L_create_soft(const char *target_path, const H5G_loc_t *link_loc, const char *link_name, hid_t lcpl_id) +H5L__create_soft(const char *target_path, const H5G_loc_t *link_loc, const char *link_name, hid_t lcpl_id) { char * norm_target = NULL; /* Pointer to normalized current name */ H5O_link_t lnk; /* Link to insert */ herr_t ret_value = SUCCEED; /* Return value */ - FUNC_ENTER_NOAPI(FAIL) + FUNC_ENTER_PACKAGE /* Check args */ HDassert(link_loc); @@ -2132,7 +2724,7 @@ done: H5MM_xfree(norm_target); FUNC_LEAVE_NOAPI(ret_value) -} /* end H5L_create_soft() */ +} /* end H5L__create_soft() */ /*------------------------------------------------------------------------- * Function: H5L__create_ud @@ -2166,7 +2758,7 @@ H5L__create_ud(const H5G_loc_t *link_loc, const char *link_name, const void *ud_ lnk.u.ud.udata = NULL; /* Make sure that this link class is registered */ - if (H5L_find_class_idx(type) < 0) + if (H5L__find_class_idx(type) < 0) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "link class has not been registered with library") /* Fill in UD link-specific information in the link struct*/ @@ -2284,7 +2876,7 @@ done: } /* end H5L__get_val_cb() */ /*------------------------------------------------------------------------- - * Function: H5L_get_val + * Function: H5L__get_val * * Purpose: Returns the value of a symbolic link or the udata for a * user-defined link. @@ -2303,12 +2895,12 @@ done: *------------------------------------------------------------------------- */ herr_t -H5L_get_val(const H5G_loc_t *loc, const char *name, void *buf /*out*/, size_t size) +H5L__get_val(const H5G_loc_t *loc, const char *name, void *buf /*out*/, size_t size) { H5L_trav_gv_t udata; /* User data for callback */ herr_t ret_value = SUCCEED; /* Return value */ - FUNC_ENTER_NOAPI(FAIL) + FUNC_ENTER_PACKAGE /* Sanity check */ HDassert(loc); @@ -2324,7 +2916,7 @@ H5L_get_val(const H5G_loc_t *loc, const char *name, void *buf /*out*/, size_t si done: FUNC_LEAVE_NOAPI(ret_value) -} /* H5L_get_val() */ +} /* H5L__get_val() */ /*------------------------------------------------------------------------- * Function: H5L__get_val_by_idx_cb @@ -2377,7 +2969,7 @@ done: } /* end H5L__get_val_by_idx_cb() */ /*------------------------------------------------------------------------- - * Function: H5L_get_val_by_idx + * Function: H5L__get_val_by_idx * * Purpose: Internal routine to query a link value according to the * index within a group @@ -2390,13 +2982,13 @@ done: *------------------------------------------------------------------------- */ herr_t -H5L_get_val_by_idx(const H5G_loc_t *loc, const char *name, H5_index_t idx_type, H5_iter_order_t order, - hsize_t n, void *buf /*out*/, size_t size) +H5L__get_val_by_idx(const H5G_loc_t *loc, const char *name, H5_index_t idx_type, H5_iter_order_t order, + hsize_t n, void *buf /*out*/, size_t size) { H5L_trav_gvbi_t udata; /* User data for callback */ herr_t ret_value = SUCCEED; /* Return value */ - FUNC_ENTER_NOAPI(FAIL) + FUNC_ENTER_PACKAGE /* Check arguments */ HDassert(loc); @@ -2415,7 +3007,7 @@ H5L_get_val_by_idx(const H5G_loc_t *loc, const char *name, H5_index_t idx_type, done: FUNC_LEAVE_NOAPI(ret_value) -} /* end H5L_get_val_by_idx() */ +} /* end H5L__get_val_by_idx() */ /*------------------------------------------------------------------------- * Function: H5L__delete_cb @@ -2467,7 +3059,7 @@ done: } /* end H5L__delete_cb() */ /*------------------------------------------------------------------------- - * Function: H5L_delete + * Function: H5L__delete * * Purpose: Delete a link from a group. * @@ -2479,12 +3071,12 @@ done: *------------------------------------------------------------------------- */ herr_t -H5L_delete(const H5G_loc_t *loc, const char *name) +H5L__delete(const H5G_loc_t *loc, const char *name) { char * norm_name = NULL; /* Pointer to normalized name */ herr_t ret_value = SUCCEED; /* Return value */ - FUNC_ENTER_NOAPI(FAIL) + FUNC_ENTER_PACKAGE /* Sanity check */ HDassert(loc); @@ -2505,7 +3097,7 @@ done: H5MM_xfree(norm_name); FUNC_LEAVE_NOAPI(ret_value) -} /* end H5L_delete() */ +} /* end H5L__delete() */ /*------------------------------------------------------------------------- * Function: H5L__delete_by_idx_cb @@ -2547,7 +3139,7 @@ done: } /* end H5L__delete_by_idx_cb() */ /*------------------------------------------------------------------------- - * Function: H5L_delete_by_idx + * Function: H5L__delete_by_idx * * Purpose: Internal routine to delete a link according to its index * within a group. @@ -2560,13 +3152,13 @@ done: *------------------------------------------------------------------------- */ herr_t -H5L_delete_by_idx(const H5G_loc_t *loc, const char *name, H5_index_t idx_type, H5_iter_order_t order, - hsize_t n) +H5L__delete_by_idx(const H5G_loc_t *loc, const char *name, H5_index_t idx_type, H5_iter_order_t order, + hsize_t n) { H5L_trav_rmbi_t udata; /* User data for callback */ herr_t ret_value = SUCCEED; /* Return value */ - FUNC_ENTER_NOAPI(FAIL) + FUNC_ENTER_PACKAGE /* Sanity check */ HDassert(loc); @@ -2584,7 +3176,7 @@ H5L_delete_by_idx(const H5G_loc_t *loc, const char *name, H5_index_t idx_type, H done: FUNC_LEAVE_NOAPI(ret_value) -} /* end H5L_delete_by_idx() */ +} /* end H5L__delete_by_idx() */ /*------------------------------------------------------------------------- * Function: H5L__move_dest_cb @@ -2678,7 +3270,7 @@ done: /* Close the location given to the user callback if it was created */ if (grp_id >= 0) { if (H5I_dec_app_ref(grp_id) < 0) - HDONE_ERROR(H5E_LINK, H5E_CANTRELEASE, FAIL, "unable to close atom from UD callback") + HDONE_ERROR(H5E_LINK, H5E_CANTRELEASE, FAIL, "unable to close ID from UD callback") } /* end if */ else if (grp != NULL) { if (H5G_close(grp) < 0) @@ -2813,7 +3405,7 @@ done: } /* end H5L__move_cb() */ /*------------------------------------------------------------------------- - * Function: H5L_move + * Function: H5L__move * * Purpose: Atomically move or copy a link. * @@ -2833,8 +3425,8 @@ done: *------------------------------------------------------------------------- */ herr_t -H5L_move(const H5G_loc_t *src_loc, const char *src_name, const H5G_loc_t *dst_loc, const char *dst_name, - hbool_t copy_flag, hid_t lcpl_id) +H5L__move(const H5G_loc_t *src_loc, const char *src_name, const H5G_loc_t *dst_loc, const char *dst_name, + hbool_t copy_flag, hid_t lcpl_id) { unsigned dst_target_flags = H5G_TARGET_NORMAL; H5T_cset_t char_encoding = H5F_DEFAULT_CSET; /* Character encoding for link */ @@ -2842,7 +3434,7 @@ H5L_move(const H5G_loc_t *src_loc, const char *src_name, const H5G_loc_t *dst_lo H5L_trav_mv_t udata; /* User data for traversal */ herr_t ret_value = SUCCEED; /* Return value */ - FUNC_ENTER_NOAPI(FAIL) + FUNC_ENTER_PACKAGE /* Sanity check */ HDassert(src_loc); @@ -2890,7 +3482,7 @@ H5L_move(const H5G_loc_t *src_loc, const char *src_name, const H5G_loc_t *dst_lo done: FUNC_LEAVE_NOAPI(ret_value) -} /* end H5L_move() */ +} /* end H5L__move() */ /*------------------------------------------------------------------------- * Function: H5L__exists_final_cb @@ -2915,7 +3507,7 @@ H5L__exists_final_cb(H5G_loc_t H5_ATTR_UNUSED *grp_loc /*in*/, const char H5_ATT FUNC_ENTER_STATIC_NOERR /* Check if the name in this group resolved to a valid link */ - udata->exists = (hbool_t)(lnk != NULL); + *udata->exists = (hbool_t)(lnk != NULL); /* Indicate that this callback didn't take ownership of the group * * location for the object */ @@ -2970,10 +3562,10 @@ H5L__exists_inter_cb(H5G_loc_t H5_ATTR_UNUSED *grp_loc /*in*/, const char H5_ATT HGOTO_ERROR(H5E_LINK, H5E_CANTGET, FAIL, "can't determine if link exists") } /* end if */ else - udata->exists = TRUE; + *udata->exists = TRUE; } /* end if */ else - udata->exists = FALSE; + *udata->exists = FALSE; /* Indicate that this callback didn't take ownership of the group * * location for the object */ @@ -2988,7 +3580,7 @@ done: * * Purpose: Returns whether a link exists in a group * - * Note: Same as H5L_exists, except that missing links are reported + * Note: Same as H5L__exists, except that missing links are reported * as 'FALSE' instead of causing failures * * Return: Non-negative (TRUE/FALSE) on success/Negative on failure @@ -2998,20 +3590,21 @@ done: * *------------------------------------------------------------------------- */ -htri_t -H5L_exists_tolerant(const H5G_loc_t *loc, const char *name) +herr_t +H5L_exists_tolerant(const H5G_loc_t *loc, const char *name, hbool_t *exists) { - H5L_trav_le_t udata; /* User data for traversal */ - H5G_traverse_t cb_func; /* Callback function for tranversal */ - char * name_copy = NULL; /* Duplicate of name */ - char * name_trav; /* Name to traverse */ - htri_t ret_value = FAIL; /* Return value */ + H5L_trav_le_t udata; /* User data for traversal */ + H5G_traverse_t cb_func; /* Callback function for tranversal */ + char * name_copy = NULL; /* Duplicate of name */ + char * name_trav; /* Name to traverse */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI(FAIL) /* Sanity checks */ HDassert(loc); HDassert(name); + HDassert(exists); /* Copy the name and skip leading '/'s */ name_trav = name_copy = H5MM_strdup(name); @@ -3020,27 +3613,25 @@ H5L_exists_tolerant(const H5G_loc_t *loc, const char *name) /* A path of "/" will always exist in a file */ if ('\0' == *name_trav) - HGOTO_DONE(TRUE) - - /* Set up user data & correct callback */ - udata.exists = FALSE; - if (NULL == (udata.sep = HDstrchr(name_trav, '/'))) - cb_func = H5L__exists_final_cb; + *exists = TRUE; else { - /* Chew through adjacent separators, if present */ - do { - *udata.sep = '\0'; - udata.sep++; - } while ('/' == *udata.sep); - cb_func = H5L__exists_inter_cb; - } /* end else */ - - /* Traverse the group hierarchy to locate the link to check */ - if (H5G_traverse(loc, name_trav, H5G_TARGET_SLINK | H5G_TARGET_UDLINK, cb_func, &udata) < 0) - HGOTO_ERROR(H5E_LINK, H5E_CANTGET, FAIL, "can't determine if link exists") + /* Set up user data & correct callback */ + udata.exists = exists; + if (NULL == (udata.sep = HDstrchr(name_trav, '/'))) + cb_func = H5L__exists_final_cb; + else { + /* Chew through adjacent separators, if present */ + do { + *udata.sep = '\0'; + udata.sep++; + } while ('/' == *udata.sep); + cb_func = H5L__exists_inter_cb; + } /* end else */ - /* Set return value */ - ret_value = (htri_t)udata.exists; + /* Traverse the group hierarchy to locate the link to check */ + if (H5G_traverse(loc, name_trav, H5G_TARGET_SLINK | H5G_TARGET_UDLINK, cb_func, &udata) < 0) + HGOTO_ERROR(H5E_LINK, H5E_CANTGET, FAIL, "can't determine if link exists") + } done: /* Release duplicated string */ @@ -3050,43 +3641,46 @@ done: } /* H5L_exists_tolerant() */ /*------------------------------------------------------------------------- - * Function: H5L_exists + * Function: H5L__exists * * Purpose: Returns whether a link exists in a group * * Note: Same as H5L_exists_tolerant, except that missing links are reported * as failures * - * Return: Non-negative (TRUE/FALSE) on success/Negative on failure + * Return: Non-negative on success, with *exists set/Negative on failure * * Programmer: Quincey Koziol * Friday, March 16 2007 * *------------------------------------------------------------------------- */ -htri_t -H5L_exists(const H5G_loc_t *loc, const char *name) +herr_t +H5L__exists(const H5G_loc_t *loc, const char *name, hbool_t *exists) { - H5L_trav_le_t udata; /* User data for traversal */ - htri_t ret_value = FAIL; /* Return value */ + H5L_trav_le_t udata; /* User data for traversal */ + herr_t ret_value = SUCCEED; /* Return value */ - FUNC_ENTER_NOAPI(FAIL) + FUNC_ENTER_PACKAGE + + /* Sanity checks */ + HDassert(loc); + HDassert(name); + HDassert(exists); /* A path of "/" will always exist in a file */ if (0 == HDstrcmp(name, "/")) - HGOTO_DONE(TRUE) - - /* Traverse the group hierarchy to locate the object to get info about */ - udata.exists = FALSE; - if (H5G_traverse(loc, name, H5G_TARGET_SLINK | H5G_TARGET_UDLINK, H5L__exists_final_cb, &udata) < 0) - HGOTO_ERROR(H5E_LINK, H5E_EXISTS, FAIL, "path doesn't exist") - - /* Set return value */ - ret_value = (htri_t)udata.exists; + *exists = TRUE; + else { + /* Traverse the group hierarchy to locate the object to get info about */ + udata.exists = exists; + if (H5G_traverse(loc, name, H5G_TARGET_SLINK | H5G_TARGET_UDLINK, H5L__exists_final_cb, &udata) < 0) + HGOTO_ERROR(H5E_LINK, H5E_EXISTS, FAIL, "link doesn't exist") + } done: FUNC_LEAVE_NOAPI(ret_value) -} /* H5L_exists() */ +} /* H5L__exists() */ /*------------------------------------------------------------------------- * Function: H5L__get_info_cb @@ -3206,7 +3800,7 @@ done: } /* end H5L__get_info_by_idx_cb() */ /*------------------------------------------------------------------------- - * Function: H5L_get_info_by_idx + * Function: H5L__get_info_by_idx * * Purpose: Internal routine to retrieve link info according to an * index's order. @@ -3216,13 +3810,13 @@ done: *------------------------------------------------------------------------- */ herr_t -H5L_get_info_by_idx(const H5G_loc_t *loc, const char *name, H5_index_t idx_type, H5_iter_order_t order, - hsize_t n, H5L_info2_t *linfo /*out*/) +H5L__get_info_by_idx(const H5G_loc_t *loc, const char *name, H5_index_t idx_type, H5_iter_order_t order, + hsize_t n, H5L_info2_t *linfo /*out*/) { H5L_trav_gibi_t udata; /* User data for callback */ herr_t ret_value = SUCCEED; /* Return value */ - FUNC_ENTER_NOAPI(FAIL) + FUNC_ENTER_PACKAGE /* Check arguments */ HDassert(loc); @@ -3241,7 +3835,7 @@ H5L_get_info_by_idx(const H5G_loc_t *loc, const char *name, H5_index_t idx_type, done: FUNC_LEAVE_NOAPI(ret_value) -} /* end H5L_get_info_by_idx() */ +} /* end H5L__get_info_by_idx() */ /*------------------------------------------------------------------------- * Function: H5L__get_name_by_idx_cb @@ -3284,7 +3878,7 @@ done: } /* end H5L__get_name_by_idx_cb() */ /*------------------------------------------------------------------------- - * Function: H5L_get_name_by_idx + * Function: H5L__get_name_by_idx * * Purpose: Internal routine to retrieve link name according to an * index's order. @@ -3294,13 +3888,13 @@ done: *------------------------------------------------------------------------- */ ssize_t -H5L_get_name_by_idx(const H5G_loc_t *loc, const char *group_name, H5_index_t idx_type, H5_iter_order_t order, - hsize_t n, char *name /*out*/, size_t size) +H5L__get_name_by_idx(const H5G_loc_t *loc, const char *group_name, H5_index_t idx_type, H5_iter_order_t order, + hsize_t n, char *name /*out*/, size_t size) { H5L_trav_gnbi_t udata; /* User data for callback */ ssize_t ret_value = FAIL; /* Return value */ - FUNC_ENTER_NOAPI(FAIL) + FUNC_ENTER_PACKAGE /* Check arguments */ HDassert(loc); @@ -3324,7 +3918,7 @@ H5L_get_name_by_idx(const H5G_loc_t *loc, const char *group_name, H5_index_t idx done: FUNC_LEAVE_NOAPI(ret_value) -} /* end H5L_get_name_by_idx() */ +} /* end H5L__get_name_by_idx() */ /*------------------------------------------------------------------------- * Function: H5L__link_copy_file @@ -3335,7 +3929,6 @@ done: * Return: Non-negative on success/Negative on failure * * Programmer: Quincey Koziol - * koziol@hdfgroup.org * Sep 29 2006 * *------------------------------------------------------------------------- diff --git a/src/H5Ldeprec.c b/src/H5Ldeprec.c index bed0566..df4c384 100644 --- a/src/H5Ldeprec.c +++ b/src/H5Ldeprec.c @@ -341,7 +341,7 @@ H5Lget_info1(hid_t loc_id, const char *name, H5L_info1_t *linfo /*out*/, hid_t l void *vol_obj_data; if (NULL == (vol_obj_data = H5VL_object_data(vol_obj))) - HGOTO_ERROR(H5E_VOL, H5E_CANTGET, FAIL, "can't get underlying VOL object") + HGOTO_ERROR(H5E_LINK, H5E_CANTGET, FAIL, "can't get underlying VOL object") if (H5VL_native_token_to_addr(vol_obj_data, loc_params.obj_type, linfo2.u.token, &linfo->u.address) < 0) @@ -431,7 +431,7 @@ H5Lget_info_by_idx1(hid_t loc_id, const char *group_name, H5_index_t idx_type, H void *vol_obj_data; if (NULL == (vol_obj_data = H5VL_object_data(vol_obj))) - HGOTO_ERROR(H5E_VOL, H5E_CANTGET, FAIL, "can't get underlying VOL object") + HGOTO_ERROR(H5E_LINK, H5E_CANTGET, FAIL, "can't get underlying VOL object") if (H5VL_native_token_to_addr(vol_obj_data, loc_params.obj_type, linfo2.u.token, &linfo->u.address) < 0) diff --git a/src/H5Lexternal.c b/src/H5Lexternal.c index c1bd83f..eccd2c6 100644 --- a/src/H5Lexternal.c +++ b/src/H5Lexternal.c @@ -38,12 +38,6 @@ /* Local Macros */ /****************/ -/* Version of external link format */ -#define H5L_EXT_VERSION 0 - -/* Valid flags for external links */ -#define H5L_EXT_FLAGS_ALL 0 - /* Size of local link name buffer for traversing external links */ #define H5L_EXT_TRAVERSE_BUF_SIZE 256 @@ -313,103 +307,6 @@ done: } /* end H5L__extern_query() */ /*------------------------------------------------------------------------- - * Function: H5Lcreate_external - * - * Purpose: Creates an external link from LINK_NAME to OBJ_NAME. - * - * External links are links to objects in other HDF5 files. They - * are allowed to "dangle" like soft links internal to a file. - * FILE_NAME is the name of the file that OBJ_NAME is is contained - * within. If OBJ_NAME is given as a relative path name, the - * path will be relative to the root group of FILE_NAME. - * LINK_NAME is interpreted relative to LINK_LOC_ID, which is - * either a file ID or a group ID. - * - * Return: Non-negative on success/Negative on failure - * - * Programmer: Quincey Koziol - * Wednesday, May 18, 2005 - * - *------------------------------------------------------------------------- - */ -herr_t -H5Lcreate_external(const char *file_name, const char *obj_name, hid_t link_loc_id, const char *link_name, - hid_t lcpl_id, hid_t lapl_id) -{ - H5VL_object_t * vol_obj = NULL; /* Object of loc_id */ - H5VL_loc_params_t loc_params; - char * norm_obj_name = NULL; /* Pointer to normalized current name */ - void * ext_link_buf = NULL; /* Buffer to contain external link */ - size_t buf_size; /* Size of buffer to hold external link */ - size_t file_name_len; /* Length of file name string */ - size_t norm_obj_name_len; /* Length of normalized object name string */ - uint8_t * p; /* Pointer into external link buffer */ - H5L_type_t link_type = H5L_TYPE_EXTERNAL; - herr_t ret_value = SUCCEED; /* Return value */ - - FUNC_ENTER_API(FAIL) - H5TRACE6("e", "*s*si*sii", file_name, obj_name, link_loc_id, link_name, lcpl_id, lapl_id); - - /* Check arguments */ - if (!file_name || !*file_name) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no file name specified") - if (!obj_name || !*obj_name) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no object name specified") - if (!link_name || !*link_name) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no link name specified") - - /* Get the link creation property list */ - if (H5P_DEFAULT == lcpl_id) - lcpl_id = H5P_LINK_CREATE_DEFAULT; - - /* Set the LCPL for the API context */ - H5CX_set_lcpl(lcpl_id); - - /* Verify access property list and set up collective metadata if appropriate */ - if (H5CX_set_apl(&lapl_id, H5P_CLS_LACC, link_loc_id, TRUE) < 0) - HGOTO_ERROR(H5E_LINK, H5E_CANTSET, FAIL, "can't set access property list info") - - /* Get normalized copy of the link target */ - if (NULL == (norm_obj_name = H5G_normalize(obj_name))) - HGOTO_ERROR(H5E_LINK, H5E_BADVALUE, FAIL, "can't normalize object name") - - /* Combine the filename and link name into a single buffer to give to the UD link */ - file_name_len = HDstrlen(file_name) + 1; - norm_obj_name_len = HDstrlen(norm_obj_name) + 1; - buf_size = 1 + file_name_len + norm_obj_name_len; - if (NULL == (ext_link_buf = H5MM_malloc(buf_size))) - HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "unable to allocate udata buffer") - - /* Encode the external link information */ - p = (uint8_t *)ext_link_buf; - *p++ = (H5L_EXT_VERSION << 4) | H5L_EXT_FLAGS_ALL; /* External link version & flags */ - HDstrncpy((char *)p, file_name, buf_size - 1); /* Name of file containing external link's object */ - p += file_name_len; - HDstrncpy((char *)p, norm_obj_name, buf_size - (file_name_len + 1)); /* External link's object */ - - loc_params.type = H5VL_OBJECT_BY_NAME; - loc_params.loc_data.loc_by_name.name = link_name; - loc_params.loc_data.loc_by_name.lapl_id = lapl_id; - loc_params.obj_type = H5I_get_type(link_loc_id); - - /* get the location object */ - if (NULL == (vol_obj = (H5VL_object_t *)H5I_object(link_loc_id))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid object identifier") - - /* Create an external link */ - if (H5VL_link_create(H5VL_LINK_CREATE_UD, vol_obj, &loc_params, lcpl_id, lapl_id, - H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL, (int)link_type, ext_link_buf, - buf_size) < 0) - HGOTO_ERROR(H5E_LINK, H5E_CANTINIT, FAIL, "unable to create external link") - -done: - H5MM_xfree(ext_link_buf); - H5MM_xfree(norm_obj_name); - - FUNC_LEAVE_API(ret_value) -} /* end H5Lcreate_external() */ - -/*------------------------------------------------------------------------- * Function: H5L_register_external * * Purpose: Registers default "External Link" link class. @@ -436,85 +333,3 @@ H5L_register_external(void) done: FUNC_LEAVE_NOAPI(ret_value) } /* end H5L_register_external() */ - -/*------------------------------------------------------------------------- - * Function: H5Lunpack_elink_val - * - * Purpose: Given a buffer holding the "link value" from an external link, - * gets pointers to the information within the link value buffer. - * - * External link link values contain some flags and - * two NULL-terminated strings, one after the other. - * - * The FLAGS value will be filled in and FILENAME and - * OBJ_PATH will be set to pointers within ext_linkval (unless - * any of these values is NULL). - * - * Using this function on strings that aren't external link - * udata buffers can result in segmentation faults. - * - * Return: Non-negative on success/ Negative on failure - * - * Programmer: James Laird - * Monday, July 17, 2006 - * - *------------------------------------------------------------------------- - */ -herr_t -H5Lunpack_elink_val(const void *_ext_linkval, size_t link_size, unsigned *flags, const char **filename, - const char **obj_path) -{ - const uint8_t *ext_linkval = (const uint8_t *)_ext_linkval; /* Pointer to the link value */ - unsigned lnk_version; /* External link format version */ - unsigned lnk_flags; /* External link flags */ - size_t len; /* Length of the filename in the linkval*/ - herr_t ret_value = SUCCEED; /* Return value */ - - FUNC_ENTER_API(FAIL) - H5TRACE5("e", "*xz*Iu**s**s", _ext_linkval, link_size, flags, filename, obj_path); - - /* Sanity check external link buffer */ - if (ext_linkval == NULL) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "not an external link linkval buffer") - lnk_version = (*ext_linkval >> 4) & 0x0F; - lnk_flags = *ext_linkval & 0x0F; - if (lnk_version > H5L_EXT_VERSION) - HGOTO_ERROR(H5E_LINK, H5E_CANTDECODE, FAIL, "bad version number for external link") - if (lnk_flags & (unsigned)~H5L_EXT_FLAGS_ALL) - HGOTO_ERROR(H5E_LINK, H5E_CANTDECODE, FAIL, "bad flags for external link") - if (link_size <= 2) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "not a valid external link buffer") - - /* Try to do some error checking. If the last character in the linkval - * (the last character of obj_path) isn't NULL, then something's wrong. - */ - if (ext_linkval[link_size - 1] != '\0') - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "linkval buffer is not NULL-terminated") - - /* We're now guaranteed that HDstrlen won't segfault, since the buffer has - * at least one NULL in it. - */ - len = HDstrlen((const char *)ext_linkval + 1); - - /* If the first NULL we found was at the very end of the buffer, then - * this external link value has no object name and is invalid. - */ - if ((len + 1) >= (link_size - 1)) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "linkval buffer doesn't contain an object path") - - /* If we got here then the buffer contains (at least) two strings packed - * in the correct way. Assume it's correct and return pointers to the - * filename and object path. - */ - if (filename) - *filename = (const char *)ext_linkval + 1; - if (obj_path) - *obj_path = ((const char *)ext_linkval + 1) + len + 1; /* Add one for NULL terminator */ - - /* Set the flags to return */ - if (flags) - *flags = lnk_flags; - -done: - FUNC_LEAVE_API(ret_value) -} /* end H5Lunpack_elink_val() */ diff --git a/src/H5Lpkg.h b/src/H5Lpkg.h index c97bbf3..7057e30 100644 --- a/src/H5Lpkg.h +++ b/src/H5Lpkg.h @@ -35,6 +35,12 @@ /* Package Private Macros */ /**************************/ +/* Version of external link format */ +#define H5L_EXT_VERSION 0 + +/* Valid flags for external links */ +#define H5L_EXT_FLAGS_ALL 0 + /****************************/ /* Package Private Typedefs */ /****************************/ @@ -47,9 +53,26 @@ /* Package Private Prototypes */ /******************************/ -H5_DLL herr_t H5L__create_ud(const H5G_loc_t *link_loc, const char *link_name, const void *ud_data, - size_t ud_data_size, H5L_type_t type, hid_t lcpl_id); -H5_DLL herr_t H5L__link_copy_file(H5F_t *dst_file, const H5O_link_t *_src_lnk, const H5O_loc_t *src_oloc, - H5O_link_t *dst_lnk, H5O_copy_t *cpy_info); +H5_DLL herr_t H5L__create_hard(H5G_loc_t *cur_loc, const char *cur_name, const H5G_loc_t *link_loc, + const char *link_name, hid_t lcpl_id); +H5_DLL herr_t H5L__create_soft(const char *target_path, const H5G_loc_t *cur_loc, const char *cur_name, + hid_t lcpl_id); +H5_DLL herr_t H5L__create_ud(const H5G_loc_t *link_loc, const char *link_name, const void *ud_data, + size_t ud_data_size, H5L_type_t type, hid_t lcpl_id); +H5_DLL herr_t H5L__exists(const H5G_loc_t *loc, const char *name, hbool_t *exists); +H5_DLL herr_t H5L__get_info_by_idx(const H5G_loc_t *loc, const char *name, H5_index_t idx_type, + H5_iter_order_t order, hsize_t n, H5L_info2_t *linfo /*out*/); +H5_DLL ssize_t H5L__get_name_by_idx(const H5G_loc_t *loc, const char *group_name, H5_index_t idx_type, + H5_iter_order_t order, hsize_t n, char *name /*out*/, size_t size); +H5_DLL herr_t H5L__get_val(const H5G_loc_t *loc, const char *name, void *buf /*out*/, size_t size); +H5_DLL herr_t H5L__get_val_by_idx(const H5G_loc_t *loc, const char *name, H5_index_t idx_type, + H5_iter_order_t order, hsize_t n, void *buf /*out*/, size_t size); +H5_DLL herr_t H5L__move(const H5G_loc_t *src_loc, const char *src_name, const H5G_loc_t *dst_loc, + const char *dst_name, hbool_t copy_flag, hid_t lcpl_id); +H5_DLL herr_t H5L__delete(const H5G_loc_t *loc, const char *name); +H5_DLL herr_t H5L__delete_by_idx(const H5G_loc_t *loc, const char *name, H5_index_t idx_type, + H5_iter_order_t order, hsize_t n); +H5_DLL herr_t H5L__link_copy_file(H5F_t *dst_file, const H5O_link_t *_src_lnk, const H5O_loc_t *src_oloc, + H5O_link_t *dst_lnk, H5O_copy_t *cpy_info); #endif /* H5Lpkg_H */ diff --git a/src/H5Lprivate.h b/src/H5Lprivate.h index 20e064c..740fc1e 100644 --- a/src/H5Lprivate.h +++ b/src/H5Lprivate.h @@ -22,8 +22,8 @@ #include "H5Lpublic.h" /* Private headers needed by this file */ -#include "H5Gprivate.h" /* Groups */ -#include "H5Oprivate.h" /* Object headers */ +#include "H5Gprivate.h" /* Groups */ +#include "H5Oprivate.h" /* Object headers */ /**************************/ /* Library Private Macros */ @@ -36,13 +36,16 @@ #define H5L_CRT_INTERMEDIATE_GROUP_NAME "intermediate_group" /* Create intermediate groups flag */ /* ======== Link access property names ======== */ -#define H5L_ACS_NLINKS_NAME "max soft links" /* Number of soft links to traverse */ -#define H5L_ACS_ELINK_PREFIX_NAME "external link prefix" /* External link prefix */ -#define H5L_ACS_ELINK_FAPL_NAME \ - "external link fapl" /* file access property list for external link access \ - */ -#define H5L_ACS_ELINK_FLAGS_NAME "external link flags" /* file access flags for external link traversal */ -#define H5L_ACS_ELINK_CB_NAME "external link callback" /* callback function for external link traversal */ +/* Number of soft links to traverse */ +#define H5L_ACS_NLINKS_NAME "max soft links" +/* External link prefix */ +#define H5L_ACS_ELINK_PREFIX_NAME "external link prefix" +/* file access property list for external link access */ +#define H5L_ACS_ELINK_FAPL_NAME "external link fapl" +/* file access flags for external link traversal */ +#define H5L_ACS_ELINK_FLAGS_NAME "external link flags" +/* callback function for external link traversal */ +#define H5L_ACS_ELINK_CB_NAME "external link callback" /****************************/ /* Library Private Typedefs */ @@ -107,32 +110,15 @@ typedef struct H5L_elink_cb_t { /******************************/ /* General operations on links */ -H5_DLL herr_t H5L_init(void); -H5_DLL herr_t H5L_link(const H5G_loc_t *new_loc, const char *new_name, H5G_loc_t *obj_loc, hid_t lcpl_id); -H5_DLL herr_t H5L_link_object(const H5G_loc_t *new_loc, const char *new_name, H5O_obj_create_t *ocrt_info, - hid_t lcpl_id); -H5_DLL herr_t H5L_create_hard(H5G_loc_t *cur_loc, const char *cur_name, const H5G_loc_t *link_loc, - const char *link_name, hid_t lcpl_id); -H5_DLL herr_t H5L_create_soft(const char *target_path, const H5G_loc_t *cur_loc, const char *cur_name, - hid_t lcpl_id); -H5_DLL herr_t H5L_move(const H5G_loc_t *src_loc, const char *src_name, const H5G_loc_t *dst_loc, - const char *dst_name, hbool_t copy_flag, hid_t lcpl_id); -H5_DLL htri_t H5L_exists_tolerant(const H5G_loc_t *loc, const char *name); -H5_DLL htri_t H5L_exists(const H5G_loc_t *loc, const char *name); -H5_DLL herr_t H5L_get_info(const H5G_loc_t *loc, const char *name, H5L_info2_t *linkbuf /*out*/); -H5_DLL herr_t H5L_delete(const H5G_loc_t *loc, const char *name); -H5_DLL herr_t H5L_delete_by_idx(const H5G_loc_t *loc, const char *name, H5_index_t idx_type, - H5_iter_order_t order, hsize_t n); -H5_DLL herr_t H5L_get_info_by_idx(const H5G_loc_t *loc, const char *name, H5_index_t idx_type, - H5_iter_order_t order, hsize_t n, H5L_info2_t *linfo /*out*/); -H5_DLL ssize_t H5L_get_name_by_idx(const H5G_loc_t *loc, const char *group_name, H5_index_t idx_type, - H5_iter_order_t order, hsize_t n, char *name /*out*/, size_t size); -H5_DLL herr_t H5L_get_val(const H5G_loc_t *loc, const char *name, void *buf /*out*/, size_t size); -H5_DLL herr_t H5L_get_val_by_idx(const H5G_loc_t *loc, const char *name, H5_index_t idx_type, - H5_iter_order_t order, hsize_t n, void *buf /*out*/, size_t size); -H5_DLL herr_t H5L_register_external(void); -H5_DLL herr_t H5L_iterate(H5G_loc_t *loc, const char *group_name, H5_index_t idx_type, H5_iter_order_t order, - hsize_t *idx_p, H5L_iterate2_t op, void *op_data); +H5_DLL herr_t H5L_init(void); +H5_DLL herr_t H5L_link(const H5G_loc_t *new_loc, const char *new_name, H5G_loc_t *obj_loc, hid_t lcpl_id); +H5_DLL herr_t H5L_link_object(const H5G_loc_t *new_loc, const char *new_name, H5O_obj_create_t *ocrt_info, + hid_t lcpl_id); +H5_DLL herr_t H5L_exists_tolerant(const H5G_loc_t *loc, const char *name, hbool_t *exists); +H5_DLL herr_t H5L_get_info(const H5G_loc_t *loc, const char *name, H5L_info2_t *linkbuf /*out*/); +H5_DLL herr_t H5L_register_external(void); +H5_DLL herr_t H5L_iterate(H5G_loc_t *loc, const char *group_name, H5_index_t idx_type, H5_iter_order_t order, + hsize_t *idx_p, H5L_iterate2_t op, void *op_data); /* User-defined link functions */ H5_DLL herr_t H5L_register(const H5L_class_t *cls); diff --git a/src/H5Lpublic.h b/src/H5Lpublic.h index 653e75f..5274649 100644 --- a/src/H5Lpublic.h +++ b/src/H5Lpublic.h @@ -25,23 +25,30 @@ #define H5Lpublic_H /* Public headers needed by this file */ -#include "H5public.h" /* Generic Functions */ -#include "H5Ipublic.h" /* IDs */ -#include "H5Opublic.h" /* Object Headers */ -#include "H5Tpublic.h" /* Datatypes */ +#include "H5public.h" /* Generic Functions */ +#include "H5Ipublic.h" /* IDs */ +#include "H5Opublic.h" /* Object Headers */ +#include "H5Tpublic.h" /* Datatypes */ /*****************/ /* Public Macros */ /*****************/ -/* Maximum length of a link's name */ -/* (encoded in a 32-bit unsigned integer) */ -#define H5L_MAX_LINK_NAME_LEN ((uint32_t)(-1)) /* (4GB - 1) */ +/** + * \brief Maximum length of a link's name + * + * The maximum length of a link's name is encoded in a 32-bit unsigned integer. + */ +#define H5L_MAX_LINK_NAME_LEN UINT32_MAX -/* Macro to indicate operation occurs on same location */ -#define H5L_SAME_LOC (hid_t)0 +/** + * \brief Macro to indicate operation occurs on same location + */ +#define H5L_SAME_LOC 0 /* (hid_t) */ -/* Current version of the H5L_class_t struct */ +/** + * \brief Current version of the H5L_class_t struct + */ #define H5L_LINK_CLASS_T_VERS 1 #ifdef __cplusplus @@ -52,88 +59,123 @@ extern "C" { /* Public Typedefs */ /*******************/ -/* Link class types. - * Values less than 64 are reserved for the HDF5 library's internal use. - * Values 64 to 255 are for "user-defined" link class types; these types are - * defined by HDF5 but their behavior can be overridden by users. - * Users who want to create new classes of links should contact the HDF5 - * development team at hdfhelp@ncsa.uiuc.edu . - * These values can never change because they appear in HDF5 files. +/** + * \brief Link class types. + * + * Values less than 64 are reserved for the HDF5 library's internal use. Values + * 64 to 255 are for "user-defined" link class types; these types are defined + * by HDF5 but their behavior can be overridden by users. Users who want to + * create new classes of links should contact the HDF5 development team at + * mailto:help@hdfgroup.org. These values can never change because they appear + * in HDF5 files. */ typedef enum { - H5L_TYPE_ERROR = (-1), /* Invalid link type id */ - H5L_TYPE_HARD = 0, /* Hard link id */ - H5L_TYPE_SOFT = 1, /* Soft link id */ - H5L_TYPE_EXTERNAL = 64, /* External link id */ - H5L_TYPE_MAX = 255 /* Maximum link type id */ + H5L_TYPE_ERROR = (-1), /**< Invalid link type id */ + H5L_TYPE_HARD = 0, /**< Hard link id */ + H5L_TYPE_SOFT = 1, /**< Soft link id */ + H5L_TYPE_EXTERNAL = 64, /**< External link id */ + H5L_TYPE_MAX = 255 /**< Maximum link type id */ } H5L_type_t; -#define H5L_TYPE_BUILTIN_MAX H5L_TYPE_SOFT /* Maximum value link value for "built-in" link types */ -#define H5L_TYPE_UD_MIN \ - H5L_TYPE_EXTERNAL /* Link ids at or above this value are "user-defined" link types. \ - */ +/** + * \brief Maximum value link value for "built-in" link types + */ +#define H5L_TYPE_BUILTIN_MAX H5L_TYPE_SOFT +/** + * \brief Link ids at or above this value are "user-defined" link types. + */ +#define H5L_TYPE_UD_MIN H5L_TYPE_EXTERNAL +/** + * \brief Maximum link id value for "user-defined" link types. + */ +#define H5L_TYPE_UD_MAX H5L_TYPE_MAX -/* Information struct for link (for H5Lget_info2/H5Lget_info_by_idx2) - * H5O_token_t version used in VOL layer and future public API calls +/** + * \brief Information struct for links */ +//! <!-- [H5L_info2_t_snip] --> typedef struct { - H5L_type_t type; /* Type of link */ - hbool_t corder_valid; /* Indicate if creation order is valid */ - int64_t corder; /* Creation order */ - H5T_cset_t cset; /* Character set of link name */ + H5L_type_t type; /**< Type of link */ + hbool_t corder_valid; /**< Indicate if creation order is valid */ + int64_t corder; /**< Creation order */ + H5T_cset_t cset; /**< Character set of link name */ union { - H5O_token_t token; /* Token of location that hard link points to */ - size_t val_size; /* Size of a soft link or UD link value */ + H5O_token_t token; /**< Token of location that hard link points to */ + size_t val_size; /**< Size of a soft link or user-defined link value */ } u; } H5L_info2_t; +//! <!-- [H5L_info2_t_snip] --> /* The H5L_class_t struct can be used to override the behavior of a * "user-defined" link class. Users should populate the struct with callback * functions defined below. */ /* Callback prototypes for user-defined links */ -/* Link creation callback */ +/** + * \brief Link creation callback + */ typedef herr_t (*H5L_create_func_t)(const char *link_name, hid_t loc_group, const void *lnkdata, size_t lnkdata_size, hid_t lcpl_id); - -/* Callback for when the link is moved */ +/** + * \brief Callback for link move + */ typedef herr_t (*H5L_move_func_t)(const char *new_name, hid_t new_loc, const void *lnkdata, size_t lnkdata_size); - -/* Callback for when the link is copied */ +/** + * \brief Callback for link copy + */ typedef herr_t (*H5L_copy_func_t)(const char *new_name, hid_t new_loc, const void *lnkdata, size_t lnkdata_size); - -/* Callback during link traversal */ +/** + * \brief Callback during link traversal + */ typedef hid_t (*H5L_traverse_func_t)(const char *link_name, hid_t cur_group, const void *lnkdata, size_t lnkdata_size, hid_t lapl_id, hid_t dxpl_id); - -/* Callback for when the link is deleted */ +/** + * \brief Callback for link deletion + */ typedef herr_t (*H5L_delete_func_t)(const char *link_name, hid_t file, const void *lnkdata, size_t lnkdata_size); - -/* Callback for querying the link */ -/* Returns the size of the buffer needed */ +/** + * \brief Callback for querying the link. + * + * Returns the size of the buffer needed. + */ typedef ssize_t (*H5L_query_func_t)(const char *link_name, const void *lnkdata, size_t lnkdata_size, void *buf /*out*/, size_t buf_size); +/** + * \brief Link prototype + * + * The H5L_class_t struct can be used to override the behavior of a + * "user-defined" link class. Users should populate the struct with callback + * functions defined elsewhere. + */ +//! <!-- [H5L_class_t_snip] --> typedef struct { - int version; /* Version number of this struct */ - H5L_type_t id; /* Link type ID */ - const char * comment; /* Comment for debugging */ - H5L_create_func_t create_func; /* Callback during link creation */ - H5L_move_func_t move_func; /* Callback after moving link */ - H5L_copy_func_t copy_func; /* Callback after copying link */ - H5L_traverse_func_t trav_func; /* Callback during link traversal */ - H5L_delete_func_t del_func; /* Callback for link deletion */ - H5L_query_func_t query_func; /* Callback for queries */ + int version; /**< Version number of this struct */ + H5L_type_t id; /**< Link type ID */ + const char * comment; /**< Comment for debugging */ + H5L_create_func_t create_func; /**< Callback during link creation */ + H5L_move_func_t move_func; /**< Callback after moving link */ + H5L_copy_func_t copy_func; /**< Callback after copying link */ + H5L_traverse_func_t trav_func; /**< Callback during link traversal */ + H5L_delete_func_t del_func; /**< Callback for link deletion */ + H5L_query_func_t query_func; /**< Callback for queries */ } H5L_class_t; +//! <!-- [H5L_class_t_snip] --> -/* Prototype for H5Literate2/H5Literate_by_name2() operator - * H5O_token_t version used in VOL layer and future public API calls +/** + * \brief Prototype for H5Literate2(), H5Literate_by_name2() operator + * + * The H5O_token_t version is used in the VOL layer and future public API calls. */ +//! <!-- [H5L_iterate2_t_snip] --> typedef herr_t (*H5L_iterate2_t)(hid_t group, const char *name, const H5L_info2_t *info, void *op_data); +//! <!-- [H5L_iterate2_t_snip] --> -/* Callback for external link traversal */ +/** + * \brief Callback for external link traversal + */ typedef herr_t (*H5L_elink_traverse_t)(const char *parent_file_name, const char *parent_group_name, const char *child_file_name, const char *child_object_name, unsigned *acc_flags, hid_t fapl_id, void *op_data); @@ -145,52 +187,1458 @@ typedef herr_t (*H5L_elink_traverse_t)(const char *parent_file_name, const char /*********************/ /* Public Prototypes */ /*********************/ +/** + * \ingroup H5L + * + * \brief Moves a link within an HDF5 file + * + * \fgdta_loc_id{src_loc} + * \param[in] src_name Original link name + * \fgdta_loc_id{dst_loc} + * \param[in] dst_name New link name + * \lcpl_id + * \lapl_id + * + * \return \herr_t + * + * \details H5Lmove() moves a link within an HDF5 file. The original link, + * \p src_name, is removed from \p src_loc and the new link, + * \p dst_name, is inserted at dst_loc. This change is + * accomplished as an atomic operation. + * + * \p src_loc and \p src_name identify the original link. + * \p src_loc is the original location identifier; \p src_name is + * the path to the link and is interpreted relative to \p src_loc. + * + * \p dst_loc and \p dst_name identify the new link. \p dst_loc is + * either a file or group identifier; \p dst_name is the path to + * the link and is interpreted relative to \p dst_loc. + * + * \p lcpl_id and \p lapl_id are the link creation and link access + * property lists, respectively, associated with the new link, + * \p dst_name. + * + * Through these property lists, several properties are available to + * govern the behavior of H5Lmove(). The property controlling creation + * of missing intermediate groups is set in the link creation property + * list with H5Pset_create_intermediate_group(); H5Lmove() ignores any + * other properties in the link creation property list. Properties + * controlling character encoding, link traversals, and external link + * prefixes are set in the link access property list with + * H5Pset_char_encoding(), H5Pset_nlinks(), and H5Pset_elink_prefix(), + * respectively. + * + * \note Note that H5Lmove() does not modify the value of the link; the new + * link points to the same object as the original link pointed to. + * Furthermore, if the object pointed to by the original link was already + * open with a valid object identifier, that identifier will remain valid + * after the call to H5Lmove(). + * + * \attention Exercise care in moving links as it is possible to render data in + * a file inaccessible with H5Lmove(). If the link being moved is on + * the only path leading to an HDF5 object, that object may become + * permanently inaccessible in the file. + * + * \since 1.8.0 + * + *------------------------------------------------------------------------- + */ H5_DLL herr_t H5Lmove(hid_t src_loc, const char *src_name, hid_t dst_loc, const char *dst_name, hid_t lcpl_id, hid_t lapl_id); +/** + * \ingroup H5L + * + * \brief Creates an identical copy of a link with the same creation time and + * target. The new link can have a different name and be in a different + * location than the original. + * + * \fgdt_loc_id{src_loc} + * \param[in] src_name Name of the link to be copied + * \fgdt_loc_id{dst_loc} + * \param[in] dst_name Name to be assigned to the new copy + * \lcpl_id + * \lapl_id + * \return \herr_t + * + * \details H5Lcopy() copies the link specified by \p src_name from the location + * specified by \p src_loc_id to the location specified by + * \p dst_loc_id. The new copy of the link is created with the name + * \p dst_name. + * + * If \p dst_loc_id is a file identifier, \p dst_name will be + * interpreted relative to that file’s root group. + * + * The new link is created with the creation and access property lists + * specified by \p lcpl_id and \p lapl_id. The interpretation of + * \p lcpl_id is limited in the manner described in the next paragraph. + * + * H5Lcopy() retains the creation time and the target of the original + * link. However, since the link may be renamed, the character + * encoding is that specified in \p lcpl_id rather than that of the + * original link. Other link creation properties are ignored. + * + * If the link is a soft link, also known as a symbolic link, its + * target is interpreted relative to the location of the copy. + * + * Several properties are available to govern the behavior of + * H5Lcopy(). These properties are set in the link creation and access + * property lists, \p lcpl_id and \p lapl_id, respectively. The + * property controlling creation of missing intermediate groups is set + * in the link creation property list with + * H5Pset_create_intermediate_group(); this function ignores any + * other properties in the link creation property list. Properties + * controlling character encoding, link traversals, and external link + * prefixes are set in the link access property list with + * H5Pset_char_encoding(), H5Pset_nlinks(), and + * H5Pset_elink_prefix(). + * + * \note H5Lcopy() does not affect the object that the link points to. + * + * \attention H5Lcopy() cannot copy hard links across files as a hard link is + * not valid without a target object; to copy objects from one file + * to another, see H5Ocopy(). + * + * \see H5Ocopy() + * + * \since 1.8.0 + * + */ H5_DLL herr_t H5Lcopy(hid_t src_loc, const char *src_name, hid_t dst_loc, const char *dst_name, hid_t lcpl_id, hid_t lapl_id); +/** + * \ingroup H5L + * + * \brief Creates a hard link to an object + * + * \fgdta_loc_id{cur_loc} + * \param[in] cur_name Name of the target object, which must already exist + * \fgdta_loc_id{dst_loc} + * \param[in] dst_name The name of the new link + * \lcpl_id + * \lapl_id + * + * \return \herr_t + * + * \details H5Lcreate_hard() creates a new hard link to a pre-existing object + * in an HDF5 file. + * + * \p cur_loc and \p cur_name specify the location + * and name, respectively, of the target object, i.e., the object that + * the new hard link points to. \p dst_loc and \p dst_name specify the + * location and name, respectively, of the new hard link. + * + * \p cur_name and \p dst_name are interpreted relative to \p cur_loc + * and \p dst_loc, respectively. If \p cur_loc and \p dst_loc are the + * same location, the HDF5 macro #H5L_SAME_LOC can be used for either + * parameter (but not both). + * + * \p lcpl_id and \p lapl_id are the link creation and access property + * lists associated with the new link. + * + * \note Hard and soft links are for use only if the target object is in the + * current file. If the desired target object is in a different file from + * the new link, an external link may be created with + * H5Lcreate_external(). + * + * \note The HDF5 library keeps a count of all hard links pointing to an + * object; if the hard link count reaches zero (0), the object will be + * deleted from the file. Creating new hard links to an object will + * prevent it from being deleted if other links are removed. The + * library maintains no similar count for soft links and they can dangle. + * + * \note The new link may be one of many that point to that object. + * + * \since 1.8.0 + * + */ H5_DLL herr_t H5Lcreate_hard(hid_t cur_loc, const char *cur_name, hid_t dst_loc, const char *dst_name, hid_t lcpl_id, hid_t lapl_id); +/** + * -------------------------------------------------------------------------- + * \ingroup ASYNC + * \async_variant_of{H5Lcreate_hard} + */ +H5_DLL herr_t H5Lcreate_hard_async(const char *app_file, const char *app_func, unsigned app_line, + hid_t cur_loc_id, const char *cur_name, hid_t new_loc_id, + const char *new_name, hid_t lcpl_id, hid_t lapl_id, hid_t es_id); +/** + * \ingroup H5L + * + * \brief Creates a soft link + * + * \param[in] link_target An HDF5 path name + * \fgdta_loc_id{link_loc_id} + * \param[in] link_name The name of the new link + * \lcpl_id + * \lapl_id + * + * \return \herr_t + * + * \details H5Lcreate_soft() creates a new soft link to an object in an HDF5 + * file. + * + * \p link_target specifies the HDF5 path name the soft link contains. + * \p link_target can be an arbitrary HDF5 path name and is + * interpreted only at lookup time. This path may be absolute in the + * file or relative to \p link_loc_id. + * + * \p link_loc_id and \p link_name specify the location and name, + * respectively, of the new soft link. \p link_name is interpreted + * relative to \p link_loc_id and must contain only the name of the soft + * link; \p link_name may not contain any additional path elements. + * + * If \p link_loc_id is a group identifier, the object pointed to by + * \p link_name will be accessed as a member of that group. If + * \p link_loc_id is a file identifier, the object will be accessed as a + * member of the file's root group. + * + * \p lcpl_id and \p lapl_id are the link creation and access property + * lists associated with the new link. + * + * For instance, if target_path is \c ./foo, \p link_loc_id specifies + * \c ./x/y/bar, and the name of the new link is \c new_link, then a + * subsequent request for \c ./x/y/bar/new_link will return same the + * object as would be found at \c ./foo. + * + * \note H5Lcreate_soft() is for use only if the target object is in the + * current file. If the desired target object is in a different file from + * the new link, use H5Lcreate_external() to create an external link. + * + * \note Soft links and external links are also known as symbolic links as they + * use a name to point to an object; hard links employ an object’s + * address in the file. + * + * \note Unlike hard links, a soft link in an HDF5 file is allowed to dangle, + * meaning that the target object need not exist at the time that the + * link is created. + * + * \note The HDF5 library does not keep a count of soft links as it does of + * hard links. + * + * \note The new link may be one of many that point to that object. + * + * \see H5Lcreate_hard(), H5Lcreate_external() + * + * \since 1.8.0 + * + + */ H5_DLL herr_t H5Lcreate_soft(const char *link_target, hid_t link_loc_id, const char *link_name, hid_t lcpl_id, hid_t lapl_id); +/** + * -------------------------------------------------------------------------- + * \ingroup ASYNC + * \async_variant_of{H5Lcreate_soft} + */ +H5_DLL herr_t H5Lcreate_soft_async(const char *app_file, const char *app_func, unsigned app_line, + const char *link_target, hid_t link_loc_id, const char *link_name, + hid_t lcpl_id, hid_t lapl_id, hid_t es_id); +/** + * \ingroup H5L + * + * \brief Removes a link from a group + * + * \fgdta_loc_id + * \param[in] name Name of the link to delete + * \lapl_id + * + * \return \herr_t + * + * \details H5Ldelete() removes the link specified by \p name from the location + * \p loc_id. + * + * If the link being removed is a hard link, H5Ldelete() also + * decrements the link count for the object to which name points. + * Unless there is a duplicate hard link in that group, this action + * removes the object to which name points from the group that + * previously contained it. + * + * Object headers keep track of how many hard links refer to an + * object; when the hard link count, also referred to as the reference + * count, reaches zero, the object can be removed from the file. The + * file space associated will then be released, i.e., identified in + * memory as freespace. Objects which are open are not removed until + * all identifiers to the object are closed. + * + * \attention Exercise caution in the use of H5Ldelete(); if the link being + * removed is on the only path leading to an HDF5 object, that + * object may become permanently inaccessible in the file. + * + * \see H5Lcreate_hard(), H5Lcreate_soft(), H5Lcreate_external() + * + * \since 1.8.0 + * + */ H5_DLL herr_t H5Ldelete(hid_t loc_id, const char *name, hid_t lapl_id); +/** + * -------------------------------------------------------------------------- + * \ingroup ASYNC + * \async_variant_of{H5Ldelete} + */ +H5_DLL herr_t H5Ldelete_async(const char *app_file, const char *app_func, unsigned app_line, hid_t loc_id, + const char *name, hid_t lapl_id, hid_t es_id); +/** + * \ingroup H5L + * + * \brief Removes the \Emph{n}-th link in a group + * + * \fgdta_loc_id + * \param[in] group_name Name of subject group + * \param[in] idx_type Index or field which determines the order + * \param[in] order Order within field or index + * \param[in] n Link for which to retrieve information + * \lapl_id + * + * \return \herr_t + * + * \details H5Ldelete_by_idx() removes the \Emph{n}-th link in a group + * according to the specified order, \p order, in the specified index, + * \p index. + * + * If \p loc_id specifies the group in which the link resides, + * \p group_name can be a dot (\c .). + * + * \see H5Ldelete() + * + * \since 1.8.0 + * + */ H5_DLL herr_t H5Ldelete_by_idx(hid_t loc_id, const char *group_name, H5_index_t idx_type, H5_iter_order_t order, hsize_t n, hid_t lapl_id); +/** + * -------------------------------------------------------------------------- + * \ingroup ASYNC + * \async_variant_of{H5Ldelete_by_idx} + */ +H5_DLL herr_t H5Ldelete_by_idx_async(const char *app_file, const char *app_func, unsigned app_line, + hid_t loc_id, const char *group_name, H5_index_t idx_type, + H5_iter_order_t order, hsize_t n, hid_t lapl_id, hid_t es_id); +/** + * \ingroup H5L + * + * \brief Returns the value of a link + * + * \fgdta_loc_id + * \param[in] name Link name + * \param[out] buf The buffer to hold the link value + * \param[in] size Maximum number of bytes of link value to be returned + * \lapl_id + * + * \return \herr_t + * + * \details H5Lget_val() returns tha value of link \p name. For smbolic links, + * this is the path to which the link points, including the null + * terminator. For external and user-defined links, it is the link + * buffer. + * + * \p size is the size of \p buf and should be the size of the link + * value being returned. This size value can be determined through a + * call to H5Lget_info(); it is returned in the \c val_size field of + * the \ref H5L_info_t \c struct. + * + * If \p size is smaller than the size of the returned value, then the + * string stored in \p buf will be truncated to \p size bytes. For + * soft links, this means that the value will not be null terminated. + * + * In the case of external links, the target file and object names are + * extracted from \p buf by calling H5Lunpack_elink_val(). + * + * The link class of link \p name can be determined with a call to + * H5Lget_info(). + * + * \p lapl_id specifies the link access property list associated with + * the link \p name. In the general case, when default link access + * properties are acceptable, this can be passed in as #H5P_DEFAULT. An + * example of a situation that requires a non-default link access + * property list is when the link is an external link; an external + * link may require that a link prefix be set in a link access + * property list (see H5Pset_elink_prefix()). + * + * This function should be used only after H5Lget_info() has been + * called to verify that \p name is a symbolic link. This can be + * deteremined from the \c link_type field of the \ref H5L_info_t + * \c struct. + * + * \note This function will fail if called on a hard link. + * + * \see H5Lget_val_by_idx() + * + * \since 1.8.0 + * + */ H5_DLL herr_t H5Lget_val(hid_t loc_id, const char *name, void *buf /*out*/, size_t size, hid_t lapl_id); +/** + * \ingroup H5L + * + * \brief Retrieves value of the \Emph{n}-th link in a group, according to the order within an index + * + * \fgdta_loc_id + * \param[in] group_name Group name + * \param[in] idx_type Type of index + * \param[in] order Order within field or index + * \param[in] n Link position for which to retrieve information + * \param[out] buf The buffer to hold the link value + * \param[in] size Maximum number of bytes of link value to be returned + * \lapl_id + * + * \return \herr_t + * + * \details H5Lget_val_by_idx() retrieves the value of the \Emph{n}-th link in + * a group, according to the specified order, \p order, within an + * index, \p index. + * + * For soft links, the value is an HDF5 path name. + * + * For external links, this is a compound value containing file and + * path name information; to use this external link information, it + * must first be decoded with H5Lunpack_elink_val() + * + * For user-defined links, this value will be described in the + * definition of the user-defined link type. + * + * \p loc_id specifies the location identifier of the group specified + * by \p group_name. + * + * \p group_name specifies the group in which the link exists. If + * \p loc_id already specifies the group in which the link exists, + * \p group_name must be a dot (\c .). + * + * The size in bytes of link_val is specified in \p size. The size + * value can be determined through a call to H5Lget_info_by_idx(); it + * is returned in the \c val_size field of the \ref H5L_info_t + * \c struct. If + * size is smaller than the size of the returned value, then the + * string stored in link_val will be truncated to size bytes. For soft + * links, this means that the value will not be null terminated. + * + * If the type of the link is unknown or uncertain, H5Lget_val_by_idx() + * should be called only after the type has been determined via a call + * to H5Lget_info_by_idx(). + * + * \note This function will fail if called on a hard link. + * + * \see H5Lget_val() + * + * \since 1.8.0 + * + */ H5_DLL herr_t H5Lget_val_by_idx(hid_t loc_id, const char *group_name, H5_index_t idx_type, H5_iter_order_t order, hsize_t n, void *buf /*out*/, size_t size, hid_t lapl_id); +/** + * \ingroup H5L + * + * \brief Determines whether a link with the specified name exists in a group + * + * \fgdta_loc_id + * \param[in] name Link name + * \lapl_id + * + * \return \herr_t + * + * \details H5Lexists() allows an application to determine whether the link \p + * name exists in the location specified by \p loc_id. The link may be + * of any type; only the presence of a link with that name is checked. + * + * Note that H5Lexists() verifies only that the target link exists. If + * name includes either a relative path or an absolute path to the + * target link, intermediate steps along the path must be verified + * before the existence of the target link can be safely checked. If + * the path is not verified and an intermediate element of the path + * does not exist, H5Lexists() will fail. The example in the next + * paragraph illustrates one step-by-step method for verifying the + * existence of a link with a relative or absolute path. + * + * \Bold{Example:} Use the following steps to verify the existence of + * the link \c datasetD in the \c group group1/group2/softlink_to_group3/, + * where \c group1 is a member of the group specified by \c loc_id: + * + * 1. First use H5Lexists() to verify that \c group1 exists. + * 2. If \c group1 exists, use H5Lexists() again, this time with name + * set to \c group1/group2, to verify that \c group2 exists. + * 3. If \c group2 exists, use H5Lexists() with name set to + * \c group1/group2/softlink_to_group3 to verify that + * \c softlink_to_group3 exists. + * 4. If \c softlink_to_group3 exists, you can now safely use + * H5Lexists() with \c name set to + * \c group1/group2/softlink_to_group3/datasetD to verify that the + * target link, \c datasetD, exists. + * + * If the link to be verified is specified with an absolute path, the + * same approach should be used, but starting with the first link in + * the file’s root group. For instance, if \c datasetD were in + * \c /group1/group2/softlink_to_group3, the first call to H5Lexists() + * would have name set to \c /group1. + * + * Note that this is an outline and does not include all necessary + * details. Depending on circumstances, for example, you may need to + * verify that an intermediate link points to a group and that a soft + * link points to an existing target. + * + * \note The behavior of H5Lexists() was changed in the 1.10 release in the + * case where the root group, \c "/", is the name of the link. This + * change is described below: + * <ol> + * <li>Let \c file denote a valid HDF5 file identifier, and let \c lapl + * denote a valid link access property list identifier. A call to + * H5Lexists() with arguments \c file, \c "/", and \c lapl + * returns a positive value; in other words, + * \Code{H5Lexists(file, "/", lapl)} returns a positive value. + * In HDF5 version 1.8.16, this function returns 0.</li> + * <li>Let \c root denote a valid HDF5 group identifier that refers to the + * root group of an HDF5 file, and let \c lapl denote a valid link + * access property list identifier. A call to H5Lexists() with + * arguments c root, \c "/", and \c lapl returns a positive value; + * in other words, \Code{H5Lexists(root, "/", lapl)} returns a postive + * value. In HDF5 version 1.8.16, this function returns 0.</li> + * </ol> + * Note that the function accepts link names and path names. This is + * potentially misleading to callers, and we plan to separate the + * functionality for link names and path names in a future release. + * + * \attention H5Lexists() checks the existence of only the final element in a + * relative or absolute path; it does not check any other path + * elements. The function will therefore fail when both of the + * following conditions exist: + * - \c name is not local to the group specified by \c loc_id or, + * if \c loc_id is something other than a group identifier, \c name + * is not local to the root group. + * - Any element of the relative path or absolute path in name, + * except the target link, does not exist. + * + * \version 1.10.0 Function behavior changed in this release. (See the note.) + * \since 1.8.0 + * + */ H5_DLL htri_t H5Lexists(hid_t loc_id, const char *name, hid_t lapl_id); -H5_DLL herr_t H5Lget_info2(hid_t loc_id, const char *name, H5L_info2_t *linfo /*out*/, hid_t lapl_id); +/** + * -------------------------------------------------------------------------- + * \ingroup ASYNC + * \async_variant_of{H5Lexists} + */ +H5_DLL herr_t H5Lexists_async(const char *app_file, const char *app_func, unsigned app_line, hid_t loc_id, + const char *name, hbool_t *exists, hid_t lapl_id, hid_t es_id); +/** + * \ingroup H5L + * + * \brief Returns information about a link + * + * \fgdta_loc_id + * \param[in] name Link name + * \param[out] linfo Buffer in which link information is returned + * \lapl_id + * + * \return \herr_t + * + * \details H5Lget_info2() returns information about the specified link through + * the \p linfo argument. + * + * The location identifier, \p loc_id, specifies the location of the + * link. A link name, \p name, interpreted relative to \p loc_id, + * specifies the link being queried. + * + * \p lapl_id is the link access property list associated with the + * link name. In the general case, when default link access properties + * are acceptable, this can be passed in as #H5P_DEFAULT. An example + * of a situation that requires a non-default link access property + * list is when the link is an external link; an external link may + * require that a link prefix be set in a link access property list + * (see H5Pset_elink_prefix()). + * + * H5Lget_info2() returns information about name in the data structure + * H5L_info2_t, which is described below and defined in H5Lpublic.h. + * This structure is returned in the buffer \p linfo. + * \snippet this H5L_info2_t_snip + * In the above struct, \c type specifies the link class. Valid values + * include the following: + * \link_types + * There will be additional valid values if user-defined links have + * been registered. + * + * \p corder specifies the link’s creation order position while + * \p corder_valid indicates whether the value in corder is valid. + * + * If \p corder_valid is \c TRUE, the value in \p corder is known to + * be valid; if \p corder_valid is \c FALSE, the value in \p corder is + * presumed to be invalid; \p corder starts at zero (0) and is + * incremented by one (1) as new links are created. But + * higher-numbered entries are not adjusted when a lower-numbered link + * is deleted; the deleted link's creation order position is simply + * left vacant. In such situations, the value of \p corder for the + * last link created will be larger than the number of links remaining + * in the group. + * + * \p cset specifies the character set in which the link name is + * encoded. Valid values include the following: + * \csets + * This value is set with H5Pset_char_encoding(). + * + * \c token is the location that a hard link points to, and + * \c val_size is the size of a soft link or user defined link value. + * H5O_token_t is used in the VOL layer. It is defined in H5public.h + * as: + * \snippet H5public.h H5O_token_t_snip + * + * If the link is a symbolic link, \c val_size will be the length of + * the link value, e.g., the length of the HDF5 path name with a null + * terminator. + * + * \since 1.12.0 + * + */ +H5_DLL herr_t H5Lget_info2(hid_t loc_id, const char *name, H5L_info2_t *linfo, hid_t lapl_id); +/** + * \ingroup H5L + * + * \brief Retrieves metadata for a link in a group, according to the order + * within a field or index + * + * \loc_id + * \param[in] group_name Group name + * \idx_type + * \order + * \param[in] n Link position for which to retrieve information + * \param[out] linfo Buffer in which link information is returned + * \lapl_id + * + * \return \herr_t + * + * \details H5get_info_by_idx2() returns the metadata for a link in a group + * according to a specified field or index and a specified order. The + * link for which information is to be returned is specified by \p + * idx_type, \p order, and \p n as follows: + * + * - \p idx_type specifies the field by which the links in \p + * group_name are ordered. The links may be indexed on this field, + * in which case operations seeking specific links are likely to + * complete more quickly. + * - \p order specifies the order in which + * the links are to be referenced for the purposes of this function. + * - \p n specifies the position of the subject link. Note that this + * count is zero-based; 0 (zero) indicates that the function will + * return the value of the first link; if \p n is 5, the function + * will return the value of the sixth link; etc. + * + * For example, assume that \p idx_type, \p order, and \p n are + * #H5_INDEX_NAME, #H5_ITER_DEC, and 5, respectively. #H5_INDEX_NAME + * indicates that the links are accessed in lexicographic order by + * their names. #H5_ITER_DEC specifies that the list be traversed in + * reverse order, or in decremented order. And 5 specifies that this + * call to the function will return the metadata for the 6th link + * (\c n + 1) from the end. + * + * See H5Literate2() for a list of valid values and further discussion + * regarding \p idx_type and \p order. + * + * If \p loc_id specifies the group in which the link resides, + * \p group_name can be a dot (\c .). + * + * \since 1.12.0 + * + * \see H5Lget_info2() + * + */ H5_DLL herr_t H5Lget_info_by_idx2(hid_t loc_id, const char *group_name, H5_index_t idx_type, - H5_iter_order_t order, hsize_t n, H5L_info2_t *linfo /*out*/, - hid_t lapl_id); + H5_iter_order_t order, hsize_t n, H5L_info2_t *linfo, hid_t lapl_id); +/** + * \ingroup H5L + * + * \brief Retrieves name of the \Emph{n}-th link in a group, according to the + * order within a specified field or index + * + * \loc_id + * \param[in] group_name Group name + * \idx_type + * \order + * \param[in] n Link position for which to retrieve information + * \param[out] name Buffer in which link name is returned + * \param[in] size Size in bytes of \p name + * \lapl_id + * + * \return Returns the size of the link name if successful; otherwise returns a + * negative value. + * + * \details H5get_name_by_idx() retrieves the name of the \Emph{n}-th link in a + * group, according to the specified order, \p order, within a specified + * field or index, \p idx_type. + * + * \p idx_type specifies the index that is used. Valid values include + * the following: + * \indexes + * + * \p order specifies the order in which objects are inspected along + * the index specified in \p idx_type. Valid values include the + * following: + * \orders + * + * If \p loc_id specifies the group in which the link resides, + * \p group_name can be a dot (\c .). + * + * The size in bytes of name is specified in \p size. If \p size is + * unknown, it can be determined via an initial H5Lget_name_by_idx() + * call with name set to NULL; the function's return value will be the + * size of the name. + * + * \note Please note that in order for the specified index to correspond to the + * creation order index, \p order must be set to #H5_ITER_INC or + * #H5_ITER_DEC when calling H5Lget_name_by_idx(). \note The index \p n + * passed to H5Lget_name_by_idx() is the index of the link within the + * link table, sorted according to \p order and \p idx_type. If order is + * #H5_ITER_NATIVE, then the link table is not sorted, and it does not + * matter what \p idx_type is. Specifying #H5_ITER_NATIVE does not + * guarantee any particular order, only that it remains consistent. + * + * \since 1.8.0 + * + */ H5_DLL ssize_t H5Lget_name_by_idx(hid_t loc_id, const char *group_name, H5_index_t idx_type, H5_iter_order_t order, hsize_t n, char *name /*out*/, size_t size, hid_t lapl_id); -H5_DLL herr_t H5Literate2(hid_t grp_id, H5_index_t idx_type, H5_iter_order_t order, hsize_t *idx, - H5L_iterate2_t op, void *op_data); -H5_DLL herr_t H5Literate_by_name2(hid_t loc_id, const char *group_name, H5_index_t idx_type, - H5_iter_order_t order, hsize_t *idx, H5L_iterate2_t op, void *op_data, - hid_t lapl_id); -H5_DLL herr_t H5Lvisit2(hid_t grp_id, H5_index_t idx_type, H5_iter_order_t order, H5L_iterate2_t op, - void *op_data); -H5_DLL herr_t H5Lvisit_by_name2(hid_t loc_id, const char *group_name, H5_index_t idx_type, - H5_iter_order_t order, H5L_iterate2_t op, void *op_data, hid_t lapl_id); - +/** + * \ingroup TRAV + * + * \brief Iterates over links in a group, with user callback routine, + * according to the order within an index. + * + * \group_id{grp_id} + * \idx_type + * \order + * \param[in,out] idx Pointer to an iteration index to allow + * continuing a previous iteration + * \op + * \op_data + * \return \success{The return value of the first operator that returns + * non-zero, or zero if all members were processed with no + * operator returning non-zero.} + * \return \failure{Negative if an error occurs in the library, or the negative + * value returned by one of the operators.} + * + * \details H5Literate2() iterates through the links in a file or + * group, \p group_id, in the order of the specified + * index, \p idx_type, using a user-defined callback routine + * \p op. H5Literate2() does not recursively follow links into + * subgroups of the specified group. + * + * Three parameters are used to manage progress of the iteration: + * \p idx_type, \p order, and \p idx_p. + * + * \p idx_type specifies the index to be used. If the links have + * not been indexed by the index type, they will first be sorted by + * that index then the iteration will begin; if the links have been + * so indexed, the sorting step will be unnecessary, so the iteration + * may begin more quickly. + * + * \p order specifies the order in which objects are to be inspected + * along the index \p idx_type. + * + * \p idx_p tracks the iteration and allows an iteration to be + * resumed if it was stopped before all members were processed. It is + * passed in by the application with a starting point and returned by + * the library with the point at which the iteration stopped. + * + * \p op_data is a user-defined pointer to the data required to + * process links in the course of the iteration. This pointer is + * passed back to each step of the iteration in the \p op callback + * function's \p op_data parameter. \p op is invoked for each link + * encounter. + * + * \p op_data is passed to and from each iteration and can be used to + * supply or aggregate information across iterations. + * + * \remark Same pattern of behavior as H5Giterate(). + * + * \note This function is also available through the H5Literate() macro. + * + * \warning The behavior of H5Literate2() is undefined if the link + * membership of \p group_id changes during the iteration. + * This does not limit the ability to change link destinations + * while iterating, but caution is advised. + * + * + * \since 1.12.0 + * + * \see H5Literate_by_name2(), H5Lvisit2(), H5Lvisit_by_name2() + * + */ +H5_DLL herr_t H5Literate2(hid_t grp_id, H5_index_t idx_type, H5_iter_order_t order, hsize_t *idx, + H5L_iterate2_t op, void *op_data); +/** + * -------------------------------------------------------------------------- + * \ingroup ASYNC + * \async_variant_of{H5Literate} + */ +H5_DLL herr_t H5Literate_async(const char *app_file, const char *app_func, unsigned app_line, hid_t group_id, + H5_index_t idx_type, H5_iter_order_t order, hsize_t *idx_p, H5L_iterate2_t op, + void *op_data, hid_t es_id); +/** + * \ingroup TRAV + * + * \brief Iterates through links in a group + * + * \loc_id + * \param[in] group_name Group name + * \idx_type + * \order + * \param[in,out] idx iteration position at which to start (\Emph{IN}) or + * position at which an interrupted iteration may be restarted + * (\Emph{OUT}) + * \op + * \op_data + * \lapl_id + * \return \success{The return value of the first operator that returns + * non-zero, or zero if all members were processed with no + * operator returning non-zero.} + * \return \failure{Negative if an error occurs in the library, or the negative + * value returned by one of the operators.} + * + * \details H5Literate_by_name2() iterates through the links in a group + * specified by \p loc_id and \p group_name, in the order of the + * specified index, \p idx_type, using a user-defined callback routine + * \p op. H5Literate_by_name2() does not recursively follow links into + * subgroups of the specified group. + * + * \p idx_type specifies the index to be used. If the links have not + * been indexed by the index type, they will first be sorted by that + * index then the iteration will begin; if the links have been so + * indexed, the sorting step will be unnecessary, so the iteration may + * begin more quickly. Valid values include the following: + * \indexes + * + * \p order specifies the order in which objects are to be inspected + * along the index specified in \p idx_type. Valid values include the + * following: + * \orders + * + * \p idx_p allows an interrupted iteration to be resumed; it is + * passed in by the application with a starting point and returned by + * the library with the point at which the iteration stopped. + * + * \note H5Literate_by_name2() is not recursive. In particular, if a member of + * \p group_name is found to be a group, call it \c subgroup_a, + * H5Literate_by_name2() does not examine the members of \c subgroup_a. + * When recursive iteration is required, the application must handle the + * recursion, explicitly calling H5Literate_by_name2() on discovered + * subgroups. + * + * \note H5Literate_by_name2() assumes that the membership of the group being + * iterated over remains unchanged through the iteration; if any of the + * links in the group change during the iteration, the function’s + * behavior is undefined. Note, however, that objects pointed to by the + * links can be modified. + * + * \note H5Literate_by_name2() is the same as H5Literate2(), except that + * H5Literate2() always proceeds in alphanumeric order. + * + * \since 1.12.0 + * + * \see H5Literate(), H5Lvisit() + * + */ +H5_DLL herr_t H5Literate_by_name2(hid_t loc_id, const char *group_name, H5_index_t idx_type, + H5_iter_order_t order, hsize_t *idx, H5L_iterate2_t op, void *op_data, + hid_t lapl_id); +/** + * \ingroup TRAV + * + * \brief Recursively visits all links starting from a specified group + * + * \group_id{grp_id} + * \idx_type + * \order + * \op + * \op_data + * \return \success{The return value of the first operator that returns + * non-zero, or zero if all members were processed with no + * operator returning non-zero.} + * \return \failure{Negative if an error occurs in the library, or the negative + * value returned by one of the operators.} + * + * \details H5Lvisit2() is a recursive iteration function to visit all links in + * and below a group in an HDF5 file, thus providing a mechanism for + * an application to perform a common set of operations across all of + * those links or a dynamically selected subset. For non-recursive + * iteration across the members of a group, see H5Literate2(). + * + * The group serving as the root of the iteration is specified by its + * group or file identifier, \p group_id. + * + * Two parameters are used to establish the iteration: \p idx_type and + * \p order. + * + * \p idx_type specifies the index to be used. If the links have not + * been indexed by the index type, they will first be sorted by that + * index then the iteration will begin; if the links have been so + * indexed, the sorting step will be unnecessary, so the iteration may + * begin more quickly. Valid values include the following: + * \indexes + * + * Note that the index type passed in \p idx_type is a best effort + * setting. If the application passes in a value indicating iteration + * in creation order and a group is encountered that was not tracked + * in creation order, that group will be iterated over in + * lexicographic order by name, or name order. (Name order is the + * native order used by the HDF5 library and is always available.) + * + * \p order specifies the order in which objects are to be inspected + * along the index specified in \p idx_type. Valid values include the + * following: + * \orders + * + * \p op is a callback function of type \ref H5L_iterate2_t that is invoked + * for each link encountered. + * \snippet this H5L_iterate2_t_snip + * + * The \ref H5L_info2_t struct is defined (in H5Lpublic.h) as follows: + * \snippet this H5L_info2_t_snip + * + * The possible return values from the callback function, and the + * effect of each, are as follows: + * \li Zero causes the visit iterator to continue, returning zero when + * all group members have been processed. + * \li A positive value causes the visit iterator to immediately + * return that positive value, indicating short-circuit success. + * \li A negative value causes the visit iterator to immediately + * return that value, indicating failure. + * + * The H5Lvisit2() \p op_data parameter is a user-defined pointer to + * the data required to process links in the course of the iteration. + * This pointer is passed back to each step of the iteration in the + * \p op callback function's \p op_data parameter. + * + * H5Lvisit2() and H5Ovisit2() are companion functions: one for + * examining and operating on links; the other for examining and + * operating on the objects that those links point to. Both functions + * ensure that by the time the function completes successfully, every + * link or object below the specified point in the file has been + * presented to the application for whatever processing the + * application requires. + * + * \since 1.12.0 + * + * \see H5Literate() + * + */ +H5_DLL herr_t H5Lvisit2(hid_t grp_id, H5_index_t idx_type, H5_iter_order_t order, H5L_iterate2_t op, + void *op_data); +/** + * \ingroup TRAV + * + * \brief Recursively visits all links starting from a specified group + * + * \loc_id + * \param[in] group_name Group name + * \idx_type + * \order + * \op + * \op_data + * \lapl_id + * + * \return \herr_t + * + * \details H5Lvisit_by_name2() is a recursive iteration function to visit all + * links in and below a group in an HDF5 file, thus providing a + * mechanism for an application to perform a common set of operations + * across all of those links or a dynamically selected subset. For + * non-recursive iteration across the members of a group, see + * H5Literate2(). + * + * The group serving as the root of the iteration is specified by the + * \p loc_id / \p group_name parameter pair. \p loc_id specifies a + * file or group; group_name specifies either a group in the file + * (with an absolute name based in the file’s root group) or a group + * relative to \p loc_id. If \p loc_id fully specifies the group that + * is to serve as the root of the iteration, group_name should be '.' + * (a dot). (Note that when \p loc_id fully specifies the the group + * that is to serve as the root of the iteration, the user may wish to + * consider using H5Lvisit2() instead of H5Lvisit_by_name2().) + * + * Two parameters are used to establish the iteration: \p idx_type and + * \p order. + * + * \p idx_type specifies the index to be used. If the links have not + * been indexed by the index type, they will first be sorted by that + * index then the iteration will begin; if the links have been so + * indexed, the sorting step will be unnecesary, so the iteration may + * begin more quickly. Valid values include the following: + * \indexes + * + * Note that the index type passed in \p idx_type is a best effort + * setting. If the application passes in a value indicating iteration + * in creation order and a group is encountered that was not tracked + * in creation order, that group will be iterated over in + * lexicographic order by name, or name order. (Name order is the + * native order used by the HDF5 library and is always available.) + * + * \p order specifies the order in which objects are to be inspected + * along the index specified in \p idx_type. Valid values include the + * following: + * \orders + * + * The \p op callback function, the related \ref H5L_info2_t + * \c struct, and the effect that the callback function's return value + * has on the application are described in H5Lvisit2(). + * + * The H5Lvisit_by_name2() \p op_data parameter is a user-defined + * pointer to the data required to process links in the course of the + * iteration. This pointer is passed back to each step of the + * iteration in the callback function's \p op_data parameter. + * + * \p lapl_id is a link access property list. In the general case, + * when default link access properties are acceptable, this can be + * passed in as #H5P_DEFAULT. An example of a situation that requires + * a non-default link access property list is when the link is an + * external link; an external link may require that a link prefix be + * set in a link access property list (see H5Pset_elink_prefix()). + * + * H5Lvisit_by_name2() and H5Ovisit_by_name2() are companion + * functions: one for examining and operating on links; the other for + * examining and operating on the objects that those links point to. + * Both functions ensure that by the time the function completes + * successfully, every link or object below the specified point in the + * file has been presented to the application for whatever processing + * the application requires. + * + * \since 1.12.0 + * + */ +H5_DLL herr_t H5Lvisit_by_name2(hid_t loc_id, const char *group_name, H5_index_t idx_type, + H5_iter_order_t order, H5L_iterate2_t op, void *op_data, hid_t lapl_id); /* UD link functions */ +/** + * \ingroup H5L + * + * \brief Creates a link of a user-defined type + * + * \loc_id{link_loc_id} + * \param[in] link_name Link name + * \param[in] link_type User-defined link class + * \param[in] udata User-supplied link information + * \param[in] udata_size Size of udata buffer + * \lcpl_id + * \lapl_id + * + * \return \herr_t + * + * \details H5Lcreate_ud() creates a link of user-defined type \p link_type + * named \p link_name at the location specified in \p link_loc_id with + * user-specified data \p udata. + * + * \p link_name is interpreted relative to \p link_loc_id. + * + * Valid values for the link class of the new link, \p link_type, + * include #H5L_TYPE_EXTERNAL and any user-defined link classes that + * have been registered with the library. See H5Lregister() for + * further information. + * + * The format of the information pointed to by \p udata is defined by + * the user. \p udata_size specifies the size of the \p udata buffer. + * \p udata may be NULL if \p udata_size is zero (0). + * + * The property lists specified by \p lcpl_id and \p lapl_id specify + * properties used to create and access the link. + * + * \note The external link type, #H5L_TYPE_EXTERNAL, included in the HDF5 + * library distribution, is implemented as a user-defined link type. This + * was done, in part, to provide a model for the implementation of other + * user-defined links. + * + * \since 1.8.0 + * + */ H5_DLL herr_t H5Lcreate_ud(hid_t link_loc_id, const char *link_name, H5L_type_t link_type, const void *udata, size_t udata_size, hid_t lcpl_id, hid_t lapl_id); +/** + * \ingroup H5LA + * + * \brief Registers a user-defined link class or changes behavior of an + * existing class + * + * \param[in] cls Pointer to a buffer containing the struct describing the + * user-defined link class + * + * \return \herr_t + * + * \details H5Lregister() registers a class of user-defined links, or changes + * the behavior of an existing class. + * + * \p cls is a pointer to a buffer containing a copy of the + * H5L_class_t struct. This struct is defined in H5Lpublic.h as + * follows: + * \snippet this H5L_class_t_snip + * + * The class definition passed with \p cls must include at least the + * following: + * \li An H5L_class_t version (which should be #H5L_LINK_CLASS_T_VERS) + * \li A link class identifier, \c class_id + * \li A traversal function, \c trav_func + * + * Remaining \c struct members are optional and may be passed as NULL. + * + * The link class passed in \c class_id must be in the user-definable + * range between #H5L_TYPE_UD_MIN and #H5L_TYPE_UD_MAX + * (see the table below) and will override + * any existing link class with that identifier. + * + * As distributed, valid values of \c class_id used in HDF5 include + * the following (defined in H5Lpublic.h): + * \link_types + * + * The hard and soft link class identifiers cannot be modified or + * reassigned, but the external link class is implemented as an + * example in the user-definable link class identifier range. + * H5Lregister() is used to register additional link classes. It could + * also be used to modify the behavior of the external link class, + * though that is not recommended. + * + * The following table summarizes existing link types and values and + * the reserved and user-definable link class identifier value ranges. + * <table> + * <tr> + * <th>Link class identifier or Value range</th> + * <th>Description</th> + * <th>Link class or label</th> + * </tr> + * <tr> + * <td>0 to 63</td> + * <td>Reserved range</td> + * <td></td> + * </tr> + * <tr> + * <td>64 to 255</td> + * <td>User-definable range</td> + * <td></td> + * </tr> + * <tr> + * <td>64</td> + * <td>Minimum user-defined value</td> + * <td>#H5L_TYPE_UD_MIN</td> + * </tr> + * <tr> + * <td>64</td> + * <td>External link</td> + * <td>#H5L_TYPE_EXTERNAL</td> + * </tr> + * <tr> + * <td>255</td> + * <td>Maximum user-defined value</td> + * <td>#H5L_TYPE_UD_MAX</td> + * </tr> + * <tr> + * <td>255</td> + * <td>Maximum value</td> + * <td>#H5L_TYPE_MAX</td> + * </tr> + * <tr> + * <td>-1</td> + * <td>Error</td> + * <td>#H5L_TYPE_ERROR</td> + * </tr> + * </table> + * + * Note that HDF5 internally registers user-defined link classes only + * by the numeric value of the link class identifier. An application, + * on the other hand, will generally use a name for a user-defined + * class, if for no other purpose than as a variable name. Assume, + * for example, that a complex link type is registered with the link + * class identifier 73 and that the code includes the following + * assignment: + * \code + * H5L_TYPE_COMPLEX_A = 73 + * \endcode + * The application can refer to the link class with a term, + * \c H5L_TYPE_COMPLEX_A, that conveys meaning to a human reviewing + * the code, while HDF5 recognizes it by the more cryptic numeric + * identifier, 73. + * + * \attention Important details and considerations include the following: + * \li If you plan to distribute files or software with a + * user-defined link class, please contact the Help Desk at + * The HDF Group to help prevent collisions between \c class_id + * values. See below. + * \li As distributed with HDF5, the external link class is + * implemented as an example of a user-defined link class with + * #H5L_TYPE_EXTERNAL equal to #H5L_TYPE_UD_MIN. \c class_id in + * the H5L_class_t \c struct must not equal #H5L_TYPE_UD_MIN + * unless you intend to overwrite or modify the behavior of + * external links. + * \li H5Lregister() can be used only with link class identifiers + * in the user-definable range (see table above). + * \li The hard and soft links defined by the HDF5 library, + * #H5L_TYPE_HARD and #H5L_TYPE_SOFT, reside in the reserved + * range below #H5L_TYPE_UD_MIN and cannot be redefined or + * modified. + * \li H5Lis_registered() can be used to determine whether a desired + * link class identifier is available. \Emph{Note that this + * function will tell you only whether the link class identifier + * has been registered with the installed copy of HDF5; it + * cannot tell you whether the link class has been registered + * with The HDF Group.} + * \li #H5L_TYPE_MAX is the maximum allowed value for a link type + * identifier. + * \li #H5L_TYPE_UD_MIN equals #H5L_TYPE_EXTERNAL. + * \li #H5L_TYPE_UD_MAX equals #H5L_TYPE_MAX. + * \li #H5L_TYPE_ERROR indicates that an error has occurred. + * + * \note \Bold{Registration with The HDF Group:}\n + * There are sometimes reasons to take a broader approach to registering + * a user-defined link class than just invoking H5Lregister(). For + * example: + * \li A user-defined link class is intended for use across an + * organization, among collaborators, or across a community of users. + * \li An application or library overlying HDF5 invokes a user-defined + * link class that must be shipped with the software. + * \li Files are distributed that make use of a user-defined link class. + * \li Or simply, a specific user-defined link class is thought to be + * widely useful. + * + * In such cases, you are encouraged to register that link class with + * The HDF Group's Helpdesk. The HDF Group maintains a registry of known + * user-defined link classes and tracks the selected link class + * identifiers. This registry is intended to reduce the risk of + * collisions between \c class_id values and to help coordinate the use + * of specialized link classes. + * + * \since 1.8.0 + * + */ H5_DLL herr_t H5Lregister(const H5L_class_t *cls); +/** + * \ingroup H5LA + * + * \brief Unregisters a class of user-defined links + * + * \param[in] id User-defined link class identifier + * + * \return \herr_t + * + * \details H5Lunregister() unregisters a class of user-defined links, + * preventing them from being traversed, queried, moved, etc. + * + * \note A link class can be re-registered using H5Lregister(). + * + * \since 1.8.0 + * + */ H5_DLL herr_t H5Lunregister(H5L_type_t id); +/** + * \ingroup H5LA + * + * \brief Determines whether a class of user-defined links is registered + * + * \param[in] id User-defined link class identifier + * + * \return \htri_t + * + * \details H5Lis_registered() tests whether a user-defined link class is + * currently registered, either by the HDF5 library or by the user + * through the use of H5Lregister(). + * + * \note A link class must be registered to create new links of that type or to + * traverse existing links of that type. + * + * \since 1.8.0 + * + */ H5_DLL htri_t H5Lis_registered(H5L_type_t id); /* External link functions */ +/** + * \ingroup H5L + * + * \brief Decodes external link information + * + * \param[in] ext_linkval Buffer containing external link information + * \param[in] link_size Size, in bytes, of the \p ext_linkval buffer + * \param[out] flags External link flags, packed as a bitmap (\Emph{Reserved as + * a bitmap for flags; no flags are currently defined, so the + * only valid value * is 0.}) + * \param[out] filename Returned filename \param[out] obj_path Returned + * object path, relative to \p filename + * + * \return \herr_t + * + * \details H5Lunpack_elink_val() decodes the external link information + * returned by H5Lget_val() in the \p ext_linkval buffer. + * + * \p ext_linkval should be the buffer set by H5Lget_val() and will + * consist of two NULL-terminated strings, the filename and object + * path, one after the other. + * + * Given this buffer, H5Lunpack_elink_val() creates pointers to the + * filename and object path within the buffer and returns them in + * \p filename and \p obj_path, unless they are passed in as NULL. + * + * H5Lunpack_elink_val() requires that \p ext_linkval contain a + * concatenated pair of null-terminated strings, so use of this + * function on a string that is not an external link \p udata buffer + * may result in a segmentation fault. This failure can be avoided by + * adhering to the following procedure: + * <ol> + * <li>Call H5Lget_info() to get the link type and the size of the + * link value.<li> + * <li>Verify that the link is an external link, i.e., that its link + * type is #H5L_TYPE_EXTERNAL.</li> + * <li>Call H5Lget_val() to get the link value.</li> + * <li>Call H5Lunpack_elink_val() to unpack that value.</li> + * </ol> + * + * \since 1.8.0 + * + */ H5_DLL herr_t H5Lunpack_elink_val(const void *ext_linkval /*in*/, size_t link_size, unsigned *flags, const char **filename /*out*/, const char **obj_path /*out*/); +/** + * \ingroup H5L + * + * \brief Creates an external link, a soft link to an object in a different file. + * + * \param[in] file_name Name of the target file containing the target object. + * \param[in] obj_name Path within the target file to the target object + * \fgdt_loc_id{link_loc_id} + * \param[in] link_name Name of the new link, relative to \p link_loc_id + * \lcpl_id + * \lapl_id + * \return \herr_t + * + * \details H5Lcreate_external() creates a new external link. An external link + * is a soft link to an object in a different HDF5 file from the + * location of the link, i.e., to an external object. + * + * \p file_name identifies the target file containing the target + * object; \p obj_name specifies the path of the target object within + * that file. \p obj_name must be an absolute pathname in + * \p file_name, i.e., it must start at the target file’s root group, + * but it is not interpreted until an application attempts to traverse + * it. + * + * \p link_loc_id and \p link_name specify the location and name, + * respectively, of the new link. \p link_name is interpreted relative + * to \p link_loc_id. + * + * \p lcpl_id is the link creation property list used in creating the + * new link. + * + * \p lapl_id is the link access property list used in traversing the + * new link. Note that an external file opened by the traversal of an + * external link is always opened with the weak file close degree + * property setting, #H5F_CLOSE_WEAK (see H5Pset_fclose_degree()); + * any file close degree property setting in \p lapl_id is ignored. + * + * An external link behaves similarly to a soft link, and like a soft + * link in an HDF5 file, it may dangle: the target file and object + * need not exist at the time that the external link is created. + * + * When the external link \p link_name is accessed, the library will + * search for the target file \p file_name as described below: + * + * - If \p file_name is a relative pathname, the following steps are + * performed: + * - The library will get the prefix(es) set in the environment + * variable \c HDF5_EXT_PREFIX and will try to prepend each prefix + * to \p file_name to form a new \p file_name. + * - If the new \p file_name does not exist or if \c HDF5_EXT_PREFIX + * is not set, the library will get the prefix set via + * H5Pset_elink_prefix() and prepend it to \p file_name to form a + * new \p file_name. + * - If the new \p file_name does not exist or no prefix is being + * set by H5Pset_elink_prefix(), then the path of the file + * associated with \p link_loc_id is obtained. This path can be + * the absolute path or the current working directory plus the + * relative path of that file when it is created/opened. The + * library will prepend this path to \p file_name to form a new + * \p file_name. + * - If the new \p file_name does not exist, then the library will + * look for \p file_name and will return failure/success + * accordingly. + * - If \p file_name is an absolute pathname, the library will first + * try to find \p file_name. If \p file_name does not exist, + * \p file_name is stripped of directory paths to form a new + * \p file_name. The search for the new \p file_name then follows + * the same steps as described above for a relative pathname. See + * examples below illustrating how target_file_name is stripped to + * form a new \p file_name. + * + * Note that \p file_name is considered to be an absolute pathname + * when the following condition is true: + * + * - For Unix, the first character of \p file_name is a slash (\c /). + * For example, consider a \p file_name of \c /tmp/A.h5. + * If that target file does not exist, the new \p file_name after + * stripping will be \c A.h5. + * - For Windows, there are 6 cases: + * -# \p file_name is an absolute drive with absolute pathname. + * For example, consider a \p file_name of \c /tmp/A.h5. If that + * target file does not exist, the new \p file_name after + * stripping will be \c A.h5. + * -# \p file_name is an absolute pathname without specifying drive + * name. For example, consider a \p file_name of \c /tmp/A.h5. + * If that target file does not exist, the new \p file_name after + * stripping will be \c A.h5. + * -# \p file_name is an absolute drive with relative pathname. + * For example, consider a \p file_name of \c /tmp/A.h5. If that + * target file does not exist, the new \p file_name after + * stripping will be \c tmp\A.h5. + * -# \p file_name is in UNC (Uniform Naming Convention) format with + * server name, share name, and pathname. For example, consider + * a \p file_name of \c /tmp/A.h5. If that target file does not + * exist, the new \p file_name after stripping will be \c A.h5. + * -# \p file_name is in Long UNC (Uniform Naming Convention) format + * with server name, share name, and pathname. For example, + * consider a \p file_name of \c /tmp/A.h5. If that target file + * does not exist, the new \p file_name after stripping will be + * \c A.h5. + * -# \p file_name is in Long UNC (Uniform Naming Convention) format + * with an absolute drive and an absolute pathname. For example, + * consider a \p file_name of \c /tmp/A.h5. If that target file + * does not exist, the new \p file_name after stripping will be + * \c A.h5. + * + * The library opens target file \p file_name with the file access + * property list that is set via H5Pset_elink_fapl() when the external + * link link_name is accessed. If no such property list is set, the + * library uses the file access property list associated with the file + * of \p link_loc_id to open the target file. + * + * If an application requires additional control over file access + * flags or the file access property list, see H5Pset_elink_cb(); this + * function enables the use of an external link callback function as + * described in H5L_elink_traverse_t(). + * + * \attention A file close degree property setting (H5Pset_fclose_degree()) in + * the external link file access property list or in the external + * link callback function will be ignored. A file opened by means of + * traversing an external link is always opened with the weak file + * close degree property setting, #H5F_CLOSE_WEAK . + * + * \see H5Lcreate_hard(), H5Lcreate_soft(), H5Lcreate_ud() + * + * \since 1.8.0 + */ H5_DLL herr_t H5Lcreate_external(const char *file_name, const char *obj_name, hid_t link_loc_id, const char *link_name, hid_t lcpl_id, hid_t lapl_id); +/* API Wrappers for async routines */ +/* (Must be defined _after_ the function prototype) */ +/* (And must only defined when included in application code, not the library) */ +#ifndef H5L_MODULE +#define H5Lcreate_hard_async(...) H5Lcreate_hard_async(__FILE__, __func__, __LINE__, __VA_ARGS__) +#define H5Lcreate_soft_async(...) H5Lcreate_soft_async(__FILE__, __func__, __LINE__, __VA_ARGS__) +#define H5Ldelete_async(...) H5Ldelete_async(__FILE__, __func__, __LINE__, __VA_ARGS__) +#define H5Ldelete_by_idx_async(...) H5Ldelete_by_idx_async(__FILE__, __func__, __LINE__, __VA_ARGS__) +#define H5Lexists_async(...) H5Lexists_async(__FILE__, __func__, __LINE__, __VA_ARGS__) +#define H5Literate_async(...) H5Literate_async(__FILE__, __func__, __LINE__, __VA_ARGS__) + +/* Define "wrapper" versions of function calls, to allow compile-time values to + * be passed in by language wrapper or library layer on top of HDF5. + */ +#define H5Lcreate_hard_async_wrap H5_NO_EXPAND(H5Lcreate_hard_async) +#define H5Lcreate_soft_async_wrap H5_NO_EXPAND(H5Lcreate_soft_async) +#define H5Ldelete_async_wrap H5_NO_EXPAND(H5Ldelete_async) +#define H5Ldelete_by_idx_async_wrap H5_NO_EXPAND(H5Ldelete_by_idx_async) +#define H5Lexists_async_wrap H5_NO_EXPAND(H5Lexists_async) +#define H5Literate_async_wrap H5_NO_EXPAND(H5Literate_async) +#endif /* H5L_MODULE */ + /* Symbols defined for compatibility with previous versions of the HDF5 API. * * Use of these symbols is deprecated. @@ -204,50 +1652,508 @@ H5_DLL herr_t H5Lcreate_external(const char *file_name, const char *obj_name, hi /* Typedefs */ -/* Information struct for link (for H5Lget_info1/H5Lget_info_by_idx1) */ +//! <!-- [H5L_info1_t_snip] --> +/** + * Information struct for link (for H5Lget_info1() and H5Lget_info_by_idx1()) + */ typedef struct { - H5L_type_t type; /* Type of link */ - hbool_t corder_valid; /* Indicate if creation order is valid */ - int64_t corder; /* Creation order */ - H5T_cset_t cset; /* Character set of link name */ + H5L_type_t type; /**< Type of link */ + hbool_t corder_valid; /**< Indicate if creation order is valid */ + int64_t corder; /**< Creation order */ + H5T_cset_t cset; /**< Character set of link name */ union { - haddr_t address; /* Address hard link points to */ - size_t val_size; /* Size of a soft link or UD link value */ + haddr_t address; /**< Address hard link points to */ + size_t val_size; /**< Size of a soft link or UD link value */ } u; } H5L_info1_t; +//! <!-- [H5L_info1_t_snip] --> -/* Callback during link traversal */ +/** Callback during link traversal */ typedef hid_t (*H5L_traverse_0_func_t)(const char *link_name, hid_t cur_group, const void *lnkdata, size_t lnkdata_size, hid_t lapl_id); -/* User-defined link types */ +/** User-defined link types */ typedef struct { - int version; /* Version number of this struct */ - H5L_type_t id; /* Link type ID */ - const char * comment; /* Comment for debugging */ - H5L_create_func_t create_func; /* Callback during link creation */ - H5L_move_func_t move_func; /* Callback after moving link */ - H5L_copy_func_t copy_func; /* Callback after copying link */ - H5L_traverse_0_func_t trav_func; /* Callback during link traversal */ - H5L_delete_func_t del_func; /* Callback for link deletion */ - H5L_query_func_t query_func; /* Callback for queries */ + int version; /**< Version number of this struct */ + H5L_type_t id; /**< Link type ID */ + const char * comment; /**< Comment for debugging */ + H5L_create_func_t create_func; /**< Callback during link creation */ + H5L_move_func_t move_func; /**< Callback after moving link */ + H5L_copy_func_t copy_func; /**< Callback after copying link */ + H5L_traverse_0_func_t trav_func; /**< Callback during link traversal */ + H5L_delete_func_t del_func; /**< Callback for link deletion */ + H5L_query_func_t query_func; /**< Callback for queries */ } H5L_class_0_t; -/* Prototype for H5Literate1/H5Literate_by_name1() operator */ +/** Prototype for H5Literate1() / H5Literate_by_name1() operator */ +//! <!-- [H5L_iterate1_t_snip] --> typedef herr_t (*H5L_iterate1_t)(hid_t group, const char *name, const H5L_info1_t *info, void *op_data); +//! <!-- [H5L_iterate1_t_snip] --> /* Function prototypes */ +/** + * \ingroup H5L + * + * \brief Returns information about a link + * + * \fgdta_loc_id + * \param[in] name Link name + * \param[out] linfo Buffer in which link information is returned + * \lapl_id + * + * \return \herr_t + * + * \deprecated As of HDF5-1.12 this function has been deprecated in favor of + * the function H5Lget_info2() or the macro H5Lget_info(). + * + * \details H5Lget_info1() returns information about the specified link through + * the \p linfo argument. + * + * The location identifier, \p loc_id, specifies the location of the + * link. A link name, \p name, interpreted relative to \p loc_id, + * specifies the link being queried. + * + * \p lapl_id is the link access property list associated with the + * link \p name. In the general case, when default link access + * properties are acceptable, this can be passed in as #H5P_DEFAULT. + * An example of a situation that requires a non-default link access + * property list is when the link is an external link; an external + * link may require that a link prefix be set in a link access + * property list (see H5Pset_elink_prefix()). + * + * H5Lget_info1() returns information about name in the data structure + * \ref H5L_info1_t, which is described below and defined in + * H5Lpublic.h. This structure is returned in the buffer \p linfo. + * \snippet this H5L_info1_t_snip + * In the above struct, type specifies the link class. Valid values + * include the following: + * \link_types + * There will be additional valid values if user-defined links have + * been registered. + * + * \c corder specifies the link’s creation order position while + * \c corder_valid indicates whether the value in \c corder is valid. + * + * If \c corder_valid is \c TRUE, the value in \c corder is known to + * be valid; if \c corder_valid is \c FALSE, the value in \c corder is + * presumed to be invalid; + * + * \c corder starts at zero (0) and is incremented by one (1) as new + * links are created. But higher-numbered entries are not adjusted + * when a lower-numbered link is deleted; the deleted link’s creation + * order position is simply left vacant. In such situations, the value + * of \c corder for the last link created will be larger than the + * number of links remaining in the group. + * + * \c cset specifies the character set in which the link name is + * encoded. Valid values include the following: + * \csets + * This value is set with H5Pset_char_encoding(). + * + * \c address and \c val_size are returned for hard and symbolic + * links, respectively. Symbolic links include soft and external links + * and some user-defined links. + * + * If the link is a hard link, \c address specifies the file address + * that the link points to. + * + * If the link is a symbolic link, \c val_size will be the length of + * the link value, e.g., the length of the HDF5 path name with a null + * terminator. + * + * \version 1.12.0 Function was deprecated. + * \version 1.8.2 Fortran subroutine added in this release. + * \version 1.8.4 Fortran subroutine syntax changed in this release. + * + * \since 1.8.0 + * + */ H5_DLL herr_t H5Lget_info1(hid_t loc_id, const char *name, H5L_info1_t *linfo /*out*/, hid_t lapl_id); +/** + * \ingroup H5L + * + * \brief Retrieves metadata for a link in a group, according to the order + * within a field or index + * + * \loc_id + * \param[in] group_name Group name + * \idx_type + * \order + * \param[in] n Link position for which to retrieve information + * \param[out] linfo Buffer in which link information is returned + * \lapl_id + * + * \return \herr_t + * + * \deprecated As of HDF5-1.12 this function has been deprecated in favor of + * the function H5Lget_info_by_idx2() and the macro + * H5Lget_info_by_idx(). + * + * \details H5get_info_by_idx1() returns the metadata for a link in a group + * according to a specified field or index and a specified order. + * + * The link for which information is to be returned is specified by \p + * idx_type, \p order, and \p n as follows: + * + * - \p idx_type specifies the field by which the links in \p + * group_name are ordered. The links may be indexed on this field, + * in which case operations seeking specific links are likely to + * complete more quickly. + * - \p order specifies the order in which + * the links are to be referenced for the purposes of this function. + * - \p n specifies the position of the subject link. Note that this + * count is zero-based; 0 (zero) indicates that the function will + * return the value of the first link; if \p n is 5, the function + * will return the value of the sixth link; etc. + * + * For example, assume that \p idx_type, \p order, and \p n are + * #H5_INDEX_NAME, #H5_ITER_DEC, and 5, respectively. #H5_INDEX_NAME + * indicates that the links are accessed in lexicographic order by + * their names. #H5_ITER_DEC specifies that the list be traversed in + * reverse order, or in decremented order. And 5 specifies that this + * call to the function will return the metadata for the 6th link + * (\c n + 1) from the end. + * + * See H5Literate1() for a list of valid values and further discussion + * regarding \p idx_type and \p order. + * + * If \p loc_id specifies the group in which the link resides, + * \p group_name can be a dot (\c .). + * + * \version 1.12.0 Function was renamed to H5Lget_index_by_idx1() and deprecated. + * \version 1.8.4 Fortran subroutine syntax changed in this release. + * \version 1.8.2 Fortran subroutine added in this release. + * + * \since 1.8.0 + * + */ H5_DLL herr_t H5Lget_info_by_idx1(hid_t loc_id, const char *group_name, H5_index_t idx_type, H5_iter_order_t order, hsize_t n, H5L_info1_t *linfo /*out*/, hid_t lapl_id); +/** + * \ingroup TRAV + * + * \brief Iterates over links in a group, with user callback routine, + * according to the order within an index. + * + * \group_id{grp_id} + * \idx_type + * \order + * \param[in,out] idx Pointer to an iteration index to allow + * continuing a previous iteration + * \op + * \op_data + * \return \success{The return value of the first operator that returns + * non-zero, or zero if all members were processed with no + * operator returning non-zero.} + * \return \failure{Negative if an error occurs in the library, or the negative + * value returned by one of the operators.} + * + * \deprecated Deprecated in favor of H5Literate2(). + * + * \details H5Literate1() iterates through the links in a file or + * group, \p group_id, in the order of the specified + * index, \p idx_type, using a user-defined callback routine + * \p op. H5Literate1() does not recursively follow links into + * subgroups of the specified group. + * + * Three parameters are used to manage progress of the iteration: + * \p idx_type, \p order, and \p idx_p. + * + * \p idx_type specifies the index to be used. If the links have + * not been indexed by the index type, they will first be sorted by + * that index then the iteration will begin; if the links have been + * so indexed, the sorting step will be unnecessary, so the iteration + * may begin more quickly. + * + * \p order specifies the order in which objects are to be inspected + * along the index \p idx_type. + * + * \p idx_p tracks the iteration and allows an iteration to be + * resumed if it was stopped before all members were processed. It is + * passed in by the application with a starting point and returned by + * the library with the point at which the iteration stopped. + * + * \p op_data is a user-defined pointer to the data required to + * process links in the course of the iteration. This pointer is + * passed back to each step of the iteration in the \p op callback + * function's \p op_data parameter. \p op is invoked for each link + * encounter. + * + * \p op_data is passed to and from each iteration and can be used to + * supply or aggregate information across iterations. + * + * \remark Same pattern of behavior as H5Giterate(). + * + * \note This function is also available through the H5Literate() macro. + * + * \warning The behavior of H5Literate1() is undefined if the link + * membership of \p group_id changes during the iteration. + * This does not limit the ability to change link destinations + * while iterating, but caution is advised. + * + * + * \version 1.12.0 Function was deprecated in this release. + * \since 1.8.0 + * + * \see H5Literate_by_name2(), H5Lvisit2(), H5Lvisit_by_name2() + * + */ H5_DLL herr_t H5Literate1(hid_t grp_id, H5_index_t idx_type, H5_iter_order_t order, hsize_t *idx, H5L_iterate1_t op, void *op_data); +/** + * \ingroup TRAV + * + * \brief Iterates through links in a group by its name + * + * \loc_id + * \param[in] group_name Group name + * \idx_type + * \order + * \param[in,out] idx iteration position at which to start (\Emph{IN}) or + * position at which an interrupted iteration may be restarted + * (\Emph{OUT}) + * \op + * \op_data + * \lapl_id + * + * \return \success{The return value of the first operator that returns + * non-zero, or zero if all members were processed with no + * operator returning non-zero.} + * \return \failure{Negative if an error occurs in the library, or the negative + * value returned by one of the operators.} + * + * \deprecated As of HDF5-1.12 this function has been deprecated in favor of + * the function H5Literate_by_name2() or the macro + * H5Literate_by_name(). + * + * \details H5Literate_by_name1() iterates through the links in a group + * specified by \p loc_id and \p group_name, in the order of the + * specified index, \p idx_type, using a user-defined callback routine + * \p op. H5Literate_by_name1() does not recursively follow links into + * subgroups of the specified group. + * + * \p idx_type specifies the index to be used. If the links have not + * been indexed by the index type, they will first be sorted by that + * index then the iteration will begin; if the links have been so + * indexed, the sorting step will be unnecessary, so the iteration may + * begin more quickly. Valid values include the following: + * \indexes + * + * \p order specifies the order in which objects are to be inspected + * along the index specified in \p idx_type. Valid values include the + * following: + * \orders + * + * \p idx allows an interrupted iteration to be resumed; it is + * passed in by the application with a starting point and returned by + * the library with the point at which the iteration stopped. + * + * \note H5Literate_by_name1() is not recursive. In particular, if a member of + * \p group_name is found to be a group, call it \c subgroup_a, + * H5Literate_by_name1() does not examine the members of \c subgroup_a. + * When recursive iteration is required, the application must handle the + * recursion, explicitly calling H5Literate_by_name1() on discovered + * subgroups. + * + * \note H5Literate_by_name1() assumes that the membership of the group being + * iterated over remains unchanged through the iteration; if any of the + * links in the group change during the iteration, the function’s + * behavior is undefined. Note, however, that objects pointed to by the + * links can be modified. + * + * \note H5Literate_by_name1() is the same as H5Giterate(), except that + * H5Giterate() always proceeds in lexicographic order. + * + * \version 1.12.0 Function H5Literate_by_name() was renamed to + * H5Literate_by_name1() and deprecated. + * \version 1.8.8 Fortran subroutine added. + * + * \since 1.8.0 + * + */ H5_DLL herr_t H5Literate_by_name1(hid_t loc_id, const char *group_name, H5_index_t idx_type, H5_iter_order_t order, hsize_t *idx, H5L_iterate1_t op, void *op_data, hid_t lapl_id); +/** + * \ingroup TRAV + * + * \brief Recursively visits all links starting from a specified group + * + * \group_id{grp_id} + * \idx_type + * \order + * \op + * \op_data + * + * \return \success{The return value of the first operator that returns + * non-zero, or zero if all members were processed with no + * operator returning non-zero.} + * \return \failure{Negative if an error occurs in the library, or the negative + * value returned by one of the operators.} + * + * \deprecated As of HDF5-1.12 this function has been deprecated in favor of + * the function H5Lvisit2() or the macro H5Lvisit(). + * + * \details H5Lvisit1() is a recursive iteration function to visit all links in + * and below a group in an HDF5 file, thus providing a mechanism for + * an application to perform a common set of operations across all of + * those links or a dynamically selected subset. For non-recursive + * iteration across the members of a group, see H5Literate1(). + * + * The group serving as the root of the iteration is specified by its + * group or file identifier, \p group_id. + * + * Two parameters are used to establish the iteration: \p idx_type and + * \p order. + * + * \p idx_type specifies the index to be used. If the links have not + * been indexed by the index type, they will first be sorted by that + * index then the iteration will begin; if the links have been so + * indexed, the sorting step will be unnecessary, so the iteration may + * begin more quickly. Valid values include the following: + * \indexes + * + * Note that the index type passed in \p idx_type is a best effort + * setting. If the application passes in a value indicating iteration + * in creation order and a group is encountered that was not tracked + * in creation order, that group will be iterated over in + * lexicographic order by name, or name order. (Name order is the + * native order used by the HDF5 library and is always available.) + * + * \p order specifies the order in which objects are to be inspected + * along the index specified in \p idx_type. Valid values include the + * following: + * \orders + * + * \p op is a callback function of type \ref H5L_iterate1_t that is invoked + * for each link encountered. + * \snippet this H5L_iterate1_t_snip + * + * The \ref H5L_info1_t struct is defined (in H5Lpublic.h) as follows: + * \snippet this H5L_info1_t_snip + * + * The possible return values from the callback function, and the + * effect of each, are as follows: + * \li Zero causes the visit iterator to continue, returning zero when + * all group members have been processed. + * \li A positive value causes the visit iterator to immediately + * return that positive value, indicating short-circuit success. + * \li A negative value causes the visit iterator to immediately + * return that value, indicating failure. + * + * The H5Lvisit1() \p op_data parameter is a user-defined pointer to + * the data required to process links in the course of the iteration. + * This pointer is passed back to each step of the iteration in the + * \p op callback function's \p op_data parameter. + * + * H5Lvisit1() and H5Ovisit1() are companion functions: one for + * examining and operating on links; the other for examining and + * operating on the objects that those links point to. Both functions + * ensure that by the time the function completes successfully, every + * link or object below the specified point in the file has been + * presented to the application for whatever processing the + * application requires. + * + * \version 1.12.0 Function was renamed from H5Lvisit() to H5Lvisit1() and + * deprecated. + * + * \since 1.8.0 + * + */ H5_DLL herr_t H5Lvisit1(hid_t grp_id, H5_index_t idx_type, H5_iter_order_t order, H5L_iterate1_t op, void *op_data); +/** + * \ingroup TRAV + * + * \brief Recursively visits all links starting from a specified group + * + * \loc_id + * \param[in] group_name Group name + * \idx_type + * \order + * \op + * \op_data + * \lapl_id + * + * \return \success{The return value of the first operator that returns + * non-zero, or zero if all members were processed with no + * operator returning non-zero.} + * \return \failure{Negative if an error occurs in the library, or the negative + * value returned by one of the operators.} + * + * \deprecated As of HDF5-1.12 this function has been deprecated in favor of + * the function H5Lvisit_by_name2() or the macro H5Lvisit_by_name(). + * + * \details H5Lvisit_by_name1() is a recursive iteration function to visit all + * links in and below a group in an HDF5 file, thus providing a + * mechanism for an application to perform a common set of operations + * across all of those links or a dynamically selected subset. For + * non-recursive iteration across the members of a group, see + * H5Literate1(). + * + * The group serving as the root of the iteration is specified by the + * \p loc_id / \p group_name parameter pair. \p loc_id specifies a + * file or group; group_name specifies either a group in the file + * (with an absolute name based in the file’s root group) or a group + * relative to \p loc_id. If \p loc_id fully specifies the group that + * is to serve as the root of the iteration, group_name should be '.' + * (a dot). (Note that when \p loc_id fully specifies the the group + * that is to serve as the root of the iteration, the user may wish to + * consider using H5Lvisit1() instead of H5Lvisit_by_name1().) + * + * Two parameters are used to establish the iteration: \p idx_type and + * \p order. + * + * \p idx_type specifies the index to be used. If the links have not + * been indexed by the index type, they will first be sorted by that + * index then the iteration will begin; if the links have been so + * indexed, the sorting step will be unnecesary, so the iteration may + * begin more quickly. Valid values include the following: + * \indexes + * + * Note that the index type passed in \p idx_type is a best effort + * setting. If the application passes in a value indicating iteration + * in creation order and a group is encountered that was not tracked + * in creation order, that group will be iterated over in + * lexicographic order by name, or name order. (Name order is the + * native order used by the HDF5 library and is always available.) + * + * \p order specifies the order in which objects are to be inspected + * along the index specified in \p idx_type. Valid values include the + * following: + * \orders + * + * The \p op callback function, the related \ref H5L_info1_t + * \c struct, and the effect that the callback function's return value + * has on the application are described in H5Lvisit1(). + * + * The H5Lvisit_by_name1() \p op_data parameter is a user-defined + * pointer to the data required to process links in the course of the + * iteration. This pointer is passed back to each step of the + * iteration in the callback function's \p op_data parameter. + * + * \p lapl_id is a link access property list. In the general case, + * when default link access properties are acceptable, this can be + * passed in as #H5P_DEFAULT. An example of a situation that requires + * a non-default link access property list is when the link is an + * external link; an external link may require that a link prefix be + * set in a link access property list (see H5Pset_elink_prefix()). + * + * H5Lvisit_by_name1() and H5Ovisit_by_name1() are companion + * functions: one for examining and operating on links; the other for + * examining and operating on the objects that those links point to. + * Both functions ensure that by the time the function completes + * successfully, every link or object below the specified point in the + * file has been presented to the application for whatever processing + * the application requires. + * + * \version 1.12.0 Function renamed from H5Lvisit_by_name() to + * H5Lvisit_by_name1() and deprecated. + * + * \since 1.8.0 + * + */ H5_DLL herr_t H5Lvisit_by_name1(hid_t loc_id, const char *group_name, H5_index_t idx_type, H5_iter_order_t order, H5L_iterate1_t op, void *op_data, hid_t lapl_id); @@ -24,6 +24,7 @@ #include "H5CXprivate.h" /* API Contexts */ #include "H5Mpkg.h" /* Maps */ #include "H5Eprivate.h" /* Error handling */ +#include "H5ESprivate.h" /* Event Sets */ #include "H5Iprivate.h" /* IDs */ #include "H5VLprivate.h" /* Virtual Object Layer */ @@ -38,8 +39,20 @@ /********************/ /* Local Prototypes */ /********************/ +static herr_t H5M__close_cb(H5VL_object_t *map_vol_obj, void **request); -static herr_t H5M__close_cb(H5VL_object_t *map_vol_obj); +#ifdef H5_HAVE_MAP_API +static hid_t H5M__create_api_common(hid_t loc_id, const char *name, hid_t key_type_id, hid_t val_type_id, + hid_t lcpl_id, hid_t mcpl_id, hid_t mapl_id, void **token_ptr, + H5VL_object_t **_vol_obj_ptr); +static hid_t H5M__open_api_common(hid_t loc_id, const char *name, hid_t mapl_id, void **token_ptr, + H5VL_object_t **_vol_obj_ptr); +static herr_t H5M__put_api_common(hid_t map_id, hid_t key_mem_type_id, const void *key, hid_t val_mem_type_id, + const void *value, hid_t dxpl_id, void **token_ptr, + H5VL_object_t **_vol_obj_ptr); +static herr_t H5M__get_api_common(hid_t map_id, hid_t key_mem_type_id, const void *key, hid_t val_mem_type_id, + void *value, hid_t dxpl_id, void **token_ptr, H5VL_object_t **_vol_obj_ptr); +#endif /* H5_HAVE_MAP_API */ /*********************/ /* Package Variables */ @@ -196,7 +209,7 @@ H5M_term_package(void) *------------------------------------------------------------------------- */ static herr_t -H5M__close_cb(H5VL_object_t *map_vol_obj) +H5M__close_cb(H5VL_object_t *map_vol_obj, void **request) { herr_t ret_value = SUCCEED; /* Return value */ @@ -206,7 +219,7 @@ H5M__close_cb(H5VL_object_t *map_vol_obj) HDassert(map_vol_obj); /* Close the map */ - if (H5VL_optional(map_vol_obj, H5VL_MAP_CLOSE, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0) + if (H5VL_optional(map_vol_obj, H5VL_MAP_CLOSE, H5P_DATASET_XFER_DEFAULT, request) < 0) HGOTO_ERROR(H5E_MAP, H5E_CLOSEERROR, FAIL, "unable to close map"); /* Free the VOL object */ @@ -220,15 +233,9 @@ done: #ifdef H5_HAVE_MAP_API /*------------------------------------------------------------------------- - * Function: H5Mcreate + * Function: H5M__create_api_common * - * Purpose: Creates a new map object for storing key-value pairs. The - * in-file datatype for keys is defined by KEY_TYPE_ID and - * the in-file datatype for values is defined by VAL_TYPE_ID. - * LOC_ID specifies the location to create the map object and - * NAME specifies the name of the link to the object - * (relative to LOC_ID). Other options can be specified - * through the property lists LCPL_ID, MCPL_ID, and MAPL_ID. + * Purpose: This is the common function for creating the HDF5 map. * * Return: Success: The object ID of the new map. * @@ -236,17 +243,18 @@ done: * *------------------------------------------------------------------------- */ -hid_t -H5Mcreate(hid_t loc_id, const char *name, hid_t key_type_id, hid_t val_type_id, hid_t lcpl_id, hid_t mcpl_id, - hid_t mapl_id) +static hid_t +H5M__create_api_common(hid_t loc_id, const char *name, hid_t key_type_id, hid_t val_type_id, hid_t lcpl_id, + hid_t mcpl_id, hid_t mapl_id, void **token_ptr, H5VL_object_t **_vol_obj_ptr) { - void * map = NULL; /* New map's info */ - H5VL_object_t * vol_obj = NULL; /* object of loc_id */ - H5VL_loc_params_t loc_params; - hid_t ret_value = H5I_INVALID_HID; /* Return value */ + void * map = NULL; /* New map's info */ + H5VL_object_t * tmp_vol_obj = NULL; /* Object for loc_id */ + H5VL_object_t **vol_obj_ptr = + (_vol_obj_ptr ? _vol_obj_ptr : &tmp_vol_obj); /* Ptr to object ptr for loc_id */ + H5VL_loc_params_t loc_params; /* Location parameters */ + hid_t ret_value = H5I_INVALID_HID; /* Return value */ - FUNC_ENTER_API(H5I_INVALID_HID) - H5TRACE7("i", "i*siiiii", loc_id, name, key_type_id, val_type_id, lcpl_id, mcpl_id, mapl_id); + FUNC_ENTER_STATIC /* Check arguments */ if (!name) @@ -266,37 +274,113 @@ H5Mcreate(hid_t loc_id, const char *name, hid_t key_type_id, hid_t val_type_id, else if (TRUE != H5P_isa_class(mcpl_id, H5P_MAP_CREATE)) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5I_INVALID_HID, "mcpl_id is not a map create property list ID") - /* Verify access property list and set up collective metadata if appropriate */ - if (H5CX_set_apl(&mapl_id, H5P_CLS_MACC, loc_id, TRUE) < 0) - HGOTO_ERROR(H5E_MAP, H5E_CANTSET, H5I_INVALID_HID, "can't set access property list info") - - /* Get the location object */ - if (NULL == (vol_obj = (H5VL_object_t *)H5I_object(loc_id))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5I_INVALID_HID, "invalid location identifier") - - /* Set location parameters */ - loc_params.type = H5VL_OBJECT_BY_SELF; - loc_params.obj_type = H5I_get_type(loc_id); + /* Set up object access arguments */ + if (H5VL_setup_acc_args(loc_id, H5P_CLS_MACC, TRUE, &mapl_id, vol_obj_ptr, &loc_params) < 0) + HGOTO_ERROR(H5E_MAP, H5E_CANTSET, H5I_INVALID_HID, "can't set object access arguments") /* Create the map */ - if (H5VL_optional(vol_obj, H5VL_MAP_CREATE, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL, &loc_params, name, + if (H5VL_optional(*vol_obj_ptr, H5VL_MAP_CREATE, H5P_DATASET_XFER_DEFAULT, token_ptr, &loc_params, name, lcpl_id, key_type_id, val_type_id, mcpl_id, mapl_id, &map) < 0) HGOTO_ERROR(H5E_MAP, H5E_CANTINIT, H5I_INVALID_HID, "unable to create map") - /* Get an atom for the map */ - if ((ret_value = H5VL_register(H5I_MAP, map, vol_obj->connector, TRUE)) < 0) - HGOTO_ERROR(H5E_MAP, H5E_CANTREGISTER, H5I_INVALID_HID, "unable to atomize map handle") + /* Get an ID for the map */ + if ((ret_value = H5VL_register(H5I_MAP, map, (*vol_obj_ptr)->connector, TRUE)) < 0) + HGOTO_ERROR(H5E_MAP, H5E_CANTREGISTER, H5I_INVALID_HID, "unable to register map handle") done: /* Cleanup on failure */ if (H5I_INVALID_HID == ret_value) - if (map && H5VL_optional(vol_obj, H5VL_MAP_CLOSE, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0) + if (map && H5VL_optional(*vol_obj_ptr, H5VL_MAP_CLOSE, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0) HDONE_ERROR(H5E_DATASET, H5E_CLOSEERROR, H5I_INVALID_HID, "unable to release map") + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5M__create_api_common() */ + +/*------------------------------------------------------------------------- + * Function: H5Mcreate + * + * Purpose: Creates a new map object for storing key-value pairs. The + * in-file datatype for keys is defined by KEY_TYPE_ID and + * the in-file datatype for values is defined by VAL_TYPE_ID. + * LOC_ID specifies the location to create the map object and + * NAME specifies the name of the link to the object + * (relative to LOC_ID). Other options can be specified + * through the property lists LCPL_ID, MCPL_ID, and MAPL_ID. + * + * Return: Success: The object ID of the new map. + * + * Failure: H5I_INVALID_HID + * + *------------------------------------------------------------------------- + */ +hid_t +H5Mcreate(hid_t loc_id, const char *name, hid_t key_type_id, hid_t val_type_id, hid_t lcpl_id, hid_t mcpl_id, + hid_t mapl_id) +{ + hid_t ret_value = H5I_INVALID_HID; /* Return value */ + + FUNC_ENTER_API(H5I_INVALID_HID) + H5TRACE7("i", "i*siiiii", loc_id, name, key_type_id, val_type_id, lcpl_id, mcpl_id, mapl_id); + + /* Create the map synchronously */ + if ((ret_value = H5M__create_api_common(loc_id, name, key_type_id, val_type_id, lcpl_id, mcpl_id, mapl_id, + NULL, NULL)) < 0) + HGOTO_ERROR(H5E_MAP, H5E_CANTCREATE, H5I_INVALID_HID, "unable to create map synchronously") + +done: FUNC_LEAVE_API(ret_value) } /* end H5Mcreate() */ /*------------------------------------------------------------------------- + * Function: H5Mcreate_async + * + * Purpose: Asynchronous version of H5Mcreate + * + * Return: Success: The object ID of the new map. + * + * Failure: H5I_INVALID_HID + * + *------------------------------------------------------------------------- + */ +hid_t +H5Mcreate_async(const char *app_file, const char *app_func, unsigned app_line, hid_t loc_id, const char *name, + hid_t key_type_id, hid_t val_type_id, hid_t lcpl_id, hid_t mcpl_id, hid_t mapl_id, + hid_t es_id) +{ + H5VL_object_t *vol_obj = NULL; /* Object for loc_id */ + void * token = NULL; /* Request token for async operation */ + void ** token_ptr = H5_REQUEST_NULL; /* Pointer to request token for async operation */ + hid_t ret_value = H5I_INVALID_HID; /* Return value */ + + FUNC_ENTER_API(H5I_INVALID_HID) + H5TRACE11("i", "*s*sIui*siiiiii", app_file, app_func, app_line, loc_id, name, key_type_id, val_type_id, + lcpl_id, mcpl_id, mapl_id, es_id); + + /* Set up request token pointer for asynchronous operation */ + if (H5ES_NONE != es_id) + token_ptr = &token; + + /* Create the map asynchronously */ + if ((ret_value = H5M__create_api_common(loc_id, name, key_type_id, val_type_id, lcpl_id, mcpl_id, mapl_id, + token_ptr, &vol_obj)) < 0) + HGOTO_ERROR(H5E_MAP, H5E_CANTCREATE, H5I_INVALID_HID, "unable to create map asynchronously") + + /* If a token was created, add the token to the event set */ + if (NULL != token) + /* clang-format off */ + if (H5ES_insert(es_id, vol_obj->connector, token, + H5ARG_TRACE11(FUNC, "*s*sIui*siiiiii", app_file, app_func, app_line, loc_id, name, key_type_id, val_type_id, lcpl_id, mcpl_id, mapl_id, es_id)) < 0) { + /* clang-format on */ + if (H5I_dec_app_ref_always_close(ret_value) < 0) + HDONE_ERROR(H5E_MAP, H5E_CANTDEC, H5I_INVALID_HID, "can't decrement count on map ID") + HGOTO_ERROR(H5E_MAP, H5E_CANTINSERT, H5I_INVALID_HID, "can't insert token into event set") + } /* end if */ + +done: + FUNC_LEAVE_API(ret_value) +} /* end H5Mcreate_async() */ + +/*------------------------------------------------------------------------- * Function: H5Mcreate_anon * * Purpose: Creates a new map object for storing key-value pairs. The @@ -368,13 +452,9 @@ done: } /* end H5Mcreate_anon() */ /*------------------------------------------------------------------------ - * Function: H5Mopen + * Function: H5M__open_api_common * - * Purpose: Finds a map named NAME at LOC_ID, opens it, and returns - * its ID. The map should be close when the caller is no - * longer interested in it. - * - * Takes a map access property list + * Purpose: This is the common function for opening the HDF5 map. * * Return: Success: Object ID of the map * @@ -382,16 +462,18 @@ done: * *------------------------------------------------------------------------- */ -hid_t -H5Mopen(hid_t loc_id, const char *name, hid_t mapl_id) +static hid_t +H5M__open_api_common(hid_t loc_id, const char *name, hid_t mapl_id, void **token_ptr, + H5VL_object_t **_vol_obj_ptr) { - void * map = NULL; /* map object from VOL connector */ - H5VL_object_t * vol_obj = NULL; /* object of loc_id */ - H5VL_loc_params_t loc_params; - hid_t ret_value = H5I_INVALID_HID; /* Return value */ + void * map = NULL; /* map object from VOL connector */ + H5VL_object_t * tmp_vol_obj = NULL; /* Object for loc_id */ + H5VL_object_t **vol_obj_ptr = + (_vol_obj_ptr ? _vol_obj_ptr : &tmp_vol_obj); /* Ptr to object ptr for loc_id */ + H5VL_loc_params_t loc_params; /* Location parameters */ + hid_t ret_value = H5I_INVALID_HID; /* Return value */ - FUNC_ENTER_API(H5I_INVALID_HID) - H5TRACE3("i", "i*si", loc_id, name, mapl_id); + FUNC_ENTER_STATIC /* Check args */ if (!name) @@ -399,26 +481,56 @@ H5Mopen(hid_t loc_id, const char *name, hid_t mapl_id) if (!*name) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, H5I_INVALID_HID, "name parameter cannot be an empty string") - /* Verify access property list and set up collective metadata if appropriate */ - if (H5CX_set_apl(&mapl_id, H5P_CLS_MACC, loc_id, FALSE) < 0) - HGOTO_ERROR(H5E_MAP, H5E_CANTSET, H5I_INVALID_HID, "can't set access property list info") - - /* get the location object */ - if (NULL == (vol_obj = (H5VL_object_t *)H5I_object(loc_id))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5I_INVALID_HID, "invalid location identifier") - - /* Set the location parameters */ - loc_params.type = H5VL_OBJECT_BY_SELF; - loc_params.obj_type = H5I_get_type(loc_id); + /* Set up object access arguments */ + if (H5VL_setup_acc_args(loc_id, H5P_CLS_MACC, FALSE, &mapl_id, vol_obj_ptr, &loc_params) < 0) + HGOTO_ERROR(H5E_MAP, H5E_CANTSET, H5I_INVALID_HID, "can't set object access arguments") /* Open the map */ - if (H5VL_optional(vol_obj, H5VL_MAP_OPEN, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL, &loc_params, name, + if (H5VL_optional(*vol_obj_ptr, H5VL_MAP_OPEN, H5P_DATASET_XFER_DEFAULT, token_ptr, &loc_params, name, mapl_id, &map) < 0) HGOTO_ERROR(H5E_MAP, H5E_CANTOPENOBJ, H5I_INVALID_HID, "unable to open map") - /* Register an atom for the map */ - if ((ret_value = H5VL_register(H5I_MAP, map, vol_obj->connector, TRUE)) < 0) - HGOTO_ERROR(H5E_MAP, H5E_CANTREGISTER, H5I_INVALID_HID, "can't register map atom") + /* Register an ID for the map */ + if ((ret_value = H5VL_register(H5I_MAP, map, (*vol_obj_ptr)->connector, TRUE)) < 0) + HGOTO_ERROR(H5E_MAP, H5E_CANTREGISTER, H5I_INVALID_HID, "can't register map ID") + +done: + /* Cleanup on failure */ + if (H5I_INVALID_HID == ret_value) + if (map && H5VL_optional(*vol_obj_ptr, H5VL_MAP_CLOSE, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0) + HDONE_ERROR(H5E_DATASET, H5E_CLOSEERROR, H5I_INVALID_HID, "unable to release map") + + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5M__open_api_common() */ + +/*------------------------------------------------------------------------ + * Function: H5Mopen + * + * Purpose: Finds a map named NAME at LOC_ID, opens it, and returns + * its ID. The map should be close when the caller is no + * longer interested in it. + * + * Takes a map access property list + * + * Return: Success: Object ID of the map + * + * Failure: H5I_INVALID_HID + * + *------------------------------------------------------------------------- + */ +hid_t +H5Mopen(hid_t loc_id, const char *name, hid_t mapl_id) +{ + void * map = NULL; /* map object from VOL connector */ + H5VL_object_t *vol_obj = NULL; /* object of loc_id */ + hid_t ret_value = H5I_INVALID_HID; /* Return value */ + + FUNC_ENTER_API(H5I_INVALID_HID) + H5TRACE3("i", "i*si", loc_id, name, mapl_id); + + /* Open the map synchronously */ + if ((ret_value = H5M__open_api_common(loc_id, name, mapl_id, NULL, NULL)) < 0) + HGOTO_ERROR(H5E_MAP, H5E_CANTCREATE, H5I_INVALID_HID, "unable to open map synchronously") done: /* Cleanup on failure */ @@ -429,6 +541,52 @@ done: FUNC_LEAVE_API(ret_value) } /* end H5Mopen() */ +/*------------------------------------------------------------------------ + * Function: H5Mopen_async + * + * Purpose: Asynchronous version of H5Mopen + * + * Return: Success: Object ID of the map + * + * Failure: H5I_INVALID_HID + * + *------------------------------------------------------------------------- + */ +hid_t +H5Mopen_async(const char *app_file, const char *app_func, unsigned app_line, hid_t loc_id, const char *name, + hid_t mapl_id, hid_t es_id) +{ + H5VL_object_t *vol_obj = NULL; /* Object for loc_id */ + void * token = NULL; /* Request token for async operation */ + void ** token_ptr = H5_REQUEST_NULL; /* Pointer to request token for async operation */ + hid_t ret_value = H5I_INVALID_HID; /* Return value */ + + FUNC_ENTER_API(H5I_INVALID_HID) + H5TRACE7("i", "*s*sIui*sii", app_file, app_func, app_line, loc_id, name, mapl_id, es_id); + + /* Set up request token pointer for asynchronous operation */ + if (H5ES_NONE != es_id) + token_ptr = &token; + + /* Open the map asynchronously */ + if ((ret_value = H5M__open_api_common(loc_id, name, mapl_id, token_ptr, &vol_obj)) < 0) + HGOTO_ERROR(H5E_MAP, H5E_CANTCREATE, H5I_INVALID_HID, "unable to open map asynchronously") + + /* If a token was created, add the token to the event set */ + if (NULL != token) + /* clang-format off */ + if (H5ES_insert(es_id, vol_obj->connector, token, + H5ARG_TRACE7(FUNC, "*s*sIui*sii", app_file, app_func, app_line, loc_id, name, mapl_id, es_id)) < 0) { + /* clang-format on */ + if (H5I_dec_app_ref_always_close(ret_value) < 0) + HDONE_ERROR(H5E_MAP, H5E_CANTDEC, H5I_INVALID_HID, "can't decrement count on map ID") + HGOTO_ERROR(H5E_MAP, H5E_CANTINSERT, H5I_INVALID_HID, "can't insert token into event set") + } /* end if */ + +done: + FUNC_LEAVE_API(ret_value) +} /* end H5Mopen_async() */ + /*------------------------------------------------------------------------- * Function: H5Mclose * @@ -463,6 +621,67 @@ done: } /* end H5Mclose() */ /*------------------------------------------------------------------------- + * Function: H5Mclose_async + * + * Purpose: Asynchronous version of H5Mclose + * + * Return: SUCCEED/FAIL + * + *------------------------------------------------------------------------- + */ +herr_t +H5Mclose_async(const char *app_file, const char *app_func, unsigned app_line, hid_t map_id, hid_t es_id) +{ + void * token = NULL; /* Request token for async operation */ + void ** token_ptr = H5_REQUEST_NULL; /* Pointer to request token for async operation */ + H5VL_object_t *vol_obj = NULL; /* VOL object of dset_id */ + H5VL_t * connector = NULL; /* VOL connector */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_API(FAIL) + H5TRACE5("e", "*s*sIuii", app_file, app_func, app_line, map_id, es_id); + + /* Check args */ + if (H5I_MAP != H5I_get_type(map_id)) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a map ID") + + /* Get map object's connector */ + if (NULL == (vol_obj = H5VL_vol_object(map_id))) + HGOTO_ERROR(H5E_MAP, H5E_CANTGET, FAIL, "can't get VOL object for map") + + /* Prepare for possible asynchronous operation */ + if (H5ES_NONE != es_id) { + /* Increase connector's refcount, so it doesn't get closed if closing + * the dataset closes the file */ + connector = vol_obj->connector; + H5VL_conn_inc_rc(connector); + + /* Point at token for operation to set up */ + token_ptr = &token; + } /* end if */ + + /* Decrement the counter on the map. It will be freed if the count + * reaches zero. + */ + if (H5I_dec_app_ref_always_close_async(map_id, token_ptr) < 0) + HGOTO_ERROR(H5E_MAP, H5E_CANTDEC, FAIL, "can't decrement count on dataset ID") + + /* If a token was created, add the token to the event set */ + if (NULL != token) + /* clang-format off */ + if (H5ES_insert(es_id, vol_obj->connector, token, + H5ARG_TRACE5(FUNC, "*s*sIuii", app_file, app_func, app_line, map_id, es_id)) < 0) + /* clang-format on */ + HGOTO_ERROR(H5E_MAP, H5E_CANTINSERT, FAIL, "can't insert token into event set") + +done: + if (connector && H5VL_conn_dec_rc(connector) < 0) + HDONE_ERROR(H5E_MAP, H5E_CANTDEC, FAIL, "can't decrement ref count on connector") + + FUNC_LEAVE_API(ret_value) +} /* end H5Mclose_async() */ + +/*------------------------------------------------------------------------- * Function: H5Mget_key_type * * Purpose: Returns a copy of the key datatype for a map. @@ -618,13 +837,13 @@ done: *------------------------------------------------------------------------- */ herr_t -H5Mget_count(hid_t map_id, hsize_t *count, hid_t dxpl_id) +H5Mget_count(hid_t map_id, hsize_t *count /*out*/, hid_t dxpl_id) { H5VL_object_t *vol_obj; /* Map structure */ herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API(H5I_INVALID_HID) - H5TRACE3("e", "i*hi", map_id, count, dxpl_id); + H5TRACE3("e", "ixi", map_id, count, dxpl_id); /* Check args */ if (NULL == (vol_obj = (H5VL_object_t *)H5I_object_verify(map_id, H5I_MAP))) @@ -648,6 +867,54 @@ done: } /* end H5Mget_count() */ /*------------------------------------------------------------------------- + * Function: H5M__put_api_common + * + * Purpose: This is the common function for putting value to map. + * + * Return: SUCCEED/FAIL + * + *------------------------------------------------------------------------- + */ +static herr_t +H5M__put_api_common(hid_t map_id, hid_t key_mem_type_id, const void *key, hid_t val_mem_type_id, + const void *value, hid_t dxpl_id, void **token_ptr, H5VL_object_t **_vol_obj_ptr) +{ + H5VL_object_t * tmp_vol_obj = NULL; /* Object for loc_id */ + H5VL_object_t **vol_obj_ptr = + (_vol_obj_ptr ? _vol_obj_ptr : &tmp_vol_obj); /* Ptr to object ptr for loc_id */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_STATIC + + /* Check arguments */ + if (key_mem_type_id < 0) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid key memory datatype ID") + if (val_mem_type_id < 0) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid value memory datatype ID") + + /* Get map pointer */ + if (NULL == (*vol_obj_ptr = (H5VL_object_t *)H5I_object_verify(map_id, H5I_MAP))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "map_id is not a map ID") + + /* Get the default dataset transfer property list if the user didn't provide one */ + if (H5P_DEFAULT == dxpl_id) + dxpl_id = H5P_DATASET_XFER_DEFAULT; + else if (TRUE != H5P_isa_class(dxpl_id, H5P_DATASET_XFER)) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not xfer parms") + + /* Set DXPL for operation */ + H5CX_set_dxpl(dxpl_id); + + /* Set the key/value pair */ + if (H5VL_optional(*vol_obj_ptr, H5VL_MAP_PUT, dxpl_id, token_ptr, key_mem_type_id, key, val_mem_type_id, + value) < 0) + HGOTO_ERROR(H5E_MAP, H5E_CANTSET, FAIL, "unable to put key/value pair") + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5M__put_api_common() */ + +/*------------------------------------------------------------------------- * Function: H5Mput * * Purpose: H5Mput adds a key-value pair to the Map specified by @@ -667,12 +934,84 @@ herr_t H5Mput(hid_t map_id, hid_t key_mem_type_id, const void *key, hid_t val_mem_type_id, const void *value, hid_t dxpl_id) { - H5VL_object_t *vol_obj = NULL; - herr_t ret_value = SUCCEED; /* Return value */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API(FAIL) H5TRACE6("e", "ii*xi*xi", map_id, key_mem_type_id, key, val_mem_type_id, value, dxpl_id); + /* Add key-value pair to the map synchronously */ + if ((ret_value = H5M__put_api_common(map_id, key_mem_type_id, key, val_mem_type_id, value, dxpl_id, NULL, + NULL)) < 0) + HGOTO_ERROR(H5E_MAP, H5E_CANTPUT, FAIL, "unable to put value to map synchronously") + +done: + FUNC_LEAVE_API(ret_value) +} /* end H5Mput() */ + +/*------------------------------------------------------------------------- + * Function: H5Mput_async + * + * Purpose: Asynchronous version of H5Mput + * + * Return: SUCCEED/FAIL + * + *------------------------------------------------------------------------- + */ +herr_t +H5Mput_async(const char *app_file, const char *app_func, unsigned app_line, hid_t map_id, + hid_t key_mem_type_id, const void *key, hid_t val_mem_type_id, const void *value, hid_t dxpl_id, + hid_t es_id) +{ + H5VL_object_t *vol_obj = NULL; /* Object for loc_id */ + void * token = NULL; /* Request token for async operation */ + void ** token_ptr = H5_REQUEST_NULL; /* Pointer to request token for async operation */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_API(FAIL) + H5TRACE10("e", "*s*sIuii*xi*xii", app_file, app_func, app_line, map_id, key_mem_type_id, key, + val_mem_type_id, value, dxpl_id, es_id); + + /* Set up request token pointer for asynchronous operation */ + if (H5ES_NONE != es_id) + token_ptr = &token; + + /* Add key-value pair to the map asynchronously */ + if ((ret_value = H5M__put_api_common(map_id, key_mem_type_id, key, val_mem_type_id, value, dxpl_id, + token_ptr, &vol_obj)) < 0) + HGOTO_ERROR(H5E_MAP, H5E_CANTPUT, FAIL, "unable to put value to map asynchronously") + + /* If a token was created, add the token to the event set */ + if (NULL != token) + /* clang-format off */ + if (H5ES_insert(es_id, vol_obj->connector, token, + H5ARG_TRACE10(FUNC, "*s*sIuii*xi*xii", app_file, app_func, app_line, map_id, key_mem_type_id, key, val_mem_type_id, value, dxpl_id, es_id)) < 0) + /* clang-format on */ + HGOTO_ERROR(H5E_MAP, H5E_CANTINSERT, FAIL, "can't insert token into event set") + +done: + FUNC_LEAVE_API(ret_value) +} /* end H5Mput_async() */ + +/*------------------------------------------------------------------------- + * Function: H5M__get_api_common + * + * Purpose: This is common function for getting value from the map. + * + * Return: SUCCEED/FAIL + * + *------------------------------------------------------------------------- + */ +static herr_t +H5M__get_api_common(hid_t map_id, hid_t key_mem_type_id, const void *key, hid_t val_mem_type_id, void *value, + hid_t dxpl_id, void **token_ptr, H5VL_object_t **_vol_obj_ptr) +{ + H5VL_object_t * tmp_vol_obj = NULL; /* Object for loc_id */ + H5VL_object_t **vol_obj_ptr = + (_vol_obj_ptr ? _vol_obj_ptr : &tmp_vol_obj); /* Ptr to object ptr for loc_id */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_STATIC + /* Check arguments */ if (key_mem_type_id < 0) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid key memory datatype ID") @@ -680,7 +1019,7 @@ H5Mput(hid_t map_id, hid_t key_mem_type_id, const void *key, hid_t val_mem_type_ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid value memory datatype ID") /* Get map pointer */ - if (NULL == (vol_obj = (H5VL_object_t *)H5I_object_verify(map_id, H5I_MAP))) + if (NULL == (*vol_obj_ptr = (H5VL_object_t *)H5I_object_verify(map_id, H5I_MAP))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "map_id is not a map ID") /* Get the default dataset transfer property list if the user didn't provide one */ @@ -692,14 +1031,14 @@ H5Mput(hid_t map_id, hid_t key_mem_type_id, const void *key, hid_t val_mem_type_ /* Set DXPL for operation */ H5CX_set_dxpl(dxpl_id); - /* Set the key/value pair */ - if (H5VL_optional(vol_obj, H5VL_MAP_PUT, dxpl_id, H5_REQUEST_NULL, key_mem_type_id, key, val_mem_type_id, - value) < 0) - HGOTO_ERROR(H5E_MAP, H5E_CANTSET, FAIL, "unable to put key/value pair") + /* Get the value for the key */ + if (H5VL_optional(*vol_obj_ptr, H5VL_MAP_GET_VAL, dxpl_id, token_ptr, key_mem_type_id, key, + val_mem_type_id, value) < 0) + HGOTO_ERROR(H5E_MAP, H5E_CANTGET, FAIL, "unable to get value from map") done: - FUNC_LEAVE_API(ret_value) -} /* end H5Mput() */ + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5M__get_api_common() */ /*------------------------------------------------------------------------- * Function: H5Mget @@ -724,39 +1063,63 @@ herr_t H5Mget(hid_t map_id, hid_t key_mem_type_id, const void *key, hid_t val_mem_type_id, void *value, hid_t dxpl_id) { - H5VL_object_t *vol_obj = NULL; - herr_t ret_value = SUCCEED; /* Return value */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API(FAIL) H5TRACE6("e", "ii*xi*xi", map_id, key_mem_type_id, key, val_mem_type_id, value, dxpl_id); - /* Check arguments */ - if (key_mem_type_id < 0) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid key memory datatype ID") - if (val_mem_type_id < 0) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid value memory datatype ID") + /* Get key-value pair from the map synchronously */ + if ((ret_value = H5M__get_api_common(map_id, key_mem_type_id, key, val_mem_type_id, value, dxpl_id, NULL, + NULL)) < 0) + HGOTO_ERROR(H5E_MAP, H5E_CANTGET, FAIL, "unable to get value from map synchronously") - /* Get map pointer */ - if (NULL == (vol_obj = (H5VL_object_t *)H5I_object_verify(map_id, H5I_MAP))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "map_id is not a map ID") - - /* Get the default dataset transfer property list if the user didn't provide one */ - if (H5P_DEFAULT == dxpl_id) - dxpl_id = H5P_DATASET_XFER_DEFAULT; - else if (TRUE != H5P_isa_class(dxpl_id, H5P_DATASET_XFER)) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not xfer parms") +done: + FUNC_LEAVE_API(ret_value) +} /* end H5Mget() */ - /* Set DXPL for operation */ - H5CX_set_dxpl(dxpl_id); +/*------------------------------------------------------------------------- + * Function: H5Mget_async + * + * Purpose: Asynchronous version of H5Mget + * + * Return: SUCCEED/FAIL + * + *------------------------------------------------------------------------- + */ +herr_t +H5Mget_async(const char *app_file, const char *app_func, unsigned app_line, hid_t map_id, + hid_t key_mem_type_id, const void *key, hid_t val_mem_type_id, void *value, hid_t dxpl_id, + hid_t es_id) +{ + H5VL_object_t *vol_obj = NULL; /* Object for loc_id */ + void * token = NULL; /* Request token for async operation */ + void ** token_ptr = H5_REQUEST_NULL; /* Pointer to request token for async operation */ + herr_t ret_value = SUCCEED; /* Return value */ - /* Get the value for the key */ - if (H5VL_optional(vol_obj, H5VL_MAP_GET_VAL, dxpl_id, H5_REQUEST_NULL, key_mem_type_id, key, - val_mem_type_id, value) < 0) - HGOTO_ERROR(H5E_MAP, H5E_CANTGET, FAIL, "unable to get value from map") + FUNC_ENTER_API(FAIL) + H5TRACE10("e", "*s*sIuii*xi*xii", app_file, app_func, app_line, map_id, key_mem_type_id, key, + val_mem_type_id, value, dxpl_id, es_id); + + /* Set up request token pointer for asynchronous operation */ + if (H5ES_NONE != es_id) + token_ptr = &token; + + /* Get key-value pair from the map asynchronously */ + if ((ret_value = H5M__get_api_common(map_id, key_mem_type_id, key, val_mem_type_id, value, dxpl_id, + token_ptr, &vol_obj)) < 0) + HGOTO_ERROR(H5E_MAP, H5E_CANTGET, FAIL, "unable to get value from map asynchronously") + + /* If a token was created, add the token to the event set */ + if (NULL != token) + /* clang-format off */ + if (H5ES_insert(es_id, vol_obj->connector, token, + H5ARG_TRACE10(FUNC, "*s*sIuii*xi*xii", app_file, app_func, app_line, map_id, key_mem_type_id, key, val_mem_type_id, value, dxpl_id, es_id)) < 0) + /* clang-format on */ + HGOTO_ERROR(H5E_MAP, H5E_CANTINSERT, FAIL, "can't insert token into event set") done: FUNC_LEAVE_API(ret_value) -} /* end H5Mget() */ +} /* end H5Mget_async() */ /*------------------------------------------------------------------------- * Function: H5Mexists @@ -873,7 +1236,7 @@ H5Miterate(hid_t map_id, hsize_t *idx, hid_t key_mem_type_id, H5M_iterate_t op, /* Iterate over keys */ if ((ret_value = H5VL_optional(vol_obj, H5VL_MAP_SPECIFIC, dxpl_id, H5_REQUEST_NULL, &loc_params, H5VL_MAP_ITER, idx, key_mem_type_id, op, op_data)) < 0) - HGOTO_ERROR(H5E_MAP, H5E_BADITER, ret_value, "unable to ierate over keys") + HGOTO_ERROR(H5E_MAP, H5E_BADITER, ret_value, "unable to iterate over keys") done: FUNC_LEAVE_API(ret_value) @@ -15,7 +15,7 @@ * * Created: H5MF.c * Jul 11 1997 - * Robb Matzke <matzke@llnl.gov> + * Robb Matzke * * Purpose: File memory management functions. * @@ -49,9 +49,11 @@ #define H5MF_FSPACE_EXPAND 120 /* Percent of "normal" size to expand serialized free space size */ #define H5MF_CHECK_FSM(FSM, CF) \ - HDassert(*CF == FALSE); \ - if (!H5F_addr_defined(FSM->addr) || !H5F_addr_defined(FSM->sect_addr)) \ - *CF = TRUE; + do { \ + HDassert(*CF == FALSE); \ + if (!H5F_addr_defined(FSM->addr) || !H5F_addr_defined(FSM->sect_addr)) \ + *CF = TRUE; \ + } while (0) /* For non-paged aggregation: map allocation request type to tracked free-space type */ /* F_SH -- pointer to H5F_shared_t; T -- H5FD_mem_t */ @@ -352,7 +354,6 @@ H5MF__alloc_to_fs_type(H5F_shared_t *f_sh, H5FD_mem_t alloc_type, hsize_t size, * Failure: negative * * Programmer: Quincey Koziol - * koziol@hdfgroup.org * Jan 8 2008 * *------------------------------------------------------------------------- @@ -430,7 +431,6 @@ done: * Failure: negative * * Programmer: Quincey Koziol - * koziol@hdfgroup.org * Jan 8 2008 * *------------------------------------------------------------------------- @@ -514,7 +514,6 @@ done: * Failure: negative * * Programmer: Quincey Koziol - * koziol@hdfgroup.org * Jan 8 2008 * *------------------------------------------------------------------------- @@ -824,7 +823,6 @@ done: * Failure: HADDR_UNDEF * * Programmer: Robb Matzke - * matzke@llnl.gov * Jul 11 1997 * *------------------------------------------------------------------------- @@ -838,6 +836,9 @@ H5MF_alloc(H5F_t *f, H5FD_mem_t alloc_type, hsize_t size) haddr_t ret_value = HADDR_UNDEF; /* Return value */ FUNC_ENTER_NOAPI_TAG(H5AC__FREESPACE_TAG, HADDR_UNDEF) +#ifdef H5MF_ALLOC_DEBUG + HDfprintf(stderr, "%s: alloc_type = %u, size = %Hu\n", FUNC, (unsigned)alloc_type, size); +#endif /* H5MF_ALLOC_DEBUG */ /* check arguments */ HDassert(f); @@ -852,6 +853,10 @@ H5MF_alloc(H5F_t *f, H5FD_mem_t alloc_type, hsize_t size) } H5MF__alloc_to_fs_type(f->shared, alloc_type, size, &fs_type); +#ifdef H5MF_ALLOC_DEBUG_MORE + HDfprintf(stderr, "%s: Check 1.0\n", FUNC); +#endif /* H5MF_ALLOC_DEBUG_MORE */ + /* Set the ring type in the API context */ if (H5MF__fsm_type_is_self_referential(f->shared, fs_type)) fsm_ring = H5AC_RING_MDFSM; @@ -885,7 +890,9 @@ H5MF_alloc(H5F_t *f, H5FD_mem_t alloc_type, hsize_t size) /* If no space is found from the free-space manager, continue further action */ if (!H5F_addr_defined(ret_value)) { - +#ifdef H5MF_ALLOC_DEBUG_MORE + HDfprintf(stderr, "%s: Check 2.0\n", FUNC); +#endif /* H5MF_ALLOC_DEBUG_MORE */ if (f->shared->fs_strategy == H5F_FSPACE_STRATEGY_PAGE) { HDassert(f->shared->fs_page_size >= H5F_FILE_SPACE_PAGE_SIZE_MIN); if (HADDR_UNDEF == (ret_value = H5MF__alloc_pagefs(f, alloc_type, size))) @@ -898,12 +905,18 @@ H5MF_alloc(H5F_t *f, H5FD_mem_t alloc_type, hsize_t size) } /* end else */ } /* end if */ HDassert(H5F_addr_defined(ret_value)); +#ifdef H5MF_ALLOC_DEBUG_MORE + HDfprintf(stderr, "%s: Check 3.0\n", FUNC); +#endif /* H5MF_ALLOC_DEBUG_MORE */ done: /* Reset the ring in the API context */ if (orig_ring != H5AC_RING_INV) H5AC_set_ring(orig_ring, NULL); +#ifdef H5MF_ALLOC_DEBUG + HDfprintf(stderr, "%s: Leaving: ret_value = %a, size = %Hu\n", FUNC, ret_value, size); +#endif /* H5MF_ALLOC_DEBUG */ #ifdef H5MF_ALLOC_DEBUG_DUMP H5MF__sects_dump(f, stderr); #endif /* H5MF_ALLOC_DEBUG_DUMP */ @@ -1121,7 +1134,6 @@ done: * Return: Non-negative on success/Negative on failure * * Programmer: Robb Matzke - * matzke@llnl.gov * Jul 17 1997 * *------------------------------------------------------------------------- @@ -1132,8 +1144,12 @@ H5MF_xfree(H5F_t *f, H5FD_mem_t alloc_type, haddr_t addr, hsize_t size) herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI_TAG(H5AC__FREESPACE_TAG, FAIL) +#ifdef H5MF_ALLOC_DEBUG + HDfprintf(stderr, "%s: Entering - alloc_type = %u, addr = %a, size = %Hu\n", FUNC, (unsigned)alloc_type, + addr, size); +#endif /* H5MF_ALLOC_DEBUG */ - /* Check arguments */ + /* check arguments */ HDassert(f); if (!H5F_addr_defined(addr) || 0 == size) HGOTO_DONE(SUCCEED) @@ -1206,18 +1222,28 @@ H5MF__xfree_inner_impl(H5F_t *f, H5FD_mem_t alloc_type, haddr_t addr, hsize_t si * see if we can avoid creating one by checking if the freed * space is at the end of the file */ - +#ifdef H5MF_ALLOC_DEBUG_MORE + HDfprintf(stderr, "%s: fs_addr = %a\n", FUNC, f->shared->fs_addr[fs_type]); +#endif /* H5MF_ALLOC_DEBUG_MORE */ if (!H5F_addr_defined(f->shared->fs_addr[fs_type])) { htri_t status; /* "can absorb" status for section into */ +#ifdef H5MF_ALLOC_DEBUG_MORE + HDfprintf(stderr, "%s: Trying to avoid starting up free space manager\n", FUNC); +#endif /* H5MF_ALLOC_DEBUG_MORE */ /* Try to shrink the file or absorb the block into a block aggregator */ if ((status = H5MF_try_shrink(f, alloc_type, addr, size)) < 0) HGOTO_ERROR(H5E_RESOURCE, H5E_CANTMERGE, FAIL, "can't check for absorbing block") else if (status > 0) + /* Indicate success */ HGOTO_DONE(SUCCEED) - else if (size < f->shared->fs_threshold) + else if (size < f->shared->fs_threshold) { +#ifdef H5MF_ALLOC_DEBUG_MORE + HDfprintf(stderr, "%s: dropping addr = %a, size = %Hu, on the floor!\n", FUNC, addr, size); +#endif /* H5MF_ALLOC_DEBUG_MORE */ HGOTO_DONE(SUCCEED) - } + } /* end else-if */ + } /* end if */ /* If we are deleting the free space manager, leave now, to avoid * [re-]starting it. @@ -1229,8 +1255,11 @@ H5MF__xfree_inner_impl(H5F_t *f, H5FD_mem_t alloc_type, haddr_t addr, hsize_t si * */ if (f->shared->fs_state[fs_type] == H5F_FS_STATE_DELETING || !H5F_HAVE_FREE_SPACE_MANAGER(f)) { +#ifdef H5MF_ALLOC_DEBUG_MORE + HDfprintf(stderr, "%s: dropping addr = %a, size = %Hu, on the floor!\n", FUNC, addr, size); +#endif /* H5MF_ALLOC_DEBUG_MORE */ HGOTO_DONE(SUCCEED) - } + } /* end if */ /* There's either already a free space manager, or the freed * space isn't at the end of the file, so start up (or create) @@ -1238,7 +1267,7 @@ H5MF__xfree_inner_impl(H5F_t *f, H5FD_mem_t alloc_type, haddr_t addr, hsize_t si */ if (H5MF__start_fstype(f, fs_type) < 0) HGOTO_ERROR(H5E_RESOURCE, H5E_CANTINIT, FAIL, "can't initialize file free space") - } + } /* end if */ /* Create the free-space section for the freed section */ ctype = H5MF_SECT_CLASS_TYPE(f, size); @@ -1249,11 +1278,19 @@ H5MF__xfree_inner_impl(H5F_t *f, H5FD_mem_t alloc_type, haddr_t addr, hsize_t si if (size >= f->shared->fs_threshold) { HDassert(f->shared->fs_man[fs_type]); +#ifdef H5MF_ALLOC_DEBUG_MORE + HDfprintf(stderr, "%s: Before H5FS_sect_add()\n", FUNC); +#endif /* H5MF_ALLOC_DEBUG_MORE */ + /* Add to the free space for the file */ if (H5MF__add_sect(f, alloc_type, f->shared->fs_man[fs_type], node) < 0) HGOTO_ERROR(H5E_RESOURCE, H5E_CANTINSERT, FAIL, "can't add section to file free space") node = NULL; - } + +#ifdef H5MF_ALLOC_DEBUG_MORE + HDfprintf(stderr, "%s: After H5FS_sect_add()\n", FUNC); +#endif /* H5MF_ALLOC_DEBUG_MORE */ + } /* end if */ else { htri_t merged; /* Whether node was merged */ H5MF_sect_ud_t udata; /* User data for callback */ @@ -1271,7 +1308,7 @@ H5MF__xfree_inner_impl(H5F_t *f, H5FD_mem_t alloc_type, haddr_t addr, hsize_t si else if (merged == TRUE) /* successfully merged */ /* Indicate that the node was used */ node = NULL; - } + } /* end else */ done: /* Reset the ring in the API context */ @@ -1283,6 +1320,9 @@ done: if (H5MF__sect_free((H5FS_section_info_t *)node) < 0) HDONE_ERROR(H5E_RESOURCE, H5E_CANTRELEASE, FAIL, "can't free simple section node") +#ifdef H5MF_ALLOC_DEBUG + HDfprintf(stderr, "%s: Leaving, ret_value = %d\n", FUNC, ret_value); +#endif /* H5MF_ALLOC_DEBUG */ #ifdef H5MF_ALLOC_DEBUG_DUMP H5MF__sects_dump(f, stderr); #endif /* H5MF_ALLOC_DEBUG_DUMP */ @@ -1373,6 +1413,10 @@ H5MF_try_extend(H5F_t *f, H5FD_mem_t alloc_type, haddr_t addr, hsize_t size, hsi htri_t ret_value = FALSE; /* Return value */ FUNC_ENTER_NOAPI_TAG(H5AC__FREESPACE_TAG, FAIL) +#ifdef H5MF_ALLOC_DEBUG + HDfprintf(stderr, "%s: Entering: alloc_type = %u, addr = %a, size = %Hu, extra_requested = %Hu\n", FUNC, + (unsigned)alloc_type, addr, size, extra_requested); +#endif /* H5MF_ALLOC_DEBUG */ /* Sanity check */ HDassert(f); @@ -1422,6 +1466,9 @@ H5MF_try_extend(H5F_t *f, H5FD_mem_t alloc_type, haddr_t addr, hsize_t size, hsi /* Try extending the block at EOA */ if ((ret_value = H5F__try_extend(f, map_type, end, extra_requested + frag_size)) < 0) HGOTO_ERROR(H5E_RESOURCE, H5E_CANTEXTEND, FAIL, "error extending file") +#ifdef H5MF_ALLOC_DEBUG_MORE + HDfprintf(stderr, "%s: extended = %t\n", FUNC, ret_value); +#endif /* H5MF_ALLOC_DEBUG_MORE */ /* If extending at EOA succeeds: */ /* for paged aggregation, put the fragment into the large-sized free-space manager */ @@ -1456,7 +1503,11 @@ H5MF_try_extend(H5F_t *f, H5FD_mem_t alloc_type, haddr_t addr, hsize_t size, hsi aggr = (map_type == H5FD_MEM_DRAW) ? &(f->shared->sdata_aggr) : &(f->shared->meta_aggr); if ((ret_value = H5MF__aggr_try_extend(f, aggr, map_type, end, extra_requested)) < 0) HGOTO_ERROR(H5E_RESOURCE, H5E_CANTEXTEND, FAIL, "error extending aggregation block") - } + +#ifdef H5MF_ALLOC_DEBUG_MORE + HDfprintf(stderr, "%s: H5MF__aggr_try_extend = %t\n", FUNC, ret_value); +#endif /* H5MF_ALLOC_DEBUG_MORE */ + } /* end if */ /* If no extension so far, try to extend into a free-space section */ if (ret_value == FALSE && @@ -1479,7 +1530,10 @@ H5MF_try_extend(H5F_t *f, H5FD_mem_t alloc_type, haddr_t addr, hsize_t size, hsi extra_requested, H5FS_ADD_RETURNED_SPACE, &udata)) < 0) HGOTO_ERROR(H5E_RESOURCE, H5E_CANTEXTEND, FAIL, "error extending block in free space manager") - } +#ifdef H5MF_ALLOC_DEBUG_MORE + HDfprintf(stderr, "%s: Try to H5FS_sect_try_extend = %t\n", FUNC, ret_value); +#endif /* H5MF_ALLOC_DEBUG_MORE */ + } /* end if */ /* For paged aggregation and a metadata block: try to extend into page end threshold */ if (ret_value == FALSE && H5F_PAGED_AGGR(f) && map_type != H5FD_MEM_DRAW) { @@ -1487,15 +1541,21 @@ H5MF_try_extend(H5F_t *f, H5FD_mem_t alloc_type, haddr_t addr, hsize_t size, hsi if (frag_size <= H5F_PGEND_META_THRES(f) && extra_requested <= frag_size) ret_value = TRUE; - } - } - } +#ifdef H5MF_ALLOC_DEBUG_MORE + HDfprintf(stderr, "%s: Try to extend into the page end threshold = %t\n", FUNC, ret_value); +#endif /* H5MF_ALLOC_DEBUG_MORE */ + } /* end if */ + } /* end if */ + } /* allow_extend */ done: /* Reset the ring in the API context */ if (orig_ring != H5AC_RING_INV) H5AC_set_ring(orig_ring, NULL); +#ifdef H5MF_ALLOC_DEBUG + HDfprintf(stderr, "%s: Leaving: ret_value = %t\n", FUNC, ret_value); +#endif /* H5MF_ALLOC_DEBUG */ #ifdef H5MF_ALLOC_DEBUG_DUMP H5MF__sects_dump(f, stderr); #endif /* H5MF_ALLOC_DEBUG_DUMP */ @@ -1512,7 +1572,6 @@ done: * Return: Non-negative on success/Negative on failure * * Programmer: Quincey Koziol - * koziol@hdfgroup.org * Feb 14 2008 * *------------------------------------------------------------------------- @@ -1520,15 +1579,19 @@ done: htri_t H5MF_try_shrink(H5F_t *f, H5FD_mem_t alloc_type, haddr_t addr, hsize_t size) { - H5MF_free_section_t * node = NULL; /* Free space section pointer */ - H5MF_sect_ud_t udata; /* User data for callback */ - H5FS_section_class_t *sect_cls; /* Section class */ - H5AC_ring_t orig_ring = H5AC_RING_INV; /* Original ring value */ - H5AC_ring_t fsm_ring = H5AC_RING_INV; /* Ring of FSM */ - H5F_mem_page_t fs_type; /* Free space type */ - htri_t ret_value = FALSE; /* Return value */ + H5MF_free_section_t * node = NULL; /* Free space section pointer */ + H5MF_sect_ud_t udata; /* User data for callback */ + const H5FS_section_class_t *sect_cls; /* Section class */ + H5AC_ring_t orig_ring = H5AC_RING_INV; /* Original ring value */ + H5AC_ring_t fsm_ring = H5AC_RING_INV; /* Ring of FSM */ + H5F_mem_page_t fs_type; /* Free space type */ + htri_t ret_value = FALSE; /* Return value */ FUNC_ENTER_NOAPI_TAG(H5AC__FREESPACE_TAG, FAIL) +#ifdef H5MF_ALLOC_DEBUG + HDfprintf(stderr, "%s: Entering - alloc_type = %u, addr = %a, size = %Hu\n", FUNC, (unsigned)alloc_type, + addr, size); +#endif /* H5MF_ALLOC_DEBUG */ /* check arguments */ HDassert(f); @@ -1582,6 +1645,9 @@ done: if (node && H5MF__sect_free((H5FS_section_info_t *)node) < 0) HDONE_ERROR(H5E_RESOURCE, H5E_CANTRELEASE, FAIL, "can't free simple section node") +#ifdef H5MF_ALLOC_DEBUG + HDfprintf(stderr, "%s: Leaving, ret_value = %d\n", FUNC, ret_value); +#endif /* H5MF_ALLOC_DEBUG */ FUNC_LEAVE_NOAPI_TAG(ret_value) } /* end H5MF_try_shrink() */ @@ -1603,6 +1669,9 @@ H5MF_close(H5F_t *f) herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI_TAG(H5AC__FREESPACE_TAG, FAIL) +#ifdef H5MF_ALLOC_DEBUG + HDfprintf(stderr, "%s: Entering\n", FUNC); +#endif /* H5MF_ALLOC_DEBUG */ /* check args */ HDassert(f); @@ -1615,9 +1684,12 @@ H5MF_close(H5F_t *f) else { if ((ret_value = H5MF__close_aggrfs(f)) < 0) HGOTO_ERROR(H5E_FILE, H5E_CANTFREE, FAIL, "can't close free-space managers for 'aggr' file space") - } /* end else */ + } done: +#ifdef H5MF_ALLOC_DEBUG + HDfprintf(stderr, "%s: Leaving\n", FUNC); +#endif /* H5MF_ALLOC_DEBUG */ FUNC_LEAVE_NOAPI_TAG(ret_value) } /* end H5MF_close() */ @@ -2223,7 +2295,7 @@ H5MF__close_shrink_eoa(H5F_t *f) } /* end for */ /* check the two aggregators */ - if ((status = H5MF_aggrs_try_shrink_eoa(f)) < 0) + if ((status = H5MF__aggrs_try_shrink_eoa(f)) < 0) HGOTO_ERROR(H5E_RESOURCE, H5E_CANTSHRINK, FAIL, "can't check for shrinking eoa") else if (status > 0) eoa_shrank = TRUE; @@ -2550,7 +2622,7 @@ H5MF__get_free_sects(H5F_t *f, H5FS_t *fspace, H5MF_sect_iter_ud_t *sect_udata, hsize_t hnums = 0; /* # of sections */ herr_t ret_value = SUCCEED; /* Return value */ - FUNC_ENTER_PACKAGE + FUNC_ENTER_STATIC /* check args */ HDassert(f); @@ -2695,6 +2767,10 @@ H5MF_settle_raw_data_fsm(H5F_t *f, hbool_t *fsm_settled) HDassert(f->shared); HDassert(fsm_settled); + /* Initialize structs */ + HDmemset(&fsinfo, 0, sizeof(fsinfo)); + HDmemset(&fs_stat, 0, sizeof(fs_stat)); + /* * Only need to settle things if we are persisting free space and * the private property in f->shared->null_fsm_addr is not enabled. @@ -3101,7 +3177,7 @@ done: * 3) Reduce the EOA to the extent possible, and make note * of the resulting value. This value will be stored * in the fsinfo superblock extension message and be used - * in the subsequent file open. + * in the subsequent file open. * * 4) Re-allocate space for any free space manager(s) that: * @@ -3142,16 +3218,16 @@ done: herr_t H5MF_settle_meta_data_fsm(H5F_t *f, hbool_t *fsm_settled) { - H5F_mem_page_t sm_fshdr_fs_type; /* small fs hdr fsm */ - H5F_mem_page_t sm_fssinfo_fs_type; /* small fs sinfo fsm */ - H5F_mem_page_t lg_fshdr_fs_type; /* large fs hdr fsm */ - H5F_mem_page_t lg_fssinfo_fs_type; /* large fs sinfo fsm */ - H5FS_t * sm_hdr_fspace = NULL; /* ptr to sm FSM hdr alloc FSM */ - H5FS_t * sm_sinfo_fspace = NULL; /* ptr to sm FSM sinfo alloc FSM */ - H5FS_t * lg_hdr_fspace = NULL; /* ptr to lg FSM hdr alloc FSM */ - H5FS_t * lg_sinfo_fspace = NULL; /* ptr to lg FSM sinfo alloc FSM */ - haddr_t eoa_fsm_fsalloc; /* eoa after file space allocation */ - /* for self referential FSMs */ + H5F_mem_page_t sm_fshdr_fs_type; /* small fs hdr fsm */ + H5F_mem_page_t sm_fssinfo_fs_type; /* small fs sinfo fsm */ + H5F_mem_page_t lg_fshdr_fs_type = H5F_MEM_PAGE_DEFAULT; /* large fs hdr fsm */ + H5F_mem_page_t lg_fssinfo_fs_type = H5F_MEM_PAGE_DEFAULT; /* large fs sinfo fsm */ + H5FS_t * sm_hdr_fspace = NULL; /* ptr to sm FSM hdr alloc FSM */ + H5FS_t * sm_sinfo_fspace = NULL; /* ptr to sm FSM sinfo alloc FSM */ + H5FS_t * lg_hdr_fspace = NULL; /* ptr to lg FSM hdr alloc FSM */ + H5FS_t * lg_sinfo_fspace = NULL; /* ptr to lg FSM sinfo alloc FSM */ + haddr_t eoa_fsm_fsalloc; /* eoa after file space allocation */ + /* for self referential FSMs */ hbool_t continue_alloc_fsm = FALSE; /* Continue allocating addr and sect_addr for FSMs */ H5AC_ring_t orig_ring = H5AC_RING_INV; /* Original ring value */ herr_t ret_value = SUCCEED; /* Return value */ @@ -3391,36 +3467,32 @@ static herr_t H5MF__continue_alloc_fsm(H5F_shared_t *f_sh, H5FS_t *sm_hdr_fspace, H5FS_t *sm_sinfo_fspace, H5FS_t *lg_hdr_fspace, H5FS_t *lg_sinfo_fspace, hbool_t *continue_alloc_fsm) { - FUNC_ENTER_NOAPI_NOINIT_NOERR + FUNC_ENTER_STATIC_NOERR /* Sanity checks */ HDassert(f_sh); HDassert(continue_alloc_fsm); /* Check sm_hdr_fspace */ - if (sm_hdr_fspace && sm_hdr_fspace->serial_sect_count > 0 && sm_hdr_fspace->sinfo) { + if (sm_hdr_fspace && sm_hdr_fspace->serial_sect_count > 0 && sm_hdr_fspace->sinfo) H5MF_CHECK_FSM(sm_hdr_fspace, continue_alloc_fsm); - } /* end if */ if (!(*continue_alloc_fsm)) if (sm_sinfo_fspace && sm_sinfo_fspace != sm_hdr_fspace && sm_sinfo_fspace->serial_sect_count > 0 && - sm_sinfo_fspace->sinfo) { + sm_sinfo_fspace->sinfo) H5MF_CHECK_FSM(sm_hdr_fspace, continue_alloc_fsm); - } /* end if */ if (H5F_SHARED_PAGED_AGGR(f_sh) && !(*continue_alloc_fsm)) { /* Check lg_hdr_fspace */ - if (lg_hdr_fspace && lg_hdr_fspace->serial_sect_count > 0 && lg_hdr_fspace->sinfo) { + if (lg_hdr_fspace && lg_hdr_fspace->serial_sect_count > 0 && lg_hdr_fspace->sinfo) H5MF_CHECK_FSM(lg_hdr_fspace, continue_alloc_fsm); - } /* end if */ /* Check lg_sinfo_fspace */ if (!(*continue_alloc_fsm)) if (lg_sinfo_fspace && lg_sinfo_fspace != lg_hdr_fspace && - lg_sinfo_fspace->serial_sect_count > 0 && lg_sinfo_fspace->sinfo) { + lg_sinfo_fspace->serial_sect_count > 0 && lg_sinfo_fspace->sinfo) H5MF_CHECK_FSM(lg_sinfo_fspace, continue_alloc_fsm); - } /* end if */ - } /* end if */ + } /* end if */ FUNC_LEAVE_NOAPI(SUCCEED) } /* H5MF__continue_alloc_fsm() */ diff --git a/src/H5MFaggr.c b/src/H5MFaggr.c index 54088ae..12e9dbe 100644 --- a/src/H5MFaggr.c +++ b/src/H5MFaggr.c @@ -12,7 +12,7 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* - * Programmer: Quincey Koziol <koziol@hdfgroup.org> + * Programmer: Quincey Koziol * Tuesday, January 8, 2008 * * Purpose: Routines for aggregating free space allocations @@ -892,7 +892,7 @@ done: } /* H5MF__aggr_free() */ /*------------------------------------------------------------------------- - * Function: H5MF_aggrs_try_shrink_eoa + * Function: H5MF__aggrs_try_shrink_eoa * * Purpose: Check the metadata & small block aggregators to see if * EOA shrink is possible; if so, shrink each aggregator @@ -904,13 +904,13 @@ done: * *------------------------------------------------------------------------- */ - htri_t H5MF_aggrs_try_shrink_eoa(H5F_t * f) + htri_t H5MF__aggrs_try_shrink_eoa(H5F_t * f) { htri_t ma_status; /* Whether the metadata aggregator can shrink the EOA */ htri_t sda_status; /* Whether the small data aggregator can shrink the EOA */ htri_t ret_value = FAIL; /* Return value */ - FUNC_ENTER_NOAPI(FAIL) + FUNC_ENTER_PACKAGE /* Check args */ HDassert(f); @@ -932,4 +932,4 @@ done: done: FUNC_LEAVE_NOAPI(ret_value) - } /* end H5MF_aggrs_try_shrink_eoa() */ + } /* end H5MF__aggrs_try_shrink_eoa() */ diff --git a/src/H5MFpkg.h b/src/H5MFpkg.h index bac9fac..f34c73e 100644 --- a/src/H5MFpkg.h +++ b/src/H5MFpkg.h @@ -50,12 +50,12 @@ /* Free-space section types for file */ /* (values stored in free space data structures in file) */ -#define H5MF_FSPACE_SECT_SIMPLE \ - 0 /* For non-paged aggregation: section is a range of actual bytes in file \ - */ -#define H5MF_FSPACE_SECT_SMALL \ - 1 /* For paged aggregation: "small" meta/raw data section which is < fsp_size) */ -#define H5MF_FSPACE_SECT_LARGE 2 /* For paged aggregation: "large" Section which is >= fsp_size) */ +/* For non-paged aggregation: section is a range of actual bytes in file */ +#define H5MF_FSPACE_SECT_SIMPLE 0 +/* For paged aggregation: "small" meta/raw data section which is < fsp_size) */ +#define H5MF_FSPACE_SECT_SMALL 1 +/* For paged aggregation: "large" Section which is >= fsp_size) */ +#define H5MF_FSPACE_SECT_LARGE 2 /* Get section class type based on size */ #define H5MF_SECT_CLASS_TYPE(F, S) \ @@ -168,9 +168,9 @@ typedef struct H5MF_fs_t { /*****************************/ /* H5MF single section inherits serializable properties from H5FS_section_class_t */ -H5_DLLVAR H5FS_section_class_t H5MF_FSPACE_SECT_CLS_SIMPLE[1]; -H5_DLLVAR H5FS_section_class_t H5MF_FSPACE_SECT_CLS_SMALL[1]; -H5_DLLVAR H5FS_section_class_t H5MF_FSPACE_SECT_CLS_LARGE[1]; +H5_DLLVAR const H5FS_section_class_t H5MF_FSPACE_SECT_CLS_SIMPLE[1]; +H5_DLLVAR const H5FS_section_class_t H5MF_FSPACE_SECT_CLS_SMALL[1]; +H5_DLLVAR const H5FS_section_class_t H5MF_FSPACE_SECT_CLS_LARGE[1]; /******************************/ /* Package Private Prototypes */ @@ -191,6 +191,7 @@ H5_DLL herr_t H5MF__sect_free(H5FS_section_info_t *sect); /* Block aggregator routines */ H5_DLL htri_t H5MF__aggr_try_extend(H5F_t *f, H5F_blk_aggr_t *aggr, H5FD_mem_t type, haddr_t abs_blk_end, hsize_t extra_requested); +H5_DLL htri_t H5MF__aggrs_try_shrink_eoa(H5F_t *f); H5_DLL htri_t H5MF__aggr_can_absorb(const H5F_t *f, const H5F_blk_aggr_t *aggr, const H5MF_free_section_t *sect, H5MF_shrink_type_t *shrink); H5_DLL herr_t H5MF__aggr_absorb(const H5F_t *f, H5F_blk_aggr_t *aggr, H5MF_free_section_t *sect, diff --git a/src/H5MFprivate.h b/src/H5MFprivate.h index 084f213..81bf36d 100644 --- a/src/H5MFprivate.h +++ b/src/H5MFprivate.h @@ -65,7 +65,6 @@ herr_t H5MF_process_deferred_frees(H5F_t *, uint64_t); /* 'block aggregator' routines */ H5_DLL herr_t H5MF_free_aggrs(H5F_t *f); -H5_DLL htri_t H5MF_aggrs_try_shrink_eoa(H5F_t *f); /* Free space manager settling routines */ H5_DLL herr_t H5MF_settle_raw_data_fsm(H5F_t *f, hbool_t *fsm_settled); diff --git a/src/H5MFsection.c b/src/H5MFsection.c index 313a7ac..bbd02f4 100644 --- a/src/H5MFsection.c +++ b/src/H5MFsection.c @@ -12,7 +12,7 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* - * Programmer: Quincey Koziol <koziol@hdfgroup.org> + * Programmer: Quincey Koziol * Tuesday, January 8, 2008 * * Purpose: Free space section callbacks for file. @@ -81,7 +81,7 @@ static herr_t H5MF__sect_large_shrink(H5FS_section_info_t **_sect, void *udata); /*********************/ /* Class info for "simple" free space sections */ -H5FS_section_class_t H5MF_FSPACE_SECT_CLS_SIMPLE[1] = {{ +const H5FS_section_class_t H5MF_FSPACE_SECT_CLS_SIMPLE[1] = {{ /* Class variables */ H5MF_FSPACE_SECT_SIMPLE, /* Section type */ 0, /* Extra serialized size */ @@ -107,7 +107,7 @@ H5FS_section_class_t H5MF_FSPACE_SECT_CLS_SIMPLE[1] = {{ }}; /* Class info for "small" free space sections */ -H5FS_section_class_t H5MF_FSPACE_SECT_CLS_SMALL[1] = {{ +const H5FS_section_class_t H5MF_FSPACE_SECT_CLS_SMALL[1] = {{ /* Class variables */ H5MF_FSPACE_SECT_SMALL, /* Section type */ 0, /* Extra serialized size */ @@ -133,7 +133,7 @@ H5FS_section_class_t H5MF_FSPACE_SECT_CLS_SMALL[1] = {{ }}; /* Class info for "large" free space sections */ -H5FS_section_class_t H5MF_FSPACE_SECT_CLS_LARGE[1] = {{ +const H5FS_section_class_t H5MF_FSPACE_SECT_CLS_LARGE[1] = {{ /* Class variables */ H5MF_FSPACE_SECT_LARGE, /* Section type */ 0, /* Extra serialized size */ @@ -181,7 +181,6 @@ H5FL_DEFINE(H5MF_free_section_t); * Return: Pointer to new section on success/NULL on failure * * Programmer: Quincey Koziol - * koziol@hdfgroup.org * January 8 2008 * *------------------------------------------------------------------------- diff --git a/src/H5Mpublic.h b/src/H5Mpublic.h index 88db39a..3f6bf01 100644 --- a/src/H5Mpublic.h +++ b/src/H5Mpublic.h @@ -177,6 +177,13 @@ H5_DLL hid_t H5Mopen_async(const char *app_file, const char *app_func, unsigned * */ H5_DLL herr_t H5Mclose(hid_t map_id); +/** + * -------------------------------------------------------------------------- + * \ingroup ASYNC + * \async_variant_of{H5Mclose} + */ +H5_DLL herr_t H5Mclose_async(const char *app_file, const char *app_func, unsigned app_line, hid_t map_id, + hid_t es_id); /** * \ingroup H5M @@ -292,6 +299,14 @@ H5_DLL herr_t H5Mget_count(hid_t map_id, hsize_t *count, hid_t dxpl_id); */ H5_DLL herr_t H5Mput(hid_t map_id, hid_t key_mem_type_id, const void *key, hid_t val_mem_type_id, const void *value, hid_t dxpl_id); +/** + * -------------------------------------------------------------------------- + * \ingroup ASYNC + * \async_variant_of{H5Mput} + */ +H5_DLL herr_t H5Mput_async(const char *app_file, const char *app_func, unsigned app_line, hid_t map_id, + hid_t key_mem_type_id, const void *key, hid_t val_mem_type_id, const void *value, + hid_t dxpl_id, hid_t es_id); /** * \ingroup H5M @@ -325,6 +340,14 @@ H5_DLL herr_t H5Mput(hid_t map_id, hid_t key_mem_type_id, const void *key, hid_t */ H5_DLL herr_t H5Mget(hid_t map_id, hid_t key_mem_type_id, const void *key, hid_t val_mem_type_id, void *value, hid_t dxpl_id); +/** + * -------------------------------------------------------------------------- + * \ingroup ASYNC + * \async_variant_of{H5Mget} + */ +H5_DLL herr_t H5Mget_async(const char *app_file, const char *app_func, unsigned app_line, hid_t map_id, + hid_t key_mem_type_id, const void *key, hid_t val_mem_type_id, void *value, + hid_t dxpl_id, hid_t es_id); /** * \ingroup H5M @@ -455,6 +478,25 @@ H5_DLL herr_t H5Miterate_by_name(hid_t loc_id, const char *map_name, hsize_t *id */ H5_DLL herr_t H5Mdelete(hid_t map_id, hid_t key_mem_type_id, const void *key, hid_t dxpl_id); +/* API Wrappers for async routines */ +/* (Must be defined _after_ the function prototype) */ +/* (And must only defined when included in application code, not the library) */ +#ifndef H5M_MODULE +#define H5Mcreate_async(...) H5Mcreate_async(__FILE__, __func__, __LINE__, __VA_ARGS__) +#define H5Mopen_async(...) H5Mopen_async(__FILE__, __func__, __LINE__, __VA_ARGS__) +#define H5Mclose_async(...) H5Mclose_async(__FILE__, __func__, __LINE__, __VA_ARGS__) +#define H5Mput_async(...) H5Mput_async(__FILE__, __func__, __LINE__, __VA_ARGS__) +#define H5Mget_async(...) H5Mget_async(__FILE__, __func__, __LINE__, __VA_ARGS__) + +/* Define "wrapper" versions of function calls, to allow compile-time values to + * be passed in by language wrapper or library layer on top of HDF5. */ +#define H5Mcreate_async_wrap H5_NO_EXPAND(H5Mcreate_async) +#define H5Mopen_async_wrap H5_NO_EXPAND(H5Mopen_async) +#define H5Mclose_async_wrap H5_NO_EXPAND(H5Mclose_async) +#define H5Mput_async_wrap H5_NO_EXPAND(H5Mput_async) +#define H5Mget_async_wrap H5_NO_EXPAND(H5Mget_async) +#endif /* H5M_MODULE */ + /* Symbols defined for compatibility with previous versions of the HDF5 API. * * Use of these symbols is deprecated. @@ -32,6 +32,7 @@ #include "H5private.h" /* Generic Functions */ #include "H5CXprivate.h" /* API Contexts */ #include "H5Eprivate.h" /* Error handling */ +#include "H5ESprivate.h" /* Event Sets */ #include "H5Fprivate.h" /* File access */ #include "H5Iprivate.h" /* IDs */ #include "H5Lprivate.h" /* Links */ @@ -55,6 +56,22 @@ /* Local Prototypes */ /********************/ +/* Helper routines for sync/async API calls */ +static hid_t H5O__open_api_common(hid_t loc_id, const char *name, hid_t lapl_id, void **token_ptr, + H5VL_object_t **_vol_obj_ptr); +static hid_t H5O__open_by_idx_api_common(hid_t loc_id, const char *group_name, H5_index_t idx_type, + H5_iter_order_t order, hsize_t n, hid_t lapl_id, void **token_ptr, + H5VL_object_t **_vol_obj_ptr); +static herr_t H5O__get_info_by_name_api_common(hid_t loc_id, const char *name, H5O_info2_t *oinfo /*out*/, + unsigned fields, hid_t lapl_id, void **token_ptr, + H5VL_object_t **_vol_obj_ptr); +static herr_t H5O__copy_api_common(hid_t src_loc_id, const char *src_name, hid_t dst_loc_id, + const char *dst_name, hid_t ocpypl_id, hid_t lcpl_id, void **token_ptr, + H5VL_object_t **_vol_obj_ptr); +static herr_t H5O__flush_api_common(hid_t obj_id, void **token_ptr, H5VL_object_t **_vol_obj_ptr); +static herr_t H5O__refresh_api_common(hid_t oid, void **token_ptr, H5VL_object_t **_vol_obj_ptr); +static htri_t H5O__close_check_common(hid_t object_id); + /*********************/ /* Package Variables */ /*********************/ @@ -68,6 +85,50 @@ /*******************/ /*------------------------------------------------------------------------- + * Function: H5O__open_api_common + * + * Purpose: This is the common function for opening an object + * + * Return: Success: An open object identifier + * Failure: H5I_INVALID_HID + * + *------------------------------------------------------------------------- + */ +static hid_t +H5O__open_api_common(hid_t loc_id, const char *name, hid_t lapl_id, void **token_ptr, + H5VL_object_t **_vol_obj_ptr) +{ + H5VL_object_t * tmp_vol_obj = NULL; /* Object for loc_id */ + H5VL_object_t **vol_obj_ptr = + (_vol_obj_ptr ? _vol_obj_ptr : &tmp_vol_obj); /* Ptr to object ptr for loc_id */ + H5I_type_t opened_type; + void * opened_obj = NULL; + H5VL_loc_params_t loc_params; + hid_t ret_value = H5I_INVALID_HID; + + FUNC_ENTER_STATIC + + /* Check args */ + + /* name is checked in this H5VL_setup_name_args() */ + /* Set up object access arguments */ + if (H5VL_setup_name_args(loc_id, name, H5P_CLS_LACC, FALSE, lapl_id, vol_obj_ptr, &loc_params) < 0) + HGOTO_ERROR(H5E_OHDR, H5E_CANTSET, H5I_INVALID_HID, "can't set object access arguments") + + /* Open the object */ + if (NULL == (opened_obj = H5VL_object_open(*vol_obj_ptr, &loc_params, &opened_type, + H5P_DATASET_XFER_DEFAULT, token_ptr))) + HGOTO_ERROR(H5E_OHDR, H5E_CANTOPENOBJ, H5I_INVALID_HID, "unable to open object") + + /* Get an atom for the object */ + if ((ret_value = H5VL_register(opened_type, opened_obj, (*vol_obj_ptr)->connector, TRUE)) < 0) + HGOTO_ERROR(H5E_OHDR, H5E_CANTREGISTER, H5I_INVALID_HID, "unable to atomize object handle") + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* H5O__open_api_common() */ + +/*------------------------------------------------------------------------- * Function: H5Oopen * * Purpose: Opens an object within an HDF5 file. @@ -93,47 +154,107 @@ hid_t H5Oopen(hid_t loc_id, const char *name, hid_t lapl_id) { - H5VL_object_t * vol_obj; /* Object of loc_id */ - H5I_type_t opened_type; - void * opened_obj = NULL; - H5VL_loc_params_t loc_params; - hid_t ret_value = H5I_INVALID_HID; + hid_t ret_value = H5I_INVALID_HID; FUNC_ENTER_API(H5I_INVALID_HID) H5TRACE3("i", "i*si", loc_id, name, lapl_id); - /* Check args */ - if (!name) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, H5I_INVALID_HID, "name parameter cannot be NULL") - if (!*name) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, H5I_INVALID_HID, "name parameter cannot be an empty string") + /* Open the object synchronously */ + if ((ret_value = H5O__open_api_common(loc_id, name, lapl_id, NULL, NULL)) < 0) + HGOTO_ERROR(H5E_OHDR, H5E_CANTOPENOBJ, H5I_INVALID_HID, "unable to synchronously open object") - /* Verify access property list and set up collective metadata if appropriate */ - if (H5CX_set_apl(&lapl_id, H5P_CLS_LACC, loc_id, FALSE) < 0) - HGOTO_ERROR(H5E_OHDR, H5E_CANTSET, H5I_INVALID_HID, "can't set access property list info") +done: + FUNC_LEAVE_API(ret_value) +} /* end H5Oopen() */ - /* Get the location object */ - if (NULL == (vol_obj = (H5VL_object_t *)H5I_object(loc_id))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5I_INVALID_HID, "invalid location identifier") +/*------------------------------------------------------------------------- + * Function: H5Oopen_async + * + * Purpose: Asynchronous version of H5Oopen + * + * Return: Success: An open object identifier + * Failure: H5I_INVALID_HID + * + *------------------------------------------------------------------------- + */ +hid_t +H5Oopen_async(const char *app_file, const char *app_func, unsigned app_line, hid_t loc_id, const char *name, + hid_t lapl_id, hid_t es_id) +{ + H5VL_object_t *vol_obj = NULL; /* Object for loc_id */ + void * token = NULL; /* Request token for async operation */ + void ** token_ptr = H5_REQUEST_NULL; /* Pointer to request token for async operation */ + hid_t ret_value = H5I_INVALID_HID; /* Return value */ - /* Set location struct fields */ - loc_params.type = H5VL_OBJECT_BY_NAME; - loc_params.loc_data.loc_by_name.name = name; - loc_params.loc_data.loc_by_name.lapl_id = lapl_id; - loc_params.obj_type = H5I_get_type(loc_id); + FUNC_ENTER_API(H5I_INVALID_HID) + H5TRACE7("i", "*s*sIui*sii", app_file, app_func, app_line, loc_id, name, lapl_id, es_id); + + /* Set up request token pointer for asynchronous operation */ + if (H5ES_NONE != es_id) + token_ptr = &token; /* Point at token for VOL connector to set up */ + + /* Open the object asynchronously */ + if ((ret_value = H5O__open_api_common(loc_id, name, lapl_id, token_ptr, &vol_obj)) < 0) + HGOTO_ERROR(H5E_OHDR, H5E_CANTOPENOBJ, H5I_INVALID_HID, "unable to asynchronously open object") + + /* If a token was created, add the token to the event set */ + if (NULL != token) + /* clang-format off */ + if (H5ES_insert(es_id, vol_obj->connector, token, + H5ARG_TRACE7(FUNC, "*s*sIui*sii", app_file, app_func, app_line, loc_id, name, lapl_id, es_id)) < 0) { + /* clang-format on */ + if (H5I_dec_app_ref_always_close(ret_value) < 0) + HDONE_ERROR(H5E_OHDR, H5E_CANTDEC, H5I_INVALID_HID, "can't decrement count on object ID") + HGOTO_ERROR(H5E_OHDR, H5E_CANTINSERT, H5I_INVALID_HID, "can't insert token into event set") + } + +done: + FUNC_LEAVE_API(ret_value) +} /* end H5Oopen_async() */ + +/*------------------------------------------------------------------------- + * Function: H5O__open_by_idx_api_common + * + * Purpose: This is the common function for opening an object within an index + * + * Return: Success: An open object identifier + * Failure: H5I_INVALID_HID + * + *------------------------------------------------------------------------- + */ +static hid_t +H5O__open_by_idx_api_common(hid_t loc_id, const char *group_name, H5_index_t idx_type, H5_iter_order_t order, + hsize_t n, hid_t lapl_id, void **token_ptr, H5VL_object_t **_vol_obj_ptr) +{ + H5VL_object_t * tmp_vol_obj = NULL; /* Object for loc_id */ + H5VL_object_t **vol_obj_ptr = + (_vol_obj_ptr ? _vol_obj_ptr : &tmp_vol_obj); /* Ptr to object ptr for loc_id */ + H5I_type_t opened_type; + void * opened_obj = NULL; + H5VL_loc_params_t loc_params; + hid_t ret_value = H5I_INVALID_HID; + + FUNC_ENTER_STATIC + + /* Check args */ + /* group_name, idx_type, order are checked in H5VL_setup_idx-args() */ + /* Set up object access arguments */ + if (H5VL_setup_idx_args(loc_id, group_name, idx_type, order, n, H5P_CLS_LACC, FALSE, lapl_id, vol_obj_ptr, + &loc_params) < 0) + HGOTO_ERROR(H5E_LINK, H5E_CANTSET, H5I_INVALID_HID, "can't set object access arguments") /* Open the object */ - if (NULL == (opened_obj = H5VL_object_open(vol_obj, &loc_params, &opened_type, H5P_DATASET_XFER_DEFAULT, - H5_REQUEST_NULL))) + if (NULL == (opened_obj = H5VL_object_open(*vol_obj_ptr, &loc_params, &opened_type, + H5P_DATASET_XFER_DEFAULT, token_ptr))) HGOTO_ERROR(H5E_OHDR, H5E_CANTOPENOBJ, H5I_INVALID_HID, "unable to open object") - /* Get an atom for the object */ - if ((ret_value = H5VL_register(opened_type, opened_obj, vol_obj->connector, TRUE)) < 0) - HGOTO_ERROR(H5E_OHDR, H5E_CANTREGISTER, H5I_INVALID_HID, "unable to atomize object handle") + /* Get an ID for the object */ + if ((ret_value = H5VL_register(opened_type, opened_obj, (*vol_obj_ptr)->connector, TRUE)) < 0) + HGOTO_ERROR(H5E_OHDR, H5E_CANTREGISTER, H5I_INVALID_HID, "unable to register object handle") done: - FUNC_LEAVE_API(ret_value) -} /* end H5Oopen() */ + FUNC_LEAVE_NOAPI(ret_value) +} /* H5O__open_by_idx_api_common() */ /*------------------------------------------------------------------------- * Function: H5Oopen_by_idx @@ -162,50 +283,67 @@ hid_t H5Oopen_by_idx(hid_t loc_id, const char *group_name, H5_index_t idx_type, H5_iter_order_t order, hsize_t n, hid_t lapl_id) { - H5VL_object_t * vol_obj; /* Object of loc_id */ - H5I_type_t opened_type; - void * opened_obj = NULL; - H5VL_loc_params_t loc_params; - hid_t ret_value = H5I_INVALID_HID; + hid_t ret_value = H5I_INVALID_HID; FUNC_ENTER_API(H5I_INVALID_HID) H5TRACE6("i", "i*sIiIohi", loc_id, group_name, idx_type, order, n, lapl_id); - /* Check args */ - if (!group_name || !*group_name) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, H5I_INVALID_HID, "no name specified") - if (idx_type <= H5_INDEX_UNKNOWN || idx_type >= H5_INDEX_N) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, H5I_INVALID_HID, "invalid index type specified") - if (order <= H5_ITER_UNKNOWN || order >= H5_ITER_N) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, H5I_INVALID_HID, "invalid iteration order specified") - - /* Verify access property list and set up collective metadata if appropriate */ - if (H5CX_set_apl(&lapl_id, H5P_CLS_LACC, loc_id, FALSE) < 0) - HGOTO_ERROR(H5E_OHDR, H5E_CANTSET, H5I_INVALID_HID, "can't set access property list info") - - loc_params.type = H5VL_OBJECT_BY_IDX; - loc_params.loc_data.loc_by_idx.name = group_name; - loc_params.loc_data.loc_by_idx.idx_type = idx_type; - loc_params.loc_data.loc_by_idx.order = order; - loc_params.loc_data.loc_by_idx.n = n; - loc_params.loc_data.loc_by_idx.lapl_id = lapl_id; - loc_params.obj_type = H5I_get_type(loc_id); + /* Open the object synchronously */ + if ((ret_value = + H5O__open_by_idx_api_common(loc_id, group_name, idx_type, order, n, lapl_id, NULL, NULL)) < 0) + HGOTO_ERROR(H5E_OHDR, H5E_CANTOPENOBJ, H5I_INVALID_HID, "unable to synchronously open object") - /* get the location object */ - if (NULL == (vol_obj = (H5VL_object_t *)H5I_object(loc_id))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5I_INVALID_HID, "invalid location identifier") +done: + FUNC_LEAVE_API(ret_value) +} /* end H5Oopen_by_idx() */ - /* Open the object */ - if (NULL == (opened_obj = H5VL_object_open(vol_obj, &loc_params, &opened_type, H5P_DATASET_XFER_DEFAULT, - H5_REQUEST_NULL))) - HGOTO_ERROR(H5E_OHDR, H5E_CANTOPENOBJ, H5I_INVALID_HID, "unable to open object") +/*------------------------------------------------------------------------- + * Function: H5Oopen_by_idx_async + * + * Purpose: Asynchronous version of H5Oopen_by_idx + * + * Return: Success: An open object identifier + * Failure: H5I_INVALID_HID + * + *------------------------------------------------------------------------- + */ +hid_t +H5Oopen_by_idx_async(const char *app_file, const char *app_func, unsigned app_line, hid_t loc_id, + const char *group_name, H5_index_t idx_type, H5_iter_order_t order, hsize_t n, + hid_t lapl_id, hid_t es_id) +{ + H5VL_object_t *vol_obj = NULL; /* Object for loc_id */ + void * token = NULL; /* Request token for async operation */ + void ** token_ptr = H5_REQUEST_NULL; /* Pointer to request token for async operation */ + hid_t ret_value = H5I_INVALID_HID; /* Return value */ - if ((ret_value = H5VL_register(opened_type, opened_obj, vol_obj->connector, TRUE)) < 0) - HGOTO_ERROR(H5E_OHDR, H5E_CANTREGISTER, H5I_INVALID_HID, "unable to atomize object handle") + FUNC_ENTER_API(H5I_INVALID_HID) + H5TRACE10("i", "*s*sIui*sIiIohii", app_file, app_func, app_line, loc_id, group_name, idx_type, order, n, + lapl_id, es_id); + + /* Set up request token pointer for asynchronous operation */ + if (H5ES_NONE != es_id) + token_ptr = &token; /* Point at token for VOL connector to set up */ + + /* Open the object asynchronously */ + if ((ret_value = H5O__open_by_idx_api_common(loc_id, group_name, idx_type, order, n, lapl_id, token_ptr, + &vol_obj)) < 0) + HGOTO_ERROR(H5E_OHDR, H5E_CANTOPENOBJ, H5I_INVALID_HID, "unable to asynchronously open object") + + /* If a token was created, add the token to the event set */ + if (NULL != token) + /* clang-format off */ + if (H5ES_insert(es_id, vol_obj->connector, token, + H5ARG_TRACE10(FUNC, "*s*sIui*sIiIohii", app_file, app_func, app_line, loc_id, group_name, idx_type, order, n, lapl_id, es_id)) < 0) { + /* clang-format on */ + if (H5I_dec_app_ref_always_close(ret_value) < 0) + HDONE_ERROR(H5E_OHDR, H5E_CANTDEC, H5I_INVALID_HID, "can't decrement count on object ID") + HGOTO_ERROR(H5E_OHDR, H5E_CANTINSERT, H5I_INVALID_HID, "can't insert token into event set") + } done: FUNC_LEAVE_API(ret_value) -} /* end H5Oopen_by_idx() */ +} /* end H5Oopen_by_idx_async() */ /*------------------------------------------------------------------------- * Function: H5Oopen_by_token @@ -256,13 +394,418 @@ H5Oopen_by_token(hid_t loc_id, H5O_token_t token) /* Register the object's ID */ if ((ret_value = H5VL_register(opened_type, opened_obj, vol_obj->connector, TRUE)) < 0) - HGOTO_ERROR(H5E_OHDR, H5E_CANTREGISTER, H5I_INVALID_HID, "unable to atomize object handle") + HGOTO_ERROR(H5E_OHDR, H5E_CANTREGISTER, H5I_INVALID_HID, "unable to register object handle") done: FUNC_LEAVE_API(ret_value) } /* end H5Oopen_by_token() */ /*------------------------------------------------------------------------- + * Function: H5O__copy_api_common + * + * Purpose: This is the common function for copying an object. + * + * Return: SUCCEED/FAIL + * + *------------------------------------------------------------------------- + */ +static herr_t +H5O__copy_api_common(hid_t src_loc_id, const char *src_name, hid_t dst_loc_id, const char *dst_name, + hid_t ocpypl_id, hid_t lcpl_id, void **token_ptr, H5VL_object_t **_vol_obj_ptr) +{ + /* dst_id */ + H5VL_object_t * tmp_vol_obj = NULL; /* Object for loc_id */ + H5VL_object_t **vol_obj_ptr = + (_vol_obj_ptr ? _vol_obj_ptr : &tmp_vol_obj); /* Ptr to object ptr for loc_id */ + H5VL_loc_params_t loc_params2; + + /* src_id */ + H5VL_object_t * vol_obj1 = NULL; /* object of src_id */ + H5VL_loc_params_t loc_params1; + + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_STATIC + + /* Check arguments */ + if (!src_name || !*src_name) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no source name specified") + if (!dst_name || !*dst_name) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no destination name specified") + + /* Get correct property lists */ + if (H5P_DEFAULT == lcpl_id) + lcpl_id = H5P_LINK_CREATE_DEFAULT; + else if (TRUE != H5P_isa_class(lcpl_id, H5P_LINK_CREATE)) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not link creation property list") + + /* Get object copy property list */ + if (H5P_DEFAULT == ocpypl_id) + ocpypl_id = H5P_OBJECT_COPY_DEFAULT; + else if (TRUE != H5P_isa_class(ocpypl_id, H5P_OBJECT_COPY)) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not object copy property list") + + /* Set the LCPL for the API context */ + H5CX_set_lcpl(lcpl_id); + + if (H5VL_setup_loc_args(src_loc_id, &vol_obj1, &loc_params1) < 0) + HGOTO_ERROR(H5E_OHDR, H5E_CANTSET, FAIL, "can't set object access arguments") + + /* get the object */ + if (NULL == (*vol_obj_ptr = (H5VL_object_t *)H5I_object(dst_loc_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid location identifier") + loc_params2.type = H5VL_OBJECT_BY_SELF; + loc_params2.obj_type = H5I_get_type(dst_loc_id); + + /* Copy the object */ + if (H5VL_object_copy(vol_obj1, &loc_params1, src_name, *vol_obj_ptr, &loc_params2, dst_name, ocpypl_id, + lcpl_id, H5P_DATASET_XFER_DEFAULT, token_ptr) < 0) + HGOTO_ERROR(H5E_OHDR, H5E_CANTCOPY, FAIL, "unable to copy object") + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* H5O__copy_api_common() */ + +/*------------------------------------------------------------------------- + * Function: H5Ocopy + * + * Purpose: Copy an object (group or dataset) to destination location + * within a file or cross files. PLIST_ID is a property list + * which is used to pass user options and properties to the + * copy. The name, dst_name, must not already be taken by some + * other object in the destination group. + * + * H5Ocopy() will fail if the name of the destination object + * exists in the destination group. For example, + * H5Ocopy(fid_src, "/dset", fid_dst, "/dset", ...) + * will fail if "/dset" exists in the destination file + * + * OPTIONS THAT HAVE BEEN IMPLEMENTED. + * H5O_COPY_SHALLOW_HIERARCHY_FLAG + * If this flag is specified, only immediate members of + * the group are copied. Otherwise (default), it will + * recursively copy all objects below the group + * H5O_COPY_EXPAND_SOFT_LINK_FLAG + * If this flag is specified, it will copy the objects + * pointed by the soft links. Otherwise (default), it + * will copy the soft link as they are + * H5O_COPY_WITHOUT_ATTR_FLAG + * If this flag is specified, it will copy object without + * copying attributes. Otherwise (default), it will + * copy object along with all its attributes + * H5O_COPY_EXPAND_REFERENCE_FLAG + * 1) Copy object between two different files: + * When this flag is specified, it will copy objects that + * are pointed by the references and update the values of + * references in the destination file. Otherwise (default) + * the values of references in the destination will set to + * zero + * The current implementation does not handle references + * inside of other datatype structure. For example, if + * a member of compound datatype is reference, H5Ocopy() + * will copy that field as it is. It will not set the + * value to zero as default is used nor copy the object + * pointed by that field the flag is set + * 2) Copy object within the same file: + * This flag does not have any effect to the H5Ocopy(). + * Datasets or attributes of references are copied as they + * are, i.e. values of references of the destination object + * are the same as the values of the source object + * + * OPTIONS THAT MAY APPLY TO COPY IN THE FUTURE. + * H5O_COPY_EXPAND_EXT_LINK_FLAG + * If this flag is specified, it will expand the external links + * into new objects, Otherwise (default), it will keep external + * links as they are (default) + * + * PROPERTIES THAT MAY APPLY TO COPY IN FUTURE + * Change data layout such as chunk size + * Add filter such as data compression. + * Add an attribute to the copied object(s) that say the date/time + * for the copy or other information about the source file. + * + * The intermediate group creation property should be passed in + * using the lcpl instead of the ocpypl. + * + * Usage: H5Ocopy(src_loc_id, src_name, dst_loc_id, dst_name, ocpypl_id, lcpl_id) + * hid_t src_loc_id IN: Source file or group identifier. + * const char *src_name IN: Name of the source object to be copied + * hid_t dst_loc_id IN: Destination file or group identifier + * const char *dst_name IN: Name of the destination object + * hid_t ocpypl_id IN: Properties which apply to the copy + * hid_t lcpl_id IN: Properties which apply to the new hard link + * + * + * Return: SUCCEED/FAIL + * + *------------------------------------------------------------------------- + */ +herr_t +H5Ocopy(hid_t src_loc_id, const char *src_name, hid_t dst_loc_id, const char *dst_name, hid_t ocpypl_id, + hid_t lcpl_id) +{ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_API(FAIL) + H5TRACE6("e", "i*si*sii", src_loc_id, src_name, dst_loc_id, dst_name, ocpypl_id, lcpl_id); + + /* To copy an object synchronously */ + if (H5O__copy_api_common(src_loc_id, src_name, dst_loc_id, dst_name, ocpypl_id, lcpl_id, NULL, NULL) < 0) + HGOTO_ERROR(H5E_OHDR, H5E_CANTCOPY, FAIL, "unable to synchronously copy object") + +done: + FUNC_LEAVE_API(ret_value) +} /* end H5Ocopy() */ + +/*------------------------------------------------------------------------- + * Function: H5Ocopy_async + * + * Purpose: Asynchronous version of H5Ocopy + * + * Return: SUCCEED/FAIL + * + *------------------------------------------------------------------------- + */ +herr_t +H5Ocopy_async(const char *app_file, const char *app_func, unsigned app_line, hid_t src_loc_id, + const char *src_name, hid_t dst_loc_id, const char *dst_name, hid_t ocpypl_id, hid_t lcpl_id, + hid_t es_id) +{ + H5VL_object_t *vol_obj = NULL; /* Object for loc_id */ + void * token = NULL; /* Request token for async operation */ + void ** token_ptr = H5_REQUEST_NULL; /* Pointer to request token for async operation */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_API(FAIL) + H5TRACE10("e", "*s*sIui*si*siii", app_file, app_func, app_line, src_loc_id, src_name, dst_loc_id, + dst_name, ocpypl_id, lcpl_id, es_id); + + /* Set up request token pointer for asynchronous operation */ + if (H5ES_NONE != es_id) + token_ptr = &token; /* Point at token for VOL connector to set up */ + + /* To copy an object asynchronously */ + if (H5O__copy_api_common(src_loc_id, src_name, dst_loc_id, dst_name, ocpypl_id, lcpl_id, token_ptr, + &vol_obj) < 0) + HGOTO_ERROR(H5E_OHDR, H5E_CANTCOPY, FAIL, "unable to asynchronously copy object") + + /* If a token was created, add the token to the event set */ + if (NULL != token) + /* clang-format off */ + if (H5ES_insert(es_id, vol_obj->connector, token, + H5ARG_TRACE10(FUNC, "*s*sIui*si*siii", app_file, app_func, app_line, src_loc_id, src_name, dst_loc_id, dst_name, ocpypl_id, lcpl_id, es_id)) < 0) + /* clang-format on */ + HGOTO_ERROR(H5E_OHDR, H5E_CANTINSERT, FAIL, "can't insert token into event set") + +done: + FUNC_LEAVE_API(ret_value) +} /* H5Ocopy_async() */ + +/*------------------------------------------------------------------------- + * Function: H5O__flush_api_common + * + * Purpose: This is the common function for flushing an object. + * + * Return: SUCCEED/FAIL + * + *------------------------------------------------------------------------- + */ +static herr_t +H5O__flush_api_common(hid_t obj_id, void **token_ptr, H5VL_object_t **_vol_obj_ptr) +{ + H5VL_object_t * tmp_vol_obj = NULL; /* Object for loc_id */ + H5VL_object_t **vol_obj_ptr = + (_vol_obj_ptr ? _vol_obj_ptr : &tmp_vol_obj); /* Ptr to object ptr for loc_id */ + H5VL_loc_params_t loc_params; /* Location parameters for object access */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_STATIC + + /* Check args */ + + if (H5VL_setup_loc_args(obj_id, vol_obj_ptr, &loc_params) < 0) + HGOTO_ERROR(H5E_OHDR, H5E_CANTSET, FAIL, "can't set object access arguments") + + /* Flush the object */ + if (H5VL_object_specific(*vol_obj_ptr, &loc_params, H5VL_OBJECT_FLUSH, H5P_DATASET_XFER_DEFAULT, + token_ptr, obj_id) < 0) + HGOTO_ERROR(H5E_OHDR, H5E_CANTFLUSH, FAIL, "unable to flush object") + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* H5O__flush_api_common() */ + +/*------------------------------------------------------------------------- + * Function: H5Oflush + * + * Purpose: Flushes all buffers associated with an object to disk. + * + * Return: Non-negative on success, negative on failure + * + * Programmer: Mike McGreevy + * May 19, 2010 + * + *------------------------------------------------------------------------- + */ +herr_t +H5Oflush(hid_t obj_id) +{ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_API(FAIL) + H5TRACE1("e", "i", obj_id); + + /* To flush an object synchronously */ + if (H5O__flush_api_common(obj_id, NULL, NULL) < 0) + HGOTO_ERROR(H5E_OHDR, H5E_CANTFLUSH, FAIL, "unable to synchronously flush object") + +done: + FUNC_LEAVE_API(ret_value) +} /* end H5Oflush() */ + +/*------------------------------------------------------------------------- + * Function: H5Oflush_async + * + * Purpose: Asynchronous version of H5Oflush + * + * Return: SUCCEED/FAIL + * + *------------------------------------------------------------------------- + */ +herr_t +H5Oflush_async(const char *app_file, const char *app_func, unsigned app_line, hid_t obj_id, hid_t es_id) +{ + H5VL_object_t *vol_obj = NULL; /* Object for loc_id */ + void * token = NULL; /* Request token for async operation */ + void ** token_ptr = H5_REQUEST_NULL; /* Pointer to request token for async operation */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_API(FAIL) + H5TRACE5("e", "*s*sIuii", app_file, app_func, app_line, obj_id, es_id); + + /* Set up request token pointer for asynchronous operation */ + if (H5ES_NONE != es_id) + token_ptr = &token; /* Point at token for VOL connector to set up */ + + /* Flush an object asynchronously */ + if (H5O__flush_api_common(obj_id, token_ptr, &vol_obj) < 0) + HGOTO_ERROR(H5E_OHDR, H5E_CANTFLUSH, FAIL, "unable to asynchronously flush object") + + /* If a token was created, add the token to the event set */ + if (NULL != token) + /* clang-format off */ + if (H5ES_insert(es_id, vol_obj->connector, token, + H5ARG_TRACE5(FUNC, "*s*sIuii", app_file, app_func, app_line, obj_id, es_id)) < 0) + /* clang-format on */ + HGOTO_ERROR(H5E_OHDR, H5E_CANTINSERT, FAIL, "can't insert token into event set") + +done: + FUNC_LEAVE_API(ret_value) +} /* H5Oflush_async() */ + +/*------------------------------------------------------------------------- + * Function: H5O__refresh_api_common + * + * Purpose: This is the common function for refreshing an object. + * + * Return: SUCCEED/FAIL + * + *------------------------------------------------------------------------- + */ +static herr_t +H5O__refresh_api_common(hid_t oid, void **token_ptr, H5VL_object_t **_vol_obj_ptr) +{ + H5VL_object_t * tmp_vol_obj = NULL; /* Object for loc_id */ + H5VL_object_t **vol_obj_ptr = + (_vol_obj_ptr ? _vol_obj_ptr : &tmp_vol_obj); /* Ptr to object ptr for loc_id */ + H5VL_loc_params_t loc_params; /* Location parameters for object access */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_STATIC + + /* Check args */ + + if (H5VL_setup_loc_args(oid, vol_obj_ptr, &loc_params) < 0) + HGOTO_ERROR(H5E_OHDR, H5E_CANTSET, FAIL, "can't set object access arguments") + + /* Refresh the object */ + if (H5VL_object_specific(*vol_obj_ptr, &loc_params, H5VL_OBJECT_REFRESH, H5P_DATASET_XFER_DEFAULT, + token_ptr, oid) < 0) + HGOTO_ERROR(H5E_OHDR, H5E_CANTLOAD, FAIL, "unable to refresh object") + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* H5O__refresh_api_common() */ + +/*------------------------------------------------------------------------- + * Function: H5Orefresh + * + * Purpose: Refreshes all buffers associated with an object. + * + * Return: Non-negative on success, negative on failure + * + * Programmer: Mike McGreevy + * July 28, 2010 + * + *------------------------------------------------------------------------- + */ +herr_t +H5Orefresh(hid_t oid) +{ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_API(FAIL) + H5TRACE1("e", "i", oid); + + /* To refresh an object synchronously */ + if (H5O__refresh_api_common(oid, NULL, NULL) < 0) + HGOTO_ERROR(H5E_OHDR, H5E_CANTLOAD, FAIL, "unable to synchronously refresh object") + +done: + FUNC_LEAVE_API(ret_value) +} /* end H5Orefresh() */ + +/*------------------------------------------------------------------------- + * Function: H5Orefresh_async + * + * Purpose: Asynchronous version of H5Orefresh + * + * Return: SUCCEED/FAIL + * + *------------------------------------------------------------------------- + */ +herr_t +H5Orefresh_async(const char *app_file, const char *app_func, unsigned app_line, hid_t oid, hid_t es_id) +{ + H5VL_object_t *vol_obj = NULL; /* Object for loc_id */ + void * token = NULL; /* Request token for async operation */ + void ** token_ptr = H5_REQUEST_NULL; /* Pointer to request token for async operation */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_API(FAIL) + H5TRACE5("e", "*s*sIuii", app_file, app_func, app_line, oid, es_id); + + /* Set up request token pointer for asynchronous operation */ + if (H5ES_NONE != es_id) + token_ptr = &token; /* Point at token for VOL connector to set up */ + + /* Refresh an object asynchronously */ + if (H5O__refresh_api_common(oid, token_ptr, &vol_obj) < 0) + HGOTO_ERROR(H5E_OHDR, H5E_CANTLOAD, FAIL, "unable to asynchronously refresh object") + + /* If a token was created, add the token to the event set */ + if (NULL != token) + /* clang-format off */ + if (H5ES_insert(es_id, vol_obj->connector, token, + H5ARG_TRACE5(FUNC, "*s*sIuii", app_file, app_func, app_line, oid, es_id)) < 0) + /* clang-format on */ + HGOTO_ERROR(H5E_OHDR, H5E_CANTINSERT, FAIL, "can't insert token into event set") + +done: + FUNC_LEAVE_API(ret_value) +} /* H5Orefresh_async() */ + +/*------------------------------------------------------------------------- * Function: H5Olink * * Purpose: Creates a hard link from NEW_NAME to the object specified @@ -522,14 +1065,14 @@ done: *------------------------------------------------------------------------- */ herr_t -H5Oget_info3(hid_t loc_id, H5O_info2_t *oinfo, unsigned fields) +H5Oget_info3(hid_t loc_id, H5O_info2_t *oinfo /*out*/, unsigned fields) { H5VL_object_t * vol_obj; /* Object of loc_id */ H5VL_loc_params_t loc_params; herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API(FAIL) - H5TRACE3("e", "i*!Iu", loc_id, oinfo, fields); + H5TRACE3("e", "ixIu", loc_id, oinfo, fields); /* Check args */ if (!oinfo) @@ -555,61 +1098,121 @@ done: } /* end H5Oget_info3() */ /*------------------------------------------------------------------------- - * Function: H5Oget_info_by_name3 + * Function: H5O__get_info_by_name_api_common * - * Purpose: Retrieve information about an object + * Purpose: This is the common function for retrieving information + * about an object. * * Return: SUCCEED/FAIL * - * Programmer: Dana Robinson - * Fall 2019 - * *------------------------------------------------------------------------- */ -herr_t -H5Oget_info_by_name3(hid_t loc_id, const char *name, H5O_info2_t *oinfo, unsigned fields, hid_t lapl_id) +static herr_t +H5O__get_info_by_name_api_common(hid_t loc_id, const char *name, H5O_info2_t *oinfo /*out*/, unsigned fields, + hid_t lapl_id, void **token_ptr, H5VL_object_t **_vol_obj_ptr) { - H5VL_object_t * vol_obj; /* Object of loc_id */ - H5VL_loc_params_t loc_params; - herr_t ret_value = SUCCEED; /* Return value */ + H5VL_object_t * tmp_vol_obj = NULL; /* Object for loc_id */ + H5VL_object_t **vol_obj_ptr = + (_vol_obj_ptr ? _vol_obj_ptr : &tmp_vol_obj); /* Ptr to object ptr for loc_id */ + H5VL_loc_params_t loc_params; /* Location parameters for object access */ + herr_t ret_value = SUCCEED; /* Return value */ - FUNC_ENTER_API(FAIL) - H5TRACE5("e", "i*s*!Iui", loc_id, name, oinfo, fields, lapl_id); + FUNC_ENTER_STATIC /* Check args */ - if (!name) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "name parameter cannot be NULL") - if (!*name) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "name parameter cannot be an empty string") if (!oinfo) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "oinfo parameter cannot be NULL") if (fields & ~H5O_INFO_ALL) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid fields") - /* Verify access property list and set up collective metadata if appropriate */ - if (H5CX_set_apl(&lapl_id, H5P_CLS_LACC, loc_id, FALSE) < 0) - HGOTO_ERROR(H5E_OHDR, H5E_CANTSET, FAIL, "can't set access property list info") - - /* Fill out location struct */ - loc_params.type = H5VL_OBJECT_BY_NAME; - loc_params.loc_data.loc_by_name.name = name; - loc_params.loc_data.loc_by_name.lapl_id = lapl_id; - loc_params.obj_type = H5I_get_type(loc_id); - - /* Get the location object */ - if (NULL == (vol_obj = H5VL_vol_object(loc_id))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid location identifier") + /* "name" is checked in H5VL_setup_name_args() */ + /* Set up object access arguments */ + if (H5VL_setup_name_args(loc_id, name, H5P_CLS_LACC, FALSE, lapl_id, vol_obj_ptr, &loc_params) < 0) + HGOTO_ERROR(H5E_OHDR, H5E_CANTSET, FAIL, "can't set object access arguments") /* Retrieve the object's information */ - if (H5VL_object_get(vol_obj, &loc_params, H5VL_OBJECT_GET_INFO, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL, + if (H5VL_object_get(*vol_obj_ptr, &loc_params, H5VL_OBJECT_GET_INFO, H5P_DATASET_XFER_DEFAULT, token_ptr, oinfo, fields) < 0) HGOTO_ERROR(H5E_OHDR, H5E_CANTGET, FAIL, "can't get data model info for object") done: + FUNC_LEAVE_NOAPI(ret_value) +} /* H5O__get_info_by_name_api_common() */ + +/*------------------------------------------------------------------------- + * Function: H5Oget_info_by_name3 + * + * Purpose: Retrieve information about an object + * + * Return: SUCCEED/FAIL + * + * Programmer: Dana Robinson + * Fall 2019 + * + *------------------------------------------------------------------------- + */ +herr_t +H5Oget_info_by_name3(hid_t loc_id, const char *name, H5O_info2_t *oinfo /*out*/, unsigned fields, + hid_t lapl_id) +{ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_API(FAIL) + H5TRACE5("e", "i*sxIui", loc_id, name, oinfo, fields, lapl_id); + + /* Retrieve object information synchronously */ + if (H5O__get_info_by_name_api_common(loc_id, name, oinfo, fields, lapl_id, NULL, NULL) < 0) + HGOTO_ERROR(H5E_OHDR, H5E_CANTGET, FAIL, "can't synchronously retrieve object info") + +done: FUNC_LEAVE_API(ret_value) } /* end H5Oget_info_by_name3() */ /*------------------------------------------------------------------------- + * Function: H5Oget_info_by_name_async + * + * Purpose: Asynchronous version of H5Oget_info_by_name3 + * + * Return: SUCCEED/FAIL + * + *------------------------------------------------------------------------- + */ +herr_t +H5Oget_info_by_name_async(const char *app_file, const char *app_func, unsigned app_line, hid_t loc_id, + const char *name, H5O_info2_t *oinfo /*out*/, unsigned fields, hid_t lapl_id, + hid_t es_id) +{ + H5VL_object_t *vol_obj = NULL; /* Object for loc_id */ + void * token = NULL; /* Request token for async operation */ + void ** token_ptr = H5_REQUEST_NULL; /* Pointer to request token for async operation */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_API(FAIL) + /* clang-format off */ + H5TRACE9("e", "*s*sIui*sxIuii", app_file, app_func, app_line, loc_id, name, oinfo, fields, lapl_id, es_id); + /* clang-format on */ + + /* Set up request token pointer for asynchronous operation */ + if (H5ES_NONE != es_id) + token_ptr = &token; /* Point at token for VOL connector to set up */ + + /* Retrieve group information asynchronously */ + if (H5O__get_info_by_name_api_common(loc_id, name, oinfo, fields, lapl_id, token_ptr, &vol_obj) < 0) + HGOTO_ERROR(H5E_OHDR, H5E_CANTGET, FAIL, "can't asynchronously retrieve object info") + + /* If a token was created, add the token to the event set */ + if (NULL != token) + /* clang-format off */ + if (H5ES_insert(es_id, vol_obj->connector, token, + H5ARG_TRACE9(FUNC, "*s*sIui*sxIuii", app_file, app_func, app_line, loc_id, name, oinfo, fields, lapl_id, es_id)) < 0) + /* clang-format on */ + HGOTO_ERROR(H5E_OHDR, H5E_CANTINSERT, FAIL, "can't insert token into event set") + +done: + FUNC_LEAVE_API(ret_value) +} /* H5Oget_info_by_name_async() */ + +/*------------------------------------------------------------------------- * Function: H5Oget_info_by_idx3 * * Purpose: Retrieve information about an object, according to @@ -625,14 +1228,14 @@ done: */ herr_t H5Oget_info_by_idx3(hid_t loc_id, const char *group_name, H5_index_t idx_type, H5_iter_order_t order, - hsize_t n, H5O_info2_t *oinfo, unsigned fields, hid_t lapl_id) + hsize_t n, H5O_info2_t *oinfo /*out*/, unsigned fields, hid_t lapl_id) { H5VL_object_t * vol_obj; /* Object of loc_id */ H5VL_loc_params_t loc_params; herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API(FAIL) - H5TRACE8("e", "i*sIiIoh*!Iui", loc_id, group_name, idx_type, order, n, oinfo, fields, lapl_id); + H5TRACE8("e", "i*sIiIohxIui", loc_id, group_name, idx_type, order, n, oinfo, fields, lapl_id); /* Check args */ if (!group_name || !*group_name) @@ -684,14 +1287,14 @@ done: *------------------------------------------------------------------------- */ herr_t -H5Oget_native_info(hid_t loc_id, H5O_native_info_t *oinfo, unsigned fields) +H5Oget_native_info(hid_t loc_id, H5O_native_info_t *oinfo /*out*/, unsigned fields) { H5VL_object_t * vol_obj; /* Object of loc_id */ H5VL_loc_params_t loc_params; herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API(FAIL) - H5TRACE3("e", "i*!Iu", loc_id, oinfo, fields); + H5TRACE3("e", "ixIu", loc_id, oinfo, fields); /* Check args */ if (!oinfo) @@ -729,7 +1332,7 @@ done: *------------------------------------------------------------------------- */ herr_t -H5Oget_native_info_by_name(hid_t loc_id, const char *name, H5O_native_info_t *oinfo, unsigned fields, +H5Oget_native_info_by_name(hid_t loc_id, const char *name, H5O_native_info_t *oinfo /*out*/, unsigned fields, hid_t lapl_id) { H5VL_object_t * vol_obj; /* Object of loc_id */ @@ -737,7 +1340,7 @@ H5Oget_native_info_by_name(hid_t loc_id, const char *name, H5O_native_info_t *oi herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API(FAIL) - H5TRACE5("e", "i*s*!Iui", loc_id, name, oinfo, fields, lapl_id); + H5TRACE5("e", "i*sxIui", loc_id, name, oinfo, fields, lapl_id); /* Check args */ if (!name) @@ -788,14 +1391,14 @@ done: */ herr_t H5Oget_native_info_by_idx(hid_t loc_id, const char *group_name, H5_index_t idx_type, H5_iter_order_t order, - hsize_t n, H5O_native_info_t *oinfo, unsigned fields, hid_t lapl_id) + hsize_t n, H5O_native_info_t *oinfo /*out*/, unsigned fields, hid_t lapl_id) { H5VL_object_t * vol_obj; /* Object of loc_id */ H5VL_loc_params_t loc_params; herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API(FAIL) - H5TRACE8("e", "i*sIiIoh*!Iui", loc_id, group_name, idx_type, order, n, oinfo, fields, lapl_id); + H5TRACE8("e", "i*sIiIohxIui", loc_id, group_name, idx_type, order, n, oinfo, fields, lapl_id); /* Check args */ if (!group_name || !*group_name) @@ -953,14 +1556,14 @@ done: *------------------------------------------------------------------------- */ ssize_t -H5Oget_comment(hid_t obj_id, char *comment, size_t bufsize) +H5Oget_comment(hid_t obj_id, char *comment /*out*/, size_t bufsize) { H5VL_object_t * vol_obj; /* Object of loc_id */ H5VL_loc_params_t loc_params; ssize_t ret_value = -1; /* Return value */ FUNC_ENTER_API((-1)) - H5TRACE3("Zs", "i*sz", obj_id, comment, bufsize); + H5TRACE3("Zs", "ixz", obj_id, comment, bufsize); /* Get the object */ if (NULL == (vol_obj = H5VL_vol_object(obj_id))) @@ -996,14 +1599,14 @@ done: *------------------------------------------------------------------------- */ ssize_t -H5Oget_comment_by_name(hid_t loc_id, const char *name, char *comment, size_t bufsize, hid_t lapl_id) +H5Oget_comment_by_name(hid_t loc_id, const char *name, char *comment /*out*/, size_t bufsize, hid_t lapl_id) { H5VL_object_t * vol_obj; /* Object of loc_id */ H5VL_loc_params_t loc_params; ssize_t ret_value = -1; /* Return value */ FUNC_ENTER_API((-1)) - H5TRACE5("Zs", "i*s*szi", loc_id, name, comment, bufsize, lapl_id); + H5TRACE5("Zs", "i*sxzi", loc_id, name, comment, bufsize, lapl_id); /* Check args */ if (!name || !*name) @@ -1191,29 +1794,21 @@ done: } /* end H5Ovisit_by_name3() */ /*------------------------------------------------------------------------- - * Function: H5Oclose - * - * Purpose: Close an open file object. - * - * This is the companion to H5Oopen. It is used to close any - * open object in an HDF5 file (but not IDs are that not file - * objects, such as property lists and dataspaces). It has - * the same effect as calling H5Gclose, H5Dclose, or H5Tclose. + * Function: H5O__close_check_common * - * Return: SUCCEED/FAIL + * Purpose: This is the common function to validate an object + * when closing it. * - * Programmer: James Laird - * July 14 2006 + * Return: TRUE/FALSE/FAIL * *------------------------------------------------------------------------- */ -herr_t -H5Oclose(hid_t object_id) +static htri_t +H5O__close_check_common(hid_t object_id) { - herr_t ret_value = SUCCEED; + htri_t ret_value = TRUE; /* Return value */ - FUNC_ENTER_API(FAIL) - H5TRACE1("e", "i", object_id); + FUNC_ENTER_STATIC /* Get the type of the object and close it in the correct way */ switch (H5I_get_type(object_id)) { @@ -1223,8 +1818,6 @@ H5Oclose(hid_t object_id) case H5I_MAP: if (H5I_object(object_id) == NULL) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "not a valid object") - if (H5I_dec_app_ref(object_id) < 0) - HGOTO_ERROR(H5E_OHDR, H5E_CANTRELEASE, FAIL, "unable to close object") break; case H5I_UNINIT: @@ -1240,18 +1833,116 @@ H5Oclose(hid_t object_id) case H5I_ERROR_MSG: case H5I_ERROR_STACK: case H5I_SPACE_SEL_ITER: + case H5I_EVENTSET: case H5I_NTYPES: default: - HGOTO_ERROR(H5E_ARGS, H5E_CANTRELEASE, FAIL, + HGOTO_ERROR(H5E_ARGS, H5E_CANTRELEASE, FALSE, "not a valid file object ID (dataset, group, or datatype)") break; } /* end switch */ done: + FUNC_LEAVE_NOAPI(ret_value) +} /* H5O__close_check_common() */ + +/*------------------------------------------------------------------------- + * Function: H5Oclose + * + * Purpose: Close an open file object. + * + * This is the companion to H5Oopen. It is used to close any + * open object in an HDF5 file (but not IDs are that not file + * objects, such as property lists and dataspaces). It has + * the same effect as calling H5Gclose, H5Dclose, or H5Tclose. + * + * Return: SUCCEED/FAIL + * + * Programmer: James Laird + * July 14 2006 + * + *------------------------------------------------------------------------- + */ +herr_t +H5Oclose(hid_t object_id) +{ + herr_t ret_value = SUCCEED; + + FUNC_ENTER_API(FAIL) + H5TRACE1("e", "i", object_id); + + /* Validate the object type before closing */ + if (H5O__close_check_common(object_id) <= 0) + HGOTO_ERROR(H5E_OHDR, H5E_CANTRELEASE, FAIL, "not a valid object") + + if (H5I_dec_app_ref(object_id) < 0) + HGOTO_ERROR(H5E_OHDR, H5E_CANTRELEASE, FAIL, "unable to close object") + +done: FUNC_LEAVE_API(ret_value) } /* end H5Oclose() */ /*------------------------------------------------------------------------- + * Function: H5Oclose_async + * + * Purpose: Asynchronous version of H5Oclose + * + * Return: SUCCEED/FAIL + * + *------------------------------------------------------------------------- + */ +herr_t +H5Oclose_async(const char *app_file, const char *app_func, unsigned app_line, hid_t object_id, hid_t es_id) +{ + H5VL_object_t *vol_obj = NULL; /* Object for loc_id */ + H5VL_t * connector = NULL; /* VOL connector */ + void * token = NULL; /* Request token for async operation */ + void ** token_ptr = H5_REQUEST_NULL; /* Pointer to request token for async operation */ + herr_t ret_value = SUCCEED; + + FUNC_ENTER_API(FAIL) + H5TRACE5("e", "*s*sIuii", app_file, app_func, app_line, object_id, es_id); + + /* Validate the object type before closing */ + if (H5O__close_check_common(object_id) <= 0) + HGOTO_ERROR(H5E_OHDR, H5E_CANTRELEASE, FAIL, "not a valid object") + + /* Prepare for possible asynchronous operation */ + if (H5ES_NONE != es_id) { + /* Get file object's connector */ + if (NULL == (vol_obj = H5VL_vol_object(object_id))) + HGOTO_ERROR(H5E_OHDR, H5E_CANTGET, FAIL, "can't get VOL object for object") + + /* Increase connector's refcount, so it doesn't get closed if closing + * this object ID closes the file */ + connector = vol_obj->connector; + H5VL_conn_inc_rc(connector); + + /* Point at token for operation to set up */ + token_ptr = &token; + } /* end if */ + + /* Asynchronously decrement reference count on ID. + * When it reaches zero the object will be closed. + */ + if (H5I_dec_app_ref_async(object_id, token_ptr) < 0) + HGOTO_ERROR(H5E_OHDR, H5E_CANTCLOSEFILE, FAIL, "decrementing object ID failed") + + /* If a token was created, add the token to the event set */ + if (NULL != token) + /* clang-format off */ + if (H5ES_insert(es_id, vol_obj->connector, token, + H5ARG_TRACE5(FUNC, "*s*sIuii", app_file, app_func, app_line, object_id, es_id)) < 0) + /* clang-format on */ + HGOTO_ERROR(H5E_OHDR, H5E_CANTINSERT, FAIL, "can't insert token into event set") + +done: + if (connector && H5VL_conn_dec_rc(connector) < 0) + HDONE_ERROR(H5E_OHDR, H5E_CANTDEC, FAIL, "can't decrement ref count on connector") + + FUNC_LEAVE_API(ret_value) +} /* end H5Oclose_async() */ + +/*------------------------------------------------------------------------- * Function: H5O_disable_mdc_flushes * * Purpose: Private version of the metadata cache cork function. @@ -1496,7 +2187,7 @@ H5Otoken_cmp(hid_t loc_id, const H5O_token_t *token1, const H5O_token_t *token2, /* Compare the two tokens */ if (H5VL_token_cmp(vol_obj, token1, token2, cmp_value) < 0) - HGOTO_ERROR(H5E_VOL, H5E_CANTCOMPARE, FAIL, "object token comparison failed") + HGOTO_ERROR(H5E_OHDR, H5E_CANTCOMPARE, FAIL, "object token comparison failed") done: FUNC_LEAVE_API(ret_value) @@ -1532,11 +2223,11 @@ H5Otoken_to_str(hid_t loc_id, const H5O_token_t *token, char **token_str) /* Get object type */ if ((vol_obj_type = H5I_get_type(loc_id)) < 0) - HGOTO_ERROR(H5E_VOL, H5E_CANTGET, FAIL, "can't get underlying VOL object type") + HGOTO_ERROR(H5E_OHDR, H5E_CANTGET, FAIL, "can't get underlying VOL object type") /* Serialize the token */ if (H5VL_token_to_str(vol_obj, vol_obj_type, token, token_str) < 0) - HGOTO_ERROR(H5E_VOL, H5E_CANTSERIALIZE, FAIL, "object token serialization failed") + HGOTO_ERROR(H5E_OHDR, H5E_CANTSERIALIZE, FAIL, "object token serialization failed") done: FUNC_LEAVE_API(ret_value) @@ -1572,11 +2263,11 @@ H5Otoken_from_str(hid_t loc_id, const char *token_str, H5O_token_t *token) /* Get object type */ if ((vol_obj_type = H5I_get_type(loc_id)) < 0) - HGOTO_ERROR(H5E_VOL, H5E_CANTGET, FAIL, "can't get underlying VOL object type") + HGOTO_ERROR(H5E_OHDR, H5E_CANTGET, FAIL, "can't get underlying VOL object type") /* Deserialize the token */ if (H5VL_token_from_str(vol_obj, vol_obj_type, token_str, token) < 0) - HGOTO_ERROR(H5E_VOL, H5E_CANTUNSERIALIZE, FAIL, "object token deserialization failed") + HGOTO_ERROR(H5E_OHDR, H5E_CANTUNSERIALIZE, FAIL, "object token deserialization failed") done: FUNC_LEAVE_API(ret_value) diff --git a/src/H5Oattribute.c b/src/H5Oattribute.c index 4adfaf7..0fc4cc6 100644 --- a/src/H5Oattribute.c +++ b/src/H5Oattribute.c @@ -93,6 +93,15 @@ typedef struct { hbool_t found; /* Found attribute to delete */ } H5O_iter_rm_t; +/* User data for iteration when checking if an attribute exists */ +typedef struct { + /* down */ + const char *name; /* Name of attribute to open */ + + /* up */ + hbool_t *exists; /* Pointer to flag to indicate attribute exists */ +} H5O_iter_xst_t; + /********************/ /* Package Typedefs */ /********************/ @@ -1723,19 +1732,19 @@ static herr_t H5O__attr_exists_cb(H5O_t H5_ATTR_UNUSED *oh, H5O_mesg_t *mesg /*in,out*/, unsigned H5_ATTR_UNUSED sequence, unsigned H5_ATTR_UNUSED *oh_modified, void *_udata /*in,out*/) { - H5O_iter_rm_t *udata = (H5O_iter_rm_t *)_udata; /* Operator user data */ - herr_t ret_value = H5_ITER_CONT; /* Return value */ + H5O_iter_xst_t *udata = (H5O_iter_xst_t *)_udata; /* Operator user data */ + herr_t ret_value = H5_ITER_CONT; /* Return value */ FUNC_ENTER_STATIC_NOERR /* check args */ HDassert(mesg); - HDassert(!udata->found); + HDassert(udata->exists && !*udata->exists); /* Check for correct attribute message */ if (HDstrcmp(((H5A_t *)mesg->native)->shared->name, udata->name) == 0) { /* Indicate that this message is the attribute sought */ - udata->found = TRUE; + *udata->exists = TRUE; /* Stop iterating */ ret_value = H5_ITER_STOP; @@ -1756,18 +1765,19 @@ H5O__attr_exists_cb(H5O_t H5_ATTR_UNUSED *oh, H5O_mesg_t *mesg /*in,out*/, unsig * *------------------------------------------------------------------------- */ -htri_t -H5O__attr_exists(const H5O_loc_t *loc, const char *name) +herr_t +H5O__attr_exists(const H5O_loc_t *loc, const char *name, hbool_t *attr_exists) { - H5O_t * oh = NULL; /* Pointer to actual object header */ - H5O_ainfo_t ainfo; /* Attribute information for object */ - htri_t ret_value = FAIL; /* Return value */ + H5O_t * oh = NULL; /* Pointer to actual object header */ + H5O_ainfo_t ainfo; /* Attribute information for object */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_PACKAGE_TAG(loc->addr) /* Check arguments */ HDassert(loc); HDassert(name); + HDassert(attr_exists); /* Protect the object header to iterate over */ if (NULL == (oh = H5O_protect(loc, H5AC__READ_ONLY_FLAG, FALSE))) @@ -1784,26 +1794,22 @@ H5O__attr_exists(const H5O_loc_t *loc, const char *name) /* Check for attributes stored densely */ if (H5F_addr_defined(ainfo.fheap_addr)) { /* Check if attribute exists in dense storage */ - if ((ret_value = H5A__dense_exists(loc->file, &ainfo, name)) < 0) + if (H5A__dense_exists(loc->file, &ainfo, name, attr_exists) < 0) HGOTO_ERROR(H5E_ATTR, H5E_BADITER, FAIL, "error checking for existence of attribute") } /* end if */ else { - H5O_iter_rm_t udata; /* User data for callback */ + H5O_iter_xst_t udata; /* User data for callback */ H5O_mesg_operator_t op; /* Wrapper for operator */ /* Set up user data for callback */ - udata.f = loc->file; - udata.name = name; - udata.found = FALSE; + udata.name = name; + udata.exists = attr_exists; /* Iterate over existing attributes, checking for attribute with same name */ op.op_type = H5O_MESG_OP_LIB; op.u.lib_op = H5O__attr_exists_cb; if (H5O__msg_iterate_real(loc->file, oh, H5O_MSG_ATTR, &op, &udata) < 0) HGOTO_ERROR(H5E_ATTR, H5E_BADITER, FAIL, "error checking for existence of attribute") - - /* Check that we found the attribute */ - ret_value = (htri_t)udata.found; } /* end else */ done: diff --git a/src/H5Ochunk.c b/src/H5Ochunk.c index 6e31668..eadbb19 100644 --- a/src/H5Ochunk.c +++ b/src/H5Ochunk.c @@ -412,7 +412,7 @@ H5O__chunk_dest(H5O_chunk_proxy_t *chk_proxy) HDassert(chk_proxy); /* Decrement reference count of object header */ - if (chk_proxy->oh && H5O__dec_rc(chk_proxy->oh) < 0) + if (H5O__dec_rc(chk_proxy->oh) < 0) HGOTO_ERROR(H5E_OHDR, H5E_CANTDEC, FAIL, "can't decrement reference count on object header") done: diff --git a/src/H5Ocopy.c b/src/H5Ocopy.c index d28590f..6716769 100644 --- a/src/H5Ocopy.c +++ b/src/H5Ocopy.c @@ -111,140 +111,7 @@ H5FL_DEFINE(haddr_t); /*******************/ /*------------------------------------------------------------------------- - * Function: H5Ocopy - * - * Purpose: Copy an object (group or dataset) to destination location - * within a file or cross files. PLIST_ID is a property list - * which is used to pass user options and properties to the - * copy. The name, dst_name, must not already be taken by some - * other object in the destination group. - * - * H5Ocopy() will fail if the name of the destination object - * exists in the destination group. For example, - * H5Ocopy(fid_src, "/dset", fid_dst, "/dset", ...) - * will fail if "/dset" exists in the destination file - * - * OPTIONS THAT HAVE BEEN IMPLEMENTED. - * H5O_COPY_SHALLOW_HIERARCHY_FLAG - * If this flag is specified, only immediate members of - * the group are copied. Otherwise (default), it will - * recursively copy all objects below the group - * H5O_COPY_EXPAND_SOFT_LINK_FLAG - * If this flag is specified, it will copy the objects - * pointed by the soft links. Otherwise (default), it - * will copy the soft link as they are - * H5O_COPY_WITHOUT_ATTR_FLAG - * If this flag is specified, it will copy object without - * copying attributes. Otherwise (default), it will - * copy object along with all its attributes - * H5O_COPY_EXPAND_REFERENCE_FLAG - * 1) Copy object between two different files: - * When this flag is specified, it will copy objects that - * are pointed by the references and update the values of - * references in the destination file. Otherwise (default) - * the values of references in the destination will set to - * zero - * The current implementation does not handle references - * inside of other datatype structure. For example, if - * a member of compound datatype is reference, H5Ocopy() - * will copy that field as it is. It will not set the - * value to zero as default is used nor copy the object - * pointed by that field the flag is set - * 2) Copy object within the same file: - * This flag does not have any effect to the H5Ocopy(). - * Datasets or attributes of references are copied as they - * are, i.e. values of references of the destination object - * are the same as the values of the source object - * - * OPTIONS THAT MAY APPLY TO COPY IN THE FUTURE. - * H5O_COPY_EXPAND_EXT_LINK_FLAG - * If this flag is specified, it will expand the external links - * into new objects, Otherwise (default), it will keep external - * links as they are (default) - * - * PROPERTIES THAT MAY APPLY TO COPY IN FUTURE - * Change data layout such as chunk size - * Add filter such as data compression. - * Add an attribute to the copied object(s) that say the date/time - * for the copy or other information about the source file. - * - * The intermediate group creation property should be passed in - * using the lcpl instead of the ocpypl. - * - * Usage: H5Ocopy(src_loc_id, src_name, dst_loc_id, dst_name, ocpypl_id, lcpl_id) - * hid_t src_loc_id IN: Source file or group identifier. - * const char *src_name IN: Name of the source object to be copied - * hid_t dst_loc_id IN: Destination file or group identifier - * const char *dst_name IN: Name of the destination object - * hid_t ocpypl_id IN: Properties which apply to the copy - * hid_t lcpl_id IN: Properties which apply to the new hard link - * - * - * Return: SUCCEED/FAIL - * - *------------------------------------------------------------------------- - */ -herr_t -H5Ocopy(hid_t src_loc_id, const char *src_name, hid_t dst_loc_id, const char *dst_name, hid_t ocpypl_id, - hid_t lcpl_id) -{ - H5VL_object_t * vol_obj1 = NULL; /* object of src_id */ - H5VL_loc_params_t loc_params1; - H5VL_object_t * vol_obj2 = NULL; /* object of dst_id */ - H5VL_loc_params_t loc_params2; - herr_t ret_value = SUCCEED; /* Return value */ - - FUNC_ENTER_API(FAIL) - H5TRACE6("e", "i*si*sii", src_loc_id, src_name, dst_loc_id, dst_name, ocpypl_id, lcpl_id); - - /* Check arguments */ - if (!src_name || !*src_name) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no source name specified") - if (!dst_name || !*dst_name) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no destination name specified") - - /* Get correct property lists */ - if (H5P_DEFAULT == lcpl_id) - lcpl_id = H5P_LINK_CREATE_DEFAULT; - else if (TRUE != H5P_isa_class(lcpl_id, H5P_LINK_CREATE)) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not link creation property list") - - /* Get object copy property list */ - if (H5P_DEFAULT == ocpypl_id) - ocpypl_id = H5P_OBJECT_COPY_DEFAULT; - else if (TRUE != H5P_isa_class(ocpypl_id, H5P_OBJECT_COPY)) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not object copy property list") - - /* Set the LCPL for the API context */ - H5CX_set_lcpl(lcpl_id); - - /* Set up collective metadata if appropriate */ - if (H5CX_set_loc(src_loc_id) < 0) - HGOTO_ERROR(H5E_OHDR, H5E_CANTSET, FAIL, "can't set collective metadata read info") - - /* get the object */ - if (NULL == (vol_obj1 = (H5VL_object_t *)H5I_object(src_loc_id))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid location identifier") - loc_params1.type = H5VL_OBJECT_BY_SELF; - loc_params1.obj_type = H5I_get_type(src_loc_id); - - /* get the object */ - if (NULL == (vol_obj2 = (H5VL_object_t *)H5I_object(dst_loc_id))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid location identifier") - loc_params2.type = H5VL_OBJECT_BY_SELF; - loc_params2.obj_type = H5I_get_type(dst_loc_id); - - /* Copy the object */ - if (H5VL_object_copy(vol_obj1, &loc_params1, src_name, vol_obj2, &loc_params2, dst_name, ocpypl_id, - lcpl_id, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0) - HGOTO_ERROR(H5E_OHDR, H5E_CANTCOPY, FAIL, "unable to copy object") - -done: - FUNC_LEAVE_API(ret_value) -} /* end H5Ocopy() */ - -/*------------------------------------------------------------------------- - * Function: H5O_copy + * Function: H5O__copy * * Purpose: Private version of H5Ocopy * @@ -256,18 +123,18 @@ done: *------------------------------------------------------------------------- */ herr_t -H5O_copy(const H5G_loc_t *loc, const char *src_name, H5G_loc_t *dst_loc, const char *dst_name, - hid_t ocpypl_id, hid_t lcpl_id) +H5O__copy(const H5G_loc_t *loc, const char *src_name, H5G_loc_t *dst_loc, const char *dst_name, + hid_t ocpypl_id, hid_t lcpl_id) { H5G_loc_t src_loc; /* Source object group location */ H5G_name_t src_path; /* Opened source object hier. path */ H5O_loc_t src_oloc; /* Opened source object object location */ - htri_t dst_exists; /* Does destination name exist already? */ + hbool_t dst_exists; /* Does destination name exist already? */ hbool_t loc_found = FALSE; /* Location at 'name' found */ hbool_t obj_open = FALSE; /* Entry at 'name' found */ herr_t ret_value = SUCCEED; /* Return value */ - FUNC_ENTER_NOAPI_NOINIT + FUNC_ENTER_PACKAGE /* Check arguments */ HDassert(loc); @@ -276,9 +143,10 @@ H5O_copy(const H5G_loc_t *loc, const char *src_name, H5G_loc_t *dst_loc, const c HDassert(dst_name && *dst_name); /* Check if destination name already exists */ - if ((dst_exists = H5L_exists_tolerant(dst_loc, dst_name)) < 0) + dst_exists = FALSE; + if (H5L_exists_tolerant(dst_loc, dst_name, &dst_exists) < 0) HGOTO_ERROR(H5E_OHDR, H5E_CANTGET, FAIL, "unable to check if destination name exists") - if (TRUE == dst_exists) + if (dst_exists) HGOTO_ERROR(H5E_OHDR, H5E_EXISTS, FAIL, "destination object already exists") /* Set up opened group location to fill in */ @@ -307,7 +175,7 @@ done: HDONE_ERROR(H5E_OHDR, H5E_CLOSEERROR, FAIL, "unable to release object header") FUNC_LEAVE_NOAPI(ret_value) -} /* end H5O_copy() */ +} /* end H5O__copy() */ /*------------------------------------------------------------------------- * Function: H5O__copy_header_real @@ -1283,10 +1151,10 @@ done: } /* end H5O__copy_comm_dt_cmp */ /*------------------------------------------------------------------------- - * Function: H5O_copy_search_comm_dt_attr_cb + * Function: H5O__copy_search_comm_dt_attr_cb * * Purpose: Callback for H5O_attr_iterate_real from - * H5O_copy_search_comm_dt_check. Checks if the attribute's + * H5O__copy_search_comm_dt_check. Checks if the attribute's * datatype is committed. If it is, adds it to the merge * committed dt skiplist present in udata if it does not match * any already present. @@ -1299,7 +1167,7 @@ done: *------------------------------------------------------------------------- */ static herr_t -H5O_copy_search_comm_dt_attr_cb(const H5A_t *attr, void *_udata) +H5O__copy_search_comm_dt_attr_cb(const H5A_t *attr, void *_udata) { H5O_copy_search_comm_dt_ud_t * udata = (H5O_copy_search_comm_dt_ud_t *)_udata; H5T_t * dt = NULL; /* Datatype */ @@ -1308,7 +1176,7 @@ H5O_copy_search_comm_dt_attr_cb(const H5A_t *attr, void *_udata) hbool_t obj_inserted = FALSE; /* Object inserted into skip list */ herr_t ret_value = SUCCEED; /* Return value */ - FUNC_ENTER_NOAPI_NOINIT + FUNC_ENTER_STATIC /* Sanity checks */ HDassert(attr); @@ -1361,10 +1229,10 @@ done: } /* end if */ FUNC_LEAVE_NOAPI(ret_value) -} /* end H5O_copy_search_comm_dt_attr_cb */ +} /* end H5O__copy_search_comm_dt_attr_cb */ /*------------------------------------------------------------------------- - * Function: H5O_copy_search_comm_dt_check + * Function: H5O__copy_search_comm_dt_check * * Purpose: Check if the object at obj_oloc is or contains a reference * to a committed datatype. If it does, adds it to the merge @@ -1379,7 +1247,7 @@ done: *------------------------------------------------------------------------- */ static herr_t -H5O_copy_search_comm_dt_check(H5O_loc_t *obj_oloc, H5O_copy_search_comm_dt_ud_t *udata) +H5O__copy_search_comm_dt_check(H5O_loc_t *obj_oloc, H5O_copy_search_comm_dt_ud_t *udata) { H5O_copy_search_comm_dt_key_t *key = NULL; /* Skiplist key */ haddr_t * addr = NULL; /* Destination address */ @@ -1388,7 +1256,7 @@ H5O_copy_search_comm_dt_check(H5O_loc_t *obj_oloc, H5O_copy_search_comm_dt_ud_t const H5O_obj_class_t * obj_class = NULL; /* Type of object */ herr_t ret_value = SUCCEED; /* Return value */ - FUNC_ENTER_NOAPI_NOINIT + FUNC_ENTER_STATIC /* Sanity checks */ HDassert(obj_oloc); @@ -1457,7 +1325,7 @@ H5O_copy_search_comm_dt_check(H5O_loc_t *obj_oloc, H5O_copy_search_comm_dt_ud_t /* Search within attributes */ attr_op.op_type = H5A_ATTR_OP_LIB; - attr_op.u.lib_op = H5O_copy_search_comm_dt_attr_cb; + attr_op.u.lib_op = H5O__copy_search_comm_dt_attr_cb; udata->obj_oloc.file = obj_oloc->file; udata->obj_oloc.addr = obj_oloc->addr; if (H5O_attr_iterate_real((hid_t)-1, obj_oloc, H5_INDEX_NAME, H5_ITER_NATIVE, (hsize_t)0, NULL, &attr_op, @@ -1479,14 +1347,14 @@ done: } /* end if */ FUNC_LEAVE_NOAPI(ret_value) -} /* end H5O_copy_search_comm_dt_check */ +} /* end H5O__copy_search_comm_dt_check */ /*------------------------------------------------------------------------- * Function: H5O__copy_search_comm_dt_cb * * Purpose: H5G_visit callback to add committed datatypes to the merge * committed dt skiplist. Mostly a wrapper for - * H5O_copy_search_comm_dt_check. + * H5O__copy_search_comm_dt_check. * * Return: Non-negative on success/Negative on failure * @@ -1529,7 +1397,7 @@ H5O__copy_search_comm_dt_cb(hid_t H5_ATTR_UNUSED group, const char *name, const obj_found = TRUE; /* Check object and add to skip list if appropriate */ - if (H5O_copy_search_comm_dt_check(&obj_oloc, udata) < 0) + if (H5O__copy_search_comm_dt_check(&obj_oloc, udata) < 0) HGOTO_ERROR(H5E_OHDR, H5E_CANTGET, H5_ITER_ERROR, "can't check object") } /* end if */ @@ -1627,7 +1495,7 @@ H5O__copy_search_comm_dt(H5F_t *file_src, H5O_t *oh_src, H5O_loc_t *oloc_dst /*i H5E_clear_stack(NULL); else /* Check object and add to skip list if appropriate */ - if (H5O_copy_search_comm_dt_check(&obj_oloc, &udata) < 0) { + if (H5O__copy_search_comm_dt_check(&obj_oloc, &udata) < 0) { if (H5G_loc_free(&obj_loc) < 0) HERROR(H5E_OHDR, H5E_CANTRELEASE, "can't free location"); HGOTO_ERROR(H5E_OHDR, H5E_CANTGET, FAIL, "can't check object") diff --git a/src/H5Ocopy_ref.c b/src/H5Ocopy_ref.c index 83643f3..e06e699 100644 --- a/src/H5Ocopy_ref.c +++ b/src/H5Ocopy_ref.c @@ -63,7 +63,7 @@ static herr_t H5O__copy_expand_ref_object1(H5O_loc_t *src_oloc, const void *buf_ static herr_t H5O__copy_expand_ref_region1(H5O_loc_t *src_oloc, const void *buf_src, H5O_loc_t *dst_oloc, H5G_loc_t *dst_root_loc, void *buf_dst, size_t ref_count, H5O_copy_t *cpy_info); -static herr_t H5O__copy_expand_ref_object2(H5O_loc_t *src_oloc, hid_t tid_src, H5T_t *dt_src, +static herr_t H5O__copy_expand_ref_object2(H5O_loc_t *src_oloc, hid_t tid_src, const H5T_t *dt_src, const void *buf_src, size_t nbytes_src, H5O_loc_t *dst_oloc, H5G_loc_t *dst_root_loc, void *buf_dst, size_t ref_count, H5O_copy_t *cpy_info); @@ -284,7 +284,7 @@ done: *------------------------------------------------------------------------- */ static herr_t -H5O__copy_expand_ref_object2(H5O_loc_t *src_oloc, hid_t tid_src, H5T_t *dt_src, const void *buf_src, +H5O__copy_expand_ref_object2(H5O_loc_t *src_oloc, hid_t tid_src, const H5T_t *dt_src, const void *buf_src, size_t nbytes_src, H5O_loc_t *dst_oloc, H5G_loc_t *dst_root_loc, void *buf_dst, size_t ref_count, H5O_copy_t *cpy_info) { @@ -423,7 +423,7 @@ done: *------------------------------------------------------------------------- */ herr_t -H5O_copy_expand_ref(H5F_t *file_src, hid_t tid_src, H5T_t *dt_src, void *buf_src, size_t nbytes_src, +H5O_copy_expand_ref(H5F_t *file_src, hid_t tid_src, const H5T_t *dt_src, void *buf_src, size_t nbytes_src, H5F_t *file_dst, void *buf_dst, H5O_copy_t *cpy_info) { H5O_loc_t dst_oloc; /* Copied object object location */ diff --git a/src/H5Oefl.c b/src/H5Oefl.c index 1ecaf36..d950249 100644 --- a/src/H5Oefl.c +++ b/src/H5Oefl.c @@ -466,7 +466,7 @@ H5O__efl_copy_file(H5F_t H5_ATTR_UNUSED *file_src, void *mesg_src, H5F_t *file_d HGOTO_ERROR(H5E_EFL, H5E_PROTECT, NULL, "unable to protect EFL file name heap") /* Insert "empty" name first */ - if (UFAIL == (name_offset = H5HL_insert(file_dst, heap, (size_t)1, ""))) + if (H5HL_insert(file_dst, heap, (size_t)1, "", &name_offset) < 0) HGOTO_ERROR(H5E_EFL, H5E_CANTINSERT, NULL, "can't insert file name into heap") HDassert(0 == name_offset); @@ -483,10 +483,10 @@ H5O__efl_copy_file(H5F_t H5_ATTR_UNUSED *file_src, void *mesg_src, H5F_t *file_d /* copy the name from the source */ for (idx = 0; idx < efl_src->nused; idx++) { efl_dst->slot[idx].name = H5MM_xstrdup(efl_src->slot[idx].name); - if (UFAIL == (efl_dst->slot[idx].name_offset = H5HL_insert( - file_dst, heap, HDstrlen(efl_dst->slot[idx].name) + 1, efl_dst->slot[idx].name))) + if (H5HL_insert(file_dst, heap, HDstrlen(efl_dst->slot[idx].name) + 1, efl_dst->slot[idx].name, + &(efl_dst->slot[idx].name_offset)) < 0) HGOTO_ERROR(H5E_EFL, H5E_CANTINSERT, NULL, "can't insert file name into heap") - } /* end for */ + } /* Set return value */ ret_value = efl_dst; diff --git a/src/H5Oflush.c b/src/H5Oflush.c index e1fa5e9..2e3c1fd 100644 --- a/src/H5Oflush.c +++ b/src/H5Oflush.c @@ -56,49 +56,6 @@ static herr_t H5O__refresh_metadata_close(hid_t oid, H5O_loc_t oloc, H5G_loc_t * /*************/ /*------------------------------------------------------------------------- - * Function: H5Oflush - * - * Purpose: Flushes all buffers associated with an object to disk. - * - * Return: SUCCEED/FAIL - * - * Programmer: Mike McGreevy - * May 19, 2010 - * - *------------------------------------------------------------------------- - */ -herr_t -H5Oflush(hid_t obj_id) -{ - H5VL_object_t * vol_obj = NULL; /* Object of obj_id */ - H5VL_loc_params_t loc_params; - herr_t ret_value = SUCCEED; /* Return value */ - - FUNC_ENTER_API(FAIL) - H5TRACE1("e", "i", obj_id); - - /* Check args */ - if (NULL == (vol_obj = H5VL_vol_object(obj_id))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid object identifier") - - /* Set up collective metadata if appropriate */ - if (H5CX_set_loc(obj_id) < 0) - HGOTO_ERROR(H5E_DATATYPE, H5E_CANTSET, FAIL, "can't set access property list info") - - /* Set location parameters */ - loc_params.type = H5VL_OBJECT_BY_SELF; - loc_params.obj_type = H5I_get_type(obj_id); - - /* Flush the object */ - if (H5VL_object_specific(vol_obj, &loc_params, H5VL_OBJECT_FLUSH, H5P_DATASET_XFER_DEFAULT, - H5_REQUEST_NULL, obj_id) < 0) - HGOTO_ERROR(H5E_OHDR, H5E_CANTFLUSH, FAIL, "unable to flush object") - -done: - FUNC_LEAVE_API(ret_value) -} /* end H5Oflush() */ - -/*------------------------------------------------------------------------- * Function: H5O_flush * * Purpose: Internal routine to flush an object @@ -217,49 +174,6 @@ done: } /* end H5O__oh_tag() */ /*------------------------------------------------------------------------- - * Function: H5Orefresh - * - * Purpose: Refreshes all buffers associated with an object. - * - * Return: SUCCEED/FAIL - * - * Programmer: Mike McGreevy - * July 28, 2010 - * - *------------------------------------------------------------------------- - */ -herr_t -H5Orefresh(hid_t oid) -{ - H5VL_object_t * vol_obj = NULL; /* Object of oid */ - H5VL_loc_params_t loc_params; - herr_t ret_value = SUCCEED; /* Return value */ - - FUNC_ENTER_API(FAIL) - H5TRACE1("e", "i", oid); - - /* Check args */ - if (NULL == (vol_obj = H5VL_vol_object(oid))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid object identifier") - - /* Set up collective metadata if appropriate */ - if (H5CX_set_loc(oid) < 0) - HGOTO_ERROR(H5E_OHDR, H5E_CANTSET, FAIL, "can't set access property list info") - - /* Set location parameters */ - loc_params.type = H5VL_OBJECT_BY_SELF; - loc_params.obj_type = H5I_get_type(oid); - - /* Refresh the object */ - if (H5VL_object_specific(vol_obj, &loc_params, H5VL_OBJECT_REFRESH, H5P_DATASET_XFER_DEFAULT, - H5_REQUEST_NULL, oid) < 0) - HGOTO_ERROR(H5E_OHDR, H5E_CANTLOAD, FAIL, "unable to refresh object") - -done: - FUNC_LEAVE_API(ret_value) -} /* end H5Orefresh() */ - -/*------------------------------------------------------------------------- * Function: H5O_refresh_metadata * * Purpose: Refreshes all buffers associated with an object. @@ -487,9 +401,8 @@ H5O_refresh_metadata_reopen(hid_t oid, H5G_loc_t *obj_loc, const H5O_refresh_sta case H5I_DATASET: object = H5D_open(obj_loc, (state == NULL) ? H5P_DATASET_ACCESS_DEFAULT : state->dapl_id); - if (NULL == object) { - HGOTO_ERROR(H5E_DATASET, H5E_CANTOPENOBJ, FAIL, "unable to open dataset"); - } + if (NULL == object) + HGOTO_ERROR(H5E_DATASET, H5E_CANTOPENOBJ, FAIL, "unable to open dataset") if (!start_swmr) /* No need to handle multiple opens when H5Fstart_swmr_write() */ if (H5D_mult_refresh_reopen((H5D_t *)object) < 0) HGOTO_ERROR(H5E_OHDR, H5E_CANTOPENOBJ, FAIL, "unable to finish refresh for dataset") @@ -511,6 +424,7 @@ H5O_refresh_metadata_reopen(hid_t oid, H5G_loc_t *obj_loc, const H5O_refresh_sta case H5I_ERROR_MSG: case H5I_ERROR_STACK: case H5I_SPACE_SEL_ITER: + case H5I_EVENTSET: case H5I_NTYPES: default: HGOTO_ERROR(H5E_OHDR, H5E_BADTYPE, FAIL, diff --git a/src/H5Oint.c b/src/H5Oint.c index a88a026..f24d0bb 100644 --- a/src/H5Oint.c +++ b/src/H5Oint.c @@ -91,35 +91,35 @@ hbool_t H5_PKG_INIT_VAR = FALSE; * message. */ const H5O_msg_class_t *const H5O_msg_class_g[] = { - H5O_MSG_NULL, /*0x0000 Null */ - H5O_MSG_SDSPACE, /*0x0001 Dataspace */ - H5O_MSG_LINFO, /*0x0002 Link information */ - H5O_MSG_DTYPE, /*0x0003 Datatype */ - H5O_MSG_FILL, /*0x0004 Old data storage -- fill value */ - H5O_MSG_FILL_NEW, /*0x0005 New data storage -- fill value */ - H5O_MSG_LINK, /*0x0006 Link */ + H5O_MSG_NULL, /*0x0000 Null */ + H5O_MSG_SDSPACE, /*0x0001 Dataspace */ + H5O_MSG_LINFO, /*0x0002 Link information */ + H5O_MSG_DTYPE, /*0x0003 Datatype */ + H5O_MSG_FILL, /*0x0004 Old data storage -- fill value */ + H5O_MSG_FILL_NEW, /*0x0005 New data storage -- fill value */ + H5O_MSG_LINK, /*0x0006 Link */ H5O_MSG_EFL, /*0x0007 Data storage -- external data files */ - H5O_MSG_LAYOUT, /*0x0008 Data Layout */ + H5O_MSG_LAYOUT, /*0x0008 Data Layout */ #ifdef H5O_ENABLE_BOGUS - H5O_MSG_BOGUS_VALID, /*0x0009 "Bogus valid" (for testing) */ + H5O_MSG_BOGUS_VALID, /*0x0009 "Bogus valid" (for testing) */ #else /* H5O_ENABLE_BOGUS */ - NULL, /*0x0009 "Bogus valid" (for testing) */ + NULL, /*0x0009 "Bogus valid" (for testing) */ #endif /* H5O_ENABLE_BOGUS */ - H5O_MSG_GINFO, /*0x000A Group information */ + H5O_MSG_GINFO, /*0x000A Group information */ H5O_MSG_PLINE, /*0x000B Data storage -- filter pipeline */ - H5O_MSG_ATTR, /*0x000C Attribute */ - H5O_MSG_NAME, /*0x000D Object name */ + H5O_MSG_ATTR, /*0x000C Attribute */ + H5O_MSG_NAME, /*0x000D Object name */ H5O_MSG_MTIME, /*0x000E Object modification date and time */ - H5O_MSG_SHMESG, /*0x000F File-wide shared message table */ - H5O_MSG_CONT, /*0x0010 Object header continuation */ - H5O_MSG_STAB, /*0x0011 Symbol table */ + H5O_MSG_SHMESG, /*0x000F File-wide shared message table */ + H5O_MSG_CONT, /*0x0010 Object header continuation */ + H5O_MSG_STAB, /*0x0011 Symbol table */ H5O_MSG_MTIME_NEW, /*0x0012 New Object modification date and time */ H5O_MSG_BTREEK, /*0x0013 Non-default v1 B-tree 'K' values */ - H5O_MSG_DRVINFO, /*0x0014 Driver info settings */ - H5O_MSG_AINFO, /*0x0015 Attribute information */ - H5O_MSG_REFCOUNT, /*0x0016 Object's ref. count */ - H5O_MSG_FSINFO, /*0x0017 Free-space manager info */ - H5O_MSG_MDCI, /*0x0018 Metadata cache image */ + H5O_MSG_DRVINFO, /*0x0014 Driver info settings */ + H5O_MSG_AINFO, /*0x0015 Attribute information */ + H5O_MSG_REFCOUNT, /*0x0016 Object's ref. count */ + H5O_MSG_FSINFO, /*0x0017 Free-space manager info */ + H5O_MSG_MDCI, /*0x0018 Metadata cache image */ H5O_MSG_UNKNOWN /*0x0019 Placeholder for unknown message */ }; @@ -204,7 +204,7 @@ H5O__init_package(void) } /* end H5O__init_package() */ /*------------------------------------------------------------------------- - * Function: H5O_set_version + * Function: H5O__set_version * * Purpose: Sets the correct version to encode the object header. * Chooses the oldest version possible, unless the file's @@ -218,12 +218,12 @@ H5O__init_package(void) *------------------------------------------------------------------------- */ static herr_t -H5O_set_version(H5F_t *f, H5O_t *oh, uint8_t oh_flags, hbool_t store_msg_crt_idx) +H5O__set_version(H5F_t *f, H5O_t *oh, uint8_t oh_flags, hbool_t store_msg_crt_idx) { uint8_t version; /* Message version */ herr_t ret_value = SUCCEED; /* Return value */ - FUNC_ENTER_NOAPI(FAIL) + FUNC_ENTER_STATIC /* check arguments */ HDassert(f); @@ -247,7 +247,7 @@ H5O_set_version(H5F_t *f, H5O_t *oh, uint8_t oh_flags, hbool_t store_msg_crt_idx done: FUNC_LEAVE_NOAPI(ret_value) -} /* end H5O_set_version() */ +} /* end H5O__set_version() */ /*------------------------------------------------------------------------- * Function: H5O_create @@ -283,13 +283,13 @@ H5O_create(H5F_t *f, size_t size_hint, size_t initial_rc, hid_t ocpl_id, H5O_loc /* create object header in freelist * header version is set internally */ - oh = H5O__create_ohdr(f, ocpl_id); + oh = H5O_create_ohdr(f, ocpl_id); if (NULL == oh) HGOTO_ERROR(H5E_OHDR, H5E_BADVALUE, FAIL, "Can't instantiate object header") /* apply object header information to file */ - if (H5O__apply_ohdr(f, oh, ocpl_id, size_hint, initial_rc, loc) < 0) + if (H5O_apply_ohdr(f, oh, ocpl_id, size_hint, initial_rc, loc) < 0) HGOTO_ERROR(H5E_OHDR, H5E_BADVALUE, FAIL, "Can't apply object header to file") done: @@ -300,7 +300,7 @@ done: } /* end H5O_create() */ /*----------------------------------------------------------------------------- - * Function: H5O__create_ohdr + * Function: H5O_create_ohdr * * Purpose: Create the object header, set version and flags. * @@ -313,7 +313,7 @@ done: *----------------------------------------------------------------------------- */ H5O_t * -H5O__create_ohdr(H5F_t *f, hid_t ocpl_id) +H5O_create_ohdr(H5F_t *f, hid_t ocpl_id) { H5P_genplist_t *oc_plist; H5O_t * oh = NULL; /* Object header in Freelist */ @@ -349,7 +349,7 @@ H5O__create_ohdr(H5F_t *f, hid_t ocpl_id) HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't get object header flags") } - if (H5O_set_version(f, oh, oh_flags, H5F_STORE_MSG_CRT_IDX(f)) < 0) + if (H5O__set_version(f, oh, oh_flags, H5F_STORE_MSG_CRT_IDX(f)) < 0) HGOTO_ERROR(H5E_OHDR, H5E_CANTSET, NULL, "can't set version of object header") oh->flags = oh_flags; @@ -361,10 +361,10 @@ done: HDONE_ERROR(H5E_OHDR, H5E_CANTFREE, NULL, "can't delete object header") FUNC_LEAVE_NOAPI(ret_value) -} /* H5O__create_ohdr() */ +} /* H5O_create_ohdr() */ /*----------------------------------------------------------------------------- - * Function: H5O__apply_ohdr + * Function: H5O_apply_ohdr * * Purpose: Initialize and set the object header in the file. * Record some information at `loc_out`. @@ -378,7 +378,7 @@ done: *----------------------------------------------------------------------------- */ herr_t -H5O__apply_ohdr(H5F_t *f, H5O_t *oh, hid_t ocpl_id, size_t size_hint, size_t initial_rc, H5O_loc_t *loc_out) +H5O_apply_ohdr(H5F_t *f, H5O_t *oh, hid_t ocpl_id, size_t size_hint, size_t initial_rc, H5O_loc_t *loc_out) { haddr_t oh_addr; size_t oh_size; @@ -449,12 +449,16 @@ H5O__apply_ohdr(H5F_t *f, H5O_t *oh, hid_t ocpl_id, size_t size_hint, size_t ini #if H5_SIZEOF_SIZE_T > H5_SIZEOF_INT32_T if (size_hint > 4294967295UL) oh->flags |= H5O_HDR_CHUNK0_8; - else -#endif /* H5_SIZEOF_SIZE_T > H5_SIZEOF_INT32_T */ - if (size_hint > 65535) + else if (size_hint > 65535) + oh->flags |= H5O_HDR_CHUNK0_4; + else if (size_hint > 255) + oh->flags |= H5O_HDR_CHUNK0_2; +#else + if (size_hint > 65535) oh->flags |= H5O_HDR_CHUNK0_4; else if (size_hint > 255) oh->flags |= H5O_HDR_CHUNK0_2; +#endif } else { /* Reset unused time fields */ @@ -538,7 +542,7 @@ H5O__apply_ohdr(H5F_t *f, H5O_t *oh, hid_t ocpl_id, size_t size_hint, size_t ini done: FUNC_LEAVE_NOAPI(ret_value); -} /* H5O__apply_ohdr() */ +} /* H5O_apply_ohdr() */ /*------------------------------------------------------------------------- * Function: H5O_open @@ -635,7 +639,7 @@ done: } /* end H5O_open_name() */ /*------------------------------------------------------------------------- - * Function: H5O_open_by_idx + * Function: H5O__open_by_idx * * Purpose: Internal routine to open an object by index within group * @@ -648,8 +652,8 @@ done: *------------------------------------------------------------------------- */ void * -H5O_open_by_idx(const H5G_loc_t *loc, const char *name, H5_index_t idx_type, H5_iter_order_t order, hsize_t n, - H5I_type_t *opened_type) +H5O__open_by_idx(const H5G_loc_t *loc, const char *name, H5_index_t idx_type, H5_iter_order_t order, + hsize_t n, H5I_type_t *opened_type) { H5G_loc_t obj_loc; /* Location used to open group */ H5G_name_t obj_path; /* Opened object group hier. path */ @@ -657,7 +661,7 @@ H5O_open_by_idx(const H5G_loc_t *loc, const char *name, H5_index_t idx_type, H5_ hbool_t loc_found = FALSE; /* Entry at 'name' found */ void * ret_value = NULL; /* Return value */ - FUNC_ENTER_NOAPI(NULL) + FUNC_ENTER_PACKAGE /* Check arguments */ HDassert(loc); @@ -683,10 +687,10 @@ done: HDONE_ERROR(H5E_OHDR, H5E_CANTRELEASE, NULL, "can't free location") FUNC_LEAVE_NOAPI(ret_value) -} /* end H5O_open_by_idx() */ +} /* end H5O__open_by_idx() */ /*------------------------------------------------------------------------- - * Function: H5O_open_by_addr + * Function: H5O__open_by_addr * * Purpose: Internal routine to open an object by its address * @@ -699,14 +703,14 @@ done: *------------------------------------------------------------------------- */ void * -H5O_open_by_addr(const H5G_loc_t *loc, haddr_t addr, H5I_type_t *opened_type) +H5O__open_by_addr(const H5G_loc_t *loc, haddr_t addr, H5I_type_t *opened_type) { H5G_loc_t obj_loc; /* Location used to open group */ H5G_name_t obj_path; /* Opened object group hier. path */ H5O_loc_t obj_oloc; /* Opened object object location */ void * ret_value = NULL; /* Return value */ - FUNC_ENTER_NOAPI(NULL) + FUNC_ENTER_PACKAGE /* Check arguments */ HDassert(loc); @@ -725,7 +729,7 @@ H5O_open_by_addr(const H5G_loc_t *loc, haddr_t addr, H5I_type_t *opened_type) done: FUNC_LEAVE_NOAPI(ret_value) -} /* end H5O_open_by_addr() */ +} /* end H5O__open_by_addr() */ /*------------------------------------------------------------------------- * Function: H5O_open_by_loc @@ -1827,6 +1831,7 @@ H5O_get_loc(hid_t object_id) case H5I_ERROR_MSG: case H5I_ERROR_STACK: case H5I_SPACE_SEL_ITER: + case H5I_EVENTSET: case H5I_NTYPES: default: HGOTO_ERROR(H5E_OHDR, H5E_BADTYPE, NULL, "invalid object type") diff --git a/src/H5Opkg.h b/src/H5Opkg.h index 3434baf..6e203bb 100644 --- a/src/H5Opkg.h +++ b/src/H5Opkg.h @@ -540,7 +540,12 @@ H5_DLLVAR const H5O_obj_class_t H5O_OBJ_DATASET[1]; H5_DLLVAR const H5O_obj_class_t H5O_OBJ_DATATYPE[1]; /* Package-local function prototypes */ +H5_DLL void *H5O__open_by_addr(const H5G_loc_t *loc, haddr_t addr, H5I_type_t *opened_type /*out*/); +H5_DLL void *H5O__open_by_idx(const H5G_loc_t *loc, const char *name, H5_index_t idx_type, + H5_iter_order_t order, hsize_t n, H5I_type_t *opened_type /*out*/); H5_DLL const H5O_obj_class_t *H5O__obj_class(const H5O_loc_t *loc); +H5_DLL herr_t H5O__copy(const H5G_loc_t *src_loc, const char *src_name, H5G_loc_t *dst_loc, + const char *dst_name, hid_t ocpypl_id, hid_t lcpl_id); H5_DLL int H5O__link_oh(H5F_t *f, int adjust, H5O_t *oh, hbool_t *deleted); H5_DLL herr_t H5O__visit(H5G_loc_t *loc, const char *obj_name, H5_index_t idx_type, H5_iter_order_t order, H5O_iterate2_t op, void *op_data, unsigned fields); diff --git a/src/H5Oprivate.h b/src/H5Oprivate.h index 3325a43..d3b469c 100644 --- a/src/H5Oprivate.h +++ b/src/H5Oprivate.h @@ -29,22 +29,22 @@ typedef struct H5O_t H5O_t; typedef struct H5O_fill_t H5O_fill_t; /* Include the public header file for this API */ -#include "H5Opublic.h" /* Object header functions */ +#include "H5Opublic.h" /* Object header functions */ /* Public headers needed by this file */ -#include "H5Dpublic.h" /* Dataset functions */ -#include "H5Lpublic.h" /* Link functions */ +#include "H5Dpublic.h" /* Dataset functions */ +#include "H5Lpublic.h" /* Link functions */ #include "H5Spublic.h" /* Dataspace functions */ /* Private headers needed by this file */ -#include "H5private.h" /* Generic Functions */ -#include "H5ACprivate.h" /* Metadata cache */ +#include "H5private.h" /* Generic Functions */ +#include "H5ACprivate.h" /* Metadata cache */ #include "H5Fprivate.h" /* File access */ -#include "H5HGprivate.h" /* Global Heaps */ +#include "H5HGprivate.h" /* Global Heaps */ #include "H5SLprivate.h" /* Skip lists */ #include "H5Tprivate.h" /* Datatype functions */ -#include "H5VLprivate.h" -#include "H5Zprivate.h" /* I/O pipeline filters */ +#include "H5VLprivate.h" /* Virtual Object Layer */ +#include "H5Zprivate.h" /* I/O pipeline filters */ /* Forward references of package typedefs */ typedef struct H5O_msg_class_t H5O_msg_class_t; @@ -232,7 +232,7 @@ typedef struct H5O_copy_t { #define H5O_FSINFO_ID 0x0017 /* File space info message. */ #define H5O_MDCI_MSG_ID 0x0018 /* Metadata Cache Image Message */ #define H5O_UNKNOWN_ID 0x0019 /* Placeholder message ID for unknown message. */ - /* (this should never exist in a file) */ +/* (this should never exist in a file) */ /* * Note: Must increment H5O_MSG_TYPES in H5Opkg.h and update H5O_msg_class_g * in H5O.c when creating a new message type. Also bump the value of @@ -912,13 +912,10 @@ struct H5P_genplist_t; H5_DLL herr_t H5O_init(void); H5_DLL herr_t H5O_create(H5F_t *f, size_t size_hint, size_t initial_rc, hid_t ocpl_id, H5O_loc_t *loc /*out*/); -H5_DLL H5O_t *H5O__create_ohdr(H5F_t *f, hid_t ocpl_id); -H5_DLL herr_t H5O__apply_ohdr(H5F_t *f, H5O_t *oh, hid_t ocpl_id, size_t size_hint, size_t initial_rc, - H5O_loc_t *loc_out); +H5_DLL H5O_t *H5O_create_ohdr(H5F_t *f, hid_t ocpl_id); +H5_DLL herr_t H5O_apply_ohdr(H5F_t *f, H5O_t *oh, hid_t ocpl_id, size_t size_hint, size_t initial_rc, + H5O_loc_t *loc_out); H5_DLL herr_t H5O_open(H5O_loc_t *loc); -H5_DLL void * H5O_open_by_idx(const H5G_loc_t *loc, const char *name, H5_index_t idx_type, - H5_iter_order_t order, hsize_t n, H5I_type_t *opened_type /*out*/); -H5_DLL void * H5O_open_by_addr(const H5G_loc_t *loc, haddr_t addr, H5I_type_t *opened_type /*out*/); H5_DLL void * H5O_open_by_loc(const H5G_loc_t *obj_loc, H5I_type_t *opened_type /*out*/); H5_DLL herr_t H5O_close(H5O_loc_t *loc, hbool_t *file_closed /*out*/); H5_DLL int H5O_link(const H5O_loc_t *loc, int adjust); @@ -1005,10 +1002,8 @@ H5_DLL herr_t H5O_are_mdc_flushes_disabled(H5O_loc_t *oloc, hbool_t *are_disable H5_DLL herr_t H5O_copy_header_map(const H5O_loc_t *oloc_src, H5O_loc_t *oloc_dst /*out */, H5O_copy_t *cpy_info, hbool_t inc_depth, H5O_type_t *obj_type, void **udata); -H5_DLL herr_t H5O_copy_expand_ref(H5F_t *file_src, hid_t tid_src, H5T_t *dt_src, void *buf_src, +H5_DLL herr_t H5O_copy_expand_ref(H5F_t *file_src, hid_t tid_src, const H5T_t *dt_src, void *buf_src, size_t nbytes_src, H5F_t *file_dst, void *buf_dst, H5O_copy_t *cpy_info); -H5_DLL herr_t H5O_copy(const H5G_loc_t *src_loc, const char *src_name, H5G_loc_t *dst_loc, - const char *dst_name, hid_t ocpypl_id, hid_t lcpl_id); /* Debugging routines */ H5_DLL herr_t H5O_debug_id(unsigned type_id, H5F_t *f, const void *mesg, FILE *stream, int indent, diff --git a/src/H5Opublic.h b/src/H5Opublic.h index 901c0fb..7bc7784 100644 --- a/src/H5Opublic.h +++ b/src/H5Opublic.h @@ -26,9 +26,9 @@ #define H5Opublic_H /* Public headers needed by this file */ -#include "H5public.h" /* Generic Functions */ -#include "H5Ipublic.h" /* IDs */ -#include "H5Lpublic.h" /* Links */ +#include "H5public.h" /* Generic Functions */ +#include "H5Ipublic.h" /* IDs */ +#include "H5Lpublic.h" /* Links */ /*****************/ /* Public Macros */ @@ -86,13 +86,15 @@ #define H5O_INFO_NUM_ATTRS 0x0004u /* Fill in the num_attrs field */ #define H5O_INFO_ALL (H5O_INFO_BASIC | H5O_INFO_TIME | H5O_INFO_NUM_ATTRS) -/* Flags for H5Oget_native_info. - * Theses flags determine which fields will be filled in in the H5O_native_info_t - * struct. +//! <!-- [H5O_native_info_fields_snip] --> +/** + * Flags for H5Oget_native_info(). Theses flags determine which fields will be + * filled in in the \ref H5O_native_info_t struct. */ #define H5O_NATIVE_INFO_HDR 0x0008u /* Fill in the hdr field */ #define H5O_NATIVE_INFO_META_SIZE 0x0010u /* Fill in the meta_size field */ #define H5O_NATIVE_INFO_ALL (H5O_NATIVE_INFO_HDR | H5O_NATIVE_INFO_META_SIZE) +//! <!-- [H5O_native_info_fields_snip] --> /* Convenience macro to check if the token is the 'undefined' token value */ #define H5O_IS_TOKEN_UNDEF(token) (!HDmemcmp(&(token), &(H5O_TOKEN_UNDEF), sizeof(H5O_token_t))) @@ -101,36 +103,48 @@ /* Public Typedefs */ /*******************/ -/* Types of objects in file */ +//! <!-- [H5O_type_t_snip] --> +/** + * Types of objects in file + */ typedef enum H5O_type_t { - H5O_TYPE_UNKNOWN = -1, /* Unknown object type */ - H5O_TYPE_GROUP, /* Object is a group */ - H5O_TYPE_DATASET, /* Object is a dataset */ - H5O_TYPE_NAMED_DATATYPE, /* Object is a named data type */ - H5O_TYPE_MAP, /* Object is a map */ - H5O_TYPE_NTYPES /* Number of different object types (must be last!) */ + H5O_TYPE_UNKNOWN = -1, /**< Unknown object type */ + H5O_TYPE_GROUP, /**< Object is a group */ + H5O_TYPE_DATASET, /**< Object is a dataset */ + H5O_TYPE_NAMED_DATATYPE, /**< Object is a named data type */ + H5O_TYPE_MAP, /**< Object is a map */ + H5O_TYPE_NTYPES /**< Number of different object types (must be last!) */ } H5O_type_t; +//! <!-- [H5O_type_t_snip] --> -/* Information struct for object header metadata (for H5Oget_info/H5Oget_info_by_name/H5Oget_info_by_idx) */ +//! <!-- [H5O_hdr_info_t_snip] --> +/** + * Information struct for object header metadata (for + * H5Oget_info(), H5Oget_info_by_name(), H5Oget_info_by_idx()) + */ typedef struct H5O_hdr_info_t { - unsigned version; /* Version number of header format in file */ - unsigned nmesgs; /* Number of object header messages */ - unsigned nchunks; /* Number of object header chunks */ - unsigned flags; /* Object header status flags */ + unsigned version; /**< Version number of header format in file */ + unsigned nmesgs; /**< Number of object header messages */ + unsigned nchunks; /**< Number of object header chunks */ + unsigned flags; /**< Object header status flags */ struct { - hsize_t total; /* Total space for storing object header in file */ - hsize_t meta; /* Space within header for object header metadata information */ - hsize_t mesg; /* Space within header for actual message information */ - hsize_t free; /* Free space within object header */ + hsize_t total; /**< Total space for storing object header in file */ + hsize_t meta; /**< Space within header for object header metadata information */ + hsize_t mesg; /**< Space within header for actual message information */ + hsize_t free; /**< Free space within object header */ } space; struct { - uint64_t present; /* Flags to indicate presence of message type in header */ - uint64_t shared; /* Flags to indicate message type is shared in header */ + uint64_t present; /**< Flags to indicate presence of message type in header */ + uint64_t shared; /**< Flags to indicate message type is shared in header */ } mesg; } H5O_hdr_info_t; +//! <!-- [H5O_hdr_info_t_snip] --> -/* Data model information struct for objects */ -/* (For H5Oget_info / H5Oget_info_by_name / H5Oget_info_by_idx version 3) */ +//! <!-- [H5O_info2_t_snip] --> +/** + * Data model information struct for objects + * (For H5Oget_info(), H5Oget_info_by_name(), H5Oget_info_by_idx() version 3) + */ typedef struct H5O_info2_t { unsigned long fileno; /* File number that object is located in */ H5O_token_t token; /* Token representing the object */ @@ -142,34 +156,52 @@ typedef struct H5O_info2_t { time_t btime; /* Birth time */ hsize_t num_attrs; /* # of attributes attached to object */ } H5O_info2_t; +//! <!-- [H5O_info2_t_snip] --> -/* Native file format information struct for objects */ -/* (For H5Oget_native_info / H5Oget_native_info_by_name / H5Oget_native_info_by_idx) */ +//! <!-- [H5O_native_info_t_snip] --> +/** + * Native file format information struct for objects. + * (For H5Oget_native_info(), H5Oget_native_info_by_name(), H5Oget_native_info_by_idx()) + */ typedef struct H5O_native_info_t { - H5O_hdr_info_t hdr; /* Object header information */ + H5O_hdr_info_t hdr; /**< Object header information */ /* Extra metadata storage for obj & attributes */ struct { - H5_ih_info_t obj; /* v1/v2 B-tree & local/fractal heap for groups, B-tree for chunked datasets */ - H5_ih_info_t attr; /* v2 B-tree & heap for attributes */ + H5_ih_info_t obj; /**< v1/v2 B-tree & local/fractal heap for groups, B-tree for chunked datasets */ + H5_ih_info_t attr; /**< v2 B-tree & heap for attributes */ } meta_size; } H5O_native_info_t; +//! <!-- [H5O_native_info_t_snip] --> -/* Typedef for message creation indexes */ +/** + * Typedef for message creation indexes + */ typedef uint32_t H5O_msg_crt_idx_t; -/* Prototype for H5Ovisit/H5Ovisit_by_name() operator (version 3) */ +//! <!-- [H5O_iterate2_t_snip] --> +/** + * Prototype for H5Ovisit(), H5Ovisit_by_name() operator (version 3) + */ typedef herr_t (*H5O_iterate2_t)(hid_t obj, const char *name, const H5O_info2_t *info, void *op_data); +//! <!-- [H5O_iterate2_t_snip] --> +//! <!-- [H5O_mcdt_search_ret_t_snip] --> typedef enum H5O_mcdt_search_ret_t { - H5O_MCDT_SEARCH_ERROR = -1, /* Abort H5Ocopy */ - H5O_MCDT_SEARCH_CONT, /* Continue the global search of all committed datatypes in the destination file */ - H5O_MCDT_SEARCH_STOP /* Stop the search, but continue copying. The committed datatype will be copied but - not merged. */ + H5O_MCDT_SEARCH_ERROR = -1, /**< Abort H5Ocopy */ + H5O_MCDT_SEARCH_CONT, /**< Continue the global search of all committed datatypes in the destination file + */ + H5O_MCDT_SEARCH_STOP /**< Stop the search, but continue copying. The committed datatype will be copied + but not merged. */ } H5O_mcdt_search_ret_t; +//! <!-- [H5O_mcdt_search_ret_t_snip] --> -/* Callback to invoke when completing the search for a matching committed datatype from the committed dtype - * list */ +//! <!-- [H5O_mcdt_search_cb_t_snip] --> +/** + * Callback to invoke when completing the search for a matching committed + * datatype from the committed dtype list + */ typedef H5O_mcdt_search_ret_t (*H5O_mcdt_search_cb_t)(void *op_data); +//! <!-- [H5O_mcdt_search_cb_t_snip] --> /********************/ /* Public Variables */ @@ -182,48 +214,1686 @@ typedef H5O_mcdt_search_ret_t (*H5O_mcdt_search_cb_t)(void *op_data); extern "C" { #endif -H5_DLL hid_t H5Oopen(hid_t loc_id, const char *name, hid_t lapl_id); -H5_DLL hid_t H5Oopen_by_token(hid_t loc_id, H5O_token_t token); -H5_DLL hid_t H5Oopen_by_idx(hid_t loc_id, const char *group_name, H5_index_t idx_type, H5_iter_order_t order, - hsize_t n, hid_t lapl_id); +/** + *------------------------------------------------------------------------- + * \ingroup H5O + * + * \brief Opens an object in an HDF5 file by location identifier and path name. + * + * \fgdta_loc_obj_id{loc_id} + * \param[in] name Path to the object; relative to \p loc_id + * \lapl_id + * + * \return \hid_tv{object} + * + * \details H5Oopen() opens a group, dataset, or committed (named) datatype + * specified by a location, \p loc_id, and a path name, \p name, in an HDF5 file. + * + * This function opens the object in the same manner as H5Gopen(), H5Topen(), and H5Dopen(). + * However, H5Oopen() does not require the type of object to be known beforehand. + * This can be useful with user-defined links, for instance, when only a path may be known. + * + * H5Oopen() cannot be used to open a dataspace, attribute, property list, or file. + * + * Once an object of unknown type has been opened with H5Oopen(), + * the type of that object can be determined by means of an H5Iget_type() call. + * + * \p loc_id may be a file, group, dataset, named datatype, or attribute. + * If an attribute is specified for \p loc_id then the object where the + * attribute is attached will be accessed. + * + * \p name must be the path to that object relative to \p loc_id. + * + * \p lapl_id is the link access property list associated with the link pointing to + * the object. If default link access properties are appropriate, this can be + * passed in as #H5P_DEFAULT. + * + * When it is no longer needed, the opened object should be closed with + * H5Oclose(), H5Gclose(), H5Tclose(), or H5Dclose(). + * + * \version 1.8.1 Fortran subroutine introduced in this release. + * + * \since 1.8.0 + * + */ +H5_DLL hid_t H5Oopen(hid_t loc_id, const char *name, hid_t lapl_id); +/** + * -------------------------------------------------------------------------- + * \ingroup ASYNC + * \async_variant_of{H5Oopen} + */ +H5_DLL hid_t H5Oopen_async(const char *app_file, const char *app_func, unsigned app_line, hid_t loc_id, + const char *name, hid_t lapl_id, hid_t es_id); + +/** + *------------------------------------------------------------------------- + * \ingroup H5O + * + * \brief Opens an object in an HDF5 file using its VOL independent token + * + * \fgdta_loc_obj_id{loc_id} + * \param[in] token Object token + * + * \return \hid_ti{object} + * + * \details H5Oopen_by_token() opens an object specified by the object + * identifier, \p loc_id and object token, \p token. + * + * \par Example + * An example snippet from examples/h5_extlink.c: + * \snippet h5_extlink.c H5Open_by_token_snip + * + * \since 1.12.0 + * + */ +H5_DLL hid_t H5Oopen_by_token(hid_t loc_id, H5O_token_t token); + +/** + *------------------------------------------------------------------------- + * \ingroup H5O + * + * \brief Opens the nth object in a group + * + * \fgdta_loc_obj_id{loc_id} + * \param[in] group_name Name of group, relative to \p loc_id, in which object is located + * \idx_type + * \order + * \param[in] n Object to open + * \lapl_id + * + * \return \hid_tv{object} + * + * \details H5Open_by_idx() opens the nth object in the group specified by \p loc_id + * and \p group_name. + * + * \p loc_id specifies a location identifier. + * \p group_name specifies the group relative to \p loc_id in which the object can be found. + * If \p loc_id fully specifies the group in which the object resides, + * \p group_name can be a dot (.). + * + * The specific object to be opened within the group is specified by the three parameters: + * \p idx_type, \p order and \p n. + * + * \p idx_type specifies the type of index by which objects are ordered. + * Valid index types include the following: + * + * \indexes + * + * \p order specifies the order in which the objects are to be referenced for the purposes + * of this function. Valid orders include the following: + * + * \orders + * + * Note that for #H5_ITER_NATIVE, rather than implying a particular order, + * it instructs the HDF5 library to iterate through the objects in the fastest + * available order, i.e., in a natural order. + * + * \p n specifies the position of the object within the index. Note that this count is + * zero-based; 0 (zero) indicates that the function will return the value of the first object; + * if \p n is 5, the function will return the value of the sixth object; etc. + * + * \p lapl_id specifies the link access property list to be used in accessing the object. + * + * An object opened with this function should be closed when it is no longer needed so that + * resource leaks will not develop. H5Oclose() can be used to close groups, datasets, + * or committed datatypes. + * + * \version 1.8.1 Fortran subroutine introduced in this release. + * + * \since 1.8.0 + * + */ +H5_DLL hid_t H5Oopen_by_idx(hid_t loc_id, const char *group_name, H5_index_t idx_type, H5_iter_order_t order, + hsize_t n, hid_t lapl_id); +/** + * -------------------------------------------------------------------------- + * \ingroup ASYNC + * \async_variant_of{H5Oopen_by_idx} + */ +H5_DLL hid_t H5Oopen_by_idx_async(const char *app_file, const char *app_func, unsigned app_line, hid_t loc_id, + const char *group_name, H5_index_t idx_type, H5_iter_order_t order, + hsize_t n, hid_t lapl_id, hid_t es_id); + +/** + *------------------------------------------------------------------------- + * \ingroup H5O + * + * \brief Determines whether a link resolves to an actual object. + * + * \fgdta_loc_obj_id{loc_id} + * \param[in] name The name of the link to check + * \lapl_id + * + * \return Returns a positive value if the object pointed to by + * the \p loc_id and \p name combination exists. + * \return Returns 0 if the object pointed to by + * the \p loc_id and \p name combination does not exist. + * \return Returns a negatvie value when the function fails. + * + * \details H5Oexists_by_name() allows an application to determine whether + * the link \p name in the group or file specified with \p loc_id + * resolves to an HDF5 object to open or if the link dangles. The + * link may be of any type, but hard links will always resolve + * to objects and do not need to be verified. + * + * Note that H5Oexists_by_name() verifies only that the target + * object exists. If \p name includes either a relative path or + * an absolute path to the target link, intermediate steps + * along the path must be verified before the existence of + * the target link can be safely checked. If the path is not + * verified and an intermediate element of the path does not + * exist, H5Oexists_by_name() will fail. The example in the next + * paragraph illustrates one step-by-step method for verifying + * the existence of a link with a relative or absolute path. + * + * \par Example + * Use the following steps to verify the existence of + * the link \c datasetD in the \c group group1/group2/softlink_to_group3/, + * where \c group1 is a member of the group specified by \c loc_id: + * + * \par + * - First use H5Lexists() to verify that a link named \c group1 exists. + * - If \c group1 exists, use H5Oexists_by_name() to verify that the + * link \c group1 resolves to an object. + * - If \c group1 exists, use H5Lexists() again, this time with name + * set to \c group1/group2, to verify that the link \c group2 exists + * in \c group1. + * - If the \c group2 link exists, use H5Oexists_by_name() to verify + * that \c group1/group2 resolves to an object. + * - If \c group2 exists, use H5Lexists() again, this time with name + * set to \c group1/group2/softlink_to_group3, to verify that the + * link \c softlink_to_group3 exists in \c group2. + * - If the \c softlink_to_group3 link exists, use H5Oexists_by_name() + * to verify that \c group1/group2/softlink_to_group3 resolves to + * an object. + * - If \c softlink_to_group3 exists, you can now safely use H5Lexists + * with name set to \c group1/group2/softlink_to_group3/datasetD to + * verify that the target link, \c datasetD, exists. + * - And finally, if the link \c datasetD exists, use H5Oexists_by_name + * to verify that \c group1/group2/softlink_to_group3/datasetD + * resolves to an object. + * + * \par + * If the link to be verified is specified with an absolute path, + * the same approach should be used, but starting with the first + * link in the file’s root group. For instance, if \c datasetD + * were in \c /group1/group2/softlink_to_group3, the first call to + * H5Lexists() would have name set to \c /group1. + * + * \par + * Note that this is an outline and does not include all necessary + * details. Depending on circumstances, for example, an application + * may need to verify the type of an object also. + * + * \warning \Bold{Failure Modes:} + * \warning If \p loc_id and \p name both exist but the combination does not + * resolve to an object, the function will return 0 (zero); + * the function does not fail in this case. + * \warning If either the location or the link specified by the \p loc_id + * and \p name combination does not exist, the function will fail, + * returning a negative value. + * \warning Note that verifying the existence of an object within an HDF5 + * file is a multistep process. An application can be certain the + * object does not exist only if H5Lexists() and H5Oexists_by_name() + * have been used to verify the existence of the links and groups + * in the hierarchy above that object. The example above, in the + * function description, provides a step-by-step description of + * that verification process. + * + * \version 1.8.11 Fortran subroutine introduced in this release. + * + * \since 1.8.5 + * + */ H5_DLL htri_t H5Oexists_by_name(hid_t loc_id, const char *name, hid_t lapl_id); + +/** + *------------------------------------------------------------------------- + * \ingroup H5O + * + * \brief Retrieves the metadata for an object specified by an identifier + * + * \fgdta_loc_obj_id{loc_id} + * \param[out] oinfo Buffer in which to return object information + * \param[in] fields Flags specifying the fields to include in \p oinfo + * + * \return \herr_t + * + * \details H5Oget_info3() specifies an object by its identifier, \p loc_id , and + * retrieves the metadata describing that object in \p oinfo , an H5O_info2_t \c struct. + * + * The H5O_info2_t \c struct is defined in H5Opublic.h as follows : + * \snippet this H5O_info2_t_snip + * + * Note the following about H5O_info2_t : + * - Of the four time fields (\c atime, \c mtime, \c ctime, and \c btime) + * only \c ctime has been implemented. + * - The \c atime value is the last time the object was read or written. + * - The \c mtime value is the last time the raw data in the object was changed. + * - The \c ctime value is the last time the metadata for the object was changed. + * - The \c btime value is the time the object was created. + * + * The H5O_token_t is defined in H5public.h as follows: + * \snippet H5public.h H5O_token_t_snip + * + * The H5O_type_t \c enum indicates the object type and + * is defined in H5Opublic.h as follows: + * \snippet this H5O_type_t_snip + * + * Note that the object retrieved as indicated by \p loc_id + * refers only to the types specified by H5O_type_t. + * + * The \p fields parameter contains flags to determine which fields will be filled in + * the H5O_info2_t \c struct returned in \p oinfo. + * These flags are defined in the H5Opublic.h file: + * + * \obj_info_fields + * + * \par Example + * An example snippet from examples/h5_attribute.c: + * \par + * \snippet h5_attribute.c H5Oget_info3_snip + * + * \note If you are iterating through a lot of different objects to + * retrieve information via the H5Oget_info() family of routines, + * you may see memory building up. This can be due to memory + * allocation for metadata such as object headers and messages + * when the iterated objects are put into the metadata cache. + * \note + * If the memory buildup is not desirable, you can configure a + * smaller cache via H5Fset_mdc_config() or set the file access + * property list via H5Pset_mdc_config(). A smaller sized cache + * will force metadata entries to be evicted from the cache, + * thus freeing the memory associated with the entries. + * + * \since 1.12.0 + * + */ H5_DLL herr_t H5Oget_info3(hid_t loc_id, H5O_info2_t *oinfo, unsigned fields); + +/** + *------------------------------------------------------------------------- + * \ingroup H5O + * + * \brief Retrieves the metadata for an object, identifying the object by + * location and relative name + * + * \fgdta_loc_obj_id{loc_id} + * \param[in] name Name of group, relative to \p loc_id + * \param[out] oinfo Buffer in which to return object information + * \param[in] fields Flags specifying the fields to include in \p oinfo + * \lapl_id + * + * \return \herr_t + * + * \details H5Oget_info_by_name3() specifies an object’s location and name, + * \p loc_id and \p name, respectively, and retrieves the metadata + * describing that object in \p oinfo, an H5O_info2_t struct. + * + * \p oinfo, in which the object information is returned, is a \c struct of + * type H5O_info2_t, which is defined in H5Opublic.h in the HDF5 source code: + * + * \snippet this H5O_info2_t_snip + * + * Note the following about H5O_info2_t : + * - Of the four time fields (\c atime, \c mtime, \c ctime, and \c btime) + * only \c ctime has been implemented. + * - The \c atime value is the last time the object was read or written. + * - The \c mtime value is the last time the raw data in the object was changed. + * - The \c ctime value is the last time the metadata for the object was changed. + * - The \c btime value is the time the object was created. + * + * The H5O_token_t is defined in H5public.h as follows: + * \snippet H5public.h H5O_token_t_snip + * + * The H5O_type_t \c enum indicates the object type and + * is defined in H5Opublic.h as follows: + * \snippet this H5O_type_t_snip + * + * Note that the object retrieved as indicated by \p loc_id + * refers only to the types specified by H5O_type_t. + * + * The \p fields parameter contains flags to determine which fields will be filled in + * the H5O_info2_t \c struct returned in \p oinfo. + * These flags are defined in the H5Opublic.h file: + * + * \obj_info_fields + * + * The link access property list, \c lapl_id, is not currently used; + * it should be passed in as #H5P_DEFAULT. + * + * \par Example + * An example snippet from test/vol.c: + * \snippet vol.c H5Oget_info_by_name3_snip + * + * \since 1.12.0 + * + */ H5_DLL herr_t H5Oget_info_by_name3(hid_t loc_id, const char *name, H5O_info2_t *oinfo, unsigned fields, hid_t lapl_id); +/** + * -------------------------------------------------------------------------- + * \ingroup ASYNC + * \async_variant_of{H5Oget_info_by_name} + */ +H5_DLL herr_t H5Oget_info_by_name_async(const char *app_file, const char *app_func, unsigned app_line, + hid_t loc_id, const char *name, H5O_info2_t *oinfo /*out*/, + unsigned fields, hid_t lapl_id, hid_t es_id); + +/** + *------------------------------------------------------------------------- + * \ingroup H5O + * + * \brief Retrieves the metadata for an object, identifying the object + * by an index position + * + * \fgdta_loc_obj_id{loc_id} + * \param[in] group_name Name of group in which object is located + * \idx_type + * \order + * \param[in] n Position within the index + * \param[out] oinfo Buffer in which to return object information + * \param[in] fields Flags specifying the fields to include in \p oinfo + * \lapl_id + * + * \return \herr_t + * + * \details H5Oget_info_by_idx3() retrieves the metadata describing an + * object in the \c struct \p oinfo, as specified by the location, + * \p loc_id, group name, \p group_name, the index by which objects + * in that group are tracked, \p idx_type, the order by which the + * index is to be traversed, \p order, and an object’s position + * \p n within that index. + * + * If \p loc_id fully specifies the group in which the object resides, + * \p group_name can be a dot (\c .). + * + * \p idx_type is of type #H5_index_t, defined in H5public.h as: + * \snippet H5public.h H5_index_t_snip + * + * \p order is of type #H5_iter_order_t defined in H5public.h as: + * \snippet H5public.h H5_iter_order_t_snip + * + * \p oinfo, in which the object information is returned, is a \c struct of + * type H5O_info2_t, which is defined in H5Opublic.h in the HDF5 source code: + * \snippet this H5O_info2_t_snip + * + * Note the following about H5O_info2_t : + * - Of the four time fields (\c atime, \c mtime, \c ctime, and \c btime) + * only \c ctime has been implemented. + * - The \c atime value is the last time the object was read or written. + * - The \c mtime value is the last time the raw data in the object was changed. + * - The \c ctime value is the last time the metadata for the object was changed. + * - The \c btime value is the time the object was created. + * + * H5O_token_t is defined in H5public.h as follows: + * \snippet H5public.h H5O_token_t_snip + * + * The #H5O_type_t \c enum indicates the object type and + * is defined in H5Opublic.h as follows: + * \snippet this H5O_type_t_snip + * + * Note that the object retrieved as indicated by \p loc_id + * refers only to the types specified by #H5O_type_t. + * + * The \p fields parameter contains flags to determine which fields will be filled in + * the H5O_info2_t \c struct returned in \p oinfo. + * These flags are defined in the H5Opublic.h file: + * \obj_info_fields + * + * The link access property list, \c lapl_id, is not currently used; + * it should be passed in as #H5P_DEFAULT. + * + * \par Example + * An example snippet from test/titerate.c: + * \snippet titerate.c H5Oget_info_by_idx3_snip + * + * \since 1.12.0 + * + */ H5_DLL herr_t H5Oget_info_by_idx3(hid_t loc_id, const char *group_name, H5_index_t idx_type, H5_iter_order_t order, hsize_t n, H5O_info2_t *oinfo, unsigned fields, hid_t lapl_id); + +/** + *------------------------------------------------------------------------- + * \ingroup H5O + * + * \brief Retrieve native file format information about an object + * + * \fgdta_loc_obj_id{loc_id} + * \param[out] oinfo Buffer in which to return native object information + * \param[in] fields Flags to determine which fields in \p oinfo are filled in + * + * \return \herr_t + * + * \details H5Oget_native_info() retrieves the native file format information for an object + * specified by \p loc_id. The information is retrieved into the + * buffer specified by \p oinfo, which is defined as a \c struct of + * type H5O_native_info_t in H5Opublic.h: + * + * \snippet this H5O_native_info_t_snip + * + * The \p fields parameter indicates which fields to fill in + * H5O_native_info_t. Possible values defined in H5Opublic.h are: + * + * \snippet this H5O_native_info_fields_snip + * + * \par Example + * An example snippet from test/tfile.c: + * \par + * \snippet tfile.c H5Oget_native_info_snip + * + * \since 1.12.0 + * + */ H5_DLL herr_t H5Oget_native_info(hid_t loc_id, H5O_native_info_t *oinfo, unsigned fields); + +/** + *------------------------------------------------------------------------- + * \ingroup H5O + * + * \brief Retrieve native file format information about an object given its name + * + * \fgdta_loc_obj_id{loc_id} + * \param[in] name Name of object + * \param[out] oinfo Buffer in which to return native object information + * \param[in] fields Flags to determine which fields in \p oinfo are filled in + * \lapl_id + * + * \return \herr_t + * + * \details H5Oget_native_info_by_name() retrieves the native file format information for an object + * specified by \p loc_id and the name \p name. The information is + * retrieved into the buffer specified by \p oinfo, which is defined + * as a \c struct of type H5O_native_info_t in H5Opublic.h: + * + * \snippet this H5O_native_info_t_snip + * + * The \p fields parameter which fields to fill in H5O_native_info_t. + * Possible values defined in H5Opublic.h are: + * + * \snippet this H5O_native_info_fields_snip + * + * \par Example + * An example snippet from test/tfile.c: + * \snippet tfile.c H5Oget_native_info_by_name_snip + * + * \since 1.12.0 + * + */ H5_DLL herr_t H5Oget_native_info_by_name(hid_t loc_id, const char *name, H5O_native_info_t *oinfo, unsigned fields, hid_t lapl_id); + +/** + *------------------------------------------------------------------------- + * \ingroup H5O + * + * \brief Retrieve native file format information about an object + * according to the order of an index + * + * \fgdta_loc_obj_id{loc_id} + * \param[in] group_name Name of group in which object is located + * \idx_type + * \order + * \param[in] n Position within the index + * \param[out] oinfo Buffer in which to return native object information + * \param[in] fields Flags to determine which fields in \p oinfo are filled in + * \lapl_id + * + * \return \herr_t + * + * \details H5Oget_native_info_by_idx() retrieves the native file format information for an object + * specified by \p loc_id, group name, \p group_name, the index by which + * objects in the group are tracked, \p idx_type, the order by which + * the index is to be traversed, \p order , and an object's position + * \p n within that index. The information is retrieved into the + * buffer specified by \p oinfo, which is defined as a \c struct of + * type H5O_native_info_t in H5Opublic.h: + * \snippet this H5O_native_info_t_snip + * + * \p idx_type is of type #H5_index_t, defined in H5public.h as: + * \snippet H5public.h H5_index_t_snip + * + * \p order is of type #H5_iter_order_t defined in H5public.h as: + * \snippet H5public.h H5_iter_order_t_snip + * + * The \p fields parameter indicates which fields to fill in H5O_native_info_t. + * Possible values defined in H5Opublic.h are: + * \snippet this H5O_native_info_fields_snip + * + * The link access property list, \c lapl_id, is not currently used; + * it should be passed in as #H5P_DEFAULT. + * + * \since 1.12.0 + * + */ H5_DLL herr_t H5Oget_native_info_by_idx(hid_t loc_id, const char *group_name, H5_index_t idx_type, H5_iter_order_t order, hsize_t n, H5O_native_info_t *oinfo, unsigned fields, hid_t lapl_id); + +/** + *------------------------------------------------------------------------- + * \ingroup H5O + * + * \brief Creates a hard link to an object in an HDF5 file + * + * \param[in] obj_id Object to be linked + * \param[in] new_loc_id Location identifier at which object is to be linked; + * may be a file, group, dataset, named datatype or attribute identifier. + * \param[in] new_name Name of link to be created, relative to \p new_loc_id. + * \lcpl_id + * \lapl_id + * + * \return \herr_t + * + * \details H5Olink() creates a new hard link to an object in an HDF5 file. + * \p new_loc_id and \p \p new_link_name specify the location and name of the + * new link while \p object_id identifies the object that the link + * points to. + * + * H5Olink() is designed for two purposes: + * - To create the first hard link to an object that has just + * been created with H5Dcreate_anon(), H5Gcreate_anon(), or + * H5Tcommit_anon(). + * - To add additional structure to an existing + * file so that, for example, an object can be shared among + * multiple groups. + * + * \p lcpl and \p lapl are the link creation and access property lists + * associated with the new link. + * + * \par Example: + * To create a new link to an object while simultaneously creating + * missing intermediate groups: Suppose that an application must + * create the group C with the path /A/B01/C but may not know + * at run time whether the groups A and B01 exist. The following + * code ensures that those groups are created if they are missing: + * \par + * \code + * + * // Creates a link creation property list (LCPL). + * hid_t lcpl_id = H5Pcreate(H5P_LINK_CREATE); + * + * // Sets "create missing intermediate groups" property in that LCPL. + * int status = H5Pset_create_intermediate_group(lcpl_id, TRUE); + * + * // Creates a group without linking it into the file structure. + * hid_t gid = H5Gcreate_anon(file_id, H5P_DEFAULT, H5P_DEFAULT); + * + * // Links group into file structure. + * status = H5Olink(gid, file_id, "/A/B01/C", lcpl_id, H5P_DEFAULT); + * + * \endcode + * + * \par + * Note that unless the object is intended to be temporary, + * the H5O_LINK call is mandatory if an object created with one + * of the H5*_CREATE_ANON functions (or with H5T_COMMIT_ANON) + * is to be retained in the file; without an H5O_LINK call, + * the object will not be linked into the HDF5 file structure + * and will be deleted when the file is closed. + * + * \version 1.8.1 Fortran subroutine introduced in this release. + * + * \since 1.8.0 + * + */ H5_DLL herr_t H5Olink(hid_t obj_id, hid_t new_loc_id, const char *new_name, hid_t lcpl_id, hid_t lapl_id); + +/** + *------------------------------------------------------------------------- + * \ingroup H5O + * + * \brief Increments an object reference count + * + * \fgdta_loc_obj_id{object_id} + * + * \return \herr_t + * + * \details H5Oincr_refcount() increments the hard link reference count for an object. + * It should be used any time a user-defined link that references + * an object by address is added. When the link is deleted, + * H5Odecr_refcount() should be used. + * + * An object’s reference count is the number of hard links in the + * file that point to that object. See the “Programming Model” + * section of the HDF5 Groups chapter in the -- <em>HDF5 User’s Guide</em> + * for a more complete discussion of reference counts. + * + * If a user application needs to determine an object’s reference + * count, an H5Oget_info() call is required; the reference count + * is returned in the \c rc field of the #H5O_info_t \c struct. + * + * \warning This function must be used with care! + * \warning Improper use can lead to inaccessible data, wasted space in the file, + * or <b><em>file corruption</em></b>. + * + * \version 1.8.11 Fortran subroutine introduced in this release. + * + * \since 1.8.0 + * + */ H5_DLL herr_t H5Oincr_refcount(hid_t object_id); + +/** + *------------------------------------------------------------------------- + * \ingroup H5O + * + * \brief Decrements an object reference count + * + * \fgdta_loc_obj_id{object_id} + * + * \return \herr_t + * + * \details H5Odecr_refcount() decrements the hard link reference count for an object. + * It should be used any time a user-defined link that references + * an object by address is deleted. In general, H5Oincr_refcount() will have + * been used previously, when the link was created. + * + * An object’s reference count is the number of hard links in the + * file that point to that object. See the “Programming Model” + * section of the HDF5 Groups chapter in the <em>HDF5 User’s Guide</em> + * for a more complete discussion of reference counts. + * + * If a user application needs to determine an object’s reference + * count, an H5Oget_info() call is required; the reference count + * is returned in the \c rc field of the #H5O_info_t \c struct. + * + * \warning This function must be used with care! + * \warning Improper use can lead to inaccessible data, wasted space in the file, + * or <b><em>file corruption</em></b>. + * + * \version 1.8.11 Fortran subroutine introduced in this release. + * + * \since 1.8.0 + * + */ H5_DLL herr_t H5Odecr_refcount(hid_t object_id); + +/** + *------------------------------------------------------------------------- + * \ingroup H5O + * + * \brief Copies an object in an HDF5 file + * + * \param[in] src_loc_id Object identifier indicating the location of the + * source object to be copied + * \param[in] src_name Name of the source object to be copied + * \param[in] dst_loc_id Location identifier specifying the destination + * \param[in] dst_name Name to be assigned to the new copy + * \param[in] ocpypl_id Object copy property list + * \lcpl_id + * + * \return \herr_t + * + * \details H5Ocopy() copies the group, dataset or committed datatype + * specified by \p src_name from the file or group specified by + * \p src_loc_id to the destination location \p dst_loc_id. + * + * The destination location, as specified in dst_loc_id, may + * be a group in the current file or a location in a different + * file. If dst_loc_id is a file identifier, the copy will be + * placed in that file’s root group. + * + * The copy will be created with the path specified in \p dst_name, + * which must not pre-exist in the destination location. If + * \p dst_name already exists at the location \p dst_loc_id, + * H5Ocopy() will fail. If \p dst_name is an absolute path, + * the copy will be created relative to the file’s root group. + * + * The copy of the object is created with the property lists + * specified by \p ocpypl_id and \p lcpl_id. #H5P_DEFAULT can be passed + * in for these property lists. The default behavior: + * + * - of the link creation property list is to NOT create + * intermediate groups. + * - of the flags specified by the object creation property list + * is described in H5Pset_copy_object(). + * + * These property lists or flags can be modified to govern the + * behavior of H5Ocopy() as follows: + * + * - A flag controlling the creation of intermediate groups that + * may not yet exist is set in the link creation property list + * \p lcpl_id with H5Pset_create_intermediate_group(). + * + * - Copying of committed datatypes can be tuned through the use + * of H5Pset_copy_object(), H5Padd_merge_committed_dtype_path(), + * H5Pset_mcdt_search_cb(), and related functions. + * + * - Flags controlling other aspects of object copying are set in the + * object copy property list \p ocpypl_id with H5Pset_copy_object(). + * + * H5Ocopy() will always try to make a copy of the object specified + * in \p src_name. + * + * - If the object specified by \p src_name is a group containing a + * soft or external link, the default is that the new copy will + * contain a soft or external link with the same value as the + * original. See H5Pset_copy_object() for optional settings. + * + * - If the path specified in \p src_name is or contains a soft link + * or an external link, H5Ocopy() will copy the target object. + * Use H5Lcopy() if the intent is to create a new soft or external + * link with the same value as the original link. + * + * H5Ocopy() can be used to copy an object in an HDF5 file. If + * an object has been changed since it was opened, it should be + * written back to the file before using H5Ocopy(). The object + * can be written back either by closing the object (H5Gclose(), + * H5Oclose(), H5Dclose(), or H5Tclose()) or by flushing + * the HDF5 file (H5Fflush()). + * + * \par See Also: + * - Functions to modify the behavior of H5Ocopy(): + * - H5Padd_merge_committed_dtype_path() + * - H5Pset_copy_object() + * - H5Pset_create_intermediate_group() + * - H5Pset_mcdt_search_cb() + * - Copying Committed Datatypes with #H5Ocopy - A comprehensive + * discussion of copying committed datatypes (PDF) in + * Advanced Topics in HDF5 + * + * \version 1.8.9 Fortran subroutine introduced in this release. + * + * \since 1.8.0 + * + */ H5_DLL herr_t H5Ocopy(hid_t src_loc_id, const char *src_name, hid_t dst_loc_id, const char *dst_name, hid_t ocpypl_id, hid_t lcpl_id); +/** + * -------------------------------------------------------------------------- + * \ingroup ASYNC + * \async_variant_of{H5Ocopy} + */ +H5_DLL herr_t H5Ocopy_async(const char *app_file, const char *app_func, unsigned app_line, hid_t src_loc_id, + const char *src_name, hid_t dst_loc_id, const char *dst_name, hid_t ocpypl_id, + hid_t lcpl_id, hid_t es_id); + +/** + *------------------------------------------------------------------------- + * \ingroup H5O + * + * \brief Sets comment for specified object + * + * \fgdta_loc_obj_id{obj_id} + * \param[in] comment The new comment + * + * \return \herr_t + * + * \details H5Oset_comment() sets the comment for the specified object + * to the contents of \p comment. Any previously existing comment + * is overwritten. + * + * The target object is specified by an identifier, \p obj_id. + * If \p comment is the empty string or a null pointer, any existing + * comment message is removed from the object. + * + * Comments should be relatively short, null-terminated, ASCII strings. + * + * Comments can be attached to any object that has an object + * header. Datasets, groups, and committed (named) datatypes have + * object headers. Symbolic links do not have object headers. + * + * If a comment is being added to an object attribute, this comment + * will be attached to the object to which the attribute belongs + * and not to the attribute itself. + * + * \version 1.8.11 Fortran subroutine introduced in this release. + * + * \since 1.8.0 + * + */ H5_DLL herr_t H5Oset_comment(hid_t obj_id, const char *comment); + +/** + *------------------------------------------------------------------------- + * \ingroup H5O + * + * \brief Sets comment for specified object + * + * \fgdta_loc_obj_id{loc_id} + * \param[in] name Name of the object whose comment is to be set or reset + * \param[in] comment The new comment + * \lapl_id + * + * \return \herr_t + * + * \details H5Oset_comment_by_name() sets the comment for the specified object + * to the contents of \p comment. Any previously existing comment + * is overwritten. + * + * The target object is specified by \p loc_id and \p name. + * \p loc_id can specify any object in the file. + * \p name can be one of the following: + * + * - The name of the object specified as a path relative to \p loc_id + * - An absolute name of the object, starting from \c /, the file’s root group + * - A dot (\c .), if \p loc_id fully specifies the object + * + * If \p comment is the empty string or a null pointer, any existing + * comment message is removed from the object. + * + * Comments should be relatively short, null-terminated, ASCII strings. + * + * Comments can be attached to any object that has an object + * header. Datasets, groups, and committed (named) datatypes have + * object headers. Symbolic links do not have object headers. + * + * If a comment is being added to an object attribute, this comment + * will be attached to the object to which the attribute belongs + * and not to the attribute itself. + * + * \p lapl_id contains a link access property list identifier. A + * link access property list can come into play when traversing + * links to access an object. + * + * \version 1.8.11 Fortran subroutine introduced in this release. + * + * \since 1.8.0 + * + */ H5_DLL herr_t H5Oset_comment_by_name(hid_t loc_id, const char *name, const char *comment, hid_t lapl_id); + +/** + *------------------------------------------------------------------------- + * \ingroup H5O + * + * \brief Retrieves comment for specified object + * + * \fgdta_loc_obj_id{obj_id} + * \param[out] comment The comment + * \param[in] bufsize Anticipated required size of the comment buffer + * + * \return Upon success, returns the number of characters in the + * comment, not including the \c NULL terminator, or zero (\c 0) if + * the object has no comment. The value returned may be larger + * than \p bufsize. Otherwise returns a negative value. + * + * \details H5Oget_comment() retrieves the comment for the specified object in + * the buffer \p comment. + * + * The target object is specified by an identifier, \p object_id. + * + * The size in bytes of the buffer \p comment, including the \c NULL + * terminator, is specified in \p bufsize. If \p bufsize is unknown, + * a preliminary H5Oget_comment() call with the pointer \p comment + * set to \c NULL will return the size of the comment <em>without</em> + * the \c NULL terminator. + * + * If \p bufsize is set to a smaller value than described above, + * only \p bufsize bytes of the comment, without a \c NULL terminator, + * are returned in \p comment. + * + * If an object does not have a comment, the empty string is + * returned in \p comment. + * + * \version 1.8.11 Fortran subroutine introduced in this release. + * + * \since 1.8.0 + * + */ H5_DLL ssize_t H5Oget_comment(hid_t obj_id, char *comment, size_t bufsize); + +/** + *------------------------------------------------------------------------- + * \ingroup H5O + * + * \brief Retrieves comment for specified object + * + * \fgdta_loc_obj_id{loc_id} + * \param[in] name Name of the object whose comment is to be retrieved + * \param[out] comment The comment + * \param[in] bufsize Anticipated required size of the \p comment buffer + * \lapl_id + * + * \return Upon success, returns the number of characters in the comment, + * not including the \c NULL terminator, or zero (\c 0) if the object + * has no comment. The value returned may be larger than \c bufsize. + * Otherwise returns a negative value. + * + * \details H5Oget_comment_by_name() retrieves the comment for an object + * in the buffer \p comment. + * + * The target object is specified by \p loc_id and \p name. + * \p loc_id can specify any object in the file. + * \p name can be one of the following: + * + * - The name of the object relative to \p loc_id + * - An absolute name of the object, starting from \c /, the file’s root group + * - A dot (\c .), if \p loc_id fully specifies the object + * + * The size in bytes of the comment, including the \c NULL terminator, + * is specified in \p bufsize. If \p bufsize is unknown, a preliminary + * H5Oget_comment_by_name() call with the pointer \p comment set + * to \c NULL will return the size of the comment <em>without</em> + * the \c NULL terminator. + * + * If \p bufsize is set to a smaller value than described above, + * only \p bufsize bytes of the comment, without a \c NULL terminator, + * are returned in \p comment. + * + * If an object does not have a comment, the empty string is + * returned in \p comment. + * + * \p lapl_id contains a link access property list identifier. A + * link access property list can come into play when traversing + * links to access an object. + * + * \version 1.8.11 Fortran subroutine introduced in this release. + * + * \since 1.8.0 + * + */ H5_DLL ssize_t H5Oget_comment_by_name(hid_t loc_id, const char *name, char *comment, size_t bufsize, hid_t lapl_id); -H5_DLL herr_t H5Ovisit3(hid_t obj_id, H5_index_t idx_type, H5_iter_order_t order, H5O_iterate2_t op, - void *op_data, unsigned fields); -H5_DLL herr_t H5Ovisit_by_name3(hid_t loc_id, const char *obj_name, H5_index_t idx_type, - H5_iter_order_t order, H5O_iterate2_t op, void *op_data, unsigned fields, - hid_t lapl_id); -H5_DLL herr_t H5Oclose(hid_t object_id); -H5_DLL herr_t H5Oflush(hid_t obj_id); -H5_DLL herr_t H5Orefresh(hid_t oid); -H5_DLL herr_t H5Odisable_mdc_flushes(hid_t object_id); -H5_DLL herr_t H5Oenable_mdc_flushes(hid_t object_id); -H5_DLL herr_t H5Oare_mdc_flushes_disabled(hid_t object_id, hbool_t *are_disabled); -H5_DLL herr_t H5Otoken_cmp(hid_t loc_id, const H5O_token_t *token1, const H5O_token_t *token2, - int *cmp_value); -H5_DLL herr_t H5Otoken_to_str(hid_t loc_id, const H5O_token_t *token, char **token_str); -H5_DLL herr_t H5Otoken_from_str(hid_t loc_id, const char *token_str, H5O_token_t *token); + +/** + *------------------------------------------------------------------------- + * \ingroup H5O + * + * \brief Recursively visits all objects accessible from a specified object + * + * \fgdta_loc_obj_id{obj_id} + * \idx_type + * \order + * \param[in] op Callback function passing data regarding the object + * to the calling application + * \param[in] op_data User-defined pointer to data required by the application + * for its processing of the object + * \param[in] fields Flags specifying the fields to be retrieved to the + * callback \p op + * + * \return On success, returns the return value of the first operator + * that returns a positive value, or zero if all members were + * processed with no operator returning non-zero. + * + * \return On failure, returns a negative value if something goes wrong + * within the library, or the first negative value returned by + * an operator. + * + * \details H5Ovisit3() is a recursive iteration function to visit the + * object \p obj_id and, if \p obj_id is a group, all objects in + * and below it in an HDF5 file, thus providing a mechanism for + * an application to perform a common set of operations across + * all of those objects or a dynamically selected subset. + * For non-recursive iteration across the members of a group, + * see H5Literate2(). + * + * If \p obj_id is a group identifier, that group serves as the + * root of a recursive iteration. If \p obj_id is a file identifier, + * that file’s root group serves as the root of the recursive + * iteration. If \p obj_id is an attribute identifier, + * then the object where the attribute is attached will be iterated. + * If \p obj_id is any other type of object, such as a dataset or + * named datatype, there is no iteration. + * + * Two parameters are used to establish the iteration: \p idx_type + * and \p order. + * + * \p idx_type specifies the index to be used. If the links in + * a group have not been indexed by the index type, they will + * first be sorted by that index then the iteration will begin; + * if the links have been so indexed, the sorting step will be + * unnecessary, so the iteration may begin more quickly. Valid + * values include the following: + * + * \indexes + * + * Note that the index type passed in \p idx_type is a + * <em>best effort</em> setting. If the application passes in + * a value indicating iteration in creation order and a group is + * encountered that was not tracked in creation order, that group + * will be iterated over in alpha-numeric order by name, or + * <em>name order</em>. (<em>Name order</em> is the native order + * used by the HDF5 library and is always available.) + * + * \p order specifies the order in which objects are to be inspected + * along the index specified in \p idx_type. Valid values include + * the following: + * + * \orders + * + * The prototype of the callback function op is as follows (as + * defined in the source code file H5Opublic.h): + * + * \snippet this H5O_iterate2_t_snip + * + * The parameters of this callback function have the following values + * or meanings: + * <table> + * <tr> + * <td>\c obj</td> + * <td>Object that serves as root of the iteration; + * same value as the H5Ovisit() \p obj_id parameter</td> + * </tr> + * <tr> + * <td>\c name</td> + * <td>Name of object, relative to \c obj, being examined at + * current step of the iteration</td> + * </tr> + * <tr> + * <td>\c info</td> + * <td>H5O_info2_t \c struct containing information + * regarding that object</td> + * </tr> + * <tr> + * <td>\c op_data</td> + * <td>User-defined pointer to data required by the application in + * processing the object; a pass-through of the \c op_data pointer + * provided with the H5Ovisit() function call</td> + * </tr> + * </table> + * + * The H5O_info2_t \c struct is defined in H5Opublic.h as follows: + * \snippet this H5O_info2_t_snip + * + * H5O_token_t is defined in H5public.h as follows: + * \snippet H5public.h H5O_token_t_snip + * + * The #H5O_type_t enum indicates the object type and is + * defined in H5Opublic.h as follows: + * \snippet this H5O_type_t_snip + * + * Note that the object retrieved as indicated by \p obj_id + * refers only to the types specified by #H5O_type_t. + * + * The return values from an operator are: + * - Zero causes the visit iterator to continue, returning zero when all + * group members have been processed. + * - A positive value causes the visit iterator to immediately return that + * positive value, indicating short-circuit success. + * - A negative value causes the visit iterator to immediately return that + * value, indicating failure. + * + * The H5Ovisit3() \p op_data parameter is a user-defined pointer to the data + * required to process objects in the course of the iteration. This pointer + * is passed back to each step of the iteration in the callback + * function’s \p op_data parameter. + * + * The \p fields parameter contains flags to determine which fields will + * be retrieved by the \p op callback function. These flags are defined + * in the H5Opublic.h file: + * \obj_info_fields + * + * H5Lvisit2() and H5Ovisit3() are companion functions: one for + * examining and operating on links; the other for examining + * and operating on the objects that those links point to. Both + * functions ensure that by the time the function completes + * successfully, every link or object below the specified point + * in the file has been presented to the application for whatever + * processing the application requires. These functions assume + * that the membership of the group being iterated over remains + * unchanged through the iteration; if any of the links in the + * group change during the iteration, the resulting behavior + * is undefined. + * + * \note \Bold{Programming Note for C++ Developers Using C Functions:} + * \note If a C routine that takes a function pointer as an argument is + * called from within C++ code, the C routine should be returned + * from normally. + * + * \note Examples of this kind of routine include callbacks such as + * H5Pset_elink_cb() and H5Pset_type_conv_cb() and + * functions such as H5Tconvert() and H5Ewalk2(). + * + * \note Exiting the routine in its normal fashion allows the HDF5 + * C library to clean up its work properly. In other words, if + * the C++ application jumps out of the routine back to the C++ + * “catch” statement, the library is not given the opportunity + * to close any temporary data structures that were set up when + * the routine was called. The C++ application should save some + * state as the routine is started so that any problem that occurs + * might be diagnosed. + * + * \par Example + * An example snippet from test/links.c: + * \snippet links.c H5Ovisit3_snip + * + * \since 1.12.0 + * + */ +H5_DLL herr_t H5Ovisit3(hid_t obj_id, H5_index_t idx_type, H5_iter_order_t order, H5O_iterate2_t op, + void *op_data, unsigned fields); + +/** + *------------------------------------------------------------------------- + * \ingroup H5O + * + * \brief Recursively visits all objects accessible from a specified object + * + * \fgdta_loc_obj_id{loc_id} + * \param[in] obj_name Name of the object, generally relative to + * \p loc_id, that will serve as root of the iteration + * \idx_type + * \order + * \param[in] op Callback function passing data regarding the object + * to the calling application + * \param[in] op_data User-defined pointer to data required by the application + * for its processing of the object + * \param[in] fields Flags specifying the fields to be retrieved to the + * callback function \p op + * \lapl_id + * + * \return On success, returns the return value of the first operator + * that returns a positive value, or zero if all members were + * processed with no operator returning non-zero. + * + * \return On failure, returns a negative value if something goes wrong + * within the library, or the first negative value returned by + * an operator. + * + * \details H5Ovisit_by_name3() is a recursive iteration function to visit + * the object specified by the \p loc_id / \p obj_name parameter + * pair and, if that object is a group, all objects in and below it + * in an HDF5 file, thus providing a mechanism for an application to + * perform a common set of operations across all of those objects or + * a dynamically selected subset. For non-recursive iteration across + * the members of a group, see H5Literate2(). + * + * The object serving as the root of the iteration is specified + * by the \p loc_id / \p obj_name parameter pair. \p loc_id specifies + * a file or an object in a file; if \p loc_id is an attribute identifier, + * the object where the attribute is attached will be used. + * \p obj_name specifies either an object in the file (with an absolute + * name based in the file’s root group) or an object name relative + * to \p loc_id. If \p loc_id fully specifies the object that is to serve + * as the root of the iteration, \p obj_name should be '\c .' (a dot). + * (Note that when \p loc_id fully specifies the object that is to serve + * as the root of the iteration, the user may wish to consider + * using H5Ovisit3() instead of H5Ovisit_by_name3().) + * + * Two parameters are used to establish the iteration: \p idx_type + * and \p order. + * + * \p idx_type specifies the index to be used. If the links in + * a group have not been indexed by the index type, they will + * first be sorted by that index then the iteration will begin; + * if the links have been so indexed, the sorting step will be + * unnecessary, so the iteration may begin more quickly. Valid + * values include the following: + * + * \indexes + * + * Note that the index type passed in \p idx_type is a + * <em>best effort</em> setting. If the application passes in a + * value indicating iteration in creation order and a group is + * encountered that was not tracked in creation order, that group + * will be iterated over in alpha-numeric order by name, or + * <em>name order</em>. (<em>Name order</em> is the native order + * used by the HDF5 library and is always available.) + * + * \p order specifies the order in which objects are to be inspected + * along the index specified in \p idx_type. Valid values include + * the following: + * + * \orders + * + * The prototype of the callback function op is as follows (as + * defined in the source code file H5Opublic.h): + * + * \snippet this H5O_iterate2_t_snip + * + * The parameters of this callback function have the following + * values or meanings: + * <table> + * <tr> + * <td>\c obj</td> + * <td>Object that serves as root of the iteration</td> + * </tr> + * <tr> + * <td>\c name</td> + * <td>Name of object, relative to \c obj, being examined at + * current step of the iteration</td> + * </tr> + * <tr> + * <td>\c info</td> + * <td>H5O_info2_t \c struct containing information + * regarding that object</td> + * </tr> + * <tr> + * <td>\c op_data</td> + * <td>User-defined pointer to data required by the application in + * processing the object</td> + * </tr> + * </table> + * + * The H5O_info2_t \c struct is defined in H5Opublic.h as follows: + * \snippet this H5O_info2_t_snip + * + * H5O_token_t is defined in H5public.h as follows: + * \snippet H5public.h H5O_token_t_snip + * + * The #H5O_type_t enum indicates the object type and is + * defined in H5Opublic.h as follows: + * \snippet this H5O_type_t_snip + * + * The H5Ovisit_by_name3() \p op_data parameter is a user-defined + * pointer to the data required to process objects in the course + * of the iteration. This pointer is passed back to each step of + * the iteration in the callback function’s \p op_data parameter. + * + * \p lapl_id is a link access property list. In the general case, + * when default link access properties are acceptable, this can + * be passed in as #H5P_DEFAULT. An example of a situation that + * requires a non-default link access property list is when + * the link is an external link; an external link may require + * that a link prefix be set in a link access property list + * (see H5Pset_elink_prefix()). + * + * The \p fields parameter contains flags to determine which fields will + * be retrieved by the \p op callback function. These flags are defined + * in the H5Opublic.h file: + * \obj_info_fields + * + * H5Lvisit_by_name2() and H5Ovisit_by_name3() are companion + * functions: one for examining and operating on links; the other + * for examining and operating on the objects that those links point to. + * Both functions ensure that by the time the function completes + * successfully, every link or object below the specified point + * in the file has been presented to the application for whatever + * processing the application requires. + * + * \note \Bold{Programming Note for C++ Developers Using C Functions:} + * \note If a C routine that takes a function pointer as an argument is + * called from within C++ code, the C routine should be returned + * from normally. + * + * \note Examples of this kind of routine include callbacks such as + * H5Pset_elink_cb() and H5Pset_type_conv_cb() and + * functions such as H5Tconvert() and H5Ewalk2(). + * + * \note Exiting the routine in its normal fashion allows the HDF5 + * C library to clean up its work properly. In other words, if + * the C++ application jumps out of the routine back to the C++ + * “catch” statement, the library is not given the opportunity + * to close any temporary data structures that were set up when + * the routine was called. The C++ application should save some + * state as the routine is started so that any problem that occurs + * might be diagnosed. + * + * \par Example + * An example snippet from test/links.c: + * \snippet links.c H5Ovisit_by_name3_snip + * + * \since 1.12.0 + * + */ +H5_DLL herr_t H5Ovisit_by_name3(hid_t loc_id, const char *obj_name, H5_index_t idx_type, + H5_iter_order_t order, H5O_iterate2_t op, void *op_data, unsigned fields, + hid_t lapl_id); + +/** + *------------------------------------------------------------------------- + * \ingroup H5O + * + * \brief Closes an object in an HDF5 file + * + * \obj_id{object_id} + * + * \return \herr_t + * + * \details H5Oclose() closes the group, dataset, or named datatype specified by + * object_id. + * + * This function is the companion to H5Oopen(), and has the same + * effect as calling H5Gclose(), H5Dclose(), or H5Tclose(). + * + * H5Oclose() is not used to close a dataspace, attribute, property + * list, or file. + * + * \version 1.8.8 Fortran subroutine introduced in this release. + * + * \since 1.8.0 + * + */ +H5_DLL herr_t H5Oclose(hid_t object_id); +/** + * -------------------------------------------------------------------------- + * \ingroup ASYNC + * \async_variant_of{H5Oclose} + */ +H5_DLL herr_t H5Oclose_async(const char *app_file, const char *app_func, unsigned app_line, hid_t object_id, + hid_t es_id); + +/** + *------------------------------------------------------------------------- + * \ingroup H5O + * + * \brief Flushes all buffers associated with an HDF5 object to disk + * + * \fgdta_loc_obj_id{obj_id} + * + * \return \herr_t + * + * \details H5Oflush() causes all buffers associated with an object to be immediately + * flushed to disk without removing the data from the cache. + * + * The object associated with \p object_id can be any named object in an + * HDF5 file including a dataset, a group, or a committed datatype. + * + * \note HDF5 does not possess full control over buffering. H5Oflush() + * flushes the internal HDF5 buffers and then asks the operating + * system (the OS) to flush the system buffers for the open + * files. After that, the OS is responsible for ensuring that + * the data is actually flushed to disk. + * + * \par See Also: + * - H5Dflush() + * - H5Drefresh() + * - H5Oflush() + * - H5Grefresh() + * - H5Oflush() + * - H5Orefresh() + * - H5Tflush() + * - H5Trefresh() + * \par + * - \c H5DOappend() + * - H5Fstart_swmr_write() + * - H5Pget_append_flush() + * - H5Pget_object_flush_cb() + * - H5Pset_append_flush() + * - H5Pset_object_flush_cb() + * \par + * - H5Oare_mdc_flushes_disabled() + * - H5Odisable_mdc_flushes() + * - H5Oenable_mdc_flushes() + * + * \since 1.10.0 + * + */ +H5_DLL herr_t H5Oflush(hid_t obj_id); +/** + * -------------------------------------------------------------------------- + * \ingroup ASYNC + * \async_variant_of{H5Oflush} + */ +H5_DLL herr_t H5Oflush_async(const char *app_file, const char *app_func, unsigned app_line, hid_t obj_id, + hid_t es_id); +/** + *------------------------------------------------------------------------- + * \ingroup H5O + * + * \brief Refreshes all buffers associated with an HDF5 object + * + * \fgdta_loc_obj_id{oid} + * + * \return \herr_t + * + * \details H5Orefresh() causes all buffers associated with an object to be cleared + * and immediately re-loaded with updated contents from disk. + * + * This function essentially closes the object, evicts all + * metadata associated with it from the cache, and then re-opens + * the object. The reopened object is automatically re-registered + * with the same identifier. + * + * The object associated with \p oid can be any named object in an + * HDF5 file including a dataset, a group, or a committed datatype. + * + * \since 1.10.0 + * + */ +H5_DLL herr_t H5Orefresh(hid_t oid); +/** + * -------------------------------------------------------------------------- + * \ingroup ASYNC + * \async_variant_of{H5Orefresh} + */ +H5_DLL herr_t H5Orefresh_async(const char *app_file, const char *app_func, unsigned app_line, hid_t oid, + hid_t es_id); + +/** + *------------------------------------------------------------------------- + * \ingroup H5O + * + * \brief Prevents metadata entries for an HDF5 object from being flushed + * from the metadata cache to storage + * + * \param[in] object_id Identifier of the object that will have flushes disabled; + * may be a group, named datatype, or dataset identifier + * + * \return \herr_t + * + * \details H5Odisable_mdc_flushes(), H5Oenable_mdc_flushes() and associated flush + * functions can be used to control the flushing of entries from + * a file’s metadata cache. + * + * This function prevents an object’s or cache’s dirty metadata + * entries from being flushed from the cache by the usual cache + * eviction/flush policy. Instead, users must manually flush the + * cache or entries for individual objects via the appropriate + * H5Fflush(), H5Dflush(), H5Gflush(), H5Tflush(), and H5Oflush() calls. + * + * Metadata cache entries can be controlled at both the individual + * HDF5 object level (datasets, groups, committed datatypes) + * and the entire metadata cache level. + * + * \note HDF5 objects include datasets, groups, and committed datatypes. + * Only #hid_t identifiers that represent these objects can be passed to the function. + * \note Passing in a #hid_t identifier that represents any other HDF5 entity is + * considered an error. + * \note It is an error to pass an HDF5 file identifier + * (obtained from H5Fopen() or H5Fcreate()) + * to this function. + * \note Misuse of this function can cause the cache to exhaust + * available memory. + * \note Objects can be returned to the default automatic flush behavior + * with H5Oenable_mdc_flushes(). + * \note Flush prevention only pertains to new or dirty metadata entries. + * Clean entries can be evicted from the cache. + * \note Calling this function on an object that has already had flushes + * disabled will return an error. + * + * \since 1.10.0 + * + */ +H5_DLL herr_t H5Odisable_mdc_flushes(hid_t object_id); + +/** + *------------------------------------------------------------------------- + * \ingroup H5O + * + * \brief Enables flushing of dirty metadata entries from a file’s metadata cache + * + * \param[in] object_id Identifier of the object that will have flushes re-enabled; + * may be a group, named datatype, or dataset identifier + * + * \return \herr_t + * + * \details H5Oenable_mdc_flushes(), H5Odisable_mdc_flushes() + * and associated flush functions can be used to control the flushing + * of entries from a file’s metadata cache. + * + * This function allows an object or cache’s dirty metadata entries to be + * flushed from the cache by the usual cache eviction/flush policy. + * + * Metadata cache entries can be controlled at both the individual HDF5 + * object level (datasets, groups, committed datatypes) and the entire + * metadata cache level. + * + * + * \note HDF5 objects include datasets, groups, and committed datatypes. + * Only #hid_t identifiers that represent these objects can be + * passed to the function. + * + * \note Passing in a #hid_t identifier that represents any other HDF5 entity + * is considered an error. + * + * \note It is an error to pass an HDF5 file identifier + * (obtained from H5Fopen() or H5Fcreate()) + * to this function. + * + * \note Using this function on an object that has not had flushes disabled + * is considered an error. The state of an object can be determined + * with H5Oare_mdc_flushes_disabled(). + * + * \note An object will be returned to the default flush algorithm when it is closed. + * + * \note All objects will be returned to the default flush algorithm when + * the file is closed. + * + * \note An object’s entries will not necessarily be flushed as a result of + * calling this function. + * + * \since 1.10.0 + * + */ +H5_DLL herr_t H5Oenable_mdc_flushes(hid_t object_id); + +/** + *------------------------------------------------------------------------- + * \ingroup H5O + * + * \brief Retrieves comment for specified object + * + * \param[in] object_id Identifier of an object in the cache; + * may be a group, named datatype, or dataset identifier + * \param[out] are_disabled Flushes enabled/disabled + * + * \return \p are_disabled will be set to \c 1 if an object has had flushes disabled + * and \c 0 if it has not had flushes disabled. + * \return \herr_t + * + * \details H5Oare_mdc_flushes_disabled() determines if an HDF5 object (dataset, group, committed + * datatype) has had flushes of metadata entries disabled. + * + * The H5Oenable_mdc_flushes(), H5Odisable_mdc_flushes() and + * associated flush functions can be used to control the flushing of + * entries from a file’s metadata cache. Metadata cache entries can be controlled + * at both the individual HDF5 object level (datasets, groups, + * committed datatypes) and the entire metadata cache level. + * + * \note HDF5 objects include datasets, groups, and committed datatypes. + * Only #hid_t identifiers that represent these objects can be passed to the function. + * \note Passing in a #hid_t identifier that represents any other HDF5 entity is + * considered an error. + * \note It is an error to pass an HDF5 file identifier + * (obtained from H5Fopen() or H5Fcreate()) to this function. + * + * \since 1.10.0 + * + */ +H5_DLL herr_t H5Oare_mdc_flushes_disabled(hid_t object_id, hbool_t *are_disabled); + +/** + *------------------------------------------------------------------------- + * \ingroup H5O + * + * \brief Compares two VOL connector object tokens + * + * \fgdta_loc_obj_id{loc_id} + * \param[in] token1 First object token + * \param[in] token2 Second object token + * \param[out] cmp_value Comparison value + * + * \return \herr_t + * + * \details H5Otoken_cmp() compares two VOL connector object tokens, \p token1 + * and \p token2 for the file or group identifier specified by \p loc_id. + * Both object tokens must be from the same VOL connector class. + * + * H5O_token_t is defined in H5public.h as follows: + * \snippet H5public.h H5O_token_t_snip + * + * A comparison value, \p cmp_value, is returned, which indicates the + * result of the comparison: + * + * <table> + * <tr> + * <th>cmp_value</th> + * <th>Result</th> + * </tr> + * <tr> + * <td> > 0</td> + * <td> \p token1 > \p token2</td> + * </tr> + * <tr> + * <td> < 0</td> + * <td>\p token1 < \p token2</td> + * </tr> + * <tr> + * <td>0</td> + * <td>\p token1 = \p token2</td> + * </tr> + * </table> + * + * \par Example + * An example snippet from test/links.c: + * \snippet links.c H5Otoken_cmp_snip + * + * \since 1.12.0 + * + */ +H5_DLL herr_t H5Otoken_cmp(hid_t loc_id, const H5O_token_t *token1, const H5O_token_t *token2, + int *cmp_value); + +/** + *------------------------------------------------------------------------- + * \ingroup H5O + * + * \brief Serializes a connector's object token into a string + * + * \fgdta_loc_obj_id{loc_id} + * \param[in] token Connector object token + * \param[out] token_str String for connector object token \p token + * + * \return \herr_t + * + * \details H5Otoken_to_str() serializes a connector's object token specified by + * \p token and the location identifier for the object, \p loc_id, + * into a string, \p token_str. + * + * \since 1.12.0 + * + */ +H5_DLL herr_t H5Otoken_to_str(hid_t loc_id, const H5O_token_t *token, char **token_str); + +/** + *------------------------------------------------------------------------- + * \ingroup H5O + * + * \brief Deserializes a string into a connector object token + * + * \fgdta_loc_obj_id{loc_id} + * \param[in] token_str Object token string + * \param[out] token Connector object token + * + * \return \herr_t + * + * \details H5Otoken_from_str() deserializes a string, \p token_str, into a + * connector object token, \p token, for the object specified by the + * location identifier, \p loc_id. + * + * \since 1.12.0 + * + */ +H5_DLL herr_t H5Otoken_from_str(hid_t loc_id, const char *token_str, H5O_token_t *token); + +/* API Wrappers for async routines */ +/* (Must be defined _after_ the function prototype) */ +/* (And must only defined when included in application code, not the library) */ +#ifndef H5O_MODULE +#define H5Oopen_async(...) H5Oopen_async(__FILE__, __func__, __LINE__, __VA_ARGS__) +#define H5Oopen_by_idx_async(...) H5Oopen_by_idx_async(__FILE__, __func__, __LINE__, __VA_ARGS__) +#define H5Oget_info_by_name_async(...) H5Oget_info_by_name_async(__FILE__, __func__, __LINE__, __VA_ARGS__) +#define H5Oclose_async(...) H5Oclose_async(__FILE__, __func__, __LINE__, __VA_ARGS__) +#define H5Oflush_async(...) H5Oflush_async(__FILE__, __func__, __LINE__, __VA_ARGS__) +#define H5Orefresh_async(...) H5Orefresh_async(__FILE__, __func__, __LINE__, __VA_ARGS__) +#define H5Ocopy_async(...) H5Ocopy_async(__FILE__, __func__, __LINE__, __VA_ARGS__) + +/* Define "wrapper" versions of function calls, to allow compile-time values to + * be passed in by language wrapper or library layer on top of HDF5. + */ +#define H5Oopen_async_wrap H5_NO_EXPAND(H5Oopen_async) +#define H5Oopen_by_idx_async_wrap H5_NO_EXPAND(H5Oopen_by_idx_async) +#define H5Oget_info_by_name_async_wrap H5_NO_EXPAND(H5Oget_info_by_name_async) +#define H5Oclose_async_wrap H5_NO_EXPAND(H5Oclose_async) +#define H5Oflush_async_wrap H5_NO_EXPAND(H5Oflush_async) +#define H5Orefresh_async_wrap H5_NO_EXPAND(H5Orefresh_async) +#define H5Ocopy_async_wrap H5_NO_EXPAND(H5Ocopy_async) +#endif /* The canonical 'undefined' token value */ #define H5O_TOKEN_UNDEF (H5OPEN H5O_TOKEN_UNDEF_g) @@ -245,55 +1915,978 @@ H5_DLLVAR const H5O_token_t H5O_TOKEN_UNDEF_g; /* Typedefs */ -/* A struct that's part of the H5G_stat_t structure (deprecated) */ +//! <!-- [H5O_stat_t_snip] --> +/** + * A struct that's part of the \ref H5G_stat_t structure + * \deprecated + */ typedef struct H5O_stat_t { - hsize_t size; /* Total size of object header in file */ - hsize_t free; /* Free space within object header */ - unsigned nmesgs; /* Number of object header messages */ - unsigned nchunks; /* Number of object header chunks */ + hsize_t size; /**< Total size of object header in file */ + hsize_t free; /**< Free space within object header */ + unsigned nmesgs; /**< Number of object header messages */ + unsigned nchunks; /**< Number of object header chunks */ } H5O_stat_t; +//! <!-- [H5O_stat_t_snip] --> -/* Information struct for object */ -/* (For H5Oget_info/H5Oget_info_by_name/H5Oget_info_by_idx versions 1 & 2) */ +//! <!-- [H5O_info1_t_snip] --> +/** + * Information struct for object (For H5Oget_info(), H5Oget_info_by_name(), + * H5Oget_info_by_idx() versions 1 & 2.) + */ typedef struct H5O_info1_t { - unsigned long fileno; /* File number that object is located in */ - haddr_t addr; /* Object address in file */ - H5O_type_t type; /* Basic object type (group, dataset, etc.) */ - unsigned rc; /* Reference count of object */ - time_t atime; /* Access time */ - time_t mtime; /* Modification time */ - time_t ctime; /* Change time */ - time_t btime; /* Birth time */ - hsize_t num_attrs; /* # of attributes attached to object */ - H5O_hdr_info_t hdr; /* Object header information */ + unsigned long fileno; /**< File number that object is located in */ + haddr_t addr; /**< Object address in file */ + H5O_type_t type; /**< Basic object type (group, dataset, etc.) */ + unsigned rc; /**< Reference count of object */ + time_t atime; /**< Access time */ + time_t mtime; /**< Modification time */ + time_t ctime; /**< Change time */ + time_t btime; /**< Birth time */ + hsize_t num_attrs; /**< # of attributes attached to object */ + H5O_hdr_info_t hdr; /**< Object header information */ /* Extra metadata storage for obj & attributes */ struct { - H5_ih_info_t obj; /* v1/v2 B-tree & local/fractal heap for groups, B-tree for chunked datasets */ - H5_ih_info_t attr; /* v2 B-tree & heap for attributes */ + H5_ih_info_t obj; /**< v1/v2 B-tree & local/fractal heap for groups, B-tree for chunked datasets */ + H5_ih_info_t attr; /**< v2 B-tree & heap for attributes */ } meta_size; } H5O_info1_t; +//! <!-- [H5O_info1_t_snip] --> -/* Prototype for H5Ovisit/H5Ovisit_by_name() operator (versions 1 & 2) */ +//! <!-- [H5O_iterate1_t_snip] --> +/** + * Prototype for H5Ovisit(), H5Ovisit_by_name() operator (versions 1 & 2) + */ typedef herr_t (*H5O_iterate1_t)(hid_t obj, const char *name, const H5O_info1_t *info, void *op_data); +//! <!-- [H5O_iterate1_t_snip] --> /* Function prototypes */ -H5_DLL hid_t H5Oopen_by_addr(hid_t loc_id, haddr_t addr); + +/** + *------------------------------------------------------------------------- + * \ingroup H5O + * + * \brief Opens an object using its address within an HDF5 file. + * + * \fgdta_loc_obj_id{loc_id} + * \param[in] addr Object's address in the file + * + * \return \hid_tv{object} + * + * \deprecated As of HDF5-1.12 this function has been deprecated in favor of + * the function H5Oopen_by_token(). + * + * \details H5Oopen_by_addr() opens a group, dataset, or committed (named) datatype using its + * address within an HDF5 file, \p addr. The resulting opened object is identical to + * an object opened with H5Oopen() and should be closed with H5Oclose() or an + * object-type-specific closing function (such as H5Gclose()) when no longer needed. + * + * \p loc_id is a location identifier in the file. + * + * The object’s address within the file, \p addr, is the byte offset of the first byte + * of the object header from the beginning of the HDF5 file space, i.e., from the + * beginning of the super block (see the “HDF5 Storage Model” section of the The + * HDF5 Data Model and File Structure chapter of the <em>HDF5 User's Guide</em>.) + * + * \p addr can be obtained via either of two function calls. H5Gget_objinfo() returns + * the object’s address in the \c objno field of the H5G_stat_t \c struct; + * H5Lget_info() returns the address in the \c address field of the #H5L_info_t \c struct. + * + * The address of the HDF5 file on a physical device has no effect on H5Oopen_by_addr(), + * nor does the use of any file driver. As stated above, the object address is its + * offset within the HDF5 file; HDF5’s file drivers will transparently map this to an + * address on a storage device. + * + * \warning This function must be used with care! + * \warning Improper use can lead to inaccessible data, wasted space in the file, + * or <b><em>file corruption</em></b>. + * \warning This function is dangerous if called on an invalid address. The risk can be safely + * overcome by retrieving the object address with H5Gget_objinfo() or H5Lget_info() + * immediately before calling H5Oopen_by_addr(). The immediacy of the operation can be + * important; if time has elapsed and the object has been deleted from the file, + * the address will be invalid and file corruption can result. + * + * \version 1.8.4 Fortran subroutine added in this release. + * + * \since 1.8.0 + * + */ +H5_DLL hid_t H5Oopen_by_addr(hid_t loc_id, haddr_t addr); + +/** + *------------------------------------------------------------------------- + * \ingroup H5O + * + * \brief Retrieves the metadata for an object specified by an identifier + * + * \fgdta_loc_obj_id{loc_id} + * \param[out] oinfo Buffer in which to return object information + * + * \return \herr_t + * + * \deprecated As of HDF5-1.12 this function has been deprecated in favor of + * the function H5Oget_info3() or the macro #H5Oget_info. + * + * \details H5Oget_info1() specifies an object by its identifier, \p loc_id , and + * retrieves the metadata describing that object in \p oinfo , + * defined as a \c struct of type H5O_info1_t : + * + * \snippet this H5O_info1_t_snip + * + * Note the following about H5O_info1_t : + * - Of the four time fields (\c atime, \c mtime, \c ctime, and \c btime) + * only \c ctime has been implemented. + * - The \c atime value is the last time the object was read or written. + * - The \c mtime value is the last time the raw data in the object was changed. + * - The \c ctime value is the last time the metadata for the object was changed. + * - The \c btime value is the time the object was created. + * - The fields nested in the \c meta_size field are for internal library use only. + * + * The #H5O_type_t \c enum indicates the object type and + * is defined in H5Opublic.h as follows: + * \snippet this H5O_type_t_snip + * + * Note that the object retrieved as indicated by \p loc_id + * refers only to the types specified by #H5O_type_t. + * + * An H5O_hdr_info_t \c struct holds object header metadata and is + * defined in H5Opublic.h as follows: + * \snippet this H5O_hdr_info_t_snip + * + * Valid values for the \c version field are \c H5O_VERSION_1 and \c H5O_VERSION_2. + * Version 2 of the object header is smaller and more efficient than version 1. + * + * Please be aware that the information held by H5O_hdr_info_t may only be useful to + * developers with extensive HDF5 experience. + * + * \note If you are iterating through a lot of different objects to + * retrieve information via the H5Oget_info() family of routines, + * you may see memory building up. This can be due to memory + * allocation for metadata such as object headers and messages + * when the iterated objects are put into the metadata cache. + * \note + * If the memory buildup is not desirable, you can configure a + * smaller cache via H5Fset_mdc_config() or set the file access + * property list via H5Pset_mdc_config(). A smaller sized cache + * will force metadata entries to be evicted from the cache, + * thus freeing the memory associated with the entries. + * + * \version 1.10.5 The macro #H5Oget_info was removed and the function + * H5Oget_info1() was copied to H5Oget_info(). + * \version 1.10.3 Function H5Oget_info() was copied to H5Oget_info1(), + * and the macro #H5Oget_info was created. + * \version 1.8.15 Added a note about the valid values for the \c version + * field in the H5O_hdr_info_t structure. + * \version 1.8.11 Fortran subroutine introduced in this release. + * \version 1.8.10 Added #H5O_type_t structure to the Description section. \n + * Separated H5O_hdr_info_t structure from #H5O_info_t in the + * Description section. \n + * Clarified the definition and implementation of the time fields. + * + * \since 1.8.0 + * + */ H5_DLL herr_t H5Oget_info1(hid_t loc_id, H5O_info1_t *oinfo); + +/** + *------------------------------------------------------------------------- + * \ingroup H5O + * + * \brief Retrieves the metadata for an object, identifying the object + * by location and relative name + * + * \fgdta_loc_obj_id{loc_id} + * \param[in] name Name of group, relative to \p loc_id + * \param[out] oinfo Buffer in which to return object information + * \lapl_id + * + * \return \herr_t + * + * \deprecated As of HDF5-1.12 this function has been deprecated in favor of + * the function H5Oget_info_by_name2() or the macro #H5Oget_info_by_name. + * + * \details H5Oget_info_by_name1() specifies an object’s location and name, \p loc_id + * and \p name, respectively, and retrieves the metadata describing that object + * in \p oinfo, an H5O_info1_t \c struct. + * + * The \c struct H5O_info1_t is defined in H5Opublic.h and described + * in the H5Oget_info1() function entry. + * + * The link access property list, \p lapl_id, is not currently used; + * it should be passed in as #H5P_DEFAULT. + * + * \version 1.10.5 The macro #H5Oget_info_by_name was removed and the function + * H5Oget_info_by_name1() was copied to H5Oget_info_by_name(). + * \version 1.10.3 Function H5Oget_info_by_name() was copied to H5Oget_info_by_name1() + * and the macro #H5Oget_info_by_name was created. + * \version 1.8.8 Fortran 2003 subroutine and \c h5o_info_t derived type introduced + * in this release. + * + * \since 1.8.0 + * + */ H5_DLL herr_t H5Oget_info_by_name1(hid_t loc_id, const char *name, H5O_info1_t *oinfo, hid_t lapl_id); + +/** + *------------------------------------------------------------------------- + * \ingroup H5O + * + * \brief Retrieves the metadata for an object, identifying the object + * by an index position + * + * \fgdta_loc_obj_id{loc_id} + * \param[in] group_name Name of group in which object is located + * \idx_type + * \order + * \param[in] n Position within the index + * \param[out] oinfo Buffer in which to return object information + * \lapl_id + * + * \return \herr_t + * + * \deprecated As of HDF5-1.12 this function has been deprecated in favor of + * the function H5Oget_info_by_idx3() or the macro H5Oget_info_by_idx(). + * + * \details H5Oget_info_by_idx1() retrieves the metadata describing an + * object in the \c struct \p oinfo, as specified by the location, + * \p loc_id, group name, \p group_name, the index by which objects + * in that group are tracked, \p idx_type, the order by which the + * index is to be traversed, \p order, and an object’s position + * \p n within that index. + * + * If \p loc_id fully specifies the group in which the object resides, + * \p group_name can be a dot (\c .). + * + * \p idx_type is of type #H5_index_t, defined in H5public.h as: + * \snippet H5public.h H5_index_t_snip + * + * \p order is of type #H5_iter_order_t defined in H5public.h as: + * \snippet H5public.h H5_iter_order_t_snip + * + * \p oinfo, in which the object information is returned, is a \c struct of + * type H5O_info1_t . + * \snippet this H5O_info1_t_snip + * + * The link access property list, \c lapl_id, is not currently used; + * it should be passed in as #H5P_DEFAULT. + * + * \version 1.10.5 The macro #H5Oget_info_by_idx was removed and the function + * H5Oget_info_by_idx() was copied to H5Oget_info_by_idx1(). + * \version 1.10.3 Function H5Oget_info_by_idx() was copied to H5Oget_info_by_idx1() + * and the macro #H5Oget_info_by_idx was created. + * \version 1.8.11 Fortran subroutine introduced in this release. + * + * \since 1.8.0 + * + */ H5_DLL herr_t H5Oget_info_by_idx1(hid_t loc_id, const char *group_name, H5_index_t idx_type, H5_iter_order_t order, hsize_t n, H5O_info1_t *oinfo, hid_t lapl_id); + +/** + *------------------------------------------------------------------------- + * \ingroup H5O + * + * \brief Retrieves the metadata for an object specified by an identifier + * + * \fgdta_loc_obj_id{loc_id} + * \param[out] oinfo Buffer in which to return object information + * \param[in] fields Flags specifying the fields to include in \p oinfo + * + * \return \herr_t + * + * \deprecated As of HDF5-1.12 this function has been deprecated in favor of + * the function H5Oget_info3() or the macro H5Oget_info(). + * + * \details H5Oget_info2() specifies an object by its identifier, \p loc_id , and + * retrieves the metadata describing that object in \p oinfo , an H5O_info1_t \c struct. + * This \c struct type is described in H5Oget_info1(). + * + * The \p fields parameter contains flags to determine which fields will be filled in + * the H5O_info1_t \c struct returned in \p oinfo. + * These flags are defined in the H5Opublic.h file: + * + * \obj_info_fields + * + * \note If you are iterating through a lot of different objects to + * retrieve information via the H5Oget_info() family of routines, + * you may see memory building up. This can be due to memory + * allocation for metadata such as object headers and messages + * when the iterated objects are put into the metadata cache. + * \note + * If the memory buildup is not desirable, you can configure a + * smaller cache via H5Fset_mdc_config() or set the file access + * property list via H5Pset_mdc_config(). A smaller sized cache + * will force metadata entries to be evicted from the cache, + * thus freeing the memory associated with the entries. + * + * \since 1.10.3 + * + */ H5_DLL herr_t H5Oget_info2(hid_t loc_id, H5O_info1_t *oinfo, unsigned fields); + +/** + *------------------------------------------------------------------------- + * \ingroup H5O + * + * \brief Retrieves the metadata for an object, identifying the object + * by location and relative name + * + * \fgdta_loc_obj_id{loc_id} + * \param[in] name Name of group, relative to \p loc_id + * \param[out] oinfo Buffer in which to return object information + * \param[in] fields Flags specifying the fields to include in \p oinfo + * \lapl_id + * + * \return \herr_t + * + * \deprecated As of HDF5-1.12 this function has been deprecated in favor of + * the function H5Oget_info_by_name3() or the macro H5Oget_info_by_name(). + * + * \details H5Oget_info_by_name2() specifies an object’s location and name, \p loc_id and + * \p name, respectively, and retrieves the metadata describing + * that object in \p oinfo, an H5O_info1_t \c struct. + * + * The \c struct H5O_info1_t is defined in H5Opublic.h and described + * in the H5Oget_info1() function entry. + * + * The \p fields parameter contains flags to determine which fields + * will be filled in in the H5O_info1_t \c struct returned in + * \p oinfo. These flags are defined in the H5Opublic.h file: + * + * \obj_info_fields + * + * The link access property list, \p lapl_id, is not currently used; + * it should be passed in as #H5P_DEFAULT. + * + * \since 1.10.3 + * + */ H5_DLL herr_t H5Oget_info_by_name2(hid_t loc_id, const char *name, H5O_info1_t *oinfo, unsigned fields, hid_t lapl_id); + +/** + *------------------------------------------------------------------------- + * \ingroup H5O + * + * \brief Retrieves the metadata for an object, identifying the object + * by an index position + * + * \fgdta_loc_obj_id{loc_id} + * \param[in] group_name Name of group in which object is located + * \idx_type + * \order + * \param[in] n Position within the index + * \param[out] oinfo Buffer in which to return object information + * \param[in] fields Flags specifying the fields to include in \p oinfo + * \lapl_id + * + * \return \herr_t + * + * \deprecated As of HDF5-1.12 this function is deprecated in favor of + * the function H5Oget_info_by_idx3() or the macro #H5Oget_info_by_idx. + * + * \details H5Oget_info_by_idx2() retrieves the metadata describing an + * object in the \c struct \p oinfo, as specified by the location, + * \p loc_id, group name, \p group_name, the index by which objects + * in that group are tracked, \p idx_type, the order by which the + * index is to be traversed, \p order, and an object’s position + * \p n within that index. + * + * \p oinfo, in which the object information is returned, is a \c struct of + * type H5O_info1_t. This and other \c struct types used + * by H5Oget_info_by_idx2() are described in H5Oget_info_by_idx1(). + * + * If \p loc_id fully specifies the group in which the object resides, + * i\p group_name can be a dot (\c .). + * + * The \p fields parameter contains flags to determine which fields will be + * filled in the H5O_info1_t \c struct returned in \p oinfo. + * These flags are defined in the H5Opublic.h file: + * \obj_info_fields + * + * The link access property list, \c lapl_id, is not currently used; + * it should be passed in as #H5P_DEFAULT. + * + * \since 1.10.3 + * + */ H5_DLL herr_t H5Oget_info_by_idx2(hid_t loc_id, const char *group_name, H5_index_t idx_type, H5_iter_order_t order, hsize_t n, H5O_info1_t *oinfo, unsigned fields, hid_t lapl_id); + +/** + *------------------------------------------------------------------------- + * \ingroup H5O + * + * \brief Recursively visits all objects accessible from a specified object + * + * \fgdta_loc_obj_id{obj_id} + * \idx_type + * \order + * \param[in] op Callback function passing data regarding the object + * to the calling application + * \param[in] op_data User-defined pointer to data required by the application + * for its processing of the object + * + * \return On success, returns the return value of the first operator + * that returns a positive value, or zero if all members were + * processed with no operator returning non-zero. + * + * \return On failure, returns a negative value if something goes wrong + * within the library, or the first negative value returned by + * an operator. + * + * \deprecated As of HDF5-1.12 this function has been deprecated in favor of + * the function H5Ovisit3() or the macro #H5Ovisit. + * + * \details H5Ovisit1() is a recursive iteration function to visit the + * object \p obj_id and, if \p obj_id is a group, all objects in + * and below it in an HDF5 file, thus providing a mechanism for + * an application to perform a common set of operations across all + * of those objects or a dynamically selected subset. For + * non-recursive iteration across the members of a group, + * see H5Literate1(). + * + * If \p obj_id is a group identifier, that group serves as the + * root of a recursive iteration. If \p obj_id is a file identifier, + * that file’s root group serves as the root of the recursive + * iteration. If \p obj_id is an attribute identifier, + * then the object where the attribute is attached will be iterated. + * If \p obj_id is any other type of object, such as a dataset or + * named datatype, there is no iteration. + * + * Two parameters are used to establish the iteration: \p idx_type + * and \p order. + * + * \p idx_type specifies the index to be used. If the links in + * a group have not been indexed by the index type, they will + * first be sorted by that index then the iteration will begin; + * if the links have been so indexed, the sorting step will be + * unnecessary, so the iteration may begin more quickly. Valid + * values include the following: + * + * \indexes + * + * Note that the index type passed in \p idx_type is a + * <em>best effort</em> setting. If the application passes in + * a value indicating iteration in creation order and a group is + * encountered that was not tracked in creation order, that group + * will be iterated over in alpha-numeric order by name, or + * <em>name order</em>. (<em>Name order</em> is the native order + * used by the HDF5 library and is always available.) + * + * \p order specifies the order in which objects are to be inspected + * along the index specified in \p idx_type. Valid values include + * the following: + * + * \orders + * + * The prototype of the callback function op is as follows (as + * defined in the source code file H5Opublic.h): + * + * \snippet this H5O_iterate1_t_snip + * + * The parameters of this callback function have the following values + * or meanings: + * <table> + * <tr> + * <td>\c obj</td> + * <td>Object that serves as root of the iteration; + * same value as the H5Ovisit1() \p obj_id parameter</td> + * </tr> + * <tr> + * <td>\c name</td> + * <td>Name of object, relative to \c obj, being examined at + * current step of the iteration</td> + * </tr> + * <tr> + * <td>\c info</td> + * <td>H5O_info1_t \c struct containing information + * regarding that object</td> + * </tr> + * <tr> + * <td>\c op_data</td> + * <td>User-defined pointer to data required by the application in + * processing the object</td> + * </tr> + * </table> + * + * The H5O_info1_t \c struct is defined in H5Opublic.h: + * \snippet this H5O_info1_t_snip + * + * The return values from an operator are: + * - Zero causes the visit iterator to continue, returning zero when all + * group members have been processed. + * - A positive value causes the visit iterator to immediately return that + * positive value, indicating short-circuit success. + * - A negative value causes the visit iterator to immediately return that + * value, indicating failure. + * + * The H5Ovisit1() \p op_data parameter is a user-defined pointer to the data + * required to process objects in the course of the iteration. This pointer + * is passed back to each step of the iteration in the callback + * function’s \p op_data parameter. + * + * H5Lvisit1() and H5Ovisit1() are companion functions: one for + * examining and operating on links; the other for examining + * and operating on the objects that those links point to. Both + * functions ensure that by the time the function completes + * successfully, every link or object below the specified point + * in the file has been presented to the application for whatever + * processing the application requires. These functions assume + * that the membership of the group being iterated over remains + * unchanged through the iteration; if any of the links in the + * group change during the iteration, the resulting behavior + * is undefined. + * + * \note \Bold{Programming Note for C++ Developers Using C Functions:} + * \note If a C routine that takes a function pointer as an argument is + * called from within C++ code, the C routine should be returned + * from normally. + * + * \note Examples of this kind of routine include callbacks such as + * H5Pset_elink_cb() and H5Pset_type_conv_cb() and + * functions such as H5Tconvert() and H5Ewalk2(). + * + * \note Exiting the routine in its normal fashion allows the HDF5 + * C library to clean up its work properly. In other words, if + * the C++ application jumps out of the routine back to the C++ + * “catch” statement, the library is not given the opportunity + * to close any temporary data structures that were set up when + * the routine was called. The C++ application should save some + * state as the routine is started so that any problem that occurs + * might be diagnosed. + * + * \version 1.10.5 The macro #H5Ovisit was removed and the function + * H5Ovisit1() was copied to H5Ovisit(). + * \version 1.10.3 Function H5Ovisit() was copied to H5Ovisit1(), + * and the macro #H5Ovisit was created. + * \version 1.8.8 Fortran subroutine introduced in this release. + * + * \since 1.8.0 + * + */ H5_DLL herr_t H5Ovisit1(hid_t obj_id, H5_index_t idx_type, H5_iter_order_t order, H5O_iterate1_t op, void *op_data); + +/** + *------------------------------------------------------------------------- + * \ingroup H5O + * + * \brief Recursively visits all objects starting from a specified object + * + * \fgdta_loc_obj_id{loc_id} + * \param[in] obj_name Name of the object, generally relative to + * \p loc_id, that will serve as root of the iteration + * \idx_type + * \order + * \param[in] op Callback function passing data regarding the object + * to the calling application + * \param[in] op_data User-defined pointer to data required by the application + * for its processing of the object + * \lapl_id + * + * \return On success, returns the return value of the first operator + * that returns a positive value, or zero if all members were + * processed with no operator returning non-zero. + * + * \return On failure, returns a negative value if something goes wrong + * within the library, or the first negative value returned by + * an operator. + * + * \deprecated As of HDF5-1.12 this function has been deprecated in favor of + * the function H5Ovisit_by_name3() or the macro #H5Ovisit_by_name. + * + * \details H5Ovisit_by_name1() is a recursive iteration function to visit + * the object specified by the \p loc_id / \p obj_name parameter + * pair and, if that object is a group, all objects in and below it + * in an HDF5 file, thus providing a mechanism for an application to + * perform a common set of operations across all of those objects or + * a dynamically selected subset. For non-recursive iteration across + * the members of a group, see H5Literate1(). + * + * The object serving as the root of the iteration is specified + * by the \p loc_id / \p obj_name parameter pair. \p loc_id specifies + * a file or an object in a file; if \p loc_id is an attribute identifier, + * the object where the attribute is attached will be used. + * \p obj_name specifies either an object in the file (with an absolute + * name based in the file’s root group) or an object name relative + * to \p loc_id. If \p loc_id fully specifies the object that is to serve + * as the root of the iteration, \p obj_name should be '\c .' (a dot). + * (Note that when \p loc_id fully specifies the object that is to serve + * as the root of the iteration, the user may wish to consider + * using H5Ovisit1() instead of H5Ovisit_by_name1().) + * + * Two parameters are used to establish the iteration: \p idx_type + * and \p order. + * + * \p idx_type specifies the index to be used. If the links in + * a group have not been indexed by the index type, they will + * first be sorted by that index then the iteration will begin; + * if the links have been so indexed, the sorting step will be + * unnecessary, so the iteration may begin more quickly. Valid + * values include the following: + * + * \indexes + * + * Note that the index type passed in \p idx_type is a + * <em>best effort</em> setting. If the application passes in a + * value indicating iteration in creation order and a group is + * encountered that was not tracked in creation order, that group + * will be iterated over in alpha-numeric order by name, or + * <em>name order</em>. (<em>Name order</em> is the native order + * used by the HDF5 library and is always available.) + * + * \p order specifies the order in which objects are to be inspected + * along the index specified in \p idx_type. Valid values include + * the following: + * + * \orders + * + * The \p op callback function and the effect of the callback + * function’s return value on the application are described + * in H5Ovisit1(). + * + * The H5O_info1_t \c struct is defined in H5Opublic.h + * and described in the H5Oget_info1() function entry. + * + * The H5Ovisit_by_name1() \p op_data parameter is a user-defined + * pointer to the data required to process objects in the course + * of the iteration. This pointer is passed back to each step of + * the iteration in the callback function’s \p op_data parameter. + * + * \p lapl_id is a link access property list. In the general case, + * when default link access properties are acceptable, this can + * be passed in as #H5P_DEFAULT. An example of a situation that + * requires a non-default link access property list is when + * the link is an external link; an external link may require + * that a link prefix be set in a link access property list + * (see H5Pset_elink_prefix()). + * + * H5Lvisit_by_name1() and H5Ovisit_by_name1() are companion + * functions: one for examining and operating on links; the other + * for examining and operating on the objects that those links point to. + * Both functions ensure that by the time the function completes + * successfully, every link or object below the specified point + * in the file has been presented to the application for whatever + * processing the application requires. + * + * \note \Bold{Programming Note for C++ Developers Using C Functions:} + * \note If a C routine that takes a function pointer as an argument is + * called from within C++ code, the C routine should be returned + * from normally. + * + * \note Examples of this kind of routine include callbacks such as + * H5Pset_elink_cb() and H5Pset_type_conv_cb() and + * functions such as H5Tconvert() and H5Ewalk2(). + * + * \note Exiting the routine in its normal fashion allows the HDF5 + * C library to clean up its work properly. In other words, if + * the C++ application jumps out of the routine back to the C++ + * “catch” statement, the library is not given the opportunity + * to close any temporary data structures that were set up when + * the routine was called. The C++ application should save some + * state as the routine is started so that any problem that occurs + * might be diagnosed. + * + * \version 1.10.5 The macro #H5Ovisit_by_name was removed and the function + * H5Ovisit_by_name1() was copied to #H5Ovisit_by_name. + * \version 1.10.3 The H5Ovisit_by_name() function was renamed to H5Ovisit_by_name1(), + * and the macro #H5Ovisit_by_name was created. + * \version 1.8.11 Fortran subroutine introduced in this release. + * + * \since 1.8.0 + * + */ H5_DLL herr_t H5Ovisit_by_name1(hid_t loc_id, const char *obj_name, H5_index_t idx_type, H5_iter_order_t order, H5O_iterate1_t op, void *op_data, hid_t lapl_id); + +/** + *------------------------------------------------------------------------- + * \ingroup H5O + * + * \brief Recursively visits all objects accessible from a specified object + * + * \fgdta_loc_obj_id{obj_id} + * \idx_type + * \order + * \param[in] op Callback function passing data regarding the object + * to the calling application + * \param[in] op_data User-defined pointer to data required by the application + * for its processing of the object + * \param[in] fields Flags specifying the fields to be retrieved to the + * callback \p op + * + * \return On success, returns the return value of the first operator + * that returns a positive value, or zero if all members were + * processed with no operator returning non-zero. + * + * \return On failure, returns a negative value if something goes wrong + * within the library, or the first negative value returned by + * an operator. + * + * \deprecated As of HDF5-1.12 this function has been deprecated in favor of + * the function H5Ovisit3() or the macro #H5Ovisit. + * + * \details H5Ovisit2() is a recursive iteration function to visit the + * object \p obj_id and, if \p obj_id is a group, all objects in + * and below it in an HDF5 file, thus providing a mechanism for + * an application to perform a common set of operations across all + * of those objects or a dynamically selected subset. For + * non-recursive iteration across the members of a group, + * see H5Literate1(). + * + * If \p obj_id is a group identifier, that group serves as the + * root of a recursive iteration. If \p obj_id is a file identifier, + * that file’s root group serves as the root of the recursive + * iteration. If \p obj_id is an attribute identifier, + * then the object where the attribute is attached will be iterated. + * If \p obj_id is any other type of object, such as a dataset or + * named datatype, there is no iteration. + * + * Two parameters are used to establish the iteration: \p idx_type + * and \p order. + * + * \p idx_type specifies the index to be used. If the links in + * a group have not been indexed by the index type, they will + * first be sorted by that index then the iteration will begin; + * if the links have been so indexed, the sorting step will be + * unnecessary, so the iteration may begin more quickly. Valid + * values include the following: + * + * \indexes + * + * Note that the index type passed in \p idx_type is a + * <em>best effort</em> setting. If the application passes in + * a value indicating iteration in creation order and a group is + * encountered that was not tracked in creation order, that group + * will be iterated over in alpha-numeric order by name, or + * <em>name order</em>. (<em>Name order</em> is the native order + * used by the HDF5 library and is always available.) + * + * \p order specifies the order in which objects are to be inspected + * along the index specified in \p idx_type. Valid values include + * the following: + * + * \orders + * + * The prototype of the callback function op is as follows (as + * defined in the source code file H5Opublic.h): + * + * \snippet this H5O_iterate1_t_snip + * + * The parameters of this callback function have the following values + * or meanings: + * <table> + * <tr> + * <td>\c obj</td> + * <td>Object that serves as root of the iteration; + * same value as the H5Ovisit1() \p obj_id parameter</td> + * </tr> + * <tr> + * <td>\c name</td> + * <td>Name of object, relative to \c obj, being examined at + * current step of the iteration</td> + * </tr> + * <tr> + * <td>\c info</td> + * <td>H5O_info1_t \c struct containing information + * regarding that object</td> + * </tr> + * <tr> + * <td>\c op_data</td> + * <td>User-defined pointer to data required by the application in + * processing the object; a pass-through of the \c op_data pointer + * provided with the H5Ovisit() function call</td> + * </tr> + * </table> + * + * The H5O_info1_t \c struct is defined in H5Opublic.h and + * described in the H5Oget_info1() function entry. + * + * The return values from an operator are: + * - Zero causes the visit iterator to continue, returning zero when all + * group members have been processed. + * - A positive value causes the visit iterator to immediately return that + * positive value, indicating short-circuit success. + * - A negative value causes the visit iterator to immediately return that + * value, indicating failure. + * + * The H5Ovisit2() \p op_data parameter is a user-defined pointer to the data + * required to process objects in the course of the iteration. This pointer + * is passed back to each step of the iteration in the callback + * function’s \p op_data parameter. + * + * The \p fields parameter contains flags to determine which fields will + * be retrieved by the \p op callback function. These flags are defined + * in the H5Opublic.h file: + * \obj_info_fields + * + * H5Lvisit() and H5Ovisit() are companion functions: one for + * examining and operating on links; the other for examining + * and operating on the objects that those links point to. Both + * functions ensure that by the time the function completes + * successfully, every link or object below the specified point + * in the file has been presented to the application for whatever + * processing the application requires. These functions assume + * that the membership of the group being iterated over remains + * unchanged through the iteration; if any of the links in the + * group change during the iteration, the resulting behavior + * is undefined. + * + * \note \Bold{Programming Note for C++ Developers Using C Functions:} + * \note If a C routine that takes a function pointer as an argument is + * called from within C++ code, the C routine should be returned + * from normally. + * + * \note Examples of this kind of routine include callbacks such as + * H5Pset_elink_cb() and H5Pset_type_conv_cb() and + * functions such as H5Tconvert() and H5Ewalk2(). + * + * \note Exiting the routine in its normal fashion allows the HDF5 + * C library to clean up its work properly. In other words, if + * the C++ application jumps out of the routine back to the C++ + * “catch” statement, the library is not given the opportunity + * to close any temporary data structures that were set up when + * the routine was called. The C++ application should save some + * state as the routine is started so that any problem that occurs + * might be diagnosed. + * + * \since 1.10.3 + * + */ H5_DLL herr_t H5Ovisit2(hid_t obj_id, H5_index_t idx_type, H5_iter_order_t order, H5O_iterate1_t op, void *op_data, unsigned fields); + +/** + *------------------------------------------------------------------------- + * \ingroup H5O + * + * \brief Recursively visits all objects starting from a specified object + * + * \fgdta_loc_obj_id{loc_id} + * \param[in] obj_name Name of the object, generally relative to + * \p loc_id, that will serve as root of the iteration + * \idx_type + * \order + * \param[in] op Callback function passing data regarding the object + * to the calling application + * \param[in] op_data User-defined pointer to data required by the application + * for its processing of the object + * \param[in] fields Flags specifying the fields to be retrieved to the + * callback function \p op + * \lapl_id + * + * \return On success, returns the return value of the first operator + * that returns a positive value, or zero if all members were + * processed with no operator returning non-zero. + * + * \return On failure, returns a negative value if something goes wrong + * within the library, or the first negative value returned by + * an operator. + * + * \deprecated As of HDF5-1.12 this function has been deprecated in favor of + * the function H5Ovisit_by_name3() or the macro #H5Ovisit_by_name. + * + * \details H5Ovisit_by_name2() is a recursive iteration function to visit + * the object specified by the \p loc_id / \p obj_name parameter + * pair and, if that object is a group, all objects in and below it + * in an HDF5 file, thus providing a mechanism for an application to + * perform a common set of operations across all of those objects or + * a dynamically selected subset. For non-recursive iteration across + * the members of a group, see #H5Literate. + * + * The object serving as the root of the iteration is specified + * by the \p loc_id / \p obj_name parameter pair. \p loc_id specifies + * a file or an object in a file; if \p loc_id is an attribute identifier, + * the object where the attribute is attached will be used. + * \p obj_name specifies either an object in the file (with an absolute + * name based in the file’s root group) or an object name relative + * to \p loc_id. If \p loc_id fully specifies the object that is to serve + * as the root of the iteration, \p obj_name should be '\c .' (a dot). + * (Note that when \p loc_id fully specifies the object that is to serve + * as the root of the iteration, the user may wish to consider + * using H5Ovisit2() instead of #H5Ovisit_by_name.) + * + * Two parameters are used to establish the iteration: \p idx_type + * and \p order. + * + * \p idx_type specifies the index to be used. If the links in + * a group have not been indexed by the index type, they will + * first be sorted by that index then the iteration will begin; + * if the links have been so indexed, the sorting step will be + * unnecessary, so the iteration may begin more quickly. Valid + * values include the following: + * + * \indexes + * + * Note that the index type passed in \p idx_type is a + * <em>best effort</em> setting. If the application passes in a + * value indicating iteration in creation order and a group is + * encountered that was not tracked in creation order, that group + * will be iterated over in alpha-numeric order by name, or + * <em>name order</em>. (<em>Name order</em> is the native order + * used by the HDF5 library and is always available.) + * + * \p order specifies the order in which objects are to be inspected + * along the index specified in \p idx_type. Valid values include + * the following: + * + * \orders + * + * The \p op callback function and the effect of the callback + * function’s return value on the application are described + * in H5Ovisit2(). + * + * The H5O_info1_t \c struct is defined in H5Opublic.h + * and described in the H5Oget_info1() function entry. + * + * The H5Ovisit_by_name2() \p op_data parameter is a user-defined + * pointer to the data required to process objects in the course + * of the iteration. This pointer is passed back to each step of + * the iteration in the callback function’s \p op_data parameter. + * + * \p lapl_id is a link access property list. In the general case, + * when default link access properties are acceptable, this can + * be passed in as #H5P_DEFAULT. An example of a situation that + * requires a non-default link access property list is when + * the link is an external link; an external link may require + * that a link prefix be set in a link access property list + * (see H5Pset_elink_prefix()). + * + * The \p fields parameter contains flags to determine which fields will + * be retrieved by the \p op callback function. These flags are defined + * in the H5Opublic.h file: + * \obj_info_fields + * + * #H5Lvisit_by_name and #H5Ovisit_by_name are companion + * functions: one for examining and operating on links; the other + * for examining and operating on the objects that those links point to. + * Both functions ensure that by the time the function completes + * successfully, every link or object below the specified point + * in the file has been presented to the application for whatever + * processing the application requires. + * + * \note \Bold{Programming Note for C++ Developers Using C Functions:} + * \note If a C routine that takes a function pointer as an argument is + * called from within C++ code, the C routine should be returned + * from normally. + * + * \note Examples of this kind of routine include callbacks such as + * H5Pset_elink_cb() and H5Pset_type_conv_cb() and + * functions such as H5Tconvert() and H5Ewalk2(). + * + * \note Exiting the routine in its normal fashion allows the HDF5 + * C library to clean up its work properly. In other words, if + * the C++ application jumps out of the routine back to the C++ + * “catch” statement, the library is not given the opportunity + * to close any temporary data structures that were set up when + * the routine was called. The C++ application should save some + * state as the routine is started so that any problem that occurs + * might be diagnosed. + * + * \since 1.10.3 + * + */ H5_DLL herr_t H5Ovisit_by_name2(hid_t loc_id, const char *obj_name, H5_index_t idx_type, H5_iter_order_t order, H5O_iterate1_t op, void *op_data, unsigned fields, hid_t lapl_id); diff --git a/src/H5Osdspace.c b/src/H5Osdspace.c index 2cdf6ec..dab989f 100644 --- a/src/H5Osdspace.c +++ b/src/H5Osdspace.c @@ -106,12 +106,13 @@ H5FL_ARR_EXTERN(hsize_t); --------------------------------------------------------------------------*/ static void * H5O__sdspace_decode(H5F_t *f, H5O_t H5_ATTR_UNUSED *open_oh, unsigned H5_ATTR_UNUSED mesg_flags, - unsigned H5_ATTR_UNUSED *ioflags, size_t H5_ATTR_UNUSED p_size, const uint8_t *p) + unsigned H5_ATTR_UNUSED *ioflags, size_t p_size, const uint8_t *p) { - H5S_extent_t *sdim = NULL; /* New extent dimensionality structure */ - unsigned flags, version; - unsigned i; /* Local counting variable */ - void * ret_value = NULL; /* Return value */ + H5S_extent_t * sdim = NULL; /* New extent dimensionality structure */ + unsigned flags, version; + unsigned i; /* Local counting variable */ + const uint8_t *p_end = p + p_size - 1; /* End of the p buffer */ + void * ret_value = NULL; /* Return value */ FUNC_ENTER_STATIC @@ -161,6 +162,13 @@ H5O__sdspace_decode(H5F_t *f, H5O_t H5_ATTR_UNUSED *open_oh, unsigned H5_ATTR_UN /* Decode dimension sizes */ if (sdim->rank > 0) { + /* Ensure that rank doesn't cause reading passed buffer's end, + due to possible data corruption */ + uint8_t sizeof_size = H5F_SIZEOF_SIZE(f); + if (p + (sizeof_size * sdim->rank - 1) > p_end) { + HGOTO_ERROR(H5E_OHDR, H5E_OVERFLOW, NULL, "rank might cause reading passed buffer's end") + } + if (NULL == (sdim->size = (hsize_t *)H5FL_ARR_MALLOC(hsize_t, (size_t)sdim->rank))) HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed") @@ -170,6 +178,11 @@ H5O__sdspace_decode(H5F_t *f, H5O_t H5_ATTR_UNUSED *open_oh, unsigned H5_ATTR_UN if (flags & H5S_VALID_MAX) { if (NULL == (sdim->max = (hsize_t *)H5FL_ARR_MALLOC(hsize_t, (size_t)sdim->rank))) HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed") + + /* Ensure that rank doesn't cause reading passed buffer's end */ + if (p + (sizeof_size * sdim->rank - 1) > p_end) + HGOTO_ERROR(H5E_OHDR, H5E_OVERFLOW, NULL, "rank might cause reading passed buffer's end") + for (i = 0; i < sdim->rank; i++) H5F_DECODE_LENGTH(f, p, sdim->max[i]); } /* end if */ @@ -104,12 +104,12 @@ done: *------------------------------------------------------------------------- */ herr_t -H5PLget_loading_state(unsigned int *plugin_control_mask) +H5PLget_loading_state(unsigned *plugin_control_mask /*out*/) { herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API(FAIL) - H5TRACE1("e", "*Iu", plugin_control_mask); + H5TRACE1("e", "x", plugin_control_mask); if (NULL == plugin_control_mask) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "plugin_control_mask parameter cannot be NULL") diff --git a/src/H5PLint.c b/src/H5PLint.c index 2eeaafa..cf6135d 100644 --- a/src/H5PLint.c +++ b/src/H5PLint.c @@ -293,12 +293,14 @@ done: H5_GCC_DIAG_OFF("pedantic") herr_t H5PL__open(const char *path, H5PL_type_t type, const H5PL_key_t *key, hbool_t *success, - const void **plugin_info) + H5PL_type_t *plugin_type, const void **plugin_info) { H5PL_HANDLE handle = NULL; H5PL_get_plugin_type_t get_plugin_type = NULL; H5PL_get_plugin_info_t get_plugin_info = NULL; - herr_t ret_value = SUCCEED; + H5PL_type_t loaded_plugin_type; + H5PL_key_t tmp_key; + herr_t ret_value = SUCCEED; FUNC_ENTER_PACKAGE @@ -310,6 +312,8 @@ H5PL__open(const char *path, H5PL_type_t type, const H5PL_key_t *key, hbool_t *s /* Initialize out parameters */ *success = FALSE; *plugin_info = NULL; + if (plugin_type) + *plugin_type = H5PL_TYPE_ERROR; /* There are different reasons why a library can't be open, e.g. wrong architecture. * If we can't open the library, just return. @@ -332,11 +336,12 @@ H5PL__open(const char *path, H5PL_type_t type, const H5PL_key_t *key, hbool_t *s HGOTO_DONE(SUCCEED) /* Check the plugin type and return if it doesn't match the one passed in */ - if (type != (H5PL_type_t)(*get_plugin_type)()) + loaded_plugin_type = (H5PL_type_t)(*get_plugin_type)(); + if ((type != H5PL_TYPE_NONE) && (type != loaded_plugin_type)) HGOTO_DONE(SUCCEED) /* Get the plugin information */ - switch (type) { + switch (loaded_plugin_type) { case H5PL_TYPE_FILTER: { const H5Z_class2_t *filter_info; @@ -344,8 +349,16 @@ H5PL__open(const char *path, H5PL_type_t type, const H5PL_key_t *key, hbool_t *s if (NULL == (filter_info = (const H5Z_class2_t *)(*get_plugin_info)())) HGOTO_ERROR(H5E_PLUGIN, H5E_CANTGET, FAIL, "can't get filter info from plugin") + /* Setup temporary plugin key if one wasn't supplied */ + if (!key) { + tmp_key.id = filter_info->id; + key = &tmp_key; + } + /* If the filter IDs match, we're done. Set the output parameters. */ if (filter_info->id == key->id) { + if (plugin_type) + *plugin_type = H5PL_TYPE_FILTER; *plugin_info = (const void *)filter_info; *success = TRUE; } @@ -354,30 +367,29 @@ H5PL__open(const char *path, H5PL_type_t type, const H5PL_key_t *key, hbool_t *s } case H5PL_TYPE_VOL: { - const H5VL_class_t *cls; + const void *cls; /* Get the plugin info */ - if (NULL == (cls = (const H5VL_class_t *)(*get_plugin_info)())) + if (NULL == (cls = (const void *)(*get_plugin_info)())) HGOTO_ERROR(H5E_PLUGIN, H5E_CANTGET, FAIL, "can't get VOL connector info from plugin") - /* Which kind of key are we looking for? */ - if (key->vol.kind == H5VL_GET_CONNECTOR_BY_NAME) { - /* If the plugin names match, we're done. Set the output parameters. */ - if (cls->name && !HDstrcmp(cls->name, key->vol.u.name)) { - *plugin_info = (const void *)cls; - *success = TRUE; - } /* end if */ - } /* end if */ - else { - /* Sanity check */ - HDassert(key->vol.kind == H5VL_GET_CONNECTOR_BY_VALUE); - - /* If the plugin values match, we're done. Set the output parameters. */ - if (cls->value == key->vol.u.value) { - *plugin_info = (const void *)cls; - *success = TRUE; - } /* end if */ - } /* end else */ + /* Setup temporary plugin key if one wasn't supplied */ + if (!key) { + tmp_key.vol.kind = H5VL_GET_CONNECTOR_BY_NAME; + tmp_key.vol.u.name = ((const H5VL_class_t *)cls)->name; + key = &tmp_key; + } + + /* Ask VOL interface if this class is the one we are looking for and is compatible, etc */ + if (H5VL_check_plugin_load(cls, key, success) < 0) + HGOTO_ERROR(H5E_PLUGIN, H5E_CANTLOAD, FAIL, "VOL connector compatibility check failed") + + /* Check for finding the correct plugin */ + if (*success) { + if (plugin_type) + *plugin_type = H5PL_TYPE_VOL; + *plugin_info = cls; + } break; } @@ -390,7 +402,7 @@ H5PL__open(const char *path, H5PL_type_t type, const H5PL_key_t *key, hbool_t *s /* If we found the correct plugin, store it in the cache */ if (*success) - if (H5PL__add_plugin(type, key, handle)) + if (H5PL__add_plugin(loaded_plugin_type, key, handle)) HGOTO_ERROR(H5E_PLUGIN, H5E_CANTINSERT, FAIL, "unable to add new plugin to plugin cache") done: @@ -420,3 +432,29 @@ H5PL__close(H5PL_HANDLE handle) FUNC_LEAVE_NOAPI(SUCCEED) } /* end H5PL__close() */ + +/*------------------------------------------------------------------------- + * Function: H5PL_iterate + * + * Purpose: Iterates over all the available plugins and calls the + * specified callback function on each plugin. + * + * Return: H5_ITER_CONT if all plugins are processed successfully + * H5_ITER_STOP if short-circuit success occurs while + * processing plugins + * H5_ITER_ERROR if an error occurs while processing plugins + * + *------------------------------------------------------------------------- + */ +herr_t +H5PL_iterate(H5PL_iterate_type_t iter_type, H5PL_iterate_t iter_op, void *op_data) +{ + herr_t ret_value = H5_ITER_CONT; + + FUNC_ENTER_NOAPI(H5_ITER_ERROR) + + ret_value = H5PL__path_table_iterate(iter_type, iter_op, op_data); + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5PL_iterate() */ diff --git a/src/H5PLpath.c b/src/H5PLpath.c index 0aaa5b1..39a7d0d 100644 --- a/src/H5PLpath.c +++ b/src/H5PLpath.c @@ -62,6 +62,8 @@ static herr_t H5PL__insert_at(const char *path, unsigned int idx); static herr_t H5PL__make_space_at(unsigned int idx); static herr_t H5PL__replace_at(const char *path, unsigned int idx); static herr_t H5PL__expand_path_table(void); +static herr_t H5PL__path_table_iterate_process_path(const char *plugin_path, H5PL_iterate_type_t iter_type, + H5PL_iterate_t iter_op, void *op_data); static herr_t H5PL__find_plugin_in_path(const H5PL_search_params_t *search_params, hbool_t *found, const char *dir, const void **plugin_info); @@ -546,7 +548,220 @@ H5PL__get_path(unsigned int idx) return H5PL_paths_g[idx]; done: FUNC_LEAVE_NOAPI(ret_value) -} /* end H5PL__replace_path() */ +} /* end H5PL__get_path() */ + +/*------------------------------------------------------------------------- + * Function: H5PL__path_table_iterate + * + * Purpose: Iterates over all the plugins in the plugin path table and + * calls the specified callback function on each plugin found. + * + * Return: H5_ITER_CONT if all plugins are processed successfully + * H5_ITER_STOP if short-circuit success occurs while + * processing plugins + * H5_ITER_ERROR if an error occurs while processing plugins + * + *------------------------------------------------------------------------- + */ +herr_t +H5PL__path_table_iterate(H5PL_iterate_type_t iter_type, H5PL_iterate_t iter_op, void *op_data) +{ + unsigned int u; + herr_t ret_value = H5_ITER_CONT; + + FUNC_ENTER_PACKAGE + + for (u = 0; (u < H5PL_num_paths_g) && (ret_value == H5_ITER_CONT); u++) + ret_value = H5PL__path_table_iterate_process_path(H5PL_paths_g[u], iter_type, iter_op, op_data); + + if (ret_value < 0) + HGOTO_ERROR(H5E_PLUGIN, H5E_BADITER, H5_ITER_ERROR, "can't iterate over plugins in plugin path '%s'", + H5PL_paths_g[u]); + +done: + FUNC_LEAVE_NOAPI(ret_value); +} /* end H5PL__path_table_iterate() */ + +/*------------------------------------------------------------------------- + * Function: H5PL__path_table_iterate_process_path + * + * Purpose: Iterates over all the plugins within a single plugin path + * entry in the plugin path table and calls the specified + * callback function on each plugin found. Two function + * definitions are for Unix and Windows. + * + * Return: H5_ITER_CONT if all plugins are processed successfully + * H5_ITER_STOP if short-circuit success occurs while + * processing plugins + * H5_ITER_ERROR if an error occurs while processing plugins + * + *------------------------------------------------------------------------- + */ +#ifndef H5_HAVE_WIN32_API +static herr_t +H5PL__path_table_iterate_process_path(const char *plugin_path, H5PL_iterate_type_t iter_type, + H5PL_iterate_t iter_op, void *op_data) +{ + H5PL_type_t plugin_type; + const void * plugin_info = NULL; + hbool_t plugin_loaded; + char * path = NULL; + DIR * dirp = NULL; /* Directory stream */ + struct dirent *dp = NULL; /* Directory entry */ + herr_t ret_value = H5_ITER_CONT; + + FUNC_ENTER_STATIC + + HDassert(plugin_path); + HDassert(iter_op); + + /* Open the directory */ + if (!(dirp = HDopendir(plugin_path))) + HGOTO_ERROR(H5E_PLUGIN, H5E_OPENERROR, H5_ITER_ERROR, "can't open directory: %s", plugin_path) + + /* Iterate through all entries in the directory */ + while (NULL != (dp = HDreaddir(dirp))) { + /* The library we are looking for should be called libxxx.so... on Unix + * or libxxx.xxx.dylib on Mac. + */ +#ifndef __CYGWIN__ + if (!HDstrncmp(dp->d_name, "lib", (size_t)3) && + (HDstrstr(dp->d_name, ".so") || HDstrstr(dp->d_name, ".dylib"))) { +#else + if (!HDstrncmp(dp->d_name, "cyg", (size_t)3) && HDstrstr(dp->d_name, ".dll")) { +#endif + + hbool_t plugin_matches; + h5_stat_t my_stat; + size_t len; + + /* Allocate & initialize the path name */ + len = HDstrlen(plugin_path) + HDstrlen(H5PL_PATH_SEPARATOR) + HDstrlen(dp->d_name) + 1 /*\0*/ + + 4; /* Extra "+4" to quiet GCC warning - 2019/07/05, QAK */ + + if (NULL == (path = (char *)H5MM_calloc(len))) + HGOTO_ERROR(H5E_PLUGIN, H5E_CANTALLOC, H5_ITER_ERROR, "can't allocate memory for path") + + HDsnprintf(path, len, "%s/%s", plugin_path, dp->d_name); + + /* Get info for directory entry */ + if (HDstat(path, &my_stat) == -1) + HGOTO_ERROR(H5E_FILE, H5E_CANTGET, H5_ITER_ERROR, "can't stat file %s -- error was: %s", path, + HDstrerror(errno)) + + /* If it is a directory, skip it */ + if (S_ISDIR(my_stat.st_mode)) + continue; + + /* Attempt to open the dynamic library */ + plugin_type = H5PL_TYPE_ERROR; + plugin_info = NULL; + plugin_loaded = FALSE; + if (H5PL__open(path, H5PL_TYPE_NONE, NULL, &plugin_loaded, &plugin_type, &plugin_info) < 0) + HGOTO_ERROR(H5E_PLUGIN, H5E_CANTGET, H5_ITER_ERROR, "failed to open plugin '%s'", path); + + /* Determine if we should process this plugin */ + plugin_matches = (iter_type == H5PL_ITER_TYPE_ALL) || + ((iter_type == H5PL_ITER_TYPE_FILTER) && (plugin_type == H5PL_TYPE_FILTER)) || + ((iter_type == H5PL_ITER_TYPE_VOL) && (plugin_type == H5PL_TYPE_VOL)); + + /* If the plugin was successfully loaded, call supplied callback function on plugin */ + if (plugin_loaded && plugin_matches && (ret_value = iter_op(plugin_type, plugin_info, op_data))) + break; + + path = (char *)H5MM_xfree(path); + } /* end if */ + } /* end while */ + + if (ret_value < 0) + HERROR(H5E_PLUGIN, H5E_CALLBACK, "callback operator function returned failure"); + +done: + if (dirp) + if (HDclosedir(dirp) < 0) + HDONE_ERROR(H5E_FILE, H5E_CLOSEERROR, H5_ITER_ERROR, "can't close directory: %s", + HDstrerror(errno)) + + path = (char *)H5MM_xfree(path); + + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5PL__path_table_iterate_process_path() */ +#else /* H5_HAVE_WIN32_API */ +static herr_t +H5PL__path_table_iterate_process_path(const char *plugin_path, H5PL_iterate_type_t iter_type, + H5PL_iterate_t iter_op, void *op_data) +{ + WIN32_FIND_DATAA fdFile; + HANDLE hFind = INVALID_HANDLE_VALUE; + H5PL_type_t plugin_type; + const void * plugin_info = NULL; + hbool_t plugin_loaded; + char * path = NULL; + char service[2048]; + herr_t ret_value = H5_ITER_CONT; + + FUNC_ENTER_STATIC + + /* Check args - Just assert on package functions */ + HDassert(plugin_path); + HDassert(iter_op); + + /* Specify a file mask. *.* = We want everything! */ + HDsprintf(service, "%s\\*.dll", plugin_path); + if ((hFind = FindFirstFileA(service, &fdFile)) == INVALID_HANDLE_VALUE) + HGOTO_ERROR(H5E_PLUGIN, H5E_OPENERROR, H5_ITER_ERROR, "can't open directory") + + /* Loop over all the files */ + do { + /* Ignore '.' and '..' */ + if (HDstrcmp(fdFile.cFileName, ".") != 0 && HDstrcmp(fdFile.cFileName, "..") != 0) { + hbool_t plugin_matches; + size_t len; + + /* Allocate & initialize the path name */ + len = HDstrlen(plugin_path) + HDstrlen(H5PL_PATH_SEPARATOR) + HDstrlen(fdFile.cFileName) + 1; + + if (NULL == (path = (char *)H5MM_calloc(len))) + HGOTO_ERROR(H5E_PLUGIN, H5E_CANTALLOC, H5_ITER_ERROR, "can't allocate memory for path") + + HDsnprintf(path, len, "%s\\%s", plugin_path, fdFile.cFileName); + + /* Ignore directories */ + if (fdFile.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) + continue; + + /* Attempt to open the dynamic library */ + plugin_type = H5PL_TYPE_ERROR; + plugin_info = NULL; + plugin_loaded = FALSE; + if (H5PL__open(path, H5PL_TYPE_NONE, NULL, &plugin_loaded, &plugin_type, &plugin_info) < 0) + HGOTO_ERROR(H5E_PLUGIN, H5E_CANTGET, H5_ITER_ERROR, "failed to open plugin '%s'", path); + + /* Determine if we should process this plugin */ + plugin_matches = (iter_type == H5PL_ITER_TYPE_ALL) || + ((iter_type == H5PL_ITER_TYPE_FILTER) && (plugin_type == H5PL_TYPE_FILTER)) || + ((iter_type == H5PL_ITER_TYPE_VOL) && (plugin_type == H5PL_TYPE_VOL)); + + /* If the plugin was successfully loaded, call supplied callback function on plugin */ + if (plugin_loaded && plugin_matches && (ret_value = iter_op(plugin_type, plugin_info, op_data))) + break; + + path = (char *)H5MM_xfree(path); + } + } while (FindNextFileA(hFind, &fdFile)); + + if (ret_value < 0) + HERROR(H5E_PLUGIN, H5E_CALLBACK, "callback operator function returned failure"); + +done: + if (hFind != INVALID_HANDLE_VALUE) + FindClose(hFind); + + path = (char *)H5MM_xfree(path); + + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5PL__path_table_iterate_process_path() */ +#endif /* H5_HAVE_WIN32_API */ /*------------------------------------------------------------------------- * Function: H5PL__find_plugin_in_path_table @@ -669,11 +884,13 @@ H5PL__find_plugin_in_path(const H5PL_search_params_t *search_params, hbool_t *fo HDstrerror(errno)) /* If it is a directory, skip it */ - if (S_ISDIR(my_stat.st_mode)) + if (S_ISDIR(my_stat.st_mode)) { + path = (char *)H5MM_xfree(path); continue; + } - /* attempt to open the dynamic library as a filter library */ - if (H5PL__open(path, search_params->type, search_params->key, found, plugin_info) < 0) + /* attempt to open the dynamic library */ + if (H5PL__open(path, search_params->type, search_params->key, found, NULL, plugin_info) < 0) HGOTO_ERROR(H5E_PLUGIN, H5E_CANTGET, FAIL, "search in directory failed") if (*found) HGOTO_DONE(SUCCEED) @@ -739,8 +956,8 @@ H5PL__find_plugin_in_path(const H5PL_search_params_t *search_params, hbool_t *fo if (fdFile.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) continue; - /* attempt to open the dynamic library as a filter library */ - if (H5PL__open(path, search_params->type, search_params->key, found, plugin_info) < 0) + /* attempt to open the dynamic library */ + if (H5PL__open(path, search_params->type, search_params->key, found, NULL, plugin_info) < 0) HGOTO_ERROR(H5E_PLUGIN, H5E_CANTGET, FAIL, "search in directory failed") if (*found) HGOTO_DONE(SUCCEED) diff --git a/src/H5PLpkg.h b/src/H5PLpkg.h index 627a5cc..cffc358 100644 --- a/src/H5PLpkg.h +++ b/src/H5PLpkg.h @@ -94,7 +94,7 @@ typedef const void *(__cdecl *H5PL_get_plugin_info_t)(void); #define H5PL_HANDLE void * /* Get a handle to a plugin library. Windows: TEXT macro handles Unicode strings */ -#define H5PL_OPEN_DLIB(S) dlopen(S, RTLD_LAZY) +#define H5PL_OPEN_DLIB(S) dlopen(S, RTLD_LAZY | RTLD_LOCAL) /* Get the address of a symbol in dynamic library */ #define H5PL_GET_LIB_FUNC(H, N) dlsym(H, N) @@ -133,7 +133,8 @@ H5_DLL herr_t H5PL__set_plugin_control_mask(unsigned int mask); /* Plugin search and manipulation */ H5_DLL herr_t H5PL__open(const char *libname, H5PL_type_t type, const H5PL_key_t *key, - hbool_t *success /*out*/, const void **plugin_info /*out*/); + hbool_t *success /*out*/, H5PL_type_t *plugin_type /*out*/, + const void **plugin_info /*out*/); H5_DLL herr_t H5PL__close(H5PL_HANDLE handle); /* Plugin cache calls */ @@ -153,7 +154,8 @@ H5_DLL herr_t H5PL__replace_path(const char *path, unsigned int index); H5_DLL herr_t H5PL__insert_path(const char *path, unsigned int index); H5_DLL herr_t H5PL__remove_path(unsigned int index); H5_DLL const char *H5PL__get_path(unsigned int index); -H5_DLL herr_t H5PL__find_plugin_in_path_table(const H5PL_search_params_t *search_params, - hbool_t *found /*out*/, const void **plugin_info /*out*/); +H5_DLL herr_t H5PL__path_table_iterate(H5PL_iterate_type_t iter_type, H5PL_iterate_t iter_op, void *op_data); +H5_DLL herr_t H5PL__find_plugin_in_path_table(const H5PL_search_params_t *search_params, + hbool_t *found /*out*/, const void **plugin_info /*out*/); #endif /* H5PLpkg_H */ diff --git a/src/H5PLplugin_cache.c b/src/H5PLplugin_cache.c index 970b511..2ec0845 100644 --- a/src/H5PLplugin_cache.c +++ b/src/H5PLplugin_cache.c @@ -264,12 +264,12 @@ H5PL__find_plugin_in_cache(const H5PL_search_params_t *search_params, hbool_t *f /* Loop over all the plugins, looking for one that matches */ for (u = 0; u < H5PL_num_plugins_g; u++) { - /* If the plugin type (filter, etc.) and ID match, query the plugin for its info */ + /* If the plugin type (filter, VOL connector, etc.) and ID match, query the plugin for its info */ if ((search_params->type == (H5PL_cache_g[u]).type) && (search_params->key->id == (H5PL_cache_g[u]).key.id)) { H5PL_get_plugin_info_t get_plugin_info_function; - const H5Z_class2_t * filter_info; + const void * info; /* Get the "get plugin info" function from the plugin. */ if (NULL == (get_plugin_info_function = (H5PL_get_plugin_info_t)H5PL_GET_LIB_FUNC( @@ -277,12 +277,12 @@ H5PL__find_plugin_in_cache(const H5PL_search_params_t *search_params, hbool_t *f HGOTO_ERROR(H5E_PLUGIN, H5E_CANTGET, FAIL, "can't get function for H5PLget_plugin_info") /* Call the "get plugin info" function */ - if (NULL == (filter_info = (const H5Z_class2_t *)(*get_plugin_info_function)())) + if (NULL == (info = (*get_plugin_info_function)())) HGOTO_ERROR(H5E_PLUGIN, H5E_CANTGET, FAIL, "can't get plugin info") /* Set output parameters */ *found = TRUE; - *plugin_info = filter_info; + *plugin_info = info; /* No need to continue processing */ break; diff --git a/src/H5PLprivate.h b/src/H5PLprivate.h index 36b8ba2..7eae513 100644 --- a/src/H5PLprivate.h +++ b/src/H5PLprivate.h @@ -44,6 +44,18 @@ typedef union H5PL_key_t { } vol; } H5PL_key_t; +/* Enum dictating the type of plugins to process + * when iterating through available plugins + */ +typedef enum { + H5PL_ITER_TYPE_FILTER, + H5PL_ITER_TYPE_VOL, + H5PL_ITER_TYPE_ALL, +} H5PL_iterate_type_t; + +/* Callback function for iterating through the available plugins */ +typedef herr_t (*H5PL_iterate_t)(H5PL_type_t plugin_type, const void *plugin_info, void *op_data); + /*****************************/ /* Library-private Variables */ /*****************************/ @@ -54,5 +66,6 @@ typedef union H5PL_key_t { /* Internal API routines */ H5_DLL const void *H5PL_load(H5PL_type_t plugin_type, const H5PL_key_t *key); +H5_DLL herr_t H5PL_iterate(H5PL_iterate_type_t iter_type, H5PL_iterate_t iter_op, void *op_data); #endif /* H5PLprivate_H */ diff --git a/src/H5PLpublic.h b/src/H5PLpublic.h index 0b8d713..55ff594 100644 --- a/src/H5PLpublic.h +++ b/src/H5PLpublic.h @@ -28,13 +28,17 @@ */ #define H5PL_NO_PLUGIN "::" -/* Plugin type used by the plugin library */ +//! <!-- [H5PL_type_t_snip] --> +/** + * Plugin type (bit-position) used by the plugin library + */ typedef enum H5PL_type_t { - H5PL_TYPE_ERROR = -1, /* Error */ - H5PL_TYPE_FILTER = 0, /* Filter */ - H5PL_TYPE_VOL = 1, /* VOL driver */ - H5PL_TYPE_NONE = 2 /* This must be last! */ + H5PL_TYPE_ERROR = -1, /**< Error */ + H5PL_TYPE_FILTER = 0, /**< Filter */ + H5PL_TYPE_VOL = 1, /**< VOL driver */ + H5PL_TYPE_NONE = 2 /**< Sentinel: This must be last! */ } H5PL_type_t; +//! <!-- [H5PL_type_t_snip] --> /* Common dynamic plugin type flags used by the set/get_loading_state functions */ #define H5PL_FILTER_PLUGIN 0x0001 @@ -46,15 +50,175 @@ extern "C" { #endif /* plugin state */ -H5_DLL herr_t H5PLset_loading_state(unsigned int plugin_control_mask); -H5_DLL herr_t H5PLget_loading_state(unsigned int *plugin_control_mask /*out*/); -H5_DLL herr_t H5PLappend(const char *search_path); -H5_DLL herr_t H5PLprepend(const char *search_path); -H5_DLL herr_t H5PLreplace(const char *search_path, unsigned int index); -H5_DLL herr_t H5PLinsert(const char *search_path, unsigned int index); -H5_DLL herr_t H5PLremove(unsigned int index); +/** + * \ingroup H5PL + * \brief Controls the loadability of dynamic plugin types + * + * \param[in] plugin_control_mask The list of dynamic plugin types to enable or disable.\n + * A plugin bit set to 0 (zero) prevents use of that dynamic plugin.\n + * A plugin bit set to 1 (one) enables use of that dynamic plugin.\n + * Setting \p plugin_control_mask to a negative value enables all dynamic + * plugin types.\n + * Setting \p plugin_control_mask to 0 (zero) disables all dynamic plugin\n + * types. + * \return \herr_t + * + * \details H5PLset_loading_state() uses one argument to enable or disable individual plugin types. + * + * \details The \p plugin_control_mask parameter is an encoded integer in which each bit controls a specific + * plugin type. Bit positions allocated to date are specified in \ref H5PL_type_t as follows: + * \snippet this H5PL_type_t_snip + * + * A plugin bit set to 0 (zero) prevents the use of the dynamic plugin type corresponding to that bit + * position. A plugin bit set to 1 (one) allows the use of that dynamic plugin type. + * + * All dynamic plugin types can be enabled by setting \p plugin_control_mask to a negative value. A + * value of 0 (zero) will disable all dynamic plugin types. + * + * The loading of external dynamic plugins can be controlled during runtime with an environment + * variable, \c HDF5_PLUGIN_PRELOAD. H5PLset_loading_state() inspects the \c HDF5_PLUGIN_PRELOAD + * environment variable every time it is called. If the environment variable is set to the special + * \c :: string, all dynamic plugins are disabled. + * + * \warning The environment variable \c HDF5_PLUGIN_PRELOAD controls the loading of dynamic plugin types at + * runtime. If it is set to disable all plugin types, then it will disable them for \Emph{all} + * running programs that access the same variable instance. + * + * \since 1.8.15 + * + */ +H5_DLL herr_t H5PLset_loading_state(unsigned int plugin_control_mask); +/** + * \ingroup H5PL + * \brief Queries the loadability of dynamic plugin types + * + * \param[out] plugin_control_mask List of dynamic plugin types that are enabled or disabled.\n + * A plugin bit set to 0 (zero) indicates that that the dynamic plugin type is + * disabled.\n + * A plugin bit set to 1 (one) indicates that that the dynamic plugin type is + * enabled.\n + * If the value of \p plugin_control_mask is negative, all dynamic plugin + * types are enabled.\n + * If the value of \p plugin_control_mask is 0 (zero), all dynamic plugins + * are disabled. + * \return \herr_t + * + * \details H5PLget_loading_state() retrieves the bitmask that controls whether a certain type of plugins + * (e.g.: filters, VOL drivers) will be loaded by the HDF5 library. + * + * Bit positions allocated to date are specified in \ref H5PL_type_t as follows: + * \snippet this H5PL_type_t_snip + * + * \since 1.8.15 + * + */ +H5_DLL herr_t H5PLget_loading_state(unsigned int *plugin_control_mask /*out*/); +/** + * \ingroup H5PL + * \brief Inserts a plugin path at the end of the plugin search path list + * + * \param[in] search_path A plugin path + * \return \herr_t + * + * \details H5PLappend() inserts a plugin path at the end of the plugin search path list. + * + * \since 1.10.1 + * + */ +H5_DLL herr_t H5PLappend(const char *search_path); +/** + * \ingroup H5PL + * \brief Inserts a plugin path at the beginning of the plugin search path list + * + * \param[in] search_path A plugin path + * \return \herr_t + * + * \details H5PLprepend() inserts a plugin path at the end of the plugin search path list. + * + * \since 1.10.1 + * + */ +H5_DLL herr_t H5PLprepend(const char *search_path); +/** + * \ingroup H5PL + * \brief Replaces the path at the specified index in the plugin search path list + * + * \param[in] search_path A plugin path + * \param[in] index Index + * \return \herr_t + * + * \details H5PLreplace() replaces a plugin path at the specified index in the plugin search path list. + * + * \since 1.10.1 + * + */ +H5_DLL herr_t H5PLreplace(const char *search_path, unsigned int index); +/** + * \ingroup H5PL + * \brief Inserts a path at the specified index in the plugin search path list + * + * \param[in] search_path A plugin path + * \param[in] index Index + * \return \herr_t + * + * \details H5PLinsert() inserts a plugin path at the specified index in the plugin search path list, + * moving other paths after \p index. + * + * \since 1.10.1 + * + */ +H5_DLL herr_t H5PLinsert(const char *search_path, unsigned int index); +/** + * \ingroup H5PL + * \brief Removes a plugin path at a specified index from the plugin search path list + * + * \param[in] index Index + * \return \herr_t + * + * \details H5PLremove() removes a plugin path at the specified \p index and compacts the plugin search path + * list. + * + * \since 1.10.1 + * + */ +H5_DLL herr_t H5PLremove(unsigned int index); +/** + * \ingroup H5PL + * \brief Queries the plugin search path list at the specified index + * + * \param[in] index Index + * \param[out] path_buf Pathname + * \param[in] buf_size Size of \p path_buf + * \return Returns the length of the path, a non-negative value, if successful; otherwise returns a negative + * value. + * + * \details H5PLget() queries the plugin path at a specified index. If \p path_buf is non-NULL then it writes + * up to \p buf_size bytes into that buffer and always returns the length of the path name. + * + * If \p path_buf is NULL, this function will simply return the number of characters required to + * store the path name, ignoring \p path_buf and \p buf_size. + * + * If an error occurs then the buffer pointed to by \p path_buf (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 path name associated with the index. and the \p path_buf buffer will be unchanged. + * + * \since 1.10.1 + * + */ H5_DLL ssize_t H5PLget(unsigned int index, char *path_buf /*out*/, size_t buf_size); -H5_DLL herr_t H5PLsize(unsigned int *num_paths /*out*/); +/** + * \ingroup H5PL + * \brief Retrieves the number of stored plugin paths + * + * \param[out] num_paths Current length of the plugin search path list + * \return \herr_t + * + * \details H5PLsize() retrieves the number of paths stored in the plugin search path list. + * + * \since 1.10.1 + * + */ +H5_DLL herr_t H5PLsize(unsigned int *num_paths /*out*/); #ifdef __cplusplus } diff --git a/src/H5Pdapl.c b/src/H5Pdapl.c index c8a97c2..2ebdbe3 100644 --- a/src/H5Pdapl.c +++ b/src/H5Pdapl.c @@ -768,7 +768,7 @@ H5Pset_chunk_cache(hid_t dapl_id, size_t rdcc_nslots, size_t rdcc_nbytes, double /* Check arguments. Note that we allow negative values - they are * considered to "unset" the property. */ - if (rdcc_w0 > (double)1.0f) + if (rdcc_w0 > 1.0) HGOTO_ERROR( H5E_ARGS, H5E_BADVALUE, FAIL, "raw data cache w0 value must be between 0.0 and 1.0 inclusive, or H5D_CHUNK_CACHE_W0_DEFAULT"); diff --git a/src/H5Pdxpl.c b/src/H5Pdxpl.c index 70fc982..de67dfd 100644 --- a/src/H5Pdxpl.c +++ b/src/H5Pdxpl.c @@ -1486,9 +1486,8 @@ H5Pset_btree_ratios(hid_t plist_id, double left, double middle, double right) H5TRACE4("e", "iddd", plist_id, left, middle, right); /* Check arguments */ - if (left < (double)0.0f || left > (double)1.0f || middle < (double)0.0f || middle > (double)1.0f || - right < (double)0.0f || right > (double)1.0f) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "split ratio must satisfy 0.0<=X<=1.0") + if (left < 0.0 || left > 1.0 || middle < 0.0 || middle > 1.0 || right < 0.0 || right > 1.0) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "split ratio must satisfy 0.0 <= X <= 1.0") /* Get the plist structure */ if (NULL == (plist = H5P_object_verify(plist_id, H5P_DATASET_XFER))) diff --git a/src/H5Pfapl.c b/src/H5Pfapl.c index 6f3884f..5332ea6 100644 --- a/src/H5Pfapl.c +++ b/src/H5Pfapl.c @@ -1708,7 +1708,7 @@ H5Pset_cache(hid_t plist_id, int H5_ATTR_UNUSED mdc_nelmts, size_t rdcc_nslots, H5TRACE5("e", "iIszzd", plist_id, mdc_nelmts, rdcc_nslots, rdcc_nbytes, rdcc_w0); /* Check arguments */ - if (rdcc_w0 < (double)0.0f || rdcc_w0 > (double)1.0f) + if (rdcc_w0 < 0.0 || rdcc_w0 > 1.0) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "raw data cache w0 value must be between 0.0 and 1.0 inclusive") diff --git a/src/H5Pint.c b/src/H5Pint.c index 4215ccb..b27a440 100644 --- a/src/H5Pint.c +++ b/src/H5Pint.c @@ -95,6 +95,10 @@ typedef herr_t (*H5P_do_pclass_op_t)(H5P_genplist_t *plist, const char *name, H5 /* Local Prototypes */ /********************/ +/* Infrastructure routines */ +static herr_t H5P__close_class_cb(void *space, void **request); +static herr_t H5P__close_list_cb(void *space, void **request); + /* General helper routines */ static H5P_genplist_t *H5P__create(H5P_genclass_t *pclass); static H5P_genprop_t * H5P__create_prop(const char *name, size_t size, H5P_prop_within_t type, @@ -394,18 +398,18 @@ H5FL_DEFINE_STATIC(H5P_genplist_t); /* Generic Property Class ID class */ static const H5I_class_t H5I_GENPROPCLS_CLS[1] = {{ - H5I_GENPROP_CLS, /* ID class value */ - 0, /* Class flags */ - 0, /* # of reserved IDs for class */ - (H5I_free_t)H5P__close_class /* Callback routine for closing objects of this class */ + H5I_GENPROP_CLS, /* ID class value */ + 0, /* Class flags */ + 0, /* # of reserved IDs for class */ + (H5I_free_t)H5P__close_class_cb /* Callback routine for closing objects of this class */ }}; /* Generic Property List ID class */ static const H5I_class_t H5I_GENPROPLST_CLS[1] = {{ - H5I_GENPROP_LST, /* ID class value */ - 0, /* Class flags */ - 0, /* # of reserved IDs for class */ - (H5I_free_t)H5P_close /* Callback routine for closing objects of this class */ + H5I_GENPROP_LST, /* ID class value */ + 0, /* Class flags */ + 0, /* # of reserved IDs for class */ + (H5I_free_t)H5P__close_list_cb /* Callback routine for closing objects of this class */ }}; /*------------------------------------------------------------------------- @@ -622,6 +626,68 @@ H5P_term_package(void) FUNC_LEAVE_NOAPI(n) } /* end H5P_term_package() */ +/*------------------------------------------------------------------------- + * Function: H5P__close_class_cb + * + * Purpose: Called when the ref count reaches zero on a property class's ID + * + * Return: SUCCEED / FAIL + * + * Programmer: Quincey Koziol + * Wednesday, April 8, 2020 + * + *------------------------------------------------------------------------- + */ +static herr_t +H5P__close_class_cb(void *_pclass, void H5_ATTR_UNUSED **request) +{ + H5P_genclass_t *pclass = (H5P_genclass_t *)_pclass; /* Property list class to close */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_STATIC + + /* Sanity check */ + HDassert(pclass); + + /* Close the property list class object */ + if (H5P__close_class(pclass) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CLOSEERROR, FAIL, "unable to close property list class"); + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5P__close_class_cb() */ + +/*------------------------------------------------------------------------- + * Function: H5P__close_list_cb + * + * Purpose: Called when the ref count reaches zero on a property list's ID + * + * Return: SUCCEED / FAIL + * + * Programmer: Quincey Koziol + * Wednesday, April 8, 2020 + * + *------------------------------------------------------------------------- + */ +static herr_t +H5P__close_list_cb(void *_plist, void H5_ATTR_UNUSED **request) +{ + H5P_genplist_t *plist = (H5P_genplist_t *)_plist; /* Property list to close */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_STATIC + + /* Sanity check */ + HDassert(plist); + + /* Close the property list object */ + if (H5P_close(plist) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CLOSEERROR, FAIL, "unable to close property list"); + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5P__close_list_cb() */ + /*-------------------------------------------------------------------------- NAME H5P__do_prop_cb1 @@ -5011,11 +5077,10 @@ done: REVISION LOG --------------------------------------------------------------------------*/ herr_t -H5P_close(void *_plist) +H5P_close(H5P_genplist_t *plist) { - H5P_genclass_t *tclass; /* Temporary class pointer */ - H5P_genplist_t *plist = (H5P_genplist_t *)_plist; - H5SL_t * seen = NULL; /* Skip list to hold names of properties already seen */ + H5P_genclass_t *tclass; /* Temporary class pointer */ + H5SL_t * seen = NULL; /* Skip list to hold names of properties already seen */ size_t nseen; /* Number of items 'seen' */ hbool_t has_parent_class; /* Flag to indicate that this property list's class has a parent */ size_t ndel; /* Number of items deleted */ @@ -5394,10 +5459,9 @@ H5P__get_class_parent(const H5P_genclass_t *pclass) REVISION LOG --------------------------------------------------------------------------*/ herr_t -H5P__close_class(void *_pclass) +H5P__close_class(H5P_genclass_t *pclass) { - H5P_genclass_t *pclass = (H5P_genclass_t *)_pclass; - herr_t ret_value = SUCCEED; /* Return value */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI_NOINIT diff --git a/src/H5Ppkg.h b/src/H5Ppkg.h index 699d5f3..dd43f76 100644 --- a/src/H5Ppkg.h +++ b/src/H5Ppkg.h @@ -166,7 +166,7 @@ H5_DLL herr_t H5P__unregister(H5P_genclass_t *pclass, const char *name); H5_DLL char * H5P__get_class_path(H5P_genclass_t *pclass); H5_DLL H5P_genclass_t *H5P__open_class_path(const char *path); H5_DLL H5P_genclass_t *H5P__get_class_parent(const H5P_genclass_t *pclass); -H5_DLL herr_t H5P__close_class(void *_pclass); +H5_DLL herr_t H5P__close_class(H5P_genclass_t *pclass); H5_DLL H5P_genprop_t *H5P__find_prop_plist(const H5P_genplist_t *plist, const char *name); H5_DLL hid_t H5P__new_plist_of_type(H5P_plist_type_t type); diff --git a/src/H5Pprivate.h b/src/H5Pprivate.h index 862c74f..6ebe5d3 100644 --- a/src/H5Pprivate.h +++ b/src/H5Pprivate.h @@ -160,7 +160,7 @@ struct H5VL_connector_prop_t; H5_DLL herr_t H5P_init(void); /* Internal versions of API routines */ -H5_DLL herr_t H5P_close(void *_plist); +H5_DLL herr_t H5P_close(H5P_genplist_t *plist); H5_DLL hid_t H5P_create_id(H5P_genclass_t *pclass, hbool_t app_ref); H5_DLL hid_t H5P_copy_plist(const H5P_genplist_t *old_plist, hbool_t app_ref); H5_DLL herr_t H5P_get(H5P_genplist_t *plist, const char *name, void *value); diff --git a/src/H5Ppublic.h b/src/H5Ppublic.h index 862a87f..72a2358 100644 --- a/src/H5Ppublic.h +++ b/src/H5Ppublic.h @@ -101,7 +101,7 @@ #define H5P_CRT_ORDER_INDEXED 0x0002 /* Default value for all property list classes */ -#define H5P_DEFAULT (hid_t)0 +#define H5P_DEFAULT 0 /* (hid_t) */ #ifdef __cplusplus extern "C" { @@ -112,13 +112,50 @@ extern "C" { /*******************/ /* Define property list class callback function pointer types */ +//! <!-- [H5P_cls_create_func_t_snip] --> typedef herr_t (*H5P_cls_create_func_t)(hid_t prop_id, void *create_data); +//! <!-- [H5P_cls_create_func_t_snip] --> + +//! <!-- [H5P_cls_copy_func_t_snip] --> typedef herr_t (*H5P_cls_copy_func_t)(hid_t new_prop_id, hid_t old_prop_id, void *copy_data); +//! <!-- [H5P_cls_copy_func_t_snip] --> + +//! <!-- [H5P_cls_close_func_t_snip] --> typedef herr_t (*H5P_cls_close_func_t)(hid_t prop_id, void *close_data); +//! <!-- [H5P_cls_close_func_t_snip] --> /* Define property list callback function pointer types */ +//! <!-- [H5P_prp_cb1_t_snip] --> +/** + * \brief Callback function for H5Pregister2(),H5Pregister1(),H5Pinsert2(),H5Pinsert1() + * + * \param[in] name The name of the property + * \param[in] size The size of the property in bytes + * \param[in,out] value The value for the property + * \return \herr_t + * + * \details The H5P_prp_cb1_t() describes the parameters used by the + * property create,copy and close callback functions. + */ typedef herr_t (*H5P_prp_cb1_t)(const char *name, size_t size, void *value); +//! <!-- [H5P_prp_cb1_t_snip] --> + +//! <!-- [H5P_prp_cb2_t_snip] --> +/** + * \brief Callback function for H5Pregister2(),H5Pregister1(),H5Pinsert2(),H5Pinsert1() + * + * \plist_id{prop_id} + * \param[in] name The name of the property + * \param[in] size The size of the property in bytes + * \param[in] value The value for the property + * \return \herr_t + * + * \details The H5P_prp_cb2_t() describes the parameters used by the + * property set ,copy and delete callback functions. + */ typedef herr_t (*H5P_prp_cb2_t)(hid_t prop_id, const char *name, size_t size, void *value); +//! <!-- [H5P_prp_cb2_t_snip] --> + typedef H5P_prp_cb1_t H5P_prp_create_func_t; typedef H5P_prp_cb2_t H5P_prp_set_func_t; typedef H5P_prp_cb2_t H5P_prp_get_func_t; @@ -126,56 +163,93 @@ typedef herr_t (*H5P_prp_encode_func_t)(const void *value, void **buf, size_t *s typedef herr_t (*H5P_prp_decode_func_t)(const void **buf, void *value); typedef H5P_prp_cb2_t H5P_prp_delete_func_t; typedef H5P_prp_cb1_t H5P_prp_copy_func_t; + +//! <!-- [H5P_prp_compare_func_t_snip] --> typedef int (*H5P_prp_compare_func_t)(const void *value1, const void *value2, size_t size); +//! <!-- [H5P_prp_compare_func_t_snip] --> + typedef H5P_prp_cb1_t H5P_prp_close_func_t; /* Define property list iteration function type */ +//! <!-- [H5P_iterate_t_snip] --> typedef herr_t (*H5P_iterate_t)(hid_t id, const char *name, void *iter_data); +//! <!-- [H5P_iterate_t_snip] --> -/* Actual IO mode property */ +//! <!--[H5D_mpio_actual_chunk_opt_mode_t_snip] --> +/** + * Actual IO mode property + * + * \details The default value, #H5D_MPIO_NO_CHUNK_OPTIMIZATION, is used for all + * I/O operations that do not use chunk optimizations, including + * non-collective I/O and contiguous collective I/O. + */ typedef enum H5D_mpio_actual_chunk_opt_mode_t { - /* The default value, H5D_MPIO_NO_CHUNK_OPTIMIZATION, is used for all I/O - * operations that do not use chunk optimizations, including non-collective - * I/O and contiguous collective I/O. - */ H5D_MPIO_NO_CHUNK_OPTIMIZATION = 0, + /**< No chunk optimization was performed. Either no collective I/O was + attempted or the dataset wasn't chunked. */ H5D_MPIO_LINK_CHUNK, + /**< Collective I/O is performed on all chunks simultaneously. */ H5D_MPIO_MULTI_CHUNK + /**< Each chunk was individually assigned collective or independent I/O based + on what fraction of processes access the chunk. If the fraction is greater + than the multi chunk ratio threshold, collective I/O is performed on that + chunk. The multi chunk ratio threshold can be set using + H5Pset_dxpl_mpio_chunk_opt_ratio(). The default value is 60%. */ } H5D_mpio_actual_chunk_opt_mode_t; +//! <!--[H5D_mpio_actual_chunk_opt_mode_t_snip] --> +//! <!-- [H5D_mpio_actual_io_mode_t_snip] --> +/** + * The following values are conveniently defined as a bit field so that + * we can switch from the default to independent or collective and then to + * mixed without having to check the original value. + */ typedef enum H5D_mpio_actual_io_mode_t { - /* The following four values are conveniently defined as a bit field so that - * we can switch from the default to independent or collective and then to - * mixed without having to check the original value. - * - * NO_COLLECTIVE means that either collective I/O wasn't requested or that - * no I/O took place. - * - * CHUNK_INDEPENDENT means that collective I/O was requested, but the - * chunk optimization scheme chose independent I/O for each chunk. - */ - H5D_MPIO_NO_COLLECTIVE = 0x0, + H5D_MPIO_NO_COLLECTIVE = 0x0, + /**< No collective I/O was performed. Collective I/O was not requested or + collective I/O isn't possible on this dataset */ H5D_MPIO_CHUNK_INDEPENDENT = 0x1, - H5D_MPIO_CHUNK_COLLECTIVE = 0x2, - H5D_MPIO_CHUNK_MIXED = 0x1 | 0x2, - - /* The contiguous case is separate from the bit field. */ + /**< HDF5 performed one the chunk collective optimization schemes and each + chunk was accessed independently */ + H5D_MPIO_CHUNK_COLLECTIVE = 0x2, + /**< HDF5 performed one the chunk collective optimization schemes and each + chunk was accessed collectively */ + H5D_MPIO_CHUNK_MIXED = 0x1 | 0x2, + /**< HDF5 performed one the chunk collective optimization schemes and some + chunks were accessed independently, some collectively. */ + /** \internal The contiguous case is separate from the bit field. */ H5D_MPIO_CONTIGUOUS_COLLECTIVE = 0x4 + /**< Collective I/O was performed on a contiguous dataset */ } H5D_mpio_actual_io_mode_t; +//! <!-- [H5D_mpio_actual_io_mode_t_snip] --> -/* Broken collective IO property */ +//! <!-- [H5D_mpio_no_collective_cause_t_snip] --> +/** + * Broken collective IO property + */ typedef enum H5D_mpio_no_collective_cause_t { - H5D_MPIO_COLLECTIVE = 0x00, - H5D_MPIO_SET_INDEPENDENT = 0x01, - H5D_MPIO_DATATYPE_CONVERSION = 0x02, - H5D_MPIO_DATA_TRANSFORMS = 0x04, - H5D_MPIO_MPI_OPT_TYPES_ENV_VAR_DISABLED = 0x08, - H5D_MPIO_NOT_SIMPLE_OR_SCALAR_DATASPACES = 0x10, - H5D_MPIO_NOT_CONTIGUOUS_OR_CHUNKED_DATASET = 0x20, - H5D_MPIO_PARALLEL_FILTERED_WRITES_DISABLED = 0x40, + H5D_MPIO_COLLECTIVE = 0x00, + /**< Collective I/O was performed successfully */ + H5D_MPIO_SET_INDEPENDENT = 0x01, + /**< Collective I/O was not performed because independent I/O was requested */ + H5D_MPIO_DATATYPE_CONVERSION = 0x02, + /**< Collective I/O was not performed because datatype conversions were required */ + H5D_MPIO_DATA_TRANSFORMS = 0x04, + /**< Collective I/O was not performed because data transforms needed to be applied */ + H5D_MPIO_MPI_OPT_TYPES_ENV_VAR_DISABLED = 0x08, + /**< \todo FIXME! */ + H5D_MPIO_NOT_SIMPLE_OR_SCALAR_DATASPACES = 0x10, + /**< Collective I/O was not performed because one of the dataspaces was neither simple nor scalar */ + H5D_MPIO_NOT_CONTIGUOUS_OR_CHUNKED_DATASET = 0x20, + /**< Collective I/O was not performed because the dataset was neither contiguous nor chunked */ + H5D_MPIO_PARALLEL_FILTERED_WRITES_DISABLED = 0x40, + /**< \todo FIXME! */ H5D_MPIO_ERROR_WHILE_CHECKING_COLLECTIVE_POSSIBLE = 0x80, - H5D_MPIO_NO_COLLECTIVE_MAX_CAUSE = 0x100 + /**< \todo FIXME! */ + H5D_MPIO_NO_COLLECTIVE_MAX_CAUSE = 0x100 + /**< Sentinel */ } H5D_mpio_no_collective_cause_t; +//! <!-- [H5D_mpio_no_collective_cause_t_snip] --> /********************/ /* Public Variables */ @@ -234,279 +308,8960 @@ H5_DLLVAR hid_t H5P_LST_REFERENCE_ACCESS_ID_g; /*********************/ /* Generic property list routines */ -H5_DLL hid_t H5Pcreate_class(hid_t parent, const char *name, H5P_cls_create_func_t cls_create, - void *create_data, H5P_cls_copy_func_t cls_copy, void *copy_data, - H5P_cls_close_func_t cls_close, void *close_data); -H5_DLL char * H5Pget_class_name(hid_t pclass_id); -H5_DLL hid_t H5Pcreate(hid_t cls_id); -H5_DLL herr_t H5Pregister2(hid_t cls_id, const char *name, size_t size, void *def_value, - H5P_prp_create_func_t prp_create, H5P_prp_set_func_t prp_set, - H5P_prp_get_func_t prp_get, H5P_prp_delete_func_t prp_del, - H5P_prp_copy_func_t prp_copy, H5P_prp_compare_func_t prp_cmp, - H5P_prp_close_func_t prp_close); -H5_DLL herr_t H5Pinsert2(hid_t plist_id, const char *name, size_t size, void *value, - H5P_prp_set_func_t prp_set, H5P_prp_get_func_t prp_get, - H5P_prp_delete_func_t prp_delete, H5P_prp_copy_func_t prp_copy, - H5P_prp_compare_func_t prp_cmp, H5P_prp_close_func_t prp_close); -H5_DLL herr_t H5Pset(hid_t plist_id, const char *name, const void *value); -H5_DLL htri_t H5Pexist(hid_t plist_id, const char *name); + +/** + * \ingroup GPLO + * + * \brief Terminates access to a property list + * + * \plist_id + * + * \return \herr_t + * + * \details H5Pclose() terminates access to a property list. All property + * lists should be closed when the application is finished + * accessing them. This frees resources used by the property + * list. + * + * \since 1.0.0 + * + */ +H5_DLL herr_t H5Pclose(hid_t plist_id); +/** + * \ingroup GPLOA + * + * \brief Closes an existing property list class + * + * \plistcls_id{plist_id} + * + * \return \herr_t + * + * \details H5Pclose_class() removes a property list class from the library. + * Existing property lists of this class will continue to exist, + * but new ones are not able to be created. + * + * \since 1.4.0 + * + */ +H5_DLL herr_t H5Pclose_class(hid_t plist_id); +/** + * \ingroup GPLO + * + * \brief Copies an existing property list to create a new property list + * + * \plist_id + * + * \return \hid_t{property list} + * + * \details H5Pcopy() copies an existing property list to create a new + * property list. The new property list has the same properties + * and values as the original property list. + * + * \since 1.0.0 + * + */ +H5_DLL hid_t H5Pcopy(hid_t plist_id); +/** + * \ingroup GPLOA + * + * \brief Copies a property from one list or class to another + * + * \param[in] dst_id Identifier of the destination property list or class + * \param[in] src_id Identifier of the source property list or class + * \param[in] name Name of the property to copy + * + * \return \herr_t + * + * \details H5Pcopy_prop() copies a property from one property list or + * class to another. + * + * If a property is copied from one class to another, all the + * property information will be first deleted from the destination + * class and then the property information will be copied from the + * source class into the destination class. + * + * If a property is copied from one list to another, the property + * will be first deleted from the destination list (generating a + * call to the close callback for the property, if one exists) + * and then the property is copied from the source list to the + * destination list (generating a call to the copy callback for + * the property, if one exists). + * + * If the property does not exist in the class or list, this + * call is equivalent to calling H5Pregister() or H5Pinsert() (for + * a class or list, as appropriate) and the create callback will + * be called in the case of the property being copied into a list + * (if such a callback exists for the property). + * + * \since 1.6.0 + * + */ +H5_DLL herr_t H5Pcopy_prop(hid_t dst_id, hid_t src_id, const char *name); +/** + * \ingroup GPLO + * + * \brief Creates a new property list as an instance of a property list class + * + * \plistcls_id{cls_id} + * + * \return \hid_t{property list} + * + * \details H5Pcreate() creates a new property list as an instance of + * some property list class. The new property list is initialized + * with default values for the specified class. The classes are as + * follows: + * + * <table> + * <tr> + * <th>Class Identifier</th> + * <th>Class Name</th> + * <th>Comments</th> + * </tr> + * <tr> + * <td>#H5P_ATTRIBUTE_CREATE</td> + * <td>attribute create</td> + * <td>Properties for attribute creation</td> + * </tr> + * <tr> + * <td>#H5P_DATASET_ACCESS</td> + * <td>dataset access</td> + * <td>Properties for dataset access</td> + * </tr> + * <tr> + * <td>#H5P_DATASET_CREATE</td> + * <td>dataset create</td> + * <td>Properties for dataset creation</td> + * </tr> + * <tr> + * <td>#H5P_DATASET_XFER</td> + * <td>data transfer</td> + * <td>Properties for raw data transfer</td> + * </tr> + * <tr> + * <td>#H5P_DATATYPE_ACCESS</td> + * <td>datatype access</td> + * <td>Properties for datatype access</td> + * </tr> + * <tr> + * <td>#H5P_DATATYPE_CREATE</td> + * <td>datatype create</td> + * <td>Properties for datatype creation</td> + * </tr> + * <tr> + * <td>#H5P_FILE_ACCESS</td> + * <td>file access</td> + * <td>Properties for file access</td> + * </tr> + * <tr> + * <td>#H5P_FILE_CREATE</td> + * <td>file create</td> + * <td>Properties for file creation</td> + * </tr> + * <tr> + * <td>#H5P_FILE_MOUNT</td> + * <td>file mount</td> + * <td>Properties for file mounting</td> + * </tr> + * <tr valign="top"> + * <td>#H5P_GROUP_ACCESS</td> + * <td>group access</td> + * <td>Properties for group access</td> + * </tr> + * <tr> + * <td>#H5P_GROUP_CREATE</td> + * <td>group create</td> + * <td>Properties for group creation</td> + * </tr> + * <tr> + * <td>#H5P_LINK_ACCESS</td> + * <td>link access</td> + * <td>Properties governing link traversal when accessing objects</td> + * </tr> + * <tr> + * <td>#H5P_LINK_CREATE</td> + * <td>link create</td> + * <td>Properties governing link creation</td> + * </tr> + * <tr> + * <td>#H5P_OBJECT_COPY</td> + * <td>object copy</td> + * <td>Properties governing the object copying process</td> + * </tr> + * <tr> + * <td>#H5P_OBJECT_CREATE</td> + * <td>object create</td> + * <td>Properties for object creation</td> + * </tr> + * <tr> + * <td>#H5P_STRING_CREATE</td> + * <td>string create</td> + * <td>Properties for character encoding when encoding strings or + * object names</td> + * </tr> + * <tr> + * <td>#H5P_VOL_INITIALIZE</td> + * <td>vol initialize</td> + * <td>Properties for VOL initialization</td> + * </tr> + * </table> + * + * This property list must eventually be closed with H5Pclose(); + * otherwise, errors are likely to occur. + * + * \version 1.12.0 The #H5P_VOL_INITIALIZE property list class was added + * \version 1.8.15 For each class, the class name returned by + * H5Pget_class_name() was added. + * The list of possible Fortran values was updated. + * \version 1.8.0 The following property list classes were added at this + * release: #H5P_DATASET_ACCESS, #H5P_GROUP_CREATE, + * #H5P_GROUP_ACCESS, #H5P_DATATYPE_CREATE, + * #H5P_DATATYPE_ACCESS, #H5P_ATTRIBUTE_CREATE + * + * \since 1.0.0 + * + */ +H5_DLL hid_t H5Pcreate(hid_t cls_id); +/** + * \ingroup GPLOA + * + * \brief Creates a new property list class + * + * \plistcls_id{parent} + * \param[in] name Name of property list class to register + * \param[in] create Callback routine called when a property list is + * created + * \param[in] create_data Pointer to user-defined class create data, to be + * passed along to class create callback + * \param[in] copy Callback routine called when a property list is + * copied + * \param[in] copy_data Pointer to user-defined class copy data, to be + * passed along to class copy callback + * \param[in] close Callback routine called when a property list is + * being closed + * \param[in] close_data Pointer to user-defined class close data, to be + * passed along to class close callback + * + * \return \hid_t{property list class} + * + * \details H5Pcreate_class() registers a new property list class with the + * library. The new property list class can inherit from an + * existing property list class, \p parent, or may be derived + * from the default “empty” class, NULL. New classes with + * inherited properties from existing classes may not remove + * those existing properties, only add or remove their own class + * properties. Property list classes defined and supported in the + * HDF5 library distribution are listed and briefly described in + * H5Pcreate(). The \p create routine is called when a new property + * list of this class is being created. The #H5P_cls_create_func_t + * callback function is defined as follows: + * + * \snippet this H5P_cls_create_func_t_snip + * + * The parameters to this callback function are defined as follows: + * <table> + * <tr> + * <td>\ref hid_t \c prop_id</td> + * <td>IN: The identifier of the property list being created</td> + * </tr> + * <tr> + * <td>\Code{void * create_data}</td> + * <td>IN: User pointer to any class creation data required</td> + * </tr> + * </table> + * + * The \p create routine is called after any registered + * \p create function is called for each property value. If the + * \p create routine returns a negative value, the new list is not + * returned to the user and the property list creation routine returns + * an error value. + * + * The \p copy routine is called when an existing property + * list of this class is copied. The #H5P_cls_copy_func_t callback + * function is defined as follows: + * \snippet this H5P_cls_copy_func_t_snip + * + * The parameters to this callback function are defined as follows: + * <table> + * <tr> + * <td>\ref hid_t \c prop_id</td> + * <td>IN: The identifier of the property list created by copying</td> + * </tr> + * <tr> + * <td>\Code{void * copy_data}</td> + * <td>IN: User pointer to any class copy data required</td> + * </tr> + * </table> + * + * The \p copy routine is called after any registered \p copy function + * is called for each property value. If the \p copy routine returns a + * negative value, the new list is not returned to the user and the + * property list \p copy routine returns an error value. + * + * The \p close routine is called when a property list of this class + * is being closed. The #H5P_cls_close_func_t callback function is + * defined as follows: + * \snippet this H5P_cls_close_func_t_snip + * + * The parameters to this callback function are defined as follows: + * <table> + * <tr> + * <td>\ref hid_t \c prop_id</td> + * <td>IN: The identifier of the property list being closed</td> + * </tr> + * <tr> + * <td>\Code{void * close_data}</td> + * <td>IN: User pointer to any class close data required</td> + * </tr> + * </table> + * + * The \p close routine is called before any registered \p close + * function is called for each property value. If the \p close routine + * returns a negative value, the property list close routine returns + * an error value but the property list is still closed. + * + * H5Pclose_class() can be used to release the property list class + * identifier returned by this function so that resources leaks will + * not develop. + * + * \since 1.4.0 + * + */ +H5_DLL hid_t H5Pcreate_class(hid_t parent, const char *name, H5P_cls_create_func_t create, void *create_data, + H5P_cls_copy_func_t copy, void *copy_data, H5P_cls_close_func_t close, + void *close_data); +/** + * \ingroup GPLO + * + * \brief Decodes property list received in a binary object buffer and + * returns a new property list identifier + * + * \param[in] buf Buffer holding the encoded property list + * + * \return \hid_tv{object} + * + * \details Given a binary property list description in a buffer, H5Pdecode() + * reconstructs the HDF5 property list and returns an identifier + * for the new property list. The binary description of the property + * list is encoded by H5Pencode(). + * + * The user is responsible for passing in the correct buffer. + * + * The property list identifier returned by this function should be + * released with H5Pclose() when the identifier is no longer needed + * so that resource leaks will not develop. + * + * \note Some properties cannot be encoded and therefore will not be available + * in the decoded property list. These properties are discussed in + * H5Pencode(). + * + * \since 1.10.0 + * + */ +H5_DLL hid_t H5Pdecode(const void *buf); +/** + * \ingroup GPLO + * + * \brief Encodes the property values in a property list into a binary + * buffer + * + * \plist_id + * \param[out] buf Buffer into which the property list will be encoded. + * If the provided buffer is NULL, the size of the + * buffer required is returned through \p nalloc; the + * function does nothing more. + * \param[out] nalloc The size of the required buffer + * \fapl_id + * + * \return \herr_t + * + * \details H5Pencode2() encodes the property list \p plist_id into the + * binary buffer \p buf, according to the file format setting + * specified by the file access property list \p fapl_id. + * + * If the required buffer size is unknown, \p buf can be passed + * in as NULL and the function will set the required buffer size + * in \p nalloc. The buffer can then be created and the property + * list encoded with a subsequent H5Pencode2() call. + * + * If the buffer passed in is not big enough to hold the encoded + * properties, the H5Pencode2() call can be expected to fail with + * a segmentation fault. + * + * The file access property list \p fapl_id is used to + * control the encoding via the \a libver_bounds property + * (see H5Pset_libver_bounds()). If the \a libver_bounds + * property is missing, H5Pencode2() proceeds as if the \a + * libver_bounds property were set to (#H5F_LIBVER_EARLIEST, + * #H5F_LIBVER_LATEST). (Functionally, H5Pencode1() is identical to + * H5Pencode2() with \a libver_bounds set to (#H5F_LIBVER_EARLIEST, + * #H5F_LIBVER_LATEST).) + * Properties that do not have encode callbacks will be skipped. + * There is currently no mechanism to register an encode callback for + * a user-defined property, so user-defined properties cannot currently + * be encoded. + * + * Some properties cannot be encoded, particularly properties that are + * reliant on local context. + * + * \b Motivation: + * This function was introduced in HDF5-1.12 as part of the \a H5Sencode + * format change to enable 64-bit selection encodings and a dataspace + * selection that is tied to a file. + * + * \since 1.12.0 + * + */ H5_DLL herr_t H5Pencode2(hid_t plist_id, void *buf, size_t *nalloc, hid_t fapl_id); -H5_DLL hid_t H5Pdecode(const void *buf); -H5_DLL herr_t H5Pget_size(hid_t id, const char *name, size_t *size); -H5_DLL herr_t H5Pget_nprops(hid_t id, size_t *nprops); -H5_DLL hid_t H5Pget_class(hid_t plist_id); -H5_DLL hid_t H5Pget_class_parent(hid_t pclass_id); -H5_DLL herr_t H5Pget(hid_t plist_id, const char *name, void *value); +/** + * \ingroup GPLOA + * + * \brief Compares two property lists or classes for equality + * + * \param[in] id1 First property object to be compared + * \param[in] id2 Second property object to be compared + * + * \return \htri_t + * + * \details H5Pequal() compares two property lists or classes to determine + * whether they are equal to one another. + * + * Either both \p id1 and \p id2 must be property lists or both + * must be classes; comparing a list to a class is an error. + * + * \since 1.4.0 + * + */ H5_DLL htri_t H5Pequal(hid_t id1, hid_t id2); +/** + * \ingroup GPLOA + * + * \brief Queries whether a property name exists in a property list or + * class + * + * \param[in] plist_id Identifier for the property list or class to query + * \param[in] name Name of property to check for + * + * \return \htri_t + * + * \details H5Pexist() determines whether a property exists within a + * property list or class. + * + * \since 1.4.0 + * + */ +H5_DLL htri_t H5Pexist(hid_t plist_id, const char *name); +/** + * \ingroup GPLOA + * + * \brief Queries the value of a property + * + * \plist_id + * \param[in] name Name of property to query + * \param[out] value Pointer to a location to which to copy the value of + * the property + * + * \return \herr_t + * + * \details H5Pget() retrieves a copy of the value for a property in a + * property list. If there is a \p get callback routine registered + * for this property, the copy of the value of the property will + * first be passed to that routine and any changes to the copy of + * the value will be used when returning the property value from + * this routine. + * + * This routine may be called for zero-sized properties with the + * \p value set to NULL. The \p get routine will be called with + * a NULL value if the callback exists. + * + * The property name must exist or this routine will fail. + * + * If the \p get callback routine returns an error, \ value will + * not be modified. + * + * \since 1.4.0 + * + */ +H5_DLL herr_t H5Pget(hid_t plist_id, const char *name, void *value); +/** + *\ingroup GPLO + * + * \brief Returns the property list class identifier for a property list + * + * \plist_id + * + * \return \hid_t{property list class} + * + * \details H5Pget_class() returns the property list class identifier for + * the property list identified by the \p plist_id parameter. + * + * Note that H5Pget_class() returns a value of #hid_t type, an + * internal HDF5 identifier, rather than directly returning a + * property list class. That identifier can then be used with + * either H5Pequal() or H5Pget_class_name() to determine which + * predefined HDF5 property list class H5Pget_class() has returned. + * + * A full list of valid predefined property list classes appears + * in the description of H5Pcreate(). + * + * Determining the HDF5 property list class name with H5Pequal() + * requires a series of H5Pequal() calls in an if-else sequence. + * An iterative sequence of H5Pequal() calls can compare the + * identifier returned by H5Pget_class() to members of the list of + * valid property list class names. A pseudo-code snippet might + * read as follows: + * + * \code + * plist_class_id = H5Pget_class (dsetA_plist); + * + * if H5Pequal (plist_class_id, H5P_OBJECT_CREATE) = TRUE; + * [ H5P_OBJECT_CREATE is the property list class ] + * [ returned by H5Pget_class. ] + * + * else if H5Pequal (plist_class_id, H5P_DATASET_CREATE) = TRUE; + * [ H5P_DATASET_CREATE is the property list class. ] + * + * else if H5Pequal (plist_class_id, H5P_DATASET_XFER) = TRUE; + * [ H5P_DATASET_XFER is the property list class. ] + * + * . + * . [ Continuing the iteration until a match is found. ] + * . + * \endcode + * + * H5Pget_class_name() returns the property list class name directly + * as a string: + * + * \code + * plist_class_id = H5Pget_class (dsetA_plist); + * plist_class_name = H5Pget_class_name (plist_class_id) + * \endcode + * + * Note that frequent use of H5Pget_class_name() can become a + * performance problem in a high-performance environment. The + * H5Pequal() approach is generally much faster. + * + * \version 1.6.0 Return type changed in this release. + * \since 1.0.0 + * + */ +H5_DLL hid_t H5Pget_class(hid_t plist_id); +/** + * \ingroup GPLOA + * + * \brief Retrieves the name of a class + * + * \plistcls_id{pclass_id} + * + * \return Returns a pointer to an allocated string containing the class + * name if successful, and NULL if not successful. + * + * \details H5Pget_class_name() retrieves the name of a generic property + * list class. The pointer to the name must be freed by the user + * with a call to H5free_memory() after each successful call. + * + * <table> + * <tr> + * <th>Class Name (class identifier) Returned</th> + * <th>Property List Class</th> + * <th>Expanded Name of the Property List Class</th> + * <th>The Class Identifier Used with H5Pcreate</th> + * <th>Comments</th> + * </tr> + * <tr> + * <td>attribute create</td> + * <td>acpl</td> + * <td>Attribute Creation Property List</td> + * <td>H5P_ATTRIBUTE_CREATE</td> + * <td> </td> + * </tr> + * <tr> + * <td>dataset access</td> + * <td>dapl</td> + * <td>Dataset Access Property List</td> + * <td>H5P_DATASET_ACCESS</td> + * <td> </td> + * </tr> + * <tr> + * <td>dataset create</td> + * <td>dcpl</td> + * <td>Dataset Creation Property List</td> + * <td>H5P_DATASET_CREATE</td> + * <td> </td> + * </tr> + * <tr> + * <td>data transfer</td> + * <td>dxpl</td> + * <td>Data Transfer Property List</td> + * <td>H5P_DATASET_XFER</td> + * <td> </td> + * </tr> + * <tr> + * <td>datatype access</td> + * <td> </td> + * <td> </td> + * <td>H5P_DATATYPE_ACCESS</td> + * <td>This class can be created, but there are no properties + * in the class currently. + * </td> + * </tr> + * <tr> + * <td>datatype create</td> + * <td> </td> + * <td> </td> + * <td>H5P_DATATYPE_CREATE</td> + * <td>This class can be created, but there + * are no properties in the class currently.</td> + * </tr> + * <tr> + * <td>file access</td> + * <td>fapl</td> + * <td>File Access Property List</td> + * <td>H5P_FILE_ACCESS</td> + * <td> </td> + * </tr> + * <tr> + * <td>file create</td> + * <td>fcpl</td> + * <td>File Creation Property List</td> + * <td>H5P_FILE_CREATE</td> + * <td> </td> + * </tr> + * <tr> + * <td>file mount</td> + * <td>fmpl</td> + * <td>File Mount Property List</td> + * <td>H5P_FILE_MOUNT</td> + * <td> </td> + * </tr> + * <tr> + * <td>group access</td> + * <td> </td> + * <td> </td> + * <td>H5P_GROUP_ACCESS</td> + * <td>This class can be created, but there + * are no properties in the class currently.</td> + * </tr> + * <tr> + * <td>group create</td> + * <td>gcpl</td> + * <td>Group Creation Property List</td> + * <td>H5P_GROUP_CREATE</td> + * <td> </td> + * </tr> + * <tr> + * <td>link access</td> + * <td>lapl</td> + * <td>Link Access Property List</td> + * <td>H5P_LINK_ACCESS</td> + * <td> </td> + * </tr> + * <tr> + * <td>link create</td> + * <td>lcpl</td> + * <td>Link Creation Property List</td> + * <td>H5P_LINK_CREATE</td> + * <td> </td> + * </tr> + * <tr> + * <td>object copy</td> + * <td>ocpypl</td> + * <td>Object Copy Property List</td> + * <td>H5P_OBJECT_COPY</td> + * <td> </td> + * </tr> + * <tr> + * <td>object create</td> + * <td>ocpl</td> + * <td>Object Creation Property List</td> + * <td>H5P_OBJECT_CREATE</td> + * <td> </td> + * </tr> + * <tr> + * <td>string create</td> + * <td>strcpl</td> + * <td>String Creation Property List</td> + * <td>H5P_STRING_CREATE</td> + * <td> </td> + * </tr> + * </table> + * + * \since 1.4.0 + * + */ +H5_DLL char *H5Pget_class_name(hid_t pclass_id); +/** + * \ingroup GPLOA + * + * \brief Retrieves the parent class of a property class + * + * \plistcls_id{pclass_id} + * + * \return \hid_t{parent class object} + * + * \details H5Pget_class_parent() retrieves an identifier for the parent + * class of a property class. + * + * \since 1.4.0 + * + */ +H5_DLL hid_t H5Pget_class_parent(hid_t pclass_id); +/** + * \ingroup GPLOA + * + * \brief Queries the number of properties in a property list or class + * + * \param[in] id Identifier for property object to query + * \param[out] nprops Number of properties in object + * + * \return \herr_t + * + * \details H5Pget_nprops() retrieves the number of properties in a + * property list or property list class. + * + * If \p id is a property list identifier, the current number of + * properties in the list is returned in \p nprops. + * + * If \p id is a property list class identifier, the number of + * registered properties in the class is returned in \p nprops. + * + * \since 1.4.0 + * + */ +H5_DLL herr_t H5Pget_nprops(hid_t id, size_t *nprops); +/** + * \ingroup GPLOA + * + * \brief Queries the size of a property value in bytes + * + * \param[in] id Identifier of property object to query + * \param[in] name Name of property to query + * \param[out] size Size of property in bytes + * + * \return \herr_t + * + * \details H5Pget_size() retrieves the size of a property's value in + * bytes. This function operates on both property lists and + * property classes. + * + * Zero-sized properties are allowed and return 0. + * + * \since 1.4.0 + * + */ +H5_DLL herr_t H5Pget_size(hid_t id, const char *name, size_t *size); +/** + * \ingroup GPLOA + * + * \brief Registers a temporary property with a property list + * + * \plist_id + * \param[in] name Name of property to create + * \param[in] size Size of property in bytes + * \param[in] value Initial value for the property + * \param[in] set Callback routine called before a new value is copied + * into the property's value + * \param[in] get Callback routine called when a property value is + * retrieved from the property + * \param[in] prp_del Callback routine called when a property is deleted + * from a property list + * \param[in] copy Callback routine called when a property is copied + * from an existing property list + * \param[in] compare Callback routine called when a property is compared + * with another property list + * \param[in] close Callback routine called when a property list is + * being closed and the property value will be disposed + * of + * + * \return \herr_t + * + * \details H5Pinsert2() creates a new property in a property + * list. The property will exist only in this property list and + * copies made from it. + * + * The initial property value must be provided in \p value and + * the property value will be set accordingly. + * + * The name of the property must not already exist in this list, + * or this routine will fail. + * + * The \p set and \p get callback routines may be set to NULL + * if they are not needed. + * + * Zero-sized properties are allowed and do not store any data + * in the property list. The default value of a zero-size + * property may be set to NULL. They may be used to indicate the + * presence or absence of a particular piece of information. + * + * The \p set routine is called before a new value is copied + * into the property. The #H5P_prp_set_func_t callback function + * is defined as follows: + * \snippet this H5P_prp_cb2_t_snip + * + * The parameters to the callback function are defined as follows: + * <table> + * <tr> + * <td>\ref hid_t \c prop_id</td> + * <td>IN: The identifier of the property list being + * modified</td> + * </tr> + * <tr> + * <td>\Code{const char * name}</td> + * <td>IN: The name of the property being modified</td> + * </tr> + * <tr> + * <td>\Code{size_t size}</td> + * <td>IN: The size of the property in bytes</td> + * </tr> + * <tr> + * <td>\Code{void * value}</td> + * <td>IN: Pointer to new value pointer for the property + * being modified</td> + * </tr> + * </table> + * + * The \p set routine may modify the value pointer to be set and + * those changes will be used when setting the property's value. + * If the \p set routine returns a negative value, the new property + * value is not copied into the property and the \p set routine + * returns an error value. The \p set routine will be called for + * the initial value. + * + * \b Note: The \p set callback function may be useful to range + * check the value being set for the property or may perform some + * transformation or translation of the value set. The \p get + * callback would then reverse the transformation or translation. + * A single \p get or \p set callback could handle multiple + * properties by performing different actions based on the + * property name or other properties in the property list. + * + * The \p get routine is called when a value is retrieved from + * a property value. The #H5P_prp_get_func_t callback function + * is defined as follows: + * + * \snippet this H5P_prp_cb2_t_snip + * + * The parameters to the above callback function are: + * + * <table> + * <tr> + * <td>\ref hid_t \c prop_id</td> + * <td>IN: The identifier of the property list being queried</td> + * </tr> + * <tr> + * <td>\Code{const char * name}</td> + * <td>IN: The name of the property being queried</td> + * </tr> + * <tr> + * <td>\Code{size_t size}</td> + * <td>IN: The size of the property in bytes</td> + * </tr> + * <tr> + * <td>\Code{void * value}</td> + * <td>IN: The value of the property being returned</td> + * </tr> + * </table> + * + * The \p get routine may modify the value to be returned from + * the query and those changes will be preserved. If the \p get + * routine returns a negative value, the query routine returns + * an error value. + * + * The \p prp_del routine is called when a property is being + * deleted from a property list. The #H5P_prp_delete_func_t + * callback function is defined as follows: + * + * \snippet this H5P_prp_cb2_t_snip + * + * The parameters to the above callback function are: + * + * <table> + * <tr> + * <td>\ref hid_t \c prop_id</td> + * <td>IN: The identifier of the property list the property is + * being deleted from</td> + * </tr> + * <tr> + * <td>\Code{const char * name}</td> + * <td>IN: The name of the property in the list</td> + * </tr> + * <tr> + * <td>\Code{size_t size}</td> + * <td>IN: The size of the property in bytes</td> + * </tr> + * <tr> + * <td>\Code{void * value}</td> + * <td>IN: The value for the property being deleted</td> + * </tr> + * </table> + * + * The \p prp_del routine may modify the value passed in, but the + * value is not used by the library when the \p prp_del routine + * returns. If the \p prp_del routine returns a negative value, + * the property list \p prp_del routine returns an error value but + * the property is still deleted. + * + * The \p copy routine is called when a new property list with + * this property is being created through a \p copy operation. + * + * The #H5P_prp_copy_func_t callback function is defined as follows: + * + * \snippet this H5P_prp_cb1_t_snip + * + * The parameters to the above callback function are: + * <table> + * <tr> + * <td>\Code{const char * name}</td> + * <td>IN: The name of the property being copied</td> + * </tr> + * <tr> + * <td>\Code{size_t size}</td> + * <td>IN: The size of the property in bytes</td> + * </tr> + * <tr> + * <td>\Code{void * value}</td> + * <td>IN/OUT: The value for the property being copied</td> + * </tr> + * </table> + * + * The \p copy routine may modify the value to be set and those + * changes will be stored as the new value of the property. If the + * \p copy routine returns a negative value, the new property value + * is not copied into the property and the copy routine returns an + * error value. + * + * The \p compare routine is called when a property list with this + * property is compared to another property list with the same + * property. + * + * The #H5P_prp_compare_func_t callback function is defined as + * follows: + * + * \snippet this H5P_prp_compare_func_t_snip + * + * The parameters to the callback function are defined as follows: + * + * <table> + * <tr> + * <td>\Code{const void * value1}</td> + * <td>IN: The value of the first property to compare</td> + * </tr> + * <tr> + * <td>\Code{const void * value2}</td> + * <td>IN: The value of the second property to compare</td> + * </tr> + * <tr> + * <td>\Code{size_t size}</td> + * <td>IN: The size of the property in bytes</td> + * </tr> + * </table> + * + * The \p compare routine may not modify the values. The \p compare + * routine should return a positive value if \p value1 is greater + * than \p value2, a negative value if \p value2 is greater than + * \p value1 and zero if \p value1 and \p value2 are equal. + * + * The \p close routine is called when a property list with this + * property is being closed. + * + * The #H5P_prp_close_func_t callback function is defined as follows: + * \snippet this H5P_prp_cb1_t_snip + * + * The parameters to the callback function are defined as follows: + * + * <table> + * <tr> + * <td>\Code{const char * name}</td> + * <td>IN: The name of the property in the list</td> + * </tr> + * <tr> + * <td>\Code{size_t size}</td> + * <td>IN: The size of the property in bytes</td> + * </tr> + * <tr> + * <td>\Code{void * value}</td> + * <td>IN: The value for the property being closed</td> + * </tr> + * </table> + * + * The \p close routine may modify the value passed in, the + * value is not used by the library when the close routine + * returns. If the \p close routine returns a negative value, + * the property list \p close routine returns an error value + * but the property list is still closed. + * + * \b Note: There is no \p create callback routine for temporary + * property list objects; the initial value is assumed to + * have any necessary setup already performed on it. + * + * \since 1.8.0 + * + */ +H5_DLL herr_t H5Pinsert2(hid_t plist_id, const char *name, size_t size, void *value, H5P_prp_set_func_t set, + H5P_prp_get_func_t get, H5P_prp_delete_func_t prp_del, H5P_prp_copy_func_t copy, + H5P_prp_compare_func_t compare, H5P_prp_close_func_t close); +/** + * \ingroup GPLOA + * + * \brief Determines whether a property list is a member of a class + * + * \plist_id + * \plistcls_id{pclass_id} + * + * \return \htri_t + * + * \details H5Pisa_class() checks to determine whether the property list + * \p plist_id is a member of the property list class + * \p pclass_id. + * + * \see H5Pcreate() + * + * \since 1.6.0 + * + */ H5_DLL htri_t H5Pisa_class(hid_t plist_id, hid_t pclass_id); -H5_DLL int H5Piterate(hid_t id, int *idx, H5P_iterate_t iter_func, void *iter_data); -H5_DLL herr_t H5Pcopy_prop(hid_t dst_id, hid_t src_id, const char *name); +/** + * \ingroup GPLOA + * + * \brief Iterates over properties in a property class or list + * + * \param[in] id Identifier of property object to iterate over + * \param[in,out] idx Index of the property to begin with + * \param[in] iter_func Function pointer to function to be called + * with each property iterated over + * \param[in,out] iter_data Pointer to iteration data from user + * + * \return On success: the return value of the last call to \p iter_func if + * it was non-zero; zero if all properties have been processed. + * On Failure, a negative value + * + * \details H5Piterate() iterates over the properties in the property + * object specified in \p id, which may be either a property + * list or a property class, performing a specified operation + * on each property in turn. + * + * For each property in the object, \p iter_func and the + * additional information specified below are passed to the + * #H5P_iterate_t operator function. + * + * The iteration begins with the \p idx-th property in the + * object; the next element to be processed by the operator + * is returned in \p idx. If \p idx is NULL, the iterator + * starts at the first property; since no stopping point is + * returned in this case, the iterator cannot be restarted if + * one of the calls to its operator returns non-zero. + * + * The prototype for the #H5P_iterate_t operator is as follows: + * \snippet this H5P_iterate_t_snip + * + * The operation receives the property list or class + * identifier for the object being iterated over, \p id, the + * name of the current property within the object, \p name, + * and the pointer to the operator data passed in to H5Piterate(), + * \p iter_data. The valid return values from an operator are + * as follows: + * + * <table> + * <tr> + * <td>Zero</td> + * <td>Causes the iterator to continue, returning zero when all + * properties have been processed</td> + * </tr> + * <tr> + * <td>Positive</td> + * <td>Causes the iterator to immediately return that positive + * value, indicating short-circuit success. The iterator + * can be restarted at the index of the next property</td> + * </tr> + * <tr> + * <td>Negative</td> + * <td>Causes the iterator to immediately return that value, + * indicating failure. The iterator can be restarted at the + * index of the next property</td> + * </tr> + * </table> + * H5Piterate() assumes that the properties in the object + * identified by \p id remain unchanged through the iteration. + * If the membership changes during the iteration, the function's + * behavior is undefined. + * + * \since 1.4.0 + * + */ +H5_DLL int H5Piterate(hid_t id, int *idx, H5P_iterate_t iter_func, void *iter_data); +/** + * \ingroup GPLOA + * + * \brief Registers a permanent property with a property list class + * + * \plistcls_id{cls_id} + * \param[in] name Name of property to register + * \param[in] size Size of property in bytes + * \param[in] def_value Default value for property in newly created + * property lists + * \param[in] create Callback routine called when a property list is + * being created and the property value will be + * initialized + * \param[in] set Callback routine called before a new value is + * copied into the property's value + * \param[in] get Callback routine called when a property value is + * retrieved from the property + * \param[in] prp_del Callback routine called when a property is deleted + * from a property list + * \param[in] copy Callback routine called when a property is copied + * from a property list + * \param[in] compare Callback routine called when a property is compared + * with another property list + * \param[in] close Callback routine called when a property list is + * being closed and the property value will be + * disposed of + * + * \return \herr_t + * + * \details H5Pregister2() registers a new property with a property list + * class. The \p cls_id identifier can be obtained by calling + * H5Pcreate_class(). The property will exist in all property + * list objects of \p cl_id created after this routine finishes. The + * name of the property must not already exist, or this routine + * will fail. The default property value must be provided and all + * new property lists created with this property will have the + * property value set to the default value. Any of the callback + * routines may be set to NULL if they are not needed. + * + * Zero-sized properties are allowed and do not store any data in + * the property list. These may be used as flags to indicate the + * presence or absence of a particular piece of information. The + * default pointer for a zero-sized property may be set to NULL. + * The property \p create and \p close callbacks are called for + * zero-sized properties, but the \p set and \p get callbacks are + * never called. + * + * The \p create routine is called when a new property list with + * this property is being created. The #H5P_prp_create_func_t + * callback function is defined as follows: + * + * \snippet this H5P_prp_cb1_t_snip + * + * The parameters to this callback function are defined as follows: + * + * <table> + * <tr> + * <td>\Code{const char * name}</td> + * <td>IN: The name of the property being modified</td> + * </tr> + * <tr> + * <td>\Code{size_t size}</td> + * <td>IN: The size of the property in bytes</td> + * </tr> + * <tr> + * <td>\Code{void * value}</td> + * <td>IN/OUT: The default value for the property being created, + * which will be passed to H5Pregister2()</td> + * </tr> + * </table> + * + * The \p create routine may modify the value to be set and those + * changes will be stored as the initial value of the property. + * If the \p create routine returns a negative value, the new + * property value is not copied into the property and the + * \p create routine returns an error value. + * + * The \p set routine is called before a new value is copied into + * the property. The #H5P_prp_set_func_t callback function is defined + * as follows: + * + * \snippet this H5P_prp_cb2_t_snip + * + * The parameters to this callback function are defined as follows: + * + * <table> + * <tr> + * <td>\ref hid_t \c prop_id</td> + * <td>IN: The identifier of the property list being modified</td> + * </tr> + * <tr> + * <td>\Code{const char * name}</td> + * <td>IN: The name of the property being modified</td> + * </tr> + * <tr> + * <td>\Code{size_t size}</td> + * <td>IN: The size of the property in bytes</td> + * </tr> + * <tr> + * <td>\Code{void *value}</td> + * <td>IN/OUT: Pointer to new value pointer for the property + * being modified</td> + * </tr> + * </table> + * + * The \p set routine may modify the value pointer to be set and + * those changes will be used when setting the property's value. + * If the \p set routine returns a negative value, the new property + * value is not copied into the property and the \p set routine + * returns an error value. The \p set routine will not be called + * for the initial value; only the \p create routine will be called. + * + * \b Note: The \p set callback function may be useful to range + * check the value being set for the property or may perform some + * transformation or translation of the value set. The \p get + * callback would then reverse the transformation or translation. + * A single \p get or \p set callback could handle multiple + * properties by performing different actions based on the property + * name or other properties in the property list. + * + * The \p get routine is called when a value is retrieved from a + * property value. The #H5P_prp_get_func_t callback function is + * defined as follows: + * + * \snippet this H5P_prp_cb2_t_snip + * + * The parameters to the callback function are defined as follows: + * + * <table> + * <tr> + * <td>\ref hid_t \c prop_id</td> + * <td>IN: The identifier of the property list being + * queried</td> + * </tr> + * <tr> + * <td>\Code{const char * name}</td> + * <td>IN: The name of the property being queried</td> + * </tr> + * <tr> + * <td>\Code{size_t size}</td> + * <td>IN: The size of the property in bytes</td> + * </tr> + * <tr> + * <td>\Code{void * value}</td> + * <td>IN/OUT: The value of the property being returned</td> + * </tr> + * </table> + * + * The \p get routine may modify the value to be returned from the + * query and those changes will be returned to the calling routine. + * If the \p set routine returns a negative value, the query + * routine returns an error value. + * + * The \p prp_del routine is called when a property is being + * deleted from a property list. The #H5P_prp_delete_func_t + * callback function is defined as follows: + * + * \snippet this H5P_prp_cb2_t_snip + * + * The parameters to the callback function are defined as follows: + * + * <table> + * <tr> + * <td>\ref hid_t \c prop_id</td> + * <td>IN: The identifier of the property list the property is + * being deleted from</td> + * </tr> + * <tr> + * <td>\Code{const char * name}</td> + * <td>IN: The name of the property in the list</td> + * </tr> + * <tr> + * <td>\Code{size_t size}</td> + * <td>IN: The size of the property in bytes</td> + * </tr> + * <tr> + * <td>\Code{void * value}</td> + * <td>IN: The value for the property being deleted</td> + * </tr> + * </table> + * + * The \p prp_del routine may modify the value passed in, but the + * value is not used by the library when the \p prp_del routine + * returns. If the \p prp_del routine returns a negative value, + * the property list delete routine returns an error value but + * the property is still deleted. + * + * The \p copy routine is called when a new property list with + * this property is being created through a \p copy operation. + * The #H5P_prp_copy_func_t callback function is defined as follows: + * + * \snippet this H5P_prp_cb1_t_snip + * + * The parameters to the callback function are defined as follows: + * + * <table> + * <tr> + * <td>\Code{const char * name}</td> + * <td>IN: The name of the property being copied</td> + * </tr> + * <tr> + * <td>\Code{size_t size}</td> + * <td>IN: The size of the property in bytes</td> + * </tr> + * <tr> + * <td>\Code{void * value}</td> + * <td>IN/OUT: The value for the property being copied</td> + * </tr> + * </table> + * + * The \p copy routine may modify the value to be set and those + * changes will be stored as the new value of the property. If + * the \p copy routine returns a negative value, the new + * property value is not copied into the property and the \p copy + * routine returns an error value. + * + * The \p compare routine is called when a property list with this + * property is compared to another property list with the same + * property. The #H5P_prp_compare_func_t callback function is + * defined as follows: + * + * \snippet this H5P_prp_compare_func_t_snip + * + * The parameters to the callback function are defined as follows: + * + * <table> + * <tr> + * <td>\Code{const void * value1}</td> + * <td>IN: The value of the first property to compare</td> + * </tr> + * <tr> + * <td>\Code{const void * value2}</td> + * <td>IN: The value of the second property to compare</td> + * </tr> + * <tr> + * <td>\Code{size_t size}</td> + * <td>IN: The size of the property in bytes</td> + * </tr> + * </table> + * + * The \p compare routine may not modify the values. The \p compare + * routine should return a positive value if \p value1 is greater + * than \p value2, a negative value if \p value2 is greater than + * \p value1 and zero if \p value1 and \p value2 are equal. + * + * The \p close routine is called when a property list with this + * property is being closed. The #H5P_prp_close_func_t callback + * function is defined as follows: + * + * \snippet this H5P_prp_cb1_t_snip + * + * The parameters to the callback function are defined as follows: + * + * <table> + * <tr> + * <td>\Code{const char * name}</td> + * <td>IN: The name of the property in the list</td> + * </tr> + * <tr> + * <td>\Code{size_t size}</td> + * <td>IN: The size of the property in bytes</td> + * </tr> + * <tr> + * <td>\Code{void * value}</td> + * <td>IN: The value for the property being closed</td> + * </tr> + * </table> + * + * The \p close routine may modify the value passed in, but the + * value is not used by the library when the \p close routine returns. + * If the \p close routine returns a negative value, the property + * list close routine returns an error value but the property list is + * still closed. + * + * \since 1.8.0 + * + */ +H5_DLL herr_t H5Pregister2(hid_t cls_id, const char *name, size_t size, void *def_value, + H5P_prp_create_func_t create, H5P_prp_set_func_t set, H5P_prp_get_func_t get, + H5P_prp_delete_func_t prp_del, H5P_prp_copy_func_t copy, + H5P_prp_compare_func_t compare, H5P_prp_close_func_t close); +/** + * \ingroup GPLOA + * + * \brief Removes a property from a property list + * + * \plist_id + * \param[in] name Name of property to remove + * + * \return \herr_t + * + * \details H5Premove() removes a property from a property list. Both + * properties which were in existence when the property list was + * created (i.e. properties registered with H5Pregister()) and + * properties added to the list after it was created (i.e. added + * with H5Pinsert1() may be removed from a property list. + * Properties do not need to be removed from a property list + * before the list itself is closed; they will be released + * automatically when H5Pclose() is called. + * + * If a \p close callback exists for the removed property, it + * will be called before the property is released. + * + * \since 1.4.0 + * + */ H5_DLL herr_t H5Premove(hid_t plist_id, const char *name); +/** + * \ingroup GPLOA + * + * \brief Sets a property list value + * + * \plist_id + * \param[in] name Name of property to modify + * \param[in] value Pointer to value to set the property to + * + * \return \herr_t + * + * \details H5Pset() sets a new value for a property in a property list. + * If there is a \p set callback routine registered for this + * property, the \p value will be passed to that routine and any + * changes to the \p value will be used when setting the property + * value. The information pointed to by the \p value pointer + * (possibly modified by the \p set callback) is copied into the + * property list value and may be changed by the application + * making the H5Pset() call without affecting the property value. + * + * The property name must exist or this routine will fail. + * + * If the \p set callback routine returns an error, the property + * value will not be modified. + * + * This routine may not be called for zero-sized properties and + * will return an error in that case. + * + * \since 1.4.0 + * + */ +H5_DLL herr_t H5Pset(hid_t plist_id, const char *name, const void *value); +/** + * \ingroup GPLOA + * + * \brief Removes a property from a property list class + * + * \plistcls_id{pclass_id} + * \param[in] name Name of property to remove + * + * \return \herr_t + * + * \details H5Punregister() removes a property from a property list class. + * Future property lists created of that class will not contain + * this property; existing property lists containing this property + * are not affected. + * + * \since 1.4.0 + * + */ H5_DLL herr_t H5Punregister(hid_t pclass_id, const char *name); -H5_DLL herr_t H5Pclose_class(hid_t plist_id); -H5_DLL herr_t H5Pclose(hid_t plist_id); -H5_DLL hid_t H5Pcopy(hid_t plist_id); /* Object creation property list (OCPL) routines */ -H5_DLL herr_t H5Pset_attr_phase_change(hid_t plist_id, unsigned max_compact, unsigned min_dense); -H5_DLL herr_t H5Pget_attr_phase_change(hid_t plist_id, unsigned *max_compact, unsigned *min_dense); -H5_DLL herr_t H5Pset_attr_creation_order(hid_t plist_id, unsigned crt_order_flags); + +/** + * \ingroup DCPL + * + * \brief Verifies that all required filters are available + * + * \plist_id + * + * \return \htri_t + * + * \details H5Pall_filters_avail() verifies that all of the filters set in + * the dataset or group creation property list \p plist_id are + * currently available. + * + * \version 1.8.5 Function extended to work with group creation property + * lists. + * \since 1.6.0 + * + */ +H5_DLL htri_t H5Pall_filters_avail(hid_t plist_id); +/** + * \ingroup OCPL + * + * \brief Retrieves tracking and indexing settings for attribute creation + * order + * + * \plist_id + * \param[out] crt_order_flags Flags specifying whether to track and + * index attribute creation order + * + * \return \herr_t + * + * \details H5Pget_attr_creation_order() retrieves the settings for + * tracking and indexing attribute creation order on an object. + * + * \p plist_id is an object creation property list (\p ocpl), + * as it can be a dataset or group creation property list + * identifier. The term \p ocpl is used when different types + * of objects may be involved. + * + * \p crt_order_flags returns flags with the following meanings: + * + * <table> + * <tr> + * <td>#H5P_CRT_ORDER_TRACKED</td> + * <td>Attribute creation order is tracked but not necessarily + * indexed.</td> + * </tr> + * <tr> + * <td>#H5P_CRT_ORDER_INDEXED </td> + * <td>Attribute creation order is indexed (requires + * #H5P_CRT_ORDER_TRACKED).</td> + * </tr> + * </table> + * + * If \p crt_order_flags is returned with a value of 0 (zero), + * attribute creation order is neither tracked nor indexed. + * + * \since 1.8.0 + * + */ H5_DLL herr_t H5Pget_attr_creation_order(hid_t plist_id, unsigned *crt_order_flags); -H5_DLL herr_t H5Pset_obj_track_times(hid_t plist_id, hbool_t track_times); +/** + * \ingroup OCPL + * + * \brief Retrieves attribute storage phase change thresholds + * + * \plist_id + * \param[out] max_compact Maximum number of attributes to be stored in + * compact storage (Default: 8) + * \param[out] min_dense Minimum number of attributes to be stored in + * dense storage (Default: 6) + * + * \return \herr_t + * + * \details H5Pget_attr_phase_change() retrieves threshold values for + * attribute storage on an object. These thresholds determine the + * point at which attribute storage changes from compact storage + * (i.e., storage in the object header) to dense storage (i.e., + * storage in a heap and indexed with a B-tree). + * + * In the general case, attributes are initially kept in compact + * storage. When the number of attributes exceeds \p max_compact, + * attribute storage switches to dense storage. If the number of + * attributes subsequently falls below \p min_dense, the + * attributes are returned to compact storage. + * + * If \p max_compact is set to 0 (zero), dense storage always used. + * + * \p plist_id is an object creation property list (\p ocpl), as it + * can be a dataset or group creation property list identifier. + * The term \p ocpl is used when different types of objects may be + * involved. + * + * \since 1.8.0 + * + */ +H5_DLL herr_t H5Pget_attr_phase_change(hid_t plist_id, unsigned *max_compact, unsigned *min_dense); +/** + * \ingroup OCPL + * + * \brief Returns information about a filter in a pipeline + * + * \todo Signature for H5Pget_filter2 is different in H5Pocpl.c than in + * H5Ppublic.h + * + * \ocpl_id{plist_id} + * \param[in] idx Sequence number within the filter pipeline of the filter + * for which information is sought + * \param[out] flags Bit vector specifying certain general properties of the + * filter + * \param[in,out] cd_nelmts Number of elements in \p cd_values + * \param[out] cd_values Auxiliary data for the filter + * \param[in] namelen Anticipated number of characters in \p name + * \param[out] name Name of the filter + * \param[out] filter_config Bit field, as described in H5Zget_filter_info() + * + * \return Returns a negative value on failure, and the filter identifier + * if successful (see #H5Z_filter_t): + * - #H5Z_FILTER_DEFLATE Data compression filter, + * employing the gzip algorithm + * - #H5Z_FILTER_SHUFFLE Data shuffling filter + * - #H5Z_FILTER_FLETCHER32 Error detection filter, employing the + * Fletcher32 checksum algorithm + * - #H5Z_FILTER_SZIP Data compression filter, employing the + * SZIP algorithm + * - #H5Z_FILTER_NBIT Data compression filter, employing the + * N-bit algorithm + * - #H5Z_FILTER_SCALEOFFSET Data compression filter, employing the + * scale-offset algorithm + * + * \details H5Pget_filter2() returns information about a filter specified by + * its filter number, in a filter pipeline specified by the property + * list with which it is associated. + * + * \p plist_id must be a dataset or group creation property list. + * + * \p idx is a value between zero and N-1, as described in + * H5Pget_nfilters(). The function will return a negative value if + * the filter number is out of range. + * + * The structure of the \p flags argument is discussed in + * H5Pset_filter(). + * + * On input, \p cd_nelmts indicates the number of entries in the + * \p cd_values array, as allocated by the caller; on return, + * \p cd_nelmts contains the number of values defined by the filter. + * + * If \p name is a pointer to an array of at least \p namelen bytes, + * the filter name will be copied into that array. The name will be + * null terminated if \p namelen is large enough. The filter name + * returned will be the name appearing in the file, the name + * registered for the filter, or an empty string. + * + * \p filter_config is the bit field described in + * H5Zget_filter_info(). + * + * \version 1.8.5 Function extended to work with group creation property + * lists. + * \since 1.8.0 + * + */ +H5_DLL H5Z_filter_t H5Pget_filter2(hid_t plist_id, unsigned idx, unsigned int *flags /*out*/, + size_t *cd_nelmts /*out*/, unsigned cd_values[] /*out*/, size_t namelen, + char name[], unsigned *filter_config /*out*/); +/** + * \ingroup OCPL + * + * \brief Returns information about the specified filter + * + * \ocpl_id{plist_id} + * \param[in] filter_id Filter identifier + * \param[out] flags Bit vector specifying certain general + * properties of the filter + * \param[in,out] cd_nelmts Number of elements in \p cd_values + * \param[out] cd_values[] Auxiliary data for the filter + * \param[in] namelen Length of filter name and number of + * elements in \p name + * \param[out] name[] Name of filter + * \param[out] filter_config Bit field, as described in + * H5Zget_filter_info() + * + * \return \herr_t + * + * \details H5Pget_filter_by_id2() returns information about the filter + * specified in \p filter_id, a filter identifier. + * + * \p plist_id must be a dataset or group creation property list + * and \p filter_id must be in the associated filter pipeline. + * + * The \p filter_id and \p flags parameters are used in the same + * manner as described in the discussion of H5Pset_filter(). + * + * Aside from the fact that they are used for output, the + * parameters \p cd_nelmts and \p cd_values[] are used in the same + * manner as described in the discussion of H5Pset_filter(). On + * input, the \p cd_nelmts parameter indicates the number of + * entries in the \p cd_values[] array allocated by the calling + * program; on exit it contains the number of values defined by + * the filter. + * + * On input, the \p namelen parameter indicates the number of + * characters allocated for the filter name by the calling program + * in the array \p name[]. On exit \p name[] contains the name of the + * filter with one character of the name in each element of the + * array. + * + * \p filter_config is the bit field described in + * H5Zget_filter_info(). + * + * If the filter specified in \p filter_id is not set for the + * property list, an error will be returned and + * H5Pget_filter_by_id2() will fail. + * + * \version 1.8.5 Function extended to work with group creation property + * lists. + * + * \since 1.8.0 + * + */ +H5_DLL herr_t H5Pget_filter_by_id2(hid_t plist_id, H5Z_filter_t filter_id, unsigned int *flags /*out*/, + size_t *cd_nelmts /*out*/, unsigned cd_values[] /*out*/, size_t namelen, + char name[] /*out*/, unsigned *filter_config /*out*/); +/** + * \ingroup OCPL + * + * \brief Returns the number of filters in the pipeline + * + * \ocpl_id{plist_id} + * + * \return Returns the number of filters in the pipeline if successful; + * otherwise returns a negative value. + * + * \details H5Pget_nfilters() returns the number of filters defined in the + * filter pipeline associated with the property list \p plist_id. + * + * In each pipeline, the filters are numbered from 0 through \Code{N-1}, + * where \c N is the value returned by this function. During output to + * the file, the filters are applied in increasing order; during + * input from the file, they are applied in decreasing order. + * + * H5Pget_nfilters() returns the number of filters in the pipeline, + * including zero (0) if there are none. + * + * \since 1.0.0 + * + */ +H5_DLL int H5Pget_nfilters(hid_t plist_id); +/** + * \ingroup OCPL + * + * \brief Determines whether times associated with an object + * are being recorded + * + * \plist_id + * \param[out] track_times Boolean value, 1 (TRUE) or 0 (FALSE), + * specifying whether object times are being recorded + * + * \return \herr_t + * + * \details H5Pget_obj_track_times() queries the object creation property + * list, \p plist_id, to determine whether object times are being + * recorded. + * + * If \p track_times is returned as 1, times are being recorded; + * if \p track_times is returned as 0, times are not being + * recorded. + * + * Time data can be retrieved with H5Oget_info(), which will return + * it in the #H5O_info_t struct. + * + * If times are not tracked, they will be reported as follows + * when queried: 12:00 AM UDT, Jan. 1, 1970 + * + * See H5Pset_obj_track_times() for further discussion. + * + * \since 1.8.0 + * + */ H5_DLL herr_t H5Pget_obj_track_times(hid_t plist_id, hbool_t *track_times); +/** + * \ingroup OCPL + * + * \brief Modifies a filter in the filter pipeline + * + * \ocpl_id{plist_id} + * \param[in] filter Filter to be modified + * \param[in] flags Bit vector specifying certain general properties + * of the filter + * \param[in] cd_nelmts Number of elements in \p cd_values + * \param[in] cd_values[] Auxiliary data for the filter + * + * \return \herr_t + * + * \details H5Pmodify_filter() modifies the specified \p filter in the + * filter pipeline. \p plist_id must be a dataset or group + * creation property list. + * + * The \p filter, \p flags \p cd_nelmts[], and \p cd_values + * parameters are used in the same manner and accept the same + * values as described in the discussion of H5Pset_filter(). + * + * \version 1.8.5 Function extended to work with group creation property + * lists. + * \since 1.6.0 + * + */ H5_DLL herr_t H5Pmodify_filter(hid_t plist_id, H5Z_filter_t filter, unsigned int flags, size_t cd_nelmts, const unsigned int cd_values[/*cd_nelmts*/]); +/** + * \ingroup OCPL + * + * \brief Delete one or more filters in the filter pipeline + * + * \ocpl_id{plist_id} + * \param[in] filter Filter to be deleted + * + * \return \herr_t + * + * \details H5Premove_filter() removes the specified \p filter from the + * filter pipeline in the dataset or group creation property + * list \p plist_id. + * + * The \p filter parameter specifies the filter to be removed. + * Valid values for use in \p filter are as follows: + * + * <table> + * <tr> + * <td>#H5Z_FILTER_ALL</td> + * <td>Removes all filters from the filter pipeline</td> + * </tr> + * <tr> + * <td>#H5Z_FILTER_DEFLATE</td> + * <td>Data compression filter, employing the gzip + * algorithm</td> + * </tr> + * <tr> + * <td>#H5Z_FILTER_SHUFFLE</td> + * <td>Data shuffling filter</td> + * </tr> + * <tr> + * <td>#H5Z_FILTER_FLETCHER32</td> + * <td>Error detection filter, employing the Fletcher32 + * checksum algorithm</td> + * </tr> + * <tr> + * <td>#H5Z_FILTER_SZIP</td> + * <td>Data compression filter, employing the SZIP + * algorithm</td> + * </tr> + * <tr> + * <td>#H5Z_FILTER_NBIT</td> + * <td>Data compression filter, employing the N-Bit + * algorithm</td> + * </tr> + * <tr> + * <td>#H5Z_FILTER_SCALEOFFSET</td> + * <td>Data compression filter, employing the scale-offset + * algorithm</td> + * </tr> + * </table> + * + * Additionally, user-defined filters can be removed with this + * routine by passing the filter identifier with which they were + * registered with the HDF5 library. + * + * Attempting to remove a filter that is not in the filter + * pipeline is an error. + * + * \version 1.8.5 Function extended to work with group creation property + * lists. + * \since 1.6.3 + * + */ +H5_DLL herr_t H5Premove_filter(hid_t plist_id, H5Z_filter_t filter); +/** + * \ingroup OCPL + * + * \brief Sets tracking and indexing of attribute creation order + * + * \plist_id + * \param[in] crt_order_flags Flags specifying whether to track and index + * attribute creation order. \em Default: No + * flag set; attribute creation order is neither + * tracked not indexed + * + * \return \herr_t + * + * \details H5Pset_attr_creation_order() sets flags for tracking and + * indexing attribute creation order on an object. + * + * \p plist_id is a dataset or group creation property list + * identifier. + * + * \p crt_order_flags contains flags with the following meanings: + * + * <table> + * <tr> + * <td>#H5P_CRT_ORDER_TRACKED</td> + * <td>Attribute creation order is tracked but not necessarily + * indexed.</td> + * </tr> + * <tr> + * <td>#H5P_CRT_ORDER_INDEXED </td> + * <td>Attribute creation order is indexed (requires + * #H5P_CRT_ORDER_TRACKED).</td> + * </tr> + * </table> + * + * Default behavior is that attribute creation order is neither + * tracked nor indexed. + * + * H5Pset_attr_creation_order() can be used to set attribute + * creation order tracking, or to set attribute creation order + * tracking and indexing. + * + * \note If a creation order index is to be built, it must be specified in + * the object creation property list. HDF5 currently provides no + * mechanism to turn on attribute creation order tracking at object + * creation time and to build the index later. + * + * \since 1.8.0 + * + */ +H5_DLL herr_t H5Pset_attr_creation_order(hid_t plist_id, unsigned crt_order_flags); +/** + * \ingroup OCPL + * + * \brief Sets attribute storage phase change thresholds + * + * \plist_id + * \param[in] max_compact Maximum number of attributes to be stored in + * compact storage (\em Default: 8); must be greater + * than or equal to \p min_dense + * + * \param[in] min_dense Minimum number of attributes to be stored in + * dense storage (\em Default: 6) + * + * \return \herr_t + * + * \details H5Pset_attr_phase_change() sets threshold values for attribute + * storage on an object. These thresholds determine the point at + * which attribute storage changes from compact storage (i.e., + * storage in the object header) to dense storage (i.e., storage + * in a heap and indexed with a B-tree). + * + * In the general case, attributes are initially kept in compact + * storage. When the number of attributes exceeds \p max_compact, + * attribute storage switches to dense storage. If the number of + * attributes subsequently falls below \p min_dense, the attributes + * are returned to compact storage. + * + * If \p max_compact is set to 0 (zero), dense storage is always + * used. \p min_dense must be set to 0 (zero) when \p max_compact + * is 0 (zero). + * + * \p plist_id is a dataset or group creation property list + * identifier. + * + * \since 1.8.0 + * + */ +H5_DLL herr_t H5Pset_attr_phase_change(hid_t plist_id, unsigned max_compact, unsigned min_dense); +/** + * \ingroup OCPL + * + * \brief Sets deflate (GNU gzip) compression method and compression level + * + * \ocpl_id{plist_id} + * \param[in] level Compression level + * + * \return \herr_t + * + * \details H5Pset_deflate() sets the deflate compression method and the + * compression level, \p level, for a dataset or group creation + * property list, \p plist_id. + * + * The filter identifier set in the property list is + * #H5Z_FILTER_DEFLATE. + * + * The compression level, \p level, is a value from zero to nine, + * inclusive. A compression level of 0 (zero) indicates no + * compression; compression improves but speed slows progressively + * from levels 1 through 9: + * + * <table> + * <tr> + * <th>Compression Level</th> + * <th>Gzip Action</th> + * </tr> + * <tr> + * <td>0</td> + * <td>No compression</td> + * </tr> + * <tr> + * <td>1</td> + * <td>Best compression speed; least compression</td> + * </tr> + * <tr> + * <td>2 through 8</td> + * <td>Compression improves; speed degrades</td> + * </tr> + * <tr> + * <td>9</td> + * <td>Best compression ratio; slowest speed</td> + * </tr> + * </table> + * + * Note that setting the compression level to 0 (zero) does not turn + * off use of the gzip filter; it simply sets the filter to perform + * no compression as it processes the data. + * + * HDF5 relies on GNU gzip for this compression. + * + * \version 1.8.5 Function extended to work with group creation property lists. + * \since 1.0.0 + * + */ +H5_DLL herr_t H5Pset_deflate(hid_t plist_id, unsigned level); +/** + * \ingroup OCPL + * + * \brief Adds a filter to the filter pipeline + * + * \ocpl_id{plist_id} + * \param[in] filter Filter identifier for the filter to be added to the + * pipeline + * \param[in] flags Bit vector specifying certain general properties of + * the filter + * \param[in] cd_nelmts Number of elements in \p c_values + * \param[in] c_values Auxiliary data for the filter + * + * \return \herr_t + * + * \details H5Pset_filter() adds the specified \p filter identifier and + * corresponding properties to the end of an output filter + * pipeline. + * + * \p plist_id must be either a dataset creation property list or + * group creation property list identifier. If \p plist_id is a + * dataset creation property list identifier, the filter is added + * to the raw data filter pipeline. + * + * If \p plist_id is a group creation property list identifier, + * the filter is added to the link filter pipeline, which filters + * the fractal heap used to store most of the link metadata in + * certain types of groups. The only predefined filters that can + * be set in a group creation property list are the gzip filter + * (#H5Z_FILTER_DEFLATE) and the Fletcher32 error detection filter + * (#H5Z_FILTER_FLETCHER32). + * + * The array \p c_values contains \p cd_nelmts integers which are + * auxiliary data for the filter. The integer values will be + * stored in the dataset object header as part of the filter + * information. + * + * The \p flags argument is a bit vector with the following + * fields specifying certain general properties of the filter: + * + * <table> + * <tr> + * <td>#H5Z_FLAG_OPTIONAL</td> + * <td>If this bit is set then the filter is optional. If the + * filter fails (see below) during an H5Dwrite() operation + * then the filter is just excluded from the pipeline for + * the chunk for which it failed; the filter will not + * participate in the pipeline during an H5Dread() of the + * chunk. This is commonly used for compression filters: + * if the filter result would be larger than the input, + * then the compression filter returns failure and the + * uncompressed data is stored in the file.<br /><br /> + * This flag should not be set for the Fletcher32 checksum + * filter as it will bypass the checksum filter without + * reporting checksum errors to an application.</td> + * </tr> + * <tr> + * <td>#H5Z_FLAG_MANDATORY</td> + * <td>If the filter is required, that is, set to mandatory, + * and the filter fails, the library’s behavior depends + * on whether the chunk cache is in use: + * \li If the chunk cache is enabled, data chunks will + * be flushed to the file during H5Dclose() and the + * library will return the failure in H5Dclose(). + * \li When the chunk cache is disabled or not big enough, + * or the chunk is being evicted from the cache, the + * failure will happen during H5Dwrite(). + * + * In each case, the library will still write to the file + * all data chunks that were processed by the filter + * before the failure occurred.<br /><br /> + * For example, assume that an application creates a + * dataset of four chunks, the chunk cache is enabled and + * is big enough to hold all four chunks, and the filter + * fails when it tries to write the fourth chunk. The + * actual flush of the chunks will happen during + * H5Dclose(), not H5Dwrite(). By the time H5Dclose() + * fails, the first three chunks will have been written + * to the file. Even though H5Dclose() fails, all the + * resources will be released and the file can be closed + * properly. <br /><br /> + * If, however, the filter fails on the second chunk, only + * the first chunk will be written to the file as nothing + * further can be written once the filter fails.</td> + * </tr> + * </table> + * The \p filter parameter specifies the filter to be set. Valid + * pre-defined filter identifiers are as follows: + * + * <table> + * <tr> + * <td>#H5Z_FILTER_DEFLATE</td> + * <td>Data compression filter, employing the gzip + * algorithm</td> + * </tr> + * <tr> + * <td>#H5Z_FILTER_SHUFFLE</td> + * <td>Data shuffling filter</td> + * </tr> + * <tr> + * <td>#H5Z_FILTER_FLETCHER32</td> + * <td>Error detection filter, employing the Fletcher32 + * checksum algorithm</td> + * </tr> + * <tr> + * <td>#H5Z_FILTER_SZIP</td> + * <td>Data compression filter, employing the SZIP + * algorithm</td> + * </tr> + * <tr> + * <td>#H5Z_FILTER_NBIT</td> + * <td>Data compression filter, employing the N-Bit + * algorithm</td> + * </tr> + * <tr> + * <td>#H5Z_FILTER_SCALEOFFSET</td> + * <td>Data compression filter, employing the scale-offset + * algorithm</td> + * </tr> + * </table> + * Also see H5Pset_edc_check() and H5Pset_filter_callback(). + * + * \note When a non-empty filter pipeline is used with a group creation + * property list, the group will be created with the new group file + * format. The filters will come into play only when dense storage + * is used (see H5Pset_link_phase_change()) and will be applied to + * the group’s fractal heap. The fractal heap will contain most of + * the the group’s link metadata, including link names. + * + * \note When working with group creation property lists, if you are + * adding a filter that is not in HDF5’s set of predefined filters, + * i.e., a user-defined or third-party filter, you must first + * determine that the filter will work for a group. See the + * discussion of the set local and can apply callback functions + * in H5Zregister(). + * + * \note If multiple filters are set for a property list, they will be + * applied to each chunk of raw data for datasets or each block + * of the fractal heap for groups in the order in which they were + * set. + * + * \note Filters can be applied only to chunked datasets; they cannot be + * used with other dataset storage methods, such as contiguous, + * compact, or external datasets. + * + * \note Dataset elements of variable-length and dataset region + * reference datatypes are stored in separate structures in the + * file called heaps. Filters cannot currently be applied to + * these heaps. + * + * \note <b>Filter Behavior in HDF5:</b><br /> + * Filters can be inserted into the HDF5 pipeline to perform + * functions such as compression and conversion. As such, they are + * a very flexible aspect of HDF5; for example, a user-defined + * filter could provide encryption for an HDF5 dataset. + * + * \note A filter can be declared as either required or optional. + * Required is the default status; optional status must be + * explicitly declared. + * + * \note A required filter that fails or is not defined causes an + * entire output operation to fail; if it was applied when the + * data was written, such a filter will cause an input operation + * to fail. + * + * \note The following table summarizes required filter behavior. + * <table> + * <tr> + * <th></th> + * <th>Required FILTER_X not available</th> + * <th>FILTER_X available</th> + * </tr> + * <tr> + * <td>H5Pset_<FILTER_X></td> + * <td>Will fail.</td> + * <td>Will succeed.</td> + * </tr> + * <tr> + * <td>H5Dwrite with FILTER_X set</td> + * <td>Will fail.</td> + * <td>Will succeed; FILTER_X will be applied to + * the data.</td> + * </tr> + * <tr> + * <td>H5Dread with FILTER_X set</td> + * <td>Will fail.</td> + * <td>Will succeed.</td> + * </tr> + * </table> + * \note An optional filter can be set for an HDF5 dataset even when + * the filter is not available. Such a filter can then be + * applied to the dataset when it becomes available on the + * original system or when the file containing the dataset is + * processed on a system on which it is available. + * + * \note A filter can be declared as optional through the use of the + * #H5Z_FLAG_OPTIONAL flag with H5Pset_filter(). + * + * \note Consider a situation where one is creating files that will + * normally be used only on systems where the optional (and + * fictional) filter FILTER_Z is routinely available. One can + * create those files on system A, which lacks FILTER_Z, create + * chunked datasets in the files with FILTER_Z defined in the + * dataset creation property list, and even write data to those + * datasets. The dataset object header will indicate that FILTER_Z + * has been associated with this dataset. But since system A does + * not have FILTER_Z, dataset chunks will be written without it + * being applied. + * + * \note HDF5 has a mechanism for determining whether chunks are + * actually written with the filters specified in the object + * header, so while the filter remains unavailable, system A will + * be able to read the data. Once the file is moved to system B, + * where FILTER_Z is available, HDF5 will apply FILTER_Z to any + * data rewritten or new data written in these datasets. Dataset + * chunks that have been written on system B will then be + * unreadable on system A; chunks that have not been re-written + * since being written on system A will remain readable on system + * A. All chunks will be readable on system B. + * + * \note The following table summarizes optional filter behavior. + * <table> + * <tr> + * <th></th> + * <th>FILTER_Z not available</th> + * <th>FILTER_Z available<br /> with encode and decode</th> + * <th>FILTER_Z available decode only</th> + * </tr> + * <tr> + * <td>H5Pset_<FILTER_Z></td> + * <td>Will succeed.</td> + * <td>Will succeed.</td> + * <td>Will succeed.</td> + * </tr> + * <tr> + * <td>H5Dread with FILTER_Z set</td> + * <td>Will succeed if FILTER_Z has not actually<br /> + * been applied to data.</td> + * <td>Will succeed.</td> + * <td>Will succeed.</td> + * </tr> + * <tr> + * <td>H5Dwrite with FILTER_Z set</td> + * <td>Will succeed;<br /> + * FILTER_Z will not be applied to the data.</td> + * <td>Will succeed;<br /> + * FILTER_Z will be applied to the data.</td> + * <td>Will succeed;<br /> + * FILTER_Z will not be applied to the data.</td> + * </tr> + * </table> + * \note The above principles apply generally in the use of HDF5 + * optional filters insofar as HDF5 does as much as possible to + * complete an operation when an optional filter is unavailable. + * (The SZIP filter is an exception to this rule; see H5Pset_szip() + * for details.) + * + * \see \ref_filter_pipe, \ref_group_impls + * + * \version 1.8.5 Function applied to group creation property lists. + * \since 1.6.0 + * + */ H5_DLL herr_t H5Pset_filter(hid_t plist_id, H5Z_filter_t filter, unsigned int flags, size_t cd_nelmts, const unsigned int c_values[]); -H5_DLL int H5Pget_nfilters(hid_t plist_id); -H5_DLL H5Z_filter_t H5Pget_filter2(hid_t plist_id, unsigned filter, unsigned int *flags /*out*/, - size_t *cd_nelmts /*out*/, unsigned cd_values[] /*out*/, size_t namelen, - char name[], unsigned *filter_config /*out*/); -H5_DLL herr_t H5Pget_filter_by_id2(hid_t plist_id, H5Z_filter_t id, unsigned int *flags /*out*/, - size_t *cd_nelmts /*out*/, unsigned cd_values[] /*out*/, size_t namelen, - char name[] /*out*/, unsigned *filter_config /*out*/); -H5_DLL htri_t H5Pall_filters_avail(hid_t plist_id); -H5_DLL herr_t H5Premove_filter(hid_t plist_id, H5Z_filter_t filter); -H5_DLL herr_t H5Pset_deflate(hid_t plist_id, unsigned aggression); -H5_DLL herr_t H5Pset_fletcher32(hid_t plist_id); +/** + * \ingroup OCPL + * + * \brief Sets up use of the Fletcher32 checksum filter + * + * \ocpl_id{plist_id} + * + * \return \herr_t + * + * \details H5Pset_fletcher32() sets the Fletcher32 checksum filter in the + * dataset or group creation property list \p plist_id. + * + * \attention The Fletcher32 EDC checksum filter was added in HDF5 Release + * 1.6.0. In the original implementation, however, the checksum + * value was calculated incorrectly on little-endian systems. + * The error was fixed in HDF5 Release 1.6.3. + * + * \attention As a result of this fix, an HDF5 library of Release 1.6.0 + * through Release 1.6.2 cannot read a dataset created or written + * with Release 1.6.3 or later if the dataset was created with + * the checksum filter and the filter is enabled in the reading + * library. (Libraries of Release 1.6.3 and later understand the + * earlier error and compensate appropriately.) + * + * \attention \b Work-around: An HDF5 library of Release 1.6.2 or earlier + * will be able to read a dataset created or written with the + * checksum filter by an HDF5 library of Release 1.6.3 or later + * if the checksum filter is disabled for the read operation. + * This can be accomplished via a call to H5Pset_edc_check() + * with the value #H5Z_DISABLE_EDC in the second parameter. + * This has the obvious drawback that the application will be + * unable to verify the checksum, but the data does remain + * accessible. + * + * \version 1.8.5 Function extended to work with group creation property + * lists. + * \version 1.6.3 Error in checksum calculation on little-endian systems + * corrected in this release. + * \since 1.6.0 + * + */ +H5_DLL herr_t H5Pset_fletcher32(hid_t plist_id); +/** + * \ingroup OCPL + * + * \brief Sets the recording of times associated with an object + * + * \param[in] plist_id Object creation property list identifier + * \param[in] track_times Boolean value, 1 or 0, specifying whether object + * times are to be tracked + * + * \return \herr_t + * + * \details H5Pset_obj_track_times() sets a property in the object creation + * property list, \p plist_id, that governs the recording of times + * associated with an object. + * + * If \p track_times is set to 1, time data will be recorded. If + * \p track_times is set to 0, time data will not be recorded. + * + * Time data can be retrieved with H5Oget_info(), which will + * return it in the #H5O_info_t struct. + * + * If times are not tracked, they will be reported as follows when queried: + * \Code{ 12:00 AM UDT, Jan. 1, 1970} + * + * That date and time are commonly used to represent the beginning of the UNIX epoch. + * + * \since 1.8.0 + * + */ +H5_DLL herr_t H5Pset_obj_track_times(hid_t plist_id, hbool_t track_times); /* File creation property list (FCPL) routines */ -H5_DLL herr_t H5Pset_userblock(hid_t plist_id, hsize_t size); -H5_DLL herr_t H5Pget_userblock(hid_t plist_id, hsize_t *size); -H5_DLL herr_t H5Pset_sizes(hid_t plist_id, size_t sizeof_addr, size_t sizeof_size); -H5_DLL herr_t H5Pget_sizes(hid_t plist_id, size_t *sizeof_addr /*out*/, size_t *sizeof_size /*out*/); -H5_DLL herr_t H5Pset_sym_k(hid_t plist_id, unsigned ik, unsigned lk); -H5_DLL herr_t H5Pget_sym_k(hid_t plist_id, unsigned *ik /*out*/, unsigned *lk /*out*/); -H5_DLL herr_t H5Pset_istore_k(hid_t plist_id, unsigned ik); +/** + * \ingroup FCPL + * + * \brief Retrieves the file space page size for a file creation property + * list + * + * \fcpl_id{plist_id} + * \param[out] fsp_size File space page size + * + * \return \herr_t + * + * \details H5Pget_file_space_page_size() retrieves the file space page + * size for paged aggregation in the parameter \p fsp_size. + * + * The library default is 4KB (4096) if \p fsp_size is not + * previously set via a call to H5Pset_file_space_page_size(). + * + * \since 1.10.1 + * + */ +H5_DLL herr_t H5Pget_file_space_page_size(hid_t plist_id, hsize_t *fsp_size); +/** + * \ingroup FCPL + * + * \brief Retrieves the file space handling strategy, persisting free-space + * condition and threshold value for a file creation property list + * + * \fcpl_id{plist_id} + * \param[out] strategy The file space handling strategy + * \param[out] persist The boolean value indicating whether free space is + * persistent or not + * \param[out] threshold The free-space section size threshold value + * + * \return \herr_t + * + * \details H5Pget_file_space_strategy() retrieves the file space handling + * strategy, the persisting free-space condition and the threshold + * value in the parameters \p strategy, \p persist and + * \p threshold respectively. + * + * The library default values returned when + * H5Pset_file_space_strategy() has not been called are: + * + * \li \p strategy - #H5F_FSPACE_STRATEGY_FSM_AGGR + * \li \p persist - 0 + * \li \p threshold - 1 + * + * \since 1.10.1 + * + */ +H5_DLL herr_t H5Pget_file_space_strategy(hid_t plist_id, H5F_fspace_strategy_t *strategy, hbool_t *persist, + hsize_t *threshold); +/** + * \ingroup FCPL + * + * \brief Queries the 1/2 rank of an indexed storage B-tree + * + * \fcpl_id{plist_id} + * \param[out] ik Pointer to location to return the chunked storage B-tree + * 1/2 rank (<em>Default value of B-tree 1/2 rank: 32</em>) + * + * \return \herr_t + * + * \details H5Pget_istore_k() queries the 1/2 rank of an indexed storage + * B-tree. + * + * The argument \p ik may be the null pointer (NULL). + * This function is valid only for file creation property lists. + * + * \see H5Pset_istore_k() + * + * \version 1.6.4 \p ik parameter type changed to \em unsigned. + * \since 1.0.0 + * + */ H5_DLL herr_t H5Pget_istore_k(hid_t plist_id, unsigned *ik /*out*/); -H5_DLL herr_t H5Pset_shared_mesg_nindexes(hid_t plist_id, unsigned nindexes); -H5_DLL herr_t H5Pget_shared_mesg_nindexes(hid_t plist_id, unsigned *nindexes); -H5_DLL herr_t H5Pset_shared_mesg_index(hid_t plist_id, unsigned index_num, unsigned mesg_type_flags, - unsigned min_mesg_size); +/** + * \ingroup FCPL + * + * \brief Retrieves the configuration settings for a shared message index + * + * \fcpl_id{plist_id} + * \param[in] index_num Index being configured + * \param[out] mesg_type_flags Types of messages that may be stored in + * this index + * \param[out] min_mesg_size Minimum message size + * + * \return \herr_t + * + * \details H5Pget_shared_mesg_index() retrieves the message type and + * minimum message size settings from the file creation property + * list \p plist_id for the shared object header message index + * specified by \p index_num. + * + * \p index_num specifies the index. \p index_num is zero-indexed, + * so in a file with three indexes, they will be numbered 0, 1, + * and 2. + * + * \p mesg_type_flags and \p min_mesg_size will contain, + * respectively, the types of messages and the minimum size, in + * bytes, of messages that can be stored in this index. + * + * Valid message types are described in H5Pset_shared_mesg_index(). + * + * \since 1.8.0 + * + */ H5_DLL herr_t H5Pget_shared_mesg_index(hid_t plist_id, unsigned index_num, unsigned *mesg_type_flags, unsigned *min_mesg_size); -H5_DLL herr_t H5Pset_shared_mesg_phase_change(hid_t plist_id, unsigned max_list, unsigned min_btree); +/** + * \ingroup FCPL + * + * \brief Retrieves the number of shared object header message indexes in file + * creation property list + * + * \fcpl_id{plist_id} + * \param[out] nindexes Number of shared object header message indexes + * available in files created with this property list + * + * \return \herr_t + * + * \details H5Pget_shared_mesg_nindexes() retrieves the number of shared + * object header message indexes in the specified file creation + * property list \p plist_id. + * + * If the value of \p nindexes is 0 (zero), shared object header + * messages are disabled in files created with this property list. + * + * \since 1.8.0 + * + */ +H5_DLL herr_t H5Pget_shared_mesg_nindexes(hid_t plist_id, unsigned *nindexes); +/** + * \ingroup FCPL + * + * \brief Retrieves shared object header message phase change information + * + * \fcpl_id{plist_id} + * \param[out] max_list Threshold above which storage of a shared object + * header message index shifts from list to B-tree + * \param[out] min_btree Threshold below which storage of a shared object + * header message index reverts to list format + * + * \return \herr_t + * + * \details H5Pget_shared_mesg_phase_change() retrieves the threshold values + * for storage of shared object header message indexes in a file. + * These phase change thresholds determine the point at which the + * index storage mechanism changes from a more compact list format + * to a more performance-oriented B-tree format, and vice-versa. + * + * By default, a shared object header message index is initially + * stored as a compact list. When the number of messages in an + * index exceeds the specified \p max_list threshold, storage + * switches to a B-tree format for improved performance. If the + * number of messages subsequently falls below the \p min_btree + * threshold, the index will revert to the list format. + * + * If \p max_list is set to 0 (zero), shared object header message + * indexes in the file will always be stored as B-trees. + * + * \p plist_id specifies the file creation property list. + * + * \since 1.8.0 + * + */ H5_DLL herr_t H5Pget_shared_mesg_phase_change(hid_t plist_id, unsigned *max_list, unsigned *min_btree); +/** + * \ingroup FCPL + * + * \brief Retrieves the size of the offsets and lengths used in an HDF5 + * file + * + * \fcpl_id{plist_id} + * \param[out] sizeof_addr Pointer to location to return offset size in + * bytes + * \param[out] sizeof_size Pointer to location to return length size in + * bytes + * + * \return \herr_t + * + * \details H5Pget_sizes() retrieves the size of the offsets and lengths + * used in an HDF5 file. This function is only valid for file + * creation property lists. + * + * \since 1.0.0 + * + */ +H5_DLL herr_t H5Pget_sizes(hid_t plist_id, size_t *sizeof_addr /*out*/, size_t *sizeof_size /*out*/); +/** + * \ingroup FCPL + * + * \brief Retrieves the size of the symbol table B-tree 1/2 rank and the + * symbol table leaf node 1/2 size + * + * \fcpl_id{plist_id} + * \param[out] ik Pointer to location to return the symbol table's B-tree + * 1/2 rank (<em>Default value of B-tree 1/2 rank: 16</em>) + * \param[out] lk Pointer to location to return the symbol table's leaf + * node 1/2 size (<em>Default value of leaf node 1/2 + * size: 4</em>) + * + * \return \herr_t + * + * \details H5Pget_sym_k() retrieves the size of the symbol table B-tree + * 1/2 rank and the symbol table leaf node 1/2 size. + * + * This function is valid only for file creation property lists. + * + * If a parameter value is set to NULL, that parameter is not + * retrieved. + * + * \see H5Pset_sym_k() + * + * \version 1.6.4 \p ik parameter type changed to \em unsigned + * \version 1.6.0 The \p ik parameter has changed from type int to + * \em unsigned + * + * \since 1.0.0 + * + */ +H5_DLL herr_t H5Pget_sym_k(hid_t plist_id, unsigned *ik /*out*/, unsigned *lk /*out*/); +/** + * \ingroup FCPL + * + * \brief Retrieves the size of a user block + * + * \fcpl_id{plist_id} + * \param[out] size Pointer to location to return user-block size + * + * \return \herr_t + * + * \details H5Pget_userblock() retrieves the size of a user block in a + * file creation property list. + * + * \since 1.0.0 + * + */ +H5_DLL herr_t H5Pget_userblock(hid_t plist_id, hsize_t *size); +/** + * \ingroup FCPL + * + * \brief Sets the file space page size for a file creation property list + * + * \fcpl_id{plist_id} + * \param[in] fsp_size File space page size + * + * \return \herr_t + * + * \details H5Pset_file_space_page_size() sets the file space page size + * \p fsp_size used in paged aggregation and paged buffering. + * + * \p fsp_size has a minimum size of 512. Setting a value less + * than 512 will return an error. The library default size for + * the file space page size when not set is 4096. + * + * The size set via this routine may not be changed for the life + * of the file. + * + * \since 1.10.1 + * + */ +H5_DLL herr_t H5Pset_file_space_page_size(hid_t plist_id, hsize_t fsp_size); +/** + * \ingroup FCPL + * + * \brief Sets the file space handling strategy and persisting free-space + * values for a file creation property list + * + * \fcpl_id{plist_id} + * \param[in] strategy The file space handling strategy to be used. See: + * #H5F_fspace_strategy_t + * \param[in] persist A boolean value to indicate whether free space + * should be persistent or not + * \param[in] threshold The smallest free-space section size that the free + * space manager will track + * + * \return \herr_t + * + * \details H5Pset_file_space_strategy() sets the file space handling + * \p strategy, specifies persisting free-space or not (\p persist), + * and sets the free-space section size \p threshold in the file + * creation property list \p plist_id. + * + * #H5F_fspace_strategy_t is a struct defined in H5Fpublic.h as + * follows: + * + * \snippet H5Fpublic.h H5F_fspace_strategy_t_snip + * + * This setting cannot be changed for the life of the file. + * + * As the #H5F_FSPACE_STRATEGY_AGGR and #H5F_FSPACE_STRATEGY_NONE + * strategies do not use the free-space managers, the \p persist + * and \p threshold settings will be ignored for those strategies. + * + * \since 1.10.1 + * + */ H5_DLL herr_t H5Pset_file_space_strategy(hid_t plist_id, H5F_fspace_strategy_t strategy, hbool_t persist, hsize_t threshold); -H5_DLL herr_t H5Pget_file_space_strategy(hid_t plist_id, H5F_fspace_strategy_t *strategy, hbool_t *persist, - hsize_t *threshold); -H5_DLL herr_t H5Pset_file_space_page_size(hid_t plist_id, hsize_t fsp_size); -H5_DLL herr_t H5Pget_file_space_page_size(hid_t plist_id, hsize_t *fsp_size); +/** + * \ingroup FCPL + * + * \brief Sets the size of the parameter used to control the B-trees for + * indexing chunked datasets + * + * \fcpl_id{plist_id} + * \param[in] ik 1/2 rank of chunked storage B-tree + * + * \return \herr_t + * + * \details H5Pset_istore_k() sets the size of the parameter used to + * control the B-trees for indexing chunked datasets. This + * function is valid only for file creation property lists. + * + * \p ik is one half the rank of a tree that stores chunked + * raw data. On average, such a tree will be 75% full, or have + * an average rank of 1.5 times the value of \p ik. + * + * The HDF5 library uses (\p ik*2) as the maximum # of entries + * before splitting a B-tree node. Since only 2 bytes are used + * in storing # of entries for a B-tree node in an HDF5 file, + * (\p ik*2) cannot exceed 65536. The default value for + * \p ik is 32. + * + * \version 1.6.4 \p ik parameter type changed to \p unsigned. + * \since 1.0.0 + * + */ +H5_DLL herr_t H5Pset_istore_k(hid_t plist_id, unsigned ik); +/** + * \ingroup FCPL + * + * \brief Configures the specified shared object header message index + * + * \fcpl_id{plist_id} + * \param[in] index_num Index being configured + * \param[in] mesg_type_flags Types of messages that should be stored in + * this index + * \param[in] min_mesg_size Minimum message size + * + * \return \herr_t + * + * \details H5Pset_shared_mesg_index() is used to configure the specified + * shared object header message index, setting the types of + * messages that may be stored in the index and the minimum size + * of each message. + * + * \p plist_id specifies the file creation property list. + * + * \p index_num specifies the index to be configured. + * \p index_num is zero-indexed, so in a file with three indexes, + * they will be numbered 0, 1, and 2. + * + * \p mesg_type_flags and \p min_mesg_size specify, respectively, + * the types and minimum size of messages that can be stored in + * this index. + * + * Valid message types are as follows: + * + * <table> + * <tr> + * <td>#H5O_SHMESG_NONE_FLAG</td> + * <td>No shared messages</td> + * </tr> + * <tr> + * <td>#H5O_SHMESG_SDSPACE_FLAG</td> + * <td>Simple dataspace message</td> + * </tr> + * <tr> + * <td>#H5O_SHMESG_DTYPE_FLAG</td> + * <td>Datatype message</td> + * </tr> + * <tr> + * <td>#H5O_SHMESG_FILL_FLAG</td> + * <td>Fill value message</td> + * </tr> + * <tr> + * <td>#H5O_SHMESG_PLINE_FLAG</td> + * <td>Filter pipeline message</td> + * </tr> + * <tr> + * <td>#H5O_SHMESG_ATTR_FLAG</td> + * <td>Attribute message</td> + * </tr> + * <tr> + * <td>#H5O_SHMESG_ALL_FLAG</td> + * <td>All message types; i.e., equivalent to the following: + * (#H5O_SHMESG_SDSPACE_FLAG | #H5O_SHMESG_DTYPE_FLAG | + * #H5O_SHMESG_FILL_FLAG | #H5O_SHMESG_PLINE_FLAG | + * #H5O_SHMESG_ATTR_FLAG)</td> + * </tr> + * </table> + * + * \since 1.8.0 + * + */ +H5_DLL herr_t H5Pset_shared_mesg_index(hid_t plist_id, unsigned index_num, unsigned mesg_type_flags, + unsigned min_mesg_size); +/** + * \ingroup FCPL + * + * \brief Sets number of shared object header message indexes + * + * \fcpl_id{plist_id} + * \param[in] nindexes Number of shared object header message indexes to be + * available in files created with this property list + * (\p nindexes must be <= #H5O_SHMESG_MAX_NINDEXES (8)) + * + * \return \herr_t + * + * \details H5Pset_shared_mesg_nindexes() sets the number of shared object + * header message indexes in the specified file creation property + * list. + * + * This setting determines the number of shared object header + * message indexes, \p nindexes, that will be available in files + * created with this property list. These indexes can then be + * configured with H5Pset_shared_mesg_index(). + * + * If \p nindexes is set to 0 (zero), shared object header messages + * are disabled in files created with this property list. + * + * There is a limit of #H5O_SHMESG_MAX_NINDEXES (8) that can be set + * with H5Pset_shared_mesg_nindexes(). An error will occur if + * specifying a value of \p nindexes that is greater than this value. + * + * \since 1.8.0 + * + */ +H5_DLL herr_t H5Pset_shared_mesg_nindexes(hid_t plist_id, unsigned nindexes); +/** + * \ingroup FCPL + * + * \brief Sets shared object header message storage phase change thresholds + * + * \fcpl_id{plist_id} + * \param[in] max_list Threshold above which storage of a shared object + * header message index shifts from list to B-tree + * \param[in] min_btree Threshold below which storage of a shared object + * header message index reverts to list format + * + * \return \herr_t + * + * \details H5Pset_shared_mesg_phase_change() sets threshold values for + * storage of shared object header message indexes in a file. + * These phase change thresholds determine the point at which the + * index storage mechanism changes from a more compact list format + * to a more performance-oriented B-tree format, and vice-versa. + * + * By default, a shared object header message index is initially + * stored as a compact list. When the number of messages in an + * index exceeds the threshold value of \p max_list, storage + * switches to a B-tree for improved performance. If the number + * of messages subsequently falls below the \p min_btree threshold, + * the index will revert to the list format. + * + * If \p max_list is set to 0 (zero), shared object header message + * indexes in the file will be created as B-trees and will never + * revert to lists. + * + * \p plist_id specifies the file creation property list. + * + * \since 1.8.0 + * + */ +H5_DLL herr_t H5Pset_shared_mesg_phase_change(hid_t plist_id, unsigned max_list, unsigned min_btree); +/** + * \ingroup FCPL + * + * \brief Sets the byte size of the offsets and lengths used to address + * objects in an HDF5 file + * + * \fcpl_id{plist_id} + * \param[in] sizeof_addr Size of an object offset in bytes + * \param[in] sizeof_size Size of an object length in bytes + * + * \return \herr_t + * + * \details H5Pset_sizes() sets the byte size of the offsets and lengths + * used to address objects in an HDF5 file. This function is only + * valid for file creation property lists. Passing in a value + * of 0 for one of the parameters retains the current value. The + * default value for both values is the same as sizeof(hsize_t) + * in the library (normally 8 bytes). Valid values currently + * are 2, 4, 8 and 16. + * + * \since 1.0.0 + * + */ +H5_DLL herr_t H5Pset_sizes(hid_t plist_id, size_t sizeof_addr, size_t sizeof_size); +/** + * \ingroup FCPL + * + * \brief + * + * \fcpl_id{plist_id} + * \param[in] ik Symbol table tree rank + * \param[in] lk Symbol table node size + * + * \return \herr_t + * + * \details H5Pset_sym_k() sets the size of parameters used to control the + * symbol table nodes. + * + * This function is valid only for file creation property lists. + * Passing in a value of zero (0) for one of the parameters retains + * the current value. + * + * \p ik is one half the rank of a B-tree that stores a symbol + * table for a group. Internal nodes of the symbol table are on + * average 75% full. That is, the average rank of the tree is + * 1.5 times the value of \p ik. The HDF5 library uses (\p ik*2) as + * the maximum # of entries before splitting a B-tree node. Since + * only 2 bytes are used in storing # of entries for a B-tree node + * in an HDF5 file, (\p ik*2) cannot exceed 65536. The default value + * for \p ik is 16. + * + * \p lk is one half of the number of symbols that can be stored in + * a symbol table node. A symbol table node is the leaf of a symbol + * table tree which is used to store a group. When symbols are + * inserted randomly into a group, the group's symbol table nodes are + * 75% full on average. That is, they contain 1.5 times the number of + * symbols specified by \p lk. The default value for \p lk is 4. + * + * \version 1.6.4 \p ik parameter type changed to \em unsigned. + * \version 1.6.0 The \p ik parameter has changed from type int to + * \em unsigned. + * + * \since 1.0.0 + * + */ +H5_DLL herr_t H5Pset_sym_k(hid_t plist_id, unsigned ik, unsigned lk); +/** + * \ingroup FCPL + * + * \brief Sets user block size + * + * \fcpl_id{plist_id} + * \param[in] size Size of the user-block in bytes + * + * \return \herr_t + * + * \details H5Pset_userblock() sets the user block size of a file creation + * property list. The default user block size is 0; it may be set + * to any power of 2 equal to 512 or greater (512, 1024, 2048, etc.). + * + * \since 1.0.0 + * + */ +H5_DLL herr_t H5Pset_userblock(hid_t plist_id, hsize_t size); /* File access property list (FAPL) routines */ -H5_DLL herr_t H5Pset_alignment(hid_t fapl_id, hsize_t threshold, hsize_t alignment); -H5_DLL herr_t H5Pget_alignment(hid_t fapl_id, hsize_t *threshold /*out*/, hsize_t *alignment /*out*/); -H5_DLL herr_t H5Pset_driver(hid_t plist_id, hid_t driver_id, const void *driver_info); -H5_DLL hid_t H5Pget_driver(hid_t plist_id); +/** + * \ingroup FAPL + * + * \brief Retrieves the current settings for alignment properties from a + * file access property list + * + * \fapl_id + * \param[out] threshold Pointer to location of return threshold value + * \param[out] alignment Pointer to location of return alignment value + * + * \return \herr_t + * + * \details H5Pget_alignment() retrieves the current settings for + * alignment properties from a file access property list. The + * \p threshold and/or \p alignment pointers may be null + * pointers (NULL). + * + * \since 1.0.0 + * + */ +H5_DLL herr_t H5Pget_alignment(hid_t fapl_id, hsize_t *threshold /*out*/, hsize_t *alignment /*out*/); +/** + * \ingroup FAPL + * + * \brief Queries the raw data chunk cache parameters + * + * \fapl_id{plist_id} + * \param[in,out] mdc_nelmts <i>No longer used</i> + * \param[in,out] rdcc_nslots Number of elements (objects) in the raw data + * chunk cache + * \param[in,out] rdcc_nbytes Total size of the raw data chunk cache, in + * bytes + * \param[in,out] rdcc_w0 Preemption policy + * + * \return \herr_t + * + * \details H5Pget_cache() retrieves the maximum possible number of + * elements in the raw data chunk cache, the maximum possible + * number of bytes in the raw data chunk cache, and the + * preemption policy value. + * + * Any (or all) arguments may be null pointers, in which case + * the corresponding datum is not returned. + * + * Note that the \p mdc_nelmts parameter is no longer used. + * + * \version 1.8.0 Use of the \p mdc_nelmts parameter discontinued. + * Metadata cache configuration is managed with + * H5Pset_mdc_config() and H5Pget_mdc_config() + * \version 1.6.0 The \p rdcc_nbytes and \p rdcc_nslots parameters changed + * from type int to size_t. + * + * \since 1.0.0 + * + */ +H5_DLL herr_t H5Pget_cache(hid_t plist_id, int *mdc_nelmts, /* out */ + size_t *rdcc_nslots /*out*/, size_t *rdcc_nbytes /*out*/, double *rdcc_w0); +/** + * \ingroup FAPL + * + * \brief Gets information about the write tracking feature used by + * the core VFD + * + * \fapl_id + * \param[out] is_enabled Whether the feature is enabled + * \param[out] page_size Size, in bytes, of write aggregation pages + * + * \return \herr_t + * + * \details H5Pget_core_write_tracking() retrieves information about the + * write tracking feature used by the core VFD. + * + * When a file is created or opened for writing using the core + * virtual file driver (VFD) with the backing store option turned + * on, the VFD can be configured to track changes to the file + * and only write out the modified bytes. To avoid a large number + * of small writes, the changes can be aggregated into pages of + * a user-specified size. The core VFD is also known as the + * memory VFD. The driver identifier is #H5FD_CORE. + * + * \note This function is only for use with the core VFD and must be used + * after the call to H5Pset_fapl_core(). It is an error to use this + * function with any other VFD. + * + * \note This function only applies to the backing store write operation + * which typically occurs when the file is flushed or closed. This + * function has no relationship to the increment parameter passed + * to H5Pset_fapl_core(). + * + * \note For optimum performance, the \p page_size parameter should be + * a power of two. + * + * \since 1.8.13 + * + */ +H5_DLL herr_t H5Pget_core_write_tracking(hid_t fapl_id, hbool_t *is_enabled, size_t *page_size); +/** + * \ingroup FAPL + * + * \brief Returns low-lever driver identifier + * + * \plist_id + * + * \return \hid_t{low level driver} + * + * \details H5Pget_driver() returns the identifier of the low-level file + * driver associated with the file access property list or + * data transfer property list \p plist_id. + * + * Valid driver identifiers distributed with HDF5 are listed and + * described in the following table. + * + * <table> + * <tr> + * <th>Driver Name</th> + * <th>Driver Identifier</th> + * <th>Description</th> + * <th>Related Function</th> + * </tr> + * <tr> + * <td>POSIX</td> + * <td>#H5FD_SEC2</td> + * <td>This driver uses POSIX file-system functions like read and + * write to perform I/O to a single, permanent file on local disk + * with no system buffering. This driver is POSIX-compliant and + * is the default file driver for all systems.</td> + * <td>H5Pset_fapl_sec2()</td> + * </tr> + * <tr> + * <td>Direct</td> + * <td>#H5FD_DIRECT</td> + * <td>This is the #H5FD_SEC2 driver except data is written to or + * read from the file synchronously without being cached by the + * system.</td> + * <td>H5Pset_fapl_direct()</td> + * </tr> + * <tr> + * <td>Log</td> + * <td>#H5FD_LOG</td> + * <td>This is the #H5FD_SEC2 driver with logging capabilities.</td> + * <td>H5Pset_fapl_log()</td> + * </tr> + * <tr> + * <td>Windows</td> + * <td>#H5FD_WINDOWS</td> + * <td>This driver was modified in HDF5-1.8.8 to be a wrapper of the + * POSIX driver, #H5FD_SEC2. This change should not affect user + * applications.</td> + * <td>H5Pset_fapl_windows()</td> + * </tr> + * <tr> + * <td>STDIO</td> + * <td>#H5FD_STDIO</td> + * <td>This driver uses functions from the standard C stdio.h to + * perform I/O to a single, permanent file on local disk with + * additional system buffering.</td> + * <td>H5Pset_fapl_stdio()</td> + * </tr> + * <tr> + * <td>Memory</td> + * <td>#H5FD_CORE</td> + * <td>With this driver, an application can work with a file in + * memory for faster reads and writes. File contents are kept in + * memory until the file is closed. At closing, the memory + * version of the file can be written back to disk or abandoned. + * </td> + * <td>H5Pset_fapl_core()</td> + * </tr> + * <tr> + * <td>Family</td> + * <td>#H5FD_FAMILY</td> + * <td>With this driver, the HDF5 file’s address space is partitioned + * into pieces and sent to separate storage files using an + * underlying driver of the user’s choice. This driver is for + * systems that do not support files larger than 2 gigabytes. + * </td> + * <td>H5Pset_fapl_family()</td> + * </tr> + * <tr> + * <td>Multi</td> + * <td>#H5FD_MULTI</td> + * <td>With this driver, data can be stored in multiple files + * according to the type of the data. I/O might work better if + * data is stored in separate files based on the type of data. + * The Split driver is a special case of this driver.</td> + * <td>H5Pset_fapl_multi()</td> + * </tr> + * <tr> + * <td>Parallel</td> + * <td>#H5FD_MPIO</td> + * <td>This is the standard HDF5 file driver for parallel file + * systems. This driver uses the MPI standard for both + * communication and file I/O.</td> + * <td>H5Pset_fapl_mpio()</td> + * </tr> + * <tr> + * <td>Parallel POSIX</td> + * <td>H5FD_MPIPOSIX</td> + * <td>This driver is no longer available.</td> + * <td></td> + * </tr> + * <tr> + * <td>Stream</td> + * <td>H5FD_STREAM</td> + * <td>This driver is no longer available.</td> + * <td></td> + * </tr> + * </table> + * + * This list does not include custom drivers that might be + * defined and registered by a user. + * + * The returned driver identifier is only valid as long as the + * file driver remains registered. + * + * + * \since 1.4.0 + * + */ +H5_DLL hid_t H5Pget_driver(hid_t plist_id); +/** + * \ingroup FAPL + * + * \brief Returns a pointer to file driver information + * + * \param[in] plist_id File access or data transfer property list + * identifier + * + * \return Returns a pointer to a struct containing low-level driver + * information. Otherwise returns NULL. NULL is also returned if + * no driver-specific properties have been registered. No error + * is pushed on the stack in this case. + * + * \details H5Pget_driver_info() returns a pointer to file driver-specific + * information for the low-level driver associated with the file + * access or data transfer property list \p plist_id. + * + * The pointer returned by this function points to an “uncopied” + * struct. Driver-specific versions of that struct are defined + * for each low-level driver in the relevant source code file + * H5FD*.c. For example, the struct used for the MULTI driver is + * \c H5FD_multi_fapl_t defined in H5FDmulti.c. + * + * If no driver-specific properties have been registered, + * H5Pget_driver_info() returns NULL. + * + * \note H5Pget_driver_info() and H5Pset_driver() are used only when + * creating a virtual file driver (VFD) in the virtual file + * layer (VFL). + * + * \version 1.10.1 Return value was changed from \em void * to + * \em const \em void *. + * \version 1.8.2 Function publicized in this release; previous releases + * described this function only in the virtual file driver + * documentation. + * + */ H5_DLL const void *H5Pget_driver_info(hid_t plist_id); -H5_DLL herr_t H5Pset_vol(hid_t plist_id, hid_t new_vol_id, const void *new_vol_info); -H5_DLL herr_t H5Pget_vol_id(hid_t plist_id, hid_t *vol_id); -H5_DLL herr_t H5Pget_vol_info(hid_t plist_id, void **vol_info); -H5_DLL herr_t H5Pset_family_offset(hid_t fapl_id, hsize_t offset); -H5_DLL herr_t H5Pget_family_offset(hid_t fapl_id, hsize_t *offset); -H5_DLL herr_t H5Pset_multi_type(hid_t fapl_id, H5FD_mem_t type); -H5_DLL herr_t H5Pget_multi_type(hid_t fapl_id, H5FD_mem_t *type); -H5_DLL herr_t H5Pset_cache(hid_t plist_id, int mdc_nelmts, size_t rdcc_nslots, size_t rdcc_nbytes, - double rdcc_w0); -H5_DLL herr_t H5Pget_cache(hid_t plist_id, int *mdc_nelmts, /* out */ - size_t *rdcc_nslots /*out*/, size_t *rdcc_nbytes /*out*/, double *rdcc_w0); -H5_DLL herr_t H5Pset_mdc_config(hid_t plist_id, H5AC_cache_config_t *config_ptr); -H5_DLL herr_t H5Pget_mdc_config(hid_t plist_id, H5AC_cache_config_t *config_ptr); /* out */ -H5_DLL herr_t H5Pset_gc_references(hid_t fapl_id, unsigned gc_ref); -H5_DLL herr_t H5Pget_gc_references(hid_t fapl_id, unsigned *gc_ref /*out*/); -H5_DLL herr_t H5Pset_fclose_degree(hid_t fapl_id, H5F_close_degree_t degree); -H5_DLL herr_t H5Pget_fclose_degree(hid_t fapl_id, H5F_close_degree_t *degree); -H5_DLL herr_t H5Pset_meta_block_size(hid_t fapl_id, hsize_t size); -H5_DLL herr_t H5Pget_meta_block_size(hid_t fapl_id, hsize_t *size /*out*/); -H5_DLL herr_t H5Pset_sieve_buf_size(hid_t fapl_id, size_t size); -H5_DLL herr_t H5Pget_sieve_buf_size(hid_t fapl_id, size_t *size /*out*/); -H5_DLL herr_t H5Pset_small_data_block_size(hid_t fapl_id, hsize_t size); -H5_DLL herr_t H5Pget_small_data_block_size(hid_t fapl_id, hsize_t *size /*out*/); -H5_DLL herr_t H5Pset_libver_bounds(hid_t plist_id, H5F_libver_t low, H5F_libver_t high); -H5_DLL herr_t H5Pget_libver_bounds(hid_t plist_id, H5F_libver_t *low, H5F_libver_t *high); -H5_DLL herr_t H5Pset_elink_file_cache_size(hid_t plist_id, unsigned efc_size); -H5_DLL herr_t H5Pget_elink_file_cache_size(hid_t plist_id, unsigned *efc_size); -H5_DLL herr_t H5Pset_file_image(hid_t fapl_id, void *buf_ptr, size_t buf_len); -H5_DLL herr_t H5Pget_file_image(hid_t fapl_id, void **buf_ptr_ptr, size_t *buf_len_ptr); -H5_DLL herr_t H5Pset_file_image_callbacks(hid_t fapl_id, H5FD_file_image_callbacks_t *callbacks_ptr); -H5_DLL herr_t H5Pget_file_image_callbacks(hid_t fapl_id, H5FD_file_image_callbacks_t *callbacks_ptr); -H5_DLL herr_t H5Pset_file_locking(hid_t fapl_id, hbool_t use_file_locking, hbool_t ignore_when_disabled); +/** + * \ingroup FAPL + * + * \brief Retrieves the size of the external link open file cache + * + * \fapl_id{plist_id} + * \param[out] efc_size External link open file cache size in number of files + * + * \return \herr_t + * + * \details H5Pget_elink_file_cache_size() retrieves the number of files that + * can be held open in an external link open file cache. + * + * \since 1.8.7 + * + */ +H5_DLL herr_t H5Pget_elink_file_cache_size(hid_t plist_id, unsigned *efc_size); +/** + * \ingroup FAPL + * + * \brief Retrieves the file access property list setting that determines + * whether an HDF5 object will be evicted from the library's metadata + * cache when it is closed + * + * \fapl_id + * \param[out] evict_on_close Pointer to a variable that will indicate if + * the object will be evicted on close + * + * \return \herr_t + * + * \details The library's metadata cache is fairly conservative about holding on + * to HDF5 object metadata (object headers, chunk index structures, + * etc.), which can cause the cache size to grow, resulting in memory + * pressure on an application or system. When enabled, the "evict on + * close" property will cause all metadata for an object to be + * immediately evicted from the cache as long as it is not referenced + * by any other open object. + * + * See H5Pset_evict_on_close() for additional notes on behavior. + * + * \since 1.10.1 + * + */ +H5_DLL herr_t H5Pget_evict_on_close(hid_t fapl_id, hbool_t *evict_on_close); +/** + * \ingroup FAPL + * + * \brief Retrieves a data offset from the file access property list + * + * \fapl_id + * \param[out] offset Offset in bytes within the HDF5 file + * + * \return \herr_t + * + * \details H5Pget_family_offset() retrieves the value of offset from the + * file access property list \p fapl_id so that the user + * application can retrieve a file handle for low-level access to + * a particular member of a family of files. The file handle is + * retrieved with a separate call to H5Fget_vfd_handle() (or, + * in special circumstances, to H5FDget_vfd_handle(), see \ref VFL). + * + * \since 1.6.0 + * + */ +H5_DLL herr_t H5Pget_family_offset(hid_t fapl_id, hsize_t *offset); +/** + * \ingroup FAPL + * + * \brief Returns the file close degree + * + * \fapl_id + * \param[out] degree Pointer to a location to which to return the file + * close degree property, the value of \p degree + * + * \return \herr_t + * + * \details H5Pget_fclose_degree() returns the current setting of the file + * close degree property \p degree in the file access property + * list \p fapl_id. The value of \p degree determines how + * aggressively H5Fclose() deals with objects within a file that + * remain open when H5Fclose() is called to close that file. + * + * \since 1.6.0 + * + */ +H5_DLL herr_t H5Pget_fclose_degree(hid_t fapl_id, H5F_close_degree_t *degree); +/** + * \ingroup FAPL + * + * \brief Retrieves a copy of the file image designated as the initial content + * and structure of a file + * + * \fapl_id + * \param[in,out] buf_ptr_ptr On input, \c NULL or a pointer to a + * pointer to a buffer that contains the + * file image.\n On successful return, if \p buf_ptr_ptr is not + * \c NULL, \Code{*buf_ptr_ptr} will contain a pointer to a copy + * of the initial image provided in the last call to + * H5Pset_file_image() for the supplied \p fapl_id. If no initial + * image has been set, \Code{*buf_ptr_ptr} will be \c NULL. + * \param[in,out] buf_len_ptr On input, \c NULL or a pointer to a buffer + * specifying the required size of the buffer to hold the file + * image.\n On successful return, if \p buf_len_ptr was not + * passed in as \c NULL, \p buf_len_ptr will return the required + * size in bytes of the buffer to hold the initial file image in + * the supplied file access property list, \p fapl_id. If no + * initial image is set, the value of \Code{*buf_len_ptr} will be + * set to 0 (zero) + * \return \herr_t + * + * \details H5Pget_file_image() allows an application to retrieve a copy of the + * file image designated for a VFD to use as the initial contents of a file. + * + * If file image callbacks are defined, H5Pget_file_image() will use + * them when allocating and loading the buffer to return to the + * application (see H5Pset_file_image_callbacks()). If file image + * callbacks are not defined, the function will use \c malloc and \c + * memcpy. When \c malloc and \c memcpy are used, it is the caller’s + * responsibility to discard the returned buffer with a call to \c + * free. + * + * It is the responsibility of the calling application to free the + * buffer whose address is returned in \p buf_ptr_ptr. This can be + * accomplished with \c free if file image callbacks have not been set + * (see H5Pset_file_image_callbacks()) or with the appropriate method + * if file image callbacks have been set. + * + * \see H5LTopen_file_image(), H5Fget_file_image(), H5Pset_file_image(), + * H5Pset_file_image_callbacks(), H5Pget_file_image_callbacks(), + * \ref H5FD_file_image_callbacks_t, \ref H5FD_file_image_op_t, + * <a href="https://portal.hdfgroup.org/display/HDF5/HDF5+File+Image+Operations"> + * HDF5 File Image Operations</a>. + * + * + * \since 1.8.9 + * + */ +H5_DLL herr_t H5Pget_file_image(hid_t fapl_id, void **buf_ptr_ptr, size_t *buf_len_ptr); +/** + * \ingroup FAPL + * + * \brief Retrieves callback routines for working with file images + * + * \fapl_id + * \param[in,out] callbacks_ptr Pointer to the instance of the + * #H5FD_file_image_callbacks_t struct in which the callback + * routines are to be returned\n + * Struct fields must be initialized to NULL before the call + * is made.\n + * Struct field contents upon return will match those passed in + * in the last H5Pset_file_image_callbacks() call for the file + * access property list \p fapl_id. + * \return \herr_t + * + * \details H5Pget_file_image_callbacks() retrieves the callback routines set for + * working with file images opened with the file access property list + * \p fapl_id. + * + * The callbacks must have been previously set with + * H5Pset_file_image_callbacks() in the file access property list. + * + * Upon the successful return of H5Pset_file_image_callbacks(), the + * fields in the instance of the #H5FD_file_image_callbacks_t struct + * pointed to by \p callbacks_ptr will contain the same values as were + * passed in the most recent H5Pset_file_image_callbacks() call for the + * file access property list \p fapl_id. + * + * \see H5LTopen_file_image(), H5Fget_file_image(), H5Pset_file_image(), + * H5Pset_file_image_callbacks(), H5Pget_file_image_callbacks(), + * \ref H5FD_file_image_callbacks_t, \ref H5FD_file_image_op_t, + * <a href="https://portal.hdfgroup.org/display/HDF5/HDF5+File+Image+Operations"> + * HDF5 File Image Operations</a>. + * + * \since 1.8.9 + * + */ +H5_DLL herr_t H5Pget_file_image_callbacks(hid_t fapl_id, H5FD_file_image_callbacks_t *callbacks_ptr); +/** + * \ingroup FAPL + * + * \brief Retrieves the file locking property values + * + * \fapl_id + * \param[out] use_file_locking File locking flag + * \param[out] ignore_when_disabled Ignore when disabled flag + * \return \herr_t + * + * \details H5Pget_file_locking() retrieves the file locking property values for + * the file access property list specified by \p fapl_id. + * + * \since 1.10.7 + * + */ H5_DLL herr_t H5Pget_file_locking(hid_t fapl_id, hbool_t *use_file_locking, hbool_t *ignore_when_disabled); -H5_DLL herr_t H5Pset_core_write_tracking(hid_t fapl_id, hbool_t is_enabled, size_t page_size); -H5_DLL herr_t H5Pget_core_write_tracking(hid_t fapl_id, hbool_t *is_enabled, size_t *page_size); -H5_DLL herr_t H5Pset_metadata_read_attempts(hid_t plist_id, unsigned attempts); +/** + * \ingroup FAPL + * + * \brief Returns garbage collecting references setting + * + * \fapl_id + * \param[out] gc_ref Flag returning the state of reference garbage + * collection. A returned value of 1 indicates that + * garbage collection is on while 0 indicates that + * garbage collection is off. + * + * \return \herr_t + * + * \details H5Pget_gc_references() returns the current setting for the + * garbage collection references property from the specified + * file access property list. The garbage collection references + * property is set by H5Pset_gc_references(). + * + * \since 1.2.0 + * + */ +H5_DLL herr_t H5Pget_gc_references(hid_t fapl_id, unsigned *gc_ref /*out*/); +/** + * \ingroup FAPL + * + * \brief Retrieves library version bounds settings that indirectly control + * the format versions used when creating objects + * + * \fapl_id{plist_id} + * \param[out] low The earliest version of the library that will be used + * for writing objects + * \param[out] high The latest version of the library that will be used for + * writing objects + * + * \return \herr_t + * + * \details H5Pget_libver_bounds() retrieves the lower and upper bounds on + * the HDF5 library release versions that indirectly determine the + * object format versions used when creating objects in the file. + * + * This property is retrieved from the file access property list + * specified by the parameter \p fapl_id. + * + * The value returned in the parameters \p low and \p high is one + * of the enumerated values in the #H5F_libver_t struct, which is + * defined in H5Fpublic.h. + * + * \version 1.10.2 Add #H5F_LIBVER_V18 to the enumerated defines in + * #H5F_libver_t + * \since 1.8.0 + * + */ +H5_DLL herr_t H5Pget_libver_bounds(hid_t plist_id, H5F_libver_t *low, H5F_libver_t *high); +/** + * \ingroup FAPL + * + * \brief Get the current initial metadata cache configuration from the + * provided file access property list + * + * \fapl_id{plist_id} + * \param[in,out] config_ptr Pointer to the instance of #H5AC_cache_config_t + * in which the current metadata cache configuration is to be + * reported + * \return \herr_t + * + * \note The \c in direction applies only to the \ref H5AC_cache_config_t.version + * field. All other fields are \c out parameters. + * + * \details The fields of the #H5AC_cache_config_t structure are shown + * below: + * \snippet H5ACpublic.h H5AC_cache_config_t_snip + * \click4more + * + * H5Pget_mdc_config() gets the initial metadata cache configuration + * contained in a file access property list and loads it into the + * instance of #H5AC_cache_config_t pointed to by the \p config_ptr + * parameter. This configuration is used when the file is opened. + * + * Note that the version field of \Code{*config_ptr} must be + * initialized; this allows the library to support earlier versions of + * the #H5AC_cache_config_t structure. + * + * See the overview of the metadata cache in the special topics section + * of the user guide for details on the configuration data returned. If + * you haven't read and understood that documentation, the results of + * this call will not make much sense. + * + * \since 1.8.0 + * + */ +H5_DLL herr_t H5Pget_mdc_config(hid_t plist_id, H5AC_cache_config_t *config_ptr); /* out */ +/** + * \ingroup FAPL + * + * \brief Retrieves the metadata cache image configuration values for a file + * access property list + * + * \fapl_id{plist_id} + * \param[out] config_ptr Pointer to metadata cache image configuration values + * \return \herr_t + * + * \details H5Pget_mdc_image_config() retrieves the metadata cache image values + * into \p config_ptr for the file access property list specified in \p + * plist_id. + * + * #H5AC_cache_image_config_t is defined as follows: + * \snippet H5ACpublic.h H5AC_cache_image_config_t_snip + * \click4more + * + * \since 1.10.1 + */ +H5_DLL herr_t H5Pget_mdc_image_config(hid_t plist_id, H5AC_cache_image_config_t *config_ptr /*out*/); +/** + * \ingroup FAPL + * + * \brief Gets metadata cache logging options + * + * \fapl_id{plist_id} + * \param[out] is_enabled Flag whether logging is enabled + * \param[out] location Location of log in UTF-8/ASCII (file path/name) (On + * Windows, this must be ASCII) + * \param[out] location_size Size in bytes of the location string + * \param[out] start_on_access Whether the logging begins as soon as the file is + * opened or created + * \return \herr_t + * + * \details The metadata cache is a central part of the HDF5 library through + * which all file metadata reads and writes take place. File metadata + * is normally invisible to the user and is used by the library for + * purposes such as locating and indexing data. File metadata should + * not be confused with user metadata, which consists of attributes + * created by users and attached to HDF5 objects such as datasets via + * \ref H5A API calls. + * + * Due to the complexity of the cache, a trace/logging feature has been + * created that can be used by HDF5 developers for debugging and + * performance analysis. The functions that control this functionality + * will normally be of use to a very limited number of developers + * outside of The HDF Group. The functions have been documented to help + * users create logs that can be sent with bug reports. + * + * Control of the log functionality is straightforward. Logging is + * enabled via the H5Pset_mdc_log_options() function, which will modify + * the file access property list used to open or create a file. This + * function has a flag that determines whether logging begins at file + * open or starts in a paused state. Log messages can then be + * controlled via the H5Fstart_mdc_logging() / H5Fstop_mdc_logging() + * functions. H5Pget_mdc_log_options() can be used to examine a file + * access property list, and H5Fget_mdc_logging_status() will return + * the current state of the logging flags. + * + * The log format is described in the + * <a href="https://bit.ly/2PG6fNv">Metadata Cache Logging</a> document. + * + * \since 1.10.0 + */ +H5_DLL herr_t H5Pget_mdc_log_options(hid_t plist_id, hbool_t *is_enabled, char *location, + size_t *location_size, hbool_t *start_on_access); +/** + * \ingroup FAPL + * + * \brief Returns the current metadata block size setting + * + * \fapl_id{fapl_id} + * \param[out] size Minimum size, in bytes, of metadata block allocations + * + * \return \herr_t + * + * \details Returns the current minimum size, in bytes, of new + * metadata block allocations. This setting is retrieved from the + * file access property list \p fapl_id. + * + * This value is set by H5Pset_meta_block_size() and is + * retrieved from the file access property list \p fapl_id. + * + * \since 1.4.0 + */ +H5_DLL herr_t H5Pget_meta_block_size(hid_t fapl_id, hsize_t *size); +/** + * \ingroup FAPL + * + * \brief Retrieves the number of read attempts from a file access + * property list + * + * \fapl_id{plist_id} + * \param[out] attempts The number of read attempts + * + * \return \herr_t + * + * \details H5Pget_metadata_read_attempts() retrieves the number of read + * attempts that is set in the file access property list \p plist_id. + * + * For a default file access property list, the value retrieved + * will depend on whether the user sets the number of attempts via + * H5Pset_metadata_read_attempts(): + * + * <ul> + * + * <li>If the number of attempts is set to N, the value + * returned will be N. + * <li>If the number of attempts is not set, the value returned + * will be the default for non-SWMR access (1). SWMR is short + * for single-writer/multiple-reader. + * </ul> + * + * For the file access property list of a specified HDF5 file, + * the value retrieved will depend on how the file is opened + * and whether the user sets the number of read attempts via + * H5Pset_metadata_read_attempts(): + * + * <ul> + * <li>For a file opened with SWMR access: + * + * <ul> + * <li> If the number of attempts is set to N, the value + * returned will be N. + * <li> If the number of attempts is not set, the value + * returned will be the default for SWMR access (100). + * </ul> + * <li>For a file opened without SWMR access, the value + * retrieved will always be the default for non-SWMR access + * (1). The value set via H5Pset_metadata_read_attempts() does + * not have any effect on non-SWMR access. + * </ul> + * + * \par Failure Modes + * \parblock + * + * When the input property list is not a file access property list. + * + * When the library is unable to retrieve the number of read attempts from + * the file access property list. + * + * \endparblock + * + * \par Examples + * \parblock + * + * The first example illustrates the two cases for retrieving the number + * of read attempts from a default file access property list. + * + * \include H5Pget_metadata_read_attempts.1.c + * + * The second example illustrates the two cases for retrieving the + * number of read attempts from the file access property list of a file + * opened with SWMR acccess. + * + * \include H5Pget_metadata_read_attempts.2.c + * + * The third example illustrates the two cases for retrieving the number + * of read attempts from the file access property list of a file opened + * with non-SWMR acccess. + * + * \include H5Pget_metadata_read_attempts.3.c + * + * \endparblock + * + * \since 1.10.0 + */ H5_DLL herr_t H5Pget_metadata_read_attempts(hid_t plist_id, unsigned *attempts); -H5_DLL herr_t H5Pset_object_flush_cb(hid_t plist_id, H5F_flush_cb_t func, void *udata); +/** + * \ingroup FAPL + * + * \brief Retrieves type of data property for MULTI driver + * + * \param[in] fapl_id File access property list or data transfer property + * list identifier + * \param[out] type Type of data + * + * \return \herr_t + * + * \details H5Pget_multi_type() retrieves the type of data setting from + * the file access or data transfer property list \p fapl_id. + * This enables a user application to specify the type of data + * the application wishes to access so that the application can + * retrieve a file handle for low-level access to the particular + * member of a set of MULTI files in which that type of data is + * stored. The file handle is retrieved with a separate call to + * H5Fget_vfd_handle() (or, in special circumstances, to + * H5FDget_vfd_handle(); see the Virtual File Layer documentation + * for more information. + * + * The type of data returned in \p type will be one of those + * listed in the discussion of the \p type parameter in the the + * description of the function H5Pset_multi_type(). + * + * Use of this function is only appropriate for an HDF5 file + * written as a set of files with the MULTI file driver. + * + * \since 1.6.0 + * + */ +H5_DLL herr_t H5Pget_multi_type(hid_t fapl_id, H5FD_mem_t *type); +/** + * \ingroup FAPL + * + * \brief Retrieves the object flush property values from the file access property list + * + * \fapl_id{plist_id} + * \param[in] func The user-defined callback function + * \param[in] udata The user-defined input data for the callback function + * + * \return \herr_t + * + * \details H5Pget_object_flush_cb() gets the user-defined callback + * function that is set in the file access property list + * \p fapl_id and stored in the parameter \p func. The callback is + * invoked whenever an object flush occurs in the file. This + * routine also obtains the user-defined input data that is + * passed along to the callback function in the parameter + * \p udata. + * + * \par Example + * \parblock + * The example below illustrates the usage of this routine to obtain the + * object flush property values. + * + * \include H5Pget_object_flush_cb.c + * \endparblock + * + * \since 1.10.0 + */ H5_DLL herr_t H5Pget_object_flush_cb(hid_t plist_id, H5F_flush_cb_t *func, void **udata); +/** + * \ingroup FAPL + * + * \brief Retrieves the maximum size for the page buffer and the minimum + percentage for metadata and raw data pages + * + * \fapl_id{plist_id} + * \param[out] buf_size Maximum size, in bytes, of the page buffer + * \param[out] min_meta_perc Minimum metadata percentage to keep in the + * page buffer before allowing pages containing metadata to + * be evicted + * + * \param[out] min_raw_perc Minimum raw data percentage to keep in the + * page buffer before allowing pages containing raw data to + * be evicted + * + * \return \herr_t + * + * \details H5Pget_page_buffer_size() retrieves \p buf_size, the maximum + * size in bytes of the page buffer, \p min_meta_perc, the + * minimum metadata percentage, and \p min_raw_perc, the + * minimum raw data percentage. + * + * \since 1.10.1 + */ +H5_DLL herr_t H5Pget_page_buffer_size(hid_t plist_id, size_t *buf_size, unsigned *min_meta_perc, + unsigned *min_raw_perc); +/** + * \ingroup FAPL + * + * \brief Returns maximum data sieve buffer size + * + * \fapl_id{fapl_id} + * \param[in] size Maximum size, in bytes, of data sieve buffer + * + * \return \herr_t + * + * \details H5Pget_sieve_buf_size() retrieves, size, the current maximum + * size of the data sieve buffer. + * + * This value is set by H5Pset_sieve_buf_size() and is retrieved + * from the file access property list fapl_id. + * + * \version 1.6.0 The \p size parameter has changed from type \c hsize_t + * to \c size_t + * \since 1.4.0 + */ +H5_DLL herr_t H5Pget_sieve_buf_size(hid_t fapl_id, size_t *size /*out*/); +/** + * \ingroup FAPL + * + * \brief Retrieves the current small data block size setting + * + * \fapl_id{fapl_id} + * \param[out] size Maximum size, in bytes, of the small data block + * + * \result \herr_t + * + * \details H5Pget_small_data_block_size() retrieves the current setting + * for the size of the small data block. + * + * If the returned value is zero (0), the small data block + * mechanism has been disabled for the file. + * + * \since 1.4.4 + */ +H5_DLL herr_t H5Pget_small_data_block_size(hid_t fapl_id, hsize_t *size /*out*/); +/** + * \todo Add missing documentation + */ +H5_DLL herr_t H5Pget_vfd_swmr_config(hid_t plist_id, H5F_vfd_swmr_config_t *config_ptr); +/** + * \ingroup FAPL + * + * \brief Returns the identifier of the current VOL connector + * + * \fapl_id{plist_id} + * \param[out] vol_id Current VOL connector identifier + * + * \return \herr_t + * + * \details H5Pget_vol_id() returns the VOL connector identifier \p vol_id for + * the file access property list \p plist_id. This identifier should + * be closed with H5VLclose(). + * + * \since 1.12.0 + * + */ +H5_DLL herr_t H5Pget_vol_id(hid_t plist_id, hid_t *vol_id); +/** + * \ingroup FAPL + * + * \brief Returns a copy of the VOL information for a connector + * + * \fapl_id{plist_id} + * \param[out] vol_info The VOL information for a connector + * + * \return \herr_t + * + * \details H5Pget_vol_info() returns a copy of the VOL information \p vol_info + * for a connector specified by the file access property list + * \p plist_id. + * + * \since 1.12.0 + * + */ +H5_DLL herr_t H5Pget_vol_info(hid_t plist_id, void **vol_info); +/** + * \ingroup FAPL + * + * \brief Sets alignment properties of a file access property list + * + * \fapl_id + * \param[in] threshold Threshold value. Note that setting the threshold + * value to 0 (zero) has the effect of a special case, + * forcing everything to be aligned + * \param[in] alignment Alignment value + * + * \return \herr_t + * + * \details H5Pset_alignment() sets the alignment properties of a + * file access property list so that any file object greater + * than or equal in size to \p threshold bytes will be aligned + * on an address which is a multiple of \p alignment. The + * addresses are relative to the end of the user block; the + * alignment is calculated by subtracting the user block size + * from the absolute file address and then adjusting the address + * to be a multiple of \p alignment. + * + * Default values for \p threshold and \p alignment are one, + * implying no alignment. Generally the default values will + * result in the best performance for single-process access to + * the file. For MPI IO and other parallel systems, choose an + * alignment which is a multiple of the disk block size. + * + * If the file space handling strategy is set to + * #H5F_FSPACE_STRATEGY_PAGE, then the alignment set via this + * routine is ignored. The file space handling strategy is set + * by H5Pset_file_space_strategy(). + * + * \since 1.0.0 + * + */ +H5_DLL herr_t H5Pset_alignment(hid_t fapl_id, hsize_t threshold, hsize_t alignment); +/** + * \ingroup FAPL + * + * \brief Sets the raw data chunk cache parameters + * + * \fapl_id{plist_id} + * \param[in] mdc_nelmts No longer used; any value passed is ignored + * \param[in] rdcc_nslots The number of chunk slots in the raw data chunk + * cache for this dataset. Increasing this value + * reduces the number of cache collisions, but + * slightly increases the memory used. Due to the + * hashing strategy, this value should ideally be a + * prime number. As a rule of thumb, this value + * should be at least 10 times the number of chunks + * that can fit in \p rdcc_nbytes bytes. For + * maximum performance, this value should be set + * approximately 100 times that number of chunks. + * The default value is 521. + * \param[in] rdcc_nbytes Total size of the raw data chunk cache in bytes. + * The default size is 1 MB per dataset. + * \param[in] rdcc_w0 The chunk preemption policy for all datasets. + * This must be between 0 and 1 inclusive and + * indicates the weighting according to which chunks + * which have been fully read or written are + * penalized when determining which chunks to flush + * from cache. A value of 0 means fully read or + * written chunks are treated no differently than + * other chunks (the preemption is strictly LRU) + * while a value of 1 means fully read or written + * chunks are always preempted before other chunks. + * If your application only reads or writes data once, + * this can be safely set to 1. Otherwise, this should + * be set lower depending on how often you re-read or + * re-write the same data. The default value is 0.75. + * If the value passed is #H5D_CHUNK_CACHE_W0_DEFAULT, + * then the property will not be set on the dataset + * access property list, and the parameter will come + * from the file access property list. + * + * \return \herr_t + * + * \details H5Pset_cache() sets the number of elements, the total number of + * bytes, and the preemption policy value for all datasets in a file + * on the file’s file access property list. + * + * The raw data chunk cache inserts chunks into the cache by first + * computing a hash value using the address of a chunk and then by + * using that hash value as the chunk’s index into the table of + * cached chunks. In other words, the size of this hash table and the + * number of possible hash values is determined by the \p rdcc_nslots + * parameter. If a different chunk in the cache has the same hash value, + * a collision will occur, which will reduce efficiency. If inserting + * the chunk into the cache would cause the cache to be too big, then + * the cache will be pruned according to the \p rdcc_w0 parameter. + * + * The \p mdc_nelmts parameter is no longer used; any value passed + * in that parameter will be ignored. + * + * \b Motivation: Setting raw data chunk cache parameters + * can be done with H5Pset_cache(), H5Pset_chunk_cache(), + * or a combination of both. H5Pset_cache() is used to + * adjust the chunk cache parameters for all datasets via + * a global setting for the file, and H5Pset_chunk_cache() + * is used to adjust the chunk cache parameters for + * individual datasets. When both are used, parameters + * set with H5Pset_chunk_cache() will override any parameters + * set with H5Pset_cache(). + * + * \note Optimum chunk cache parameters may vary widely depending + * on different data layout and access patterns. For datasets + * with low performance requirements for example, changing + * the cache settings can save memory. + * + * \note Note: Raw dataset chunk caching is not currently + * supported when using the MPI I/O and MPI POSIX file drivers + * in read/write mode; see H5Pset_fapl_mpio() and + * H5Pset_fapl_mpiposix(), respectively. When using one of these + * file drivers, all calls to H5Dread() and H5Dwrite() will access + * the disk directly, and H5Pset_cache() will have no effect on + * performance. + * + * \note Raw dataset chunk caching is supported when these drivers are + * used in read-only mode. + * + * \todo Check on H5Pset_fapl_mpio() and H5Pset_fapl_mpiposix(). + * + * \version 1.8.0 The use of the \p mdc_nelmts parameter was discontinued. + * Metadata cache configuration is managed with + * H5Pset_mdc_config() and H5Pget_mdc_config(). + * \version 1.6.0 The \p rdcc_nbytes and \p rdcc_nelmts parameters + * changed from type int to size_t. + * \since 1.0.0 + * + */ +H5_DLL herr_t H5Pset_cache(hid_t plist_id, int mdc_nelmts, size_t rdcc_nslots, size_t rdcc_nbytes, + double rdcc_w0); +/** + * \ingroup FAPL + * + * \brief Sets write tracking information for core driver, #H5FD_CORE + * + * \fapl_id{fapl_id} + * \param[in] is_enabled Boolean value specifying whether feature is + enabled + * \param[in] page_size Positive integer specifying size, in bytes, of + * write aggregation pages Value of 1 (one) enables + * tracking with no paging. + * + * \return \herr_t + * + * \details When a file is created or opened for writing using the core + * virtual file driver (VFD) with the backing store option + * turned on, the core driver can be configured to track + * changes to the file and write out only the modified bytes. + * + * This write tracking feature is enabled and disabled with \p + * is_enabled. The default setting is that write tracking is + * disabled, or off. + * + * To avoid a large number of small writes, changes can + * be aggregated into pages of a user-specified size, \p + * page_size. + * + * Setting \p page_size to 1 enables tracking with no page + * aggregation. + * + * The backing store option is set via the function + * H5Pset_fapl_core. + * + * \attention + * \parblock + * This function is only for use with the core VFD and must + * be used after the call to H5Pset_fapl_core(). It is an error + * to use this function with any other VFD. + * + * It is an error to use this function when the backing store + * flag has not been set using H5Pset_fapl_core(). + * + * This function only applies to the backing store write + * operation which typically occurs when the file is flushed + * or closed. This function has no relationship to the + * increment parameter passed to H5Pset_fapl_core(). + * + * For optimum performance, the \p page_size parameter should be + * a power of two. + * + * It is an error to set the page size to 0. + * \endparblock + * + * \version 1.8.14 C function modified in this release to return error + * if \p page_size is set to 0 (zero). + * \since 1.8.13 + * + */ +H5_DLL herr_t H5Pset_core_write_tracking(hid_t fapl_id, hbool_t is_enabled, size_t page_size); +/** + * \ingroup FAPL + * + * \brief Sets a file driver + * + * \plist_id + * \param[in] driver_id The new driver identifier + * \param[in] driver_info Optional struct containing driver properties + * + * \return \herr_t + * + * \details H5Pset_driver() sets the file driver, driver_id, for a file + * access or data transfer property list, \p plist_id, and + * supplies an optional struct containing the driver-specific + * properties, \p driver_info. + * + * The driver properties will be copied into the property list + * and the reference count on the driver will be incremented, + * allowing the caller to close the driver identifier but still + * use the property list. + * + * \version 1.8.2 Function publicized in this release; previous releases + * described this function only in the virtual file driver + * documentation. + * + */ +H5_DLL herr_t H5Pset_driver(hid_t plist_id, hid_t driver_id, const void *driver_info); +/** + * \ingroup FAPL + * + * \brief Sets the number of files that can be held open in an external + * link open file cache + * + * \par Motivation + * \parblock + * The <em>external link open file cache</em> holds files open after + * they have been accessed via an external link. This cache reduces + * the number of times such files are opened when external links are + * accessed repeatedly and can siginificantly improves performance in + * certain heavy-use situations and when low-level file opens or closes + * are expensive. + * + * H5Pset_elink_file_cache_size() sets the number of files + * that will be held open in an external link open file + * cache. H5Pget_elink_file_cache_size() retrieves the size of an existing + * cache; and H5Fclear_elink_file_cache() clears an existing cache without + * closing it. + * \endparblock + * + * \fapl_id{plist_id} + * \param[in] efc_size External link open file cache size in number of files + * <em>Default setting is 0 (zero).</em> + * + * \return \herr_t + * + * \details H5Pset_elink_file_cache_size() specifies the number of files + * that will be held open in an external link open file cache. + * + * The default external link open file cache size is 0 (zero), + * meaning that files accessed via an external link are not + * held open. Setting the cache size to a positive integer + * turns on the cache; setting the size back to zero turns it + * off. + * + * With this property set, files are placed in the external + * link open file cache cache when they are opened via an + * external link. Files are then held open until either + * they are evicted from the cache or the parent file is + * closed. This property setting can improve performance when + * external links are repeatedly accessed. + * + * When the cache is full, files will be evicted using a least + * recently used (LRU) scheme; the file which has gone the + * longest time without being accessed through the parent file + * will be evicted and closed if nothing else is holding that + * file open. + * + * Files opened through external links inherit the parent + * file’s file access property list by default, and therefore + * inherit the parent file’s external link open file cache + * setting. + * + * When child files contain external links of their own, the + * caches can form a graph of cached external files. Closing + * the last external reference to such a graph will recursively + * close all files in the graph, even if cycles are present. + * \par Example + * \parblock + * The following code sets up an external link open file cache that will + * hold open up to 8 files reached through external links: + * + * \code + * status = H5Pset_elink_file_cache_size(fapl_id, 8); + * \endcode + * \endparblock + * + * \since 1.8.7 + */ +H5_DLL herr_t H5Pset_elink_file_cache_size(hid_t plist_id, unsigned efc_size); +/** + * \ingroup FAPL + * + * \brief Controls the library's behavior of evicting metadata associated with + * a closed object + * + * \fapl_id + * \param[in] evict_on_close Whether the HDF5 object should be evicted on close + * + * \return \herr_t + * + * \details The library's metadata cache is fairly conservative about holding + * on to HDF5 object metadata(object headers, chunk index structures, + * etc.), which can cause the cache size to grow, resulting in memory + * pressure on an application or system. When enabled, the "evict on + * close" property will cause all metadata for an object to be evicted + * from the cache as long as metadata is not referenced by any other + * open object. + * + * This function only applies to file access property lists. + * + * The default library behavior is to not evict on object or file + * close. + * + * When applied to a file access property list, any subsequently opened + * object will inherit the "evict on close" property and will have + * its metadata evicted when the object is closed. + * + * \since 1.10.1 + * + */ +H5_DLL herr_t H5Pset_evict_on_close(hid_t fapl_id, hbool_t evict_on_close); +/** + * \ingroup FAPL + * + * \brief Sets offset property for low-level access to a file in a family of + * files + * + * \fapl_id + * \param[in] offset Offset in bytes within the HDF5 file + * + * \return \herr_t + * + * \details H5Pset_family_offset() sets the offset property in the file access + * property list \p fapl_id so that the user application can + * retrieve a file handle for low-level access to a particular member + * of a family of files. The file handle is retrieved with a separate + * call to H5Fget_vfd_handle() (or, in special circumstances, to + * H5FDget_vfd_handle(); see \ref VFL). + * + * The value of \p offset is an offset in bytes from the beginning of + * the HDF5 file, identifying a user-determined location within the + * HDF5 file. + * The file handle the user application is seeking is for the specific + * member-file in the associated family of files to which this offset + * is mapped. + * + * Use of this function is only appropriate for an HDF5 file written as + * a family of files with the \c FAMILY file driver. + * + * \since 1.6.0 + * + */ +H5_DLL herr_t H5Pset_family_offset(hid_t fapl_id, hsize_t offset); +/** + * \ingroup FAPL + * + * \brief Sets the file close degree + * + * \fapl_id + * \param[in] degree Pointer to a location containing the file close + * degree property, the value of \p degree + * + * \return \herr_t + * + * \details H5Pset_fclose_degree() sets the file close degree property + * \p degree in the file access property list \p fapl_id. + * + * The value of \p degree determines how aggressively + * H5Fclose() deals with objects within a file that remain open + * when H5Fclose() is called to close that file. \p degree can + * have any one of four valid values: + * + * <table> + * <tr> + * <th>Degree name</th> + * <th>H5Fclose behavior with no open object in file</th> + * <th>H5Fclose behavior with open object(s) in file</th> + * </tr> + * <tr> + * <td>#H5F_CLOSE_WEAK</td> + * <td>Actual file is closed.</td> + * <td>Access to file identifier is terminated; actual file + * close is delayed until all objects in file are closed + * </td> + * </tr> + * <tr> + * <td>#H5F_CLOSE_SEMI</td> + * <td>Actual file is closed.</td> + * <td>Function returns FAILURE</td> + * </tr> + * <tr> + * <td>#H5F_CLOSE_STRONG</td> + * <td>Actual file is closed.</td> + * <td>All open objects remaining in the file are closed then + * file is closed</td> + * </tr> + * <tr> + * <td>#H5F_CLOSE_DEFAULT</td> + * <td>The VFL driver chooses the behavior. Currently, all VFL + * drivers set this value to #H5F_CLOSE_WEAK, except for the + * MPI-I/O driver, which sets it to #H5F_CLOSE_SEMI.</td> + * <td></td> + * </tr> + * + * </table> + * \warning If a file is opened multiple times without being closed, each + * open operation must use the same file close degree setting. + * For example, if a file is already open with #H5F_CLOSE_WEAK, + * an H5Fopen() call with #H5F_CLOSE_STRONG will fail. + * + * \since 1.6.0 + * + */ +H5_DLL herr_t H5Pset_fclose_degree(hid_t fapl_id, H5F_close_degree_t degree); +/** + * \ingroup FAPL + * + * \brief Sets an initial file image in a memory buffer + * + * \fapl_id + * \param[in] buf_ptr Pointer to the initial file image, or + * NULL if no initial file image is desired + * \param[in] buf_len Size of the supplied buffer, or + * 0 (zero) if no initial image is desired + * + * \return \herr_t + * + * \details H5Pset_file_image() allows an application to provide a file image + * to be used as the initial contents of a file. + * Calling H5Pset_file_image()makes a copy of the buffer specified in + * \p buf_ptr of size \p buf_len. + * + * \par Motivation: + * H5Pset_file_image() and other elements of HDF5 are + * used to load an image of an HDF5 file into system memory and open + * that image as a regular HDF5 file. An application can then use the + * file without the overhead of disk I/O. + * + * \par Recommended Reading: + * This function is part of the file image + * operations feature set. It is highly recommended to study the guide + * [<em>HDF5 File Image Operations</em>] + * (https://portal.hdfgroup.org/display/HDF5/HDF5+File+Image+Operations + * ) before using this feature set. See the “See Also” section below + * for links to other elements of HDF5 file image operations. + * + * \see + * \li H5LTopen_file_image() + * \li H5Fget_file_image() + * \li H5Pget_file_image() + * \li H5Pset_file_image_callbacks() + * \li H5Pget_file_image_callbacks() + * + * \li [HDF5 File Image Operations] + * (https://portal.hdfgroup.org/display/HDF5/HDF5+File+Image+Operations) + * in [Advanced Topics in HDF5] + * (https://portal.hdfgroup.org/display/HDF5/Advanced+Topics+in+HDF5) + * + * \li Within H5Pset_file_image_callbacks(): + * \li Callback #H5FD_file_image_callbacks_t + * \li Callback #H5FD_file_image_op_t + * + * \version 1.8.13 Fortran subroutine added in this release. + * \since 1.8.9 + * + */ +H5_DLL herr_t H5Pset_file_image(hid_t fapl_id, void *buf_ptr, size_t buf_len); +/** + * \ingroup FAPL + * + * \brief Sets the callbacks for working with file images + * + * \note **Motivation:** H5Pset_file_image_callbacks() and other elements + * of HDF5 are used to load an image of an HDF5 file into system + * memory and open that image as a regular HDF5 file. An application + * can then use the file without the overhead of disk I/O.\n + * **Recommended Reading:** This function is part of the file + * image operations feature set. It is highly recommended to study + * the guide [HDF5 File Image Operations] + * (https://portal.hdfgroup.org/display/HDF5/HDF5+File+Image+Operations + * ) before using this feature set. See the “See Also” section below + * for links to other elements of HDF5 file image operations. + * + * \fapl_id + * \param[in,out] callbacks_ptr Pointer to the instance of the + * #H5FD_file_image_callbacks_t structure + * + * \return \herr_t \n + * **Failure Modes**: Due to interactions between this function and + * H5Pset_file_image() and H5Pget_file_image(), + * H5Pset_file_image_callbacks() will fail if a file image has + * already been set in the target file access property list, \p fapl_id. + * + * \details H5Pset_file_image_callbacks() sets callback functions for working + * with file images in memory. + * + * H5Pset_file_image_callbacks() allows an application to control the + * management of file image buffers through user defined callbacks. + * These callbacks can be used in the management of file image buffers + * in property lists and with certain file drivers. + * + * H5Pset_file_image_callbacks() must be used before any file image has + * been set in the file access property list. Once a file image has + * been set, the function will fail. + * + * The callback routines set up by H5Pset_file_image_callbacks() are + * invoked when a new file image buffer is allocated, when an existing + * file image buffer is copied or resized, or when a file image buffer + * is released from use. + * + * Some file drivers allow the use of user-defined callback functions + * for allocating, freeing, and copying the driver’s internal buffer, + * potentially allowing optimizations such as avoiding large \c malloc + * and \c memcpy operations, or to perform detailed logging. + * + * From the perspective of the HDF5 library, the operations of the + * \ref H5FD_file_image_callbacks_t.image_malloc "image_malloc", + * \ref H5FD_file_image_callbacks_t.image_memcpy "image_memcpy", + * \ref H5FD_file_image_callbacks_t.image_realloc "image_realloc", and + * \ref H5FD_file_image_callbacks_t.image_free "image_free" callbacks + * must be identical to those of the + * corresponding C standard library calls (\c malloc, \c memcpy, + * \c realloc, and \c free). While the operations must be identical, + * the file image callbacks have more parameters. The return values + * of \ref H5FD_file_image_callbacks_t.image_malloc "image_malloc" and + * \ref H5FD_file_image_callbacks_t.image_realloc "image_realloc" are identical to + * the return values of \c malloc and \c realloc. The return values of + * \ref H5FD_file_image_callbacks_t.image_malloc "image_malloc" and + * \ref H5FD_file_image_callbacks_t.image_free "image_free" differ from the return + * values of \c memcpy and \c free in that the return values of + * \ref H5FD_file_image_callbacks_t.image_memcpy "image_memcpy" and + * \ref H5FD_file_image_callbacks_t.image_free "image_free" can also indicate failure. + * + * The callbacks and their parameters, along with a struct and + * an \c ENUM required for their use, are described below. + * + * <b>Callback struct and \c ENUM:</b> + * + * The callback functions set up by H5Pset_file_image_callbacks() use + * a struct and an \c ENUM that are defined as follows + * + * The struct #H5FD_file_image_callbacks_t serves as a container + * for the callback functions and a pointer to user-supplied data. + * The struct is defined as follows: + * \snippet H5FDpublic.h H5FD_file_image_callbacks_t_snip + * + * Elements of the #H5FD_file_image_op_t are used by the + * callbacks to invoke certain operations on file images. The ENUM is + * defined as follows: + * \snippet H5FDpublic.h H5FD_file_image_op_t_snip + * + * The elements of the #H5FD_file_image_op_t are used in the following + * callbacks: + * + * - The \ref H5FD_file_image_callbacks_t.image_malloc "image_malloc" callback + * contains a pointer to a function that must appear to HDF5 to have + * functionality identical to that of the standard C library \c malloc() call. + * + * - Signature in #H5FD_file_image_callbacks_t: + * \snippet H5FDpublic.h image_malloc_snip + * \n + * - The \ref H5FD_file_image_callbacks_t.image_memcpy "image_memcpy" + * callback contains a pointer to a function + * that must appear to HDF5 to have functionality identical to that + * of the standard C library \c memcopy() call, except that it returns + * a \p NULL on failure. (The \c memcpy C Library routine is defined + * to return the \p dest parameter in all cases.) + * + * - Setting \ref H5FD_file_image_callbacks_t.image_memcpy "image_memcpy" + * to \c NULL indicates that HDF5 should invoke + * the standard C library \c memcpy() routine when copying buffers. + * + * - Signature in #H5FD_file_image_callbacks_t: + * \snippet H5FDpublic.h image_memcpy_snip + * \n + * - The \ref H5FD_file_image_callbacks_t.image_realloc "image_realloc" callback + * contains a pointer to a function that must appear to HDF5 to have + * functionality identical to that of the standard C library \c realloc() call. + * + * - Setting \ref H5FD_file_image_callbacks_t.image_realloc "image_realloc" + * to \p NULL indicates that HDF5 should + * invoke the standard C library \c realloc() routine when resizing + * file image buffers. + * + * - Signature in #H5FD_file_image_callbacks_t: + * \snippet H5FDpublic.h image_realloc_snip + * \n + * - The \ref H5FD_file_image_callbacks_t.image_free "image_free" callback contains + * a pointer to a function that must appear to HDF5 to have functionality + * identical to that of the standard C library \c free() call, except + * that it will return \c 0 (\c SUCCEED) on success and \c -1 (\c FAIL) on failure. + * + * - Setting \ref H5FD_file_image_callbacks_t.image_free "image_free" + * to \c NULL indicates that HDF5 should invoke + * the standard C library \c free() routine when releasing file image + * buffers. + * + * - Signature in #H5FD_file_image_callbacks_t: + * \snippet H5FDpublic.h image_free_snip + * \n + * - The \ref H5FD_file_image_callbacks_t.udata_copy "udata_copy" + * callback contains a pointer to a function + * that, from the perspective of HDF5, allocates a buffer of suitable + * size, copies the contents of the supplied \p udata into the new + * buffer, and returns the address of the new buffer. The function + * returns NULL on failure. This function is necessary if a non-NULL + * \p udata parameter is supplied, so that property lists containing + * the image callbacks can be copied. If the \p udata parameter below + * is \c NULL, then this parameter should be \c NULL as well. + * + * - Signature in #H5FD_file_image_callbacks_t: + * \snippet H5FDpublic.h udata_copy_snip + * \n + * - The \ref H5FD_file_image_callbacks_t.udata_free "udata_free" + * callback contains a pointer to a function + * that, from the perspective of HDF5, frees a user data block. This + * function is necessary if a non-NULL udata parameter is supplied so + * that property lists containing image callbacks can be discarded + * without a memory leak. If the udata parameter below is \c NULL, + * this parameter should be \c NULL as well. + * + * - Signature in #H5FD_file_image_callbacks_t: + * \snippet H5FDpublic.h udata_free_snip + * + * - \p **udata**, the final field in the #H5FD_file_image_callbacks_t + * struct, provides a pointer to user-defined data. This pointer will + * be passed to the + * \ref H5FD_file_image_callbacks_t.image_malloc "image_malloc", + * \ref H5FD_file_image_callbacks_t.image_memcpy "image_memcpy", + * \ref H5FD_file_image_callbacks_t.image_realloc "image_realloc", and + * \ref H5FD_file_image_callbacks_t.image_free "image_free" callbacks. + * Define udata as \c NULL if no user-defined data is provided. + * + * \since 1.8.9 + * + */ +H5_DLL herr_t H5Pset_file_image_callbacks(hid_t fapl_id, H5FD_file_image_callbacks_t *callbacks_ptr); +/** + * \ingroup FAPL + * + * \brief Sets the file locking property values + * + * \fapl_id + * \param[in] use_file_locking Toggle to specify file locking (or not) + * \param[in] ignore_when_disabled Toggle to ignore when disabled (or not) + * + * \return \herr_t + * + * \details H5Pset_file_locking() overrides the default file locking flag + * setting that was set when the library was configured. + * + * This setting can be overridden by the \c HDF5_USE_FILE_LOCKING + * environment variable. + * + * File locking is used when creating/opening a file to prevent + * problematic file accesses. + * + * \since 1.10.7 + * + */ +H5_DLL herr_t H5Pset_file_locking(hid_t fapl_id, hbool_t use_file_locking, hbool_t ignore_when_disabled); +/** + * \ingroup FAPL + * + * \brief Sets garbage collecting references flag + * + * \fapl_id + * \param[in] gc_ref Flag setting reference garbage collection to on (1) or off (0) + * + * \return \herr_t + * + * \details H5Pset_gc_references() sets the flag for garbage collecting + * references for the file. + * + * Dataset region references and other reference types use space in an + * HDF5 file's global heap. If garbage collection is on and the user + * passes in an uninitialized value in a reference structure, the heap + * might get corrupted. When garbage collection is off, however, and + * the user re-uses a reference, the previous heap block will be + * orphaned and not returned to the free heap space. + * + * When garbage collection is on, the user must initialize the + * reference structures to 0 or risk heap corruption. + * + * The default value for garbage collecting references is off. + * + */ +H5_DLL herr_t H5Pset_gc_references(hid_t fapl_id, unsigned gc_ref); +/** + * \ingroup FAPL + * + * \brief Controls the range of library release versions used when creating + * objects in a file + * + * \fapl_id{plist_id} + * \param[in] low The earliest version of the library that will be used + * for writing objects + * \param[in] high The latest version of the library that will be used for + * writing objects + * + * \return \herr_t + * + * \details H5Pset_libver_bounds() controls the range of library release + * versions that will be used when creating objects in a file. + * The object format versions are determined indirectly from the + * library release versions specified in the call. + * + * This property is set in the file access property list + * specified by the parameter \p fapl_id. + * + * The parameter \p low sets the earliest possible format + * versions that the library will use when creating objects in + * the file. Note that earliest possible is different from + * earliest, as some features introduced in library versions + * later than 1.0.0 resulted in updates to object formats. + * The parameter \p high sets the latest format versions that + * the library will be allowed to use when creating objects in + * the file. + * + * The parameters \p low and \p high must be one of the + * enumerated values in the #H5F_libver_t struct, which is + * defined in H5Fpublic.h. + * + * The macro #H5F_LIBVER_LATEST is aliased to the highest + * enumerated value in #H5F_libver_t, indicating that this is + * currently the latest format available. + * + * The library supports the following five pairs of + * (\p low, \p high) combinations as derived from the values + * in #H5F_libver_t: + * + * <table> + * <tr> + * <th>Value of \p low and \p high</th> + * <th>Result</th> + * </tr> + * <tr> + * <td>\p low=#H5F_LIBVER_EARLIEST<br /> + * \p high=#H5F_LIBVER_V18</td> + * <td> + * \li The library will create objects with the earliest + * possible format versions. + * \li The library will allow objects to be created with the + * latest format versions available to library release 1.8.x. + * \li API calls that create objects or features that are + * available to versions of the library greater than 1.8.x + * release will fail. + * </td> + * </tr> + * <tr> + * <td>\p low=#H5F_LIBVER_EARLIEST<br /> + * \p high=#H5F_LIBVER_V110</td> + * <td> + * \li The library will create objects with the earliest possible + * format versions. + * \li The library will allow objects to be created with the latest + * format versions available to library release 1.10.x. + * Since 1.10.x is also #H5F_LIBVER_LATEST, there is no upper + * limit on the format versions to use. For example, if a newer + * format version is required to support a feature e.g. virtual + * dataset, this setting will allow the object to be created. + * \li This is the library default setting and provides the greatest + * format compatibility. + * </td> + * </tr> + * <tr> + * <td>\p low=#H5F_LIBVER_V18<br /> + * \p high=#H5F_LIBVER_V18</td> + * <td> + * \li The library will create objects with the latest format + * versions available to library release 1.8.x. + * \li API calls that create objects or features that are available + * to versions of the library greater than 1.8.x release will + * fail. + * \li Earlier versions of the library may not be able to access + * objects created with this setting.</td> + * </tr> + * <tr> + * <td>\p low=#H5F_LIBVER_V18<br /> + * \p high=#H5F_LIBVER_V110</td> + * <td> + * \li The library will create objects with the latest format + * versions available to library release 1.8.x. + * \li The library will allow objects to be created with the latest + * format versions available to library release 1.10.x. + * Since 1.10.x is also #H5F_LIBVER_LATEST, there is no upper + * limit on the format versions to use. For example, if a + * newer format version is required to support a feature e.g. + * virtual dataset, this setting will allow the object to be + * created. + * \li Earlier versions of the library may not be able to access + * objects created with this setting.</td> + * </tr> + * <tr> + * <td>\p low=#H5F_LIBVER_V110<br /> + * \p high=#H5F_LIBVER_V110 + * </td> + * <td> + * \li The library will create objects with the latest format + * versions available to library release 1.10.x. + * \li The library will allow objects to be created with the latest + * format versions available to library release 1.10.x. + * Since 1.10.x is also #H5F_LIBVER_LATEST, there is no upper + * limit on the format versions to use. For example, if a + * newer format version is required to support a feature e.g. + * virtual dataset, this setting will allow the object to be + * created. + * \li This setting allows users to take advantage of the latest + * features and performance enhancements in the library. + * However, objects written with this setting may be + * accessible to a smaller range of library versions than + * would be the case if low is set to #H5F_LIBVER_EARLIEST. + * \li Earlier versions of the library may not be able to access + * objects created with this + * setting. + * </td> + * </tr> + * </table> + * + * \version 1.10.2 #H5F_LIBVER_V18 added to the enumerated defines in + * #H5F_libver_t. + * + * \since 1.8.0 + * + */ +H5_DLL herr_t H5Pset_libver_bounds(hid_t plist_id, H5F_libver_t low, H5F_libver_t high); +/** + * \ingroup FAPL + * + * \brief Set the initial metadata cache configuration in the indicated File + * Access Property List to the supplied value + * + * \fapl_id{plist_id} + * \param[in] config_ptr Pointer to the instance of \p H5AC_cache_config_t + * containing the desired configuration + * \return \herr_t + * + * \details The fields of the #H5AC_cache_config_t structure are shown + * below: + * \snippet H5ACpublic.h H5AC_cache_config_t_snip + * \click4more + * + * \details H5Pset_mdc_config() attempts to set the initial metadata cache + * configuration to the supplied value. It will fail if an invalid + * configuration is detected. This configuration is used when the file + * is opened. + * + * See the overview of the metadata cache in the special topics section + * of the user manual for details on what is being configured. If you + * have not read and understood that documentation, you really should + * not be using this API call. + * + * \since 1.8.0 + * + */ +H5_DLL herr_t H5Pset_mdc_config(hid_t plist_id, H5AC_cache_config_t *config_ptr); +/** + * \ingroup FAPL + * + * \brief Sets metadata cache logging options + * + * \fapl_id{plist_id} + * \param[in] is_enabled Whether logging is enabled + * \param[in] location Location of log in UTF-8/ASCII (file path/name) + * (On Windows, this must be ASCII) + * \param[in] start_on_access Whether the logging will begin as soon as the + * file is opened or created + * + * \return \herr_t + * + * \details The metadata cache is a central part of the HDF5 library through + * which all file metadata reads and writes take place. File metadata + * is normally invisible to the user and is used by the library for + * purposes such as locating and indexing data. File metadata should + * not be confused with user metadata, which consists of attributes + * created by users and attached to HDF5 objects such as datasets via + * H5A API calls. + * + * Due to the complexity of the cache, a trace/logging feature has + * been created that can be used by HDF5 developers for debugging and + * performance analysis. The functions that control this functionality + * will normally be of use to a very limited number of developers + * outside of The HDF Group. The functions have been documented to + * help users create logs that can be sent with bug reports. + * + * Control of the log functionality is straightforward. Logging is + * enabled via the H5Pset_mdc_log_options() function, + * which will modify the file access property list used to open or + * create a file. This function has a flag that determines whether + * logging begins at file open or starts in a paused state. Log + * messages can then be controlled via the H5Fstart_mdc_logging() + * and H5Fstop_mdc_logging() function. + * + * H5Pget_mdc_log_options() can be used to examine a file access + * property list, and H5Fget_mdc_logging_status() will return the + * current state of the logging flags. + * + * The log format is described in [<em>Metadata Cache Logging</em>] + * (https://portal.hdfgroup.org/display/HDF5/Fine-tuning+the+Metadata+Cache). + * + * \since 1.10.0 + * + */ H5_DLL herr_t H5Pset_mdc_log_options(hid_t plist_id, hbool_t is_enabled, const char *location, hbool_t start_on_access); -H5_DLL herr_t H5Pget_mdc_log_options(hid_t plist_id, hbool_t *is_enabled, char *location, - size_t *location_size, hbool_t *start_on_access); -H5_DLL herr_t H5Pset_evict_on_close(hid_t fapl_id, hbool_t evict_on_close); -H5_DLL herr_t H5Pget_evict_on_close(hid_t fapl_id, hbool_t *evict_on_close); +/** + * \ingroup FAPL + * + * \brief Sets the minimum metadata block size + * + * \fapl_id{fapl_id} + * \param[in] size Minimum size, in bytes, of metadata block allocations + * + * \return \herr_t + * + * \details H5Pset_meta_block_size() sets the minimum size, in bytes, of + * metadata block allocations when #H5FD_FEAT_AGGREGATE_METADATA is set by a VFL + * driver. + + * Each raw metadata block is initially allocated to be of the given size. + * Specific metadata objects (e.g., object headers, local heaps, B-trees) are then + * sub-allocated from this block. + * + * The default setting is 2048 bytes, meaning that the library will + * attempt to aggregate metadata in at least 2K blocks in the file. + * Setting the value to zero (\Code{0}) with this function will turn + * off metadata aggregation, even if the VFL driver attempts to use the + * metadata aggregation strategy. + * + * Metadata aggregation reduces the number of small data objects in the file that + * would otherwise be required for metadata. The aggregated block of metadata is + * usually written in a single write action and always in a contiguous block, + * potentially significantly improving library and application performance. + * + * \since 1.4.0 + */ +H5_DLL herr_t H5Pset_meta_block_size(hid_t fapl_id, hsize_t size); +/** + * \ingroup FAPL + * + * \brief Sets the number of read attempts in a file access property list + * + * \fapl_id{plist_id} + * \param[in] attempts The number of read attempts. Must be a value greater than \Code{0} + * + * \return \herr_t + * + * \return Failure Modes: + * - When the user sets the number of read attempts to \Code{0}. + * - When the input property list is not a file access property list. + * - When the library is unable to set the number of read attempts in the file access property list. + * + * \details H5Pset_metadata_read_attempts() sets the number of reads that the + * library will try when reading checksummed metadata in an HDF5 file opened + * with SWMR access. When reading such metadata, the library will compare the + * checksum computed for the metadata just read with the checksum stored within + * the piece of checksum. When performing SWMR operations on a file, the + * checksum check might fail when the library reads data on a system that is not + * atomic. To remedy such situations, the library will repeatedly read the piece + * of metadata until the check passes or finally fails the read when the allowed + * number of attempts is reached. + * + * The number of read attempts used by the library will depend on how the file is + * opened and whether the user sets the number of read attempts via this routine: + + * - For a file opened with SWMR access: + * - If the user sets the number of attempts to \Code{N}, the library will use \Code{N}. + * - If the user does not set the number of attempts, the library will use the + * default for SWMR access (\Code{100}). + * - For a file opened with non-SWMR access, the library will always use the default + * for non-SWMR access (\Code{1}). The value set via this routine does not have any effect + * during non-SWMR access. + * + * \b Example: The first example illustrates the case in setting the number of read attempts for a file + * opened with SWMR access. + * + * \snippet H5Pset_metadata_read_attempts.c SWMR Access + * + * \b Example: The second example illustrates the case in setting the number of + * read attempts for a file opened with non-SWMR access. The value + * set in the file access property list does not have any effect. + * + * \snippet H5Pset_metadata_read_attempts.c non-SWMR Access + * + * \note \b Motivation: On a system that is not atomic, the library might + * possibly read inconsistent metadata with checksum when performing + * single-writer/multiple-reader (SWMR) operations for an HDF5 file. Upon + * encountering such situations, the library will try reading the metadata + * again to obtain consistent data. This routine provides the means to set + * the number of read attempts other than the library default. + * + * \since 1.10.0 + */ +H5_DLL herr_t H5Pset_metadata_read_attempts(hid_t plist_id, unsigned attempts); +/** + * \ingroup FAPL + * + * \brief Specifies type of data to be accessed via the \Code{MULTI} driver, + * enabling more direct access + * + * \fapl_id{fapl_id} + * \param[in] type Type of data to be accessed + * + * \return \herr_t + * + * \details H5Pset_multi_type() sets the \Emph{type of data} property in the file + * access property list \p fapl_id. This setting enables a user + * application to specify the type of data the application wishes to + * access so that the application can retrieve a file handle for + * low-level access to the particular member of a set of \Code{MULTI} + * files in which that type of data is stored. The file handle is + * retrieved with a separate call to H5Fget_vfd_handle() (or, in special + * circumstances, to H5FDget_vfd_handle(); see \ref VFL. + * + * The type of data specified in \p type may be one of the following: + * + * <table> + * <tr> + * <td>#H5FD_MEM_SUPER</td> <td>Super block data</td> + * </tr> + * <tr> + * <td>#H5FD_MEM_BTREE</td> <td>B-tree data</td> + * </tr> + * <tr> + * <td>#H5FD_MEM_DRAW</td> <td>Dataset raw data</td> + * </tr> + * <tr> + * <td>#H5FD_MEM_GHEAP</td> <td>Global heap data</td> + * </tr> + * <tr> + * <td>#H5FD_MEM_LHEAP</td> <td>Local Heap data</td> + * </tr> + * <tr> + * <td>#H5FD_MEM_OHDR</td> <td>Object header data</td> + * </tr> + * </table> + * + * This function is for use only when accessing an HDF5 file written as a set of + * files with the \Code{MULTI} file driver. + * + * \since 1.6.0 + */ +H5_DLL herr_t H5Pset_multi_type(hid_t fapl_id, H5FD_mem_t type); +/** + * \ingroup FAPL + * + * \brief Sets a callback function to invoke when an object flush occurs in the file + * + * \fapl_id{plist_id} + * \op{func} + * \op_data_in{udata} + * + * \return \herr_t + * + * \details H5Pset_object_flush_cb() sets the callback function to invoke in the + * file access property list \p plist_id whenever an object flush occurs in + * the file. Library objects are group, dataset, and committed + * datatype. + * + * The callback function \p func must conform to the prototype defined below: + * \code + * typedef herr_t (*H5F_flush_cb_t)(hid_t object_id, void *user_data) + * \endcode + * + * The parameters of the callback function, per the above prototypes, are defined as follows: + * - \Code{object_id} is the identifier of the object which has just been flushed. + * - \Code{user_data} is the user-defined input data for the callback function. + * + * \b Example: The example below illustrates the usage of this routine to set + * the callback function to invoke when an object flush occurs. + * + * \include H5Pset_object_flush_cb.c + * + * \since 1.10.0 + */ +H5_DLL herr_t H5Pset_object_flush_cb(hid_t plist_id, H5F_flush_cb_t func, void *udata); +/** + * \ingroup FAPL + * + * \brief Sets the maximum size of the data sieve buffer + * + * \fapl_id{fapl_id} + * \param[in] size Maximum size, in bytes, of data sieve buffer + * + * \return \herr_t + * + * \details H5Pset_sieve_buf_size() sets \p size, the maximum size in bytes of the + * data sieve buffer, which is used by file drivers that are capable of + * using data sieving. + * + * The data sieve buffer is used when performing I/O on datasets in the + * file. Using a buffer which is large enough to hold several pieces of + * the dataset being read in for hyperslab selections boosts + * performance by quite a bit. + * + * The default value is set to 64KB, indicating that file I/O for raw + * data reads and writes will occur in at least 64KB blocks. Setting + * the value to zero (\Code{0}) with this API function will turn off + * the data sieving, even if the VFL driver attempts to use that + * strategy. + * + * Internally, the library checks the storage sizes of the datasets in + * the file. It picks the smaller one between the size from the file + * access property and the size of the dataset to allocate the sieve + * buffer for the dataset in order to save memory usage. + * + * \version 1.6.0 The \p size parameter has changed from type \Code{hsize_t} to \Code{size_t}. + * + * \since 1.4.0 + */ +H5_DLL herr_t H5Pset_sieve_buf_size(hid_t fapl_id, size_t size); +/** + * \ingroup FAPL + * + * \brief Sets the size of a contiguous block reserved for small data + * + * \fapl_id{fapl_id} + * \param[in] size Maximum size, in bytes, of the small data block. + The default size is \Code{2048}. + * + * \return \herr_t + * + * \details H5Pset_small_data_block_size() reserves blocks of \p size bytes for the + * contiguous storage of the raw data portion of \Emph{small} datasets. The + * HDF5 library then writes the raw data from small datasets to this + * reserved space, thus reducing unnecessary discontinuities within + * blocks of meta data and improving I/O performance. + * + * A small data block is actually allocated the first time a qualifying + * small dataset is written to the file. Space for the raw data portion + * of this small dataset is suballocated within the small data block. + * The raw data from each subsequent small dataset is also written to + * the small data block until it is filled; additional small data + * blocks are allocated as required. + * + * The HDF5 library employs an algorithm that determines whether I/O + * performance is likely to benefit from the use of this mechanism with + * each dataset as storage space is allocated in the file. A larger + * \p size will result in this mechanism being employed with larger + * datasets. + * + * The small data block size is set as an allocation property in the + * file access property list identified by \p fapl_id. + * + * Setting \p size to zero (\Code{0}) disables the small data block mechanism. + * + * \since 1.4.4 + */ +H5_DLL herr_t H5Pset_small_data_block_size(hid_t fapl_id, hsize_t size); +/** + * \ingroup FAPL + * + * \brief Set the file VOL connector for a file access property list + * + * \fapl_id{plist_id} + * \param[in] new_vol_id VOL connector identifier + * \param[in] new_vol_info Optional VOL information + * + * \return \herr_t + * + * \details H5Pset_vol() sets the VOL connector \p new_vol_id for a file access + * property list \p plist_id using the (optional) VOL information in + * \p new_vol_info. + * + * \since 1.12.0 + * + */ +H5_DLL herr_t H5Pset_vol(hid_t plist_id, hid_t new_vol_id, const void *new_vol_info); + #ifdef H5_HAVE_PARALLEL +/** + * \ingroup GACPL + * + * \brief Sets metadata I/O mode for read operations to collective or independent (default) + * + * \gacpl_id + * \param[in] is_collective Boolean value indicating whether metadata reads are collective + * (\Code{1}) or independent (\Code{0}). + * Default mode: Independent (\Code{0}) + * + * \return \herr_t + * + * \details H5Pset_all_coll_metadata_ops() sets the metadata I/O mode for read + * operations in the access property list \p plist_id. + * + * When engaging in parallel I/O, all metadata write operations must be + * collective. If \p is_collective is \Code{1}, this property specifies + * that the HDF5 library will perform all metadata read operations + * collectively; if \p is_collective is \Code{0}, such operations may + * be performed independently. + * + * Users must be aware that several HDF5 operations can potentially + * issue metadata reads. These include opening a dataset, datatype, or + * group; reading an attribute; or issuing a \Emph{get info} call such + * as getting information for a group with H5Fget_info(). Collective + * I/O requirements must be kept in mind when issuing such calls in the + * context of parallel I/O. + * + * If this property is collective on a file access property list that + * is used in creating or opening a file, then the HDF5 library will + * assume that all metadata read operations issued on that file + * identifier will be issued collectively from all ranks irrespective + * of the individual setting of a particular operation. If this + * assumption is not adhered to, corruption will be introduced in the + * metadata cache and HDF5’s behavior will be undefined. + * + * Alternatively, a user may wish to avoid setting this property + * globally on the file access property list, and individually set it + * on particular object access property lists (dataset, group, link, + * datatype, attribute access property lists) for certain operations. + * This will indicate that only the operations issued with such an + * access property list will be called collectively and other + * operations may potentially be called independently. There are, + * however, several HDF5 operations that can issue metadata reads but + * have no property list in their function signatures to allow passing + * the collective requirement property. For those operations, the only + * option is to set the global collective requirement property on the + * file access property list; otherwise the metadata reads that can be + * triggered from those operations will be done independently by each + * process. + * + * Functions that do not accommodate an access property list but that + * might issue metadata reads are listed in \ref maybe_metadata_reads. + * + * \attention As noted above, corruption will be introduced into the metadata + * cache and HDF5 library behavior will be undefined when both of the following + * conditions exist: + * - A file is created or opened with a file access property list in which the + * collective metadata I/O property is set to \Code{1}. + * - Any function is called that triggers an independent metadata read while the + * file remains open with that file access property list. + * + * \attention An approach that avoids this corruption risk is described above. + * + * \sa_metadata_ops + * + * \since 1.10.0 + */ H5_DLL herr_t H5Pset_all_coll_metadata_ops(hid_t plist_id, hbool_t is_collective); +/** + * \ingroup GACPL + * + * \brief Retrieves metadata read mode setting + * + * \gacpl_id + * \param[out] is_collective Pointer to a buffer containing the Boolean value indicating whether metadata + * reads are collective (\Code{>0}) or independent (\Code{0}). + * Default mode: Independent (\Code{0}) + * + * \return \herr_t + * + * \details H5Pget_all_coll_metadata_ops() retrieves the collective metadata read setting from the access + * property list \p plist_id into \p is_collective. + * + * \sa_metadata_ops + * + * \since 1.10.0 + */ H5_DLL herr_t H5Pget_all_coll_metadata_ops(hid_t plist_id, hbool_t *is_collective); +/** + * \ingroup FAPL + * + * \brief Sets metadata write mode to collective or independent (default) + * + * \fapl_id{plist_id} + * \param[out] is_collective Boolean value indicating whether metadata + * writes are collective (\Code{>0}) or independent (\Code{0}). + * \Emph{Default mode:} Independent (\Code{0}) + * \return \herr_t + * + * \details H5Pset_coll_metadata_write() tells the HDF5 library whether to + * perform metadata writes collectively (1) or independently (0). + * + * If collective access is selected, then on a flush of the metadata + * cache, all processes will divide the metadata cache entries to be + * flushed evenly among themselves and issue a single MPI-IO collective + * write operation. This is the preferred method when the size of the + * metadata created by the application is large. + * + * If independent access is selected, the library uses the default + * method for doing metadata I/O either from process zero or + * independently from each process. + * + * \sa_metadata_ops + * + * \since 1.10.0 + */ H5_DLL herr_t H5Pset_coll_metadata_write(hid_t plist_id, hbool_t is_collective); +/** + * \ingroup FAPL + * + * \brief Retrieves metadata write mode setting + * + * \fapl_id{plist_id} + * \param[out] is_collective Pointer to a boolean value indicating whether + * metadata writes are collective (\Code{>0}) or independent (\Code{0}). + * \Emph{Default mode:} Independent (\Code{0}) + * \return \herr_t + * + * \details H5Pget_coll_metadata_write() retrieves the collective metadata write + * setting from the file access property into \p is_collective. + * + * \sa_metadata_ops + * + * \since 1.10.0 + */ H5_DLL herr_t H5Pget_coll_metadata_write(hid_t plist_id, hbool_t *is_collective); + +/** + * \todo Add missing documentation + */ H5_DLL herr_t H5Pget_mpi_params(hid_t fapl_id, MPI_Comm *comm, MPI_Info *info); + +/** + * \todo Add missing documentation + */ H5_DLL herr_t H5Pset_mpi_params(hid_t fapl_id, MPI_Comm comm, MPI_Info info); #endif /* H5_HAVE_PARALLEL */ +/** + * \ingroup FAPL + * + * \brief Sets the metadata cache image option for a file access property list + * + * \fapl_id{plist_id} + * \param[out] config_ptr Pointer to metadata cache image configuration values + * \return \herr_t + * + * \details H5Pset_mdc_image_config() sets the metadata cache image option with + * configuration values specified by \p config_ptr for the file access + * property list specified in \p plist_id. + * + * #H5AC_cache_image_config_t is defined as follows: + * \snippet H5ACpublic.h H5AC_cache_image_config_t_snip + * \click4more + * + * \par Limitations: While it is an obvious error to request a cache image when + * opening the file read only, it is not in general possible to test for + * this error in the H5Pset_mdc_image_config() call. Rather than fail the + * subsequent file open, the library silently ignores the file image + * request in this case.\n It is also an error to request a cache image on + * a file that does not support superblock extension messages (i.e. a + * superblock version less than 2). As above, it is not always possible to + * detect this error in the H5Pset_mdc_image_config() call, and thus the + * request for a cache image will fail silently in this case as well.\n + * Creation of cache images is currently disabled in parallel -- as above, + * any request for a cache image in this context will fail silently.\n + * Files with cache images may be read in parallel applications, but note + * that the load of the cache image is a collective operation triggered by + * the first operation that accesses metadata after file open (or, if + * persistent free space managers are enabled, on the first allocation or + * deallocation of file space, or read of file space manager status, + * whichever comes first). Thus the parallel process may deadlock if any + * process does not participate in this access.\n + * In long sequences of file closes and opens, infrequently accessed + * metadata can accumulate in the cache image to the point where the cost + * of storing and restoring this metadata exceeds the benefit of retaining + * frequently used metadata in the cache image. When implemented, the + * #H5AC_cache_image_config_t::entry_ageout should address this problem. In + * the interim, not requesting a cache image every n file close/open cycles + * may be an acceptable work around. The choice of \c n will be driven by + * application behavior, but \Code{n = 10} seems a good starting point. + * + * \since 1.10.1 + */ H5_DLL herr_t H5Pset_mdc_image_config(hid_t plist_id, H5AC_cache_image_config_t *config_ptr); -H5_DLL herr_t H5Pget_mdc_image_config(hid_t plist_id, H5AC_cache_image_config_t *config_ptr /*out*/); +/** + * \ingroup FAPL + * + * \brief Sets the maximum size for the page buffer and the minimum percentage + * for metadata and raw data pages + * + * \fapl_id{plist_id} + * \param[in] buf_size Maximum size, in bytes, of the page buffer + * \param[in] min_meta_per Minimum metadata percentage to keep in the page buffer + * before allowing pages containing metadata to be evicted (Default is 0) + * \param[in] min_raw_per Minimum raw data percentage to keep in the page buffer + * before allowing pages containing raw data to be evicted (Default is 0) + * \return \herr_t + * + * \details H5Pset_page_buffer_size() sets buf_size, the maximum size in bytes + * of the page buffer. The default value is zero, meaning that page + * buffering is disabled. When a non-zero page buffer size is set, the + * library will enable page buffering if that size is larger or equal + * than a single page size if a paged file space strategy is enabled + * using the functions H5Pset_file_space_strategy() and + * H5Pset_file_space_page_size(). + * + * The page buffer layer captures all I/O requests before they are + * issued to the VFD and "caches" them in fixed sized pages. Once the + * total number of pages exceeds the page buffer size, the library + * evicts pages from the page buffer by writing them to the VFD. At + * file close, the page buffer is flushed writing all the pages to the + * file. + * + * If a non-zero page buffer size is set, and the file space strategy + * is not set to paged or the page size for the file space strategy is + * larger than the page buffer size, the subsequent call to H5Fcreate() + * or H5Fopen() using the \p plist_id will fail. + * + * The function also allows setting the minimum percentage of pages for + * metadata and raw data to prevent a certain type of data to evict hot + * data of the other type. + * + * \since 1.10.1 + * + */ H5_DLL herr_t H5Pset_page_buffer_size(hid_t plist_id, size_t buf_size, unsigned min_meta_per, unsigned min_raw_per); -H5_DLL herr_t H5Pget_page_buffer_size(hid_t plist_id, size_t *buf_size, unsigned *min_meta_per, - unsigned *min_raw_per); -/* VFD SWMR configuration */ +/** + * \todo Add missing documentation + */ H5_DLL herr_t H5Pset_vfd_swmr_config(hid_t plist_id, H5F_vfd_swmr_config_t *config_ptr); -H5_DLL herr_t H5Pget_vfd_swmr_config(hid_t plist_id, H5F_vfd_swmr_config_t *config_ptr); /* Dataset creation property list (DCPL) routines */ -H5_DLL herr_t H5Pset_layout(hid_t plist_id, H5D_layout_t layout); +/** + * \ingroup DCPL + * + * \brief Determines whether fill value is defined + * + * \dcpl_id{plist} + * \param[out] status Status of fill value in property list + * + * \return \herr_t + * + * \details H5Pfill_value_defined() determines whether a fill value is + * defined in the dataset creation property list \p plist. Valid + * values returned in status are as follows: + * + * <table> + * <tr> + * <td>#H5D_FILL_VALUE_UNDEFINED</td> + * <td>Fill value is undefined.</td> + * </tr> + * <tr> + * <td>#H5D_FILL_VALUE_DEFAULT</td> + * <td>Fill value is the library default.</td> + * </tr> + * <tr> + * <td>#H5D_FILL_VALUE_USER_DEFINED</td> + * <td>Fill value is defined by the application.</td> + * </tr> + * </table> + * + * \since 1.6.0 + * + */ +H5_DLL herr_t H5Pfill_value_defined(hid_t plist, H5D_fill_value_t *status); +/** + * \ingroup DCPL + * + * \brief Retrieves the timing for storage space allocation + * + * \dcpl_id{plist_id} + * \param[out] alloc_time The timing setting for allocating dataset + * storage space + * + * \return \herr_t + * + * \details H5Pget_alloc_time() retrieves the timing for allocating storage + * space for a dataset's raw data. This property is set in the + * dataset creation property list \p plist_id. The timing setting + * is returned in \p alloc_time as one of the following values: + * + * <table> + * <tr> + * <td>#H5D_ALLOC_TIME_DEFAULT<br /> </td> + * <td>Uses the default allocation time, based on the dataset + * storage method. <br />See the \p alloc_time description in + * H5Pset_alloc_time() for default allocation times for + * various storage methods.</td> + * </tr> + * <tr> + * <td>#H5D_ALLOC_TIME_EARLY</td> + * <td>All space is allocated when the dataset is created.</td> + * </tr> + * <tr> + * <td>#H5D_ALLOC_TIME_INCR</td> + * <td>Space is allocated incrementally as data is written + * to the dataset.</td> + * </tr> + * <tr> + * <td>#H5D_ALLOC_TIME_LATE</td> + * <td>All space is allocated when data is first written to + * the dataset.</td> + * </tr> + * </table> + * + * \note H5Pget_alloc_time() is designed to work in concert with the + * dataset fill value and fill value write time properties, set + * with the functions H5Pget_fill_value() and H5Pget_fill_time(). + * + * \since 1.6.0 + * + */ +H5_DLL herr_t H5Pget_alloc_time(hid_t plist_id, H5D_alloc_time_t *alloc_time /*out*/); +/** + * \ingroup DCPL + * + * \brief Retrieves the size of chunks for the raw data of a chunked + * layout dataset + * + * \dcpl_id{plist_id} + * \param[in] max_ndims Size of the \p dims array + * \param[out] dim Array to store the chunk dimensions + * + * \return Returns chunk dimensionality if successful; + * otherwise returns a negative value. + * + * \details H5Pget_chunk() retrieves the size of chunks for the raw data + * of a chunked layout dataset. This function is only valid for + * dataset creation property lists. At most, \p max_ndims elements + * of \p dim will be initialized. + * + * \since 1.0.0 + * + */ +H5_DLL int H5Pget_chunk(hid_t plist_id, int max_ndims, hsize_t dim[] /*out*/); +/** + * + * \ingroup DCPL + * + * \brief Retrieves the edge chunk option setting from a dataset creation + * property list + * + * \dcpl_id{plist_id} + * \param[out] opts Edge chunk option flag. Valid values are described in + * H5Pset_chunk_opts(). The option status can be + * retrieved using the bitwise AND operator ( & ). For + * example, the expression + * (opts&#H5D_CHUNK_DONT_FILTER_PARTIAL_CHUNKS) will + * evaluate to #H5D_CHUNK_DONT_FILTER_PARTIAL_CHUNKS if + * that option has been enabled. Otherwise, it will + * evaluate to 0 (zero). + * + * \return \herr_t + * + * \details H5Pget_chunk_opts() retrieves the edge chunk option setting + * stored in the dataset creation property list \p plist_id. + * + * \since 1.10.0 + * + */ +H5_DLL herr_t H5Pget_chunk_opts(hid_t plist_id, unsigned *opts); +/** + * \ingroup DCPL + * + * \brief Retrieves the setting for whether or not to create minimized + * dataset object headers + * + * \dcpl_id + * \param[out] minimize Flag indicating whether the library will or will + * not create minimized dataset object headers + * + * \return \herr_t + * + * \details H5Pget_dset_no_attrs_hint() retrieves the + * <i>no dataset attributes</i> hint setting for the dataset + * creation property list \p dcpl_id. This setting is used to + * inform the library to create minimized dataset object headers + * when TRUE. The setting value is returned in the boolean pointer + * \p minimize. + * + * \since 1.10.5 + * + */ +H5_DLL herr_t H5Pget_dset_no_attrs_hint(hid_t dcpl_id, hbool_t *minimize); +/** + * \ingroup DCPL + * + * \brief Returns information about an external file + * + * \dcpl_id{plist_id} + * \param[in] idx External file index + * \param[in] name_size Maximum length of \p name array + * \param[out] name Name of the external file + * \param[out] offset Pointer to a location to return an offset value + * \param[out] size Pointer to a location to return the size of the + * external file data + * + * \return \herr_t + * + * \details H5Pget_external() returns information about an external file. + * The external file is specified by its index, \p idx, which + * is a number from zero to N-1, where N is the value returned + * by H5Pget_external_count(). At most \p name_size characters + * are copied into the \p name array. If the external file name + * is longer than \p name_size with the null terminator, the + * return value is not null terminated (similar to strncpy()). + * + * If \p name_size is zero or \p name is the null pointer, the + * external file name is not returned. If \p offset or \p size + * are null pointers then the corresponding information is not + * returned. + * + * \version 1.6.4 \p idx parameter type changed to unsigned. + * \since 1.0.0 + * + */ +H5_DLL herr_t H5Pget_external(hid_t plist_id, unsigned idx, size_t name_size, char *name /*out*/, + off_t *offset /*out*/, hsize_t *size /*out*/); +/** + * \ingroup DCPL + * + * \brief Returns the number of external files for a dataset + * + * \dcpl_id{plist_id} + * + * \return Returns the number of external files if successful; otherwise + * returns a negative value. + * + * \details H5Pget_external_count() returns the number of external files + * for the specified dataset. + * + * \since 1.0.0 + * + */ +H5_DLL int H5Pget_external_count(hid_t plist_id); +/** + * \ingroup DCPL + * + * \brief Retrieves the time when fill values are written to a dataset + * + * \dcpl_id{plist_id} + * \param[out] fill_time Setting for the timing of writing fill values to + * the dataset + * + * \return \herr_t + * + * \details H5Pget_fill_time() examines the dataset creation property list + * \p plist_id to determine when fill values are to be written to + * a dataset. Valid values returned in \p fill_time are as + * follows: + * + * <table> + * <tr> + * <td>#H5D_FILL_TIME_IFSET</td> + * <td>Fill values are written to the dataset when storage + * space is allocated only if there is a user-defined fill + * value, i.e., one set with H5Pset_fill_value(). (Default) + * </td> + * </tr> + * <tr> + * <td>#H5D_FILL_TIME_ALLOC</td> + * <td>Fill values are written to the dataset when storage + * space is allocated.</td> + * </tr> + * <tr> + * <td>#H5D_FILL_TIME_NEVER</td> + * <td>Fill values are never written to the dataset.</td> + * </tr> + * </table> + * + * \note H5Pget_fill_time() is designed to work in coordination with the + * dataset fill value and dataset storage allocation time properties, + * retrieved with the functions H5Pget_fill_value() and + * H5Pget_alloc_time(). + * + * \since 1.6.0 + * + */ +H5_DLL herr_t H5Pget_fill_time(hid_t plist_id, H5D_fill_time_t *fill_time /*out*/); +/** + * \ingroup DCPL + * + * \brief Retrieves a dataset fill value + * + * \dcpl_id{plist_id} + * \param[in] type_id Datatype identifier for the value passed via + * \p value + * \param[out] value Pointer to buffer to contain the returned + * fill value + * + * \return \herr_t + * + * \details H5Pget_fill_value() returns the dataset fill value defined in + * the dataset creation property list \p plist_id. The fill value + * is returned through the \p value pointer and will be converted + * to the datatype specified by \p type_id. This datatype may + * differ from the fill value datatype in the property list, but + * the HDF5 library must be able to convert between the two + * datatypes. + * + * If the fill value is undefined, i.e., set to NULL in the + * property list, H5Pget_fill_value() will return an error. + * H5Pfill_value_defined() should be used to check for this + * condition before H5Pget_fill_value() is called. + * + * Memory must be allocated by the calling application. + * + * \note H5Pget_fill_value() is designed to coordinate with the dataset + * storage allocation time and fill value write time properties, + * which can be retrieved with the functions H5Pget_alloc_time() + * and H5Pget_fill_time(), respectively. + * + * \since 1.0.0 + * + */ +H5_DLL herr_t H5Pget_fill_value(hid_t plist_id, hid_t type_id, void *value /*out*/); +/** + * \ingroup DCPL + * + * \brief Returns the layout of the raw data for a dataset + * + * \dcpl_id{plist_id} + * + * \return Returns the layout type (a non-negative value) of a dataset + * creation property list if successful. Valid return values are: + * - #H5D_COMPACT: Raw data is stored in the object header in the + * file. + * - #H5D_CONTIGUOUS: Raw data is stored separately from the object + * header in one contiguous chunk in the file. + * - #H5D_CHUNKED: Raw data is stored separately from the object + * header in chunks in separate locations in the + * file. + * - #H5D_VIRTUAL: Raw data is drawn from multiple datasets in + * different files. + * \return + * Otherwise, returns a negative value indicating failure. + * + * \details H5Pget_layout() returns the layout of the raw data for a + * dataset. This function is only valid for dataset creation + * property lists. + * + * Note that a compact storage layout may affect writing data to + * the dataset with parallel applications. See the H5Dwrite() + * documentation for details. + * + * \version 1.10.0 #H5D_VIRTUAL added in this release. + * + * \since 1.0.0 + * + */ H5_DLL H5D_layout_t H5Pget_layout(hid_t plist_id); -H5_DLL herr_t H5Pset_chunk(hid_t plist_id, int ndims, const hsize_t dim[/*ndims*/]); -H5_DLL int H5Pget_chunk(hid_t plist_id, int max_ndims, hsize_t dim[] /*out*/); -H5_DLL herr_t H5Pset_virtual(hid_t dcpl_id, hid_t vspace_id, const char *src_file_name, - const char *src_dset_name, hid_t src_space_id); -H5_DLL herr_t H5Pget_virtual_count(hid_t dcpl_id, size_t *count /*out*/); -H5_DLL hid_t H5Pget_virtual_vspace(hid_t dcpl_id, size_t index); -H5_DLL hid_t H5Pget_virtual_srcspace(hid_t dcpl_id, size_t index); -H5_DLL ssize_t H5Pget_virtual_filename(hid_t dcpl_id, size_t index, char *name /*out*/, size_t size); -H5_DLL ssize_t H5Pget_virtual_dsetname(hid_t dcpl_id, size_t index, char *name /*out*/, size_t size); -H5_DLL herr_t H5Pset_external(hid_t plist_id, const char *name, off_t offset, hsize_t size); -H5_DLL herr_t H5Pset_chunk_opts(hid_t plist_id, unsigned opts); -H5_DLL herr_t H5Pget_chunk_opts(hid_t plist_id, unsigned *opts); -H5_DLL int H5Pget_external_count(hid_t plist_id); -H5_DLL herr_t H5Pget_external(hid_t plist_id, unsigned idx, size_t name_size, char *name /*out*/, - off_t *offset /*out*/, hsize_t *size /*out*/); -H5_DLL herr_t H5Pset_szip(hid_t plist_id, unsigned options_mask, unsigned pixels_per_block); -H5_DLL herr_t H5Pset_shuffle(hid_t plist_id); -H5_DLL herr_t H5Pset_nbit(hid_t plist_id); -H5_DLL herr_t H5Pset_scaleoffset(hid_t plist_id, H5Z_SO_scale_type_t scale_type, int scale_factor); -H5_DLL herr_t H5Pset_fill_value(hid_t plist_id, hid_t type_id, const void *value); -H5_DLL herr_t H5Pget_fill_value(hid_t plist_id, hid_t type_id, void *value /*out*/); -H5_DLL herr_t H5Pfill_value_defined(hid_t plist, H5D_fill_value_t *status); -H5_DLL herr_t H5Pset_alloc_time(hid_t plist_id, H5D_alloc_time_t alloc_time); -H5_DLL herr_t H5Pget_alloc_time(hid_t plist_id, H5D_alloc_time_t *alloc_time /*out*/); -H5_DLL herr_t H5Pset_fill_time(hid_t plist_id, H5D_fill_time_t fill_time); -H5_DLL herr_t H5Pget_fill_time(hid_t plist_id, H5D_fill_time_t *fill_time /*out*/); -H5_DLL herr_t H5Pget_dset_no_attrs_hint(hid_t dcpl_id, hbool_t *minimize); -H5_DLL herr_t H5Pset_dset_no_attrs_hint(hid_t dcpl_id, hbool_t minimize); +/** + * \ingroup DCPL + * + * \brief Gets the number of mappings for the virtual dataset + * + * \dcpl_id + * \param[out] count The number of mappings + * + * \return \herr_t + * + * \details H5Pget_virtual_count() gets the number of mappings for a + * virtual dataset that has the creation property list specified + * by \p dcpl_id. + * + * \see_virtual + * + * \since 1.10.0 + * + */ +H5_DLL herr_t H5Pget_virtual_count(hid_t dcpl_id, size_t *count /*out*/); +/** + * \ingroup DCPL + * + * \brief Gets the name of a source dataset used in the mapping + * + * \dcpl_id + * \param[in] index Mapping index. The value of \p index is 0 (zero) or + * greater and less than \p count + * (0 ≤ \p index < \p count), where \p count is the + * number of mappings returned by H5Pget_virtual_count(). + * \param[out] name A buffer containing the name of the source dataset + * \param[in] size The size, in bytes, of the name buffer. Must be the + * size of the dataset name in bytes plus 1 for a NULL + * terminator + * + * \return Returns the length of the dataset name if successful; + * otherwise returns a negative value. + * + * \details H5Pget_virtual_dsetname() takes the dataset creation property + * list for the virtual dataset, \p dcpl_id, the mapping index, + * \p index, the size of the dataset name for a source dataset, + * \p size, and retrieves the name of the source dataset used in + * the mapping. + * + * Up to \p size characters of the dataset name are returned in + * \p name; additional characters, if any, are not returned to + * the user application. + * + * If the length of the dataset name, which determines the + * required value of \p size, is unknown, a preliminary call + * to H5Pget_virtual_dsetname() with the last two parameters + * set to NULL and zero respectively can be made. The return + * value of this call will be the size in bytes of the dataset + * name. That value, plus 1 for a NULL terminator, must then be + * assigned to \p size for a second H5Pget_virtual_dsetname() + * call, which will retrieve the actual dataset name. + * + * \see_virtual + * + * \since 1.10.0 + * + */ +H5_DLL ssize_t H5Pget_virtual_dsetname(hid_t dcpl_id, size_t index, char *name /*out*/, size_t size); +/** + * \ingroup DCPL + * + * \brief Gets the filename of a source dataset used in the mapping + * + * \dcpl_id + * \param[in] index Mapping index. The value of \p index is 0 (zero) or + * greater and less than \p count + * (0 ≤ \p index < \p count), where \p count is the + * number of mappings returned by H5Pget_virtual_count(). + * \param[out] name A buffer containing the name of the file containing + * the source dataset + * \param[in] size The size, in bytes, of the name buffer. Must be the + * size of the filename in bytes plus 1 for a NULL + * terminator + * + * \return Returns the length of the filename if successful; otherwise + * returns a negative value. + * + * \details H5Pget_virtual_filename() takes the dataset creation property + * list for the virtual dataset, \p dcpl_id, the mapping index, + * \p index, the size of the filename for a source dataset, + * \p size, and retrieves the name of the file for a source dataset + * used in the mapping. + * + * Up to \p size characters of the filename are returned in + * \p name; additional characters, if any, are not returned to + * the user application. + * + * If the length of the filename, which determines the required + * value of \p size, is unknown, a preliminary call to + * H5Pget_virtual_filename() with the last two parameters set + * to NULL and zero respectively can be made. The return value + * of this call will be the size in bytes of the filename. That + * value, plus 1 for a NULL terminator, must then be assigned to + * \p size for a second H5Pget_virtual_filename() call, which + * will retrieve the actual filename. + * + * \see_virtual + * + * \since 1.10.0 + * + */ +H5_DLL ssize_t H5Pget_virtual_filename(hid_t dcpl_id, size_t index, char *name /*out*/, size_t size); +/** + * \ingroup DCPL + * + * \brief Gets a dataspace identifier for the selection within the source + * dataset used in the mapping + * + * \dcpl_id + * \param[in] index Mapping index. The value of \p index is 0 (zero) or + * greater and less than \p count + * (0 ≤ \p index < \p count), where \p count is the number + * of mappings returned by H5Pget_virtual_count(). + * + * \return \hid_t{valid dataspace identifier} + * + * \details H5Pget_virtual_srcspace() takes the dataset creation property + * list for the virtual dataset, \p dcpl_id, and the mapping + * index, \p index, and returns a dataspace identifier for the + * selection within the source dataset used in the mapping. + * + * \see_virtual + * + * \since 1.10.0 + * + */ +H5_DLL hid_t H5Pget_virtual_srcspace(hid_t dcpl_id, size_t index); +/** + * \ingroup DCPL + * + * \brief Gets a dataspace identifier for the selection within the virtual + * dataset used in the mapping + * + * \dcpl_id + * \param[in] index Mapping index. The value of \p index is 0 (zero) or + * greater and less than \p count + * (0 ≤ \p index < \p count), where \p count is the number + * of mappings returned by H5Pget_virtual_count() + * + * \return \hid_t{valid dataspace identifier} + * + * \details H5Pget_virtual_vspace() takes the dataset creation property + * list for the virtual dataset, \p dcpl_id, and the mapping + * index, \p index, and returns a dataspace identifier for the + * selection within the virtual dataset used in the mapping. + * + * \see_virtual + * + * \since 1.10.0 + * + */ +H5_DLL hid_t H5Pget_virtual_vspace(hid_t dcpl_id, size_t index); +/** + * \ingroup DCPL + * + * \brief Sets the timing for storage space allocation + * + * \dcpl_id{plist_id} + * \param[in] alloc_time When to allocate dataset storage space + * + * \return \herr_t + * + * \details H5Pset_alloc_time() sets up the timing for the allocation of + * storage space for a dataset's raw data. This property is set + * in the dataset creation property list \p plist_id. Timing is + * specified in \p alloc_time with one of the following values: + * + * <table> + * <tr> + * <td>#H5D_ALLOC_TIME_DEFAULT</td> + * <td>Allocate dataset storage space at the default time<br /> + * (Defaults differ by storage method.)</td> + * </tr> + * <tr> + * <td>#H5D_ALLOC_TIME_EARLY</td> + * <td>Allocate all space when the dataset is created<br /> + * (Default for compact datasets.)</td> + * </tr> + * <tr> + * <td>#H5D_ALLOC_TIME_INCR</td> + * <td>Allocate space incrementally, as data is written to + * the dataset<br />(Default for chunked storage datasets.) + * + * \li Chunked datasets: Storage space allocation for each + * chunk is deferred until data is written to the chunk. + * \li Contiguous datasets: Incremental storage space + * allocation for contiguous data is treated as late + * allocation. + * \li Compact datasets: Incremental allocation is not + * allowed with compact datasets; H5Pset_alloc_time() + * will return an error.</td> + * </tr> + * <tr> + * <td>#H5D_ALLOC_TIME_LATE</td> + * <td>Allocate all space when data is first written to the + * dataset<br /> + * (Default for contiguous datasets.)</td> + * </tr> + * </table> + * + * \note H5Pset_alloc_time() is designed to work in concert with the + * dataset fill value and fill value write time properties, set + * with the functions H5Pset_fill_value() and H5Pset_fill_time(). + * + * \note See H5Dcreate() for further cross-references. + * + * \since 1.6.0 + * + */ +H5_DLL herr_t H5Pset_alloc_time(hid_t plist_id, H5D_alloc_time_t alloc_time); +/** + * \ingroup DCPL + * + * \brief Sets the size of the chunks used to store a chunked layout + * dataset + * + * \dcpl_id{plist_id} + * \param[in] ndims The number of dimensions of each chunk + * \param[in] dim An array defining the size, in dataset elements, of + * each chunk + * + * \return \herr_t + * \details H5Pset_chunk() sets the size of the chunks used to store a + * chunked layout dataset. This function is only valid for dataset + * creation property lists. + * + * The \p ndims parameter currently must be the same size as the + * rank of the dataset. + * + * The values of the \p dim array define the size of the chunks + * to store the dataset's raw data. The unit of measure for \p dim + * values is dataset elements. + * + * As a side-effect of this function, the layout of the dataset is + * changed to #H5D_CHUNKED, if it is not already so set. + * + * \note Chunk size cannot exceed the size of a fixed-size dataset. For + * example, a dataset consisting of a 5x4 fixed-size array cannot be + * defined with 10x10 chunks. Chunk maximums: + * - The maximum number of elements in a chunk is 2<sup>32</sup>-1 which + * is equal to 4,294,967,295. If the number of elements in a chunk is + * set via H5Pset_chunk() to a value greater than 2<sup>32</sup>-1, + * then H5Pset_chunk() will fail. + * - The maximum size for any chunk is 4GB. If a chunk that is larger + * than 4GB attempts to be written with H5Dwrite(), then H5Dwrite() + * will fail. + * + * \see H5Pset_layout(), H5Dwrite() + * + * \since 1.0.0 + * + */ +H5_DLL herr_t H5Pset_chunk(hid_t plist_id, int ndims, const hsize_t dim[/*ndims*/]); +/** + * \ingroup DCPL + * + * \brief Sets the edge chunk option in a dataset creation property list + * + * \dcpl_id{plist_id} + * \param[in] opts Edge chunk option flag. Valid values are: + * \li #H5D_CHUNK_DONT_FILTER_PARTIAL_CHUNKS + * When enabled, filters are not applied to partial + * edge chunks. When disabled, partial edge chunks are + * filtered. Enabling this option will improve + * performance when appending to the dataset and, when + * compression filters are used, prevent reallocation + * of these chunks. Datasets created with this option + * enabled will be inaccessible with HDF5 library + * versions before Release 1.10. Default: \e Disabled + * \li 0 (zero) Disables option; partial edge chunks + * will be compressed. + * + * \return \herr_t + * + * \details H5Pset_chunk_opts() sets the edge chunk option in the + * dataset creation property list \p dcpl_id. + * + * The available option is detailed in the parameters section. + * Only chunks that are not completely filled by the dataset’s + * dataspace are affected by this option. Such chunks are + * referred to as partial edge chunks. + * + * \b Motivation: H5Pset_chunk_opts() is used to specify storage + * options for chunks on the edge of a dataset’s dataspace. This + * capability allows the user to tune performance in cases where + * the dataset size may not be a multiple of the chunk size and + * the handling of partial edge chunks can impact performance. + * + * \since 1.10.0 + * + */ +H5_DLL herr_t H5Pset_chunk_opts(hid_t plist_id, unsigned opts); +/** + * \ingroup DCPL + * + * \brief Sets the flag to create minimized dataset object headers + * + * \dcpl_id + * \param[in] minimize Flag for indicating whether or not a dataset's + * object header will be minimized + * + * \return \herr_t + * + * \details H5Pset_dset_no_attrs_hint() sets the no dataset attributes + * hint setting for the dataset creation property list \p dcpl_id. + * Datasets created with the dataset creation property list + * \p dcpl_id will have their object headers minimized if the + * boolean flag \p minimize is set to TRUE. By setting \p minimize + * to TRUE, the library expects that no attributes will be added + * to the dataset. Attributes can be added, but they are appended + * with a continuation message, which can reduce performance. + * + * This setting interacts with H5Fset_dset_no_attrs_hint(): if + * either is set to TRUE, then the created dataset's object header + * will be minimized. + * + * \since 1.10.5 + * + */ +H5_DLL herr_t H5Pset_dset_no_attrs_hint(hid_t dcpl_id, hbool_t minimize); +/** + * \ingroup DCPL + * + * \brief Adds an external file to the list of external files + * + * \dcpl_id{plist_id} + * \param[in] name Name of an external file + * \param[in] offset Offset, in bytes, from the beginning of the file to + * the location in the file where the data starts + * \param[in] size Number of bytes reserved in the file for the data + * + * \return \herr_t + * + * \details The first call to H5Pset_external() sets the external + * storage property in the property list, thus designating that + * the dataset will be stored in one or more non-HDF5 file(s) + * external to the HDF5 file. This call also adds the file + * \p name as the first file in the list of external files. + * Subsequent calls to the function add the named file as the + * next file in the list. + * + * If a dataset is split across multiple files, then the files + * should be defined in order. The total size of the dataset is + * the sum of the \p size arguments for all the external files. + * If the total size is larger than the size of a dataset then + * the dataset can be extended (provided the data space also + * allows the extending). + * + * The \p size argument specifies the number of bytes reserved + * for data in the external file. If \p size is set to + * #H5F_UNLIMITED, the external file can be of unlimited size + * and no more files can be added to the external files list. + * If \p size is set to 0 (zero), no external file will actually + * be created. + * + * All of the external files for a given dataset must be specified + * with H5Pset_external() before H5Dcreate() is called to create + * the dataset. If one these files does not exist on the system + * when H5Dwrite() is called to write data to it, the library + * will create the file. + * + * \since 1.0.0 + * + */ +H5_DLL herr_t H5Pset_external(hid_t plist_id, const char *name, off_t offset, hsize_t size); +/** + * \ingroup DCPL + * + * \brief Sets the time when fill values are written to a dataset + * + * \dcpl_id{plist_id} + * \param[in] fill_time When to write fill values to a dataset + * + * \return \herr_t + * + * \details H5Pset_fill_time() sets up the timing for writing fill values + * to a dataset. This property is set in the dataset creation + * property list \p plist_id. Timing is specified in \p fill_time + * with one of the following values: + * + * <table> + * <tr> + * <td>#H5D_FILL_TIME_IFSET</td> + * <td>Write fill values to the dataset when storage space is + * allocated only if there is a user-defined fill value, + * i.e.,one set with H5Pset_fill_value(). (Default)</td> + * </tr> + * <tr> + * <td>#H5D_FILL_TIME_ALLOC</td> + * <td>Write fill values to the dataset when storage space is + * allocated.</td> + * </tr> + * <tr> + * <td>#H5D_FILL_TIME_NEVER</td> + * <td>Never write fill values to the dataset.</td> + * </tr> + * </table> + * + * \note H5Pset_fill_time() is designed for coordination with the dataset + * fill value and dataset storage allocation time properties, set + * with the functions H5Pset_fill_value() and H5Pset_alloc_time(). + * See H5Dcreate() for further cross-references. + * + * \since 1.6.0 + * + */ +H5_DLL herr_t H5Pset_fill_time(hid_t plist_id, H5D_fill_time_t fill_time); +/** + * \ingroup DCPL + * + * \brief Sets the fill value for a dataset + * + * \dcpl_id{plist_id} + * \param[in] type_id Datatype of \p value + * \param[in] value Pointer to buffer containing value to use as + * fill value + * + * \return \herr_t + * + * \details H5Pset_fill_value() sets the fill value for a dataset in the + * dataset creation property list. \p value is interpreted as + * being of datatype \p type_id. This datatype may differ from + * that of the dataset, but the HDF5 library must be able to + * convert \p value to the dataset datatype when the dataset is + * created. + * + * The default fill value is 0 (zero), which is interpreted + * according to the actual dataset datatype. + * + * Setting \p value to NULL indicates that the fill value is to + * be undefined. + * + * \note Applications sometimes write data only to portions of an allocated + * dataset. It is often useful in such cases to fill the unused space + * with a known fill value. This function allows the user application + * to set that fill value; the functions H5Dfill() and + * H5Pset_fill_time(), respectively, provide the ability to apply the + * fill value on demand or to set up its automatic application. + * + * \note A fill value should be defined so that it is appropriate for the + * application. While the HDF5 default fill value is 0 (zero), it is + * often appropriate to use another value. It might be useful, for + * example, to use a value that is known to be impossible for the + * application to legitimately generate. + * + * \note H5Pset_fill_value() is designed to work in concert with + * H5Pset_alloc_time() and H5Pset_fill_time(). H5Pset_alloc_time() + * and H5Pset_fill_time() govern the timing of dataset storage + * allocation and fill value write operations and can be important in + * tuning application performance. + * + * \note See H5Dcreate() for further cross-references. + * + * \since 1.0.0 + * + */ +H5_DLL herr_t H5Pset_fill_value(hid_t plist_id, hid_t type_id, const void *value); +/** + * \ingroup DCPL + * + * \brief Sets up use of the shuffle filter + * + * \dcpl_id{plist_id} + * + * \return \herr_t + * + * \details H5Pset_shuffle() sets the shuffle filter, #H5Z_FILTER_SHUFFLE, + * in the dataset creation property list \p plist_id. The shuffle + * filter de-interlaces a block of data by reordering the bytes. + * All the bytes from one consistent byte position of each data + * element are placed together in one block; all bytes from a + * second consistent byte position of each data element are placed + * together a second block; etc. For example, given three data + * elements of a 4-byte datatype stored as 012301230123, shuffling + * will re-order data as 000111222333. This can be a valuable step + * in an effective compression algorithm because the bytes in each + * byte position are often closely related to each other and + * putting them together can increase the compression ratio. + * + * As implied above, the primary value of the shuffle filter lies + * in its coordinated use with a compression filter; it does not + * provide data compression when used alone. When the shuffle + * filter is applied to a dataset immediately prior to the use of + * a compression filter, the compression ratio achieved is often + * superior to that achieved by the use of a compression filter + * without the shuffle filter. + * + * \since 1.6.0 + * + */ +H5_DLL herr_t H5Pset_shuffle(hid_t plist_id); +/** + * \ingroup DCPL + * + * \brief Sets the type of storage used to store the raw data for a dataset + * + * \dcpl_id{plist_id} + * \param[in] layout Type of storage layout for raw data + * + * \return \herr_t + * \details H5Pset_layout() sets the type of storage used to store the raw + * data for a dataset. This function is only valid for dataset + * creation property lists. + * + * Valid values for \p layout are: + * - #H5D_COMPACT: Store raw data in the dataset object header + * in file. This should only be used for datasets + * with small amounts of raw data. The raw data + * size limit is 64K (65520 bytes). Attempting + * to create a dataset with raw data larger than + * this limit will cause the H5Dcreate() call to + * fail. + * - #H5D_CONTIGUOUS: Store raw data separately from the object + * header in one large chunk in the file. + * - #H5D_CHUNKED: Store raw data separately from the object header + * as chunks of data in separate locations in + * the file. + * - #H5D_VIRTUAL: Draw raw data from multiple datasets in + * different files. + * + * Note that a compact storage layout may affect writing data to + * the dataset with parallel applications. See the note in + * H5Dwrite() documentation for details. + * \version 1.10.0 #H5D_VIRTUAL added in this release. + * \since 1.0.0 + * + */ +H5_DLL herr_t H5Pset_layout(hid_t plist_id, H5D_layout_t layout); +/** + * \ingroup DCPL + * + * \brief Sets up the use of the N-Bit filter + * + * \dcpl_id{plist_id} + * + * \return \herr_t + * + * \details H5Pset_nbit() sets the N-Bit filter, #H5Z_FILTER_NBIT, in the + * dataset creation property list \p plist_id. + * + * The HDF5 user can create an N-Bit datatype with the following + * code: + * <pre> + * hid_t nbit_datatype = H5Tcopy(H5T_STD_I32LE); + * H5Tset_precision(nbit_datatype, 16); + * H5Tset_offset(nbit_datatype, 4); + * </pre> + * + * In memory, one value of the N-Bit datatype in the above example + * will be stored on a little-endian machine as follows: + * + * <table> + * <tr> + * <td>byte 3</td> + * <td>byte 2</td> + * <td>byte 1</td> + * <td>byte 0</td> + * </tr> + * <tr> + * <td>????????</td> + * <td>????SPPP</td> + * <td>PPPPPPPP</td> + * <td>PPPP????</td> + * </tr> + * </table> + * Note: S - sign bit, P - significant bit, ? - padding bit; For + * signed integer, the sign bit is included in the precision. + * + * When data of the above datatype is stored on disk using the + * N-bit filter, all padding bits are chopped off and only + * significant bits are stored. The values on disk will be + * something like: + * + * <table> + * <tr> + * <td>1st value</td> + * <td>2nd value</td> + * <td>...</td> + * </tr> + * <tr> + * <td>SPPPPPPPPPPPPPPP</td> + * <td>SPPPPPPPPPPPPPPP</td> + * <td>...</td> + * </tr> + * </table> + * The N-Bit filter is used effectively for compressing data of + * an N-Bit datatype as well as a compound and an array + * datatype with N-Bit fields. However, the datatype classes of + * the N-Bit datatype or the N-Bit field of the compound + * datatype or the array datatype are limited to integer or + * floating-point. + * + * The N-Bit filter supports complex situations where a compound + * datatype contains member(s) of a compound datatype or an array + * datatype that has a compound datatype as the base type. + * However, it does not support the situation where an array + * datatype has a variable-length or variable-length string as + * its base datatype. The filter does support the situation where + * a variable-length or variable-length string is a member of a + * compound datatype. + * + * The N-Bit filter allows all other HDF5 datatypes (such as + * time, string, bitfield, opaque, reference, enum, and variable + * length) to pass through as a no-op. + * + * Like other I/O filters supported by the HDF5 library, + * application using the N-Bit filter must store data with + * chunked storage. + * + * By nature, the N-Bit filter should not be used together with + * other I/O filters. + * + * \version 1.8.8 Fortran subroutine introduced in this release. + * + * \since 1.8.0 + * + */ +H5_DLL herr_t H5Pset_nbit(hid_t plist_id); +/** + * \ingroup DCPL + * + * \brief Sets up the use of the scale-offset filter + * + * \dcpl_id{plist_id} + * \param[in] scale_type Flag indicating compression method + * \param[in] scale_factor Parameter related to scale. Must be + * non-negative + * + * \return \herr_t + * + * \details H5Pset_scaleoffset() sets the scale-offset filter, + * #H5Z_FILTER_SCALEOFFSET, for a dataset. + * + * Generally speaking, scale-offset compression performs a scale and/or + * offset operation on each data value and truncates the resulting + * value to a minimum number of bits (MinBits) before storing it. The + * current scale-offset filter supports integer and floating-point + * datatypes. + * + * For an integer datatype, the parameter \p scale_type should be set + * to #H5Z_SO_INT (2). The parameter \p scale_factor denotes MinBits. + * If the user sets it to H5Z_SO_INT_MINBITS_DEFAULT (0), the filter + * will calculate MinBits. If \p scale_factor is set to a positive + * integer, the filter does not do any calculation and just uses the + * number as MinBits. However, if the user gives a MinBits that is less + * than what would be generated by the filter, the compression will be + * lossy. Also, the MinBits supplied by the user cannot exceed the + * number of bits to store one value of the dataset datatype. + * + * For a floating-point datatype, the filter adopts the GRiB data + * packing mechanism, which offers two alternate methods: E-scaling and + * D-scaling. Both methods are lossy compression. If the parameter + * \p scale_type is set to #H5Z_SO_FLOAT_DSCALE (0), the filter will + * use the D-scaling method; if it is set to #H5Z_SO_FLOAT_ESCALE (1), + * the filter will use the E-scaling method. Since only the D-scaling + * method is implemented, \p scale_type should be set to + * #H5Z_SO_FLOAT_DSCALE or 0. + * + * When the D-scaling method is used, the original data is "D" scaled + * — multiplied by 10 to the power of \p scale_factor, and the + * "significant" part of the value is moved to the left of the decimal + * point. Care should be taken in setting the decimal \p scale_factor + * so that the integer part will have enough precision to contain the + * appropriate information of the data value. For example, if + * \p scale_factor is set to 2, the number 104.561 will be 10456.1 + * after "D" scaling. The last digit 1 is not "significant" and is + * thrown off in the process of rounding. The user should make sure that + * after "D" scaling and rounding, the data values are within the range + * that can be represented by the integer (same size as the + * floating-point type). + * + * Valid values for scale_type are as follows: + * + * <table> + * <tr> + * <td>#H5Z_SO_FLOAT_DSCALE (0)</td> + * <td>Floating-point type, using variable MinBits method</td> + * </tr> + * <tr> + * <td>#H5Z_SO_FLOAT_ESCALE (1)</td> + * <td>Floating-point type, using fixed MinBits method</td> + * </tr> + * <tr> + * <td>#H5Z_SO_INT (2)</td> + * <td>Integer type</td> + * </tr> + * </table> + * + * The meaning of \p scale_factor varies according to the value + * assigned to \p scale_type: + * + * <table> + * <tr> + * <th>\p scale_type value</th> + * <th>\p scale_factor description</th> + * </tr> + * <tr> + * <td>#H5Z_SO_FLOAT_DSCALE</td> + * <td>Denotes the decimal scale factor for D-scaling and can be + * positive, negative or zero. This is the current + * implementation of the library.</td> + * </tr> + * <tr> + * <td>#H5Z_SO_FLOAT_ESCALE</td> + * <td>Denotes MinBits for E-scaling and must be a positive integer. + * This is not currently implemented by the library.</td> + * </tr> + * <tr> + * <td>#H5Z_SO_INT</td> + * <td>Denotes MinBits and it should be a positive integer or + * #H5Z_SO_INT_MINBITS_DEFAULT (0). If it is less than 0, the + * library will reset it to 0 since it is not implemented. + * </td> + * </tr> + * </table> + * Like other I/O filters supported by the HDF5 library, an + * application using the scale-offset filter must store data with + * chunked storage. + * + * \version 1.8.8 Fortran90 subroutine introduced in this release. + * + * \since 1.8.0 + * + */ +H5_DLL herr_t H5Pset_scaleoffset(hid_t plist_id, H5Z_SO_scale_type_t scale_type, int scale_factor); +/** + * \ingroup DCPL + * + * \brief Sets up use of the SZIP compression filter + * + * \dcpl_id{plist_id} + * \param[in] options_mask A bit-mask conveying the desired SZIP options; + * Valid values are #H5_SZIP_EC_OPTION_MASK and + * #H5_SZIP_NN_OPTION_MASK. + * \param[in] pixels_per_block The number of pixels or data elements in each + * data block + * + * \return \herr_t + * + * \details H5Pset_szip() sets an SZIP compression filter, #H5Z_FILTER_SZIP, + * for a dataset. SZIP is a compression method designed for use with + * scientific data. + * + * Before proceeding, all users should review the “Limitations” + * section below. + * + * Users familiar with SZIP outside the HDF5 context may benefit + * from reviewing the Note “For Users Familiar with SZIP in Other + * Contexts” below. + * + * In the text below, the term pixel refers to an HDF5 data element. + * This terminology derives from SZIP compression's use with image + * data, where pixel referred to an image pixel. + * + * The SZIP \p bits_per_pixel value (see Note, below) is automatically + * set, based on the HDF5 datatype. SZIP can be used with atomic + * datatypes that may have size of 8, 16, 32, or 64 bits. + * Specifically, a dataset with a datatype that is 8-, 16-, 32-, or + * 64-bit signed or unsigned integer; char; or 32- or 64-bit float + * can be compressed with SZIP. See Note, below, for further + * discussion of the the SZIP \p bits_per_pixel setting. + * + * SZIP options are passed in an options mask, \p options_mask, + * as follows. + * + * <table> + * <tr> + * <th>Option</th> + * <th>Description (Mutually exclusive; select one.)</th> + * </tr> + * <tr> + * <td>#H5_SZIP_EC_OPTION_MASK</td> + * <td>Selects entropy coding method</td> + * </tr> + * <tr> + * <td>#H5_SZIP_NN_OPTION_MASK</td> + * <td>Selects nearest neighbor coding method</td> + * </tr> + * </table> + * + * The following guidelines can be used in determining which + * option to select: + * + * - The entropy coding method, the EC option specified by + * #H5_SZIP_EC_OPTION_MASK, is best suited for data that has been + * processed. The EC method works best for small numbers. + * - The nearest neighbor coding method, the NN option specified + * by #H5_SZIP_NN_OPTION_MASK, preprocesses the data then the + * applies EC method as above. + * + * Other factors may affect results, but the above criteria + * provides a good starting point for optimizing data compression. + * + * SZIP compresses data block by block, with a user-tunable block + * size. This block size is passed in the parameter + * \p pixels_per_block and must be even and not greater than 32, + * with typical values being 8, 10, 16, or 32. This parameter + * affects compression ratio; the more pixel values vary, the + * smaller this number should be to achieve better performance. + * + * In HDF5, compression can be applied only to chunked datasets. + * If \p pixels_per_block is bigger than the total number of + * elements in a dataset chunk, H5Pset_szip() will succeed but + * the subsequent call to H5Dcreate() will fail; the conflict + * can be detected only when the property list is used. + * + * To achieve optimal performance for SZIP compression, it is + * recommended that a chunk's fastest-changing dimension be equal + * to N times \p pixels_per_block where N is the maximum number of + * blocks per scan line allowed by the SZIP library. In the + * current version of SZIP, N is set to 128. + * + * SZIP compression is an optional HDF5 filter. + * + * \b Limitations: + * + * - SZIP compression cannot be applied to compound, array, + * variable-length, enumeration, or any other user-defined + * datatypes. If an SZIP filter is set in a dataset creation + * property list used to create a dataset containing a + * non-allowed datatype, the call to H5Dcreate() will fail; the + * conflict can be detected only when the property list is used. + * - Users should be aware that there are factors that affect one’s + * rights and ability to use SZIP compression by reviewing the + * SZIP copyright notice. + * + * \note \b For \b Users \b Familiar \b with \b SZIP \b in \b Other \b Contexts: + * + * \note The following notes are of interest primarily to those who have + * used SZIP compression outside of the HDF5 context. + * In non-HDF5 applications, SZIP typically requires that the user + * application supply additional parameters: + * - \p pixels_in_object, the number of pixels in the object to + * be compressed + * - \p bits_per_pixel, the number of bits per pixel + * - \p pixels_per_scanline, the number of pixels per scan line + * + * \note These values need not be independently supplied in the HDF5 + * environment as they are derived from the datatype and dataspace, + * which are already known. In particular, HDF5 sets + * \p pixels_in_object to the number of elements in a chunk and + * \p bits_per_pixel to the size of the element or pixel datatype. + * + * \note The following algorithm is used to set \p pixels_per_scanline: + * - If the size of a chunk's fastest-changing dimension, size, + * is greater than 4K, set \p pixels_per_scanline to 128 times + * \p pixels_per_block. + * - If size is less than 4K but greater than \p pixels_per_block, + * set \p pixels_per_scanline to the minimum of size and 128 + * times \p pixels_per_block. + * - If size is less than \p pixels_per_block but greater than the + * number elements in the chunk, set \p pixels_per_scanline to + * the minimum of the number elements in the chunk and 128 times + * \p pixels_per_block. + * + * \note The HDF5 datatype may have precision that is less than the full + * size of the data element, e.g., an 11-bit integer can be defined + * using H5Tset_precision(). To a certain extent, SZIP can take + * advantage of the precision of the datatype to improve compression: + * - If the HDF5 datatype size is 24-bit or less and the offset of + * the bits in the HDF5 datatype is zero (see H5Tset_offset() or + * H5Tget_offset()), the data is the in lowest N bits of the data + * element. In this case, the SZIP \p bits_per_pixel is set to the + * precision of the HDF5 datatype. + * - If the offset is not zero, the SZIP \p bits_per_pixel will be + * set to the number of bits in the full size of the data element. + * - If the HDF5 datatype precision is 25-bit to 32-bit, the SZIP + * \p bits_per_pixel will be set to 32. + * - If the HDF5 datatype precision is 33-bit to 64-bit, the SZIP + * \p bits_per_pixel will be set to 64. + * + * \note HDF5 always modifies the options mask provided by the user to set up + * usage of RAW_OPTION_MASK, ALLOW_K13_OPTION_MASK, and one of + * LSB_OPTION_MASK or MSB_OPTION_MASK, depending on endianness of the + * datatype. + * + * \since 1.6.0 + * + */ +H5_DLL herr_t H5Pset_szip(hid_t plist_id, unsigned options_mask, unsigned pixels_per_block); + +/** + * \ingroup DCPL + * + * \brief Sets the mapping between virtual and source datasets + * + * \dcpl_id + * \param[in] vspace_id The dataspace identifier with the selection within the + * virtual dataset applied, possibly an unlimited selection + * \param[in] src_file_name The name of the HDF5 file where the source dataset is + * located or a \Code{"."} (period) for a source dataset in the same + * file. The file might not exist yet. The name can be specified using + * a C-style \c printf statement as described below. + * \param[in] src_dset_name The path to the HDF5 dataset in the file specified by + * \p src_file_name. The dataset might not exist yet. The dataset name + * can be specified using a C-style \c printf statement as described below. + * \param[in] src_space_id The source dataset’s dataspace identifier with a + * selection applied, possibly an unlimited selection + * \return \herr_t + * + * \details H5Pset_virtual() maps elements of the virtual dataset (VDS) + * described by the virtual dataspace identifier \p vspace_id to the + * elements of the source dataset described by the source dataset + * dataspace identifier \p src_space_id. The source dataset is + * identified by the name of the file where it is located, + * \p src_file_name, and the name of the dataset, \p src_dset_name. + * + * \par C-style \c printf Formatting Statements: + * C-style \c printf formatting allows a pattern to be specified in the name + * of a source file or dataset. Strings for the file and dataset names are + * treated as literals except for the following substitutions: + * <table> + * <tr> + * <td>\Code{"%%"}</td> + * <td>Replaced with a single \Code{"%"} (percent) character.</td> + * </tr> + * <tr> + * <td><code>"%<d>b"</code></td> + * <td>Where <code>"<d>"</code> is the virtual dataset dimension axis (0-based) + * and \Code{"b"} indicates that the block count of the selection in that + * dimension should be used. The full expression (for example, \Code{"%0b"}) + * is replaced with a single numeric value when the mapping is evaluated at + * VDS access time. Example code for many source and virtual dataset mappings + * is available in the "Examples of Source to Virtual Dataset Mapping" + * chapter in the + * <a href="https://portal.hdfgroup.org/display/HDF5/RFC+HDF5+Virtual+Dataset"> + * RFC: HDF5 Virtual Dataset</a>. + * </td> + * </tr> + * </table> + * If the printf form is used for the source file or dataset names, the + * selection in the source dataset’s dataspace must be fixed-size. + * + * \par Source File Resolutions: + * When a source dataset residing in a different file is accessed, the + * library will search for the source file \p src_file_name as described + * below: + * \li If \p src_file_name is a \Code{"."} (period) then it refers to the + * file containing the virtual dataset. + * \li If \p src_file_name is a relative pathname, the following steps are + * performed: + * - The library will get the prefix(es) set in the environment + * variable \c HDF5_VDS_PREFIX and will try to prepend each prefix + * to \p src_file_name to form a new \p src_file_name. If the new + * \p src_file_name does not exist or if \c HDF5_VDS_PREFIX is not + * set, the library will get the prefix set via H5Pset_virtual_prefix() + * and prepend it to \p src_file_name to form a new \p src_file_name. + * If the new \p src_file_name does not exist or no prefix is being + * set by H5Pset_virtual_prefix() then the path of the file containing + * the virtual dataset is obtained. This path can be the absolute path + * or the current working directory plus the relative path of that + * file when it is created/opened. The library will prepend this path + * to \p src_file_name to form a new \p src_file_name. + * - If the new \p src_file_name does not exist, then the library will + * look for \p src_file_name and will return failure/success accordingly. + * \li If \p src_file_name is an absolute pathname, the library will first + * try to find \p src_file_name. If \p src_file_name does not exist, + * \p src_file_name is stripped of directory paths to form a new + * \p src_file_name. The search for the new \p src_file_name then follows + * the same steps as described above for a relative pathname. See + * examples below illustrating how \p src_file_name is stripped to form + * a new \p src_file_name. + * \par + * Note that \p src_file_name is considered to be an absolute pathname when + * the following condition is true: + * \li For Unix, the first character of \p src_file_name is a slash + * (\Code{/}).\n For example, consider a \p src_file_name of + * \Code{/tmp/A.h5}. If that source file does not exist, the new + * \p src_file_name after stripping will be \Code{A.h5}. + * \li For Windows, there are 6 cases: + * 1. \p src_file_name is an absolute drive with absolute pathname.\n + * For example, consider a \p src_file_name of \Code{/tmp/A.h5}. + * If that source file does not exist, the new \p src_file_name + * after stripping will be \Code{A.h5}. + * 2. \p src_file_name is an absolute pathname without specifying + * drive name.\n For example, consider a \p src_file_name of + * \Code{/tmp/A.h5}. If that source file does not exist, the new + * \p src_file_name after stripping will be \Code{A.h5}. + * 3. \p src_file_name is an absolute drive with relative pathname.\n + * For example, consider a \p src_file_name of \Code{/tmp/A.h5}. + * If that source file does not exist, the new \p src_file_name + * after stripping will be \Code{tmp/A.h5}. + * 4. \p src_file_name is in UNC (Uniform Naming Convention) format + * with server name, share name, and pathname.\n + * For example, consider a \p src_file_name of \Code{/tmp/A.h5}. + * If that source file does not exist, the new \p src_file_name + * after stripping will be \Code{A.h5}. + * 5. \p src_file_name is in Long UNC (Uniform Naming Convention) + * format with server name, share name, and pathname.\n + * For example, consider a \p src_file_name of \Code{/tmp/A.h5}. + * If that source file does not exist, the new \p src_file_name + * after stripping will be \Code{A.h5}. + * 6. \p src_file_name is in Long UNC (Uniform Naming Convention) + * format with an absolute drive and an absolute pathname.\n + * For example, consider a \p src_file_name of \Code{/tmp/A.h5}. + * If that source file does not exist, the new \p src_file_name + * after stripping will be \Code{A.h5} + * + * \see <a href="https://portal.hdfgroup.org/display/HDF5/Virtual+Dataset++-+VDS"> + * Virtual Dataset Overview</a> + * + * \see_virtual + * + * \version 1.10.2 A change was made to the method of searching for VDS source files. + * \since 1.10.0 + * + */ +H5_DLL herr_t H5Pset_virtual(hid_t dcpl_id, hid_t vspace_id, const char *src_file_name, + const char *src_dset_name, hid_t src_space_id); /* Dataset access property list (DAPL) routines */ -H5_DLL herr_t H5Pset_chunk_cache(hid_t dapl_id, size_t rdcc_nslots, size_t rdcc_nbytes, double rdcc_w0); -H5_DLL herr_t H5Pget_chunk_cache(hid_t dapl_id, size_t *rdcc_nslots /*out*/, size_t *rdcc_nbytes /*out*/, - double *rdcc_w0 /*out*/); -H5_DLL herr_t H5Pset_virtual_view(hid_t plist_id, H5D_vds_view_t view); -H5_DLL herr_t H5Pget_virtual_view(hid_t plist_id, H5D_vds_view_t *view); -H5_DLL herr_t H5Pset_virtual_printf_gap(hid_t plist_id, hsize_t gap_size); -H5_DLL herr_t H5Pget_virtual_printf_gap(hid_t plist_id, hsize_t *gap_size); -H5_DLL herr_t H5Pset_virtual_prefix(hid_t dapl_id, const char *prefix); -H5_DLL ssize_t H5Pget_virtual_prefix(hid_t dapl_id, char *prefix /*out*/, size_t size); -H5_DLL herr_t H5Pset_append_flush(hid_t plist_id, unsigned ndims, const hsize_t boundary[], - H5D_append_cb_t func, void *udata); -H5_DLL herr_t H5Pget_append_flush(hid_t plist_id, unsigned dims, hsize_t boundary[], H5D_append_cb_t *func, - void **udata); -H5_DLL herr_t H5Pset_efile_prefix(hid_t dapl_id, const char *prefix); +/** + * \ingroup DAPL + * + * \brief Retrieves the values of the append property that is set up in + * the dataset access property list + * + * \dapl_id + * \param[in] dims The number of elements for \p boundary + * \param[in] boundary The dimension sizes used to determine the boundary + * \param[in] func The user-defined callback function + * \param[in] udata The user-defined input data + * + * \return \herr_t + * + * \details H5Pget_append_flush() obtains the following information + * from the dataset access property list, \p dapl_id. + * + * \p boundary consists of the sizes set up in the access + * property list that are used to determine when a dataset + * dimension size hits the boundary. Only at most \p dims + * boundary sizes are retrieved, and \p dims will not exceed + * the corresponding value that is set in the property list. + * + * \p func is the user-defined callback function to invoke when + * a dataset’s appended dimension size reaches a boundary and + * \p udata is the user-defined input data for the callback + * function. + * + * \since 1.10.0 + * + */ +H5_DLL herr_t H5Pget_append_flush(hid_t dapl_id, unsigned dims, hsize_t boundary[], H5D_append_cb_t *func, + void **udata); +/** + * \ingroup DAPL + * + * \brief Retrieves the raw data chunk cache parameters + * + * \dapl_id + * \param[out] rdcc_nslots Number of chunk slots in the raw data chunk + * cache hash table + * \param[out] rdcc_nbytes Total size of the raw data chunk cache, in + * bytes + * \param[out] rdcc_w0 Preemption policy + * + * \return \herr_t + * + * \details H5Pget_chunk_cache() retrieves the number of chunk slots in + * the raw data chunk cache hash table, the maximum possible + * number of bytes in the raw data chunk cache, and the + * preemption policy value. + * + * These values are retrieved from a dataset access property + * list. If the values have not been set on the property list, + * then values returned will be the corresponding values from + * a default file access property list. + * + * Any (or all) pointer arguments may be null pointers, in which + * case the corresponding data is not returned. + * + * \since 1.8.3 + * + */ +H5_DLL herr_t H5Pget_chunk_cache(hid_t dapl_id, size_t *rdcc_nslots /*out*/, size_t *rdcc_nbytes /*out*/, + double *rdcc_w0 /*out*/); +/** + * \ingroup DAPL + * + * \brief Retrieves the prefix for external raw data storage files as set + * in the dataset access property list + * + * \dapl_id + * \param[in,out] prefix Dataset external storage prefix in UTF-8 or + * ASCII (\em Path and \em filename must be ASCII + * on Windows systems.) + * \param[in] size Size of prefix buffer in bytes + * + * \return Returns the size of \p prefix and the prefix string will be + * stored in \p prefix if successful. + * Otherwise returns a negative value and the contents of \p prefix + * will be undefined. + * + * \details H5Pget_efile_prefix() retrieves the file system path prefix + * for locating external files associated with a dataset that + * uses external storage. This will be the value set with + * H5Pset_efile_prefix() or the HDF5 library’s default. + * + * The value of \p size is the size in bytes of the prefix, + * including the NULL terminator. If the size is unknown, a + * preliminary H5Pget_elink_prefix() call with the pointer + * \p prefix set to NULL will return the size of the prefix + * without the NULL terminator. + * + * The \p prefix buffer must be allocated by the caller. In a + * call that retrieves the actual prefix, that buffer must be + * of the size specified in \p size. + * + * \note See H5Pset_efile_prefix() for a more complete description of + * file location behavior and for notes on the use of the + * HDF5_EXTFILE_PREFIX environment variable. + * + * \since 1.10.0, 1.8.17 + * + */ H5_DLL ssize_t H5Pget_efile_prefix(hid_t dapl_id, char *prefix /*out*/, size_t size); +/** + * \ingroup DAPL + * + * \brief Retrieves prefix applied to VDS source file paths + * + * \dapl_id + * \param[out] prefix Prefix applied to VDS source file paths + * \param[in] size Size of prefix, including null terminator + * + * \return If successful, returns a non-negative value specifying the size + * in bytes of the prefix without the NULL terminator; otherwise + * returns a negative value. + * + * \details H5Pget_virtual_prefix() retrieves the prefix applied to the + * path of any VDS source files traversed. + * + * When an VDS source file is traversed, the prefix is retrieved + * from the dataset access property list \p dapl_id, returned + * in the user-allocated buffer pointed to by \p prefix, and + * prepended to the filename stored in the VDS virtual file, set + * with H5Pset_virtual(). + * + * The size in bytes of the prefix, including the NULL terminator, + * is specified in \p size. If \p size is unknown, a preliminary + * H5Pget_virtual_prefix() call with the pointer \p prefix set to + * NULL will return the size of the prefix without the NULL + * terminator. + * + * \see_virtual + * + * \since 1.10.2 + * + */ +H5_DLL ssize_t H5Pget_virtual_prefix(hid_t dapl_id, char *prefix /*out*/, size_t size); +/** + * \ingroup DAPL + * + * \brief Returns the maximum number of missing source files and/or datasets + * with the printf-style names when getting the extent for an unlimited + * virtual dataset + * + * \dapl_id + * \param[out] gap_size Maximum number of the files and/or datasets + * allowed to be missing for determining the extent + * of an unlimited virtual dataset with printf-style + * mappings. (\em Default: 0) + * + * \return \herr_t + * + * \details H5Pget_virtual_printf_gap() returns the maximum number of + * missing printf-style files and/or datasets for determining the + * extent of an unlimited virtual dataaset, \p gap_size, using + * the access property list for the virtual dataset, \p dapl_id. + * + * The default library value for \p gap_size is 0 (zero). + * + * \since 1.10.0 + * + */ +H5_DLL herr_t H5Pget_virtual_printf_gap(hid_t dapl_id, hsize_t *gap_size); +/** + * \ingroup DAPL + * + * \brief Retrieves the view of a virtual dataset accessed with + * \p dapl_id + * + * \dapl_id + * \param[out] view The flag specifying the view of the virtual dataset. + * Valid values are: + * \li #H5D_VDS_FIRST_MISSING + * \li #H5D_VDS_LAST_AVAILABLE + * + * \return \herr_t + * + * \details H5Pget_virtual_view() takes the virtual dataset access property + * list, \p dapl_id, and retrieves the flag, \p view, set by the + * H5Pset_virtual_view() call. + * + * \see_virtual + * + * \since 1.10.0 + * + */ +H5_DLL herr_t H5Pget_virtual_view(hid_t dapl_id, H5D_vds_view_t *view); +/** + * \ingroup DAPL + * + * \brief Sets two actions to perform when the size of a dataset’s + * dimension being appended reaches a specified boundary + * + * \dapl_id + * \param[in] ndims The number of elements for boundary + * \param[in] boundary The dimension sizes used to determine the boundary + * \param[in] func The user-defined callback function + * \param[in] udata The user-defined input data + * + * \return \herr_t + * + * \details H5Pset_append_flush() sets the following two actions to + * perform for a dataset associated with the dataset access + * property list \p dapl_id: + * + * \li Call the callback function \p func set in the property + * list + * \li Flush the dataset associated with the dataset access + * property list + * + * When a user is appending data to a dataset via H5DOappend() + * and the dataset’s newly extended dimension size hits a + * specified boundary, the library will perform the first action + * listed above. Upon return from the callback function, the + * library will then perform the second action listed above and + * return to the user. If no boundary is hit or set, the two + * actions above are not invoked. + * + * The specified boundary is indicated by the parameter + * \p boundary. It is a 1-dimensional array with \p ndims + * elements, which should be the same as the rank of the + * dataset’s dataspace. While appending to a dataset along a + * particular dimension index via H5Dappend(), the library + * determines a boundary is reached when the resulting dimension + * size is divisible by \p boundary[index]. A zero value for + * \p boundary[index] indicates no boundary is set for that + * dimension index. + * + * The setting of this property will apply only for a chunked + * dataset with an extendible dataspace. A dataspace is extendible + * when it is defined with either one of the following: + * + * \li A dataspace with fixed current and maximum dimension sizes + * \li A dataspace with at least one unlimited dimension for its + * maximum dimension size + * + * When creating or opening a chunked dataset, the library will + * check whether the boundary as specified in the access property + * list is set up properly. The library will fail the dataset + * create or open if the following conditions are true: + * + * \li \p ndims, the number of elements for boundary, is not the + * same as the rank of the dataset’s dataspace. + * \li A non-zero boundary value is specified for a non-extendible + * dimension. + * + * The callback function \p func must conform to the following + * prototype: + * \snippet H5Dpublic.h H5D_append_cb_t_snip + * + * The parameters of the callback function, per the above + * prototype, are defined as follows: + * + * \li \p dataset_id is the dataset identifier. + * \li \p cur_dims is the dataset’s current dimension sizes when + * a boundary is hit. + * \li \p user_data is the user-defined input data. + * + * \since 1.10.0 + * + */ +H5_DLL herr_t H5Pset_append_flush(hid_t dapl_id, unsigned ndims, const hsize_t boundary[], + H5D_append_cb_t func, void *udata); +/** + * \ingroup DAPL + * + * \brief Sets the raw data chunk cache parameters + * + * \dapl_id + * \param[in] rdcc_nslots The number of chunk slots in the raw data chunk + * cache for this dataset. Increasing this value + * reduces the number of cache collisions, but + * slightly increases the memory used. Due to the + * hashing strategy, this value should ideally be a + * prime number. As a rule of thumb, this value + * should be at least 10 times the number of chunks + * that can fit in \p rdcc_nbytes bytes. For maximum + * performance, this value should be set + * approximately 100 times that number of chunks. + * The default value is 521. If the value passed is + * #H5D_CHUNK_CACHE_NSLOTS_DEFAULT, then the + * property will not be set on \p dapl_id and the + * parameter will come from the file access + * property list used to open the file. + * \param[in] rdcc_nbytes The total size of the raw data chunk cache for + * this dataset. In most cases increasing this + * number will improve performance, as long as + * you have enough free memory. + * The default size is 1 MB. If the value passed is + * #H5D_CHUNK_CACHE_NBYTES_DEFAULT, then the + * property will not be set on \p dapl_id and the + * parameter will come from the file access + * property list. + * \param[in] rdcc_w0 The chunk preemption policy for this dataset. + * This must be between 0 and 1 inclusive and + * indicates the weighting according to which chunks + * which have been fully read or written are + * penalized when determining which chunks to flush + * from cache. A value of 0 means fully read or + * written chunks are treated no differently than + * other chunks (the preemption is strictly LRU) + * while a value of 1 means fully read or written + * chunks are always preempted before other chunks. + * If your application only reads or writes data + * once, this can be safely set to 1. Otherwise, + * this should be set lower, depending on how often + * you re-read or re-write the same data. + * The default value is 0.75. If the value passed is + * #H5D_CHUNK_CACHE_W0_DEFAULT, then the property + * will not be set on \p dapl_id and the parameter + * will come from the file access property list. + * + * \return \herr_t + * + * \details H5Pset_chunk_cache() sets the number of elements, the total + * number of bytes, and the preemption policy value in the raw + * data chunk cache on a dataset access property list. After + * calling this function, the values set in the property list + * will override the values in the file's file access property + * list. + * + * The raw data chunk cache inserts chunks into the cache + * by first computing a hash value using the address of a chunk, + * then using that hash value as the chunk's index into the table + * of cached chunks. The size of this hash table, i.e., and the + * number of possible hash values, is determined by the + * \p rdcc_nslots parameter. If a different chunk in the cache + * has the same hash value, this causes a collision, which + * reduces efficiency. If inserting the chunk into cache would + * cause the cache to be too big, then the cache is pruned + * according to the \p rdcc_w0 parameter. + * + * \b Motivation: H5Pset_chunk_cache() is used to adjust the chunk + * cache parameters on a per-dataset basis, as opposed to a global + * setting for the file using H5Pset_cache(). The optimum chunk + * cache parameters may vary widely with different data layout and + * access patterns, so for optimal performance they must be set + * individually for each dataset. It may also be beneficial to + * reduce the size of the chunk cache for datasets whose + * performance is not important in order to save memory space. + * + * \b Example \b Usage: The following code sets the chunk cache to + * use a hash table with 12421 elements and a maximum size of + * 16 MB, while using the preemption policy specified for the + * entire file: + * \Code{ + * H5Pset_chunk_cache(dapl_id, 12421, 16*1024*1024, + * H5D_CHUNK_CACHE_W0_DEFAULT);} + * + * \b Usage \b Notes: The chunk cache size is a property for + * accessing a dataset and is not stored with a dataset or a + * file. To guarantee the same chunk cache settings each time + * the dataset is opened, call H5Dopen() with a dataset access + * property list where the chunk cache size is set by calling + * H5Pset_chunk_cache() for that property list. The property + * list can be used for multiple accesses in the same + * application. + * + * For files where the same chunk cache size will be + * appropriate for all or most datasets, H5Pset_cache() can + * be called with a file access property list to set the + * chunk cache size for accessing all datasets in the file. + * + * Both methods can be used in combination, in which case + * the chunk cache size set by H5Pset_cache() will apply + * except for specific datasets where H5Dopen() is called + * with dataset property list with the chunk cache size + * set by H5Pset_chunk_cache(). + * + * In the absence of any cache settings, H5Dopen() will + * by default create a 1 MB chunk cache for the opened + * dataset. If this size happens to be appropriate, no + * call will be needed to either function to set the + * chunk cache size. + * + * It is also possible that a change in access pattern + * for later access to a dataset will change the + * appropriate chunk cache size. + * + * \since 1.8.3 + * + */ +H5_DLL herr_t H5Pset_chunk_cache(hid_t dapl_id, size_t rdcc_nslots, size_t rdcc_nbytes, double rdcc_w0); +/** + * \ingroup DAPL + * + * \brief Sets the external dataset storage file prefix in the dataset + * access property list + * + * \dapl_id + * \param[in] prefix Dataset external storage prefix in UTF-8 or ASCII + * (<em>Path and filename must be ASCII on Windows systems.</em>) + * + * \return \herr_t + * + * \details H5Pset_efile_prefix() sets the prefix used to locate raw data + * files for a dataset that uses external storage. This prefix + * can provide either an absolute path or a relative path to the + * external files. + * + * H5Pset_efile_prefix() is used in conjunction with + * H5Pset_external() to control the behavior of the HDF5 library + * when searching for the raw data files associated with a dataset + * that uses external storage: + * + * \li The default behavior of the library is to search for the + * dataset’s external storage raw data files in the same + * directory as the HDF5 file which contains the dataset. + * \li If the prefix is set to an absolute path, the target + * directory will be searched for the dataset’s external + * storage raw data files. + * \li If the prefix is set to a relative path, the target + * directory, relative to the current working directory, will + * be searched for the dataset’s external storage raw data + * files. + * \li If the prefix is set to a relative path that begins with + * the special token ${ORIGIN}, that directory, relative to + * the HDF5 file containing the dataset, will be searched for + * the dataset’s external storage raw data files. + * + * The HDF5_EXTFILE_PREFIX environment variable can be used to + * override the above behavior (the environment variable + * supersedes the API call). Setting the variable to a path + * string and calling H5Dcreate() or H5Dopen() is the equivalent + * of calling H5Pset_efile_prefix() and calling the same create + * or open function. The environment variable is checked at the + * time of the create or open action and copied so it can be + * safely changed after the H5Dcreate() or H5Dopen() call. + * + * Calling H5Pset_efile_prefix() with \p prefix set to NULL or + * the empty string returns the search path to the default. The + * result would be the same as if H5Pset_efile_prefix() had never + * been called. + * + * \note If the external file prefix is not an absolute path and the HDF5 + * file is moved, the external storage files will also need to be + * moved so they can be accessed at the new location. + * + * \note As stated above, the use of the HDF5_EXTFILE_PREFIX environment + * variable overrides any property list setting. + * H5Pset_efile_prefix() and H5Pget_efile_prefix(), being property + * functions, set and retrieve only the property list setting; they + * are unaware of the environment variable. + * + * \note On Windows, the prefix must be an ASCII string since the Windows + * standard C library’s I/O functions cannot handle UTF-8 file names. + * + * \since 1.10.0, 1.8.17 + * + */ +H5_DLL herr_t H5Pset_efile_prefix(hid_t dapl_id, const char *prefix); +/** + * \ingroup DAPL + * + * \brief Sets prefix to be applied to VDS source file paths + * + * \dapl_id + * \param[in] prefix Prefix to be applied to VDS source file paths + * + * \return \herr_t + * + * \details H5Pset_virtual_prefix() sets the prefix to be applied to the + * path of any VDS source files traversed. The prefix is prepended + * to the filename stored in the VDS virtual file, set with + * H5Pset_virtual(). + * + * The prefix is specified in the user-allocated buffer \p prefix + * and set in the dataset access property list \p dapl_id. The + * buffer should not be freed until the property list has been + * closed. + * + * \see_virtual + * + * \since 1.10.2 + * + */ +H5_DLL herr_t H5Pset_virtual_prefix(hid_t dapl_id, const char *prefix); +/** + * \ingroup DAPL + * + * \brief Sets the maximum number of missing source files and/or datasets + * with the printf-style names when getting the extent of an + * unlimited virtual dataset + * + * \dapl_id + * \param[in] gap_size Maximum number of files and/or datasets allowed to + * be missing for determining the extent of an + * unlimited virtual dataset with printf-style + * mappings (<em>Default value</em>: 0) + * + * \return \herr_t + * + * \details H5Pset_virtual_printf_gap() sets the access property list for + * the virtual dataset, \p dapl_id, to instruct the library to + * stop looking for the mapped data stored in the files and/or + * datasets with the printf-style names after not finding + * \p gap_size files and/or datasets. The found source files and + * datasets will determine the extent of the unlimited virtual + * dataset with the printf-style mappings. + * + * Consider the following examples where the regularly spaced + * blocks of a virtual dataset are mapped to datasets with the + * names d-1, d-2, d-3, ..., d-N, ... : + * + * \li If the dataset d-2 is missing and \p gap_size is set to 0, + * then the virtual dataset will contain only data found + * in d-1. + * \li If d-2 and d-3 are missing and \p gap_size is set to 2, + * then the virtual dataset will contain the data from + * d-1, d-3, ..., d-N, ... . The blocks that are mapped to + * d-2 and d-3 will be filled according to the virtual + * dataset’s fill value setting. + * + * \see_virtual + * + * \since 1.10.0 + * + */ +H5_DLL herr_t H5Pset_virtual_printf_gap(hid_t dapl_id, hsize_t gap_size); +/** + * \ingroup DAPL + * + * \brief Sets the view of the virtual dataset (VDS) to include or exclude + * missing mapped elements + * + * \dapl_id + * \param[in] view Flag specifying the extent of the data to be included + * in the view. Valid values are: + * \li #H5D_VDS_FIRST_MISSING: View includes all data + * before the first missing mapped data + * \li #H5D_VDS_LAST_AVAILABLE View includes all + * available mapped data + * + * \return \herr_t + * + * \details H5Pset_virtual_view() takes the access property list for the + * virtual dataset, \p dapl_id, and the flag, \p view, and sets + * the VDS view according to the flag value. + * + * If \p view is set to #H5D_VDS_FIRST_MISSING, the view includes + * all data before the first missing mapped data. This setting + * provides a view containing only the continuous data starting + * with the dataset’s first data element. Any break in + * continuity terminates the view. + * + * If \p view is set to #H5D_VDS_LAST_AVAILABLE, the view + * includes all available mapped data. + * + * Missing mapped data is filled with the fill value set in the + * VDS creation property list. + * + * \see_virtual + * + * \since 1.10.0 + * + */ +H5_DLL herr_t H5Pset_virtual_view(hid_t dapl_id, H5D_vds_view_t view); /* Dataset xfer property list (DXPL) routines */ -H5_DLL herr_t H5Pset_data_transform(hid_t plist_id, const char *expression); -H5_DLL ssize_t H5Pget_data_transform(hid_t plist_id, char *expression /*out*/, size_t size); -H5_DLL herr_t H5Pset_buffer(hid_t plist_id, size_t size, void *tconv, void *bkg); -H5_DLL size_t H5Pget_buffer(hid_t plist_id, void **tconv /*out*/, void **bkg /*out*/); -H5_DLL herr_t H5Pset_preserve(hid_t plist_id, hbool_t status); -H5_DLL int H5Pget_preserve(hid_t plist_id); -H5_DLL herr_t H5Pset_edc_check(hid_t plist_id, H5Z_EDC_t check); +/** + * + * \ingroup DXPL + * + * \brief Gets B-tree split ratios for a dataset transfer property list + * + * \dxpl_id{plist_id} + * \param[out] left The B-tree split ratio for left-most nodes + * \param[out] middle The B-tree split ratio for right-most nodes and lone nodes + * \param[out] right The B-tree split ratio for all other nodes + * \return \herr_t + * + * \details H5Pget_btree_ratios() returns the B-tree split ratios for a dataset + * transfer property list. + * + * The B-tree split ratios are returned through the non-NULL arguments + * \p left, \p middle, and \p right, as set by the H5Pset_btree_ratios() + * function. + * + */ +H5_DLL herr_t H5Pget_btree_ratios(hid_t plist_id, double *left /*out*/, double *middle /*out*/, + double *right /*out*/); +/** + * + * \ingroup DXPL + * + * \brief Reads buffer settings + * + * \param[in] plist_id Identifier for the dataset transfer property list + * \param[out] tconv Address of the pointer to application-allocated type + * conversion buffer + * \param[out] bkg Address of the pointer to application-allocated + * background buffer + * + * \return Returns buffer size, in bytes, if successful; otherwise 0 on failure. + * + * \details H5Pget_buffer() reads values previously set with H5Pset_buffer(). + * + * \version 1.6.0 The return type changed from \p hsize_t to \p size_t. + * \version 1.4.0 The return type changed to \p hsize_t. + * + */ +H5_DLL size_t H5Pget_buffer(hid_t plist_id, void **tconv /*out*/, void **bkg /*out*/); +/** + * + * \ingroup DXPL + * + * \brief Retrieves a data transform expression + * + * \param[in] plist_id Identifier of the property list or class + * \param[out] expression Pointer to memory where the transform expression will + * be copied + * \param[in] size Number of bytes of the transform expression to copy + * to + * + * \return Success: the size of the transform expression. Failure: a negative + * value. + * + * \details H5Pget_data_transform() retrieves the data transform expression + * previously set in the dataset transfer property list \p plist_id + * by H5Pset_data_transform(). + * + * H5Pget_data_transform() can be used to both retrieve the transform + * expression and query its size. + * + * If \p expression is non-NULL, up to \p size bytes of the data + * transform expression are written to the buffer. If \p expression + * is NULL, \p size is ignored, and the function does not write + * anything to the buffer. The function always returns the size of + * the data transform expression. + * + * If 0 is returned for the size of the expression, no data transform + * expression exists for the property list. + * + * If an error occurs, the buffer pointed to by \p expression is + * unchanged, and the function returns a negative value. + * + * \par Example + * An example snippet from examples/h5_dtransform.c: + * \snippet h5_dtransform.c H5Pget_data_transform_snip + * + * \since 1.8.0 + * + */ +H5_DLL ssize_t H5Pget_data_transform(hid_t plist_id, char *expression /*out*/, size_t size); +/** + * + * \ingroup DXPL + * + * \brief Determines whether error-detection is enabled for dataset reads + * + * \param[in] plist_id Dataset transfer property list identifier + * + * \return Returns \p H5Z_ENABLE_EDC or \p H5Z_DISABLE_EDC if successful; + * otherwise returns a negative value. + * + * \details H5Pget_edc_check() queries the dataset transfer property + * list \p plist to determine whether error detection is enabled for + * data read operations. + * + * \since 1.6.0 + * + */ H5_DLL H5Z_EDC_t H5Pget_edc_check(hid_t plist_id); -H5_DLL herr_t H5Pset_filter_callback(hid_t plist_id, H5Z_filter_func_t func, void *op_data); -H5_DLL herr_t H5Pset_btree_ratios(hid_t plist_id, double left, double middle, double right); -H5_DLL herr_t H5Pget_btree_ratios(hid_t plist_id, double *left /*out*/, double *middle /*out*/, - double *right /*out*/); -H5_DLL herr_t H5Pset_vlen_mem_manager(hid_t plist_id, H5MM_allocate_t alloc_func, void *alloc_info, - H5MM_free_t free_func, void *free_info); -H5_DLL herr_t H5Pget_vlen_mem_manager(hid_t plist_id, H5MM_allocate_t *alloc_func, void **alloc_info, - H5MM_free_t *free_func, void **free_info); -H5_DLL herr_t H5Pset_hyper_vector_size(hid_t fapl_id, size_t size); -H5_DLL herr_t H5Pget_hyper_vector_size(hid_t fapl_id, size_t *size /*out*/); -H5_DLL herr_t H5Pset_type_conv_cb(hid_t dxpl_id, H5T_conv_except_func_t op, void *operate_data); -H5_DLL herr_t H5Pget_type_conv_cb(hid_t dxpl_id, H5T_conv_except_func_t *op, void **operate_data); +/** + * + * \ingroup DXPL + * + * \brief Retrieves number of I/O vectors to be read/written in hyperslab I/O + * + * \param[in] fapl_id Dataset transfer property list identifier + * \param[out] size Number of I/O vectors to accumulate in memory for I/O operations + * + * \return \herr_t + * + * \details H5Pget_hyper_vector_size() retrieves the number of I/O vectors to be accumulated in + * memory before being issued to the lower levels of the HDF5 library for reading or + * writing the actual data. + * + * The number of I/O vectors set in the dataset transfer property list \p fapl_id is + * returned in \p size. Unless the default value is in use, \p size was + * previously set with a call to H5Pset_hyper_vector_size(). + * + * \since 1.6.0 + * + */ +H5_DLL herr_t H5Pget_hyper_vector_size(hid_t fapl_id, size_t *size /*out*/); +/** + * + * \ingroup DXPL + * + * \brief Checks status of the dataset transfer property list (\b DEPRECATED) + * + * \deprecated{H5Pget_preserve() is deprecated as it is no longer useful; + * compound datatype field preservation is now core functionality + * in the HDF5 library.} + * + * \param[in] plist_id Identifier for the dataset transfer property list + * + * \return Returns 1 or 0 if successful; otherwise returns a negative value. + * + * \details H5Pget_preserve() checks the status of the dataset transfer + * property list. + * + * \version 1.6.0 The flag parameter was changed from INTEGER to LOGICAL to + * better match the C API. (Fortran 90) + * + */ +H5_DLL int H5Pget_preserve(hid_t plist_id); +/** + * + * \ingroup DXPL + * + * \brief Gets user-defined datatype conversion callback function + * + * \param[in] dxpl_id Dataset transfer property list identifier + * \param[out] op User-defined type conversion callback function + * \param[out] operate_data User-defined input data for the callback function + * + * \return \herr_t + * + * \details H5Pget_type_conv_cb() gets the user-defined datatype conversion + * callback function \p op in the dataset transfer property list + * \p dxpl_id. + * + * The parameter \p operate_data is a pointer to user-defined input + * data for the callback function. + * + * The callback function \p op defines the actions an application is + * to take when there is an exception during datatype conversion. + * + * Please refer to the function H5Pset_type_conv_cb() for more details. + * + */ +H5_DLL herr_t H5Pget_type_conv_cb(hid_t dxpl_id, H5T_conv_except_func_t *op, void **operate_data); +/** + * + * \ingroup DXPL + * + * \brief Gets the memory manager for variable-length datatype allocation in H5Dread() and H5Dvlen_reclaim() + * + * \param[in] plist_id Identifier for the dataset transfer property list + * \param[out] alloc_func User's allocate routine, or NULL for system malloc + * \param[out] alloc_info Extra parameter for user’s allocation routine. + * Contents are ignored if preceding + * parameter is NULL \param[out] free_func User's free routine, or NULL for + * system free \param[out] free_info + * Extra parameter for user’s free routine. Contents are ignored if preceding + * parameter is NULL + * + * \return \herr_t + * + * \details H5Pget_vlen_mem_manager() is the companion function to + * H5Pset_vlen_mem_manager(), returning the parameters set by + * that function. + * + */ +H5_DLL herr_t H5Pget_vlen_mem_manager(hid_t plist_id, H5MM_allocate_t *alloc_func, void **alloc_info, + H5MM_free_t *free_func, void **free_info); +/** + * + * \ingroup DXPL + * + * \brief Sets B-tree split ratios for a dataset transfer property list + * + * \param[in] plist_id The dataset transfer property list identifier + * \param[in] left The B-tree split ratio for left-most nodes + * \param[in] middle The B-tree split ratio for all other nodes + * \param[in] right The B-tree split ratio for right-most nodes and lone + * nodes + * + * \return \herr_t + * + * \details H5Pset_btree_ratios() sets the B-tree split ratios for a dataset + * transfer property list. The split ratios determine what percent of + * children go in the first node when a node splits. + * + * The ratio \p left is used when the splitting node is the left-most + * node at its level in the tree; + * the ratio \p right is used when the splitting node is the right-most + * node at its level; and + * the ratio \p middle is used for all other cases. + * + * A node that is the only node at its level in the tree uses the + * ratio \p right when it splits. + * + * All ratios are real numbers between 0 and 1, inclusive. + * + */ +H5_DLL herr_t H5Pset_btree_ratios(hid_t plist_id, double left, double middle, double right); + +/** + * + * \ingroup DXPL + * + * \brief Sets type conversion and background buffers + * + * \dxpl_id{plist_id} + * \param[in] size Size, in bytes, of the type conversion and background buffers + * \param[in] tconv Pointer to application-allocated type conversion buffer + * \param[in] bkg Pointer to application-allocated background buffer + * \return \herr_t + * + * \details Given a dataset transfer property list, H5Pset_buffer() sets the + * maximum size for the type conversion buffer and background buffer + * and optionally supplies pointers to application-allocated + * buffers. If the buffer size is smaller than the entire amount of + * data being transferred between the application and the file, and a + * type conversion buffer or background buffer is required, then strip + * mining will be used. + * + * Note that there are minimum size requirements for the buffer. Strip + * mining can only break the data up along the first dimension, so the + * buffer must be large enough to accommodate a complete slice that + * encompasses all of the remaining dimensions. For example, when strip + * mining a \Code{100x200x300} hyperslab of a simple data space, the + * buffer must be large enough to hold \Code{1x200x300} data + * elements. When strip mining a \Code{100x200x300x150} hyperslab of a + * simple data space, the buffer must be large enough to hold + * \Code{1x200x300x150} data elements. + * + * If \p tconv and/or \p bkg are null pointers, then buffers will be + * allocated and freed during the data transfer. + * + * The default value for the maximum buffer is 1 MiB. + * + * \version 1.6.0 The \p size parameter has changed from type hsize_t to \c size_t. + * \version 1.4.0 The \p size parameter has changed to type hsize_t. + * + */ +H5_DLL herr_t H5Pset_buffer(hid_t plist_id, size_t size, void *tconv, void *bkg); + +/** + * \ingroup DXPL + * + * \brief Sets a data transform expression + * + * \dxpl_id{plist_id} + * \param[in] expression Pointer to the null-terminated data transform + * expression + * \return \herr_t + * + * \details H5Pset_data_transform() sets the data transform to be used for + * reading and writing data. This function operates on the dataset + * transfer property list \p plist_id. + * + * The \p expression parameter is a string containing an algebraic + * expression, such as \Code{(5/9.0)*(x-32)} or \Code{x*(x-5)}. When a + * dataset is read or written with this property list, the transform + * expression is applied with the \c x being replaced by the values in + * the dataset. When reading data, the values in the file are not + * changed and the transformed data is returned to the user. + * + * Data transforms can only be applied to integer or + * floating-point datasets. Order of operations is obeyed and + * the only supported operations are +, -, *, and /. Parentheses + * can be nested arbitrarily and can be used to change precedence. + * When writing data back to the dataset, the transformed data is + * written to the file and there is no way to recover the original + * values to which the transform was applied. + * + * \since 1.8.0 + * + */ +H5_DLL herr_t H5Pset_data_transform(hid_t plist_id, const char *expression); + +/** + * \ingroup DXPL + * + * \brief Sets the dataset transfer property list to enable or disable error + * detection when reading data + * + * \dxpl_id{plist_id} + * \param[in] check Specifies whether error checking is enabled or disabled + * for dataset read operations + * \return \herr_t + * + * \details H5Pset_edc_check() sets the dataset transfer property list \p plist + * to enable or disable error detection when reading data. + * + * Whether error detection is enabled or disabled is specified in the + * \p check parameter. Valid values are #H5Z_ENABLE_EDC (default) and + * #H5Z_DISABLE_EDC. + * + * \note The initial error detection implementation, Fletcher32 checksum, + * supports error detection for chunked datasets only. + * + * \attention The Fletcher32 EDC checksum filter, set with H5Pset_fletcher32(), + * was added in HDF5 Release 1.6.0. In the original implementation, + * however, the checksum value was calculated incorrectly on + * little-endian systems. The error was fixed in HDF5 Release 1.6.3.\n + * As a result of this fix, an HDF5 library of Release 1.6.0 through + * Release 1.6.2 cannot read a dataset created or written with + * Release 1.6.3 or later if the dataset was created with the + * checksum filter and the filter is enabled in the reading + * library. (Libraries of Release 1.6.3 and later understand the + * earlier error and compensate appropriately.)\n + * \Bold{Work-around:} An HDF5 library of Release 1.6.2 or earlier + * will be able to read a dataset created or written with the + * checksum filter by an HDF5 library of Release 1.6.3 or later if + * the checksum filter is disabled for the read operation. This can + * be accomplished via an H5Pset_edc_check() call with the value + * #H5Z_DISABLE_EDC in the second parameter. This has the obvious + * drawback that the application will be unable to verify the + * checksum, but the data does remain accessible. + * + * \version 1.6.3 Error in checksum calculation on little-endian systems + * corrected in this release. + * \since 1.6.0 + * + */ +H5_DLL herr_t H5Pset_edc_check(hid_t plist_id, H5Z_EDC_t check); + +/** + * \ingroup DXPL + * + * \brief Sets user-defined filter callback function + * + * \dxpl_id{plist_id} + * \param[in] func User-defined filter callback function + * \param[in] op_data User-defined input data for the callback function + * \return \herr_t + * + * \details H5Pset_filter_callback() sets the user-defined filter callback + * function \p func in the dataset transfer property list \p plist_id. + * + * The parameter \p op_data is a pointer to user-defined input data for + * the callback function and will be passed through to the callback + * function. + * + * The callback function \p func defines the actions an application is + * to take when a filter fails. The function prototype is as follows: + * \snippet H5Zpublic.h H5Z_filter_func_t_snip + * where \c filter indicates which filter has failed, \c buf and \c buf_size + * are used to pass in the failed data, and op_data is the required + * input data for this callback function. + * + * Valid callback function return values are #H5Z_CB_FAIL and #H5Z_CB_CONT. + * + * \since 1.6.0 + * + */ +H5_DLL herr_t H5Pset_filter_callback(hid_t plist_id, H5Z_filter_func_t func, void *op_data); + +/** + * \ingroup DXPL + * + * \brief Sets number of I/O vectors to be read/written in hyperslab I/O + * + * \dxpl_id{plist_id} + * \param[in] size Number of I/O vectors to accumulate in memory for I/O + * operations\n + * Must be greater than 1 (one)\n + * Default value: 1024 + * \return \herr_t + * + * \details H5Pset_hyper_vector_size() sets the number of I/O vectors to be + * accumulated in memory before being issued to the lower levels of + * the HDF5 library for reading or writing the actual data. + * + * The I/O vectors are hyperslab offset and length pairs and are + * generated during hyperslab I/O. + * + * The number of I/O vectors is passed in \p size to be set in the + * dataset transfer property list \p plist_id. \p size must be + * greater than 1 (one). + * + * H5Pset_hyper_vector_size() is an I/O optimization function; + * increasing vector_size should provide better performance, but the + * library will use more memory during hyperslab I/O. The default value + * of \p size is 1024. + * + * \since 1.6.0 + * + */ +H5_DLL herr_t H5Pset_hyper_vector_size(hid_t plist_id, size_t size); + +/** + * \ingroup DXPL + * + * \brief Sets the dataset transfer property list \p status + * + * \dxpl_id{plist_id} + * \param[in] status Status toggle of the dataset transfer property list + * \return \herr_t + * + * \deprecated This function is deprecated as it no longer has any effect; + * compound datatype field preservation is now core functionality in + * the HDF5 library. + * + * \details H5Pset_preserve() sets the dataset transfer property list status to + * \c 1 or \c 0. + * + * When reading or writing compound datatypes and the destination is + * partially initialized and the read/write is intended to initialize + * the other members, one must set this property to \c 1. Otherwise the + * I/O pipeline treats the destination datapoints as completely + * uninitialized. + * + * \todo Add missing version information: introduction, deprecation, etc. + * Why is the declaration not in the deprecated section? + * + */ +H5_DLL herr_t H5Pset_preserve(hid_t plist_id, hbool_t status); + +/** + * \ingroup DXPL + * + * \brief Sets user-defined datatype conversion callback function + * + * \dxpl_id + * \param[in] op User-defined type conversion callback function + * \param[in] operate_data User-defined input data for the callback function + * \return \herr_t + * + * \details H5Pset_type_conv_cb() sets the user-defined datatype conversion + * callback function \p op in the dataset transfer property list \p + * dxpl_id + * + * The parameter operate_data is a pointer to user-defined input data + * for the callback function and will be passed through to the callback + * function. + * + * The callback function \p op defines the actions an application is to + * take when there is an exception during datatype conversion. The + * function prototype is as follows: + * \snippet H5Tpublic.h H5T_conv_except_func_t_snip + * + * \todo Add version information. + * + */ +H5_DLL herr_t H5Pset_type_conv_cb(hid_t dxpl_id, H5T_conv_except_func_t op, void *operate_data); + +/** + * \ingroup DXPL + * + * \brief Sets the memory manager for variable-length datatype allocation in + * H5Dread() and H5Dvlen_reclaim() + * + * \dxpl_id{plist_id} + * \param[in] alloc_func User's allocate routine, or \c NULL for system \c malloc + * \param[in] alloc_info Extra parameter for user's allocation routine. + * Contents are ignored if preceding parameter is \c NULL. + * \param[in] free_func User's free routine, or \c NULL for system \c free + * \param[in] free_info Extra parameter for user's free routine. Contents are + * ignored if preceding parameter is \c NULL + * \return \herr_t + * + * \details H5Pset_vlen_mem_manager() sets the memory manager for + * variable-length datatype allocation in H5Dread() and free in + * H5Dvlen_reclaim(). + * + * The \p alloc_func and \p free_func parameters identify the memory + * management routines to be used. If the user has defined custom + * memory management routines, \p alloc_func and/or free_func should be + * set to make those routine calls (i.e., the name of the routine is + * used as the value of the parameter); if the user prefers to use the + * system's \c malloc and/or \c free, the \p alloc_func and \p + * free_func parameters, respectively, should be set to \c NULL + * + * The prototypes for these user-defined functions are as follows: + * \snippet H5MMpublic.h H5MM_allocate_t_snip + * + * \snippet H5MMpublic.h H5MM_free_t_snip + * + * The \p alloc_info and \p free_info parameters can be used to pass + * along any required information to the user's memory management + * routines. + * + * In summary, if the user has defined custom memory management + * routines, the name(s) of the routines are passed in the \p + * alloc_func and \p free_func parameters and the custom routines' + * parameters are passed in the \p alloc_info and \p free_info + * parameters. If the user wishes to use the system \c malloc and \c + * free functions, the \p alloc_func and/or \p free_func parameters are + * set to \c NULL and the \p alloc_info and \p free_info parameters are + * ignored. + * + * \todo Add version information. + */ +H5_DLL herr_t H5Pset_vlen_mem_manager(hid_t plist_id, H5MM_allocate_t alloc_func, void *alloc_info, + H5MM_free_t free_func, void *free_info); + #ifdef H5_HAVE_PARALLEL +/** + * \ingroup DXPL + * + * \brief Retrieves the type of chunk optimization that HDF5 actually performed + * on the last parallel I/O call (not necessarily the type requested) + * + * \dxpl_id{plist_id} + * \param[out] actual_chunk_opt_mode The type of chunk optimization performed by HDF5 + * \return \herr_t + * + * \par Motivation: + * A user can request collective I/O via a data transfer property list + * (DXPL) that has been suitably modified with H5Pset_dxpl_mpio(). + * However, HDF5 will sometimes ignore this request and perform independent + * I/O instead. This property allows the user to see what kind of I/O HDF5 + * actually performed. Used in conjunction with H5Pget_mpio_actual_io_mode(), + * this property allows the user to determine exactly what HDF5 did when + * attempting collective I/O. + * + * \details H5Pget_mpio_actual_chunk_opt_mode() retrieves the type of chunk + * optimization performed when collective I/O was requested. This + * property is set before I/O takes place, and will be set even if I/O + * fails. + * + * Valid values returned in \p actual_chunk_opt_mode: + * \snippet this H5D_mpio_actual_chunk_opt_mode_t_snip + * \click4more + * + * \since 1.8.8 + * + */ H5_DLL herr_t H5Pget_mpio_actual_chunk_opt_mode(hid_t plist_id, H5D_mpio_actual_chunk_opt_mode_t *actual_chunk_opt_mode); +/** + * \ingroup DXPL + * + * \brief Retrieves the type of I/O that HDF5 actually performed on the last + * parallel I/O call (not necessarily the type requested) + * + * \dxpl_id{plist_id} + * \param[out] actual_io_mode The type of I/O performed by this process + * \return \herr_t + * + * \par Motivation: + * A user can request collective I/O via a data transfer property list + * (DXPL) that has been suitably modified with H5Pset_dxpl_mpio(). + * However, HDF5 will sometimes ignore this request and perform independent + * I/O instead. This property allows the user to see what kind of I/O HDF5 + * actually performed. Used in conjunction with H5Pget_mpio_actual_chunk_opt_mode(), + * this property allows the user to determine exactly HDF5 did when + * attempting collective I/O. + * + * \details H5Pget_mpio_actual_io_mode() retrieves the type of I/O performed on + * the selection of the current process. This property is set after all + * I/O is completed; if I/O fails, it will not be set. + * + * Valid values returned in \p actual_io_mode: + * \snippet this H5D_mpio_actual_io_mode_t_snip + * \click4more + * + * \attention All processes do not need to have the same value. For example, if + * I/O is being performed using the multi chunk optimization scheme, + * one process's selection may include only chunks accessed + * collectively, while another may include chunks accessed + * independently. In this case, the first process will report + * #H5D_MPIO_CHUNK_COLLECTIVE while the second will report + * #H5D_MPIO_CHUNK_INDEPENDENT. + * + * \see H5Pget_mpio_no_collective_cause(), H5Pget_mpio_actual_chunk_opt_mode() + * + * \since 1.8.8 + * + */ H5_DLL herr_t H5Pget_mpio_actual_io_mode(hid_t plist_id, H5D_mpio_actual_io_mode_t *actual_io_mode); +/** + * \ingroup DXPL + * + * \brief Retrieves local and global causes that broke collective I/O on the last + * parallel I/O call + * + * \dxpl_id{plist_id} + * \param[out] local_no_collective_cause An enumerated set value indicating the + * causes that prevented collective I/O in the local process + * \param[out] global_no_collective_cause An enumerated set value indicating + * the causes across all processes that prevented collective I/O + * \return \herr_t + * + * \par Motivation: + * A user can request collective I/O via a data transfer property list (DXPL) + * that has been suitably modified with H5P_SET_DXPL_MPIO. However, there are + * conditions that can cause HDF5 to forgo collective I/O and perform + * independent I/O. Such causes can be different across the processes of a + * parallel application. This function allows the user to determine what + * caused the HDF5 library to skip collective I/O locally, that is in the + * local process, and globally, across all processes. + * + * \details H5Pget_mpio_no_collective_cause() serves two purposes. It can be + * used to determine whether collective I/O was used for the last + * preceding parallel I/O call. If collective I/O was not used, the + * function retrieves the local and global causes that broke collective + * I/O on that parallel I/O call. The properties retrieved by this + * function are set before I/O takes place and are retained even when + * I/O fails. + * + * Valid values returned in \p local_no_collective_cause and \p + * global_no_collective_cause are as follows or, if there are multiple + * causes, a bitwise OR of the relevant causes; the numbers in the + * center column are the bitmask values: + * \snippet this H5D_mpio_no_collective_cause_t_snip + * \click4more + * + * \attention Each process determines whether it can perform collective I/O and + * broadcasts the result. Those results are combined to make a + * collective decision; collective I/O will be performed only if all + * processes can perform collective I/O.\n + * If collective I/O was not used, the causes that prevented it are + * reported by individual process by means of an enumerated set. The + * causes may differ among processes, so H5Pget_mpio_no_collective_cause() + * returns two property values. The first value is the one produced + * by the local process to report local causes. This local information + * is encoded in an enumeration, the \ref H5D_mpio_no_collective_cause_t + * described above, with all individual causes combined into a single + * enumeration value by means of a bitwise OR operation. The second + * value reports global causes; this global value is the result of a + * bitwise-OR operation across the values returned by all the processes. + * + * \since 1.8.10 + * + */ H5_DLL herr_t H5Pget_mpio_no_collective_cause(hid_t plist_id, uint32_t *local_no_collective_cause, uint32_t *global_no_collective_cause); #endif /* H5_HAVE_PARALLEL */ /* Link creation property list (LCPL) routines */ -H5_DLL herr_t H5Pset_create_intermediate_group(hid_t plist_id, unsigned crt_intmd); +/** + * \ingroup ALCAPL + * + * \brief Determines whether property is set to enable creating missing + * intermediate groups + * + * \lcpl_id{plist_id} + * \param[out] crt_intmd Flag specifying whether to create intermediate + * groups upon creation of an object + * + * \return \herr_t + * + * \details H5Pget_create_intermediate_group() determines whether the link + * creation property list \p plist_id is set to allow functions + * that create objects in groups different from the current + * working group to create intermediate groups that may be + * missing in the path of a new or moved object. + * + * Functions that create objects in or move objects to a group + * other than the current working group make use of this + * property. H5Gcreate_anon() and H5Lmove() are examples of such + * functions. + * + * If \p crt_intmd is positive, missing intermediate groups will + * be created; if \p crt_intmd is non-positive, missing intermediate + * groups will not be created. + * + * \since 1.8.0 + * + */ H5_DLL herr_t H5Pget_create_intermediate_group(hid_t plist_id, unsigned *crt_intmd /*out*/); +/** + * \ingroup ALCAPL + * + * \brief Specifies in property list whether to create missing + * intermediate groups + * + * \lcpl_id{plist_id} + * \param[in] crt_intmd Flag specifying whether to create intermediate + * groups upon the creation of an object + * + * \return \herr_t + * + * \details H5Pset_create_intermediate_group() + * + * \since + * + */ +H5_DLL herr_t H5Pset_create_intermediate_group(hid_t plist_id, unsigned crt_intmd); /* Group creation property list (GCPL) routines */ -H5_DLL herr_t H5Pset_local_heap_size_hint(hid_t plist_id, size_t size_hint); -H5_DLL herr_t H5Pget_local_heap_size_hint(hid_t plist_id, size_t *size_hint /*out*/); -H5_DLL herr_t H5Pset_link_phase_change(hid_t plist_id, unsigned max_compact, unsigned min_dense); + +/** + * \ingroup GCPL + * + * \brief Returns the estimated link count and average link name length in a group + * + * \gcpl_id{plist_id} + * \param[out] est_num_entries The estimated number of links in the group + * referenced by \p plist_id + * \param[out] est_name_len The estimated average length of line names in the group + * referenced by \p plist_id + * \return \herr_t + * + * \details H5Pget_est_link_info() retrieves two settings from the group creation + * property list \p plist_id: the estimated number of links that are + * expected to be inserted into a group created with the property list + * and the estimated average length of those link names. + * + * The estimated number of links is returned in \p est_num_entries. The + * limit for \p est_num_entries is 64 K. + * + * The estimated average length of the anticipated link names is returned + * in \p est_name_len. The limit for \p est_name_len is 64 K. + * + * See \ref_group_impls for a discussion of the available types of HDF5 + * group structures. + * + * \since 1.8.0 + * + */ +H5_DLL herr_t H5Pget_est_link_info(hid_t plist_id, unsigned *est_num_entries /* out */, + unsigned *est_name_len /* out */); +/** + * \ingroup GCPL + * + * \brief Queries whether link creation order is tracked and/or indexed in + * a group + * + * \param[in] plist_id Group or file creation property list + * identifier + * \param[out] crt_order_flags Creation order flag(s) + * + * \return \herr_t + * + * \details H5Pget_link_creation_order() queries the group or file creation + * property list, \p plist_id, and returns a flag indicating whether + * link creation order is tracked and/or indexed in a group. + * + * See H5Pset_link_creation_order() for a list of valid creation + * order flags, as passed in \p crt_order_flags, and their + * meanings. + * + * \since 1.8.0 + * + */ +H5_DLL herr_t H5Pget_link_creation_order(hid_t plist_id, unsigned *crt_order_flags /* out */); +/** + * \ingroup GCPL + * + * \brief Queries the settings for conversion between compact and dense + * groups + * + * \gcpl_id{plist_id} + * \param[out] max_compact Maximum number of links for compact storage + * \param[out] min_dense Minimum number of links for dense storage + * + * \return \herr_t + * + * \details H5Pget_link_phase_change() queries the maximum number of + * entries for a compact group and the minimum number of links + * to require before converting a group to a dense form. + * + * In the compact format, links are stored as messages in the + * group’s header. In the dense format, links are stored in a + * fractal heap and indexed with a version 2 B-tree. + * + * \p max_compact is the maximum number of links to store as + * header messages in the group header before converting the + * group to the dense format. Groups that are in the compact + * format and exceed this number of links are automatically + * converted to the dense format. + * + * \p min_dense is the minimum number of links to store in the + * dense format. Groups which are in dense format and in which + * the number of links falls below this number are automatically + * converted back to the compact format. + * + * In the compact format, links are stored as messages in the + * group’s header. In the dense format, links are stored in a + * fractal heap and indexed with a version 2 B-tree. + * + * See H5Pset_link_phase_change() for a discussion of + * traditional, compact, and dense group storage. + * + * \since 1.8.0 + * + */ H5_DLL herr_t H5Pget_link_phase_change(hid_t plist_id, unsigned *max_compact /*out*/, unsigned *min_dense /*out*/); +/** + * \ingroup GCPL + * + * \brief Retrieves the anticipated size of the local heap for original-style + * groups + * + * \gcpl_id{plist_id} + * \param[out] size_hint Anticipated size of local heap + * \return \herr_t + * + * \details H5Pget_local_heap_size_hint() queries the group creation property + * list, \p plist_id, for the anticipated size of the local heap, \p + * size_hint, for original-style groups, i.e., for groups of the style + * used prior to HDF5 Release 1.8.0. See H5Pset_local_heap_size_hint() + * for further discussion. + * + * \since 1.8.0 + * + */ +H5_DLL herr_t H5Pget_local_heap_size_hint(hid_t plist_id, size_t *size_hint /*out*/); +/** + * \ingroup GCPL + * + * \brief Sets estimated number of links and length of link names in a group + * + * \gcpl_id{plist_id} + * \param[in] est_num_entries Estimated number of links to be inserted into group + * \param[in] est_name_len Estimated average length of link names + * \return \herr_t + * + * \details H5Pset_est_link_info() inserts two settings into the group creation + * property list plist_id: the estimated number of links that are + * expected to be inserted into a group created with the property list + * and the estimated average length of those link names. + * + * The estimated number of links is passed in \p est_num_entries. The + * limit for \p est_num_entries is 64 K. + * + * The estimated average length of the anticipated link names is passed + * in \p est_name_len. The limit for \p est_name_len is 64 K. + * + * The values for these two settings are multiplied to compute the + * initial local heap size (for old-style groups, if the local heap + * size hint is not set) or the initial object header size for + * (new-style compact groups; see \ref_group_impls). Accurately setting + * these parameters will help reduce wasted file space. + * + * If a group is expected to have many links and to be stored in dense + * format, set \p est_num_entries to 0 (zero) for maximum + * efficiency. This will prevent the group from being created in the + * compact format. + * + * See \ref_group_impls for a discussion of the available types of HDF5 + * group structures. + * + * \since 1.8.0 + * + */ H5_DLL herr_t H5Pset_est_link_info(hid_t plist_id, unsigned est_num_entries, unsigned est_name_len); -H5_DLL herr_t H5Pget_est_link_info(hid_t plist_id, unsigned *est_num_entries /* out */, - unsigned *est_name_len /* out */); +/** + * \ingroup GCPL + * + * \brief Sets creation order tracking and indexing for links in a group + * + * \param[in] plist_id Group or file creation property list + * identifier + * \param[out] crt_order_flags Creation order flag(s) + * + * \return \herr_t + * + * \details H5Pset_link_creation_order() sets flags for tracking and + * indexing links on creation order in groups created with the + * group (or file) creation property list \p plist_id. + * + * \p crt_order_flags contains flags with the following meanings: + * + * <table> + * <tr> + * <td>#H5P_CRT_ORDER_TRACKED</td> + * <td>Link creation order is tracked but not necessarily + * indexed</td> + * </tr> + * <tr> + * <td>#H5P_CRT_ORDER_INDEXED</td> + * <td>Link creation order is indexed (requires + * #H5P_CRT_ORDER_TRACKED)</td> + * </tr> + * </table> + * + * The default behavior is that links are tracked and indexed by + * name, and link creation order is neither tracked nor indexed. + * The name is always the primary index for links in a group. + * + * H5Pset_link_creation_order() can be used to set link creation + * order tracking, or to set link creation order tracking and + * indexing. + * + * If (#H5P_CRT_ORDER_TRACKED | #H5P_CRT_ORDER_INDEXED) is + * specified for \p crt_order_flags, then links will be tracked + * and indexed by creation order. The creation order is added as + * a secondary index and enables faster queries and iterations + * by creation order. + * + * If just #H5P_CRT_ORDER_TRACKED is specified for + * \p crt_order_flags, then links will be tracked by creation + * order, but not indexed by creation order. Queries and iterations + * by creation order will work but will be much slower for large + * groups than if #H5P_CRT_ORDER_INDEXED had been included. + * + * \note If a creation order index is to be built, it must be specified in + * the group creation property list. HDF5 currently provides no + * mechanism to turn on link creation order tracking at group + * creation time and to build the index later. + * + * \since 1.8.0 + * + */ H5_DLL herr_t H5Pset_link_creation_order(hid_t plist_id, unsigned crt_order_flags); -H5_DLL herr_t H5Pget_link_creation_order(hid_t plist_id, unsigned *crt_order_flags /* out */); +/** + * \ingroup GCPL + * + * \brief Sets the parameters for conversion between compact and dense + * groups + * + * \gcpl_id{plist_id} + * \param[in] max_compact Maximum number of links for compact storage + * (\a Default: 8) + * \param[in] min_dense Minimum number of links for dense storage + * (\a Default: 6) + * + * \return \herr_t + * + * \details H5Pset_link_phase_change() sets the maximum number of entries + * for a compact group and the minimum number of links to allow + * before converting a dense group back to the compact format. + * + * \p max_compact is the maximum number of links to store as + * header messages in the group header before converting the + * group to the dense format. Groups that are in compact format + * and which exceed this number of links are automatically + * converted to dense format. + * + * \p min_dense is the minimum number of links to store in the + * dense format. Groups which are in dense format and in which + * the number of links falls below this threshold are + * automatically converted to compact format. + * + * \since 1.8.0 + * + */ +H5_DLL herr_t H5Pset_link_phase_change(hid_t plist_id, unsigned max_compact, unsigned min_dense); +/** + * \ingroup GCPL + * + * \brief Specifies the anticipated maximum size of a local heap + * + * \gcpl_id{plist_id} + * \param[in] size_hint Anticipated maximum size in bytes of local heap + * \return \herr_t + * + * \details H5Pset_local_heap_size_hint() is used with original-style HDF5 + * groups (see “Motivation” below) to specify the anticipated maximum + * local heap size, size_hint, for groups created with the group + * creation property list \p plist_id. The HDF5 library then uses \p + * size_hint to allocate contiguous local heap space in the file for + * each group created with \p plist_id. + * + * For groups with many members or very few members, an appropriate + * initial value of \p size_hint would be the anticipated number of + * group members times the average length of group member names, plus a + * small margin: + * \code + * size_hint = max_number_of_group_members * + * (average_length_of_group_member_link_names + 2) + * \endcode + * If it is known that there will be groups with zero members, the use + * of a group creation property list with \p size_hint set to to 1 (one) + * will guarantee the smallest possible local heap for each of those groups. + * + * Setting \p size_hint to zero (0) causes the library to make a + * reasonable estimate for the default local heap size. + * + * \par Motivation: + * In situations where backward-compatibility is required, specifically, when + * libraries prior to HDF5 Release 1.8.0 may be used to read the file, groups + * must be created and maintained in the original style. This is HDF5’s default + * behavior. If backward compatibility with pre-1.8.0 libraries is not a concern, + * greater efficiencies can be obtained with the new-format compact and indexed + * groups. See <a href="https://portal.hdfgroup.org/display/HDF5/Groups">Group + * implementations in HDF5</a> in the \ref H5G API introduction (at the bottom).\n + * H5Pset_local_heap_size_hint() is useful for tuning file size when files + * contain original-style groups with either zero members or very large + * numbers of members.\n + * The original style of HDF5 groups, the only style available prior to HDF5 + * Release 1.8.0, was well-suited for moderate-sized groups but was not optimized + * for either very small or very large groups. This original style remains the + * default, but two new group implementations were introduced in HDF5 Release 1.8.0: + * compact groups to accommodate zero to small numbers of members and indexed groups + * for thousands or tens of thousands of members ... or millions, if that's what + * your application requires.\n + * The local heap size hint, \p size_hint, is a performance tuning parameter for + * original-style groups. As indicated above, an HDF5 group may have zero, a handful, + * or tens of thousands of members. Since the original style of HDF5 groups stores the + * metadata for all of these group members in a uniform format in a local heap, the size + * of that metadata (and hence, the size of the local heap) can vary wildly from group + * to group. To intelligently allocate space and to avoid unnecessary fragmentation of + * the local heap, it can be valuable to provide the library with a hint as to the local + * heap’s likely eventual size. This can be particularly valuable when it is known that + * a group will eventually have a great many members. It can also be useful in conserving + * space in a file when it is known that certain groups will never have any members. + * + * \since 1.8.0 + * + */ +H5_DLL herr_t H5Pset_local_heap_size_hint(hid_t plist_id, size_t size_hint); /* Map access property list (MAPL) routines */ #ifdef H5_HAVE_MAP_API +/** + * \ingroup MAPL + * + * \brief Set map iteration hints + * + * \mapl_id + * \param[in] key_prefetch_size Number of keys to prefetch at a time during + * iteration + * \param[in] key_alloc_size The initial size of the buffer allocated to hold + * prefetched keys + * \return \herr_t + * + * \details H5Pset_map_iterate_hints() adjusts the behavior of H5Miterate() when + * prefetching keys for iteration. The \p key_prefetch_size parameter + * specifies the number of keys to prefetch at a time during + * iteration. The \p key_alloc_size parameter specifies the initial + * size of the buffer allocated to hold these prefetched keys. If this + * buffer is too small it will be reallocated to a larger size, though + * this may result in an additional I/O. + * + * \since 1.12.0 + * + */ H5_DLL herr_t H5Pset_map_iterate_hints(hid_t mapl_id, size_t key_prefetch_size, size_t key_alloc_size); +/** + * \ingroup MAPL + * + * \brief Set map iteration hints + * + * \mapl_id + * \param[out] key_prefetch_size Pointer to number of keys to prefetch at a time + * during iteration + * \param[out] key_alloc_size Pointer to the initial size of the buffer allocated + * to hold prefetched keys + * \return \herr_t + * + * \details H5Pget_map_iterate() returns the map iterate hints, \p key_prefetch_size + * and \p key_alloc_size, as set by H5Pset_map_iterate_hints(). + * + * \since 1.12.0 + * + */ H5_DLL herr_t H5Pget_map_iterate_hints(hid_t mapl_id, size_t *key_prefetch_size /*out*/, size_t *key_alloc_size /*out*/); #endif /* H5_HAVE_MAP_API */ /* String creation property list (STRCPL) routines */ -H5_DLL herr_t H5Pset_char_encoding(hid_t plist_id, H5T_cset_t encoding); +/** + * \ingroup ALCAPL + * + * \brief Retrieves the character encoding used to create a link or + * attribute name + * + * \param[in] plist_id Link creation or attribute creation property list + * identifier + * \param[out] encoding String encoding character set + * + * \return \herr_t + * + * \details H5Pget_char_encoding() retrieves the character encoding used + * to encode link or attribute names that are created with the + * property list \p plist_id. + * + * Valid values for \p encoding are defined in H5Tpublic.h and + * include the following: + * + * \csets + * + * \note H5Pget_char_encoding() retrieves the character set used for an + * HDF5 link or attribute name while H5Tget_cset() retrieves the + * character set used in a character or string datatype. + * + * \since 1.8.0 + * + */ H5_DLL herr_t H5Pget_char_encoding(hid_t plist_id, H5T_cset_t *encoding /*out*/); +/** + * \ingroup ALCAPL + * + * \brief Sets the character encoding used to encode link and attribute + * names + * + * \param[in] plist_id Link creation or attribute creation property list + * identifier + * \param[in] encoding String encoding character set + * + * \return \herr_t + * + * \details H5Pset_char_encoding() sets the character encoding used for + * the names of links (which provide the names by which objects + * are referenced) or attributes created with the property list + * \p plist_id. + * + * Valid values for encoding include the following: + * \csets + * \details For example, if the character set for the property list + * \p plist_id is set to #H5T_CSET_UTF8, link names pointing to + * objects created with the link creation property list + * \p plist_id will be encoded using the UTF-8 character set. + * Similarly, names of attributes created with the attribute + * creation property list \p plist_id will be encoded as UTF-8. + * + * ASCII and UTF-8 Unicode are the only currently supported + * character encodings. Extended ASCII encodings (for example, + * ISO 8859) are not supported. This encoding policy is not + * enforced by the HDF5 library. Using encodings other than + * ASCII and UTF-8 can lead to compatibility and usability + * problems. + * + * \note H5Pset_char_encoding() sets the character set used for an + * HDF5 link or attribute name while H5Tset_cset() sets the + * character set used in a character or string datatype. + * + * \since 1.8.0 + * + */ +H5_DLL herr_t H5Pset_char_encoding(hid_t plist_id, H5T_cset_t encoding); /* Link access property list (LAPL) routines */ -H5_DLL herr_t H5Pset_nlinks(hid_t plist_id, size_t nlinks); -H5_DLL herr_t H5Pget_nlinks(hid_t plist_id, size_t *nlinks); -H5_DLL herr_t H5Pset_elink_prefix(hid_t plist_id, const char *prefix); +/** + * \ingroup LAPL + * + * \brief Retrieves the external link traversal file access flag from the + * specified link access property list + * + * \lapl_id + * \param[out] flags File access flag for link traversal + * + * \return \herr_t + * + * \details H5Pget_elink_acc_flags() retrieves the file access flag used + * to open an external link target file from the specified link + * access property list. + * + * Valid values for \p flags include: + * \li #H5F_ACC_RDWR - Files opened through external links will + * be opened with write access + * \li #H5F_ACC_RDONLY - Files opened through external links will + * be opened with read-only access + * \li #H5F_ACC_DEFAULT - Files opened through external links will + * be opened with the same access flag as + * the parent file + * + * The value returned, if it is not #H5F_ACC_DEFAULT, will + * override the default access flag, which is the access flag + * used to open the parent file. + * + * <b>Example Usage:</b> + * The following code retrieves the external link access flag + * settings on the link access property list \p lapl_id into a + * local variable: + * <pre> + * unsigned acc_flags; + * status = H5Pget_elink_acc_flags(lapl_id, &acc_flags); + * </pre> + * + * \since 1.8.3 + * + */ +H5_DLL herr_t H5Pget_elink_acc_flags(hid_t lapl_id, unsigned *flags); +/** + * \ingroup LAPL + * + * \brief Retrieves the external link traversal callback function from the + * specified link access property list + * + * \lapl_id + * \param[out] func User-defined external link traversal callback + * function + * \param[out] op_data User-defined input data for the callback function + * + * \return \herr_t + * + * \details H5Pget_elink_cb() retrieves the user-defined external link + * traversal callback function defined in the specified link + * access property list. + * + * The callback function may adjust the file access property + * list and file access flag to use when opening a file through + * an external link. The callback will be executed by the HDF5 + * library immediately before opening the target file. + * + * <b>Failure Modes:</b> H5Pget_elink_cb() will fail if the link + * access property list identifier, \p lapl_id, is invalid. + * + * An invalid function pointer or data pointer, \p func or + * \p op_data respectively, may cause a segmentation fault or an + * invalid memory access. + * + * <b>Example Usage:</b> The following code retrieves the external + * link callback settings on the link access property list + * \p lapl_id into local variables: + * <pre> + * H5L_elink_traverse_t elink_callback_func; + * void *elink_callback_udata; + * status = H5Pget_elink_cb (lapl_id, &elink_callback_func, + * &elink_callback_udata); + * </pre> + * + * \since 1.8.3 + * + */ +H5_DLL herr_t H5Pget_elink_cb(hid_t lapl_id, H5L_elink_traverse_t *func, void **op_data); +/** + * \ingroup LAPL + * + * \brief Retrieves the file access property list identifier associated + * with the link access property list + * + * \lapl_id + * + * \return \hid_t{file access property list} + * + * \details H5Pget_elink_fapl() retrieves the file access property list + * identifier that is set for the link access property list + * identifier, \p lapl_id. The library uses this file access + * property list identifier to open the target file for the + * external link access. When no such identifier is set, this + * routine returns #H5P_DEFAULT. + * + * \see H5Pset_elink_fapl() and H5Lcreate_external(). + * + * \since 1.8.0 + * + */ +H5_DLL hid_t H5Pget_elink_fapl(hid_t lapl_id); +/** + * \ingroup LAPL + * + * \brief Retrieves prefix applied to external link paths + * + * \lapl_id{plist_id} + * \param[out] prefix Prefix applied to external link paths + * \param[in] size Size of prefix, including null terminator + * + * \return If successful, returns a non-negative value specifying the size + * in bytes of the prefix without the NULL terminator; otherwise + * returns a negative value. + * + * \details H5Pget_elink_prefix() retrieves the prefix applied to the + * path of any external links traversed. + * + * When an external link is traversed, the prefix is retrieved + * from the link access property list \p plist_id, returned in + * the user-allocated buffer pointed to by \p prefix, and + * prepended to the filename stored in the external link. + * + * The size in bytes of the prefix, including the NULL terminator, + * is specified in \p size. If size is unknown, a preliminary + * H5Pget_elink_prefix() call with the pointer \p prefix set to + * NULL will return the size of the prefix without the NULL + * terminator. + * + * \since 1.8.0 + * + */ H5_DLL ssize_t H5Pget_elink_prefix(hid_t plist_id, char *prefix, size_t size); -H5_DLL hid_t H5Pget_elink_fapl(hid_t lapl_id); -H5_DLL herr_t H5Pset_elink_fapl(hid_t lapl_id, hid_t fapl_id); -H5_DLL herr_t H5Pset_elink_acc_flags(hid_t lapl_id, unsigned flags); -H5_DLL herr_t H5Pget_elink_acc_flags(hid_t lapl_id, unsigned *flags); -H5_DLL herr_t H5Pset_elink_cb(hid_t lapl_id, H5L_elink_traverse_t func, void *op_data); -H5_DLL herr_t H5Pget_elink_cb(hid_t lapl_id, H5L_elink_traverse_t *func, void **op_data); +/** + * \ingroup LAPL + * + * \brief Retrieves the maximum number of link traversals + * + * \lapl_id{plist_id} + * \param[out] nlinks Maximum number of links to traverse + * + * \return \herr_t + * + * \details H5Pget_nlinks() retrieves the maximum number of soft or + * user-defined link traversals allowed, \p nlinks, before the + * library assumes it has found a cycle and aborts the traversal. + * This value is retrieved from the link access property list + * \p plist_id. + * + * The limit on the number of soft or user-defined link traversals + * is designed to terminate link traversal if one or more links + * form a cycle. User control is provided because some files may + * have legitimate paths formed of large numbers of soft or + * user-defined links. This property can be used to allow + * traversal of as many links as desired. + * + * \since 1.8.0 + * + */ +H5_DLL herr_t H5Pget_nlinks(hid_t plist_id, size_t *nlinks); +/** + * \ingroup LAPL + * + * \brief Sets the external link traversal file access flag in a link + * access property list + * + * \lapl_id + * \param[in] flags The access flag for external link traversal + * + * \return \herr_t + * + * \details H5Pset_elink_acc_flags() specifies the file access flag to use + * to open the target file of an external link. This allows + * read-only access of files reached through an external link in + * a file opened with write access, or vice-versa. + * + * Valid values for \p flags include: + * \li #H5F_ACC_RDWR - Causes files opened through external links + * to be opened with write access + * \li #H5F_ACC_RDONLY - Causes files opened through external + * links to be opened with read-only access + * \li #H5F_ACC_DEFAULT - Removes any external link file access + * flag setting from \p lapl_id, causing the file access flag + * setting to be taken from the parent file + * + * The library will normally use the file access flag used to + * open the parent file as the file access flag for the target + * file. This function provides a way to override that behavior. + * The external link traversal callback function set by + * H5Pset_elink_cb() can override the setting from + * H5Pset_elink_acc_flags(). + * + * <b>Motivation:</b> H5Pset_elink_acc_flags() is used to adjust the + * file access flag used to open files reached through external links. + * This may be useful to, for example, prevent modifying files + * accessed through an external link. Otherwise, the target file is + * opened with whatever flag was used to open the parent. + * + * <b>Example Usage:</b> The following code sets the link access + * property list \p lapl_id to open external link target files with + * read-only access: + * <pre> + * status = H5Pset_elink_acc_flags(lapl_id, H5F_ACC_RDONLY); + * </pre> + * + * \since 1.8.3 + * + */ +H5_DLL herr_t H5Pset_elink_acc_flags(hid_t lapl_id, unsigned flags); +/** + * \ingroup LAPL + * + * \brief Sets the external link traversal callback function in a link + * access property list + * + * \lapl_id + * \param[in] func User-defined external link traversal callback + * function + * \param[in] op_data User-defined input data for the callback function + * + * \return \herr_t + * + * \details H5Pset_elink_cb() sets a user-defined external link traversal + * callback function in the link access property list \p lapl_id. + * The callback function \p func must conform to the prototype + * specified in #H5L_elink_traverse_t. + * + * The callback function may adjust the file access property + * list and file access flags to use when opening a file through + * an external link. The callback will be executed by the HDF5 + * library immediately before opening the target file. + * + * The callback will be made after the file access property list + * set by H5Pset_elink_fapl() and the file access flag set by + * H5Pset_elink_acc_flags() are applied, so changes made by this + * callback function will take precedence. + * + * \attention A file close degree property setting (H5Pset_fclose_degree()) + * in this callback function or an associated property list will + * be ignored. A file opened by means of traversing an external + * link is always opened with the weak file close degree + * property setting, #H5F_CLOSE_WEAK. + * + * <b>Motivation:</b> H5Pset_elink_cb() is used to specify a + * callback function that is executed by the HDF5 library when + * traversing an external link. This provides a mechanism to set + * specific access permissions, modify the file access property + * list, modify the parent or target file, or take any other + * user-defined action. This callback function is used in + * situations where the HDF5 library's default behavior is not + * suitable. + * + * <b>Failure Modes:</b> H5Pset_elink_cb() will fail if the link + * access property list identifier, \p lapl_id, is invalid or if + * the function pointer, \p func, is NULL. + * + * An invalid function pointer, \p func, will cause a segmentation + * fault or other failure when an attempt is subsequently made to + * traverse an external link. + * + * <b>Example Usage:</b> + * This example defines a callback function that prints the name + * of the target file every time an external link is followed, and + * sets this callback function on \p lapl_id. + * <pre> + * herr_t elink_callback(const char *parent_file_name, const char + * *parent_group_name, const char *child_file_name, const char + * *child_object_name, unsigned *acc_flags, hid_t fapl_id, void *op_data) { + * puts(child_file_name); + * return 0; + * } + * int main(void) { + * hid_t lapl_id = H5Pcreate(H5P_LINK_ACCESS); + * H5Pset_elink_cb(lapl_id, elink_callback, NULL); + * ... + * } + * </pre> + * + * + * \since 1.8.3 + * + */ +H5_DLL herr_t H5Pset_elink_cb(hid_t lapl_id, H5L_elink_traverse_t func, void *op_data); +/** + * \ingroup LAPL + * + * \brief Sets a file access property list for use in accessing a file + * pointed to by an external link + * + * \lapl_id + * \fapl_id + * + * \return \herr_t + * + * \details H5Pset_elink_fapl() sets the file access property list, + * \p fapl_id, to be used when accessing the target file of an + * external link associated with \p lapl_id. + * + * \since 1.8.0 + * + */ +H5_DLL herr_t H5Pset_elink_fapl(hid_t lapl_id, hid_t fapl_id); +/** + * \ingroup LAPL + * + * \brief Sets prefix to be applied to external link paths + * + * \lapl_id{plist_id} + * \param[in] prefix Prefix to be applied to external link paths + * + * \return \herr_t + * + * \details H5Pset_elink_prefix() sets the prefix to be applied to the + * path of any external links traversed. The prefix is prepended + * to the filename stored in the external link. + * + * The prefix is specified in the user-allocated buffer \p prefix + * and set in the link access property list \p plist_id. The buffer + * should not be freed until the property list has been closed. + * + * \since 1.8.0 + * + */ +H5_DLL herr_t H5Pset_elink_prefix(hid_t plist_id, const char *prefix); +/** + * \ingroup LAPL + * + * \brief Sets maximum number of soft or user-defined link traversals + * + * \lapl_id{plist_id} + * \param[in] nlinks Maximum number of links to traverse + * + * \return \herr_t + * + * \details H5Pset_nlinks() sets the maximum number of soft or user-defined + * link traversals allowed, \p nlinks, before the library assumes + * it has found a cycle and aborts the traversal. This value is + * set in the link access property list \p plist_id. + * + * The limit on the number of soft or user-defined link traversals + * is designed to terminate link traversal if one or more links + * form a cycle. User control is provided because some files may + * have legitimate paths formed of large numbers of soft or + * user-defined links. This property can be used to allow + * traversal of as many links as desired. + * + * \since 1.8.0 + * + */ +H5_DLL herr_t H5Pset_nlinks(hid_t plist_id, size_t nlinks); /* Object copy property list (OCPYPL) routines */ -H5_DLL herr_t H5Pset_copy_object(hid_t plist_id, unsigned crt_intmd); -H5_DLL herr_t H5Pget_copy_object(hid_t plist_id, unsigned *crt_intmd /*out*/); +/** + * \ingroup OCPPL + * + * \brief Adds a path to the list of paths that will be searched in the + * destination file for a matching committed datatype + * + * \param[in] plist_id Object copy property list identifier + * \param[in] path The path to be added + * + * \return \herr_t + * + * \details H5Padd_merge_committed_dtype_path() adds a path, \p path, + * which points to a committed datatype, to the current list of + * suggested paths stored in the object copy property list + * \p plist_id. The search as described in the next paragraph is + * effective only if the #H5O_COPY_MERGE_COMMITTED_DTYPE_FLAG is + * enabled in the object copy property list via + * H5Pset_copy_object(). + * + * When copying a committed datatype, a dataset with a committed + * datatype, or an object with an attribute of a committed + * datatype, the default behavior of H5Ocopy() is to search for + * a matching committed datatype: + * <ol> + * <li> First search the list of suggested paths in the object + * copy property list.</li> + * <li> Then, if no match has been found, search all the committed + * datatypes in the destination file. + * </ol> + * The default Step 2 in this search process can be changed by + * setting a callback function (see H5Pset_mcdt_search_cb()). + * + * Two datatypes are determined equal if their descriptions are + * identical, in a manner similar to H5Tequal(). If either + * committed datatype has one or more attributes, then all + * attributes must be present in both committed datatypes and they + * must be identical. Two attributes are considered identical if + * their datatype description, dataspace, and raw data values are + * the same. However, if an attribute uses a committed datatype, + * that committed datatype’s attributes will not be compared. + * + * If a match is found, H5Ocopy() will perform the following in + * the destination file: + * \li For a committed datatype, the library will create a hard + * link to the found datatype. + * \li For a dataset that uses a committed datatype, the library + * will modify the copied dataset to use the found committed + * datatype as its datatype. + * \li For an object with an attribute of a committed datatype, + * the library will modify the copied object’s attribute to + * use the found committed datatype as its datatype. + * + * If no match is found, H5Ocopy() will perform the following in + * the destination file: + * \li For a committed datatype, the library will copy it as it + * would any other object, creating a named committed + * datatype at the destination. That is, the library will + * create a committed datatype that is accessible in the + * file by a unique path. + * \li For a dataset that uses a committed datatype, the + * library will copy the datatype as an anonymous + * committed datatype and use that as the dataset’s + * datatype. + * \li For an object with an attribute of a committed datatype, + * the library will copy the datatype as an anonymous + * committed datatype and use that as the attribute’s + * datatype. + * + * \b Motivation: H5Padd_merge_committed_dtype_path() provides a + * means to override the default behavior of H5Ocopy() when + * #H5O_COPY_MERGE_COMMITTED_DTYPE_FLAG is set in an object + * copy property list. + * H5Padd_merge_committed_dtype_path() is the mechanism for + * suggesting search paths where H5Ocopy() will look for a + * matching committed datatype. This can be substantially + * faster than the default approach of searching the entire + * destination file for a match. + * + * \b Example \b Usage: This example adds two paths to the object + * copy property list. H5Ocopy() will search the two suggested + * paths for a match before searching all the committed datatypes + * in the destination file. + * + * <pre> + * int main(void) { + * hid_t ocpypl_id = H5Pcreate(H5P_OBJECT_COPY); + * + * H5Pset_copy_object(ocpypl_id, H5O_COPY_MERGE_COMMITTED_DTYPE_FLAG); + * H5Padd_merge_committed_dtype_path(ocpypl_id, "/group/committed_dtypeA"); + * H5Padd_merge_committed_dtype_path(ocpypl_id, "/group2/committed_dset"); + * H5Ocopy(...ocpypl_id...); + * ... + * ... + * } + * </pre> + * + * \note H5Padd_merge_committed_dtype_path() will fail if the object + * copy property list is invalid. + * It will also fail if there is insufficient memory when + * duplicating \p path. + * + * \see + * \li H5Ocopy() + * \li #H5O_mcdt_search_cb_t + * \li H5Padd_merge_committed_dtype_path() + * \li H5Pfree_merge_committed_dtype_paths() + * \li H5Pget_mcdt_search_cb() + * \li H5Pset_copy_object() + * \li H5Pset_mcdt_search_cb() + * \li \ref_h5ocopy + * + * \since 1.8.9 + * + */ H5_DLL herr_t H5Padd_merge_committed_dtype_path(hid_t plist_id, const char *path); +/** + * \ingroup OCPPL + * + * \brief Clears the list of paths stored in the object copy property list + * + * \param[in] plist_id Object copy property list identifier + * + * \return \herr_t + * + * \details H5Pfree_merge_committed_dtype_paths() clears the suggested + * paths stored in the object copy property list \p plist_id. + * These are the suggested paths previously set with + * H5Padd_merge_committed_dtype_path(). + * + * \b Example \b Usage: This example adds a suggested path to the + * object copy property list, does the copy, clears the list, and + * then adds a new suggested path to the list for another copy. + * + * <pre> + * int main(void) { + * hid_t ocpypl_id = H5Pcreate(H5P_OBJECT_COPY); + * + * H5Pset_copy_object(ocpypl_id, H5O_COPY_MERGE_COMMITTED_DTYPE_FLAG); + * H5Padd_merge_committed_dtype_path(ocpypl_id, "/group/committed_dtypeA"); + * H5Ocopy(...ocpypl_id...); + * ... + * ... + * H5Pfree_merge_committed_dtype_paths(ocpypl_id); + * H5Padd_merge_committed_dtype_path(ocpypl_id, "/group2/committed_dtypeB"); + * H5Ocopy(...ocpypl_id...); + * ... + * ... + * } + * </pre> + * + * \note H5Pfree_merge_committed_dtype_paths() will fail if the + * object copy property list is invalid. + * + * \see + * \li H5Ocopy() + * \li #H5O_mcdt_search_cb_t + * \li H5Padd_merge_committed_dtype_path() + * \li H5Pfree_merge_committed_dtype_paths() + * \li H5Pget_mcdt_search_cb() + * \li H5Pset_copy_object() + * \li H5Pset_mcdt_search_cb() + * + * \since 1.8.9 + * + */ H5_DLL herr_t H5Pfree_merge_committed_dtype_paths(hid_t plist_id); -H5_DLL herr_t H5Pset_mcdt_search_cb(hid_t plist_id, H5O_mcdt_search_cb_t func, void *op_data); +/** + * \ingroup OCPPL + * + * \brief Retrieves the properties to be used when an object is copied + * + * \param[in] plist_id Object copy property list identifier + * \param[out] copy_options Copy option(s) set in the object copy property + * list + * + * \return \herr_t + * + * \details H5Pget_copy_object() retrieves the properties currently + * specified in the object copy property list \p plist_id, which + * will be invoked when a new copy is made of an existing object. + * + * \p copy_options is a bit map indicating the flags, or + * properties, governing object copying that are set in the + * property list \p plist_id. + * + * The available flags are described in H5Pset_copy_object(). + * + * \since 1.8.0 + * + */ +H5_DLL herr_t H5Pget_copy_object(hid_t plist_id, unsigned *copy_options /*out*/); +/** + * \ingroup OCPPL + * + * \brief Retrieves the callback function from the specified object copy + * property list + * + * \param[in] plist_id Object copy property list identifier + * \param[out] func User-defined callback function + * \param[out] op_data User-defined data for the callback + * function + * + * \return \herr_t + * + * \details H5Pget_mcdt_search_cb() retrieves the user-defined callback + * function and the user data that are set via + * H5Pset_mcdt_search_cb() in the object copy property list + * \p plist_id. + * + * The callback function will be returned in the parameter \p func + * and the user data will be returned in the parameter \p op_data. + * + * \note H5Pget_mcdt_search_cb() will fail if the object copy property + * list is invalid. + * + * \see + * \li H5Ocopy() + * \li #H5O_mcdt_search_cb_t + * \li H5Padd_merge_committed_dtype_path() + * \li H5Pfree_merge_committed_dtype_paths() + * \li H5Pget_mcdt_search_cb() + * \li H5Pset_copy_object() + * \li H5Pset_mcdt_search_cb() + * \li \ref_h5ocopy + * + * \since 1.8.9 + * + */ H5_DLL herr_t H5Pget_mcdt_search_cb(hid_t plist_id, H5O_mcdt_search_cb_t *func, void **op_data); +/** + * \ingroup OCPPL + * + * \brief Sets properties to be used when an object is copied + * + * \param[in] plist_id Object copy property list identifier + * \param[out] copy_options Copy option(s) to be set + * + * \return \herr_t + * + * \details H5Pset_copy_object() sets properties in the object copy + * property list \p plist_id. When an existing object is copied, + * that property list will determine how the new copy is created. + * + * The following flags are available for use in an object copy + * property list: + * + * <table> + * <tr> + * <td>#H5O_COPY_SHALLOW_HIERARCHY_FLAG</td> + * <td>Copy only immediate members of a group<br /> + * <em>Default behavior, without flag:</em> Recursively + * copy all objects in and below the group.</td> + * </tr> + * <tr> + * <td>#H5O_COPY_EXPAND_SOFT_LINK_FLAG</td> + * <td>Expand soft links into new objects<br /> + * <em>Default behavior, without flag:</em> Copy soft + * links as they are.</td> + * </tr> + * <tr> + * <td>#H5O_COPY_EXPAND_EXT_LINK_FLAG</td> + * <td>Expand external link into new objects<br /> + * <em>Default behavior, without flag:</em> Copy external + * links as they are.</td> + * </tr> + * <tr> + * <td>#H5O_COPY_EXPAND_REFERENCE_FLAG</td> + * <td>Copy objects that are pointed to by references and + * update reference values in destination file<br /> + * <em>Default behavior, without flag:</em> Set reference + * values in destination file to zero (0)</td> + * </tr> + * <tr> + * <td>#H5O_COPY_WITHOUT_ATTR_FLAG</td> + * <td>Copy object without copying attributes<br /> + * <em>Default behavior, without flag:</em> Copy object + * with all its attributes</td> + * </tr> + * <tr> + * <td>#H5O_COPY_MERGE_COMMITTED_DTYPE_FLAG</td> + * <td>Use a matching committed datatype in the destination + * file when copying a committed datatype, a dataset with + * a committed datatype, or an object with an attribute + * of committed datatype <br /> + * <em>Default behavior without flag:</em> + * + * \li A committed datatype in the source will be copied to + * the destination as a committed datatype. + * \li If a dataset in the source uses a committed + * datatype or an object in the source has an attribute + * of a committed datatype, that committed datatype will + * be written to the destination as an anonymous + * committed datatype. + * If copied in a single H5Ocopy() operation, objects + * that share a committed datatype in the source will + * share an anonymous committed dataype in the + * destination copy. Subsequent H5Ocopy() operations, + * however, will be unaware of prior anonymous committed + * dataypes and will create new ones. + * + * See the “See Also” section immediately below for + * functions related to the use of this flag.</td> + * </tr> + * </table> + * + * \see + * Functions and a callback function used to tune committed datatype + * copying behavior: + * \li #H5O_mcdt_search_cb_t + * \li H5Padd_merge_committed_dtype_path() + * \li H5Pfree_merge_committed_dtype_paths() + * \li H5Pget_mcdt_search_cb() + * \li H5Pset_copy_object() + * \li H5Pset_mcdt_search_cb() + * \li \ref_h5ocopy + * + * \version 1.8.9 #H5O_COPY_MERGE_COMMITTED_DTYPE_FLAG added in this release. + * + * \since 1.8.0 + * + */ +H5_DLL herr_t H5Pset_copy_object(hid_t plist_id, unsigned copy_options); +/** + * \ingroup OCPPL + * + * \brief Sets the callback function that H5Ocopy() will invoke before + * searching the entire destination file for a matching committed + * datatype + * + * \param[in] plist_id Object copy property list identifier + * \param[in] func User-defined callback function + * \param[in] op_data User-defined input data for the callback function + * + * \return \herr_t + * + * \details H5Pset_mcdt_search_cb() allows an application to set a + * callback function, \p func, that will be invoked before + * searching the destination file for a matching committed + * datatype. The default, global search process is described in + * H5Padd_merge_committed_dtype_path(). + * + * The callback function must conform to the #H5O_mcdt_search_cb_t + * prototype and will return an instruction for one of the + * following actions: + * + * \li Continue the search for a matching committed datatype in + * the destination file. + * \li Discontinue the search for a matching committed datatype. + * H5Ocopy() will then apply the default behavior of creating + * an anonymous committed datatype. + * \li Abort the copy operation and exit H5Ocopy(). + * + * \b Motivation: H5Pset_mcdt_search_cb() provides the means to + * define a callback function. An application can then use that + * callback to take an additional action before the default search + * of all committed datatypes in the destination file or to take an + * action that replaces the default search. This mechanism is + * intended to improve performance when the global search might + * take a long time. + * + * \b Example \b Usage: This example defines a callback function in + * the object copy property list. + * + * <pre> + * static H5O_mcdt_search_ret_t + * mcdt_search_cb(void *_udata) + * { + * H5O_mcdt_search_ret_t action = *((H5O_mcdt_search_ret_t *)_udata); + * + * return(action); + * } + * + * int main(void) { + * hid_t ocpypl_id = H5Pcreate(H5P_OBJECT_COPY); + * + * H5Pset_copy_object(ocpypl_id, H5O_COPY_MERGE_COMMITTED_DTYPE_FLAG); + * H5Padd_merge_committed_dtype_path(ocpypl_id, "/group/committed_dtypeA"); + * + * action = H5O_MCDT_SEARCH_STOP; + * H5Pset_mcdt_search_cb(ocpypl_id, mcdt_search_cb, &action); + * H5Ocopy(...ocpypl_id...); + * ... + * ... + * } + * </pre> + * + * \note H5Pset_mcdt_search_cb() will fail if the + * object copy property list is invalid. + * + * \warning If the callback function return value causes H5Ocopy() to + * abort, the destination file may be left in an inconsistent or + * corrupted state. + * + * \see + * \li H5Ocopy() + * \li #H5O_mcdt_search_cb_t + * \li H5Padd_merge_committed_dtype_path() + * \li H5Pfree_merge_committed_dtype_paths() + * \li H5Pget_mcdt_search_cb() + * \li H5Pset_copy_object() + * \li H5Pset_mcdt_search_cb() + * \li \ref_h5ocopy + * + * \since 1.8.9 + * + */ +H5_DLL herr_t H5Pset_mcdt_search_cb(hid_t plist_id, H5O_mcdt_search_cb_t func, void *op_data); /* Symbols defined for compatibility with previous versions of the HDF5 API. * @@ -520,27 +9275,471 @@ H5_DLL herr_t H5Pget_mcdt_search_cb(hid_t plist_id, H5O_mcdt_search_cb_t *func, #define H5P_NO_CLASS H5P_ROOT /* Typedefs */ +/** + * \ingroup GPLOA + * + * \brief Registers a permanent property with a property list class + * + * \plistcls_id{cls_id} + * \param[in] name Name of property to register + * \param[in] size Size of property in bytes + * \param[in] def_value Default value for property in newly created + * property lists + * \param[in] prp_create Callback routine called when a property list is + * being created and the property value will be + * initialized + * \param[in] prp_set Callback routine called before a new value is + * copied into the property's value + * \param[in] prp_get Callback routine called when a property value is + * retrieved from the property + * \param[in] prp_del Callback routine called when a property is deleted + * from a property list + * \param[in] prp_copy Callback routine called when a property is copied + * from a property list + * \param[in] prp_close Callback routine called when a property list is + * being closed and the property value will be + * disposed of + * + * \return \herr_t + * + * \deprecated As of HDF5-1.8 this function was deprecated in favor of + * H5Pregister2() or the macro H5Pregister(). + * + * \details H5Pregister1() registers a new property with a property list + * class. The property will exist in all property list objects + * of that class after this routine is finished. The name of + * the property must not already exist. The default property + * value must be provided and all new property lists created + * with this property will have the property value set to the + * default provided. Any of the callback routines may be set + * to NULL if they are not needed. + * + * Zero-sized properties are allowed and do not store any data in + * the property list. These may be used as flags to indicate the + * presence or absence of a particular piece of information. The + * default pointer for a zero-sized property may be set to NULL. + * The property \p prp_create and \p prp_close callbacks are called for + * zero-sized properties, but the \p prp_set and \p prp_get callbacks + * are never called. + * + * The \p prp_create routine is called when a new property list with + * this property is being created. The #H5P_prp_create_func_t + * callback function is defined as #H5P_prp_cb1_t. + * + * The \p prp_create routine may modify the value to be set and those + * changes will be stored as the initial value of the property. + * If the \p prp_create routine returns a negative value, the new + * property value is not copied into the property and the + * \p prp_create routine returns an error value. + * + * The \p prp_set routine is called before a new value is copied into + * the property. The #H5P_prp_set_func_t callback function is defined + * as #H5P_prp_cb2_t. + * + * The \p prp_set routine may modify the value pointer to be set and + * those changes will be used when setting the property's value. + * If the \p prp_set routine returns a negative value, the new property + * value is not copied into the property and the \p prp_set routine + * returns an error value. The \p prp_set routine will not be called + * for the initial value; only the \p prp_create routine will be + * called. + * + * \b Note: The \p prp_set callback function may be useful to range + * check the value being set for the property or may perform some + * transformation or translation of the value set. The \p prp_get + * callback would then reverse the transformation or translation. + * A single \p prp_get or \p prp_set callback could handle multiple + * properties by performing different actions based on the property + * name or other properties in the property list. + * + * The \p prp_get routine is called when a value is retrieved from a + * property value. The #H5P_prp_get_func_t callback function is + * defined as #H5P_prp_cb2_t. + * + * The \p prp_get routine may modify the value to be returned from the + * query and those changes will be returned to the calling routine. + * If the \p prp_set routine returns a negative value, the query + * routine returns an error value. + * + * The \p prp_del routine is called when a property is being + * deleted from a property list. The #H5P_prp_delete_func_t + * callback function is defined as #H5P_prp_cb2_t. + * + * The \p prp_del routine may modify the value passed in, but the + * value is not used by the library when the \p prp_del routine + * returns. If the \p prp_del routine returns a negative value, + * the property list deletion routine returns an error value but + * the property is still deleted. + * + * The \p prp_copy routine is called when a new property list with + * this property is being created through a \p prp_copy operation. + * The #H5P_prp_copy_func_t callback function is defined as + * #H5P_prp_cb1_t. + * + * The \p prp_copy routine may modify the value to be set and those + * changes will be stored as the new value of the property. If + * the \p prp_copy routine returns a negative value, the new + * property value is not copied into the property and the \p prp_copy + * routine returns an error value. + * + * The \p prp_close routine is called when a property list with this + * property is being closed. The #H5P_prp_close_func_t callback + * function is defined as #H5P_prp_cb1_t. + * + * The \p prp_close routine may modify the value passed in, but the + * value is not used by the library when the \p prp_close routine + * returns. If the \p prp_close routine returns a negative value, the + * property list close routine returns an error value but the property + * list is still closed. + * + * The #H5P_prp_cb1_t is as follows: + * \snippet this H5P_prp_cb1_t_snip + * + * The #H5P_prp_cb2_t is as follows: + * \snippet this H5P_prp_cb2_t_snip + * + * + * \cpp_c_api_note + * + */ /* Function prototypes */ -H5_DLL herr_t H5Pregister1(hid_t cls_id, const char *name, size_t size, void *def_value, - H5P_prp_create_func_t prp_create, H5P_prp_set_func_t prp_set, - H5P_prp_get_func_t prp_get, H5P_prp_delete_func_t prp_del, - H5P_prp_copy_func_t prp_copy, H5P_prp_close_func_t prp_close); -H5_DLL herr_t H5Pinsert1(hid_t plist_id, const char *name, size_t size, void *value, - H5P_prp_set_func_t prp_set, H5P_prp_get_func_t prp_get, - H5P_prp_delete_func_t prp_delete, H5P_prp_copy_func_t prp_copy, - H5P_prp_close_func_t prp_close); -H5_DLL herr_t H5Pencode1(hid_t plist_id, void *buf, size_t *nalloc); +H5_DLL herr_t H5Pregister1(hid_t cls_id, const char *name, size_t size, void *def_value, + H5P_prp_create_func_t prp_create, H5P_prp_set_func_t prp_set, + H5P_prp_get_func_t prp_get, H5P_prp_delete_func_t prp_del, + H5P_prp_copy_func_t prp_copy, H5P_prp_close_func_t prp_close); +/** + * \ingroup GPLOA + * + * \brief Registers a temporary property with a property list + * + * \plist_id + * \param[in] name Name of property to create + * \param[in] size Size of property in bytes + * \param[in] value Initial value for the property + * \param[in] prp_set Callback routine called before a new value is copied + * into the property's value + * \param[in] prp_get Callback routine called when a property value is + * retrieved from the property + * \param[in] prp_delete Callback routine called when a property is deleted + * from a property list + * \param[in] prp_copy Callback routine called when a property is copied + * from an existing property list + * \param[in] prp_close Callback routine called when a property list is + * being closed and the property value will be disposed + * of + * + * \return \herr_t + * + * \deprecated As of HDF5-1.8 this function was deprecated in favor of + * H5Pinsert2() or the macro H5Pinsert(). + * + * \details H5Pinsert1() creates a new property in a property + * list. The property will exist only in this property list and + * copies made from it. + * + * The initial property value must be provided in \p value and + * the property value will be set accordingly. + * + * The name of the property must not already exist in this list, + * or this routine will fail. + * + * The \p prp_set and \p prp_get callback routines may be set to NULL + * if they are not needed. + * + * Zero-sized properties are allowed and do not store any data + * in the property list. The default value of a zero-size + * property may be set to NULL. They may be used to indicate the + * presence or absence of a particular piece of information. + * + * The \p prp_set routine is called before a new value is copied + * into the property. The #H5P_prp_set_func_t callback function + * is defined as #H5P_prp_cb2_t. + * The \p prp_set routine may modify the value pointer to be set and + * those changes will be used when setting the property's value. + * If the \p prp_set routine returns a negative value, the new property + * value is not copied into the property and the \p set routine + * returns an error value. The \p prp_set routine will be called for + * the initial value. + * + * \b Note: The \p prp_set callback function may be useful to range + * check the value being set for the property or may perform some + * transformation or translation of the value set. The \p prp_get + * callback would then reverse the transformation or translation. + * A single \p prp_get or \p prp_set callback could handle multiple + * properties by performing different actions based on the + * property name or other properties in the property list. + * + * The \p prp_get routine is called when a value is retrieved from + * a property value. The #H5P_prp_get_func_t callback function + * is defined as #H5P_prp_cb2_t. + * + * The \p prp_get routine may modify the value to be returned from + * the query and those changes will be preserved. If the \p prp_get + * routine returns a negative value, the query routine returns + * an error value. + * + * The \p prp_delete routine is called when a property is being + * deleted from a property list. The #H5P_prp_delete_func_t + * callback function is defined as #H5P_prp_cb2_t. + * + * The \p prp_copy routine is called when a new property list with + * this property is being created through a \p prp_copy operation. + * The #H5P_prp_copy_func_t callback function is defined as + * #H5P_prp_cb1_t. + * + * The \p prp_copy routine may modify the value to be set and those + * changes will be stored as the new value of the property. If the + * \p prp_copy routine returns a negative value, the new property value + * is not copied into the property and the prp_copy routine returns an + * error value. + * + * The \p prp_close routine is called when a property list with this + * property is being closed. + * The #H5P_prp_close_func_t callback function is defined as + * #H5P_prp_cb1_t. + * + * The \p prp_close routine may modify the value passed in, the + * value is not used by the library when the close routine + * returns. If the \p prp_close routine returns a negative value, + * the property list \p prp_close routine returns an error value + * but the property list is still closed. + * + * \b Note: There is no \p prp_create callback routine for temporary + * property list objects; the initial value is assumed to + * have any necessary setup already performed on it. + * + * The #H5P_prp_cb1_t is as follows: + * \snippet this H5P_prp_cb1_t_snip + * + * The #H5P_prp_cb2_t is as follows: + * \snippet this H5P_prp_cb2_t_snip + + * \cpp_c_api_note + */ +H5_DLL herr_t H5Pinsert1(hid_t plist_id, const char *name, size_t size, void *value, + H5P_prp_set_func_t prp_set, H5P_prp_get_func_t prp_get, + H5P_prp_delete_func_t prp_delete, H5P_prp_copy_func_t prp_copy, + H5P_prp_close_func_t prp_close); +/** + * \ingroup GPLO + * + * \brief Encodes the property values in a property list into a binary + * buffer + * + * \plist_id + * \param[out] buf Buffer into which the property list will be encoded. + * If the provided buffer is NULL, the size of the + * buffer required is returned through \p nalloc; the + * function does nothing more. + * \param[out] nalloc The size of the required buffer + * + * \return \herr_t + * + * \deprecated As of HDF5-1.12 this function has been deprecated in favor of + * H5Pencode2() or the macro H5Pencode(). + * + * \details H5Pencode1() encodes the property list \p plist_id into the + * binary buffer \p buf. + * + * If the required buffer size is unknown, \p buf can be passed + * in as NULL and the function will set the required buffer size + * in \p nalloc. The buffer can then be created and the property + * list encoded with a subsequent H5Pencode1() call. + * + * If the buffer passed in is not big enough to hold the encoded + * properties, the H5Pencode1() call can be expected to fail with + * a segmentation fault. + * + * Properties that do not have encode callbacks will be skipped. + * There is currently no mechanism to register an encode callback for + * a user-defined property, so user-defined properties cannot currently + * be encoded. + * + * Some properties cannot be encoded, particularly properties that are + * reliant on local context. + * + * \since 1.10.0 + * + */ +H5_DLL herr_t H5Pencode1(hid_t plist_id, void *buf, size_t *nalloc); +/** + * \ingroup DCPL + * + * \brief Returns information about a filter in a pipeline (DEPRECATED) + * + * + * + * \plist_id{plist_id} + * \param[in] filter Sequence number within the filter pipeline of + * the filter for which information is sought + * \param[out] flags Bit vector specifying certain general properties + * of the filter + * \param[in,out] cd_nelmts Number of elements in \p cd_values + * \param[out] cd_values Auxiliary data for the filter + * \param[in] namelen Anticipated number of characters in \p name + * \param[out] name Name of the filter + * + * \return Returns the filter identifier if successful; Otherwise returns + * a negative value. See: #H5Z_filter_t + * + * \deprecated When was this function deprecated? + * + * \details H5Pget_filter1() returns information about a filter, specified + * by its filter number, in a filter pipeline, specified by the + * property list with which it is associated. + * + * \p plist_id must be a dataset or group creation property list. + * + * \p filter is a value between zero and N-1, as described in + * H5Pget_nfilters(). The function will return a negative value + * if the filter number is out of range. + * + * The structure of the \p flags argument is discussed in + * H5Pset_filter(). + * + * On input, \p cd_nelmts indicates the number of entries in the + * \p cd_values array, as allocated by the caller; on return, + * \p cd_nelmts contains the number of values defined by the filter. + * + * If \p name is a pointer to an array of at least \p namelen + * bytes, the filter name will be copied into that array. The name + * will be null terminated if \p namelen is large enough. The + * filter name returned will be the name appearing in the file, the + * name registered for the filter, or an empty string. + * + * \version 1.8.5 Function extended to work with group creation property + * lists. + * \version 1.8.0 N-bit and scale-offset filters added. + * \version 1.8.0 Function H5Pget_filter() renamed to H5Pget_filter1() and + * deprecated in this release. + * \version 1.6.4 \p filter parameter type changed to unsigned. + * + */ H5_DLL H5Z_filter_t H5Pget_filter1(hid_t plist_id, unsigned filter, unsigned int *flags /*out*/, size_t *cd_nelmts /*out*/, unsigned cd_values[] /*out*/, size_t namelen, char name[]); -H5_DLL herr_t H5Pget_filter_by_id1(hid_t plist_id, H5Z_filter_t id, unsigned int *flags /*out*/, - size_t *cd_nelmts /*out*/, unsigned cd_values[] /*out*/, size_t namelen, - char name[] /*out*/); -H5_DLL herr_t H5Pget_version(hid_t plist_id, unsigned *boot /*out*/, unsigned *freelist /*out*/, - unsigned *stab /*out*/, unsigned *shhdr /*out*/); -H5_DLL herr_t H5Pset_file_space(hid_t plist_id, H5F_file_space_type_t strategy, hsize_t threshold); -H5_DLL herr_t H5Pget_file_space(hid_t plist_id, H5F_file_space_type_t *strategy, hsize_t *threshold); +/** + * \ingroup DCPL + * + * \brief Returns information about the specified filter + * + * \plist_id{plist_id} + * \param[in] id Filter identifier + * \param[out] flags Bit vector specifying certain general properties + * of the filter + * \param[in,out] cd_nelmts Number of elements in \p cd_values + * \param[out] cd_values Auxiliary data for the filter + * \param[in] namelen Anticipated number of characters in \p name + * \param[out] name Name of the filter + * + * + * \return Returns a non-negative value if successful; Otherwise returns + * a negative value. + * + * \deprecated As of HDF5-1.8 this function was deprecated in favor of + * H5Pget_filter_by_id2() or the macro H5Pget_filter_by_id(). + * + * \details H5Pget_filter_by_id1() returns information about a filter, specified + * in \p id, a filter identifier. + * + * \p plist_id must be a dataset or group creation property list and + * \p id must be in the associated filter pipeline. + * + * The \p id and \p flags parameters are used in the same + * manner as described in the discussion of H5Pset_filter(). + * + * Aside from the fact that they are used for output, the parameters + * \p cd_nelmts and \p cd_values[] are used in the same manner as + * described in the discussion of H5Pset_filter(). + * On input, the \p cd_nelmts parameter indicates the number of entries + * in the \p cd_values[] array allocated by the calling program; + * on exit it contains the number of values defined by the filter. + * + * On input, the \p namelen parameter indicates the number of + * characters allocated for the filter name by the calling program + * in the array \p name[]. On exit \p name[] contains the name of the + * filter with one character of the name in each element of the array. + * + * If the filter specified in \p id is not set for the property + * list, an error will be returned and this function will fail. + * + * + * \version 1.8.5 Function extended to work with group creation property + * lists. + * \version 1.8.0 Function H5Pget_filter_by_id() renamed to + * H5Pget_filter_by_id1() and deprecated in this release. + * \version 1.6.0 Function introduced in this release. + */ +H5_DLL herr_t H5Pget_filter_by_id1(hid_t plist_id, H5Z_filter_t id, unsigned int *flags /*out*/, + size_t *cd_nelmts /*out*/, unsigned cd_values[] /*out*/, size_t namelen, + char name[] /*out*/); +/** + * \ingroup FCPL + * + * \brief Retrieves the version information of various objects + * for a file creation property list(deprecated) + * + * \plist_id + * \param[out] boot Pointer to location to return super block version number + * \param[out] freelist Pointer to location to return global freelist version number + * \param[out] stab Pointer to location to return symbol table version number + * \param[out] shhdr Pointer to location to return shared object header version + * number + * + * \return \herr_t + * + * \deprecated Deprecated in favor of the function H5Fget_info() + * + * \details H5Pget_version() retrieves the version information of various objects + * for a file creation property list. Any pointer parameters which are + * passed as NULL are not queried. + * + * \version 1.6.4 \p boot, \p freelist, \p stab, \p shhdr parameter types + * changed to unsigned. + * + */ +H5_DLL herr_t H5Pget_version(hid_t plist_id, unsigned *boot /*out*/, unsigned *freelist /*out*/, + unsigned *stab /*out*/, unsigned *shhdr /*out*/); +/** + * \ingroup FCPL + * + * \brief Sets the file space handling strategy and the free-space section + * size threshold. + * + * \fcpl_id{plist_id} + * \param[in] strategy The file space handling strategy to be used. See: + * #H5F_fspace_strategy_t + * \param[in] threshold The smallest free-space section size that the free + * space manager will track + * + * \return \herr_t + * + * \deprecated When was this function deprecated? + * + * \details Maps to the function H5Pset_file_space_strategy(). + * + */ +H5_DLL herr_t H5Pset_file_space(hid_t plist_id, H5F_file_space_type_t strategy, hsize_t threshold); +/** + * \ingroup FCPL + * + * \brief Retrieves the file space handling strategy, and threshold value for + * a file creation property list + * + * \fcpl_id{plist_id} + * \param[out] strategy Pointer to the file space handling strategy + * \param[out] threshold Pointer to the free-space section size threshold value + * + * \return \herr_t + * + * \deprecated When was this function deprecated? + * + * \details Maps to the function H5Pget_file_space_strategy() + * + * + */ +H5_DLL herr_t H5Pget_file_space(hid_t plist_id, H5F_file_space_type_t *strategy, hsize_t *threshold); #endif /* H5_NO_DEPRECATED_SYMBOLS */ #ifdef __cplusplus @@ -27,10 +27,12 @@ #include "H5private.h" /* Generic Functions */ #include "H5CXprivate.h" /* API Contexts */ #include "H5Eprivate.h" /* Error handling */ +#include "H5ESprivate.h" /* Event Sets */ #include "H5Iprivate.h" /* IDs */ #include "H5MMprivate.h" /* Memory management */ #include "H5Rpkg.h" /* References */ #include "H5Sprivate.h" /* Dataspaces */ +#include "H5VLprivate.h" /* Virtual Object Layer */ /****************/ /* Local Macros */ @@ -44,6 +46,14 @@ /* Local Prototypes */ /********************/ +/* Helper routines for sync/async API calls */ +static hid_t H5R__open_object_api_common(H5R_ref_t *ref_ptr, hid_t rapl_id, hid_t oapl_id, void **token_ptr, + H5VL_object_t **_vol_obj_ptr); +static hid_t H5R__open_region_api_common(H5R_ref_t *ref_ptr, hid_t rapl_id, hid_t oapl_id, void **token_ptr, + H5VL_object_t **_vol_obj_ptr); +static hid_t H5R__open_attr_api_common(H5R_ref_t *ref_ptr, hid_t rapl_id, hid_t aapl_id, void **token_ptr, + H5VL_object_t **_vol_obj_ptr); + /*********************/ /* Package Variables */ /*********************/ @@ -175,7 +185,7 @@ H5Rcreate_region(hid_t loc_id, const char *name, hid_t space_id, hid_t oapl_id, HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid reference pointer") if (!name || !*name) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no name given") - if ((space_id == H5I_BADID) || (space_id == H5S_ALL)) + if ((space_id == H5I_INVALID_HID) || (space_id == H5S_ALL)) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "reference region dataspace id must be valid") if (NULL == (space = (struct H5S_t *)H5I_object_verify(space_id, H5I_DATASPACE))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a dataspace") @@ -448,28 +458,29 @@ done: } /* end H5Rcopy() */ /*------------------------------------------------------------------------- - * Function: H5Ropen_object + * Function: H5R__open_object_api_common * - * Purpose: Given a reference to some object, open that object and - * return an ID for that object. + * Purpose: This is the common function for opening an object via a reference. * * Return: Valid ID on success / H5I_INVALID_HID on failure * *------------------------------------------------------------------------- */ -hid_t -H5Ropen_object(H5R_ref_t *ref_ptr, hid_t rapl_id, hid_t oapl_id) +static hid_t +H5R__open_object_api_common(H5R_ref_t *ref_ptr, hid_t rapl_id, hid_t oapl_id, void **token_ptr, + H5VL_object_t **_vol_obj_ptr) { - hid_t loc_id; /* Reference location ID */ - H5VL_object_t * vol_obj = NULL; /* Object of loc_id */ - H5VL_loc_params_t loc_params; /* Location parameters */ - H5O_token_t obj_token = {0}; /* Object token */ - H5I_type_t opened_type; /* Opened object type */ - void * opened_obj = NULL; /* Opened object */ - hid_t ret_value = H5I_INVALID_HID; /* Return value */ - - FUNC_ENTER_API(H5I_INVALID_HID) - H5TRACE3("i", "*Rrii", ref_ptr, rapl_id, oapl_id); + hid_t loc_id; /* Reference location ID */ + H5VL_object_t * tmp_vol_obj = NULL; /* Object for loc_id */ + H5VL_object_t **vol_obj_ptr = + (_vol_obj_ptr ? _vol_obj_ptr : &tmp_vol_obj); /* Ptr to object ptr for loc_id */ + H5VL_loc_params_t loc_params; /* Location parameters */ + H5O_token_t obj_token = {0}; /* Object token */ + H5I_type_t opened_type; /* Opened object type */ + void * opened_obj = NULL; /* Opened object */ + hid_t ret_value = H5I_INVALID_HID; /* Return value */ + + FUNC_ENTER_STATIC /* Check args */ if (ref_ptr == NULL) @@ -489,52 +500,118 @@ H5Ropen_object(H5R_ref_t *ref_ptr, hid_t rapl_id, hid_t oapl_id) HGOTO_ERROR(H5E_REFERENCE, H5E_CANTOPENFILE, H5I_INVALID_HID, "cannot re-open referenced file") } - /* Get object token */ - if (H5R__get_obj_token((const H5R_ref_priv_t *)ref_ptr, &obj_token, NULL) < 0) - HGOTO_ERROR(H5E_REFERENCE, H5E_CANTGET, H5I_INVALID_HID, "unable to get object token") - /* Verify access property list and set up collective metadata if appropriate */ if (H5CX_set_apl(&oapl_id, H5P_CLS_DACC, loc_id, FALSE) < 0) HGOTO_ERROR(H5E_REFERENCE, H5E_CANTSET, H5I_INVALID_HID, "can't set access property list info") - /* Get the VOL object */ - if (NULL == (vol_obj = H5VL_vol_object(loc_id))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5I_INVALID_HID, "invalid location identifier") + /* Get object token */ + if (H5R__get_obj_token((const H5R_ref_priv_t *)ref_ptr, &obj_token, NULL) < 0) + HGOTO_ERROR(H5E_REFERENCE, H5E_CANTGET, H5I_INVALID_HID, "unable to get object token") - /* Set location parameters */ - loc_params.type = H5VL_OBJECT_BY_TOKEN; - loc_params.loc_data.loc_by_token.token = &obj_token; - loc_params.obj_type = H5I_get_type(loc_id); + /* Set up arguments for object access by token */ + if (H5VL_setup_token_args(loc_id, &obj_token, vol_obj_ptr, &loc_params) < 0) + HGOTO_ERROR(H5E_REFERENCE, H5E_CANTSET, H5I_INVALID_HID, "can't set object access arguments") /* Open object by token */ - if (NULL == (opened_obj = H5VL_object_open(vol_obj, &loc_params, &opened_type, H5P_DATASET_XFER_DEFAULT, - H5_REQUEST_NULL))) + if (NULL == (opened_obj = H5VL_object_open(*vol_obj_ptr, &loc_params, &opened_type, + H5P_DATASET_XFER_DEFAULT, token_ptr))) HGOTO_ERROR(H5E_REFERENCE, H5E_CANTOPENOBJ, H5I_INVALID_HID, "unable to open object by token") /* Register object */ - if ((ret_value = H5VL_register(opened_type, opened_obj, vol_obj->connector, TRUE)) < 0) + if ((ret_value = H5VL_register(opened_type, opened_obj, (*vol_obj_ptr)->connector, TRUE)) < 0) HGOTO_ERROR(H5E_REFERENCE, H5E_CANTREGISTER, H5I_INVALID_HID, "unable to register object handle") done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5R__open_object_api_common() */ + +/*------------------------------------------------------------------------- + * Function: H5Ropen_object + * + * Purpose: Given a reference to some object, open that object and + * return an ID for that object. + * + * Return: Valid ID on success / H5I_INVALID_HID on failure + * + *------------------------------------------------------------------------- + */ +hid_t +H5Ropen_object(H5R_ref_t *ref_ptr, hid_t rapl_id, hid_t oapl_id) +{ + hid_t ret_value = H5I_INVALID_HID; /* Return value */ + + FUNC_ENTER_API(H5I_INVALID_HID) + H5TRACE3("i", "*Rrii", ref_ptr, rapl_id, oapl_id); + + /* Open the dataset synchronously */ + if ((ret_value = H5R__open_object_api_common(ref_ptr, rapl_id, oapl_id, NULL, NULL)) < 0) + HGOTO_ERROR(H5E_REFERENCE, H5E_CANTOPENOBJ, H5I_INVALID_HID, "unable to open object synchronously") + +done: FUNC_LEAVE_API(ret_value) } /* end H5Ropen_object() */ /*------------------------------------------------------------------------- - * Function: H5Ropen_region + * Function: H5Ropen_object_async * - * Purpose: Given a reference to some object, creates a copy of the dataset - * pointed to's dataspace and defines a selection in the copy - * which is the region pointed to. + * Purpose: Asynchronous version of H5Ropen_object * * Return: Valid ID on success / H5I_INVALID_HID on failure * *------------------------------------------------------------------------- */ hid_t -H5Ropen_region(H5R_ref_t *ref_ptr, hid_t rapl_id, hid_t oapl_id) +H5Ropen_object_async(const char *app_file, const char *app_func, unsigned app_line, H5R_ref_t *ref_ptr, + hid_t rapl_id, hid_t oapl_id, hid_t es_id) { - hid_t loc_id; /* Reference location ID */ - H5VL_object_t * vol_obj = NULL; /* Object of loc_id */ + H5VL_object_t *vol_obj = NULL; /* Object of loc_id */ + void * token = NULL; /* Request token for async operation */ + void ** token_ptr = H5_REQUEST_NULL; /* Pointer to request token for async operation */ + hid_t ret_value = H5I_INVALID_HID; /* Return value */ + + FUNC_ENTER_API(H5I_INVALID_HID) + H5TRACE7("i", "*s*sIu*Rriii", app_file, app_func, app_line, ref_ptr, rapl_id, oapl_id, es_id); + + /* Set up request token pointer for asynchronous operation */ + if (H5ES_NONE != es_id) + token_ptr = &token; /* Point at token for VOL connector to set up */ + + /* Open the object asynchronously */ + if ((ret_value = H5R__open_object_api_common(ref_ptr, rapl_id, oapl_id, token_ptr, &vol_obj)) < 0) + HGOTO_ERROR(H5E_REFERENCE, H5E_CANTOPENOBJ, H5I_INVALID_HID, "unable to open object asynchronously") + + /* If a token was created, add the token to the event set */ + if (NULL != token) + /* clang-format off */ + if (H5ES_insert(es_id, vol_obj->connector, token, + H5ARG_TRACE7(FUNC, "*s*sIu*Rriii", app_file, app_func, app_line, ref_ptr, rapl_id, oapl_id, es_id)) < 0) { + /* clang-format on */ + if (H5I_dec_app_ref_always_close(ret_value) < 0) + HGOTO_ERROR(H5E_REFERENCE, H5E_CANTDEC, H5I_INVALID_HID, "can't decrement count on object ID") + HGOTO_ERROR(H5E_REFERENCE, H5E_CANTINSERT, H5I_INVALID_HID, "can't insert token into event set") + } /* end if */ + +done: + FUNC_LEAVE_API(ret_value) +} /* end H5Ropen_object_async() */ + +/*------------------------------------------------------------------------- + * Function: H5R__open_region_api_common + * + * Purpose: This is the common function for opening a region. + * + * Return: Valid ID on success / H5I_INVALID_HID on failure + * + *------------------------------------------------------------------------- + */ +static hid_t +H5R__open_region_api_common(H5R_ref_t *ref_ptr, hid_t rapl_id, hid_t oapl_id, void **token_ptr, + H5VL_object_t **_vol_obj_ptr) +{ + hid_t loc_id; /* Reference location ID */ + H5VL_object_t * tmp_vol_obj = NULL; /* Object for loc_id */ + H5VL_object_t **vol_obj_ptr = + (_vol_obj_ptr ? _vol_obj_ptr : &tmp_vol_obj); /* Ptr to object ptr for loc_id */ H5VL_loc_params_t loc_params; /* Location parameters */ H5O_token_t obj_token = {0}; /* Object token */ H5I_type_t opened_type; /* Opened object type */ @@ -544,8 +621,7 @@ H5Ropen_region(H5R_ref_t *ref_ptr, hid_t rapl_id, hid_t oapl_id) hid_t space_id = H5I_INVALID_HID; /* Dataspace ID */ hid_t ret_value = H5I_INVALID_HID; /* Return value */ - FUNC_ENTER_API(H5I_INVALID_HID) - H5TRACE3("i", "*Rrii", ref_ptr, rapl_id, oapl_id); + FUNC_ENTER_STATIC /* Check args */ if (ref_ptr == NULL) @@ -569,22 +645,17 @@ H5Ropen_region(H5R_ref_t *ref_ptr, hid_t rapl_id, hid_t oapl_id) if (H5R__get_obj_token((const H5R_ref_priv_t *)ref_ptr, &obj_token, NULL) < 0) HGOTO_ERROR(H5E_REFERENCE, H5E_CANTGET, H5I_INVALID_HID, "unable to get object token") - /* Get the VOL object */ - if (NULL == (vol_obj = H5VL_vol_object(loc_id))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5I_INVALID_HID, "invalid location identifier") - - /* Set location parameters */ - loc_params.type = H5VL_OBJECT_BY_TOKEN; - loc_params.loc_data.loc_by_token.token = &obj_token; - loc_params.obj_type = H5I_get_type(loc_id); + /* Set up arguments for object access by token */ + if (H5VL_setup_token_args(loc_id, &obj_token, vol_obj_ptr, &loc_params) < 0) + HGOTO_ERROR(H5E_REFERENCE, H5E_CANTSET, H5I_INVALID_HID, "can't set object access arguments") /* Open object by token */ - if (NULL == (opened_obj = H5VL_object_open(vol_obj, &loc_params, &opened_type, H5P_DATASET_XFER_DEFAULT, - H5_REQUEST_NULL))) + if (NULL == (opened_obj = H5VL_object_open(*vol_obj_ptr, &loc_params, &opened_type, + H5P_DATASET_XFER_DEFAULT, token_ptr))) HGOTO_ERROR(H5E_REFERENCE, H5E_CANTOPENOBJ, H5I_INVALID_HID, "unable to open object by token") /* Register object */ - if ((opened_obj_id = H5VL_register(opened_type, opened_obj, vol_obj->connector, FALSE)) < 0) + if ((opened_obj_id = H5VL_register(opened_type, opened_obj, (*vol_obj_ptr)->connector, FALSE)) < 0) HGOTO_ERROR(H5E_REFERENCE, H5E_CANTREGISTER, H5I_INVALID_HID, "unable to register object handle") /* Get VOL object object */ @@ -612,24 +683,97 @@ done: if ((space_id != H5I_INVALID_HID) && (H5I_dec_ref(space_id) < 0)) HDONE_ERROR(H5E_REFERENCE, H5E_CLOSEERROR, H5I_INVALID_HID, "can't close dataspace") + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5R__open_region_api_common() */ + +/*------------------------------------------------------------------------- + * Function: H5Ropen_region + * + * Purpose: Given a reference to some object, creates a copy of the dataset + * pointed to's dataspace and defines a selection in the copy + * which is the region pointed to. + * + * Return: Valid ID on success / H5I_INVALID_HID on failure + * + *------------------------------------------------------------------------- + */ +hid_t +H5Ropen_region(H5R_ref_t *ref_ptr, hid_t rapl_id, hid_t oapl_id) +{ + hid_t ret_value = H5I_INVALID_HID; /* Return value */ + + FUNC_ENTER_API(H5I_INVALID_HID) + H5TRACE3("i", "*Rrii", ref_ptr, rapl_id, oapl_id); + + /* Open the region synchronously */ + if ((ret_value = H5R__open_region_api_common(ref_ptr, rapl_id, oapl_id, NULL, NULL)) < 0) + HGOTO_ERROR(H5E_REFERENCE, H5E_CANTOPENOBJ, H5I_INVALID_HID, "unable to open region synchronously") + +done: FUNC_LEAVE_API(ret_value) } /* end H5Ropen_region() */ /*------------------------------------------------------------------------- - * Function: H5Ropen_attr + * Function: H5Ropen_region_async * - * Purpose: Given a reference to some attribute, open that attribute and - * return an ID for that attribute. + * Purpose: Asynchronous version of H5Ropen_region * * Return: Valid ID on success / H5I_INVALID_HID on failure * *------------------------------------------------------------------------- */ hid_t -H5Ropen_attr(H5R_ref_t *ref_ptr, hid_t rapl_id, hid_t aapl_id) +H5Ropen_region_async(const char *app_file, const char *app_func, unsigned app_line, H5R_ref_t *ref_ptr, + hid_t rapl_id, hid_t oapl_id, hid_t es_id) +{ + H5VL_object_t *vol_obj = NULL; /* Object of loc_id */ + void * token = NULL; /* Request token for async operation */ + void ** token_ptr = H5_REQUEST_NULL; /* Pointer to request token for async operation */ + hid_t ret_value = H5I_INVALID_HID; /* Return value */ + + FUNC_ENTER_API(H5I_INVALID_HID) + H5TRACE7("i", "*s*sIu*Rriii", app_file, app_func, app_line, ref_ptr, rapl_id, oapl_id, es_id); + + /* Set up request token pointer for asynchronous operation */ + if (H5ES_NONE != es_id) + token_ptr = &token; /* Point at token for VOL connector to set up */ + + /* Open the region asynchronously */ + if ((ret_value = H5R__open_region_api_common(ref_ptr, rapl_id, oapl_id, token_ptr, &vol_obj)) < 0) + HGOTO_ERROR(H5E_REFERENCE, H5E_CANTOPENOBJ, H5I_INVALID_HID, "unable to open region asynchronously") + + /* If a token was created, add the token to the event set */ + if (NULL != token) + /* clang-format off */ + if (H5ES_insert(es_id, vol_obj->connector, token, + H5ARG_TRACE7(FUNC, "*s*sIu*Rriii", app_file, app_func, app_line, ref_ptr, rapl_id, oapl_id, es_id)) < 0) { + /* clang-format on */ + if (H5I_dec_app_ref_always_close(ret_value) < 0) + HGOTO_ERROR(H5E_REFERENCE, H5E_CANTDEC, H5I_INVALID_HID, "can't decrement count on region ID") + HGOTO_ERROR(H5E_REFERENCE, H5E_CANTINSERT, H5I_INVALID_HID, "can't insert token into event set") + } /* end if */ + +done: + FUNC_LEAVE_API(ret_value) +} /* end H5Ropen_region_async() */ + +/*------------------------------------------------------------------------- + * Function: H5R__open_attr_api_common + * + * Purpose: This is the common function for opening an attribute via a reference. + * + * Return: Valid ID on success / H5I_INVALID_HID on failure + * + *------------------------------------------------------------------------- + */ +static hid_t +H5R__open_attr_api_common(H5R_ref_t *ref_ptr, hid_t rapl_id, hid_t aapl_id, void **token_ptr, + H5VL_object_t **_vol_obj_ptr) { - hid_t loc_id; /* Reference location ID */ - H5VL_object_t * vol_obj = NULL; /* Object of loc_id */ + hid_t loc_id; /* Reference location ID */ + H5VL_object_t * tmp_vol_obj = NULL; /* Object for loc_id */ + H5VL_object_t **vol_obj_ptr = + (_vol_obj_ptr ? _vol_obj_ptr : &tmp_vol_obj); /* Ptr to object ptr for loc_id */ H5VL_loc_params_t loc_params; /* Location parameters */ H5O_token_t obj_token = {0}; /* Object token */ H5I_type_t opened_type; /* Opened object type */ @@ -638,8 +782,7 @@ H5Ropen_attr(H5R_ref_t *ref_ptr, hid_t rapl_id, hid_t aapl_id) void * opened_attr = NULL; /* Opened attribute */ hid_t ret_value = H5I_INVALID_HID; /* Return value */ - FUNC_ENTER_API(H5I_INVALID_HID) - H5TRACE3("i", "*Rrii", ref_ptr, rapl_id, aapl_id); + FUNC_ENTER_STATIC /* Check args */ if (ref_ptr == NULL) @@ -663,7 +806,7 @@ H5Ropen_attr(H5R_ref_t *ref_ptr, hid_t rapl_id, hid_t aapl_id) HGOTO_ERROR(H5E_REFERENCE, H5E_CANTGET, H5I_INVALID_HID, "unable to get object token") /* Get the VOL object */ - if (NULL == (vol_obj = H5VL_vol_object(loc_id))) + if (NULL == (*vol_obj_ptr = H5VL_vol_object(loc_id))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5I_INVALID_HID, "invalid location identifier") /* Set location parameters */ @@ -672,12 +815,12 @@ H5Ropen_attr(H5R_ref_t *ref_ptr, hid_t rapl_id, hid_t aapl_id) loc_params.obj_type = H5I_get_type(loc_id); /* Open object by token */ - if (NULL == (opened_obj = H5VL_object_open(vol_obj, &loc_params, &opened_type, H5P_DATASET_XFER_DEFAULT, - H5_REQUEST_NULL))) + if (NULL == (opened_obj = H5VL_object_open(*vol_obj_ptr, &loc_params, &opened_type, + H5P_DATASET_XFER_DEFAULT, token_ptr))) HGOTO_ERROR(H5E_REFERENCE, H5E_CANTOPENOBJ, H5I_INVALID_HID, "unable to open object by token") /* Register object */ - if ((opened_obj_id = H5VL_register(opened_type, opened_obj, vol_obj->connector, FALSE)) < 0) + if ((opened_obj_id = H5VL_register(opened_type, opened_obj, (*vol_obj_ptr)->connector, FALSE)) < 0) HGOTO_ERROR(H5E_REFERENCE, H5E_CANTREGISTER, H5I_INVALID_HID, "unable to register object handle") /* Verify access property list and set up collective metadata if appropriate */ @@ -700,19 +843,90 @@ H5Ropen_attr(H5R_ref_t *ref_ptr, hid_t rapl_id, hid_t aapl_id) H5R_REF_ATTRNAME((const H5R_ref_priv_t *)ref_ptr)) /* Register the attribute and get an ID for it */ - if ((ret_value = H5VL_register(H5I_ATTR, opened_attr, vol_obj->connector, TRUE)) < 0) - HGOTO_ERROR(H5E_REFERENCE, H5E_CANTREGISTER, H5I_INVALID_HID, "unable to atomize attribute handle") + if ((ret_value = H5VL_register(H5I_ATTR, opened_attr, (*vol_obj_ptr)->connector, TRUE)) < 0) + HGOTO_ERROR(H5E_REFERENCE, H5E_CANTREGISTER, H5I_INVALID_HID, "unable to register attribute handle") done: if ((opened_obj_id != H5I_INVALID_HID) && (H5I_dec_ref(opened_obj_id) < 0)) HDONE_ERROR(H5E_REFERENCE, H5E_CLOSEERROR, H5I_INVALID_HID, "can't close object") if (H5I_INVALID_HID == ret_value) /* Cleanup on failure */ - if (opened_attr && H5VL_attr_close(vol_obj, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0) + if (opened_attr && H5VL_attr_close(*vol_obj_ptr, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0) HDONE_ERROR(H5E_REFERENCE, H5E_CLOSEERROR, H5I_INVALID_HID, "can't close attribute") + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5R__open_attr_api_common() */ + +/*------------------------------------------------------------------------- + * Function: H5Ropen_attr + * + * Purpose: Given a reference to some attribute, open that attribute and + * return an ID for that attribute. + * + * Return: Valid ID on success / H5I_INVALID_HID on failure + * + *------------------------------------------------------------------------- + */ +hid_t +H5Ropen_attr(H5R_ref_t *ref_ptr, hid_t rapl_id, hid_t aapl_id) +{ + hid_t ret_value = H5I_INVALID_HID; /* Return value */ + + FUNC_ENTER_API(H5I_INVALID_HID) + H5TRACE3("i", "*Rrii", ref_ptr, rapl_id, aapl_id); + + /* Open the attribute synchronously */ + if ((ret_value = H5R__open_attr_api_common(ref_ptr, rapl_id, aapl_id, NULL, NULL)) < 0) + HGOTO_ERROR(H5E_REFERENCE, H5E_OPENERROR, H5I_INVALID_HID, "unable to open attribute synchronously") + +done: FUNC_LEAVE_API(ret_value) } /* end H5Ropen_attr() */ +/*-------------------------------------------------------------------------- + * Function: H5Ropen_attr_async + * + * Purpose: Asynchronous version of H5Ropen_attr + * + * Return: An attribute ID on success / H5I_INVALID_HID on failure + * + *------------------------------------------------------------------------- + */ +hid_t +H5Ropen_attr_async(const char *app_file, const char *app_func, unsigned app_line, H5R_ref_t *ref_ptr, + hid_t rapl_id, hid_t aapl_id, hid_t es_id) +{ + H5VL_object_t *vol_obj = NULL; /* Object for loc_id */ + void * token = NULL; /* Request token for async operation */ + void ** token_ptr = H5_REQUEST_NULL; /* Pointer to request token for async operation */ + hid_t ret_value; /* Return value */ + + FUNC_ENTER_API(H5I_INVALID_HID) + H5TRACE7("i", "*s*sIu*Rriii", app_file, app_func, app_line, ref_ptr, rapl_id, aapl_id, es_id); + + /* Set up request token pointer for asynchronous operation */ + if (H5ES_NONE != es_id) + token_ptr = &token; /* Point at token for VOL connector to set up */ + + /* Open the attribute asynchronously */ + if ((ret_value = H5R__open_attr_api_common(ref_ptr, rapl_id, aapl_id, token_ptr, &vol_obj)) < 0) + HGOTO_ERROR(H5E_REFERENCE, H5E_OPENERROR, H5I_INVALID_HID, "unable to open attribute asynchronously") + + /* If a token was created, add the token to the event set */ + if (NULL != token) + /* clang-format off */ + if (H5ES_insert(es_id, vol_obj->connector, token, + H5ARG_TRACE7(FUNC, "*s*sIu*Rriii", app_file, app_func, app_line, ref_ptr, rapl_id, aapl_id, es_id)) < 0) { + /* clang-format on */ + if (H5I_dec_app_ref_always_close(ret_value) < 0) + HGOTO_ERROR(H5E_REFERENCE, H5E_CANTDEC, H5I_INVALID_HID, + "can't decrement count on attribute ID") + HGOTO_ERROR(H5E_REFERENCE, H5E_CANTINSERT, H5I_INVALID_HID, "can't insert token into event set") + } /* end if */ + +done: + FUNC_LEAVE_API(ret_value) +} /* H5Ropen_attr_async() */ + /*------------------------------------------------------------------------- * Function: H5Rget_obj_type3 * @@ -724,7 +938,7 @@ done: *------------------------------------------------------------------------- */ herr_t -H5Rget_obj_type3(H5R_ref_t *ref_ptr, hid_t rapl_id, H5O_type_t *obj_type) +H5Rget_obj_type3(H5R_ref_t *ref_ptr, hid_t rapl_id, H5O_type_t *obj_type /*out*/) { hid_t loc_id; /* Reference location ID */ H5VL_object_t * vol_obj = NULL; /* Object of loc_id */ @@ -733,7 +947,7 @@ H5Rget_obj_type3(H5R_ref_t *ref_ptr, hid_t rapl_id, H5O_type_t *obj_type) herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API(FAIL) - H5TRACE3("e", "*Rri*Ot", ref_ptr, rapl_id, obj_type); + H5TRACE3("e", "*Rrix", ref_ptr, rapl_id, obj_type); /* Check args */ if (ref_ptr == NULL) @@ -784,13 +998,13 @@ done: *------------------------------------------------------------------------- */ ssize_t -H5Rget_file_name(const H5R_ref_t *ref_ptr, char *buf, size_t size) +H5Rget_file_name(const H5R_ref_t *ref_ptr, char *buf /*out*/, size_t size) { hid_t loc_id; /* Reference location ID */ ssize_t ret_value; /* Return value */ FUNC_ENTER_API((-1)) - H5TRACE3("Zs", "*Rr*sz", ref_ptr, buf, size); + H5TRACE3("Zs", "*Rrxz", ref_ptr, buf, size); /* Check args */ if (ref_ptr == NULL) @@ -833,7 +1047,7 @@ done: *------------------------------------------------------------------------- */ ssize_t -H5Rget_obj_name(H5R_ref_t *ref_ptr, hid_t rapl_id, char *buf, size_t size) +H5Rget_obj_name(H5R_ref_t *ref_ptr, hid_t rapl_id, char *buf /*out*/, size_t size) { hid_t loc_id; /* Reference location ID */ H5VL_object_t * vol_obj = NULL; /* Object of loc_id */ @@ -842,7 +1056,7 @@ H5Rget_obj_name(H5R_ref_t *ref_ptr, hid_t rapl_id, char *buf, size_t size) ssize_t ret_value = 0; /* Return value */ FUNC_ENTER_API((-1)) - H5TRACE4("Zs", "*Rri*sz", ref_ptr, rapl_id, buf, size); + H5TRACE4("Zs", "*Rrixz", ref_ptr, rapl_id, buf, size); /* Check args */ if (ref_ptr == NULL) @@ -892,12 +1106,12 @@ done: *------------------------------------------------------------------------- */ ssize_t -H5Rget_attr_name(const H5R_ref_t *ref_ptr, char *buf, size_t size) +H5Rget_attr_name(const H5R_ref_t *ref_ptr, char *buf /*out*/, size_t size) { ssize_t ret_value; /* Return value */ FUNC_ENTER_API((-1)) - H5TRACE3("Zs", "*Rr*sz", ref_ptr, buf, size); + H5TRACE3("Zs", "*Rrxz", ref_ptr, buf, size); /* Check args */ if (ref_ptr == NULL) diff --git a/src/H5Rdeprec.c b/src/H5Rdeprec.c index c66ae7c..d5f5a7d 100644 --- a/src/H5Rdeprec.c +++ b/src/H5Rdeprec.c @@ -61,6 +61,10 @@ /********************/ /* Local Prototypes */ /********************/ +static herr_t H5R__encode_token_region_compat(H5F_t *f, const H5O_token_t *obj_token, size_t token_size, + H5S_t *space, unsigned char *buf, size_t *nalloc); +static herr_t H5R__decode_token_compat(H5VL_object_t *vol_obj, H5I_type_t type, H5R_type_t ref_type, + const unsigned char *buf, H5O_token_t *obj_token); /*********************/ /* Package Variables */ @@ -74,8 +78,155 @@ /* Local Variables */ /*******************/ -#ifndef H5_NO_DEPRECATED_SYMBOLS +/*------------------------------------------------------------------------- + * Function: H5R__decode_token_compat + * + * Purpose: Decode an object token. (native only) + * + * Return: SUCCEED/FAIL + * + *------------------------------------------------------------------------- + */ +static herr_t +H5R__decode_token_compat(H5VL_object_t *vol_obj, H5I_type_t type, H5R_type_t ref_type, + const unsigned char *buf, H5O_token_t *obj_token) +{ + hid_t file_id = H5I_INVALID_HID; /* File ID for region reference */ + H5VL_object_t * vol_obj_file = NULL; + H5VL_file_cont_info_t cont_info = {H5VL_CONTAINER_INFO_VERSION, 0, 0, 0}; + herr_t ret_value = SUCCEED; + + FUNC_ENTER_STATIC + +#ifndef NDEBUG + { + hbool_t is_native = FALSE; /* Whether the src file is using the native VOL connector */ + + /* Check if using native VOL connector */ + if (H5VL_object_is_native(vol_obj, &is_native) < 0) + HGOTO_ERROR(H5E_REFERENCE, H5E_CANTGET, FAIL, "can't query if file uses native VOL connector") + + /* Must use native VOL connector for this operation */ + HDassert(is_native); + } +#endif /* NDEBUG */ + + /* Get the file for the object */ + if ((file_id = H5F_get_file_id(vol_obj, type, FALSE)) < 0) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file or file object") + + /* Retrieve VOL object */ + if (NULL == (vol_obj_file = H5VL_vol_object(file_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid location identifier") + + /* Get container info */ + if (H5VL_file_get((const H5VL_object_t *)vol_obj_file, H5VL_FILE_GET_CONT_INFO, H5P_DATASET_XFER_DEFAULT, + H5_REQUEST_NULL, &cont_info) < 0) + HGOTO_ERROR(H5E_REFERENCE, H5E_CANTGET, FAIL, "unable to get container info") + if (ref_type == H5R_OBJECT1) { + size_t buf_size = H5R_OBJ_REF_BUF_SIZE; + + /* Get object address */ + if (H5R__decode_token_obj_compat(buf, &buf_size, obj_token, cont_info.token_size) < 0) + HGOTO_ERROR(H5E_REFERENCE, H5E_CANTDECODE, FAIL, "unable to get object token") + } /* end if */ + else { + size_t buf_size = H5R_DSET_REG_REF_BUF_SIZE; + H5F_t *f = NULL; + + /* Retrieve file from VOL object */ + if (NULL == (f = (H5F_t *)H5VL_object_data((const H5VL_object_t *)vol_obj_file))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid VOL object") + + /* Get object address */ + if (H5R__decode_token_region_compat(f, buf, &buf_size, obj_token, cont_info.token_size, NULL) < 0) + HGOTO_ERROR(H5E_REFERENCE, H5E_CANTDECODE, FAIL, "unable to get object address") + } /* end else */ + +done: + if (file_id != H5I_INVALID_HID && H5I_dec_ref(file_id) < 0) + HDONE_ERROR(H5E_REFERENCE, H5E_CANTDEC, FAIL, "unable to decrement refcount on file") + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5R__decode_token_compat() */ + +/*------------------------------------------------------------------------- + * Function: H5R__encode_token_region_compat + * + * Purpose: Encode dataset selection and insert data into heap + * (native only). + * + * Return: SUCCEED/FAIL + * + *------------------------------------------------------------------------- + */ +static herr_t +H5R__encode_token_region_compat(H5F_t *f, const H5O_token_t *obj_token, size_t token_size, H5S_t *space, + unsigned char *buf, size_t *nalloc) +{ + size_t buf_size; + unsigned char *data = NULL; + herr_t ret_value = SUCCEED; + + FUNC_ENTER_STATIC + + HDassert(f); + HDassert(obj_token); + HDassert(token_size); + HDassert(space); + HDassert(nalloc); + + /* Get required buffer size */ + if (H5R__encode_heap(f, NULL, &buf_size, NULL, (size_t)0) < 0) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid location identifier") + + if (buf && *nalloc >= buf_size) { + ssize_t data_size; + uint8_t *p; + + /* Pass the correct encoding version for the selection depending on the + * file libver bounds, this is later retrieved in H5S hyper encode */ + H5CX_set_libver_bounds(f); + + /* Zero the heap ID out, may leak heap space if user is re-using + * reference and doesn't have garbage collection turned on + */ + HDmemset(buf, 0, buf_size); + + /* Get the amount of space required to serialize the selection */ + if ((data_size = H5S_SELECT_SERIAL_SIZE(space)) < 0) + HGOTO_ERROR(H5E_REFERENCE, H5E_CANTINIT, FAIL, + "Invalid amount of space for serializing selection") + + /* Increase buffer size to allow for the dataset token */ + data_size += (hssize_t)token_size; + + /* Allocate the space to store the serialized information */ + H5_CHECK_OVERFLOW(data_size, hssize_t, size_t); + if (NULL == (data = (uint8_t *)H5MM_malloc((size_t)data_size))) + HGOTO_ERROR(H5E_REFERENCE, H5E_NOSPACE, FAIL, "memory allocation failed") + + /* Serialize information for dataset OID into heap buffer */ + p = (uint8_t *)data; + H5MM_memcpy(p, obj_token, token_size); + p += token_size; + + /* Serialize the selection into heap buffer */ + if (H5S_SELECT_SERIALIZE(space, &p) < 0) + HGOTO_ERROR(H5E_REFERENCE, H5E_CANTCOPY, FAIL, "Unable to serialize selection") + + /* Write to heap */ + if (H5R__encode_heap(f, buf, nalloc, data, (size_t)data_size) < 0) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid location identifier") + } + *nalloc = buf_size; + +done: + H5MM_free(data); + FUNC_LEAVE_NOAPI(ret_value) +} /* H5R__encode_token_region_compat() */ + +#ifndef H5_NO_DEPRECATED_SYMBOLS /*------------------------------------------------------------------------- * Function: H5Rget_obj_type1 * @@ -298,7 +449,7 @@ H5Rcreate(void *ref, hid_t loc_id, const char *name, H5R_type_t ref_type, hid_t size_t buf_size = H5R_DSET_REG_REF_BUF_SIZE; /* Retrieve space */ - if (space_id == H5I_BADID) + if (space_id == H5I_INVALID_HID) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "reference region dataspace id must be valid") if (NULL == (space = (struct H5S_t *)H5I_object_verify(space_id, H5I_DATASPACE))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a dataspace") @@ -330,7 +481,7 @@ done: *------------------------------------------------------------------------- */ herr_t -H5Rget_obj_type2(hid_t id, H5R_type_t ref_type, const void *ref, H5O_type_t *obj_type) +H5Rget_obj_type2(hid_t id, H5R_type_t ref_type, const void *ref, H5O_type_t *obj_type /*out*/) { H5VL_object_t * vol_obj = NULL; /* Object of loc_id */ H5I_type_t vol_obj_type = H5I_BADID; /* Object type of loc_id */ @@ -340,7 +491,7 @@ H5Rget_obj_type2(hid_t id, H5R_type_t ref_type, const void *ref, H5O_type_t *obj herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API(FAIL) - H5TRACE4("e", "iRt*x*Ot", id, ref_type, ref, obj_type); + H5TRACE4("e", "iRt*xx", id, ref_type, ref, obj_type); /* Check args */ if (buf == NULL) @@ -520,9 +671,9 @@ H5Rget_region(hid_t id, H5R_type_t ref_type, const void *ref) if (H5R__decode_token_region_compat(f, buf, &buf_size, NULL, cont_info.token_size, &space) < 0) HGOTO_ERROR(H5E_REFERENCE, H5E_CANTGET, H5I_INVALID_HID, "unable to get dataspace") - /* Atomize */ + /* Register */ if ((ret_value = H5I_register(H5I_DATASPACE, space, TRUE)) < 0) - HGOTO_ERROR(H5E_REFERENCE, H5E_CANTREGISTER, H5I_INVALID_HID, "unable to register dataspace atom") + HGOTO_ERROR(H5E_REFERENCE, H5E_CANTREGISTER, H5I_INVALID_HID, "unable to register dataspace ID") done: if (file_id != H5I_INVALID_HID && H5I_dec_ref(file_id) < 0) @@ -542,7 +693,7 @@ done: *------------------------------------------------------------------------- */ ssize_t -H5Rget_name(hid_t id, H5R_type_t ref_type, const void *ref, char *name, size_t size) +H5Rget_name(hid_t id, H5R_type_t ref_type, const void *ref, char *name /*out*/, size_t size) { H5VL_object_t * vol_obj = NULL; /* Object of loc_id */ H5I_type_t vol_obj_type = H5I_BADID; /* Object type of loc_id */ @@ -552,7 +703,7 @@ H5Rget_name(hid_t id, H5R_type_t ref_type, const void *ref, char *name, size_t s ssize_t ret_value = -1; /* Return value */ FUNC_ENTER_API((-1)) - H5TRACE5("Zs", "iRt*x*sz", id, ref_type, ref, name, size); + H5TRACE5("Zs", "iRt*xxz", id, ref_type, ref, name, size); /* Check args */ if (buf == NULL) diff --git a/src/H5Rint.c b/src/H5Rint.c index 685c709..b714f09 100644 --- a/src/H5Rint.c +++ b/src/H5Rint.c @@ -89,7 +89,6 @@ } while (0) /* Debug */ -//#define H5R_DEBUG #ifdef H5R_DEBUG #define H5R_LOG_DEBUG(...) \ do { \ @@ -192,7 +191,7 @@ H5R__init_package(void) RETURNS void DESCRIPTION - Release IDs for the atom group, deferring full interface shutdown + Release IDs for the ID group, deferring full interface shutdown until later (in H5R_term_package). GLOBAL VARIABLES COMMENTS, BUGS, ASSUMPTIONS @@ -225,7 +224,7 @@ H5R_top_term_package(void) RETURNS void DESCRIPTION - Release the atom group and any other resources allocated. + Release the ID group and any other resources allocated. GLOBAL VARIABLES COMMENTS, BUGS, ASSUMPTIONS Can't report errors... @@ -547,7 +546,7 @@ H5R__reopen_file(H5R_ref_priv_t *ref, hid_t fapl_id) void * new_file = NULL; /* File object opened */ H5VL_connector_prop_t connector_prop; /* Property for VOL connector ID & info */ H5VL_object_t * vol_obj = NULL; /* VOL object for file */ - hbool_t supported; /* Whether 'post open' operation is supported by VOL connector */ + uint64_t supported; /* Whether 'post open' operation is supported by VOL connector */ hid_t ret_value = H5I_INVALID_HID; FUNC_ENTER_PACKAGE @@ -579,17 +578,17 @@ H5R__reopen_file(H5R_ref_priv_t *ref, hid_t fapl_id) /* Get an ID for the file */ if ((ret_value = H5VL_register_using_vol_id(H5I_FILE, new_file, connector_prop.connector_id, TRUE)) < 0) - HGOTO_ERROR(H5E_REFERENCE, H5E_CANTREGISTER, H5I_INVALID_HID, "unable to atomize file handle") + HGOTO_ERROR(H5E_REFERENCE, H5E_CANTREGISTER, H5I_INVALID_HID, "unable to register file handle") /* Get the file object */ if (NULL == (vol_obj = H5VL_vol_object(ret_value))) HGOTO_ERROR(H5E_REFERENCE, H5E_CANTGET, H5I_INVALID_HID, "invalid object identifier") /* Make the 'post open' callback */ - supported = FALSE; + supported = 0; if (H5VL_introspect_opt_query(vol_obj, H5VL_SUBCLS_FILE, H5VL_NATIVE_FILE_POST_OPEN, &supported) < 0) HGOTO_ERROR(H5E_REFERENCE, H5E_CANTGET, H5I_INVALID_HID, "can't check for 'post open' operation") - if (supported) + if (supported & H5VL_OPT_QUERY_SUPPORTED) if (H5VL_file_optional(vol_obj, H5VL_NATIVE_FILE_POST_OPEN, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0) HGOTO_ERROR(H5E_REFERENCE, H5E_CANTINIT, H5I_INVALID_HID, @@ -747,8 +746,10 @@ H5R__copy(const H5R_ref_priv_t *src_ref, H5R_ref_priv_t *dst_ref) dst_ref->info.obj.filename = NULL; /* Set location ID and hold reference to it */ - if (H5R__set_loc_id(dst_ref, src_ref->loc_id, TRUE, TRUE) < 0) - HGOTO_ERROR(H5E_REFERENCE, H5E_CANTSET, FAIL, "cannot set reference location ID") + dst_ref->loc_id = src_ref->loc_id; + if (H5I_inc_ref(dst_ref->loc_id, TRUE) < 0) + HGOTO_ERROR(H5E_REFERENCE, H5E_CANTINC, FAIL, "incrementing location ID failed") + dst_ref->app_ref = TRUE; } done: @@ -807,7 +808,7 @@ H5R__set_obj_token(H5R_ref_priv_t *ref, const H5O_token_t *obj_token, size_t tok HDassert(token_size); HDassert(token_size <= H5O_MAX_TOKEN_SIZE); - H5MM_memcpy(&ref->info.obj.token, obj_token, sizeof(H5O_token_t)); + H5MM_memcpy(&ref->info.obj.token, obj_token, token_size); HDassert(token_size <= 255); ref->token_size = (uint8_t)token_size; @@ -1040,12 +1041,13 @@ H5R__decode(const unsigned char *buf, size_t *nbytes, H5R_ref_priv_t *ref) FUNC_ENTER_PACKAGE + /* Sanity checks */ HDassert(buf); HDassert(nbytes); HDassert(ref); - buf_size = *nbytes; /* Don't decode if buffer size isn't big enough */ + buf_size = *nbytes; if (buf_size < H5R_ENCODE_HEADER_SIZE) HGOTO_ERROR(H5E_REFERENCE, H5E_CANTDECODE, FAIL, "Buffer size is too small") @@ -1106,6 +1108,7 @@ H5R__decode(const unsigned char *buf, size_t *nbytes, H5R_ref_priv_t *ref) H5R_LOG_DEBUG("Decoded reference, filename=%s, obj_addr=%s, encode size=%u", ref->info.obj.filename, H5R__print_token(ref->info.obj.token), ref->encode_size); + /* Set output info */ *nbytes = decode_size; done: @@ -1465,122 +1468,6 @@ done: } /* end H5R__decode_heap() */ /*------------------------------------------------------------------------- - * Function: H5R__free_heap - * - * Purpose: Remove data previously inserted into heap (native only). - * - * Return: SUCCEED/FAIL - * - *------------------------------------------------------------------------- - */ -herr_t -H5R__free_heap(H5F_t *f, const unsigned char *buf, size_t nbytes) -{ - H5HG_t hobjid; - const uint8_t *p = (const uint8_t *)buf; - size_t buf_size; - herr_t ret_value = SUCCEED; - - FUNC_ENTER_PACKAGE - - HDassert(f); - HDassert(buf); - - buf_size = H5HG_HEAP_ID_SIZE(f); - /* Don't decode if buffer size isn't big enough */ - if (nbytes < buf_size) - HGOTO_ERROR(H5E_REFERENCE, H5E_CANTDECODE, FAIL, "Buffer size is too small") - - /* Get the heap information */ - H5F_addr_decode(f, &p, &(hobjid.addr)); - if (!H5F_addr_defined(hobjid.addr) || hobjid.addr == 0) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "Undefined reference pointer") - UINT32DECODE(p, hobjid.idx); - - /* Free heap object */ - if (hobjid.addr > 0) { - /* Free heap object */ - if (H5HG_remove(f, &hobjid) < 0) - HGOTO_ERROR(H5E_REFERENCE, H5E_WRITEERROR, FAIL, "Unable to remove heap object") - } /* end if */ - -done: - FUNC_LEAVE_NOAPI(ret_value) -} /* end H5R__free_heap() */ - -/*------------------------------------------------------------------------- - * Function: H5R__decode_token_compat - * - * Purpose: Decode an object token. (native only) - * - * Return: SUCCEED/FAIL - * - *------------------------------------------------------------------------- - */ -herr_t -H5R__decode_token_compat(H5VL_object_t *vol_obj, H5I_type_t type, H5R_type_t ref_type, - const unsigned char *buf, H5O_token_t *obj_token) -{ - hid_t file_id = H5I_INVALID_HID; /* File ID for region reference */ - H5VL_object_t * vol_obj_file = NULL; - H5VL_file_cont_info_t cont_info = {H5VL_CONTAINER_INFO_VERSION, 0, 0, 0}; - herr_t ret_value = SUCCEED; - - FUNC_ENTER_PACKAGE - -#ifndef NDEBUG - { - hbool_t is_native = FALSE; /* Whether the src file is using the native VOL connector */ - - /* Check if using native VOL connector */ - if (H5VL_object_is_native(vol_obj, &is_native) < 0) - HGOTO_ERROR(H5E_REFERENCE, H5E_CANTGET, FAIL, "can't query if file uses native VOL connector") - - /* Must use native VOL connector for this operation */ - HDassert(is_native); - } -#endif /* NDEBUG */ - - /* Get the file for the object */ - if ((file_id = H5F_get_file_id(vol_obj, type, FALSE)) < 0) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file or file object") - - /* Retrieve VOL object */ - if (NULL == (vol_obj_file = H5VL_vol_object(file_id))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid location identifier") - - /* Get container info */ - if (H5VL_file_get((const H5VL_object_t *)vol_obj_file, H5VL_FILE_GET_CONT_INFO, H5P_DATASET_XFER_DEFAULT, - H5_REQUEST_NULL, &cont_info) < 0) - HGOTO_ERROR(H5E_REFERENCE, H5E_CANTGET, FAIL, "unable to get container info") - - if (ref_type == H5R_OBJECT1) { - size_t buf_size = H5R_OBJ_REF_BUF_SIZE; - - /* Get object address */ - if (H5R__decode_token_obj_compat(buf, &buf_size, obj_token, cont_info.token_size) < 0) - HGOTO_ERROR(H5E_REFERENCE, H5E_CANTDECODE, FAIL, "unable to get object token") - } /* end if */ - else { - size_t buf_size = H5R_DSET_REG_REF_BUF_SIZE; - H5F_t *f = NULL; - - /* Retrieve file from VOL object */ - if (NULL == (f = (H5F_t *)H5VL_object_data((const H5VL_object_t *)vol_obj_file))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid VOL object") - - /* Get object address */ - if (H5R__decode_token_region_compat(f, buf, &buf_size, obj_token, cont_info.token_size, NULL) < 0) - HGOTO_ERROR(H5E_REFERENCE, H5E_CANTDECODE, FAIL, "unable to get object address") - } /* end else */ - -done: - if (file_id != H5I_INVALID_HID && H5I_dec_ref(file_id) < 0) - HDONE_ERROR(H5E_REFERENCE, H5E_CANTDEC, FAIL, "unable to decrement refcount on file") - FUNC_LEAVE_NOAPI(ret_value) -} /* end H5R__decode_token_compat() */ - -/*------------------------------------------------------------------------- * Function: H5R__encode_token_obj_compat * * Purpose: Encode an object token. (native only) @@ -1645,82 +1532,6 @@ done: } /* H5R__decode_token_obj_compat() */ /*------------------------------------------------------------------------- - * Function: H5R__encode_token_region_compat - * - * Purpose: Encode dataset selection and insert data into heap - * (native only). - * - * Return: SUCCEED/FAIL - * - *------------------------------------------------------------------------- - */ -herr_t -H5R__encode_token_region_compat(H5F_t *f, const H5O_token_t *obj_token, size_t token_size, H5S_t *space, - unsigned char *buf, size_t *nalloc) -{ - size_t buf_size; - unsigned char *data = NULL; - herr_t ret_value = SUCCEED; - - FUNC_ENTER_PACKAGE - - HDassert(f); - HDassert(obj_token); - HDassert(token_size); - HDassert(space); - HDassert(nalloc); - - /* Get required buffer size */ - if (H5R__encode_heap(f, NULL, &buf_size, NULL, (size_t)0) < 0) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid location identifier") - - if (buf && *nalloc >= buf_size) { - ssize_t data_size; - uint8_t *p; - - /* Pass the correct encoding version for the selection depending on the - * file libver bounds, this is later retrieved in H5S hyper encode */ - H5CX_set_libver_bounds(f); - - /* Zero the heap ID out, may leak heap space if user is re-using - * reference and doesn't have garbage collection turned on - */ - HDmemset(buf, 0, buf_size); - - /* Get the amount of space required to serialize the selection */ - if ((data_size = H5S_SELECT_SERIAL_SIZE(space)) < 0) - HGOTO_ERROR(H5E_REFERENCE, H5E_CANTINIT, FAIL, - "Invalid amount of space for serializing selection") - - /* Increase buffer size to allow for the dataset token */ - data_size += (hssize_t)token_size; - - /* Allocate the space to store the serialized information */ - H5_CHECK_OVERFLOW(data_size, hssize_t, size_t); - if (NULL == (data = (uint8_t *)H5MM_malloc((size_t)data_size))) - HGOTO_ERROR(H5E_REFERENCE, H5E_NOSPACE, FAIL, "memory allocation failed") - - /* Serialize information for dataset OID into heap buffer */ - p = (uint8_t *)data; - H5MM_memcpy(p, obj_token, token_size); - p += token_size; - - /* Serialize the selection into heap buffer */ - if (H5S_SELECT_SERIALIZE(space, &p) < 0) - HGOTO_ERROR(H5E_REFERENCE, H5E_CANTCOPY, FAIL, "Unable to serialize selection") - - /* Write to heap */ - if (H5R__encode_heap(f, buf, nalloc, data, (size_t)data_size) < 0) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid location identifier") - } - *nalloc = buf_size; - -done: - H5MM_free(data); - FUNC_LEAVE_NOAPI(ret_value) -} /* H5R__encode_token_region_compat() */ - -/*------------------------------------------------------------------------- * Function: H5R__decode_token_region_compat * * Purpose: Decode dataset selection from data inserted into heap diff --git a/src/H5Rpkg.h b/src/H5Rpkg.h index 4224805..ee5fb71 100644 --- a/src/H5Rpkg.h +++ b/src/H5Rpkg.h @@ -119,18 +119,12 @@ H5_DLL herr_t H5R__encode_heap(H5F_t *f, unsigned char *buf, size_t *nalloc, con size_t data_size); H5_DLL herr_t H5R__decode_heap(H5F_t *f, const unsigned char *buf, size_t *nbytes, unsigned char **data_ptr, size_t *data_size); -H5_DLL herr_t H5R__free_heap(H5F_t *f, const unsigned char *buf, size_t nbytes); - -H5_DLL herr_t H5R__decode_token_compat(H5VL_object_t *vol_obj, H5I_type_t type, H5R_type_t ref_type, - const unsigned char *buf, H5O_token_t *obj_token); H5_DLL herr_t H5R__encode_token_obj_compat(const H5O_token_t *obj_token, size_t token_size, unsigned char *buf, size_t *nalloc); H5_DLL herr_t H5R__decode_token_obj_compat(const unsigned char *buf, size_t *nbytes, H5O_token_t *obj_token, size_t token_size); -H5_DLL herr_t H5R__encode_token_region_compat(H5F_t *f, const H5O_token_t *obj_token, size_t token_size, - H5S_t *space, unsigned char *buf, size_t *nalloc); H5_DLL herr_t H5R__decode_token_region_compat(H5F_t *f, const unsigned char *buf, size_t *nbytes, H5O_token_t *obj_token, size_t token_size, H5S_t **space_ptr); diff --git a/src/H5Rpublic.h b/src/H5Rpublic.h index 4a82119..b33960e 100644 --- a/src/H5Rpublic.h +++ b/src/H5Rpublic.h @@ -40,40 +40,54 @@ /* Public Typedefs */ /*******************/ -/* +//! <!-- [H5R_type_t_snip] --> +/** * Reference types allowed. - * DO NOT CHANGE THE ORDER or VALUES as reference type values are encoded into - * the datatype message header. + * + * \internal DO NOT CHANGE THE ORDER or VALUES as reference type values are + * encoded into the datatype message header. */ typedef enum { - H5R_BADTYPE = (-1), /* Invalid reference type */ - H5R_OBJECT1 = 0, /* Backward compatibility (object) */ - H5R_DATASET_REGION1 = 1, /* Backward compatibility (region) */ - H5R_OBJECT2 = 2, /* Object reference */ - H5R_DATASET_REGION2 = 3, /* Region reference */ - H5R_ATTR = 4, /* Attribute Reference */ - H5R_MAXTYPE = 5 /* Highest type (invalid) */ + H5R_BADTYPE = (-1), /**< Invalid reference type */ + H5R_OBJECT1 = 0, /**< Backward compatibility (object) */ + H5R_DATASET_REGION1 = 1, /**< Backward compatibility (region) */ + H5R_OBJECT2 = 2, /**< Object reference */ + H5R_DATASET_REGION2 = 3, /**< Region reference */ + H5R_ATTR = 4, /**< Attribute Reference */ + H5R_MAXTYPE = 5 /**< Highest type (invalid) */ } H5R_type_t; +//! <!-- [H5R_type_t_snip] --> /* Deprecated types are kept for backward compatibility with previous versions */ +//! <!-- [hobj_ref_t_snip] --> /** - * Deprecated object reference type that is used with deprecated reference APIs. - * Note! This type can only be used with the "native" HDF5 VOL connector. + * \deprecated Deprecated object reference type that is used with deprecated + * reference APIs. + * + * \note This type can only be used with the "native" HDF5 VOL connector. */ typedef haddr_t hobj_ref_t; +//! <!-- [hobj_ref_t_snip] --> +//! <!-- [hdset_reg_ref_t_snip] --> /** - * Dataset region reference type that is used with deprecated reference APIs. - * (Buffer to store heap ID and index) - * This needs to be large enough to store largest haddr_t in a worst case + * Buffer to store heap ID and index + * + * This needs to be large enough to store largest #haddr_t in a worst case * machine (8 bytes currently) plus an int. - * Note! This type can only be used with the "native" HDF5 VOL connector. + * + * \deprecated Dataset region reference type that is used with deprecated + * reference APIs. + * + * \note This type can only be used with the "native" HDF5 VOL connector. */ typedef struct { uint8_t __data[H5R_DSET_REG_REF_BUF_SIZE]; } hdset_reg_ref_t; +//! <!-- [hdset_reg_ref_t_snip] --> +//! <!-- [H5R_ref_t_snip] --> /** * Opaque reference type. The same reference type is used for object, * dataset region and attribute references. This is the type that @@ -81,10 +95,11 @@ typedef struct { */ typedef struct { union { - uint8_t __data[H5R_REF_BUF_SIZE]; /* opaque data */ - int64_t align; /* ensures alignment */ + uint8_t __data[H5R_REF_BUF_SIZE]; /**< opaque data */ + int64_t align; /**< ensures alignment */ } u; } H5R_ref_t; +//! <!-- [H5R_ref_t_snip] --> /********************/ /* Public Variables */ @@ -99,30 +114,466 @@ extern "C" { #endif /* Constructors */ +/** + * -------------------------------------------------------------------------- + * \ingroup H5R + * + * \brief Creates an object reference + * + * \fgdta_loc_id + * \param[in] name Name of object + * \oapl_id + * \param[out] ref_ptr Pointer to reference + * + * \return \herr_t + * + * \details H5Rcreate_object() creates a reference pointing to the + * object named \p name located at \p loc_id. The parameters \p + * loc_id and \p name are used to locate the object. + * + * The parameter \p oapl_id is an object access property list + * identifier for the referenced object. The access property list + * must be of the same type as the object being referenced, that is + * a group, dataset or committed datatype property list. + * + * \ref H5R_ref_t is defined in H5Rpublic.h as: + * \snippet this H5R_ref_t_snip + * + * H5Rdestroy() should be used to release the resource from the + * reference. + * + */ H5_DLL herr_t H5Rcreate_object(hid_t loc_id, const char *name, hid_t oapl_id, H5R_ref_t *ref_ptr); + +/** + * -------------------------------------------------------------------------- + * \ingroup H5R + * + * \brief Creates a region reference + * + * \fgdta_loc_id + * \param[in] name Name of object + * \space_id + * \oapl_id + * \param[out] ref_ptr Pointer to reference + * + * \return \herr_t + * + * \details H5Rcreate_region() creates the reference, \p ref_ptr, + * pointing to the region represented by \p space_id within the + * object named name located at \p loc_id. + * + * The parameters \p loc_id and \p name are used to locate the + * object. The parameter \p space_id identifies the dataset region + * that a dataset region reference points to. + * + * The parameter \p oapl_id is an object access property list + * identifier for the referenced object. The access property list + * must be of the same type as the object being referenced, that is + * a dataset property list in this case. + * + * \ref H5R_ref_t is defined in H5Rpublic.h as: + * \snippet this H5R_ref_t_snip + * + * H5Rdestroy() should be used to release the resource from the + * reference. + * + */ H5_DLL herr_t H5Rcreate_region(hid_t loc_id, const char *name, hid_t space_id, hid_t oapl_id, H5R_ref_t *ref_ptr); + +/** + * -------------------------------------------------------------------------- + * \ingroup H5R + * + * \brief Creates an attribute reference + * + * \fgdta_loc_id + * \param[in] name Name of object + * \param[in] attr_name Name of attribute + * \oapl_id + * \param[out] ref_ptr Pointer to reference + * + * \return \herr_t + * + * \details H5Rcreate_attr() creates the reference, \p ref_ptr, pointing + * to the attribute named \p attr_name and attached to the object + * named \p name located at \p loc_id. + * + * The parameters \p loc_id and \p name locate the object. The + * parameter \p attr_name specifies the attribute within the object. + * + * The parameter \p oapl_id is an object access property list + * identifier for the object that the referenced attribute is + * attached to. The access property list must be of the same type + * as that object, that is a group, dataset or committed datatype + * property list. + * + * \ref H5R_ref_t is defined in H5Rpublic.h as: + * \snippet this H5R_ref_t_snip + * + * H5Rdestroy() should be used to release the resource from the + * reference. + * + */ H5_DLL herr_t H5Rcreate_attr(hid_t loc_id, const char *name, const char *attr_name, hid_t oapl_id, H5R_ref_t *ref_ptr); + +/** + * -------------------------------------------------------------------------- + * \ingroup H5R + * + * \brief Closes a reference + * + * \param[in] ref_ptr Pointer to reference + * + * \return \herr_t + * + * \details Given a reference, \p ref_ptr, to an object, region or attribute + * attached to an object, H5Rdestroy() releases allocated resources + * from a previous create call. + * + * \ref H5R_ref_t is defined in H5Rpublic.h as: + * \snippet this H5R_ref_t_snip + * + */ H5_DLL herr_t H5Rdestroy(H5R_ref_t *ref_ptr); /* Info */ + +/** + * -------------------------------------------------------------------------- + * \ingroup H5R + * + * \brief Retrieves the type of a reference + * + * \param[in] ref_ptr Pointer to reference + * + * \return Returns a valid reference type if successful; otherwise returns #H5R_BADTYPE . + * + * \details Given a reference, \p ref_ptr, H5Rget_type() returns the + * type of the reference. + * + * Valid returned reference types are: + * \snippet this H5R_type_t_snip + * + * Note that #H5R_OBJECT1 and #H5R_DATASET_REGION1 can never be + * associated to an \ref H5R_ref_t reference and can therefore never be + * returned through that function. + * + * \ref H5R_ref_t is defined in H5Rpublic.h as: + * \snippet this H5R_ref_t_snip + * + */ H5_DLL H5R_type_t H5Rget_type(const H5R_ref_t *ref_ptr); -H5_DLL htri_t H5Requal(const H5R_ref_t *ref1_ptr, const H5R_ref_t *ref2_ptr); -H5_DLL herr_t H5Rcopy(const H5R_ref_t *src_ref_ptr, H5R_ref_t *dst_ref_ptr); + +/** + * -------------------------------------------------------------------------- + * \ingroup H5R + * + * \brief Determines whether two references are equal + * + * \param[in] ref1_ptr Pointer to reference to compare + * \param[in] ref2_ptr Pointer to reference to compare + * + * \return Returns a positive value if the references are equal. Returns + * 0 if the references are not equal. Returns a negative value when the + * function fails. + * + * \details H5Requal() determines whether two references point to the + * same object, region or attribute. + * + * \ref H5R_ref_t is defined in H5Rpublic.h as: + * \snippet this H5R_ref_t_snip + * + */ +H5_DLL htri_t H5Requal(const H5R_ref_t *ref1_ptr, const H5R_ref_t *ref2_ptr); + +/** + * -------------------------------------------------------------------------- + * \ingroup H5R + * + * \brief Copies an existing reference + * + * \param[in] src_ref_ptr Pointer to reference to copy + * \param[out] dst_ref_ptr Pointer to output reference + * + * \return \herr_t + * + * \details H5Rcopy() creates a copy of an existing reference. + * \p src_ref_ptr points to the reference to copy and \p dst_ref_ptr is the + * pointer to the destination reference. + * + */ +H5_DLL herr_t H5Rcopy(const H5R_ref_t *src_ref_ptr, H5R_ref_t *dst_ref_ptr); /* Dereference */ + +/** + * -------------------------------------------------------------------------- + * \ingroup H5R + * + * \brief Opens the HDF5 object referenced + * + * \param[in] ref_ptr Pointer to reference to open + * \rapl_id + * \oapl_id + * + * \return \hid_t{object} + * + * \details Given a reference, \p ref_ptr, to an object, a region in + * an object, or an attribute attached to an object, H5Ropen_object() + * opens that object and returns an identifier. + * + * The parameter \p oapl_id is an object access property list + * identifier for the referenced object. The access property list + * must be of the same type as the object being referenced, that is + * a group or dataset property list. + * + * \ref H5R_ref_t is defined in H5Rpublic.h as: + * \snippet this H5R_ref_t_snip + * + * The object opened with this function should be closed when it + * is no longer needed so that resource leaks will not develop. Use + * the appropriate close function such as H5Oclose() or H5Dclose() + * for datasets. + * + */ H5_DLL hid_t H5Ropen_object(H5R_ref_t *ref_ptr, hid_t rapl_id, hid_t oapl_id); + +/** + * -------------------------------------------------------------------------- + * \ingroup ASYNC + * \async_variant_of{H5Ropen} + */ +H5_DLL hid_t H5Ropen_object_async(const char *app_file, const char *app_func, unsigned app_line, + H5R_ref_t *ref_ptr, hid_t rapl_id, hid_t oapl_id, hid_t es_id); + +/** + * -------------------------------------------------------------------------- + * \ingroup H5R + * + * \brief Sets up a dataspace and selection as specified by a region reference. + * + * \param[in] ref_ptr Pointer to reference to open + * \rapl_id + * \oapl_id + * + * \return \hid_t{dataspace} + * + * \details H5Ropen_region() creates a copy of the dataspace of the + * dataset pointed to by a region reference, \p ref_ptr, and defines + * a selection matching the selection pointed to by \p ref_ptr within + * the dataspace copy. + * + * The parameter \p rapl id is a reference access property list + * identifier for the reference. The access property list can + * be used to access external files that the reference points to + * (through a file access property list). + * + * The parameter \p oapl id is an object access property list + * identifier for the referenced object. The access property list + * must be of the same type as the object being referenced, that is + * a dataset property list in that case. + * + * Use H5Sclose() to release the dataspace identifier returned by + * this function when the identifier is no longer needed. + * + */ H5_DLL hid_t H5Ropen_region(H5R_ref_t *ref_ptr, hid_t rapl_id, hid_t oapl_id); + +/** + * -------------------------------------------------------------------------- + * \ingroup ASYNC + * \async_variant_of{H5Ropen_region} + */ +H5_DLL hid_t H5Ropen_region_async(const char *app_file, const char *app_func, unsigned app_line, + H5R_ref_t *ref_ptr, hid_t rapl_id, hid_t oapl_id, hid_t es_id); + +/** + * -------------------------------------------------------------------------- + * \ingroup H5R + * + * \brief Opens the HDF5 attribute referenced + * + * \param[in] ref_ptr Pointer to reference to open + * \rapl_id + * \aapl_id + * + * \return \hid_t{attribute} + * + * \details Given a reference, \p ref_ptr, to an attribute attached to + * an object, H5Ropen_attr() opens the attribute attached to that + * object and returns an identifier. + * + * The parameter \p rapl id is a reference access property list + * identifier for the reference. The access property list can + * be used to access external files that the reference points to + * (through a file access property list). + * + * The parameter \p aapl_id is an attribute access property list + * identifier for the referenced attribute. + * + * The attribute opened with this function should be closed with + * H5Aclose() when it is no longer needed. + * + */ H5_DLL hid_t H5Ropen_attr(H5R_ref_t *ref_ptr, hid_t rapl_id, hid_t aapl_id); +/** + * -------------------------------------------------------------------------- + * \ingroup ASYNC + * \async_variant_of{H5Ropen_attr} + */ +H5_DLL hid_t H5Ropen_attr_async(const char *app_file, const char *app_func, unsigned app_line, + H5R_ref_t *ref_ptr, hid_t rapl_id, hid_t aapl_id, hid_t es_id); + /* Get type */ + +/** + * -------------------------------------------------------------------------- + * \ingroup H5R + * + * \brief Retrieves the type of object that an object reference points to + * + * \param[in] ref_ptr Pointer to reference to query + * \rapl_id + * \param[out] obj_type Type of referenced object + * + * \return \herr_t + * + * \details Given a reference, \p ref_ptr, H5Rget_obj_type3() retrieves + * the type of the referenced object in \p obj_type. + * + * The parameter \p rapl id is a reference access property list + * identifier for the reference. The access property list can + * be used to access external files that the reference points to + * (through a file access property list). + * + * Upon success, the function returns in \p obj_type the type of + * the object that the reference points to. Valid values for this + * referenced object type are as followed (defined in H5Opublic.h): + * \snippet H5Opublic.h H5O_type_t_snip + * + */ H5_DLL herr_t H5Rget_obj_type3(H5R_ref_t *ref_ptr, hid_t rapl_id, H5O_type_t *obj_type); /* Get name */ -H5_DLL ssize_t H5Rget_file_name(const H5R_ref_t *ref_ptr, char *buf, size_t size); -H5_DLL ssize_t H5Rget_obj_name(H5R_ref_t *ref_ptr, hid_t rapl_id, char *buf, size_t size); -H5_DLL ssize_t H5Rget_attr_name(const H5R_ref_t *ref_ptr, char *buf, size_t size); + +/** + * -------------------------------------------------------------------------- + * \ingroup H5R + * + * \brief Retrieves the file name for a referenced object + * + * \param[in] ref_ptr Pointer to reference to query + * \param[in,out] name Buffer to place the file name of the reference + * \param[in] size Size of the \p name buffer + * + * \return Returns the length of the name if successful, otherwise, a negative value. + * + * \details H5Rget_file_name() retrieves the file name for the object, + * region or attribute reference pointed to by \p ref_ptr. + * + * Up to \p size characters of the name are returned in \p name; + * additional characters, if any, are not returned to the user + * application. If the length of the name, which determines + * the required value of size, is unknown, a preliminary + * H5Rget_file_name() call can be made. The return value of this + * call will be the size of the file name. That value can then be + * passed in for size in the second call to H5Rget_file_name(), + * which will retrieve the actual name. + * + */ +H5_DLL ssize_t H5Rget_file_name(const H5R_ref_t *ref_ptr, char *name, size_t size); + +/** + * -------------------------------------------------------------------------- + * \ingroup H5R + * + * \brief Retrieves the object name for a referenced object + * + * \param[in] ref_ptr Pointer to reference to query + * \rapl_id + * \param[in,out] name Buffer to place the file name of the reference + * \param[in] size Size of the \p name buffer + * + * \return Returns the length of the name if successful, returning + * 0 (zero) if no name is associated with the identifier. Otherwise + * returns a negative value. + * + * \details H5Rget_obj_name() retrieves the object name for the object, + * region or attribute reference pointed to by \p ref_ptr. + * + * The parameter \p rapl_id is a reference access property list + * identifier for the reference. The access property list can + * be used to access external files that the reference points to + * (through a file access property list). + * + * Up to size characters of the name are returned in \p name; additional + * characters, if any, are not returned to the user application. If + * the length of the name, which determines the required value of + * \p size, is unknown, a preliminary call to H5Rget_obj_name() call + * can be made. The return value of this call will be the size of the + * object name. That value can then be passed in for \p size in the + * second call to H5Rget_obj_name(), which will retrieve the actual + * name. If there is no name associated with the object identifier + * or if the name is NULL, H5Rget_obj_name() returns the size of + * the name buffer (the size does not include the \c \0 terminator). + * + * If \p ref_ptr is an object reference, \p name will be returned with + * a name for the referenced object. If \p ref_ptr is a dataset region + * reference, \p name will contain a name for the object containing + * the referenced region. If \p ref_ptr is an attribute reference, \p + * name will contain a name for the object the attribute is attached + * to. Note that an object in an HDF5 file may have multiple paths + * if there are multiple links pointing to it. This function may + * return any one of these paths. + * + */ +H5_DLL ssize_t H5Rget_obj_name(H5R_ref_t *ref_ptr, hid_t rapl_id, char *name, size_t size); + +/** + * -------------------------------------------------------------------------- + * \ingroup H5R + * + * \brief Retrieves the attribute name for a referenced object + * + * \param[in] ref_ptr Pointer to reference to query + * \param[in,out] name Buffer to place the attribute name of the reference + * \param[in] size Size of the \p name buffer + * + * \return Returns the length of the name if successful, otherwise, a negative value. + * + * \details H5Rget_attr_name() retrieves the attribute name for the + * attribute reference pointed to by \p ref_ptr. + * + * Up to size characters of the name are returned in \p name; + * additional characters, if any, are not returned to the user + * application. If the length of the name, which determines + * the required value of \p size, is unknown, a preliminary + * H5Rget_attr_name() call can be made. The return value of this + * call will be the size of the attribute name. That value can then + * be passed in for size in the second call to H5Rget_attr_name(), + * which will retrieve the actual name. + * + */ +H5_DLL ssize_t H5Rget_attr_name(const H5R_ref_t *ref_ptr, char *name, size_t size); + +/* API Wrappers for async routines */ +/* (Must be defined _after_ the function prototype) */ +/* (And must only defined when included in application code, not the library) */ +#ifndef H5R_MODULE +#define H5Ropen_object_async(...) H5Ropen_object_async(__FILE__, __func__, __LINE__, __VA_ARGS__) +#define H5Ropen_region_async(...) H5Ropen_region_async(__FILE__, __func__, __LINE__, __VA_ARGS__) +#define H5Ropen_attr_async(...) H5Ropen_attr_async(__FILE__, __func__, __LINE__, __VA_ARGS__) + +/* Define "wrapper" versions of function calls, to allow compile-time values to + * be passed in by language wrapper or library layer on top of HDF5. */ +#define H5Ropen_object_async_wrap H5_NO_EXPAND(H5Ropen_object_async) +#define H5Ropen_region_async_wrap H5_NO_EXPAND(H5Ropen_region_async) +#define H5Ropen_attr_async_wrap H5_NO_EXPAND(H5Ropen_attr_async) +#endif /* H5R_MODULE */ /* Symbols defined for compatibility with previous versions of the HDF5 API. * @@ -138,15 +589,334 @@ H5_DLL ssize_t H5Rget_attr_name(const H5R_ref_t *ref_ptr, char *buf, size_t size /* Function prototypes */ #ifndef H5_NO_DEPRECATED_SYMBOLS +/** + * -------------------------------------------------------------------------- + * \ingroup H5R + * + * \brief Retrieves the type of object that an object reference points to + * + * \param[in] id The dataset containing the reference object or the group + * containing that dataset + * \param[in] ref_type Type of reference to query + * \param[in] ref Reference to query + * + * \return Returns a valid object type if successful; otherwise returns a + * negative value (#H5G_UNKNOWN). + * + * \deprecated This function has been renamed from H5Rget_obj_type() and is + * deprecated in favor of the macro H5Rget_obj_type() or the + * function H5Rget_obj_type2(). + * + * \details Given an object reference, \p ref, H5Rget_obj_type1() returns the + * type of the referenced object. + * + * A \Emph{reference type} is the type of reference, either an object + * reference or a dataset region reference. An \Emph{object reference} + * points to an HDF5 object while a \Emph{dataset region reference} + * points to a defined region within a dataset. + * + * The \Emph{referenced object} is the object the reference points + * to. The \Emph{referenced object type}, or the type of the referenced + * object, is the type of the object that the reference points to. + * + * The location identifier, \p id, is the identifier for either the + * dataset containing the object reference or the group containing that + * dataset. + * + * Valid reference types, to pass in as \p ref_type, include the + * following: + * \snippet this H5R_type_t_snip + * + * If the application does not already know the object reference type, + * that can be determined with three preliminary calls: + * + * \li Call H5Dget_type() on the dataset containing the reference to + * get a datatype identifier for the dataset’s datatype. + * \li Using that datatype identifier, H5Tget_class() returns a datatype + * class.\n If the datatype class is #H5T_REFERENCE, H5Tequal() can + * then be used to determine whether the reference’s datatype is + * #H5T_STD_REF_OBJ or #H5T_STD_REF_DSETREG: + * - If the datatype is #H5T_STD_REF_OBJ, the reference object type + * is #H5R_OBJECT. + * - If the datatype is #H5T_STD_REF_DSETREG, the reference object + * type is #H5R_DATASET_REGION. + * + * When the function completes successfully, it returns one of the + * following valid object type values (defined in H5Gpublic.h): + * \snippet H5Gpublic.h H5G_obj_t_snip + * + * \version 1.8.0 Function H5Rget_obj_type() renamed to H5Rget_obj_type1() and + * deprecated in this release. + * \since 1.6.0 + * + */ H5_DLL H5G_obj_t H5Rget_obj_type1(hid_t id, H5R_type_t ref_type, const void *ref); -H5_DLL hid_t H5Rdereference1(hid_t obj_id, H5R_type_t ref_type, const void *ref); + +/** + * -------------------------------------------------------------------------- + * \ingroup H5R + * + * \brief Opens the HDF5 object referenced + * + * \obj_id + * \param[in] ref_type The reference type of \p ref + * \param[in] ref Reference to open + * + * \return Returns identifier of referenced object if successful; otherwise + * returns a negative value. + * + * \deprecated This function has been renamed from H5Rdereference() and is + * deprecated in favor of the macro H5Rdereference() or the function + * H5Rdereference2(). + * + * \details Given a reference, \p ref, to an object or a region in an object, + * H5Rdereference1() opens that object and returns an identifier. + * + * The parameter \p obj_id must be a valid identifier for an object in + * the HDF5 file containing the referenced object, including the file + * identifier. + * + * The parameter \p ref_type specifies the reference type of the + * reference \p ref. \p ref_type may contain either of the following + * values: + * - #H5R_OBJECT + * - #H5R_DATASET_REGION + * + * The object opened with this function should be closed when it is no + * longer needed so that resource leaks will not develop. Use the + * appropriate close function such as H5Oclose() or H5Dclose() for + * datasets. + * + * \version 1.10.0 Function H5Rdereference() renamed to H5Rdereference1() and + * deprecated in this release. + * \since 1.8.0 + * + */ +H5_DLL hid_t H5Rdereference1(hid_t obj_id, H5R_type_t ref_type, const void *ref); #endif /* H5_NO_DEPRECATED_SYMBOLS */ -H5_DLL herr_t H5Rcreate(void *ref, hid_t loc_id, const char *name, H5R_type_t ref_type, hid_t space_id); -H5_DLL herr_t H5Rget_obj_type2(hid_t id, H5R_type_t ref_type, const void *ref, H5O_type_t *obj_type); -H5_DLL hid_t H5Rdereference2(hid_t obj_id, hid_t oapl_id, H5R_type_t ref_type, const void *ref); -H5_DLL hid_t H5Rget_region(hid_t dataset, H5R_type_t ref_type, const void *ref); +/** + * -------------------------------------------------------------------------- + * \ingroup H5R + * + * \brief Creates a reference + * + * \param[out] ref Reference created by the function call + * \param[in] loc_id Location identifier used to locate the object being pointed to + * \param[in] name Name of object at location \p loc_id + * \param[in] ref_type Type of reference + * \param[in] space_id Dataspace identifier with selection. Used only for + * dataset region references; pass as -1 if reference is + * an object reference, i.e., of type #H5R_OBJECT + * + * \return \herr_t + * + * \details H5Rcreate() creates the reference, \p ref, of the type specified in + * \p ref_type, pointing to the object \p name located at \p loc_id. + * + * The HDF5 library maps the void type specified above for \p ref to + * the type specified in \p ref_type, which will be one of the following: + * \snippet this H5R_type_t_snip + * + * The parameters \p loc_id and \p name are used to locate the object. + * + * The parameter \p space_id identifies the dataset region that a + * dataset region reference points to. This parameter is used only with + * dataset region references and should be set to -1 if the reference + * is an object reference, #H5R_OBJECT. + * + * \since 1.8.0 + */ +H5_DLL herr_t H5Rcreate(void *ref, hid_t loc_id, const char *name, H5R_type_t ref_type, hid_t space_id); + +/** + * -------------------------------------------------------------------------- + * \ingroup H5R + * + * \brief Retrieves the type of object that an object reference points to + * + * \param[in] id The dataset containing the reference object or the group + * containing that dataset + * \param[in] ref_type Type of reference to query + * \param[in] ref Reference to query + * \param[out] obj_type Type of referenced object + * + * \return \herr_t + * + * \details Given an object reference, \p ref, H5Rget_obj_type2() returns the + * type of the referenced object in \p obj_type. + * + * A \Emph{reference type} is the type of reference, either an object + * reference or a dataset region reference. An \Emph{object reference} + * points to an HDF5 object while a \Emph{dataset region reference} + * points to a defined region within a dataset. + * + * The \Emph{referenced object} is the object the reference points + * to. The \Emph{referenced object type}, or the type of the referenced + * object, is the type of the object that the reference points to. + * + * The location identifier, \p id, is the identifier for either the + * dataset containing the object reference or the group containing that + * dataset. + * + * Valid reference types, to pass in as \p ref_type, include the + * following: + * \snippet this H5R_type_t_snip + * + * If the application does not already know the object reference type, + * that can be determined with three preliminary calls: + * + * \li Call H5Dget_type() on the dataset containing the reference to + * get a datatype identifier for the dataset’s datatype. + * \li Using that datatype identifier, H5Tget_class() returns a datatype + * class.\n If the datatype class is #H5T_REFERENCE, H5Tequal() can + * then be used to determine whether the reference’s datatype is + * #H5T_STD_REF_OBJ or #H5T_STD_REF_DSETREG: + * - If the datatype is #H5T_STD_REF_OBJ, the reference object type + * is #H5R_OBJECT. + * - If the datatype is #H5T_STD_REF_DSETREG, the reference object + * type is #H5R_DATASET_REGION. + * + * When the function completes successfully, it returns one of the + * following valid object type values (defined in H5Opublic.h): + * \snippet H5Opublic.h H5O_type_t_snip + * + * \since 1.8.0 + * + */ +H5_DLL herr_t H5Rget_obj_type2(hid_t id, H5R_type_t ref_type, const void *ref, H5O_type_t *obj_type); + +/** + * -------------------------------------------------------------------------- + * \ingroup H5R + * + * \brief Opens the HDF5 object referenced + * + * \obj_id + * \oapl_id + * \param[in] ref_type The reference type of \p ref + * \param[in] ref Reference to open + * + * \return Returns identifier of referenced object if successful; otherwise + * returns a negative value. + * + * \details Given a reference, \p ref, to an object or a region in an object, + * H5Rdereference2() opens that object and returns an identifier. + * + * The parameter \p obj_id must be a valid identifier for the HDF5 file + * containing the referenced object or for any object in that HDF5 + * file. + * + * The parameter \p oapl_id is an object access property list + * identifier for the referenced object. The access property list must + * be of the same type as the object being referenced, that is a group, + * dataset, or datatype property list. + * + * The parameter \p ref_type specifies the reference type of the + * reference \p ref. \p ref_type may contain either of the following + * values: + * - #H5R_OBJECT + * - #H5R_DATASET_REGION + * + * The object opened with this function should be closed when it is no + * longer needed so that resource leaks will not develop. Use the + * appropriate close function such as H5Oclose() or H5Dclose() for + * datasets. + * + * \since 1.10.0 + * + */ +H5_DLL hid_t H5Rdereference2(hid_t obj_id, hid_t oapl_id, H5R_type_t ref_type, const void *ref); + +/** + * -------------------------------------------------------------------------- + * \ingroup H5R + * + * \brief Sets up a dataspace and selection as specified by a region reference + * + * \param[in] dataset File identifier or identifier for any object in the file + * containing the referenced region + * \param[in] ref_type Reference type of \p ref, which must be #H5R_DATASET_REGION + * \param[in] ref Region reference to open + * + * \return Returns a valid dataspace identifier if successful; otherwise returns + * a negative value. + * + * \details H5Rget_region() creates a copy of the dataspace of the dataset + * pointed to by a region reference, \p ref, and defines a selection + * matching the selection pointed to by ref within the dataspace copy. + * + * \p dataset is used to identify the file containing the referenced + * region; it can be a file identifier or an identifier for any object + * in the file. + * + * The parameter \p ref_type specifies the reference type of \p ref and + * must contain the value #H5R_DATASET_REGION. + * + * Use H5Sclose() to release the dataspace identifier returned by this + * function when the identifier is no longer needed. + * + */ +H5_DLL hid_t H5Rget_region(hid_t dataset, H5R_type_t ref_type, const void *ref); + +/** + * -------------------------------------------------------------------------- + * \ingroup H5R + * + * \brief Retrieves a name for a referenced object + * + * \param[in] loc_id Identifier for the file containing the reference or for + * any object in that file + * \param[in] ref_type Type of reference + * \param[in] ref An object or dataset region reference + * \param[out] name A buffer to place the name of the referenced object or + * dataset region. If \c NULL, then this call will return the + * size in bytes of the name. + * \param[in] size The size of the \p name buffer. When the size is passed in, + * the \c NULL terminator needs to be included. + * + * \return Returns the length of the name if successful, returning 0 (zero) if + * no name is associated with the identifier. Otherwise returns a + * negative value. + * + * \details H5Rget_name() retrieves a name for the object identified by \p ref.\n + * \p loc_id is used to identify the file containing the reference. It + * can be the file identifier for the file containing the reference or + * an identifier for any object in that file. + * + * \ref H5R_type_t is the reference type of \p ref. Valid values + * include the following: + * \snippet this H5R_type_t_snip + * + * \p ref is the reference for which the target object’s name is + * sought. + * + * If \p ref is an object reference, \p name will be returned with a + * name for the referenced object. If \p ref is a dataset region + * reference, \p name will contain a name for the object containing the + * referenced region. + * + * Up to \p size characters of the name are returned in \p name; + * additional characters, if any, are not returned to the user + * application. + * + * If the length of the name, which determines the required value of \p + * size, is unknown, a preliminary H5Rget_name() call can be made. The + * return value of this call will be the size of the object name. That + * value can then be assigned to \p size for a second H5Rget_name() + * call, which will retrieve the actual name. + * + * If there is no name associated with the object identifier or if the + * \p name is \c NULL, H5Rget_name() returns the size of the \p name + * buffer (the size does not include the \p NULL terminator). + * + * Note that an object in an HDF5 file may have multiple paths if there + * are multiple links pointing to it. This function may return any one + * of these paths. + * + * \since 1.8.0 + */ H5_DLL ssize_t H5Rget_name(hid_t loc_id, H5R_type_t ref_type, const void *ref, char *name, size_t size); #ifdef __cplusplus @@ -56,6 +56,7 @@ static herr_t H5SM__find_in_list(const H5SM_list_t *list, const H5SM_mesg_key_t size_t *list_pos); static herr_t H5SM__convert_list_to_btree(H5F_t *f, H5SM_index_header_t *header, H5SM_list_t **_list, H5HF_t *fheap, H5O_t *open_oh); +static herr_t H5SM__bt2_convert_to_list_op(const void *record, void *op_data); static herr_t H5SM__convert_btree_to_list(H5F_t *f, H5SM_index_header_t *header); static herr_t H5SM__incr_ref(void *record, void *_op_data, hbool_t *changed); static herr_t H5SM__write_mesg(H5F_t *f, H5O_t *open_oh, H5SM_index_header_t *header, hbool_t defer, @@ -265,7 +266,7 @@ H5SM__type_to_flag(unsigned type_id, unsigned *type_flag) switch (type_id) { case H5O_FILL_ID: type_id = H5O_FILL_NEW_ID; - /* Fall through... */ + /* FALLTHROUGH */ H5_ATTR_FALLTHROUGH case H5O_SDSPACE_ID: @@ -285,7 +286,7 @@ done: } /* end H5SM__type_to_flag() */ /*------------------------------------------------------------------------- - * Function: H5SM_get_index + * Function: H5SM__get_index * * Purpose: Get the index number for a given message type. * @@ -301,13 +302,13 @@ done: *------------------------------------------------------------------------- */ ssize_t -H5SM_get_index(const H5SM_master_table_t *table, unsigned type_id) +H5SM__get_index(const H5SM_master_table_t *table, unsigned type_id) { size_t x; unsigned type_flag; ssize_t ret_value = FAIL; - FUNC_ENTER_NOAPI_NOINIT + FUNC_ENTER_PACKAGE /* Translate the H5O type_id into an H5SM type flag */ if (H5SM__type_to_flag(type_id, &type_flag) < 0) @@ -325,7 +326,7 @@ H5SM_get_index(const H5SM_master_table_t *table, unsigned type_id) */ done: FUNC_LEAVE_NOAPI(ret_value) -} /* end H5SM_get_index() */ +} /* end H5SM__get_index() */ /*------------------------------------------------------------------------- * Function: H5SM_type_shared @@ -419,7 +420,7 @@ H5SM_get_fheap_addr(H5F_t *f, unsigned type_id, haddr_t *fheap_addr) HGOTO_ERROR(H5E_SOHM, H5E_CANTPROTECT, FAIL, "unable to load SOHM master table") /* Look up index for message type */ - if ((index_num = H5SM_get_index(table, type_id)) < 0) + if ((index_num = H5SM__get_index(table, type_id)) < 0) HGOTO_ERROR(H5E_SOHM, H5E_CANTPROTECT, FAIL, "unable to find correct SOHM index") /* Retrieve heap address for index */ @@ -788,6 +789,47 @@ done: } /* H5SM__convert_list_to_btree() */ /*------------------------------------------------------------------------- + * Function: H5SM__bt2_convert_to_list_op + * + * Purpose: An H5B2_remove_t callback function to convert a SOHM + * B-tree index to a list. + * + * Inserts this record into the list passed through op_data. + * + * Return: Non-negative on success + * Negative on failure + * + * Programmer: James Laird + * Monday, November 6, 2006 + * + *------------------------------------------------------------------------- + */ +static herr_t +H5SM__bt2_convert_to_list_op(const void *record, void *op_data) +{ + const H5SM_sohm_t *message = (const H5SM_sohm_t *)record; + const H5SM_list_t *list = (const H5SM_list_t *)op_data; + size_t mesg_idx; /* Index of message to modify */ + + FUNC_ENTER_STATIC_NOERR + + /* Sanity checks */ + HDassert(record); + HDassert(op_data); + + /* Get the message index, and increment the # of messages in list */ + mesg_idx = list->header->num_messages++; + HDassert(list->header->num_messages <= list->header->list_max); + + /* Insert this message at the end of the list */ + HDassert(list->messages[mesg_idx].location == H5SM_NO_LOC); + HDassert(message->location != H5SM_NO_LOC); + H5MM_memcpy(&(list->messages[mesg_idx]), message, sizeof(H5SM_sohm_t)); + + FUNC_LEAVE_NOAPI(SUCCEED) +} /* end H5SM__bt2_convert_to_list_op() */ + +/*------------------------------------------------------------------------- * Function: H5SM__convert_btree_to_list * * Purpose: Given a B-tree index, turns it into a list index. This is @@ -835,7 +877,7 @@ H5SM__convert_btree_to_list(H5F_t *f, H5SM_index_header_t *header) /* Delete the B-tree and have messages copy themselves to the * list as they're deleted */ - if (H5B2_delete(f, btree_addr, f, H5SM_bt2_convert_to_list_op, list) < 0) + if (H5B2_delete(f, btree_addr, f, H5SM__bt2_convert_to_list_op, list) < 0) HGOTO_ERROR(H5E_SOHM, H5E_CANTDELETE, FAIL, "unable to delete B-tree") done: @@ -847,7 +889,7 @@ done: } /* end H5SM__convert_btree_to_list() */ /*------------------------------------------------------------------------- - * Function: H5SM_can_share_common + * Function: H5SM__can_share_common * * Purpose: "trivial" checks for determining if a message can be shared. * @@ -865,11 +907,11 @@ done: *------------------------------------------------------------------------- */ static htri_t -H5SM_can_share_common(const H5F_t *f, unsigned type_id, const void *mesg) +H5SM__can_share_common(const H5F_t *f, unsigned type_id, const void *mesg) { htri_t ret_value = FAIL; /* Return value */ - FUNC_ENTER_NOAPI_NOINIT + FUNC_ENTER_STATIC /* Check whether this message ought to be shared or not */ /* If sharing is disabled in this file, don't share the message */ @@ -888,7 +930,7 @@ H5SM_can_share_common(const H5F_t *f, unsigned type_id, const void *mesg) done: FUNC_LEAVE_NOAPI(ret_value) -} /* end H5SM_can_share_common() */ +} /* end H5SM__can_share_common() */ /*------------------------------------------------------------------------- * Function: H5SM_can_share @@ -920,7 +962,7 @@ H5SM_can_share(H5F_t *f, H5SM_master_table_t *table, ssize_t *sohm_index_num, un FUNC_ENTER_NOAPI_TAG(H5AC__SOHM_TAG, FAIL) /* "trivial" sharing checks */ - if ((tri_ret = H5SM_can_share_common(f, type_id, mesg)) < 0) + if ((tri_ret = H5SM__can_share_common(f, type_id, mesg)) < 0) HGOTO_ERROR(H5E_SOHM, H5E_BADTYPE, FAIL, "'trivial' sharing checks returned error") if (tri_ret == FALSE) HGOTO_DONE(FALSE) @@ -943,7 +985,7 @@ H5SM_can_share(H5F_t *f, H5SM_master_table_t *table, ssize_t *sohm_index_num, un /* Find the right index for this message type. If there is no such index * then this type of message isn't shareable */ - if ((index_num = H5SM_get_index(my_table, type_id)) < 0) { + if ((index_num = H5SM__get_index(my_table, type_id)) < 0) { H5E_clear_stack(NULL); /*ignore error*/ HGOTO_DONE(FALSE) } /* end if */ @@ -1059,7 +1101,7 @@ H5SM_try_share(H5F_t *f, H5O_t *open_oh, unsigned defer_flags, unsigned type_id, /* "trivial" sharing checks */ if (mesg_flags && (*mesg_flags & H5O_MSG_FLAG_DONTSHARE)) HGOTO_DONE(FALSE) - if ((tri_ret = H5SM_can_share_common(f, type_id, mesg)) < 0) + if ((tri_ret = H5SM__can_share_common(f, type_id, mesg)) < 0) HGOTO_ERROR(H5E_SOHM, H5E_BADTYPE, FAIL, "'trivial' sharing checks returned error") if (tri_ret == FALSE) HGOTO_DONE(FALSE) @@ -1220,16 +1262,16 @@ static herr_t H5SM__write_mesg(H5F_t *f, H5O_t *open_oh, H5SM_index_header_t *header, hbool_t defer, unsigned type_id, void *mesg, unsigned *cache_flags_ptr) { - H5SM_list_t * list = NULL; /* List index */ - H5SM_mesg_key_t key; /* Key used to search the index */ - H5SM_list_cache_ud_t cache_udata; /* User-data for metadata cache callback */ - H5O_shared_t shared; /* Shared H5O message */ - hbool_t found = FALSE; /* Was the message in the index? */ - H5HF_t * fheap = NULL; /* Fractal heap handle */ - H5B2_t * bt2 = NULL; /* v2 B-tree handle for index */ - size_t buf_size; /* Size of the encoded message */ - void * encoding_buf = NULL; /* Buffer for encoded message */ - size_t empty_pos = UFAIL; /* Empty entry in list */ + H5SM_list_t * list = NULL; /* List index */ + H5SM_mesg_key_t key; /* Key used to search the index */ + H5SM_list_cache_ud_t cache_udata; /* User-data for metadata cache callback */ + H5O_shared_t shared; /* Shared H5O message */ + hbool_t found = FALSE; /* Was the message in the index? */ + H5HF_t * fheap = NULL; /* Fractal heap handle */ + H5B2_t * bt2 = NULL; /* v2 B-tree handle for index */ + size_t buf_size; /* Size of the encoded message */ + void * encoding_buf = NULL; /* Buffer for encoded message */ + size_t empty_pos = SIZE_MAX; /* Empty entry in list */ herr_t ret_value = SUCCEED; FUNC_ENTER_STATIC_TAG(H5AC__SOHM_TAG) @@ -1283,11 +1325,11 @@ H5SM__write_mesg(H5F_t *f, H5O_t *open_oh, H5SM_index_header_t *header, hbool_t HGOTO_ERROR(H5E_SOHM, H5E_CANTINSERT, FAIL, "unable to search for message in list") if (defer) { - if (list_pos != UFAIL) + if (list_pos != SIZE_MAX) found = TRUE; } /* end if */ else { - if (list_pos != UFAIL) { + if (list_pos != SIZE_MAX) { /* If the message was previously shared in an object header, share * it in the heap now. */ @@ -1322,16 +1364,13 @@ H5SM__write_mesg(H5F_t *f, H5O_t *open_oh, H5SM_index_header_t *header, hbool_t HGOTO_ERROR(H5E_SOHM, H5E_CANTOPENOBJ, FAIL, "unable to open v2 B-tree for SOHM index") if (defer) { - htri_t bt2_find; /* Result from searching in the v2 B-tree */ - /* If this returns 0, it means that the message wasn't found. */ /* If it return 1, set the heap_id in the shared struct. It will * return a heap ID, since a message with a reference count greater * than 1 is always shared in the heap. */ - if ((bt2_find = H5B2_find(bt2, &key, NULL, NULL)) < 0) + if (H5B2_find(bt2, &key, &found, NULL, NULL) < 0) HGOTO_ERROR(H5E_SOHM, H5E_NOTFOUND, FAIL, "can't search for message in index") - found = (hbool_t)bt2_find; } /* end if */ else { H5SM_incr_ref_opdata op_data; @@ -1442,13 +1481,13 @@ H5SM__write_mesg(H5F_t *f, H5O_t *open_oh, H5SM_index_header_t *header, hbool_t /* Insert the new message into the SOHM index */ if (header->index_type == H5SM_LIST) { /* Index is a list. Find an empty spot if we haven't already */ - if (empty_pos == UFAIL) { + if (empty_pos == SIZE_MAX) { size_t pos; if (H5SM__find_in_list(list, NULL, &empty_pos, &pos) < 0) HGOTO_ERROR(H5E_SOHM, H5E_CANTINSERT, FAIL, "unable to search for message in list") - if (pos == UFAIL || empty_pos == UFAIL) + if (pos == SIZE_MAX || empty_pos == SIZE_MAX) HGOTO_ERROR(H5E_SOHM, H5E_CANTINSERT, FAIL, "unable to find empty entry in list") } /* Insert message into list */ @@ -1551,7 +1590,7 @@ H5SM_delete(H5F_t *f, H5O_t *open_oh, H5O_shared_t *sh_mesg) HGOTO_ERROR(H5E_SOHM, H5E_CANTPROTECT, FAIL, "unable to load SOHM master table") /* Find the correct index and try to delete from it */ - if ((index_num = H5SM_get_index(table, type_id)) < 0) + if ((index_num = H5SM__get_index(table, type_id)) < 0) HGOTO_ERROR(H5E_SOHM, H5E_NOTFOUND, FAIL, "unable to find correct SOHM index") /* If mesg_buf is not NULL, the message's reference count has reached @@ -1608,9 +1647,14 @@ done: * * If EMPTY_POS is NULL, don't store anything in it. * - * Return: Message's position in the list on success - * UFAIL if message couldn't be found - * empty_pos set to position of empty message or UFAIL. + * Return: Success: SUCCEED + * pos = position (if found) + * pos = SIZE_MAX (if not found) + * empty_pos = indeterminate (if found) + * empty_pos = 1st empty position (if not found) + * + * Failure: FAIL + * pos & empty_pos indeterminate * * Programmer: James Laird * Tuesday, May 2, 2006 @@ -1631,7 +1675,7 @@ H5SM__find_in_list(const H5SM_list_t *list, const H5SM_mesg_key_t *key, size_t * /* Initialize empty_pos to an invalid value */ if (empty_pos) - *empty_pos = UFAIL; + *empty_pos = SIZE_MAX; /* Find the first (only) message equal to the key passed in. * Also record the first empty position we find. @@ -1654,44 +1698,17 @@ H5SM__find_in_list(const H5SM_list_t *list, const H5SM_mesg_key_t *key, size_t * /* Found earlier position possible, don't check any more */ empty_pos = NULL; - } /* end if */ - } /* end for */ + } + } /* If we reached this point, we didn't find the message */ - *pos = UFAIL; + *pos = SIZE_MAX; done: FUNC_LEAVE_NOAPI(ret_value) } /* end H5SM__find_in_list */ /*------------------------------------------------------------------------- - * Function: H5SM_get_hash_fh_cb - * - * Purpose: Callback for fractal heap operator, to make copy of link when - * when lookup up a link by index - * - * Return: SUCCEED/FAIL - * - * Programmer: Quincey Koziol - * koziol@hdfgroup.org - * Nov 7 2006 - * - *------------------------------------------------------------------------- - */ -herr_t -H5SM_get_hash_fh_cb(const void *obj, size_t obj_len, void *_udata) -{ - H5SM_fh_ud_gh_t *udata = (H5SM_fh_ud_gh_t *)_udata; /* User data for fractal heap 'op' callback */ - - FUNC_ENTER_NOAPI_NOINIT_NOERR - - /* Compute hash value on raw message */ - udata->hash = H5_checksum_lookup3(obj, obj_len, udata->type_id); - - FUNC_LEAVE_NOAPI(SUCCEED) -} /* end H5SM_get_hash_fh_cb() */ - -/*------------------------------------------------------------------------- * Function: H5SM__decr_ref * * Purpose: Decrement the reference count for a SOHM message. Doesn't @@ -1827,7 +1844,7 @@ H5SM__delete_from_index(H5F_t *f, H5O_t *open_oh, H5SM_index_header_t *header, c /* Find the message in the list */ if (H5SM__find_in_list(list, &key, NULL, &list_pos) < 0) HGOTO_ERROR(H5E_SOHM, H5E_NOTFOUND, FAIL, "unable to search for message in list") - if (list_pos == UFAIL) + if (list_pos == SIZE_MAX) HGOTO_ERROR(H5E_SOHM, H5E_NOTFOUND, FAIL, "message not in index") if (list->messages[list_pos].location == H5SM_IN_HEAP) @@ -2093,7 +2110,7 @@ H5SM_reconstitute(H5O_shared_t *sh_mesg, H5F_t *f, unsigned msg_type_id, H5O_fhe } /* end H5SM_reconstitute() */ /*------------------------------------------------------------------------- - * Function: H5SM_get_refcount_bt2_cb + * Function: H5SM__get_refcount_bt2_cb * * Purpose: v2 B-tree 'find' callback to retrieve the record for a message * @@ -2105,12 +2122,12 @@ H5SM_reconstitute(H5O_shared_t *sh_mesg, H5F_t *f, unsigned msg_type_id, H5O_fhe *------------------------------------------------------------------------- */ static herr_t -H5SM_get_refcount_bt2_cb(const void *_record, void *_op_data) +H5SM__get_refcount_bt2_cb(const void *_record, void *_op_data) { const H5SM_sohm_t *record = (const H5SM_sohm_t *)_record; /* v2 B-tree record for message */ H5SM_sohm_t * op_data = (H5SM_sohm_t *)_op_data; /* "op data" from v2 B-tree find */ - FUNC_ENTER_NOAPI_NOINIT_NOERR + FUNC_ENTER_STATIC_NOERR /* * Check arguments. @@ -2122,7 +2139,7 @@ H5SM_get_refcount_bt2_cb(const void *_record, void *_op_data) *op_data = *record; FUNC_LEAVE_NOAPI(SUCCEED) -} /* end H5SM_get_refcount_bt2_cb() */ +} /* end H5SM__get_refcount_bt2_cb() */ /*------------------------------------------------------------------------- * Function: H5SM_get_refcount @@ -2168,7 +2185,7 @@ H5SM_get_refcount(H5F_t *f, unsigned type_id, const H5O_shared_t *sh_mesg, hsize HGOTO_ERROR(H5E_SOHM, H5E_CANTPROTECT, FAIL, "unable to load SOHM master table") /* Find the correct index and find the message in it */ - if ((index_num = H5SM_get_index(table, type_id)) < 0) + if ((index_num = H5SM__get_index(table, type_id)) < 0) HGOTO_ERROR(H5E_SOHM, H5E_NOTFOUND, FAIL, "unable to find correct SOHM index") header = &(table->indexes[index_num]); @@ -2209,14 +2226,14 @@ H5SM_get_refcount(H5F_t *f, unsigned type_id, const H5O_shared_t *sh_mesg, hsize /* Find the message in the list */ if (H5SM__find_in_list(list, &key, NULL, &list_pos) < 0) HGOTO_ERROR(H5E_SOHM, H5E_NOTFOUND, FAIL, "unable to search for message in list") - if (list_pos == UFAIL) + if (list_pos == SIZE_MAX) HGOTO_ERROR(H5E_SOHM, H5E_NOTFOUND, FAIL, "message not in index") /* Copy the message */ message = list->messages[list_pos]; } /* end if */ else { - htri_t msg_exists; /* Whether the message exists in the v2 B-tree */ + hbool_t msg_exists; /* Whether the message exists in the v2 B-tree */ /* Index is a B-tree */ HDassert(header->index_type == H5SM_BTREE); @@ -2226,7 +2243,8 @@ H5SM_get_refcount(H5F_t *f, unsigned type_id, const H5O_shared_t *sh_mesg, hsize HGOTO_ERROR(H5E_SOHM, H5E_CANTOPENOBJ, FAIL, "unable to open v2 B-tree for SOHM index") /* Look up the message in the v2 B-tree */ - if ((msg_exists = H5B2_find(bt2, &key, H5SM_get_refcount_bt2_cb, &message)) < 0) + msg_exists = FALSE; + if (H5B2_find(bt2, &key, &msg_exists, H5SM__get_refcount_bt2_cb, &message) < 0) HGOTO_ERROR(H5E_SOHM, H5E_CANTGET, FAIL, "error finding message in index") if (!msg_exists) HGOTO_ERROR(H5E_SOHM, H5E_NOTFOUND, FAIL, "message not in index") @@ -2447,7 +2465,7 @@ done: } /* end H5SM__read_mesg */ /*------------------------------------------------------------------------- - * Function: H5SM_table_free + * Function: H5SM__table_free * * Purpose: Frees memory used by the SOHM table. * @@ -2459,9 +2477,9 @@ done: *------------------------------------------------------------------------- */ herr_t -H5SM_table_free(H5SM_master_table_t *table) +H5SM__table_free(H5SM_master_table_t *table) { - FUNC_ENTER_NOAPI_NOINIT_NOERR + FUNC_ENTER_PACKAGE_NOERR /* Sanity check */ HDassert(table); @@ -2472,10 +2490,10 @@ H5SM_table_free(H5SM_master_table_t *table) table = H5FL_FREE(H5SM_master_table_t, table); FUNC_LEAVE_NOAPI(SUCCEED) -} /* end H5SM_table_free() */ +} /* end H5SM__table_free() */ /*------------------------------------------------------------------------- - * Function: H5SM_list_free + * Function: H5SM__list_free * * Purpose: Frees all memory used by the list. * @@ -2487,9 +2505,9 @@ H5SM_table_free(H5SM_master_table_t *table) *------------------------------------------------------------------------- */ herr_t -H5SM_list_free(H5SM_list_t *list) +H5SM__list_free(H5SM_list_t *list) { - FUNC_ENTER_NOAPI_NOINIT_NOERR + FUNC_ENTER_PACKAGE_NOERR HDassert(list); HDassert(list->messages); @@ -2499,14 +2517,14 @@ H5SM_list_free(H5SM_list_t *list) list = H5FL_FREE(H5SM_list_t, list); FUNC_LEAVE_NOAPI(SUCCEED) -} /* end H5SM_list_free() */ +} /* end H5SM__list_free() */ /*------------------------------------------------------------------------- * Function: H5SM_table_debug * * Purpose: Print debugging information for the master table. * - * If table_vers and num_indexes are not UFAIL, they are used + * If table_vers and num_indexes are not UINT_MAX, they are used * instead of the values in the superblock. * * Return: Non-negative on success/Negative on failure @@ -2533,14 +2551,14 @@ H5SM_table_debug(H5F_t *f, haddr_t table_addr, FILE *stream, int indent, int fwi HDassert(indent >= 0); HDassert(fwidth >= 0); - /* If table_vers and num_indexes are UFAIL, replace them with values from + /* If table_vers and num_indexes are UINT_MAX, replace them with values from * userblock */ - if (table_vers == UFAIL) + if (table_vers == UINT_MAX) table_vers = H5F_SOHM_VERS(f); else if (table_vers != H5F_SOHM_VERS(f)) HDfprintf(stream, "*** SOHM TABLE VERSION DOESN'T MATCH VERSION IN SUPERBLOCK!\n"); - if (num_indexes == UFAIL) + if (num_indexes == UINT_MAX) num_indexes = H5F_SOHM_NINDEXES(f); else if (num_indexes != H5F_SOHM_NINDEXES(f)) HDfprintf(stream, "*** NUMBER OF SOHM INDEXES DOESN'T MATCH VALUE IN SUPERBLOCK!\n"); diff --git a/src/H5SMbtree2.c b/src/H5SMbtree2.c index 6f71966..2dca9fd 100644 --- a/src/H5SMbtree2.c +++ b/src/H5SMbtree2.c @@ -199,44 +199,3 @@ H5SM__bt2_debug(FILE *stream, int indent, int fwidth, const void *record, const FUNC_LEAVE_NOAPI(SUCCEED) } /* end H5SM__bt2_debug */ - -/*------------------------------------------------------------------------- - * Function: H5SM_bt2_convert_to_list_op - * - * Purpose: An H5B2_remove_t callback function to convert a SOHM - * B-tree index to a list. - * - * Inserts this record into the list passed through op_data. - * - * Return: Non-negative on success - * Negative on failure - * - * Programmer: James Laird - * Monday, November 6, 2006 - * - *------------------------------------------------------------------------- - */ -herr_t -H5SM_bt2_convert_to_list_op(const void *record, void *op_data) -{ - const H5SM_sohm_t *message = (const H5SM_sohm_t *)record; - const H5SM_list_t *list = (const H5SM_list_t *)op_data; - size_t mesg_idx; /* Index of message to modify */ - - FUNC_ENTER_NOAPI_NOINIT_NOERR - - /* Sanity checks */ - HDassert(record); - HDassert(op_data); - - /* Get the message index, and increment the # of messages in list */ - mesg_idx = list->header->num_messages++; - HDassert(list->header->num_messages <= list->header->list_max); - - /* Insert this message at the end of the list */ - HDassert(list->messages[mesg_idx].location == H5SM_NO_LOC); - HDassert(message->location != H5SM_NO_LOC); - H5MM_memcpy(&(list->messages[mesg_idx]), message, sizeof(H5SM_sohm_t)); - - FUNC_LEAVE_NOAPI(SUCCEED) -} /* end H5SM_bt2_convert_to_list_op() */ diff --git a/src/H5SMcache.c b/src/H5SMcache.c index 3364e49..6884665 100644 --- a/src/H5SMcache.c +++ b/src/H5SMcache.c @@ -15,7 +15,7 @@ * * Created: H5SMcache.c * Nov 13 2006 - * James Laird <jlaird@hdfgroup.org> + * James Laird * * Purpose: Implement shared message metadata cache methods. * @@ -240,7 +240,7 @@ H5SM__cache_table_deserialize(const void *_image, size_t H5_ATTR_NDEBUG_UNUSED l HDassert(table->table_size == len); /* Check magic number */ - if (HDmemcmp(image, H5SM_TABLE_MAGIC, (size_t)H5_SIZEOF_MAGIC)) + if (HDmemcmp(image, H5SM_TABLE_MAGIC, (size_t)H5_SIZEOF_MAGIC) != 0) HGOTO_ERROR(H5E_SOHM, H5E_CANTLOAD, NULL, "bad SOHM table signature") image += H5_SIZEOF_MAGIC; @@ -296,7 +296,7 @@ H5SM__cache_table_deserialize(const void *_image, size_t H5_ATTR_NDEBUG_UNUSED l done: if (!ret_value && table) - if (H5SM_table_free(table) < 0) + if (H5SM__table_free(table) < 0) HDONE_ERROR(H5E_SOHM, H5E_CANTFREE, NULL, "unable to destroy sohm table") FUNC_LEAVE_NOAPI(ret_value) @@ -452,7 +452,7 @@ H5SM__cache_table_free_icr(void *_thing) HDassert(table->cache_info.type == H5AC_SOHM_TABLE); /* Destroy Shared Object Header Message table */ - if (H5SM_table_free(table) < 0) + if (H5SM__table_free(table) < 0) HGOTO_ERROR(H5E_SOHM, H5E_CANTRELEASE, FAIL, "unable to free shared message table") done: @@ -582,7 +582,7 @@ H5SM__cache_list_deserialize(const void *_image, size_t H5_ATTR_NDEBUG_UNUSED le list->header = udata->header; /* Check magic number */ - if (HDmemcmp(image, H5SM_LIST_MAGIC, (size_t)H5_SIZEOF_MAGIC)) + if (HDmemcmp(image, H5SM_LIST_MAGIC, (size_t)H5_SIZEOF_MAGIC) != 0) HGOTO_ERROR(H5E_SOHM, H5E_CANTLOAD, NULL, "bad SOHM list signature") image += H5_SIZEOF_MAGIC; @@ -756,7 +756,7 @@ H5SM__cache_list_free_icr(void *_thing) HDassert(list->cache_info.type == H5AC_SOHM_LIST); /* Destroy Shared Object Header Message list */ - if (H5SM_list_free(list) < 0) + if (H5SM__list_free(list) < 0) HGOTO_ERROR(H5E_SOHM, H5E_CANTRELEASE, FAIL, "unable to free shared message list") done: diff --git a/src/H5SMmessage.c b/src/H5SMmessage.c index 6cdbc80..4499b0c 100644 --- a/src/H5SMmessage.c +++ b/src/H5SMmessage.c @@ -35,7 +35,7 @@ /* Local Typedefs */ /******************/ -/* Udata struct for calls to H5SM_compare_cb and H5SM_compare_iter_op*/ +/* Udata struct for calls to H5SM__compare_cb and H5SM__compare_iter_op*/ typedef struct H5SM_compare_udata_t { const H5SM_mesg_key_t *key; /* Key; compare this against stored message */ H5O_msg_crt_idx_t idx; /* Index of the message in the OH, if applicable */ @@ -45,9 +45,9 @@ typedef struct H5SM_compare_udata_t { /********************/ /* Local Prototypes */ /********************/ -static herr_t H5SM_compare_cb(const void *obj, size_t obj_len, void *udata); -static herr_t H5SM_compare_iter_op(H5O_t *oh, H5O_mesg_t *mesg, unsigned sequence, unsigned *oh_modified, - void *udata); +static herr_t H5SM__compare_cb(const void *obj, size_t obj_len, void *udata); +static herr_t H5SM__compare_iter_op(H5O_t *oh, H5O_mesg_t *mesg, unsigned sequence, unsigned *oh_modified, + void *udata); /*********************/ /* Package Variables */ @@ -62,7 +62,7 @@ static herr_t H5SM_compare_iter_op(H5O_t *oh, H5O_mesg_t *mesg, unsigned sequenc /*******************/ /*------------------------------------------------------------------------- - * Function: H5SM_compare_cb + * Function: H5SM__compare_cb * * Purpose: Callback for H5HF_op, used in H5SM__message_compare below. * Determines whether the search key passed in in _UDATA is @@ -78,11 +78,11 @@ static herr_t H5SM_compare_iter_op(H5O_t *oh, H5O_mesg_t *mesg, unsigned sequenc *------------------------------------------------------------------------- */ static herr_t -H5SM_compare_cb(const void *obj, size_t obj_len, void *_udata) +H5SM__compare_cb(const void *obj, size_t obj_len, void *_udata) { H5SM_compare_udata_t *udata = (H5SM_compare_udata_t *)_udata; - FUNC_ENTER_NOAPI_NOINIT_NOERR + FUNC_ENTER_STATIC_NOERR /* If the encoding sizes are different, it's not the same object */ if (udata->key->encoding_size > obj_len) @@ -94,10 +94,10 @@ H5SM_compare_cb(const void *obj, size_t obj_len, void *_udata) udata->ret = HDmemcmp(udata->key->encoding, obj, obj_len); FUNC_LEAVE_NOAPI(SUCCEED) -} /* end H5SM_compare_cb() */ +} /* end H5SM__compare_cb() */ /*------------------------------------------------------------------------- - * Function: H5SM_compare_iter_op + * Function: H5SM__compare_iter_op * * Purpose: OH iteration callback to compare a key against a message in * an OH @@ -113,13 +113,13 @@ H5SM_compare_cb(const void *obj, size_t obj_len, void *_udata) *------------------------------------------------------------------------- */ static herr_t -H5SM_compare_iter_op(H5O_t *oh, H5O_mesg_t *mesg /*in,out*/, unsigned sequence, - unsigned H5_ATTR_UNUSED *oh_modified, void *_udata /*in,out*/) +H5SM__compare_iter_op(H5O_t *oh, H5O_mesg_t *mesg /*in,out*/, unsigned sequence, + unsigned H5_ATTR_UNUSED *oh_modified, void *_udata /*in,out*/) { H5SM_compare_udata_t *udata = (H5SM_compare_udata_t *)_udata; herr_t ret_value = H5_ITER_CONT; - FUNC_ENTER_NOAPI_NOINIT + FUNC_ENTER_STATIC /* * Check arguments. @@ -156,7 +156,7 @@ H5SM_compare_iter_op(H5O_t *oh, H5O_mesg_t *mesg /*in,out*/, unsigned sequence, done: FUNC_LEAVE_NOAPI(ret_value) -} /* end H5SM_compare_iter_op() */ +} /* end H5SM__compare_iter_op() */ /*------------------------------------------------------------------------- * Function: H5SM__message_compare @@ -227,7 +227,7 @@ H5SM__message_compare(const void *rec1, const void *rec2, int *result) */ if (mesg->location == H5SM_IN_HEAP) { /* Call heap op routine with comparison callback */ - if (H5HF_op(key->fheap, &(mesg->u.heap_loc.fheap_id), H5SM_compare_cb, &udata) < 0) + if (H5HF_op(key->fheap, &(mesg->u.heap_loc.fheap_id), H5SM__compare_cb, &udata) < 0) HGOTO_ERROR(H5E_HEAP, H5E_CANTCOMPARE, FAIL, "can't compare btree2 records") } /* end if */ else { @@ -251,7 +251,7 @@ H5SM__message_compare(const void *rec1, const void *rec2, int *result) /* Locate the right message and compare with it */ op.op_type = H5O_MESG_OP_LIB; - op.u.lib_op = H5SM_compare_iter_op; + op.u.lib_op = H5SM__compare_iter_op; if (H5O_msg_iterate(&oloc, mesg->msg_type_id, &op, &udata) < 0) HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "error iterating over links") } /* end else */ diff --git a/src/H5SMpkg.h b/src/H5SMpkg.h index abf9a70..ae9a5f6 100644 --- a/src/H5SMpkg.h +++ b/src/H5SMpkg.h @@ -255,22 +255,16 @@ H5_DLLVAR const H5B2_class_t H5SM_INDEX[1]; /****************************/ /* General routines */ -H5_DLL ssize_t H5SM_get_index(const H5SM_master_table_t *table, unsigned type_id); +H5_DLL ssize_t H5SM__get_index(const H5SM_master_table_t *table, unsigned type_id); /* Encode and decode routines, used for B-tree and cache encoding/decoding */ H5_DLL herr_t H5SM__message_compare(const void *rec1, const void *rec2, int *result); H5_DLL herr_t H5SM__message_encode(uint8_t *raw, const void *native, void *ctx); H5_DLL herr_t H5SM__message_decode(const uint8_t *raw, void *native, void *ctx); -/* H5B2_remove_t callback to add messages to a list index */ -H5_DLL herr_t H5SM_bt2_convert_to_list_op(const void *record, void *op_data); - -/* Fractal heap 'op' callback to compute hash value for message "in place" */ -H5_DLL herr_t H5SM_get_hash_fh_cb(const void *obj, size_t obj_len, void *_udata); - /* Routines to release data structures */ -herr_t H5SM_table_free(H5SM_master_table_t *table); -herr_t H5SM_list_free(H5SM_list_t *list); +H5_DLL herr_t H5SM__table_free(H5SM_master_table_t *table); +H5_DLL herr_t H5SM__list_free(H5SM_list_t *list); /* Testing functions */ #ifdef H5SM_TESTING diff --git a/src/H5SMtest.c b/src/H5SMtest.c index 3641ade..d6f96be 100644 --- a/src/H5SMtest.c +++ b/src/H5SMtest.c @@ -91,7 +91,7 @@ H5SM__get_mesg_count_test(H5F_t *f, unsigned type_id, size_t *mesg_count) HGOTO_ERROR(H5E_SOHM, H5E_CANTPROTECT, FAIL, "unable to load SOHM master table") /* Find the correct index for this message type */ - if ((index_num = H5SM_get_index(table, type_id)) < 0) + if ((index_num = H5SM__get_index(table, type_id)) < 0) HGOTO_ERROR(H5E_SOHM, H5E_NOTFOUND, FAIL, "unable to find correct SOHM index") header = &(table->indexes[index_num]); diff --git a/src/H5Smpio.c b/src/H5Smpio.c index 9a38aaa..7b85209 100644 --- a/src/H5Smpio.c +++ b/src/H5Smpio.c @@ -1014,8 +1014,7 @@ H5S__mpio_span_hyper_type(const H5S_t *space, size_t elmt_size, MPI_Datatype *ne elmt_type_is_derived = TRUE; /* Compute 'down' sizes for each dimension */ - if (H5VM_array_down(space->extent.rank, space->extent.size, down) < 0) - HGOTO_ERROR(H5E_DATASPACE, H5E_CANTGETSIZE, FAIL, "couldn't compute 'down' dimension sizes") + H5VM_array_down(space->extent.rank, space->extent.size, down); /* Acquire an operation generation value for creating MPI datatypes */ op_gen = H5S__hyper_get_op_gen(); diff --git a/src/H5Spublic.h b/src/H5Spublic.h index fd85dcc..c2c0aef 100644 --- a/src/H5Spublic.h +++ b/src/H5Spublic.h @@ -22,7 +22,7 @@ #include "H5Ipublic.h" /* Define atomic datatypes */ -#define H5S_ALL (hid_t)0 +#define H5S_ALL 0 /* (hid_t) */ #define H5S_UNLIMITED HSIZE_UNDEF /* Define user-level maximum number of dimensions */ @@ -32,6 +32,7 @@ #include "H5CXprivate.h" /* API Contexts */ #include "H5Dprivate.h" /* Datasets */ #include "H5Eprivate.h" /* Error handling */ +#include "H5ESprivate.h" /* Event Sets */ #include "H5Fprivate.h" /* Files */ #include "H5FLprivate.h" /* Free Lists */ #include "H5FOprivate.h" /* File objects */ @@ -346,7 +347,7 @@ static herr_t H5T__register(H5T_pers_t pers, const char *name, H5T_t *src, H5T_t static herr_t H5T__unregister(H5T_pers_t pers, const char *name, H5T_t *src, H5T_t *dst, H5T_conv_t func); static htri_t H5T__compiler_conv(H5T_t *src, H5T_t *dst); static herr_t H5T__set_size(H5T_t *dt, size_t size); -static herr_t H5T__close_cb(H5T_t *dt); +static herr_t H5T__close_cb(H5T_t *dt, void **request); static H5T_path_t *H5T__path_find_real(const H5T_t *src, const H5T_t *dst, const char *name, H5T_conv_func_t *conv); static hbool_t H5T__detect_vlen_ref(const H5T_t *dt); @@ -561,8 +562,8 @@ size_t H5T_NATIVE_UINT_FAST64_ALIGN_g = 0; /* (+/- Inf for all floating-point types) */ float H5T_NATIVE_FLOAT_POS_INF_g = 0.0f; float H5T_NATIVE_FLOAT_NEG_INF_g = 0.0f; -double H5T_NATIVE_DOUBLE_POS_INF_g = (double)0.0f; -double H5T_NATIVE_DOUBLE_NEG_INF_g = (double)0.0f; +double H5T_NATIVE_DOUBLE_POS_INF_g = 0.0; +double H5T_NATIVE_DOUBLE_NEG_INF_g = 0.0; /* Declare the free list for H5T_t's and H5T_shared_t's */ H5FL_DEFINE(H5T_t); @@ -1478,6 +1479,8 @@ done: if (copied_dtype) (void)H5T_close_real(dt); else { + if (dt->shared->owned_vol_obj && H5VL_free_object(dt->shared->owned_vol_obj) < 0) + HDONE_ERROR(H5E_DATATYPE, H5E_CANTCLOSEOBJ, FAIL, "unable to close owned VOL object") dt->shared = H5FL_FREE(H5T_shared_t, dt->shared); dt = H5FL_FREE(H5T_t, dt); } /* end else */ @@ -1509,7 +1512,8 @@ H5T__unlock_cb(void *_dt, hid_t H5_ATTR_UNUSED id, void *_udata) FUNC_ENTER_STATIC_NOERR - HDassert(dt && dt->shared); + HDassert(dt); + HDassert(dt->shared); if (H5T_STATE_IMMUTABLE == dt->shared->state) { dt->shared->state = H5T_STATE_RDONLY; @@ -1775,7 +1779,7 @@ H5T_term_package(void) *------------------------------------------------------------------------- */ static herr_t -H5T__close_cb(H5T_t *dt) +H5T__close_cb(H5T_t *dt, void **request) { herr_t ret_value = SUCCEED; /* Return value */ @@ -1790,7 +1794,7 @@ H5T__close_cb(H5T_t *dt) */ if (NULL != dt->vol_obj) { /* Close the connector-managed datatype data */ - if (H5VL_datatype_close(dt->vol_obj, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0) + if (H5VL_datatype_close(dt->vol_obj, H5P_DATASET_XFER_DEFAULT, request) < 0) HGOTO_ERROR(H5E_DATATYPE, H5E_CLOSEERROR, FAIL, "unable to close datatype") /* Free the VOL object */ @@ -1987,6 +1991,66 @@ done: } /* end H5Tclose() */ /*------------------------------------------------------------------------- + * Function: H5Tclose_async + * + * Purpose: Asynchronous version of H5Tclose. + * + * Return: Non-negative on success/Negative on failure + * + *------------------------------------------------------------------------- + */ +herr_t +H5Tclose_async(const char *app_file, const char *app_func, unsigned app_line, hid_t type_id, hid_t es_id) +{ + H5T_t * dt; /* Pointer to datatype to close */ + void * token = NULL; /* Request token for async operation */ + void ** token_ptr = H5_REQUEST_NULL; /* Pointer to request token for async operation */ + H5VL_object_t *vol_obj = NULL; /* VOL object of dset_id */ + H5VL_t * connector = NULL; /* VOL connector */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_API(FAIL) + H5TRACE5("e", "*s*sIuii", app_file, app_func, app_line, type_id, es_id); + + /* Check args */ + if (NULL == (dt = (H5T_t *)H5I_object_verify(type_id, H5I_DATATYPE))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a datatype") + if (H5T_STATE_IMMUTABLE == dt->shared->state) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "immutable datatype") + + /* Get dataset object's connector */ + if (NULL == (vol_obj = H5VL_vol_object(type_id))) + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTGET, FAIL, "can't get VOL object for dataset") + + /* Prepare for possible asynchronous operation */ + if (H5ES_NONE != es_id) { + /* Increase connector's refcount, so it doesn't get closed if closing + * the dataset closes the file */ + connector = vol_obj->connector; + H5VL_conn_inc_rc(connector); + + /* Point at token for operation to set up */ + token_ptr = &token; + } /* end if */ + + /* When the reference count reaches zero the resources are freed */ + if (H5I_dec_app_ref_async(type_id, token_ptr) < 0) + HGOTO_ERROR(H5E_ID, H5E_BADID, FAIL, "problem freeing id") + + /* If a token was created, add the token to the event set */ + if (NULL != token) + if (H5ES_insert(es_id, vol_obj->connector, token, + H5ARG_TRACE5(FUNC, "*s*sIuii", app_file, app_func, app_line, type_id, es_id)) < 0) + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINSERT, FAIL, "can't insert token into event set") + +done: + if (connector && H5VL_conn_dec_rc(connector) < 0) + HDONE_ERROR(H5E_DATATYPE, H5E_CANTDEC, FAIL, "can't decrement ref count on connector") + + FUNC_LEAVE_API(ret_value) +} /* end H5Tclose_async() */ + +/*------------------------------------------------------------------------- * Function: H5Tequal * * Purpose: Determines if two datatypes are equal. @@ -3386,6 +3450,8 @@ H5T__create(H5T_class_t type, size_t size) done: if (NULL == ret_value) { if (dt) { + if (dt->shared->owned_vol_obj && H5VL_free_object(dt->shared->owned_vol_obj) < 0) + HDONE_ERROR(H5E_DATATYPE, H5E_CANTCLOSEOBJ, NULL, "unable to close owned VOL object") dt->shared = H5FL_FREE(H5T_shared_t, dt->shared); dt = H5FL_FREE(H5T_t, dt); } @@ -3428,9 +3494,12 @@ H5T__initiate_copy(const H5T_t *old_dt) /* Copy shared information */ *(new_dt->shared) = *(old_dt->shared); - /* Reset VOL fields */ - new_dt->vol_obj = NULL; - new_dt->shared->owned_vol_obj = NULL; + /* Increment ref count on owned VOL object */ + if (new_dt->shared->owned_vol_obj) + (void)H5VL_object_inc_rc(new_dt->shared->owned_vol_obj); + + /* Reset vol_obj field */ + new_dt->vol_obj = NULL; /* Set return value */ ret_value = new_dt; @@ -3438,8 +3507,11 @@ H5T__initiate_copy(const H5T_t *old_dt) done: if (ret_value == NULL) if (new_dt) { - if (new_dt->shared) + if (new_dt->shared) { + if (new_dt->shared->owned_vol_obj && H5VL_free_object(new_dt->shared->owned_vol_obj) < 0) + HDONE_ERROR(H5E_DATATYPE, H5E_CANTCLOSEOBJ, NULL, "unable to close owned VOL object") new_dt->shared = H5FL_FREE(H5T_shared_t, new_dt->shared); + } /* end if */ new_dt = H5FL_FREE(H5T_t, new_dt); } /* end if */ @@ -3768,6 +3840,8 @@ done: if (ret_value == NULL) if (new_dt) { HDassert(new_dt->shared); + if (new_dt->shared->owned_vol_obj && H5VL_free_object(new_dt->shared->owned_vol_obj) < 0) + HDONE_ERROR(H5E_DATATYPE, H5E_CANTCLOSEOBJ, NULL, "unable to close owned VOL object") new_dt->shared = H5FL_FREE(H5T_shared_t, new_dt->shared); new_dt = H5FL_FREE(H5T_t, new_dt); } /* end if */ @@ -3835,6 +3909,8 @@ H5T_copy_reopen(H5T_t *old_dt) /* The object is already open. Free the H5T_shared_t struct * we had been using and use the one that already exists. * Not terribly efficient. */ + if (new_dt->shared->owned_vol_obj && H5VL_free_object(new_dt->shared->owned_vol_obj) < 0) + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTCLOSEOBJ, NULL, "unable to close owned VOL object") new_dt->shared = H5FL_FREE(H5T_shared_t, new_dt->shared); new_dt->shared = reopened_fo; @@ -3871,6 +3947,8 @@ done: if (ret_value == NULL) if (new_dt) { HDassert(new_dt->shared); + if (new_dt->shared->owned_vol_obj && H5VL_free_object(new_dt->shared->owned_vol_obj) < 0) + HDONE_ERROR(H5E_DATATYPE, H5E_CANTCLOSEOBJ, NULL, "unable to close owned VOL object") new_dt->shared = H5FL_FREE(H5T_shared_t, new_dt->shared); new_dt = H5FL_FREE(H5T_t, new_dt); } /* end if */ @@ -3965,8 +4043,10 @@ H5T__alloc(void) done: if (ret_value == NULL) if (dt) { - if (dt->shared) + if (dt->shared) { + HDassert(!dt->shared->owned_vol_obj); dt->shared = H5FL_FREE(H5T_shared_t, dt->shared); + } /* end if */ dt = H5FL_FREE(H5T_t, dt); } /* end if */ @@ -4087,6 +4167,7 @@ H5T_close_real(H5T_t *dt) if (H5T__free(dt) < 0) HGOTO_ERROR(H5E_DATATYPE, H5E_CANTFREE, FAIL, "unable to free datatype"); + HDassert(!dt->shared->owned_vol_obj); dt->shared = H5FL_FREE(H5T_shared_t, dt->shared); } /* end if */ else @@ -4221,6 +4302,7 @@ H5T__set_size(H5T_t *dt, size_t size) /* Check args */ HDassert(dt); + HDassert(dt->shared); HDassert(size != 0); HDassert(H5T_REFERENCE != dt->shared->type); HDassert(!(H5T_ENUM == dt->shared->type && 0 == dt->shared->u.enumer.nmembs)); @@ -4408,11 +4490,38 @@ H5T_get_size(const H5T_t *dt) /* check args */ HDassert(dt); + HDassert(dt->shared); FUNC_LEAVE_NOAPI(dt->shared->size) } /* end H5T_get_size() */ /*------------------------------------------------------------------------- + * Function: H5T_get_force_conv + * + * Purpose: Determines if the type has forced conversion. This will be + * true if and only if the type keeps a pointer to a file VOL + * object internally. + * + * Return: TRUE/FALSE (never fails) + * + * Programmer: Neil Fortner + * Thursday, January 21, 2021 + *------------------------------------------------------------------------- + */ +hbool_t +H5T_get_force_conv(const H5T_t *dt) +{ + /* Use FUNC_ENTER_NOAPI_NOINIT_NOERR here to avoid performance issues */ + FUNC_ENTER_NOAPI_NOINIT_NOERR + + /* check args */ + HDassert(dt); + HDassert(dt->shared); + + FUNC_LEAVE_NOAPI(dt->shared->force_conv) +} /* end H5T_get_force_conv() */ + +/*------------------------------------------------------------------------- * Function: H5T_cmp * * Purpose: Compares two data types. @@ -4448,6 +4557,9 @@ H5T_cmp(const H5T_t *dt1, const H5T_t *dt2, hbool_t superset) if (dt1 == dt2) HGOTO_DONE(0); + HDassert(dt1->shared); + HDassert(dt2->shared); + /* compare */ if (dt1->shared->type < dt2->shared->type) HGOTO_DONE(-1); @@ -4853,6 +4965,10 @@ H5T_cmp(const H5T_t *dt1, const H5T_t *dt2, hbool_t superset) HGOTO_DONE(-1); if (dt1->shared->u.atomic.u.r.loc > dt2->shared->u.atomic.u.r.loc) HGOTO_DONE(1); + if (dt1->shared->u.atomic.u.r.file < dt2->shared->u.atomic.u.r.file) + HGOTO_DONE(-1); + if (dt1->shared->u.atomic.u.r.file > dt2->shared->u.atomic.u.r.file) + HGOTO_DONE(1); break; case H5T_NO_CLASS: @@ -5218,7 +5334,10 @@ H5T__path_find_real(const H5T_t *src, const H5T_t *dst, const char *name, H5T_co } /* end else-if */ /* Set the flag to indicate both source and destination types are compound types - * for the optimization of data reading (in H5Dio.c). */ + * for the optimization of data reading (in H5Dio.c). + * Make sure that path->are_compounds is only TRUE for compound types. + */ + path->are_compounds = FALSE; if (H5T_COMPOUND == H5T_get_class(src, TRUE) && H5T_COMPOUND == H5T_get_class(dst, TRUE)) path->are_compounds = TRUE; @@ -5286,11 +5405,6 @@ H5T_path_noop(const H5T_path_t *p) * Programmer: Raymond Lu * 8 June 2007 * - * Modifications: Neil Fortner - * 19 September 2008 - * Changed return value to H5T_subset_info_t - * (to allow it to return copy_size) - * *------------------------------------------------------------------------- */ H5T_subset_info_t * @@ -5826,10 +5940,12 @@ H5T_set_loc(H5T_t *dt, H5VL_object_t *file, H5T_loc_t loc) case H5T_VLEN: /* Recurse on the VL information if it's VL, compound or array, then free VL sequence */ - /* Recurse if it's VL, compound, enum or array */ + /* Recurse if it's VL, compound, enum or array (ignore references here so that we can encode + * them as part of the same blob)*/ /* (If the force_conv flag is _not_ set, the type cannot change in size, so don't recurse) */ if (dt->shared->parent->shared->force_conv && - H5T_IS_COMPLEX(dt->shared->parent->shared->type)) { + H5T_IS_COMPLEX(dt->shared->parent->shared->type) && + (dt->shared->parent->shared->type != H5T_REFERENCE)) { if ((changed = H5T_set_loc(dt->shared->parent, file, loc)) < 0) HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "Unable to set VL location"); if (changed > 0) @@ -6010,7 +6126,7 @@ done: } /* end H5T_is_vl_storage() */ /*------------------------------------------------------------------------- - * Function: H5T_upgrade_version_cb + * Function: H5T__upgrade_version_cb * * Purpose: H5T__visit callback to Upgrade the version of a datatype * (if there's any benefit to doing so) @@ -6027,9 +6143,9 @@ done: *------------------------------------------------------------------------- */ static herr_t -H5T_upgrade_version_cb(H5T_t *dt, void *op_value) +H5T__upgrade_version_cb(H5T_t *dt, void *op_value) { - FUNC_ENTER_NOAPI_NOINIT_NOERR + FUNC_ENTER_STATIC_NOERR /* Sanity check */ HDassert(dt); @@ -6064,7 +6180,7 @@ H5T_upgrade_version_cb(H5T_t *dt, void *op_value) } /* end switch */ FUNC_LEAVE_NOAPI(SUCCEED) -} /* end H5T_upgrade_version_cb() */ +} /* end H5T__upgrade_version_cb() */ /*------------------------------------------------------------------------- * Function: H5T__upgrade_version @@ -6091,7 +6207,8 @@ H5T__upgrade_version(H5T_t *dt, unsigned new_version) HDassert(dt); /* Iterate over entire datatype, upgrading the version of components, if it's useful */ - if (H5T__visit(dt, (H5T_VISIT_SIMPLE | H5T_VISIT_COMPLEX_LAST), H5T_upgrade_version_cb, &new_version) < 0) + if (H5T__visit(dt, (H5T_VISIT_SIMPLE | H5T_VISIT_COMPLEX_LAST), H5T__upgrade_version_cb, &new_version) < + 0) HGOTO_ERROR(H5E_DATATYPE, H5E_BADITER, FAIL, "iteration to upgrade datatype encoding version failed") done: @@ -6233,6 +6350,7 @@ H5T_own_vol_obj(H5T_t *dt, H5VL_object_t *vol_obj) /* Take ownership */ dt->shared->owned_vol_obj = vol_obj; + (void)H5VL_object_inc_rc(vol_obj); done: FUNC_LEAVE_NOAPI(ret_value) diff --git a/src/H5Tbit.c b/src/H5Tbit.c index c35a530..04e2a97 100644 --- a/src/H5Tbit.c +++ b/src/H5Tbit.c @@ -228,10 +228,7 @@ done: * Purpose: Return a small bit sequence as a number. Bit vector starts * at OFFSET and is SIZE bits long. * - * Return: Success: The bit sequence interpretted as an unsigned - * integer. - * - * Failure: 0 + * Return: The bit sequence interpretted as an unsigned integer * *------------------------------------------------------------------------- */ @@ -264,14 +261,13 @@ H5T__bit_get_d(uint8_t *buf, size_t offset, size_t size) case H5T_ORDER_NONE: case H5T_ORDER_MIXED: default: - /* Unknown endianness. Bail out. */ - HGOTO_DONE(UFAIL) + /* This function can't return errors */ + HDassert(0 && "unknown byte order"); } /* Set return value */ ret_value = val; -done: FUNC_LEAVE_NOAPI(ret_value) } /* end H5T__bit_get_d() */ @@ -388,7 +384,7 @@ H5T__bit_set(uint8_t *buf, size_t offset, size_t size, hbool_t value) *------------------------------------------------------------------------- */ ssize_t -H5T__bit_find(uint8_t *buf, size_t offset, size_t size, H5T_sdir_t direction, hbool_t value) +H5T__bit_find(const uint8_t *buf, size_t offset, size_t size, H5T_sdir_t direction, hbool_t value) { ssize_t base = (ssize_t)offset; ssize_t idx, i; diff --git a/src/H5Tcommit.c b/src/H5Tcommit.c index 0842312..d214ca1 100644 --- a/src/H5Tcommit.c +++ b/src/H5Tcommit.c @@ -29,6 +29,7 @@ #include "H5ACprivate.h" /* Metadata cache */ #include "H5CXprivate.h" /* API Contexts */ #include "H5Eprivate.h" /* Error handling */ +#include "H5ESprivate.h" /* Event Sets */ #include "H5FLprivate.h" /* Free lists */ #include "H5FOprivate.h" /* File objects */ #include "H5Iprivate.h" /* IDs */ @@ -54,6 +55,11 @@ /********************/ /* Local Prototypes */ /********************/ +static herr_t H5T__commit_api_common(hid_t loc_id, const char *name, hid_t type_id, hid_t lcpl_id, + hid_t tcpl_id, hid_t tapl_id, void **token_ptr, + H5VL_object_t **_vol_obj_ptr); +static hid_t H5T__open_api_common(hid_t loc_id, const char *name, hid_t tapl_id, void **token_ptr, + H5VL_object_t **_vol_obj_ptr); static H5T_t *H5T__open_oid(const H5G_loc_t *loc); /*********************/ @@ -79,27 +85,28 @@ H5FL_EXTERN(H5VL_t); H5FL_EXTERN(H5VL_object_t); /*------------------------------------------------------------------------- - * Function: H5Tcommit2 + * Function: H5T__commit_api_common * - * Purpose: Save a transient datatype to a file and turn the type handle - * into a "named", immutable type. + * Purpose: This is the common function for committing a datytype. * - * Return: SUCCEED/FAIL + * Return: Non-negative on success/Negative on failure * *------------------------------------------------------------------------- */ -herr_t -H5Tcommit2(hid_t loc_id, const char *name, hid_t type_id, hid_t lcpl_id, hid_t tcpl_id, hid_t tapl_id) +static herr_t +H5T__commit_api_common(hid_t loc_id, const char *name, hid_t type_id, hid_t lcpl_id, hid_t tcpl_id, + hid_t tapl_id, void **token_ptr, H5VL_object_t **_vol_obj_ptr) { - void * data = NULL; /* VOL-managed datatype data */ - H5VL_object_t * new_obj = NULL; /* VOL object that holds the datatype object and the VOL info */ - H5T_t * dt = NULL; /* High level datatype object that wraps the VOL object */ - H5VL_object_t * vol_obj = NULL; /* object of loc_id */ - H5VL_loc_params_t loc_params; - herr_t ret_value = SUCCEED; /* Return value */ + void * data = NULL; /* VOL-managed datatype data */ + H5VL_object_t * new_obj = NULL; /* VOL object that holds the datatype object and the VOL info */ + H5T_t * dt = NULL; /* High level datatype object that wraps the VOL object */ + H5VL_object_t * tmp_vol_obj = NULL; /* Object for loc_id */ + H5VL_object_t **vol_obj_ptr = + (_vol_obj_ptr ? _vol_obj_ptr : &tmp_vol_obj); /* Ptr to object ptr for loc_id */ + H5VL_loc_params_t loc_params; /* Location parameters */ + herr_t ret_value = SUCCEED; /* Return value */ - FUNC_ENTER_API(FAIL) - H5TRACE6("e", "i*siiii", loc_id, name, type_id, lcpl_id, tcpl_id, tapl_id); + FUNC_ENTER_STATIC /* Check arguments */ if (!name) @@ -126,38 +133,100 @@ H5Tcommit2(hid_t loc_id, const char *name, hid_t type_id, hid_t lcpl_id, hid_t t /* Set the LCPL for the API context */ H5CX_set_lcpl(lcpl_id); - /* Verify access property list and set up collective metadata if appropriate */ - if (H5CX_set_apl(&tapl_id, H5P_CLS_TACC, loc_id, TRUE) < 0) - HGOTO_ERROR(H5E_DATATYPE, H5E_CANTSET, FAIL, "can't set access property list info") - - /* Fill in location struct fields */ - loc_params.type = H5VL_OBJECT_BY_SELF; - loc_params.obj_type = H5I_get_type(loc_id); - - /* Get the object from the loc_id */ - if (NULL == (vol_obj = (H5VL_object_t *)H5I_object(loc_id))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid object identifier") + /* Set up object access arguments */ + if (H5VL_setup_acc_args(loc_id, H5P_CLS_TACC, TRUE, &tapl_id, vol_obj_ptr, &loc_params) < 0) + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTSET, FAIL, "can't set object access arguments") /* Commit the type */ - if (NULL == (data = H5VL_datatype_commit(vol_obj, &loc_params, name, type_id, lcpl_id, tcpl_id, tapl_id, - H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL))) + if (NULL == (data = H5VL_datatype_commit(*vol_obj_ptr, &loc_params, name, type_id, lcpl_id, tcpl_id, + tapl_id, H5P_DATASET_XFER_DEFAULT, token_ptr))) HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to commit datatype") /* Set up VOL object */ - if (NULL == (new_obj = H5FL_CALLOC(H5VL_object_t))) - HGOTO_ERROR(H5E_DATATYPE, H5E_CANTALLOC, FAIL, "can't allocate top object structure") - new_obj->connector = vol_obj->connector; - new_obj->connector->nrefs++; - new_obj->data = data; + if (NULL == (new_obj = H5VL_create_object(data, (*vol_obj_ptr)->connector))) + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTALLOC, FAIL, "can't create VOL object for committed datatype") /* Set the committed type object to the VOL connector pointer in the H5T_t struct */ dt->vol_obj = new_obj; done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5T__commit_api_common() */ + +/*------------------------------------------------------------------------- + * Function: H5Tcommit2 + * + * Purpose: Save a transient datatype to a file and turn the type handle + * into a "named", immutable type. + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Quincey Koziol + * April 5, 2007 + * + *------------------------------------------------------------------------- + */ +herr_t +H5Tcommit2(hid_t loc_id, const char *name, hid_t type_id, hid_t lcpl_id, hid_t tcpl_id, hid_t tapl_id) +{ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_API(FAIL) + H5TRACE6("e", "i*siiii", loc_id, name, type_id, lcpl_id, tcpl_id, tapl_id); + + /* Commit the dataset synchronously */ + if ((ret_value = H5T__commit_api_common(loc_id, name, type_id, lcpl_id, tcpl_id, tapl_id, NULL, NULL)) < + 0) + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTOPENOBJ, FAIL, "unable to commit datatype synchronously") + +done: FUNC_LEAVE_API(ret_value) } /* end H5Tcommit2() */ /*------------------------------------------------------------------------- + * Function: H5Tcommit_async + * + * Purpose: Asynchronous version of H5Tcommit2 + * + * Return: Non-negative on success/Negative on failure + * + *------------------------------------------------------------------------- + */ +herr_t +H5Tcommit_async(const char *app_file, const char *app_func, unsigned app_line, hid_t loc_id, const char *name, + hid_t type_id, hid_t lcpl_id, hid_t tcpl_id, hid_t tapl_id, hid_t es_id) +{ + H5VL_object_t *vol_obj = NULL; /* Object for loc_id */ + void * token = NULL; /* Request token for async operation */ + void ** token_ptr = H5_REQUEST_NULL; /* Pointer to request token for async operation */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_API(FAIL) + H5TRACE10("e", "*s*sIui*siiiii", app_file, app_func, app_line, loc_id, name, type_id, lcpl_id, tcpl_id, + tapl_id, es_id); + + /* Set up request token pointer for asynchronous operation */ + if (H5ES_NONE != es_id) + token_ptr = &token; + + /* Commit the datatype asynchronously */ + if ((ret_value = H5T__commit_api_common(loc_id, name, type_id, lcpl_id, tcpl_id, tapl_id, token_ptr, + &vol_obj)) < 0) + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTOPENOBJ, FAIL, "unable to commit datatype asynchronously") + + /* If a token was created, add the token to the event set */ + if (NULL != token) + /* clang-format off */ + if (H5ES_insert(es_id, vol_obj->connector, token, + H5ARG_TRACE10(FUNC, "*s*sIui*siiiii", app_file, app_func, app_line, loc_id, name, type_id, lcpl_id, tcpl_id, tapl_id, es_id)) < 0) + /* clang-format on */ + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINSERT, FAIL, "can't insert token into event set") + +done: + FUNC_LEAVE_API(ret_value) +} /* end H5Tcommit_async() */ + +/*------------------------------------------------------------------------- * Function: H5T__commit_named * * Purpose: Internal routine to save a transient datatype to a file and @@ -248,7 +317,10 @@ done: * Note: The datatype access property list is unused currently, but * is checked for sanity anyway. * - * Return: SUCCEED/FAIL + * Return: Non-negative on success/Negative on failure + * + * Programmer: Peter Cao + * May 17, 2005 * *------------------------------------------------------------------------- */ @@ -295,11 +367,8 @@ H5Tcommit_anon(hid_t loc_id, hid_t type_id, hid_t tcpl_id, hid_t tapl_id) HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to commit datatype") /* Setup VOL object */ - if (NULL == (new_obj = H5FL_CALLOC(H5VL_object_t))) - HGOTO_ERROR(H5E_DATATYPE, H5E_CANTALLOC, FAIL, "can't allocate top object structure") - new_obj->connector = vol_obj->connector; - new_obj->connector->nrefs++; - new_obj->data = dt; + if (NULL == (new_obj = H5VL_create_object(dt, vol_obj->connector))) + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTALLOC, FAIL, "can't create VOL object for committed datatype") /* Set the committed type object to the VOL connector pointer in the H5T_t struct */ type->vol_obj = new_obj; @@ -479,7 +548,10 @@ done: * * Purpose: Determines if a datatype is committed or not. * - * Return: TRUE/FALSE/FAIL + * Return: TRUE/FALSE/Negative + * + * Programmer: Robb Matzke + * Thursday, June 4, 1998 * *------------------------------------------------------------------------- */ @@ -510,7 +582,7 @@ done: * ADJUST to the link count. * * Return: Success: New link count - * Failure: Negative + * Failure: -1 * * Programmer: Quincey Koziol * Friday, September 26, 2003 @@ -536,10 +608,9 @@ done: } /* end H5T_link() */ /*------------------------------------------------------------------------- - * Function: H5Topen2 + * Function: H5T__open_api_common * - * Purpose: Opens a named datatype using a Datatype Access Property - * List. + * Purpose: This is the common function for opening a datatype. * * Return: Success: Object ID of the named datatype * @@ -547,16 +618,18 @@ done: * *------------------------------------------------------------------------- */ -hid_t -H5Topen2(hid_t loc_id, const char *name, hid_t tapl_id) +static hid_t +H5T__open_api_common(hid_t loc_id, const char *name, hid_t tapl_id, void **token_ptr, + H5VL_object_t **_vol_obj_ptr) { - void * dt = NULL; /* datatype object created by VOL connector */ - H5VL_object_t * vol_obj = NULL; /* object of loc_id */ + void * dt = NULL; /* datatype object created by VOL connector */ + H5VL_object_t * tmp_vol_obj = NULL; /* Object for loc_id */ + H5VL_object_t **vol_obj_ptr = + (_vol_obj_ptr ? _vol_obj_ptr : &tmp_vol_obj); /* Ptr to object ptr for loc_id */ H5VL_loc_params_t loc_params; hid_t ret_value = H5I_INVALID_HID; /* Return value */ - FUNC_ENTER_API(H5I_INVALID_HID) - H5TRACE3("i", "i*si", loc_id, name, tapl_id); + FUNC_ENTER_STATIC /* Check args */ if (!name) @@ -564,37 +637,108 @@ H5Topen2(hid_t loc_id, const char *name, hid_t tapl_id) if (!*name) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, H5I_INVALID_HID, "name parameter cannot be an empty string") - /* Verify access property list and set up collective metadata if appropriate */ - if (H5CX_set_apl(&tapl_id, H5P_CLS_TACC, loc_id, FALSE) < 0) - HGOTO_ERROR(H5E_DATATYPE, H5E_CANTSET, FAIL, "can't set access property list info") - - /* Fill in location struct fields */ - loc_params.type = H5VL_OBJECT_BY_SELF; - loc_params.obj_type = H5I_get_type(loc_id); - - /* get the location object */ - if (NULL == (vol_obj = (H5VL_object_t *)H5I_object(loc_id))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5I_INVALID_HID, "invalid file identifier") + /* Set up object access arguments */ + if (H5VL_setup_acc_args(loc_id, H5P_CLS_TACC, FALSE, &tapl_id, vol_obj_ptr, &loc_params) < 0) + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTSET, H5I_INVALID_HID, "can't set object access arguments") /* Open the datatype */ - if (NULL == (dt = H5VL_datatype_open(vol_obj, &loc_params, name, tapl_id, H5P_DATASET_XFER_DEFAULT, - H5_REQUEST_NULL))) + if (NULL == (dt = H5VL_datatype_open(*vol_obj_ptr, &loc_params, name, tapl_id, H5P_DATASET_XFER_DEFAULT, + token_ptr))) HGOTO_ERROR(H5E_DATATYPE, H5E_CANTOPENOBJ, H5I_INVALID_HID, "unable to open named datatype") /* Register the type and return the ID */ - if ((ret_value = H5VL_register(H5I_DATATYPE, dt, vol_obj->connector, TRUE)) < 0) + if ((ret_value = H5VL_register(H5I_DATATYPE, dt, (*vol_obj_ptr)->connector, TRUE)) < 0) HGOTO_ERROR(H5E_DATATYPE, H5E_CANTREGISTER, H5I_INVALID_HID, "unable to register named datatype") done: /* Cleanup on error */ if (H5I_INVALID_HID == ret_value) - if (dt && H5VL_datatype_close(vol_obj, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0) + if (dt && H5VL_datatype_close(*vol_obj_ptr, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0) HDONE_ERROR(H5E_DATATYPE, H5E_CLOSEERROR, H5I_INVALID_HID, "unable to release datatype") + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5T__open_api_common() */ + +/*------------------------------------------------------------------------- + * Function: H5Topen2 + * + * Purpose: Opens a named datatype using a Datatype Access Property + * List. + * + * Return: Success: Object ID of the named datatype + * + * Failure: H5I_INVALID_HID + * + * Programmer: James Laird + * Thursday July 27, 2006 + * + *------------------------------------------------------------------------- + */ +hid_t +H5Topen2(hid_t loc_id, const char *name, hid_t tapl_id) +{ + hid_t ret_value = H5I_INVALID_HID; /* Return value */ + + FUNC_ENTER_API(H5I_INVALID_HID) + H5TRACE3("i", "i*si", loc_id, name, tapl_id); + + /* Open the datatype synchronously */ + if ((ret_value = H5T__open_api_common(loc_id, name, tapl_id, NULL, NULL)) < 0) + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTOPENOBJ, H5I_INVALID_HID, + "unable to open named datatype synchronously") +done: FUNC_LEAVE_API(ret_value) } /* end H5Topen2() */ /*------------------------------------------------------------------------- + * Function: H5Topen_async + * + * Purpose: Asynchronous version of H5Topen2. + * + * Return: Success: Object ID of the named datatype + * + * Failure: H5I_INVALID_HID + * + *------------------------------------------------------------------------- + */ +hid_t +H5Topen_async(const char *app_file, const char *app_func, unsigned app_line, hid_t loc_id, const char *name, + hid_t tapl_id, hid_t es_id) +{ + H5VL_object_t *vol_obj = NULL; /* Object for loc_id */ + void * token = NULL; /* Request token for async operation */ + void ** token_ptr = H5_REQUEST_NULL; /* Pointer to request token for async operation */ + hid_t ret_value = H5I_INVALID_HID; /* Return value */ + + FUNC_ENTER_API(H5I_INVALID_HID) + H5TRACE7("i", "*s*sIui*sii", app_file, app_func, app_line, loc_id, name, tapl_id, es_id); + + /* Set up request token pointer for asynchronous operation */ + if (H5ES_NONE != es_id) + token_ptr = &token; /* Point at token for VOL connector to set up */ + + /* Open the datatype asynchronously */ + if ((ret_value = H5T__open_api_common(loc_id, name, tapl_id, token_ptr, &vol_obj)) < 0) + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTOPENOBJ, H5I_INVALID_HID, + "unable to open named datatype asynchronously") + + /* If a token was created, add the token to the event set */ + if (NULL != token) + /* clang-format off */ + if (H5ES_insert(es_id, vol_obj->connector, token, + H5ARG_TRACE7(FUNC, "*s*sIui*sii", app_file, app_func, app_line, loc_id, name, tapl_id, es_id)) < 0) { + /* clang-format on */ + if (H5I_dec_app_ref_always_close(ret_value) < 0) + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTDEC, H5I_INVALID_HID, + "can't decrement count on datatype ID") + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINSERT, H5I_INVALID_HID, "can't insert token into event set") + } /* end if */ + +done: + FUNC_LEAVE_API(ret_value) +} /* end H5Topen_async() */ + +/*------------------------------------------------------------------------- * Function: H5Tget_create_plist * * Purpose: Returns a copy of the datatype creation property list. @@ -608,6 +752,9 @@ done: * * Failure: H5I_INVALID_HID * + * Programmer: Quincey Koziol + * Tuesday, November 28, 2006 + * *------------------------------------------------------------------------- */ hid_t @@ -961,8 +1108,11 @@ H5T_open(const H5G_loc_t *loc) done: if (ret_value == NULL) { if (dt) { - if (shared_fo == NULL) /* Need to free shared fo */ + if (shared_fo == NULL) { /* Need to free shared fo */ + if (dt->shared->owned_vol_obj && H5VL_free_object(dt->shared->owned_vol_obj) < 0) + HDONE_ERROR(H5E_DATATYPE, H5E_CANTCLOSEOBJ, NULL, "unable to close owned VOL object") dt->shared = H5FL_FREE(H5T_shared_t, dt->shared); + } /* end if */ H5O_loc_free(&(dt->oloc)); H5G_name_free(&(dt->path)); @@ -1180,7 +1330,7 @@ H5T_save_refresh_state(hid_t tid, H5O_shared_t *cached_H5O_shared) if (NULL == (dt = (H5T_t *)H5I_object_verify(tid, H5I_DATATYPE))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "tid is not a datatype ID") - vol_dt = (H5T_t *)(dt->vol_obj->data); + vol_dt = H5T_get_actual_type(dt); if (NULL == vol_dt) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "tid is not not a named datatype ID") @@ -1220,7 +1370,7 @@ H5T_restore_refresh_state(hid_t tid, H5O_shared_t *cached_H5O_shared) if (NULL == (dt = (H5T_t *)H5I_object_verify(tid, H5I_DATATYPE))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "tid not a datatype ID") - vol_dt = (H5T_t *)(dt->vol_obj->data); + vol_dt = H5T_get_actual_type(dt); if (NULL == vol_dt) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "tid is not not a named datatype ID") diff --git a/src/H5Tconv.c b/src/H5Tconv.c index a33a67c..0c98633 100644 --- a/src/H5Tconv.c +++ b/src/H5Tconv.c @@ -710,17 +710,17 @@ FUNC_ENTER_PACKAGE \ \ { \ - size_t elmtno; /*element number */ \ + size_t elmtno; /*element number */ \ H5T_CONV_DECL_PREC(PREC) /*declare precision variables, or not */ \ - void * src_buf; /*'raw' source buffer */ \ - void * dst_buf; /*'raw' destination buffer */ \ - ST * src, *s; /*source buffer */ \ - DT * dst, *d; /*destination buffer */ \ - H5T_t * st, *dt; /*datatype descriptors */ \ - ST src_aligned; /*source aligned type */ \ - DT dst_aligned; /*destination aligned type */ \ - hbool_t s_mv, d_mv; /*move data to align it? */ \ - ssize_t s_stride, d_stride; /*src and dst strides */ \ + void * src_buf; /*'raw' source buffer */ \ + void * dst_buf; /*'raw' destination buffer */ \ + ST * src, *s; /*source buffer */ \ + DT * dst, *d; /*destination buffer */ \ + H5T_t * st, *dt; /*datatype descriptors */ \ + ST src_aligned; /*source aligned type */ \ + DT dst_aligned; /*destination aligned type */ \ + hbool_t s_mv, d_mv; /*move data to align it? */ \ + ssize_t s_stride, d_stride; /*src and dst strides */ \ size_t safe; /*how many elements are safe to process in each pass */ \ H5T_conv_cb_t cb_struct; /*conversion callback structure */ \ \ @@ -859,9 +859,9 @@ done: #define H5T_CONV_DECL_PREC(PREC) H5_GLUE(H5T_CONV_DECL_PREC_, PREC) #define H5T_CONV_DECL_PREC_Y \ - size_t sprec; /*source precision */ \ - size_t dprec; /*destination precision */ \ - H5T_class_t tclass; /*datatype's class */ + size_t sprec; /*source precision */ \ + size_t dprec; /*destination precision */ \ + H5T_class_t tclass; /*datatype's class */ #define H5T_CONV_DECL_PREC_N /*no precision variables */ @@ -1067,7 +1067,7 @@ typedef struct H5T_conv_hw_t { /* Local Prototypes */ /********************/ -static herr_t H5T_reverse_order(uint8_t *rev, uint8_t *s, size_t size, H5T_order_t order); +static herr_t H5T__reverse_order(uint8_t *rev, uint8_t *s, size_t size, H5T_order_t order); /*********************/ /* Public Variables */ @@ -1095,15 +1095,15 @@ H5FL_BLK_DEFINE_STATIC(array_seq); H5FL_BLK_DEFINE_STATIC(ref_seq); /*------------------------------------------------------------------------- - * Function: H5T__conv_noop + * Function: H5T__conv_noop * - * Purpose: The no-op conversion. The library knows about this - * conversion without it being registered. + * Purpose: The no-op conversion. The library knows about this + * conversion without it being registered. * - * Return: Non-negative on success/Negative on failure + * Return: Non-negative on success/Negative on failure * - * Programmer: Robb Matzke - * Wednesday, January 14, 1998 + * Programmer: Robb Matzke + * Wednesday, January 14, 1998 * *------------------------------------------------------------------------- */ @@ -1137,18 +1137,18 @@ done: } /* end H5T__conv_noop() */ /*------------------------------------------------------------------------- - * Function: H5T__conv_order_opt + * Function: H5T__conv_order_opt * - * Purpose: Convert one type to another when byte order is the only - * difference. This is the optimized version of H5T__conv_order() + * Purpose: Convert one type to another when byte order is the only + * difference. This is the optimized version of H5T__conv_order() * for a handful of different sizes. * - * Note: This is a soft conversion function. + * Note: This is a soft conversion function. * - * Return: Non-negative on success/Negative on failure + * Return: Non-negative on success/Negative on failure * - * Programmer: Robb Matzke - * Friday, January 25, 2002 + * Programmer: Robb Matzke + * Friday, January 25, 2002 * *------------------------------------------------------------------------- */ @@ -1547,17 +1547,17 @@ done: } /* end H5T__conv_order_opt() */ /*------------------------------------------------------------------------- - * Function: H5T__conv_order + * Function: H5T__conv_order * - * Purpose: Convert one type to another when byte order is the only - * difference. + * Purpose: Convert one type to another when byte order is the only + * difference. * - * Note: This is a soft conversion function. + * Note: This is a soft conversion function. * - * Return: Non-negative on success/Negative on failure + * Return: Non-negative on success/Negative on failure * - * Programmer: Robb Matzke - * Tuesday, January 13, 1998 + * Programmer: Robb Matzke + * Tuesday, January 13, 1998 * *------------------------------------------------------------------------- */ @@ -1646,14 +1646,14 @@ done: } /* end H5T__conv_order() */ /*------------------------------------------------------------------------- - * Function: H5T__conv_b_b + * Function: H5T__conv_b_b * - * Purpose: Convert from one bitfield to any other bitfield. + * Purpose: Convert from one bitfield to any other bitfield. * - * Return: Non-negative on success/Negative on failure + * Return: Non-negative on success/Negative on failure * - * Programmer: Robb Matzke - * Thursday, May 20, 1999 + * Programmer: Robb Matzke + * Thursday, May 20, 1999 * *------------------------------------------------------------------------- */ @@ -1662,14 +1662,14 @@ H5T__conv_b_b(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, siz size_t H5_ATTR_UNUSED bkg_stride, void *_buf, void H5_ATTR_UNUSED *background) { uint8_t * buf = (uint8_t *)_buf; - H5T_t * src = NULL, *dst = NULL; /*source and dest datatypes */ - ssize_t direction; /*direction of traversal */ - size_t elmtno; /*element number */ - size_t olap; /*num overlapping elements */ + H5T_t * src = NULL, *dst = NULL; /*source and dest datatypes */ + ssize_t direction; /*direction of traversal */ + size_t elmtno; /*element number */ + size_t olap; /*num overlapping elements */ size_t half_size; /*1/2 of total size for swapping*/ uint8_t * s, *sp, *d, *dp; /*source and dest traversal ptrs*/ - uint8_t dbuf[256]; /*temp destination buffer */ - size_t msb_pad_offset; /*offset for dest MSB padding */ + uint8_t dbuf[256] = {0}; /*temp destination buffer */ + size_t msb_pad_offset; /*offset for dest MSB padding */ size_t i; uint8_t * src_rev = NULL; /*order-reversed source buffer */ H5T_conv_cb_t cb_struct = {NULL, NULL}; /*conversion callback structure */ @@ -1787,8 +1787,8 @@ H5T__conv_b_b(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, siz if (src->shared->u.atomic.prec > dst->shared->u.atomic.prec) { /*overflow*/ if (cb_struct.func) { /*If user's exception handler is present, use it*/ - H5T_reverse_order(src_rev, s, src->shared->size, - src->shared->u.atomic.order); /*reverse order first*/ + H5T__reverse_order(src_rev, s, src->shared->size, + src->shared->u.atomic.order); /*reverse order first*/ except_ret = (cb_struct.func)(H5T_CONV_EXCEPT_RANGE_HI, src_id, dst_id, src_rev, d, cb_struct.user_data); } /* end if */ @@ -1893,26 +1893,26 @@ done: } /* end H5T__conv_b_b() */ /*------------------------------------------------------------------------- - * Function: H5T_conv_struct_free + * Function: H5T__conv_struct_free * - * Purpose: Free the private data structure used by the compound + * Purpose: Free the private data structure used by the compound * conversion functions. * - * Return: The result of H5MM_xfree(priv) (NULL) + * Return: The result of H5MM_xfree(priv) (NULL) * - * Programmer: Neil Fortner - * Wednesday, October 1, 2008 + * Programmer: Neil Fortner + * Wednesday, October 1, 2008 * *------------------------------------------------------------------------- */ static H5T_conv_struct_t * -H5T_conv_struct_free(H5T_conv_struct_t *priv) +H5T__conv_struct_free(H5T_conv_struct_t *priv) { int * src2dst = priv->src2dst; hid_t * src_memb_id = priv->src_memb_id, *dst_memb_id = priv->dst_memb_id; unsigned i; - FUNC_ENTER_NOAPI_NOINIT_NOERR + FUNC_ENTER_STATIC_NOERR for (i = 0; i < priv->src_nmembs; i++) if (src2dst[i] >= 0) { @@ -1930,25 +1930,25 @@ H5T_conv_struct_free(H5T_conv_struct_t *priv) H5MM_xfree(priv->memb_path); FUNC_LEAVE_NOAPI((H5T_conv_struct_t *)H5MM_xfree(priv)) -} /* end H5T_conv_struct_free() */ +} /* end H5T__conv_struct_free() */ /*------------------------------------------------------------------------- - * Function: H5T_conv_struct_init + * Function: H5T__conv_struct_init * - * Purpose: Initialize the `priv' field of `cdata' with conversion - * information that is relatively constant. If `priv' is - * already initialized then the member conversion functions - * are recalculated. + * Purpose: Initialize the `priv' field of `cdata' with conversion + * information that is relatively constant. If `priv' is + * already initialized then the member conversion functions + * are recalculated. * - * Priv fields are indexed by source member number or - * destination member number depending on whether the field - * contains information about the source datatype or the - * destination datatype (fields that contains the same - * information for both source and destination are indexed by - * source member number). The src2dst[] priv array maps source - * member numbers to destination member numbers, but if the - * source member doesn't have a corresponding destination member - * then the src2dst[i]=-1. + * Priv fields are indexed by source member number or + * destination member number depending on whether the field + * contains information about the source datatype or the + * destination datatype (fields that contains the same + * information for both source and destination are indexed by + * source member number). The src2dst[] priv array maps source + * member numbers to destination member numbers, but if the + * source member doesn't have a corresponding destination member + * then the src2dst[i]=-1. * * Special optimization case when the source and destination * members are a subset of each other, and the order is the same, @@ -1971,15 +1971,15 @@ H5T_conv_struct_free(H5T_conv_struct_t *priv) * The optimization is simply moving data to the appropriate * places in the buffer. * - * Return: Non-negative on success/Negative on failure + * Return: Non-negative on success/Negative on failure * - * Programmer: Robb Matzke - * Monday, January 26, 1998 + * Programmer: Robb Matzke + * Monday, January 26, 1998 * *------------------------------------------------------------------------- */ static herr_t -H5T_conv_struct_init(H5T_t *src, H5T_t *dst, H5T_cdata_t *cdata) +H5T__conv_struct_init(H5T_t *src, H5T_t *dst, H5T_cdata_t *cdata) { H5T_conv_struct_t *priv = (H5T_conv_struct_t *)(cdata->priv); int * src2dst = NULL; @@ -1987,7 +1987,7 @@ H5T_conv_struct_init(H5T_t *src, H5T_t *dst, H5T_cdata_t *cdata) unsigned i, j; herr_t ret_value = SUCCEED; /* Return value */ - FUNC_ENTER_NOAPI_NOINIT + FUNC_ENTER_STATIC src_nmembs = src->shared->u.compnd.nmembs; dst_nmembs = dst->shared->u.compnd.nmembs; @@ -2010,7 +2010,7 @@ H5T_conv_struct_init(H5T_t *src, H5T_t *dst, H5T_cdata_t *cdata) priv->subset_info.copy_size = 0; /* - * Insure that members are sorted. + * Ensure that members are sorted. */ H5T__sort_value(src, NULL); H5T__sort_value(dst, NULL); @@ -2069,7 +2069,7 @@ H5T_conv_struct_init(H5T_t *src, H5T_t *dst, H5T_cdata_t *cdata) dst->shared->u.compnd.memb[src2dst[i]].type); if (NULL == (priv->memb_path[i] = tpath)) { - cdata->priv = H5T_conv_struct_free(priv); + cdata->priv = H5T__conv_struct_free(priv); HGOTO_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, "unable to convert member datatype") } /* end if */ } /* end if */ @@ -2130,10 +2130,10 @@ H5T_conv_struct_init(H5T_t *src, H5T_t *dst, H5T_cdata_t *cdata) done: FUNC_LEAVE_NOAPI(ret_value) -} /* end H5T_conv_struct_init() */ +} /* end H5T__conv_struct_init() */ /*------------------------------------------------------------------------- - * Function: H5T__conv_struct_subset + * Function: H5T__conv_struct_subset * * Purpose: A quick way to return a field in a struct private in this * file. The flag SMEMBS_SUBSET indicates whether the source @@ -2151,8 +2151,8 @@ done: * Return: A pointer to the subset info struct in p. Points directly * into the structure. * - * Programmer: Raymond Lu - * 8 June 2007 + * Programmer: Raymond Lu + * 8 June 2007 * *------------------------------------------------------------------------- */ @@ -2172,28 +2172,28 @@ H5T__conv_struct_subset(const H5T_cdata_t *cdata) } /* end H5T__conv_struct_subset() */ /*------------------------------------------------------------------------- - * Function: H5T__conv_struct + * Function: H5T__conv_struct * - * Purpose: Converts between compound datatypes. This is a soft - * conversion function. The algorithm is basically: + * Purpose: Converts between compound datatypes. This is a soft + * conversion function. The algorithm is basically: * - * For each element do - * For I=1..NELMTS do - * If sizeof destination type <= sizeof source type then - * Convert member to destination type; - * Move member as far left as possible; + * For each element do + * For I=1..NELMTS do + * If sizeof destination type <= sizeof source type then + * Convert member to destination type; + * Move member as far left as possible; * - * For I=NELMTS..1 do - * If not destination type then - * Convert member to destination type; - * Move member to correct position in BKG + * For I=NELMTS..1 do + * If not destination type then + * Convert member to destination type; + * Move member to correct position in BKG * - * Copy BKG to BUF + * Copy BKG to BUF * - * Return: Non-negative on success/Negative on failure + * Return: Non-negative on success/Negative on failure * - * Programmer: Robb Matzke - * Thursday, January 22, 1998 + * Programmer: Robb Matzke + * Thursday, January 22, 1998 * *------------------------------------------------------------------------- */ @@ -2201,20 +2201,20 @@ herr_t H5T__conv_struct(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, size_t buf_stride, size_t bkg_stride, void *_buf, void *_bkg) { - uint8_t * buf = (uint8_t *)_buf; /*cast for pointer arithmetic */ - uint8_t * bkg = (uint8_t *)_bkg; /*background pointer arithmetic */ + uint8_t * buf = (uint8_t *)_buf; /*cast for pointer arithmetic */ + uint8_t * bkg = (uint8_t *)_bkg; /*background pointer arithmetic */ uint8_t * xbuf = buf, *xbkg = bkg; /*temp pointers into buf and bkg*/ - H5T_t * src = NULL; /*source datatype */ - H5T_t * dst = NULL; /*destination datatype */ - int * src2dst = NULL; /*maps src member to dst member */ + H5T_t * src = NULL; /*source datatype */ + H5T_t * dst = NULL; /*destination datatype */ + int * src2dst = NULL; /*maps src member to dst member */ H5T_cmemb_t * src_memb = NULL; /*source struct member descript.*/ - H5T_cmemb_t * dst_memb = NULL; /*destination struct memb desc. */ - size_t offset; /*byte offset wrt struct */ - ssize_t src_delta; /*source stride */ - ssize_t bkg_delta; /*background stride */ + H5T_cmemb_t * dst_memb = NULL; /*destination struct memb desc. */ + size_t offset; /*byte offset wrt struct */ + ssize_t src_delta; /*source stride */ + ssize_t bkg_delta; /*background stride */ size_t elmtno; - unsigned u; /*counters */ - int i; /*counters */ + unsigned u; /*counters */ + int i; /*counters */ H5T_conv_struct_t *priv = (H5T_conv_struct_t *)(cdata->priv); herr_t ret_value = SUCCEED; /* Return value */ @@ -2235,7 +2235,7 @@ H5T__conv_struct(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, if (H5T_COMPOUND != dst->shared->type) HGOTO_ERROR(H5E_DATATYPE, H5E_BADTYPE, FAIL, "not a H5T_COMPOUND datatype") - if (H5T_conv_struct_init(src, dst, cdata) < 0) + if (H5T__conv_struct_init(src, dst, cdata) < 0) HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to initialize conversion data") break; @@ -2243,7 +2243,7 @@ H5T__conv_struct(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, /* * Free the private conversion data. */ - cdata->priv = H5T_conv_struct_free(priv); + cdata->priv = H5T__conv_struct_free(priv); break; case H5T_CONV_CONV: @@ -2255,7 +2255,7 @@ H5T__conv_struct(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, HDassert(priv); HDassert(bkg && cdata->need_bkg); - if (cdata->recalc && H5T_conv_struct_init(src, dst, cdata) < 0) + if (cdata->recalc && H5T__conv_struct_init(src, dst, cdata) < 0) HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to initialize conversion data") /* @@ -2382,27 +2382,27 @@ done: } /* end H5T__conv_struct() */ /*------------------------------------------------------------------------- - * Function: H5T__conv_struct_opt + * Function: H5T__conv_struct_opt * - * Purpose: Converts between compound datatypes in a manner more - * efficient than the general-purpose H5T__conv_struct() - * function. This function isn't applicable if the destination - * is larger than the source type. This is a soft conversion - * function. The algorithm is basically: + * Purpose: Converts between compound datatypes in a manner more + * efficient than the general-purpose H5T__conv_struct() + * function. This function isn't applicable if the destination + * is larger than the source type. This is a soft conversion + * function. The algorithm is basically: * - * For each member of the struct - * If sizeof destination type <= sizeof source type then - * Convert member to destination type for all elements - * Move memb to BKG buffer for all elements - * Else - * Move member as far left as possible for all elements + * For each member of the struct + * If sizeof destination type <= sizeof source type then + * Convert member to destination type for all elements + * Move memb to BKG buffer for all elements + * Else + * Move member as far left as possible for all elements * - * For each member of the struct (in reverse order) - * If not destination type then - * Convert member to destination type for all elements - * Move member to correct position in BKG for all elements + * For each member of the struct (in reverse order) + * If not destination type then + * Convert member to destination type for all elements + * Move member to correct position in BKG for all elements * - * Copy BKG to BUF for all elements + * Copy BKG to BUF for all elements * * Special case when the source and destination members * are a subset of each other, and the order is the same, and no @@ -2417,10 +2417,10 @@ done: * The optimization is simply moving data to the appropriate * places in the buffer. * - * Return: Non-negative on success/Negative on failure + * Return: Non-negative on success/Negative on failure * - * Programmer: Robb Matzke - * Thursday, January 22, 1998 + * Programmer: Robb Matzke + * Thursday, January 22, 1998 * *------------------------------------------------------------------------- */ @@ -2428,22 +2428,22 @@ herr_t H5T__conv_struct_opt(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, size_t buf_stride, size_t bkg_stride, void *_buf, void *_bkg) { - uint8_t * buf = (uint8_t *)_buf; /*cast for pointer arithmetic */ - uint8_t * bkg = (uint8_t *)_bkg; /*background pointer arithmetic */ - uint8_t * xbuf = NULL; /*temporary pointer into `buf' */ - uint8_t * xbkg = NULL; /*temporary pointer into `bkg' */ - H5T_t * src = NULL; /*source datatype */ - H5T_t * dst = NULL; /*destination datatype */ - int * src2dst = NULL; /*maps src member to dst member */ + uint8_t * buf = (uint8_t *)_buf; /*cast for pointer arithmetic */ + uint8_t * bkg = (uint8_t *)_bkg; /*background pointer arithmetic */ + uint8_t * xbuf = NULL; /*temporary pointer into `buf' */ + uint8_t * xbkg = NULL; /*temporary pointer into `bkg' */ + H5T_t * src = NULL; /*source datatype */ + H5T_t * dst = NULL; /*destination datatype */ + int * src2dst = NULL; /*maps src member to dst member */ H5T_cmemb_t * src_memb = NULL; /*source struct member descript.*/ - H5T_cmemb_t * dst_memb = NULL; /*destination struct memb desc. */ - size_t offset; /*byte offset wrt struct */ - size_t elmtno; /*element counter */ + H5T_cmemb_t * dst_memb = NULL; /*destination struct memb desc. */ + size_t offset; /*byte offset wrt struct */ + size_t elmtno; /*element counter */ size_t copy_size; /*size of element for copying */ - H5T_conv_struct_t *priv = NULL; /*private data */ + H5T_conv_struct_t *priv = NULL; /*private data */ hbool_t no_stride = FALSE; /*flag to indicate no stride */ - unsigned u; /*counters */ - int i; /*counters */ + unsigned u; /*counters */ + int i; /*counters */ herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_PACKAGE @@ -2464,7 +2464,7 @@ H5T__conv_struct_opt(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelm HGOTO_ERROR(H5E_DATATYPE, H5E_BADTYPE, FAIL, "not a H5T_COMPOUND datatype") /* Initialize data which is relatively constant */ - if (H5T_conv_struct_init(src, dst, cdata) < 0) + if (H5T__conv_struct_init(src, dst, cdata) < 0) HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to initialize conversion data") priv = (H5T_conv_struct_t *)(cdata->priv); src2dst = priv->src2dst; @@ -2497,7 +2497,7 @@ H5T__conv_struct_opt(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelm if (dst_memb->size > src_memb->size) { offset -= src_memb->size; if (dst_memb->size > src->shared->size - offset) { - cdata->priv = H5T_conv_struct_free(priv); + cdata->priv = H5T__conv_struct_free(priv); HGOTO_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, "conversion is unsupported by this function") } /* end if */ @@ -2510,7 +2510,7 @@ H5T__conv_struct_opt(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelm /* * Free the private conversion data. */ - cdata->priv = H5T_conv_struct_free((H5T_conv_struct_t *)(cdata->priv)); + cdata->priv = H5T__conv_struct_free((H5T_conv_struct_t *)(cdata->priv)); break; case H5T_CONV_CONV: @@ -2521,7 +2521,7 @@ H5T__conv_struct_opt(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelm HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a datatype") /* Update cached data if necessary */ - if (cdata->recalc && H5T_conv_struct_init(src, dst, cdata) < 0) + if (cdata->recalc && H5T__conv_struct_init(src, dst, cdata) < 0) HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to initialize conversion data") priv = (H5T_conv_struct_t *)(cdata->priv); HDassert(priv); @@ -2656,31 +2656,31 @@ done: } /* end H5T__conv_struct_opt() */ /*------------------------------------------------------------------------- - * Function: H5T_conv_enum_init + * Function: H5T__conv_enum_init * - * Purpose: Initialize information for H5T__conv_enum(). + * Purpose: Initialize information for H5T__conv_enum(). * - * Return: Success: Non-negative + * Return: Success: Non-negative * - * Failure: Negative + * Failure: Negative * - * Programmer: Robb Matzke + * Programmer: Robb Matzke * Monday, January 4, 1999 * *------------------------------------------------------------------------- */ static herr_t -H5T_conv_enum_init(H5T_t *src, H5T_t *dst, H5T_cdata_t *cdata) -{ - H5T_enum_struct_t *priv = NULL; /*private conversion data */ - int n; /*src value cast as native int */ - int domain[2] = {0, 0}; /*min and max source values */ - int * map = NULL; /*map from src value to dst idx */ - unsigned length; /*nelmts in map array */ - unsigned i, j; /*counters */ +H5T__conv_enum_init(H5T_t *src, H5T_t *dst, H5T_cdata_t *cdata) +{ + H5T_enum_struct_t *priv = NULL; /*private conversion data */ + int n; /*src value cast as native int */ + int domain[2] = {0, 0}; /*min and max source values */ + int * map = NULL; /*map from src value to dst idx */ + unsigned length; /*nelmts in map array */ + unsigned i, j; /*counters */ herr_t ret_value = SUCCEED; /* Return value */ - FUNC_ENTER_NOAPI_NOINIT + FUNC_ENTER_STATIC cdata->need_bkg = H5T_BKG_NO; if (NULL == (priv = (H5T_enum_struct_t *)(cdata->priv = H5MM_calloc(sizeof(*priv))))) @@ -2699,7 +2699,7 @@ H5T_conv_enum_init(H5T_t *src, H5T_t *dst, H5T_cdata_t *cdata) HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed") for (i = 0, j = 0; i < src->shared->u.enumer.nmembs && j < dst->shared->u.enumer.nmembs; i++, j++) { while (j < dst->shared->u.enumer.nmembs && - HDstrcmp(src->shared->u.enumer.name[i], dst->shared->u.enumer.name[j])) + HDstrcmp(src->shared->u.enumer.name[i], dst->shared->u.enumer.name[j]) != 0) j++; if (j >= dst->shared->u.enumer.nmembs) HGOTO_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, @@ -2712,12 +2712,12 @@ H5T_conv_enum_init(H5T_t *src, H5T_t *dst, H5T_cdata_t *cdata) * value converted. However, if all of the following constraints are met * then we can build a perfect hash table and use an O(1) lookup method. * - * A: The source datatype size matches one of our native datatype - * sizes. + * A: The source datatype size matches one of our native datatype + * sizes. * - * B: After casting the source value bit pattern to a native type - * the size of the range of values is less than 20% larger than - * the number of values. + * B: After casting the source value bit pattern to a native type + * the size of the range of values is less than 20% larger than + * the number of values. * * If this special case is met then we use the source bit pattern cast as * a native integer type as an index into the `val2dst'. The values of @@ -2799,15 +2799,15 @@ done: } /*------------------------------------------------------------------------- - * Function: H5T__conv_enum + * Function: H5T__conv_enum * - * Purpose: Converts one type of enumerated data to another. + * Purpose: Converts one type of enumerated data to another. * - * Return: Success: Non-negative + * Return: Success: Non-negative * - * Failure: negative + * Failure: negative * - * Programmer: Robb Matzke + * Programmer: Robb Matzke * Monday, January 4, 1999 *------------------------------------------------------------------------- */ @@ -2815,15 +2815,15 @@ herr_t H5T__conv_enum(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *_buf, void H5_ATTR_UNUSED *bkg) { - uint8_t * buf = (uint8_t *)_buf; /*cast for pointer arithmetic */ - H5T_t * src = NULL, *dst = NULL; /*src and dst datatypes */ - uint8_t * s = NULL, *d = NULL; /*src and dst BUF pointers */ - ssize_t src_delta, dst_delta; /*conversion strides */ - int n; /*src value cast as native int */ + uint8_t * buf = (uint8_t *)_buf; /*cast for pointer arithmetic */ + H5T_t * src = NULL, *dst = NULL; /*src and dst datatypes */ + uint8_t * s = NULL, *d = NULL; /*src and dst BUF pointers */ + ssize_t src_delta, dst_delta; /*conversion strides */ + int n; /*src value cast as native int */ H5T_enum_struct_t *priv = (H5T_enum_struct_t *)(cdata->priv); H5T_conv_cb_t cb_struct; /*conversion callback structure */ H5T_conv_ret_t except_ret; /*return of callback function */ - size_t i; /*counters */ + size_t i; /*counters */ herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_PACKAGE @@ -2843,7 +2843,7 @@ H5T__conv_enum(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, si if (H5T_ENUM != dst->shared->type) HGOTO_ERROR(H5E_DATATYPE, H5E_BADTYPE, FAIL, "not a H5T_ENUM datatype") - if (H5T_conv_enum_init(src, dst, cdata) < 0) + if (H5T__conv_enum_init(src, dst, cdata) < 0) HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to initialize private data") break; @@ -2871,7 +2871,7 @@ H5T__conv_enum(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, si HGOTO_ERROR(H5E_DATATYPE, H5E_BADTYPE, FAIL, "not a H5T_ENUM datatype") /* priv->src2dst map was computed for certain sort keys. Make sure those same - * sort keys are used here during conversion. See H5T_conv_enum_init(). But + * sort keys are used here during conversion. See H5T__conv_enum_init(). But * we actually don't care about the source type's order when doing the O(1) * conversion algorithm, which is turned on by non-zero priv->length */ H5T__sort_name(dst, NULL); @@ -2910,7 +2910,7 @@ H5T__conv_enum(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, si /* (The casting won't work when the byte orders are different. i.g. if the source value * is big-endian 0x0000000f, the direct casting "n = *((int*)s);" will make it a big * number 0x0f000000 on little-endian machine. But we won't fix it because it's an - * optimization code. Please also see the comment in the H5T_conv_enum_init() function. + * optimization code. Please also see the comment in the H5T__conv_enum_init() function. * SLU - 2011/5/24) */ if (1 == src->shared->size) @@ -2993,18 +2993,18 @@ done: } /* end H5T__conv_enum() */ /*------------------------------------------------------------------------- - * Function: H5T__conv_enum_numeric + * Function: H5T__conv_enum_numeric * - * Purpose: Converts enumerated data to a numeric type (integer or + * Purpose: Converts enumerated data to a numeric type (integer or * floating-point number). This function is registered into * the conversion table twice in H5T_init_interface in H5T.c. * Once for enum-integer conversion. Once for enum-float conversion. * - * Return: Success: Non-negative + * Return: Success: Non-negative * - * Failure: negative + * Failure: negative * - * Programmer: Raymond Lu + * Programmer: Raymond Lu * 12 October 2012 *------------------------------------------------------------------------- */ @@ -3013,7 +3013,7 @@ H5T__conv_enum_numeric(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t ne size_t H5_ATTR_UNUSED buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *_buf, void H5_ATTR_UNUSED *bkg) { - H5T_t * src, *dst; /*src and dst datatypes */ + H5T_t * src, *dst; /*src and dst datatypes */ H5T_t * src_parent; /*parent type for src */ hid_t src_parent_id = -1; /*ID for parent of the source */ H5T_path_t *tpath; /* Conversion information */ @@ -3076,26 +3076,26 @@ done: } /* end H5T__conv_enum_numeric() */ /*------------------------------------------------------------------------- - * Function: H5T__conv_vlen + * Function: H5T__conv_vlen * - * Purpose: Converts between VL datatypes in memory and on disk. - * This is a soft conversion function. The algorithm is - * basically: + * Purpose: Converts between VL datatypes in memory and on disk. + * This is a soft conversion function. The algorithm is + * basically: * - * For every VL struct in the main buffer: - * 1. Allocate space for temporary dst VL data (reuse buffer - * if possible) + * For every VL struct in the main buffer: + * 1. Allocate space for temporary dst VL data (reuse buffer + * if possible) * 2. Copy VL data from src buffer into dst buffer * 3. Convert VL data into dst representation * 4. Allocate buffer in dst heap - * 5. Free heap objects storing old data + * 5. Free heap objects storing old data * 6. Write dst VL data into dst heap * 7. Store (heap ID or pointer) and length in main dst buffer * - * Return: Non-negative on success/Negative on failure + * Return: Non-negative on success/Negative on failure * - * Programmer: Quincey Koziol - * Wednesday, May 26, 1999 + * Programmer: Quincey Koziol + * Wednesday, May 26, 1999 * *------------------------------------------------------------------------- */ @@ -3104,27 +3104,27 @@ H5T__conv_vlen(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, si size_t bkg_stride, void *buf, void *bkg) { H5T_vlen_alloc_info_t vl_alloc_info; /* VL allocation info */ - H5T_path_t * tpath = NULL; /* Type conversion path */ + H5T_path_t * tpath = NULL; /* Type conversion path */ hbool_t noop_conv = FALSE; /* Flag to indicate a noop conversion */ hbool_t write_to_file = FALSE; /* Flag to indicate writing to file */ htri_t parent_is_vlen; /* Flag to indicate parent is vlen datatyp */ size_t bg_seq_len = 0; /* The number of elements in the background sequence */ - hid_t tsrc_id = -1, tdst_id = -1; /*temporary type atoms */ - H5T_t * src = NULL; /*source datatype */ - H5T_t * dst = NULL; /*destination datatype */ - uint8_t * s = NULL; /*source buffer */ - uint8_t * d = NULL; /*destination buffer */ - uint8_t * b = NULL; /*background buffer */ - ssize_t s_stride, d_stride; /*src and dst strides */ - ssize_t b_stride; /*bkg stride */ + hid_t tsrc_id = -1, tdst_id = -1; /*temporary type atoms */ + H5T_t * src = NULL; /*source datatype */ + H5T_t * dst = NULL; /*destination datatype */ + uint8_t * s = NULL; /*source buffer */ + uint8_t * d = NULL; /*destination buffer */ + uint8_t * b = NULL; /*background buffer */ + ssize_t s_stride, d_stride; /*src and dst strides */ + ssize_t b_stride; /*bkg stride */ size_t safe; /*how many elements are safe to process in each pass */ size_t src_base_size, dst_base_size; /*source & destination base size*/ - void * conv_buf = NULL; /*temporary conversion buffer */ + void * conv_buf = NULL; /*temporary conversion buffer */ size_t conv_buf_size = 0; /*size of conversion buffer in bytes */ - void * tmp_buf = NULL; /*temporary background buffer */ - size_t tmp_buf_size = 0; /*size of temporary bkg buffer */ + void * tmp_buf = NULL; /*temporary background buffer */ + size_t tmp_buf_size = 0; /*size of temporary bkg buffer */ hbool_t nested = FALSE; /*flag of nested VL case */ - size_t elmtno; /*element number counter */ + size_t elmtno; /*element number counter */ herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_PACKAGE @@ -3459,15 +3459,15 @@ done: } /* end H5T__conv_vlen() */ /*------------------------------------------------------------------------- - * Function: H5T__conv_array + * Function: H5T__conv_array * - * Purpose: Converts between array datatypes in memory and on disk. - * This is a soft conversion function. + * Purpose: Converts between array datatypes in memory and on disk. + * This is a soft conversion function. * - * Return: Non-negative on success/Negative on failure + * Return: Non-negative on success/Negative on failure * - * Programmer: Quincey Koziol - * Monday, November 6, 2000 + * Programmer: Quincey Koziol + * Monday, November 6, 2000 * *------------------------------------------------------------------------- */ @@ -3475,16 +3475,16 @@ herr_t H5T__conv_array(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, size_t buf_stride, size_t bkg_stride, void *_buf, void H5_ATTR_UNUSED *_bkg) { - H5T_path_t *tpath; /* Type conversion path */ - hid_t tsrc_id = -1, tdst_id = -1; /*temporary type atoms */ - H5T_t * src = NULL; /*source datatype */ - H5T_t * dst = NULL; /*destination datatype */ + H5T_path_t *tpath; /* Type conversion path */ + hid_t tsrc_id = -1, tdst_id = -1; /*temporary type atoms */ + H5T_t * src = NULL; /*source datatype */ + H5T_t * dst = NULL; /*destination datatype */ uint8_t * sp, *dp; /*source and dest traversal ptrs */ - ssize_t src_delta, dst_delta; /*source & destination stride */ - int direction; /*direction of traversal */ - size_t elmtno; /*element number counter */ + ssize_t src_delta, dst_delta; /*source & destination stride */ + int direction; /*direction of traversal */ + size_t elmtno; /*element number counter */ unsigned u; /* local index variable */ - void * bkg_buf = NULL; /*temporary background buffer */ + void * bkg_buf = NULL; /*temporary background buffer */ herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_PACKAGE @@ -3760,7 +3760,7 @@ H5T__conv_ref(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, siz if (0 == (buf_size = src->shared->u.atomic.u.r.cls->getsize( src->shared->u.atomic.u.r.file, s, src->shared->size, dst->shared->u.atomic.u.r.file, &dst_copy))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "incorrect size") + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "unable to obtain size of reference") /* Check if conversion buffer is large enough, resize if necessary. */ if (conv_buf_size < buf_size) { @@ -3818,16 +3818,16 @@ done: } /* end H5T__conv_ref() */ /*------------------------------------------------------------------------- - * Function: H5T__conv_i_i + * Function: H5T__conv_i_i * - * Purpose: Convert one integer type to another. This is the catch-all - * function for integer conversions and is probably not - * particularly fast. + * Purpose: Convert one integer type to another. This is the catch-all + * function for integer conversions and is probably not + * particularly fast. * - * Return: Non-negative on success/Negative on failure + * Return: Non-negative on success/Negative on failure * - * Programmer: Robb Matzke - * Wednesday, June 10, 1998 + * Programmer: Robb Matzke + * Wednesday, June 10, 1998 * *------------------------------------------------------------------------- */ @@ -3835,18 +3835,18 @@ herr_t H5T__conv_i_i(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, void H5_ATTR_UNUSED *bkg) { - H5T_t * src = NULL; /*source datatype */ - H5T_t * dst = NULL; /*destination datatype */ - ssize_t src_delta, dst_delta; /*source & destination stride */ - int direction; /*direction of traversal */ - size_t elmtno; /*element number */ - size_t half_size; /*half the type size */ - size_t olap; /*num overlapping elements */ + H5T_t * src = NULL; /*source datatype */ + H5T_t * dst = NULL; /*destination datatype */ + ssize_t src_delta, dst_delta; /*source & destination stride */ + int direction; /*direction of traversal */ + size_t elmtno; /*element number */ + size_t half_size; /*half the type size */ + size_t olap; /*num overlapping elements */ uint8_t * s, *sp, *d, *dp; /*source and dest traversal ptrs*/ - uint8_t * src_rev = NULL; /*order-reversed source buffer */ - uint8_t dbuf[64]; /*temp destination buffer */ + uint8_t * src_rev = NULL; /*order-reversed source buffer */ + uint8_t dbuf[64] = {0}; /*temp destination buffer */ size_t first; - ssize_t sfirst; /*a signed version of `first' */ + ssize_t sfirst; /*a signed version of `first' */ size_t i; /*Local index variables */ H5T_conv_cb_t cb_struct = {NULL, NULL}; /*conversion callback structure */ H5T_conv_ret_t except_ret; /*return of callback function */ @@ -3996,8 +3996,8 @@ H5T__conv_i_i(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, siz else if (first >= dst->shared->u.atomic.prec) { /*overflow*/ if (cb_struct.func) { /*If user's exception handler is present, use it*/ - H5T_reverse_order(src_rev, s, src->shared->size, - src->shared->u.atomic.order); /*reverse order first*/ + H5T__reverse_order(src_rev, s, src->shared->size, + src->shared->u.atomic.order); /*reverse order first*/ except_ret = (cb_struct.func)(H5T_CONV_EXCEPT_RANGE_HI, src_id, dst_id, src_rev, d, cb_struct.user_data); } @@ -4029,8 +4029,8 @@ H5T__conv_i_i(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, siz if (first + 1 == src->shared->u.atomic.prec) { /*overflow - source is negative*/ if (cb_struct.func) { /*If user's exception handler is present, use it*/ - H5T_reverse_order(src_rev, s, src->shared->size, - src->shared->u.atomic.order); /*reverse order first*/ + H5T__reverse_order(src_rev, s, src->shared->size, + src->shared->u.atomic.order); /*reverse order first*/ except_ret = (cb_struct.func)(H5T_CONV_EXCEPT_RANGE_LOW, src_id, dst_id, src_rev, d, cb_struct.user_data); } @@ -4054,8 +4054,8 @@ H5T__conv_i_i(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, siz else if (first >= dst->shared->u.atomic.prec) { /*overflow - source is positive*/ if (cb_struct.func) { /*If user's exception handler is present, use it*/ - H5T_reverse_order(src_rev, s, src->shared->size, - src->shared->u.atomic.order); /*reverse order first*/ + H5T__reverse_order(src_rev, s, src->shared->size, + src->shared->u.atomic.order); /*reverse order first*/ except_ret = (cb_struct.func)(H5T_CONV_EXCEPT_RANGE_HI, src_id, dst_id, src_rev, d, cb_struct.user_data); } @@ -4084,8 +4084,8 @@ H5T__conv_i_i(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, siz if (first + 1 >= dst->shared->u.atomic.prec) { /*overflow*/ if (cb_struct.func) { /*If user's exception handler is present, use it*/ - H5T_reverse_order(src_rev, s, src->shared->size, - src->shared->u.atomic.order); /*reverse order first*/ + H5T__reverse_order(src_rev, s, src->shared->size, + src->shared->u.atomic.order); /*reverse order first*/ except_ret = (cb_struct.func)(H5T_CONV_EXCEPT_RANGE_HI, src_id, dst_id, src_rev, d, cb_struct.user_data); } @@ -4129,8 +4129,8 @@ H5T__conv_i_i(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, siz if (sfz >= 0 && fz + 1 >= dst->shared->u.atomic.prec) { /*overflow*/ if (cb_struct.func) { /*If user's exception handler is present, use it*/ - H5T_reverse_order(src_rev, s, src->shared->size, - src->shared->u.atomic.order); /*reverse order first*/ + H5T__reverse_order(src_rev, s, src->shared->size, + src->shared->u.atomic.order); /*reverse order first*/ except_ret = (cb_struct.func)(H5T_CONV_EXCEPT_RANGE_LOW, src_id, dst_id, src_rev, d, cb_struct.user_data); } @@ -4169,8 +4169,8 @@ H5T__conv_i_i(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, siz if (first + 1 >= dst->shared->u.atomic.prec) { /*overflow*/ if (cb_struct.func) { /*If user's exception handler is present, use it*/ - H5T_reverse_order(src_rev, s, src->shared->size, - src->shared->u.atomic.order); /*reverse order first*/ + H5T__reverse_order(src_rev, s, src->shared->size, + src->shared->u.atomic.order); /*reverse order first*/ except_ret = (cb_struct.func)(H5T_CONV_EXCEPT_RANGE_HI, src_id, dst_id, src_rev, d, cb_struct.user_data); } @@ -4256,16 +4256,16 @@ done: } /* end H5T__conv_i_i() */ /*------------------------------------------------------------------------- - * Function: H5T__conv_f_f + * Function: H5T__conv_f_f * - * Purpose: Convert one floating point type to another. This is a catch - * all for floating point conversions and is probably not - * particularly fast! + * Purpose: Convert one floating point type to another. This is a catch + * all for floating point conversions and is probably not + * particularly fast! * - * Return: Non-negative on success/Negative on failure + * Return: Non-negative on success/Negative on failure * - * Programmer: Robb Matzke - * Tuesday, June 23, 1998 + * Programmer: Robb Matzke + * Tuesday, June 23, 1998 * *------------------------------------------------------------------------- */ @@ -4274,32 +4274,32 @@ H5T__conv_f_f(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, siz size_t H5_ATTR_UNUSED bkg_stride, void *buf, void H5_ATTR_UNUSED *bkg) { /* Traversal-related variables */ - H5T_t * src_p; /*source datatype */ - H5T_t * dst_p; /*destination datatype */ - H5T_atomic_t src; /*atomic source info */ - H5T_atomic_t dst; /*atomic destination info */ - ssize_t src_delta, dst_delta; /*source & destination stride */ - int direction; /*forward or backward traversal */ - size_t elmtno; /*element number */ - size_t half_size; /*half the type size */ + H5T_t * src_p; /*source datatype */ + H5T_t * dst_p; /*destination datatype */ + H5T_atomic_t src; /*atomic source info */ + H5T_atomic_t dst; /*atomic destination info */ + ssize_t src_delta, dst_delta; /*source & destination stride */ + int direction; /*forward or backward traversal */ + size_t elmtno; /*element number */ + size_t half_size; /*half the type size */ size_t tsize; /*type size for swapping bytes */ - size_t olap; /*num overlapping elements */ - ssize_t bitno = 0; /*bit number */ + size_t olap; /*num overlapping elements */ + ssize_t bitno = 0; /*bit number */ uint8_t * s, *sp, *d, *dp; /*source and dest traversal ptrs*/ - uint8_t * src_rev = NULL; /*order-reversed source buffer */ - uint8_t dbuf[64]; /*temp destination buffer */ + uint8_t * src_rev = NULL; /*order-reversed source buffer */ + uint8_t dbuf[64] = {0}; /*temp destination buffer */ uint8_t tmp1, tmp2; /*temp variables for swapping bytes*/ /* Conversion-related variables */ - int64_t expo; /*exponent */ - hssize_t expo_max; /*maximum possible dst exponent */ + int64_t expo; /*exponent */ + hssize_t expo_max; /*maximum possible dst exponent */ size_t msize = 0; /*useful size of mantissa in src*/ - size_t mpos; /*offset to useful mant is src */ + size_t mpos; /*offset to useful mant is src */ uint64_t sign; /*source sign bit value */ size_t mrsh; /*amount to right shift mantissa*/ - hbool_t carry = FALSE; /*carry after rounding mantissa */ - size_t i; /*miscellaneous counters */ - size_t implied; /*destination implied bits */ + hbool_t carry = FALSE; /*carry after rounding mantissa */ + size_t i; /*miscellaneous counters */ + size_t implied; /*destination implied bits */ hbool_t denormalized = FALSE; /*is either source or destination denormalized?*/ H5T_conv_cb_t cb_struct = {NULL, NULL}; /*conversion callback structure */ H5T_conv_ret_t except_ret; /*return of callback function */ @@ -4459,7 +4459,8 @@ H5T__conv_f_f(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, siz /* +Inf or -Inf */ if (cb_struct.func) { /*If user's exception handler is present, use it*/ /*reverse order first*/ - H5T_reverse_order(src_rev, s, src_p->shared->size, src_p->shared->u.atomic.order); + H5T__reverse_order(src_rev, s, src_p->shared->size, + src_p->shared->u.atomic.order); if (sign) except_ret = (cb_struct.func)(H5T_CONV_EXCEPT_NINF, src_id, dst_id, src_rev, d, cb_struct.user_data); @@ -4499,7 +4500,7 @@ H5T__conv_f_f(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, siz /* +Inf or -Inf */ if (cb_struct.func) { /*If user's exception handler is present, use it*/ /*reverse order first*/ - H5T_reverse_order(src_rev, s, src_p->shared->size, src_p->shared->u.atomic.order); + H5T__reverse_order(src_rev, s, src_p->shared->size, src_p->shared->u.atomic.order); if (sign) except_ret = (cb_struct.func)(H5T_CONV_EXCEPT_NINF, src_id, dst_id, src_rev, d, cb_struct.user_data); @@ -4537,7 +4538,7 @@ H5T__conv_f_f(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, siz /* NaN */ if (cb_struct.func) { /*If user's exception handler is present, use it*/ /*reverse order first*/ - H5T_reverse_order(src_rev, s, src_p->shared->size, src_p->shared->u.atomic.order); + H5T__reverse_order(src_rev, s, src_p->shared->size, src_p->shared->u.atomic.order); except_ret = (cb_struct.func)(H5T_CONV_EXCEPT_NAN, src_id, dst_id, src_rev, d, cb_struct.user_data); } @@ -4562,7 +4563,7 @@ H5T__conv_f_f(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, siz /* * Get the exponent as an unsigned quantity from the section of - * the source bit field where it's located. Don't worry about + * the source bit field where it's located. Don't worry about * the exponent bias yet. */ expo = (int64_t)H5T__bit_get_d(s, src.u.f.epos, src.u.f.esize); @@ -4650,7 +4651,7 @@ H5T__conv_f_f(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, siz else if (expo >= expo_max) { /* * The exponent is too large to fit in the available region - * or it results in the maximum possible value. Use positive + * or it results in the maximum possible value. Use positive * or negative infinity instead unless the application * specifies something else. Before calling the overflow * handler make sure the source buffer we hand it is in the @@ -4658,7 +4659,7 @@ H5T__conv_f_f(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, siz */ if (cb_struct.func) { /*If user's exception handler is present, use it*/ /*reverse order first*/ - H5T_reverse_order(src_rev, s, src_p->shared->size, src_p->shared->u.atomic.order); + H5T__reverse_order(src_rev, s, src_p->shared->size, src_p->shared->u.atomic.order); except_ret = (cb_struct.func)(H5T_CONV_EXCEPT_RANGE_HI, src_id, dst_id, src_rev, d, cb_struct.user_data); } @@ -4748,7 +4749,8 @@ H5T__conv_f_f(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, siz */ if (cb_struct.func) { /*If user's exception handler is present, use it*/ /*reverse order first*/ - H5T_reverse_order(src_rev, s, src_p->shared->size, src_p->shared->u.atomic.order); + H5T__reverse_order(src_rev, s, src_p->shared->size, + src_p->shared->u.atomic.order); except_ret = (cb_struct.func)(H5T_CONV_EXCEPT_RANGE_HI, src_id, dst_id, src_rev, d, cb_struct.user_data); } @@ -4842,14 +4844,14 @@ done: } /* end H5T__conv_f_f() */ /*------------------------------------------------------------------------- - * Function: H5T__conv_s_s + * Function: H5T__conv_s_s * - * Purpose: Convert one fixed-length string type to another. + * Purpose: Convert one fixed-length string type to another. * - * Return: Non-negative on success/Negative on failure + * Return: Non-negative on success/Negative on failure * - * Programmer: Robb Matzke - * Friday, August 7, 1998 + * Programmer: Robb Matzke + * Friday, August 7, 1998 * *------------------------------------------------------------------------- */ @@ -4857,15 +4859,15 @@ herr_t H5T__conv_s_s(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, void H5_ATTR_UNUSED *bkg) { - H5T_t * src = NULL; /*source datatype */ - H5T_t * dst = NULL; /*destination datatype */ - ssize_t src_delta, dst_delta; /*source & destination stride */ - int direction; /*direction of traversal */ - size_t elmtno; /*element number */ - size_t olap; /*num overlapping elements */ - size_t nchars = 0; /*number of characters copied */ + H5T_t * src = NULL; /*source datatype */ + H5T_t * dst = NULL; /*destination datatype */ + ssize_t src_delta, dst_delta; /*source & destination stride */ + int direction; /*direction of traversal */ + size_t elmtno; /*element number */ + size_t olap; /*num overlapping elements */ + size_t nchars = 0; /*number of characters copied */ uint8_t *s, *sp, *d, *dp; /*src and dst traversal pointers*/ - uint8_t *dbuf = NULL; /*temp buf for overlap convers. */ + uint8_t *dbuf = NULL; /*temp buf for overlap convers. */ herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_PACKAGE @@ -4945,7 +4947,7 @@ H5T__conv_s_s(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, siz dst_delta = (ssize_t)direction * (ssize_t)(buf_stride ? buf_stride : dst->shared->size); /* Allocate the overlap buffer */ - if (NULL == (dbuf = (uint8_t *)H5MM_malloc(dst->shared->size))) + if (NULL == (dbuf = (uint8_t *)H5MM_calloc(dst->shared->size))) HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed for string conversion") /* The conversion loop. */ @@ -5085,16 +5087,16 @@ done: } /* end H5T__conv_s_s() */ /*------------------------------------------------------------------------- - * Function: H5T__conv_schar_uchar + * Function: H5T__conv_schar_uchar * - * Purpose: Converts `signed char' to `unsigned char' + * Purpose: Converts `signed char' to `unsigned char' * - * Return: Success: non-negative + * Return: Success: non-negative * - * Failure: negative + * Failure: negative * - * Programmer: Robb Matzke - * Monday, November 16, 1998 + * Programmer: Robb Matzke + * Monday, November 16, 1998 * *------------------------------------------------------------------------- */ @@ -5106,16 +5108,16 @@ H5T__conv_schar_uchar(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nel } /*------------------------------------------------------------------------- - * Function: H5T__conv_uchar_schar + * Function: H5T__conv_uchar_schar * - * Purpose: Converts `unsigned char' to `signed char' + * Purpose: Converts `unsigned char' to `signed char' * - * Return: Success: non-negative + * Return: Success: non-negative * - * Failure: negative + * Failure: negative * - * Programmer: Robb Matzke - * Monday, November 16, 1998 + * Programmer: Robb Matzke + * Monday, November 16, 1998 * *------------------------------------------------------------------------- */ @@ -5127,16 +5129,16 @@ H5T__conv_uchar_schar(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nel } /*------------------------------------------------------------------------- - * Function: H5T__conv_schar_short + * Function: H5T__conv_schar_short * - * Purpose: Converts `signed char' to `short' + * Purpose: Converts `signed char' to `short' * - * Return: Success: Non-negative + * Return: Success: Non-negative * - * Failure: Negative + * Failure: Negative * - * Programmer: Robb Matzke - * Friday, November 13, 1998 + * Programmer: Robb Matzke + * Friday, November 13, 1998 * *------------------------------------------------------------------------- */ @@ -5148,16 +5150,16 @@ H5T__conv_schar_short(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nel } /*------------------------------------------------------------------------- - * Function: H5T__conv_schar_ushort + * Function: H5T__conv_schar_ushort * - * Purpose: Converts `signed char' to `unsigned short' + * Purpose: Converts `signed char' to `unsigned short' * - * Return: Success: Non-negative + * Return: Success: Non-negative * - * Failure: Negative + * Failure: Negative * - * Programmer: Robb Matzke - * Friday, November 13, 1998 + * Programmer: Robb Matzke + * Friday, November 13, 1998 * *------------------------------------------------------------------------- */ @@ -5169,16 +5171,16 @@ H5T__conv_schar_ushort(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t ne } /*------------------------------------------------------------------------- - * Function: H5T__conv_uchar_short + * Function: H5T__conv_uchar_short * - * Purpose: Converts `unsigned char' to `short' + * Purpose: Converts `unsigned char' to `short' * - * Return: Success: non-negative + * Return: Success: non-negative * - * Failure: negative + * Failure: negative * - * Programmer: Robb Matzke - * Friday, November 13, 1998 + * Programmer: Robb Matzke + * Friday, November 13, 1998 * *------------------------------------------------------------------------- */ @@ -5190,16 +5192,16 @@ H5T__conv_uchar_short(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nel } /*------------------------------------------------------------------------- - * Function: H5T__conv_uchar_ushort + * Function: H5T__conv_uchar_ushort * - * Purpose: Converts `unsigned char' to `unsigned short' + * Purpose: Converts `unsigned char' to `unsigned short' * - * Return: Success: non-negative + * Return: Success: non-negative * - * Failure: negative + * Failure: negative * - * Programmer: Robb Matzke - * Friday, November 13, 1998 + * Programmer: Robb Matzke + * Friday, November 13, 1998 * *------------------------------------------------------------------------- */ @@ -5211,16 +5213,16 @@ H5T__conv_uchar_ushort(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t ne } /*------------------------------------------------------------------------- - * Function: H5T__conv_schar_int + * Function: H5T__conv_schar_int * - * Purpose: Converts `signed char' to `int' + * Purpose: Converts `signed char' to `int' * - * Return: Success: Non-negative + * Return: Success: Non-negative * - * Failure: Negative + * Failure: Negative * - * Programmer: Robb Matzke - * Friday, November 13, 1998 + * Programmer: Robb Matzke + * Friday, November 13, 1998 * *------------------------------------------------------------------------- */ @@ -5232,16 +5234,16 @@ H5T__conv_schar_int(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmt } /*------------------------------------------------------------------------- - * Function: H5T__conv_schar_uint + * Function: H5T__conv_schar_uint * - * Purpose: Converts `signed char' to `unsigned int' + * Purpose: Converts `signed char' to `unsigned int' * - * Return: Success: Non-negative + * Return: Success: Non-negative * - * Failure: Negative + * Failure: Negative * - * Programmer: Robb Matzke - * Friday, November 13, 1998 + * Programmer: Robb Matzke + * Friday, November 13, 1998 * *------------------------------------------------------------------------- */ @@ -5253,16 +5255,16 @@ H5T__conv_schar_uint(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelm } /*------------------------------------------------------------------------- - * Function: H5T__conv_uchar_int + * Function: H5T__conv_uchar_int * - * Purpose: Converts `unsigned char' to `int' + * Purpose: Converts `unsigned char' to `int' * - * Return: Success: Non-negative + * Return: Success: Non-negative * - * Failure: Negative + * Failure: Negative * - * Programmer: Robb Matzke - * Friday, November 13, 1998 + * Programmer: Robb Matzke + * Friday, November 13, 1998 * *------------------------------------------------------------------------- */ @@ -5274,16 +5276,16 @@ H5T__conv_uchar_int(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmt } /*------------------------------------------------------------------------- - * Function: H5T__conv_uchar_uint + * Function: H5T__conv_uchar_uint * - * Purpose: Converts `unsigned char' to `unsigned int' + * Purpose: Converts `unsigned char' to `unsigned int' * - * Return: Success: Non-negative + * Return: Success: Non-negative * - * Failure: Negative + * Failure: Negative * - * Programmer: Robb Matzke - * Friday, November 13, 1998 + * Programmer: Robb Matzke + * Friday, November 13, 1998 * *------------------------------------------------------------------------- */ @@ -5295,16 +5297,16 @@ H5T__conv_uchar_uint(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelm } /*------------------------------------------------------------------------- - * Function: H5T__conv_schar_long + * Function: H5T__conv_schar_long * - * Purpose: Converts `signed char' to `long' + * Purpose: Converts `signed char' to `long' * - * Return: Success: Non-negative + * Return: Success: Non-negative * - * Failure: Negative + * Failure: Negative * - * Programmer: Robb Matzke - * Friday, November 13, 1998 + * Programmer: Robb Matzke + * Friday, November 13, 1998 * *------------------------------------------------------------------------- */ @@ -5316,16 +5318,16 @@ H5T__conv_schar_long(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelm } /*------------------------------------------------------------------------- - * Function: H5T__conv_schar_ulong + * Function: H5T__conv_schar_ulong * - * Purpose: Converts `signed char' to `unsigned long' + * Purpose: Converts `signed char' to `unsigned long' * - * Return: Success: Non-negative + * Return: Success: Non-negative * - * Failure: Negative + * Failure: Negative * - * Programmer: Robb Matzke - * Friday, November 13, 1998 + * Programmer: Robb Matzke + * Friday, November 13, 1998 * *------------------------------------------------------------------------- */ @@ -5337,16 +5339,16 @@ H5T__conv_schar_ulong(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nel } /*------------------------------------------------------------------------- - * Function: H5T__conv_uchar_long + * Function: H5T__conv_uchar_long * - * Purpose: Converts `unsigned char' to `long' + * Purpose: Converts `unsigned char' to `long' * - * Return: Success: Non-negative + * Return: Success: Non-negative * - * Failure: Negative + * Failure: Negative * - * Programmer: Robb Matzke - * Friday, November 13, 1998 + * Programmer: Robb Matzke + * Friday, November 13, 1998 * *------------------------------------------------------------------------- */ @@ -5358,16 +5360,16 @@ H5T__conv_uchar_long(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelm } /*------------------------------------------------------------------------- - * Function: H5T__conv_uchar_ulong + * Function: H5T__conv_uchar_ulong * - * Purpose: Converts `unsigned char' to `unsigned long' + * Purpose: Converts `unsigned char' to `unsigned long' * - * Return: Success: Non-negative + * Return: Success: Non-negative * - * Failure: Negative + * Failure: Negative * - * Programmer: Robb Matzke - * Friday, November 13, 1998 + * Programmer: Robb Matzke + * Friday, November 13, 1998 * *------------------------------------------------------------------------- */ @@ -5379,16 +5381,16 @@ H5T__conv_uchar_ulong(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nel } /*------------------------------------------------------------------------- - * Function: H5T__conv_schar_llong + * Function: H5T__conv_schar_llong * - * Purpose: Converts `signed char' to `long long' + * Purpose: Converts `signed char' to `long long' * - * Return: Success: Non-negative + * Return: Success: Non-negative * - * Failure: Negative + * Failure: Negative * - * Programmer: Robb Matzke - * Friday, November 13, 1998 + * Programmer: Robb Matzke + * Friday, November 13, 1998 * *------------------------------------------------------------------------- */ @@ -5400,16 +5402,16 @@ H5T__conv_schar_llong(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nel } /*------------------------------------------------------------------------- - * Function: H5T__conv_schar_ullong + * Function: H5T__conv_schar_ullong * - * Purpose: Converts `signed char' to `unsigned long long' + * Purpose: Converts `signed char' to `unsigned long long' * - * Return: Success: Non-negative + * Return: Success: Non-negative * - * Failure: Negative + * Failure: Negative * - * Programmer: Robb Matzke - * Friday, November 13, 1998 + * Programmer: Robb Matzke + * Friday, November 13, 1998 * *------------------------------------------------------------------------- */ @@ -5421,16 +5423,16 @@ H5T__conv_schar_ullong(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t ne } /*------------------------------------------------------------------------- - * Function: H5T__conv_uchar_llong + * Function: H5T__conv_uchar_llong * - * Purpose: Converts `unsigned char' to `long long' + * Purpose: Converts `unsigned char' to `long long' * - * Return: Success: Non-negative + * Return: Success: Non-negative * - * Failure: Negative + * Failure: Negative * - * Programmer: Robb Matzke - * Friday, November 13, 1998 + * Programmer: Robb Matzke + * Friday, November 13, 1998 * *------------------------------------------------------------------------- */ @@ -5442,16 +5444,16 @@ H5T__conv_uchar_llong(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nel } /*------------------------------------------------------------------------- - * Function: H5T__conv_uchar_ullong + * Function: H5T__conv_uchar_ullong * - * Purpose: Converts `unsigned char' to `unsigned long long' + * Purpose: Converts `unsigned char' to `unsigned long long' * - * Return: Success: Non-negative + * Return: Success: Non-negative * - * Failure: Negative + * Failure: Negative * - * Programmer: Robb Matzke - * Friday, November 13, 1998 + * Programmer: Robb Matzke + * Friday, November 13, 1998 * *------------------------------------------------------------------------- */ @@ -5463,16 +5465,16 @@ H5T__conv_uchar_ullong(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t ne } /*------------------------------------------------------------------------- - * Function: H5T__conv_short_schar + * Function: H5T__conv_short_schar * - * Purpose: Converts `short' to `signed char' + * Purpose: Converts `short' to `signed char' * - * Return: Success: non-negative + * Return: Success: non-negative * - * Failure: negative + * Failure: negative * - * Programmer: Robb Matzke - * Friday, November 13, 1998 + * Programmer: Robb Matzke + * Friday, November 13, 1998 * *------------------------------------------------------------------------- */ @@ -5484,16 +5486,16 @@ H5T__conv_short_schar(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nel } /*------------------------------------------------------------------------- - * Function: H5T__conv_short_uchar + * Function: H5T__conv_short_uchar * - * Purpose: Converts `short' to `unsigned char' + * Purpose: Converts `short' to `unsigned char' * - * Return: Success: non-negative + * Return: Success: non-negative * - * Failure: negative + * Failure: negative * - * Programmer: Robb Matzke - * Friday, November 13, 1998 + * Programmer: Robb Matzke + * Friday, November 13, 1998 * *------------------------------------------------------------------------- */ @@ -5505,16 +5507,16 @@ H5T__conv_short_uchar(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nel } /*------------------------------------------------------------------------- - * Function: H5T__conv_ushort_schar + * Function: H5T__conv_ushort_schar * - * Purpose: Converts `unsigned short' to `signed char' + * Purpose: Converts `unsigned short' to `signed char' * - * Return: Success: non-negative + * Return: Success: non-negative * - * Failure: negative + * Failure: negative * - * Programmer: Robb Matzke - * Friday, November 13, 1998 + * Programmer: Robb Matzke + * Friday, November 13, 1998 * *------------------------------------------------------------------------- */ @@ -5526,16 +5528,16 @@ H5T__conv_ushort_schar(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t ne } /*------------------------------------------------------------------------- - * Function: H5T__conv_ushort_uchar + * Function: H5T__conv_ushort_uchar * - * Purpose: Converts `unsigned short' to `unsigned char' + * Purpose: Converts `unsigned short' to `unsigned char' * - * Return: Success: non-negative + * Return: Success: non-negative * - * Failure: negative + * Failure: negative * - * Programmer: Robb Matzke - * Friday, November 13, 1998 + * Programmer: Robb Matzke + * Friday, November 13, 1998 * *------------------------------------------------------------------------- */ @@ -5547,16 +5549,16 @@ H5T__conv_ushort_uchar(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t ne } /*------------------------------------------------------------------------- - * Function: H5T__conv_short_ushort + * Function: H5T__conv_short_ushort * - * Purpose: Converts `short' to `unsigned short' + * Purpose: Converts `short' to `unsigned short' * - * Return: Success: non-negative + * Return: Success: non-negative * - * Failure: negative + * Failure: negative * - * Programmer: Robb Matzke - * Monday, November 16, 1998 + * Programmer: Robb Matzke + * Monday, November 16, 1998 * *------------------------------------------------------------------------- */ @@ -5568,16 +5570,16 @@ H5T__conv_short_ushort(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t ne } /*------------------------------------------------------------------------- - * Function: H5T__conv_ushort_short + * Function: H5T__conv_ushort_short * - * Purpose: Converts `unsigned short' to `short' + * Purpose: Converts `unsigned short' to `short' * - * Return: Success: non-negative + * Return: Success: non-negative * - * Failure: negative + * Failure: negative * - * Programmer: Robb Matzke - * Monday, November 16, 1998 + * Programmer: Robb Matzke + * Monday, November 16, 1998 * *------------------------------------------------------------------------- */ @@ -5589,16 +5591,16 @@ H5T__conv_ushort_short(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t ne } /*------------------------------------------------------------------------- - * Function: H5T__conv_short_int + * Function: H5T__conv_short_int * - * Purpose: Converts `short' to `int' + * Purpose: Converts `short' to `int' * - * Return: Success: non-negative + * Return: Success: non-negative * - * Failure: negative + * Failure: negative * - * Programmer: Robb Matzke - * Friday, November 13, 1998 + * Programmer: Robb Matzke + * Friday, November 13, 1998 * *------------------------------------------------------------------------- */ @@ -5610,16 +5612,16 @@ H5T__conv_short_int(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmt } /*------------------------------------------------------------------------- - * Function: H5T__conv_short_uint + * Function: H5T__conv_short_uint * - * Purpose: Converts `short' to `unsigned int' + * Purpose: Converts `short' to `unsigned int' * - * Return: Success: Non-negative + * Return: Success: Non-negative * - * Failure: Negative + * Failure: Negative * - * Programmer: Robb Matzke - * Friday, November 13, 1998 + * Programmer: Robb Matzke + * Friday, November 13, 1998 * *------------------------------------------------------------------------- */ @@ -5631,16 +5633,16 @@ H5T__conv_short_uint(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelm } /*------------------------------------------------------------------------- - * Function: H5T__conv_ushort_int + * Function: H5T__conv_ushort_int * - * Purpose: Converts `unsigned short' to `int' + * Purpose: Converts `unsigned short' to `int' * - * Return: Success: Non-negative + * Return: Success: Non-negative * - * Failure: Negative + * Failure: Negative * - * Programmer: Robb Matzke - * Friday, November 13, 1998 + * Programmer: Robb Matzke + * Friday, November 13, 1998 * *------------------------------------------------------------------------- */ @@ -5652,16 +5654,16 @@ H5T__conv_ushort_int(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelm } /*------------------------------------------------------------------------- - * Function: H5T__conv_ushort_uint + * Function: H5T__conv_ushort_uint * - * Purpose: Converts `unsigned short' to `unsigned int' + * Purpose: Converts `unsigned short' to `unsigned int' * - * Return: Success: non-negative + * Return: Success: non-negative * - * Failure: negative + * Failure: negative * - * Programmer: Robb Matzke - * Friday, November 13, 1998 + * Programmer: Robb Matzke + * Friday, November 13, 1998 * *------------------------------------------------------------------------- */ @@ -5673,16 +5675,16 @@ H5T__conv_ushort_uint(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nel } /*------------------------------------------------------------------------- - * Function: H5T__conv_short_long + * Function: H5T__conv_short_long * - * Purpose: Converts `short' to `long' + * Purpose: Converts `short' to `long' * - * Return: Success: non-negative + * Return: Success: non-negative * - * Failure: negative + * Failure: negative * - * Programmer: Robb Matzke - * Friday, November 13, 1998 + * Programmer: Robb Matzke + * Friday, November 13, 1998 * *------------------------------------------------------------------------- */ @@ -5694,16 +5696,16 @@ H5T__conv_short_long(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelm } /*------------------------------------------------------------------------- - * Function: H5T__conv_short_ulong + * Function: H5T__conv_short_ulong * - * Purpose: Converts `short' to `unsigned long' + * Purpose: Converts `short' to `unsigned long' * - * Return: Success: Non-negative + * Return: Success: Non-negative * - * Failure: Negative + * Failure: Negative * - * Programmer: Robb Matzke - * Friday, November 13, 1998 + * Programmer: Robb Matzke + * Friday, November 13, 1998 * *------------------------------------------------------------------------- */ @@ -5715,16 +5717,16 @@ H5T__conv_short_ulong(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nel } /*------------------------------------------------------------------------- - * Function: H5T__conv_ushort_long + * Function: H5T__conv_ushort_long * - * Purpose: Converts `unsigned short' to `long' + * Purpose: Converts `unsigned short' to `long' * - * Return: Success: Non-negative + * Return: Success: Non-negative * - * Failure: Negative + * Failure: Negative * - * Programmer: Robb Matzke - * Friday, November 13, 1998 + * Programmer: Robb Matzke + * Friday, November 13, 1998 * *------------------------------------------------------------------------- */ @@ -5736,16 +5738,16 @@ H5T__conv_ushort_long(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nel } /*------------------------------------------------------------------------- - * Function: H5T__conv_ushort_ulong + * Function: H5T__conv_ushort_ulong * - * Purpose: Converts `unsigned short' to `unsigned long' + * Purpose: Converts `unsigned short' to `unsigned long' * - * Return: Success: non-negative + * Return: Success: non-negative * - * Failure: negative + * Failure: negative * - * Programmer: Robb Matzke - * Friday, November 13, 1998 + * Programmer: Robb Matzke + * Friday, November 13, 1998 * *------------------------------------------------------------------------- */ @@ -5757,16 +5759,16 @@ H5T__conv_ushort_ulong(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t ne } /*------------------------------------------------------------------------- - * Function: H5T__conv_short_llong + * Function: H5T__conv_short_llong * - * Purpose: Converts `short' to `long long' + * Purpose: Converts `short' to `long long' * - * Return: Success: Non-negative + * Return: Success: Non-negative * - * Failure: Negative + * Failure: Negative * - * Programmer: Robb Matzke - * Friday, November 13, 1998 + * Programmer: Robb Matzke + * Friday, November 13, 1998 * *------------------------------------------------------------------------- */ @@ -5778,16 +5780,16 @@ H5T__conv_short_llong(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nel } /*------------------------------------------------------------------------- - * Function: H5T__conv_short_ullong + * Function: H5T__conv_short_ullong * - * Purpose: Converts `short' to `unsigned long long' + * Purpose: Converts `short' to `unsigned long long' * - * Return: Success: Non-negative + * Return: Success: Non-negative * - * Failure: Negative + * Failure: Negative * - * Programmer: Robb Matzke - * Friday, November 13, 1998 + * Programmer: Robb Matzke + * Friday, November 13, 1998 * *------------------------------------------------------------------------- */ @@ -5799,16 +5801,16 @@ H5T__conv_short_ullong(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t ne } /*------------------------------------------------------------------------- - * Function: H5T__conv_ushort_llong + * Function: H5T__conv_ushort_llong * - * Purpose: Converts `unsigned short' to `long long' + * Purpose: Converts `unsigned short' to `long long' * - * Return: Success: Non-negative + * Return: Success: Non-negative * - * Failure: Negative + * Failure: Negative * - * Programmer: Robb Matzke - * Friday, November 13, 1998 + * Programmer: Robb Matzke + * Friday, November 13, 1998 * *------------------------------------------------------------------------- */ @@ -5820,16 +5822,16 @@ H5T__conv_ushort_llong(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t ne } /*------------------------------------------------------------------------- - * Function: H5T__conv_ushort_ullong + * Function: H5T__conv_ushort_ullong * - * Purpose: Converts `unsigned short' to `unsigned long long' + * Purpose: Converts `unsigned short' to `unsigned long long' * - * Return: Success: Non-negative + * Return: Success: Non-negative * - * Failure: Negative + * Failure: Negative * - * Programmer: Robb Matzke - * Friday, November 13, 1998 + * Programmer: Robb Matzke + * Friday, November 13, 1998 * *------------------------------------------------------------------------- */ @@ -5841,16 +5843,16 @@ H5T__conv_ushort_ullong(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t n } /*------------------------------------------------------------------------- - * Function: H5T__conv_int_schar + * Function: H5T__conv_int_schar * - * Purpose: Converts `int' to `signed char' + * Purpose: Converts `int' to `signed char' * - * Return: Success: non-negative + * Return: Success: non-negative * - * Failure: negative + * Failure: negative * - * Programmer: Robb Matzke - * Friday, November 13, 1998 + * Programmer: Robb Matzke + * Friday, November 13, 1998 * *------------------------------------------------------------------------- */ @@ -5862,16 +5864,16 @@ H5T__conv_int_schar(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmt } /*------------------------------------------------------------------------- - * Function: H5T__conv_int_uchar + * Function: H5T__conv_int_uchar * - * Purpose: Converts `int' to `unsigned char' + * Purpose: Converts `int' to `unsigned char' * - * Return: Success: non-negative + * Return: Success: non-negative * - * Failure: negative + * Failure: negative * - * Programmer: Robb Matzke - * Friday, November 13, 1998 + * Programmer: Robb Matzke + * Friday, November 13, 1998 * *------------------------------------------------------------------------- */ @@ -5883,16 +5885,16 @@ H5T__conv_int_uchar(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmt } /*------------------------------------------------------------------------- - * Function: H5T__conv_uint_schar + * Function: H5T__conv_uint_schar * - * Purpose: Converts `unsigned int' to `signed char' + * Purpose: Converts `unsigned int' to `signed char' * - * Return: Success: non-negative + * Return: Success: non-negative * - * Failure: negative + * Failure: negative * - * Programmer: Robb Matzke - * Friday, November 13, 1998 + * Programmer: Robb Matzke + * Friday, November 13, 1998 * *------------------------------------------------------------------------- */ @@ -5904,16 +5906,16 @@ H5T__conv_uint_schar(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelm } /*------------------------------------------------------------------------- - * Function: H5T__conv_uint_uchar + * Function: H5T__conv_uint_uchar * - * Purpose: Converts `unsigned int' to `unsigned char' + * Purpose: Converts `unsigned int' to `unsigned char' * - * Return: Success: non-negative + * Return: Success: non-negative * - * Failure: negative + * Failure: negative * - * Programmer: Robb Matzke - * Friday, November 13, 1998 + * Programmer: Robb Matzke + * Friday, November 13, 1998 * *------------------------------------------------------------------------- */ @@ -5925,16 +5927,16 @@ H5T__conv_uint_uchar(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelm } /*------------------------------------------------------------------------- - * Function: H5T__conv_int_short + * Function: H5T__conv_int_short * - * Purpose: Converts `int' to `short' + * Purpose: Converts `int' to `short' * - * Return: Success: non-negative + * Return: Success: non-negative * - * Failure: negative + * Failure: negative * - * Programmer: Robb Matzke - * Friday, November 13, 1998 + * Programmer: Robb Matzke + * Friday, November 13, 1998 * *------------------------------------------------------------------------- */ @@ -5946,16 +5948,16 @@ H5T__conv_int_short(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmt } /*------------------------------------------------------------------------- - * Function: H5T__conv_int_ushort + * Function: H5T__conv_int_ushort * - * Purpose: Converts `int' to `unsigned short' + * Purpose: Converts `int' to `unsigned short' * - * Return: Success: non-negative + * Return: Success: non-negative * - * Failure: negative + * Failure: negative * - * Programmer: Robb Matzke - * Friday, November 13, 1998 + * Programmer: Robb Matzke + * Friday, November 13, 1998 * *------------------------------------------------------------------------- */ @@ -5967,16 +5969,16 @@ H5T__conv_int_ushort(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelm } /*------------------------------------------------------------------------- - * Function: H5T__conv_uint_short + * Function: H5T__conv_uint_short * - * Purpose: Converts `unsigned int' to `short' + * Purpose: Converts `unsigned int' to `short' * - * Return: Success: non-negative + * Return: Success: non-negative * - * Failure: negative + * Failure: negative * - * Programmer: Robb Matzke - * Friday, November 13, 1998 + * Programmer: Robb Matzke + * Friday, November 13, 1998 * *------------------------------------------------------------------------- */ @@ -5988,16 +5990,16 @@ H5T__conv_uint_short(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelm } /*------------------------------------------------------------------------- - * Function: H5T__conv_uint_ushort + * Function: H5T__conv_uint_ushort * - * Purpose: Converts `unsigned int' to `unsigned short' + * Purpose: Converts `unsigned int' to `unsigned short' * - * Return: Success: non-negative + * Return: Success: non-negative * - * Failure: negative + * Failure: negative * - * Programmer: Robb Matzke - * Friday, November 13, 1998 + * Programmer: Robb Matzke + * Friday, November 13, 1998 * *------------------------------------------------------------------------- */ @@ -6009,16 +6011,16 @@ H5T__conv_uint_ushort(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nel } /*------------------------------------------------------------------------- - * Function: H5T__conv_int_uint + * Function: H5T__conv_int_uint * - * Purpose: Converts `int' to `unsigned int' + * Purpose: Converts `int' to `unsigned int' * - * Return: Success: non-negative + * Return: Success: non-negative * - * Failure: negative + * Failure: negative * - * Programmer: Robb Matzke - * Monday, November 16, 1998 + * Programmer: Robb Matzke + * Monday, November 16, 1998 * *------------------------------------------------------------------------- */ @@ -6030,16 +6032,16 @@ H5T__conv_int_uint(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts } /*------------------------------------------------------------------------- - * Function: H5T__conv_uint_int + * Function: H5T__conv_uint_int * - * Purpose: Converts `unsigned int' to `int' + * Purpose: Converts `unsigned int' to `int' * - * Return: Success: non-negative + * Return: Success: non-negative * - * Failure: negative + * Failure: negative * - * Programmer: Robb Matzke - * Monday, November 16, 1998 + * Programmer: Robb Matzke + * Monday, November 16, 1998 * *------------------------------------------------------------------------- */ @@ -6051,16 +6053,16 @@ H5T__conv_uint_int(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts } /*------------------------------------------------------------------------- - * Function: H5T__conv_int_long + * Function: H5T__conv_int_long * - * Purpose: Converts `int' to `long' + * Purpose: Converts `int' to `long' * - * Return: Success: non-negative + * Return: Success: non-negative * - * Failure: negative + * Failure: negative * - * Programmer: Robb Matzke - * Friday, November 13, 1998 + * Programmer: Robb Matzke + * Friday, November 13, 1998 * *------------------------------------------------------------------------- */ @@ -6072,16 +6074,16 @@ H5T__conv_int_long(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts } /*------------------------------------------------------------------------- - * Function: H5T__conv_int_ulong + * Function: H5T__conv_int_ulong * - * Purpose: Converts `int' to `unsigned long' + * Purpose: Converts `int' to `unsigned long' * - * Return: Success: Non-negative + * Return: Success: Non-negative * - * Failure: Negative + * Failure: Negative * - * Programmer: Robb Matzke - * Friday, November 13, 1998 + * Programmer: Robb Matzke + * Friday, November 13, 1998 * *------------------------------------------------------------------------- */ @@ -6093,16 +6095,16 @@ H5T__conv_int_ulong(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmt } /*------------------------------------------------------------------------- - * Function: H5T__conv_uint_long + * Function: H5T__conv_uint_long * - * Purpose: Converts `unsigned int' to `long' + * Purpose: Converts `unsigned int' to `long' * - * Return: Success: Non-negative + * Return: Success: Non-negative * - * Failure: Negative + * Failure: Negative * - * Programmer: Robb Matzke - * Friday, November 13, 1998 + * Programmer: Robb Matzke + * Friday, November 13, 1998 * *------------------------------------------------------------------------- */ @@ -6114,16 +6116,16 @@ H5T__conv_uint_long(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmt } /*------------------------------------------------------------------------- - * Function: H5T__conv_uint_ulong + * Function: H5T__conv_uint_ulong * - * Purpose: Converts `unsigned int' to `unsigned long' + * Purpose: Converts `unsigned int' to `unsigned long' * - * Return: Success: non-negative + * Return: Success: non-negative * - * Failure: negative + * Failure: negative * - * Programmer: Robb Matzke - * Friday, November 13, 1998 + * Programmer: Robb Matzke + * Friday, November 13, 1998 * *------------------------------------------------------------------------- */ @@ -6135,16 +6137,16 @@ H5T__conv_uint_ulong(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelm } /*------------------------------------------------------------------------- - * Function: H5T__conv_int_llong + * Function: H5T__conv_int_llong * - * Purpose: Converts `int' to `long long' + * Purpose: Converts `int' to `long long' * - * Return: Success: Non-negative + * Return: Success: Non-negative * - * Failure: Negative + * Failure: Negative * - * Programmer: Robb Matzke - * Friday, November 13, 1998 + * Programmer: Robb Matzke + * Friday, November 13, 1998 * *------------------------------------------------------------------------- */ @@ -6156,16 +6158,16 @@ H5T__conv_int_llong(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmt } /*------------------------------------------------------------------------- - * Function: H5T__conv_int_ullong + * Function: H5T__conv_int_ullong * - * Purpose: Converts `int' to `unsigned long long' + * Purpose: Converts `int' to `unsigned long long' * - * Return: Success: Non-negative + * Return: Success: Non-negative * - * Failure: Negative + * Failure: Negative * - * Programmer: Robb Matzke - * Friday, November 13, 1998 + * Programmer: Robb Matzke + * Friday, November 13, 1998 * *------------------------------------------------------------------------- */ @@ -6177,16 +6179,16 @@ H5T__conv_int_ullong(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelm } /*------------------------------------------------------------------------- - * Function: H5T__conv_uint_llong + * Function: H5T__conv_uint_llong * - * Purpose: Converts `unsigned int' to `long long' + * Purpose: Converts `unsigned int' to `long long' * - * Return: Success: Non-negative + * Return: Success: Non-negative * - * Failure: Negative + * Failure: Negative * - * Programmer: Robb Matzke - * Friday, November 13, 1998 + * Programmer: Robb Matzke + * Friday, November 13, 1998 * *------------------------------------------------------------------------- */ @@ -6198,16 +6200,16 @@ H5T__conv_uint_llong(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelm } /*------------------------------------------------------------------------- - * Function: H5T__conv_uint_ullong + * Function: H5T__conv_uint_ullong * - * Purpose: Converts `unsigned int' to `unsigned long long' + * Purpose: Converts `unsigned int' to `unsigned long long' * - * Return: Success: Non-negative + * Return: Success: Non-negative * - * Failure: Negative + * Failure: Negative * - * Programmer: Robb Matzke - * Friday, November 13, 1998 + * Programmer: Robb Matzke + * Friday, November 13, 1998 * *------------------------------------------------------------------------- */ @@ -6219,16 +6221,16 @@ H5T__conv_uint_ullong(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nel } /*------------------------------------------------------------------------- - * Function: H5T__conv_long_schar + * Function: H5T__conv_long_schar * - * Purpose: Converts `long' to `signed char' + * Purpose: Converts `long' to `signed char' * - * Return: Success: non-negative + * Return: Success: non-negative * - * Failure: negative + * Failure: negative * - * Programmer: Robb Matzke - * Friday, November 13, 1998 + * Programmer: Robb Matzke + * Friday, November 13, 1998 * *------------------------------------------------------------------------- */ @@ -6240,16 +6242,16 @@ H5T__conv_long_schar(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelm } /*------------------------------------------------------------------------- - * Function: H5T__conv_long_uchar + * Function: H5T__conv_long_uchar * - * Purpose: Converts `long' to `unsigned char' + * Purpose: Converts `long' to `unsigned char' * - * Return: Success: non-negative + * Return: Success: non-negative * - * Failure: negative + * Failure: negative * - * Programmer: Robb Matzke - * Friday, November 13, 1998 + * Programmer: Robb Matzke + * Friday, November 13, 1998 * *------------------------------------------------------------------------- */ @@ -6261,16 +6263,16 @@ H5T__conv_long_uchar(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelm } /*------------------------------------------------------------------------- - * Function: H5T__conv_ulong_schar + * Function: H5T__conv_ulong_schar * - * Purpose: Converts `unsigned long' to `signed char' + * Purpose: Converts `unsigned long' to `signed char' * - * Return: Success: non-negative + * Return: Success: non-negative * - * Failure: negative + * Failure: negative * - * Programmer: Robb Matzke - * Friday, November 13, 1998 + * Programmer: Robb Matzke + * Friday, November 13, 1998 * *------------------------------------------------------------------------- */ @@ -6282,16 +6284,16 @@ H5T__conv_ulong_schar(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nel } /*------------------------------------------------------------------------- - * Function: H5T__conv_ulong_uchar + * Function: H5T__conv_ulong_uchar * - * Purpose: Converts `unsigned long' to `unsigned char' + * Purpose: Converts `unsigned long' to `unsigned char' * - * Return: Success: non-negative + * Return: Success: non-negative * - * Failure: negative + * Failure: negative * - * Programmer: Robb Matzke - * Friday, November 13, 1998 + * Programmer: Robb Matzke + * Friday, November 13, 1998 * *------------------------------------------------------------------------- */ @@ -6303,16 +6305,16 @@ H5T__conv_ulong_uchar(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nel } /*------------------------------------------------------------------------- - * Function: H5T__conv_long_short + * Function: H5T__conv_long_short * - * Purpose: Converts `long' to `short' + * Purpose: Converts `long' to `short' * - * Return: Success: non-negative + * Return: Success: non-negative * - * Failure: negative + * Failure: negative * - * Programmer: Robb Matzke - * Friday, November 13, 1998 + * Programmer: Robb Matzke + * Friday, November 13, 1998 * *------------------------------------------------------------------------- */ @@ -6324,16 +6326,16 @@ H5T__conv_long_short(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelm } /*------------------------------------------------------------------------- - * Function: H5T__conv_long_ushort + * Function: H5T__conv_long_ushort * - * Purpose: Converts `long' to `unsigned short' + * Purpose: Converts `long' to `unsigned short' * - * Return: Success: non-negative + * Return: Success: non-negative * - * Failure: negative + * Failure: negative * - * Programmer: Robb Matzke - * Friday, November 13, 1998 + * Programmer: Robb Matzke + * Friday, November 13, 1998 * *------------------------------------------------------------------------- */ @@ -6345,16 +6347,16 @@ H5T__conv_long_ushort(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nel } /*------------------------------------------------------------------------- - * Function: H5T__conv_ulong_short + * Function: H5T__conv_ulong_short * - * Purpose: Converts `unsigned long' to `short' + * Purpose: Converts `unsigned long' to `short' * - * Return: Success: non-negative + * Return: Success: non-negative * - * Failure: negative + * Failure: negative * - * Programmer: Robb Matzke - * Friday, November 13, 1998 + * Programmer: Robb Matzke + * Friday, November 13, 1998 * *------------------------------------------------------------------------- */ @@ -6366,16 +6368,16 @@ H5T__conv_ulong_short(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nel } /*------------------------------------------------------------------------- - * Function: H5T__conv_ulong_ushort + * Function: H5T__conv_ulong_ushort * - * Purpose: Converts `unsigned long' to `unsigned short' + * Purpose: Converts `unsigned long' to `unsigned short' * - * Return: Success: non-negative + * Return: Success: non-negative * - * Failure: negative + * Failure: negative * - * Programmer: Robb Matzke - * Friday, November 13, 1998 + * Programmer: Robb Matzke + * Friday, November 13, 1998 * *------------------------------------------------------------------------- */ @@ -6387,16 +6389,16 @@ H5T__conv_ulong_ushort(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t ne } /*------------------------------------------------------------------------- - * Function: H5T__conv_long_int + * Function: H5T__conv_long_int * - * Purpose: Converts `long' to `int' + * Purpose: Converts `long' to `int' * - * Return: Success: non-negative + * Return: Success: non-negative * - * Failure: negative + * Failure: negative * - * Programmer: Robb Matzke - * Friday, November 13, 1998 + * Programmer: Robb Matzke + * Friday, November 13, 1998 * *------------------------------------------------------------------------- */ @@ -6408,16 +6410,16 @@ H5T__conv_long_int(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts } /*------------------------------------------------------------------------- - * Function: H5T__conv_long_uint + * Function: H5T__conv_long_uint * - * Purpose: Converts `long' to `unsigned int' + * Purpose: Converts `long' to `unsigned int' * - * Return: Success: non-negative + * Return: Success: non-negative * - * Failure: negative + * Failure: negative * - * Programmer: Robb Matzke - * Friday, November 13, 1998 + * Programmer: Robb Matzke + * Friday, November 13, 1998 * *------------------------------------------------------------------------- */ @@ -6429,16 +6431,16 @@ H5T__conv_long_uint(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmt } /*------------------------------------------------------------------------- - * Function: H5T__conv_ulong_int + * Function: H5T__conv_ulong_int * - * Purpose: Converts `unsigned long' to `int' + * Purpose: Converts `unsigned long' to `int' * - * Return: Success: non-negative + * Return: Success: non-negative * - * Failure: negative + * Failure: negative * - * Programmer: Robb Matzke - * Friday, November 13, 1998 + * Programmer: Robb Matzke + * Friday, November 13, 1998 * *------------------------------------------------------------------------- */ @@ -6450,16 +6452,16 @@ H5T__conv_ulong_int(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmt } /*------------------------------------------------------------------------- - * Function: H5T__conv_ulong_uint + * Function: H5T__conv_ulong_uint * - * Purpose: Converts `unsigned long' to `unsigned int' + * Purpose: Converts `unsigned long' to `unsigned int' * - * Return: Success: non-negative + * Return: Success: non-negative * - * Failure: negative + * Failure: negative * - * Programmer: Robb Matzke - * Friday, November 13, 1998 + * Programmer: Robb Matzke + * Friday, November 13, 1998 * *------------------------------------------------------------------------- */ @@ -6471,16 +6473,16 @@ H5T__conv_ulong_uint(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelm } /*------------------------------------------------------------------------- - * Function: H5T__conv_long_ulong + * Function: H5T__conv_long_ulong * - * Purpose: Converts `long' to `unsigned long' + * Purpose: Converts `long' to `unsigned long' * - * Return: Success: non-negative + * Return: Success: non-negative * - * Failure: negative + * Failure: negative * - * Programmer: Robb Matzke - * Monday, November 16, 1998 + * Programmer: Robb Matzke + * Monday, November 16, 1998 * *------------------------------------------------------------------------- */ @@ -6492,16 +6494,16 @@ H5T__conv_long_ulong(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelm } /*------------------------------------------------------------------------- - * Function: H5T__conv_ulong_long + * Function: H5T__conv_ulong_long * - * Purpose: Converts `unsigned long' to `long' + * Purpose: Converts `unsigned long' to `long' * - * Return: Success: non-negative + * Return: Success: non-negative * - * Failure: negative + * Failure: negative * - * Programmer: Robb Matzke - * Monday, November 16, 1998 + * Programmer: Robb Matzke + * Monday, November 16, 1998 * *------------------------------------------------------------------------- */ @@ -6513,16 +6515,16 @@ H5T__conv_ulong_long(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelm } /*------------------------------------------------------------------------- - * Function: H5T__conv_long_llong + * Function: H5T__conv_long_llong * - * Purpose: Converts `long' to `long long' + * Purpose: Converts `long' to `long long' * - * Return: Success: Non-negative + * Return: Success: Non-negative * - * Failure: Negative + * Failure: Negative * - * Programmer: Robb Matzke - * Friday, November 13, 1998 + * Programmer: Robb Matzke + * Friday, November 13, 1998 * *------------------------------------------------------------------------- */ @@ -6534,16 +6536,16 @@ H5T__conv_long_llong(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelm } /*------------------------------------------------------------------------- - * Function: H5T__conv_long_ullong + * Function: H5T__conv_long_ullong * - * Purpose: Converts `long' to `unsigned long long' + * Purpose: Converts `long' to `unsigned long long' * - * Return: Success: Non-negative + * Return: Success: Non-negative * - * Failure: Negative + * Failure: Negative * - * Programmer: Robb Matzke - * Friday, November 13, 1998 + * Programmer: Robb Matzke + * Friday, November 13, 1998 * *------------------------------------------------------------------------- */ @@ -6555,16 +6557,16 @@ H5T__conv_long_ullong(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nel } /*------------------------------------------------------------------------- - * Function: H5T__conv_ulong_llong + * Function: H5T__conv_ulong_llong * - * Purpose: Converts `unsigned long' to `long long' + * Purpose: Converts `unsigned long' to `long long' * - * Return: Success: Non-negative + * Return: Success: Non-negative * - * Failure: Negative + * Failure: Negative * - * Programmer: Robb Matzke - * Friday, November 13, 1998 + * Programmer: Robb Matzke + * Friday, November 13, 1998 * *------------------------------------------------------------------------- */ @@ -6576,16 +6578,16 @@ H5T__conv_ulong_llong(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nel } /*------------------------------------------------------------------------- - * Function: H5T__conv_ulong_ullong + * Function: H5T__conv_ulong_ullong * - * Purpose: Converts `unsigned long' to `unsigned long long' + * Purpose: Converts `unsigned long' to `unsigned long long' * - * Return: Success: Non-negative + * Return: Success: Non-negative * - * Failure: Negative + * Failure: Negative * - * Programmer: Robb Matzke - * Friday, November 13, 1998 + * Programmer: Robb Matzke + * Friday, November 13, 1998 * *------------------------------------------------------------------------- */ @@ -6597,16 +6599,16 @@ H5T__conv_ulong_ullong(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t ne } /*------------------------------------------------------------------------- - * Function: H5T__conv_llong_schar + * Function: H5T__conv_llong_schar * - * Purpose: Converts `long long' to `signed char' + * Purpose: Converts `long long' to `signed char' * - * Return: Success: Non-negative + * Return: Success: Non-negative * - * Failure: Negative + * Failure: Negative * - * Programmer: Robb Matzke - * Friday, November 13, 1998 + * Programmer: Robb Matzke + * Friday, November 13, 1998 * *------------------------------------------------------------------------- */ @@ -6618,16 +6620,16 @@ H5T__conv_llong_schar(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nel } /*------------------------------------------------------------------------- - * Function: H5T__conv_llong_uchar + * Function: H5T__conv_llong_uchar * - * Purpose: Converts `long long' to `unsigned char' + * Purpose: Converts `long long' to `unsigned char' * - * Return: Success: Non-negative + * Return: Success: Non-negative * - * Failure: Negative + * Failure: Negative * - * Programmer: Robb Matzke - * Friday, November 13, 1998 + * Programmer: Robb Matzke + * Friday, November 13, 1998 * *------------------------------------------------------------------------- */ @@ -6639,16 +6641,16 @@ H5T__conv_llong_uchar(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nel } /*------------------------------------------------------------------------- - * Function: H5T__conv_ullong_schar + * Function: H5T__conv_ullong_schar * - * Purpose: Converts `unsigned long long' to `signed char' + * Purpose: Converts `unsigned long long' to `signed char' * - * Return: Success: Non-negative + * Return: Success: Non-negative * - * Failure: Negative + * Failure: Negative * - * Programmer: Robb Matzke - * Friday, November 13, 1998 + * Programmer: Robb Matzke + * Friday, November 13, 1998 * *------------------------------------------------------------------------- */ @@ -6660,16 +6662,16 @@ H5T__conv_ullong_schar(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t ne } /*------------------------------------------------------------------------- - * Function: H5T__conv_ullong_uchar + * Function: H5T__conv_ullong_uchar * - * Purpose: Converts `unsigned long long' to `unsigned char' + * Purpose: Converts `unsigned long long' to `unsigned char' * - * Return: Success: Non-negative + * Return: Success: Non-negative * - * Failure: Negative + * Failure: Negative * - * Programmer: Robb Matzke - * Friday, November 13, 1998 + * Programmer: Robb Matzke + * Friday, November 13, 1998 * *------------------------------------------------------------------------- */ @@ -6681,16 +6683,16 @@ H5T__conv_ullong_uchar(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t ne } /*------------------------------------------------------------------------- - * Function: H5T__conv_llong_short + * Function: H5T__conv_llong_short * - * Purpose: Converts `long long' to `short' + * Purpose: Converts `long long' to `short' * - * Return: Success: Non-negative + * Return: Success: Non-negative * - * Failure: Negative + * Failure: Negative * - * Programmer: Robb Matzke - * Friday, November 13, 1998 + * Programmer: Robb Matzke + * Friday, November 13, 1998 * *------------------------------------------------------------------------- */ @@ -6702,16 +6704,16 @@ H5T__conv_llong_short(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nel } /*------------------------------------------------------------------------- - * Function: H5T__conv_llong_ushort + * Function: H5T__conv_llong_ushort * - * Purpose: Converts `long long' to `unsigned short' + * Purpose: Converts `long long' to `unsigned short' * - * Return: Success: Non-negative + * Return: Success: Non-negative * - * Failure: Negative + * Failure: Negative * - * Programmer: Robb Matzke - * Friday, November 13, 1998 + * Programmer: Robb Matzke + * Friday, November 13, 1998 * *------------------------------------------------------------------------- */ @@ -6723,16 +6725,16 @@ H5T__conv_llong_ushort(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t ne } /*------------------------------------------------------------------------- - * Function: H5T__conv_ullong_short + * Function: H5T__conv_ullong_short * - * Purpose: Converts `unsigned long long' to `short' + * Purpose: Converts `unsigned long long' to `short' * - * Return: Success: Non-negative + * Return: Success: Non-negative * - * Failure: Negative + * Failure: Negative * - * Programmer: Robb Matzke - * Friday, November 13, 1998 + * Programmer: Robb Matzke + * Friday, November 13, 1998 * *------------------------------------------------------------------------- */ @@ -6744,16 +6746,16 @@ H5T__conv_ullong_short(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t ne } /*------------------------------------------------------------------------- - * Function: H5T__conv_ullong_ushort + * Function: H5T__conv_ullong_ushort * - * Purpose: Converts `unsigned long long' to `unsigned short' + * Purpose: Converts `unsigned long long' to `unsigned short' * - * Return: Success: Non-negative + * Return: Success: Non-negative * - * Failure: Negative + * Failure: Negative * - * Programmer: Robb Matzke - * Friday, November 13, 1998 + * Programmer: Robb Matzke + * Friday, November 13, 1998 * *------------------------------------------------------------------------- */ @@ -6765,16 +6767,16 @@ H5T__conv_ullong_ushort(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t n } /*------------------------------------------------------------------------- - * Function: H5T__conv_llong_int + * Function: H5T__conv_llong_int * - * Purpose: Converts `long long' to `int' + * Purpose: Converts `long long' to `int' * - * Return: Success: Non-negative + * Return: Success: Non-negative * - * Failure: Negative + * Failure: Negative * - * Programmer: Robb Matzke - * Friday, November 13, 1998 + * Programmer: Robb Matzke + * Friday, November 13, 1998 * *------------------------------------------------------------------------- */ @@ -6786,16 +6788,16 @@ H5T__conv_llong_int(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmt } /*------------------------------------------------------------------------- - * Function: H5T__conv_llong_uint + * Function: H5T__conv_llong_uint * - * Purpose: Converts `long long' to `unsigned int' + * Purpose: Converts `long long' to `unsigned int' * - * Return: Success: Non-negative + * Return: Success: Non-negative * - * Failure: Negative + * Failure: Negative * - * Programmer: Robb Matzke - * Friday, November 13, 1998 + * Programmer: Robb Matzke + * Friday, November 13, 1998 * *------------------------------------------------------------------------- */ @@ -6807,16 +6809,16 @@ H5T__conv_llong_uint(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelm } /*------------------------------------------------------------------------- - * Function: H5T__conv_ullong_int + * Function: H5T__conv_ullong_int * - * Purpose: Converts `unsigned long long' to `int' + * Purpose: Converts `unsigned long long' to `int' * - * Return: Success: Non-negative + * Return: Success: Non-negative * - * Failure: Negative + * Failure: Negative * - * Programmer: Robb Matzke - * Friday, November 13, 1998 + * Programmer: Robb Matzke + * Friday, November 13, 1998 * *------------------------------------------------------------------------- */ @@ -6828,16 +6830,16 @@ H5T__conv_ullong_int(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelm } /*------------------------------------------------------------------------- - * Function: H5T__conv_ullong_uint + * Function: H5T__conv_ullong_uint * - * Purpose: Converts `unsigned long long' to `unsigned int' + * Purpose: Converts `unsigned long long' to `unsigned int' * - * Return: Success: Non-negative + * Return: Success: Non-negative * - * Failure: Negative + * Failure: Negative * - * Programmer: Robb Matzke - * Friday, November 13, 1998 + * Programmer: Robb Matzke + * Friday, November 13, 1998 * *------------------------------------------------------------------------- */ @@ -6849,16 +6851,16 @@ H5T__conv_ullong_uint(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nel } /*------------------------------------------------------------------------- - * Function: H5T__conv_llong_long + * Function: H5T__conv_llong_long * - * Purpose: Converts `long long' to `long' + * Purpose: Converts `long long' to `long' * - * Return: Success: Non-negative + * Return: Success: Non-negative * - * Failure: Negative + * Failure: Negative * - * Programmer: Robb Matzke - * Friday, November 13, 1998 + * Programmer: Robb Matzke + * Friday, November 13, 1998 * *------------------------------------------------------------------------- */ @@ -6870,16 +6872,16 @@ H5T__conv_llong_long(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelm } /*------------------------------------------------------------------------- - * Function: H5T__conv_llong_ulong + * Function: H5T__conv_llong_ulong * - * Purpose: Converts `long long' to `unsigned long' + * Purpose: Converts `long long' to `unsigned long' * - * Return: Success: Non-negative + * Return: Success: Non-negative * - * Failure: Negative + * Failure: Negative * - * Programmer: Robb Matzke - * Friday, November 13, 1998 + * Programmer: Robb Matzke + * Friday, November 13, 1998 * *------------------------------------------------------------------------- */ @@ -6891,16 +6893,16 @@ H5T__conv_llong_ulong(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nel } /*------------------------------------------------------------------------- - * Function: H5T__conv_ullong_long + * Function: H5T__conv_ullong_long * - * Purpose: Converts `unsigned long long' to `long' + * Purpose: Converts `unsigned long long' to `long' * - * Return: Success: Non-negative + * Return: Success: Non-negative * - * Failure: Negative + * Failure: Negative * - * Programmer: Robb Matzke - * Friday, November 13, 1998 + * Programmer: Robb Matzke + * Friday, November 13, 1998 * *------------------------------------------------------------------------- */ @@ -6912,16 +6914,16 @@ H5T__conv_ullong_long(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nel } /*------------------------------------------------------------------------- - * Function: H5T__conv_ullong_ulong + * Function: H5T__conv_ullong_ulong * - * Purpose: Converts `unsigned long long' to `unsigned long' + * Purpose: Converts `unsigned long long' to `unsigned long' * - * Return: Success: Non-negative + * Return: Success: Non-negative * - * Failure: Negative + * Failure: Negative * - * Programmer: Robb Matzke - * Friday, November 13, 1998 + * Programmer: Robb Matzke + * Friday, November 13, 1998 * *------------------------------------------------------------------------- */ @@ -6933,16 +6935,16 @@ H5T__conv_ullong_ulong(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t ne } /*------------------------------------------------------------------------- - * Function: H5T__conv_llong_ullong + * Function: H5T__conv_llong_ullong * - * Purpose: Converts `long long' to `unsigned long long' + * Purpose: Converts `long long' to `unsigned long long' * - * Return: Success: non-negative + * Return: Success: non-negative * - * Failure: negative + * Failure: negative * - * Programmer: Robb Matzke - * Monday, November 16, 1998 + * Programmer: Robb Matzke + * Monday, November 16, 1998 * *------------------------------------------------------------------------- */ @@ -6954,16 +6956,16 @@ H5T__conv_llong_ullong(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t ne } /*------------------------------------------------------------------------- - * Function: H5T__conv_ullong_llong + * Function: H5T__conv_ullong_llong * - * Purpose: Converts `unsigned long long' to `long long' + * Purpose: Converts `unsigned long long' to `long long' * - * Return: Success: non-negative + * Return: Success: non-negative * - * Failure: negative + * Failure: negative * - * Programmer: Robb Matzke - * Monday, November 16, 1998 + * Programmer: Robb Matzke + * Monday, November 16, 1998 * *------------------------------------------------------------------------- */ @@ -6975,15 +6977,15 @@ H5T__conv_ullong_llong(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t ne } /*------------------------------------------------------------------------- - * Function: H5T__conv_float_double + * Function: H5T__conv_float_double * - * Purpose: Convert native `float' to native `double' using hardware. - * This is a fast special case. + * Purpose: Convert native `float' to native `double' using hardware. + * This is a fast special case. * - * Return: Non-negative on success/Negative on failure + * Return: Non-negative on success/Negative on failure * - * Programmer: Robb Matzke - * Tuesday, June 23, 1998 + * Programmer: Robb Matzke + * Tuesday, June 23, 1998 * *------------------------------------------------------------------------- */ @@ -6995,15 +6997,15 @@ H5T__conv_float_double(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t ne } /*------------------------------------------------------------------------- - * Function: H5T__conv_float_ldouble + * Function: H5T__conv_float_ldouble * - * Purpose: Convert native `float' to native `long double' using hardware. - * This is a fast special case. + * Purpose: Convert native `float' to native `long double' using hardware. + * This is a fast special case. * - * Return: Non-negative on success/Negative on failure + * Return: Non-negative on success/Negative on failure * - * Programmer: Raymond Lu - * Friday, Feb 25, 2005 + * Programmer: Raymond Lu + * Friday, Feb 25, 2005 * *------------------------------------------------------------------------- */ @@ -7017,15 +7019,15 @@ H5T__conv_float_ldouble(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t n #endif /* H5_SIZEOF_LONG_DOUBLE != 0 */ /*------------------------------------------------------------------------- - * Function: H5T__conv_double_float + * Function: H5T__conv_double_float * - * Purpose: Convert native `double' to native `float' using hardware. - * This is a fast special case. + * Purpose: Convert native `double' to native `float' using hardware. + * This is a fast special case. * - * Return: Non-negative on success/Negative on failure + * Return: Non-negative on success/Negative on failure * - * Programmer: Robb Matzke - * Tuesday, June 23, 1998 + * Programmer: Robb Matzke + * Tuesday, June 23, 1998 * *------------------------------------------------------------------------- */ @@ -7037,15 +7039,15 @@ H5T__conv_double_float(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t ne } /*------------------------------------------------------------------------- - * Function: H5T__conv_double_ldouble + * Function: H5T__conv_double_ldouble * - * Purpose: Convert native `double' to native `long double' using hardware. - * This is a fast special case. + * Purpose: Convert native `double' to native `long double' using hardware. + * This is a fast special case. * - * Return: Non-negative on success/Negative on failure + * Return: Non-negative on success/Negative on failure * - * Programmer: Raymond Lu - * Friday, Feb 25, 2005 + * Programmer: Raymond Lu + * Friday, Feb 25, 2005 * *------------------------------------------------------------------------- */ @@ -7059,15 +7061,15 @@ H5T__conv_double_ldouble(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t #endif /* H5_SIZEOF_LONG_DOUBLE != 0 */ /*------------------------------------------------------------------------- - * Function: H5T__conv_ldouble_float + * Function: H5T__conv_ldouble_float * - * Purpose: Convert native `long double' to native `float' using hardware. - * This is a fast special case. + * Purpose: Convert native `long double' to native `float' using hardware. + * This is a fast special case. * - * Return: Non-negative on success/Negative on failure + * Return: Non-negative on success/Negative on failure * - * Programmer: Raymond Lu - * Friday, Feb 25, 2005 + * Programmer: Raymond Lu + * Friday, Feb 25, 2005 * *------------------------------------------------------------------------- */ @@ -7081,15 +7083,15 @@ H5T__conv_ldouble_float(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t n #endif /* H5_SIZEOF_LONG_DOUBLE != 0 */ /*------------------------------------------------------------------------- - * Function: H5T__conv_ldouble_double + * Function: H5T__conv_ldouble_double * - * Purpose: Convert native `long double' to native `double' using hardware. - * This is a fast special case. + * Purpose: Convert native `long double' to native `double' using hardware. + * This is a fast special case. * - * Return: Non-negative on success/Negative on failure + * Return: Non-negative on success/Negative on failure * - * Programmer: Raymond Lu - * Friday, Feb 25, 2005 + * Programmer: Raymond Lu + * Friday, Feb 25, 2005 * *------------------------------------------------------------------------- */ @@ -7103,15 +7105,15 @@ H5T__conv_ldouble_double(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t #endif /* H5_SIZEOF_LONG_DOUBLE != 0 */ /*------------------------------------------------------------------------- - * Function: H5T__conv_schar_float + * Function: H5T__conv_schar_float * - * Purpose: Convert native signed char to native float using hardware. - * This is a fast special case. + * Purpose: Convert native signed char to native float using hardware. + * This is a fast special case. * - * Return: Non-negative on success/Negative on failure + * Return: Non-negative on success/Negative on failure * - * Programmer: Raymond Lu - * Friday, November 7, 2003 + * Programmer: Raymond Lu + * Friday, November 7, 2003 * *------------------------------------------------------------------------- */ @@ -7123,15 +7125,15 @@ H5T__conv_schar_float(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nel } /*------------------------------------------------------------------------- - * Function: H5T__conv_schar_double + * Function: H5T__conv_schar_double * - * Purpose: Convert native signed char to native double using hardware. - * This is a fast special case. + * Purpose: Convert native signed char to native double using hardware. + * This is a fast special case. * - * Return: Non-negative on success/Negative on failure + * Return: Non-negative on success/Negative on failure * - * Programmer: Raymond Lu - * Friday, November 7, 2003 + * Programmer: Raymond Lu + * Friday, November 7, 2003 * *------------------------------------------------------------------------- */ @@ -7143,15 +7145,15 @@ H5T__conv_schar_double(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t ne } /*------------------------------------------------------------------------- - * Function: H5T__conv_schar_ldouble + * Function: H5T__conv_schar_ldouble * - * Purpose: Convert native signed char to native long double using + * Purpose: Convert native signed char to native long double using * hardware. This is a fast special case. * - * Return: Non-negative on success/Negative on failure + * Return: Non-negative on success/Negative on failure * - * Programmer: Raymond Lu - * Tuesday, Febuary 1, 2005 + * Programmer: Raymond Lu + * Tuesday, Febuary 1, 2005 * *------------------------------------------------------------------------- */ @@ -7163,15 +7165,15 @@ H5T__conv_schar_ldouble(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t n } /*------------------------------------------------------------------------- - * Function: H5T__conv_uchar_float + * Function: H5T__conv_uchar_float * - * Purpose: Convert native unsigned char to native float using hardware. - * This is a fast special case. + * Purpose: Convert native unsigned char to native float using hardware. + * This is a fast special case. * - * Return: Non-negative on success/Negative on failure + * Return: Non-negative on success/Negative on failure * - * Programmer: Raymond Lu - * Friday, November 7, 2003 + * Programmer: Raymond Lu + * Friday, November 7, 2003 * *------------------------------------------------------------------------- */ @@ -7183,15 +7185,15 @@ H5T__conv_uchar_float(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nel } /*------------------------------------------------------------------------- - * Function: H5T__conv_uchar_double + * Function: H5T__conv_uchar_double * - * Purpose: Convert native unsigned char to native double using hardware. - * This is a fast special case. + * Purpose: Convert native unsigned char to native double using hardware. + * This is a fast special case. * - * Return: Non-negative on success/Negative on failure + * Return: Non-negative on success/Negative on failure * - * Programmer: Raymond Lu - * Friday, November 7, 2003 + * Programmer: Raymond Lu + * Friday, November 7, 2003 * *------------------------------------------------------------------------- */ @@ -7203,15 +7205,15 @@ H5T__conv_uchar_double(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t ne } /*------------------------------------------------------------------------- - * Function: H5T__conv_uchar_ldouble + * Function: H5T__conv_uchar_ldouble * - * Purpose: Convert native unsigned char to native long double using + * Purpose: Convert native unsigned char to native long double using * hardware. This is a fast special case. * - * Return: Non-negative on success/Negative on failure + * Return: Non-negative on success/Negative on failure * - * Programmer: Raymond Lu - * Tuesday, Febuary 1, 2005 + * Programmer: Raymond Lu + * Tuesday, Febuary 1, 2005 * *------------------------------------------------------------------------- */ @@ -7223,15 +7225,15 @@ H5T__conv_uchar_ldouble(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t n } /*------------------------------------------------------------------------- - * Function: H5T__conv_short_float + * Function: H5T__conv_short_float * - * Purpose: Convert native short to native float using hardware. - * This is a fast special case. + * Purpose: Convert native short to native float using hardware. + * This is a fast special case. * - * Return: Non-negative on success/Negative on failure + * Return: Non-negative on success/Negative on failure * - * Programmer: Raymond Lu - * Friday, November 7, 2003 + * Programmer: Raymond Lu + * Friday, November 7, 2003 * *------------------------------------------------------------------------- */ @@ -7243,15 +7245,15 @@ H5T__conv_short_float(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nel } /*------------------------------------------------------------------------- - * Function: H5T__conv_short_double + * Function: H5T__conv_short_double * - * Purpose: Convert native short to native double using hardware. - * This is a fast special case. + * Purpose: Convert native short to native double using hardware. + * This is a fast special case. * - * Return: Non-negative on success/Negative on failure + * Return: Non-negative on success/Negative on failure * - * Programmer: Raymond Lu - * Friday, November 7, 2003 + * Programmer: Raymond Lu + * Friday, November 7, 2003 * *------------------------------------------------------------------------- */ @@ -7263,15 +7265,15 @@ H5T__conv_short_double(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t ne } /*------------------------------------------------------------------------- - * Function: H5T__conv_short_ldouble + * Function: H5T__conv_short_ldouble * - * Purpose: Convert native short to native long double using hardware. - * This is a fast special case. + * Purpose: Convert native short to native long double using hardware. + * This is a fast special case. * - * Return: Non-negative on success/Negative on failure + * Return: Non-negative on success/Negative on failure * - * Programmer: Raymond Lu - * Tuesday, Febuary 1, 2005 + * Programmer: Raymond Lu + * Tuesday, Febuary 1, 2005 * *------------------------------------------------------------------------- */ @@ -7283,15 +7285,15 @@ H5T__conv_short_ldouble(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t n } /*------------------------------------------------------------------------- - * Function: H5T__conv_ushort_float + * Function: H5T__conv_ushort_float * - * Purpose: Convert native unsigned short to native float using hardware. - * This is a fast special case. + * Purpose: Convert native unsigned short to native float using hardware. + * This is a fast special case. * - * Return: Non-negative on success/Negative on failure + * Return: Non-negative on success/Negative on failure * - * Programmer: Raymond Lu - * Friday, November 7, 2003 + * Programmer: Raymond Lu + * Friday, November 7, 2003 * *------------------------------------------------------------------------- */ @@ -7303,15 +7305,15 @@ H5T__conv_ushort_float(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t ne } /*------------------------------------------------------------------------- - * Function: H5T__conv_ushort_double + * Function: H5T__conv_ushort_double * - * Purpose: Convert native unsigned short to native double using hardware. - * This is a fast special case. + * Purpose: Convert native unsigned short to native double using hardware. + * This is a fast special case. * - * Return: Non-negative on success/Negative on failure + * Return: Non-negative on success/Negative on failure * - * Programmer: Raymond Lu - * Friday, November 7, 2003 + * Programmer: Raymond Lu + * Friday, November 7, 2003 * *------------------------------------------------------------------------- */ @@ -7323,15 +7325,15 @@ H5T__conv_ushort_double(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t n } /*------------------------------------------------------------------------- - * Function: H5T__conv_ushort_ldouble + * Function: H5T__conv_ushort_ldouble * - * Purpose: Convert native unsigned short to native long double using + * Purpose: Convert native unsigned short to native long double using * hardware. This is a fast special case. * - * Return: Non-negative on success/Negative on failure + * Return: Non-negative on success/Negative on failure * - * Programmer: Raymond Lu - * Tuesday, Febuary 1, 2005 + * Programmer: Raymond Lu + * Tuesday, Febuary 1, 2005 * *------------------------------------------------------------------------- */ @@ -7343,15 +7345,15 @@ H5T__conv_ushort_ldouble(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t } /*------------------------------------------------------------------------- - * Function: H5T__conv_int_float + * Function: H5T__conv_int_float * - * Purpose: Convert native integer to native float using hardware. - * This is a fast special case. + * Purpose: Convert native integer to native float using hardware. + * This is a fast special case. * - * Return: Non-negative on success/Negative on failure + * Return: Non-negative on success/Negative on failure * - * Programmer: Raymond Lu - * Friday, November 7, 2003 + * Programmer: Raymond Lu + * Friday, November 7, 2003 * *------------------------------------------------------------------------- */ @@ -7363,15 +7365,15 @@ H5T__conv_int_float(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmt } /*------------------------------------------------------------------------- - * Function: H5T__conv_int_double + * Function: H5T__conv_int_double * - * Purpose: Convert native integer to native double using hardware. - * This is a fast special case. + * Purpose: Convert native integer to native double using hardware. + * This is a fast special case. * - * Return: Non-negative on success/Negative on failure + * Return: Non-negative on success/Negative on failure * - * Programmer: Raymond Lu - * Friday, November 7, 2003 + * Programmer: Raymond Lu + * Friday, November 7, 2003 * *------------------------------------------------------------------------- */ @@ -7383,15 +7385,15 @@ H5T__conv_int_double(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelm } /*------------------------------------------------------------------------- - * Function: H5T__conv_int_ldouble + * Function: H5T__conv_int_ldouble * - * Purpose: Convert native integer to native long double using hardware. - * This is a fast special case. + * Purpose: Convert native integer to native long double using hardware. + * This is a fast special case. * - * Return: Non-negative on success/Negative on failure + * Return: Non-negative on success/Negative on failure * - * Programmer: Raymond Lu - * Tuesday, Febuary 1, 2005 + * Programmer: Raymond Lu + * Tuesday, Febuary 1, 2005 * *------------------------------------------------------------------------- */ @@ -7403,15 +7405,15 @@ H5T__conv_int_ldouble(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nel } /*------------------------------------------------------------------------- - * Function: H5T__conv_uint_float + * Function: H5T__conv_uint_float * - * Purpose: Convert native unsigned integer to native float using + * Purpose: Convert native unsigned integer to native float using * hardware. This is a fast special case. * - * Return: Non-negative on success/Negative on failure + * Return: Non-negative on success/Negative on failure * - * Programmer: Raymond Lu - * Friday, November 7, 2003 + * Programmer: Raymond Lu + * Friday, November 7, 2003 * *------------------------------------------------------------------------- */ @@ -7423,15 +7425,15 @@ H5T__conv_uint_float(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelm } /*------------------------------------------------------------------------- - * Function: H5T__conv_uint_double + * Function: H5T__conv_uint_double * - * Purpose: Convert native unsigned integer to native double using + * Purpose: Convert native unsigned integer to native double using * hardware. This is a fast special case. * - * Return: Non-negative on success/Negative on failure + * Return: Non-negative on success/Negative on failure * - * Programmer: Raymond Lu - * Friday, November 7, 2003 + * Programmer: Raymond Lu + * Friday, November 7, 2003 * *------------------------------------------------------------------------- */ @@ -7443,15 +7445,15 @@ H5T__conv_uint_double(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nel } /*------------------------------------------------------------------------- - * Function: H5T__conv_uint_ldouble + * Function: H5T__conv_uint_ldouble * - * Purpose: Convert native unsigned integer to native long double using + * Purpose: Convert native unsigned integer to native long double using * hardware. This is a fast special case. * - * Return: Non-negative on success/Negative on failure + * Return: Non-negative on success/Negative on failure * - * Programmer: Raymond Lu - * Tuesday, Febuary 1, 2005 + * Programmer: Raymond Lu + * Tuesday, Febuary 1, 2005 * *------------------------------------------------------------------------- */ @@ -7463,15 +7465,15 @@ H5T__conv_uint_ldouble(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t ne } /*------------------------------------------------------------------------- - * Function: H5T__conv_long_float + * Function: H5T__conv_long_float * - * Purpose: Convert native long to native float using hardware. - * This is a fast special case. + * Purpose: Convert native long to native float using hardware. + * This is a fast special case. * - * Return: Non-negative on success/Negative on failure + * Return: Non-negative on success/Negative on failure * - * Programmer: Raymond Lu - * Friday, November 7, 2003 + * Programmer: Raymond Lu + * Friday, November 7, 2003 * *------------------------------------------------------------------------- */ @@ -7483,15 +7485,15 @@ H5T__conv_long_float(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelm } /*------------------------------------------------------------------------- - * Function: H5T__conv_long_double + * Function: H5T__conv_long_double * - * Purpose: Convert native long to native double using hardware. - * This is a fast special case. + * Purpose: Convert native long to native double using hardware. + * This is a fast special case. * - * Return: Non-negative on success/Negative on failure + * Return: Non-negative on success/Negative on failure * - * Programmer: Raymond Lu - * Friday, November 7, 2003 + * Programmer: Raymond Lu + * Friday, November 7, 2003 * *------------------------------------------------------------------------- */ @@ -7503,15 +7505,15 @@ H5T__conv_long_double(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nel } /*------------------------------------------------------------------------- - * Function: H5T__conv_long_ldouble + * Function: H5T__conv_long_ldouble * - * Purpose: Convert native long to native long double using hardware. - * This is a fast special case. + * Purpose: Convert native long to native long double using hardware. + * This is a fast special case. * - * Return: Non-negative on success/Negative on failure + * Return: Non-negative on success/Negative on failure * - * Programmer: Raymond Lu - * Tuesday, Febuary 1, 2005 + * Programmer: Raymond Lu + * Tuesday, Febuary 1, 2005 * *------------------------------------------------------------------------- */ @@ -7523,15 +7525,15 @@ H5T__conv_long_ldouble(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t ne } /*------------------------------------------------------------------------- - * Function: H5T__conv_ulong_float + * Function: H5T__conv_ulong_float * - * Purpose: Convert native unsigned long to native float using hardware. - * This is a fast special case. + * Purpose: Convert native unsigned long to native float using hardware. + * This is a fast special case. * - * Return: Non-negative on success/Negative on failure + * Return: Non-negative on success/Negative on failure * - * Programmer: Raymond Lu - * Friday, November 7, 2003 + * Programmer: Raymond Lu + * Friday, November 7, 2003 * *------------------------------------------------------------------------- */ @@ -7543,15 +7545,15 @@ H5T__conv_ulong_float(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nel } /*------------------------------------------------------------------------- - * Function: H5T__conv_ulong_double + * Function: H5T__conv_ulong_double * - * Purpose: Convert native unsigned long to native double using hardware. - * This is a fast special case. + * Purpose: Convert native unsigned long to native double using hardware. + * This is a fast special case. * - * Return: Non-negative on success/Negative on failure + * Return: Non-negative on success/Negative on failure * - * Programmer: Raymond Lu - * Friday, November 7, 2003 + * Programmer: Raymond Lu + * Friday, November 7, 2003 * *------------------------------------------------------------------------- */ @@ -7563,15 +7565,15 @@ H5T__conv_ulong_double(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t ne } /*------------------------------------------------------------------------- - * Function: H5T__conv_ulong_ldouble + * Function: H5T__conv_ulong_ldouble * - * Purpose: Convert native unsigned long to native long double using + * Purpose: Convert native unsigned long to native long double using * hardware. This is a fast special case. * - * Return: Non-negative on success/Negative on failure + * Return: Non-negative on success/Negative on failure * - * Programmer: Raymond Lu - * Tuesday, Febuary 1, 2005 + * Programmer: Raymond Lu + * Tuesday, Febuary 1, 2005 * *------------------------------------------------------------------------- */ @@ -7583,15 +7585,15 @@ H5T__conv_ulong_ldouble(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t n } /*------------------------------------------------------------------------- - * Function: H5T__conv_llong_float + * Function: H5T__conv_llong_float * - * Purpose: Convert native long long to native float using hardware. - * This is a fast special case. + * Purpose: Convert native long long to native float using hardware. + * This is a fast special case. * - * Return: Non-negative on success/Negative on failure + * Return: Non-negative on success/Negative on failure * - * Programmer: Raymond Lu - * Friday, November 7, 2003 + * Programmer: Raymond Lu + * Friday, November 7, 2003 * *------------------------------------------------------------------------- */ @@ -7603,15 +7605,15 @@ H5T__conv_llong_float(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nel } /*------------------------------------------------------------------------- - * Function: H5T__conv_llong_double + * Function: H5T__conv_llong_double * - * Purpose: Convert native long long to native double using hardware. - * This is a fast special case. + * Purpose: Convert native long long to native double using hardware. + * This is a fast special case. * - * Return: Non-negative on success/Negative on failure + * Return: Non-negative on success/Negative on failure * - * Programmer: Raymond Lu - * Friday, November 7, 2003 + * Programmer: Raymond Lu + * Friday, November 7, 2003 * *------------------------------------------------------------------------- */ @@ -7623,15 +7625,15 @@ H5T__conv_llong_double(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t ne } /*------------------------------------------------------------------------- - * Function: H5T__conv_llong_ldouble + * Function: H5T__conv_llong_ldouble * - * Purpose: Convert native long long to native long double using + * Purpose: Convert native long long to native long double using * hardware. This is a fast special case. * - * Return: Non-negative on success/Negative on failure + * Return: Non-negative on success/Negative on failure * - * Programmer: Raymond Lu - * Tuesday, Febuary 1, 2005 + * Programmer: Raymond Lu + * Tuesday, Febuary 1, 2005 * *------------------------------------------------------------------------- */ @@ -7645,15 +7647,15 @@ H5T__conv_llong_ldouble(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t n #endif /* H5T_CONV_INTERNAL_LLONG_LDOUBLE */ /*------------------------------------------------------------------------- - * Function: H5T__conv_ullong_float + * Function: H5T__conv_ullong_float * - * Purpose: Convert native unsigned long long to native float using + * Purpose: Convert native unsigned long long to native float using * hardware. This is a fast special case. * - * Return: Non-negative on success/Negative on failure + * Return: Non-negative on success/Negative on failure * - * Programmer: Raymond Lu - * Friday, November 7, 2003 + * Programmer: Raymond Lu + * Friday, November 7, 2003 * *------------------------------------------------------------------------- */ @@ -7665,15 +7667,15 @@ H5T__conv_ullong_float(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t ne } /*------------------------------------------------------------------------- - * Function: H5T__conv_ullong_double + * Function: H5T__conv_ullong_double * - * Purpose: Convert native unsigned long long to native double using + * Purpose: Convert native unsigned long long to native double using * hardware. This is a fast special case. * - * Return: Non-negative on success/Negative on failure + * Return: Non-negative on success/Negative on failure * - * Programmer: Raymond Lu - * Friday, November 7, 2003 + * Programmer: Raymond Lu + * Friday, November 7, 2003 * *------------------------------------------------------------------------- */ @@ -7685,15 +7687,15 @@ H5T__conv_ullong_double(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t n } /*------------------------------------------------------------------------- - * Function: H5T__conv_ullong_ldouble + * Function: H5T__conv_ullong_ldouble * - * Purpose: Convert native unsigned long long to native long double using + * Purpose: Convert native unsigned long long to native long double using * hardware. This is a fast special case. * - * Return: Non-negative on success/Negative on failure + * Return: Non-negative on success/Negative on failure * - * Programmer: Raymond Lu - * Tuesday, Febuary 1, 2005 + * Programmer: Raymond Lu + * Tuesday, Febuary 1, 2005 * *------------------------------------------------------------------------- */ @@ -7707,15 +7709,15 @@ H5T__conv_ullong_ldouble(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t #endif /*H5T_CONV_INTERNAL_ULLONG_LDOUBLE*/ /*------------------------------------------------------------------------- - * Function: H5T__conv_float_schar + * Function: H5T__conv_float_schar * - * Purpose: Convert native float to native signed char using + * Purpose: Convert native float to native signed char using * hardware. This is a fast special case. * - * Return: Non-negative on success/Negative on failure + * Return: Non-negative on success/Negative on failure * - * Programmer: Raymond Lu - * Friday, November 7, 2003 + * Programmer: Raymond Lu + * Friday, November 7, 2003 * *------------------------------------------------------------------------- */ @@ -7729,15 +7731,15 @@ H5T__conv_float_schar(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nel } /*------------------------------------------------------------------------- - * Function: H5T__conv_float_uchar + * Function: H5T__conv_float_uchar * - * Purpose: Convert native float to native unsigned char using + * Purpose: Convert native float to native unsigned char using * hardware. This is a fast special case. * - * Return: Non-negative on success/Negative on failure + * Return: Non-negative on success/Negative on failure * - * Programmer: Raymond Lu - * Friday, November 7, 2003 + * Programmer: Raymond Lu + * Friday, November 7, 2003 * *------------------------------------------------------------------------- */ @@ -7751,15 +7753,15 @@ H5T__conv_float_uchar(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nel } /*------------------------------------------------------------------------- - * Function: H5T__conv_double_schar + * Function: H5T__conv_double_schar * - * Purpose: Convert native double to native signed char using + * Purpose: Convert native double to native signed char using * hardware. This is a fast special case. * - * Return: Non-negative on success/Negative on failure + * Return: Non-negative on success/Negative on failure * - * Programmer: Raymond Lu - * Friday, November 7, 2003 + * Programmer: Raymond Lu + * Friday, November 7, 2003 * *------------------------------------------------------------------------- */ @@ -7773,15 +7775,15 @@ H5T__conv_double_schar(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t ne } /*------------------------------------------------------------------------- - * Function: H5T__conv_double_uchar + * Function: H5T__conv_double_uchar * - * Purpose: Convert native double to native unsigned char using + * Purpose: Convert native double to native unsigned char using * hardware. This is a fast special case. * - * Return: Non-negative on success/Negative on failure + * Return: Non-negative on success/Negative on failure * - * Programmer: Raymond Lu - * Friday, November 7, 2003 + * Programmer: Raymond Lu + * Friday, November 7, 2003 * *------------------------------------------------------------------------- */ @@ -7795,15 +7797,15 @@ H5T__conv_double_uchar(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t ne } /*------------------------------------------------------------------------- - * Function: H5T__conv_ldouble_schar + * Function: H5T__conv_ldouble_schar * - * Purpose: Convert native long double to native signed char using + * Purpose: Convert native long double to native signed char using * hardware. This is a fast special case. * - * Return: Non-negative on success/Negative on failure + * Return: Non-negative on success/Negative on failure * - * Programmer: Raymond Lu - * Tuesday, Febuary 1, 2005 + * Programmer: Raymond Lu + * Tuesday, Febuary 1, 2005 * *------------------------------------------------------------------------- */ @@ -7817,15 +7819,15 @@ H5T__conv_ldouble_schar(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t n } /*------------------------------------------------------------------------- - * Function: H5T__conv_ldouble_uchar + * Function: H5T__conv_ldouble_uchar * - * Purpose: Convert native long double to native unsigned char using + * Purpose: Convert native long double to native unsigned char using * hardware. This is a fast special case. * - * Return: Non-negative on success/Negative on failure + * Return: Non-negative on success/Negative on failure * - * Programmer: Raymond Lu - * Tuesday, Febuary 1, 2005 + * Programmer: Raymond Lu + * Tuesday, Febuary 1, 2005 * *------------------------------------------------------------------------- */ @@ -7839,15 +7841,15 @@ H5T__conv_ldouble_uchar(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t n } /*------------------------------------------------------------------------- - * Function: H5T__conv_float_short + * Function: H5T__conv_float_short * - * Purpose: Convert native float to native short using + * Purpose: Convert native float to native short using * hardware. This is a fast special case. * - * Return: Non-negative on success/Negative on failure + * Return: Non-negative on success/Negative on failure * - * Programmer: Raymond Lu - * Friday, November 7, 2003 + * Programmer: Raymond Lu + * Friday, November 7, 2003 * *------------------------------------------------------------------------- */ @@ -7861,15 +7863,15 @@ H5T__conv_float_short(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nel } /*------------------------------------------------------------------------- - * Function: H5T__conv_float_ushort + * Function: H5T__conv_float_ushort * - * Purpose: Convert native float to native unsigned short using + * Purpose: Convert native float to native unsigned short using * hardware. This is a fast special case. * - * Return: Non-negative on success/Negative on failure + * Return: Non-negative on success/Negative on failure * - * Programmer: Raymond Lu - * Friday, November 7, 2003 + * Programmer: Raymond Lu + * Friday, November 7, 2003 * *------------------------------------------------------------------------- */ @@ -7883,15 +7885,15 @@ H5T__conv_float_ushort(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t ne } /*------------------------------------------------------------------------- - * Function: H5T__conv_double_short + * Function: H5T__conv_double_short * - * Purpose: Convert native double to native short using + * Purpose: Convert native double to native short using * hardware. This is a fast special case. * - * Return: Non-negative on success/Negative on failure + * Return: Non-negative on success/Negative on failure * - * Programmer: Raymond Lu - * Friday, November 7, 2003 + * Programmer: Raymond Lu + * Friday, November 7, 2003 * *------------------------------------------------------------------------- */ @@ -7905,15 +7907,15 @@ H5T__conv_double_short(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t ne } /*------------------------------------------------------------------------- - * Function: H5T__conv_double_ushort + * Function: H5T__conv_double_ushort * - * Purpose: Convert native double to native unsigned short using + * Purpose: Convert native double to native unsigned short using * hardware. This is a fast special case. * - * Return: Non-negative on success/Negative on failure + * Return: Non-negative on success/Negative on failure * - * Programmer: Raymond Lu - * Friday, November 7, 2003 + * Programmer: Raymond Lu + * Friday, November 7, 2003 * *------------------------------------------------------------------------- */ @@ -7927,15 +7929,15 @@ H5T__conv_double_ushort(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t n } /*------------------------------------------------------------------------- - * Function: H5T__conv_ldouble_short + * Function: H5T__conv_ldouble_short * - * Purpose: Convert native long double to native short using + * Purpose: Convert native long double to native short using * hardware. This is a fast special case. * - * Return: Non-negative on success/Negative on failure + * Return: Non-negative on success/Negative on failure * - * Programmer: Raymond Lu - * Tuesday, Febuary 1, 2005 + * Programmer: Raymond Lu + * Tuesday, Febuary 1, 2005 * *------------------------------------------------------------------------- */ @@ -7949,15 +7951,15 @@ H5T__conv_ldouble_short(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t n } /*------------------------------------------------------------------------- - * Function: H5T__conv_ldouble_ushort + * Function: H5T__conv_ldouble_ushort * - * Purpose: Convert native long double to native unsigned short using + * Purpose: Convert native long double to native unsigned short using * hardware. This is a fast special case. * - * Return: Non-negative on success/Negative on failure + * Return: Non-negative on success/Negative on failure * - * Programmer: Raymond Lu - * Tuesday, Febuary 1, 2005 + * Programmer: Raymond Lu + * Tuesday, Febuary 1, 2005 * *------------------------------------------------------------------------- */ @@ -7971,15 +7973,15 @@ H5T__conv_ldouble_ushort(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t } /*------------------------------------------------------------------------- - * Function: H5T__conv_float_int + * Function: H5T__conv_float_int * - * Purpose: Convert native float to native int using + * Purpose: Convert native float to native int using * hardware. This is a fast special case. * - * Return: Non-negative on success/Negative on failure + * Return: Non-negative on success/Negative on failure * - * Programmer: Raymond Lu - * Friday, November 7, 2003 + * Programmer: Raymond Lu + * Friday, November 7, 2003 * *------------------------------------------------------------------------- */ @@ -7993,15 +7995,15 @@ H5T__conv_float_int(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmt } /*------------------------------------------------------------------------- - * Function: H5T__conv_float_uint + * Function: H5T__conv_float_uint * - * Purpose: Convert native float to native unsigned int using + * Purpose: Convert native float to native unsigned int using * hardware. This is a fast special case. * - * Return: Non-negative on success/Negative on failure + * Return: Non-negative on success/Negative on failure * - * Programmer: Raymond Lu - * Friday, November 7, 2003 + * Programmer: Raymond Lu + * Friday, November 7, 2003 * *------------------------------------------------------------------------- */ @@ -8015,15 +8017,15 @@ H5T__conv_float_uint(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelm } /*------------------------------------------------------------------------- - * Function: H5T__conv_double_int + * Function: H5T__conv_double_int * - * Purpose: Convert native double to native int using + * Purpose: Convert native double to native int using * hardware. This is a fast special case. * - * Return: Non-negative on success/Negative on failure + * Return: Non-negative on success/Negative on failure * - * Programmer: Raymond Lu - * Friday, November 7, 2003 + * Programmer: Raymond Lu + * Friday, November 7, 2003 * *------------------------------------------------------------------------- */ @@ -8037,15 +8039,15 @@ H5T__conv_double_int(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelm } /*------------------------------------------------------------------------- - * Function: H5T__conv_double_uint + * Function: H5T__conv_double_uint * - * Purpose: Convert native double to native unsigned int using + * Purpose: Convert native double to native unsigned int using * hardware. This is a fast special case. * - * Return: Non-negative on success/Negative on failure + * Return: Non-negative on success/Negative on failure * - * Programmer: Raymond Lu - * Friday, November 7, 2003 + * Programmer: Raymond Lu + * Friday, November 7, 2003 * *------------------------------------------------------------------------- */ @@ -8059,15 +8061,15 @@ H5T__conv_double_uint(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nel } /*------------------------------------------------------------------------- - * Function: H5T__conv_ldouble_int + * Function: H5T__conv_ldouble_int * - * Purpose: Convert native long double to native int using + * Purpose: Convert native long double to native int using * hardware. This is a fast special case. * - * Return: Non-negative on success/Negative on failure + * Return: Non-negative on success/Negative on failure * - * Programmer: Raymond Lu - * Tuesday, Febuary 1, 2005 + * Programmer: Raymond Lu + * Tuesday, Febuary 1, 2005 * *------------------------------------------------------------------------- */ @@ -8081,15 +8083,15 @@ H5T__conv_ldouble_int(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nel } /*------------------------------------------------------------------------- - * Function: H5T__conv_ldouble_uint + * Function: H5T__conv_ldouble_uint * - * Purpose: Convert native long double to native unsigned int using + * Purpose: Convert native long double to native unsigned int using * hardware. This is a fast special case. * - * Return: Non-negative on success/Negative on failure + * Return: Non-negative on success/Negative on failure * - * Programmer: Raymond Lu - * Tuesday, Febuary 1, 2005 + * Programmer: Raymond Lu + * Tuesday, Febuary 1, 2005 * *------------------------------------------------------------------------- */ @@ -8103,15 +8105,15 @@ H5T__conv_ldouble_uint(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t ne } /*------------------------------------------------------------------------- - * Function: H5T__conv_float_long + * Function: H5T__conv_float_long * - * Purpose: Convert native float to native long using + * Purpose: Convert native float to native long using * hardware. This is a fast special case. * - * Return: Non-negative on success/Negative on failure + * Return: Non-negative on success/Negative on failure * - * Programmer: Raymond Lu - * Friday, November 7, 2003 + * Programmer: Raymond Lu + * Friday, November 7, 2003 * *------------------------------------------------------------------------- */ @@ -8125,15 +8127,15 @@ H5T__conv_float_long(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelm } /*------------------------------------------------------------------------- - * Function: H5T__conv_float_ulong + * Function: H5T__conv_float_ulong * - * Purpose: Convert native float to native unsigned long using + * Purpose: Convert native float to native unsigned long using * hardware. This is a fast special case. * - * Return: Non-negative on success/Negative on failure + * Return: Non-negative on success/Negative on failure * - * Programmer: Raymond Lu - * Friday, November 7, 2003 + * Programmer: Raymond Lu + * Friday, November 7, 2003 * *------------------------------------------------------------------------- */ @@ -8147,15 +8149,15 @@ H5T__conv_float_ulong(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nel } /*------------------------------------------------------------------------- - * Function: H5T__conv_double_long + * Function: H5T__conv_double_long * - * Purpose: Convert native double to native long using + * Purpose: Convert native double to native long using * hardware. This is a fast special case. * - * Return: Non-negative on success/Negative on failure + * Return: Non-negative on success/Negative on failure * - * Programmer: Raymond Lu - * Friday, November 7, 2003 + * Programmer: Raymond Lu + * Friday, November 7, 2003 * *------------------------------------------------------------------------- */ @@ -8169,15 +8171,15 @@ H5T__conv_double_long(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nel } /*------------------------------------------------------------------------- - * Function: H5T__conv_double_ulong + * Function: H5T__conv_double_ulong * - * Purpose: Convert native double to native unsigned long using + * Purpose: Convert native double to native unsigned long using * hardware. This is a fast special case. * - * Return: Non-negative on success/Negative on failure + * Return: Non-negative on success/Negative on failure * - * Programmer: Raymond Lu - * Friday, November 7, 2003 + * Programmer: Raymond Lu + * Friday, November 7, 2003 * *------------------------------------------------------------------------- */ @@ -8191,15 +8193,15 @@ H5T__conv_double_ulong(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t ne } /*------------------------------------------------------------------------- - * Function: H5T__conv_ldouble_long + * Function: H5T__conv_ldouble_long * - * Purpose: Convert native long double to native long using + * Purpose: Convert native long double to native long using * hardware. This is a fast special case. * - * Return: Non-negative on success/Negative on failure + * Return: Non-negative on success/Negative on failure * - * Programmer: Raymond Lu - * Tuesday, Febuary 1, 2005 + * Programmer: Raymond Lu + * Tuesday, Febuary 1, 2005 * *------------------------------------------------------------------------- */ @@ -8213,15 +8215,15 @@ H5T__conv_ldouble_long(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t ne } /*------------------------------------------------------------------------- - * Function: H5T__conv_ldouble_ulong + * Function: H5T__conv_ldouble_ulong * - * Purpose: Convert native long double to native unsigned long using + * Purpose: Convert native long double to native unsigned long using * hardware. This is a fast special case. * - * Return: Non-negative on success/Negative on failure + * Return: Non-negative on success/Negative on failure * - * Programmer: Raymond Lu - * Tuesday, Febuary 1, 2005 + * Programmer: Raymond Lu + * Tuesday, Febuary 1, 2005 * *------------------------------------------------------------------------- */ @@ -8235,15 +8237,15 @@ H5T__conv_ldouble_ulong(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t n } /*------------------------------------------------------------------------- - * Function: H5T__conv_float_llong + * Function: H5T__conv_float_llong * - * Purpose: Convert native float to native long long using + * Purpose: Convert native float to native long long using * hardware. This is a fast special case. * - * Return: Non-negative on success/Negative on failure + * Return: Non-negative on success/Negative on failure * - * Programmer: Raymond Lu - * Friday, November 7, 2003 + * Programmer: Raymond Lu + * Friday, November 7, 2003 * *------------------------------------------------------------------------- */ @@ -8257,15 +8259,15 @@ H5T__conv_float_llong(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nel } /*------------------------------------------------------------------------- - * Function: H5T__conv_float_ullong + * Function: H5T__conv_float_ullong * - * Purpose: Convert native float to native unsigned long long using + * Purpose: Convert native float to native unsigned long long using * hardware. This is a fast special case. * - * Return: Non-negative on success/Negative on failure + * Return: Non-negative on success/Negative on failure * - * Programmer: Raymond Lu - * Friday, November 7, 2003 + * Programmer: Raymond Lu + * Friday, November 7, 2003 * *------------------------------------------------------------------------- */ @@ -8279,15 +8281,15 @@ H5T__conv_float_ullong(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t ne } /*------------------------------------------------------------------------- - * Function: H5T__conv_double_llong + * Function: H5T__conv_double_llong * - * Purpose: Convert native double to native long long using + * Purpose: Convert native double to native long long using * hardware. This is a fast special case. * - * Return: Non-negative on success/Negative on failure + * Return: Non-negative on success/Negative on failure * - * Programmer: Raymond Lu - * Friday, November 7, 2003 + * Programmer: Raymond Lu + * Friday, November 7, 2003 * *------------------------------------------------------------------------- */ @@ -8301,15 +8303,15 @@ H5T__conv_double_llong(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t ne } /*------------------------------------------------------------------------- - * Function: H5T__conv_double_ullong + * Function: H5T__conv_double_ullong * - * Purpose: Convert native double to native unsigned long long using + * Purpose: Convert native double to native unsigned long long using * hardware. This is a fast special case. * - * Return: Non-negative on success/Negative on failure + * Return: Non-negative on success/Negative on failure * - * Programmer: Raymond Lu - * Friday, November 7, 2003 + * Programmer: Raymond Lu + * Friday, November 7, 2003 * *------------------------------------------------------------------------- */ @@ -8323,15 +8325,15 @@ H5T__conv_double_ullong(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t n } /*------------------------------------------------------------------------- - * Function: H5T__conv_ldouble_llong + * Function: H5T__conv_ldouble_llong * - * Purpose: Convert native long double to native long long using + * Purpose: Convert native long double to native long long using * hardware. This is a fast special case. * - * Return: Non-negative on success/Negative on failure + * Return: Non-negative on success/Negative on failure * - * Programmer: Raymond Lu - * Tuesday, Febuary 1, 2005 + * Programmer: Raymond Lu + * Tuesday, Febuary 1, 2005 * *------------------------------------------------------------------------- */ @@ -8347,15 +8349,15 @@ H5T__conv_ldouble_llong(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t n #endif /*H5T_CONV_INTERNAL_LDOUBLE_LLONG*/ /*------------------------------------------------------------------------- - * Function: H5T__conv_ldouble_ullong + * Function: H5T__conv_ldouble_ullong * - * Purpose: Convert native long double to native unsigned long long using + * Purpose: Convert native long double to native unsigned long long using * hardware. This is a fast special case. * - * Return: Non-negative on success/Negative on failure + * Return: Non-negative on success/Negative on failure * - * Programmer: Raymond Lu - * Tuesday, Febuary 1, 2005 + * Programmer: Raymond Lu + * Tuesday, Febuary 1, 2005 * *------------------------------------------------------------------------- */ @@ -8371,16 +8373,16 @@ H5T__conv_ldouble_ullong(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t #endif /*H5T_CONV_INTERNAL_LDOUBLE_ULLONG*/ /*------------------------------------------------------------------------- - * Function: H5T__conv_f_i + * Function: H5T__conv_f_i * - * Purpose: Convert one floating-point type to an integer. This is + * Purpose: Convert one floating-point type to an integer. This is * the catch-all function for float-integer conversions and * is probably not particularly fast. * - * Return: Non-negative on success/Negative on failure + * Return: Non-negative on success/Negative on failure * - * Programmer: Raymond Lu - * Wednesday, Jan 21, 2004 + * Programmer: Raymond Lu + * Wednesday, Jan 21, 2004 * *------------------------------------------------------------------------- */ @@ -8389,28 +8391,28 @@ H5T__conv_f_i(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, siz size_t H5_ATTR_UNUSED bkg_stride, void *buf, void H5_ATTR_UNUSED *bkg) { /* Traversal-related variables */ - H5T_t * src_p; /*source datatype */ - H5T_t * dst_p; /*destination datatype */ - H5T_atomic_t src; /*atomic source info */ - H5T_atomic_t dst; /*atomic destination info */ - int direction; /*forward or backward traversal */ - size_t elmtno; /*element number */ - size_t half_size; /*half the type size */ + H5T_t * src_p; /*source datatype */ + H5T_t * dst_p; /*destination datatype */ + H5T_atomic_t src; /*atomic source info */ + H5T_atomic_t dst; /*atomic destination info */ + int direction; /*forward or backward traversal */ + size_t elmtno; /*element number */ + size_t half_size; /*half the type size */ size_t tsize; /*type size for swapping bytes */ - size_t olap; /*num overlapping elements */ + size_t olap; /*num overlapping elements */ uint8_t * s, *sp, *d, *dp; /*source and dest traversal ptrs*/ - uint8_t * src_rev = NULL; /*order-reversed source buffer */ - uint8_t dbuf[64]; /*temp destination buffer */ + uint8_t * src_rev = NULL; /*order-reversed source buffer */ + uint8_t dbuf[64] = {0}; /*temp destination buffer */ uint8_t tmp1, tmp2; /*temp variables for swapping bytes*/ /* Conversion-related variables */ - hssize_t expo; /*source exponent */ + hssize_t expo; /*source exponent */ hssize_t sign; /*source sign bit value */ uint8_t * int_buf = NULL; /*buffer for temporary value */ size_t buf_size; /*buffer size for temporary value */ - size_t i; /*miscellaneous counters */ + size_t i; /*miscellaneous counters */ size_t first; /*first bit(MSB) in an integer */ - ssize_t sfirst; /*a signed version of `first' */ + ssize_t sfirst; /*a signed version of `first' */ H5T_conv_cb_t cb_struct = {NULL, NULL}; /*conversion callback structure */ hbool_t truncated; /*if fraction value is dropped */ hbool_t reverse; /*if reverse order of destination at the end */ @@ -8475,7 +8477,7 @@ H5T__conv_f_i(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, siz /* Allocate enough space for the buffer holding temporary * converted value */ - buf_size = (size_t)(HDpow((double)2.0f, (double)src.u.f.esize) / 8 + 1); + buf_size = (size_t)(HDpow(2.0, (double)src.u.f.esize) / 8 + 1); int_buf = (uint8_t *)H5MM_calloc(buf_size); /* Get conversion exception callback property */ @@ -8566,8 +8568,8 @@ H5T__conv_f_i(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, siz if (sign) { /* -Infinity */ if (cb_struct.func) { /*If user's exception handler is present, use it*/ /*reverse order first*/ - H5T_reverse_order(src_rev, s, src_p->shared->size, - src_p->shared->u.atomic.order); + H5T__reverse_order(src_rev, s, src_p->shared->size, + src_p->shared->u.atomic.order); except_ret = (cb_struct.func)(H5T_CONV_EXCEPT_NINF, src_id, dst_id, src_rev, d, cb_struct.user_data); } @@ -8588,8 +8590,8 @@ H5T__conv_f_i(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, siz else { /* +Infinity */ if (cb_struct.func) { /*If user's exception handler is present, use it*/ /*reverse order first*/ - H5T_reverse_order(src_rev, s, src_p->shared->size, - src_p->shared->u.atomic.order); + H5T__reverse_order(src_rev, s, src_p->shared->size, + src_p->shared->u.atomic.order); except_ret = (cb_struct.func)(H5T_CONV_EXCEPT_PINF, src_id, dst_id, src_rev, d, cb_struct.user_data); } @@ -8622,7 +8624,8 @@ H5T__conv_f_i(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, siz if (sign) { /* -Infinity */ if (cb_struct.func) { /*If user's exception handler is present, use it*/ /*reverse order first*/ - H5T_reverse_order(src_rev, s, src_p->shared->size, src_p->shared->u.atomic.order); + H5T__reverse_order(src_rev, s, src_p->shared->size, + src_p->shared->u.atomic.order); except_ret = (cb_struct.func)(H5T_CONV_EXCEPT_NINF, src_id, dst_id, src_rev, d, cb_struct.user_data); } @@ -8643,7 +8646,8 @@ H5T__conv_f_i(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, siz else { /* +Infinity */ if (cb_struct.func) { /*If user's exception handler is present, use it*/ /*reverse order first*/ - H5T_reverse_order(src_rev, s, src_p->shared->size, src_p->shared->u.atomic.order); + H5T__reverse_order(src_rev, s, src_p->shared->size, + src_p->shared->u.atomic.order); except_ret = (cb_struct.func)(H5T_CONV_EXCEPT_PINF, src_id, dst_id, src_rev, d, cb_struct.user_data); } @@ -8669,7 +8673,7 @@ H5T__conv_f_i(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, siz /* NaN */ if (cb_struct.func) { /*If user's exception handler is present, use it*/ /*reverse order first*/ - H5T_reverse_order(src_rev, s, src_p->shared->size, src_p->shared->u.atomic.order); + H5T__reverse_order(src_rev, s, src_p->shared->size, src_p->shared->u.atomic.order); except_ret = (cb_struct.func)(H5T_CONV_EXCEPT_NAN, src_id, dst_id, src_rev, d, cb_struct.user_data); } @@ -8771,7 +8775,8 @@ H5T__conv_f_i(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, siz if (sign) { /*source is negative*/ if (cb_struct.func) { /*If user's exception handler is present, use it*/ /*reverse order first*/ - H5T_reverse_order(src_rev, s, src_p->shared->size, src_p->shared->u.atomic.order); + H5T__reverse_order(src_rev, s, src_p->shared->size, + src_p->shared->u.atomic.order); except_ret = (cb_struct.func)(H5T_CONV_EXCEPT_RANGE_LOW, src_id, dst_id, src_rev, d, cb_struct.user_data); if (except_ret == H5T_CONV_ABORT) @@ -8789,8 +8794,8 @@ H5T__conv_f_i(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, siz /*overflow*/ if (cb_struct.func) { /*If user's exception handler is present, use it*/ /*reverse order first*/ - H5T_reverse_order(src_rev, s, src_p->shared->size, - src_p->shared->u.atomic.order); + H5T__reverse_order(src_rev, s, src_p->shared->size, + src_p->shared->u.atomic.order); except_ret = (cb_struct.func)(H5T_CONV_EXCEPT_RANGE_HI, src_id, dst_id, src_rev, d, cb_struct.user_data); } @@ -8810,8 +8815,8 @@ H5T__conv_f_i(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, siz if (truncated && cb_struct.func) { /*If user's exception handler is present, use it*/ /*reverse order first*/ - H5T_reverse_order(src_rev, s, src_p->shared->size, - src_p->shared->u.atomic.order); + H5T__reverse_order(src_rev, s, src_p->shared->size, + src_p->shared->u.atomic.order); except_ret = (cb_struct.func)(H5T_CONV_EXCEPT_TRUNCATE, src_id, dst_id, src_rev, d, cb_struct.user_data); } @@ -8836,8 +8841,8 @@ H5T__conv_f_i(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, siz if (truncated && cb_struct.func) { /*If user's exception handler is present, use it*/ /*reverse order first*/ - H5T_reverse_order(src_rev, s, src_p->shared->size, - src_p->shared->u.atomic.order); + H5T__reverse_order(src_rev, s, src_p->shared->size, + src_p->shared->u.atomic.order); except_ret = (cb_struct.func)(H5T_CONV_EXCEPT_TRUNCATE, src_id, dst_id, src_rev, d, cb_struct.user_data); } @@ -8866,8 +8871,8 @@ H5T__conv_f_i(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, siz */ if (cb_struct.func) { /*If user's exception handler is present, use it*/ /*reverse order first*/ - H5T_reverse_order(src_rev, s, src_p->shared->size, - src_p->shared->u.atomic.order); + H5T__reverse_order(src_rev, s, src_p->shared->size, + src_p->shared->u.atomic.order); except_ret = (cb_struct.func)(H5T_CONV_EXCEPT_RANGE_LOW, src_id, dst_id, src_rev, d, cb_struct.user_data); } @@ -8889,8 +8894,8 @@ H5T__conv_f_i(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, siz /*overflow*/ if (cb_struct.func) { /*If user's exception handler is present, use it*/ /*reverse order first*/ - H5T_reverse_order(src_rev, s, src_p->shared->size, - src_p->shared->u.atomic.order); + H5T__reverse_order(src_rev, s, src_p->shared->size, + src_p->shared->u.atomic.order); except_ret = (cb_struct.func)(H5T_CONV_EXCEPT_RANGE_HI, src_id, dst_id, src_rev, d, cb_struct.user_data); } @@ -8910,8 +8915,8 @@ H5T__conv_f_i(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, siz if (truncated && cb_struct.func) { /*If user's exception handler is present, use it*/ /*reverse order first*/ - H5T_reverse_order(src_rev, s, src_p->shared->size, - src_p->shared->u.atomic.order); + H5T__reverse_order(src_rev, s, src_p->shared->size, + src_p->shared->u.atomic.order); except_ret = (cb_struct.func)(H5T_CONV_EXCEPT_TRUNCATE, src_id, dst_id, src_rev, d, cb_struct.user_data); } @@ -8994,16 +8999,16 @@ done: } /* end H5T__conv_f_i() */ /*------------------------------------------------------------------------- - * Function: H5T__conv_i_f + * Function: H5T__conv_i_f * - * Purpose: Convert one integer type to a floating-point type. This is + * Purpose: Convert one integer type to a floating-point type. This is * the catch-all function for integer-float conversions and * is probably not particularly fast. * - * Return: Non-negative on success/Negative on failure + * Return: Non-negative on success/Negative on failure * - * Programmer: Raymond Lu - * Friday, Feb 6, 2004 + * Programmer: Raymond Lu + * Friday, Feb 6, 2004 * *------------------------------------------------------------------------- */ @@ -9012,31 +9017,31 @@ H5T__conv_i_f(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, siz size_t H5_ATTR_UNUSED bkg_stride, void *buf, void H5_ATTR_UNUSED *bkg) { /* Traversal-related variables */ - H5T_t * src_p; /*source datatype */ - H5T_t * dst_p; /*destination datatype */ - H5T_atomic_t src; /*atomic source info */ - H5T_atomic_t dst; /*atomic destination info */ - int direction; /*forward or backward traversal */ - size_t elmtno; /*element number */ - size_t half_size; /*half the type size */ + H5T_t * src_p; /*source datatype */ + H5T_t * dst_p; /*destination datatype */ + H5T_atomic_t src; /*atomic source info */ + H5T_atomic_t dst; /*atomic destination info */ + int direction; /*forward or backward traversal */ + size_t elmtno; /*element number */ + size_t half_size; /*half the type size */ size_t tsize; /*type size for swapping bytes */ - size_t olap; /*num overlapping elements */ + size_t olap; /*num overlapping elements */ uint8_t * s, *sp, *d, *dp; /*source and dest traversal ptrs*/ - uint8_t * src_rev = NULL; /*order-reversed source buffer */ - uint8_t dbuf[64]; /*temp destination buffer */ + uint8_t * src_rev = NULL; /*order-reversed source buffer */ + uint8_t dbuf[64] = {0}; /*temp destination buffer */ uint8_t tmp1, tmp2; /*temp variables for swapping bytes*/ /* Conversion-related variables */ - hsize_t expo; /*destination exponent */ + hsize_t expo; /*destination exponent */ hsize_t expo_max; /*maximal possible exponent value */ size_t sign; /*source sign bit value */ hbool_t is_max_neg; /*source is maximal negative value*/ hbool_t do_round; /*whether there is roundup */ uint8_t * int_buf = NULL; /*buffer for temporary value */ size_t buf_size; /*buffer size for temporary value */ - size_t i; /*miscellaneous counters */ + size_t i; /*miscellaneous counters */ size_t first; /*first bit(MSB) in an integer */ - ssize_t sfirst; /*a signed version of `first' */ + ssize_t sfirst; /*a signed version of `first' */ H5T_conv_cb_t cb_struct = {NULL, NULL}; /*conversion callback structure */ H5T_conv_ret_t except_ret; /*return of callback function */ hbool_t reverse; /*if reverse the order of destination */ @@ -9243,8 +9248,8 @@ H5T__conv_i_f(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, siz * precision loss. Let user's handler deal with the case if it's present */ if (cb_struct.func) { - H5T_reverse_order(src_rev, s, src_p->shared->size, - src_p->shared->u.atomic.order); /*reverse order first*/ + H5T__reverse_order(src_rev, s, src_p->shared->size, + src_p->shared->u.atomic.order); /*reverse order first*/ except_ret = (cb_struct.func)(H5T_CONV_EXCEPT_PRECISION, src_id, dst_id, src_rev, d, cb_struct.user_data); } @@ -9314,8 +9319,8 @@ H5T__conv_i_f(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, siz if (expo > expo_max) { /*overflows*/ if (cb_struct.func) { /*user's exception handler. Reverse back source order*/ - H5T_reverse_order(src_rev, s, src_p->shared->size, - src_p->shared->u.atomic.order); /*reverse order first*/ + H5T__reverse_order(src_rev, s, src_p->shared->size, + src_p->shared->u.atomic.order); /*reverse order first*/ except_ret = (cb_struct.func)(H5T_CONV_EXCEPT_RANGE_HI, src_id, dst_id, src_rev, d, cb_struct.user_data); @@ -9420,9 +9425,9 @@ done: } /* end H5T__conv_i_f() */ /*------------------------------------------------------------------------- - * Function: H5T_reverse_order + * Function: H5T__reverse_order * - * Purpose: Internal assisting function to reverse the order of + * Purpose: Internal assisting function to reverse the order of * a sequence of byte when it's big endian or VAX order. * The byte sequence simulates the endian order. * @@ -9430,17 +9435,17 @@ done: * * Failure: Null * - * Programmer: Raymond Lu - * April 26, 2004 + * Programmer: Raymond Lu + * April 26, 2004 * *------------------------------------------------------------------------- */ static herr_t -H5T_reverse_order(uint8_t *rev, uint8_t *s, size_t size, H5T_order_t order) +H5T__reverse_order(uint8_t *rev, uint8_t *s, size_t size, H5T_order_t order) { size_t i; - FUNC_ENTER_NOAPI_NOINIT_NOERR + FUNC_ENTER_STATIC_NOERR HDassert(s); HDassert(size); diff --git a/src/H5Tdeprec.c b/src/H5Tdeprec.c index 277c9a2..116d34c 100644 --- a/src/H5Tdeprec.c +++ b/src/H5Tdeprec.c @@ -134,11 +134,8 @@ H5Tcommit1(hid_t loc_id, const char *name, hid_t type_id) HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to commit datatype") /* Set up VOL object */ - if (NULL == (new_obj = H5FL_CALLOC(H5VL_object_t))) - HGOTO_ERROR(H5E_VOL, H5E_NOSPACE, FAIL, "can't allocate top object structure") - new_obj->connector = vol_obj->connector; - new_obj->connector->nrefs++; - new_obj->data = data; + if (NULL == (new_obj = H5VL_create_object(data, vol_obj->connector))) + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTALLOC, FAIL, "can't create VOL object for committed datatype") /* Set the committed type object to the VOL connector pointer in the H5T_t struct */ dt->vol_obj = new_obj; diff --git a/src/H5Tpkg.h b/src/H5Tpkg.h index 220adb3b2..51ecaca 100644 --- a/src/H5Tpkg.h +++ b/src/H5Tpkg.h @@ -49,7 +49,8 @@ #define H5T_NAMELEN 32 /* Macro to ease detecting "complex" datatypes (i.e. those with base types or fields) */ -#define H5T_IS_COMPLEX(t) ((t) == H5T_COMPOUND || (t) == H5T_ENUM || (t) == H5T_VLEN || (t) == H5T_ARRAY) +#define H5T_IS_COMPLEX(t) \ + ((t) == H5T_COMPOUND || (t) == H5T_ENUM || (t) == H5T_VLEN || (t) == H5T_ARRAY || (t) == H5T_REFERENCE) /* Macro to ease detecting fixed "string" datatypes */ #define H5T_IS_FIXED_STRING(dt) (H5T_STRING == (dt)->type) @@ -851,7 +852,8 @@ H5_DLL herr_t H5T__bit_shift(uint8_t *buf, ssize_t shift_dist, size_t offset, H5_DLL void H5T__bit_set(uint8_t *buf, size_t offset, size_t size, hbool_t value); H5_DLL uint64_t H5T__bit_get_d(uint8_t *buf, size_t offset, size_t size); H5_DLL void H5T__bit_set_d(uint8_t *buf, size_t offset, size_t size, uint64_t val); -H5_DLL ssize_t H5T__bit_find(uint8_t *buf, size_t offset, size_t size, H5T_sdir_t direction, hbool_t value); +H5_DLL ssize_t H5T__bit_find(const uint8_t *buf, size_t offset, size_t size, H5T_sdir_t direction, + hbool_t value); H5_DLL hbool_t H5T__bit_inc(uint8_t *buf, size_t start, size_t size); H5_DLL hbool_t H5T__bit_dec(uint8_t *buf, size_t start, size_t size); H5_DLL void H5T__bit_neg(uint8_t *buf, size_t start, size_t size); @@ -859,7 +861,7 @@ H5_DLL void H5T__bit_neg(uint8_t *buf, size_t start, size_t size); /* VL functions */ H5_DLL H5T_t *H5T__vlen_create(const H5T_t *base); H5_DLL herr_t H5T__vlen_reclaim(void *elem, const H5T_t *dt, H5T_vlen_alloc_info_t *alloc_info); -H5_DLL htri_t H5T__vlen_set_loc(const H5T_t *dt, H5VL_object_t *file, H5T_loc_t loc); +H5_DLL htri_t H5T__vlen_set_loc(H5T_t *dt, H5VL_object_t *file, H5T_loc_t loc); /* Array functions */ H5_DLL H5T_t *H5T__array_create(H5T_t *base, unsigned ndims, const hsize_t dim[/* ndims */]); @@ -868,7 +870,7 @@ H5_DLL int H5T__get_array_dims(const H5T_t *dt, hsize_t dims[]); /* Reference functions */ H5_DLL herr_t H5T__ref_reclaim(void *elem, const H5T_t *dt); -H5_DLL htri_t H5T__ref_set_loc(const H5T_t *dt, H5VL_object_t *file, H5T_loc_t loc); +H5_DLL htri_t H5T__ref_set_loc(H5T_t *dt, H5VL_object_t *file, H5T_loc_t loc); /* Compound functions */ H5_DLL herr_t H5T__insert(H5T_t *parent, const char *name, size_t offset, const H5T_t *member); diff --git a/src/H5Tprecis.c b/src/H5Tprecis.c index f992141..1dc0073 100644 --- a/src/H5Tprecis.c +++ b/src/H5Tprecis.c @@ -24,7 +24,7 @@ #include "H5Tpkg.h" /* Datatypes */ /* Static local functions */ -static herr_t H5T_set_precision(const H5T_t *dt, size_t prec); +static herr_t H5T__set_precision(const H5T_t *dt, size_t prec); /*------------------------------------------------------------------------- * Function: H5Tget_precision @@ -153,7 +153,7 @@ H5Tset_precision(hid_t type_id, size_t prec) HGOTO_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, "operation not defined for specified datatype") /* Do the work */ - if (H5T_set_precision(dt, prec) < 0) + if (H5T__set_precision(dt, prec) < 0) HGOTO_ERROR(H5E_DATATYPE, H5E_CANTSET, FAIL, "unable to set precision") done: @@ -161,7 +161,7 @@ done: } /*------------------------------------------------------------------------- - * Function: H5T_set_precision + * Function: H5T__set_precision * * Purpose: Sets the precision of a datatype. The precision is * the number of significant bits which, unless padding is @@ -186,12 +186,12 @@ done: *------------------------------------------------------------------------- */ static herr_t -H5T_set_precision(const H5T_t *dt, size_t prec) +H5T__set_precision(const H5T_t *dt, size_t prec) { size_t offset, size; herr_t ret_value = SUCCEED; /* Return value */ - FUNC_ENTER_NOAPI(FAIL) + FUNC_ENTER_STATIC /* Check args */ HDassert(dt); @@ -202,7 +202,7 @@ H5T_set_precision(const H5T_t *dt, size_t prec) HDassert(!(H5T_ENUM == dt->shared->type && 0 == dt->shared->u.enumer.nmembs)); if (dt->shared->parent) { - if (H5T_set_precision(dt->shared->parent, prec) < 0) + if (H5T__set_precision(dt->shared->parent, prec) < 0) HGOTO_ERROR(H5E_DATATYPE, H5E_CANTSET, FAIL, "unable to set precision for base type") /* Adjust size of datatype appropriately */ diff --git a/src/H5Tprivate.h b/src/H5Tprivate.h index e1d0f88..2507afc 100644 --- a/src/H5Tprivate.h +++ b/src/H5Tprivate.h @@ -41,11 +41,13 @@ typedef struct H5T_t H5T_t; #define H5T_GET_SHARED(T) ((T)->shared) #define H5T_GET_MEMBER_OFFSET(T, I) ((T)->u.compnd.memb[I].offset) #define H5T_GET_MEMBER_SIZE(T, I) ((T)->u.compnd.memb[I].shared->size) +#define H5T_GET_FORCE_CONV(T) ((T)->shared->force_conv) #else /* H5T_MODULE */ #define H5T_GET_SIZE(T) (H5T_get_size(T)) #define H5T_GET_SHARED(T) (H5T_get_shared(T)) #define H5T_GET_MEMBER_OFFSET(T, I) (H5T_get_member_offset((T), (I))) #define H5T_GET_MEMBER_SIZE(T, I) (H5T_get_member_size((T), (I))) +#define H5T_GET_FORCE_CONV(T) (H5T_get_force_conv(T)) #endif /* H5T_MODULE */ /* Forward references of package typedefs (declared in H5Tpkg.h) */ @@ -117,6 +119,7 @@ H5_DLL H5T_t * H5T_get_super(const H5T_t *dt); H5_DLL H5T_class_t H5T_get_class(const H5T_t *dt, htri_t internal); H5_DLL htri_t H5T_detect_class(const H5T_t *dt, H5T_class_t cls, hbool_t from_api); H5_DLL size_t H5T_get_size(const H5T_t *dt); +H5_DLL hbool_t H5T_get_force_conv(const H5T_t *dt); H5_DLL int H5T_cmp(const H5T_t *dt1, const H5T_t *dt2, hbool_t superset); H5_DLL herr_t H5T_encode(H5T_t *obj, unsigned char *buf, size_t *nalloc); H5_DLL H5T_t * H5T_decode(size_t buf_size, const unsigned char *buf); diff --git a/src/H5Tpublic.h b/src/H5Tpublic.h index 9855348..70a119d 100644 --- a/src/H5Tpublic.h +++ b/src/H5Tpublic.h @@ -23,197 +23,269 @@ #define HOFFSET(S, M) (offsetof(S, M)) -/* These are the various classes of datatypes */ -/* If this goes over 16 types (0-15), the file format will need to change) */ +/** + * These are the various classes of datatypes + * internal If this goes over 16 types (0-15), the file format will need to + * change. + */ +//! <!-- [H5T_class_t_snip] --> typedef enum H5T_class_t { - H5T_NO_CLASS = -1, /*error */ - H5T_INTEGER = 0, /*integer types */ - H5T_FLOAT = 1, /*floating-point types */ - H5T_TIME = 2, /*date and time types */ - H5T_STRING = 3, /*character string types */ - H5T_BITFIELD = 4, /*bit field types */ - H5T_OPAQUE = 5, /*opaque types */ - H5T_COMPOUND = 6, /*compound types */ - H5T_REFERENCE = 7, /*reference types */ - H5T_ENUM = 8, /*enumeration types */ - H5T_VLEN = 9, /*Variable-Length types */ - H5T_ARRAY = 10, /*Array types */ - - H5T_NCLASSES /*this must be last */ + H5T_NO_CLASS = -1, /**< error */ + H5T_INTEGER = 0, /**< integer types */ + H5T_FLOAT = 1, /**< floating-point types */ + H5T_TIME = 2, /**< date and time types */ + H5T_STRING = 3, /**< character string types */ + H5T_BITFIELD = 4, /**< bit field types */ + H5T_OPAQUE = 5, /**< opaque types */ + H5T_COMPOUND = 6, /**< compound types */ + H5T_REFERENCE = 7, /**< reference types */ + H5T_ENUM = 8, /**< enumeration types */ + H5T_VLEN = 9, /**< variable-Length types */ + H5T_ARRAY = 10, /**< array types */ + + H5T_NCLASSES /**< sentinel: this must be last */ } H5T_class_t; +//! <!-- [H5T_class_t_snip] --> -/* Byte orders */ +/** + * Byte orders + */ +//! <!-- [H5T_order_t_snip] --> typedef enum H5T_order_t { - H5T_ORDER_ERROR = -1, /*error */ - H5T_ORDER_LE = 0, /*little endian */ - H5T_ORDER_BE = 1, /*bit endian */ - H5T_ORDER_VAX = 2, /*VAX mixed endian */ - H5T_ORDER_MIXED = 3, /*Compound type with mixed member orders */ - H5T_ORDER_NONE = 4 /*no particular order (strings, bits,..) */ + H5T_ORDER_ERROR = -1, /**< error */ + H5T_ORDER_LE = 0, /**< little endian */ + H5T_ORDER_BE = 1, /**< bit endian */ + H5T_ORDER_VAX = 2, /**< VAX mixed endian */ + H5T_ORDER_MIXED = 3, /**< Compound type with mixed member orders */ + H5T_ORDER_NONE = 4 /**< no particular order (strings, bits,..) */ /*H5T_ORDER_NONE must be last */ } H5T_order_t; +//! <!-- [H5T_order_t_snip] --> -/* Types of integer sign schemes */ +/** + * Types of integer sign schemes + */ +//! <!-- [H5T_sign_t_snip] --> typedef enum H5T_sign_t { - H5T_SGN_ERROR = -1, /*error */ - H5T_SGN_NONE = 0, /*this is an unsigned type */ - H5T_SGN_2 = 1, /*two's complement */ + H5T_SGN_ERROR = -1, /**< error */ + H5T_SGN_NONE = 0, /**< this is an unsigned type */ + H5T_SGN_2 = 1, /**< two's complement */ - H5T_NSGN = 2 /*this must be last! */ + H5T_NSGN = 2 /** sentinel: this must be last! */ } H5T_sign_t; +//! <!-- [H5T_sign_t_snip] --> -/* Floating-point normalization schemes */ +/** + * Floating-point normalization schemes + */ +//! <!-- [H5T_norm_t_snip] --> typedef enum H5T_norm_t { - H5T_NORM_ERROR = -1, /*error */ - H5T_NORM_IMPLIED = 0, /*msb of mantissa isn't stored, always 1 */ - H5T_NORM_MSBSET = 1, /*msb of mantissa is always 1 */ - H5T_NORM_NONE = 2 /*not normalized */ + H5T_NORM_ERROR = -1, /**< error */ + H5T_NORM_IMPLIED = 0, /**< msb of mantissa isn't stored, always 1 */ + H5T_NORM_MSBSET = 1, /**< msb of mantissa is always 1 */ + H5T_NORM_NONE = 2 /**< not normalized */ /*H5T_NORM_NONE must be last */ } H5T_norm_t; +//! <!-- [H5T_norm_t_snip] --> -/* - * Character set to use for text strings. Do not change these values since - * they appear in HDF5 files! +/** + * Character set to use for text strings. + * \internal Do not change these values since they appear in HDF5 files! */ typedef enum H5T_cset_t { - H5T_CSET_ERROR = -1, /*error */ - H5T_CSET_ASCII = 0, /*US ASCII */ - H5T_CSET_UTF8 = 1, /*UTF-8 Unicode encoding */ - H5T_CSET_RESERVED_2 = 2, /*reserved for later use */ - H5T_CSET_RESERVED_3 = 3, /*reserved for later use */ - H5T_CSET_RESERVED_4 = 4, /*reserved for later use */ - H5T_CSET_RESERVED_5 = 5, /*reserved for later use */ - H5T_CSET_RESERVED_6 = 6, /*reserved for later use */ - H5T_CSET_RESERVED_7 = 7, /*reserved for later use */ - H5T_CSET_RESERVED_8 = 8, /*reserved for later use */ - H5T_CSET_RESERVED_9 = 9, /*reserved for later use */ - H5T_CSET_RESERVED_10 = 10, /*reserved for later use */ - H5T_CSET_RESERVED_11 = 11, /*reserved for later use */ - H5T_CSET_RESERVED_12 = 12, /*reserved for later use */ - H5T_CSET_RESERVED_13 = 13, /*reserved for later use */ - H5T_CSET_RESERVED_14 = 14, /*reserved for later use */ - H5T_CSET_RESERVED_15 = 15 /*reserved for later use */ + H5T_CSET_ERROR = -1, /**< error */ + H5T_CSET_ASCII = 0, /**< US ASCII */ + H5T_CSET_UTF8 = 1, /**< UTF-8 Unicode encoding */ + H5T_CSET_RESERVED_2 = 2, /**< reserved for later use */ + H5T_CSET_RESERVED_3 = 3, /**< reserved for later use */ + H5T_CSET_RESERVED_4 = 4, /**< reserved for later use */ + H5T_CSET_RESERVED_5 = 5, /**< reserved for later use */ + H5T_CSET_RESERVED_6 = 6, /**< reserved for later use */ + H5T_CSET_RESERVED_7 = 7, /**< reserved for later use */ + H5T_CSET_RESERVED_8 = 8, /**< reserved for later use */ + H5T_CSET_RESERVED_9 = 9, /**< reserved for later use */ + H5T_CSET_RESERVED_10 = 10, /**< reserved for later use */ + H5T_CSET_RESERVED_11 = 11, /**< reserved for later use */ + H5T_CSET_RESERVED_12 = 12, /**< reserved for later use */ + H5T_CSET_RESERVED_13 = 13, /**< reserved for later use */ + H5T_CSET_RESERVED_14 = 14, /**< reserved for later use */ + H5T_CSET_RESERVED_15 = 15 /**< reserved for later use */ } H5T_cset_t; #define H5T_NCSET H5T_CSET_RESERVED_2 /*Number of character sets actually defined */ -/* - * Type of padding to use in character strings. Do not change these values - * since they appear in HDF5 files! +/** + * Type of padding to use in character strings. + * \internal Do not change these values since they appear in HDF5 files! */ typedef enum H5T_str_t { - H5T_STR_ERROR = -1, /*error */ - H5T_STR_NULLTERM = 0, /*null terminate like in C */ - H5T_STR_NULLPAD = 1, /*pad with nulls */ - H5T_STR_SPACEPAD = 2, /*pad with spaces like in Fortran */ - H5T_STR_RESERVED_3 = 3, /*reserved for later use */ - H5T_STR_RESERVED_4 = 4, /*reserved for later use */ - H5T_STR_RESERVED_5 = 5, /*reserved for later use */ - H5T_STR_RESERVED_6 = 6, /*reserved for later use */ - H5T_STR_RESERVED_7 = 7, /*reserved for later use */ - H5T_STR_RESERVED_8 = 8, /*reserved for later use */ - H5T_STR_RESERVED_9 = 9, /*reserved for later use */ - H5T_STR_RESERVED_10 = 10, /*reserved for later use */ - H5T_STR_RESERVED_11 = 11, /*reserved for later use */ - H5T_STR_RESERVED_12 = 12, /*reserved for later use */ - H5T_STR_RESERVED_13 = 13, /*reserved for later use */ - H5T_STR_RESERVED_14 = 14, /*reserved for later use */ - H5T_STR_RESERVED_15 = 15 /*reserved for later use */ + H5T_STR_ERROR = -1, /**< error */ + H5T_STR_NULLTERM = 0, /**< null terminate like in C */ + H5T_STR_NULLPAD = 1, /**< pad with nulls */ + H5T_STR_SPACEPAD = 2, /**< pad with spaces like in Fortran */ + H5T_STR_RESERVED_3 = 3, /**< reserved for later use */ + H5T_STR_RESERVED_4 = 4, /**< reserved for later use */ + H5T_STR_RESERVED_5 = 5, /**< reserved for later use */ + H5T_STR_RESERVED_6 = 6, /**< reserved for later use */ + H5T_STR_RESERVED_7 = 7, /**< reserved for later use */ + H5T_STR_RESERVED_8 = 8, /**< reserved for later use */ + H5T_STR_RESERVED_9 = 9, /**< reserved for later use */ + H5T_STR_RESERVED_10 = 10, /**< reserved for later use */ + H5T_STR_RESERVED_11 = 11, /**< reserved for later use */ + H5T_STR_RESERVED_12 = 12, /**< reserved for later use */ + H5T_STR_RESERVED_13 = 13, /**< reserved for later use */ + H5T_STR_RESERVED_14 = 14, /**< reserved for later use */ + H5T_STR_RESERVED_15 = 15 /**< reserved for later use */ } H5T_str_t; #define H5T_NSTR H5T_STR_RESERVED_3 /*num H5T_str_t types actually defined */ -/* Type of padding to use in other atomic types */ +/** + * Type of padding to use in other atomic types + */ +//! <!-- [H5T_pad_t_snip] --> typedef enum H5T_pad_t { - H5T_PAD_ERROR = -1, /*error */ - H5T_PAD_ZERO = 0, /*always set to zero */ - H5T_PAD_ONE = 1, /*always set to one */ - H5T_PAD_BACKGROUND = 2, /*set to background value */ + H5T_PAD_ERROR = -1, /**< error */ + H5T_PAD_ZERO = 0, /**< always set to zero */ + H5T_PAD_ONE = 1, /**< always set to one */ + H5T_PAD_BACKGROUND = 2, /**< set to background value */ - H5T_NPAD = 3 /*THIS MUST BE LAST */ + H5T_NPAD = 3 /**< sentinal: THIS MUST BE LAST */ } H5T_pad_t; +//! <!-- [H5T_pad_t_snip] --> -/* Commands sent to conversion functions */ +/** + * Commands sent to conversion functions + */ typedef enum H5T_cmd_t { - H5T_CONV_INIT = 0, /*query and/or initialize private data */ - H5T_CONV_CONV = 1, /*convert data from source to dest datatype */ - H5T_CONV_FREE = 2 /*function is being removed from path */ + H5T_CONV_INIT = 0, /**< query and/or initialize private data */ + H5T_CONV_CONV = 1, /**< convert data from source to dest datatype */ + H5T_CONV_FREE = 2 /**< function is being removed from path */ } H5T_cmd_t; -/* How is the `bkg' buffer used by the conversion function? */ +/** + * How is the `bkg' buffer used by the conversion function? + */ typedef enum H5T_bkg_t { - H5T_BKG_NO = 0, /*background buffer is not needed, send NULL */ - H5T_BKG_TEMP = 1, /*bkg buffer used as temp storage only */ - H5T_BKG_YES = 2 /*init bkg buf with data before conversion */ + H5T_BKG_NO = 0, /**< background buffer is not needed, send NULL */ + H5T_BKG_TEMP = 1, /**< bkg buffer used as temp storage only */ + H5T_BKG_YES = 2 /**< init bkg buf with data before conversion */ } H5T_bkg_t; -/* Type conversion client data */ +/** + * Type conversion client data + */ +//! <!-- [H5T_cdata_t_snip] --> typedef struct H5T_cdata_t { - H5T_cmd_t command; /*what should the conversion function do? */ - H5T_bkg_t need_bkg; /*is the background buffer needed? */ - hbool_t recalc; /*recalculate private data */ - void * priv; /*private data */ + H5T_cmd_t command; /**< what should the conversion function do? */ + H5T_bkg_t need_bkg; /**< is the background buffer needed? */ + hbool_t recalc; /**< recalculate private data */ + void * priv; /**< private data */ } H5T_cdata_t; +//! <!-- [H5T_cdata_t_snip] --> -/* Conversion function persistence */ +/** + * Conversion function persistence + */ typedef enum H5T_pers_t { - H5T_PERS_DONTCARE = -1, /*wild card */ - H5T_PERS_HARD = 0, /*hard conversion function */ - H5T_PERS_SOFT = 1 /*soft conversion function */ + H5T_PERS_DONTCARE = -1, /**< wild card */ + H5T_PERS_HARD = 0, /**< hard conversion function */ + H5T_PERS_SOFT = 1 /**< soft conversion function */ } H5T_pers_t; -/* The order to retrieve atomic native datatype */ +/** + * The order to retrieve atomic native datatype + */ +//! <!-- [H5T_direction_t_snip] --> typedef enum H5T_direction_t { - H5T_DIR_DEFAULT = 0, /*default direction is inscendent */ - H5T_DIR_ASCEND = 1, /*in inscendent order */ - H5T_DIR_DESCEND = 2 /*in descendent order */ + H5T_DIR_DEFAULT = 0, /**< default direction is inscendent */ + H5T_DIR_ASCEND = 1, /**< in inscendent order */ + H5T_DIR_DESCEND = 2 /**< in descendent order */ } H5T_direction_t; +//! <!-- [H5T_direction_t_snip] --> -/* The exception type passed into the conversion callback function */ +/** + * The exception type passed into the conversion callback function + */ typedef enum H5T_conv_except_t { - H5T_CONV_EXCEPT_RANGE_HI = 0, /*source value is greater than destination's range */ - H5T_CONV_EXCEPT_RANGE_LOW = 1, /*source value is less than destination's range */ - H5T_CONV_EXCEPT_PRECISION = 2, /*source value loses precision in destination */ - H5T_CONV_EXCEPT_TRUNCATE = 3, /*source value is truncated in destination */ - H5T_CONV_EXCEPT_PINF = 4, /*source value is positive infinity(floating number) */ - H5T_CONV_EXCEPT_NINF = 5, /*source value is negative infinity(floating number) */ - H5T_CONV_EXCEPT_NAN = 6 /*source value is NaN(floating number) */ + H5T_CONV_EXCEPT_RANGE_HI = 0, + /**< Source value is greater than destination's range */ + H5T_CONV_EXCEPT_RANGE_LOW = 1, + /**< Source value is less than destination's range */ + H5T_CONV_EXCEPT_PRECISION = 2, + /**< Source value loses precision in destination */ + H5T_CONV_EXCEPT_TRUNCATE = 3, + /**< Source value is truncated in destination */ + H5T_CONV_EXCEPT_PINF = 4, + /**< Source value is positive infinity */ + H5T_CONV_EXCEPT_NINF = 5, + /**< Source value is negative infinity */ + H5T_CONV_EXCEPT_NAN = 6 + /**< Source value is \c NaN (not a number, including \c QNaN and \c SNaN) */ } H5T_conv_except_t; -/* The return value from conversion callback function H5T_conv_except_func_t */ +/** + * The return value from conversion callback function H5T_conv_except_func_t() + */ typedef enum H5T_conv_ret_t { - H5T_CONV_ABORT = -1, /*abort conversion */ - H5T_CONV_UNHANDLED = 0, /*callback function failed to handle the exception */ - H5T_CONV_HANDLED = 1 /*callback function handled the exception successfully */ + H5T_CONV_ABORT = -1, /**< abort conversion */ + H5T_CONV_UNHANDLED = 0, /**< callback function failed to handle the exception */ + H5T_CONV_HANDLED = 1 /**< callback function handled the exception successfully */ } H5T_conv_ret_t; -/* Variable Length Datatype struct in memory */ -/* (This is only used for VL sequences, not VL strings, which are stored in char *'s) */ +/** + * Variable Length Datatype struct in memory (This is only used for VL + * sequences, not VL strings, which are stored in char *'s) + */ typedef struct { - size_t len; /* Length of VL data (in base type units) */ - void * p; /* Pointer to VL data */ + size_t len; /**< Length of VL data (in base type units) */ + void * p; /**< Pointer to VL data */ } hvl_t; /* Variable Length String information */ -#define H5T_VARIABLE \ - ((size_t)( \ - -1)) /* Indicate that a string is variable length (null-terminated in C, instead of fixed length) */ +/** + * Indicate that a string is variable length (null-terminated in C, instead of + * fixed length) + */ +#define H5T_VARIABLE SIZE_MAX /* Opaque information */ -#define H5T_OPAQUE_TAG_MAX 256 /* Maximum length of an opaque tag */ - /* This could be raised without too much difficulty */ +/** + * Maximum length of an opaque tag + * \internal This could be raised without too much difficulty + */ +#define H5T_OPAQUE_TAG_MAX 256 #ifdef __cplusplus extern "C" { #endif -/* All datatype conversion functions are... */ +/** + * All datatype conversion functions are... + */ +//! <!-- [H5T_conv_t_snip] --> typedef herr_t (*H5T_conv_t)(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, size_t buf_stride, size_t bkg_stride, void *buf, void *bkg, hid_t dset_xfer_plist); +//! <!-- [H5T_conv_t_snip] --> -/* Exception handler. If an exception like overflow happenes during conversion, - * this function is called if it's registered through H5Pset_type_conv_cb. +//! <!-- [H5T_conv_except_func_t_snip] --> +/** + * \brief Exception handler. + * + * \param[in] except_type The kind of exception that occurred + * \param[in] src_id Source datatype identifier + * \param[in] dst_id Destination datatype identifier + * \param[in] src_buf Source data buffer + * \param[in,out] dst_buf Destination data buffer + * \param[in,out] user_data Callback context + * \returns Valid callback function return values are #H5T_CONV_ABORT, + * #H5T_CONV_UNHANDLED and #H5T_CONV_HANDLED. + * + * \details If an exception like overflow happenes during conversion, this + * function is called if it's registered through H5Pset_type_conv_cb(). + * */ typedef H5T_conv_ret_t (*H5T_conv_except_func_t)(H5T_conv_except_t except_type, hid_t src_id, hid_t dst_id, void *src_buf, void *dst_buf, void *user_data); +//! <!-- [H5T_conv_except_func_t_snip] --> /* When this header is included from a private header, don't make calls to H5open() */ #undef H5OPEN @@ -226,9 +298,25 @@ typedef H5T_conv_ret_t (*H5T_conv_except_func_t)(H5T_conv_except_t except_type, /* * The IEEE floating point types in various byte orders. */ +/** + * \ingroup PDTIEEE + * 32-bit big-endian IEEE floating-point numbers + */ #define H5T_IEEE_F32BE (H5OPEN H5T_IEEE_F32BE_g) +/** + * \ingroup PDTIEEE + * 32-bit little-endian IEEE floating-point numbers + */ #define H5T_IEEE_F32LE (H5OPEN H5T_IEEE_F32LE_g) +/** + * \ingroup PDTIEEE + * 64-bit big-endian IEEE floating-point numbers + */ #define H5T_IEEE_F64BE (H5OPEN H5T_IEEE_F64BE_g) +/** + * \ingroup PDTIEEE + * 64-bit little-endian IEEE floating-point numbers + */ #define H5T_IEEE_F64LE (H5OPEN H5T_IEEE_F64LE_g) H5_DLLVAR hid_t H5T_IEEE_F32BE_g; H5_DLLVAR hid_t H5T_IEEE_F32LE_g; @@ -239,33 +327,141 @@ H5_DLLVAR hid_t H5T_IEEE_F64LE_g; * These are "standard" types. For instance, signed (2's complement) and * unsigned integers of various sizes and byte orders. */ -#define H5T_STD_I8BE (H5OPEN H5T_STD_I8BE_g) -#define H5T_STD_I8LE (H5OPEN H5T_STD_I8LE_g) -#define H5T_STD_I16BE (H5OPEN H5T_STD_I16BE_g) -#define H5T_STD_I16LE (H5OPEN H5T_STD_I16LE_g) -#define H5T_STD_I32BE (H5OPEN H5T_STD_I32BE_g) -#define H5T_STD_I32LE (H5OPEN H5T_STD_I32LE_g) -#define H5T_STD_I64BE (H5OPEN H5T_STD_I64BE_g) -#define H5T_STD_I64LE (H5OPEN H5T_STD_I64LE_g) -#define H5T_STD_U8BE (H5OPEN H5T_STD_U8BE_g) -#define H5T_STD_U8LE (H5OPEN H5T_STD_U8LE_g) -#define H5T_STD_U16BE (H5OPEN H5T_STD_U16BE_g) -#define H5T_STD_U16LE (H5OPEN H5T_STD_U16LE_g) -#define H5T_STD_U32BE (H5OPEN H5T_STD_U32BE_g) -#define H5T_STD_U32LE (H5OPEN H5T_STD_U32LE_g) -#define H5T_STD_U64BE (H5OPEN H5T_STD_U64BE_g) -#define H5T_STD_U64LE (H5OPEN H5T_STD_U64LE_g) -#define H5T_STD_B8BE (H5OPEN H5T_STD_B8BE_g) -#define H5T_STD_B8LE (H5OPEN H5T_STD_B8LE_g) -#define H5T_STD_B16BE (H5OPEN H5T_STD_B16BE_g) -#define H5T_STD_B16LE (H5OPEN H5T_STD_B16LE_g) -#define H5T_STD_B32BE (H5OPEN H5T_STD_B32BE_g) -#define H5T_STD_B32LE (H5OPEN H5T_STD_B32LE_g) -#define H5T_STD_B64BE (H5OPEN H5T_STD_B64BE_g) -#define H5T_STD_B64LE (H5OPEN H5T_STD_B64LE_g) -#define H5T_STD_REF_OBJ (H5OPEN H5T_STD_REF_OBJ_g) +/** + * \ingroup PDTSTD + * 8-bit big-endian signed integers + */ +#define H5T_STD_I8BE (H5OPEN H5T_STD_I8BE_g) +/** + * \ingroup PDTSTD + * 8-bit little-endian signed integers + */ +#define H5T_STD_I8LE (H5OPEN H5T_STD_I8LE_g) +/** + * \ingroup PDTSTD + * 16-bit big-endian signed integers + */ +#define H5T_STD_I16BE (H5OPEN H5T_STD_I16BE_g) +/** + * \ingroup PDTSTD + * 16-bit little-endian signed integers + */ +#define H5T_STD_I16LE (H5OPEN H5T_STD_I16LE_g) +/** + * \ingroup PDTSTD + * 32-bit big-endian signed integers + */ +#define H5T_STD_I32BE (H5OPEN H5T_STD_I32BE_g) +/** + * \ingroup PDTSTD + * 32-bit little-endian signed integers + */ +#define H5T_STD_I32LE (H5OPEN H5T_STD_I32LE_g) +/** + * \ingroup PDTSTD + * 64-bit big-endian signed integers + */ +#define H5T_STD_I64BE (H5OPEN H5T_STD_I64BE_g) +/** + * \ingroup PDTSTD + * 64-bit little-endian signed integers + */ +#define H5T_STD_I64LE (H5OPEN H5T_STD_I64LE_g) +/** + * \ingroup PDTSTD + * 8-bit big-endian unsigned integers + */ +#define H5T_STD_U8BE (H5OPEN H5T_STD_U8BE_g) +/** + * \ingroup PDTSTD + * 8-bit little-endian unsigned integers + */ +#define H5T_STD_U8LE (H5OPEN H5T_STD_U8LE_g) +/** + * \ingroup PDTSTD + * 16-bit big-endian unsigned integers + */ +#define H5T_STD_U16BE (H5OPEN H5T_STD_U16BE_g) +/** + * \ingroup PDTSTD + * 16-bit little-endian unsigned integers + */ +#define H5T_STD_U16LE (H5OPEN H5T_STD_U16LE_g) +/** + * \ingroup PDTSTD + * 32-bit big-endian unsigned integers + */ +#define H5T_STD_U32BE (H5OPEN H5T_STD_U32BE_g) +/** + * \ingroup PDTSTD + * 32-bit little-endian unsigned integers + */ +#define H5T_STD_U32LE (H5OPEN H5T_STD_U32LE_g) +/** + * \ingroup PDTSTD + * 64-bit big-endian unsigned integers + */ +#define H5T_STD_U64BE (H5OPEN H5T_STD_U64BE_g) +/** + * \ingroup PDTSTD + * 64-bit little-endian unsigned integers + */ +#define H5T_STD_U64LE (H5OPEN H5T_STD_U64LE_g) +/** + * \ingroup PDTSTD + * 8-bit big-endian bitfield + */ +#define H5T_STD_B8BE (H5OPEN H5T_STD_B8BE_g) +/** + * \ingroup PDTSTD + * 8-bit little-endian bitfield + */ +#define H5T_STD_B8LE (H5OPEN H5T_STD_B8LE_g) +/** + * \ingroup PDTSTD + * 16-bit big-endian bitfield + */ +#define H5T_STD_B16BE (H5OPEN H5T_STD_B16BE_g) +/** + * \ingroup PDTSTD + * 16-bit little-endian bitfield + */ +#define H5T_STD_B16LE (H5OPEN H5T_STD_B16LE_g) +/** + * \ingroup PDTSTD + * 32-bit big-endian bitfield + */ +#define H5T_STD_B32BE (H5OPEN H5T_STD_B32BE_g) +/** + * \ingroup PDTSTD + * 32-bit little-endian bitfield + */ +#define H5T_STD_B32LE (H5OPEN H5T_STD_B32LE_g) +/** + * \ingroup PDTSTD + * 64-bit big-endian bitfield + */ +#define H5T_STD_B64BE (H5OPEN H5T_STD_B64BE_g) +/** + * \ingroup PDTSTD + * 64-bit little-endian bitfield + */ +#define H5T_STD_B64LE (H5OPEN H5T_STD_B64LE_g) +/** + * \ingroup PDTSTD + * Object reference + */ +#define H5T_STD_REF_OBJ (H5OPEN H5T_STD_REF_OBJ_g) +/** + * \ingroup PDTSTD + * Dataset region reference + */ #define H5T_STD_REF_DSETREG (H5OPEN H5T_STD_REF_DSETREG_g) -#define H5T_STD_REF (H5OPEN H5T_STD_REF_g) +/** + * \ingroup PDTSTD + * Generic reference + */ +#define H5T_STD_REF (H5OPEN H5T_STD_REF_g) H5_DLLVAR hid_t H5T_STD_I8BE_g; H5_DLLVAR hid_t H5T_STD_I8LE_g; H5_DLLVAR hid_t H5T_STD_I16BE_g; @@ -297,9 +493,21 @@ H5_DLLVAR hid_t H5T_STD_REF_g; /* * Types which are particular to Unix. */ +/** + * \ingroup PDTUNIX + */ #define H5T_UNIX_D32BE (H5OPEN H5T_UNIX_D32BE_g) +/** + * \ingroup PDTUNIX + */ #define H5T_UNIX_D32LE (H5OPEN H5T_UNIX_D32LE_g) +/** + * \ingroup PDTUNIX + */ #define H5T_UNIX_D64BE (H5OPEN H5T_UNIX_D64BE_g) +/** + * \ingroup PDTUNIX + */ #define H5T_UNIX_D64LE (H5OPEN H5T_UNIX_D64LE_g) H5_DLLVAR hid_t H5T_UNIX_D32BE_g; H5_DLLVAR hid_t H5T_UNIX_D32LE_g; @@ -310,12 +518,20 @@ H5_DLLVAR hid_t H5T_UNIX_D64LE_g; * Types particular to the C language. String types use `bytes' instead * of `bits' as their size. */ +/** + * \ingroup PDTS + * String datatype in C (size defined in bytes rather than in bits) + */ #define H5T_C_S1 (H5OPEN H5T_C_S1_g) H5_DLLVAR hid_t H5T_C_S1_g; /* * Types particular to Fortran. */ +/** + * \ingroup PDTS + * String datatype in Fortran (as defined for the HDF5 C library) + */ #define H5T_FORTRAN_S1 (H5OPEN H5T_FORTRAN_S1_g) H5_DLLVAR hid_t H5T_FORTRAN_S1_g; @@ -323,63 +539,239 @@ H5_DLLVAR hid_t H5T_FORTRAN_S1_g; * These types are for Intel CPU's. They are little endian with IEEE * floating point. */ -#define H5T_INTEL_I8 H5T_STD_I8LE +/** + * \ingroup PDTX86 + * 8-bit little-endian signed (2's complement) integers for Intel CPUs + */ +#define H5T_INTEL_I8 H5T_STD_I8LE +/** + * \ingroup PDTX86 + * 16-bit little-endian signed (2's complement) integers for Intel CPUs + */ #define H5T_INTEL_I16 H5T_STD_I16LE +/** + * \ingroup PDTX86 + * 32-bit little-endian signed (2's complement) integers for Intel CPUs + */ #define H5T_INTEL_I32 H5T_STD_I32LE +/** + * \ingroup PDTX86 + * 64-bit little-endian signed (2's complement) integers for Intel CPUs + */ #define H5T_INTEL_I64 H5T_STD_I64LE -#define H5T_INTEL_U8 H5T_STD_U8LE +/** + * \ingroup PDTX86 + * 8-bit little-endian unsigned integers for Intel CPUs + */ +#define H5T_INTEL_U8 H5T_STD_U8LE +/** + * \ingroup PDTX86 + * 16-bit little-endian unsigned integers for Intel CPUs + */ #define H5T_INTEL_U16 H5T_STD_U16LE +/** + * \ingroup PDTX86 + * 32-bit little-endian unsigned integers for Intel CPUs + */ #define H5T_INTEL_U32 H5T_STD_U32LE +/** + * \ingroup PDTX86 + * 64-bit little-endian unsigned integers for Intel CPUs + */ #define H5T_INTEL_U64 H5T_STD_U64LE -#define H5T_INTEL_B8 H5T_STD_B8LE +/** + * \ingroup PDTX86 + * 8-bit little-endian bitfield for Intel CPUs + */ +#define H5T_INTEL_B8 H5T_STD_B8LE +/** + * \ingroup PDTX86 + * 16-bit little-endian bitfield for Intel CPUs + */ #define H5T_INTEL_B16 H5T_STD_B16LE +/** + * \ingroup PDTX86 + * 32-bit little-endian bitfield for Intel CPUs + */ #define H5T_INTEL_B32 H5T_STD_B32LE +/** + * \ingroup PDTX86 + * 64-bit little-endian bitfield for Intel CPUs + */ #define H5T_INTEL_B64 H5T_STD_B64LE +/** + * \ingroup PDTX86 + * 32-bit little-endian IEEE floating-point numbers for Intel CPUs + */ #define H5T_INTEL_F32 H5T_IEEE_F32LE +/** + * \ingroup PDTX86 + * 64-bit little-endian IEEE floating-point numbers for Intel CPUs + */ #define H5T_INTEL_F64 H5T_IEEE_F64LE /* * These types are for DEC Alpha CPU's. They are little endian with IEEE * floating point. */ -#define H5T_ALPHA_I8 H5T_STD_I8LE +/** + * \ingroup PDTALPHA + * 8-bit little-endian signed (2's complement) integers for DEC Alpha CPUs + */ +#define H5T_ALPHA_I8 H5T_STD_I8LE +/** + * \ingroup PDTALPHA + * 16-bit little-endian signed (2's complement) integers for DEC Alpha CPUs + */ #define H5T_ALPHA_I16 H5T_STD_I16LE +/** + * \ingroup PDTALPHA + * 32-bit little-endian signed (2's complement) integers for DEC Alpha CPUs + */ #define H5T_ALPHA_I32 H5T_STD_I32LE +/** + * \ingroup PDTALPHA + * 64-bit little-endian signed (2's complement) integers for DEC Alpha CPUs + */ #define H5T_ALPHA_I64 H5T_STD_I64LE -#define H5T_ALPHA_U8 H5T_STD_U8LE +/** + * \ingroup PDTALPHA + * 8-bit little-endian unsigned integers for DEC Alpha CPUs + */ +#define H5T_ALPHA_U8 H5T_STD_U8LE +/** + * \ingroup PDTALPHA + * 16-bit little-endian unsigned integers for DEC Alpha CPUs + */ #define H5T_ALPHA_U16 H5T_STD_U16LE +/** + * \ingroup PDTALPHA + * 32-bit little-endian unsigned integers for DEC Alpha CPUs + */ #define H5T_ALPHA_U32 H5T_STD_U32LE +/** + * \ingroup PDTALPHA + * 64-bit little-endian unsigned integers for DEC Alpha CPUs + */ #define H5T_ALPHA_U64 H5T_STD_U64LE -#define H5T_ALPHA_B8 H5T_STD_B8LE +/** + * \ingroup PDTALPHA + * 8-bit little-endian bitfield for DEC Alpha CPUs + */ +#define H5T_ALPHA_B8 H5T_STD_B8LE +/** + * \ingroup PDTALPHA + * 16-bit little-endian bitfield for DEC Alpha CPUs + */ #define H5T_ALPHA_B16 H5T_STD_B16LE +/** + * \ingroup PDTALPHA + * 32-bit little-endian bitfield for DEC Alpha CPUs + */ #define H5T_ALPHA_B32 H5T_STD_B32LE +/** + * \ingroup PDTALPHA + * 64-bit little-endian bitfield for DEC Alpha CPUs + */ #define H5T_ALPHA_B64 H5T_STD_B64LE +/** + * \ingroup PDTALPHA + * 32-bit little-endian IEEE floating-point numbers for DEC Alpha CPUs + */ #define H5T_ALPHA_F32 H5T_IEEE_F32LE +/** + * \ingroup PDTALPHA + * 64-bit little-endian IEEE floating-point numbers for DEC Alpha CPUs + */ #define H5T_ALPHA_F64 H5T_IEEE_F64LE /* * These types are for MIPS cpu's commonly used in SGI systems. They are big * endian with IEEE floating point. */ -#define H5T_MIPS_I8 H5T_STD_I8BE +/** + * \ingroup PDTMIPS + * 8-bit big-endian signed (2's complement) integers for SGI MIPS CPUs + */ +#define H5T_MIPS_I8 H5T_STD_I8BE +/** + * \ingroup PDTMIPS + * 16-bit big-endian signed (2's complement) integers for SGI MIPS CPUs + */ #define H5T_MIPS_I16 H5T_STD_I16BE +/** + * \ingroup PDTMIPS + * 32-bit big-endian signed (2's complement) integers for SGI MIPS CPUs + */ #define H5T_MIPS_I32 H5T_STD_I32BE +/** + * \ingroup PDTMIPS + * 64-bit big-endian signed (2's complement) integers for SGI MIPS CPUs + */ #define H5T_MIPS_I64 H5T_STD_I64BE -#define H5T_MIPS_U8 H5T_STD_U8BE +/** + * \ingroup PDTMIPS + * 8-bit big-endian unsigned integers for SGI MIPS CPUs + */ +#define H5T_MIPS_U8 H5T_STD_U8BE +/** + * \ingroup PDTMIPS + * 16-bit big-endian unsigned integers for SGI MIPS CPUs + */ #define H5T_MIPS_U16 H5T_STD_U16BE +/** + * \ingroup PDTMIPS + * 32-bit big-endian unsigned integers for SGI MIPS CPUs + */ #define H5T_MIPS_U32 H5T_STD_U32BE +/** + * \ingroup PDTMIPS + * 64-bit big-endian unsigned integers for SGI MIPS CPUs + */ #define H5T_MIPS_U64 H5T_STD_U64BE -#define H5T_MIPS_B8 H5T_STD_B8BE +/** + * \ingroup PDTMIPS + * 8-bit big-endian bitfield for SGI MIPS CPUs + */ +#define H5T_MIPS_B8 H5T_STD_B8BE +/** + * \ingroup PDTMIPS + * 16-bit big-endian bitfield for SGI MIPS CPUs + */ #define H5T_MIPS_B16 H5T_STD_B16BE +/** + * \ingroup PDTMIPS + * 32-bit big-endian bitfield for SGI MIPS CPUs + */ #define H5T_MIPS_B32 H5T_STD_B32BE +/** + * \ingroup PDTMIPS + * 64-bit big-endian bitfield for SGI MIPS CPUs + */ #define H5T_MIPS_B64 H5T_STD_B64BE +/** + * \ingroup PDTMIPS + * 32-bit big-endian IEEE floating-point numbers for MIPS CPUs + */ #define H5T_MIPS_F32 H5T_IEEE_F32BE +/** + * \ingroup PDTMIPS + * 64-bit big-endian IEEE floating-point numbers for MIPS CPUs + */ #define H5T_MIPS_F64 H5T_IEEE_F64BE /* * The VAX floating point types (i.e. in VAX byte order) */ +/** + * \ingroup PDTALPHA + * 32-bit VAX byte order floating-point numbers for OpenVMS on DEC Alpha CPUs + */ #define H5T_VAX_F32 (H5OPEN H5T_VAX_F32_g) +/** + * \ingroup PDTALPHA + * 64-bit VAX byte order floating-point numbers for OpenVMS on DEC Alpha CPUs + */ #define H5T_VAX_F64 (H5OPEN H5T_VAX_F64_g) H5_DLLVAR hid_t H5T_VAX_F32_g; H5_DLLVAR hid_t H5T_VAX_F64_g; @@ -393,32 +785,128 @@ H5_DLLVAR hid_t H5T_VAX_F64_g; * to C's `long long' and LDOUBLE is `long double' (these types might be the * same as `LONG' and `DOUBLE' respectively). */ -#define H5T_NATIVE_CHAR (CHAR_MIN ? H5T_NATIVE_SCHAR : H5T_NATIVE_UCHAR) -#define H5T_NATIVE_SCHAR (H5OPEN H5T_NATIVE_SCHAR_g) -#define H5T_NATIVE_UCHAR (H5OPEN H5T_NATIVE_UCHAR_g) -#define H5T_NATIVE_SHORT (H5OPEN H5T_NATIVE_SHORT_g) +/** + * \ingroup PDTNAT + * C-style \c char + */ +#define H5T_NATIVE_CHAR (CHAR_MIN ? H5T_NATIVE_SCHAR : H5T_NATIVE_UCHAR) +/** + * \ingroup PDTNAT + * C-style \Code{signed char} + */ +#define H5T_NATIVE_SCHAR (H5OPEN H5T_NATIVE_SCHAR_g) +/** + * \ingroup PDTNAT + * C-style \Code{unsigned char} + */ +#define H5T_NATIVE_UCHAR (H5OPEN H5T_NATIVE_UCHAR_g) +/** + * \ingroup PDTNAT + * C-style \Code{short} + */ +#define H5T_NATIVE_SHORT (H5OPEN H5T_NATIVE_SHORT_g) +/** + * \ingroup PDTNAT + * C-style \Code{unsigned short} + */ #define H5T_NATIVE_USHORT (H5OPEN H5T_NATIVE_USHORT_g) -#define H5T_NATIVE_INT (H5OPEN H5T_NATIVE_INT_g) -#define H5T_NATIVE_UINT (H5OPEN H5T_NATIVE_UINT_g) -#define H5T_NATIVE_LONG (H5OPEN H5T_NATIVE_LONG_g) -#define H5T_NATIVE_ULONG (H5OPEN H5T_NATIVE_ULONG_g) -#define H5T_NATIVE_LLONG (H5OPEN H5T_NATIVE_LLONG_g) +/** + * \ingroup PDTNAT + * C-style \Code{int} + */ +#define H5T_NATIVE_INT (H5OPEN H5T_NATIVE_INT_g) +/** + * \ingroup PDTNAT + * C-style \Code{unsigned int} + */ +#define H5T_NATIVE_UINT (H5OPEN H5T_NATIVE_UINT_g) +/** + * \ingroup PDTNAT + * C-style \Code{long} + */ +#define H5T_NATIVE_LONG (H5OPEN H5T_NATIVE_LONG_g) +/** + * \ingroup PDTNAT + * C-style \Code{unsigned long} + */ +#define H5T_NATIVE_ULONG (H5OPEN H5T_NATIVE_ULONG_g) +/** + * \ingroup PDTNAT + * C-style \Code{long long} + */ +#define H5T_NATIVE_LLONG (H5OPEN H5T_NATIVE_LLONG_g) +/** + * \ingroup PDTNAT + * C-style \Code{unsigned long long} + */ #define H5T_NATIVE_ULLONG (H5OPEN H5T_NATIVE_ULLONG_g) -#define H5T_NATIVE_FLOAT (H5OPEN H5T_NATIVE_FLOAT_g) +/** + * \ingroup PDTNAT + * C-style \Code{float} + */ +#define H5T_NATIVE_FLOAT (H5OPEN H5T_NATIVE_FLOAT_g) +/** + * \ingroup PDTNAT + * C-style \Code{double} + */ #define H5T_NATIVE_DOUBLE (H5OPEN H5T_NATIVE_DOUBLE_g) #if H5_SIZEOF_LONG_DOUBLE != 0 +/** + * \ingroup PDTNAT + * C-style \Code{long double} + */ #define H5T_NATIVE_LDOUBLE (H5OPEN H5T_NATIVE_LDOUBLE_g) #endif -#define H5T_NATIVE_B8 (H5OPEN H5T_NATIVE_B8_g) -#define H5T_NATIVE_B16 (H5OPEN H5T_NATIVE_B16_g) -#define H5T_NATIVE_B32 (H5OPEN H5T_NATIVE_B32_g) -#define H5T_NATIVE_B64 (H5OPEN H5T_NATIVE_B64_g) +/** + * \ingroup PDTNAT + * HDF5 8-bit bitfield based on native types + */ +#define H5T_NATIVE_B8 (H5OPEN H5T_NATIVE_B8_g) +/** + * \ingroup PDTNAT + * HDF5 16-bit bitfield based on native types + */ +#define H5T_NATIVE_B16 (H5OPEN H5T_NATIVE_B16_g) +/** + * \ingroup PDTNAT + * HDF5 32-bit bitfield based on native types + */ +#define H5T_NATIVE_B32 (H5OPEN H5T_NATIVE_B32_g) +/** + * \ingroup PDTNAT + * HDF5 64-bit bitfield based on native types + */ +#define H5T_NATIVE_B64 (H5OPEN H5T_NATIVE_B64_g) +/** + * \ingroup PDTNAT + * HDF5 opaque unit based on native types + */ #define H5T_NATIVE_OPAQUE (H5OPEN H5T_NATIVE_OPAQUE_g) -#define H5T_NATIVE_HADDR (H5OPEN H5T_NATIVE_HADDR_g) -#define H5T_NATIVE_HSIZE (H5OPEN H5T_NATIVE_HSIZE_g) +/** + * \ingroup PDTNAT + * HDF5 address type based on native types + */ +#define H5T_NATIVE_HADDR (H5OPEN H5T_NATIVE_HADDR_g) +/** + * \ingroup PDTNAT + * HDF5 size type based on native types + */ +#define H5T_NATIVE_HSIZE (H5OPEN H5T_NATIVE_HSIZE_g) +/** + * \ingroup PDTNAT + * HDF5 signed size type based on native types + */ #define H5T_NATIVE_HSSIZE (H5OPEN H5T_NATIVE_HSSIZE_g) -#define H5T_NATIVE_HERR (H5OPEN H5T_NATIVE_HERR_g) -#define H5T_NATIVE_HBOOL (H5OPEN H5T_NATIVE_HBOOL_g) +/** + * \ingroup PDTNAT + * HDF5 error code type based on native types + */ +#define H5T_NATIVE_HERR (H5OPEN H5T_NATIVE_HERR_g) +/** + * \ingroup PDTNAT + * HDF5 Boolean type based on native types + */ +#define H5T_NATIVE_HBOOL (H5OPEN H5T_NATIVE_HBOOL_g) H5_DLLVAR hid_t H5T_NATIVE_SCHAR_g; H5_DLLVAR hid_t H5T_NATIVE_UCHAR_g; H5_DLLVAR hid_t H5T_NATIVE_SHORT_g; @@ -446,12 +934,30 @@ H5_DLLVAR hid_t H5T_NATIVE_HERR_g; H5_DLLVAR hid_t H5T_NATIVE_HBOOL_g; /* C9x integer types */ -#define H5T_NATIVE_INT8 (H5OPEN H5T_NATIVE_INT8_g) -#define H5T_NATIVE_UINT8 (H5OPEN H5T_NATIVE_UINT8_g) -#define H5T_NATIVE_INT_LEAST8 (H5OPEN H5T_NATIVE_INT_LEAST8_g) +/** + * \ingroup PDTC9x + */ +#define H5T_NATIVE_INT8 (H5OPEN H5T_NATIVE_INT8_g) +/** + * \ingroup PDTC9x + */ +#define H5T_NATIVE_UINT8 (H5OPEN H5T_NATIVE_UINT8_g) +/** + * \ingroup PDTC9x + */ +#define H5T_NATIVE_INT_LEAST8 (H5OPEN H5T_NATIVE_INT_LEAST8_g) +/** + * \ingroup PDTC9x + */ #define H5T_NATIVE_UINT_LEAST8 (H5OPEN H5T_NATIVE_UINT_LEAST8_g) -#define H5T_NATIVE_INT_FAST8 (H5OPEN H5T_NATIVE_INT_FAST8_g) -#define H5T_NATIVE_UINT_FAST8 (H5OPEN H5T_NATIVE_UINT_FAST8_g) +/** + * \ingroup PDTC9x + */ +#define H5T_NATIVE_INT_FAST8 (H5OPEN H5T_NATIVE_INT_FAST8_g) +/** + * \ingroup PDTC9x + */ +#define H5T_NATIVE_UINT_FAST8 (H5OPEN H5T_NATIVE_UINT_FAST8_g) H5_DLLVAR hid_t H5T_NATIVE_INT8_g; H5_DLLVAR hid_t H5T_NATIVE_UINT8_g; H5_DLLVAR hid_t H5T_NATIVE_INT_LEAST8_g; @@ -459,12 +965,30 @@ H5_DLLVAR hid_t H5T_NATIVE_UINT_LEAST8_g; H5_DLLVAR hid_t H5T_NATIVE_INT_FAST8_g; H5_DLLVAR hid_t H5T_NATIVE_UINT_FAST8_g; -#define H5T_NATIVE_INT16 (H5OPEN H5T_NATIVE_INT16_g) -#define H5T_NATIVE_UINT16 (H5OPEN H5T_NATIVE_UINT16_g) -#define H5T_NATIVE_INT_LEAST16 (H5OPEN H5T_NATIVE_INT_LEAST16_g) +/** + * \ingroup PDTC9x + */ +#define H5T_NATIVE_INT16 (H5OPEN H5T_NATIVE_INT16_g) +/** + * \ingroup PDTC9x + */ +#define H5T_NATIVE_UINT16 (H5OPEN H5T_NATIVE_UINT16_g) +/** + * \ingroup PDTC9x + */ +#define H5T_NATIVE_INT_LEAST16 (H5OPEN H5T_NATIVE_INT_LEAST16_g) +/** + * \ingroup PDTC9x + */ #define H5T_NATIVE_UINT_LEAST16 (H5OPEN H5T_NATIVE_UINT_LEAST16_g) -#define H5T_NATIVE_INT_FAST16 (H5OPEN H5T_NATIVE_INT_FAST16_g) -#define H5T_NATIVE_UINT_FAST16 (H5OPEN H5T_NATIVE_UINT_FAST16_g) +/** + * \ingroup PDTC9x + */ +#define H5T_NATIVE_INT_FAST16 (H5OPEN H5T_NATIVE_INT_FAST16_g) +/** + * \ingroup PDTC9x + */ +#define H5T_NATIVE_UINT_FAST16 (H5OPEN H5T_NATIVE_UINT_FAST16_g) H5_DLLVAR hid_t H5T_NATIVE_INT16_g; H5_DLLVAR hid_t H5T_NATIVE_UINT16_g; H5_DLLVAR hid_t H5T_NATIVE_INT_LEAST16_g; @@ -472,12 +996,30 @@ H5_DLLVAR hid_t H5T_NATIVE_UINT_LEAST16_g; H5_DLLVAR hid_t H5T_NATIVE_INT_FAST16_g; H5_DLLVAR hid_t H5T_NATIVE_UINT_FAST16_g; -#define H5T_NATIVE_INT32 (H5OPEN H5T_NATIVE_INT32_g) -#define H5T_NATIVE_UINT32 (H5OPEN H5T_NATIVE_UINT32_g) -#define H5T_NATIVE_INT_LEAST32 (H5OPEN H5T_NATIVE_INT_LEAST32_g) +/** + * \ingroup PDTC9x + */ +#define H5T_NATIVE_INT32 (H5OPEN H5T_NATIVE_INT32_g) +/** + * \ingroup PDTC9x + */ +#define H5T_NATIVE_UINT32 (H5OPEN H5T_NATIVE_UINT32_g) +/** + * \ingroup PDTC9x + */ +#define H5T_NATIVE_INT_LEAST32 (H5OPEN H5T_NATIVE_INT_LEAST32_g) +/** + * \ingroup PDTC9x + */ #define H5T_NATIVE_UINT_LEAST32 (H5OPEN H5T_NATIVE_UINT_LEAST32_g) -#define H5T_NATIVE_INT_FAST32 (H5OPEN H5T_NATIVE_INT_FAST32_g) -#define H5T_NATIVE_UINT_FAST32 (H5OPEN H5T_NATIVE_UINT_FAST32_g) +/** + * \ingroup PDTC9x + */ +#define H5T_NATIVE_INT_FAST32 (H5OPEN H5T_NATIVE_INT_FAST32_g) +/** + * \ingroup PDTC9x + */ +#define H5T_NATIVE_UINT_FAST32 (H5OPEN H5T_NATIVE_UINT_FAST32_g) H5_DLLVAR hid_t H5T_NATIVE_INT32_g; H5_DLLVAR hid_t H5T_NATIVE_UINT32_g; H5_DLLVAR hid_t H5T_NATIVE_INT_LEAST32_g; @@ -485,12 +1027,30 @@ H5_DLLVAR hid_t H5T_NATIVE_UINT_LEAST32_g; H5_DLLVAR hid_t H5T_NATIVE_INT_FAST32_g; H5_DLLVAR hid_t H5T_NATIVE_UINT_FAST32_g; -#define H5T_NATIVE_INT64 (H5OPEN H5T_NATIVE_INT64_g) -#define H5T_NATIVE_UINT64 (H5OPEN H5T_NATIVE_UINT64_g) -#define H5T_NATIVE_INT_LEAST64 (H5OPEN H5T_NATIVE_INT_LEAST64_g) +/** + * \ingroup PDTC9x + */ +#define H5T_NATIVE_INT64 (H5OPEN H5T_NATIVE_INT64_g) +/** + * \ingroup PDTC9x + */ +#define H5T_NATIVE_UINT64 (H5OPEN H5T_NATIVE_UINT64_g) +/** + * \ingroup PDTC9x + */ +#define H5T_NATIVE_INT_LEAST64 (H5OPEN H5T_NATIVE_INT_LEAST64_g) +/** + * \ingroup PDTC9x + */ #define H5T_NATIVE_UINT_LEAST64 (H5OPEN H5T_NATIVE_UINT_LEAST64_g) -#define H5T_NATIVE_INT_FAST64 (H5OPEN H5T_NATIVE_INT_FAST64_g) -#define H5T_NATIVE_UINT_FAST64 (H5OPEN H5T_NATIVE_UINT_FAST64_g) +/** + * \ingroup PDTC9x + */ +#define H5T_NATIVE_INT_FAST64 (H5OPEN H5T_NATIVE_INT_FAST64_g) +/** + * \ingroup PDTC9x + */ +#define H5T_NATIVE_UINT_FAST64 (H5OPEN H5T_NATIVE_UINT_FAST64_g) H5_DLLVAR hid_t H5T_NATIVE_INT64_g; H5_DLLVAR hid_t H5T_NATIVE_UINT64_g; H5_DLLVAR hid_t H5T_NATIVE_INT_LEAST64_g; @@ -499,98 +1059,1867 @@ H5_DLLVAR hid_t H5T_NATIVE_INT_FAST64_g; H5_DLLVAR hid_t H5T_NATIVE_UINT_FAST64_g; /* Operations defined on all datatypes */ -H5_DLL hid_t H5Tcreate(H5T_class_t type, size_t size); -H5_DLL hid_t H5Tcopy(hid_t type_id); +/** + * \ingroup H5T + * + * \brief Creates a new datatype. + * + * \param[in] type Class of datatype to create + * \param[in] size Size, in bytes, of the datatype being created + * + * \return \hid_t{datatype} + * + * \details H5Tcreate() creates a new datatype of the specified class with the + * specified number of bytes. This function is used only with the + * following datatype classes: + * - #H5T_COMPOUND + * - #H5T_OPAQUE + * - #H5T_ENUM + * - #H5T_STRING + * + * Other datatypes, including integer and floating-point datatypes, + * are typically created by using H5Tcopy() to copy and modify a + * predefined datatype. + * + * When creating a variable-length string datatype, \p size must + * be #H5T_VARIABLE; see \ref_vlen_strings. + * + * When creating a fixed-length string datatype, \p size will + * be the length of the string in bytes. The length of the + * string in characters will depend on i the encoding used; see + * H5Pset_char_encoding(). + * + * ENUMs created with this function have a signed native integer + * base datatype. Use H5Tenum_create() if a different integer base + * datatype is required. + * + * The datatype identifier returned from this function should be + * released with H5Tclose or resource leaks will result. + * + * \see H5Tclose() + * + * \since 1.2.0 + * + */ +H5_DLL hid_t H5Tcreate(H5T_class_t type, size_t size); +/** + * \ingroup H5T + * + * \brief Copies an existing datatype. + * + * \type_id + * + * \return \hid_t{datatype} + * + * \details H5Tcopy() makes a copy of an existing datatype. The returned type + * is always transient and unlocked. + * + * The \p type_id argument can be either a datatype identifier, + * a predefined datatype (defined in H5Tpublic.h), or a dataset + * identifier. If \p type_id is a dataset identifier, this function + * returns a transient, modifiable datatype which is a copy of the + * dataset's datatype. + * + * The returned datatype identifier should be released with H5Tclose() + * to prevent resource leak. + * + */ +H5_DLL hid_t H5Tcopy(hid_t type_id); +/** + * \ingroup H5T + * + * \brief Releases a datatype + * + * \type_id + * + * \return \herr_t + * + * \details H5Tclose() releases the datatype \p dtype_id. Further access + * through this datatype identifier is illegal. Failure to release + * a datatype with this call will result in resource leaks. + * + */ H5_DLL herr_t H5Tclose(hid_t type_id); +/** + * \ingroup H5T + * + * \brief Asynchronous version of H5Tclose(). + * + */ +H5_DLL herr_t H5Tclose_async(const char *app_file, const char *app_func, unsigned app_line, hid_t type_id, + hid_t es_id); +/** + * \ingroup H5T + * + * \brief Determines whether two datatype identifiers refer to the same datatype + * + * \type_id{type1_id} + * \type_id{type2_id} + * + * \return \htri_t + * + * \details H5Tequal() determines whether two datatype identifiers refer to + * the same datatype. + * + * \since 1.6 or earlier + * + */ H5_DLL htri_t H5Tequal(hid_t type1_id, hid_t type2_id); +/** + * \ingroup H5T + * + * \brief Locks a datatype + * + * \type_id + * + * \return \herr_t + * + * \details H5Tlock() locks the datatype specified by the dtype_id identifier, + * making it read-only and non-destructible. This is normally done by + * the library for predefined datatypes so the application does not + * inadvertently change or delete a predefined type. Once a datatype + * is locked it can never be unlocked. + * + */ H5_DLL herr_t H5Tlock(hid_t type_id); +/** + * \ingroup H5T + * + * \brief Commits a transient datatype, linking it into the file and creating + * a new committed datatype + * + * \fg_loc_id + * \param[in] name Name given to committed datatype + * \type_id Identifier of datatype to be committed and, upon function’s + * return, identifier for the committed datatype + * \lcpl_id + * \tcpl_id + * \tapl_id + * + * \return \herr_t + * + * \details H5Tcommit2() saves a transient datatype as an immutable committed + * datatype in a file. The datatype specified by \p dtype_id is + * committed to the file with the name name at the location specified + * by \p loc_id and with the datatype creation and access property + * lists \p tcpl_id and \p tapl_id, respectively. + * + * \p loc_id may be a file identifier, or a group identifier within + * that file. \p name may be either an absolute path in the file or + * a relative path from \p loc_id naming the newly-commited datatype. + * + * The link creation property list, \p lcpl_id, governs creation of + * the link(s) by which the new committed datatype is accessed and + * the creation of any intermediate groups that may be missing. + * + * Once commited, this datatype may be used to define the datatype + * of any other dataset or attribute in the file. + * + * This function will not accept a datatype that cannot actually hold + * information. This currently includes compound datatypes with no + * fields and enumerated datatypes with no members. + * + * Committed datatypes are sometimes referred to as named datatypes. + * + * \version 1.8.7 Function modified in this release to reject datatypes that + * will not accomodate actual data, such as a compound datatype + * with no fields or an enumerated datatype with no members. + * + * \since 1.8.0 + * + */ H5_DLL herr_t H5Tcommit2(hid_t loc_id, const char *name, hid_t type_id, hid_t lcpl_id, hid_t tcpl_id, hid_t tapl_id); -H5_DLL hid_t H5Topen2(hid_t loc_id, const char *name, hid_t tapl_id); +/** + * \ingroup H5T + * + * \brief Asynchronous version of H5Tcommit2(). + * + */ +H5_DLL herr_t H5Tcommit_async(const char *app_file, const char *app_func, unsigned app_line, hid_t loc_id, + const char *name, hid_t type_id, hid_t lcpl_id, hid_t tcpl_id, hid_t tapl_id, + hid_t es_id); +/** + * -------------------------------------------------------------------------- + * \ingroup H5T + * + * \brief Opens a committed (named) datatype + * + * \fgdta_loc_id + * \param[in] name Name of the datatype to open + * \tapl_id + * + * \return \hid_t{datatype} + * + * \details H5Topen2() opens a committed datatype at the location specified + * by \p loc_id and returns an identifier for the datatype. \p + * loc_id is either a file or group identifier. The identifier should + * eventually be closed by calling H5Tclose() to release resources. + * + * The committed datatype is opened with the datatype access property + * list tapl_id. + * + * \since 1.8.0 + * + */ +H5_DLL hid_t H5Topen2(hid_t loc_id, const char *name, hid_t tapl_id); +/** + * \ingroup H5T + * + * \brief Asynchronous version of H5Topen2(). + * + */ +H5_DLL hid_t H5Topen_async(const char *app_file, const char *app_func, unsigned app_line, hid_t loc_id, + const char *name, hid_t tapl_id, hid_t es_id); +/** + * \ingroup H5T + * + * \brief Commits a transient datatype to a file, creating a new named + * datatype, but does not link it into the file structure + * + * \fg_loc_id + * \type_id + * \tcpl_id + * \tapl_id + * + * \return \herr_t + * + * \details H5Tcommit_anon() commits a transient datatype (not immutable) + * to a file, turning it into a named datatype with the specified + * creation and property lists. With default property lists, + * #H5P_DEFAULT, H5Tcommit_anon() provides similar functionality to + * that of H5Tcommit(), with the differences described below. + * + * #H5P_DEFAULT can be passed in for the datatype creation property + * list identifier, \p tcpl_id. The datatype access property list + * identifier, \p tapl_id, is provided for future functionality and + * is not used at this time. This parameter should always be passed + * as the value #H5P_DEFAULT. + * + * Note that H5Tcommit_anon() does not link this newly-committed + * datatype into the file. After the H5Tcommit_anon() call, the + * datatype identifier \p type_id must be linked into the HDF5 file + * structure with H5Olink() or it will be deleted from the file when + * the file is closed. + * + * The differences between this function and H5Tcommit() are as follows: + * \li H5Tcommit_anon() explicitly includes property lists, + * which provides for greater control of the creation process + * and of the properties of the new named datatype. H5Tcommit() + * always uses default properties. + * \li H5Tcommit_anon() neither provides the new named datatype’s + * name nor links it into the HDF5 file structure; those actions + * must be performed separately through a call to H5Olink(), + * which offers greater control over linking. + * + * This function will not accept a datatype that cannot actually + * hold data. This currently includes compound datatypes with no + * fields and enumerated datatypes with no members. + * + * \version 1.8.7 Function modified in this release to reject datatypes that + * will not accomodate actual data, such as a compound datatype + * with no fields or an enumerated datatype with no members. + * + * \since 1.2.0 + * + */ H5_DLL herr_t H5Tcommit_anon(hid_t loc_id, hid_t type_id, hid_t tcpl_id, hid_t tapl_id); -H5_DLL hid_t H5Tget_create_plist(hid_t type_id); +/** + * \ingroup H5T + * + * \brief Returns a copy of a datatype's creation property list + * + * \type_id + * + * \return \hid_t{datatype creation property list} + * + * \details H5Tget_create_plist() returns a property list identifier + * for the datatype creation property list associated with the datatype + * specified by \p type_id. + * + * The creation property list identifier should be released with + * H5Pclose() to prevent memory leaks. + * + * \since 1.8.0 + * + */ +H5_DLL hid_t H5Tget_create_plist(hid_t type_id); +/** + * \ingroup H5T + * + * \brief Determines whether a datatype is a committed type or a transient type + * + * \type_id + * + * \return \htri_t + * + * \details H5Tcommitted() queries a type to determine whether the type + * specified by the \p dtype_id identifier is a committed (formerly + * known as a \Emph{named}) type or a transient type. If this function returns + * a positive value, then the type is committed (that is, it has been + * committed, perhaps by some other application). Datasets which + * return committed datatypes with H5Dget_type() are able to share + * the datatype with other datasets in the same file. + * + * \version 1.8.0 Fortran API was added + * + * \since 1.6 or earlier + * + */ H5_DLL htri_t H5Tcommitted(hid_t type_id); +/** + * \ingroup H5T + * + * \brief Encodes a datatype object description into a binary buffer + * + * \param[in] obj_id Identifier of the object to be encoded + * \param[in,out] buf Buffer for the object to be encoded into. + * \param[in,out] nalloc IN: The size of the allocated buffer + * OUT: The size of the buffer needed + * + * \return \herr_t + * + * \details H5Tencode() Given datatype identifier, H5Tencode() converts a + * datatype description into binary form in a buffer. Using this + * binary form in the buffer, a datatype object can be reconstructed + * using H5Tdecode() to return a new object handle (\ref hid_t) for + * this datatype. + * + * If the provided buffer is NULL, only the size of buffer needed is + * returned through \p nalloc. + * + * A preliminary H5Tencode() call can be made to find out the size + * of the buffer needed. This value is returned as \p nalloc. That + * value can then be assigned to \p nalloc for a second H5Tencode() + * call, which will retrieve the actual encoded object. + * + * If the library finds that \p nalloc is not big enough for the + * object, it simply returns the size of the buffer needed through + * \p nalloc without encoding the provided buffer. + * + * \since 1.2.0 + * + */ H5_DLL herr_t H5Tencode(hid_t obj_id, void *buf, size_t *nalloc); -H5_DLL hid_t H5Tdecode(const void *buf); +/** + * \ingroup H5T + * + * \brief Decodes a binary object description of datatype and return a new + * object handle + * + * \param[in] buf Buffer for the datatype object to be decoded + * + * \return \hid_t{datatype} + * + * \details H5Tdecode() Given an object description of datatype in binary in a + * buffer, H5Tdecode() reconstructs the HDF5 datatype object and + * returns a new object handle for it. The binary description of + * the object is encoded by H5Tencode(). User is responsible for + * passing in the right buffer. + * + * The datatype identifier returned by this function can be released + * with H5Tclose() when the identifier is no longer needed so that + * resource leaks will not develop. + * + */ +H5_DLL hid_t H5Tdecode(const void *buf); +/** + * \ingroup H5T + * + * \brief Flushes all buffers associated with a committed datatype to disk + * + * \type_id + * + * \return \herr_t + * + * \details H5Tflush() causes all buffers associated with a committed datatype + * \p type_id to be immediately flushed to disk without removing the + * data from the cache. + * + * HDF5 does not possess full control over buffering. H5Tflush() + * flushes the internal HDF5 buffers and then asks the operating + * system (the OS) to flush the system buffers for the open + * files. After that, the OS is responsible for ensuring that the + * data is actually flushed to disk. + * + * \return \herr_t + * + * \since 1.10.0 C function introduced with this release. + * + * \see H5Dflush() + * H5Drefresh() + * H5Tflush() + * H5Grefresh() + * H5Oflush() + * H5Orefresh() + * H5Tflush() + * H5Trefresh() + * H5Fstart_swmr_write() + * H5Pget_append_flush() + * H5Pget_object_flush_cb() + * H5Pset_append_flush() + * H5Pset_object_flush_cb() + * + */ H5_DLL herr_t H5Tflush(hid_t type_id); +/** + * \ingroup H5T + * + * \brief Refreshes all buffers associated with a committed datatype + * + * \type_id + * + * \return \herr_t + * + * \details H5Trefresh() causes all buffers associated with a committed + * datatype to be cleared and immediately re-loaded with updated + * contents from disk. + * + * This function essentially closes the datatype, evicts all + * metadata associated with it from the cache, and then re-opens the + * datatype. The reopened datatype is automatically re-registered + * with the same identifier. + * + * \since 1.2.0 + * + */ H5_DLL herr_t H5Trefresh(hid_t type_id); /* Operations defined on compound datatypes */ +/** + * \ingroup COMPOUND + * + * \brief Adds a new member to a compound datatype. + * + * \type_id{parent_id} + * \param[in] name Name of the field to insert + * \param[in] offset Offset in memory structure of the field to insert + * \param[in] member_id Datatype identifier of the field to insert + * + * \return \herr_t + * + * \details H5Tinsert() adds another member to the compound datatype, specified + * \p type_id. + * + * The new member has a \p name which must be unique within the + * compound datatype. The \p offset argument defines the start of the + * member in an instance of the compound datatype, and \p member_id + * is the datatype identifier of the new member. + * + * \note Members of a compound datatype do not have to be atomic + * datatypes; a compound datatype can have a member which is a + * compound datatype. + * + * \since 1.2.0 + * + */ H5_DLL herr_t H5Tinsert(hid_t parent_id, const char *name, size_t offset, hid_t member_id); +/** + * \ingroup COMPOUND + * + * \brief Recursively removes padding from within a compound datatype + * + * \type_id + * + * \return \herr_t + * + * \details H5Tpack() recursively removes padding from within a compound + * datatype to make it more efficient (space-wise) to store that data. + * + * \since 1.2.0 + * + */ H5_DLL herr_t H5Tpack(hid_t type_id); /* Operations defined on enumeration datatypes */ -H5_DLL hid_t H5Tenum_create(hid_t base_id); +/** + * \ingroup ENUM + * + * \brief Creates a new enumeration datatype + * + * \param[in] base_id Datatype identifier for the base datatype. Must be an + * integer datatype + * + * \return \hid_t{enumeration datatype} + * + * \details H5Tenum_create() creates a new enumeration datatype based on the + * specified base datatype, dtype_id, which must be an integer datatype. + * + * If a particular architecture datatype is required, a little endian + * or big endian datatype for example, use a native datatype as the + * base datatype and use H5Tconvert() on values as they are read + * from or written to a dataset. + * + * \since 1.2.0 + * + */ +H5_DLL hid_t H5Tenum_create(hid_t base_id); +/** + * \ingroup ENUM + * + * \brief Inserts a new enumeration datatype member + * + * \type_id{type} + * \param[in] name Name of the new member + * \param[in] value Pointer to the value of the new member + * + * \return \herr_t + * + * \details H5Tenum_insert() inserts a new enumeration datatype member into an + * enumeration datatype. + * + * \p type_id is the datatype identifier for the enumeration datatype, + * \p name is the name of the new member, and \p value points to the + * value of the new member. + * + * \p name and \p value must both be unique within \p dtype_id. + * + * \p value points to data which must be of the integer base datatype + * used when the enumeration datatype was created. If a particular + * architecture datatype is required, a little endian or big endian + * datatype for example, use a native datatype as the base datatype + * and use H5Tconvert() on values as they are read from or written + * to a dataset. + * + * \since 1.2.0 + * + */ H5_DLL herr_t H5Tenum_insert(hid_t type, const char *name, const void *value); +/** + * \ingroup ENUM + * + * \brief Returns the symbol name corresponding to a specified member of an + * enumeration datatype + * + * \type_id{type} + * \param[in] value Value of the enumeration datatype + * \param[out] name Buffer for output of the symbol name + * \param[in] size Anticipated size of the symbol name, in bytes + * + * \return Returns a non-negative value if successful. Otherwise returns a + * negative value + * + * \details H5Tenum_nameof() finds the symbol name that corresponds to the + * specified \p value of the enumeration datatype \p type. + * + * At most \p size characters of the symbol \p name are copied into + * the \p name buffer. If the entire symbol name and null terminator + * do not fit in the name buffer, then as many characters as possible + * are copied (not null terminated) and the function fails. + * + * \since 1.2.0 + * + */ H5_DLL herr_t H5Tenum_nameof(hid_t type, const void *value, char *name /*out*/, size_t size); +/** + * \ingroup ENUM + * + * \brief Returns the value corresponding to a specified member of an + * enumeration datatype + * + * \type_id{type} + * \param[in] name Symbol name of the enumeration datatype + * \param[out] value Buffer for the value of the enumeration datatype + * + * \return \herr_t + * + * \details H5Tenum_valueof() finds the value that corresponds to the + * specified name of the enumeration datatype \p dtype_id. + * + * Values returned in \p value will be of the enumerated type’s + * base type, that is, the datatype used by H5Tenum_create() when + * the enumerated type was created. + * + * The \p value buffer must be at least large enough to hold a value + * of that base type. If the size is unknown, you can determine it + * with H5Tget_size(). + * + * \since 1.2.0 + * + */ H5_DLL herr_t H5Tenum_valueof(hid_t type, const char *name, void *value /*out*/); /* Operations defined on variable-length datatypes */ +/** + * \ingroup VLEN + * + * \brief Creates a new variable-length array datatype + * + * \type_id{base_id}, the element type of the datatype to create + * + * \return \hid_t{variable-length datatype} + * + * \details H5Tvlen_create() creates a new one-dimensional array datatype of + * variable-length (VL) with the base datatype \p base_id. + * + * This one-dimensional array often represents a data sequence of the + * base datatype, such as characters for character sequences or vertex + * coordinates for polygon lists. The base type specified for the VL + * datatype can be any HDF5 datatype, including another VL datatype, a + * compound datatype, or an atomic datatype. + * + * When necessary, use H5Tget_super() to determine the base type of + * the VL datatype. + * + * The datatype identifier returned from this function should be + * released with H5Tclose() or resource leaks will result. Under + * certain circumstances, H5Dvlen_reclaim() must also be used. + * + * \attention H5Tvlen_create() cannot be used to create a variable-length + * string datatype. H5Tvlen_create() called with a string or + * character base type creates a variable-length sequence of strings + * (a variable-length, 1-dimensional array), with each element of + * the array being of the string or character base type.\n + * To create a variable-length string datatype, see \ref_vlen_strings. + * + */ H5_DLL hid_t H5Tvlen_create(hid_t base_id); /* Operations defined on array datatypes */ +/** + * \ingroup ARRAY + * + * \brief Creates an array datatype object + * + * \param[in] base_id Datatype identifier for the array base datatype + * \param[in] ndims Rank of the array + * \param[in] dim Size of each array dimension + * + * \return \hid_t{array datatype} + * + * \details H5Tarray_create2() creates a new array datatype object.\n\n + * \p base_id is the datatype of every element of the array, i.e., + * of the number at each position in the array. + * + * \p ndims is the number of dimensions and the size of each dimension + * is specified in the array \p dim. The value of \p rank is + * currently limited to #H5S_MAX_RANK and must be greater than 0 + * (zero). All dimension sizes specified in \p dim must be greater + * than 0 (zero). + * + * \since 1.8.0 + * + */ H5_DLL hid_t H5Tarray_create2(hid_t base_id, unsigned ndims, const hsize_t dim[/* ndims */]); -H5_DLL int H5Tget_array_ndims(hid_t type_id); -H5_DLL int H5Tget_array_dims2(hid_t type_id, hsize_t dims[]); +/** + * \ingroup ARRAY + * + * \brief Returns the rank of an array datatype + * + * \type_id + * + * \return Returns the rank of the array if successful; otherwise returns a + * negative value. + * + * \details H5Tget_array_ndims() returns the rank, i.e., the number of + * dimensions, of an array datatype object. + * + * \since 1.2.0 + * + */ +H5_DLL int H5Tget_array_ndims(hid_t type_id); +/** + * \ingroup ARRAY + * + * \brief Retrieves sizes of array dimensions + * + * \type_id + * \param[out] dims Sizes of array dimensions + * + * \return Returns the non-negative number of dimensions of the array type + * if successful; otherwise returns a negative value. + * + * \details H5Tget_array_dims2() returns the sizes of the dimensions of the + * specified array datatype object in the array \p dims. + * + * \since 1.2.0 + * + */ +H5_DLL int H5Tget_array_dims2(hid_t type_id, hsize_t dims[]); /* Operations defined on opaque datatypes */ +/** + * \ingroup OPAQUE + * + * \brief Tags an opaque datatype + * + * \type_id{type} of an opaque datatype + * \param[in] tag Descriptive ASCII string with which the opaque datatype is + * to be tagged + * + * \return \herr_t + * + * \details H5Tset_tag() tags an opaque datatype \p type with a descriptive + * ASCII identifier, \p tag. + * + * \p tag is intended to provide a concise description; the maximum + * size is hard-coded in the HDF5 library as 256 bytes + * (#H5T_OPAQUE_TAG_MAX). + * + * \version 1.6.5 The #H5T_OPAQUE_TAG_MAX macro constant, specifying the + * maximum size of an opaque datatype tag, was added in + * H5Tpublic.h. + * + */ H5_DLL herr_t H5Tset_tag(hid_t type, const char *tag); -H5_DLL char * H5Tget_tag(hid_t type); +/** + * \ingroup OPAQUE + * + * \brief Gets the tag associated with an opaque datatype + * + * \type_id{type} of an opaque datatype + * + * \return Returns a pointer to an allocated string if successful; otherwise + * returns NULL. + * + * \details H5Tget_tag() returns the tag associated with the opaque datatype + * \p type. + * + * \attention The tag is returned via a pointer to an allocated string, which + * the caller must free. + * + */ +H5_DLL char *H5Tget_tag(hid_t type); /* Querying property values */ -H5_DLL hid_t H5Tget_super(hid_t type); +/** + * \ingroup H5T + * + * \brief Returns the base datatype from which a datatype is derived + * + * \type_id{type} + * + * \return \hid_t{datatype} + * + * \details H5Tget_super() returns the base datatype from which the datatype + * \p type_id is derived. In the case of an enumeration type, the + * return value is an integer type. + * + * The datatype identifier returned by this function must be released + * with H5Tclose() when the identifier is no longer needed so that + * resource leaks will not develop. + * + */ +H5_DLL hid_t H5Tget_super(hid_t type); +/** + * \ingroup H5T + * + * \brief Returns a datatype class + * + * \type_id + * + * \return Returns the datatype class if successful; otherwise #H5T_NO_CLASS. + * + * \details H5Tget_class() returns the class of the datatype \p type_id. + * Valid class identifiers, as defined in H5Tpublic.h, are: + * \snippet this H5T_class_t_snip + * + * \note The library returns #H5T_STRING for both fixed-length and + * variable-length strings. + * + * \note Unsupported datatype: The time datatype class, #H5T_TIME, + * is not supported. If #H5T_TIME is used, the resulting data will + * be readable and modifiable only on the originating computing + * platform; it will not be portable to other platforms. + * + */ H5_DLL H5T_class_t H5Tget_class(hid_t type_id); -H5_DLL htri_t H5Tdetect_class(hid_t type_id, H5T_class_t cls); -H5_DLL size_t H5Tget_size(hid_t type_id); +/** + * \ingroup H5T + * + * \brief Determines whether a datatype contains any datatypes of the given + * datatype class + * + * \type_id + * \param[in] cls Datatype class + * + * \return \htri_t + * + * \details H5Tdetect_class() determines whether the datatype specified in + * \p type_id contains any datatypes of the datatype class specified + * in \p dtype_class. + * + * This function is useful primarily in recursively examining all the + * fields and/or base types of compound, array, and variable-length + * datatypes. + * + * Valid class identifiers, as defined in H5Tpublic.h, are: + * \snippet this H5T_class_t_snip + * + * \since 1.6.0 + * + */ +H5_DLL htri_t H5Tdetect_class(hid_t type_id, H5T_class_t cls); +/** + * \ingroup H5T + * + * \brief Returns the size of a datatype + * + * \type_id + * + * \return Returns the size of the datatype in bytes if successful; otherwise, + * returns 0. + * + * \details H5Tget_size() returns the size of a datatype in bytes. + * \li For atomic datatypes, array datatypes, compound datatypes, and + * other datatypes of a constant size, the returned value is the + * size of the actual datatype in bytes. + * \li For variable-length string datatypes the returned value is + * the size of the pointer to the actual string, or \c sizeof(\c + * char \c *). This function does not return the size of actual + * variable-length string data. + * \li For variable-length sequence datatypes (see H5Tvlen_create()), + * the returned value is the size of the \p hvl_t struct, or \c + * sizeof(\p hvl_t). The \p hvl_t struct contains a pointer to the + * actual data and a size value. This function does not return the + * size of actual variable-length sequence data. + * + * \see H5Tset_size() + * + * \since 1.2.0 + */ +H5_DLL size_t H5Tget_size(hid_t type_id); +/** + * \ingroup ATOM + * + * \brief Returns the byte order of an atomic datatype + * + * \type_id + * + * \return Returns a byte order constant if successful; otherwise returns + * #H5T_ORDER_ERROR (-1) + * + * \details H5Tget_order() returns the byte order of an atomic datatype. + * Possible return values are: + * \snippet this H5T_order_t_snip + * Members of a compound datatype need not have the same byte + * order. If members of a compound datatype have more than one of + * little endian, big endian, or VAX byte order, H5Tget_order() will + * return #H5T_ORDER_MIXED for the compound datatype. A byte order of + * #H5T_ORDER_NONE will, however, be ignored; for example, if one or + * more members of a compound datatype have byte order #H5T_ORDER_NONE + * but all other members have byte order #H5T_ORDER_LE, H5Tget_order() + * will return #H5T_ORDER_LE for the compound datatype. + * + * \since 1.2.0 + * + */ H5_DLL H5T_order_t H5Tget_order(hid_t type_id); -H5_DLL size_t H5Tget_precision(hid_t type_id); -H5_DLL int H5Tget_offset(hid_t type_id); -H5_DLL herr_t H5Tget_pad(hid_t type_id, H5T_pad_t *lsb /*out*/, H5T_pad_t *msb /*out*/); -H5_DLL H5T_sign_t H5Tget_sign(hid_t type_id); +/** + * \ingroup ATOM + * + * \brief Returns the precision of an atomic datatype + * + * \type_id + * + * \return Returns the number of significant bits if successful; otherwise 0 + * + * \details H5Tget_precision() returns the precision of an atomic datatype + * (for example, integer or float) or a datatype whose base (parent) + * type is an atomic type (for example, array, enum and variable + * length). The precision is the number of significant bits which, + * unless padding is present, is 8 times larger than the value + * returned by H5Tget_size(). + * + * \since 1.2.0 + * + */ +H5_DLL size_t H5Tget_precision(hid_t type_id); +/** + * \ingroup ATOM + * + * \brief Retrieves the bit offset of the first significant bit + * + * \type_id + * + * \return Returns an offset value if successful; otherwise returns a + * negative value. + * + * \details H5Tget_offset() retrieves the bit offset of the first significant + * bit. The significant bits of an atomic datum can be offset from the + * beginning of the memory for that datum by an amount of padding. The + * 'offset' property specifies the number of bits of padding that + * appear to the "right of" the value. That is, if we have a 32-bit + * datum with 16-bits of precision having the value 0x1122 then it + * will be laid out in memory as (from small byte address toward + * larger byte addresses): + * \code{.unparsed} + * 0: [ pad] [0x11] [0x22] [ pad] + * 1: [ pad] [0x22] [0x11] [ pad] + * 2: [0x11] [ pad] [ pad] [0x22] + * 3: [0x22] [ pad] [ pad] [0x11] + * \endcode + * + * \since 1.2.0 + * + */ +H5_DLL int H5Tget_offset(hid_t type_id); +/** + * \ingroup ATOM + * + * \brief Retrieves the padding type of the least and most-significant bit padding + * + * \type_id + * \param[out] lsb Buffer for the least-significant bit padding type + * \param[out] msb Buffer for the most-significant bit padding type + * + * \return \herr_t + * + * \details H5Tget_pad() retrieves the padding type of the least and + * most-significant bit padding. Valid padding types are: + * \snippet this H5T_pad_t_snip + * + * \since 1.2.0 + * + */ +H5_DLL herr_t H5Tget_pad(hid_t type_id, H5T_pad_t *lsb /*out*/, H5T_pad_t *msb /*out*/); +/** + * \ingroup ATOM + * + * \brief Retrieves the sign type for an integer type + * + * \type_id + * + * \return Returns a valid sign type if successful; otherwise #H5T_SGN_ERROR (-1) + * + * \details H5Tget_sign() retrieves the sign type for an integer type. + * Valid types are: + * \snippet this H5T_sign_t_snip + * + * \since 1.2.0 + * + */ +H5_DLL H5T_sign_t H5Tget_sign(hid_t type_id); +/** + * \ingroup ATOM + * + * \brief Retrieves floating point datatype bit field information + * + * \type_id + * \param[out] spos Pointer to location to return floating-point sign bit + * \param[out] epos Pointer to location to return exponent bit-position + * \param[out] esize Pointer to location to return size of exponent in bits + * \param[out] mpos Pointer to location to return mantissa bit-position + * \param[out] msize Pointer to location to return size of mantissa in bits + * + * \return \herr_t + * + * \details H5Tget_fields() retrieves information about the locations of + * the various bit fields of a floating point datatype. The field + * positions are bit positions in the significant region of the + * datatype. Bits are numbered with the least significant bit number + * zero. Any (or even all) of the arguments can be null pointers. + * + * \since 1.2.0 + * + */ H5_DLL herr_t H5Tget_fields(hid_t type_id, size_t *spos /*out*/, size_t *epos /*out*/, size_t *esize /*out*/, size_t *mpos /*out*/, size_t *msize /*out*/); +/** + * \ingroup ATOM + * + * \brief Retrieves the exponent bias of a floating-point type + * + * \type_id + * + * \return Returns the bias if successful and 0, otherwise. + * + * \details H5Tget_ebias() retrieves the exponent bias of a floating-point type. + * + * \since 1.2.0 + * + */ H5_DLL size_t H5Tget_ebias(hid_t type_id); -H5_DLL H5T_norm_t H5Tget_norm(hid_t type_id); -H5_DLL H5T_pad_t H5Tget_inpad(hid_t type_id); -H5_DLL H5T_str_t H5Tget_strpad(hid_t type_id); -H5_DLL int H5Tget_nmembers(hid_t type_id); -H5_DLL char * H5Tget_member_name(hid_t type_id, unsigned membno); -H5_DLL int H5Tget_member_index(hid_t type_id, const char *name); -H5_DLL size_t H5Tget_member_offset(hid_t type_id, unsigned membno); +/** + * -------------------------------------------------------------------------- + * \ingroup ATOM + * + * \brief Retrieves mantissa normalization of a floating-point datatype + * + * \type_id + * + * \return Returns a valid normalization type if successful; otherwise + * returns #H5T_NORM_ERROR (-1) + * + * \details H5Tget_norm() retrieves the mantissa normalization of a + * floating-point datatype. Valid normalization types are: + * \snippet this H5T_norm_t_snip + * + * \since 1.2.0 + * + */ +H5_DLL H5T_norm_t H5Tget_norm(hid_t type_id); +/** + * \ingroup ATOM + * + * \brief Retrieves the internal padding type for unused bits in floating-point + * datatypes + * + * \type_id + * + * \return Returns a valid padding type if successful; otherwise returns + * #H5T_PAD_ERROR (-1). + * + * \details H5Tget_inpad() retrieves the internal padding type for unused + * bits in floating-point datatypes. Valid padding types are: + * \snippet this H5T_pad_t_snip + * + * \since 1.2.0 + * + */ +H5_DLL H5T_pad_t H5Tget_inpad(hid_t type_id); +/** + * \ingroup ATOM + * + * \brief Retrieves the type of padding used for a string datatype + * + * \type_id + * + * \return Returns a valid string of the padding if successful; otherwise + * returns #H5T_STR_ERROR (-1) + * + * \details H5Tget_strpad() retrieves the type of padding used for a string + * datatype. + * + * The string padding type is set with H5Tset_strpad(). Possible + * values returned are: + * \str_pad_type + * + * \since 1.2.0 + * + */ +H5_DLL H5T_str_t H5Tget_strpad(hid_t type_id); +/** + * \ingroup COMPOUND ENUM + * + * \brief Retrieves the number of elements in a compound or enumeration datatype + * + * \type_id + * + * \return Returns the number of elements if successful; otherwise returns a + * negative value. + * + * \details H5Tget_nmembers() retrieves the number of fields in a compound + * datatype or the number of members of an enumeration datatype. + * + * \since 1.2.0 + * + */ +H5_DLL int H5Tget_nmembers(hid_t type_id); +/** + * \ingroup COMPOUND ENUM + * + * \brief Retrieves the name of a compound or enumeration datatype member + * + * \type_id + * \param[in] membno Zero-based index of the field or element + * + * \return Returns a valid pointer to a string allocated with malloc() if + * successful; otherwise returns NULL. + * + * \details H5Tget_member_name() retrieves the name of a field of a compound + * datatype or an element of an enumeration datatype. + * + * The index of the target field or element is specified in \p + * member_no. Compound datatype fields and enumeration datatype + * elements are stored in no particular order with index values of + * 0 through N-1, where N is the value returned by H5Tget_nmembers(). + * + * The HDF5 library allocates a buffer to receive the name of + * the field. The caller must subsequently free the buffer with + * H5free_memory(). + * + * \since 1.2.0 + * + */ +H5_DLL char *H5Tget_member_name(hid_t type_id, unsigned membno); +/** + * \ingroup COMPOUND ENUM + * + * \brief Retrieves the index of a compound or enumeration datatype member + * + * \type_id + * \param[in] name Name of the field or member + * + * \return \herr_t + * + * \details H5Tget_member_index() retrieves the index of a field of a compound + * datatype or an element of an enumeration datatype. + * + * The name of the target field or element is specified by \p name. + * + * Fields are stored in no particular order with index values of 0 + * through N-1, where N is the value returned by H5Tget_nmembers() . + * + * \since 1.2.0 + * + */ +H5_DLL int H5Tget_member_index(hid_t type_id, const char *name); +/** + * \ingroup COMPOUND + * + * \brief Retrieves the offset of a field of a compound datatype + * + * \type_id + * \param[in] membno Zero-based index of the field or element + * + * \return Returns the byte offset of the field if successful; otherwise + * returns 0 (zero). + * + * \details H5Tget_member_offset() retrieves the byte offset of the beginning + * of a field within a compound datatype with respect to the beginning + * of the compound datatype datum. + * + * Note that zero is a valid offset and that this function will fail + * only if a call to H5Tget_member_class() fails with the same arguments. + * + * \version 1.6.4 \p member_no parameter type changed to unsigned. + * + * \since 1.2.0 + * + */ +H5_DLL size_t H5Tget_member_offset(hid_t type_id, unsigned membno); +/** + * \ingroup COMPOUND + * + * \brief Returns datatype class of compound datatype member + * + * \type_id + * \param[in] membno Zero-based index of the field or element + * + * \return Returns the datatype class, a non-negative value, if successful; + * otherwise returns a negative value. + * + * \details Given a compound datatype, \p dtype_id, H5Tget_member_class() + * returns the datatype class of the member specified by \p member_no. + * + * Valid class identifiers, as defined in H5Tpublic.h, are: + * \snippet this H5T_class_t_snip + * + * \since 1.2.0 + * + */ H5_DLL H5T_class_t H5Tget_member_class(hid_t type_id, unsigned membno); -H5_DLL hid_t H5Tget_member_type(hid_t type_id, unsigned membno); -H5_DLL herr_t H5Tget_member_value(hid_t type_id, unsigned membno, void *value /*out*/); -H5_DLL H5T_cset_t H5Tget_cset(hid_t type_id); -H5_DLL htri_t H5Tis_variable_str(hid_t type_id); -H5_DLL hid_t H5Tget_native_type(hid_t type_id, H5T_direction_t direction); +/** + * \ingroup COMPOUND + * + * \brief Returns the datatype of the specified member + * + * \type_id + * \param[in] membno Zero-based index of the field or element + * + * \return Returns the identifier of a copy of the datatype of the field if + * successful; otherwise returns a negative value. + * + * \details H5Tget_member_type() returns the datatype of the specified member. + * The caller should invoke H5Tclose() to release resources associated + * with the type. + * + * \version 1.6.4 \p membno parameter type changed to unsigned. + * + * \since 1.2.0 + * + */ +H5_DLL hid_t H5Tget_member_type(hid_t type_id, unsigned membno); +/** + * \ingroup ENUM + * + * \brief Returns the value of an enumeration datatype member + * + * \type_id + * \param[in] membno Number of the enumeration datatype member + * \param[out] value Buffer for the value of the enumeration datatype member + * + * \return \herr_t + * + * \details H5Tget_member_value() returns the value of the enumeration datatype + * member \p member_no. + * + * The member value is returned in a user-supplied buffer pointed to + * by \p value. Values returned in \p value will be of the enumerated + * type’s base type, that is, the datatype used by H5Tenum_create() + * when the enumerated type was created. + * + * The value buffer must be at least large enough to hold a value + * of that base type. If the size is unknown, you can determine it + * with H5Tget_size(). + * + * \since 1.2.0 + * + */ +H5_DLL herr_t H5Tget_member_value(hid_t type_id, unsigned membno, void *value /*out*/); +/** + * \ingroup ATOM + * + * \brief Retrieves the character set type of a string datatype + * + * \type_id + * + * \return Returns a valid character set type if successful; otherwise + * #H5T_CSET_ERROR (-1). + * + * \details H5Tget_cset() retrieves the character set type of a string datatype. + * Valid character set types are: + * \csets + * + * \since 1.2.0 + * + */ +H5_DLL H5T_cset_t H5Tget_cset(hid_t type_id); +/** + * \ingroup ATOM + * + * \brief Determines whether datatype is a variable-length string + * + * \type_id + * + * \return Returns: + * \li a positive value if the specified datatype is a variable-length + * string + * \li 0 if the specified datatype is not a variable-length string + * \li a negative value when the function fails + * + * \details H5Tis_variable_str() determines whether the datatype identified + * by \p dtype_id is a variable-length string. + * + * This function can be used to distinguish between fixed and + * variable-length string datatypes. + * + * \since 1.6.0 + * + */ +H5_DLL htri_t H5Tis_variable_str(hid_t type_id); +/** + * \ingroup H5T + * + * \brief Returns the native datatype identifier of a specified datatype + * + * \type_id + * \param[in] direction Direction of search + * + * \return \hid_t{native datatype} + * + * \details H5Tget_native_type() returns the equivalent native datatype + * identifier for the datatype specified by \p type_id. + * + * H5Tget_native_type() is designed primarily to facilitate use of + * the H5Dread() function, for which users otherwise must undertake a + * multi-step process to determine the native datatype of a dataset + * prior to reading it into memory. This function can be used for + * the following purposes: + * + * \li To determine the native datatype of an atomic datatype + * \li To determine the base datatype of an array, enumerated, or + * variable-length datatype + * \li To determine the native atomic datatypes of the individual + * components of a compound datatype + * + * For example, if \p type_id is a compound datatype, the returned + * datatype identifier will be for a similar compound datatype with + * each element converted to the corresponding native datatype; + * nested compound datatypes will be unwound. If \p type_id is an + * array, the returned datatype identifier will be for the native + * datatype of a single array element. + * + * H5Tget_native_type() selects the first matching native datatype + * from the following list: + * + * \li #H5T_NATIVE_CHAR + * \li #H5T_NATIVE_SHORT + * \li #H5T_NATIVE_INT + * \li #H5T_NATIVE_LONG + * \li #H5T_NATIVE_LLONG + * + * \li #H5T_NATIVE_UCHAR + * \li #H5T_NATIVE_USHORT + * \li #H5T_NATIVE_UINT + * \li #H5T_NATIVE_ULONG + * \li #H5T_NATIVE_ULLONG + * + * \li #H5T_NATIVE_FLOAT + * \li #H5T_NATIVE_DOUBLE + * \li #H5T_NATIVE_LDOUBLE + * + * \li #H5T_NATIVE_B8 + * \li #H5T_NATIVE_B16 + * \li #H5T_NATIVE_B32 + * \li #H5T_NATIVE_B64 + * + * The direction parameter indicates the order in which the library + * searches for a native datatype match. Valid values for direction + * are as follows: + * \snippet this H5T_direction_t_snip + * + * H5Tget_native_type() is designed primarily for use with integer, + * floating point, and bitfield datatypes. String, time, opaque, and + * reference datatypes are returned as a copy of dtype_id. See above + * for compound, array, enumerated, and variable-length datatypes. + * + * The identifier returned by H5Tget_native_type() should eventually + * be closed by calling H5Tclose() to release resources. + * + * \note Please note that a datatype is actually an object + * identifier or handle returned from opening the datatype. It + * is not persistent and its value can be different from one HDF5 + * session to the next. + * + * \note H5Tequal() can be used to compare datatypes. + * + * \note HDF5 High Level APIs that may also be of interest are: H5LTdtype_to_text() + * creates a text description of a datatype. H5LTtext_to_dtype() creates an + * HDF5 datatype given a text description. + * + * \since 1.6.0 + * + */ +H5_DLL hid_t H5Tget_native_type(hid_t type_id, H5T_direction_t direction); /* Setting property values */ +/** + * \ingroup H5T + * + * \brief Sets size for a datatype. + * + * \type_id + * \param[in] size New datatype size is bytes or #H5T_VARIABLE + * + * \return \herr_t + * + * \details H5Tset_size() sets the total size, \p size, in bytes, for a + * datatype. + * + * \p size must have a positive value, unless it is passed in as + * #H5T_VARIABLE and the datatype is a string datatype. + * + * \li Numeric datatypes: If the datatype is atomic and the size + * is decreased so that significant bits of the datatype extend + * beyond the edge of the new size, then the offset property of the + * datatype is decreased toward zero. If the offset becomes zero + * and the significant bits of the datatype still hang over the edge + * of the new size, then the number of significant bits is decreased. + * + * \li String or character datatypes: The size set for a string + * datatype should include space for the null-terminator character, + * otherwise it will not be stored on (or retrieved from) + * disk. Adjusting the size of a string automatically sets the + * precision to \p 8*size. + * + * \li Variable-length string datatypes: If \p dtype_id is a + * variable-length string, size must normally be set to #H5T_VARIABLE. + * See \ref_vlen_strings. + * + * \li Compound datatypes: This function may be used to increase or + * decrease the size of a compound datatype, but the function will + * fail if the new size is too small to accommodate all member fields. + * + * \li Ineligible datatypes: This function cannot be used with + * enumerated datatypes (#H5T_ENUM), array datatypes (#H5T_ARRAY), + * variable-length array datatypes (#H5T_VLEN), or reference datatypes + * (#H5T_REFERENCE). + * + * \see H5Tget_size() + * + * \since 1.2.0 + * + */ H5_DLL herr_t H5Tset_size(hid_t type_id, size_t size); +/** + * \ingroup ATOM + * + * \brief Sets the byte order of a datatype + * + * \type_id + * \param[in] order Byte order constant + * + * \return \herr_t + * + * \details H5Tset_order() sets the byte order of a datatype.\n + * Byte order can currently be set to any of the following: + * \snippet this H5T_order_t_snip + * #H5T_ORDER_MIXED (3) is a valid value for order only when + * returned by the function H5Tget_order(); it cannot be set with + * H5Tset_order(). + * + * #H5T_ORDER_NONE (4) is a valid value for order, but it has no + * effect. It is valid only for fixed-length strings and object and + * region references and specifies “no particular order.” + * + * The byte order of a derived datatype is initially the same as + * that of the parent type, but can be changed with H5Tset_order(). + * + * This function cannot be used with a datatype after it has been + * committed. + * + * \note Special considerations: + * \li ENUM datatypes: Byte order must be set before any member on + * an ENUM is defined. + * \li Compound datatypes: Byte order is set individually on each member + * of a compound datatype; members of a compound datatype need not + * have the same byte order. + * \li Opaque datatypes: Byte order can be set but has no effect. + * + * \since 1.2.0 + * + */ H5_DLL herr_t H5Tset_order(hid_t type_id, H5T_order_t order); +/** + * \ingroup ATOM + * + * \brief Sets the precision of an atomic datatype + * + * \type_id + * \param[in] prec Number of bits of precision for datatype + * + * \return \herr_t + * + * \details H5Tset_precision() sets the precision of an atomic datatype. The + * precision is the number of significant bits which, unless + * padding is present, is 8 times larger than the value returned + * by H5Tget_size(). + * + * If the precision is increased then the offset is decreased and + * then the size is increased to insure that significant bits do not + * "hang over" the edge of the datatype. + * + * Changing the precision of an #H5T_STRING automatically changes + * the size as well. The precision must be a multiple of 8. + * + * When decreasing the precision of a floating point type, set the + * locations and sizes of the sign, mantissa, and exponent fields + * first. + * + * \since 1.2.0 + * + */ H5_DLL herr_t H5Tset_precision(hid_t type_id, size_t prec); +/** + * \ingroup ATOM + * + * \brief Sets the bit offset of the first significant bit + * + * \type_id + * \param[in] offset Offset of first significant bit + * + * \return \herr_t + * + * \details H5Tset_offset() sets the bit offset of the first significant + * bit. The significant bits of an atomic datum can be offset from + * the beginning of the memory for that datum by an amount of + * padding. The offset property specifies the number of bits of + * padding that appear “to the right of” the value. That is, + * if we have a 32-bit datum with 16-bits of precision having the + * value 0x1122, then it will be laid out in memory as (from small + * byte address toward larger byte addresses): + * \code{.unparsed} + * 0: [ pad] [0x11] [0x22] [ pad] + * 1: [ pad] [0x22] [0x11] [ pad] + * 2: [0x11] [ pad] [ pad] [0x22] + * 3: [0x22] [ pad] [ pad] [0x11] + * \endcode + * If the offset is incremented then the total size is incremented + * also if necessary to prevent significant bits of the value from + * hanging over the edge of the datatype. + * + * The offset of an #H5T_STRING cannot be set to anything but zero. + * + * \since 1.2.0 + * + */ H5_DLL herr_t H5Tset_offset(hid_t type_id, size_t offset); +/** + * \ingroup ATOM + * + * \brief Sets the least and most-significant bits padding types + * + * \type_id + * \param[in] lsb Padding type for least-significant bits + * \param[in] msb Padding type for most-significant bits + * + * \return \herr_t + * + * \details H5Tset_pad() sets the least and most-significant bits padding types. + * Available values are: + * \padding_type + * + * \since 1.2.0 + * + */ H5_DLL herr_t H5Tset_pad(hid_t type_id, H5T_pad_t lsb, H5T_pad_t msb); +/** + * \ingroup ATOM + * + * \brief Sets the sign property for an integer type + * + * \type_id + * \param[in] sign Sign type + * + * \return \herr_t + * + * \details H5Tset_sign() sets the sign property for an integer type: + * \sign_prop + * + * \since 1.2.0 + * + */ H5_DLL herr_t H5Tset_sign(hid_t type_id, H5T_sign_t sign); +/** + * \ingroup ATOM + * + * \brief Sets locations and sizes of floating point bit fields + * + * \type_id + * \param[in] spos Sign position, i.e., the bit offset of the floating-point + * sign bit + * \param[in] epos Exponent bit position + * \param[in] esize Size of exponent in bits + * \param[in] mpos Mantissa bit position + * \param[in] msize Size of mantissa in bits + * + * \return \herr_t + * + * \details H5Tset_fields() sets the locations and sizes of the various + * floating-point bit fields. The field positions are bit positions + * in the significant region of the datatype. Bits are numbered with + * the least significant bit number zero. + * + * Fields are not allowed to extend beyond the number of bits of + * precision, nor are they allowed to overlap with one another. + * + * \since 1.2.0 + * + */ H5_DLL herr_t H5Tset_fields(hid_t type_id, size_t spos, size_t epos, size_t esize, size_t mpos, size_t msize); +/** + * \ingroup ATOM + * + * \brief Sets the exponent bias of a floating-point type + * + * \type_id + * \param[in] ebias Exponent bias value + * + * \return \herr_t + * + * \details H5Tset_ebias() sets the exponent bias of a floating-point type. + * + * \since 1.2.0 + * + */ H5_DLL herr_t H5Tset_ebias(hid_t type_id, size_t ebias); +/** + * \ingroup ATOM + * + * \brief Sets the mantissa normalization of a floating-point datatype + * + * \type_id + * \param[in] norm Mantissa normalization type + * + * \return \herr_t + * + * \details H5Tset_norm() sets the mantissa normalization of a floating-point + * datatype. Valid normalization types are: + * \snippet this H5T_norm_t_snip + * + * \since 1.2.0 + * + */ H5_DLL herr_t H5Tset_norm(hid_t type_id, H5T_norm_t norm); +/** + * \ingroup ATOM + * + * \brief Fills unused internal floating-point bits + * + * \type_id + * \param[in] pad Padding type + * + * \return \herr_t + * + * \details H5Tset_inpad() If any internal bits of a floating point-type are + * unused (that is, those significant bits which are not part of the + * sign, exponent, or mantissa), then H5Tset_inpad() will be filled + * according to the value of the padding value property inpad. Valid + * padding types are: + * \snippet this H5T_pad_t_snip + * + * \since 1.2.0 + * + */ H5_DLL herr_t H5Tset_inpad(hid_t type_id, H5T_pad_t pad); +/** + * \ingroup ATOM + * + * \brief Sets character set to be used in a string or character datatype + * + * \type_id + * \param[in] cset Character set type + * + * \return \herr_t + * + * \details H5Tset_cset() sets the character set to be used in a dataset with + * a string or character datatype. + * + * Valid values for cset include the following: + * \csets + * For example, if the character set for the datatype \p type_id is set + * to #H5T_CSET_UTF8, string or character data of datatype dtype_id + * will be encoded using the UTF-8 Unicode character set. + * + * ASCII and UTF-8 Unicode are the only currently supported character + * encodings. Extended ASCII encodings (for example, ISO 8859) are + * not supported. This encoding policy is not enforced by the HDF5 + * library. Using encodings other than ASCII and UTF-8 can lead to + * compatibility and usability problems. + * + * Note that H5Tset_cset() sets the character set for a character or + * string datatype while H5Pset_char_encoding() sets the character + * set used for an HDF5 link or attribute name. + * + * \since 1.2.0 + * + */ H5_DLL herr_t H5Tset_cset(hid_t type_id, H5T_cset_t cset); +/** + * \ingroup ATOM + * + * \brief Defines the type of padding used for character strings + * + * \type_id + * \param[in] strpad String padding type + * + * \return \herr_t + * + * \details H5Tset_strpad() defines the type of padding used for a string + * datatype. + * + * The method used to store character strings differs with the + * programming language. C usually null terminates strings while + * Fortran left-justifies and space-pads strings. + * + * Valid values of \p strpad are as follows: + * \str_pad_type + * When converting from a longer string to a shorter string, the + * behavior is as follows. If the shorter string is #H5T_STR_NULLPAD + * or #H5T_STR_SPACEPAD, then the string is simply truncated. If + * the short string is #H5T_STR_NULLTERM, it is truncated and a null + * terminator is appended. + * + * When converting from a shorter string to a longer string, the + * longer string is padded on the end by appending nulls or spaces. + * + * \since 1.2.0 + * + */ H5_DLL herr_t H5Tset_strpad(hid_t type_id, H5T_str_t strpad); /* Type conversion database */ +/** + * \ingroup CONV + * + * \brief Registers a datatype conversion function + * + * \param[in] pers Conversion function type + * \param[in] name Name displayed in diagnostic output + * \type_id{src_id} of source datatype + * \type_id{dst_id} of destination datatype + * \param[in] func Function to convert between source and destination datatypes + * + * \return \herr_t + * + * \details H5Tregister() registers a hard or soft conversion function for a + * datatype conversion path. The parameter \p pers indicates whether a + * conversion function is hard (#H5T_PERS_HARD) or soft + * (#H5T_PERS_SOFT). User-defined functions employing compiler casting + * are designated as \Emph{hard}; other user-defined conversion + * functions registered with the HDF5 library (with H5Tregister() ) + * are designated as \Emph{soft}. The HDF5 library also has its own + * hard and soft conversion functions. + * + * A conversion path can have only one hard function. When type is + * #H5T_PERS_HARD, \p func replaces any previous hard function. + * + * When type is #H5T_PERS_SOFT, H5Tregister() adds the function to the + * end of the master soft list and replaces the soft function in all + * applicable existing conversion paths. Soft functions are used when + * determining which conversion function is appropriate for this path. + * + * The \p name is used only for debugging and should be a short + * identifier for the function. + * + * The path is specified by the source and destination datatypes \p + * src_id and \p dst_id. For soft conversion functions, only the class + * of these types is important. + * + * The type of the conversion function pointer is declared as: + * \snippet this H5T_conv_t_snip + * + * The \ref H5T_cdata_t \c struct is declared as: + * \snippet this H5T_cdata_t_snip + * + * \since 1.6.3 The following change occurred in the \ref H5T_conv_t function: + * the \c nelmts parameter type changed to size_t. + * + */ H5_DLL herr_t H5Tregister(H5T_pers_t pers, const char *name, hid_t src_id, hid_t dst_id, H5T_conv_t func); +/** + * \ingroup CONV + * + * \brief Removes a conversion function + * + * \param[in] pers Conversion function type + * \param[in] name Name displayed in diagnostic output + * \type_id{src_id} of source datatype + * \type_id{dst_id} of destination datatype + * \param[in] func Function to convert between source and destination datatypes + * + * \return \herr_t + * + * \details H5Tunregister() removes a conversion function matching criteria + * such as soft or hard conversion, source and destination types, and + * the conversion function. + * + * If a user is trying to remove a conversion function he registered, + * all parameters can be used. If he is trying to remove a library’s + * default conversion function, there is no guarantee the \p name and + * \p func parameters will match the user’s chosen values. Passing in + * some values may cause this function to fail. A good practice is to + * pass in NULL as their values. + * + * All parameters are optional. The missing parameters will be used to + * generalize the search criteria. + * + * The conversion function pointer type declaration is described in + * H5Tregister(). + * + * \version 1.6.3 The following change occurred in the \ref H5T_conv_t function: + * the \c nelmts parameter type changed to size_t. + * + */ H5_DLL herr_t H5Tunregister(H5T_pers_t pers, const char *name, hid_t src_id, hid_t dst_id, H5T_conv_t func); +/** + * \ingroup CONV + * + * \brief Finds a conversion function + * + * \type_id{src_id} of source datatype + * \type_id{dst_id} of destination datatype + * \param[out] pcdata Pointer to type conversion data + * + * \return Returns a pointer to a suitable conversion function if successful. + * Otherwise returns NULL. + * + * \details H5Tfind() finds a conversion function that can handle a conversion + * from type \p src_id to type \p dst_id. The \p pcdata argument is a + * pointer to a pointer to type conversion data which was created and + * initialized by the soft type conversion function of this path when + * the conversion function was installed on the path. + * + */ H5_DLL H5T_conv_t H5Tfind(hid_t src_id, hid_t dst_id, H5T_cdata_t **pcdata); -H5_DLL htri_t H5Tcompiler_conv(hid_t src_id, hid_t dst_id); -H5_DLL herr_t H5Tconvert(hid_t src_id, hid_t dst_id, size_t nelmts, void *buf, void *background, - hid_t plist_id); -H5_DLL herr_t H5Treclaim(hid_t type_id, hid_t space_id, hid_t plist_id, void *buf); +/** + * \ingroup CONV + * + * \brief Check whether the library’s default conversion is hard conversion + * + * \type_id{src_id} of source datatype + * \type_id{dst_id} of destination datatype + * + * \return \htri_t + * + * \details H5Tcompiler_conv() determines whether the library’s conversion + * function from type \p src_id to type \p dst_id is a compiler (hard) + * conversion or not. A compiler conversion uses compiler’s casting; a + * library (soft) conversion uses the library’s own conversion + * function. + * + * \since 1.8.0 + * + */ +H5_DLL htri_t H5Tcompiler_conv(hid_t src_id, hid_t dst_id); +/** + * -------------------------------------------------------------------------- + * \ingroup CONV + * + * \brief Converts data from one specified datatype to another + * + * \type_id{src_id} of source datatype + * \type_id{dst_id} of destination datatype + * \param[in] nelmts Size of array \p buf + * \param[in,out] buf Array containing pre- and post-conversion values + * \param[in] background Optional background buffer + * \dxpl_id{plist_id} + * + * \return \herr_t + * + * \details H5Tconvert() converts \p nelmts elements from a source datatype, + * specified by \p src_id, to a destination datatype, \p dst_id. The + * source elements are packed in \p buf and on return the destination + * elements will be packed in \p buf. That is, the conversion is + * performed in place. + * + * The optional background buffer is for use with compound datatypes. + * It is an array of \p nelmts values for the destination datatype + * which can then be merged with the converted values to recreate the + * compound datatype. For instance, background might be an array of + * structs with the \c a and \c b fields already initialized and the + * conversion of buf supplies the \c c and \c d field values. + * + * The parameter \p plist_id contains the dataset transfer property list + * identifier which is passed to the conversion functions. As of + * Release 1.2, this parameter is only used to pass along the + * variable-length datatype custom allocation information. + * + * \note H5Tconvert() will not resize the buffer \p buf; it must be large + * enough to hold the larger of the input and output data. + * + * \version 1.6.3 \p nelmts parameter type changed to size_t. + * \version 1.4.0 \p nelmts parameter type changed to hsize_t. + * + */ +H5_DLL herr_t H5Tconvert(hid_t src_id, hid_t dst_id, size_t nelmts, void *buf, void *background, + hid_t plist_id); +/** + * \ingroup VLEN + * + * \brief Reclaims the variable length (VL) datatype memory buffers + * + * \type_id + * \space_id + * \dxpl_id{plist_id} used to create the buffer + * \param[in] buf Pointer to the buffer to be reclaimed + * + * \return \herr_t + * + * \details H5Treclaim() reclaims memory buffers created to store VL datatypes. + * It only frees the variable length data in the selection defined in + * the dataspace specified by \p space_id. The dataset transfer + * property list \p plist_id is required to find the correct + * allocation and/or free methods for the variable-length data in the + * buffer. + * + * \since 1.12.0 + * + */ +H5_DLL herr_t H5Treclaim(hid_t type_id, hid_t space_id, hid_t plist_id, void *buf); /* Symbols defined for compatibility with previous versions of the HDF5 API. * * Use of these symbols is deprecated. */ + +/* API Wrappers for async routines */ +/* (Must be defined _after_ the function prototype) */ +/* (And must only defined when included in application code, not the library) */ +#ifndef H5T_MODULE +#define H5Tcommit_async(...) H5Tcommit_async(__FILE__, __func__, __LINE__, __VA_ARGS__) +#define H5Topen_async(...) H5Topen_async(__FILE__, __func__, __LINE__, __VA_ARGS__) +#define H5Tclose_async(...) H5Tclose_async(__FILE__, __func__, __LINE__, __VA_ARGS__) + +/* Define "wrapper" versions of function calls, to allow compile-time values to + * be passed in by language wrapper or library layer on top of HDF5. */ +#define H5Tcommit_async_wrap H5_NO_EXPAND(H5Tcommit_async) +#define H5Topen_async_wrap H5_NO_EXPAND(H5Topen_async) +#define H5Tclose_async_wrap H5_NO_EXPAND(H5Tclose_async) +#endif /* H5T_MODULE */ + #ifndef H5_NO_DEPRECATED_SYMBOLS /* Macros */ @@ -598,11 +2927,140 @@ H5_DLL herr_t H5Treclaim(hid_t type_id, hid_t space_id, hid_t plist_id, void /* Typedefs */ /* Function prototypes */ +/** + * \ingroup H5T + * + * \brief Commits a transient datatype to a file, creating a new named datatype + * + * \fg_loc_id + * \param[in] name Name given to committed datatype + * \param[in] type_id Identifier of datatype to be committed + * + * \return \herr_t + * + * \deprecated This function has been renamed from H5Tcommit() and is + * deprecated in favor of the macro #H5Tcommit or the function + * H5Tcommit2(). + * + * \details H5Tcommit1() commits the transient datatype (not immutable) to + * a file, turning it into a named datatype. + * + * The datatype \p dtype_id is committed as a named datatype at the + * location \p loc_id, which is either a file or group identifier, + * with the name \p name. + * + * \p name can be a relative path based at \p loc_id or an absolute + * path from the root of the file. Use of this function requires + * that any intermediate groups specified in the path already exist. + * + * As is the case for any object in a group, the length of the name + * of a named datatype is not limited. + * + * See H5Tcommit_anon() for a discussion of the differences between + * H5Tcommit() and H5Tcommit_anon(). + * + * This function will not accept a datatype that cannot actually + * hold data. This currently includes compound datatypes with no + * fields and enumerated datatypes with no members. + * + * \version 1.8.7 Function modified in this release to reject datatypes that + * will not accommodate actual data, such as a compound datatype with + * no fields or an enumerated datatype with no members. + * \version 1.8.0 C function H5Tcommit() renamed to H5Tcommit1() and deprecated + * in this release. + * \since 1.2.0 + * + */ H5_DLL herr_t H5Tcommit1(hid_t loc_id, const char *name, hid_t type_id); -H5_DLL hid_t H5Topen1(hid_t loc_id, const char *name); -H5_DLL hid_t H5Tarray_create1(hid_t base_id, int ndims, const hsize_t dim[/* ndims */], - const int perm[/* ndims */]); -H5_DLL int H5Tget_array_dims1(hid_t type_id, hsize_t dims[], int perm[]); +/** + * \ingroup H5T + * + * \brief Opens a named datatype + * + * \fg_loc_id + * \param[in] name A datatype name, defined within the specified file or group + * + * \return \herr_t + * + * \deprecated This function has been renamed from H5Topen() and is + * deprecated in favor of the macro #H5Topen or the function + * H5Topen2(). + * + * \details H5Topen1() opens a named datatype at the location specified by + * \p loc_id and returns an identifier for the datatype. \p loc_id + * can be either a file or group identifier. The identifier should + * eventually be closed by calling H5Tclose() to release resources. + * + * \version 1.8.0 Function H5Topen() renamed to H5Topen1() and deprecated in + * this release. + * + * \since 1.2.0 + * + */ +H5_DLL hid_t H5Topen1(hid_t loc_id, const char *name); +/** + * \ingroup ARRAY + * + * \brief Creates an array datatype object + * + * \param[in] base_id Datatype identifier for the array base datatype + * \param[in] ndims Rank of the array + * \param[in] dim Size of each array dimension + * \param[in] perm Dimension permutation (Currently not implemented.) + * + * \return \hid_t{array datatype} + * + * \deprecated This function has been renamed from H5Tarray_create() and is + * deprecated in favor of the macro #H5Tarray_create or the function + * H5Tarray_create2(). + * + * \details H5Tarray_create1() creates a new array datatype object.\n\n + * \p base_id is the datatype of every element of the array, i.e., + * of the number at each position in the array. + * + * \p rank is the number of dimensions and the size of each dimension + * is specified in the array dims. The value of rank is currently + * limited to #H5S_MAX_RANK and must be greater than 0 (zero). All + * dimension sizes specified in dims must be greater than 0 (zero). + * + * The array \p perm is designed to contain the dimension permutation, + * i.e. C versus FORTRAN array order. (The parameter perm is + * currently unused and is not yet implemented.) + * + * \version 1.8.0 Function H5Tarray_create() renamed to H5Tarray_create1() + * and deprecated in this release. + * \since 1.4.0 + * + */ +H5_DLL hid_t H5Tarray_create1(hid_t base_id, int ndims, const hsize_t dim[/* ndims */], + const int perm[/* ndims */]); +/** + * \ingroup ARRAY + * + * \brief Retrieves sizes of array dimensions + * + * \type_id + * \param[out] dims Sizes of array dimensions + * \param[out] perm Dimension permutations (This parameter is not used.) + * + * \return Returns the non-negative number of dimensions of the array type + * if successful; otherwise, returns a negative value. + * + * \deprecated This function has been renamed from H5Tget_array_dims() and is + * deprecated in favor of the macro #H5Tget_array_dims or the + * function H5Tget_array_dims2(). + * + * \details H5Tget_array_dims1() returns the sizes of the dimensions and + * the dimension permutations of the specified array datatype object. + * + * The sizes of the dimensions are returned in the array \p dims. + * + * \version 1.8.0 Function H5Tarray_create() renamed to H5Tarray_create1() + * and deprecated in this release. + * \since 1.2.0 + * + */ +H5_DLL int H5Tget_array_dims1(hid_t type_id, hsize_t dims[], int perm[]); #endif /* H5_NO_DEPRECATED_SYMBOLS */ diff --git a/src/H5Tref.c b/src/H5Tref.c index 98389e8..1114c25 100644 --- a/src/H5Tref.c +++ b/src/H5Tref.c @@ -156,7 +156,7 @@ static const H5T_ref_class_t H5T_ref_dsetreg_disk_g = { *------------------------------------------------------------------------- */ htri_t -H5T__ref_set_loc(const H5T_t *dt, H5VL_object_t *file, H5T_loc_t loc) +H5T__ref_set_loc(H5T_t *dt, H5VL_object_t *file, H5T_loc_t loc) { htri_t ret_value = FALSE; /* Indicate success, but no location change */ @@ -180,6 +180,13 @@ H5T__ref_set_loc(const H5T_t *dt, H5VL_object_t *file, H5T_loc_t loc) /* Mark this type as being stored in memory */ dt->shared->u.atomic.u.r.loc = H5T_LOC_MEMORY; + /* Release owned file */ + if (dt->shared->owned_vol_obj) { + if (H5VL_free_object(dt->shared->owned_vol_obj) < 0) + HGOTO_ERROR(H5E_REFERENCE, H5E_CANTCLOSEOBJ, FAIL, "unable to close owned VOL object") + dt->shared->owned_vol_obj = NULL; + } /* end if */ + /* Reset file ID (since this reference is in memory) */ dt->shared->u.atomic.u.r.file = file; /* file is NULL */ @@ -220,6 +227,10 @@ H5T__ref_set_loc(const H5T_t *dt, H5VL_object_t *file, H5T_loc_t loc) /* Set file pointer (since this reference is on disk) */ dt->shared->u.atomic.u.r.file = file; + /* dt now owns a reference to file */ + if (H5T_own_vol_obj(dt, file) < 0) + HGOTO_ERROR(H5E_REFERENCE, H5E_CANTINIT, FAIL, "can't give ownership of VOL object") + if (dt->shared->u.atomic.u.r.rtype == H5R_OBJECT1) { H5F_t *f; diff --git a/src/H5Tvlen.c b/src/H5Tvlen.c index e220450..39d14f3 100644 --- a/src/H5Tvlen.c +++ b/src/H5Tvlen.c @@ -245,7 +245,7 @@ done: *------------------------------------------------------------------------- */ htri_t -H5T__vlen_set_loc(const H5T_t *dt, H5VL_object_t *file, H5T_loc_t loc) +H5T__vlen_set_loc(H5T_t *dt, H5VL_object_t *file, H5T_loc_t loc) { H5VL_file_cont_info_t cont_info = {H5VL_CONTAINER_INFO_VERSION, 0, 0, 0}; htri_t ret_value = FALSE; /* Indicate success, but no location change */ @@ -282,6 +282,13 @@ H5T__vlen_set_loc(const H5T_t *dt, H5VL_object_t *file, H5T_loc_t loc) else HDassert(0 && "Invalid VL type"); + /* Release owned file */ + if (dt->shared->owned_vol_obj) { + if (H5VL_free_object(dt->shared->owned_vol_obj) < 0) + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTCLOSEOBJ, FAIL, "unable to close owned VOL object") + dt->shared->owned_vol_obj = NULL; + } /* end if */ + /* Reset file pointer (since this VL is in memory) */ dt->shared->u.vlen.file = NULL; break; @@ -307,6 +314,10 @@ H5T__vlen_set_loc(const H5T_t *dt, H5VL_object_t *file, H5T_loc_t loc) /* Set file ID (since this VL is on disk) */ dt->shared->u.vlen.file = file; + + /* dt now owns a reference to file */ + if (H5T_own_vol_obj(dt, file) < 0) + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "can't give ownership of VOL object") break; case H5T_LOC_BADLOC: @@ -87,25 +87,6 @@ H5VLregister_connector(const H5VL_class_t *cls, hid_t vipl_id) FUNC_ENTER_API(H5I_INVALID_HID) H5TRACE2("i", "*#i", cls, vipl_id); - /* Check arguments */ - if (!cls) - HGOTO_ERROR(H5E_ARGS, H5E_UNINITIALIZED, H5I_INVALID_HID, - "VOL connector class pointer cannot be NULL") - if (!cls->name) - HGOTO_ERROR(H5E_VOL, H5E_CANTREGISTER, H5I_INVALID_HID, - "VOL connector class name cannot be the NULL pointer") - if (0 == HDstrlen(cls->name)) - HGOTO_ERROR(H5E_VOL, H5E_CANTREGISTER, H5I_INVALID_HID, - "VOL connector class name cannot be the empty string") - if (cls->info_cls.copy && !cls->info_cls.free) - HGOTO_ERROR( - H5E_VOL, H5E_CANTREGISTER, H5I_INVALID_HID, - "VOL connector must provide free callback for VOL info objects when a copy callback is provided") - if (cls->wrap_cls.get_wrap_ctx && !cls->wrap_cls.free_wrap_ctx) - HGOTO_ERROR(H5E_VOL, H5E_CANTREGISTER, H5I_INVALID_HID, - "VOL connector must provide free callback for object wrapping contexts when a get " - "callback is provided") - /* Check VOL initialization property list */ if (H5P_DEFAULT == vipl_id) vipl_id = H5P_VOL_INITIALIZE_DEFAULT; @@ -113,7 +94,7 @@ H5VLregister_connector(const H5VL_class_t *cls, hid_t vipl_id) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5I_INVALID_HID, "not a VOL initialize property list") /* Register connector */ - if ((ret_value = H5VL__register_connector(cls, TRUE, vipl_id)) < 0) + if ((ret_value = H5VL__register_connector_by_class(cls, TRUE, vipl_id)) < 0) HGOTO_ERROR(H5E_VOL, H5E_CANTREGISTER, H5I_INVALID_HID, "unable to register VOL connector") done: @@ -628,6 +609,7 @@ H5VLwrap_register(void *obj, H5I_type_t type) case H5I_ERROR_MSG: case H5I_ERROR_STACK: case H5I_SPACE_SEL_ITER: + case H5I_EVENTSET: case H5I_NTYPES: default: HGOTO_ERROR(H5E_VOL, H5E_BADRANGE, H5I_INVALID_HID, "invalid type number") @@ -686,7 +668,7 @@ done: hid_t H5VLget_file_type(void *file_obj, hid_t connector_id, hid_t dtype_id) { - H5T_t * dtype; /* unatomized type */ + H5T_t * dtype; /* unregistered type */ H5T_t * file_type = NULL; /* copied file type */ hid_t file_type_id = -1; /* copied file type id */ H5VL_object_t *file_vol_obj = NULL; /* VOL object for file */ @@ -701,8 +683,10 @@ H5VLget_file_type(void *file_obj, hid_t connector_id, hid_t dtype_id) if (NULL == (dtype = (H5T_t *)H5I_object_verify(dtype_id, H5I_DATATYPE))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data type") - /* Create VOL object for file */ - if (NULL == (file_vol_obj = H5VL_create_object_using_vol_id(H5I_FILE, file_obj, connector_id))) + /* Create VOL object for file if necessary (force_conv will be TRUE if and + * only if file needs to be passed to H5T_set_loc) */ + if (H5T_GET_FORCE_CONV(dtype) && + (NULL == (file_vol_obj = H5VL_create_object_using_vol_id(H5I_FILE, file_obj, connector_id)))) HGOTO_ERROR(H5E_VOL, H5E_CANTCREATE, FAIL, "can't create VOL object") /* Copy the datatype */ @@ -719,10 +703,12 @@ H5VLget_file_type(void *file_obj, hid_t connector_id, hid_t dtype_id) if (H5T_set_loc(file_type, file_vol_obj, H5T_LOC_DISK) < 0) HGOTO_ERROR(H5E_VOL, H5E_CANTINIT, FAIL, "can't set datatype location") - /* file_type now owns file_vol_obj */ - if (H5T_own_vol_obj(file_type, file_vol_obj) < 0) - HGOTO_ERROR(H5E_VOL, H5E_CANTINIT, FAIL, "can't give ownership of VOL object") - file_vol_obj = NULL; + /* Release our reference to file_type */ + if (file_vol_obj) { + if (H5VL_free_object(file_vol_obj) < 0) + HGOTO_ERROR(H5E_VOL, H5E_CANTDEC, FAIL, "unable to free VOL object") + file_vol_obj = NULL; + } /* end if */ /* Set return value */ ret_value = file_type_id; @@ -757,13 +743,13 @@ done: *--------------------------------------------------------------------------- */ herr_t -H5VLretrieve_lib_state(void **state) +H5VLretrieve_lib_state(void **state /*out*/) { herr_t ret_value = SUCCEED; /* Return value */ /* Must use this, to avoid modifying the API context stack in FUNC_ENTER */ FUNC_ENTER_API_NOINIT - H5TRACE1("e", "**x", state); + H5TRACE1("e", "x", state); /* Check args */ if (NULL == state) @@ -895,7 +881,8 @@ done: * Function: H5VLquery_optional * * Purpose: Determine if a VOL connector supports a particular optional - * callback operation. + * callback operation, and a general sense of the operation's + * behavior. * * Return: Success: Non-negative * Failure: Negative @@ -903,23 +890,23 @@ done: *--------------------------------------------------------------------------- */ herr_t -H5VLquery_optional(hid_t obj_id, H5VL_subclass_t subcls, int opt_type, hbool_t *supported) +H5VLquery_optional(hid_t obj_id, H5VL_subclass_t subcls, int opt_type, uint64_t *flags /*out*/) { H5VL_object_t *vol_obj = NULL; herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API(FAIL) - H5TRACE4("e", "iVSIs*b", obj_id, subcls, opt_type, supported); + H5TRACE4("e", "iVSIsx", obj_id, subcls, opt_type, flags); /* Check args */ - if (NULL == supported) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid supported pointer") + if (NULL == flags) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid 'flags' pointer") if (NULL == (vol_obj = (H5VL_object_t *)H5I_object(obj_id))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid object identifier") /* Query the connector */ - if (H5VL_introspect_opt_query(vol_obj, subcls, opt_type, supported) < 0) - HGOTO_ERROR(H5E_VOL, H5E_CANTGET, FAIL, "unable to query VOL connector support") + if (H5VL_introspect_opt_query(vol_obj, subcls, opt_type, flags) < 0) + HGOTO_ERROR(H5E_VOL, H5E_CANTGET, FAIL, "unable to query VOL connector operation") done: FUNC_LEAVE_API(ret_value) diff --git a/src/H5VLcallback.c b/src/H5VLcallback.c index 85c5ebd..02e0ee0 100644 --- a/src/H5VLcallback.c +++ b/src/H5VLcallback.c @@ -29,10 +29,11 @@ #include "H5private.h" /* Generic Functions */ #include "H5Eprivate.h" /* Error handling */ -#include "H5Fprivate.h" /* File access */ +#include "H5Fprivate.h" /* File access */ #include "H5Iprivate.h" /* IDs */ #include "H5MMprivate.h" /* Memory management */ #include "H5Pprivate.h" /* Property lists */ +#include "H5PLprivate.h" /* Plugins */ #include "H5VLpkg.h" /* Virtual Object Layer */ /****************/ @@ -43,6 +44,16 @@ /* Local Typedefs */ /******************/ +/* Structure used when trying to find a + * VOL connector to open a given file with. + */ +typedef struct H5VL_file_open_find_connector_t { + const char * filename; + const H5VL_class_t * cls; + H5VL_connector_prop_t *connector_prop; + hid_t fapl_id; +} H5VL_file_open_find_connector_t; + /********************/ /* Package Typedefs */ /********************/ @@ -101,6 +112,8 @@ static void * H5VL__file_create(const H5VL_class_t *cls, const char *name, unsig hid_t fapl_id, hid_t dxpl_id, void **req); static void * H5VL__file_open(const H5VL_class_t *cls, const char *name, unsigned flags, hid_t fapl_id, hid_t dxpl_id, void **req); +static herr_t H5VL__file_open_find_connector_cb(H5PL_type_t plugin_type, const void *plugin_info, + void *op_data); static herr_t H5VL__file_get(void *obj, const H5VL_class_t *cls, H5VL_file_get_t get_type, hid_t dxpl_id, void **req, va_list arguments); static herr_t H5VL__file_specific(void *obj, const H5VL_class_t *cls, H5VL_file_specific_t specific_type, @@ -152,10 +165,11 @@ static herr_t H5VL__object_optional(void *obj, const H5VL_class_t *cls, H5VL_obj static herr_t H5VL__introspect_get_conn_cls(void *obj, const H5VL_class_t *cls, H5VL_get_conn_lvl_t lvl, const H5VL_class_t **conn_cls); static herr_t H5VL__introspect_opt_query(void *obj, const H5VL_class_t *cls, H5VL_subclass_t subcls, - int opt_type, hbool_t *supported); -static herr_t H5VL__request_wait(void *req, const H5VL_class_t *cls, uint64_t timeout, H5ES_status_t *status); + int opt_type, uint64_t *flags); +static herr_t H5VL__request_wait(void *req, const H5VL_class_t *cls, uint64_t timeout, + H5VL_request_status_t *status); static herr_t H5VL__request_notify(void *req, const H5VL_class_t *cls, H5VL_request_notify_t cb, void *ctx); -static herr_t H5VL__request_cancel(void *req, const H5VL_class_t *cls); +static herr_t H5VL__request_cancel(void *req, const H5VL_class_t *cls, H5VL_request_status_t *status); static herr_t H5VL__request_specific(void *req, const H5VL_class_t *cls, H5VL_request_specific_t specific_type, va_list arguments); static herr_t H5VL__request_optional(void *req, const H5VL_class_t *cls, H5VL_request_optional_t opt_type, @@ -263,13 +277,13 @@ done: *--------------------------------------------------------------------------- */ herr_t -H5VLget_cap_flags(hid_t connector_id, unsigned *cap_flags) +H5VLget_cap_flags(hid_t connector_id, unsigned *cap_flags /*out*/) { H5VL_class_t *cls; /* VOL connector's class struct */ herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API_NOINIT - H5TRACE2("e", "i*Iu", connector_id, cap_flags); + H5TRACE2("e", "ix", connector_id, cap_flags); /* Check args */ if (NULL == (cls = (H5VL_class_t *)H5I_object_verify(connector_id, H5I_VOL))) @@ -294,13 +308,13 @@ done: *--------------------------------------------------------------------------- */ herr_t -H5VLget_value(hid_t connector_id, H5VL_class_value_t *value) +H5VLget_value(hid_t connector_id, H5VL_class_value_t *value /*out*/) { H5VL_class_t *cls; /* VOL connector's class struct */ herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API_NOINIT - H5TRACE2("e", "i*VC", connector_id, value); + H5TRACE2("e", "ix", connector_id, value); /* Check args */ if (NULL == (cls = (H5VL_class_t *)H5I_object_verify(connector_id, H5I_VOL))) @@ -599,12 +613,12 @@ done: *--------------------------------------------------------------------------- */ herr_t -H5VLconnector_str_to_info(const char *str, hid_t connector_id, void **info) +H5VLconnector_str_to_info(const char *str, hid_t connector_id, void **info /*out*/) { herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API_NOINIT - H5TRACE3("e", "*si**x", str, connector_id, info); + H5TRACE3("e", "*six", str, connector_id, info); /* Call internal routine */ if (H5VL__connector_str_to_info(str, connector_id, info) < 0) @@ -698,13 +712,13 @@ done: *--------------------------------------------------------------------------- */ herr_t -H5VLget_wrap_ctx(void *obj, hid_t connector_id, void **wrap_ctx) +H5VLget_wrap_ctx(void *obj, hid_t connector_id, void **wrap_ctx /*out*/) { H5VL_class_t *cls; /* VOL connector's class struct */ herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API_NOINIT - H5TRACE3("e", "*xi**x", obj, connector_id, wrap_ctx); + H5TRACE3("e", "*xix", obj, connector_id, wrap_ctx); /* Check args and get class pointer */ if (NULL == (cls = (H5VL_class_t *)H5I_object_verify(connector_id, H5I_VOL))) @@ -994,14 +1008,15 @@ done: */ void * H5VLattr_create(void *obj, const H5VL_loc_params_t *loc_params, hid_t connector_id, const char *name, - hid_t type_id, hid_t space_id, hid_t acpl_id, hid_t aapl_id, hid_t dxpl_id, void **req) + hid_t type_id, hid_t space_id, hid_t acpl_id, hid_t aapl_id, hid_t dxpl_id, + void **req /*out*/) { H5VL_class_t *cls; /* VOL connector's class struct */ void * ret_value = NULL; /* Return value */ FUNC_ENTER_API_NOINIT - H5TRACE10("*x", "*x*#i*siiiii**x", obj, loc_params, connector_id, name, type_id, space_id, acpl_id, - aapl_id, dxpl_id, req); + H5TRACE10("*x", "*x*#i*siiiiix", obj, loc_params, connector_id, name, type_id, space_id, acpl_id, aapl_id, + dxpl_id, req); /* Check args and get class pointer */ if (NULL == obj) @@ -1097,13 +1112,13 @@ done: */ void * H5VLattr_open(void *obj, const H5VL_loc_params_t *loc_params, hid_t connector_id, const char *name, - hid_t aapl_id, hid_t dxpl_id, void **req) + hid_t aapl_id, hid_t dxpl_id, void **req /*out*/) { H5VL_class_t *cls; /* VOL connector's class struct */ void * ret_value = NULL; /* Return value */ FUNC_ENTER_API_NOINIT - H5TRACE7("*x", "*x*#i*sii**x", obj, loc_params, connector_id, name, aapl_id, dxpl_id, req); + H5TRACE7("*x", "*x*#i*siix", obj, loc_params, connector_id, name, aapl_id, dxpl_id, req); /* Check args and get class pointer */ if (NULL == obj) @@ -1194,13 +1209,13 @@ done: *------------------------------------------------------------------------- */ herr_t -H5VLattr_read(void *obj, hid_t connector_id, hid_t mem_type_id, void *buf, hid_t dxpl_id, void **req) +H5VLattr_read(void *obj, hid_t connector_id, hid_t mem_type_id, void *buf, hid_t dxpl_id, void **req /*out*/) { H5VL_class_t *cls; /* VOL connector's class struct */ herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API_NOINIT - H5TRACE6("e", "*xii*xi**x", obj, connector_id, mem_type_id, buf, dxpl_id, req); + H5TRACE6("e", "*xii*xix", obj, connector_id, mem_type_id, buf, dxpl_id, req); /* Check args and get class pointer */ if (NULL == obj) @@ -1292,13 +1307,14 @@ done: *------------------------------------------------------------------------- */ herr_t -H5VLattr_write(void *obj, hid_t connector_id, hid_t mem_type_id, const void *buf, hid_t dxpl_id, void **req) +H5VLattr_write(void *obj, hid_t connector_id, hid_t mem_type_id, const void *buf, hid_t dxpl_id, + void **req /*out*/) { H5VL_class_t *cls; /* VOL connector's class struct */ herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API_NOINIT - H5TRACE6("e", "*xii*xi**x", obj, connector_id, mem_type_id, buf, dxpl_id, req); + H5TRACE6("e", "*xii*xix", obj, connector_id, mem_type_id, buf, dxpl_id, req); /* Check args and get class pointer */ if (NULL == obj) @@ -1398,14 +1414,14 @@ done: *------------------------------------------------------------------------- */ herr_t -H5VLattr_get(void *obj, hid_t connector_id, H5VL_attr_get_t get_type, hid_t dxpl_id, void **req, +H5VLattr_get(void *obj, hid_t connector_id, H5VL_attr_get_t get_type, hid_t dxpl_id, void **req /*out*/, va_list arguments) { H5VL_class_t *cls; /* VOL connector's class struct */ herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API_NOINIT - H5TRACE6("e", "*xiVai**xx", obj, connector_id, get_type, dxpl_id, req, arguments); + H5TRACE6("e", "*xiVaixx", obj, connector_id, get_type, dxpl_id, req, arguments); /* Check args and get class pointer */ if (NULL == obj) @@ -1508,13 +1524,13 @@ done: */ herr_t H5VLattr_specific(void *obj, const H5VL_loc_params_t *loc_params, hid_t connector_id, - H5VL_attr_specific_t specific_type, hid_t dxpl_id, void **req, va_list arguments) + H5VL_attr_specific_t specific_type, hid_t dxpl_id, void **req /*out*/, va_list arguments) { H5VL_class_t *cls; /* VOL connector's class struct */ herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API_NOINIT - H5TRACE7("e", "*x*#iVbi**xx", obj, loc_params, connector_id, specific_type, dxpl_id, req, arguments); + H5TRACE7("e", "*x*#iVbixx", obj, loc_params, connector_id, specific_type, dxpl_id, req, arguments); /* Check args and get class pointer */ if (NULL == obj) @@ -1616,14 +1632,14 @@ done: *------------------------------------------------------------------------- */ herr_t -H5VLattr_optional(void *obj, hid_t connector_id, H5VL_attr_optional_t opt_type, hid_t dxpl_id, void **req, - va_list arguments) +H5VLattr_optional(void *obj, hid_t connector_id, H5VL_attr_optional_t opt_type, hid_t dxpl_id, + void **req /*out*/, va_list arguments) { H5VL_class_t *cls; /* VOL connector's class struct */ herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API_NOINIT - H5TRACE6("e", "*xiVsi**xx", obj, connector_id, opt_type, dxpl_id, req, arguments); + H5TRACE6("e", "*xiVsixx", obj, connector_id, opt_type, dxpl_id, req, arguments); /* Check args and get class pointer */ if (NULL == obj) @@ -1707,13 +1723,13 @@ done: *------------------------------------------------------------------------- */ herr_t -H5VLattr_close(void *obj, hid_t connector_id, hid_t dxpl_id, void **req) +H5VLattr_close(void *obj, hid_t connector_id, hid_t dxpl_id, void **req /*out*/) { H5VL_class_t *cls; /* VOL connector's class struct */ herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API_NOINIT - H5TRACE4("e", "*xii**x", obj, connector_id, dxpl_id, req); + H5TRACE4("e", "*xiix", obj, connector_id, dxpl_id, req); /* Check args and get class pointer */ if (NULL == obj) @@ -1813,13 +1829,13 @@ done: void * H5VLdataset_create(void *obj, const H5VL_loc_params_t *loc_params, hid_t connector_id, const char *name, hid_t lcpl_id, hid_t type_id, hid_t space_id, hid_t dcpl_id, hid_t dapl_id, hid_t dxpl_id, - void **req) + void **req /*out*/) { H5VL_class_t *cls; /* VOL connector's class struct */ void * ret_value = NULL; /* Return value */ FUNC_ENTER_API_NOINIT - H5TRACE11("*x", "*x*#i*siiiiii**x", obj, loc_params, connector_id, name, lcpl_id, type_id, space_id, + H5TRACE11("*x", "*x*#i*siiiiiix", obj, loc_params, connector_id, name, lcpl_id, type_id, space_id, dcpl_id, dapl_id, dxpl_id, req); /* Check args and get class pointer */ @@ -1916,13 +1932,13 @@ done: */ void * H5VLdataset_open(void *obj, const H5VL_loc_params_t *loc_params, hid_t connector_id, const char *name, - hid_t dapl_id, hid_t dxpl_id, void **req) + hid_t dapl_id, hid_t dxpl_id, void **req /*out*/) { H5VL_class_t *cls; /* VOL connector's class struct */ void * ret_value = NULL; /* Return value */ FUNC_ENTER_API_NOINIT - H5TRACE7("*x", "*x*#i*sii**x", obj, loc_params, connector_id, name, dapl_id, dxpl_id, req); + H5TRACE7("*x", "*x*#i*siix", obj, loc_params, connector_id, name, dapl_id, dxpl_id, req); /* Check args and get class pointer */ if (NULL == obj) @@ -2017,13 +2033,13 @@ done: */ herr_t H5VLdataset_read(void *obj, hid_t connector_id, hid_t mem_type_id, hid_t mem_space_id, hid_t file_space_id, - hid_t dxpl_id, void *buf, void **req) + hid_t dxpl_id, void *buf, void **req /*out*/) { H5VL_class_t *cls; /* VOL connector's class struct */ herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API_NOINIT - H5TRACE8("e", "*xiiiii*x**x", obj, connector_id, mem_type_id, mem_space_id, file_space_id, dxpl_id, buf, + H5TRACE8("e", "*xiiiii*xx", obj, connector_id, mem_type_id, mem_space_id, file_space_id, dxpl_id, buf, req); /* Check args and get class pointer */ @@ -2119,13 +2135,13 @@ done: */ herr_t H5VLdataset_write(void *obj, hid_t connector_id, hid_t mem_type_id, hid_t mem_space_id, hid_t file_space_id, - hid_t dxpl_id, const void *buf, void **req) + hid_t dxpl_id, const void *buf, void **req /*out*/) { H5VL_class_t *cls; /* VOL connector's class struct */ herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API_NOINIT - H5TRACE8("e", "*xiiiii*x**x", obj, connector_id, mem_type_id, mem_space_id, file_space_id, dxpl_id, buf, + H5TRACE8("e", "*xiiiii*xx", obj, connector_id, mem_type_id, mem_space_id, file_space_id, dxpl_id, buf, req); /* Check args and get class pointer */ @@ -2226,14 +2242,14 @@ done: *------------------------------------------------------------------------- */ herr_t -H5VLdataset_get(void *obj, hid_t connector_id, H5VL_dataset_get_t get_type, hid_t dxpl_id, void **req, +H5VLdataset_get(void *obj, hid_t connector_id, H5VL_dataset_get_t get_type, hid_t dxpl_id, void **req /*out*/, va_list arguments) { H5VL_class_t *cls; /* VOL connector's class struct */ herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API_NOINIT - H5TRACE6("e", "*xiVci**xx", obj, connector_id, get_type, dxpl_id, req, arguments); + H5TRACE6("e", "*xiVcixx", obj, connector_id, get_type, dxpl_id, req, arguments); /* Check args and get class pointer */ if (NULL == obj) @@ -2336,13 +2352,13 @@ done: */ herr_t H5VLdataset_specific(void *obj, hid_t connector_id, H5VL_dataset_specific_t specific_type, hid_t dxpl_id, - void **req, va_list arguments) + void **req /*out*/, va_list arguments) { H5VL_class_t *cls; /* VOL connector's class struct */ herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API_NOINIT - H5TRACE6("e", "*xiVdi**xx", obj, connector_id, specific_type, dxpl_id, req, arguments); + H5TRACE6("e", "*xiVdixx", obj, connector_id, specific_type, dxpl_id, req, arguments); /* Check args and get class pointer */ if (NULL == obj) @@ -2444,13 +2460,13 @@ done: */ herr_t H5VLdataset_optional(void *obj, hid_t connector_id, H5VL_dataset_optional_t opt_type, hid_t dxpl_id, - void **req, va_list arguments) + void **req /*out*/, va_list arguments) { H5VL_class_t *cls; /* VOL connector's class struct */ herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API_NOINIT - H5TRACE6("e", "*xiVti**xx", obj, connector_id, opt_type, dxpl_id, req, arguments); + H5TRACE6("e", "*xiVtixx", obj, connector_id, opt_type, dxpl_id, req, arguments); /* Check args and get class pointer */ if (NULL == obj) @@ -2551,13 +2567,13 @@ done: *------------------------------------------------------------------------- */ herr_t -H5VLdataset_close(void *obj, hid_t connector_id, hid_t dxpl_id, void **req) +H5VLdataset_close(void *obj, hid_t connector_id, hid_t dxpl_id, void **req /*out*/) { H5VL_class_t *cls; /* VOL connector's class struct */ herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API_NOINIT - H5TRACE4("e", "*xii**x", obj, connector_id, dxpl_id, req); + H5TRACE4("e", "*xiix", obj, connector_id, dxpl_id, req); /* Check args and get class pointer */ if (NULL == obj) @@ -2654,14 +2670,15 @@ done: */ void * H5VLdatatype_commit(void *obj, const H5VL_loc_params_t *loc_params, hid_t connector_id, const char *name, - hid_t type_id, hid_t lcpl_id, hid_t tcpl_id, hid_t tapl_id, hid_t dxpl_id, void **req) + hid_t type_id, hid_t lcpl_id, hid_t tcpl_id, hid_t tapl_id, hid_t dxpl_id, + void **req /*out*/) { H5VL_class_t *cls; /* VOL connector's class struct */ void * ret_value = NULL; /* Return value */ FUNC_ENTER_API_NOINIT - H5TRACE10("*x", "*x*#i*siiiii**x", obj, loc_params, connector_id, name, type_id, lcpl_id, tcpl_id, - tapl_id, dxpl_id, req); + H5TRACE10("*x", "*x*#i*siiiiix", obj, loc_params, connector_id, name, type_id, lcpl_id, tcpl_id, tapl_id, + dxpl_id, req); /* Check args and get class pointer */ if (NULL == obj) @@ -2757,13 +2774,13 @@ done: */ void * H5VLdatatype_open(void *obj, const H5VL_loc_params_t *loc_params, hid_t connector_id, const char *name, - hid_t tapl_id, hid_t dxpl_id, void **req) + hid_t tapl_id, hid_t dxpl_id, void **req /*out*/) { H5VL_class_t *cls; /* VOL connector's class struct */ void * ret_value = NULL; /* Return value */ FUNC_ENTER_API_NOINIT - H5TRACE7("*x", "*x*#i*sii**x", obj, loc_params, connector_id, name, tapl_id, dxpl_id, req); + H5TRACE7("*x", "*x*#i*siix", obj, loc_params, connector_id, name, tapl_id, dxpl_id, req); /* Check args and get class pointer */ if (NULL == obj) @@ -2863,14 +2880,14 @@ done: *------------------------------------------------------------------------- */ herr_t -H5VLdatatype_get(void *obj, hid_t connector_id, H5VL_datatype_get_t get_type, hid_t dxpl_id, void **req, - va_list arguments) +H5VLdatatype_get(void *obj, hid_t connector_id, H5VL_datatype_get_t get_type, hid_t dxpl_id, + void **req /*out*/, va_list arguments) { H5VL_class_t *cls; /* VOL connector's class struct */ herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API_NOINIT - H5TRACE6("e", "*xiVei**xx", obj, connector_id, get_type, dxpl_id, req, arguments); + H5TRACE6("e", "*xiVeixx", obj, connector_id, get_type, dxpl_id, req, arguments); /* Check args and get class pointer */ if (NULL == obj) @@ -2977,13 +2994,13 @@ done: */ herr_t H5VLdatatype_specific(void *obj, hid_t connector_id, H5VL_datatype_specific_t specific_type, hid_t dxpl_id, - void **req, va_list arguments) + void **req /*out*/, va_list arguments) { H5VL_class_t *cls; /* VOL connector's class struct */ herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API_NOINIT - H5TRACE6("e", "*xiVfi**xx", obj, connector_id, specific_type, dxpl_id, req, arguments); + H5TRACE6("e", "*xiVfixx", obj, connector_id, specific_type, dxpl_id, req, arguments); /* Check args and get class pointer */ if (NULL == obj) @@ -3086,13 +3103,13 @@ done: */ herr_t H5VLdatatype_optional(void *obj, hid_t connector_id, H5VL_datatype_optional_t opt_type, hid_t dxpl_id, - void **req, va_list arguments) + void **req /*out*/, va_list arguments) { H5VL_class_t *cls; /* VOL connector's class struct */ herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API_NOINIT - H5TRACE6("e", "*xiVui**xx", obj, connector_id, opt_type, dxpl_id, req, arguments); + H5TRACE6("e", "*xiVuixx", obj, connector_id, opt_type, dxpl_id, req, arguments); /* Check args and get class pointer */ if (NULL == obj) @@ -3183,13 +3200,13 @@ done: *------------------------------------------------------------------------- */ herr_t -H5VLdatatype_close(void *obj, hid_t connector_id, hid_t dxpl_id, void **req) +H5VLdatatype_close(void *obj, hid_t connector_id, hid_t dxpl_id, void **req /*out*/) { H5VL_class_t *cls; /* VOL connector's class struct */ herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API_NOINIT - H5TRACE4("e", "*xii**x", obj, connector_id, dxpl_id, req); + H5TRACE4("e", "*xiix", obj, connector_id, dxpl_id, req); /* Check args and get class pointer */ if (NULL == obj) @@ -3283,7 +3300,8 @@ done: *------------------------------------------------------------------------- */ void * -H5VLfile_create(const char *name, unsigned flags, hid_t fcpl_id, hid_t fapl_id, hid_t dxpl_id, void **req) +H5VLfile_create(const char *name, unsigned flags, hid_t fcpl_id, hid_t fapl_id, hid_t dxpl_id, + void **req /*out*/) { H5P_genplist_t * plist; /* Property list pointer */ H5VL_connector_prop_t connector_prop; /* Property for VOL connector ID & info */ @@ -3291,7 +3309,7 @@ H5VLfile_create(const char *name, unsigned flags, hid_t fcpl_id, hid_t fapl_id, void * ret_value = NULL; /* Return value */ FUNC_ENTER_API_NOINIT - H5TRACE6("*x", "*sIuiii**x", name, flags, fcpl_id, fapl_id, dxpl_id, req); + H5TRACE6("*x", "*sIuiiix", name, flags, fcpl_id, fapl_id, dxpl_id, req); /* Get the VOL info from the fapl */ if (NULL == (plist = (H5P_genplist_t *)H5I_object(fapl_id))) @@ -3342,6 +3360,98 @@ done: } /* end H5VL__file_open() */ /*------------------------------------------------------------------------- + * Function: H5VL__file_open_find_connector_cb + * + * Purpose: Iteration callback for H5PL_iterate that tries to find the + * correct VOL connector to open a file with when + * H5VL_file_open fails for its given VOL connector. Iterates + * through all of the available VOL connector plugins until + * H5Fis_accessible returns true for the given filename and + * VOL connector. + * + * Return: H5_ITER_CONT if current plugin can't open the given file + * H5_ITER_STOP if current plugin can open given file + * H5_ITER_ERROR if an error occurs while trying to determine + * if current plugin can open given file. + * + *------------------------------------------------------------------------- + */ +static herr_t +H5VL__file_open_find_connector_cb(H5PL_type_t plugin_type, const void *plugin_info, void *op_data) +{ + H5VL_file_open_find_connector_t *udata = (H5VL_file_open_find_connector_t *)op_data; + const H5VL_class_t * cls = (const H5VL_class_t *)plugin_info; + H5P_genplist_t * fapl_plist; + H5P_genplist_t * fapl_plist_copy; + herr_t status; + htri_t is_accessible = FALSE; + hid_t connector_id = H5I_INVALID_HID; + hid_t fapl_id = H5I_INVALID_HID; + herr_t ret_value = H5_ITER_CONT; + + FUNC_ENTER_STATIC + + HDassert(udata); + HDassert(udata->filename); + HDassert(udata->connector_prop); + HDassert(cls); + HDassert(plugin_type == H5PL_TYPE_VOL); + + /* Silence compiler */ + (void)plugin_type; + + udata->cls = cls; + + /* Attempt to register plugin as a VOL connector */ + if ((connector_id = H5VL__register_connector_by_class(cls, TRUE, H5P_VOL_INITIALIZE_DEFAULT)) < 0) + HGOTO_ERROR(H5E_VOL, H5E_CANTREGISTER, H5_ITER_ERROR, "unable to register VOL connector") + + /* Setup FAPL with registered VOL connector */ + if (NULL == (fapl_plist = (H5P_genplist_t *)H5I_object_verify(udata->fapl_id, H5I_GENPROP_LST))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5_ITER_ERROR, "not a property list") + if ((fapl_id = H5P_copy_plist(fapl_plist, TRUE)) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTCOPY, H5_ITER_ERROR, "can't copy fapl"); + if (NULL == (fapl_plist_copy = (H5P_genplist_t *)H5I_object_verify(fapl_id, H5I_GENPROP_LST))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5_ITER_ERROR, "not a property list") + if (H5P_set_vol(fapl_plist_copy, connector_id, NULL) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, H5_ITER_ERROR, "can't set VOL connector on fapl") + + /* Check if file is accessible with given VOL connector */ + H5E_BEGIN_TRY + { + status = H5VL_file_specific(NULL, H5VL_FILE_IS_ACCESSIBLE, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL, + fapl_id, udata->filename, &is_accessible); + } + H5E_END_TRY; + + /* If the file was accessible with the current VOL connector, return + * the FAPL with that VOL connector set on it. Errors are ignored here + * as some VOL connectors may not support H5Fis_accessible. + */ + if (status == SUCCEED && is_accessible > 0) { + /* Modify 'connector_prop' to point to the VOL connector that + * was actually used to open the file, rather than the original + * VOL connector that was requested. + */ + udata->connector_prop->connector_id = connector_id; + udata->connector_prop->connector_info = NULL; + + udata->fapl_id = fapl_id; + ret_value = H5_ITER_STOP; + } /* end if */ + +done: + if (ret_value != H5_ITER_STOP) { + if (fapl_id >= 0 && H5I_dec_app_ref(fapl_id) < 0) + HDONE_ERROR(H5E_PLIST, H5E_CANTCLOSEOBJ, H5_ITER_ERROR, "can't close fapl") + if (connector_id >= 0 && H5I_dec_app_ref(connector_id) < 0) + HDONE_ERROR(H5E_ID, H5E_CANTCLOSEOBJ, H5_ITER_ERROR, "can't close VOL connector ID") + } /* end if */ + + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5VL__file_open_find_connector_cb() */ + +/*------------------------------------------------------------------------- * Function: H5VL_file_open * * Purpose: Opens a file through the VOL. @@ -3355,7 +3465,7 @@ done: *------------------------------------------------------------------------- */ void * -H5VL_file_open(const H5VL_connector_prop_t *connector_prop, const char *name, unsigned flags, hid_t fapl_id, +H5VL_file_open(H5VL_connector_prop_t *connector_prop, const char *name, unsigned flags, hid_t fapl_id, hid_t dxpl_id, void **req) { H5VL_class_t *cls; /* VOL Class structure for callback info */ @@ -3368,8 +3478,54 @@ H5VL_file_open(const H5VL_connector_prop_t *connector_prop, const char *name, un HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "not a VOL connector ID") /* Call the corresponding internal VOL routine */ - if (NULL == (ret_value = H5VL__file_open(cls, name, flags, fapl_id, dxpl_id, req))) - HGOTO_ERROR(H5E_VOL, H5E_CANTOPENOBJ, NULL, "open failed") + if (NULL == (ret_value = H5VL__file_open(cls, name, flags, fapl_id, dxpl_id, req))) { + H5VL_file_open_find_connector_t find_connector_ud; + hbool_t find_connector; + hbool_t connector_available = FALSE; + + /* Opening the file failed - Determine whether we should search + * the plugin path to see if any other VOL connectors are available + * to attempt to open the file with. This only occurs if no particular + * VOL connector was specified (either via a FAPL or the + * HDF5_VOL_CONNECTOR environment variable). + */ + find_connector = !getenv("HDF5_VOL_CONNECTOR") && ((H5P_FILE_ACCESS_DEFAULT == fapl_id) || + connector_prop->connector_id == H5_DEFAULT_VOL); + + if (find_connector) { + herr_t iter_ret; + + find_connector_ud.connector_prop = connector_prop; + find_connector_ud.filename = name; + find_connector_ud.cls = NULL; + find_connector_ud.fapl_id = fapl_id; + + iter_ret = H5PL_iterate(H5PL_ITER_TYPE_VOL, H5VL__file_open_find_connector_cb, + (void *)&find_connector_ud); + if (iter_ret < 0) + HGOTO_ERROR(H5E_VOL, H5E_BADITER, NULL, + "failed to iterate over available VOL connector plugins") + else if (iter_ret) + connector_available = TRUE; + } /* end if */ + + /* If one of the available VOL connector plugins is + * able to open the file, clear the error stack from any + * previous file open failures and then open the file. + * Otherwise, if no VOL connectors are available, throw + * error from original file open failure. + */ + if (connector_available) { + H5E_clear_stack(NULL); + + if (NULL == (ret_value = H5VL__file_open(find_connector_ud.cls, name, flags, + find_connector_ud.fapl_id, dxpl_id, req))) + HGOTO_ERROR(H5E_VOL, H5E_CANTOPENOBJ, NULL, "can't open file '%s' with VOL connector '%s'", + name, find_connector_ud.cls->name) + } + else + HGOTO_ERROR(H5E_VOL, H5E_CANTOPENOBJ, NULL, "open failed") + } /* end if */ done: FUNC_LEAVE_NOAPI(ret_value) @@ -3386,7 +3542,7 @@ done: *------------------------------------------------------------------------- */ void * -H5VLfile_open(const char *name, unsigned flags, hid_t fapl_id, hid_t dxpl_id, void **req) +H5VLfile_open(const char *name, unsigned flags, hid_t fapl_id, hid_t dxpl_id, void **req /*out*/) { H5P_genplist_t * plist; /* Property list pointer */ H5VL_connector_prop_t connector_prop; /* Property for VOL connector ID & info */ @@ -3394,7 +3550,7 @@ H5VLfile_open(const char *name, unsigned flags, hid_t fapl_id, hid_t dxpl_id, vo void * ret_value = NULL; /* Return value */ FUNC_ENTER_API_NOINIT - H5TRACE5("*x", "*sIuii**x", name, flags, fapl_id, dxpl_id, req); + H5TRACE5("*x", "*sIuiix", name, flags, fapl_id, dxpl_id, req); /* Get the VOL info from the fapl */ if (NULL == (plist = (H5P_genplist_t *)H5I_object(fapl_id))) @@ -3498,14 +3654,14 @@ done: *------------------------------------------------------------------------- */ herr_t -H5VLfile_get(void *obj, hid_t connector_id, H5VL_file_get_t get_type, hid_t dxpl_id, void **req, +H5VLfile_get(void *obj, hid_t connector_id, H5VL_file_get_t get_type, hid_t dxpl_id, void **req /*out*/, va_list arguments) { H5VL_class_t *cls; /* VOL connector's class struct */ herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API_NOINIT - H5TRACE6("e", "*xiVgi**xx", obj, connector_id, get_type, dxpl_id, req, arguments); + H5TRACE6("e", "*xiVgixx", obj, connector_id, get_type, dxpl_id, req, arguments); /* Check args and get class pointer */ if (NULL == obj) @@ -3643,13 +3799,13 @@ done: */ herr_t H5VLfile_specific(void *obj, hid_t connector_id, H5VL_file_specific_t specific_type, hid_t dxpl_id, - void **req, va_list arguments) + void **req /*out*/, va_list arguments) { H5VL_class_t *cls; /* VOL connector's class struct */ herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API_NOINIT - H5TRACE6("e", "*xiVhi**xx", obj, connector_id, specific_type, dxpl_id, req, arguments); + H5TRACE6("e", "*xiVhixx", obj, connector_id, specific_type, dxpl_id, req, arguments); /* Check args and get class pointer */ if (NULL == (cls = (H5VL_class_t *)H5I_object_verify(connector_id, H5I_VOL))) @@ -3748,14 +3904,14 @@ done: *------------------------------------------------------------------------- */ herr_t -H5VLfile_optional(void *obj, hid_t connector_id, H5VL_file_optional_t opt_type, hid_t dxpl_id, void **req, - va_list arguments) +H5VLfile_optional(void *obj, hid_t connector_id, H5VL_file_optional_t opt_type, hid_t dxpl_id, + void **req /*out*/, va_list arguments) { H5VL_class_t *cls; /* VOL connector's class struct */ herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API_NOINIT - H5TRACE6("e", "*xiVvi**xx", obj, connector_id, opt_type, dxpl_id, req, arguments); + H5TRACE6("e", "*xiVvixx", obj, connector_id, opt_type, dxpl_id, req, arguments); /* Check args and get class pointer */ if (NULL == obj) @@ -3850,13 +4006,13 @@ done: *------------------------------------------------------------------------- */ herr_t -H5VLfile_close(void *obj, hid_t connector_id, hid_t dxpl_id, void **req) +H5VLfile_close(void *obj, hid_t connector_id, hid_t dxpl_id, void **req /*out*/) { H5VL_class_t *cls; /* VOL connector's class struct */ herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API_NOINIT - H5TRACE4("e", "*xii**x", obj, connector_id, dxpl_id, req); + H5TRACE4("e", "*xiix", obj, connector_id, dxpl_id, req); /* Check args and get class pointer */ if (NULL == obj) @@ -3952,13 +4108,13 @@ done: */ void * H5VLgroup_create(void *obj, const H5VL_loc_params_t *loc_params, hid_t connector_id, const char *name, - hid_t lcpl_id, hid_t gcpl_id, hid_t gapl_id, hid_t dxpl_id, void **req) + hid_t lcpl_id, hid_t gcpl_id, hid_t gapl_id, hid_t dxpl_id, void **req /*out*/) { H5VL_class_t *cls; /* VOL connector's class struct */ void * ret_value = NULL; /* Return value */ FUNC_ENTER_API_NOINIT - H5TRACE9("*x", "*x*#i*siiii**x", obj, loc_params, connector_id, name, lcpl_id, gcpl_id, gapl_id, dxpl_id, + H5TRACE9("*x", "*x*#i*siiiix", obj, loc_params, connector_id, name, lcpl_id, gcpl_id, gapl_id, dxpl_id, req); /* Check args and get class pointer */ @@ -4055,13 +4211,13 @@ done: */ void * H5VLgroup_open(void *obj, const H5VL_loc_params_t *loc_params, hid_t connector_id, const char *name, - hid_t gapl_id, hid_t dxpl_id, void **req) + hid_t gapl_id, hid_t dxpl_id, void **req /*out*/) { H5VL_class_t *cls; /* VOL connector's class struct */ void * ret_value = NULL; /* Return value */ FUNC_ENTER_API_NOINIT - H5TRACE7("*x", "*x*#i*sii**x", obj, loc_params, connector_id, name, gapl_id, dxpl_id, req); + H5TRACE7("*x", "*x*#i*siix", obj, loc_params, connector_id, name, gapl_id, dxpl_id, req); /* Check args and get class pointer */ if (NULL == obj) @@ -4161,14 +4317,14 @@ done: *------------------------------------------------------------------------- */ herr_t -H5VLgroup_get(void *obj, hid_t connector_id, H5VL_group_get_t get_type, hid_t dxpl_id, void **req, +H5VLgroup_get(void *obj, hid_t connector_id, H5VL_group_get_t get_type, hid_t dxpl_id, void **req /*out*/, va_list arguments) { H5VL_class_t *cls; /* VOL connector's class struct */ herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API_NOINIT - H5TRACE6("e", "*xiVii**xx", obj, connector_id, get_type, dxpl_id, req, arguments); + H5TRACE6("e", "*xiViixx", obj, connector_id, get_type, dxpl_id, req, arguments); /* Check args and get class pointer */ if (NULL == obj) @@ -4271,13 +4427,13 @@ done: */ herr_t H5VLgroup_specific(void *obj, hid_t connector_id, H5VL_group_specific_t specific_type, hid_t dxpl_id, - void **req, va_list arguments) + void **req /*out*/, va_list arguments) { H5VL_class_t *cls; /* VOL connector's class struct */ herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API_NOINIT - H5TRACE6("e", "*xiVji**xx", obj, connector_id, specific_type, dxpl_id, req, arguments); + H5TRACE6("e", "*xiVjixx", obj, connector_id, specific_type, dxpl_id, req, arguments); /* Check args and get class pointer */ if (NULL == obj) @@ -4379,14 +4535,14 @@ done: *------------------------------------------------------------------------- */ herr_t -H5VLgroup_optional(void *obj, hid_t connector_id, H5VL_group_optional_t opt_type, hid_t dxpl_id, void **req, - va_list arguments) +H5VLgroup_optional(void *obj, hid_t connector_id, H5VL_group_optional_t opt_type, hid_t dxpl_id, + void **req /*out*/, va_list arguments) { H5VL_class_t *cls; /* VOL connector's class struct */ herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API_NOINIT - H5TRACE6("e", "*xiVwi**xx", obj, connector_id, opt_type, dxpl_id, req, arguments); + H5TRACE6("e", "*xiVwixx", obj, connector_id, opt_type, dxpl_id, req, arguments); /* Check args and get class pointer */ if (NULL == obj) @@ -4481,13 +4637,13 @@ done: *------------------------------------------------------------------------- */ herr_t -H5VLgroup_close(void *obj, hid_t connector_id, hid_t dxpl_id, void **req) +H5VLgroup_close(void *obj, hid_t connector_id, hid_t dxpl_id, void **req /*out*/) { H5VL_class_t *cls; /* VOL connector's class struct */ herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API_NOINIT - H5TRACE4("e", "*xii**x", obj, connector_id, dxpl_id, req); + H5TRACE4("e", "*xiix", obj, connector_id, dxpl_id, req); /* Check args and get class pointer */ if (NULL == obj) @@ -4613,15 +4769,15 @@ done: */ herr_t H5VLlink_create(H5VL_link_create_type_t create_type, void *obj, const H5VL_loc_params_t *loc_params, - hid_t connector_id, hid_t lcpl_id, hid_t lapl_id, hid_t dxpl_id, void **req, + hid_t connector_id, hid_t lcpl_id, hid_t lapl_id, hid_t dxpl_id, void **req /*out*/, va_list arguments) { H5VL_class_t *cls; /* VOL connector's class struct */ herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API_NOINIT - H5TRACE9("e", "Vk*x*#iiii**xx", create_type, obj, loc_params, connector_id, lcpl_id, lapl_id, dxpl_id, - req, arguments); + H5TRACE9("e", "Vk*x*#iiiixx", create_type, obj, loc_params, connector_id, lcpl_id, lapl_id, dxpl_id, req, + arguments); /* Get class pointer */ if (NULL == (cls = (H5VL_class_t *)H5I_object_verify(connector_id, H5I_VOL))) @@ -4721,14 +4877,14 @@ done: herr_t H5VLlink_copy(void *src_obj, const H5VL_loc_params_t *loc_params1, void *dst_obj, const H5VL_loc_params_t *loc_params2, hid_t connector_id, hid_t lcpl_id, hid_t lapl_id, - hid_t dxpl_id, void **req) + hid_t dxpl_id, void **req /*out*/) { H5VL_class_t *cls; /* VOL connector's class struct */ herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API_NOINIT - H5TRACE9("e", "*x*#*x*#iiii**x", src_obj, loc_params1, dst_obj, loc_params2, connector_id, lcpl_id, - lapl_id, dxpl_id, req); + H5TRACE9("e", "*x*#*x*#iiiix", src_obj, loc_params1, dst_obj, loc_params2, connector_id, lcpl_id, lapl_id, + dxpl_id, req); /* Get class pointer */ if (NULL == (cls = (H5VL_class_t *)H5I_object_verify(connector_id, H5I_VOL))) @@ -4828,14 +4984,14 @@ done: herr_t H5VLlink_move(void *src_obj, const H5VL_loc_params_t *loc_params1, void *dst_obj, const H5VL_loc_params_t *loc_params2, hid_t connector_id, hid_t lcpl_id, hid_t lapl_id, - hid_t dxpl_id, void **req) + hid_t dxpl_id, void **req /*out*/) { H5VL_class_t *cls; /* VOL connector's class struct */ herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API_NOINIT - H5TRACE9("e", "*x*#*x*#iiii**x", src_obj, loc_params1, dst_obj, loc_params2, connector_id, lcpl_id, - lapl_id, dxpl_id, req); + H5TRACE9("e", "*x*#*x*#iiiix", src_obj, loc_params1, dst_obj, loc_params2, connector_id, lcpl_id, lapl_id, + dxpl_id, req); /* Get class pointer */ if (NULL == (cls = (H5VL_class_t *)H5I_object_verify(connector_id, H5I_VOL))) @@ -4936,13 +5092,13 @@ done: */ herr_t H5VLlink_get(void *obj, const H5VL_loc_params_t *loc_params, hid_t connector_id, H5VL_link_get_t get_type, - hid_t dxpl_id, void **req, va_list arguments) + hid_t dxpl_id, void **req /*out*/, va_list arguments) { H5VL_class_t *cls; /* VOL connector's class struct */ herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API_NOINIT - H5TRACE7("e", "*x*#iVli**xx", obj, loc_params, connector_id, get_type, dxpl_id, req, arguments); + H5TRACE7("e", "*x*#iVlixx", obj, loc_params, connector_id, get_type, dxpl_id, req, arguments); /* Check args and get class pointer */ if (NULL == obj) @@ -5045,13 +5201,13 @@ done: */ herr_t H5VLlink_specific(void *obj, const H5VL_loc_params_t *loc_params, hid_t connector_id, - H5VL_link_specific_t specific_type, hid_t dxpl_id, void **req, va_list arguments) + H5VL_link_specific_t specific_type, hid_t dxpl_id, void **req /*out*/, va_list arguments) { H5VL_class_t *cls; /* VOL connector's class struct */ herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API_NOINIT - H5TRACE7("e", "*x*#iVmi**xx", obj, loc_params, connector_id, specific_type, dxpl_id, req, arguments); + H5TRACE7("e", "*x*#iVmixx", obj, loc_params, connector_id, specific_type, dxpl_id, req, arguments); /* Check args and get class pointer */ if (NULL == obj) @@ -5152,14 +5308,14 @@ done: *------------------------------------------------------------------------- */ herr_t -H5VLlink_optional(void *obj, hid_t connector_id, H5VL_link_optional_t opt_type, hid_t dxpl_id, void **req, - va_list arguments) +H5VLlink_optional(void *obj, hid_t connector_id, H5VL_link_optional_t opt_type, hid_t dxpl_id, + void **req /*out*/, va_list arguments) { H5VL_class_t *cls; /* VOL connector's class struct */ herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API_NOINIT - H5TRACE6("e", "*xiVxi**xx", obj, connector_id, opt_type, dxpl_id, req, arguments); + H5TRACE6("e", "*xiVxixx", obj, connector_id, opt_type, dxpl_id, req, arguments); /* Check args and get class pointer */ if (NULL == obj) @@ -5254,13 +5410,13 @@ done: */ void * H5VLobject_open(void *obj, const H5VL_loc_params_t *params, hid_t connector_id, H5I_type_t *opened_type, - hid_t dxpl_id, void **req) + hid_t dxpl_id, void **req /*out*/) { H5VL_class_t *cls; /* VOL connector's class struct */ void * ret_value = NULL; /* Return value */ FUNC_ENTER_API_NOINIT - H5TRACE6("*x", "*x*#i*Iti**x", obj, params, connector_id, opened_type, dxpl_id, req); + H5TRACE6("*x", "*x*#i*Itix", obj, params, connector_id, opened_type, dxpl_id, req); /* Check args and get class pointer */ if (NULL == obj) @@ -5364,14 +5520,14 @@ done: herr_t H5VLobject_copy(void *src_obj, const H5VL_loc_params_t *src_loc_params, const char *src_name, void *dst_obj, const H5VL_loc_params_t *dst_loc_params, const char *dst_name, hid_t connector_id, - hid_t ocpypl_id, hid_t lcpl_id, hid_t dxpl_id, void **req) + hid_t ocpypl_id, hid_t lcpl_id, hid_t dxpl_id, void **req /*out*/) { H5VL_class_t *cls; /* VOL connector's class struct */ herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API_NOINIT - H5TRACE11("e", "*x*#*s*x*#*siiii**x", src_obj, src_loc_params, src_name, dst_obj, dst_loc_params, - dst_name, connector_id, ocpypl_id, lcpl_id, dxpl_id, req); + H5TRACE11("e", "*x*#*s*x*#*siiiix", src_obj, src_loc_params, src_name, dst_obj, dst_loc_params, dst_name, + connector_id, ocpypl_id, lcpl_id, dxpl_id, req); /* Check args and get class pointers */ if (NULL == src_obj || NULL == dst_obj) @@ -5475,13 +5631,13 @@ done: */ herr_t H5VLobject_get(void *obj, const H5VL_loc_params_t *loc_params, hid_t connector_id, H5VL_object_get_t get_type, - hid_t dxpl_id, void **req, va_list arguments) + hid_t dxpl_id, void **req /*out*/, va_list arguments) { H5VL_class_t *cls; /* VOL connector's class struct */ herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API_NOINIT - H5TRACE7("e", "*x*#iVni**xx", obj, loc_params, connector_id, get_type, dxpl_id, req, arguments); + H5TRACE7("e", "*x*#iVnixx", obj, loc_params, connector_id, get_type, dxpl_id, req, arguments); /* Check args and get class pointer */ if (NULL == obj) @@ -5584,13 +5740,14 @@ done: */ herr_t H5VLobject_specific(void *obj, const H5VL_loc_params_t *loc_params, hid_t connector_id, - H5VL_object_specific_t specific_type, hid_t dxpl_id, void **req, va_list arguments) + H5VL_object_specific_t specific_type, hid_t dxpl_id, void **req /*out*/, + va_list arguments) { H5VL_class_t *cls; /* VOL connector's class struct */ herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API_NOINIT - H5TRACE7("e", "*x*#iVoi**xx", obj, loc_params, connector_id, specific_type, dxpl_id, req, arguments); + H5TRACE7("e", "*x*#iVoixx", obj, loc_params, connector_id, specific_type, dxpl_id, req, arguments); /* Check args and get class pointer */ if (NULL == obj) @@ -5695,14 +5852,14 @@ done: *------------------------------------------------------------------------- */ herr_t -H5VLobject_optional(void *obj, hid_t connector_id, H5VL_object_optional_t opt_type, hid_t dxpl_id, void **req, - va_list arguments) +H5VLobject_optional(void *obj, hid_t connector_id, H5VL_object_optional_t opt_type, hid_t dxpl_id, + void **req /*out*/, va_list arguments) { H5VL_class_t *cls; /* VOL connector's class struct */ herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API_NOINIT - H5TRACE6("e", "*xiVyi**xx", obj, connector_id, opt_type, dxpl_id, req, arguments); + H5TRACE6("e", "*xiVyixx", obj, connector_id, opt_type, dxpl_id, req, arguments); /* Check args and get class pointer */ if (NULL == obj) @@ -5805,13 +5962,13 @@ done: */ herr_t H5VLintrospect_get_conn_cls(void *obj, hid_t connector_id, H5VL_get_conn_lvl_t lvl, - const H5VL_class_t **conn_cls) + const H5VL_class_t **conn_cls /*out*/) { H5VL_class_t *cls; /* VOL connector's class struct */ herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API_NOINIT - H5TRACE4("e", "*xiVL**#", obj, connector_id, lvl, conn_cls); + H5TRACE4("e", "*xiVLx", obj, connector_id, lvl, conn_cls); /* Check args */ if (NULL == obj) @@ -5844,7 +6001,7 @@ done: */ static herr_t H5VL__introspect_opt_query(void *obj, const H5VL_class_t *cls, H5VL_subclass_t subcls, int opt_type, - hbool_t *supported) + uint64_t *flags) { herr_t ret_value = SUCCEED; /* Return value */ @@ -5855,7 +6012,7 @@ H5VL__introspect_opt_query(void *obj, const H5VL_class_t *cls, H5VL_subclass_t s HGOTO_ERROR(H5E_VOL, H5E_UNSUPPORTED, FAIL, "VOL connector has no 'opt_query' method") /* Call the corresponding VOL callback */ - if ((cls->introspect_cls.opt_query)(obj, subcls, opt_type, supported) < 0) + if ((cls->introspect_cls.opt_query)(obj, subcls, opt_type, flags) < 0) HGOTO_ERROR(H5E_VOL, H5E_CANTGET, FAIL, "can't query optional operation support") done: @@ -5874,8 +6031,7 @@ done: *------------------------------------------------------------------------- */ herr_t -H5VL_introspect_opt_query(const H5VL_object_t *vol_obj, H5VL_subclass_t subcls, int opt_type, - hbool_t *supported) +H5VL_introspect_opt_query(const H5VL_object_t *vol_obj, H5VL_subclass_t subcls, int opt_type, uint64_t *flags) { hbool_t vol_wrapper_set = FALSE; /* Whether the VOL object wrapping context was set up */ herr_t ret_value = SUCCEED; /* Return value */ @@ -5888,7 +6044,7 @@ H5VL_introspect_opt_query(const H5VL_object_t *vol_obj, H5VL_subclass_t subcls, vol_wrapper_set = TRUE; /* Call the corresponding internal VOL routine */ - if (H5VL__introspect_opt_query(vol_obj->data, vol_obj->connector->cls, subcls, opt_type, supported) < 0) + if (H5VL__introspect_opt_query(vol_obj->data, vol_obj->connector->cls, subcls, opt_type, flags) < 0) HGOTO_ERROR(H5E_VOL, H5E_CANTGET, FAIL, "can't query optional operation support") done: @@ -5912,20 +6068,20 @@ done: */ herr_t H5VLintrospect_opt_query(void *obj, hid_t connector_id, H5VL_subclass_t subcls, int opt_type, - hbool_t *supported) + uint64_t *flags /*out*/) { H5VL_class_t *cls; /* VOL connector's class struct */ herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API_NOINIT - H5TRACE5("e", "*xiVSIs*b", obj, connector_id, subcls, opt_type, supported); + H5TRACE5("e", "*xiVSIsx", obj, connector_id, subcls, opt_type, flags); /* Get class pointer */ if (NULL == (cls = (H5VL_class_t *)H5I_object_verify(connector_id, H5I_VOL))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a VOL connector ID") /* Call the corresponding internal VOL routine */ - if (H5VL__introspect_opt_query(obj, cls, subcls, opt_type, supported) < 0) + if (H5VL__introspect_opt_query(obj, cls, subcls, opt_type, flags) < 0) HGOTO_ERROR(H5E_VOL, H5E_CANTGET, FAIL, "can't query optional operation support") done: @@ -5937,16 +6093,13 @@ done: * * Purpose: Waits on an asychronous request through the VOL * - * Note: Releases the request if the operation has completed and the - * connector callback succeeds - * * Return: Success: Non-negative * Failure: Negative * *------------------------------------------------------------------------- */ static herr_t -H5VL__request_wait(void *req, const H5VL_class_t *cls, uint64_t timeout, H5ES_status_t *status) +H5VL__request_wait(void *req, const H5VL_class_t *cls, uint64_t timeout, H5VL_request_status_t *status) { herr_t ret_value = SUCCEED; /* Return value */ @@ -5974,16 +6127,13 @@ done: * * Purpose: Waits on an asychronous request through the VOL * - * Note: Releases the request if the operation has completed and the - * connector callback succeeds - * * Return: Success: Non-negative * Failure: Negative * *------------------------------------------------------------------------- */ herr_t -H5VL_request_wait(const H5VL_object_t *vol_obj, uint64_t timeout, H5ES_status_t *status) +H5VL_request_wait(const H5VL_object_t *vol_obj, uint64_t timeout, H5VL_request_status_t *status) { hbool_t vol_wrapper_set = FALSE; /* Whether the VOL object wrapping context was set up */ herr_t ret_value = SUCCEED; /* Return value */ @@ -6015,22 +6165,19 @@ done: * * Purpose: Waits on a request * - * Note: Releases the request if the operation has completed and the - * connector callback succeeds - * * Return: Success: Non-negative * Failure: Negative * *------------------------------------------------------------------------- */ herr_t -H5VLrequest_wait(void *req, hid_t connector_id, uint64_t timeout, H5ES_status_t *status) +H5VLrequest_wait(void *req, hid_t connector_id, uint64_t timeout, H5VL_request_status_t *status /*out*/) { H5VL_class_t *cls; /* VOL connector's class struct */ herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API_NOINIT - H5TRACE4("e", "*xiUL*Es", req, connector_id, timeout, status); + H5TRACE4("e", "*xiULx", req, connector_id, timeout, status); /* Get class pointer */ if (NULL == (cls = (H5VL_class_t *)H5I_object_verify(connector_id, H5I_VOL))) @@ -6050,8 +6197,6 @@ done: * Purpose: Registers a user callback to be invoked when an asynchronous * operation completes * - * Note: Releases the request, if connector callback succeeds - * * Return: Success: Non-negative * Failure: Negative * @@ -6086,8 +6231,6 @@ done: * Purpose: Registers a user callback to be invoked when an asynchronous * operation completes * - * Note: Releases the request, if connector callback succeeds - * * Return: Success: Non-negative * Failure: Negative * @@ -6127,8 +6270,6 @@ done: * Purpose: Registers a user callback to be invoked when an asynchronous * operation completes * - * Note: Releases the request, if connector callback succeeds - * * Return: Success: Non-negative * Failure: Negative * @@ -6160,15 +6301,13 @@ done: * * Purpose: Cancels an asynchronous request through the VOL * - * Note: Releases the request, if connector callback succeeds - * * Return: Success: Non-negative * Failure: Negative * *------------------------------------------------------------------------- */ static herr_t -H5VL__request_cancel(void *req, const H5VL_class_t *cls) +H5VL__request_cancel(void *req, const H5VL_class_t *cls, H5VL_request_status_t *status) { herr_t ret_value = SUCCEED; /* Return value */ @@ -6183,7 +6322,7 @@ H5VL__request_cancel(void *req, const H5VL_class_t *cls) HGOTO_ERROR(H5E_VOL, H5E_UNSUPPORTED, FAIL, "VOL connector has no 'async cancel' method") /* Call the corresponding VOL callback */ - if ((cls->request_cls.cancel)(req) < 0) + if ((cls->request_cls.cancel)(req, status) < 0) HGOTO_ERROR(H5E_VOL, H5E_CANTRELEASE, FAIL, "request cancel failed") done: @@ -6195,15 +6334,13 @@ done: * * Purpose: Cancels an asynchronous request through the VOL * - * Note: Releases the request, if connector callback succeeds - * * Return: Success: Non-negative * Failure: Negative * *------------------------------------------------------------------------- */ herr_t -H5VL_request_cancel(const H5VL_object_t *vol_obj) +H5VL_request_cancel(const H5VL_object_t *vol_obj, H5VL_request_status_t *status) { hbool_t vol_wrapper_set = FALSE; /* Whether the VOL object wrapping context was set up */ herr_t ret_value = SUCCEED; /* Return value */ @@ -6219,7 +6356,7 @@ H5VL_request_cancel(const H5VL_object_t *vol_obj) vol_wrapper_set = TRUE; /* Call the corresponding internal VOL routine */ - if (H5VL__request_cancel(vol_obj->data, vol_obj->connector->cls) < 0) + if (H5VL__request_cancel(vol_obj->data, vol_obj->connector->cls, status) < 0) HGOTO_ERROR(H5E_VOL, H5E_CANTRELEASE, FAIL, "request cancel failed") done: @@ -6235,28 +6372,26 @@ done: * * Purpose: Cancels a request * - * Note: Releases the request, if connector callback succeeds - * * Return: Success: Non-negative * Failure: Negative * *------------------------------------------------------------------------- */ herr_t -H5VLrequest_cancel(void *req, hid_t connector_id) +H5VLrequest_cancel(void *req, hid_t connector_id, H5VL_request_status_t *status) { H5VL_class_t *cls; /* VOL connector's class struct */ herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API_NOINIT - H5TRACE2("e", "*xi", req, connector_id); + H5TRACE3("e", "*xi*#", req, connector_id, status); /* Get class pointer */ if (NULL == (cls = (H5VL_class_t *)H5I_object_verify(connector_id, H5I_VOL))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a VOL connector ID") /* Call the corresponding internal VOL routine */ - if (H5VL__request_cancel(req, cls) < 0) + if (H5VL__request_cancel(req, cls, status) < 0) HGOTO_ERROR(H5E_VOL, H5E_CANTRELEASE, FAIL, "unable to cancel request") done: @@ -6783,13 +6918,13 @@ done: *------------------------------------------------------------------------- */ herr_t -H5VLblob_get(void *obj, hid_t connector_id, const void *blob_id, void *buf, size_t size, void *ctx) +H5VLblob_get(void *obj, hid_t connector_id, const void *blob_id, void *buf /*out*/, size_t size, void *ctx) { H5VL_class_t *cls; /* VOL connector's class struct */ herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API_NOINIT - H5TRACE6("e", "*xi*x*xz*x", obj, connector_id, blob_id, buf, size, ctx); + H5TRACE6("e", "*xi*xxz*x", obj, connector_id, blob_id, buf, size, ctx); /* Get class pointer */ if (NULL == obj) @@ -7495,13 +7630,13 @@ done: *------------------------------------------------------------------------- */ herr_t -H5VLoptional(void *obj, hid_t connector_id, int op_type, hid_t dxpl_id, void **req, va_list arguments) +H5VLoptional(void *obj, hid_t connector_id, int op_type, hid_t dxpl_id, void **req /*out*/, va_list arguments) { H5VL_class_t *cls; /* VOL connector's class struct */ herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API_NOINIT - H5TRACE6("e", "*xiIsi**xx", obj, connector_id, op_type, dxpl_id, req, arguments); + H5TRACE6("e", "*xiIsixx", obj, connector_id, op_type, dxpl_id, req, arguments); /* Check args and get class pointer */ if (NULL == obj) diff --git a/src/H5VLconnector.h b/src/H5VLconnector.h index acebe27..63613bc 100644 --- a/src/H5VLconnector.h +++ b/src/H5VLconnector.h @@ -82,7 +82,8 @@ typedef enum H5VL_dataset_specific_t { H5VL_DATASET_SET_EXTENT, /* H5Dset_extent */ H5VL_DATASET_FLUSH, /* H5Dflush */ H5VL_DATASET_REFRESH, /* H5Drefresh */ - H5VL_DATASET_WAIT /* H5Dwait */ + H5VL_DATASET_WAIT, /* H5Dwait */ + H5VL_DATASET_CHUNK_ITER /* H5Dchunk_iter */ } H5VL_dataset_specific_t; /* Typedef for VOL connector dataset optional VOL operations */ @@ -410,7 +411,7 @@ typedef struct H5VL_object_class_t { } H5VL_object_class_t; /* Asynchronous request 'notify' callback */ -typedef herr_t (*H5VL_request_notify_t)(void *ctx, H5ES_status_t status); +typedef herr_t (*H5VL_request_notify_t)(void *ctx, H5VL_request_status_t status); /* "Levels" for 'get connector class' introspection callback */ typedef enum H5VL_get_conn_lvl_t { @@ -426,14 +427,14 @@ struct H5VL_class_t; /* Container/connector introspection routines */ typedef struct H5VL_introspect_class_t { herr_t (*get_conn_cls)(void *obj, H5VL_get_conn_lvl_t lvl, const struct H5VL_class_t **conn_cls); - herr_t (*opt_query)(void *obj, H5VL_subclass_t cls, int opt_type, hbool_t *supported); + herr_t (*opt_query)(void *obj, H5VL_subclass_t cls, int opt_type, uint64_t *flags); } H5VL_introspect_class_t; /* Async request operation routines */ typedef struct H5VL_request_class_t { - herr_t (*wait)(void *req, uint64_t timeout, H5ES_status_t *status); + herr_t (*wait)(void *req, uint64_t timeout, H5VL_request_status_t *status); herr_t (*notify)(void *req, H5VL_request_notify_t cb, void *ctx); - herr_t (*cancel)(void *req); + herr_t (*cancel)(void *req, H5VL_request_status_t *status); herr_t (*specific)(void *req, H5VL_request_specific_t specific_type, va_list arguments); herr_t (*optional)(void *req, H5VL_request_optional_t opt_type, va_list arguments); herr_t (*free)(void *req); diff --git a/src/H5VLconnector_passthru.h b/src/H5VLconnector_passthru.h index 1b6715b..720740f 100644 --- a/src/H5VLconnector_passthru.h +++ b/src/H5VLconnector_passthru.h @@ -195,12 +195,13 @@ H5_DLL herr_t H5VLobject_optional(void *obj, hid_t connector_id, H5VL_object_opt H5_DLL herr_t H5VLintrospect_get_conn_cls(void *obj, hid_t connector_id, H5VL_get_conn_lvl_t lvl, const H5VL_class_t **conn_cls); H5_DLL herr_t H5VLintrospect_opt_query(void *obj, hid_t connector_id, H5VL_subclass_t subcls, int opt_type, - hbool_t *supported); + uint64_t *flags); /* Public wrappers for asynchronous request callbacks */ -H5_DLL herr_t H5VLrequest_wait(void *req, hid_t connector_id, uint64_t timeout, H5ES_status_t *status); +H5_DLL herr_t H5VLrequest_wait(void *req, hid_t connector_id, uint64_t timeout, + H5VL_request_status_t *status); H5_DLL herr_t H5VLrequest_notify(void *req, hid_t connector_id, H5VL_request_notify_t cb, void *ctx); -H5_DLL herr_t H5VLrequest_cancel(void *req, hid_t connector_id); +H5_DLL herr_t H5VLrequest_cancel(void *req, hid_t connector_id, H5VL_request_status_t *status); H5_DLL herr_t H5VLrequest_specific(void *req, hid_t connector_id, H5VL_request_specific_t specific_type, va_list arguments); H5_DLL herr_t H5VLrequest_optional(void *req, hid_t connector_id, H5VL_request_optional_t opt_type, diff --git a/src/H5VLint.c b/src/H5VLint.c index 7b3da7a..500e075 100644 --- a/src/H5VLint.c +++ b/src/H5VLint.c @@ -86,14 +86,12 @@ typedef struct { /********************/ /* Local Prototypes */ /********************/ -static herr_t H5VL__free_cls(H5VL_class_t *cls); +static herr_t H5VL__free_cls(H5VL_class_t *cls, void **request); static int H5VL__get_connector_cb(void *obj, hid_t id, void *_op_data); static herr_t H5VL__set_def_conn(void); static void * H5VL__wrap_obj(void *obj, H5I_type_t obj_type); static H5VL_object_t *H5VL__new_vol_obj(H5I_type_t type, void *object, H5VL_t *vol_connector, hbool_t wrap_obj); -static int64_t H5VL__conn_inc_rc(H5VL_t *connector); -static int64_t H5VL__conn_dec_rc(H5VL_t *connector); static void * H5VL__object(hid_t id, H5I_type_t obj_type); static herr_t H5VL__free_vol_wrapper(H5VL_wrap_ctx_t *vol_wrap_ctx); @@ -289,7 +287,7 @@ H5VL_term_package(void) *------------------------------------------------------------------------- */ static herr_t -H5VL__free_cls(H5VL_class_t *cls) +H5VL__free_cls(H5VL_class_t *cls, void H5_ATTR_UNUSED **request) { herr_t ret_value = SUCCEED; @@ -570,9 +568,10 @@ H5VL__new_vol_obj(H5I_type_t type, void *object, H5VL_t *vol_connector, hbool_t } /* end if */ else new_vol_obj->data = object; + new_vol_obj->rc = 1; /* Bump the reference count on the VOL connector */ - H5VL__conn_inc_rc(vol_connector); + H5VL_conn_inc_rc(vol_connector); conn_rc_incr = TRUE; /* If this is a datatype, we have to hide the VOL object under the H5T_t pointer */ @@ -586,7 +585,7 @@ H5VL__new_vol_obj(H5I_type_t type, void *object, H5VL_t *vol_connector, hbool_t done: /* Cleanup on error */ if (NULL == ret_value) { - if (conn_rc_incr && H5VL__conn_dec_rc(vol_connector) < 0) + if (conn_rc_incr && H5VL_conn_dec_rc(vol_connector) < 0) HDONE_ERROR(H5E_VOL, H5E_CANTDEC, NULL, "unable to decrement ref count on VOL connector") } /* end if */ @@ -816,6 +815,46 @@ done: } /* end H5VL_register_using_vol_id() */ /*------------------------------------------------------------------------- + * Function: H5VL_create_object + * + * Purpose: Similar to H5VL_register but does not create an ID. + * Creates a new VOL object for the provided generic object + * using the provided vol connector. Should only be used for + * internal objects returned from the connector such as + * requests. + * + * Return: Success: A valid VOL object + * Failure: NULL + * + *------------------------------------------------------------------------- + */ +H5VL_object_t * +H5VL_create_object(void *object, H5VL_t *vol_connector) +{ + H5VL_object_t *ret_value = NULL; /* Return value */ + + FUNC_ENTER_NOAPI(NULL) + + /* Check arguments */ + HDassert(object); + HDassert(vol_connector); + + /* Set up VOL object for the passed-in data */ + /* (Does not wrap object, since it's from a VOL callback) */ + if (NULL == (ret_value = H5FL_CALLOC(H5VL_object_t))) + HGOTO_ERROR(H5E_VOL, H5E_CANTALLOC, NULL, "can't allocate memory for VOL object") + ret_value->connector = vol_connector; + ret_value->data = object; + ret_value->rc = 1; + + /* Bump the reference count on the VOL connector */ + H5VL_conn_inc_rc(vol_connector); + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5VL_create_object() */ + +/*------------------------------------------------------------------------- * Function: H5VL_create_object_using_vol_id * * Purpose: Similar to H5VL_register_using_vol_id but does not create @@ -871,7 +910,7 @@ done: } /* end H5VL_create_object_using_vol_id() */ /*------------------------------------------------------------------------- - * Function: H5VL__conn_inc_rc + * Function: H5VL_conn_inc_rc * * Purpose: Wrapper to increment the ref. count on a connector. * @@ -882,10 +921,12 @@ done: * *------------------------------------------------------------------------- */ -static int64_t -H5VL__conn_inc_rc(H5VL_t *connector) +int64_t +H5VL_conn_inc_rc(H5VL_t *connector) { - FUNC_ENTER_STATIC_NOERR + int64_t ret_value = -1; + + FUNC_ENTER_NOAPI(-1) /* Check arguments */ HDassert(connector); @@ -893,11 +934,14 @@ H5VL__conn_inc_rc(H5VL_t *connector) /* Increment refcount for connector */ connector->nrefs++; - FUNC_LEAVE_NOAPI(connector->nrefs) -} /* end H5VL__conn_inc_rc() */ + ret_value = connector->nrefs; + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5VL_conn_inc_rc() */ /*------------------------------------------------------------------------- - * Function: H5VL__conn_dec_rc + * Function: H5VL_conn_dec_rc * * Purpose: Wrapper to decrement the ref. count on a connector. * @@ -908,12 +952,12 @@ H5VL__conn_inc_rc(H5VL_t *connector) * *------------------------------------------------------------------------- */ -static int64_t -H5VL__conn_dec_rc(H5VL_t *connector) +int64_t +H5VL_conn_dec_rc(H5VL_t *connector) { int64_t ret_value = -1; /* Return value */ - FUNC_ENTER_STATIC + FUNC_ENTER_NOAPI(-1) /* Check arguments */ HDassert(connector); @@ -936,7 +980,28 @@ H5VL__conn_dec_rc(H5VL_t *connector) done: FUNC_LEAVE_NOAPI(ret_value) -} /* end H5VL__conn_dec_rc() */ +} /* end H5VL_conn_dec_rc() */ + +/*------------------------------------------------------------------------- + * Function: H5VL_object_inc_rc + * + * Purpose: Wrapper to increment the ref count on a VOL object. + * + * Return: SUCCEED/FAIL + * + *------------------------------------------------------------------------- + */ +hsize_t +H5VL_object_inc_rc(H5VL_object_t *vol_obj) +{ + FUNC_ENTER_NOAPI_NOERR_NOFS + + /* Check arguments */ + HDassert(vol_obj); + + /* Increment refcount for object and return */ + FUNC_LEAVE_NOAPI(++vol_obj->rc) +} /* end H5VL_object_inc_rc() */ /*------------------------------------------------------------------------- * Function: H5VL_free_object @@ -958,11 +1023,13 @@ H5VL_free_object(H5VL_object_t *vol_obj) /* Check arguments */ HDassert(vol_obj); - /* Decrement refcount on connector */ - if (H5VL__conn_dec_rc(vol_obj->connector) < 0) - HGOTO_ERROR(H5E_VOL, H5E_CANTDEC, FAIL, "unable to decrement ref count on VOL connector") + if (--vol_obj->rc == 0) { + /* Decrement refcount on connector */ + if (H5VL_conn_dec_rc(vol_obj->connector) < 0) + HGOTO_ERROR(H5E_VOL, H5E_CANTDEC, FAIL, "unable to decrement ref count on VOL connector") - vol_obj = H5FL_FREE(H5VL_object_t, vol_obj); + vol_obj = H5FL_FREE(H5VL_object_t, vol_obj); + } /* end if */ done: FUNC_LEAVE_NOAPI(ret_value) @@ -1075,7 +1142,7 @@ done: } /* end H5VL_file_is_same() */ /*------------------------------------------------------------------------- - * Function: H5VL_register_connector + * Function: H5VL__register_connector * * Purpose: Registers a new VOL connector as a member of the virtual object * layer class. @@ -1091,13 +1158,13 @@ done: *------------------------------------------------------------------------- */ hid_t -H5VL_register_connector(const void *_cls, hbool_t app_ref, hid_t vipl_id) +H5VL__register_connector(const void *_cls, hbool_t app_ref, hid_t vipl_id) { const H5VL_class_t *cls = (const H5VL_class_t *)_cls; H5VL_class_t * saved = NULL; hid_t ret_value = H5I_INVALID_HID; - FUNC_ENTER_NOAPI(H5I_INVALID_HID) + FUNC_ENTER_PACKAGE /* Check arguments */ HDassert(cls); @@ -1128,10 +1195,10 @@ done: } /* end if */ FUNC_LEAVE_NOAPI(ret_value) -} /* end H5VL_register_connector() */ +} /* end H5VL__register_connector() */ /*------------------------------------------------------------------------- - * Function: H5VL__register_connector + * Function: H5VL__register_connector_by_class * * Purpose: Registers a new VOL connector as a member of the virtual object * layer class. @@ -1148,13 +1215,34 @@ done: *------------------------------------------------------------------------- */ hid_t -H5VL__register_connector(const H5VL_class_t *cls, hbool_t app_ref, hid_t vipl_id) +H5VL__register_connector_by_class(const H5VL_class_t *cls, hbool_t app_ref, hid_t vipl_id) { H5VL_get_connector_ud_t op_data; /* Callback info for connector search */ hid_t ret_value = H5I_INVALID_HID; /* Return value */ FUNC_ENTER_PACKAGE + /* Check arguments */ + if (!cls) + HGOTO_ERROR(H5E_ARGS, H5E_UNINITIALIZED, H5I_INVALID_HID, + "VOL connector class pointer cannot be NULL") + if (H5VL_VERSION != cls->version) + HGOTO_ERROR(H5E_VOL, H5E_CANTREGISTER, H5I_INVALID_HID, "VOL connector has incompatible version") + if (!cls->name) + HGOTO_ERROR(H5E_VOL, H5E_CANTREGISTER, H5I_INVALID_HID, + "VOL connector class name cannot be the NULL pointer") + if (0 == HDstrlen(cls->name)) + HGOTO_ERROR(H5E_VOL, H5E_CANTREGISTER, H5I_INVALID_HID, + "VOL connector class name cannot be the empty string") + if (cls->info_cls.copy && !cls->info_cls.free) + HGOTO_ERROR( + H5E_VOL, H5E_CANTREGISTER, H5I_INVALID_HID, + "VOL connector must provide free callback for VOL info objects when a copy callback is provided") + if (cls->wrap_cls.get_wrap_ctx && !cls->wrap_cls.free_wrap_ctx) + HGOTO_ERROR(H5E_VOL, H5E_CANTREGISTER, H5I_INVALID_HID, + "VOL connector must provide free callback for object wrapping contexts when a get " + "callback is provided") + /* Set up op data for iteration */ op_data.kind = H5VL_GET_CONNECTOR_BY_NAME; op_data.u.name = cls->name; @@ -1173,13 +1261,13 @@ H5VL__register_connector(const H5VL_class_t *cls, hbool_t app_ref, hid_t vipl_id } /* end if */ else { /* Create a new class ID */ - if ((ret_value = H5VL_register_connector(cls, app_ref, vipl_id)) < 0) + if ((ret_value = H5VL__register_connector(cls, app_ref, vipl_id)) < 0) HGOTO_ERROR(H5E_VOL, H5E_CANTREGISTER, H5I_INVALID_HID, "unable to register VOL connector") } /* end else */ done: FUNC_LEAVE_NOAPI(ret_value) -} /* end H5VL__register_connector() */ +} /* end H5VL__register_connector_by_class() */ /*------------------------------------------------------------------------- * Function: H5VL__register_connector_by_name @@ -1233,7 +1321,7 @@ H5VL__register_connector_by_name(const char *name, hbool_t app_ref, hid_t vipl_i HGOTO_ERROR(H5E_VOL, H5E_CANTINIT, H5I_INVALID_HID, "unable to load VOL connector") /* Register the connector we loaded */ - if ((ret_value = H5VL_register_connector(cls, app_ref, vipl_id)) < 0) + if ((ret_value = H5VL__register_connector(cls, app_ref, vipl_id)) < 0) HGOTO_ERROR(H5E_VOL, H5E_CANTREGISTER, H5I_INVALID_HID, "unable to register VOL connector ID") } /* end else */ @@ -1293,7 +1381,7 @@ H5VL__register_connector_by_value(H5VL_class_value_t value, hbool_t app_ref, hid HGOTO_ERROR(H5E_VOL, H5E_CANTINIT, H5I_INVALID_HID, "unable to load VOL connector") /* Register the connector we loaded */ - if ((ret_value = H5VL_register_connector(cls, app_ref, vipl_id)) < 0) + if ((ret_value = H5VL__register_connector(cls, app_ref, vipl_id)) < 0) HGOTO_ERROR(H5E_VOL, H5E_CANTREGISTER, H5I_INVALID_HID, "unable to register VOL connector ID") } /* end else */ @@ -1650,7 +1738,7 @@ H5VL_vol_object(hid_t id) obj_type = H5I_get_type(id); if (H5I_FILE == obj_type || H5I_GROUP == obj_type || H5I_ATTR == obj_type || H5I_DATASET == obj_type || - H5I_DATATYPE == obj_type) { + H5I_DATATYPE == obj_type || H5I_MAP == obj_type) { /* Get the object */ if (NULL == (obj = H5I_object(id))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "invalid identifier") @@ -1776,6 +1864,7 @@ H5VL__object(hid_t id, H5I_type_t obj_type) case H5I_ERROR_MSG: case H5I_ERROR_STACK: case H5I_SPACE_SEL_ITER: + case H5I_EVENTSET: case H5I_NTYPES: default: HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "unknown data object type") @@ -2095,7 +2184,7 @@ H5VL__free_vol_wrapper(H5VL_wrap_ctx_t *vol_wrap_ctx) "unable to release connector's object wrapping context") /* Decrement refcount on connector */ - if (H5VL__conn_dec_rc(vol_wrap_ctx->connector) < 0) + if (H5VL_conn_dec_rc(vol_wrap_ctx->connector) < 0) HGOTO_ERROR(H5E_VOL, H5E_CANTDEC, FAIL, "unable to decrement ref count on VOL connector") /* Release object wrapping context */ @@ -2152,7 +2241,7 @@ H5VL_set_vol_wrapper(const H5VL_object_t *vol_obj) HGOTO_ERROR(H5E_VOL, H5E_CANTALLOC, FAIL, "can't allocate VOL wrap context") /* Increment the outstanding objects that are using the connector */ - H5VL__conn_inc_rc(vol_obj->connector); + H5VL_conn_inc_rc(vol_obj->connector); /* Set up VOL object wrapper context */ vol_wrap_ctx->rc = 1; @@ -2343,6 +2432,58 @@ done: } /* end H5VL_wrap_register() */ /*------------------------------------------------------------------------- + * Function: H5VL_check_plugin_load + * + * Purpose: Check if a VOL connector matches the search criteria, and + * can be loaded. + * + * Note: Matching the connector's name / value, but the connector + * having an incompatible version is not an error, but means + * that the connector isn't a "match". Setting the SUCCEED + * value to FALSE and not failing for that case allows the + * plugin framework to keep looking for other DLLs that match + * and have a compatible version. + * + * Return: SUCCEED / FAIL + * + *------------------------------------------------------------------------- + */ +herr_t +H5VL_check_plugin_load(const H5VL_class_t *cls, const H5PL_key_t *key, hbool_t *success) +{ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI(FAIL) + + /* Sanity checks */ + HDassert(cls); + HDassert(key); + HDassert(success); + + /* Which kind of key are we looking for? */ + if (key->vol.kind == H5VL_GET_CONNECTOR_BY_NAME) { + /* Check if plugin name matches VOL connector class name */ + if (cls->name && !HDstrcmp(cls->name, key->vol.u.name)) + *success = TRUE; + } /* end if */ + else { + /* Sanity check */ + HDassert(key->vol.kind == H5VL_GET_CONNECTOR_BY_VALUE); + + /* Check if plugin value matches VOL connector class value */ + if (cls->value == key->vol.u.value) + *success = TRUE; + } /* end else */ + + /* Connector is a match, but might not be a compatible version */ + if (*success && cls->version != H5VL_VERSION) + *success = FALSE; + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5VL_check_plugin_load() */ + +/*------------------------------------------------------------------------- * Function: H5VL_setup_args * * Purpose: Set up arguments to access an object diff --git a/src/H5VLnative.c b/src/H5VLnative.c index 4d914b0..b70d489 100644 --- a/src/H5VLnative.c +++ b/src/H5VLnative.c @@ -187,7 +187,7 @@ H5VL_native_register(void) /* Register the native VOL connector, if it isn't already */ if (H5I_INVALID_HID == H5VL_NATIVE_ID_g) if ((H5VL_NATIVE_ID_g = - H5VL_register_connector(&H5VL_native_cls_g, TRUE, H5P_VOL_INITIALIZE_DEFAULT)) < 0) + H5VL__register_connector(&H5VL_native_cls_g, TRUE, H5P_VOL_INITIALIZE_DEFAULT)) < 0) HGOTO_ERROR(H5E_VOL, H5E_CANTINSERT, H5I_INVALID_HID, "can't create ID for native VOL connector") /* Set return value */ diff --git a/src/H5VLnative_attr.c b/src/H5VLnative_attr.c index ab97c40..7beb98f 100644 --- a/src/H5VLnative_attr.c +++ b/src/H5VLnative_attr.c @@ -430,17 +430,18 @@ H5VL__native_attr_specific(void *obj, const H5VL_loc_params_t *loc_params, H5VL_ } case H5VL_ATTR_EXISTS: { - const char *attr_name = HDva_arg(arguments, const char *); - htri_t * ret = HDva_arg(arguments, htri_t *); + const char *attr_name = HDva_arg(arguments, const char *); + hbool_t * attr_exists = HDva_arg(arguments, hbool_t *); if (loc_params->type == H5VL_OBJECT_BY_SELF) { /* H5Aexists */ /* Check if the attribute exists */ - if ((*ret = H5O__attr_exists(loc.oloc, attr_name)) < 0) + if (H5O__attr_exists(loc.oloc, attr_name, attr_exists) < 0) HGOTO_ERROR(H5E_ATTR, H5E_CANTGET, FAIL, "unable to determine if attribute exists") } /* end if */ else if (loc_params->type == H5VL_OBJECT_BY_NAME) { /* H5Aexists_by_name */ /* Check if the attribute exists */ - if ((*ret = H5A__exists_by_name(loc, loc_params->loc_data.loc_by_name.name, attr_name)) < 0) + if (H5A__exists_by_name(loc, loc_params->loc_data.loc_by_name.name, attr_name, attr_exists) < + 0) HGOTO_ERROR(H5E_ATTR, H5E_CANTGET, FAIL, "unable to determine if attribute exists") } /* end else-if */ else diff --git a/src/H5VLnative_dataset.c b/src/H5VLnative_dataset.c index d78388e..21491e7 100644 --- a/src/H5VLnative_dataset.c +++ b/src/H5VLnative_dataset.c @@ -353,6 +353,24 @@ H5VL__native_dataset_specific(void *obj, H5VL_dataset_specific_t specific_type, break; } + case H5VL_DATASET_CHUNK_ITER: { /* H5Dchunk_iter */ + H5D_chunk_iter_op_t cb = HDva_arg(arguments, H5D_chunk_iter_op_t); + void * op_data = HDva_arg(arguments, void *); + + HDassert(dset->shared); + + /* Make sure the dataset is chunked */ + if (H5D_CHUNKED != dset->shared->layout.type) { + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a chunked dataset") + } + + /* Call private function */ + if (H5D__chunk_iter(dset, cb, op_data) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't iterate over chunks") + + break; + } + default: HGOTO_ERROR(H5E_VOL, H5E_UNSUPPORTED, FAIL, "invalid specific operation") } /* end switch */ diff --git a/src/H5VLnative_introspect.c b/src/H5VLnative_introspect.c index 9d1244b..6af33ba 100644 --- a/src/H5VLnative_introspect.c +++ b/src/H5VLnative_introspect.c @@ -35,16 +35,192 @@ *--------------------------------------------------------------------------- */ herr_t -H5VL__native_introspect_opt_query(void H5_ATTR_UNUSED *obj, H5VL_subclass_t H5_ATTR_UNUSED cls, - int H5_ATTR_UNUSED opt_type, hbool_t *supported) +H5VL__native_introspect_opt_query(void H5_ATTR_UNUSED *obj, H5VL_subclass_t subcls, int opt_type, + uint64_t *flags) { - FUNC_ENTER_PACKAGE_NOERR + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_PACKAGE /* Sanity check */ - HDassert(supported); + HDassert(flags); /* The native VOL connector supports all optional operations */ - *supported = TRUE; + *flags = H5VL_OPT_QUERY_SUPPORTED; + + /* Set appropriate flags for each operation in each subclass */ + switch (subcls) { + case H5VL_SUBCLS_NONE: + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "unknown optional 'none' operation") + + case H5VL_SUBCLS_INFO: + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "unknown optional info operation") + + case H5VL_SUBCLS_WRAP: + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "unknown optional wrapper operation") + + case H5VL_SUBCLS_ATTR: + switch (opt_type) { +#ifndef H5_NO_DEPRECATED_SYMBOLS + case H5VL_NATIVE_ATTR_ITERATE_OLD: + /* Don't allow asynchronous execution, due to iterator callbacks */ + *flags |= H5VL_OPT_QUERY_NO_ASYNC; + break; +#endif /* H5_NO_DEPRECATED_SYMBOLS */ + + default: + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "unknown optional attribute operation") + break; + } /* end switch */ + break; + + case H5VL_SUBCLS_DATASET: + switch (opt_type) { + case H5VL_NATIVE_DATASET_FORMAT_CONVERT: + *flags |= H5VL_OPT_QUERY_MODIFY_METADATA; + break; + + case H5VL_NATIVE_DATASET_GET_CHUNK_INDEX_TYPE: + case H5VL_NATIVE_DATASET_GET_CHUNK_STORAGE_SIZE: + case H5VL_NATIVE_DATASET_GET_NUM_CHUNKS: + case H5VL_NATIVE_DATASET_GET_CHUNK_INFO_BY_IDX: + case H5VL_NATIVE_DATASET_GET_CHUNK_INFO_BY_COORD: + case H5VL_NATIVE_DATASET_GET_VLEN_BUF_SIZE: + case H5VL_NATIVE_DATASET_GET_OFFSET: + *flags |= H5VL_OPT_QUERY_QUERY_METADATA; + break; + + case H5VL_NATIVE_DATASET_CHUNK_READ: + *flags |= H5VL_OPT_QUERY_READ_DATA; + break; + + case H5VL_NATIVE_DATASET_CHUNK_WRITE: + *flags |= H5VL_OPT_QUERY_WRITE_DATA; + break; + + default: + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "unknown optional dataset operation") + break; + } /* end switch */ + break; + + case H5VL_SUBCLS_DATATYPE: + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "unknown optional datatype operation") + + case H5VL_SUBCLS_FILE: + switch (opt_type) { + case H5VL_NATIVE_FILE_CLEAR_ELINK_CACHE: + case H5VL_NATIVE_FILE_RESET_MDC_HIT_RATE: + case H5VL_NATIVE_FILE_SET_MDC_CONFIG: + *flags |= H5VL_OPT_QUERY_MODIFY_METADATA; + break; + + case H5VL_NATIVE_FILE_GET_FILE_IMAGE: + *flags |= H5VL_OPT_QUERY_QUERY_METADATA; + *flags |= H5VL_OPT_QUERY_READ_DATA; + break; + + case H5VL_NATIVE_FILE_GET_FREE_SECTIONS: + case H5VL_NATIVE_FILE_GET_FREE_SPACE: + case H5VL_NATIVE_FILE_GET_INFO: + case H5VL_NATIVE_FILE_GET_MDC_CONF: + case H5VL_NATIVE_FILE_GET_MDC_HR: + case H5VL_NATIVE_FILE_GET_MDC_SIZE: + case H5VL_NATIVE_FILE_GET_SIZE: + case H5VL_NATIVE_FILE_GET_VFD_HANDLE: + case H5VL_NATIVE_FILE_GET_METADATA_READ_RETRY_INFO: + *flags |= H5VL_OPT_QUERY_QUERY_METADATA; + break; + + case H5VL_NATIVE_FILE_START_SWMR_WRITE: + *flags |= H5VL_OPT_QUERY_MODIFY_METADATA; + *flags |= H5VL_OPT_QUERY_WRITE_DATA; + *flags |= H5VL_OPT_QUERY_NO_ASYNC; + break; + + case H5VL_NATIVE_FILE_START_MDC_LOGGING: + case H5VL_NATIVE_FILE_STOP_MDC_LOGGING: + case H5VL_NATIVE_FILE_GET_MDC_LOGGING_STATUS: + case H5VL_NATIVE_FILE_FORMAT_CONVERT: + case H5VL_NATIVE_FILE_RESET_PAGE_BUFFERING_STATS: + case H5VL_NATIVE_FILE_GET_PAGE_BUFFERING_STATS: + case H5VL_NATIVE_FILE_GET_MDC_IMAGE_INFO: + case H5VL_NATIVE_FILE_GET_EOA: + case H5VL_NATIVE_FILE_INCR_FILESIZE: + case H5VL_NATIVE_FILE_SET_LIBVER_BOUNDS: + case H5VL_NATIVE_FILE_GET_MIN_DSET_OHDR_FLAG: + case H5VL_NATIVE_FILE_SET_MIN_DSET_OHDR_FLAG: + case H5VL_NATIVE_FILE_GET_MPI_ATOMICITY: + case H5VL_NATIVE_FILE_SET_MPI_ATOMICITY: + case H5VL_NATIVE_FILE_POST_OPEN: + break; + + default: + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "unknown optional file operation") + break; + } /* end switch */ + break; + + case H5VL_SUBCLS_GROUP: + switch (opt_type) { +#ifndef H5_NO_DEPRECATED_SYMBOLS + case H5VL_NATIVE_GROUP_ITERATE_OLD: + /* Don't allow asynchronous execution, due to iterator callbacks */ + *flags |= H5VL_OPT_QUERY_NO_ASYNC; + break; + + case H5VL_NATIVE_GROUP_GET_OBJINFO: + *flags |= H5VL_OPT_QUERY_QUERY_METADATA; + break; +#endif /* H5_NO_DEPRECATED_SYMBOLS */ + + default: + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "unknown optional group operation") + break; + } /* end switch */ + break; + + case H5VL_SUBCLS_LINK: + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "unknown optional link operation") + + case H5VL_SUBCLS_OBJECT: + switch (opt_type) { + case H5VL_NATIVE_OBJECT_GET_COMMENT: + *flags |= H5VL_OPT_QUERY_QUERY_METADATA; + break; + + case H5VL_NATIVE_OBJECT_SET_COMMENT: + *flags |= H5VL_OPT_QUERY_MODIFY_METADATA; + break; + + case H5VL_NATIVE_OBJECT_DISABLE_MDC_FLUSHES: + case H5VL_NATIVE_OBJECT_ENABLE_MDC_FLUSHES: + case H5VL_NATIVE_OBJECT_ARE_MDC_FLUSHES_DISABLED: + break; + + case H5VL_NATIVE_OBJECT_GET_NATIVE_INFO: + *flags |= H5VL_OPT_QUERY_QUERY_METADATA; + break; + + default: + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "unknown optional object operation") + break; + } /* end switch */ + break; + + case H5VL_SUBCLS_REQUEST: + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "unknown optional request operation") + + case H5VL_SUBCLS_BLOB: + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "unknown optional blob operation") + + case H5VL_SUBCLS_TOKEN: + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "unknown optional token operation") + + default: + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "unknown H5VL subclass") + } /* end switch */ - FUNC_LEAVE_NOAPI(SUCCEED) +done: + FUNC_LEAVE_NOAPI(ret_value) } /* end H5VL__native_introspect_opt_query() */ diff --git a/src/H5VLnative_link.c b/src/H5VLnative_link.c index 4128ac0..72f6cde 100644 --- a/src/H5VLnative_link.c +++ b/src/H5VLnative_link.c @@ -73,8 +73,9 @@ H5VL__native_link_create(H5VL_link_create_type_t create_type, void *obj, const H "source and destination should be in the same file.") /* Create the link */ - if ((ret_value = H5L_create_hard(cur_loc_p, cur_params->loc_data.loc_by_name.name, link_loc_p, - loc_params->loc_data.loc_by_name.name, lcpl_id)) < 0) + if ((ret_value = + H5L__create_hard(cur_loc_p, cur_params->loc_data.loc_by_name.name, link_loc_p, + loc_params->loc_data.loc_by_name.name, lcpl_id)) < 0) HGOTO_ERROR(H5E_LINK, H5E_CANTINIT, FAIL, "unable to create link") } /* end if */ else { /* H5Olink */ @@ -93,8 +94,8 @@ H5VL__native_link_create(H5VL_link_create_type_t create_type, void *obj, const H HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file or file object") /* Create the link */ - if ((ret_value = H5L_create_soft(target_name, &link_loc, loc_params->loc_data.loc_by_name.name, - lcpl_id)) < 0) + if ((ret_value = H5L__create_soft(target_name, &link_loc, loc_params->loc_data.loc_by_name.name, + lcpl_id)) < 0) HGOTO_ERROR(H5E_LINK, H5E_CANTINIT, FAIL, "unable to create link") break; } @@ -157,8 +158,8 @@ H5VL__native_link_copy(void *src_obj, const H5VL_loc_params_t *loc_params1, void dst_loc_p = src_loc_p; /* Copy the link */ - if (H5L_move(src_loc_p, loc_params1->loc_data.loc_by_name.name, dst_loc_p, - loc_params2->loc_data.loc_by_name.name, TRUE, lcpl_id) < 0) + if (H5L__move(src_loc_p, loc_params1->loc_data.loc_by_name.name, dst_loc_p, + loc_params2->loc_data.loc_by_name.name, TRUE, lcpl_id) < 0) HGOTO_ERROR(H5E_LINK, H5E_CANTCOPY, FAIL, "unable to copy link") done: @@ -199,8 +200,8 @@ H5VL__native_link_move(void *src_obj, const H5VL_loc_params_t *loc_params1, void dst_loc_p = src_loc_p; /* Move the link */ - if (H5L_move(src_loc_p, loc_params1->loc_data.loc_by_name.name, dst_loc_p, - loc_params2->loc_data.loc_by_name.name, FALSE, lcpl_id) < 0) + if (H5L__move(src_loc_p, loc_params1->loc_data.loc_by_name.name, dst_loc_p, + loc_params2->loc_data.loc_by_name.name, FALSE, lcpl_id) < 0) HGOTO_ERROR(H5E_LINK, H5E_CANTMOVE, FAIL, "unable to move link") done: @@ -239,7 +240,7 @@ H5VL__native_link_get(void *obj, const H5VL_loc_params_t *loc_params, H5VL_link_ HGOTO_ERROR(H5E_LINK, H5E_NOTFOUND, FAIL, "unable to get link info") } /* end if */ else if (loc_params->type == H5VL_OBJECT_BY_IDX) { /* H5Lget_info_by_idx */ - if (H5L_get_info_by_idx( + if (H5L__get_info_by_idx( &loc, loc_params->loc_data.loc_by_idx.name, loc_params->loc_data.loc_by_idx.idx_type, loc_params->loc_data.loc_by_idx.order, loc_params->loc_data.loc_by_idx.n, linfo2) < 0) HGOTO_ERROR(H5E_LINK, H5E_NOTFOUND, FAIL, "unable to get link info") @@ -257,10 +258,10 @@ H5VL__native_link_get(void *obj, const H5VL_loc_params_t *loc_params, H5VL_link_ ssize_t *ret = HDva_arg(arguments, ssize_t *); /* Get the link name */ - if ((*ret = H5L_get_name_by_idx(&loc, loc_params->loc_data.loc_by_idx.name, - loc_params->loc_data.loc_by_idx.idx_type, - loc_params->loc_data.loc_by_idx.order, - loc_params->loc_data.loc_by_idx.n, name, size)) < 0) + if ((*ret = H5L__get_name_by_idx(&loc, loc_params->loc_data.loc_by_idx.name, + loc_params->loc_data.loc_by_idx.idx_type, + loc_params->loc_data.loc_by_idx.order, + loc_params->loc_data.loc_by_idx.n, name, size)) < 0) HGOTO_ERROR(H5E_LINK, H5E_NOTFOUND, FAIL, "unable to get link info") break; @@ -273,15 +274,15 @@ H5VL__native_link_get(void *obj, const H5VL_loc_params_t *loc_params, H5VL_link_ /* Get the link information */ if (loc_params->type == H5VL_OBJECT_BY_NAME) { /* H5Lget_val */ - if (H5L_get_val(&loc, loc_params->loc_data.loc_by_name.name, buf, size) < 0) + if (H5L__get_val(&loc, loc_params->loc_data.loc_by_name.name, buf, size) < 0) HGOTO_ERROR(H5E_LINK, H5E_NOTFOUND, FAIL, "unable to get link value") } else if (loc_params->type == H5VL_OBJECT_BY_IDX) { /* H5Lget_val_by_idx */ - if (H5L_get_val_by_idx(&loc, loc_params->loc_data.loc_by_idx.name, - loc_params->loc_data.loc_by_idx.idx_type, - loc_params->loc_data.loc_by_idx.order, - loc_params->loc_data.loc_by_idx.n, buf, size) < 0) + if (H5L__get_val_by_idx(&loc, loc_params->loc_data.loc_by_idx.name, + loc_params->loc_data.loc_by_idx.idx_type, + loc_params->loc_data.loc_by_idx.order, + loc_params->loc_data.loc_by_idx.n, buf, size) < 0) HGOTO_ERROR(H5E_LINK, H5E_NOTFOUND, FAIL, "unable to get link val") } else @@ -317,14 +318,14 @@ H5VL__native_link_specific(void *obj, const H5VL_loc_params_t *loc_params, H5VL_ switch (specific_type) { case H5VL_LINK_EXISTS: { - htri_t * ret = HDva_arg(arguments, htri_t *); + hbool_t * exists = HDva_arg(arguments, hbool_t *); H5G_loc_t loc; if (H5G_loc_real(obj, loc_params->obj_type, &loc) < 0) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file or file object") /* Check for the existence of the link */ - if ((*ret = H5L_exists(&loc, loc_params->loc_data.loc_by_name.name)) < 0) + if (H5L__exists(&loc, loc_params->loc_data.loc_by_name.name, exists) < 0) HGOTO_ERROR(H5E_LINK, H5E_NOTFOUND, FAIL, "unable to specific link info") break; } @@ -383,11 +384,11 @@ H5VL__native_link_specific(void *obj, const H5VL_loc_params_t *loc_params, H5VL_ /* Unlink */ if (loc_params->type == H5VL_OBJECT_BY_NAME) { /* H5Ldelete */ - if (H5L_delete(&loc, loc_params->loc_data.loc_by_name.name) < 0) + if (H5L__delete(&loc, loc_params->loc_data.loc_by_name.name) < 0) HGOTO_ERROR(H5E_LINK, H5E_CANTDELETE, FAIL, "unable to delete link") } /* end if */ else if (loc_params->type == H5VL_OBJECT_BY_IDX) { /* H5Ldelete_by_idx */ - if (H5L_delete_by_idx( + if (H5L__delete_by_idx( &loc, loc_params->loc_data.loc_by_idx.name, loc_params->loc_data.loc_by_idx.idx_type, loc_params->loc_data.loc_by_idx.order, loc_params->loc_data.loc_by_idx.n) < 0) HGOTO_ERROR(H5E_LINK, H5E_CANTDELETE, FAIL, "unable to delete link") diff --git a/src/H5VLnative_object.c b/src/H5VLnative_object.c index c985120..449f389 100644 --- a/src/H5VLnative_object.c +++ b/src/H5VLnative_object.c @@ -61,10 +61,10 @@ H5VL__native_object_open(void *obj, const H5VL_loc_params_t *loc_params, H5I_typ case H5VL_OBJECT_BY_IDX: { /* Open the object */ - if (NULL == (ret_value = H5O_open_by_idx(&loc, loc_params->loc_data.loc_by_idx.name, - loc_params->loc_data.loc_by_idx.idx_type, - loc_params->loc_data.loc_by_idx.order, - loc_params->loc_data.loc_by_idx.n, opened_type))) + if (NULL == (ret_value = H5O__open_by_idx(&loc, loc_params->loc_data.loc_by_idx.name, + loc_params->loc_data.loc_by_idx.idx_type, + loc_params->loc_data.loc_by_idx.order, + loc_params->loc_data.loc_by_idx.n, opened_type))) HGOTO_ERROR(H5E_OHDR, H5E_CANTOPENOBJ, NULL, "unable to open object by index") break; } @@ -79,7 +79,7 @@ H5VL__native_object_open(void *obj, const H5VL_loc_params_t *loc_params, H5I_typ "can't deserialize object token into address") /* Open the object */ - if (NULL == (ret_value = H5O_open_by_addr(&loc, addr, opened_type))) + if (NULL == (ret_value = H5O__open_by_addr(&loc, addr, opened_type))) HGOTO_ERROR(H5E_OHDR, H5E_CANTOPENOBJ, NULL, "unable to open object by address") break; } @@ -121,7 +121,7 @@ H5VL__native_object_copy(void *src_obj, const H5VL_loc_params_t *loc_params1, co HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file or file object") /* Copy the object */ - if ((ret_value = H5O_copy(&src_loc, src_name, &dst_loc, dst_name, ocpypl_id, lcpl_id)) < 0) + if ((ret_value = H5O__copy(&src_loc, src_name, &dst_loc, dst_name, ocpypl_id, lcpl_id)) < 0) HGOTO_ERROR(H5E_OHDR, H5E_CANTCOPY, FAIL, "unable to copy object") done: diff --git a/src/H5VLnative_private.h b/src/H5VLnative_private.h index 126441d..687221a 100644 --- a/src/H5VLnative_private.h +++ b/src/H5VLnative_private.h @@ -151,7 +151,7 @@ H5_DLL herr_t H5VL__native_object_optional(void *obj, H5VL_object_optional_t opt H5_DLL herr_t H5VL__native_introspect_get_conn_cls(void *obj, H5VL_get_conn_lvl_t lvl, const H5VL_class_t **conn_cls); H5_DLL herr_t H5VL__native_introspect_opt_query(void *obj, H5VL_subclass_t cls, int opt_type, - hbool_t *supported); + uint64_t *flags); /* Blob callbacks */ H5_DLL herr_t H5VL__native_blob_put(void *obj, const void *buf, size_t size, void *blob_id, void *ctx); diff --git a/src/H5VLpassthru.c b/src/H5VLpassthru.c index fa59f4a..5ccc082 100644 --- a/src/H5VLpassthru.c +++ b/src/H5VLpassthru.c @@ -225,12 +225,12 @@ static herr_t H5VL_pass_through_object_optional(void *obj, H5VL_object_optional_ static herr_t H5VL_pass_through_introspect_get_conn_cls(void *obj, H5VL_get_conn_lvl_t lvl, const H5VL_class_t **conn_cls); static herr_t H5VL_pass_through_introspect_opt_query(void *obj, H5VL_subclass_t cls, int opt_type, - hbool_t *supported); + uint64_t *flags); /* Async request callbacks */ -static herr_t H5VL_pass_through_request_wait(void *req, uint64_t timeout, H5ES_status_t *status); +static herr_t H5VL_pass_through_request_wait(void *req, uint64_t timeout, H5VL_request_status_t *status); static herr_t H5VL_pass_through_request_notify(void *obj, H5VL_request_notify_t cb, void *ctx); -static herr_t H5VL_pass_through_request_cancel(void *req); +static herr_t H5VL_pass_through_request_cancel(void *req, H5VL_request_status_t *status); static herr_t H5VL_pass_through_request_specific(void *req, H5VL_request_specific_t specific_type, va_list arguments); static herr_t H5VL_pass_through_request_optional(void *req, H5VL_request_optional_t opt_type, @@ -488,7 +488,7 @@ H5VL_pass_through_init(hid_t vipl_id) #endif /* Shut compiler up about unused parameter */ - vipl_id = vipl_id; + (void)vipl_id; return 0; } /* end H5VL_pass_through_init() */ @@ -2636,7 +2636,7 @@ H5VL_pass_through_introspect_get_conn_cls(void *obj, H5VL_get_conn_lvl_t lvl, co *------------------------------------------------------------------------- */ herr_t -H5VL_pass_through_introspect_opt_query(void *obj, H5VL_subclass_t cls, int opt_type, hbool_t *supported) +H5VL_pass_through_introspect_opt_query(void *obj, H5VL_subclass_t cls, int opt_type, uint64_t *flags) { H5VL_pass_through_t *o = (H5VL_pass_through_t *)obj; herr_t ret_value; @@ -2645,7 +2645,7 @@ H5VL_pass_through_introspect_opt_query(void *obj, H5VL_subclass_t cls, int opt_t printf("------- PASS THROUGH VOL INTROSPECT OptQuery\n"); #endif - ret_value = H5VLintrospect_opt_query(o->under_object, o->under_vol_id, cls, opt_type, supported); + ret_value = H5VLintrospect_opt_query(o->under_object, o->under_vol_id, cls, opt_type, flags); return ret_value; } /* end H5VL_pass_through_introspect_opt_query() */ @@ -2664,7 +2664,7 @@ H5VL_pass_through_introspect_opt_query(void *obj, H5VL_subclass_t cls, int opt_t *------------------------------------------------------------------------- */ static herr_t -H5VL_pass_through_request_wait(void *obj, uint64_t timeout, H5ES_status_t *status) +H5VL_pass_through_request_wait(void *obj, uint64_t timeout, H5VL_request_status_t *status) { H5VL_pass_through_t *o = (H5VL_pass_through_t *)obj; herr_t ret_value; @@ -2725,7 +2725,7 @@ H5VL_pass_through_request_notify(void *obj, H5VL_request_notify_t cb, void *ctx) *------------------------------------------------------------------------- */ static herr_t -H5VL_pass_through_request_cancel(void *obj) +H5VL_pass_through_request_cancel(void *obj, H5VL_request_status_t *status) { H5VL_pass_through_t *o = (H5VL_pass_through_t *)obj; herr_t ret_value; @@ -2734,7 +2734,7 @@ H5VL_pass_through_request_cancel(void *obj) printf("------- PASS THROUGH VOL REQUEST Cancel\n"); #endif - ret_value = H5VLrequest_cancel(o->under_object, o->under_vol_id); + ret_value = H5VLrequest_cancel(o->under_object, o->under_vol_id, status); if (ret_value >= 0) H5VL_pass_through_free_obj(o); @@ -2822,13 +2822,13 @@ H5VL_pass_through_request_specific(void *obj, H5VL_request_specific_t specific_t /* Release requests that have completed */ if (H5VL_REQUEST_WAITANY == specific_type) { - size_t * idx; /* Pointer to the index of completed request */ - H5ES_status_t *status; /* Pointer to the request's status */ + size_t * idx; /* Pointer to the index of completed request */ + H5VL_request_status_t *status; /* Pointer to the request's status */ /* Retrieve the remaining arguments */ idx = va_arg(tmp_arguments, size_t *); assert(*idx <= req_count); - status = va_arg(tmp_arguments, H5ES_status_t *); + status = va_arg(tmp_arguments, H5VL_request_status_t *); /* Reissue the WAITANY 'request specific' call */ ret_value = H5VL_pass_through_request_specific_reissue(o->under_object, o->under_vol_id, @@ -2844,15 +2844,15 @@ H5VL_pass_through_request_specific(void *obj, H5VL_request_specific_t specific_t } /* end if */ } /* end if */ else if (H5VL_REQUEST_WAITSOME == specific_type) { - size_t * outcount; /* # of completed requests */ - unsigned * array_of_indices; /* Array of indices for completed requests */ - H5ES_status_t *array_of_statuses; /* Array of statuses for completed requests */ + size_t * outcount; /* # of completed requests */ + unsigned * array_of_indices; /* Array of indices for completed requests */ + H5VL_request_status_t *array_of_statuses; /* Array of statuses for completed requests */ /* Retrieve the remaining arguments */ outcount = va_arg(tmp_arguments, size_t *); assert(*outcount <= req_count); array_of_indices = va_arg(tmp_arguments, unsigned *); - array_of_statuses = va_arg(tmp_arguments, H5ES_status_t *); + array_of_statuses = va_arg(tmp_arguments, H5VL_request_status_t *); /* Reissue the WAITSOME 'request specific' call */ ret_value = H5VL_pass_through_request_specific_reissue( @@ -2872,14 +2872,14 @@ H5VL_pass_through_request_specific(void *obj, H5VL_request_specific_t specific_t tmp_o = (H5VL_pass_through_t *)req_array[idx_array[u]]; H5VL_pass_through_free_obj(tmp_o); - } /* end for */ - } /* end if */ - } /* end else-if */ - else { /* H5VL_REQUEST_WAITALL == specific_type */ - H5ES_status_t *array_of_statuses; /* Array of statuses for completed requests */ + } /* end for */ + } /* end if */ + } /* end else-if */ + else { /* H5VL_REQUEST_WAITALL == specific_type */ + H5VL_request_status_t *array_of_statuses; /* Array of statuses for completed requests */ /* Retrieve the remaining arguments */ - array_of_statuses = va_arg(tmp_arguments, H5ES_status_t *); + array_of_statuses = va_arg(tmp_arguments, H5VL_request_status_t *); /* Reissue the WAITALL 'request specific' call */ ret_value = H5VL_pass_through_request_specific_reissue( @@ -2906,8 +2906,11 @@ H5VL_pass_through_request_specific(void *obj, H5VL_request_specific_t specific_t /* Finish use of copied vararg list */ va_end(tmp_arguments); } /* end if */ - else - assert(0 && "Unknown 'specific' operation"); + else { + H5VL_pass_through_t *o = (H5VL_pass_through_t *)obj; + + ret_value = H5VLrequest_specific(o->under_object, o->under_vol_id, specific_type, arguments); + } /* end else */ return ret_value; } /* end H5VL_pass_through_request_specific() */ diff --git a/src/H5VLpkg.h b/src/H5VLpkg.h index fa1d37e..7b8a877 100644 --- a/src/H5VLpkg.h +++ b/src/H5VLpkg.h @@ -43,7 +43,8 @@ /******************************/ /* Package Private Prototypes */ /******************************/ -H5_DLL hid_t H5VL__register_connector(const H5VL_class_t *cls, hbool_t app_ref, hid_t vipl_id); +H5_DLL hid_t H5VL__register_connector(const void *cls, hbool_t app_ref, hid_t vipl_id); +H5_DLL hid_t H5VL__register_connector_by_class(const H5VL_class_t *cls, hbool_t app_ref, hid_t vipl_id); H5_DLL hid_t H5VL__register_connector_by_name(const char *name, hbool_t app_ref, hid_t vipl_id); H5_DLL hid_t H5VL__register_connector_by_value(H5VL_class_value_t value, hbool_t app_ref, hid_t vipl_id); H5_DLL htri_t H5VL__is_connector_registered_by_name(const char *name); diff --git a/src/H5VLprivate.h b/src/H5VLprivate.h index e116c8f..34fb13d 100644 --- a/src/H5VLprivate.h +++ b/src/H5VLprivate.h @@ -37,6 +37,7 @@ typedef struct H5VL_t { typedef struct H5VL_object_t { void * data; /* Pointer to connector-managed data for this object */ H5VL_t *connector; /* Pointer to VOL connector struct */ + size_t rc; /* Reference count */ } H5VL_object_t; /* Internal structure to hold the connector ID & info for FAPLs */ @@ -60,14 +61,17 @@ typedef enum H5VL_get_connector_kind_t { /******************************/ /* Utility functions */ -H5_DLL herr_t H5VL_init_phase1(void); -H5_DLL herr_t H5VL_init_phase2(void); -H5_DLL herr_t H5VL_cmp_connector_cls(int *cmp_value, const H5VL_class_t *cls1, const H5VL_class_t *cls2); -H5_DLL herr_t H5VL_conn_copy(H5VL_connector_prop_t *value); -H5_DLL herr_t H5VL_conn_free(const H5VL_connector_prop_t *info); +H5_DLL herr_t H5VL_init_phase1(void); +H5_DLL herr_t H5VL_init_phase2(void); +H5_DLL herr_t H5VL_cmp_connector_cls(int *cmp_value, const H5VL_class_t *cls1, const H5VL_class_t *cls2); +H5_DLL herr_t H5VL_conn_copy(H5VL_connector_prop_t *value); +H5_DLL int64_t H5VL_conn_inc_rc(H5VL_t *connector); +H5_DLL int64_t H5VL_conn_dec_rc(H5VL_t *connector); +H5_DLL herr_t H5VL_conn_free(const H5VL_connector_prop_t *info); /* Functions that deal with VOL connectors */ -H5_DLL hid_t H5VL_register_connector(const void *cls, hbool_t app_ref, hid_t vipl_id); +union H5PL_key_t; +H5_DLL herr_t H5VL_check_plugin_load(const H5VL_class_t *cls, const union H5PL_key_t *key, hbool_t *success); /* NOTE: The object and ID functions below deal in VOL objects (i.e.; * H5VL_object_t). Similar non-VOL calls exist in H5Iprivate.h. Use @@ -85,7 +89,9 @@ H5_DLL void *H5VL_object_data(const H5VL_object_t *vol_obj); H5_DLL void *H5VL_object_unwrap(const H5VL_object_t *vol_obj); H5_DLL void *H5VL_object_verify(hid_t id, H5I_type_t obj_type); H5_DLL H5VL_object_t *H5VL_vol_object(hid_t id); +H5_DLL H5VL_object_t *H5VL_create_object(void *object, H5VL_t *vol_connector); H5_DLL H5VL_object_t *H5VL_create_object_using_vol_id(H5I_type_t type, void *obj, hid_t connector_id); +H5_DLL hsize_t H5VL_object_inc_rc(H5VL_object_t *obj); H5_DLL herr_t H5VL_free_object(H5VL_object_t *obj); H5_DLL herr_t H5VL_object_is_native(const H5VL_object_t *obj, hbool_t *is_native); H5_DLL herr_t H5VL_file_is_same(const H5VL_object_t *vol_obj1, const H5VL_object_t *vol_obj2, @@ -193,7 +199,7 @@ H5_DLL herr_t H5VL_datatype_close(const H5VL_object_t *vol_obj, hid_t dxpl_id, v /* File functions */ H5_DLL void * H5VL_file_create(const H5VL_connector_prop_t *connector_prop, const char *name, unsigned flags, hid_t fcpl_id, hid_t fapl_id, hid_t dxpl_id, void **req); -H5_DLL void * H5VL_file_open(const H5VL_connector_prop_t *connector_prop, const char *name, unsigned flags, +H5_DLL void * H5VL_file_open(H5VL_connector_prop_t *connector_prop, const char *name, unsigned flags, hid_t fapl_id, hid_t dxpl_id, void **req); H5_DLL herr_t H5VL_file_get(const H5VL_object_t *vol_obj, H5VL_file_get_t get_type, hid_t dxpl_id, void **req, ...); @@ -252,12 +258,13 @@ H5_DLL herr_t H5VL_object_optional(const H5VL_object_t *vol_obj, H5VL_object_opt H5_DLL herr_t H5VL_introspect_get_conn_cls(const H5VL_object_t *vol_obj, H5VL_get_conn_lvl_t lvl, const H5VL_class_t **conn_cls); H5_DLL herr_t H5VL_introspect_opt_query(const H5VL_object_t *vol_obj, H5VL_subclass_t subcls, int opt_type, - hbool_t *supported); + uint64_t *flags); /* Asynchronous functions */ -H5_DLL herr_t H5VL_request_wait(const H5VL_object_t *vol_obj, uint64_t timeout, H5ES_status_t *status); +H5_DLL herr_t H5VL_request_wait(const H5VL_object_t *vol_obj, uint64_t timeout, + H5VL_request_status_t *status); H5_DLL herr_t H5VL_request_notify(const H5VL_object_t *vol_obj, H5VL_request_notify_t cb, void *ctx); -H5_DLL herr_t H5VL_request_cancel(const H5VL_object_t *vol_obj); +H5_DLL herr_t H5VL_request_cancel(const H5VL_object_t *vol_obj, H5VL_request_status_t *status); H5_DLL herr_t H5VL_request_specific(const H5VL_object_t *vol_obj, H5VL_request_specific_t specific_type, ...); H5_DLL herr_t H5VL_request_optional(const H5VL_object_t *vol_obj, H5VL_request_optional_t opt_type, ...); H5_DLL herr_t H5VL_request_free(const H5VL_object_t *vol_obj); diff --git a/src/H5VLpublic.h b/src/H5VLpublic.h index 63fea64..c5f85dc 100644 --- a/src/H5VLpublic.h +++ b/src/H5VLpublic.h @@ -352,7 +352,7 @@ H5_DLL herr_t H5VLunregister_connector(hid_t connector_id); * * \since 1.12.0 */ -H5_DLL herr_t H5VLquery_optional(hid_t obj_id, H5VL_subclass_t subcls, int opt_type, hbool_t *supported); +H5_DLL herr_t H5VLquery_optional(hid_t obj_id, H5VL_subclass_t subcls, int opt_type, uint64_t *flags); #ifdef __cplusplus } @@ -43,20 +43,20 @@ static void H5VM__stride_copy2(hsize_t nelmts, hsize_t elmt_size, unsigned dst_n #endif /* LATER */ /*------------------------------------------------------------------------- - * Function: H5VM__stride_optimize1 + * Function: H5VM__stride_optimize1 * - * Purpose: Given a stride vector which references elements of the - * specified size, optimize the dimensionality, the stride - * vector, and the element size to minimize the dimensionality - * and the number of memory accesses. + * Purpose: Given a stride vector which references elements of the + * specified size, optimize the dimensionality, the stride + * vector, and the element size to minimize the dimensionality + * and the number of memory accesses. * - * All arguments are passed by reference and their values may be - * modified by this function. + * All arguments are passed by reference and their values may be + * modified by this function. * - * Return: None + * Return: void * - * Programmer: Robb Matzke - * Saturday, October 11, 1997 + * Programmer: Robb Matzke + * Saturday, October 11, 1997 * *------------------------------------------------------------------------- */ @@ -66,15 +66,12 @@ H5VM__stride_optimize1(unsigned *np /*in,out*/, hsize_t *elmt_size /*in,out*/, c { FUNC_ENTER_STATIC_NOERR - /* - * This has to be true because if we optimize the dimensionality down to + /* This has to be true because if we optimize the dimensionality down to * zero we still must make one reference. */ HDassert(1 == H5VM_vector_reduce_product(0, NULL)); - /* - * Combine adjacent memory accesses - */ + /* Combine adjacent memory accesses */ while (*np && stride1[*np - 1] > 0 && (hsize_t)(stride1[*np - 1]) == *elmt_size) { *elmt_size *= size[*np - 1]; if (--*np) @@ -85,20 +82,20 @@ H5VM__stride_optimize1(unsigned *np /*in,out*/, hsize_t *elmt_size /*in,out*/, c } /*------------------------------------------------------------------------- - * Function: H5VM__stride_optimize2 + * Function: H5VM__stride_optimize2 * - * Purpose: Given two stride vectors which reference elements of the - * specified size, optimize the dimensionality, the stride - * vectors, and the element size to minimize the dimensionality - * and the number of memory accesses. + * Purpose: Given two stride vectors which reference elements of the + * specified size, optimize the dimensionality, the stride + * vectors, and the element size to minimize the dimensionality + * and the number of memory accesses. * - * All arguments are passed by reference and their values may be - * modified by this function. + * All arguments are passed by reference and their values may be + * modified by this function. * - * Return: Non-negative on success/Negative on failure + * Return: Non-negative on success/Negative on failure * - * Programmer: Robb Matzke - * Saturday, October 11, 1997 + * Programmer: Robb Matzke + * Saturday, October 11, 1997 * *------------------------------------------------------------------------- */ @@ -108,16 +105,13 @@ H5VM__stride_optimize2(unsigned *np /*in,out*/, hsize_t *elmt_size /*in,out*/, c { FUNC_ENTER_STATIC_NOERR - /* - * This has to be true because if we optimize the dimensionality down to + /* This has to be true because if we optimize the dimensionality down to * zero we still must make one reference. */ HDassert(1 == H5VM_vector_reduce_product(0, NULL)); HDassert(*elmt_size > 0); - /* - * Combine adjacent memory accesses - */ + /* Combine adjacent memory accesses */ /* Unroll loop for common cases */ switch (*np) { @@ -206,29 +200,26 @@ H5VM__stride_optimize2(unsigned *np /*in,out*/, hsize_t *elmt_size /*in,out*/, c } /*------------------------------------------------------------------------- - * Function: H5VM_hyper_stride - * - * Purpose: Given a description of a hyperslab, this function returns - * (through STRIDE[]) the byte strides appropriate for accessing - * all bytes of the hyperslab and the byte offset where the - * striding will begin. The SIZE can be passed to the various - * stride functions. + * Function: H5VM_hyper_stride * - * The dimensionality of the whole array, the hyperslab, and the - * returned stride array is N. The whole array dimensions are - * TOTAL_SIZE and the hyperslab is at offset OFFSET and has - * dimensions SIZE. + * Purpose: Given a description of a hyperslab, this function returns + * (through STRIDE[]) the byte strides appropriate for accessing + * all bytes of the hyperslab and the byte offset where the + * striding will begin. The SIZE can be passed to the various + * stride functions. * - * The stride and starting point returned will cause the - * hyperslab elements to be referenced in C order. + * The dimensionality of the whole array, the hyperslab, and the + * returned stride array is N. The whole array dimensions are + * TOTAL_SIZE and the hyperslab is at offset OFFSET and has + * dimensions SIZE. * - * Return: Success: Byte offset from beginning of array to start - * of striding. + * The stride and starting point returned will cause the + * hyperslab elements to be referenced in C order. * - * Failure: abort() -- should never fail + * Return: Byte offset from beginning of array to start of striding. * - * Programmer: Robb Matzke - * Saturday, October 11, 1997 + * Programmer: Robb Matzke + * Saturday, October 11, 1997 * *------------------------------------------------------------------------- */ @@ -308,23 +299,22 @@ H5VM_hyper_stride(unsigned n, const hsize_t *size, const hsize_t *total_size, co } /*------------------------------------------------------------------------- - * Function: H5VM_hyper_eq + * Function: H5VM_hyper_eq * - * Purpose: Determines whether two hyperslabs are equal. This function - * assumes that both hyperslabs are relative to the same array, - * for if not, they could not possibly be equal. + * Purpose: Determines whether two hyperslabs are equal. This function + * assumes that both hyperslabs are relative to the same array, + * for if not, they could not possibly be equal. * - * Return: Success: TRUE if the hyperslabs are equal (that is, - * both refer to exactly the same elements of an - * array) + * Return: TRUE if the hyperslabs are equal (that is, + * both refer to exactly the same elements of an + * array) * - * FALSE otherwise. + * FALSE otherwise * - * Failure: TRUE the rank is zero or if both hyperslabs - * are of zero size. + * Never returns FAIL * - * Programmer: Robb Matzke - * Friday, October 17, 1997 + * Programmer: Robb Matzke + * Friday, October 17, 1997 * *------------------------------------------------------------------------- */ @@ -360,19 +350,19 @@ done: /*------------------------------------------------------------------------- * Function: H5VM_hyper_fill * - * Purpose: Similar to memset() except it operates on hyperslabs... + * Purpose: Similar to memset() except it operates on hyperslabs... * - * Fills a hyperslab of array BUF with some value VAL. BUF - * is treated like a C-order array with N dimensions where the - * size of each dimension is TOTAL_SIZE[]. The hyperslab which - * will be filled with VAL begins at byte offset OFFSET[] from - * the minimum corner of BUF and continues for SIZE[] bytes in - * each dimension. + * Fills a hyperslab of array BUF with some value VAL. BUF + * is treated like a C-order array with N dimensions where the + * size of each dimension is TOTAL_SIZE[]. The hyperslab which + * will be filled with VAL begins at byte offset OFFSET[] from + * the minimum corner of BUF and continues for SIZE[] bytes in + * each dimension. * - * Return: Non-negative on success/Negative on failure + * Return: Non-negative on success/Negative on failure * - * Programmer: Robb Matzke - * Friday, October 10, 1997 + * Programmer: Robb Matzke + * Friday, October 10, 1997 * *------------------------------------------------------------------------- */ @@ -418,31 +408,31 @@ H5VM_hyper_fill(unsigned n, const hsize_t *_size, const hsize_t *total_size, con } /*------------------------------------------------------------------------- - * Function: H5VM_hyper_copy + * Function: H5VM_hyper_copy * - * Purpose: Copies a hyperslab from the source to the destination. + * Purpose: Copies a hyperslab from the source to the destination. * - * A hyperslab is a logically contiguous region of - * multi-dimensional size SIZE of an array whose dimensionality - * is N and whose total size is DST_TOTAL_SIZE or SRC_TOTAL_SIZE. - * The minimum corner of the hyperslab begins at a - * multi-dimensional offset from the minimum corner of the DST - * (destination) or SRC (source) array. The sizes and offsets - * are assumed to be in C order, that is, the first size/offset - * varies the slowest while the last varies the fastest in the - * mapping from N-dimensional space to linear space. This - * function assumes that the array elements are single bytes (if - * your array has multi-byte elements then add an additional - * dimension whose size is that of your element). + * A hyperslab is a logically contiguous region of + * multi-dimensional size SIZE of an array whose dimensionality + * is N and whose total size is DST_TOTAL_SIZE or SRC_TOTAL_SIZE. + * The minimum corner of the hyperslab begins at a + * multi-dimensional offset from the minimum corner of the DST + * (destination) or SRC (source) array. The sizes and offsets + * are assumed to be in C order, that is, the first size/offset + * varies the slowest while the last varies the fastest in the + * mapping from N-dimensional space to linear space. This + * function assumes that the array elements are single bytes (if + * your array has multi-byte elements then add an additional + * dimension whose size is that of your element). * - * The SRC and DST array may be the same array, but the results - * are undefined if the source hyperslab overlaps the - * destination hyperslab. + * The SRC and DST array may be the same array, but the results + * are undefined if the source hyperslab overlaps the + * destination hyperslab. * - * Return: Non-negative on success/Negative on failure + * Return: Non-negative on success/Negative on failure * - * Programmer: Robb Matzke - * Friday, October 10, 1997 + * Programmer: Robb Matzke + * Friday, October 10, 1997 * *------------------------------------------------------------------------- */ @@ -592,13 +582,13 @@ H5VM_hyper_copy(unsigned n, const hsize_t *_size, const hsize_t *dst_size, const /*------------------------------------------------------------------------- * Function: H5VM_stride_fill * - * Purpose: Fills all bytes of a hyperslab with the same value using - * memset(). + * Purpose: Fills all bytes of a hyperslab with the same value using + * memset(). * - * Return: Non-negative on success/Negative on failure + * Return: Non-negative on success/Negative on failure * - * Programmer: Robb Matzke - * Saturday, October 11, 1997 + * Programmer: Robb Matzke + * Saturday, October 11, 1997 * *------------------------------------------------------------------------- */ @@ -643,19 +633,19 @@ H5VM_stride_fill(unsigned n, hsize_t elmt_size, const hsize_t *size, const hsize /*------------------------------------------------------------------------- * Function: H5VM_stride_copy * - * Purpose: Uses DST_STRIDE and SRC_STRIDE to advance through the arrays - * DST and SRC while copying bytes from SRC to DST. This - * function minimizes the number of calls to memcpy() by - * combining various strides, but it will never touch memory - * outside the hyperslab defined by the strides. + * Purpose: Uses DST_STRIDE and SRC_STRIDE to advance through the arrays + * DST and SRC while copying bytes from SRC to DST. This + * function minimizes the number of calls to memcpy() by + * combining various strides, but it will never touch memory + * outside the hyperslab defined by the strides. * - * Note: If the src_stride is all zero and elmt_size is one, then it's - * probably more efficient to use H5VM_stride_fill() instead. + * Note: If the src_stride is all zero and elmt_size is one, then it's + * probably more efficient to use H5VM_stride_fill() instead. * - * Return: Non-negative on success/Negative on failure + * Return: Non-negative on success/Negative on failure * - * Programmer: Robb Matzke - * Saturday, October 11, 1997 + * Programmer: Robb Matzke + * Saturday, October 11, 1997 * *------------------------------------------------------------------------- */ @@ -709,19 +699,19 @@ H5VM_stride_copy(unsigned n, hsize_t elmt_size, const hsize_t *size, const hsize /*------------------------------------------------------------------------- * Function: H5VM_stride_copy_s * - * Purpose: Uses DST_STRIDE and SRC_STRIDE to advance through the arrays - * DST and SRC while copying bytes from SRC to DST. This - * function minimizes the number of calls to memcpy() by - * combining various strides, but it will never touch memory - * outside the hyperslab defined by the strides. + * Purpose: Uses DST_STRIDE and SRC_STRIDE to advance through the arrays + * DST and SRC while copying bytes from SRC to DST. This + * function minimizes the number of calls to memcpy() by + * combining various strides, but it will never touch memory + * outside the hyperslab defined by the strides. * - * Note: If the src_stride is all zero and elmt_size is one, then it's - * probably more efficient to use H5VM_stride_fill() instead. + * Note: If the src_stride is all zero and elmt_size is one, then it's + * probably more efficient to use H5VM_stride_fill() instead. * - * Return: Non-negative on success/Negative on failure + * Return: Non-negative on success/Negative on failure * - * Programmer: Robb Matzke - * Saturday, October 11, 1997 + * Programmer: Robb Matzke + * Saturday, October 11, 1997 * *------------------------------------------------------------------------- */ @@ -775,17 +765,17 @@ H5VM_stride_copy_s(unsigned n, hsize_t elmt_size, const hsize_t *size, const hss #ifdef LATER /*------------------------------------------------------------------------- - * Function: H5VM__stride_copy2 + * Function: H5VM__stride_copy2 * - * Purpose: Similar to H5VM_stride_copy() except the source and - * destination each have their own dimensionality and size and - * we copy exactly NELMTS elements each of size ELMT_SIZE. The - * size counters wrap if NELMTS is more than a size counter. + * Purpose: Similar to H5VM_stride_copy() except the source and + * destination each have their own dimensionality and size and + * we copy exactly NELMTS elements each of size ELMT_SIZE. The + * size counters wrap if NELMTS is more than a size counter. * - * Return: None + * Return: void * - * Programmer: Robb Matzke - * Saturday, October 11, 1997 + * Programmer: Robb Matzke + * Saturday, October 11, 1997 * *------------------------------------------------------------------------- */ @@ -843,16 +833,16 @@ H5VM__stride_copy2(hsize_t nelmts, hsize_t elmt_size, unsigned dst_n, const hsiz #endif /* LATER */ /*------------------------------------------------------------------------- - * Function: H5VM_array_fill + * Function: H5VM_array_fill * - * Purpose: Fills all bytes of an array with the same value using - * memset(). Increases amount copied by power of two until the - * halfway point is crossed, then copies the rest in one swoop. + * Purpose: Fills all bytes of an array with the same value using + * memset(). Increases amount copied by power of two until the + * halfway point is crossed, then copies the rest in one swoop. * - * Return: Non-negative on success/Negative on failure + * Return: Non-negative on success/Negative on failure * - * Programmer: Quincey Koziol - * Thursday, June 18, 1998 + * Programmer: Quincey Koziol + * Thursday, June 18, 1998 * *------------------------------------------------------------------------- */ @@ -895,25 +885,25 @@ H5VM_array_fill(void *_dst, const void *src, size_t size, size_t count) } /* H5VM_array_fill() */ /*------------------------------------------------------------------------- - * Function: H5VM_array_down + * Function: H5VM_array_down * - * Purpose: Given a set of dimension sizes, calculate the size of each + * Purpose: Given a set of dimension sizes, calculate the size of each * "down" slice. This is the size of the dimensions for all the * dimensions below the current one, which is used for indexing * offsets in this dimension. * - * Return: Non-negative on success/Negative on failure + * Return: void * - * Programmer: Quincey Koziol - * Monday, April 28, 2003 + * Programmer: Quincey Koziol + * Monday, April 28, 2003 * *------------------------------------------------------------------------- */ -herr_t +void H5VM_array_down(unsigned n, const hsize_t *total_size, hsize_t *down) { - hsize_t acc; /*accumulator */ - int i; /*counter */ + hsize_t acc; /* Accumulator */ + int i; /* Counter */ FUNC_ENTER_NOAPI_NOINIT_NOERR @@ -921,31 +911,31 @@ H5VM_array_down(unsigned n, const hsize_t *total_size, hsize_t *down) HDassert(total_size); HDassert(down); - /* Build the sizes of each dimension in the array */ - /* (From fastest to slowest) */ + /* Build the sizes of each dimension in the array + * (From fastest to slowest) + */ for (i = (int)(n - 1), acc = 1; i >= 0; i--) { down[i] = acc; acc *= total_size[i]; - } /* end for */ + } - FUNC_LEAVE_NOAPI(SUCCEED) + FUNC_LEAVE_NOAPI_VOID } /* end H5VM_array_down() */ /*------------------------------------------------------------------------- * Function: H5VM_array_offset_pre * - * Purpose: Given a coordinate description of a location in an array, this - * function returns the byte offset of the coordinate. + * Purpose: Given a coordinate description of a location in an array, this + * function returns the byte offset of the coordinate. * - * The dimensionality of the whole array, and the offset is N. + * The dimensionality of the whole array, and the offset is N. * The whole array dimensions are TOTAL_SIZE and the coordinate * is at offset OFFSET. * - * Return: Success: Byte offset from beginning of array to element offset - * Failure: abort() -- should never fail + * Return: Byte offset from beginning of array to element offset * * Programmer: Quincey Koziol - * Tuesday, June 22, 1999 + * Tuesday, June 22, 1999 * *------------------------------------------------------------------------- */ @@ -971,18 +961,17 @@ H5VM_array_offset_pre(unsigned n, const hsize_t *acc, const hsize_t *offset) /*------------------------------------------------------------------------- * Function: H5VM_array_offset * - * Purpose: Given a coordinate description of a location in an array, this - * function returns the byte offset of the coordinate. + * Purpose: Given a coordinate description of a location in an array, + * this function returns the byte offset of the coordinate. * - * The dimensionality of the whole array, and the offset is N. + * The dimensionality of the whole array, and the offset is N. * The whole array dimensions are TOTAL_SIZE and the coordinate * is at offset OFFSET. * - * Return: Success: Byte offset from beginning of array to element offset - * Failure: abort() -- should never fail + * Return: Byte offset from beginning of array to element offset * * Programmer: Quincey Koziol - * Tuesday, June 22, 1999 + * Tuesday, June 22, 1999 * *------------------------------------------------------------------------- */ @@ -992,38 +981,36 @@ H5VM_array_offset(unsigned n, const hsize_t *total_size, const hsize_t *offset) hsize_t acc_arr[H5VM_HYPER_NDIMS]; /* Accumulated size of down dimensions */ hsize_t ret_value; /* Return value */ - FUNC_ENTER_NOAPI((HDabort(), 0)) /*lint !e527 Don't worry about unreachable statement */ + FUNC_ENTER_NOAPI_NOERR HDassert(n <= H5VM_HYPER_NDIMS); HDassert(total_size); HDassert(offset); /* Build the sizes of each dimension in the array */ - if (H5VM_array_down(n, total_size, acc_arr) < 0) - HGOTO_ERROR(H5E_INTERNAL, H5E_BADVALUE, UFAIL, "can't compute down sizes") + H5VM_array_down(n, total_size, acc_arr); /* Set return value */ ret_value = H5VM_array_offset_pre(n, acc_arr, offset); -done: FUNC_LEAVE_NOAPI(ret_value) } /* end H5VM_array_offset() */ /*------------------------------------------------------------------------- * Function: H5VM_array_calc_pre * - * Purpose: Given a linear offset in an array, the dimensions of that + * Purpose: Given a linear offset in an array, the dimensions of that * array and the pre-computed 'down' (accumulator) sizes, this * function computes the coordinates of that offset in the array. * - * The dimensionality of the whole array, and the coordinates is N. + * The dimensionality of the whole array, and the coordinates is N. * The array dimensions are TOTAL_SIZE and the coordinates * are returned in COORD. The linear offset is in OFFSET. * - * Return: Non-negative on success/Negative on failure + * Return: Non-negative on success/Negative on failure * - * Programmer: Quincey Koziol - * Thursday, July 16, 2009 + * Programmer: Quincey Koziol + * Thursday, July 16, 2009 * *------------------------------------------------------------------------- */ @@ -1050,18 +1037,18 @@ H5VM_array_calc_pre(hsize_t offset, unsigned n, const hsize_t *down, hsize_t *co /*------------------------------------------------------------------------- * Function: H5VM_array_calc * - * Purpose: Given a linear offset in an array and the dimensions of that + * Purpose: Given a linear offset in an array and the dimensions of that * array, this function computes the coordinates of that offset * in the array. * - * The dimensionality of the whole array, and the coordinates is N. + * The dimensionality of the whole array, and the coordinates is N. * The array dimensions are TOTAL_SIZE and the coordinates * are returned in COORD. The linear offset is in OFFSET. * - * Return: Non-negative on success/Negative on failure + * Return: Non-negative on success/Negative on failure * - * Programmer: Quincey Koziol - * Wednesday, April 16, 2003 + * Programmer: Quincey Koziol + * Wednesday, April 16, 2003 * *------------------------------------------------------------------------- */ @@ -1079,8 +1066,7 @@ H5VM_array_calc(hsize_t offset, unsigned n, const hsize_t *total_size, hsize_t * HDassert(coords); /* Build the sizes of each dimension in the array */ - if (H5VM_array_down(n, total_size, idx) < 0) - HGOTO_ERROR(H5E_INTERNAL, H5E_BADVALUE, FAIL, "can't compute down sizes") + H5VM_array_down(n, total_size, idx); /* Compute the coordinates from the offset */ if (H5VM_array_calc_pre(offset, n, idx, coords) < 0) @@ -1093,7 +1079,7 @@ done: /*------------------------------------------------------------------------- * Function: H5VM_chunk_index * - * Purpose: Given a coordinate offset (COORD), the size of each chunk + * Purpose: Given a coordinate offset (COORD), the size of each chunk * (CHUNK), the number of chunks in each dimension (NCHUNKS) * and the number of dimensions of all of these (NDIMS), calculate * a "chunk index" for the chunk that the coordinate offset is @@ -1123,10 +1109,10 @@ done: * The chunk index is placed in the CHUNK_IDX location for return * from this function * - * Return: Chunk index on success (can't fail) + * Return: Chunk index on success (can't fail) * - * Programmer: Quincey Koziol - * Monday, April 21, 2003 + * Programmer: Quincey Koziol + * Monday, April 21, 2003 * *------------------------------------------------------------------------- */ @@ -1151,14 +1137,14 @@ H5VM_chunk_index(unsigned ndims, const hsize_t *coord, const uint32_t *chunk, co } /* end H5VM_chunk_index() */ /*------------------------------------------------------------------------- - * Function: H5VM_chunk_scaled + * Function: H5VM_chunk_scaled * - * Purpose: Compute the scaled coordinates for a chunk offset + * Purpose: Compute the scaled coordinates for a chunk offset * - * Return: <none> + * Return: void * - * Programmer: Quincey Koziol - * Wednesday, November 19, 2014 + * Programmer: Quincey Koziol + * Wednesday, November 19, 2014 * *------------------------------------------------------------------------- */ @@ -1186,7 +1172,7 @@ H5VM_chunk_scaled(unsigned ndims, const hsize_t *coord, const uint32_t *chunk, h /*------------------------------------------------------------------------- * Function: H5VM_chunk_index_scaled * - * Purpose: Given a coordinate offset (COORD), the size of each chunk + * Purpose: Given a coordinate offset (COORD), the size of each chunk * (CHUNK), the number of chunks in each dimension (NCHUNKS) * and the number of dimensions of all of these (NDIMS), calculate * a "chunk index" for the chunk that the coordinate offset is @@ -1216,13 +1202,13 @@ H5VM_chunk_scaled(unsigned ndims, const hsize_t *coord, const uint32_t *chunk, h * The chunk index is placed in the CHUNK_IDX location for return * from this function * - * Note: This routine is identical to H5VM_chunk_index(), except for - * caching the scaled information. Make changes in both places. + * Note: This routine is identical to H5VM_chunk_index(), except for + * caching the scaled information. Make changes in both places. * - * Return: Chunk index on success (can't fail) + * Return: Chunk index on success (can't fail) * - * Programmer: Vailin Choi - * Monday, February 9, 2015 + * Programmer: Vailin Choi + * Monday, February 9, 2015 * *------------------------------------------------------------------------- */ @@ -1257,22 +1243,22 @@ H5VM_chunk_index_scaled(unsigned ndims, const hsize_t *coord, const uint32_t *ch /*------------------------------------------------------------------------- * Function: H5VM_opvv * - * Purpose: Perform an operation on a source & destination sequences - * of offset/length pairs. Each set of sequnces has an array - * of lengths, an array of offsets, the maximum number of - * sequences and the current sequence to start at in the sequence. + * Purpose: Perform an operation on a source & destination sequences + * of offset/length pairs. Each set of sequnces has an array + * of lengths, an array of offsets, the maximum number of + * sequences and the current sequence to start at in the sequence. * * There may be different numbers of bytes in the source and * destination sequences, the operation stops when either the * source or destination sequence runs out of information. * - * Note: The algorithm in this routine is [basically] the same as for - * H5VM_memcpyvv(). Changes should be made to both! + * Note: The algorithm in this routine is [basically] the same as for + * H5VM_memcpyvv(). Changes should be made to both! * - * Return: Non-negative # of bytes operated on, on success/Negative on failure + * Return: Non-negative # of bytes operated on, on success/Negative on failure * - * Programmer: Quincey Koziol - * Thursday, September 30, 2010 + * Programmer: Quincey Koziol + * Thursday, September 30, 2010 * *------------------------------------------------------------------------- */ @@ -1460,7 +1446,7 @@ done: /*------------------------------------------------------------------------- * Function: H5VM_memcpyvv * - * Purpose: Given source and destination buffers in memory (SRC & DST) + * Purpose: Given source and destination buffers in memory (SRC & DST) * copy sequences of from the source buffer into the destination * buffer. Each set of sequences has an array of lengths, an * array of offsets, the maximum number of sequences and the @@ -1470,13 +1456,13 @@ done: * destination sequences, data copying stops when either the * source or destination buffer runs out of sequence information. * - * Note: The algorithm in this routine is [basically] the same as for - * H5VM_opvv(). Changes should be made to both! + * Note: The algorithm in this routine is [basically] the same as for + * H5VM_opvv(). Changes should be made to both! * - * Return: Non-negative # of bytes copied on success/Negative on failure + * Return: Non-negative # of bytes copied on success/Negative on failure * - * Programmer: Quincey Koziol - * Friday, May 2, 2003 + * Programmer: Quincey Koziol + * Friday, May 2, 2003 * *------------------------------------------------------------------------- */ diff --git a/src/H5VMprivate.h b/src/H5VMprivate.h index 2fea2fc..0d3bd0f 100644 --- a/src/H5VMprivate.h +++ b/src/H5VMprivate.h @@ -105,7 +105,7 @@ H5_DLL herr_t H5VM_stride_copy_s(unsigned n, hsize_t elmt_size, const hsize_t *_ const hssize_t *dst_stride, void *_dst, const hssize_t *src_stride, const void *_src); H5_DLL herr_t H5VM_array_fill(void *_dst, const void *src, size_t size, size_t count); -H5_DLL herr_t H5VM_array_down(unsigned n, const hsize_t *total_size, hsize_t *down); +H5_DLL void H5VM_array_down(unsigned n, const hsize_t *total_size, hsize_t *down); H5_DLL hsize_t H5VM_array_offset_pre(unsigned n, const hsize_t *acc, const hsize_t *offset); H5_DLL hsize_t H5VM_array_offset(unsigned n, const hsize_t *total_size, const hsize_t *offset); H5_DLL herr_t H5VM_array_calc_pre(hsize_t offset, unsigned n, const hsize_t *down, hsize_t *coords); diff --git a/src/H5Zdeflate.c b/src/H5Zdeflate.c index d8fed41..d29d8e5 100644 --- a/src/H5Zdeflate.c +++ b/src/H5Zdeflate.c @@ -48,7 +48,7 @@ const H5Z_class2_t H5Z_DEFLATE[1] = {{ H5Z__filter_deflate, /* The actual filter function */ }}; -#define H5Z_DEFLATE_SIZE_ADJUST(s) (HDceil(((double)(s)) * (double)1.001f) + 12) +#define H5Z_DEFLATE_SIZE_ADJUST(s) (HDceil(((double)(s)) * 1.001) + 12) /*------------------------------------------------------------------------- * Function: H5Z__filter_deflate diff --git a/src/H5Zscaleoffset.c b/src/H5Zscaleoffset.c index 5310f7d..2e1a474 100644 --- a/src/H5Zscaleoffset.c +++ b/src/H5Zscaleoffset.c @@ -1116,7 +1116,7 @@ H5Z__filter_scaleoffset(unsigned flags, size_t cd_nelmts, const unsigned cd_valu unsigned filavail; /* flag indicating if fill value is defined or not */ H5Z_SO_scale_type_t scale_type = H5Z_SO_FLOAT_DSCALE; /* scale type */ int scale_factor = 0; /* scale factor */ - double D_val = 0.0f; /* decimal scale factor */ + double D_val = 0.0; /* decimal scale factor */ uint32_t minbits = 0; /* minimum number of bits to store values */ unsigned long long minval = 0; /* minimum value of input buffer */ enum H5Z_scaleoffset_t type; /* memory type corresponding to dataset datatype */ diff --git a/src/H5private.h b/src/H5private.h index 8a9f5c9..75b94bd 100644 --- a/src/H5private.h +++ b/src/H5private.h @@ -370,7 +370,6 @@ */ #define SUCCEED 0 #define FAIL (-1) -#define UFAIL (unsigned)(-1) /* The HDF5 library uses the symbol `ERR` frequently. So do * header files for libraries such as curses(3), terminfo(3), etc. @@ -2961,6 +2960,7 @@ H5_DLL int H5CX_term_package(void); H5_DLL int H5D_term_package(void); H5_DLL int H5D_top_term_package(void); H5_DLL int H5E_term_package(void); +H5_DLL int H5ES_term_package(void); H5_DLL int H5F_term_package(void); H5_DLL int H5FD_term_package(void); H5_DLL int H5FL_term_package(void); diff --git a/src/H5timer.c b/src/H5timer.c index 54a3365..b2cc5f0 100644 --- a/src/H5timer.c +++ b/src/H5timer.c @@ -42,9 +42,9 @@ #define H5TIMER_TIME_STRING_LEN 1536 /* Conversion factors */ -#define H5_SEC_PER_DAY (double)(24.0F * 60.0F * 60.0F) -#define H5_SEC_PER_HOUR (double)(60.0F * 60.0F) -#define H5_SEC_PER_MIN (double)(60.0F) +#define H5_SEC_PER_DAY (24.0 * 60.0 * 60.0) +#define H5_SEC_PER_HOUR (60.0 * 60.0) +#define H5_SEC_PER_MIN (60.0) /******************/ /* Local Typedefs */ @@ -100,13 +100,13 @@ H5_bandwidth(char *buf /*out*/, double nbytes, double nseconds) { double bw; - if (nseconds <= (double)0.0F) + if (nseconds <= 0.0) HDstrcpy(buf, " NaN"); else { bw = nbytes / nseconds; - if (H5_DBL_ABS_EQUAL(bw, (double)0.0F)) + if (H5_DBL_ABS_EQUAL(bw, 0.0)) HDstrcpy(buf, "0.000 B/s"); - else if (bw < (double)1.0F) + else if (bw < 1.0) HDsprintf(buf, "%10.4e", bw); else if (bw < (double)H5_KB) { HDsprintf(buf, "%05.4f", bw); @@ -224,7 +224,7 @@ H5_now_usec(void) double H5_get_time(void) { - double ret_value = (double)0.0f; + double ret_value = 0.0; FUNC_ENTER_NOAPI_NOINIT_NOERR @@ -233,14 +233,14 @@ H5_get_time(void) struct timespec ts; HDclock_gettime(CLOCK_MONOTONIC, &ts); - ret_value = (double)ts.tv_sec + ((double)ts.tv_nsec / (double)1000000000.0f); + ret_value = (double)ts.tv_sec + ((double)ts.tv_nsec / 1000000000.0); } #elif defined(H5_HAVE_GETTIMEOFDAY) { struct timeval now_tv; HDgettimeofday(&now_tv, NULL); - ret_value = (double)now_tv.tv_sec + ((double)now_tv.tv_usec / (double)1000000.0f); + ret_value = (double)now_tv.tv_sec + ((double)now_tv.tv_usec / 1000000.0); } #else ret_value = (double)HDtime(NULL); @@ -289,8 +289,8 @@ H5__timer_get_timevals(H5_timevals_t *times /*in,out*/) if (HDgetrusage(RUSAGE_SELF, &res) < 0) return -1; - times->system = (double)res.ru_stime.tv_sec + ((double)res.ru_stime.tv_usec / (double)1.0E6F); - times->user = (double)res.ru_utime.tv_sec + ((double)res.ru_utime.tv_usec / (double)1.0E6F); + times->system = (double)res.ru_stime.tv_sec + ((double)res.ru_stime.tv_usec / 1.0E6); + times->user = (double)res.ru_utime.tv_sec + ((double)res.ru_utime.tv_usec / 1.0E6); } #else /* No suitable way to get system/user times */ @@ -589,7 +589,7 @@ H5_timer_get_time_string(double seconds) double remainder_sec = 0.0; /* Extract larger time units from count of seconds */ - if (seconds > (double)60.0F) { + if (seconds > 60.0) { /* Set initial # of seconds */ remainder_sec = seconds; @@ -617,19 +617,19 @@ H5_timer_get_time_string(double seconds) * time unit. Perhaps this could be passed as an integer. * (name? round_up_size? ?) */ - if (seconds < (double)0.0F) + if (seconds < 0.0) HDsprintf(s, "N/A"); - else if (H5_DBL_ABS_EQUAL((double)0.0F, seconds)) + else if (H5_DBL_ABS_EQUAL(0.0, seconds)) HDsprintf(s, "0.0 s"); - else if (seconds < (double)1.0E-6F) + else if (seconds < 1.0E-6) /* t < 1 us, Print time in ns */ - HDsprintf(s, "%.f ns", seconds * (double)1.0E9F); - else if (seconds < (double)1.0E-3F) + HDsprintf(s, "%.f ns", seconds * 1.0E9); + else if (seconds < 1.0E-3) /* t < 1 ms, Print time in us */ - HDsprintf(s, "%.1f us", seconds * (double)1.0E6F); - else if (seconds < (double)1.0F) + HDsprintf(s, "%.1f us", seconds * 1.0E6); + else if (seconds < 1.0) /* t < 1 s, Print time in ms */ - HDsprintf(s, "%.1f ms", seconds * (double)1.0E3F); + HDsprintf(s, "%.1f ms", seconds * 1.0E3); else if (seconds < H5_SEC_PER_MIN) /* t < 1 m, Print time in s */ HDsprintf(s, "%.2f s", seconds); diff --git a/src/H5trace.c b/src/H5trace.c index d587853..ecb2705 100644 --- a/src/H5trace.c +++ b/src/H5trace.c @@ -3903,14 +3903,14 @@ H5_trace(const double *returning, const char *func, const char *type, ...) if (returning) { if (current_depth > 1) { --current_depth; - return (double)0.0F; + return 0.0; } } else { if (current_depth > 0) { /* Do not update last_call_depth */ current_depth++; - return (double)0.0F; + return 0.0; } } } @@ -3997,5 +3997,5 @@ H5_trace(const double *returning, const char *func, const char *type, ...) if (H5_debug_g.ttimes) return function_times.elapsed; else - return (double)0.0F; + return 0.0; } /* end H5_trace() */ diff --git a/src/Makefile.am b/src/Makefile.am index 65002c1..deda22b 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -55,6 +55,7 @@ libhdf5_la_SOURCES= H5.c H5checksum.c H5dbg.c H5lib_settings.c H5system.c \ H5E.c H5Edeprec.c H5Eint.c \ H5EA.c H5EAcache.c H5EAdbg.c H5EAdblkpage.c H5EAdblock.c H5EAhdr.c \ H5EAiblock.c H5EAint.c H5EAsblock.c H5EAstat.c H5EAtest.c \ + H5ES.c H5ESevent.c H5ESint.c H5ESlist.c \ H5F.c H5Faccum.c H5Fcwfs.c H5Fdbg.c H5Fdeprec.c H5Fefc.c H5Ffake.c \ H5Fint.c H5Fio.c H5Fmount.c H5Fquery.c H5Fsfile.c H5Fspace.c \ H5Fsuper.c H5Fsuper_cache.c H5Ftest.c \ @@ -154,7 +155,7 @@ include_HEADERS = hdf5.h H5api_adpt.h H5overflow.h H5pubconf.h H5public.h H5queu H5Gpublic.h H5Ipublic.h H5Lpublic.h \ H5Mpublic.h H5MMpublic.h H5Opublic.h H5Ppublic.h \ H5PLextern.h H5PLpublic.h \ - H5Rpublic.h H5Spublic.h H5Tpublic.h \ + H5Rpublic.h H5Spublic.h H5Tpublic.h H5TSpublic.h \ H5VLconnector.h H5VLconnector_passthru.h \ H5VLnative.h H5VLpassthru.h H5VLpublic.h \ H5Zpublic.h @@ -203,11 +204,6 @@ $(top_srcdir)/src/H5version.h: $(top_srcdir)/src/H5vers.txt $(top_srcdir)/src/H5overflow.h: $(top_srcdir)/src/H5overflow.txt perl $(top_srcdir)/bin/make_overflow $? -# doxygen support -if BUILD_DOXYGEN_CONDITIONAL -doxygen: doxygen-doc -endif - # Add TRACE macros to library source files. This is done via the trace script # in the hdf5/bin directory. If the file contains HDF5 API macros, a "clean" # version of the source file is saved with a tilde (~) after its name and |