summaryrefslogtreecommitdiffstats
path: root/src/H5Aint.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/H5Aint.c')
-rw-r--r--src/H5Aint.c1152
1 files changed, 1152 insertions, 0 deletions
diff --git a/src/H5Aint.c b/src/H5Aint.c
index ab9bece..625bfa9 100644
--- a/src/H5Aint.c
+++ b/src/H5Aint.c
@@ -119,6 +119,1108 @@ 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: attribute structure on success, NULL on Failure.
+ *
+ * Programmer: Quincey Koziol
+ * April 2, 1998
+ *
+ *-------------------------------------------------------------------------
+ */
+H5A_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 */
+ H5A_t *ret_value; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT_TAG(dxpl_id, loc->oloc->addr, NULL)
+
+ /* 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, NULL, "error checking attributes")
+ else if(tri_ret > 0)
+ HGOTO_ERROR(H5E_ATTR, H5E_ALREADYEXISTS, NULL, "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, NULL, "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, NULL, "datatype is not sensible")
+
+ /* Build the attribute information */
+ if(NULL == (attr = H5FL_CALLOC(H5A_t)))
+ HGOTO_ERROR(H5E_ATTR, H5E_CANTALLOC, NULL, "memory allocation failed for attribute info")
+
+ if(NULL == (attr->shared = H5FL_CALLOC(H5A_shared_t)))
+ HGOTO_ERROR(H5E_ATTR, H5E_CANTALLOC, NULL, "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, NULL, "not a property list")
+
+ if(H5P_get(ac_plist, H5P_STRCRT_CHAR_ENCODING_NAME, &(attr->shared->encoding)) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "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, NULL, "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, NULL, "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, NULL, "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, NULL, "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, NULL, "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, NULL, "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, NULL, "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, NULL, "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, NULL, "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, NULL, "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, NULL, "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, NULL, "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, NULL, "unable to create attribute in object header")
+
+ ret_value = attr;
+done:
+ if(NULL == ret_value && attr && H5A_close(attr))
+ HDONE_ERROR(H5E_ATTR, H5E_CANTFREE, NULL, "can't close attribute")
+ FUNC_LEAVE_NOAPI_TAG(ret_value, NULL)
+} /* 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")
+
+ /* Create an atom */
+ if((ret_value = H5I_register(H5I_DATATYPE, dt, TRUE)) < 0)
+ HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL, "unable to register datatype")
+
+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_ID_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_NOERR
+
+ /* 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)
+{
+ FUNC_ENTER_NOAPI_NOERR
+
+ /* 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(SUCCEED)
+} /* end H5A_get_info() */
+
+
+/*-------------------------------------------------------------------------
+ * 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_NOERR
+
+ HDassert(attr);
+
+ /* Set return value */
+ ret_value = &(attr->oloc);
+
+ 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_NOERR
+
+ HDassert(attr);
+
+ /* Set return value */
+ ret_value=&(attr->path);
+
+ 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_NOERR
+
+ HDassert(attr);
+
+ /* Set return value */
+ ret_value = attr->shared->dt;
+
+ 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
@@ -1259,3 +2361,53 @@ done:
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5A_dense_post_copy_file_all */
+
+/*-------------------------------------------------------------------------
+ * Function: H5A_rename_by_name
+ *
+ * Purpose: Private version of H5Arename_by_name
+ *
+ * Return: Success: Non-negative
+ * Failure: Negative
+ *
+ * Programmer: Quincey Koziol
+ * February 20, 2007
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5A_rename_by_name(H5G_loc_t loc, const char *obj_name, const char *old_attr_name,
+ const char *new_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 */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+ /* Avoid thrashing things if the names are the same */
+ if(HDstrcmp(old_attr_name, new_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, H5AC_ind_dxpl_id) < 0)
+ HGOTO_ERROR(H5E_ATTR, H5E_NOTFOUND, FAIL, "object not found")
+ loc_found = TRUE;
+
+ /* Call attribute rename routine */
+ if(H5O_attr_rename(obj_loc.oloc, H5AC_dxpl_id, old_attr_name, new_attr_name) < 0)
+ HGOTO_ERROR(H5E_ATTR, H5E_CANTRENAME, FAIL, "can't rename attribute")
+ } /* end if */
+
+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_rename_by_name() */