diff options
Diffstat (limited to 'src/H5A.c')
-rw-r--r-- | src/H5A.c | 302 |
1 files changed, 163 insertions, 139 deletions
@@ -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) |