summaryrefslogtreecommitdiffstats
path: root/src/H5A.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/H5A.c')
-rw-r--r--src/H5A.c302
1 files changed, 163 insertions, 139 deletions
diff --git a/src/H5A.c b/src/H5A.c
index dc00135..aec538f 100644
--- a/src/H5A.c
+++ b/src/H5A.c
@@ -85,9 +85,12 @@ static herr_t H5A_read(const H5A_t *attr, const H5T_t *mem_type, void *buf, hid_
/* Local Variables */
/*******************/
-/* Declare the free lists for H5A_t's */
+/* Declare the free lists of H5A_t */
H5FL_DEFINE(H5A_t);
+/* Declare the free lists for H5A_shared_t's */
+H5FL_DEFINE(H5A_shared_t);
+
/* Declare a free list to manage blocks of type conversion data */
H5FL_BLK_DEFINE(attr_buf);
@@ -392,9 +395,12 @@ H5A_create(const H5G_loc_t *loc, const char *name, const H5T_t *type,
if((attr = H5FL_CALLOC(H5A_t)) == NULL)
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed for attribute info")
+ if(NULL == (attr->shared = H5FL_CALLOC(H5A_shared_t)))
+ HGOTO_ERROR(H5E_FILE, H5E_NOSPACE, 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->encoding = H5F_DEFAULT_CSET;
+ attr->shared->encoding = H5F_DEFAULT_CSET;
else {
H5P_genplist_t *ac_plist; /* ACPL Property list */
@@ -402,59 +408,59 @@ H5A_create(const H5G_loc_t *loc, const char *name, const H5T_t *type,
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->encoding)) < 0)
+ 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->name = H5MM_xstrdup(name);
+ attr->shared->name = H5MM_xstrdup(name);
/* Copy the attribute's datatype */
- attr->dt = H5T_copy(type, H5T_COPY_ALL);
+ attr->shared->dt = H5T_copy(type, H5T_COPY_ALL);
/* Mark any datatypes as being on disk now */
- if(H5T_set_loc(attr->dt, loc->oloc->file, H5T_LOC_DISK) < 0)
+ 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->dt) < 0)
+ 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->ds = H5S_copy(space, FALSE, TRUE);
+ 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->ds) < 0)
+ if(H5S_set_latest_version(attr->shared->ds) < 0)
HGOTO_ERROR(H5E_DATASET, H5E_CANTSET, FAIL, "can't set latest version of dataspace")
/* Mark it initially set to initialized */
- attr->initialized = TRUE; /*for now, set to false later*/
+ attr->shared->initialized = TRUE; /*for now, set to false later*/
/* Copy the object header information */
- if(H5O_loc_copy(&(attr->oloc), loc->oloc, H5_COPY_DEEP) < 0)
+ if(H5O_loc_copy(&(attr->shared->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_CANTOPENOBJ, FAIL, "unable to copy path")
+ 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, H5O_DTYPE_ID, attr->dt, NULL) < 0)
+ if(H5SM_try_share(attr->shared->oloc.file, dxpl_id, NULL, 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, H5O_SDSPACE_ID, attr->ds, NULL) < 0)
+ if(H5SM_try_share(attr->shared->oloc.file, dxpl_id, NULL, 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->dt)) {
+ if(H5T_committed(attr->shared->dt)) {
/* Increment the reference count on the shared datatype */
- if(H5T_link(attr->dt, 1, dxpl_id) < 0)
+ 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 */
@@ -462,29 +468,29 @@ H5A_create(const H5G_loc_t *loc, const char *name, const H5T_t *type,
* datatype and dataspace messages themselves, or the size of the "shared"
* messages if either or both of them are shared.
*/
- attr->dt_size = H5O_msg_raw_size(attr->oloc.file, H5O_DTYPE_ID, FALSE, attr->dt);
- attr->ds_size = H5O_msg_raw_size(attr->oloc.file, H5O_SDSPACE_ID, FALSE, attr->ds);
+ attr->shared->dt_size = H5O_msg_raw_size(attr->shared->oloc.file, H5O_DTYPE_ID, FALSE, attr->shared->dt);
+ attr->shared->ds_size = H5O_msg_raw_size(attr->shared->oloc.file, H5O_SDSPACE_ID, FALSE, attr->shared->ds);
/* Get # of elements for attribute's dataspace */
- if((snelmts = H5S_GET_EXTENT_NPOINTS(attr->ds)) < 0)
+ 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->dt_size > 0);
- HDassert(attr->ds_size > 0);
- attr->data_size = nelmts * H5T_get_size(attr->dt);
+ 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)
+ if(H5O_open(&(attr->shared->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)
+ if(H5A_set_version(attr->shared->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)
+ if(H5O_attr_create(&(attr->shared->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 */
@@ -492,12 +498,11 @@ H5A_create(const H5G_loc_t *loc, const char *name, const H5T_t *type,
HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL, "unable to register attribute for ID")
/* Now it's safe to say it's uninitialized */
- attr->initialized = FALSE;
+ attr->shared->initialized = FALSE;
done:
/* Cleanup on failure */
- if(ret_value < 0)
- if(attr && H5A_close(attr) < 0)
+ if(ret_value < 0 && attr && H5A_close(attr) < 0)
HDONE_ERROR(H5E_ATTR, H5E_CANTFREE, FAIL, "can't close attribute")
FUNC_LEAVE_NOAPI(ret_value)
@@ -544,7 +549,7 @@ H5Aopen(hid_t loc_id, const char *attr_name, hid_t UNUSED aapl_id)
/* Read in attribute from object header */
if(NULL == (attr = H5O_attr_open_by_name(loc.oloc, attr_name, H5AC_ind_dxpl_id)))
HGOTO_ERROR(H5E_ATTR, H5E_CANTINIT, FAIL, "unable to load attribute info from object header")
- attr->initialized = TRUE;
+ attr->shared->initialized = TRUE;
/* Finish initializing attribute */
if(H5A_open_common(&loc, attr) < 0)
@@ -731,7 +736,7 @@ H5A_open_common(const H5G_loc_t *loc, H5A_t *attr)
#if defined(H5_USING_MEMCHECKER) || !defined(NDEBUG)
/* Clear object location */
- if(H5O_loc_reset(&(attr->oloc)) < 0)
+ if(H5O_loc_reset(&(attr->shared->oloc)) < 0)
HGOTO_ERROR(H5E_ATTR, H5E_CANTOPENOBJ, FAIL, "unable to reset location")
#endif /* H5_USING_MEMCHECKER */
@@ -740,15 +745,15 @@ H5A_open_common(const H5G_loc_t *loc, H5A_t *attr)
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)
+ if(H5O_loc_copy(&(attr->shared->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_CANTOPENOBJ, FAIL, "unable to copy entry")
+ 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)
+ if(H5O_open(&(attr->shared->oloc)) < 0)
HGOTO_ERROR(H5E_ATTR, H5E_CANTOPENOBJ, FAIL, "unable to open")
attr->obj_opened = TRUE;
@@ -799,7 +804,7 @@ H5A_open_by_idx(const H5G_loc_t *loc, const char *obj_name, H5_index_t idx_type,
/* 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")
- attr->initialized = TRUE;
+ attr->shared->initialized = TRUE;
/* Finish initializing attribute */
if(H5A_open_common(&obj_loc, attr) < 0)
@@ -865,7 +870,7 @@ H5A_open_by_name(const H5G_loc_t *loc, const char *obj_name, const char *attr_na
/* 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")
- attr->initialized = TRUE;
+ attr->shared->initialized = TRUE;
/* Finish initializing attribute */
if(H5A_open_common(loc, attr) < 0)
@@ -969,7 +974,7 @@ H5A_write(H5A_t *attr, const H5T_t *mem_type, const void *buf, hid_t dxpl_id)
HDassert(buf);
/* Get # of elements for attribute's dataspace */
- if((snelmts = H5S_GET_EXTENT_NPOINTS(attr->ds)) < 0)
+ 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);
@@ -977,17 +982,17 @@ H5A_write(H5A_t *attr, const H5T_t *mem_type, const void *buf, hid_t dxpl_id)
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->dt);
+ 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->dt, NULL, NULL, dxpl_id, FALSE)))
+ 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))) < 0 ||
- (dst_id = H5I_register(H5I_DATATYPE, H5T_copy(attr->dt, H5T_COPY_ALL))) < 0)
+ (dst_id = H5I_register(H5I_DATATYPE, H5T_copy(attr->shared->dt, H5T_COPY_ALL))) < 0)
HGOTO_ERROR(H5E_ATTR, H5E_CANTREGISTER, FAIL, "unable to register types for conversion")
/* Get the maximum buffer size needed and allocate it */
@@ -1003,11 +1008,11 @@ H5A_write(H5A_t *attr, const H5T_t *mem_type, const void *buf, hid_t dxpl_id)
HGOTO_ERROR(H5E_ATTR, H5E_CANTENCODE, FAIL, "datatype conversion failed")
/* Free the previous attribute data buffer, if there is one */
- if(attr->data)
- attr->data = H5FL_BLK_FREE(attr_buf, attr->data);
+ 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->data = tconv_buf;
+ attr->shared->data = tconv_buf;
tconv_owned = TRUE;
} /* end if */
/* No type conversion necessary */
@@ -1015,21 +1020,21 @@ H5A_write(H5A_t *attr, const H5T_t *mem_type, const void *buf, hid_t dxpl_id)
HDassert(dst_type_size == src_type_size);
/* Allocate the attribute buffer, if there isn't one */
- if(attr->data == NULL)
- if(NULL == (attr->data = H5FL_BLK_MALLOC(attr_buf, dst_type_size * nelmts)))
+ 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->data, buf, (dst_type_size * nelmts));
+ 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)
+ if(H5O_attr_write(&(attr->shared->oloc), dxpl_id, attr) < 0)
HGOTO_ERROR(H5E_ATTR, H5E_CANTINIT, FAIL, "unable to modify attribute")
} /* end if */
/* Indicate the the attribute doesn't need fill-values */
- attr->initialized = TRUE;
+ attr->shared->initialized = TRUE;
done:
/* Release resources */
@@ -1126,27 +1131,27 @@ H5A_read(const H5A_t *attr, const H5T_t *mem_type, void *buf, hid_t dxpl_id)
HDassert(buf);
/* Create buffer for data to store on disk */
- if((snelmts = H5S_GET_EXTENT_NPOINTS(attr->ds)) < 0)
+ 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->dt);
+ 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->initialized)
+ if(attr->obj_opened && !attr->shared->initialized)
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->dt, mem_type, NULL, NULL, dxpl_id, FALSE)))
+ 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->dt, H5T_COPY_ALL))) < 0 ||
+ if((src_id = H5I_register(H5I_DATATYPE, H5T_copy(attr->shared->dt, H5T_COPY_ALL))) < 0 ||
(dst_id = H5I_register(H5I_DATATYPE, H5T_copy(mem_type, H5T_COPY_ALL))) < 0)
HGOTO_ERROR(H5E_ATTR, H5E_CANTREGISTER, FAIL, "unable to register types for conversion")
@@ -1156,7 +1161,7 @@ H5A_read(const H5A_t *attr, const H5T_t *mem_type, void *buf, hid_t dxpl_id)
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed")
/* Copy the attribute data into the buffer for conversion */
- HDmemcpy(tconv_buf, attr->data, (src_type_size * nelmts));
+ 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)
@@ -1170,7 +1175,7 @@ H5A_read(const H5A_t *attr, const H5T_t *mem_type, void *buf, hid_t dxpl_id)
HDassert(dst_type_size == src_type_size);
/* Copy the attribute data into the user's buffer */
- HDmemcpy(buf, attr->data, (dst_type_size * nelmts));
+ HDmemcpy(buf, attr->shared->data, (dst_type_size * nelmts));
} /* end else */
} /* end else */
} /* end if */
@@ -1221,7 +1226,7 @@ H5Aget_space(hid_t attr_id)
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not an attribute")
/* Copy the attribute's dataspace */
- if(NULL == (ds = H5S_copy(attr->ds, FALSE, TRUE)))
+ if(NULL == (ds = H5S_copy(attr->shared->ds, FALSE, TRUE)))
HGOTO_ERROR(H5E_ATTR, H5E_CANTINIT, FAIL, "unable to copy dataspace")
/* Atomize */
@@ -1271,7 +1276,7 @@ H5Aget_type(hid_t attr_id)
* reopen the type before returning it to the user. Make the type
* read-only.
*/
- if(NULL == (dt = H5T_copy(attr->dt, H5T_COPY_REOPEN)))
+ 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 */
@@ -1340,7 +1345,7 @@ H5Aget_create_plist(hid_t attr_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->encoding)) < 0)
+ 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;
@@ -1374,21 +1379,53 @@ done:
ssize_t
H5Aget_name(hid_t attr_id, size_t buf_size, char *buf)
{
- H5A_t *attr; /* Attribute object for ID */
- size_t copy_len, nbytes;
+ H5A_t *my_attr; /* Attribute object for ID */
ssize_t ret_value;
FUNC_ENTER_API(H5Aget_name, FAIL)
H5TRACE3("Zs", "iz*s", attr_id, buf_size, buf);
/* check arguments */
- if(NULL == (attr = (H5A_t *)H5I_object_verify(attr_id, H5I_ATTR)))
+ if(NULL == (my_attr = (H5A_t *)H5I_object_verify(attr_id, H5I_ATTR)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not an attribute")
if(!buf && buf_size)
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid buffer")
+ /* Call private function in turn */
+ if(0 > (ret_value = H5A_get_name(my_attr, buf_size, buf)))
+ HGOTO_ERROR(H5E_ATTR, H5E_CANTGET, FAIL, "can't get attribute name")
+
+done:
+ FUNC_LEAVE_API(ret_value)
+} /* 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(H5A_get_name, FAIL)
+
/* get the real attribute length */
- nbytes = HDstrlen(attr->name);
+ 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 */
@@ -1396,7 +1433,7 @@ H5Aget_name(hid_t attr_id, size_t buf_size, char *buf)
/* Copy all/some of the name */
if(buf && copy_len > 0) {
- HDmemcpy(buf, attr->name, copy_len);
+ HDmemcpy(buf, attr->shared->name, copy_len);
/* Terminate the string */
buf[copy_len]='\0';
@@ -1406,8 +1443,8 @@ H5Aget_name(hid_t attr_id, size_t buf_size, char *buf)
ret_value = (ssize_t)nbytes;
done:
- FUNC_LEAVE_API(ret_value)
-} /* H5Aget_name() */
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* H5A_get_name() */
/*-------------------------------------------------------------------------
@@ -1462,11 +1499,11 @@ H5Aget_name_by_idx(hid_t loc_id, const char *obj_name, H5_index_t idx_type,
HGOTO_ERROR(H5E_ATTR, H5E_CANTOPENOBJ, FAIL, "can't open attribute")
/* Get the length of the name */
- ret_value = (ssize_t)HDstrlen(attr->name);
+ ret_value = (ssize_t)HDstrlen(attr->shared->name);
/* Copy the name into the user's buffer, if given */
if(name) {
- HDstrncpy(name, attr->name, MIN((size_t)(ret_value + 1), size));
+ HDstrncpy(name, attr->shared->name, MIN((size_t)(ret_value + 1), size));
if((size_t)ret_value >= size)
name[size - 1]='\0';
} /* end if */
@@ -1511,7 +1548,7 @@ H5Aget_storage_size(hid_t attr_id)
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, 0, "not an attribute")
/* Set return value */
- ret_value = attr->data_size;
+ ret_value = attr->shared->data_size;
done:
FUNC_LEAVE_API(ret_value)
@@ -1698,15 +1735,15 @@ H5A_get_info(const H5A_t *attr, H5A_info_t *ainfo)
HDassert(ainfo);
/* Set info for attribute */
- ainfo->cset = attr->encoding;
- ainfo->data_size = attr->data_size;
- if(attr->crt_idx == H5O_MAX_CRT_ORDER_IDX) {
+ 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->crt_idx;
+ ainfo->corder = attr->shared->crt_idx;
} /* end else */
done:
@@ -2259,6 +2296,10 @@ done:
* Programmer: Robb Matzke
* Thursday, December 4, 1997
*
+ * Modification:Raymond Lu
+ * 4 June 2008
+ * Changed some attribute information to be shared.
+ *
*-------------------------------------------------------------------------
*/
H5A_t *
@@ -2275,7 +2316,7 @@ H5A_copy(H5A_t *_new_attr, const H5A_t *old_attr)
/* Allocate attribute structure */
if(_new_attr == NULL) {
- if(NULL == (new_attr = H5FL_MALLOC(H5A_t)))
+ if(NULL == (new_attr = H5FL_CALLOC(H5A_t)))
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed")
allocated_attr = TRUE;
} /* end if */
@@ -2283,44 +2324,20 @@ H5A_copy(H5A_t *_new_attr, const H5A_t *old_attr)
new_attr = _new_attr;
/* Copy the top level of the attribute */
- *new_attr = *old_attr;
+ new_attr->sh_loc = old_attr->sh_loc;
- /* Don't open the object header for a copy */
- new_attr->obj_opened = FALSE;
-
- /* Copy the guts of the attribute */
- if(NULL == (new_attr->name = H5MM_xstrdup(old_attr->name)))
- HGOTO_ERROR(H5E_ATTR, H5E_CANTCOPY, NULL, "unable to copy attribute name")
- if(NULL == (new_attr->dt = H5T_copy(old_attr->dt, H5T_COPY_ALL)))
- HGOTO_ERROR(H5E_ATTR, H5E_CANTCOPY, NULL, "unable to copy attribute datatype")
- if(NULL == (new_attr->ds = H5S_copy(old_attr->ds, FALSE, TRUE)))
- HGOTO_ERROR(H5E_ATTR, H5E_CANTCOPY, NULL, "unable to copy attribute dataspace")
-
-#if defined(H5_USING_MEMCHECKER) || !defined(NDEBUG)
- /* Clear object location */
- if(H5O_loc_reset(&(new_attr->oloc)) < 0)
- HGOTO_ERROR(H5E_ATTR, H5E_CANTOPENOBJ, NULL, "unable to reset location")
-
- /* Clear path name */
- if(H5G_name_reset(&(new_attr->path)) < 0)
- HGOTO_ERROR(H5E_ATTR, H5E_CANTOPENOBJ, NULL, "unable to reset path")
-#endif /* H5_USING_MEMCHECKER */
-
- /* Copy the object location and group path */
- if(H5O_loc_copy(&(new_attr->oloc), &(old_attr->oloc), H5_COPY_DEEP) < 0)
- HGOTO_ERROR(H5E_ATTR, H5E_CANTCOPY, NULL, "can't copy object location")
+ /* 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, "can't copy path")
+ HGOTO_ERROR(H5E_ATTR, H5E_CANTCOPY, NULL, "unable to copy path")
- /* Copy the attribute data, if there is any */
- if(old_attr->data) {
- /* Allocate data buffer for new attribute */
- if(NULL == (new_attr->data = H5FL_BLK_MALLOC(attr_buf, old_attr->data_size)))
- HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed")
+ /* Share some attribute information */
+ new_attr->shared = old_attr->shared;
- /* Copy the attribute data */
- HDmemcpy(new_attr->data, old_attr->data, old_attr->data_size);
- } /* end if */
+ /* 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;
@@ -2359,18 +2376,22 @@ H5A_free(H5A_t *attr)
HDassert(attr);
/* Free dynamicly allocated items */
- if(attr->name)
- H5MM_xfree(attr->name);
- if(attr->dt)
- if(H5T_close(attr->dt) < 0)
+ 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")
- if(attr->ds)
- if(H5S_close(attr->ds) < 0)
+ 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")
- if(attr->data)
- attr->data = H5FL_BLK_FREE(attr_buf, attr->data);
- if(H5G_name_free(&(attr->path)) < 0)
- HGOTO_ERROR(H5E_ATTR, H5E_CANTRELEASE, FAIL, "can't release group hier. path")
+ 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)
@@ -2388,7 +2409,9 @@ done:
* Monday, December 8, 1997
*
* Modifications:
- *
+ * Raymond Lu
+ * 4 June 2008
+ * Changed some attribute object information to be shared.
*-------------------------------------------------------------------------
*/
herr_t
@@ -2399,30 +2422,31 @@ H5A_close(H5A_t *attr)
FUNC_ENTER_NOAPI(H5A_close, FAIL)
HDassert(attr);
-
- /* Check if the attribute has any data yet, if not, fill with zeroes */
- if(attr->obj_opened && !attr->initialized && attr->data_size) {
- uint8_t *tmp_buf = H5FL_BLK_CALLOC(attr_buf, attr->data_size);
- if(NULL == tmp_buf)
- HGOTO_ERROR(H5E_ATTR, H5E_NOSPACE, FAIL, "memory allocation failed for attribute fill-value")
-
- /* Go write the fill data to the attribute */
- if(H5A_write(attr, attr->dt, tmp_buf, H5AC_dxpl_id) < 0)
- HGOTO_ERROR(H5E_ATTR, H5E_WRITEERROR, FAIL, "unable to write attribute")
-
- /* Free temporary buffer */
- H5FL_BLK_FREE(attr_buf, tmp_buf);
- } /* end if */
-
- /* Free dynamicly allocated items */
- if(H5A_free(attr) < 0)
- HGOTO_ERROR(H5E_ATTR, H5E_CANTRELEASE, FAIL, "can't release attribute info")
+ HDassert(attr->shared);
/* Close the object's symbol-table entry */
- if(attr->obj_opened)
- if(H5O_close(&(attr->oloc)) < 0)
- HGOTO_ERROR(H5E_ATTR, H5E_CANTRELEASE, FAIL, "can't release object header info")
+ if(attr->obj_opened && (H5O_close(&(attr->shared->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(1 >= attr->shared->nrefs) {
+ /* 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);
+ } else if(attr->shared->nrefs > 1) {
+ /* There are other references to the shared part of the attribute.
+ * Only decrement the reference count. */
+ --attr->shared->nrefs;
+ }
+
+ /* 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;
H5FL_FREE(H5A_t, attr);
done:
@@ -2455,7 +2479,7 @@ H5A_oloc(H5A_t *attr)
HDassert(attr);
/* Set return value */
- ret_value = &(attr->oloc);
+ ret_value = &(attr->shared->oloc);
done:
FUNC_LEAVE_NOAPI(ret_value)