From df961a00414a440b8967983f62281b6205b9627c Mon Sep 17 00:00:00 2001 From: Mohamad Chaarawi Date: Fri, 15 Jun 2012 14:12:08 -0500 Subject: [svn-r22468] split H5F.c into 2 files, H5F.c for public routines and H5Fint.c for private ones move H5A private routines to H5Aint.c --- MANIFEST | 7 + src/CMakeLists.txt | 1 + src/H5A.c | 1157 ----------------------- src/H5Aint.c | 1155 +++++++++++++++++++++++ src/H5F.c | 2574 +++++----------------------------------------------- src/H5Fint.c | 2195 ++++++++++++++++++++++++++++++++++++++++++++ src/H5Fprivate.h | 19 + src/Makefile.am | 2 +- src/Makefile.in | 87 +- 9 files changed, 3640 insertions(+), 3557 deletions(-) create mode 100644 src/H5Fint.c diff --git a/MANIFEST b/MANIFEST index a63581d..1425665 100644 --- a/MANIFEST +++ b/MANIFEST @@ -632,6 +632,7 @@ ./src/H5EAstat.c ./src/H5EAtest.c ./src/H5F.c +./src/H5Fint.c ./src/H5Faccum.c ./src/H5Fcwfs.c ./src/H5Fdbg.c @@ -659,6 +660,12 @@ ./src/H5FAprivate.h ./src/H5FAstat.c ./src/H5FAtest.c +./src/H5VLpublic.h +./src/H5VLprivate.h +./src/H5VL.c +./src/H5VLint.c +./src/H5VLnative.h +./src/H5VLnative.c ./src/H5FD.c ./src/H5FDcore.c ./src/H5FDcore.h diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index f98b206..910bedc 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -152,6 +152,7 @@ IDE_GENERATED_PROPERTIES ("H5EA" "${H5EA_HDRS}" "${H5EA_SRCS}" ) SET (H5F_SRCS ${HDF5_SRC_DIR}/H5F.c + ${HDF5_SRC_DIR}/H5Fint.c ${HDF5_SRC_DIR}/H5Faccum.c ${HDF5_SRC_DIR}/H5Fcwfs.c ${HDF5_SRC_DIR}/H5Fdbg.c diff --git a/src/H5A.c b/src/H5A.c index a945cdc..df22e16 100644 --- a/src/H5A.c +++ b/src/H5A.c @@ -339,175 +339,6 @@ done: } /* H5Acreate_by_name() */ -/*------------------------------------------------------------------------- - * Function: H5A_create - * - * Purpose: - * This is the guts of creating an attribute. - * Usage: - * hid_t H5A_create(ent, name, type, space) - * const H5G_entry_t *ent; IN: Pointer to symbol table entry for object to attribute - * const char *name; IN: Name of attribute - * H5T_t *type; IN: Datatype of attribute - * H5S_t *space; IN: Dataspace of attribute - * hid_t acpl_id IN: Attribute creation property list - * - * Return: Non-negative on success/Negative on failure - * - * Programmer: Quincey Koziol - * April 2, 1998 - * - *------------------------------------------------------------------------- - */ -hid_t -H5A_create(const H5G_loc_t *loc, const char *name, const H5T_t *type, - const H5S_t *space, hid_t acpl_id, hid_t dxpl_id) -{ - H5A_t *attr = NULL; /* Attribute created */ - hssize_t snelmts; /* elements in attribute */ - size_t nelmts; /* elements in attribute */ - htri_t tri_ret; /* htri_t return value */ - hid_t ret_value; /* Return value */ - - FUNC_ENTER_NOAPI_NOINIT_TAG(dxpl_id, loc->oloc->addr, FAIL) - - /* check args */ - HDassert(loc); - HDassert(name); - HDassert(type); - HDassert(space); - - /* Check for existing attribute with same name */ - /* (technically, the "attribute create" operation will fail for a duplicated - * name, but it's going to be hard to unwind all the special cases on - * failure, so just check first, for now - QAK) - */ - if((tri_ret = H5O_attr_exists(loc->oloc, name, H5AC_ind_dxpl_id)) < 0) - HGOTO_ERROR(H5E_ATTR, H5E_NOTFOUND, FAIL, "error checking attributes") - else if(tri_ret > 0) - HGOTO_ERROR(H5E_ATTR, H5E_ALREADYEXISTS, FAIL, "attribute already exists") - - /* Check if the dataspace has an extent set (or is NULL) */ - if(!(H5S_has_extent(space))) - HGOTO_ERROR(H5E_ATTR, H5E_BADVALUE, FAIL, "dataspace extent has not been set") - - /* Check if the datatype is "sensible" for use in a dataset */ - if(H5T_is_sensible(type) != TRUE) - HGOTO_ERROR(H5E_ATTR, H5E_BADTYPE, FAIL, "datatype is not sensible") - - /* Build the attribute information */ - if(NULL == (attr = H5FL_CALLOC(H5A_t))) - HGOTO_ERROR(H5E_ATTR, H5E_CANTALLOC, FAIL, "memory allocation failed for attribute info") - - if(NULL == (attr->shared = H5FL_CALLOC(H5A_shared_t))) - HGOTO_ERROR(H5E_ATTR, H5E_CANTALLOC, FAIL, "can't allocate shared attr structure") - - /* If the creation property list is H5P_DEFAULT, use the default character encoding */ - if(acpl_id == H5P_DEFAULT) - attr->shared->encoding = H5F_DEFAULT_CSET; - else { - H5P_genplist_t *ac_plist; /* ACPL Property list */ - - /* Get a local copy of the attribute creation property list */ - if(NULL == (ac_plist = (H5P_genplist_t *)H5I_object(acpl_id))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a property list") - - if(H5P_get(ac_plist, H5P_STRCRT_CHAR_ENCODING_NAME, &(attr->shared->encoding)) < 0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get character encoding flag") - } /* end else */ - - /* Copy the attribute name */ - attr->shared->name = H5MM_xstrdup(name); - - /* Copy datatype */ - if(NULL == (attr->shared->dt = H5T_copy(type, H5T_COPY_ALL))) - HGOTO_ERROR(H5E_ATTR, H5E_CANTGET, FAIL, "can't get shared datatype info") - - /* Mark datatype as being on disk now */ - if(H5T_set_loc(attr->shared->dt, loc->oloc->file, H5T_LOC_DISK) < 0) - HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "invalid datatype location") - - /* Set the latest format for datatype, if requested */ - if(H5F_USE_LATEST_FORMAT(loc->oloc->file)) - if(H5T_set_latest_version(attr->shared->dt) < 0) - HGOTO_ERROR(H5E_DATASET, H5E_CANTSET, FAIL, "can't set latest version of datatype") - - /* Copy the dataspace for the attribute */ - attr->shared->ds = H5S_copy(space, FALSE, TRUE); - - /* Set the latest format for dataspace, if requested */ - if(H5F_USE_LATEST_FORMAT(loc->oloc->file)) - if(H5S_set_latest_version(attr->shared->ds) < 0) - HGOTO_ERROR(H5E_DATASET, H5E_CANTSET, FAIL, "can't set latest version of dataspace") - - /* Copy the object header information */ - if(H5O_loc_copy(&(attr->oloc), loc->oloc, H5_COPY_DEEP) < 0) - HGOTO_ERROR(H5E_ATTR, H5E_CANTOPENOBJ, FAIL, "unable to copy entry") - - /* Deep copy of the group hierarchy path */ - if(H5G_name_copy(&(attr->path), loc->path, H5_COPY_DEEP) < 0) - HGOTO_ERROR(H5E_ATTR, H5E_CANTCOPY, FAIL, "unable to copy path") - - /* Check if any of the pieces should be (or are already) shared in the - * SOHM table - */ - if(H5SM_try_share(attr->oloc.file, dxpl_id, NULL, 0, H5O_DTYPE_ID, attr->shared->dt, NULL) < 0) - HGOTO_ERROR(H5E_OHDR, H5E_BADMESG, FAIL, "trying to share datatype failed") - if(H5SM_try_share(attr->oloc.file, dxpl_id, NULL, 0, H5O_SDSPACE_ID, attr->shared->ds, NULL) < 0) - HGOTO_ERROR(H5E_OHDR, H5E_BADMESG, FAIL, "trying to share dataspace failed") - - /* Check whether datatype is committed & increment ref count - * (to maintain ref. count incr/decr similarity with "shared message" - * type of datatype sharing) - */ - if(H5T_committed(attr->shared->dt)) { - /* Increment the reference count on the shared datatype */ - if(H5T_link(attr->shared->dt, 1, dxpl_id) < 0) - HGOTO_ERROR(H5E_OHDR, H5E_LINKCOUNT, FAIL, "unable to adjust shared datatype link count") - } /* end if */ - - /* Compute the size of pieces on disk. This is either the size of the - * datatype and dataspace messages themselves, or the size of the "shared" - * messages if either or both of them are shared. - */ - attr->shared->dt_size = H5O_msg_raw_size(attr->oloc.file, H5O_DTYPE_ID, FALSE, attr->shared->dt); - attr->shared->ds_size = H5O_msg_raw_size(attr->oloc.file, H5O_SDSPACE_ID, FALSE, attr->shared->ds); - - /* Get # of elements for attribute's dataspace */ - if((snelmts = H5S_GET_EXTENT_NPOINTS(attr->shared->ds)) < 0) - HGOTO_ERROR(H5E_ATTR, H5E_CANTCOUNT, FAIL, "dataspace is invalid") - H5_ASSIGN_OVERFLOW(nelmts, snelmts, hssize_t, size_t); - - HDassert(attr->shared->dt_size > 0); - HDassert(attr->shared->ds_size > 0); - attr->shared->data_size = nelmts * H5T_GET_SIZE(attr->shared->dt); - - /* Hold the symbol table entry (and file) open */ - if(H5O_open(&(attr->oloc)) < 0) - HGOTO_ERROR(H5E_ATTR, H5E_CANTOPENOBJ, FAIL, "unable to open") - attr->obj_opened = TRUE; - - /* Set the version to encode the attribute with */ - if(H5A_set_version(attr->oloc.file, attr) < 0) - HGOTO_ERROR(H5E_ATTR, H5E_CANTSET, FAIL, "unable to update attribute version") - - /* Insert the attribute into the object header */ - if(H5O_attr_create(&(attr->oloc), dxpl_id, attr) < 0) - HGOTO_ERROR(H5E_ATTR, H5E_CANTINSERT, FAIL, "unable to create attribute in object header") - - /* Register the new attribute and get an ID for it */ - if((ret_value = H5I_register(H5I_ATTR, attr, TRUE)) < 0) - HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL, "unable to register attribute for ID") - -done: - /* Cleanup on failure */ - if(ret_value < 0 && attr && H5A_close(attr) < 0) - HDONE_ERROR(H5E_ATTR, H5E_CANTFREE, FAIL, "can't close attribute") - - FUNC_LEAVE_NOAPI_TAG(ret_value, FAIL) -} /* H5A_create() */ - - /*-------------------------------------------------------------------------- NAME H5Aopen @@ -669,192 +500,6 @@ done: } /* H5Aopen_by_idx() */ -/*------------------------------------------------------------------------- - * Function: H5A_open_common - * - * Purpose: - * Finishes initializing an attributes the open - * - * Usage: - * herr_t H5A_open_common(loc, name, dxpl_id) - * const H5G_loc_t *loc; IN: Pointer to group location for object - * H5A_t *attr; IN/OUT: Pointer to attribute to initialize - * - * Return: Non-negative on success/Negative on failure - * - * Programmer: Quincey Koziol - * December 18, 2006 - * - *------------------------------------------------------------------------- - */ -herr_t -H5A_open_common(const H5G_loc_t *loc, H5A_t *attr) -{ - herr_t ret_value = SUCCEED; /* Return value */ - - FUNC_ENTER_NOAPI_NOINIT - - /* check args */ - HDassert(loc); - HDassert(attr); - -#if defined(H5_USING_MEMCHECKER) || !defined(NDEBUG) - /* Clear object location */ - if(H5O_loc_reset(&(attr->oloc)) < 0) - HGOTO_ERROR(H5E_ATTR, H5E_CANTOPENOBJ, FAIL, "unable to reset location") -#endif /* H5_USING_MEMCHECKER */ - - /* Free any previous group hier. path */ - if(H5G_name_free(&(attr->path)) < 0) - HGOTO_ERROR(H5E_ATTR, H5E_CANTRELEASE, FAIL, "can't release group hier. path") - - /* Deep copy of the symbol table entry */ - if(H5O_loc_copy(&(attr->oloc), loc->oloc, H5_COPY_DEEP) < 0) - HGOTO_ERROR(H5E_ATTR, H5E_CANTOPENOBJ, FAIL, "unable to copy entry") - - /* Deep copy of the group hier. path */ - if(H5G_name_copy(&(attr->path), loc->path, H5_COPY_DEEP) < 0) - HGOTO_ERROR(H5E_ATTR, H5E_CANTCOPY, FAIL, "unable to copy entry") - - /* Hold the symbol table entry (and file) open */ - if(H5O_open(&(attr->oloc)) < 0) - HGOTO_ERROR(H5E_ATTR, H5E_CANTOPENOBJ, FAIL, "unable to open") - attr->obj_opened = TRUE; - -done: - FUNC_LEAVE_NOAPI(ret_value) -} /* H5A_open_common() */ - - -/*------------------------------------------------------------------------- - * Function: H5A_open_by_idx - * - * Purpose: Open an attribute according to its index order - * - * Return: Non-negative on success/Negative on failure - * - * Programmer: Quincey Koziol - * April 2, 1998 - * - *------------------------------------------------------------------------- - */ -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, hid_t lapl_id, hid_t dxpl_id) -{ - 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 */ - H5A_t *attr = NULL; /* Attribute from object header */ - H5A_t *ret_value; /* Return value */ - - FUNC_ENTER_NOAPI_NOINIT - - /* check args */ - HDassert(loc); - HDassert(obj_name); - - /* Set up opened group location to fill in */ - obj_loc.oloc = &obj_oloc; - obj_loc.path = &obj_path; - H5G_loc_reset(&obj_loc); - - /* Find the object's location */ - if(H5G_loc_find(loc, obj_name, &obj_loc/*out*/, lapl_id, dxpl_id) < 0) - HGOTO_ERROR(H5E_ATTR, H5E_NOTFOUND, NULL, "object not found") - loc_found = TRUE; - - /* Read in attribute from object header */ - if(NULL == (attr = H5O_attr_open_by_idx(obj_loc.oloc, idx_type, order, n, dxpl_id))) - HGOTO_ERROR(H5E_ATTR, H5E_CANTOPENOBJ, NULL, "unable to load attribute info from object header") - - /* Finish initializing attribute */ - if(H5A_open_common(&obj_loc, attr) < 0) - HGOTO_ERROR(H5E_ATTR, H5E_CANTINIT, NULL, "unable to initialize attribute") - - /* Set return value */ - ret_value = attr; - -done: - /* Release resources */ - if(loc_found && H5G_loc_free(&obj_loc) < 0) - HDONE_ERROR(H5E_ATTR, H5E_CANTRELEASE, NULL, "can't free location") - - /* Cleanup on failure */ - if(ret_value == NULL) - if(attr && H5A_close(attr) < 0) - HDONE_ERROR(H5E_ATTR, H5E_CANTFREE, NULL, "can't close attribute") - - FUNC_LEAVE_NOAPI(ret_value) -} /* H5A_open_by_idx() */ - - -/*------------------------------------------------------------------------- - * Function: H5A_open_by_name - * - * Purpose: Open an attribute in an object header, according to it's name - * - * Return: Non-negative on success/Negative on failure - * - * Programmer: Quincey Koziol - * December 11, 2006 - * - *------------------------------------------------------------------------- - */ -H5A_t * -H5A_open_by_name(const H5G_loc_t *loc, const char *obj_name, const char *attr_name, - hid_t lapl_id, hid_t dxpl_id) -{ - 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 */ - H5A_t *attr = NULL; /* Attribute from object header */ - H5A_t *ret_value; /* Return value */ - - FUNC_ENTER_NOAPI(NULL) - - /* check args */ - HDassert(loc); - HDassert(obj_name); - HDassert(attr_name); - - /* Set up opened group location to fill in */ - obj_loc.oloc = &obj_oloc; - obj_loc.path = &obj_path; - H5G_loc_reset(&obj_loc); - - /* Find the object's location */ - if(H5G_loc_find(loc, obj_name, &obj_loc/*out*/, lapl_id, dxpl_id) < 0) - HGOTO_ERROR(H5E_ATTR, H5E_NOTFOUND, NULL, "object not found") - loc_found = TRUE; - - /* Read in attribute from object header */ - if(NULL == (attr = H5O_attr_open_by_name(obj_loc.oloc, attr_name, dxpl_id))) - HGOTO_ERROR(H5E_ATTR, H5E_CANTINIT, NULL, "unable to load attribute info from object header") - - /* Finish initializing attribute */ - if(H5A_open_common(loc, attr) < 0) - HGOTO_ERROR(H5E_ATTR, H5E_CANTINIT, NULL, "unable to initialize attribute") - - /* Set return value */ - ret_value = attr; - -done: - /* Release resources */ - if(loc_found && H5G_loc_free(&obj_loc) < 0) - HDONE_ERROR(H5E_ATTR, H5E_CANTRELEASE, NULL, "can't free location") - - /* Cleanup on failure */ - if(ret_value == NULL) - if(attr && H5A_close(attr) < 0) - HDONE_ERROR(H5E_ATTR, H5E_CANTFREE, NULL, "can't close attribute") - - FUNC_LEAVE_NOAPI(ret_value) -} /* H5A_open_by_name() */ - - /*-------------------------------------------------------------------------- NAME H5Awrite @@ -894,120 +539,6 @@ done: /*-------------------------------------------------------------------------- NAME - H5A_write - PURPOSE - Actually write out data to an attribute - USAGE - herr_t H5A_write (attr, mem_type, buf) - H5A_t *attr; IN: Attribute to write - const H5T_t *mem_type; IN: Memory datatype of buffer - const void *buf; IN: Buffer of data to write - RETURNS - Non-negative on success/Negative on failure - - DESCRIPTION - This function writes a complete attribute to disk. ---------------------------------------------------------------------------*/ -herr_t -H5A_write(H5A_t *attr, const H5T_t *mem_type, const void *buf, hid_t dxpl_id) -{ - uint8_t *tconv_buf = NULL; /* datatype conv buffer */ - hbool_t tconv_owned = FALSE; /* Whether the datatype conv buffer is owned by attribute */ - uint8_t *bkg_buf = NULL; /* temp conversion buffer */ - hssize_t snelmts; /* elements in attribute */ - size_t nelmts; /* elements in attribute */ - H5T_path_t *tpath = NULL; /* conversion information*/ - hid_t src_id = -1, dst_id = -1;/* temporary type atoms */ - size_t src_type_size; /* size of source type */ - size_t dst_type_size; /* size of destination type*/ - size_t buf_size; /* desired buffer size */ - herr_t ret_value = SUCCEED; - - FUNC_ENTER_NOAPI_NOINIT_TAG(dxpl_id, attr->oloc.addr, FAIL) - - HDassert(attr); - HDassert(mem_type); - HDassert(buf); - - /* Get # of elements for attribute's dataspace */ - if((snelmts = H5S_GET_EXTENT_NPOINTS(attr->shared->ds)) < 0) - HGOTO_ERROR(H5E_ATTR, H5E_CANTCOUNT, FAIL, "dataspace is invalid") - H5_ASSIGN_OVERFLOW(nelmts, snelmts, hssize_t, size_t); - - /* If there's actually data elements for the attribute, make a copy of the data passed in */ - if(nelmts > 0) { - /* Get the memory and file datatype sizes */ - src_type_size = H5T_GET_SIZE(mem_type); - dst_type_size = H5T_GET_SIZE(attr->shared->dt); - - /* Convert memory buffer into disk buffer */ - /* Set up type conversion function */ - if(NULL == (tpath = H5T_path_find(mem_type, attr->shared->dt, NULL, NULL, dxpl_id, FALSE))) - HGOTO_ERROR(H5E_ATTR, H5E_UNSUPPORTED, FAIL, "unable to convert between src and dst datatypes") - - /* Check for type conversion required */ - if(!H5T_path_noop(tpath)) { - if((src_id = H5I_register(H5I_DATATYPE, H5T_copy(mem_type, H5T_COPY_ALL), FALSE)) < 0 || - (dst_id = H5I_register(H5I_DATATYPE, H5T_copy(attr->shared->dt, H5T_COPY_ALL), FALSE)) < 0) - HGOTO_ERROR(H5E_ATTR, H5E_CANTREGISTER, FAIL, "unable to register types for conversion") - - /* Get the maximum buffer size needed and allocate it */ - buf_size = nelmts * MAX(src_type_size, dst_type_size); - if(NULL == (tconv_buf = H5FL_BLK_MALLOC(attr_buf, buf_size))) - HGOTO_ERROR(H5E_ATTR, H5E_CANTALLOC, FAIL, "memory allocation failed") - if(NULL == (bkg_buf = H5FL_BLK_CALLOC(attr_buf, buf_size))) - HGOTO_ERROR(H5E_ATTR, H5E_CANTALLOC, FAIL, "memory allocation failed") - - /* Copy the user's data into the buffer for conversion */ - HDmemcpy(tconv_buf, buf, (src_type_size * nelmts)); - - /* Perform datatype conversion */ - if(H5T_convert(tpath, src_id, dst_id, nelmts, (size_t)0, (size_t)0, tconv_buf, bkg_buf, dxpl_id) < 0) - HGOTO_ERROR(H5E_ATTR, H5E_CANTENCODE, FAIL, "datatype conversion failed") - - /* Free the previous attribute data buffer, if there is one */ - if(attr->shared->data) - attr->shared->data = H5FL_BLK_FREE(attr_buf, attr->shared->data); - - /* Set the pointer to the attribute data to the converted information */ - attr->shared->data = tconv_buf; - tconv_owned = TRUE; - } /* end if */ - /* No type conversion necessary */ - else { - HDassert(dst_type_size == src_type_size); - - /* Allocate the attribute buffer, if there isn't one */ - if(attr->shared->data == NULL) - if(NULL == (attr->shared->data = H5FL_BLK_MALLOC(attr_buf, dst_type_size * nelmts))) - HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed") - - /* Copy the attribute data into the user's buffer */ - HDmemcpy(attr->shared->data, buf, (dst_type_size * nelmts)); - } /* end else */ - - /* Modify the attribute in the object header */ - if(H5O_attr_write(&(attr->oloc), dxpl_id, attr) < 0) - HGOTO_ERROR(H5E_ATTR, H5E_CANTINIT, FAIL, "unable to modify attribute") - } /* end if */ - -done: - /* Release resources */ - if(src_id >= 0 && H5I_dec_ref(src_id) < 0) - HDONE_ERROR(H5E_ATTR, H5E_CANTDEC, FAIL, "unable to close temporary object") - if(dst_id >= 0 && H5I_dec_ref(dst_id) < 0) - HDONE_ERROR(H5E_ATTR, H5E_CANTDEC, FAIL, "unable to close temporary object") - if(tconv_buf && !tconv_owned) - tconv_buf = H5FL_BLK_FREE(attr_buf, tconv_buf); - if(bkg_buf) - bkg_buf = H5FL_BLK_FREE(attr_buf, bkg_buf); - - FUNC_LEAVE_NOAPI_TAG(ret_value, FAIL) -} /* H5A_write() */ - - -/*-------------------------------------------------------------------------- - NAME H5Aread PURPOSE Read in data from an attribute @@ -1045,109 +576,6 @@ done: /*-------------------------------------------------------------------------- NAME - H5A_read - PURPOSE - Actually read in data from an attribute - USAGE - herr_t H5A_read (attr, mem_type, buf) - H5A_t *attr; IN: Attribute to read - const H5T_t *mem_type; IN: Memory datatype of buffer - void *buf; IN: Buffer for data to read - RETURNS - Non-negative on success/Negative on failure - - DESCRIPTION - This function reads a complete attribute from disk. ---------------------------------------------------------------------------*/ -herr_t -H5A_read(const H5A_t *attr, const H5T_t *mem_type, void *buf, hid_t dxpl_id) -{ - uint8_t *tconv_buf = NULL; /* datatype conv buffer*/ - uint8_t *bkg_buf = NULL; /* background buffer */ - hssize_t snelmts; /* elements in attribute */ - size_t nelmts; /* elements in attribute*/ - H5T_path_t *tpath = NULL; /* type conversion info */ - hid_t src_id = -1, dst_id = -1;/* temporary type atoms*/ - size_t src_type_size; /* size of source type */ - size_t dst_type_size; /* size of destination type */ - size_t buf_size; /* desired buffer size */ - herr_t ret_value = SUCCEED; - - FUNC_ENTER_NOAPI_NOINIT - - HDassert(attr); - HDassert(mem_type); - HDassert(buf); - - /* Create buffer for data to store on disk */ - if((snelmts = H5S_GET_EXTENT_NPOINTS(attr->shared->ds)) < 0) - HGOTO_ERROR(H5E_ATTR, H5E_CANTCOUNT, FAIL, "dataspace is invalid") - H5_ASSIGN_OVERFLOW(nelmts, snelmts, hssize_t, size_t); - - if(nelmts > 0) { - /* Get the memory and file datatype sizes */ - src_type_size = H5T_GET_SIZE(attr->shared->dt); - dst_type_size = H5T_GET_SIZE(mem_type); - - /* Check if the attribute has any data yet, if not, fill with zeroes */ - if(attr->obj_opened && !attr->shared->data) - HDmemset(buf, 0, (dst_type_size * nelmts)); - else { /* Attribute exists and has a value */ - /* Convert memory buffer into disk buffer */ - /* Set up type conversion function */ - if(NULL == (tpath = H5T_path_find(attr->shared->dt, mem_type, NULL, NULL, dxpl_id, FALSE))) - HGOTO_ERROR(H5E_ATTR, H5E_UNSUPPORTED, FAIL, "unable to convert between src and dst datatypes") - - /* Check for type conversion required */ - if(!H5T_path_noop(tpath)) { - if((src_id = H5I_register(H5I_DATATYPE, H5T_copy(attr->shared->dt, H5T_COPY_ALL), FALSE)) < 0 || - (dst_id = H5I_register(H5I_DATATYPE, H5T_copy(mem_type, H5T_COPY_ALL), FALSE)) < 0) - HGOTO_ERROR(H5E_ATTR, H5E_CANTREGISTER, FAIL, "unable to register types for conversion") - - /* Get the maximum buffer size needed and allocate it */ - buf_size = nelmts * MAX(src_type_size, dst_type_size); - if(NULL == (tconv_buf = H5FL_BLK_MALLOC(attr_buf, buf_size))) - HGOTO_ERROR(H5E_ATTR, H5E_NOSPACE, FAIL, "memory allocation failed") - if(NULL == (bkg_buf = H5FL_BLK_CALLOC(attr_buf, buf_size))) - HGOTO_ERROR(H5E_ATTR, H5E_NOSPACE, FAIL, "memory allocation failed") - - /* Copy the attribute data into the buffer for conversion */ - HDmemcpy(tconv_buf, attr->shared->data, (src_type_size * nelmts)); - - /* Perform datatype conversion. */ - if(H5T_convert(tpath, src_id, dst_id, nelmts, (size_t)0, (size_t)0, tconv_buf, bkg_buf, dxpl_id) < 0) - HGOTO_ERROR(H5E_ATTR, H5E_CANTENCODE, FAIL, "datatype conversion failed") - - /* Copy the converted data into the user's buffer */ - HDmemcpy(buf, tconv_buf, (dst_type_size * nelmts)); - } /* end if */ - /* No type conversion necessary */ - else { - HDassert(dst_type_size == src_type_size); - - /* Copy the attribute data into the user's buffer */ - HDmemcpy(buf, attr->shared->data, (dst_type_size * nelmts)); - } /* end else */ - } /* end else */ - } /* end if */ - -done: - /* Release resources */ - if(src_id >= 0 && H5I_dec_ref(src_id) < 0) - HDONE_ERROR(H5E_ATTR, H5E_CANTDEC, FAIL, "unable to close temporary object") - if(dst_id >= 0 && H5I_dec_ref(dst_id) < 0) - HDONE_ERROR(H5E_ATTR, H5E_CANTDEC, FAIL, "unable to close temporary object") - if(tconv_buf) - tconv_buf = H5FL_BLK_FREE(attr_buf, tconv_buf); - if(bkg_buf) - bkg_buf = H5FL_BLK_FREE(attr_buf, bkg_buf); - - FUNC_LEAVE_NOAPI(ret_value) -} /* H5A_read() */ - - -/*-------------------------------------------------------------------------- - NAME H5Aget_space PURPOSE Gets a copy of the dataspace for an attribute @@ -1179,46 +607,6 @@ done: } /* H5Aget_space() */ -/*------------------------------------------------------------------------- - * Function: H5A_get_space - * - * Purpose: Returns and ID for the dataspace of the attribute. - * - * Return: Success: ID for dataspace - * - * Failure: FAIL - * - * Programmer: Mohamad Chaarawi - * March, 2012 - * - *------------------------------------------------------------------------- - */ -hid_t -H5A_get_space(H5A_t *attr) -{ - H5S_t *ds = NULL; - hid_t ret_value = FAIL; - - FUNC_ENTER_NOAPI_NOINIT - - /* Copy the attribute's dataspace */ - if(NULL == (ds = H5S_copy(attr->shared->ds, FALSE, TRUE))) - HGOTO_ERROR(H5E_ATTR, H5E_CANTINIT, FAIL, "unable to copy dataspace") - - /* Atomize */ - if((ret_value = H5I_register(H5I_DATASPACE, ds, TRUE)) < 0) - HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL, "unable to register dataspace atom") - -done: - if(ret_value < 0 && ds) { - if(H5S_close(ds) < 0) - HDONE_ERROR(H5E_DATASET, H5E_CLOSEERROR, FAIL, "unable to release dataspace") - } /* end if */ - - FUNC_LEAVE_NOAPI(ret_value) -} /* end H5A_get_space() */ - - /*-------------------------------------------------------------------------- NAME H5Aget_type @@ -1252,62 +640,6 @@ done: } /* H5Aget_type() */ -/*------------------------------------------------------------------------- - * Function: H5A_get_type - * - * Purpose: Returns and ID for the datatype of the dataset. - * - * Return: Success: ID for datatype - * - * Failure: FAIL - * - * Programmer: Mohamad Chaarawi - * March, 2012 - * - *------------------------------------------------------------------------- - */ -hid_t -H5A_get_type(H5A_t *attr) -{ - H5T_t *dt = NULL; - hid_t ret_value = FAIL; - - FUNC_ENTER_NOAPI_NOINIT - - /* Patch the datatype's "top level" file pointer */ - if(H5T_patch_file(attr->shared->dt, attr->oloc.file) < 0) - HGOTO_ERROR(H5E_ATTR, H5E_CANTINIT, FAIL, "unable to patch datatype's file pointer") - - /* - * Copy the attribute's datatype. If the type is a named type then - * reopen the type before returning it to the user. Make the type - * read-only. - */ - if(NULL == (dt = H5T_copy(attr->shared->dt, H5T_COPY_REOPEN))) - HGOTO_ERROR(H5E_ATTR, H5E_CANTINIT, FAIL, "unable to copy datatype") - - /* Mark any datatypes as being in memory now */ - if(H5T_set_loc(dt, NULL, H5T_LOC_MEMORY) < 0) - HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "invalid datatype location") - - /* Lock copied type */ - if(H5T_lock(dt, FALSE) < 0) - HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to lock transient datatype") - - /* Atomize */ - if((ret_value = H5I_register(H5I_DATATYPE, dt, TRUE)) < 0) - HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL, "unable to register datatype ID") - -done: - if(ret_value < 0) { - if(dt && H5T_close(dt) < 0) - HDONE_ERROR(H5E_DATASET, H5E_CLOSEERROR, FAIL, "unable to release datatype") - } /* end if */ - - FUNC_LEAVE_NOAPI(ret_value) -} /* end H5A_get_type() */ - - /*-------------------------------------------------------------------------- NAME H5Aget_create_plist @@ -1348,51 +680,6 @@ done: /*-------------------------------------------------------------------------- NAME - H5A_get_create_plist - PURPOSE - private version of H5Aget_create_plist - RETURNS - This function returns the ID of a copy of the attribute's creation - property list, or negative on failure. - - ERRORS - - DESCRIPTION - This function returns a copy of the creation property list for - an attribute. The resulting ID must be closed with H5Pclose() or - resource leaks will occur. ---------------------------------------------------------------------------*/ -hid_t -H5A_get_create_plist(H5A_t* attr) -{ - H5P_genplist_t *plist; /* Default property list */ - hid_t new_plist_id; /* ID of ACPL to return */ - H5P_genplist_t *new_plist; /* ACPL to return */ - hid_t ret_value; - FUNC_ENTER_NOAPI_NOINIT - - if(NULL == (plist = (H5P_genplist_t *)H5I_object(H5P_LST_ATTRIBUTE_CREATE_g))) - HGOTO_ERROR(H5E_PLIST, H5E_BADTYPE, FAIL, "can't get default ACPL") - - /* Create the property list object to return */ - if((new_plist_id = H5P_copy_plist(plist, TRUE)) < 0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTINIT, FAIL, "unable to copy attribute creation properties") - if(NULL == (new_plist = (H5P_genplist_t *)H5I_object(new_plist_id))) - HGOTO_ERROR(H5E_PLIST, H5E_BADTYPE, FAIL, "can't get property list") - - /* Set the character encoding on the new property list */ - if(H5P_set(new_plist, H5P_STRCRT_CHAR_ENCODING_NAME, &(attr->shared->encoding)) < 0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set character encoding") - - ret_value = new_plist_id; - -done: - FUNC_LEAVE_NOAPI(ret_value) -} /* end H5Aget_create_plist() */ - - -/*-------------------------------------------------------------------------- - NAME H5Aget_name PURPOSE Gets a copy of the name for an attribute @@ -1433,53 +720,6 @@ done: } /* H5Aget_name() */ -/*-------------------------------------------------------------------------- - NAME - H5A_get_name - PURPOSE - Private function for H5Aget_name. Gets a copy of the name for an - attribute - RETURNS - This function returns the length of the attribute's name (which may be - longer than 'buf_size') on success or negative for failure. - DESCRIPTION - This function retrieves the name of an attribute for an attribute ID. - Up to 'buf_size' characters are stored in 'buf' followed by a '\0' string - terminator. If the name of the attribute is longer than 'buf_size'-1, - the string terminator is stored in the last position of the buffer to - properly terminate the string. ---------------------------------------------------------------------------*/ -ssize_t -H5A_get_name(H5A_t *attr, size_t buf_size, char *buf) -{ - size_t copy_len, nbytes; - ssize_t ret_value; - - FUNC_ENTER_NOAPI(FAIL) - - /* get the real attribute length */ - nbytes = HDstrlen(attr->shared->name); - HDassert((ssize_t)nbytes >= 0); /*overflow, pretty unlikely --rpm*/ - - /* compute the string length which will fit into the user's buffer */ - copy_len = MIN(buf_size - 1, nbytes); - - /* Copy all/some of the name */ - if(buf && copy_len > 0) { - HDmemcpy(buf, attr->shared->name, copy_len); - - /* Terminate the string */ - buf[copy_len]='\0'; - } /* end if */ - - /* Set return value */ - ret_value = (ssize_t)nbytes; - -done: - FUNC_LEAVE_NOAPI(ret_value) -} /* H5A_get_name() */ - - /*------------------------------------------------------------------------- * Function: H5Aget_name_by_idx * @@ -1751,47 +991,6 @@ done: /*------------------------------------------------------------------------- - * Function: H5A_get_info - * - * Purpose: Retrieve information about an attribute. - * - * Return: Success: Non-negative - * Failure: Negative - * - * Programmer: Quincey Koziol - * February 6, 2007 - * - *------------------------------------------------------------------------- - */ -herr_t -H5A_get_info(const H5A_t *attr, H5A_info_t *ainfo) -{ - herr_t ret_value = SUCCEED; /* Return value */ - - FUNC_ENTER_NOAPI(FAIL) - - /* Check args */ - HDassert(attr); - HDassert(ainfo); - - /* Set info for attribute */ - ainfo->cset = attr->shared->encoding; - ainfo->data_size = attr->shared->data_size; - if(attr->shared->crt_idx == H5O_MAX_CRT_ORDER_IDX) { - ainfo->corder_valid = FALSE; - ainfo->corder = 0; - } /* end if */ - else { - ainfo->corder_valid = TRUE; - ainfo->corder = attr->shared->crt_idx; - } /* end else */ - -done: - FUNC_LEAVE_NOAPI(ret_value) -} /* end H5A_get_info() */ - - -/*------------------------------------------------------------------------- * Function: H5Arename * * Purpose: Rename an attribute @@ -2233,49 +1432,6 @@ done: /*-------------------------------------------------------------------------- NAME - H5A_delete_by_idx - PURPOSE - private version of H5Adelete_by_idx - RETURNS - Non-negative on success/Negative on failure ---------------------------------------------------------------------------*/ -herr_t -H5A_delete_by_idx(H5G_loc_t loc, const char *obj_name, H5_index_t idx_type, - H5_iter_order_t order, hsize_t n, hid_t lapl_id) -{ - 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_NOAPI_NOINIT - - /* Set up opened group location to fill in */ - obj_loc.oloc = &obj_oloc; - obj_loc.path = &obj_path; - H5G_loc_reset(&obj_loc); - - /* Find the object's location */ - if(H5G_loc_find(&loc, obj_name, &obj_loc/*out*/, lapl_id, H5AC_dxpl_id) < 0) - HGOTO_ERROR(H5E_ATTR, H5E_NOTFOUND, FAIL, "object not found") - loc_found = TRUE; - - /* Delete the attribute from the location */ - if(H5O_attr_remove_by_idx(obj_loc.oloc, idx_type, order, n, H5AC_dxpl_id) < 0) - HGOTO_ERROR(H5E_ATTR, H5E_CANTDELETE, FAIL, "unable to delete attribute") - -done: - /* Release resources */ - if(loc_found && H5G_loc_free(&obj_loc) < 0) - HDONE_ERROR(H5E_ATTR, H5E_CANTRELEASE, FAIL, "can't free location") - - FUNC_LEAVE_NOAPI(ret_value) -} /* H5A_delete_by_idx() */ - - -/*-------------------------------------------------------------------------- - NAME H5Aclose PURPOSE Close an attribute ID @@ -2307,271 +1463,6 @@ done: /*------------------------------------------------------------------------- - * Function: H5A_copy - * - * Purpose: Copies attribute OLD_ATTR. - * - * Return: Success: Pointer to a new copy of the OLD_ATTR argument. - * - * Failure: NULL - * - * Programmer: Robb Matzke - * Thursday, December 4, 1997 - * - * Modification:Raymond Lu - * 4 June 2008 - * Changed some attribute information to be shared. - * - *------------------------------------------------------------------------- - */ -H5A_t * -H5A_copy(H5A_t *_new_attr, const H5A_t *old_attr) -{ - H5A_t *new_attr = NULL; - hbool_t allocated_attr = FALSE; /* Whether the attribute was allocated */ - H5A_t *ret_value = NULL; /* Return value */ - - FUNC_ENTER_NOAPI(NULL) - - /* check args */ - HDassert(old_attr); - - /* Allocate attribute structure */ - if(_new_attr == NULL) { - if(NULL == (new_attr = H5FL_CALLOC(H5A_t))) - HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed") - allocated_attr = TRUE; - } /* end if */ - else - new_attr = _new_attr; - - /* Copy the top level of the attribute */ - new_attr->sh_loc = old_attr->sh_loc; - - /* Deep copy of the group hierarchy path */ - if(H5G_name_copy(&(new_attr->path), &(old_attr->path), H5_COPY_DEEP) < 0) - HGOTO_ERROR(H5E_ATTR, H5E_CANTCOPY, NULL, "unable to copy path") - - /* Share some attribute information */ - new_attr->shared = old_attr->shared; - - /* Increment reference count for shared object */ - new_attr->shared->nrefs++; - - /* Don't open the object header for a copy */ - new_attr->obj_opened = FALSE; - - /* Set the return value */ - ret_value = new_attr; - -done: - if(ret_value == NULL) - if(allocated_attr && new_attr && H5A_close(new_attr) < 0) - HDONE_ERROR(H5E_ATTR, H5E_CANTFREE, NULL, "can't close attribute") - - FUNC_LEAVE_NOAPI(ret_value) -} /* end H5A_copy() */ - - -/*------------------------------------------------------------------------- - * Function: H5A_free - * - * Purpose: Frees all memory associated with an attribute, but does not - * free the H5A_t structure (which should be done in H5T_close). - * - * Return: Non-negative on success/Negative on failure - * - * Programmer: Quincey Koziol - * Monday, November 15, 2004 - * - * Modifications: - * - *------------------------------------------------------------------------- - */ -herr_t -H5A_free(H5A_t *attr) -{ - herr_t ret_value = SUCCEED; /* Return value */ - - FUNC_ENTER_NOAPI(FAIL) - - HDassert(attr); - - /* Free dynamicly allocated items */ - if(attr->shared->name) { - H5MM_xfree(attr->shared->name); - attr->shared->name = NULL; - } - if(attr->shared->dt) { - if(H5T_close(attr->shared->dt) < 0) - HGOTO_ERROR(H5E_ATTR, H5E_CANTRELEASE, FAIL, "can't release datatype info") - attr->shared->dt = NULL; - } - if(attr->shared->ds) { - if(H5S_close(attr->shared->ds) < 0) - HGOTO_ERROR(H5E_ATTR, H5E_CANTRELEASE, FAIL, "can't release dataspace info") - attr->shared->ds = NULL; - } - if(attr->shared->data) - attr->shared->data = H5FL_BLK_FREE(attr_buf, attr->shared->data); - -done: - FUNC_LEAVE_NOAPI(ret_value) -} /* end H5A_free() */ - - -/*------------------------------------------------------------------------- - * Function: H5A_close - * - * Purpose: Frees an attribute and all associated memory. - * - * Return: Non-negative on success/Negative on failure - * - * Programmer: Robb Matzke - * Monday, December 8, 1997 - * - * Modifications: - * Raymond Lu - * 4 June 2008 - * Changed some attribute object information to be shared. - *------------------------------------------------------------------------- - */ -herr_t -H5A_close(H5A_t *attr) -{ - herr_t ret_value = SUCCEED; /* Return value */ - - FUNC_ENTER_NOAPI(FAIL) - - HDassert(attr); - HDassert(attr->shared); - - /* Close the object's symbol-table entry */ - if(attr->obj_opened && (H5O_close(&(attr->oloc)) < 0)) - HGOTO_ERROR(H5E_ATTR, H5E_CANTRELEASE, FAIL, "can't release object header info") - - /* Reference count can be 0. It only happens when H5A_create fails. */ - if(attr->shared->nrefs <= 1) { - /* Free dynamicly allocated items */ - if(H5A_free(attr) < 0) - HGOTO_ERROR(H5E_ATTR, H5E_CANTRELEASE, FAIL, "can't release attribute info") - - /* Destroy shared attribute struct */ - attr->shared = H5FL_FREE(H5A_shared_t, attr->shared); - } /* end if */ - else { - /* There are other references to the shared part of the attribute. - * Only decrement the reference count. */ - --attr->shared->nrefs; - } /* end else */ - - /* Free group hierarchy path */ - if(H5G_name_free(&(attr->path)) < 0) - HGOTO_ERROR(H5E_ATTR, H5E_CANTRELEASE, FAIL, "can't release group hier. path") - - attr->shared = NULL; - attr = H5FL_FREE(H5A_t, attr); - -done: - FUNC_LEAVE_NOAPI(ret_value) -} /* end H5A_close() */ - - -/*------------------------------------------------------------------------- - * Function: H5A_oloc - * - * Purpose: Return the object location for an attribute. It's the - * object location for the object to which the attribute - * belongs, not the attribute itself. - * - * Return: Success: Ptr to entry - * Failure: NULL - * - * Programmer: Robb Matzke - * Thursday, August 6, 1998 - * - *------------------------------------------------------------------------- - */ -H5O_loc_t * -H5A_oloc(H5A_t *attr) -{ - H5O_loc_t *ret_value; /* Return value */ - - FUNC_ENTER_NOAPI(NULL) - - HDassert(attr); - - /* Set return value */ - ret_value = &(attr->oloc); - -done: - FUNC_LEAVE_NOAPI(ret_value) -} /* end H5A_oloc() */ - - -/*------------------------------------------------------------------------- - * Function: H5A_nameof - * - * Purpose: Return the group hier. path for an attribute. It's the - * group hier. path for the object to which the attribute - * belongs, not the attribute itself. - * - * Return: Success: Ptr to entry - * Failure: NULL - * - * Programmer: Quincey Koziol - * Monday, September 12, 2005 - * - *------------------------------------------------------------------------- - */ -H5G_name_t * -H5A_nameof(H5A_t *attr) -{ - H5G_name_t *ret_value; /* Return value */ - - FUNC_ENTER_NOAPI(NULL) - - HDassert(attr); - - /* Set return value */ - ret_value=&(attr->path); - -done: - FUNC_LEAVE_NOAPI(ret_value) -} /* end H5A_nameof() */ - - -/*------------------------------------------------------------------------- - * Function: H5A_type - * - * Purpose: Return the datatype for an attribute. - * - * Return: Success: Ptr to entry - * Failure: NULL - * - * Programmer: Neil Fortner - * Friday, November 11, 2011 - * - *------------------------------------------------------------------------- - */ -H5T_t * -H5A_type(const H5A_t *attr) -{ - H5T_t *ret_value; /* Return value */ - - FUNC_ENTER_NOAPI(NULL) - - HDassert(attr); - - /* Set return value */ - ret_value = attr->shared->dt; - -done: - FUNC_LEAVE_NOAPI(ret_value) -} /* end H5A_type() */ - - -/*------------------------------------------------------------------------- * Function: H5Aexists * * Purpose: Checks if an attribute with a given name exists on an opened @@ -2659,51 +1550,3 @@ H5Aexists_by_name(hid_t loc_id, const char *obj_name, const char *attr_name, done: FUNC_LEAVE_API(ret_value) } /* H5Aexists_by_name() */ - - -/*------------------------------------------------------------------------- - * Function: H5A_exists_by_name - * - * Purpose: Private version of H5Aexists_by_name - * - * Return: Success: TRUE/FALSE - * Failure: Negative - * - * Programmer: Quincey Koziol - * Thursday, November 1, 2007 - * - *------------------------------------------------------------------------- - */ -htri_t -H5A_exists_by_name(H5G_loc_t loc, const char *obj_name, const char *attr_name, - hid_t lapl_id) -{ - 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; /* Return value */ - - FUNC_ENTER_NOAPI_NOINIT - - /* Set up opened group location to fill in */ - obj_loc.oloc = &obj_oloc; - obj_loc.path = &obj_path; - H5G_loc_reset(&obj_loc); - - /* Find the object's location */ - if(H5G_loc_find(&loc, obj_name, &obj_loc/*out*/, lapl_id, H5AC_ind_dxpl_id) < 0) - HGOTO_ERROR(H5E_ATTR, H5E_NOTFOUND, FAIL, "object not found") - loc_found = TRUE; - - /* Check if the attribute exists */ - if((ret_value = H5O_attr_exists(obj_loc.oloc, attr_name, H5AC_ind_dxpl_id)) < 0) - HGOTO_ERROR(H5E_ATTR, H5E_CANTGET, FAIL, "unable to determine if attribute exists") - -done: - /* Release resources */ - if(loc_found && H5G_loc_free(&obj_loc) < 0) - HDONE_ERROR(H5E_ATTR, H5E_CANTRELEASE, FAIL, "can't free location") - - FUNC_LEAVE_NOAPI(ret_value) -} /* H5A_exists_by_name() */ diff --git a/src/H5Aint.c b/src/H5Aint.c index 1bbbd31..3cc0cc0 100644 --- a/src/H5Aint.c +++ b/src/H5Aint.c @@ -119,6 +119,1161 @@ H5FL_SEQ_DEFINE(H5A_t_ptr); /*------------------------------------------------------------------------- + * Function: H5A_create + * + * Purpose: + * This is the guts of creating an attribute. + * Usage: + * hid_t H5A_create(ent, name, type, space) + * const H5G_entry_t *ent; IN: Pointer to symbol table entry for object to attribute + * const char *name; IN: Name of attribute + * H5T_t *type; IN: Datatype of attribute + * H5S_t *space; IN: Dataspace of attribute + * hid_t acpl_id IN: Attribute creation property list + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Quincey Koziol + * April 2, 1998 + * + *------------------------------------------------------------------------- + */ +hid_t +H5A_create(const H5G_loc_t *loc, const char *name, const H5T_t *type, + const H5S_t *space, hid_t acpl_id, hid_t dxpl_id) +{ + H5A_t *attr = NULL; /* Attribute created */ + hssize_t snelmts; /* elements in attribute */ + size_t nelmts; /* elements in attribute */ + htri_t tri_ret; /* htri_t return value */ + hid_t ret_value; /* Return value */ + + FUNC_ENTER_NOAPI_NOINIT_TAG(dxpl_id, loc->oloc->addr, FAIL) + + /* check args */ + HDassert(loc); + HDassert(name); + HDassert(type); + HDassert(space); + + /* Check for existing attribute with same name */ + /* (technically, the "attribute create" operation will fail for a duplicated + * name, but it's going to be hard to unwind all the special cases on + * failure, so just check first, for now - QAK) + */ + if((tri_ret = H5O_attr_exists(loc->oloc, name, H5AC_ind_dxpl_id)) < 0) + HGOTO_ERROR(H5E_ATTR, H5E_NOTFOUND, FAIL, "error checking attributes") + else if(tri_ret > 0) + HGOTO_ERROR(H5E_ATTR, H5E_ALREADYEXISTS, FAIL, "attribute already exists") + + /* Check if the dataspace has an extent set (or is NULL) */ + if(!(H5S_has_extent(space))) + HGOTO_ERROR(H5E_ATTR, H5E_BADVALUE, FAIL, "dataspace extent has not been set") + + /* Check if the datatype is "sensible" for use in a dataset */ + if(H5T_is_sensible(type) != TRUE) + HGOTO_ERROR(H5E_ATTR, H5E_BADTYPE, FAIL, "datatype is not sensible") + + /* Build the attribute information */ + if(NULL == (attr = H5FL_CALLOC(H5A_t))) + HGOTO_ERROR(H5E_ATTR, H5E_CANTALLOC, FAIL, "memory allocation failed for attribute info") + + if(NULL == (attr->shared = H5FL_CALLOC(H5A_shared_t))) + HGOTO_ERROR(H5E_ATTR, H5E_CANTALLOC, FAIL, "can't allocate shared attr structure") + + /* If the creation property list is H5P_DEFAULT, use the default character encoding */ + if(acpl_id == H5P_DEFAULT) + attr->shared->encoding = H5F_DEFAULT_CSET; + else { + H5P_genplist_t *ac_plist; /* ACPL Property list */ + + /* Get a local copy of the attribute creation property list */ + if(NULL == (ac_plist = (H5P_genplist_t *)H5I_object(acpl_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a property list") + + if(H5P_get(ac_plist, H5P_STRCRT_CHAR_ENCODING_NAME, &(attr->shared->encoding)) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get character encoding flag") + } /* end else */ + + /* Copy the attribute name */ + attr->shared->name = H5MM_xstrdup(name); + + /* Copy datatype */ + if(NULL == (attr->shared->dt = H5T_copy(type, H5T_COPY_ALL))) + HGOTO_ERROR(H5E_ATTR, H5E_CANTGET, FAIL, "can't get shared datatype info") + + /* Mark datatype as being on disk now */ + if(H5T_set_loc(attr->shared->dt, loc->oloc->file, H5T_LOC_DISK) < 0) + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "invalid datatype location") + + /* Set the latest format for datatype, if requested */ + if(H5F_USE_LATEST_FORMAT(loc->oloc->file)) + if(H5T_set_latest_version(attr->shared->dt) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTSET, FAIL, "can't set latest version of datatype") + + /* Copy the dataspace for the attribute */ + attr->shared->ds = H5S_copy(space, FALSE, TRUE); + + /* Set the latest format for dataspace, if requested */ + if(H5F_USE_LATEST_FORMAT(loc->oloc->file)) + if(H5S_set_latest_version(attr->shared->ds) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTSET, FAIL, "can't set latest version of dataspace") + + /* Copy the object header information */ + if(H5O_loc_copy(&(attr->oloc), loc->oloc, H5_COPY_DEEP) < 0) + HGOTO_ERROR(H5E_ATTR, H5E_CANTOPENOBJ, FAIL, "unable to copy entry") + + /* Deep copy of the group hierarchy path */ + if(H5G_name_copy(&(attr->path), loc->path, H5_COPY_DEEP) < 0) + HGOTO_ERROR(H5E_ATTR, H5E_CANTCOPY, FAIL, "unable to copy path") + + /* Check if any of the pieces should be (or are already) shared in the + * SOHM table + */ + if(H5SM_try_share(attr->oloc.file, dxpl_id, NULL, 0, H5O_DTYPE_ID, attr->shared->dt, NULL) < 0) + HGOTO_ERROR(H5E_OHDR, H5E_BADMESG, FAIL, "trying to share datatype failed") + if(H5SM_try_share(attr->oloc.file, dxpl_id, NULL, 0, H5O_SDSPACE_ID, attr->shared->ds, NULL) < 0) + HGOTO_ERROR(H5E_OHDR, H5E_BADMESG, FAIL, "trying to share dataspace failed") + + /* Check whether datatype is committed & increment ref count + * (to maintain ref. count incr/decr similarity with "shared message" + * type of datatype sharing) + */ + if(H5T_committed(attr->shared->dt)) { + /* Increment the reference count on the shared datatype */ + if(H5T_link(attr->shared->dt, 1, dxpl_id) < 0) + HGOTO_ERROR(H5E_OHDR, H5E_LINKCOUNT, FAIL, "unable to adjust shared datatype link count") + } /* end if */ + + /* Compute the size of pieces on disk. This is either the size of the + * datatype and dataspace messages themselves, or the size of the "shared" + * messages if either or both of them are shared. + */ + attr->shared->dt_size = H5O_msg_raw_size(attr->oloc.file, H5O_DTYPE_ID, FALSE, attr->shared->dt); + attr->shared->ds_size = H5O_msg_raw_size(attr->oloc.file, H5O_SDSPACE_ID, FALSE, attr->shared->ds); + + /* Get # of elements for attribute's dataspace */ + if((snelmts = H5S_GET_EXTENT_NPOINTS(attr->shared->ds)) < 0) + HGOTO_ERROR(H5E_ATTR, H5E_CANTCOUNT, FAIL, "dataspace is invalid") + H5_ASSIGN_OVERFLOW(nelmts, snelmts, hssize_t, size_t); + + HDassert(attr->shared->dt_size > 0); + HDassert(attr->shared->ds_size > 0); + attr->shared->data_size = nelmts * H5T_GET_SIZE(attr->shared->dt); + + /* Hold the symbol table entry (and file) open */ + if(H5O_open(&(attr->oloc)) < 0) + HGOTO_ERROR(H5E_ATTR, H5E_CANTOPENOBJ, FAIL, "unable to open") + attr->obj_opened = TRUE; + + /* Set the version to encode the attribute with */ + if(H5A_set_version(attr->oloc.file, attr) < 0) + HGOTO_ERROR(H5E_ATTR, H5E_CANTSET, FAIL, "unable to update attribute version") + + /* Insert the attribute into the object header */ + if(H5O_attr_create(&(attr->oloc), dxpl_id, attr) < 0) + HGOTO_ERROR(H5E_ATTR, H5E_CANTINSERT, FAIL, "unable to create attribute in object header") + + /* Register the new attribute and get an ID for it */ + if((ret_value = H5I_register(H5I_ATTR, attr, TRUE)) < 0) + HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL, "unable to register attribute for ID") + +done: + /* Cleanup on failure */ + if(ret_value < 0 && attr && H5A_close(attr) < 0) + HDONE_ERROR(H5E_ATTR, H5E_CANTFREE, FAIL, "can't close attribute") + + FUNC_LEAVE_NOAPI_TAG(ret_value, FAIL) +} /* H5A_create() */ + + +/*------------------------------------------------------------------------- + * Function: H5A_open_common + * + * Purpose: + * Finishes initializing an attributes the open + * + * Usage: + * herr_t H5A_open_common(loc, name, dxpl_id) + * const H5G_loc_t *loc; IN: Pointer to group location for object + * H5A_t *attr; IN/OUT: Pointer to attribute to initialize + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Quincey Koziol + * December 18, 2006 + * + *------------------------------------------------------------------------- + */ +herr_t +H5A_open_common(const H5G_loc_t *loc, H5A_t *attr) +{ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI_NOINIT + + /* check args */ + HDassert(loc); + HDassert(attr); + +#if defined(H5_USING_MEMCHECKER) || !defined(NDEBUG) + /* Clear object location */ + if(H5O_loc_reset(&(attr->oloc)) < 0) + HGOTO_ERROR(H5E_ATTR, H5E_CANTOPENOBJ, FAIL, "unable to reset location") +#endif /* H5_USING_MEMCHECKER */ + + /* Free any previous group hier. path */ + if(H5G_name_free(&(attr->path)) < 0) + HGOTO_ERROR(H5E_ATTR, H5E_CANTRELEASE, FAIL, "can't release group hier. path") + + /* Deep copy of the symbol table entry */ + if(H5O_loc_copy(&(attr->oloc), loc->oloc, H5_COPY_DEEP) < 0) + HGOTO_ERROR(H5E_ATTR, H5E_CANTOPENOBJ, FAIL, "unable to copy entry") + + /* Deep copy of the group hier. path */ + if(H5G_name_copy(&(attr->path), loc->path, H5_COPY_DEEP) < 0) + HGOTO_ERROR(H5E_ATTR, H5E_CANTCOPY, FAIL, "unable to copy entry") + + /* Hold the symbol table entry (and file) open */ + if(H5O_open(&(attr->oloc)) < 0) + HGOTO_ERROR(H5E_ATTR, H5E_CANTOPENOBJ, FAIL, "unable to open") + attr->obj_opened = TRUE; + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* H5A_open_common() */ + + +/*------------------------------------------------------------------------- + * Function: H5A_open_by_idx + * + * Purpose: Open an attribute according to its index order + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Quincey Koziol + * April 2, 1998 + * + *------------------------------------------------------------------------- + */ +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, hid_t lapl_id, hid_t dxpl_id) +{ + 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 */ + H5A_t *attr = NULL; /* Attribute from object header */ + H5A_t *ret_value; /* Return value */ + + FUNC_ENTER_NOAPI_NOINIT + + /* check args */ + HDassert(loc); + HDassert(obj_name); + + /* Set up opened group location to fill in */ + obj_loc.oloc = &obj_oloc; + obj_loc.path = &obj_path; + H5G_loc_reset(&obj_loc); + + /* Find the object's location */ + if(H5G_loc_find(loc, obj_name, &obj_loc/*out*/, lapl_id, dxpl_id) < 0) + HGOTO_ERROR(H5E_ATTR, H5E_NOTFOUND, NULL, "object not found") + loc_found = TRUE; + + /* Read in attribute from object header */ + if(NULL == (attr = H5O_attr_open_by_idx(obj_loc.oloc, idx_type, order, n, dxpl_id))) + HGOTO_ERROR(H5E_ATTR, H5E_CANTOPENOBJ, NULL, "unable to load attribute info from object header") + + /* Finish initializing attribute */ + if(H5A_open_common(&obj_loc, attr) < 0) + HGOTO_ERROR(H5E_ATTR, H5E_CANTINIT, NULL, "unable to initialize attribute") + + /* Set return value */ + ret_value = attr; + +done: + /* Release resources */ + if(loc_found && H5G_loc_free(&obj_loc) < 0) + HDONE_ERROR(H5E_ATTR, H5E_CANTRELEASE, NULL, "can't free location") + + /* Cleanup on failure */ + if(ret_value == NULL) + if(attr && H5A_close(attr) < 0) + HDONE_ERROR(H5E_ATTR, H5E_CANTFREE, NULL, "can't close attribute") + + FUNC_LEAVE_NOAPI(ret_value) +} /* H5A_open_by_idx() */ + + +/*------------------------------------------------------------------------- + * Function: H5A_open_by_name + * + * Purpose: Open an attribute in an object header, according to it's name + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Quincey Koziol + * December 11, 2006 + * + *------------------------------------------------------------------------- + */ +H5A_t * +H5A_open_by_name(const H5G_loc_t *loc, const char *obj_name, const char *attr_name, + hid_t lapl_id, hid_t dxpl_id) +{ + 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 */ + H5A_t *attr = NULL; /* Attribute from object header */ + H5A_t *ret_value; /* Return value */ + + FUNC_ENTER_NOAPI(NULL) + + /* check args */ + HDassert(loc); + HDassert(obj_name); + HDassert(attr_name); + + /* Set up opened group location to fill in */ + obj_loc.oloc = &obj_oloc; + obj_loc.path = &obj_path; + H5G_loc_reset(&obj_loc); + + /* Find the object's location */ + if(H5G_loc_find(loc, obj_name, &obj_loc/*out*/, lapl_id, dxpl_id) < 0) + HGOTO_ERROR(H5E_ATTR, H5E_NOTFOUND, NULL, "object not found") + loc_found = TRUE; + + /* Read in attribute from object header */ + if(NULL == (attr = H5O_attr_open_by_name(obj_loc.oloc, attr_name, dxpl_id))) + HGOTO_ERROR(H5E_ATTR, H5E_CANTINIT, NULL, "unable to load attribute info from object header") + + /* Finish initializing attribute */ + if(H5A_open_common(loc, attr) < 0) + HGOTO_ERROR(H5E_ATTR, H5E_CANTINIT, NULL, "unable to initialize attribute") + + /* Set return value */ + ret_value = attr; + +done: + /* Release resources */ + if(loc_found && H5G_loc_free(&obj_loc) < 0) + HDONE_ERROR(H5E_ATTR, H5E_CANTRELEASE, NULL, "can't free location") + + /* Cleanup on failure */ + if(ret_value == NULL) + if(attr && H5A_close(attr) < 0) + HDONE_ERROR(H5E_ATTR, H5E_CANTFREE, NULL, "can't close attribute") + + FUNC_LEAVE_NOAPI(ret_value) +} /* H5A_open_by_name() */ + + +/*-------------------------------------------------------------------------- + NAME + H5A_write + PURPOSE + Actually write out data to an attribute + USAGE + herr_t H5A_write (attr, mem_type, buf) + H5A_t *attr; IN: Attribute to write + const H5T_t *mem_type; IN: Memory datatype of buffer + const void *buf; IN: Buffer of data to write + RETURNS + Non-negative on success/Negative on failure + + DESCRIPTION + This function writes a complete attribute to disk. +--------------------------------------------------------------------------*/ +herr_t +H5A_write(H5A_t *attr, const H5T_t *mem_type, const void *buf, hid_t dxpl_id) +{ + uint8_t *tconv_buf = NULL; /* datatype conv buffer */ + hbool_t tconv_owned = FALSE; /* Whether the datatype conv buffer is owned by attribute */ + uint8_t *bkg_buf = NULL; /* temp conversion buffer */ + hssize_t snelmts; /* elements in attribute */ + size_t nelmts; /* elements in attribute */ + H5T_path_t *tpath = NULL; /* conversion information*/ + hid_t src_id = -1, dst_id = -1;/* temporary type atoms */ + size_t src_type_size; /* size of source type */ + size_t dst_type_size; /* size of destination type*/ + size_t buf_size; /* desired buffer size */ + herr_t ret_value = SUCCEED; + + FUNC_ENTER_NOAPI_NOINIT_TAG(dxpl_id, attr->oloc.addr, FAIL) + + HDassert(attr); + HDassert(mem_type); + HDassert(buf); + + /* Get # of elements for attribute's dataspace */ + if((snelmts = H5S_GET_EXTENT_NPOINTS(attr->shared->ds)) < 0) + HGOTO_ERROR(H5E_ATTR, H5E_CANTCOUNT, FAIL, "dataspace is invalid") + H5_ASSIGN_OVERFLOW(nelmts, snelmts, hssize_t, size_t); + + /* If there's actually data elements for the attribute, make a copy of the data passed in */ + if(nelmts > 0) { + /* Get the memory and file datatype sizes */ + src_type_size = H5T_GET_SIZE(mem_type); + dst_type_size = H5T_GET_SIZE(attr->shared->dt); + + /* Convert memory buffer into disk buffer */ + /* Set up type conversion function */ + if(NULL == (tpath = H5T_path_find(mem_type, attr->shared->dt, NULL, NULL, dxpl_id, FALSE))) + HGOTO_ERROR(H5E_ATTR, H5E_UNSUPPORTED, FAIL, "unable to convert between src and dst datatypes") + + /* Check for type conversion required */ + if(!H5T_path_noop(tpath)) { + if((src_id = H5I_register(H5I_DATATYPE, H5T_copy(mem_type, H5T_COPY_ALL), FALSE)) < 0 || + (dst_id = H5I_register(H5I_DATATYPE, H5T_copy(attr->shared->dt, H5T_COPY_ALL), FALSE)) < 0) + HGOTO_ERROR(H5E_ATTR, H5E_CANTREGISTER, FAIL, "unable to register types for conversion") + + /* Get the maximum buffer size needed and allocate it */ + buf_size = nelmts * MAX(src_type_size, dst_type_size); + if(NULL == (tconv_buf = H5FL_BLK_MALLOC(attr_buf, buf_size))) + HGOTO_ERROR(H5E_ATTR, H5E_CANTALLOC, FAIL, "memory allocation failed") + if(NULL == (bkg_buf = H5FL_BLK_CALLOC(attr_buf, buf_size))) + HGOTO_ERROR(H5E_ATTR, H5E_CANTALLOC, FAIL, "memory allocation failed") + + /* Copy the user's data into the buffer for conversion */ + HDmemcpy(tconv_buf, buf, (src_type_size * nelmts)); + + /* Perform datatype conversion */ + if(H5T_convert(tpath, src_id, dst_id, nelmts, (size_t)0, (size_t)0, tconv_buf, bkg_buf, dxpl_id) < 0) + HGOTO_ERROR(H5E_ATTR, H5E_CANTENCODE, FAIL, "datatype conversion failed") + + /* Free the previous attribute data buffer, if there is one */ + if(attr->shared->data) + attr->shared->data = H5FL_BLK_FREE(attr_buf, attr->shared->data); + + /* Set the pointer to the attribute data to the converted information */ + attr->shared->data = tconv_buf; + tconv_owned = TRUE; + } /* end if */ + /* No type conversion necessary */ + else { + HDassert(dst_type_size == src_type_size); + + /* Allocate the attribute buffer, if there isn't one */ + if(attr->shared->data == NULL) + if(NULL == (attr->shared->data = H5FL_BLK_MALLOC(attr_buf, dst_type_size * nelmts))) + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed") + + /* Copy the attribute data into the user's buffer */ + HDmemcpy(attr->shared->data, buf, (dst_type_size * nelmts)); + } /* end else */ + + /* Modify the attribute in the object header */ + if(H5O_attr_write(&(attr->oloc), dxpl_id, attr) < 0) + HGOTO_ERROR(H5E_ATTR, H5E_CANTINIT, FAIL, "unable to modify attribute") + } /* end if */ + +done: + /* Release resources */ + if(src_id >= 0 && H5I_dec_ref(src_id) < 0) + HDONE_ERROR(H5E_ATTR, H5E_CANTDEC, FAIL, "unable to close temporary object") + if(dst_id >= 0 && H5I_dec_ref(dst_id) < 0) + HDONE_ERROR(H5E_ATTR, H5E_CANTDEC, FAIL, "unable to close temporary object") + if(tconv_buf && !tconv_owned) + tconv_buf = H5FL_BLK_FREE(attr_buf, tconv_buf); + if(bkg_buf) + bkg_buf = H5FL_BLK_FREE(attr_buf, bkg_buf); + + FUNC_LEAVE_NOAPI_TAG(ret_value, FAIL) +} /* H5A_write() */ + + +/*-------------------------------------------------------------------------- + NAME + H5A_read + PURPOSE + Actually read in data from an attribute + USAGE + herr_t H5A_read (attr, mem_type, buf) + H5A_t *attr; IN: Attribute to read + const H5T_t *mem_type; IN: Memory datatype of buffer + void *buf; IN: Buffer for data to read + RETURNS + Non-negative on success/Negative on failure + + DESCRIPTION + This function reads a complete attribute from disk. +--------------------------------------------------------------------------*/ +herr_t +H5A_read(const H5A_t *attr, const H5T_t *mem_type, void *buf, hid_t dxpl_id) +{ + uint8_t *tconv_buf = NULL; /* datatype conv buffer*/ + uint8_t *bkg_buf = NULL; /* background buffer */ + hssize_t snelmts; /* elements in attribute */ + size_t nelmts; /* elements in attribute*/ + H5T_path_t *tpath = NULL; /* type conversion info */ + hid_t src_id = -1, dst_id = -1;/* temporary type atoms*/ + size_t src_type_size; /* size of source type */ + size_t dst_type_size; /* size of destination type */ + size_t buf_size; /* desired buffer size */ + herr_t ret_value = SUCCEED; + + FUNC_ENTER_NOAPI_NOINIT + + HDassert(attr); + HDassert(mem_type); + HDassert(buf); + + /* Create buffer for data to store on disk */ + if((snelmts = H5S_GET_EXTENT_NPOINTS(attr->shared->ds)) < 0) + HGOTO_ERROR(H5E_ATTR, H5E_CANTCOUNT, FAIL, "dataspace is invalid") + H5_ASSIGN_OVERFLOW(nelmts, snelmts, hssize_t, size_t); + + if(nelmts > 0) { + /* Get the memory and file datatype sizes */ + src_type_size = H5T_GET_SIZE(attr->shared->dt); + dst_type_size = H5T_GET_SIZE(mem_type); + + /* Check if the attribute has any data yet, if not, fill with zeroes */ + if(attr->obj_opened && !attr->shared->data) + HDmemset(buf, 0, (dst_type_size * nelmts)); + else { /* Attribute exists and has a value */ + /* Convert memory buffer into disk buffer */ + /* Set up type conversion function */ + if(NULL == (tpath = H5T_path_find(attr->shared->dt, mem_type, NULL, NULL, dxpl_id, FALSE))) + HGOTO_ERROR(H5E_ATTR, H5E_UNSUPPORTED, FAIL, "unable to convert between src and dst datatypes") + + /* Check for type conversion required */ + if(!H5T_path_noop(tpath)) { + if((src_id = H5I_register(H5I_DATATYPE, H5T_copy(attr->shared->dt, H5T_COPY_ALL), FALSE)) < 0 || + (dst_id = H5I_register(H5I_DATATYPE, H5T_copy(mem_type, H5T_COPY_ALL), FALSE)) < 0) + HGOTO_ERROR(H5E_ATTR, H5E_CANTREGISTER, FAIL, "unable to register types for conversion") + + /* Get the maximum buffer size needed and allocate it */ + buf_size = nelmts * MAX(src_type_size, dst_type_size); + if(NULL == (tconv_buf = H5FL_BLK_MALLOC(attr_buf, buf_size))) + HGOTO_ERROR(H5E_ATTR, H5E_NOSPACE, FAIL, "memory allocation failed") + if(NULL == (bkg_buf = H5FL_BLK_CALLOC(attr_buf, buf_size))) + HGOTO_ERROR(H5E_ATTR, H5E_NOSPACE, FAIL, "memory allocation failed") + + /* Copy the attribute data into the buffer for conversion */ + HDmemcpy(tconv_buf, attr->shared->data, (src_type_size * nelmts)); + + /* Perform datatype conversion. */ + if(H5T_convert(tpath, src_id, dst_id, nelmts, (size_t)0, (size_t)0, tconv_buf, bkg_buf, dxpl_id) < 0) + HGOTO_ERROR(H5E_ATTR, H5E_CANTENCODE, FAIL, "datatype conversion failed") + + /* Copy the converted data into the user's buffer */ + HDmemcpy(buf, tconv_buf, (dst_type_size * nelmts)); + } /* end if */ + /* No type conversion necessary */ + else { + HDassert(dst_type_size == src_type_size); + + /* Copy the attribute data into the user's buffer */ + HDmemcpy(buf, attr->shared->data, (dst_type_size * nelmts)); + } /* end else */ + } /* end else */ + } /* end if */ + +done: + /* Release resources */ + if(src_id >= 0 && H5I_dec_ref(src_id) < 0) + HDONE_ERROR(H5E_ATTR, H5E_CANTDEC, FAIL, "unable to close temporary object") + if(dst_id >= 0 && H5I_dec_ref(dst_id) < 0) + HDONE_ERROR(H5E_ATTR, H5E_CANTDEC, FAIL, "unable to close temporary object") + if(tconv_buf) + tconv_buf = H5FL_BLK_FREE(attr_buf, tconv_buf); + if(bkg_buf) + bkg_buf = H5FL_BLK_FREE(attr_buf, bkg_buf); + + FUNC_LEAVE_NOAPI(ret_value) +} /* H5A_read() */ + + +/*------------------------------------------------------------------------- + * Function: H5A_get_space + * + * Purpose: Returns and ID for the dataspace of the attribute. + * + * Return: Success: ID for dataspace + * + * Failure: FAIL + * + * Programmer: Mohamad Chaarawi + * March, 2012 + * + *------------------------------------------------------------------------- + */ +hid_t +H5A_get_space(H5A_t *attr) +{ + H5S_t *ds = NULL; + hid_t ret_value = FAIL; + + FUNC_ENTER_NOAPI_NOINIT + + /* Copy the attribute's dataspace */ + if(NULL == (ds = H5S_copy(attr->shared->ds, FALSE, TRUE))) + HGOTO_ERROR(H5E_ATTR, H5E_CANTINIT, FAIL, "unable to copy dataspace") + + /* Atomize */ + if((ret_value = H5I_register(H5I_DATASPACE, ds, TRUE)) < 0) + HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL, "unable to register dataspace atom") + +done: + if(ret_value < 0 && ds) { + if(H5S_close(ds) < 0) + HDONE_ERROR(H5E_DATASET, H5E_CLOSEERROR, FAIL, "unable to release dataspace") + } /* end if */ + + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5A_get_space() */ + + +/*------------------------------------------------------------------------- + * Function: H5A_get_type + * + * Purpose: Returns and ID for the datatype of the dataset. + * + * Return: Success: ID for datatype + * + * Failure: FAIL + * + * Programmer: Mohamad Chaarawi + * March, 2012 + * + *------------------------------------------------------------------------- + */ +hid_t +H5A_get_type(H5A_t *attr) +{ + H5T_t *dt = NULL; + hid_t ret_value = FAIL; + + FUNC_ENTER_NOAPI_NOINIT + + /* Patch the datatype's "top level" file pointer */ + if(H5T_patch_file(attr->shared->dt, attr->oloc.file) < 0) + HGOTO_ERROR(H5E_ATTR, H5E_CANTINIT, FAIL, "unable to patch datatype's file pointer") + + /* + * Copy the attribute's datatype. If the type is a named type then + * reopen the type before returning it to the user. Make the type + * read-only. + */ + if(NULL == (dt = H5T_copy(attr->shared->dt, H5T_COPY_REOPEN))) + HGOTO_ERROR(H5E_ATTR, H5E_CANTINIT, FAIL, "unable to copy datatype") + + /* Mark any datatypes as being in memory now */ + if(H5T_set_loc(dt, NULL, H5T_LOC_MEMORY) < 0) + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "invalid datatype location") + + /* Lock copied type */ + if(H5T_lock(dt, FALSE) < 0) + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to lock transient datatype") + + /* Atomize */ + if((ret_value = H5I_register(H5I_DATATYPE, dt, TRUE)) < 0) + HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL, "unable to register datatype ID") + +done: + if(ret_value < 0) { + if(dt && H5T_close(dt) < 0) + HDONE_ERROR(H5E_DATASET, H5E_CLOSEERROR, FAIL, "unable to release datatype") + } /* end if */ + + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5A_get_type() */ + + +/*-------------------------------------------------------------------------- + NAME + H5A_get_create_plist + PURPOSE + private version of H5Aget_create_plist + RETURNS + This function returns the ID of a copy of the attribute's creation + property list, or negative on failure. + + ERRORS + + DESCRIPTION + This function returns a copy of the creation property list for + an attribute. The resulting ID must be closed with H5Pclose() or + resource leaks will occur. +--------------------------------------------------------------------------*/ +hid_t +H5A_get_create_plist(H5A_t* attr) +{ + H5P_genplist_t *plist; /* Default property list */ + hid_t new_plist_id; /* ID of ACPL to return */ + H5P_genplist_t *new_plist; /* ACPL to return */ + hid_t ret_value; + FUNC_ENTER_NOAPI_NOINIT + + if(NULL == (plist = (H5P_genplist_t *)H5I_object(H5P_LST_ATTRIBUTE_CREATE_g))) + HGOTO_ERROR(H5E_PLIST, H5E_BADTYPE, FAIL, "can't get default ACPL") + + /* Create the property list object to return */ + if((new_plist_id = H5P_copy_plist(plist, TRUE)) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTINIT, FAIL, "unable to copy attribute creation properties") + if(NULL == (new_plist = (H5P_genplist_t *)H5I_object(new_plist_id))) + HGOTO_ERROR(H5E_PLIST, H5E_BADTYPE, FAIL, "can't get property list") + + /* Set the character encoding on the new property list */ + if(H5P_set(new_plist, H5P_STRCRT_CHAR_ENCODING_NAME, &(attr->shared->encoding)) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set character encoding") + + ret_value = new_plist_id; + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5Aget_create_plist() */ + + +/*-------------------------------------------------------------------------- + NAME + H5A_get_name + PURPOSE + Private function for H5Aget_name. Gets a copy of the name for an + attribute + RETURNS + This function returns the length of the attribute's name (which may be + longer than 'buf_size') on success or negative for failure. + DESCRIPTION + This function retrieves the name of an attribute for an attribute ID. + Up to 'buf_size' characters are stored in 'buf' followed by a '\0' string + terminator. If the name of the attribute is longer than 'buf_size'-1, + the string terminator is stored in the last position of the buffer to + properly terminate the string. +--------------------------------------------------------------------------*/ +ssize_t +H5A_get_name(H5A_t *attr, size_t buf_size, char *buf) +{ + size_t copy_len, nbytes; + ssize_t ret_value; + + FUNC_ENTER_NOAPI(FAIL) + + /* get the real attribute length */ + nbytes = HDstrlen(attr->shared->name); + HDassert((ssize_t)nbytes >= 0); /*overflow, pretty unlikely --rpm*/ + + /* compute the string length which will fit into the user's buffer */ + copy_len = MIN(buf_size - 1, nbytes); + + /* Copy all/some of the name */ + if(buf && copy_len > 0) { + HDmemcpy(buf, attr->shared->name, copy_len); + + /* Terminate the string */ + buf[copy_len]='\0'; + } /* end if */ + + /* Set return value */ + ret_value = (ssize_t)nbytes; + + FUNC_LEAVE_NOAPI(ret_value) +} /* H5A_get_name() */ + + +/*------------------------------------------------------------------------- + * Function: H5A_get_info + * + * Purpose: Retrieve information about an attribute. + * + * Return: Success: Non-negative + * Failure: Negative + * + * Programmer: Quincey Koziol + * February 6, 2007 + * + *------------------------------------------------------------------------- + */ +herr_t +H5A_get_info(const H5A_t *attr, H5A_info_t *ainfo) +{ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI(FAIL) + + /* Check args */ + HDassert(attr); + HDassert(ainfo); + + /* Set info for attribute */ + ainfo->cset = attr->shared->encoding; + ainfo->data_size = attr->shared->data_size; + if(attr->shared->crt_idx == H5O_MAX_CRT_ORDER_IDX) { + ainfo->corder_valid = FALSE; + ainfo->corder = 0; + } /* end if */ + else { + ainfo->corder_valid = TRUE; + ainfo->corder = attr->shared->crt_idx; + } /* end else */ + + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5A_get_info() */ + + +/*-------------------------------------------------------------------------- + NAME + H5A_delete_by_idx + PURPOSE + private version of H5Adelete_by_idx + RETURNS + Non-negative on success/Negative on failure +--------------------------------------------------------------------------*/ +herr_t +H5A_delete_by_idx(H5G_loc_t loc, const char *obj_name, H5_index_t idx_type, + H5_iter_order_t order, hsize_t n, hid_t lapl_id) +{ + 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_NOAPI_NOINIT + + /* Set up opened group location to fill in */ + obj_loc.oloc = &obj_oloc; + obj_loc.path = &obj_path; + H5G_loc_reset(&obj_loc); + + /* Find the object's location */ + if(H5G_loc_find(&loc, obj_name, &obj_loc/*out*/, lapl_id, H5AC_dxpl_id) < 0) + HGOTO_ERROR(H5E_ATTR, H5E_NOTFOUND, FAIL, "object not found") + loc_found = TRUE; + + /* Delete the attribute from the location */ + if(H5O_attr_remove_by_idx(obj_loc.oloc, idx_type, order, n, H5AC_dxpl_id) < 0) + HGOTO_ERROR(H5E_ATTR, H5E_CANTDELETE, FAIL, "unable to delete attribute") + +done: + /* Release resources */ + if(loc_found && H5G_loc_free(&obj_loc) < 0) + HDONE_ERROR(H5E_ATTR, H5E_CANTRELEASE, FAIL, "can't free location") + + FUNC_LEAVE_NOAPI(ret_value) +} /* H5A_delete_by_idx() */ + + +/*------------------------------------------------------------------------- + * Function: H5A_copy + * + * Purpose: Copies attribute OLD_ATTR. + * + * Return: Success: Pointer to a new copy of the OLD_ATTR argument. + * + * Failure: NULL + * + * Programmer: Robb Matzke + * Thursday, December 4, 1997 + * + * Modification:Raymond Lu + * 4 June 2008 + * Changed some attribute information to be shared. + * + *------------------------------------------------------------------------- + */ +H5A_t * +H5A_copy(H5A_t *_new_attr, const H5A_t *old_attr) +{ + H5A_t *new_attr = NULL; + hbool_t allocated_attr = FALSE; /* Whether the attribute was allocated */ + H5A_t *ret_value = NULL; /* Return value */ + + FUNC_ENTER_NOAPI(NULL) + + /* check args */ + HDassert(old_attr); + + /* Allocate attribute structure */ + if(_new_attr == NULL) { + if(NULL == (new_attr = H5FL_CALLOC(H5A_t))) + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed") + allocated_attr = TRUE; + } /* end if */ + else + new_attr = _new_attr; + + /* Copy the top level of the attribute */ + new_attr->sh_loc = old_attr->sh_loc; + + /* Deep copy of the group hierarchy path */ + if(H5G_name_copy(&(new_attr->path), &(old_attr->path), H5_COPY_DEEP) < 0) + HGOTO_ERROR(H5E_ATTR, H5E_CANTCOPY, NULL, "unable to copy path") + + /* Share some attribute information */ + new_attr->shared = old_attr->shared; + + /* Increment reference count for shared object */ + new_attr->shared->nrefs++; + + /* Don't open the object header for a copy */ + new_attr->obj_opened = FALSE; + + /* Set the return value */ + ret_value = new_attr; + +done: + if(ret_value == NULL) + if(allocated_attr && new_attr && H5A_close(new_attr) < 0) + HDONE_ERROR(H5E_ATTR, H5E_CANTFREE, NULL, "can't close attribute") + + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5A_copy() */ + + +/*------------------------------------------------------------------------- + * Function: H5A_free + * + * Purpose: Frees all memory associated with an attribute, but does not + * free the H5A_t structure (which should be done in H5T_close). + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Quincey Koziol + * Monday, November 15, 2004 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +herr_t +H5A_free(H5A_t *attr) +{ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI(FAIL) + + HDassert(attr); + + /* Free dynamicly allocated items */ + if(attr->shared->name) { + H5MM_xfree(attr->shared->name); + attr->shared->name = NULL; + } + if(attr->shared->dt) { + if(H5T_close(attr->shared->dt) < 0) + HGOTO_ERROR(H5E_ATTR, H5E_CANTRELEASE, FAIL, "can't release datatype info") + attr->shared->dt = NULL; + } + if(attr->shared->ds) { + if(H5S_close(attr->shared->ds) < 0) + HGOTO_ERROR(H5E_ATTR, H5E_CANTRELEASE, FAIL, "can't release dataspace info") + attr->shared->ds = NULL; + } + if(attr->shared->data) + attr->shared->data = H5FL_BLK_FREE(attr_buf, attr->shared->data); + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5A_free() */ + + +/*------------------------------------------------------------------------- + * Function: H5A_close + * + * Purpose: Frees an attribute and all associated memory. + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Robb Matzke + * Monday, December 8, 1997 + * + * Modifications: + * Raymond Lu + * 4 June 2008 + * Changed some attribute object information to be shared. + *------------------------------------------------------------------------- + */ +herr_t +H5A_close(H5A_t *attr) +{ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI(FAIL) + + HDassert(attr); + HDassert(attr->shared); + + /* Close the object's symbol-table entry */ + if(attr->obj_opened && (H5O_close(&(attr->oloc)) < 0)) + HGOTO_ERROR(H5E_ATTR, H5E_CANTRELEASE, FAIL, "can't release object header info") + + /* Reference count can be 0. It only happens when H5A_create fails. */ + if(attr->shared->nrefs <= 1) { + /* Free dynamicly allocated items */ + if(H5A_free(attr) < 0) + HGOTO_ERROR(H5E_ATTR, H5E_CANTRELEASE, FAIL, "can't release attribute info") + + /* Destroy shared attribute struct */ + attr->shared = H5FL_FREE(H5A_shared_t, attr->shared); + } /* end if */ + else { + /* There are other references to the shared part of the attribute. + * Only decrement the reference count. */ + --attr->shared->nrefs; + } /* end else */ + + /* Free group hierarchy path */ + if(H5G_name_free(&(attr->path)) < 0) + HGOTO_ERROR(H5E_ATTR, H5E_CANTRELEASE, FAIL, "can't release group hier. path") + + attr->shared = NULL; + attr = H5FL_FREE(H5A_t, attr); + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5A_close() */ + + +/*------------------------------------------------------------------------- + * Function: H5A_oloc + * + * Purpose: Return the object location for an attribute. It's the + * object location for the object to which the attribute + * belongs, not the attribute itself. + * + * Return: Success: Ptr to entry + * Failure: NULL + * + * Programmer: Robb Matzke + * Thursday, August 6, 1998 + * + *------------------------------------------------------------------------- + */ +H5O_loc_t * +H5A_oloc(H5A_t *attr) +{ + H5O_loc_t *ret_value; /* Return value */ + + FUNC_ENTER_NOAPI(NULL) + + HDassert(attr); + + /* Set return value */ + ret_value = &(attr->oloc); + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5A_oloc() */ + + +/*------------------------------------------------------------------------- + * Function: H5A_nameof + * + * Purpose: Return the group hier. path for an attribute. It's the + * group hier. path for the object to which the attribute + * belongs, not the attribute itself. + * + * Return: Success: Ptr to entry + * Failure: NULL + * + * Programmer: Quincey Koziol + * Monday, September 12, 2005 + * + *------------------------------------------------------------------------- + */ +H5G_name_t * +H5A_nameof(H5A_t *attr) +{ + H5G_name_t *ret_value; /* Return value */ + + FUNC_ENTER_NOAPI(NULL) + + HDassert(attr); + + /* Set return value */ + ret_value=&(attr->path); + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5A_nameof() */ + + +/*------------------------------------------------------------------------- + * Function: H5A_type + * + * Purpose: Return the datatype for an attribute. + * + * Return: Success: Ptr to entry + * Failure: NULL + * + * Programmer: Neil Fortner + * Friday, November 11, 2011 + * + *------------------------------------------------------------------------- + */ +H5T_t * +H5A_type(const H5A_t *attr) +{ + H5T_t *ret_value; /* Return value */ + + FUNC_ENTER_NOAPI(NULL) + + HDassert(attr); + + /* Set return value */ + ret_value = attr->shared->dt; + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5A_type() */ + + +/*------------------------------------------------------------------------- + * Function: H5A_exists_by_name + * + * Purpose: Private version of H5Aexists_by_name + * + * Return: Success: TRUE/FALSE + * Failure: Negative + * + * Programmer: Quincey Koziol + * Thursday, November 1, 2007 + * + *------------------------------------------------------------------------- + */ +htri_t +H5A_exists_by_name(H5G_loc_t loc, const char *obj_name, const char *attr_name, + hid_t lapl_id) +{ + 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; /* Return value */ + + FUNC_ENTER_NOAPI_NOINIT + + /* Set up opened group location to fill in */ + obj_loc.oloc = &obj_oloc; + obj_loc.path = &obj_path; + H5G_loc_reset(&obj_loc); + + /* Find the object's location */ + if(H5G_loc_find(&loc, obj_name, &obj_loc/*out*/, lapl_id, H5AC_ind_dxpl_id) < 0) + HGOTO_ERROR(H5E_ATTR, H5E_NOTFOUND, FAIL, "object not found") + loc_found = TRUE; + + /* Check if the attribute exists */ + if((ret_value = H5O_attr_exists(obj_loc.oloc, attr_name, H5AC_ind_dxpl_id)) < 0) + HGOTO_ERROR(H5E_ATTR, H5E_CANTGET, FAIL, "unable to determine if attribute exists") + +done: + /* Release resources */ + if(loc_found && H5G_loc_free(&obj_loc) < 0) + HDONE_ERROR(H5E_ATTR, H5E_CANTRELEASE, FAIL, "can't free location") + + FUNC_LEAVE_NOAPI(ret_value) +} /* H5A_exists_by_name() */ + + +/*------------------------------------------------------------------------- * Function: H5A_compact_build_table_cb * * Purpose: Object header iterator callback routine to copy attribute diff --git a/src/H5F.c b/src/H5F.c index 167ffe3..e8ac4cf 100644 --- a/src/H5F.c +++ b/src/H5F.c @@ -16,171 +16,64 @@ #define H5F_PACKAGE /*suppress error about including H5Fpkg */ /* Interface initialization */ -#define H5_INTERFACE_INIT_FUNC H5F_init_interface +#define H5_INTERFACE_INIT_FUNC H5F__init_pub_interface /* Packages needed by this file... */ #include "H5private.h" /* Generic Functions */ -#include "H5Aprivate.h" /* Attributes */ -#include "H5ACprivate.h" /* Metadata cache */ -#include "H5Dprivate.h" /* Datasets */ #include "H5Eprivate.h" /* Error handling */ #include "H5Fpkg.h" /* File access */ -#include "H5FDprivate.h" /* File drivers */ -#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 "H5SMprivate.h" /* Shared Object Header Messages */ -#include "H5Tprivate.h" /* Datatypes */ #include "H5VLprivate.h" /* VOL plugins */ -/* Struct only used by functions H5F_get_objects and H5F_get_objects_cb */ -typedef struct H5F_olist_t { - H5I_type_t obj_type; /* Type of object to look for */ - hid_t *obj_id_list; /* Pointer to the list of open IDs to return */ - size_t *obj_id_count; /* Number of open IDs */ - struct { - hbool_t local; /* Set flag for "local" file searches */ - union { - H5F_file_t *shared; /* Pointer to shared file to look inside */ - const H5F_t *file; /* Pointer to file to look inside */ - } ptr; - } file_info; - size_t list_index; /* Current index in open ID array */ - size_t max_index; /* Maximum # of IDs to put into array */ -} H5F_olist_t; - -/* User data for traversal routine to get ID counts */ -typedef struct { - ssize_t *obj_count; /* number of objects counted so far */ - unsigned types; /* types of objects to be counted */ -} H5F_trav_obj_cnt_t; - -/* User data for traversal routine to get ID lists */ -typedef struct { - size_t max_objs; - hid_t *oid_list; - ssize_t *obj_count; /* number of objects counted so far */ - unsigned types; /* types of objects to be counted */ -} H5F_trav_obj_ids_t; - -/* PRIVATE PROTOTYPES */ -static herr_t H5F_get_objects(const H5F_t *f, unsigned types, size_t max_index, hid_t *obj_id_list, hbool_t app_ref, size_t *obj_id_count_ptr); -static int H5F_get_objects_cb(void *obj_ptr, hid_t obj_id, void *key); -static int H5F_get_obj_count_cb(void *obj_ptr, hid_t obj_id, void *key); -static int H5F_get_obj_ids_cb(void *obj_ptr, hid_t obj_id, void *key); -static H5F_t *H5F_new(H5F_file_t *shared, hid_t fcpl_id, hid_t fapl_id, - H5FD_t *lf); -static herr_t H5F_build_actual_name(const H5F_t *f, const H5P_genplist_t *fapl, - const char *name, char ** /*out*/ actual_name); -static herr_t H5F_dest(H5F_t *f, hid_t dxpl_id, hbool_t flush); - -/* Declare a free list to manage the H5F_t struct */ -H5FL_DEFINE(H5F_t); - -/* Declare a free list to manage the H5F_file_t struct */ -H5FL_DEFINE(H5F_file_t); +/****************/ +/* Local Macros */ +/****************/ - -/*------------------------------------------------------------------------- - * Function: H5F_init - * - * Purpose: Initialize the interface from some other layer. - * - * Return: Success: non-negative - * Failure: negative - * - * Programmer: Robb Matzke - * Wednesday, December 16, 1998 - * - *------------------------------------------------------------------------- - */ -herr_t -H5F_init(void) -{ - herr_t ret_value = SUCCEED; /* Return value */ +/******************/ +/* Local Typedefs */ +/******************/ - FUNC_ENTER_NOAPI(FAIL) - /* FUNC_ENTER() does all the work */ +/********************/ +/* Local Prototypes */ +/********************/ -done: - FUNC_LEAVE_NOAPI(ret_value) -} /* end H5F_init() */ +static herr_t H5F__init_pub_interface(void); - -/*------------------------------------------------------------------------- - * Function: H5F_init_interface - * - * Purpose: Initialize interface-specific information. - * - * Return: Success: non-negative - * Failure: negative - * - * Programmer: Robb Matzke - * Friday, November 20, 1998 - * - *------------------------------------------------------------------------- - */ -static herr_t -H5F_init_interface(void) -{ - herr_t ret_value = SUCCEED; /* Return value */ - FUNC_ENTER_NOAPI_NOINIT +/*********************/ +/* Package Variables */ +/*********************/ - /* - * Initialize the atom group for the file IDs. - */ - if(H5I_register_type(H5I_FILE, (size_t)H5I_FILEID_HASHSIZE, 0, (H5I_free_t)H5F_close)shared->mdc_initCacheCfg)) < 0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set initial metadata cache resize config.") - if(H5P_set(new_plist, H5F_ACS_DATA_CACHE_NUM_SLOTS_NAME, &(f->shared->rdcc_nslots)) < 0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set data cache number of slots") - if(H5P_set(new_plist, H5F_ACS_DATA_CACHE_BYTE_SIZE_NAME, &(f->shared->rdcc_nbytes)) < 0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set data cache byte size") - if(H5P_set(new_plist, H5F_ACS_PREEMPT_READ_CHUNKS_NAME, &(f->shared->rdcc_w0)) < 0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set preempt read chunks") - if(H5P_set(new_plist, H5F_ACS_ALIGN_THRHD_NAME, &(f->shared->threshold)) < 0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set alignment threshold") - if(H5P_set(new_plist, H5F_ACS_ALIGN_NAME, &(f->shared->alignment)) < 0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set alignment") - if(H5P_set(new_plist, H5F_ACS_GARBG_COLCT_REF_NAME, &(f->shared->gc_ref)) < 0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set garbage collect reference") - if(H5P_set(new_plist, H5F_ACS_META_BLOCK_SIZE_NAME, &(f->shared->meta_aggr.alloc_size)) < 0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set metadata cache size") - if(H5P_set(new_plist, H5F_ACS_SIEVE_BUF_SIZE_NAME, &(f->shared->sieve_buf_size)) < 0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't sieve buffer size") - if(H5P_set(new_plist, H5F_ACS_SDATA_BLOCK_SIZE_NAME, &(f->shared->sdata_aggr.alloc_size)) < 0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set 'small data' cache size") - if(H5P_set(new_plist, H5F_ACS_LATEST_FORMAT_NAME, &(f->shared->latest_format)) < 0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set 'latest format' flag") - if(f->shared->efc) - efc_size = H5F_efc_max_nfiles(f->shared->efc); - if(H5P_set(new_plist, H5F_ACS_EFC_SIZE_NAME, &efc_size) < 0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't set elink file cache size") - - /* - * Since we're resetting the driver ID and info, close them if they - * exist in this new property list. - */ - if(H5P_facc_close(ret_value, NULL) < 0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTFREE, FAIL, "can't free the old driver information") - - /* Increment the reference count on the driver ID and insert it into the property list */ - if(H5I_inc_ref(f->shared->lf->driver_id, FALSE) < 0) - HGOTO_ERROR(H5E_FILE, H5E_CANTINC, FAIL, "unable to increment ref count on VFL driver") - if(H5P_set(new_plist, H5F_ACS_FILE_DRV_ID_NAME, &(f->shared->lf->driver_id)) < 0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set file driver ID") - - /* Set the driver "info" in the property list */ - driver_info = H5FD_fapl_get(f->shared->lf); - if(driver_info != NULL && H5P_set(new_plist, H5F_ACS_FILE_DRV_INFO_NAME, &driver_info) < 0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set file driver info") - - /* Set the file close degree appropriately */ - if(f->shared->fc_degree == H5F_CLOSE_DEFAULT && H5P_set(new_plist, H5F_ACS_CLOSE_DEGREE_NAME, &(f->shared->lf->cls->fc_degree)) < 0) { - HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set file close degree") - } else if(f->shared->fc_degree != H5F_CLOSE_DEFAULT && H5P_set(new_plist, H5F_ACS_CLOSE_DEGREE_NAME, &(f->shared->fc_degree)) < 0) { - HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set file close degree") - } - - /* MSC TODO move this to the upper VOL get routine & set the vol info too*/ - /* Set the VOL class in the property list */ - if(H5P_set(new_plist, H5F_ACS_VOL_NAME, &(f->vol_cls)) < 0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set file VOL plugin") - -done: - FUNC_LEAVE_NOAPI(ret_value) -} /* end H5F_get_access_plist() */ - - -/*------------------------------------------------------------------------- * Function: H5Fget_obj_count * * Purpose: Public function returning the number of opened object IDs @@ -404,71 +189,6 @@ done: /*------------------------------------------------------------------------- - * Function: H5F_get_obj_count_cb - * - * Purpose: H5F_get_obj_count_cb callback function. It calls in the - * VOL and gets the object count for the file ID passed - * - * Return: TRUE if the value has been added. - * FALSE otherwise. - * - * Programmer: Mohamad Chaarawi - * May 2012 - * - *------------------------------------------------------------------------- - */ -static int -H5F_get_obj_count_cb(void UNUSED *obj_ptr, hid_t obj_id, void *key) -{ - H5F_trav_obj_cnt_t *udata = (H5F_trav_obj_cnt_t *)key; - ssize_t obj_count = 0; - int ret_value = H5_ITER_CONT; /* Return value */ - - FUNC_ENTER_NOAPI_NOINIT - - if(H5VL_file_get(obj_id, H5VL_FILE_GET_OBJ_COUNT, H5_REQUEST_NULL, &obj_count, udata->types) < 0) - HGOTO_ERROR(H5E_INTERNAL, H5E_CANTGET, H5_ITER_ERROR, "unable to get object count in file(s)") - - *(udata->obj_count) += obj_count; - -done: - FUNC_LEAVE_NOAPI(ret_value) -} /* H5F_get_obj_count_cb */ - - -/*------------------------------------------------------------------------- - * Function: H5F_get_obj_count - * - * Purpose: Private function return the number of opened object IDs - * (files, datasets, groups, datatypes) in the same file. - * - * Return: SUCCEED on success, FAIL on failure. - * - * Programmer: Raymond Lu - * Wednesday, Dec 5, 2001 - * - *------------------------------------------------------------------------- - */ -herr_t -H5F_get_obj_count(const H5F_t *f, unsigned types, hbool_t app_ref, size_t *obj_id_count_ptr) -{ - herr_t ret_value = SUCCEED; - - FUNC_ENTER_NOAPI(FAIL) - - /* Sanity check */ - HDassert(obj_id_count_ptr); - - /* Perform the query */ - if((ret_value = H5F_get_objects(f, types, 0, NULL, app_ref, obj_id_count_ptr)) < 0) - HGOTO_ERROR(H5E_INTERNAL, H5E_BADITER, FAIL, "H5F_get_objects failed") - -done: - FUNC_LEAVE_NOAPI(ret_value) -} /* end H5F_get_obj_count() */ - - -/*------------------------------------------------------------------------- * Function: H5Fget_object_ids * * Purpose: Public function to return a list of opened object IDs. @@ -523,287 +243,6 @@ done: /*------------------------------------------------------------------------- - * Function: H5F_get_obj_ids_cb - * - * Purpose: H5F_get_obj_ids_cb callback function. It calls in the - * VOL and gets the object ids for the file ID passed - * - * Return: TRUE if the value has been added. - * FALSE otherwise. - * - * Programmer: Mohamad Chaarawi - * May 2012 - * - *------------------------------------------------------------------------- - */ -static int -H5F_get_obj_ids_cb(void UNUSED *obj_ptr, hid_t obj_id, void *key) -{ - H5F_trav_obj_ids_t *udata = (H5F_trav_obj_ids_t *)key; - ssize_t obj_count = 0; - int ret_value = H5_ITER_CONT; /* Return value */ - - FUNC_ENTER_NOAPI_NOINIT - - if(H5VL_file_get(obj_id, H5VL_FILE_GET_OBJ_IDS, H5_REQUEST_NULL, udata->types, - udata->max_objs, udata->oid_list, &obj_count) < 0) - HGOTO_ERROR(H5E_INTERNAL, H5E_CANTGET, H5_ITER_ERROR, "unable to get object count in file(s)") - - *(udata->obj_count) += obj_count; - udata->max_objs -= obj_count; - udata->oid_list += obj_count; - - if(udata->max_objs <= 0) - ret_value = H5_ITER_STOP; - -done: - FUNC_LEAVE_NOAPI(ret_value) -} /* H5F_get_obj_count_cb */ - - -/*------------------------------------------------------------------------- - * Function: H5F_get_obj_ids - * - * Purpose: Private function to return a list of opened object IDs. - * - * Return: Non-negative on success; can't fail. - * - * Programmer: Raymond Lu - * Wednesday, Dec 5, 2001 - * - *------------------------------------------------------------------------- - */ -herr_t -H5F_get_obj_ids(const H5F_t *f, unsigned types, size_t max_objs, hid_t *oid_list, hbool_t app_ref, size_t *obj_id_count_ptr) -{ - herr_t ret_value = SUCCEED; /* Return value */ - - FUNC_ENTER_NOAPI(FAIL) - - /* Sanity check */ - HDassert(obj_id_count_ptr); - - /* Perform the query */ - if((ret_value = H5F_get_objects(f, types, max_objs, oid_list, app_ref, obj_id_count_ptr)) < 0) - HGOTO_ERROR(H5E_INTERNAL, H5E_BADITER, FAIL, "H5F_get_objects failed") - -done: - FUNC_LEAVE_NOAPI(ret_value) -} /* end H5F_get_obj_ids() */ - - -/*--------------------------------------------------------------------------- - * Function: H5F_get_objects - * - * Purpose: This function is called by H5F_get_obj_count or - * H5F_get_obj_ids to get number of object IDs and/or a - * list of opened object IDs (in return value). - * Return: Non-negative on success; Can't fail. - * - * Programmer: Raymond Lu - * Wednesday, Dec 5, 2001 - * - *--------------------------------------------------------------------------- - */ -static herr_t -H5F_get_objects(const H5F_t *f, unsigned types, size_t max_index, hid_t *obj_id_list, hbool_t app_ref, size_t *obj_id_count_ptr) -{ - size_t obj_id_count=0; /* Number of open IDs */ - H5F_olist_t olist; /* Structure to hold search results */ - herr_t ret_value = SUCCEED; /* Return value */ - - FUNC_ENTER_NOAPI_NOINIT - - /* Sanity check */ - HDassert(obj_id_count_ptr); - - /* Set up search information */ - olist.obj_id_list = (max_index==0 ? NULL : obj_id_list); - olist.obj_id_count = &obj_id_count; - olist.list_index = 0; - olist.max_index = max_index; - - /* Determine if we are searching for local or global objects */ - if(types & H5F_OBJ_LOCAL) { - olist.file_info.local = TRUE; - olist.file_info.ptr.file = f; - } /* end if */ - else { - olist.file_info.local = FALSE; - olist.file_info.ptr.shared = f ? f->shared : NULL; - } /* end else */ - - /* Iterate through file IDs to count the number, and put their - * IDs on the object list. */ - if(types & H5F_OBJ_FILE) { - olist.obj_type = H5I_FILE; - if(H5I_iterate(H5I_FILE, H5F_get_objects_cb, &olist, app_ref) < 0) - HGOTO_ERROR(H5E_FILE, H5E_BADITER, FAIL, "iteration failed(1)") - } /* end if */ - - /* Search through dataset IDs to count number of datasets, and put their - * IDs on the object list */ - if(types & H5F_OBJ_DATASET) { - olist.obj_type = H5I_DATASET; - if(H5I_iterate(H5I_DATASET, H5F_get_objects_cb, &olist, app_ref) < 0) - HGOTO_ERROR(H5E_FILE, H5E_BADITER, FAIL, "iteration failed(2)") - } /* end if */ - - /* Search through group IDs to count number of groups, and put their - * IDs on the object list */ - if(types & H5F_OBJ_GROUP) { - olist.obj_type = H5I_GROUP; - if(H5I_iterate(H5I_GROUP, H5F_get_objects_cb, &olist, app_ref) < 0) - HGOTO_ERROR(H5E_FILE, H5E_BADITER, FAIL, "iteration failed(3)") - } /* end if */ - - /* Search through datatype IDs to count number of named datatypes, and put their - * IDs on the object list */ - if(types & H5F_OBJ_DATATYPE) { - olist.obj_type = H5I_DATATYPE; - if(H5I_iterate(H5I_DATATYPE, H5F_get_objects_cb, &olist, app_ref) < 0) - HGOTO_ERROR(H5E_FILE, H5E_BADITER, FAIL, "iteration failed(4)") - } /* end if */ - - /* Search through attribute IDs to count number of attributes, and put their - * IDs on the object list */ - if(types & H5F_OBJ_ATTR) { - olist.obj_type = H5I_ATTR; - if(H5I_iterate(H5I_ATTR, H5F_get_objects_cb, &olist, app_ref) < 0) - HGOTO_ERROR(H5E_FILE, H5E_BADITER, FAIL, "iteration failed(5)") - } /* end if */ - - /* Set the number of objects currently open */ - *obj_id_count_ptr = obj_id_count; - -done: - FUNC_LEAVE_NOAPI(ret_value) -} /* end H5F_get_objects() */ - - -/*------------------------------------------------------------------------- - * Function: H5F_get_objects_cb - * - * Purpose: H5F_get_objects' callback function. It verifies if an - * object is in the file, and either count it or put its ID - * on the list. - * - * Return: TRUE if the array of object IDs is filled up. - * FALSE otherwise. - * - * Programmer: Raymond Lu - * Wednesday, Dec 5, 2001 - * - *------------------------------------------------------------------------- - */ -static int -H5F_get_objects_cb(void *obj_ptr, hid_t obj_id, void *key) -{ - H5F_olist_t *olist = (H5F_olist_t *)key; /* Alias for search info */ - int ret_value = FALSE; /* Return value */ - - FUNC_ENTER_NOAPI_NOINIT - - HDassert(obj_ptr); - HDassert(olist); - - /* Count file IDs */ - if(olist->obj_type == H5I_FILE) { - if((olist->file_info.local && - (!olist->file_info.ptr.file || (olist->file_info.ptr.file && (H5F_t*)obj_ptr == olist->file_info.ptr.file) )) - || (!olist->file_info.local && - ( !olist->file_info.ptr.shared || (olist->file_info.ptr.shared && ((H5F_t*)obj_ptr)->shared == olist->file_info.ptr.shared) ))) { - /* Add the object's ID to the ID list, if appropriate */ - if(olist->obj_id_list) { - olist->obj_id_list[olist->list_index] = obj_id; - olist->list_index++; - } - - /* Increment the number of open objects */ - if(olist->obj_id_count) - (*olist->obj_id_count)++; - - /* Check if we've filled up the array. Return TRUE only if - * we have filled up the array. Otherwise return FALSE(RET_VALUE is - * preset to FALSE) because H5I_iterate needs the return value of - * FALSE to continue the iteration. */ - if(olist->max_index>0 && olist->list_index>=olist->max_index) - HGOTO_DONE(TRUE) /* Indicate that the iterator should stop */ - } - } /* end if */ - else { /* either count opened object IDs or put the IDs on the list */ - H5O_loc_t *oloc; /* Group entry info for object */ - - switch(olist->obj_type) { - case H5I_ATTR: - oloc = H5A_oloc((H5A_t *)obj_ptr); - break; - - case H5I_GROUP: - oloc = H5G_oloc((H5G_t *)obj_ptr); - break; - - case H5I_DATASET: - oloc = H5D_oloc((H5D_t *)obj_ptr); - break; - - case H5I_DATATYPE: - if(H5T_is_named((H5T_t*)obj_ptr)==TRUE) - oloc = H5T_oloc((H5T_t*)obj_ptr); - else - oloc = NULL; - break; - - case H5I_UNINIT: - case H5I_BADID: - case H5I_FILE: - case H5I_DATASPACE: - case H5I_REFERENCE: - case H5I_VFL: - case H5I_VOL: - case H5I_GENPROP_CLS: - case H5I_GENPROP_LST: - case H5I_ERROR_CLASS: - case H5I_ERROR_MSG: - case H5I_ERROR_STACK: - case H5I_NTYPES: - default: - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "unknown data object") - } /* end switch */ - - if((olist->file_info.local && - ( (!olist->file_info.ptr.file && olist->obj_type == H5I_DATATYPE && H5T_is_immutable((H5T_t *)obj_ptr) == FALSE) - || (!olist->file_info.ptr.file && olist->obj_type != H5I_DATATYPE) - || (oloc && oloc->file == olist->file_info.ptr.file))) - || (!olist->file_info.local && - ((!olist->file_info.ptr.shared && olist->obj_type == H5I_DATATYPE && H5T_is_immutable((H5T_t *)obj_ptr) == FALSE) - || (!olist->file_info.ptr.shared && olist->obj_type != H5I_DATATYPE) - || (oloc && oloc->file && oloc->file->shared == olist->file_info.ptr.shared)))) { - /* Add the object's ID to the ID list, if appropriate */ - if(olist->obj_id_list) { - olist->obj_id_list[olist->list_index] = obj_id; - olist->list_index++; - } /* end if */ - - /* Increment the number of open objects */ - if(olist->obj_id_count) - (*olist->obj_id_count)++; - - /* Check if we've filled up the array. Return TRUE only if - * we have filled up the array. Otherwise return FALSE(RET_VALUE is - * preset to FALSE) because H5I_iterate needs the return value of - * FALSE to continue iterating. */ - if(olist->max_index>0 && olist->list_index>=olist->max_index) - HGOTO_DONE(TRUE) /* Indicate that the iterator should stop */ - } /* end if */ - } /* end else */ - -done: - FUNC_LEAVE_NOAPI(ret_value) -} /* end H5F_get_objects_cb() */ - - -/*------------------------------------------------------------------------- * Function: H5Fget_vfd_handle * * Purpose: Returns a pointer to the file handle of the low-level file @@ -838,51 +277,6 @@ done: /*------------------------------------------------------------------------- - * Function: H5F_is_hdf5 - * - * Purpose: Check the file signature to detect an HDF5 file. - * - * Bugs: This function is not robust: it only uses the default file - * driver when attempting to open the file when in fact it - * should use all known file drivers. - * - * Return: Success: TRUE/FALSE - * - * Failure: Negative - * - * Programmer: Unknown - * - * Modifications: - * Robb Matzke, 1999-08-02 - * Rewritten to use the virtual file layer. - *------------------------------------------------------------------------- - */ -htri_t -H5F_is_hdf5(const char *name) -{ - H5FD_t *file = NULL; /* Low-level file struct */ - htri_t ret_value; /* Return value */ - - FUNC_ENTER_NOAPI_NOINIT - - /* Open the file at the virtual file layer */ - if(NULL == (file = H5FD_open(name, H5F_ACC_RDONLY, H5P_FILE_ACCESS_DEFAULT, HADDR_UNDEF))) - HGOTO_ERROR(H5E_IO, H5E_CANTINIT, FAIL, "unable to open file") - - /* The file is an hdf5 file if the hdf5 file signature can be found */ - ret_value = (HADDR_UNDEF != H5F_locate_signature(file, H5AC_ind_dxpl_id)); - -done: - /* Close the file */ - if(file) - if(H5FD_close(file) < 0 && ret_value >= 0) - HDONE_ERROR(H5E_IO, H5E_CANTCLOSEFILE, FAIL, "unable to close file") - - FUNC_LEAVE_NOAPI(ret_value) -} /* end H5F_is_hdf5() */ - - -/*------------------------------------------------------------------------- * Function: H5Fis_accessible * * Purpose: Check if the file can be opened with the given fapl. @@ -916,645 +310,79 @@ done: /*------------------------------------------------------------------------- - * Function: H5F_new + * Function: H5Fcreate * - * Purpose: Creates a new file object and initializes it. The - * H5Fopen and H5Fcreate functions then fill in various - * fields. If SHARED is a non-null pointer then the shared info - * to which it points has the reference count incremented. - * Otherwise a new, empty shared info struct is created and - * initialized with the specified file access property list. + * 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. * - * Errors: + * 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: Success: Ptr to a new file struct. + * See also: H5Fpublic.h for the list of supported flags. H5Ppublic.h for + * the list of file creation and file access properties. * - * Failure: NULL + * Return: Success: A file ID * - * Programmer: Robb Matzke - * matzke@llnl.gov - * Jul 18 1997 + * Failure: FAIL + * + * Programmer: Unknown * *------------------------------------------------------------------------- */ -static H5F_t * -H5F_new(H5F_file_t *shared, hid_t fcpl_id, hid_t fapl_id, H5FD_t *lf) +hid_t +H5Fcreate(const char *filename, unsigned flags, hid_t fcpl_id, hid_t fapl_id) { - H5F_t *f = NULL, *ret_value; + hid_t ret_value; /*return value */ + + FUNC_ENTER_API(FAIL) + H5TRACE4("i", "*sIuii", filename, flags, fcpl_id, fapl_id); + + /* Check/fix arguments */ + if(!filename || !*filename) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid file name") + /* In this routine, we only accept the following flags: + * H5F_ACC_EXCL, H5F_ACC_TRUNC and H5F_ACC_DEBUG + */ + if(flags & ~(H5F_ACC_EXCL | H5F_ACC_TRUNC | H5F_ACC_DEBUG)) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid flags") + /* The H5F_ACC_EXCL and H5F_ACC_TRUNC flags are mutually exclusive */ + if((flags & H5F_ACC_EXCL) && (flags & H5F_ACC_TRUNC)) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "mutually exclusive flags for file creation") - FUNC_ENTER_NOAPI_NOINIT + /* Check file creation property list */ + if(H5P_DEFAULT == fcpl_id) + fcpl_id = H5P_FILE_CREATE_DEFAULT; + else + if(TRUE != H5P_isa_class(fcpl_id, H5P_FILE_CREATE)) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not file create property list") - if(NULL == (f = H5FL_CALLOC(H5F_t))) - HGOTO_ERROR(H5E_FILE, H5E_NOSPACE, NULL, "can't allocate top file structure") - f->file_id = -1; + /* Check the file access property list */ + if(H5P_DEFAULT == fapl_id) + fapl_id = H5P_FILE_ACCESS_DEFAULT; + else + if(TRUE != H5P_isa_class(fapl_id, H5P_FILE_ACCESS)) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not file access property list") - if(shared) { - HDassert(lf == NULL); - f->shared = shared; - } /* end if */ - else { - H5P_genplist_t *plist; /* Property list */ - unsigned efc_size; /* External file cache size */ - size_t u; /* Local index variable */ - - HDassert(lf != NULL); - if(NULL == (f->shared = H5FL_CALLOC(H5F_file_t))) - HGOTO_ERROR(H5E_FILE, H5E_NOSPACE, NULL, "can't allocate shared file structure") - - f->shared->sohm_addr = HADDR_UNDEF; - f->shared->sohm_vers = HDF5_SHAREDHEADER_VERSION; - for(u = 0; u < NELMTS(f->shared->fs_addr); u++) - f->shared->fs_addr[u] = HADDR_UNDEF; - f->shared->accum.loc = HADDR_UNDEF; - f->shared->lf = lf; - - /* - * Copy the file creation and file access property lists into the - * new file handle. We do this early because some values might need - * to change as the file is being opened. - */ - if(NULL == (plist = (H5P_genplist_t *)H5I_object(fcpl_id))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "not property list") - f->shared->fcpl_id = H5P_copy_plist(plist, FALSE); - - /* Get the FCPL values to cache */ - if(H5P_get(plist, H5F_CRT_ADDR_BYTE_NUM_NAME, &f->shared->sizeof_addr) < 0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't get byte number for address") - if(H5P_get(plist, H5F_CRT_OBJ_BYTE_NUM_NAME, &f->shared->sizeof_size) < 0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't get byte number for object size") - if(H5P_get(plist, H5F_CRT_SHMSG_NINDEXES_NAME, &f->shared->sohm_nindexes) < 0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't get number of SOHM indexes") - HDassert(f->shared->sohm_nindexes < 255); - if(H5P_get(plist, H5F_CRT_FILE_SPACE_STRATEGY_NAME, &f->shared->fs_strategy) < 0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't get file space strategy") - if(H5P_get(plist, H5F_CRT_FREE_SPACE_THRESHOLD_NAME, &f->shared->fs_threshold) < 0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't get free-space section threshold") - - /* Get the FAPL values to cache */ - if(NULL == (plist = (H5P_genplist_t *)H5I_object(fapl_id))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "not file access property list") - if(H5P_get(plist, H5F_ACS_META_CACHE_INIT_CONFIG_NAME, &(f->shared->mdc_initCacheCfg)) < 0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't get initial metadata cache resize config") - if(H5P_get(plist, H5F_ACS_DATA_CACHE_NUM_SLOTS_NAME, &(f->shared->rdcc_nslots)) < 0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't get data cache number of slots") - if(H5P_get(plist, H5F_ACS_DATA_CACHE_BYTE_SIZE_NAME, &(f->shared->rdcc_nbytes)) < 0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't get data cache byte size") - if(H5P_get(plist, H5F_ACS_PREEMPT_READ_CHUNKS_NAME, &(f->shared->rdcc_w0)) < 0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't get preempt read chunk") - if(H5P_get(plist, H5F_ACS_ALIGN_THRHD_NAME, &(f->shared->threshold)) < 0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't get alignment threshold") - if(H5P_get(plist, H5F_ACS_ALIGN_NAME, &(f->shared->alignment)) < 0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't get alignment") - if(H5P_get(plist, H5F_ACS_GARBG_COLCT_REF_NAME,&(f->shared->gc_ref)) < 0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't get garbage collect reference") - if(H5P_get(plist, H5F_ACS_SIEVE_BUF_SIZE_NAME, &(f->shared->sieve_buf_size)) < 0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't get sieve buffer size") - if(H5P_get(plist, H5F_ACS_LATEST_FORMAT_NAME, &(f->shared->latest_format)) < 0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't get 'latest format' flag") - if(H5P_get(plist, H5F_ACS_META_BLOCK_SIZE_NAME, &(f->shared->meta_aggr.alloc_size)) < 0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't get metadata cache size") - f->shared->meta_aggr.feature_flag = H5FD_FEAT_AGGREGATE_METADATA; - if(H5P_get(plist, H5F_ACS_SDATA_BLOCK_SIZE_NAME, &(f->shared->sdata_aggr.alloc_size)) < 0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't get 'small data' cache size") - f->shared->sdata_aggr.feature_flag = H5FD_FEAT_AGGREGATE_SMALLDATA; - if(H5P_get(plist, H5F_ACS_EFC_SIZE_NAME, &efc_size) < 0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't get elink file cache size") - if(efc_size > 0) - if(NULL == (f->shared->efc = H5F_efc_create(efc_size))) - HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, NULL, "can't create external file cache") - - /* Get the VFD values to cache */ - f->shared->maxaddr = H5FD_get_maxaddr(lf); - if(!H5F_addr_defined(f->shared->maxaddr)) - HGOTO_ERROR(H5E_FILE, H5E_BADVALUE, NULL, "bad maximum address from VFD") - if(H5FD_get_feature_flags(lf, &f->shared->feature_flags) < 0) - HGOTO_ERROR(H5E_FILE, H5E_CANTGET, NULL, "can't get feature flags from VFD") - if(H5FD_get_fs_type_map(lf, f->shared->fs_type_map) < 0) - HGOTO_ERROR(H5E_FILE, H5E_CANTGET, NULL, "can't get free space type mapping from VFD") - if(H5MF_init_merge_flags(f) < 0) - HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, NULL, "problem initializing free space merge flags") - f->shared->tmp_addr = f->shared->maxaddr; - /* Disable temp. space allocation for parallel I/O (for now) */ - /* (When we've arranged to have the relocated metadata addresses (and - * sizes) broadcast during the "end of epoch" metadata operations, - * this can be enabled - QAK) - */ - /* (This should be disabled when the metadata journaling branch is - * merged into the trunk and journaling is enabled, at least until - * we make it work. - QAK) - */ - f->shared->use_tmp_space = !H5F_HAS_FEATURE(f, H5FD_FEAT_HAS_MPI); - - /* - * Create a metadata cache with the specified number of elements. - * The cache might be created with a different number of elements and - * the access property list should be updated to reflect that. - */ - if(H5AC_create(f, &(f->shared->mdc_initCacheCfg)) < 0) - HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, NULL, "unable to create metadata cache") - - /* Create the file's "open object" information */ - if(H5FO_create(f) < 0) - HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, NULL, "unable to create open object data structure") - - /* Add new "shared" struct to list of open files */ - if(H5F_sfile_add(f->shared) < 0) - HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, NULL, "unable to append to list of open files") - } /* end else */ - - f->shared->nrefs++; - - /* Create the file's "top open object" information */ - if(H5FO_top_create(f) < 0) - HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, NULL, "unable to create open object data structure") - - /* Set return value */ - ret_value = f; + /* + * Create a new file or truncate an existing file. + */ + if((ret_value = H5VL_file_create(filename, flags, fcpl_id, fapl_id, H5_REQUEST_NULL)) < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, FAIL, "unable to create file") done: - if(!ret_value && f) { - if(!shared) - f->shared = H5FL_FREE(H5F_file_t, f->shared); - f = H5FL_FREE(H5F_t, f); - } /* end if */ - - FUNC_LEAVE_NOAPI(ret_value) -} /* end H5F_new() */ + FUNC_LEAVE_API(ret_value) +} /* end H5Fcreate() */ /*------------------------------------------------------------------------- - * Function: H5F_dest - * - * Purpose: Destroys a file structure. This function flushes the cache - * but doesn't do any other cleanup other than freeing memory - * for the file struct. The shared info for the file is freed - * only when its reference count reaches zero. - * - * Return: Non-negative on success/Negative on failure - * - * Programmer: Robb Matzke - * matzke@llnl.gov - * Jul 18 1997 - * - *------------------------------------------------------------------------- - */ -static herr_t -H5F_dest(H5F_t *f, hid_t dxpl_id, hbool_t flush) -{ - herr_t ret_value = SUCCEED; /* Return value */ - - FUNC_ENTER_NOAPI_NOINIT - - /* Sanity check */ - HDassert(f); - HDassert(f->shared); - - if(1 == f->shared->nrefs) { - /* Flush at this point since the file will be closed. - * Only try to flush the file if it was opened with write access, and if - * the caller requested a flush. - */ - if((f->shared->flags & H5F_ACC_RDWR) && flush) - if(H5F_flush(f, dxpl_id, TRUE) < 0) - HDONE_ERROR(H5E_CACHE, H5E_CANTFLUSH, FAIL, "unable to flush cache") - - /* Release the external file cache */ - if(f->shared->efc) { - if(H5F_efc_destroy(f->shared->efc) < 0) - HDONE_ERROR(H5E_FILE, H5E_CANTRELEASE, FAIL, "can't destroy external file cache") - f->shared->efc = NULL; - } /* end if */ - - /* Release objects that depend on the superblock being initialized */ - if(f->shared->sblock) { - /* Shutdown file free space manager(s) */ - /* (We should release the free space information now (before truncating - * the file and before the metadata cache is shut down) since the - * free space manager is holding some data structures in memory - * and also because releasing free space can shrink the file's - * 'eoa' value) - */ - if(H5F_ACC_RDWR & H5F_INTENT(f)) { - if(H5MF_close(f, dxpl_id) < 0) - /* Push error, but keep going*/ - HDONE_ERROR(H5E_FILE, H5E_CANTRELEASE, FAIL, "can't release file free space info") - } /* end if */ - - /* Unpin the superblock, since we're about to destroy the cache */ - if(H5AC_unpin_entry(f->shared->sblock) < 0) - /* Push error, but keep going*/ - HDONE_ERROR(H5E_FSPACE, H5E_CANTUNPIN, FAIL, "unable to unpin superblock") - f->shared->sblock = NULL; - } /* end if */ - - /* Remove shared file struct from list of open files */ - if(H5F_sfile_remove(f->shared) < 0) - /* Push error, but keep going*/ - HDONE_ERROR(H5E_FILE, H5E_CANTRELEASE, FAIL, "problems closing file") - - /* Shutdown the metadata cache */ - if(H5AC_dest(f, dxpl_id)) - /* Push error, but keep going*/ - HDONE_ERROR(H5E_FILE, H5E_CANTRELEASE, FAIL, "problems closing file") - - /* - * Do not close the root group since we didn't count it, but free - * the memory associated with it. - */ - if(f->shared->root_grp) { - /* Free the root group */ - if(H5G_root_free(f->shared->root_grp) < 0) - /* Push error, but keep going*/ - HDONE_ERROR(H5E_FILE, H5E_CANTRELEASE, FAIL, "problems closing file") - f->shared->root_grp = NULL; - } /* end if */ - - /* Destroy other components of the file */ - if(H5F_accum_reset(f, dxpl_id, TRUE) < 0) - /* Push error, but keep going*/ - HDONE_ERROR(H5E_FILE, H5E_CANTRELEASE, FAIL, "problems closing file") - if(H5FO_dest(f) < 0) - /* Push error, but keep going*/ - HDONE_ERROR(H5E_FILE, H5E_CANTRELEASE, FAIL, "problems closing file") - f->shared->cwfs = (struct H5HG_heap_t **)H5MM_xfree(f->shared->cwfs); - if(H5G_node_close(f) < 0) - /* Push error, but keep going*/ - HDONE_ERROR(H5E_FILE, H5E_CANTRELEASE, FAIL, "problems closing file") - - /* Destroy file creation properties */ - if(H5I_GENPROP_LST != H5I_get_type(f->shared->fcpl_id)) - /* Push error, but keep going*/ - HDONE_ERROR(H5E_FILE, H5E_BADTYPE, FAIL, "not a property list") - if(H5I_dec_ref(f->shared->fcpl_id) < 0) - /* Push error, but keep going*/ - HDONE_ERROR(H5E_FILE, H5E_CANTDEC, FAIL, "can't close property list") - - /* Only truncate the file on an orderly close, with write-access */ - if(f->closing && (H5F_ACC_RDWR & H5F_INTENT(f))) { - /* Truncate the file to the current allocated size */ - if(H5FD_truncate(f->shared->lf, dxpl_id, (unsigned)TRUE) < 0) - /* Push error, but keep going*/ - HDONE_ERROR(H5E_FILE, H5E_WRITEERROR, FAIL, "low level truncate failed") - } /* end if */ - - /* Close the file */ - if(H5FD_close(f->shared->lf) < 0) - /* Push error, but keep going*/ - HDONE_ERROR(H5E_FILE, H5E_CANTCLOSEFILE, FAIL, "unable to close file") - - /* Free mount table */ - f->shared->mtab.child = (H5F_mount_t *)H5MM_xfree(f->shared->mtab.child); - f->shared->mtab.nalloc = 0; - - /* Destroy shared file struct */ - f->shared = (H5F_file_t *)H5FL_FREE(H5F_file_t, f->shared); - - } else if(f->shared->nrefs > 0) { - /* - * There are other references to the shared part of the file. - * Only decrement the reference count. - */ - --f->shared->nrefs; - } - - /* 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); - f->extpath = (char *)H5MM_xfree(f->extpath); - if(H5FO_top_dest(f) < 0) - HDONE_ERROR(H5E_FILE, H5E_CANTINIT, FAIL, "problems closing file") - f->shared = NULL; - f = H5FL_FREE(H5F_t, f); - - FUNC_LEAVE_NOAPI(ret_value) -} /* end H5F_dest() */ - - -/*------------------------------------------------------------------------- - * Function: H5F_open - * - * Purpose: Opens (or creates) a file. This function understands the - * following flags which are similar in nature to the Posix - * open(2) flags. - * - * H5F_ACC_RDWR: Open with read/write access. If the file is - * currently open for read-only access then it - * will be reopened. Absence of this flag - * implies read-only access. - * - * H5F_ACC_CREAT: Create a new file if it doesn't exist yet. - * The permissions are 0666 bit-wise AND with - * the current umask. H5F_ACC_WRITE must also - * be specified. - * - * H5F_ACC_EXCL: This flag causes H5F_open() to fail if the - * file already exists. - * - * H5F_ACC_TRUNC: The file is truncated and a new HDF5 superblock - * is written. This operation will fail if the - * file is already open. - * - * Unlinking the file name from the group directed graph while - * the file is opened causes the file to continue to exist but - * one will not be able to upgrade the file from read-only - * access to read-write access by reopening it. Disk resources - * for the file are released when all handles to the file are - * closed. NOTE: This paragraph probably only applies to Unix; - * deleting the file name in other OS's has undefined results. - * - * The CREATE_PARMS argument is optional. A null pointer will - * cause the default file creation parameters to be used. - * - * The ACCESS_PARMS argument is optional. A null pointer will - * cause the default file access parameters to be used. - * - * Return: Success: A new file pointer. - * Failure: NULL - * - * Programmer: Robb Matzke - * Tuesday, September 23, 1997 - * - *------------------------------------------------------------------------- - */ -H5F_t * -H5F_open(const char *name, unsigned flags, hid_t fcpl_id, hid_t fapl_id, - hid_t dxpl_id) -{ - H5F_t *file = NULL; /*the success return value */ - H5F_file_t *shared = NULL; /*shared part of `file' */ - H5FD_t *lf = NULL; /*file driver part of `shared' */ - unsigned tent_flags; /*tentative flags */ - H5FD_class_t *drvr; /*file driver class info */ - H5P_genplist_t *a_plist; /*file access property list */ - H5F_close_degree_t fc_degree; /*file close degree */ - H5F_t *ret_value; /*actual return value */ - - FUNC_ENTER_NOAPI(NULL) - - /* - * 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. - * Otherwise it is the application's responsibility to never open the - * same file more than once at a time. - */ - if(NULL == (drvr = H5FD_get_class(fapl_id))) - HGOTO_ERROR(H5E_FILE, H5E_CANTGET, NULL, "unable to retrieve VFL class") - - /* - * Opening a file is a two step process. First we try to open the - * file in a way which doesn't affect its state (like not truncating - * or creating it) so we can compare it with files that are already - * open. If that fails then we try again with the full set of flags - * (only if they're different than the original failed attempt). - * However, if the file driver can't distinquish between files then - * there's no reason to open the file tentatively because it's the - * application's responsibility to prevent this situation (there's no - * way for us to detect it here anyway). - */ - if(drvr->cmp) - tent_flags = flags & ~(H5F_ACC_CREAT|H5F_ACC_TRUNC|H5F_ACC_EXCL); - else - tent_flags = flags; - - if(NULL == (lf = H5FD_open(name, tent_flags, fapl_id, HADDR_UNDEF))) { - if(tent_flags == flags) { -#ifndef H5_USING_MEMCHECKER - time_t mytime = HDtime(NULL); - - HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, "unable to open file: time = %s, name = '%s', tent_flags = %x", HDctime(&mytime), name, tent_flags) -#else /* H5_USING_MEMCHECKER */ - HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, "unable to open file: name = '%s', tent_flags = %x", name, tent_flags) -#endif /* H5_USING_MEMCHECKER */ - } /* end if */ - H5E_clear_stack(NULL); - tent_flags = flags; - if(NULL == (lf = H5FD_open(name, tent_flags, fapl_id, HADDR_UNDEF))) { -#ifndef H5_USING_MEMCHECKER - time_t mytime = HDtime(NULL); - - HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, "unable to open file: time = %s, name = '%s', tent_flags = %x", HDctime(&mytime), name, tent_flags) -#else /* H5_USING_MEMCHECKER */ - HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, "unable to open file: name = '%s', tent_flags = %x", name, tent_flags) -#endif /* H5_USING_MEMCHECKER */ - } /* end if */ - } /* end if */ - - /* Is the file already open? */ - if((shared = H5F_sfile_search(lf)) != NULL) { - /* - * 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 - * exists), or if the new request adds write access (since the - * readers don't expect the file to change under them). - */ - if(H5FD_close(lf) < 0) - HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, "unable to close low-level file info") - if(flags & H5F_ACC_TRUNC) - HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, "unable to truncate a file which is already open") - if(flags & H5F_ACC_EXCL) - HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, "file exists") - if((flags & H5F_ACC_RDWR) && 0 == (shared->flags & H5F_ACC_RDWR)) - HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, "file is already open for read-only") - - /* Allocate new "high-level" file struct */ - if((file = H5F_new(shared, fcpl_id, fapl_id, NULL)) == NULL) - HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, "unable to create new file object") - } /* end if */ - else { - /* Check if tentative open was good enough */ - if(flags != tent_flags) { - /* - * This file is not yet open by the library and the flags we used to - * open it are different than the desired flags. Close the tentative - * file and open it for real. - */ - if(H5FD_close(lf) < 0) { - file = NULL; /*to prevent destruction of wrong file*/ - HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, "unable to close low-level file info") - } /* end if */ - if(NULL == (lf = H5FD_open(name, flags, fapl_id, HADDR_UNDEF))) { - file = NULL; /*to prevent destruction of wrong file*/ - HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, "unable to open file") - } /* end if */ - } /* end if */ - - if(NULL == (file = H5F_new(NULL, fcpl_id, fapl_id, lf))) - HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, "unable to create new file object") - file->shared->flags = flags; - } /* end else */ - - /* Short cuts */ - shared = file->shared; - lf = shared->lf; - - /* - * The intent at the top level file struct are not necessarily the same as - * the flags at the bottom. The top level describes how the file can be - * accessed through the HDF5 library. The bottom level describes how the - * file can be accessed through the C library. - */ - file->intent = flags; - file->open_name = H5MM_xstrdup(name); - - /* - * Read or write the file superblock, depending on whether the file is - * empty or not. - */ - if(0 == H5FD_get_eof(lf) && (flags & H5F_ACC_RDWR)) { - /* - * We've just opened a fresh new file (or truncated one). We need - * to create & write the superblock. - */ - - /* Initialize information about the superblock and allocate space for it */ - /* (Writes superblock extension messages, if there are any) */ - if(H5F_super_init(file, dxpl_id) < 0) - HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, NULL, "unable to allocate file superblock") - - /* Create and open the root group */ - /* (This must be after the space for the superblock is allocated in - * the file, since the superblock must be at offset 0) - */ - if(H5G_mkroot(file, dxpl_id, TRUE) < 0) - HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, NULL, "unable to create/open root group") - } else if (1 == shared->nrefs) { - /* Read the superblock if it hasn't been read before. */ - if(H5F_super_read(file, dxpl_id) < 0) - HGOTO_ERROR(H5E_FILE, H5E_READERROR, NULL, "unable to read superblock") - - /* Open the root group */ - if(H5G_mkroot(file, dxpl_id, FALSE) < 0) - HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, "unable to read root group") - } /* end if */ - - /* Get the file access property list, for future queries */ - if(NULL == (a_plist = (H5P_genplist_t *)H5I_object(fapl_id))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "not file access property list") - - /* Store a pointer to the VOL plugin in the file struct */ - if(H5P_get(a_plist, H5F_ACS_VOL_NAME, &(file->vol_cls)) < 0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't get vol plugin") - - /* - * Decide the file close degree. If it's the first time to open the - * file, set the degree to access property list value; if it's the - * second time or later, verify the access property list value matches - * the degree in shared file structure. - */ - if(H5P_get(a_plist, H5F_ACS_CLOSE_DEGREE_NAME, &fc_degree) < 0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't get file close degree") - - if(shared->nrefs == 1) { - if(fc_degree == H5F_CLOSE_DEFAULT) - shared->fc_degree = lf->cls->fc_degree; - else - shared->fc_degree = fc_degree; - } else if(shared->nrefs > 1) { - if(fc_degree == H5F_CLOSE_DEFAULT && shared->fc_degree != lf->cls->fc_degree) - HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, NULL, "file close degree doesn't match") - if(fc_degree != H5F_CLOSE_DEFAULT && fc_degree != shared->fc_degree) - HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, NULL, "file close degree doesn't match") - } /* end if */ - - /* Formulate the absolute path for later search of target file for external links */ - if(H5_build_extpath(name, &file->extpath) < 0) - HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, NULL, "unable to build extpath") - - /* Formulate the actual file name, after following symlinks, etc. */ - if(H5F_build_actual_name(file, a_plist, name, &file->actual_name) < 0) - HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, NULL, "unable to build actual name") - - /* Success */ - ret_value = file; - -done: - if(!ret_value && file) - if(H5F_dest(file, dxpl_id, FALSE) < 0) - HDONE_ERROR(H5E_FILE, H5E_CANTCLOSEFILE, NULL, "problems closing file") - - FUNC_LEAVE_NOAPI(ret_value) -} /* end H5F_open() */ - - -/*------------------------------------------------------------------------- - * 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: FAIL - * - * Programmer: Unknown - * - *------------------------------------------------------------------------- - */ -hid_t -H5Fcreate(const char *filename, unsigned flags, hid_t fcpl_id, hid_t fapl_id) -{ - hid_t ret_value; /*return value */ - - FUNC_ENTER_API(FAIL) - H5TRACE4("i", "*sIuii", filename, flags, fcpl_id, fapl_id); - - /* Check/fix arguments */ - if(!filename || !*filename) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid file name") - /* In this routine, we only accept the following flags: - * H5F_ACC_EXCL, H5F_ACC_TRUNC and H5F_ACC_DEBUG - */ - if(flags & ~(H5F_ACC_EXCL | H5F_ACC_TRUNC | H5F_ACC_DEBUG)) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid flags") - /* The H5F_ACC_EXCL and H5F_ACC_TRUNC flags are mutually exclusive */ - if((flags & H5F_ACC_EXCL) && (flags & H5F_ACC_TRUNC)) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "mutually exclusive flags for file creation") - - /* Check file creation property list */ - if(H5P_DEFAULT == fcpl_id) - fcpl_id = H5P_FILE_CREATE_DEFAULT; - else - if(TRUE != H5P_isa_class(fcpl_id, H5P_FILE_CREATE)) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not file create property list") - - /* Check the file access property list */ - if(H5P_DEFAULT == fapl_id) - fapl_id = H5P_FILE_ACCESS_DEFAULT; - else - if(TRUE != H5P_isa_class(fapl_id, H5P_FILE_ACCESS)) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not file access property list") - - /* - * Create a new file or truncate an existing file. - */ - if((ret_value = H5VL_file_create(filename, flags, fcpl_id, fapl_id, H5_REQUEST_NULL)) < 0) - HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, FAIL, "unable to create file") - -done: - FUNC_LEAVE_API(ret_value) -} /* end H5Fcreate() */ - - -/*------------------------------------------------------------------------- - * Function: H5Fopen + * Function: H5Fopen * * Purpose: This is the primary function for accessing existing HDF5 * files. The FLAGS argument determines whether writing to an @@ -1566,918 +394,199 @@ done: * * See Also: H5Fpublic.h for a list of possible values for FLAGS. * - * Return: Success: A file ID - * - * Failure: FAIL - * - * Programmer: Unknown - * - * Modifications: - * Robb Matzke, 1997-07-18 - * File struct creation and destruction is through H5F_new() and - * H5F_dest(). Reading the root symbol table entry is done with - * H5G_decode(). - * - * Robb Matzke, 1997-09-23 - * Most of the work is now done by H5F_open() since H5Fcreate() - * and H5Fopen() originally contained almost identical code. - * - * Robb Matzke, 1998-02-18 - * Added better error checking for the flags and the file access - * property list. It used to be possible to make the library - * dump core by passing an object ID that was not a file access - * property list. - * - * Robb Matzke, 1999-08-02 - * The file access property list is passed to the H5F_open() as - * object IDs. - *------------------------------------------------------------------------- - */ -hid_t -H5Fopen(const char *filename, unsigned flags, hid_t fapl_id) -{ - hid_t ret_value; /*return value */ - - FUNC_ENTER_API(FAIL) - H5TRACE3("i", "*sIui", filename, flags, fapl_id); - - /* Check/fix arguments. */ - if(!filename || !*filename) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid file name") - /* Reject undefined flags (~H5F_ACC_PUBLIC_FLAGS) and the H5F_ACC_TRUNC & H5F_ACC_EXCL flags */ - if((flags & ~H5F_ACC_PUBLIC_FLAGS) || - (flags & H5F_ACC_TRUNC) || (flags & H5F_ACC_EXCL)) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid file open flags") - if(H5P_DEFAULT == fapl_id) - fapl_id = H5P_FILE_ACCESS_DEFAULT; - else - if(TRUE != H5P_isa_class(fapl_id, H5P_FILE_ACCESS)) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not file access property list") - - /* Open the file */ - if((ret_value = H5VL_file_open(filename, flags, fapl_id, H5_REQUEST_NULL))<0) - HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, FAIL, "unable to open file") - -done: - FUNC_LEAVE_API(ret_value) -} /* end H5Fopen() */ - - -/*------------------------------------------------------------------------- - * 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: Non-negative on success/Negative on failure - * - * Programmer: Robb Matzke - * Thursday, August 6, 1998 - * - *------------------------------------------------------------------------- - */ -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); - - if((ret_value = H5VL_file_flush(object_id, scope, H5_REQUEST_NULL)) < 0) - HGOTO_ERROR(H5E_FILE, H5E_CANTFLUSH, FAIL, "unable to flush file") - -done: - FUNC_LEAVE_API(ret_value) -} /* end H5Fflush() */ - - -/*------------------------------------------------------------------------- - * Function: H5F_flush - * - * Purpose: Flushes cached data. - * - * Return: Non-negative on success/Negative on failure - * - * Programmer: Robb Matzke - * matzke@llnl.gov - * Aug 29 1997 - * - *------------------------------------------------------------------------- - */ -herr_t -H5F_flush(H5F_t *f, hid_t dxpl_id, hbool_t closing) -{ - herr_t ret_value = SUCCEED; /* Return value */ - - FUNC_ENTER_NOAPI(FAIL) - - /* Sanity check arguments */ - HDassert(f); - - /* Flush any cached dataset storage raw data */ - if(H5D_flush(f, dxpl_id) < 0) - /* Push error, but keep going*/ - HDONE_ERROR(H5E_CACHE, H5E_CANTFLUSH, FAIL, "unable to flush dataset cache") - - /* Release any space allocated to space aggregators, so that the eoa value - * corresponds to the end of the space written to in the file. - */ - /* (needs to happen before cache flush, with superblock write, since the - * 'eoa' value is written in superblock -QAK) - */ - if(H5MF_free_aggrs(f, dxpl_id) < 0) - /* Push error, but keep going*/ - HDONE_ERROR(H5E_FILE, H5E_CANTRELEASE, FAIL, "can't release file space") - - /* Flush the entire metadata cache */ - if(H5AC_flush(f, dxpl_id) < 0) - /* Push error, but keep going*/ - HDONE_ERROR(H5E_CACHE, H5E_CANTFLUSH, FAIL, "unable to flush metadata cache") - - /* Flush out the metadata accumulator */ - if(H5F_accum_flush(f, dxpl_id) < 0) - /* Push error, but keep going*/ - HDONE_ERROR(H5E_IO, H5E_CANTFLUSH, FAIL, "unable to flush metadata accumulator") - - /* Flush file buffers to disk. */ - if(H5FD_flush(f->shared->lf, dxpl_id, closing) < 0) - /* Push error, but keep going*/ - HDONE_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "low level flush failed") - -done: - FUNC_LEAVE_NOAPI(ret_value) -} /* end H5F_flush() */ - - -/*------------------------------------------------------------------------- - * Function: H5F_close - * - * Purpose: Closes a file or causes the close operation to be pended. - * This function is called two ways: from the API it gets called - * by H5Fclose->H5I_dec_ref->H5F_close when H5I_dec_ref() - * decrements the file ID reference count to zero. The file ID - * is removed from the H5I_FILE group by H5I_dec_ref() just - * before H5F_close() is called. If there are open object - * headers then the close is pended by moving the file to the - * H5I_FILE_CLOSING ID group (the f->closing contains the ID - * assigned to file). - * - * This function is also called directly from H5O_close() when - * the last object header is closed for the file and the file - * has a pending close. - * - * Return: Non-negative on success/Negative on failure - * - * Programmer: Robb Matzke - * Tuesday, September 23, 1997 - * - *------------------------------------------------------------------------- - */ -herr_t -H5F_close(H5F_t *f) -{ - herr_t ret_value = SUCCEED; /* Return value */ - - FUNC_ENTER_NOAPI_NOINIT - - /* Sanity check */ - HDassert(f); - HDassert(f->file_id > 0); /* This routine should only be called when a file ID's ref count drops to zero */ - - /* Perform checks for "semi" file close degree here, since closing the - * file is not allowed if there are objects still open */ - if(f->shared->fc_degree == H5F_CLOSE_SEMI) { - unsigned nopen_files = 0; /* Number of open files in file/mount hierarchy */ - unsigned nopen_objs = 0; /* Number of open objects in file/mount hierarchy */ - - /* Get the number of open objects and open files on this file/mount hierarchy */ - if(H5F_mount_count_ids(f, &nopen_files, &nopen_objs) < 0) - HGOTO_ERROR(H5E_SYM, H5E_MOUNT, FAIL, "problem checking mount hierarchy") - - /* If there are no other file IDs open on this file/mount hier., but - * there are still open objects, issue an error and bail out now, - * without decrementing the file ID's reference count and triggering - * a "real" attempt at closing the file */ - if(nopen_files == 1 && nopen_objs > 0) - HGOTO_ERROR(H5E_FILE, H5E_CANTCLOSEFILE, FAIL, "can't close file, there are objects still open") - } /* end if */ - - /* Reset the file ID for this file */ - f->file_id = -1; - - /* Attempt to close the file/mount hierarchy */ - if(H5F_try_close(f) < 0) - HGOTO_ERROR(H5E_FILE, H5E_CANTCLOSEFILE, FAIL, "can't close file") - -done: - FUNC_LEAVE_NOAPI(ret_value) -} /* end H5F_close() */ - - -/*------------------------------------------------------------------------- - * Function: H5F_try_close - * - * Purpose: Attempts to close a file due to one of several actions: - * - The reference count on the file ID dropped to zero - * - The last open object was closed in the file - * - The file was unmounted - * - * Return: Non-negative on success/Negative on failure - * - * Programmer: Quincey Koziol - * Tuesday, July 19, 2005 - * - *------------------------------------------------------------------------- - */ -herr_t -H5F_try_close(H5F_t *f) -{ - unsigned nopen_files = 0; /* Number of open files in file/mount hierarchy */ - unsigned nopen_objs = 0; /* Number of open objects in file/mount hierarchy */ - herr_t ret_value = SUCCEED; /* Return value */ - - FUNC_ENTER_NOAPI_NOINIT - - /* Sanity check */ - HDassert(f); - HDassert(f->shared); - - /* Check if this file is already in the process of closing */ - if(f->closing) - HGOTO_DONE(SUCCEED) - - /* Get the number of open objects and open files on this file/mount hierarchy */ - if(H5F_mount_count_ids(f, &nopen_files, &nopen_objs) < 0) - HGOTO_ERROR(H5E_SYM, H5E_MOUNT, FAIL, "problem checking mount hierarchy") - - /* - * Close file according to close degree: - * - * H5F_CLOSE_WEAK: if there are still objects open, wait until - * they are all closed. - * H5F_CLOSE_SEMI: if there are still objects open, return fail; - * otherwise, close file. - * H5F_CLOSE_STRONG: if there are still objects open, close them - * first, then close file. - */ - switch(f->shared->fc_degree) { - case H5F_CLOSE_WEAK: - /* - * If file or object IDS are still open then delay deletion of - * resources until they have all been closed. Flush all - * caches and update the object header anyway so that failing to - * close all objects isn't a major problem. - */ - if((nopen_files + nopen_objs) > 0) - HGOTO_DONE(SUCCEED) - break; - - case H5F_CLOSE_SEMI: - /* Can leave safely if file IDs are still open on this file */ - if(nopen_files > 0) - HGOTO_DONE(SUCCEED) - - /* Sanity check: If close degree if "semi" and we have gotten this - * far and there are objects left open, bail out now */ - HDassert(nopen_files == 0 && nopen_objs == 0); - - /* If we've gotten this far (ie. there are no open objects in the file), fall through to flush & close */ - break; - - case H5F_CLOSE_STRONG: - /* If there are other open files in the hierarchy, we can leave now */ - if(nopen_files > 0) - HGOTO_DONE(SUCCEED) - - /* If we've gotten this far (ie. there are no open file IDs in the file/mount hierarchy), fall through to flush & close */ - break; - - case H5F_CLOSE_DEFAULT: - default: - HGOTO_ERROR(H5E_FILE, H5E_CANTCLOSEFILE, FAIL, "can't close file, unknown file close degree") - } /* end switch */ - - /* Mark this file as closing (prevents re-entering file shutdown code below) */ - f->closing = TRUE; - - /* If the file close degree is "strong", close all the open objects in this file */ - if(f->shared->fc_degree == H5F_CLOSE_STRONG) { - HDassert(nopen_files == 0); - - /* Forced close of all opened objects in this file */ - if(f->nopen_objs > 0) { - size_t obj_count; /* # of open objects */ - hid_t objs[128]; /* Array of objects to close */ - herr_t result; /* Local result from obj ID query */ - size_t u; /* Local index variable */ - - /* Get the list of IDs of open dataset, group, & attribute objects */ - while((result = H5F_get_obj_ids(f, H5F_OBJ_LOCAL | H5F_OBJ_DATASET | H5F_OBJ_GROUP | H5F_OBJ_ATTR, (int)(sizeof(objs) / sizeof(objs[0])), objs, FALSE, &obj_count)) <= 0 - && obj_count != 0 ) { - - /* Try to close all the open objects in this file */ - for(u = 0; u < obj_count; u++) - if(H5I_dec_ref(objs[u]) < 0) - HGOTO_ERROR(H5E_ATOM, H5E_CLOSEERROR, FAIL, "can't close object") - } /* end while */ - if(result < 0) - HGOTO_ERROR(H5E_INTERNAL, H5E_BADITER, FAIL, "H5F_get_obj_ids failed(1)") - - /* Get the list of IDs of open named datatype objects */ - /* (Do this separately from the dataset & attribute IDs, because - * they could be using one of the named datatypes and then the - * open named datatype ID will get closed twice) - */ - while((result = H5F_get_obj_ids(f, H5F_OBJ_LOCAL | H5F_OBJ_DATATYPE, (int)(sizeof(objs) / sizeof(objs[0])), objs, FALSE, &obj_count)) <= 0 - && obj_count != 0) { - - /* Try to close all the open objects in this file */ - for(u = 0; u < obj_count; u++) - if(H5I_dec_ref(objs[u]) < 0) - HGOTO_ERROR(H5E_ATOM, H5E_CLOSEERROR, FAIL, "can't close object") - } /* end while */ - if(result < 0) - HGOTO_ERROR(H5E_INTERNAL, H5E_BADITER, FAIL, "H5F_get_obj_ids failed(2)") - } /* end if */ - } /* end if */ - - /* Check if this is a child file in a mounting hierarchy & proceed up the - * hierarchy if so. - */ - if(f->parent) { - if(H5F_try_close(f->parent) < 0) - HGOTO_ERROR(H5E_FILE, H5E_CANTCLOSEFILE, FAIL, "can't close parent file") - } - /* Unmount and close each child before closing the current file. */ - if(H5F_close_mounts(f) < 0) - HGOTO_ERROR(H5E_FILE, H5E_CANTCLOSEFILE, FAIL, "can't unmount child files") - - /* If there is more than one reference to the shared file struct and the - * file has an external file cache, we should see if it can be closed. This - * can happen if a cycle is formed with external file caches */ - if(f->shared->efc && (f->shared->nrefs > 1)) - if(H5F_efc_try_close(f) < 0) - HGOTO_ERROR(H5E_FILE, H5E_CANTRELEASE, FAIL, "can't attempt to close EFC") - - /* Delay flush until the shared file struct is closed, in H5F_dest. If the - * application called H5Fclose, it would have been flushed in that function - * (unless it will have been flushed in H5F_dest anyways). */ - - /* - * Destroy the H5F_t struct and decrement the reference count for the - * shared H5F_file_t struct. If the reference count for the H5F_file_t - * struct reaches zero then destroy it also. - */ - if(H5F_dest(f, H5AC_dxpl_id, TRUE) < 0) - HGOTO_ERROR(H5E_FILE, H5E_CANTCLOSEFILE, FAIL, "problems closing file") - -done: - FUNC_LEAVE_NOAPI(ret_value) -} /* end H5F_try_close() */ - - -/*------------------------------------------------------------------------- - * Function: H5Fclose - * - * Purpose: This function closes the file specified by FILE_ID by - * flushing all data to storage, and terminating access to the - * file through FILE_ID. If objects (e.g., datasets, groups, - * etc.) are open in the file then the underlying storage is not - * closed until those objects are closed; however, all data for - * the file and the open objects is flushed. - * - * Return: Success: Non-negative - * - * Failure: Negative - * - * Programmer: Robb Matzke - * Saturday, February 20, 1999 - * - * Modifications: - * - *------------------------------------------------------------------------- - */ -herr_t -H5Fclose(hid_t file_id) -{ - herr_t ret_value = SUCCEED; - - FUNC_ENTER_API(FAIL) - H5TRACE1("e", "i", file_id); - - /* Close the file */ - if((ret_value = H5VL_file_close(file_id, H5_REQUEST_NULL)) < 0) - HGOTO_ERROR(H5E_FILE, H5E_CANTCLOSEFILE, FAIL, "unable to close file") - -done: - FUNC_LEAVE_API(ret_value) -} /* end H5Fclose() */ - - -/*------------------------------------------------------------------------- - * Function: H5Freopen - * - * Purpose: Reopen a file. The new file handle which is returned points - * to the same file as the specified file handle. Both handles - * share caches and other information. The only difference - * between the handles is that the new handle is not mounted - * anywhere and no files are mounted on it. - * - * Return: Success: New file ID - * - * Failure: FAIL - * - * Programmer: Robb Matzke - * Friday, October 16, 1998 - * - * Modifications: - * Quincey Koziol, May 14, 2002 - * Keep old file's read/write intent in reopened file. - * - *------------------------------------------------------------------------- - */ -hid_t -H5Freopen(hid_t file_id) -{ - hid_t ret_value; - - FUNC_ENTER_API(FAIL) - H5TRACE1("i", "i", file_id); - - if(H5VL_file_optional(file_id, H5VL_FILE_REOPEN, H5_REQUEST_NULL, &ret_value) < 0) - HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, FAIL, "unable to reopen file") - -done: - FUNC_LEAVE_API(ret_value) -} /* end H5Freopen() */ - - -/*------------------------------------------------------------------------- - * Function: H5F_reopen - * - * Purpose: Reopen a file. The new file handle which is returned points - * to the same file as the specified file handle. Both handles - * share caches and other information. The only difference - * between the handles is that the new handle is not mounted - * anywhere and no files are mounted on it. - * - * Return: Success: New file ID - * - * Failure: FAIL - * - * Programmer: Robb Matzke - * Friday, October 16, 1998 - * - * Modifications: - * Quincey Koziol, May 14, 2002 - * Keep old file's read/write intent in reopened file. - * - *------------------------------------------------------------------------- - */ -hid_t -H5F_reopen(H5F_t *f) -{ - H5F_t *new_file = NULL; - hid_t ret_value; - - FUNC_ENTER_NOAPI_NOINIT - - /* Get a new "top level" file struct, sharing the same "low level" file struct */ - if(NULL == (new_file = H5F_new(f->shared, H5P_FILE_CREATE_DEFAULT, - H5P_FILE_ACCESS_DEFAULT, NULL))) - HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, FAIL, "unable to reopen file") - - /* Keep old file's read/write intent in new file */ - new_file->intent = f->intent; - /* Duplicate old file's names */ - new_file->open_name = H5MM_xstrdup(f->open_name); - new_file->actual_name = H5MM_xstrdup(f->actual_name); - - if((ret_value = H5I_register(H5I_FILE, new_file, TRUE)) < 0) - HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL, "unable to atomize file handle") - - /* Keep this ID in file object structure */ - new_file->file_id = ret_value; - -done: - if(ret_value < 0 && new_file) - if(H5F_dest(new_file, H5AC_dxpl_id, FALSE) < 0) - HDONE_ERROR(H5E_FILE, H5E_CANTCLOSEFILE, FAIL, "can't close file") - - FUNC_LEAVE_NOAPI(ret_value) -} /* end H5F_reopen() */ - - -/*------------------------------------------------------------------------- - * Function: H5Fget_intent - * - * Purpose: Public API to retrieve the file's 'intent' flags passed - * during H5Fopen() - * - * Return: Non-negative on success/negative on failure - * - * Programmer: James Laird - * August 23, 2006 - * - *------------------------------------------------------------------------- - */ -herr_t -H5Fget_intent(hid_t file_id, unsigned *intent_flags) -{ - herr_t ret_value = SUCCEED; - - FUNC_ENTER_API(FAIL) - H5TRACE2("e", "i*Iu", file_id, intent_flags); - - /* If no intent flags were passed in, exit quietly */ - if(intent_flags) { - if((ret_value = H5VL_file_get(file_id, H5VL_FILE_GET_INTENT, H5_REQUEST_NULL, intent_flags)) < 0) - HGOTO_ERROR(H5E_INTERNAL, H5E_CANTGET, FAIL, "unable to get file intent") - } - -done: - FUNC_LEAVE_API(ret_value) -} /* end H5Fget_intent() */ - - -/*------------------------------------------------------------------------- - * Function: H5F_get_id - * - * Purpose: Get the file ID, incrementing it, or "resurrecting" it as - * appropriate. - * - * Return: Non-negative on success/Negative on failure - * - * Programmer: Raymond Lu - * Oct 29, 2003 - * - *------------------------------------------------------------------------- - */ -hid_t -H5F_get_id(H5F_t *file, hbool_t app_ref) -{ - hid_t ret_value; - - FUNC_ENTER_NOAPI_NOINIT - - HDassert(file); - - if(file->file_id == -1) { - /* Get an atom for the file */ - if((file->file_id = H5I_register(H5I_FILE, file, app_ref)) < 0) - HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL, "unable to atomize file") - - /* attach VOL information to the ID */ - if (H5I_register_aux(file->file_id, file->vol_cls, (H5I_free_t)H5VL_close) < 0) - HGOTO_ERROR(H5E_VOL, H5E_CANTINIT, FAIL, "can't attach vol info to ID") - } else { - /* Increment reference count on atom. */ - if(H5I_inc_ref(file->file_id, app_ref) < 0) - HGOTO_ERROR(H5E_ATOM, H5E_CANTSET, FAIL, "incrementing file ID failed") - } /* end else */ - - ret_value = file->file_id; - -done: - FUNC_LEAVE_NOAPI(ret_value) -} /* end H5F_get_id() */ - - -/*------------------------------------------------------------------------- - * Function: H5F_incr_nopen_objs - * - * Purpose: Increment the number of open objects for a file. - * - * Return: Success: The number of open objects, after the increment - * - * Failure: (can't happen) - * - * Programmer: Quincey Koziol - * koziol@hdfgroup.org - * Mar 6 2007 - * - *------------------------------------------------------------------------- - */ -unsigned -H5F_incr_nopen_objs(H5F_t *f) -{ - /* Use FUNC_ENTER_NOAPI_NOINIT_NOERR here to avoid performance issues */ - FUNC_ENTER_NOAPI_NOINIT_NOERR - - HDassert(f); - - FUNC_LEAVE_NOAPI(++f->nopen_objs) -} /* end H5F_incr_nopen_objs() */ - - -/*------------------------------------------------------------------------- - * Function: H5F_decr_nopen_objs - * - * Purpose: Decrement the number of open objects for a file. - * - * Return: Success: The number of open objects, after the decrement - * - * Failure: (can't happen) - * - * Programmer: Quincey Koziol - * koziol@hdfgroup.org - * Mar 6 2007 - * - *------------------------------------------------------------------------- - */ -unsigned -H5F_decr_nopen_objs(H5F_t *f) -{ - /* Use FUNC_ENTER_NOAPI_NOINIT_NOERR here to avoid performance issues */ - FUNC_ENTER_NOAPI_NOINIT_NOERR - - HDassert(f); - - FUNC_LEAVE_NOAPI(--f->nopen_objs) -} /* end H5F_decr_nopen_objs() */ - - -/*------------------------------------------------------------------------- - * Function: H5F_build_actual_name - * - * Purpose: Retrieve the name of a file, after following symlinks, etc. + * Return: Success: A file ID + * + * Failure: FAIL + * + * Programmer: Unknown * - * Note: Currently only working for "POSIX I/O compatible" VFDs + * Modifications: + * Robb Matzke, 1997-07-18 + * File struct creation and destruction is through H5F_new() and + * H5F_dest(). Reading the root symbol table entry is done with + * H5G_decode(). * - * Return: Success: 0 - * Failure: -1 + * Robb Matzke, 1997-09-23 + * Most of the work is now done by H5F_open() since H5Fcreate() + * and H5Fopen() originally contained almost identical code. * - * Programmer: Quincey Koziol - * November 25, 2009 + * Robb Matzke, 1998-02-18 + * Added better error checking for the flags and the file access + * property list. It used to be possible to make the library + * dump core by passing an object ID that was not a file access + * property list. * + * Robb Matzke, 1999-08-02 + * The file access property list is passed to the H5F_open() as + * object IDs. *------------------------------------------------------------------------- */ -static herr_t -H5F_build_actual_name(const H5F_t *f, const H5P_genplist_t *fapl, const char *name, - char **actual_name/*out*/) +hid_t +H5Fopen(const char *filename, unsigned flags, hid_t fapl_id) { - hid_t new_fapl_id = -1; /* ID for duplicated FAPL */ - herr_t ret_value = SUCCEED; /* Return value */ - - FUNC_ENTER_NOAPI_NOINIT + hid_t ret_value; /*return value */ - /* Sanity check */ - HDassert(f); - HDassert(fapl); - HDassert(name); - HDassert(actual_name); + FUNC_ENTER_API(FAIL) + H5TRACE3("i", "*sIui", filename, flags, fapl_id); - /* Clear actual name pointer to begin with */ - *actual_name = NULL; + /* Check/fix arguments. */ + if(!filename || !*filename) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid file name") + /* Reject undefined flags (~H5F_ACC_PUBLIC_FLAGS) and the H5F_ACC_TRUNC & H5F_ACC_EXCL flags */ + if((flags & ~H5F_ACC_PUBLIC_FLAGS) || + (flags & H5F_ACC_TRUNC) || (flags & H5F_ACC_EXCL)) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid file open flags") + if(H5P_DEFAULT == fapl_id) + fapl_id = H5P_FILE_ACCESS_DEFAULT; + else + if(TRUE != H5P_isa_class(fapl_id, H5P_FILE_ACCESS)) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not file access property list") -/* Assume that if the OS can't create symlinks, that we don't need to worry - * about resolving them either. -QAK - */ -#ifdef H5_HAVE_SYMLINK - /* Check for POSIX I/O compatible file handle */ - if(H5F_HAS_FEATURE(f, H5FD_FEAT_POSIX_COMPAT_HANDLE)) { - h5_stat_t lst; /* Stat info from lstat() call */ - - /* Call lstat() on the file's name */ - if(HDlstat(name, &lst) < 0) - HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "can't retrieve stat info for file") - - /* Check for symbolic link */ - if(S_IFLNK == (lst.st_mode & S_IFMT)) { - H5P_genplist_t *new_fapl; /* Duplicated FAPL */ - int *fd; /* POSIX I/O file descriptor */ - h5_stat_t st; /* Stat info from stat() call */ - h5_stat_t fst; /* Stat info from fstat() call */ - char realname[PATH_MAX]; /* Fully resolved path name of file */ - hbool_t want_posix_fd; /* Flag for retrieving file descriptor from VFD */ - - /* Perform a sanity check that the file or link wasn't switched - * between when we opened it and when we called lstat(). This is - * according to the security best practices for lstat() documented - * here: https://www.securecoding.cert.org/confluence/display/seccode/POS35-C.+Avoid+race+conditions+while+checking+for+the+existence+of+a+symbolic+link - */ - - /* Copy the FAPL object to modify */ - if((new_fapl_id = H5P_copy_plist(fapl, FALSE)) < 0) - HGOTO_ERROR(H5E_FILE, H5E_CANTCOPY, FAIL, "unable to copy file access property list") - if(NULL == (new_fapl = (H5P_genplist_t *)H5I_object(new_fapl_id))) - HGOTO_ERROR(H5E_FILE, H5E_CANTCREATE, FAIL, "can't get property list") - - /* Set the character encoding on the new property list */ - want_posix_fd = TRUE; - if(H5P_set(new_fapl, H5F_ACS_WANT_POSIX_FD_NAME, &want_posix_fd) < 0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set character encoding") - - /* Retrieve the file handle */ - if(H5F_get_vfd_handle(f, new_fapl_id, (void **)&fd) < 0) - HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "can't retrieve POSIX file descriptor") - - /* Stat the filename we're resolving */ - if(HDstat(name, &st) < 0) - HSYS_GOTO_ERROR(H5E_FILE, H5E_BADFILE, FAIL, "unable to stat file") - - /* Stat the file we opened */ - if(HDfstat(*fd, &fst) < 0) - HSYS_GOTO_ERROR(H5E_FILE, H5E_BADFILE, FAIL, "unable to fstat file") - - /* Verify that the files are really the same */ - if(st.st_mode != fst.st_mode || st.st_ino != fst.st_ino || st.st_dev != fst.st_dev) - HGOTO_ERROR(H5E_FILE, H5E_BADVALUE, FAIL, "files' st_ino or st_dev fields changed!") - - /* Get the resolved path for the file name */ - if(NULL == HDrealpath(name, realname)) - HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "can't retrieve real path for file") - - /* Duplicate the resolved path for the file name */ - if(NULL == (*actual_name = (char *)H5MM_strdup(realname))) - HGOTO_ERROR(H5E_FILE, H5E_CANTALLOC, FAIL, "can't duplicate real path") - } /* end if */ - } /* end if */ -#endif /* H5_HAVE_SYMLINK */ - - /* Check if we've resolved the file's name */ - if(NULL == *actual_name) { - /* Just duplicate the name used to open the file */ - if(NULL == (*actual_name = (char *)H5MM_strdup(name))) - HGOTO_ERROR(H5E_FILE, H5E_CANTALLOC, FAIL, "can't duplicate open name") - } /* end else */ + /* Open the file */ + if((ret_value = H5VL_file_open(filename, flags, fapl_id, H5_REQUEST_NULL))<0) + HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, FAIL, "unable to open file") done: - if(new_fapl_id > 0 && H5Pclose(new_fapl_id) < 0) - HGOTO_ERROR(H5E_FILE, H5E_CANTCLOSEOBJ, FAIL, "can't close duplicated FAPL") - - FUNC_LEAVE_NOAPI(ret_value) -} /* H5F_build_actual_name() */ + FUNC_LEAVE_API(ret_value) +} /* end H5Fopen() */ /*------------------------------------------------------------------------- - * Function: H5F_addr_encode_len + * Function: H5Fflush * - * Purpose: Encodes an address into the buffer pointed to by *PP and - * then increments the pointer to the first byte after the - * address. An undefined value is stored as all 1's. + * 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: void + * Return: Non-negative on success/Negative on failure * * Programmer: Robb Matzke - * Friday, November 7, 1997 + * Thursday, August 6, 1998 * *------------------------------------------------------------------------- */ -void -H5F_addr_encode_len(size_t addr_len, uint8_t **pp/*in,out*/, haddr_t addr) +herr_t +H5Fflush(hid_t object_id, H5F_scope_t scope) { - unsigned u; /* Local index variable */ - - /* Use FUNC_ENTER_NOAPI_NOINIT_NOERR here to avoid performance issues */ - FUNC_ENTER_NOAPI_NOINIT_NOERR + herr_t ret_value = SUCCEED; /* Return value */ - HDassert(addr_len); - HDassert(pp && *pp); + FUNC_ENTER_API(FAIL) + H5TRACE2("e", "iFs", object_id, scope); - if(H5F_addr_defined(addr)) { - for(u = 0; u < addr_len; u++) { - *(*pp)++ = (uint8_t)(addr & 0xff); - addr >>= 8; - } /* end for */ - HDassert("overflow" && 0 == addr); - } /* end if */ - else { - for(u = 0; u < addr_len; u++) - *(*pp)++ = 0xff; - } /* end else */ + if((ret_value = H5VL_file_flush(object_id, scope, H5_REQUEST_NULL)) < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTFLUSH, FAIL, "unable to flush file") - FUNC_LEAVE_NOAPI_VOID -} /* end H5F_addr_encode_len() */ +done: + FUNC_LEAVE_API(ret_value) +} /* end H5Fflush() */ /*------------------------------------------------------------------------- - * Function: H5F_addr_encode + * Function: H5Fclose + * + * Purpose: This function closes the file specified by FILE_ID by + * flushing all data to storage, and terminating access to the + * file through FILE_ID. If objects (e.g., datasets, groups, + * etc.) are open in the file then the underlying storage is not + * closed until those objects are closed; however, all data for + * the file and the open objects is flushed. * - * Purpose: Encodes an address into the buffer pointed to by *PP and - * then increments the pointer to the first byte after the - * address. An undefined value is stored as all 1's. + * Return: Success: Non-negative * - * Return: void + * Failure: Negative * * Programmer: Robb Matzke - * Friday, November 7, 1997 + * Saturday, February 20, 1999 + * + * Modifications: * *------------------------------------------------------------------------- */ -void -H5F_addr_encode(const H5F_t *f, uint8_t **pp/*in,out*/, haddr_t addr) +herr_t +H5Fclose(hid_t file_id) { - /* Use FUNC_ENTER_NOAPI_NOINIT_NOERR here to avoid performance issues */ - FUNC_ENTER_NOAPI_NOINIT_NOERR + herr_t ret_value = SUCCEED; - HDassert(f); + FUNC_ENTER_API(FAIL) + H5TRACE1("e", "i", file_id); - H5F_addr_encode_len(H5F_SIZEOF_ADDR(f), pp, addr); + /* Close the file */ + if((ret_value = H5VL_file_close(file_id, H5_REQUEST_NULL)) < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTCLOSEFILE, FAIL, "unable to close file") - FUNC_LEAVE_NOAPI_VOID -} /* end H5F_addr_encode() */ +done: + FUNC_LEAVE_API(ret_value) +} /* end H5Fclose() */ /*------------------------------------------------------------------------- - * Function: H5F_addr_decode_len + * Function: H5Freopen * - * Purpose: Decodes an address from the buffer pointed to by *PP and - * updates the pointer to point to the next byte after the - * address. + * Purpose: Reopen a file. The new file handle which is returned points + * to the same file as the specified file handle. Both handles + * share caches and other information. The only difference + * between the handles is that the new handle is not mounted + * anywhere and no files are mounted on it. * - * If the value read is all 1's then the address is returned - * with an undefined value. + * Return: Success: New file ID * - * Return: void + * Failure: FAIL * * Programmer: Robb Matzke - * Friday, November 7, 1997 + * Friday, October 16, 1998 + * + * Modifications: + * Quincey Koziol, May 14, 2002 + * Keep old file's read/write intent in reopened file. * *------------------------------------------------------------------------- */ -void -H5F_addr_decode_len(size_t addr_len, const uint8_t **pp/*in,out*/, haddr_t *addr_p/*out*/) +hid_t +H5Freopen(hid_t file_id) { - hbool_t all_zero = TRUE; /* True if address was all zeroes */ - unsigned u; /* Local index variable */ - - /* Use FUNC_ENTER_NOAPI_NOINIT_NOERR here to avoid performance issues */ - FUNC_ENTER_NOAPI_NOINIT_NOERR - - HDassert(addr_len); - HDassert(pp && *pp); - HDassert(addr_p); - - /* Reset value in destination */ - *addr_p = 0; - - /* Decode bytes from address */ - for(u = 0; u < addr_len; u++) { - uint8_t c; /* Local decoded byte */ - - /* Get decoded byte (and advance pointer) */ - c = *(*pp)++; - - /* Check for non-undefined address byte value */ - if(c != 0xff) - all_zero = FALSE; - - if(u < sizeof(*addr_p)) { - haddr_t tmp = c; /* Local copy of address, for casting */ - - /* Shift decoded byte to correct position */ - tmp <<= (u * 8); /*use tmp to get casting right */ + hid_t ret_value; - /* Merge into already decoded bytes */ - *addr_p |= tmp; - } /* end if */ - else - if(!all_zero) - HDassert(0 == **pp); /*overflow */ - } /* end for */ + FUNC_ENTER_API(FAIL) + H5TRACE1("i", "i", file_id); - /* If 'all_zero' is still TRUE, the address was entirely composed of '0xff' - * bytes, which is the encoded form of 'HADDR_UNDEF', so set the destination - * to that value */ - if(all_zero) - *addr_p = HADDR_UNDEF; + if(H5VL_file_optional(file_id, H5VL_FILE_REOPEN, H5_REQUEST_NULL, &ret_value) < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, FAIL, "unable to reopen file") - FUNC_LEAVE_NOAPI_VOID -} /* end H5F_addr_decode_len() */ +done: + FUNC_LEAVE_API(ret_value) +} /* end H5Freopen() */ /*------------------------------------------------------------------------- - * Function: H5F_addr_decode - * - * Purpose: Decodes an address from the buffer pointed to by *PP and - * updates the pointer to point to the next byte after the - * address. + * Function: H5Fget_intent * - * If the value read is all 1's then the address is returned - * with an undefined value. + * Purpose: Public API to retrieve the file's 'intent' flags passed + * during H5Fopen() * - * Return: void + * Return: Non-negative on success/negative on failure * - * Programmer: Robb Matzke - * Friday, November 7, 1997 + * Programmer: James Laird + * August 23, 2006 * *------------------------------------------------------------------------- */ -void -H5F_addr_decode(const H5F_t *f, const uint8_t **pp/*in,out*/, haddr_t *addr_p/*out*/) +herr_t +H5Fget_intent(hid_t file_id, unsigned *intent_flags) { - /* Use FUNC_ENTER_NOAPI_NOINIT_NOERR here to avoid performance issues */ - FUNC_ENTER_NOAPI_NOINIT_NOERR + herr_t ret_value = SUCCEED; - HDassert(f); + FUNC_ENTER_API(FAIL) + H5TRACE2("e", "i*Iu", file_id, intent_flags); - H5F_addr_decode_len(H5F_SIZEOF_ADDR(f), pp, addr_p); + /* If no intent flags were passed in, exit quietly */ + if(intent_flags) { + if((ret_value = H5VL_file_get(file_id, H5VL_FILE_GET_INTENT, H5_REQUEST_NULL, intent_flags)) < 0) + HGOTO_ERROR(H5E_INTERNAL, H5E_CANTGET, FAIL, "unable to get file intent") + } - FUNC_LEAVE_NOAPI_VOID -} /* end H5F_addr_decode() */ +done: + FUNC_LEAVE_API(ret_value) +} /* end H5Fget_intent() */ /*------------------------------------------------------------------------- @@ -2608,107 +717,6 @@ done: /*------------------------------------------------------------------------- - * Function: H5F_get_file_image - * - * Purpose: Private version of H5Fget_file_image - * - * Return: Success: Bytes copied / number of bytes needed. - * Failure: negative value - * - * Programmer: John Mainzer - * 11/15/11 - * - *------------------------------------------------------------------------- - */ -ssize_t -H5F_get_file_image(H5F_t *file, void *buf_ptr, size_t buf_len) -{ - H5FD_t *fd_ptr; /* file driver */ - haddr_t eoa; /* End of file address */ - ssize_t ret_value; /* Return value */ - - FUNC_ENTER_NOAPI_NOINIT - - /* Check args */ - if(!file || !file->shared || !file->shared->lf) - HGOTO_ERROR(H5E_FILE, H5E_BADVALUE, FAIL, "file_id yields invalid file pointer") - fd_ptr = file->shared->lf; - if(!fd_ptr->cls) - HGOTO_ERROR(H5E_FILE, H5E_BADVALUE, FAIL, "fd_ptr yields invalid class pointer") - - /* the address space used by the split and multi file drivers is not - * a good fit for this call. Since the plan is to depreciate these - * drivers anyway, don't bother to do a "force fit". - * - * The following clause tests for the multi file driver, and fails - * if the supplied file has the multi file driver as its top level - * file driver. However, this test will not work if there is some - * other file driver sitting on top of the multi file driver. - * - * I'm not sure if this is possible at present, but in all likelyhood, - * it will become possible in the future. On the other hand, we may - * remove the split/multi file drivers before then. - * - * I am leaving this solution in for now, but we should review it, - * and improve the solution if necessary. - * - * JRM -- 11/11/22 - */ - if(HDstrcmp(fd_ptr->cls->name, "multi") == 0) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "Not supported for multi file driver.") - - /* While the family file driver is conceptually fully compatible - * with the get file image operation, it sets a file driver message - * in the super block that prevents the image being opened with any - * driver other than the family file driver. Needless to say, this - * rather defeats the purpose of the get file image operation. - * - * While this problem is quire solvable, the required time and - * resources are lacking at present. Hence, for now, we don't - * allow the get file image operation to be perfomed on files - * opened with the family file driver. - * - * Observe that the following test only looks at the top level - * driver, and fails if there is some other driver sitting on to - * of the family file driver. - * - * I don't think this can happen at present, but that may change - * in the future. - * JRM -- 12/21/11 - */ - if(HDstrcmp(fd_ptr->cls->name, "family") == 0) - HGOTO_ERROR(H5E_FILE, H5E_BADVALUE, FAIL, "Not supported for family file driver.") - - - /* Go get the actual file size */ - if(HADDR_UNDEF == (eoa = H5FD_get_eoa(file->shared->lf, H5FD_MEM_DEFAULT))) - HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "unable to get file size") - - /* set ret_value = to eoa -- will overwrite this if appropriate */ - ret_value = (ssize_t)eoa; - - /* test to see if a buffer was provided -- if not, we are done */ - if(buf_ptr != NULL) { - size_t space_needed; /* size of file image */ - - /* Check for buffer too small */ - if((haddr_t)buf_len < eoa) - HGOTO_ERROR(H5E_FILE, H5E_BADVALUE, FAIL, "supplied buffer too small") - - space_needed = (size_t)eoa; - - /* read in the file image */ - /* (Note compensation for base address addition in internal routine) */ - if(H5FD_read(fd_ptr, H5AC_ind_dxpl_id, H5FD_MEM_DEFAULT, 0, space_needed, buf_ptr) < 0) - HGOTO_ERROR(H5E_FILE, H5E_READERROR, FAIL, "file image read request failed") - } /* end if */ - -done: - FUNC_LEAVE_NOAPI(ret_value) -} /* H5F_get_file_image() */ - - -/*------------------------------------------------------------------------- * Function: H5Fget_mdc_config * * Purpose: Retrieves the current automatic cache resize configuration @@ -3024,149 +1032,3 @@ H5Fclear_elink_file_cache(hid_t file_id) done: FUNC_LEAVE_API(ret_value) } /* end H5Fclear_elink_file_cache() */ - - -/*------------------------------------------------------------------------- - * Function: H5F_set_grp_btree_shared - * - * Purpose: Set the grp_btree_shared field with a valid ref-count pointer. - * - * Return: Success: SUCCEED - * Failure: FAIL - * - * Programmer: Quincey Koziol - * 7/19/11 - * - *------------------------------------------------------------------------- - */ -herr_t -H5F_set_grp_btree_shared(H5F_t *f, H5RC_t *rc) -{ - /* Use FUNC_ENTER_NOAPI_NOINIT_NOERR here to avoid performance issues */ - FUNC_ENTER_NOAPI_NOINIT_NOERR - - /* Sanity check */ - HDassert(f); - HDassert(f->shared); - HDassert(rc); - - f->shared->grp_btree_shared = rc; - - FUNC_LEAVE_NOAPI(SUCCEED) -} /* H5F_set_grp_btree_shared() */ - - -/*------------------------------------------------------------------------- - * Function: H5F_set_sohm_addr - * - * Purpose: Set the sohm_addr field with a new value. - * - * Return: Success: SUCCEED - * Failure: FAIL - * - * Programmer: Quincey Koziol - * 7/20/11 - * - *------------------------------------------------------------------------- - */ -herr_t -H5F_set_sohm_addr(H5F_t *f, haddr_t addr) -{ - /* Use FUNC_ENTER_NOAPI_NOINIT_NOERR here to avoid performance issues */ - FUNC_ENTER_NOAPI_NOINIT_NOERR - - /* Sanity check */ - HDassert(f); - HDassert(f->shared); - - f->shared->sohm_addr = addr; - - FUNC_LEAVE_NOAPI(SUCCEED) -} /* H5F_set_sohm_addr() */ - - -/*------------------------------------------------------------------------- - * Function: H5F_set_sohm_vers - * - * Purpose: Set the sohm_vers field with a new value. - * - * Return: Success: SUCCEED - * Failure: FAIL - * - * Programmer: Quincey Koziol - * 7/20/11 - * - *------------------------------------------------------------------------- - */ -herr_t -H5F_set_sohm_vers(H5F_t *f, unsigned vers) -{ - /* Use FUNC_ENTER_NOAPI_NOINIT_NOERR here to avoid performance issues */ - FUNC_ENTER_NOAPI_NOINIT_NOERR - - /* Sanity check */ - HDassert(f); - HDassert(f->shared); - - f->shared->sohm_vers = vers; - - FUNC_LEAVE_NOAPI(SUCCEED) -} /* H5F_set_sohm_vers() */ - - -/*------------------------------------------------------------------------- - * Function: H5F_set_sohm_nindexes - * - * Purpose: Set the sohm_nindexes field with a new value. - * - * Return: Success: SUCCEED - * Failure: FAIL - * - * Programmer: Quincey Koziol - * 7/20/11 - * - *------------------------------------------------------------------------- - */ -herr_t -H5F_set_sohm_nindexes(H5F_t *f, unsigned nindexes) -{ - /* Use FUNC_ENTER_NOAPI_NOINIT_NOERR here to avoid performance issues */ - FUNC_ENTER_NOAPI_NOINIT_NOERR - - /* Sanity check */ - HDassert(f); - HDassert(f->shared); - - f->shared->sohm_nindexes = nindexes; - - FUNC_LEAVE_NOAPI(SUCCEED) -} /* H5F_set_sohm_nindexes() */ - - -/*------------------------------------------------------------------------- - * Function: H5F_set_store_msg_crt_idx - * - * Purpose: Set the store_msg_crt_idx field with a new value. - * - * Return: Success: SUCCEED - * Failure: FAIL - * - * Programmer: Quincey Koziol - * 7/20/11 - * - *------------------------------------------------------------------------- - */ -herr_t -H5F_set_store_msg_crt_idx(H5F_t *f, hbool_t flag) -{ - /* Use FUNC_ENTER_NOAPI_NOINIT_NOERR here to avoid performance issues */ - FUNC_ENTER_NOAPI_NOINIT_NOERR - - /* Sanity check */ - HDassert(f); - HDassert(f->shared); - - f->shared->store_msg_crt_idx = flag; - - FUNC_LEAVE_NOAPI(SUCCEED) -} /* H5F_set_store_msg_crt_idx() */ diff --git a/src/H5Fint.c b/src/H5Fint.c new file mode 100644 index 0000000..ae93989 --- /dev/null +++ b/src/H5Fint.c @@ -0,0 +1,2195 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * Copyright by The HDF Group. * + * Copyright by the Board of Trustees of the University of Illinois. * + * 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 files COPYING and Copyright.html. COPYING can be found at the root * + * of the source code distribution tree; Copyright.html can be found at the * + * root level of an installed copy of the electronic HDF5 document set and * + * is linked from the top-level documents page. It can also be found at * + * http://hdfgroup.org/HDF5/doc/Copyright.html. If you do not have * + * access to either file, you may request a copy from help@hdfgroup.org. * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +#define H5F_PACKAGE /*suppress error about including H5Fpkg */ + +/* Interface initialization */ +#define H5_INTERFACE_INIT_FUNC H5F_init_interface + + +/* Packages needed by this file... */ +#include "H5private.h" /* Generic Functions */ +#include "H5Aprivate.h" /* Attributes */ +#include "H5ACprivate.h" /* Metadata cache */ +#include "H5Dprivate.h" /* Datasets */ +#include "H5Eprivate.h" /* Error handling */ +#include "H5Fpkg.h" /* File access */ +#include "H5FDprivate.h" /* File drivers */ +#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 "H5SMprivate.h" /* Shared Object Header Messages */ +#include "H5Tprivate.h" /* Datatypes */ +#include "H5VLprivate.h" /* VOL plugins */ + +/* Struct only used by functions H5F_get_objects and H5F_get_objects_cb */ +typedef struct H5F_olist_t { + H5I_type_t obj_type; /* Type of object to look for */ + hid_t *obj_id_list; /* Pointer to the list of open IDs to return */ + size_t *obj_id_count; /* Number of open IDs */ + struct { + hbool_t local; /* Set flag for "local" file searches */ + union { + H5F_file_t *shared; /* Pointer to shared file to look inside */ + const H5F_t *file; /* Pointer to file to look inside */ + } ptr; + } file_info; + size_t list_index; /* Current index in open ID array */ + size_t max_index; /* Maximum # of IDs to put into array */ +} H5F_olist_t; + +/* private prototypes */ +static H5F_t *H5F_new(H5F_file_t *shared, hid_t fcpl_id, hid_t fapl_id, H5FD_t *lf); +static herr_t H5F_build_actual_name(const H5F_t *f, const struct H5P_genplist_t *fapl, + const char *name, char ** /*out*/ actual_name); +static herr_t H5F_dest(H5F_t *f, hid_t dxpl_id, hbool_t flush); + +/* Declare a free list to manage the H5F_t struct */ +H5FL_DEFINE(H5F_t); + +/* Declare a free list to manage the H5F_file_t struct */ +H5FL_DEFINE(H5F_file_t); + + +/*------------------------------------------------------------------------- + * Function: H5F_init + * + * Purpose: Initialize the interface from some other layer. + * + * Return: Success: non-negative + * Failure: negative + * + * Programmer: Robb Matzke + * Wednesday, December 16, 1998 + * + *------------------------------------------------------------------------- + */ +herr_t +H5F_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 H5F_init() */ + + +/*------------------------------------------------------------------------- + * Function: H5F_init_interface + * + * Purpose: Initialize interface-specific information. + * + * Return: Success: non-negative + * Failure: negative + * + * Programmer: Robb Matzke + * Friday, November 20, 1998 + * + *------------------------------------------------------------------------- + */ +static herr_t +H5F_init_interface(void) +{ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI_NOINIT + + /* + * Initialize the atom group for the file IDs. + */ + if(H5I_register_type(H5I_FILE, (size_t)H5I_FILEID_HASHSIZE, 0, (H5I_free_t)H5F_close)shared->mdc_initCacheCfg)) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set initial metadata cache resize config.") + if(H5P_set(new_plist, H5F_ACS_DATA_CACHE_NUM_SLOTS_NAME, &(f->shared->rdcc_nslots)) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set data cache number of slots") + if(H5P_set(new_plist, H5F_ACS_DATA_CACHE_BYTE_SIZE_NAME, &(f->shared->rdcc_nbytes)) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set data cache byte size") + if(H5P_set(new_plist, H5F_ACS_PREEMPT_READ_CHUNKS_NAME, &(f->shared->rdcc_w0)) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set preempt read chunks") + if(H5P_set(new_plist, H5F_ACS_ALIGN_THRHD_NAME, &(f->shared->threshold)) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set alignment threshold") + if(H5P_set(new_plist, H5F_ACS_ALIGN_NAME, &(f->shared->alignment)) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set alignment") + if(H5P_set(new_plist, H5F_ACS_GARBG_COLCT_REF_NAME, &(f->shared->gc_ref)) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set garbage collect reference") + if(H5P_set(new_plist, H5F_ACS_META_BLOCK_SIZE_NAME, &(f->shared->meta_aggr.alloc_size)) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set metadata cache size") + if(H5P_set(new_plist, H5F_ACS_SIEVE_BUF_SIZE_NAME, &(f->shared->sieve_buf_size)) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't sieve buffer size") + if(H5P_set(new_plist, H5F_ACS_SDATA_BLOCK_SIZE_NAME, &(f->shared->sdata_aggr.alloc_size)) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set 'small data' cache size") + if(H5P_set(new_plist, H5F_ACS_LATEST_FORMAT_NAME, &(f->shared->latest_format)) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set 'latest format' flag") + if(f->shared->efc) + efc_size = H5F_efc_max_nfiles(f->shared->efc); + if(H5P_set(new_plist, H5F_ACS_EFC_SIZE_NAME, &efc_size) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't set elink file cache size") + + /* + * Since we're resetting the driver ID and info, close them if they + * exist in this new property list. + */ + if(H5P_facc_close(ret_value, NULL) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTFREE, FAIL, "can't free the old driver information") + + /* Increment the reference count on the driver ID and insert it into the property list */ + if(H5I_inc_ref(f->shared->lf->driver_id, FALSE) < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTINC, FAIL, "unable to increment ref count on VFL driver") + if(H5P_set(new_plist, H5F_ACS_FILE_DRV_ID_NAME, &(f->shared->lf->driver_id)) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set file driver ID") + + /* Set the driver "info" in the property list */ + driver_info = H5FD_fapl_get(f->shared->lf); + if(driver_info != NULL && H5P_set(new_plist, H5F_ACS_FILE_DRV_INFO_NAME, &driver_info) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set file driver info") + + /* Set the file close degree appropriately */ + if(f->shared->fc_degree == H5F_CLOSE_DEFAULT && H5P_set(new_plist, H5F_ACS_CLOSE_DEGREE_NAME, &(f->shared->lf->cls->fc_degree)) < 0) { + HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set file close degree") + } else if(f->shared->fc_degree != H5F_CLOSE_DEFAULT && H5P_set(new_plist, H5F_ACS_CLOSE_DEGREE_NAME, &(f->shared->fc_degree)) < 0) { + HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set file close degree") + } + + /* MSC TODO move this to the upper VOL get routine & set the vol info too*/ + /* Set the VOL class in the property list */ + if(H5P_set(new_plist, H5F_ACS_VOL_NAME, &(f->vol_cls)) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set file VOL plugin") + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5F_get_access_plist() */ + + +/*------------------------------------------------------------------------- + * Function: H5F_get_obj_count_cb + * + * Purpose: H5F_get_obj_count_cb callback function. It calls in the + * VOL and gets the object count for the file ID passed + * + * Return: TRUE if the value has been added. + * FALSE otherwise. + * + * Programmer: Mohamad Chaarawi + * May 2012 + * + *------------------------------------------------------------------------- + */ +int +H5F_get_obj_count_cb(void UNUSED *obj_ptr, hid_t obj_id, void *key) +{ + H5F_trav_obj_cnt_t *udata = (H5F_trav_obj_cnt_t *)key; + ssize_t obj_count = 0; + int ret_value = H5_ITER_CONT; /* Return value */ + + FUNC_ENTER_NOAPI_NOINIT + + if(H5VL_file_get(obj_id, H5VL_FILE_GET_OBJ_COUNT, H5_REQUEST_NULL, &obj_count, udata->types) < 0) + HGOTO_ERROR(H5E_INTERNAL, H5E_CANTGET, H5_ITER_ERROR, "unable to get object count in file(s)") + + *(udata->obj_count) += obj_count; + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* H5F_get_obj_count_cb */ + + +/*------------------------------------------------------------------------- + * Function: H5F_get_obj_count + * + * Purpose: Private function return the number of opened object IDs + * (files, datasets, groups, datatypes) in the same file. + * + * Return: SUCCEED on success, FAIL on failure. + * + * Programmer: Raymond Lu + * Wednesday, Dec 5, 2001 + * + *------------------------------------------------------------------------- + */ +herr_t +H5F_get_obj_count(const H5F_t *f, unsigned types, hbool_t app_ref, size_t *obj_id_count_ptr) +{ + herr_t ret_value = SUCCEED; + + FUNC_ENTER_NOAPI(FAIL) + + /* Sanity check */ + HDassert(obj_id_count_ptr); + + /* Perform the query */ + if((ret_value = H5F_get_objects(f, types, 0, NULL, app_ref, obj_id_count_ptr)) < 0) + HGOTO_ERROR(H5E_INTERNAL, H5E_BADITER, FAIL, "H5F_get_objects failed") + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5F_get_obj_count() */ + + +/*------------------------------------------------------------------------- + * Function: H5F_get_obj_ids_cb + * + * Purpose: H5F_get_obj_ids_cb callback function. It calls in the + * VOL and gets the object ids for the file ID passed + * + * Return: TRUE if the value has been added. + * FALSE otherwise. + * + * Programmer: Mohamad Chaarawi + * May 2012 + * + *------------------------------------------------------------------------- + */ +int +H5F_get_obj_ids_cb(void UNUSED *obj_ptr, hid_t obj_id, void *key) +{ + H5F_trav_obj_ids_t *udata = (H5F_trav_obj_ids_t *)key; + ssize_t obj_count = 0; + int ret_value = H5_ITER_CONT; /* Return value */ + + FUNC_ENTER_NOAPI_NOINIT + + if(H5VL_file_get(obj_id, H5VL_FILE_GET_OBJ_IDS, H5_REQUEST_NULL, udata->types, + udata->max_objs, udata->oid_list, &obj_count) < 0) + HGOTO_ERROR(H5E_INTERNAL, H5E_CANTGET, H5_ITER_ERROR, "unable to get object count in file(s)") + + *(udata->obj_count) += obj_count; + udata->max_objs -= obj_count; + udata->oid_list += obj_count; + + if(udata->max_objs <= 0) + ret_value = H5_ITER_STOP; + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* H5F_get_obj_count_cb */ + + +/*------------------------------------------------------------------------- + * Function: H5F_get_obj_ids + * + * Purpose: Private function to return a list of opened object IDs. + * + * Return: Non-negative on success; can't fail. + * + * Programmer: Raymond Lu + * Wednesday, Dec 5, 2001 + * + *------------------------------------------------------------------------- + */ +herr_t +H5F_get_obj_ids(const H5F_t *f, unsigned types, size_t max_objs, hid_t *oid_list, hbool_t app_ref, size_t *obj_id_count_ptr) +{ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI(FAIL) + + /* Sanity check */ + HDassert(obj_id_count_ptr); + + /* Perform the query */ + if((ret_value = H5F_get_objects(f, types, max_objs, oid_list, app_ref, obj_id_count_ptr)) < 0) + HGOTO_ERROR(H5E_INTERNAL, H5E_BADITER, FAIL, "H5F_get_objects failed") + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5F_get_obj_ids() */ + + +/*--------------------------------------------------------------------------- + * Function: H5F_get_objects + * + * Purpose: This function is called by H5F_get_obj_count or + * H5F_get_obj_ids to get number of object IDs and/or a + * list of opened object IDs (in return value). + * Return: Non-negative on success; Can't fail. + * + * Programmer: Raymond Lu + * Wednesday, Dec 5, 2001 + * + *--------------------------------------------------------------------------- + */ +herr_t +H5F_get_objects(const H5F_t *f, unsigned types, size_t max_index, hid_t *obj_id_list, hbool_t app_ref, size_t *obj_id_count_ptr) +{ + size_t obj_id_count=0; /* Number of open IDs */ + H5F_olist_t olist; /* Structure to hold search results */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI_NOINIT + + /* Sanity check */ + HDassert(obj_id_count_ptr); + + /* Set up search information */ + olist.obj_id_list = (max_index==0 ? NULL : obj_id_list); + olist.obj_id_count = &obj_id_count; + olist.list_index = 0; + olist.max_index = max_index; + + /* Determine if we are searching for local or global objects */ + if(types & H5F_OBJ_LOCAL) { + olist.file_info.local = TRUE; + olist.file_info.ptr.file = f; + } /* end if */ + else { + olist.file_info.local = FALSE; + olist.file_info.ptr.shared = f ? f->shared : NULL; + } /* end else */ + + /* Iterate through file IDs to count the number, and put their + * IDs on the object list. */ + if(types & H5F_OBJ_FILE) { + olist.obj_type = H5I_FILE; + if(H5I_iterate(H5I_FILE, H5F_get_objects_cb, &olist, app_ref) < 0) + HGOTO_ERROR(H5E_FILE, H5E_BADITER, FAIL, "iteration failed(1)") + } /* end if */ + + /* Search through dataset IDs to count number of datasets, and put their + * IDs on the object list */ + if(types & H5F_OBJ_DATASET) { + olist.obj_type = H5I_DATASET; + if(H5I_iterate(H5I_DATASET, H5F_get_objects_cb, &olist, app_ref) < 0) + HGOTO_ERROR(H5E_FILE, H5E_BADITER, FAIL, "iteration failed(2)") + } /* end if */ + + /* Search through group IDs to count number of groups, and put their + * IDs on the object list */ + if(types & H5F_OBJ_GROUP) { + olist.obj_type = H5I_GROUP; + if(H5I_iterate(H5I_GROUP, H5F_get_objects_cb, &olist, app_ref) < 0) + HGOTO_ERROR(H5E_FILE, H5E_BADITER, FAIL, "iteration failed(3)") + } /* end if */ + + /* Search through datatype IDs to count number of named datatypes, and put their + * IDs on the object list */ + if(types & H5F_OBJ_DATATYPE) { + olist.obj_type = H5I_DATATYPE; + if(H5I_iterate(H5I_DATATYPE, H5F_get_objects_cb, &olist, app_ref) < 0) + HGOTO_ERROR(H5E_FILE, H5E_BADITER, FAIL, "iteration failed(4)") + } /* end if */ + + /* Search through attribute IDs to count number of attributes, and put their + * IDs on the object list */ + if(types & H5F_OBJ_ATTR) { + olist.obj_type = H5I_ATTR; + if(H5I_iterate(H5I_ATTR, H5F_get_objects_cb, &olist, app_ref) < 0) + HGOTO_ERROR(H5E_FILE, H5E_BADITER, FAIL, "iteration failed(5)") + } /* end if */ + + /* Set the number of objects currently open */ + *obj_id_count_ptr = obj_id_count; + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5F_get_objects() */ + + +/*------------------------------------------------------------------------- + * Function: H5F_get_objects_cb + * + * Purpose: H5F_get_objects' callback function. It verifies if an + * object is in the file, and either count it or put its ID + * on the list. + * + * Return: TRUE if the array of object IDs is filled up. + * FALSE otherwise. + * + * Programmer: Raymond Lu + * Wednesday, Dec 5, 2001 + * + *------------------------------------------------------------------------- + */ +int +H5F_get_objects_cb(void *obj_ptr, hid_t obj_id, void *key) +{ + H5F_olist_t *olist = (H5F_olist_t *)key; /* Alias for search info */ + int ret_value = FALSE; /* Return value */ + + FUNC_ENTER_NOAPI_NOINIT + + HDassert(obj_ptr); + HDassert(olist); + + /* Count file IDs */ + if(olist->obj_type == H5I_FILE) { + if((olist->file_info.local && + (!olist->file_info.ptr.file || (olist->file_info.ptr.file && (H5F_t*)obj_ptr == olist->file_info.ptr.file) )) + || (!olist->file_info.local && + ( !olist->file_info.ptr.shared || (olist->file_info.ptr.shared && ((H5F_t*)obj_ptr)->shared == olist->file_info.ptr.shared) ))) { + /* Add the object's ID to the ID list, if appropriate */ + if(olist->obj_id_list) { + olist->obj_id_list[olist->list_index] = obj_id; + olist->list_index++; + } + + /* Increment the number of open objects */ + if(olist->obj_id_count) + (*olist->obj_id_count)++; + + /* Check if we've filled up the array. Return TRUE only if + * we have filled up the array. Otherwise return FALSE(RET_VALUE is + * preset to FALSE) because H5I_iterate needs the return value of + * FALSE to continue the iteration. */ + if(olist->max_index>0 && olist->list_index>=olist->max_index) + HGOTO_DONE(TRUE) /* Indicate that the iterator should stop */ + } + } /* end if */ + else { /* either count opened object IDs or put the IDs on the list */ + H5O_loc_t *oloc; /* Group entry info for object */ + + switch(olist->obj_type) { + case H5I_ATTR: + oloc = H5A_oloc((H5A_t *)obj_ptr); + break; + + case H5I_GROUP: + oloc = H5G_oloc((H5G_t *)obj_ptr); + break; + + case H5I_DATASET: + oloc = H5D_oloc((H5D_t *)obj_ptr); + break; + + case H5I_DATATYPE: + if(H5T_is_named((H5T_t*)obj_ptr)==TRUE) + oloc = H5T_oloc((H5T_t*)obj_ptr); + else + oloc = NULL; + break; + + case H5I_UNINIT: + case H5I_BADID: + case H5I_FILE: + case H5I_DATASPACE: + case H5I_REFERENCE: + case H5I_VFL: + case H5I_VOL: + case H5I_GENPROP_CLS: + case H5I_GENPROP_LST: + case H5I_ERROR_CLASS: + case H5I_ERROR_MSG: + case H5I_ERROR_STACK: + case H5I_NTYPES: + default: + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "unknown data object") + } /* end switch */ + + if((olist->file_info.local && + ( (!olist->file_info.ptr.file && olist->obj_type == H5I_DATATYPE && H5T_is_immutable((H5T_t *)obj_ptr) == FALSE) + || (!olist->file_info.ptr.file && olist->obj_type != H5I_DATATYPE) + || (oloc && oloc->file == olist->file_info.ptr.file))) + || (!olist->file_info.local && + ((!olist->file_info.ptr.shared && olist->obj_type == H5I_DATATYPE && H5T_is_immutable((H5T_t *)obj_ptr) == FALSE) + || (!olist->file_info.ptr.shared && olist->obj_type != H5I_DATATYPE) + || (oloc && oloc->file && oloc->file->shared == olist->file_info.ptr.shared)))) { + /* Add the object's ID to the ID list, if appropriate */ + if(olist->obj_id_list) { + olist->obj_id_list[olist->list_index] = obj_id; + olist->list_index++; + } /* end if */ + + /* Increment the number of open objects */ + if(olist->obj_id_count) + (*olist->obj_id_count)++; + + /* Check if we've filled up the array. Return TRUE only if + * we have filled up the array. Otherwise return FALSE(RET_VALUE is + * preset to FALSE) because H5I_iterate needs the return value of + * FALSE to continue iterating. */ + if(olist->max_index>0 && olist->list_index>=olist->max_index) + HGOTO_DONE(TRUE) /* Indicate that the iterator should stop */ + } /* end if */ + } /* end else */ + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5F_get_objects_cb() */ + + +/*------------------------------------------------------------------------- + * Function: H5F_is_hdf5 + * + * Purpose: Check the file signature to detect an HDF5 file. + * + * Bugs: This function is not robust: it only uses the default file + * driver when attempting to open the file when in fact it + * should use all known file drivers. + * + * Return: Success: TRUE/FALSE + * + * Failure: Negative + * + * Programmer: Unknown + * + * Modifications: + * Robb Matzke, 1999-08-02 + * Rewritten to use the virtual file layer. + *------------------------------------------------------------------------- + */ +htri_t +H5F_is_hdf5(const char *name) +{ + H5FD_t *file = NULL; /* Low-level file struct */ + htri_t ret_value; /* Return value */ + + FUNC_ENTER_NOAPI_NOINIT + + /* Open the file at the virtual file layer */ + if(NULL == (file = H5FD_open(name, H5F_ACC_RDONLY, H5P_FILE_ACCESS_DEFAULT, HADDR_UNDEF))) + HGOTO_ERROR(H5E_IO, H5E_CANTINIT, FAIL, "unable to open file") + + /* The file is an hdf5 file if the hdf5 file signature can be found */ + ret_value = (HADDR_UNDEF != H5F_locate_signature(file, H5AC_ind_dxpl_id)); + +done: + /* Close the file */ + if(file) + if(H5FD_close(file) < 0 && ret_value >= 0) + HDONE_ERROR(H5E_IO, H5E_CANTCLOSEFILE, FAIL, "unable to close file") + + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5F_is_hdf5() */ + + +/*------------------------------------------------------------------------- + * Function: H5F_new + * + * Purpose: Creates a new file object and initializes it. The + * H5Fopen and H5Fcreate functions then fill in various + * fields. If SHARED is a non-null pointer then the shared info + * to which it points has the reference count incremented. + * Otherwise a new, empty shared info struct is created and + * initialized with the specified file access property list. + * + * Errors: + * + * Return: Success: Ptr to a new file struct. + * + * Failure: NULL + * + * Programmer: Robb Matzke + * matzke@llnl.gov + * Jul 18 1997 + * + *------------------------------------------------------------------------- + */ +static H5F_t * +H5F_new(H5F_file_t *shared, hid_t fcpl_id, hid_t fapl_id, H5FD_t *lf) +{ + H5F_t *f = NULL, *ret_value; + + FUNC_ENTER_NOAPI_NOINIT + + if(NULL == (f = H5FL_CALLOC(H5F_t))) + HGOTO_ERROR(H5E_FILE, H5E_NOSPACE, NULL, "can't allocate top file structure") + f->file_id = -1; + + if(shared) { + HDassert(lf == NULL); + f->shared = shared; + } /* end if */ + else { + H5P_genplist_t *plist; /* Property list */ + unsigned efc_size; /* External file cache size */ + size_t u; /* Local index variable */ + + HDassert(lf != NULL); + if(NULL == (f->shared = H5FL_CALLOC(H5F_file_t))) + HGOTO_ERROR(H5E_FILE, H5E_NOSPACE, NULL, "can't allocate shared file structure") + + f->shared->sohm_addr = HADDR_UNDEF; + f->shared->sohm_vers = HDF5_SHAREDHEADER_VERSION; + for(u = 0; u < NELMTS(f->shared->fs_addr); u++) + f->shared->fs_addr[u] = HADDR_UNDEF; + f->shared->accum.loc = HADDR_UNDEF; + f->shared->lf = lf; + + /* + * Copy the file creation and file access property lists into the + * new file handle. We do this early because some values might need + * to change as the file is being opened. + */ + if(NULL == (plist = (H5P_genplist_t *)H5I_object(fcpl_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "not property list") + f->shared->fcpl_id = H5P_copy_plist(plist, FALSE); + + /* Get the FCPL values to cache */ + if(H5P_get(plist, H5F_CRT_ADDR_BYTE_NUM_NAME, &f->shared->sizeof_addr) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't get byte number for address") + if(H5P_get(plist, H5F_CRT_OBJ_BYTE_NUM_NAME, &f->shared->sizeof_size) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't get byte number for object size") + if(H5P_get(plist, H5F_CRT_SHMSG_NINDEXES_NAME, &f->shared->sohm_nindexes) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't get number of SOHM indexes") + HDassert(f->shared->sohm_nindexes < 255); + if(H5P_get(plist, H5F_CRT_FILE_SPACE_STRATEGY_NAME, &f->shared->fs_strategy) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't get file space strategy") + if(H5P_get(plist, H5F_CRT_FREE_SPACE_THRESHOLD_NAME, &f->shared->fs_threshold) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't get free-space section threshold") + + /* Get the FAPL values to cache */ + if(NULL == (plist = (H5P_genplist_t *)H5I_object(fapl_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "not file access property list") + if(H5P_get(plist, H5F_ACS_META_CACHE_INIT_CONFIG_NAME, &(f->shared->mdc_initCacheCfg)) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't get initial metadata cache resize config") + if(H5P_get(plist, H5F_ACS_DATA_CACHE_NUM_SLOTS_NAME, &(f->shared->rdcc_nslots)) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't get data cache number of slots") + if(H5P_get(plist, H5F_ACS_DATA_CACHE_BYTE_SIZE_NAME, &(f->shared->rdcc_nbytes)) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't get data cache byte size") + if(H5P_get(plist, H5F_ACS_PREEMPT_READ_CHUNKS_NAME, &(f->shared->rdcc_w0)) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't get preempt read chunk") + if(H5P_get(plist, H5F_ACS_ALIGN_THRHD_NAME, &(f->shared->threshold)) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't get alignment threshold") + if(H5P_get(plist, H5F_ACS_ALIGN_NAME, &(f->shared->alignment)) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't get alignment") + if(H5P_get(plist, H5F_ACS_GARBG_COLCT_REF_NAME,&(f->shared->gc_ref)) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't get garbage collect reference") + if(H5P_get(plist, H5F_ACS_SIEVE_BUF_SIZE_NAME, &(f->shared->sieve_buf_size)) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't get sieve buffer size") + if(H5P_get(plist, H5F_ACS_LATEST_FORMAT_NAME, &(f->shared->latest_format)) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't get 'latest format' flag") + if(H5P_get(plist, H5F_ACS_META_BLOCK_SIZE_NAME, &(f->shared->meta_aggr.alloc_size)) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't get metadata cache size") + f->shared->meta_aggr.feature_flag = H5FD_FEAT_AGGREGATE_METADATA; + if(H5P_get(plist, H5F_ACS_SDATA_BLOCK_SIZE_NAME, &(f->shared->sdata_aggr.alloc_size)) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't get 'small data' cache size") + f->shared->sdata_aggr.feature_flag = H5FD_FEAT_AGGREGATE_SMALLDATA; + if(H5P_get(plist, H5F_ACS_EFC_SIZE_NAME, &efc_size) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't get elink file cache size") + if(efc_size > 0) + if(NULL == (f->shared->efc = H5F_efc_create(efc_size))) + HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, NULL, "can't create external file cache") + + /* Get the VFD values to cache */ + f->shared->maxaddr = H5FD_get_maxaddr(lf); + if(!H5F_addr_defined(f->shared->maxaddr)) + HGOTO_ERROR(H5E_FILE, H5E_BADVALUE, NULL, "bad maximum address from VFD") + if(H5FD_get_feature_flags(lf, &f->shared->feature_flags) < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTGET, NULL, "can't get feature flags from VFD") + if(H5FD_get_fs_type_map(lf, f->shared->fs_type_map) < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTGET, NULL, "can't get free space type mapping from VFD") + if(H5MF_init_merge_flags(f) < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, NULL, "problem initializing free space merge flags") + f->shared->tmp_addr = f->shared->maxaddr; + /* Disable temp. space allocation for parallel I/O (for now) */ + /* (When we've arranged to have the relocated metadata addresses (and + * sizes) broadcast during the "end of epoch" metadata operations, + * this can be enabled - QAK) + */ + /* (This should be disabled when the metadata journaling branch is + * merged into the trunk and journaling is enabled, at least until + * we make it work. - QAK) + */ + f->shared->use_tmp_space = !H5F_HAS_FEATURE(f, H5FD_FEAT_HAS_MPI); + + /* + * Create a metadata cache with the specified number of elements. + * The cache might be created with a different number of elements and + * the access property list should be updated to reflect that. + */ + if(H5AC_create(f, &(f->shared->mdc_initCacheCfg)) < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, NULL, "unable to create metadata cache") + + /* Create the file's "open object" information */ + if(H5FO_create(f) < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, NULL, "unable to create open object data structure") + + /* Add new "shared" struct to list of open files */ + if(H5F_sfile_add(f->shared) < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, NULL, "unable to append to list of open files") + } /* end else */ + + f->shared->nrefs++; + + /* Create the file's "top open object" information */ + if(H5FO_top_create(f) < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, NULL, "unable to create open object data structure") + + /* Set return value */ + ret_value = f; + +done: + if(!ret_value && f) { + if(!shared) + f->shared = H5FL_FREE(H5F_file_t, f->shared); + f = H5FL_FREE(H5F_t, f); + } /* end if */ + + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5F_new() */ + + +/*------------------------------------------------------------------------- + * Function: H5F_dest + * + * Purpose: Destroys a file structure. This function flushes the cache + * but doesn't do any other cleanup other than freeing memory + * for the file struct. The shared info for the file is freed + * only when its reference count reaches zero. + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Robb Matzke + * matzke@llnl.gov + * Jul 18 1997 + * + *------------------------------------------------------------------------- + */ +static herr_t +H5F_dest(H5F_t *f, hid_t dxpl_id, hbool_t flush) +{ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI_NOINIT + + /* Sanity check */ + HDassert(f); + HDassert(f->shared); + + if(1 == f->shared->nrefs) { + /* Flush at this point since the file will be closed. + * Only try to flush the file if it was opened with write access, and if + * the caller requested a flush. + */ + if((f->shared->flags & H5F_ACC_RDWR) && flush) + if(H5F_flush(f, dxpl_id, TRUE) < 0) + HDONE_ERROR(H5E_CACHE, H5E_CANTFLUSH, FAIL, "unable to flush cache") + + /* Release the external file cache */ + if(f->shared->efc) { + if(H5F_efc_destroy(f->shared->efc) < 0) + HDONE_ERROR(H5E_FILE, H5E_CANTRELEASE, FAIL, "can't destroy external file cache") + f->shared->efc = NULL; + } /* end if */ + + /* Release objects that depend on the superblock being initialized */ + if(f->shared->sblock) { + /* Shutdown file free space manager(s) */ + /* (We should release the free space information now (before truncating + * the file and before the metadata cache is shut down) since the + * free space manager is holding some data structures in memory + * and also because releasing free space can shrink the file's + * 'eoa' value) + */ + if(H5F_ACC_RDWR & H5F_INTENT(f)) { + if(H5MF_close(f, dxpl_id) < 0) + /* Push error, but keep going*/ + HDONE_ERROR(H5E_FILE, H5E_CANTRELEASE, FAIL, "can't release file free space info") + } /* end if */ + + /* Unpin the superblock, since we're about to destroy the cache */ + if(H5AC_unpin_entry(f->shared->sblock) < 0) + /* Push error, but keep going*/ + HDONE_ERROR(H5E_FSPACE, H5E_CANTUNPIN, FAIL, "unable to unpin superblock") + f->shared->sblock = NULL; + } /* end if */ + + /* Remove shared file struct from list of open files */ + if(H5F_sfile_remove(f->shared) < 0) + /* Push error, but keep going*/ + HDONE_ERROR(H5E_FILE, H5E_CANTRELEASE, FAIL, "problems closing file") + + /* Shutdown the metadata cache */ + if(H5AC_dest(f, dxpl_id)) + /* Push error, but keep going*/ + HDONE_ERROR(H5E_FILE, H5E_CANTRELEASE, FAIL, "problems closing file") + + /* + * Do not close the root group since we didn't count it, but free + * the memory associated with it. + */ + if(f->shared->root_grp) { + /* Free the root group */ + if(H5G_root_free(f->shared->root_grp) < 0) + /* Push error, but keep going*/ + HDONE_ERROR(H5E_FILE, H5E_CANTRELEASE, FAIL, "problems closing file") + f->shared->root_grp = NULL; + } /* end if */ + + /* Destroy other components of the file */ + if(H5F_accum_reset(f, dxpl_id, TRUE) < 0) + /* Push error, but keep going*/ + HDONE_ERROR(H5E_FILE, H5E_CANTRELEASE, FAIL, "problems closing file") + if(H5FO_dest(f) < 0) + /* Push error, but keep going*/ + HDONE_ERROR(H5E_FILE, H5E_CANTRELEASE, FAIL, "problems closing file") + f->shared->cwfs = (struct H5HG_heap_t **)H5MM_xfree(f->shared->cwfs); + if(H5G_node_close(f) < 0) + /* Push error, but keep going*/ + HDONE_ERROR(H5E_FILE, H5E_CANTRELEASE, FAIL, "problems closing file") + + /* Destroy file creation properties */ + if(H5I_GENPROP_LST != H5I_get_type(f->shared->fcpl_id)) + /* Push error, but keep going*/ + HDONE_ERROR(H5E_FILE, H5E_BADTYPE, FAIL, "not a property list") + if(H5I_dec_ref(f->shared->fcpl_id) < 0) + /* Push error, but keep going*/ + HDONE_ERROR(H5E_FILE, H5E_CANTDEC, FAIL, "can't close property list") + + /* Only truncate the file on an orderly close, with write-access */ + if(f->closing && (H5F_ACC_RDWR & H5F_INTENT(f))) { + /* Truncate the file to the current allocated size */ + if(H5FD_truncate(f->shared->lf, dxpl_id, (unsigned)TRUE) < 0) + /* Push error, but keep going*/ + HDONE_ERROR(H5E_FILE, H5E_WRITEERROR, FAIL, "low level truncate failed") + } /* end if */ + + /* Close the file */ + if(H5FD_close(f->shared->lf) < 0) + /* Push error, but keep going*/ + HDONE_ERROR(H5E_FILE, H5E_CANTCLOSEFILE, FAIL, "unable to close file") + + /* Free mount table */ + f->shared->mtab.child = (H5F_mount_t *)H5MM_xfree(f->shared->mtab.child); + f->shared->mtab.nalloc = 0; + + /* Destroy shared file struct */ + f->shared = (H5F_file_t *)H5FL_FREE(H5F_file_t, f->shared); + + } else if(f->shared->nrefs > 0) { + /* + * There are other references to the shared part of the file. + * Only decrement the reference count. + */ + --f->shared->nrefs; + } + + /* 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); + f->extpath = (char *)H5MM_xfree(f->extpath); + if(H5FO_top_dest(f) < 0) + HDONE_ERROR(H5E_FILE, H5E_CANTINIT, FAIL, "problems closing file") + f->shared = NULL; + f = H5FL_FREE(H5F_t, f); + + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5F_dest() */ + + +/*------------------------------------------------------------------------- + * Function: H5F_open + * + * Purpose: Opens (or creates) a file. This function understands the + * following flags which are similar in nature to the Posix + * open(2) flags. + * + * H5F_ACC_RDWR: Open with read/write access. If the file is + * currently open for read-only access then it + * will be reopened. Absence of this flag + * implies read-only access. + * + * H5F_ACC_CREAT: Create a new file if it doesn't exist yet. + * The permissions are 0666 bit-wise AND with + * the current umask. H5F_ACC_WRITE must also + * be specified. + * + * H5F_ACC_EXCL: This flag causes H5F_open() to fail if the + * file already exists. + * + * H5F_ACC_TRUNC: The file is truncated and a new HDF5 superblock + * is written. This operation will fail if the + * file is already open. + * + * Unlinking the file name from the group directed graph while + * the file is opened causes the file to continue to exist but + * one will not be able to upgrade the file from read-only + * access to read-write access by reopening it. Disk resources + * for the file are released when all handles to the file are + * closed. NOTE: This paragraph probably only applies to Unix; + * deleting the file name in other OS's has undefined results. + * + * The CREATE_PARMS argument is optional. A null pointer will + * cause the default file creation parameters to be used. + * + * The ACCESS_PARMS argument is optional. A null pointer will + * cause the default file access parameters to be used. + * + * Return: Success: A new file pointer. + * Failure: NULL + * + * Programmer: Robb Matzke + * Tuesday, September 23, 1997 + * + *------------------------------------------------------------------------- + */ +H5F_t * +H5F_open(const char *name, unsigned flags, hid_t fcpl_id, hid_t fapl_id, + hid_t dxpl_id) +{ + H5F_t *file = NULL; /*the success return value */ + H5F_file_t *shared = NULL; /*shared part of `file' */ + H5FD_t *lf = NULL; /*file driver part of `shared' */ + unsigned tent_flags; /*tentative flags */ + H5FD_class_t *drvr; /*file driver class info */ + H5P_genplist_t *a_plist; /*file access property list */ + H5F_close_degree_t fc_degree; /*file close degree */ + H5F_t *ret_value; /*actual return value */ + + FUNC_ENTER_NOAPI(NULL) + + /* + * 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. + * Otherwise it is the application's responsibility to never open the + * same file more than once at a time. + */ + if(NULL == (drvr = H5FD_get_class(fapl_id))) + HGOTO_ERROR(H5E_FILE, H5E_CANTGET, NULL, "unable to retrieve VFL class") + + /* + * Opening a file is a two step process. First we try to open the + * file in a way which doesn't affect its state (like not truncating + * or creating it) so we can compare it with files that are already + * open. If that fails then we try again with the full set of flags + * (only if they're different than the original failed attempt). + * However, if the file driver can't distinquish between files then + * there's no reason to open the file tentatively because it's the + * application's responsibility to prevent this situation (there's no + * way for us to detect it here anyway). + */ + if(drvr->cmp) + tent_flags = flags & ~(H5F_ACC_CREAT|H5F_ACC_TRUNC|H5F_ACC_EXCL); + else + tent_flags = flags; + + if(NULL == (lf = H5FD_open(name, tent_flags, fapl_id, HADDR_UNDEF))) { + if(tent_flags == flags) { +#ifndef H5_USING_MEMCHECKER + time_t mytime = HDtime(NULL); + + HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, "unable to open file: time = %s, name = '%s', tent_flags = %x", HDctime(&mytime), name, tent_flags) +#else /* H5_USING_MEMCHECKER */ + HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, "unable to open file: name = '%s', tent_flags = %x", name, tent_flags) +#endif /* H5_USING_MEMCHECKER */ + } /* end if */ + H5E_clear_stack(NULL); + tent_flags = flags; + if(NULL == (lf = H5FD_open(name, tent_flags, fapl_id, HADDR_UNDEF))) { +#ifndef H5_USING_MEMCHECKER + time_t mytime = HDtime(NULL); + + HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, "unable to open file: time = %s, name = '%s', tent_flags = %x", HDctime(&mytime), name, tent_flags) +#else /* H5_USING_MEMCHECKER */ + HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, "unable to open file: name = '%s', tent_flags = %x", name, tent_flags) +#endif /* H5_USING_MEMCHECKER */ + } /* end if */ + } /* end if */ + + /* Is the file already open? */ + if((shared = H5F_sfile_search(lf)) != NULL) { + /* + * 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 + * exists), or if the new request adds write access (since the + * readers don't expect the file to change under them). + */ + if(H5FD_close(lf) < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, "unable to close low-level file info") + if(flags & H5F_ACC_TRUNC) + HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, "unable to truncate a file which is already open") + if(flags & H5F_ACC_EXCL) + HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, "file exists") + if((flags & H5F_ACC_RDWR) && 0 == (shared->flags & H5F_ACC_RDWR)) + HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, "file is already open for read-only") + + /* Allocate new "high-level" file struct */ + if((file = H5F_new(shared, fcpl_id, fapl_id, NULL)) == NULL) + HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, "unable to create new file object") + } /* end if */ + else { + /* Check if tentative open was good enough */ + if(flags != tent_flags) { + /* + * This file is not yet open by the library and the flags we used to + * open it are different than the desired flags. Close the tentative + * file and open it for real. + */ + if(H5FD_close(lf) < 0) { + file = NULL; /*to prevent destruction of wrong file*/ + HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, "unable to close low-level file info") + } /* end if */ + if(NULL == (lf = H5FD_open(name, flags, fapl_id, HADDR_UNDEF))) { + file = NULL; /*to prevent destruction of wrong file*/ + HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, "unable to open file") + } /* end if */ + } /* end if */ + + if(NULL == (file = H5F_new(NULL, fcpl_id, fapl_id, lf))) + HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, "unable to create new file object") + file->shared->flags = flags; + } /* end else */ + + /* Short cuts */ + shared = file->shared; + lf = shared->lf; + + /* + * The intent at the top level file struct are not necessarily the same as + * the flags at the bottom. The top level describes how the file can be + * accessed through the HDF5 library. The bottom level describes how the + * file can be accessed through the C library. + */ + file->intent = flags; + file->open_name = H5MM_xstrdup(name); + + /* + * Read or write the file superblock, depending on whether the file is + * empty or not. + */ + if(0 == H5FD_get_eof(lf) && (flags & H5F_ACC_RDWR)) { + /* + * We've just opened a fresh new file (or truncated one). We need + * to create & write the superblock. + */ + + /* Initialize information about the superblock and allocate space for it */ + /* (Writes superblock extension messages, if there are any) */ + if(H5F_super_init(file, dxpl_id) < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, NULL, "unable to allocate file superblock") + + /* Create and open the root group */ + /* (This must be after the space for the superblock is allocated in + * the file, since the superblock must be at offset 0) + */ + if(H5G_mkroot(file, dxpl_id, TRUE) < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, NULL, "unable to create/open root group") + } else if (1 == shared->nrefs) { + /* Read the superblock if it hasn't been read before. */ + if(H5F_super_read(file, dxpl_id) < 0) + HGOTO_ERROR(H5E_FILE, H5E_READERROR, NULL, "unable to read superblock") + + /* Open the root group */ + if(H5G_mkroot(file, dxpl_id, FALSE) < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, "unable to read root group") + } /* end if */ + + /* Get the file access property list, for future queries */ + if(NULL == (a_plist = (H5P_genplist_t *)H5I_object(fapl_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "not file access property list") + + /* Store a pointer to the VOL plugin in the file struct */ + if(H5P_get(a_plist, H5F_ACS_VOL_NAME, &(file->vol_cls)) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't get vol plugin") + + /* + * Decide the file close degree. If it's the first time to open the + * file, set the degree to access property list value; if it's the + * second time or later, verify the access property list value matches + * the degree in shared file structure. + */ + if(H5P_get(a_plist, H5F_ACS_CLOSE_DEGREE_NAME, &fc_degree) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't get file close degree") + + if(shared->nrefs == 1) { + if(fc_degree == H5F_CLOSE_DEFAULT) + shared->fc_degree = lf->cls->fc_degree; + else + shared->fc_degree = fc_degree; + } else if(shared->nrefs > 1) { + if(fc_degree == H5F_CLOSE_DEFAULT && shared->fc_degree != lf->cls->fc_degree) + HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, NULL, "file close degree doesn't match") + if(fc_degree != H5F_CLOSE_DEFAULT && fc_degree != shared->fc_degree) + HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, NULL, "file close degree doesn't match") + } /* end if */ + + /* Formulate the absolute path for later search of target file for external links */ + if(H5_build_extpath(name, &file->extpath) < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, NULL, "unable to build extpath") + + /* Formulate the actual file name, after following symlinks, etc. */ + if(H5F_build_actual_name(file, a_plist, name, &file->actual_name) < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, NULL, "unable to build actual name") + + /* Success */ + ret_value = file; + +done: + if(!ret_value && file) + if(H5F_dest(file, dxpl_id, FALSE) < 0) + HDONE_ERROR(H5E_FILE, H5E_CANTCLOSEFILE, NULL, "problems closing file") + + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5F_open() */ + + +/*------------------------------------------------------------------------- + * Function: H5F_flush + * + * Purpose: Flushes cached data. + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Robb Matzke + * matzke@llnl.gov + * Aug 29 1997 + * + *------------------------------------------------------------------------- + */ +herr_t +H5F_flush(H5F_t *f, hid_t dxpl_id, hbool_t closing) +{ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI(FAIL) + + /* Sanity check arguments */ + HDassert(f); + + /* Flush any cached dataset storage raw data */ + if(H5D_flush(f, dxpl_id) < 0) + /* Push error, but keep going*/ + HDONE_ERROR(H5E_CACHE, H5E_CANTFLUSH, FAIL, "unable to flush dataset cache") + + /* Release any space allocated to space aggregators, so that the eoa value + * corresponds to the end of the space written to in the file. + */ + /* (needs to happen before cache flush, with superblock write, since the + * 'eoa' value is written in superblock -QAK) + */ + if(H5MF_free_aggrs(f, dxpl_id) < 0) + /* Push error, but keep going*/ + HDONE_ERROR(H5E_FILE, H5E_CANTRELEASE, FAIL, "can't release file space") + + /* Flush the entire metadata cache */ + if(H5AC_flush(f, dxpl_id) < 0) + /* Push error, but keep going*/ + HDONE_ERROR(H5E_CACHE, H5E_CANTFLUSH, FAIL, "unable to flush metadata cache") + + /* Flush out the metadata accumulator */ + if(H5F_accum_flush(f, dxpl_id) < 0) + /* Push error, but keep going*/ + HDONE_ERROR(H5E_IO, H5E_CANTFLUSH, FAIL, "unable to flush metadata accumulator") + + /* Flush file buffers to disk. */ + if(H5FD_flush(f->shared->lf, dxpl_id, closing) < 0) + /* Push error, but keep going*/ + HDONE_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "low level flush failed") + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5F_flush() */ + + +/*------------------------------------------------------------------------- + * Function: H5F_close + * + * Purpose: Closes a file or causes the close operation to be pended. + * This function is called two ways: from the API it gets called + * by H5Fclose->H5I_dec_ref->H5F_close when H5I_dec_ref() + * decrements the file ID reference count to zero. The file ID + * is removed from the H5I_FILE group by H5I_dec_ref() just + * before H5F_close() is called. If there are open object + * headers then the close is pended by moving the file to the + * H5I_FILE_CLOSING ID group (the f->closing contains the ID + * assigned to file). + * + * This function is also called directly from H5O_close() when + * the last object header is closed for the file and the file + * has a pending close. + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Robb Matzke + * Tuesday, September 23, 1997 + * + *------------------------------------------------------------------------- + */ +herr_t +H5F_close(H5F_t *f) +{ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI_NOINIT + + /* Sanity check */ + HDassert(f); + HDassert(f->file_id > 0); /* This routine should only be called when a file ID's ref count drops to zero */ + + /* Perform checks for "semi" file close degree here, since closing the + * file is not allowed if there are objects still open */ + if(f->shared->fc_degree == H5F_CLOSE_SEMI) { + unsigned nopen_files = 0; /* Number of open files in file/mount hierarchy */ + unsigned nopen_objs = 0; /* Number of open objects in file/mount hierarchy */ + + /* Get the number of open objects and open files on this file/mount hierarchy */ + if(H5F_mount_count_ids(f, &nopen_files, &nopen_objs) < 0) + HGOTO_ERROR(H5E_SYM, H5E_MOUNT, FAIL, "problem checking mount hierarchy") + + /* If there are no other file IDs open on this file/mount hier., but + * there are still open objects, issue an error and bail out now, + * without decrementing the file ID's reference count and triggering + * a "real" attempt at closing the file */ + if(nopen_files == 1 && nopen_objs > 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTCLOSEFILE, FAIL, "can't close file, there are objects still open") + } /* end if */ + + /* Reset the file ID for this file */ + f->file_id = -1; + + /* Attempt to close the file/mount hierarchy */ + if(H5F_try_close(f) < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTCLOSEFILE, FAIL, "can't close file") + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5F_close() */ + + +/*------------------------------------------------------------------------- + * Function: H5F_try_close + * + * Purpose: Attempts to close a file due to one of several actions: + * - The reference count on the file ID dropped to zero + * - The last open object was closed in the file + * - The file was unmounted + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Quincey Koziol + * Tuesday, July 19, 2005 + * + *------------------------------------------------------------------------- + */ +herr_t +H5F_try_close(H5F_t *f) +{ + unsigned nopen_files = 0; /* Number of open files in file/mount hierarchy */ + unsigned nopen_objs = 0; /* Number of open objects in file/mount hierarchy */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI_NOINIT + + /* Sanity check */ + HDassert(f); + HDassert(f->shared); + + /* Check if this file is already in the process of closing */ + if(f->closing) + HGOTO_DONE(SUCCEED) + + /* Get the number of open objects and open files on this file/mount hierarchy */ + if(H5F_mount_count_ids(f, &nopen_files, &nopen_objs) < 0) + HGOTO_ERROR(H5E_SYM, H5E_MOUNT, FAIL, "problem checking mount hierarchy") + + /* + * Close file according to close degree: + * + * H5F_CLOSE_WEAK: if there are still objects open, wait until + * they are all closed. + * H5F_CLOSE_SEMI: if there are still objects open, return fail; + * otherwise, close file. + * H5F_CLOSE_STRONG: if there are still objects open, close them + * first, then close file. + */ + switch(f->shared->fc_degree) { + case H5F_CLOSE_WEAK: + /* + * If file or object IDS are still open then delay deletion of + * resources until they have all been closed. Flush all + * caches and update the object header anyway so that failing to + * close all objects isn't a major problem. + */ + if((nopen_files + nopen_objs) > 0) + HGOTO_DONE(SUCCEED) + break; + + case H5F_CLOSE_SEMI: + /* Can leave safely if file IDs are still open on this file */ + if(nopen_files > 0) + HGOTO_DONE(SUCCEED) + + /* Sanity check: If close degree if "semi" and we have gotten this + * far and there are objects left open, bail out now */ + HDassert(nopen_files == 0 && nopen_objs == 0); + + /* If we've gotten this far (ie. there are no open objects in the file), fall through to flush & close */ + break; + + case H5F_CLOSE_STRONG: + /* If there are other open files in the hierarchy, we can leave now */ + if(nopen_files > 0) + HGOTO_DONE(SUCCEED) + + /* If we've gotten this far (ie. there are no open file IDs in the file/mount hierarchy), fall through to flush & close */ + break; + + case H5F_CLOSE_DEFAULT: + default: + HGOTO_ERROR(H5E_FILE, H5E_CANTCLOSEFILE, FAIL, "can't close file, unknown file close degree") + } /* end switch */ + + /* Mark this file as closing (prevents re-entering file shutdown code below) */ + f->closing = TRUE; + + /* If the file close degree is "strong", close all the open objects in this file */ + if(f->shared->fc_degree == H5F_CLOSE_STRONG) { + HDassert(nopen_files == 0); + + /* Forced close of all opened objects in this file */ + if(f->nopen_objs > 0) { + size_t obj_count; /* # of open objects */ + hid_t objs[128]; /* Array of objects to close */ + herr_t result; /* Local result from obj ID query */ + size_t u; /* Local index variable */ + + /* Get the list of IDs of open dataset, group, & attribute objects */ + while((result = H5F_get_obj_ids(f, H5F_OBJ_LOCAL | H5F_OBJ_DATASET | H5F_OBJ_GROUP | H5F_OBJ_ATTR, (int)(sizeof(objs) / sizeof(objs[0])), objs, FALSE, &obj_count)) <= 0 + && obj_count != 0 ) { + + /* Try to close all the open objects in this file */ + for(u = 0; u < obj_count; u++) + if(H5I_dec_ref(objs[u]) < 0) + HGOTO_ERROR(H5E_ATOM, H5E_CLOSEERROR, FAIL, "can't close object") + } /* end while */ + if(result < 0) + HGOTO_ERROR(H5E_INTERNAL, H5E_BADITER, FAIL, "H5F_get_obj_ids failed(1)") + + /* Get the list of IDs of open named datatype objects */ + /* (Do this separately from the dataset & attribute IDs, because + * they could be using one of the named datatypes and then the + * open named datatype ID will get closed twice) + */ + while((result = H5F_get_obj_ids(f, H5F_OBJ_LOCAL | H5F_OBJ_DATATYPE, (int)(sizeof(objs) / sizeof(objs[0])), objs, FALSE, &obj_count)) <= 0 + && obj_count != 0) { + + /* Try to close all the open objects in this file */ + for(u = 0; u < obj_count; u++) + if(H5I_dec_ref(objs[u]) < 0) + HGOTO_ERROR(H5E_ATOM, H5E_CLOSEERROR, FAIL, "can't close object") + } /* end while */ + if(result < 0) + HGOTO_ERROR(H5E_INTERNAL, H5E_BADITER, FAIL, "H5F_get_obj_ids failed(2)") + } /* end if */ + } /* end if */ + + /* Check if this is a child file in a mounting hierarchy & proceed up the + * hierarchy if so. + */ + if(f->parent) { + if(H5F_try_close(f->parent) < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTCLOSEFILE, FAIL, "can't close parent file") + } + /* Unmount and close each child before closing the current file. */ + if(H5F_close_mounts(f) < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTCLOSEFILE, FAIL, "can't unmount child files") + + /* If there is more than one reference to the shared file struct and the + * file has an external file cache, we should see if it can be closed. This + * can happen if a cycle is formed with external file caches */ + if(f->shared->efc && (f->shared->nrefs > 1)) + if(H5F_efc_try_close(f) < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTRELEASE, FAIL, "can't attempt to close EFC") + + /* Delay flush until the shared file struct is closed, in H5F_dest. If the + * application called H5Fclose, it would have been flushed in that function + * (unless it will have been flushed in H5F_dest anyways). */ + + /* + * Destroy the H5F_t struct and decrement the reference count for the + * shared H5F_file_t struct. If the reference count for the H5F_file_t + * struct reaches zero then destroy it also. + */ + if(H5F_dest(f, H5AC_dxpl_id, TRUE) < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTCLOSEFILE, FAIL, "problems closing file") + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5F_try_close() */ + + +/*------------------------------------------------------------------------- + * Function: H5F_reopen + * + * Purpose: Reopen a file. The new file handle which is returned points + * to the same file as the specified file handle. Both handles + * share caches and other information. The only difference + * between the handles is that the new handle is not mounted + * anywhere and no files are mounted on it. + * + * Return: Success: New file ID + * + * Failure: FAIL + * + * Programmer: Robb Matzke + * Friday, October 16, 1998 + * + * Modifications: + * Quincey Koziol, May 14, 2002 + * Keep old file's read/write intent in reopened file. + * + *------------------------------------------------------------------------- + */ +hid_t +H5F_reopen(H5F_t *f) +{ + H5F_t *new_file = NULL; + hid_t ret_value; + + FUNC_ENTER_NOAPI_NOINIT + + /* Get a new "top level" file struct, sharing the same "low level" file struct */ + if(NULL == (new_file = H5F_new(f->shared, H5P_FILE_CREATE_DEFAULT, + H5P_FILE_ACCESS_DEFAULT, NULL))) + HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, FAIL, "unable to reopen file") + + /* Keep old file's read/write intent in new file */ + new_file->intent = f->intent; + /* Duplicate old file's names */ + new_file->open_name = H5MM_xstrdup(f->open_name); + new_file->actual_name = H5MM_xstrdup(f->actual_name); + + if((ret_value = H5I_register(H5I_FILE, new_file, TRUE)) < 0) + HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL, "unable to atomize file handle") + + /* Keep this ID in file object structure */ + new_file->file_id = ret_value; + +done: + if(ret_value < 0 && new_file) + if(H5F_dest(new_file, H5AC_dxpl_id, FALSE) < 0) + HDONE_ERROR(H5E_FILE, H5E_CANTCLOSEFILE, FAIL, "can't close file") + + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5F_reopen() */ + + +/*------------------------------------------------------------------------- + * Function: H5F_get_id + * + * Purpose: Get the file ID, incrementing it, or "resurrecting" it as + * appropriate. + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Raymond Lu + * Oct 29, 2003 + * + *------------------------------------------------------------------------- + */ +hid_t +H5F_get_id(H5F_t *file, hbool_t app_ref) +{ + hid_t ret_value; + + FUNC_ENTER_NOAPI_NOINIT + + HDassert(file); + + if(file->file_id == -1) { + /* Get an atom for the file */ + if((file->file_id = H5I_register(H5I_FILE, file, app_ref)) < 0) + HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL, "unable to atomize file") + + /* attach VOL information to the ID */ + if (H5I_register_aux(file->file_id, file->vol_cls, (H5I_free_t)H5VL_close) < 0) + HGOTO_ERROR(H5E_VOL, H5E_CANTINIT, FAIL, "can't attach vol info to ID") + } else { + /* Increment reference count on atom. */ + if(H5I_inc_ref(file->file_id, app_ref) < 0) + HGOTO_ERROR(H5E_ATOM, H5E_CANTSET, FAIL, "incrementing file ID failed") + } /* end else */ + + ret_value = file->file_id; + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5F_get_id() */ + + +/*------------------------------------------------------------------------- + * Function: H5F_incr_nopen_objs + * + * Purpose: Increment the number of open objects for a file. + * + * Return: Success: The number of open objects, after the increment + * + * Failure: (can't happen) + * + * Programmer: Quincey Koziol + * koziol@hdfgroup.org + * Mar 6 2007 + * + *------------------------------------------------------------------------- + */ +unsigned +H5F_incr_nopen_objs(H5F_t *f) +{ + /* Use FUNC_ENTER_NOAPI_NOINIT_NOERR here to avoid performance issues */ + FUNC_ENTER_NOAPI_NOINIT_NOERR + + HDassert(f); + + FUNC_LEAVE_NOAPI(++f->nopen_objs) +} /* end H5F_incr_nopen_objs() */ + + +/*------------------------------------------------------------------------- + * Function: H5F_decr_nopen_objs + * + * Purpose: Decrement the number of open objects for a file. + * + * Return: Success: The number of open objects, after the decrement + * + * Failure: (can't happen) + * + * Programmer: Quincey Koziol + * koziol@hdfgroup.org + * Mar 6 2007 + * + *------------------------------------------------------------------------- + */ +unsigned +H5F_decr_nopen_objs(H5F_t *f) +{ + /* Use FUNC_ENTER_NOAPI_NOINIT_NOERR here to avoid performance issues */ + FUNC_ENTER_NOAPI_NOINIT_NOERR + + HDassert(f); + + FUNC_LEAVE_NOAPI(--f->nopen_objs) +} /* end H5F_decr_nopen_objs() */ + + +/*------------------------------------------------------------------------- + * Function: H5F_build_actual_name + * + * Purpose: Retrieve the name of a file, after following symlinks, etc. + * + * Note: Currently only working for "POSIX I/O compatible" VFDs + * + * Return: Success: 0 + * Failure: -1 + * + * Programmer: Quincey Koziol + * November 25, 2009 + * + *------------------------------------------------------------------------- + */ +static herr_t +H5F_build_actual_name(const H5F_t *f, const H5P_genplist_t *fapl, const char *name, + char **actual_name/*out*/) +{ + hid_t new_fapl_id = -1; /* ID for duplicated FAPL */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI_NOINIT + + /* Sanity check */ + HDassert(f); + HDassert(fapl); + HDassert(name); + HDassert(actual_name); + + /* Clear actual name pointer to begin with */ + *actual_name = NULL; + +/* Assume that if the OS can't create symlinks, that we don't need to worry + * about resolving them either. -QAK + */ +#ifdef H5_HAVE_SYMLINK + /* Check for POSIX I/O compatible file handle */ + if(H5F_HAS_FEATURE(f, H5FD_FEAT_POSIX_COMPAT_HANDLE)) { + h5_stat_t lst; /* Stat info from lstat() call */ + + /* Call lstat() on the file's name */ + if(HDlstat(name, &lst) < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "can't retrieve stat info for file") + + /* Check for symbolic link */ + if(S_IFLNK == (lst.st_mode & S_IFMT)) { + H5P_genplist_t *new_fapl; /* Duplicated FAPL */ + int *fd; /* POSIX I/O file descriptor */ + h5_stat_t st; /* Stat info from stat() call */ + h5_stat_t fst; /* Stat info from fstat() call */ + char realname[PATH_MAX]; /* Fully resolved path name of file */ + hbool_t want_posix_fd; /* Flag for retrieving file descriptor from VFD */ + + /* Perform a sanity check that the file or link wasn't switched + * between when we opened it and when we called lstat(). This is + * according to the security best practices for lstat() documented + * here: https://www.securecoding.cert.org/confluence/display/seccode/POS35-C.+Avoid+race+conditions+while+checking+for+the+existence+of+a+symbolic+link + */ + + /* Copy the FAPL object to modify */ + if((new_fapl_id = H5P_copy_plist(fapl, FALSE)) < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTCOPY, FAIL, "unable to copy file access property list") + if(NULL == (new_fapl = (H5P_genplist_t *)H5I_object(new_fapl_id))) + HGOTO_ERROR(H5E_FILE, H5E_CANTCREATE, FAIL, "can't get property list") + + /* Set the character encoding on the new property list */ + want_posix_fd = TRUE; + if(H5P_set(new_fapl, H5F_ACS_WANT_POSIX_FD_NAME, &want_posix_fd) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set character encoding") + + /* Retrieve the file handle */ + if(H5F_get_vfd_handle(f, new_fapl_id, (void **)&fd) < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "can't retrieve POSIX file descriptor") + + /* Stat the filename we're resolving */ + if(HDstat(name, &st) < 0) + HSYS_GOTO_ERROR(H5E_FILE, H5E_BADFILE, FAIL, "unable to stat file") + + /* Stat the file we opened */ + if(HDfstat(*fd, &fst) < 0) + HSYS_GOTO_ERROR(H5E_FILE, H5E_BADFILE, FAIL, "unable to fstat file") + + /* Verify that the files are really the same */ + if(st.st_mode != fst.st_mode || st.st_ino != fst.st_ino || st.st_dev != fst.st_dev) + HGOTO_ERROR(H5E_FILE, H5E_BADVALUE, FAIL, "files' st_ino or st_dev fields changed!") + + /* Get the resolved path for the file name */ + if(NULL == HDrealpath(name, realname)) + HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "can't retrieve real path for file") + + /* Duplicate the resolved path for the file name */ + if(NULL == (*actual_name = (char *)H5MM_strdup(realname))) + HGOTO_ERROR(H5E_FILE, H5E_CANTALLOC, FAIL, "can't duplicate real path") + } /* end if */ + } /* end if */ +#endif /* H5_HAVE_SYMLINK */ + + /* Check if we've resolved the file's name */ + if(NULL == *actual_name) { + /* Just duplicate the name used to open the file */ + if(NULL == (*actual_name = (char *)H5MM_strdup(name))) + HGOTO_ERROR(H5E_FILE, H5E_CANTALLOC, FAIL, "can't duplicate open name") + } /* end else */ + +done: + if(new_fapl_id > 0 && H5Pclose(new_fapl_id) < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTCLOSEOBJ, FAIL, "can't close duplicated FAPL") + + FUNC_LEAVE_NOAPI(ret_value) +} /* H5F_build_actual_name() */ + + +/*------------------------------------------------------------------------- + * Function: H5F_addr_encode_len + * + * Purpose: Encodes an address into the buffer pointed to by *PP and + * then increments the pointer to the first byte after the + * address. An undefined value is stored as all 1's. + * + * Return: void + * + * Programmer: Robb Matzke + * Friday, November 7, 1997 + * + *------------------------------------------------------------------------- + */ +void +H5F_addr_encode_len(size_t addr_len, uint8_t **pp/*in,out*/, haddr_t addr) +{ + unsigned u; /* Local index variable */ + + /* Use FUNC_ENTER_NOAPI_NOINIT_NOERR here to avoid performance issues */ + FUNC_ENTER_NOAPI_NOINIT_NOERR + + HDassert(addr_len); + HDassert(pp && *pp); + + if(H5F_addr_defined(addr)) { + for(u = 0; u < addr_len; u++) { + *(*pp)++ = (uint8_t)(addr & 0xff); + addr >>= 8; + } /* end for */ + HDassert("overflow" && 0 == addr); + } /* end if */ + else { + for(u = 0; u < addr_len; u++) + *(*pp)++ = 0xff; + } /* end else */ + + FUNC_LEAVE_NOAPI_VOID +} /* end H5F_addr_encode_len() */ + + +/*------------------------------------------------------------------------- + * Function: H5F_addr_encode + * + * Purpose: Encodes an address into the buffer pointed to by *PP and + * then increments the pointer to the first byte after the + * address. An undefined value is stored as all 1's. + * + * Return: void + * + * Programmer: Robb Matzke + * Friday, November 7, 1997 + * + *------------------------------------------------------------------------- + */ +void +H5F_addr_encode(const H5F_t *f, uint8_t **pp/*in,out*/, haddr_t addr) +{ + /* Use FUNC_ENTER_NOAPI_NOINIT_NOERR here to avoid performance issues */ + FUNC_ENTER_NOAPI_NOINIT_NOERR + + HDassert(f); + + H5F_addr_encode_len(H5F_SIZEOF_ADDR(f), pp, addr); + + FUNC_LEAVE_NOAPI_VOID +} /* end H5F_addr_encode() */ + + +/*------------------------------------------------------------------------- + * Function: H5F_addr_decode_len + * + * Purpose: Decodes an address from the buffer pointed to by *PP and + * updates the pointer to point to the next byte after the + * address. + * + * If the value read is all 1's then the address is returned + * with an undefined value. + * + * Return: void + * + * Programmer: Robb Matzke + * Friday, November 7, 1997 + * + *------------------------------------------------------------------------- + */ +void +H5F_addr_decode_len(size_t addr_len, const uint8_t **pp/*in,out*/, haddr_t *addr_p/*out*/) +{ + hbool_t all_zero = TRUE; /* True if address was all zeroes */ + unsigned u; /* Local index variable */ + + /* Use FUNC_ENTER_NOAPI_NOINIT_NOERR here to avoid performance issues */ + FUNC_ENTER_NOAPI_NOINIT_NOERR + + HDassert(addr_len); + HDassert(pp && *pp); + HDassert(addr_p); + + /* Reset value in destination */ + *addr_p = 0; + + /* Decode bytes from address */ + for(u = 0; u < addr_len; u++) { + uint8_t c; /* Local decoded byte */ + + /* Get decoded byte (and advance pointer) */ + c = *(*pp)++; + + /* Check for non-undefined address byte value */ + if(c != 0xff) + all_zero = FALSE; + + if(u < sizeof(*addr_p)) { + haddr_t tmp = c; /* Local copy of address, for casting */ + + /* Shift decoded byte to correct position */ + tmp <<= (u * 8); /*use tmp to get casting right */ + + /* Merge into already decoded bytes */ + *addr_p |= tmp; + } /* end if */ + else + if(!all_zero) + HDassert(0 == **pp); /*overflow */ + } /* end for */ + + /* If 'all_zero' is still TRUE, the address was entirely composed of '0xff' + * bytes, which is the encoded form of 'HADDR_UNDEF', so set the destination + * to that value */ + if(all_zero) + *addr_p = HADDR_UNDEF; + + FUNC_LEAVE_NOAPI_VOID +} /* end H5F_addr_decode_len() */ + + +/*------------------------------------------------------------------------- + * Function: H5F_addr_decode + * + * Purpose: Decodes an address from the buffer pointed to by *PP and + * updates the pointer to point to the next byte after the + * address. + * + * If the value read is all 1's then the address is returned + * with an undefined value. + * + * Return: void + * + * Programmer: Robb Matzke + * Friday, November 7, 1997 + * + *------------------------------------------------------------------------- + */ +void +H5F_addr_decode(const H5F_t *f, const uint8_t **pp/*in,out*/, haddr_t *addr_p/*out*/) +{ + /* Use FUNC_ENTER_NOAPI_NOINIT_NOERR here to avoid performance issues */ + FUNC_ENTER_NOAPI_NOINIT_NOERR + + HDassert(f); + + H5F_addr_decode_len(H5F_SIZEOF_ADDR(f), pp, addr_p); + + FUNC_LEAVE_NOAPI_VOID +} /* end H5F_addr_decode() */ + + +/*------------------------------------------------------------------------- + * Function: H5F_get_file_image + * + * Purpose: Private version of H5Fget_file_image + * + * Return: Success: Bytes copied / number of bytes needed. + * Failure: negative value + * + * Programmer: John Mainzer + * 11/15/11 + * + *------------------------------------------------------------------------- + */ +ssize_t +H5F_get_file_image(H5F_t *file, void *buf_ptr, size_t buf_len) +{ + H5FD_t *fd_ptr; /* file driver */ + haddr_t eoa; /* End of file address */ + ssize_t ret_value; /* Return value */ + + FUNC_ENTER_NOAPI_NOINIT + + /* Check args */ + if(!file || !file->shared || !file->shared->lf) + HGOTO_ERROR(H5E_FILE, H5E_BADVALUE, FAIL, "file_id yields invalid file pointer") + fd_ptr = file->shared->lf; + if(!fd_ptr->cls) + HGOTO_ERROR(H5E_FILE, H5E_BADVALUE, FAIL, "fd_ptr yields invalid class pointer") + + /* the address space used by the split and multi file drivers is not + * a good fit for this call. Since the plan is to depreciate these + * drivers anyway, don't bother to do a "force fit". + * + * The following clause tests for the multi file driver, and fails + * if the supplied file has the multi file driver as its top level + * file driver. However, this test will not work if there is some + * other file driver sitting on top of the multi file driver. + * + * I'm not sure if this is possible at present, but in all likelyhood, + * it will become possible in the future. On the other hand, we may + * remove the split/multi file drivers before then. + * + * I am leaving this solution in for now, but we should review it, + * and improve the solution if necessary. + * + * JRM -- 11/11/22 + */ + if(HDstrcmp(fd_ptr->cls->name, "multi") == 0) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "Not supported for multi file driver.") + + /* While the family file driver is conceptually fully compatible + * with the get file image operation, it sets a file driver message + * in the super block that prevents the image being opened with any + * driver other than the family file driver. Needless to say, this + * rather defeats the purpose of the get file image operation. + * + * While this problem is quire solvable, the required time and + * resources are lacking at present. Hence, for now, we don't + * allow the get file image operation to be perfomed on files + * opened with the family file driver. + * + * Observe that the following test only looks at the top level + * driver, and fails if there is some other driver sitting on to + * of the family file driver. + * + * I don't think this can happen at present, but that may change + * in the future. + * JRM -- 12/21/11 + */ + if(HDstrcmp(fd_ptr->cls->name, "family") == 0) + HGOTO_ERROR(H5E_FILE, H5E_BADVALUE, FAIL, "Not supported for family file driver.") + + + /* Go get the actual file size */ + if(HADDR_UNDEF == (eoa = H5FD_get_eoa(file->shared->lf, H5FD_MEM_DEFAULT))) + HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "unable to get file size") + + /* set ret_value = to eoa -- will overwrite this if appropriate */ + ret_value = (ssize_t)eoa; + + /* test to see if a buffer was provided -- if not, we are done */ + if(buf_ptr != NULL) { + size_t space_needed; /* size of file image */ + + /* Check for buffer too small */ + if((haddr_t)buf_len < eoa) + HGOTO_ERROR(H5E_FILE, H5E_BADVALUE, FAIL, "supplied buffer too small") + + space_needed = (size_t)eoa; + + /* read in the file image */ + /* (Note compensation for base address addition in internal routine) */ + if(H5FD_read(fd_ptr, H5AC_ind_dxpl_id, H5FD_MEM_DEFAULT, 0, space_needed, buf_ptr) < 0) + HGOTO_ERROR(H5E_FILE, H5E_READERROR, FAIL, "file image read request failed") + } /* end if */ + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* H5F_get_file_image() */ + + +/*------------------------------------------------------------------------- + * Function: H5F_set_grp_btree_shared + * + * Purpose: Set the grp_btree_shared field with a valid ref-count pointer. + * + * Return: Success: SUCCEED + * Failure: FAIL + * + * Programmer: Quincey Koziol + * 7/19/11 + * + *------------------------------------------------------------------------- + */ +herr_t +H5F_set_grp_btree_shared(H5F_t *f, H5RC_t *rc) +{ + /* Use FUNC_ENTER_NOAPI_NOINIT_NOERR here to avoid performance issues */ + FUNC_ENTER_NOAPI_NOINIT_NOERR + + /* Sanity check */ + HDassert(f); + HDassert(f->shared); + HDassert(rc); + + f->shared->grp_btree_shared = rc; + + FUNC_LEAVE_NOAPI(SUCCEED) +} /* H5F_set_grp_btree_shared() */ + + +/*------------------------------------------------------------------------- + * Function: H5F_set_sohm_addr + * + * Purpose: Set the sohm_addr field with a new value. + * + * Return: Success: SUCCEED + * Failure: FAIL + * + * Programmer: Quincey Koziol + * 7/20/11 + * + *------------------------------------------------------------------------- + */ +herr_t +H5F_set_sohm_addr(H5F_t *f, haddr_t addr) +{ + /* Use FUNC_ENTER_NOAPI_NOINIT_NOERR here to avoid performance issues */ + FUNC_ENTER_NOAPI_NOINIT_NOERR + + /* Sanity check */ + HDassert(f); + HDassert(f->shared); + + f->shared->sohm_addr = addr; + + FUNC_LEAVE_NOAPI(SUCCEED) +} /* H5F_set_sohm_addr() */ + + +/*------------------------------------------------------------------------- + * Function: H5F_set_sohm_vers + * + * Purpose: Set the sohm_vers field with a new value. + * + * Return: Success: SUCCEED + * Failure: FAIL + * + * Programmer: Quincey Koziol + * 7/20/11 + * + *------------------------------------------------------------------------- + */ +herr_t +H5F_set_sohm_vers(H5F_t *f, unsigned vers) +{ + /* Use FUNC_ENTER_NOAPI_NOINIT_NOERR here to avoid performance issues */ + FUNC_ENTER_NOAPI_NOINIT_NOERR + + /* Sanity check */ + HDassert(f); + HDassert(f->shared); + + f->shared->sohm_vers = vers; + + FUNC_LEAVE_NOAPI(SUCCEED) +} /* H5F_set_sohm_vers() */ + + +/*------------------------------------------------------------------------- + * Function: H5F_set_sohm_nindexes + * + * Purpose: Set the sohm_nindexes field with a new value. + * + * Return: Success: SUCCEED + * Failure: FAIL + * + * Programmer: Quincey Koziol + * 7/20/11 + * + *------------------------------------------------------------------------- + */ +herr_t +H5F_set_sohm_nindexes(H5F_t *f, unsigned nindexes) +{ + /* Use FUNC_ENTER_NOAPI_NOINIT_NOERR here to avoid performance issues */ + FUNC_ENTER_NOAPI_NOINIT_NOERR + + /* Sanity check */ + HDassert(f); + HDassert(f->shared); + + f->shared->sohm_nindexes = nindexes; + + FUNC_LEAVE_NOAPI(SUCCEED) +} /* H5F_set_sohm_nindexes() */ + + +/*------------------------------------------------------------------------- + * Function: H5F_set_store_msg_crt_idx + * + * Purpose: Set the store_msg_crt_idx field with a new value. + * + * Return: Success: SUCCEED + * Failure: FAIL + * + * Programmer: Quincey Koziol + * 7/20/11 + * + *------------------------------------------------------------------------- + */ +herr_t +H5F_set_store_msg_crt_idx(H5F_t *f, hbool_t flag) +{ + /* Use FUNC_ENTER_NOAPI_NOINIT_NOERR here to avoid performance issues */ + FUNC_ENTER_NOAPI_NOINIT_NOERR + + /* Sanity check */ + HDassert(f); + HDassert(f->shared); + + f->shared->store_msg_crt_idx = flag; + + FUNC_LEAVE_NOAPI(SUCCEED) +} /* H5F_set_store_msg_crt_idx() */ diff --git a/src/H5Fprivate.h b/src/H5Fprivate.h index e163f85..53698a7 100644 --- a/src/H5Fprivate.h +++ b/src/H5Fprivate.h @@ -39,6 +39,20 @@ typedef struct H5F_file_t H5F_file_t; /* Block aggregation structure */ typedef struct H5F_blk_aggr_t H5F_blk_aggr_t; +/* User data for traversal routine to get ID counts */ +typedef struct { + ssize_t *obj_count; /* number of objects counted so far */ + unsigned types; /* types of objects to be counted */ +} H5F_trav_obj_cnt_t; + +/* User data for traversal routine to get ID lists */ +typedef struct { + size_t max_objs; + hid_t *oid_list; + ssize_t *obj_count; /* number of objects counted so far */ + unsigned types; /* types of objects to be counted */ +} H5F_trav_obj_ids_t; + /* * Encode and decode macros for file meta-data. * Currently, all file meta-data is little-endian. @@ -517,6 +531,11 @@ H5_DLL herr_t H5F_close(H5F_t *f); H5_DLL herr_t H5F_try_close(H5F_t *f); H5_DLL hid_t H5F_reopen(H5F_t *f); H5_DLL htri_t H5F_is_hdf5(const char *name); +H5_DLL herr_t H5F_get_objects(const H5F_t *f, unsigned types, size_t max_index, hid_t *obj_id_list, hbool_t app_ref, size_t *obj_id_count_ptr); +H5_DLL int H5F_get_objects_cb(void *obj_ptr, hid_t obj_id, void *key); +H5_DLL int H5F_get_obj_count_cb(void *obj_ptr, hid_t obj_id, void *key); +H5_DLL int H5F_get_obj_ids_cb(void *obj_ptr, hid_t obj_id, void *key); + /* Functions than retrieve values from the file struct */ H5_DLL unsigned H5F_get_intent(const H5F_t *f); diff --git a/src/Makefile.am b/src/Makefile.am index 44b28bf..82d5690 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -53,7 +53,7 @@ libhdf5_la_SOURCES= H5.c H5checksum.c H5dbg.c H5system.c H5timer.c H5trace.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 \ - H5F.c H5Faccum.c H5Fcwfs.c \ + H5F.c H5Fint.c H5Faccum.c H5Fcwfs.c \ H5Fdbg.c H5Fdeprec.c H5Fefc.c H5Ffake.c H5Fio.c \ H5Fmount.c H5Fmpi.c H5Fquery.c \ H5Fsfile.c H5Fsuper.c H5Fsuper_cache.c H5Ftest.c \ diff --git a/src/Makefile.in b/src/Makefile.in index ae9be00..cfdf496 100644 --- a/src/Makefile.in +++ b/src/Makefile.in @@ -106,48 +106,48 @@ am_libhdf5_la_OBJECTS = H5.lo H5checksum.lo H5dbg.lo H5system.lo \ H5Dtest.lo H5E.lo H5Edeprec.lo H5Eint.lo H5EA.lo H5EAcache.lo \ H5EAdbg.lo H5EAdblkpage.lo H5EAdblock.lo H5EAhdr.lo \ H5EAiblock.lo H5EAint.lo H5EAsblock.lo H5EAstat.lo H5EAtest.lo \ - H5F.lo H5Faccum.lo H5Fcwfs.lo H5Fdbg.lo H5Fdeprec.lo H5Fefc.lo \ - H5Ffake.lo H5Fio.lo H5Fmount.lo H5Fmpi.lo H5Fquery.lo \ - H5Fsfile.lo H5Fsuper.lo H5Fsuper_cache.lo H5Ftest.lo H5FA.lo \ - H5FAcache.lo H5FAdbg.lo H5FAdblock.lo H5FAdblkpage.lo \ - H5FAhdr.lo H5FAstat.lo H5FAtest.lo H5VL.lo H5VLint.lo \ - H5VLnative.lo H5VLdummy.lo H5FD.lo H5FDcore.lo H5FDdirect.lo \ - H5FDfamily.lo H5FDint.lo H5FDlog.lo H5FDmpi.lo H5FDmpio.lo \ - H5FDmpiposix.lo H5FDmulti.lo H5FDsec2.lo H5FDspace.lo \ - H5FDstdio.lo H5FL.lo H5FO.lo H5FS.lo H5FScache.lo H5FSdbg.lo \ - H5FSsection.lo H5FSstat.lo H5FStest.lo H5G.lo H5Gbtree2.lo \ - H5Gcache.lo H5Gcompact.lo H5Gdense.lo H5Gdeprec.lo H5Gent.lo \ - H5Gint.lo H5Glink.lo H5Gloc.lo H5Gname.lo H5Gnode.lo H5Gobj.lo \ - H5Goh.lo H5Groot.lo H5Gstab.lo H5Gtest.lo H5Gtraverse.lo \ - H5HF.lo H5HFbtree2.lo H5HFcache.lo H5HFdbg.lo H5HFdblock.lo \ - H5HFdtable.lo H5HFhdr.lo H5HFhuge.lo H5HFiblock.lo H5HFiter.lo \ - H5HFman.lo H5HFsection.lo H5HFspace.lo H5HFstat.lo H5HFtest.lo \ - H5HFtiny.lo H5HG.lo H5HGcache.lo H5HGdbg.lo H5HGquery.lo \ - H5HL.lo H5HLcache.lo H5HLdbg.lo H5HLint.lo H5HP.lo H5I.lo \ - H5Itest.lo H5L.lo H5Lexternal.lo H5lib_settings.lo H5MF.lo \ - H5MFaggr.lo H5MFdbg.lo H5MFsection.lo H5MM.lo H5MP.lo \ - H5MPtest.lo H5O.lo H5Oainfo.lo H5Oalloc.lo H5Oattr.lo \ - H5Oattribute.lo H5Obogus.lo H5Obtreek.lo H5Ocache.lo \ - H5Ochunk.lo H5Ocont.lo H5Ocopy.lo H5Odbg.lo H5Odrvinfo.lo \ - H5Odtype.lo H5Oefl.lo H5Ofill.lo H5Ofsinfo.lo H5Oginfo.lo \ - H5Olayout.lo H5Olinfo.lo H5Olink.lo H5Omessage.lo H5Omtime.lo \ - H5Oname.lo H5Onull.lo H5Opline.lo H5Orefcount.lo H5Osdspace.lo \ - H5Oshared.lo H5Ostab.lo H5Oshmesg.lo H5Otest.lo H5Ounknown.lo \ - H5P.lo H5Pacpl.lo H5Pdapl.lo H5Pdcpl.lo H5Pdeprec.lo \ - H5Pdxpl.lo H5Pfapl.lo H5Pfcpl.lo H5Pfmpl.lo H5Pgcpl.lo \ - H5Pint.lo H5Plapl.lo H5Plcpl.lo H5Pocpl.lo H5Pocpypl.lo \ - H5Pstrcpl.lo H5Ptest.lo H5R.lo H5Rdeprec.lo H5RC.lo H5RS.lo \ - H5S.lo H5Sall.lo H5Sdbg.lo H5Shyper.lo H5Smpio.lo H5Snone.lo \ - H5Spoint.lo H5Sselect.lo H5Stest.lo H5SL.lo H5SM.lo \ - H5SMbtree2.lo H5SMcache.lo H5SMmessage.lo H5SMtest.lo H5ST.lo \ - H5T.lo H5Tarray.lo H5Tbit.lo H5Tcommit.lo H5Tcompound.lo \ - H5Tconv.lo H5Tcset.lo H5Tdbg.lo H5Tdeprec.lo H5Tenum.lo \ - H5Tfields.lo H5Tfixed.lo H5Tfloat.lo H5Tinit.lo H5Tnative.lo \ - H5Toffset.lo H5Toh.lo H5Topaque.lo H5Torder.lo H5Tpad.lo \ - H5Tprecis.lo H5Tstrpad.lo H5Tvisit.lo H5Tvlen.lo H5TS.lo \ - H5V.lo H5WB.lo H5Z.lo H5Zdeflate.lo H5Zfletcher32.lo \ - H5Znbit.lo H5Zshuffle.lo H5Zszip.lo H5Zscaleoffset.lo \ - H5Ztrans.lo + H5F.lo H5Fint.lo H5Faccum.lo H5Fcwfs.lo H5Fdbg.lo H5Fdeprec.lo \ + H5Fefc.lo H5Ffake.lo H5Fio.lo H5Fmount.lo H5Fmpi.lo \ + H5Fquery.lo H5Fsfile.lo H5Fsuper.lo H5Fsuper_cache.lo \ + H5Ftest.lo H5FA.lo H5FAcache.lo H5FAdbg.lo H5FAdblock.lo \ + H5FAdblkpage.lo H5FAhdr.lo H5FAstat.lo H5FAtest.lo H5VL.lo \ + H5VLint.lo H5VLnative.lo H5VLdummy.lo H5FD.lo H5FDcore.lo \ + H5FDdirect.lo H5FDfamily.lo H5FDint.lo H5FDlog.lo H5FDmpi.lo \ + H5FDmpio.lo H5FDmpiposix.lo H5FDmulti.lo H5FDsec2.lo \ + H5FDspace.lo H5FDstdio.lo H5FL.lo H5FO.lo H5FS.lo H5FScache.lo \ + H5FSdbg.lo H5FSsection.lo H5FSstat.lo H5FStest.lo H5G.lo \ + H5Gbtree2.lo H5Gcache.lo H5Gcompact.lo H5Gdense.lo \ + H5Gdeprec.lo H5Gent.lo H5Gint.lo H5Glink.lo H5Gloc.lo \ + H5Gname.lo H5Gnode.lo H5Gobj.lo H5Goh.lo H5Groot.lo H5Gstab.lo \ + H5Gtest.lo H5Gtraverse.lo H5HF.lo H5HFbtree2.lo H5HFcache.lo \ + H5HFdbg.lo H5HFdblock.lo H5HFdtable.lo H5HFhdr.lo H5HFhuge.lo \ + H5HFiblock.lo H5HFiter.lo H5HFman.lo H5HFsection.lo \ + H5HFspace.lo H5HFstat.lo H5HFtest.lo H5HFtiny.lo H5HG.lo \ + H5HGcache.lo H5HGdbg.lo H5HGquery.lo H5HL.lo H5HLcache.lo \ + H5HLdbg.lo H5HLint.lo H5HP.lo H5I.lo H5Itest.lo H5L.lo \ + H5Lexternal.lo H5lib_settings.lo H5MF.lo H5MFaggr.lo \ + H5MFdbg.lo H5MFsection.lo H5MM.lo H5MP.lo H5MPtest.lo H5O.lo \ + H5Oainfo.lo H5Oalloc.lo H5Oattr.lo H5Oattribute.lo H5Obogus.lo \ + H5Obtreek.lo H5Ocache.lo H5Ochunk.lo H5Ocont.lo H5Ocopy.lo \ + H5Odbg.lo H5Odrvinfo.lo H5Odtype.lo H5Oefl.lo H5Ofill.lo \ + H5Ofsinfo.lo H5Oginfo.lo H5Olayout.lo H5Olinfo.lo H5Olink.lo \ + H5Omessage.lo H5Omtime.lo H5Oname.lo H5Onull.lo H5Opline.lo \ + H5Orefcount.lo H5Osdspace.lo H5Oshared.lo H5Ostab.lo \ + H5Oshmesg.lo H5Otest.lo H5Ounknown.lo H5P.lo H5Pacpl.lo \ + H5Pdapl.lo H5Pdcpl.lo H5Pdeprec.lo H5Pdxpl.lo H5Pfapl.lo \ + H5Pfcpl.lo H5Pfmpl.lo H5Pgcpl.lo H5Pint.lo H5Plapl.lo \ + H5Plcpl.lo H5Pocpl.lo H5Pocpypl.lo H5Pstrcpl.lo H5Ptest.lo \ + H5R.lo H5Rdeprec.lo H5RC.lo H5RS.lo H5S.lo H5Sall.lo H5Sdbg.lo \ + H5Shyper.lo H5Smpio.lo H5Snone.lo H5Spoint.lo H5Sselect.lo \ + H5Stest.lo H5SL.lo H5SM.lo H5SMbtree2.lo H5SMcache.lo \ + H5SMmessage.lo H5SMtest.lo H5ST.lo H5T.lo H5Tarray.lo \ + H5Tbit.lo H5Tcommit.lo H5Tcompound.lo H5Tconv.lo H5Tcset.lo \ + H5Tdbg.lo H5Tdeprec.lo H5Tenum.lo H5Tfields.lo H5Tfixed.lo \ + H5Tfloat.lo H5Tinit.lo H5Tnative.lo H5Toffset.lo H5Toh.lo \ + H5Topaque.lo H5Torder.lo H5Tpad.lo H5Tprecis.lo H5Tstrpad.lo \ + H5Tvisit.lo H5Tvlen.lo H5TS.lo H5V.lo H5WB.lo H5Z.lo \ + H5Zdeflate.lo H5Zfletcher32.lo H5Znbit.lo H5Zshuffle.lo \ + H5Zszip.lo H5Zscaleoffset.lo H5Ztrans.lo libhdf5_la_OBJECTS = $(am_libhdf5_la_OBJECTS) AM_V_lt = $(am__v_lt_$(V)) am__v_lt_ = $(am__v_lt_$(AM_DEFAULT_VERBOSITY)) @@ -513,7 +513,7 @@ libhdf5_la_SOURCES = H5.c H5checksum.c H5dbg.c H5system.c H5timer.c H5trace.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 \ - H5F.c H5Faccum.c H5Fcwfs.c \ + H5F.c H5Fint.c H5Faccum.c H5Fcwfs.c \ H5Fdbg.c H5Fdeprec.c H5Fefc.c H5Ffake.c H5Fio.c \ H5Fmount.c H5Fmpi.c H5Fquery.c \ H5Fsfile.c H5Fsuper.c H5Fsuper_cache.c H5Ftest.c \ @@ -797,6 +797,7 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5Fdeprec.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5Fefc.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5Ffake.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5Fint.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5Fio.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5Fmount.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5Fmpi.Plo@am__quote@ -- cgit v0.12