diff options
Diffstat (limited to 'src/H5Oattribute.c')
-rw-r--r-- | src/H5Oattribute.c | 320 |
1 files changed, 185 insertions, 135 deletions
diff --git a/src/H5Oattribute.c b/src/H5Oattribute.c index 982948f..72f02df 100644 --- a/src/H5Oattribute.c +++ b/src/H5Oattribute.c @@ -138,7 +138,7 @@ typedef struct { static herr_t H5O_attr_iterate_real(hid_t loc_id, const H5O_loc_t *loc, hid_t dxpl_id, H5_index_t idx_type, H5_iter_order_t order, hsize_t skip, hsize_t *last_attr, const H5A_attr_iter_op_t *attr_op, void *op_data); -static htri_t H5O_attr_find_opened_attr(const H5O_loc_t *loc, H5A_t **attr, +static htri_t H5O_attr_find_opened_attr(const H5O_loc_t *loc, H5A_t **attr, const char* name_to_open); /*********************/ @@ -239,15 +239,16 @@ H5O_attr_create(const H5O_loc_t *loc, hid_t dxpl_id, H5A_t *attr) /* Check if this object already has attribute information */ if(oh->version > H5O_VERSION_1) { - hbool_t new_ainfo = FALSE; /* Flag to indicate that the attribute information is new */ - - if(NULL == H5A_get_ainfo(loc->file, dxpl_id, oh, &ainfo)) { - /* Clear error stack from not finding attribute info */ - H5E_clear_stack(NULL); + hbool_t new_ainfo = FALSE; /* Flag to indicate that the attribute information is new */ + htri_t ainfo_exists; /* Whether the attribute info was retrieved */ + /* Check for (& retrieve if available) attribute info */ + if((ainfo_exists = H5A_get_ainfo(loc->file, dxpl_id, oh, &ainfo)) < 0) + HGOTO_ERROR(H5E_ATTR, H5E_CANTGET, FAIL, "can't check for attribute info message") + if(!ainfo_exists) { /* Initialize attribute information */ - ainfo.track_corder = (oh->flags & H5O_HDR_ATTR_CRT_ORDER_TRACKED) ? TRUE : FALSE; - ainfo.index_corder = (oh->flags & H5O_HDR_ATTR_CRT_ORDER_INDEXED) ? TRUE : FALSE; + ainfo.track_corder = (hbool_t)((oh->flags & H5O_HDR_ATTR_CRT_ORDER_TRACKED) ? TRUE : FALSE); + ainfo.index_corder = (hbool_t)((oh->flags & H5O_HDR_ATTR_CRT_ORDER_INDEXED) ? TRUE : FALSE); ainfo.max_crt_idx = 0; ainfo.corder_bt2_addr = HADDR_UNDEF; ainfo.nattrs = 0; @@ -346,10 +347,10 @@ H5O_attr_create(const H5O_loc_t *loc, hid_t dxpl_id, H5A_t *attr) HGOTO_ERROR(H5E_ATTR, H5E_CANTINSERT, FAIL, "unable to create new attribute in header") } /* end else */ - /* Increment reference count for shared attribute object for the + /* Increment reference count for shared attribute object for the * object handle created by the caller function H5A_create. The count * for the cached object header has been incremented in the step above - * (in H5O_msg_append_real). The dense storage doesn't need a count. */ + * (in H5O_msg_append_real). The dense storage doesn't need a count. */ attr->shared->nrefs += 1; /* Was new attribute shared? */ @@ -465,7 +466,7 @@ done: * * Modification:Raymond Lu * 23 June 2008 - * If the attribute is in dense storage and has already been + * If the attribute is in dense storage and has already been * opened, make a copy of already opened object to share some * object information. *------------------------------------------------------------------------- @@ -491,22 +492,29 @@ H5O_attr_open_by_name(const H5O_loc_t *loc, const char *name, hid_t dxpl_id) /* Check for attribute info stored */ ainfo.fheap_addr = HADDR_UNDEF; - if(oh->version > H5O_VERSION_1 && NULL == H5A_get_ainfo(loc->file, dxpl_id, oh, &ainfo)) - /* Clear error stack from not finding attribute info */ - H5E_clear_stack(NULL); + if(oh->version > H5O_VERSION_1) { + /* Check for (& retrieve if available) attribute info */ + if(H5A_get_ainfo(loc->file, dxpl_id, oh, &ainfo) < 0) + HGOTO_ERROR(H5E_ATTR, H5E_CANTGET, NULL, "can't check for attribute info message") + } /* end if */ /* If found the attribute is already opened, make a copy of it to share the - object information. If not, open attribute as a new object */ + * object information. If not, open attribute as a new object + */ if((found_open_attr = H5O_attr_find_opened_attr(loc, &exist_attr, name)) < 0) HGOTO_ERROR(H5E_ATTR, H5E_CANTGET, NULL, "failed in finding opened attribute") else if(found_open_attr == TRUE) { if(NULL == (ret_value = H5A_copy(NULL, exist_attr))) HGOTO_ERROR(H5E_ATTR, H5E_CANTCOPY, NULL, "can't copy existing attribute") - } else { - if(H5F_addr_defined(ainfo.fheap_addr)) { /* open attribute with dense storage */ + } /* end else if */ + else { + /* Check for attributes in dense storage */ + if(H5F_addr_defined(ainfo.fheap_addr)) { + /* Open attribute with dense storage */ if(NULL == (ret_value = H5A_dense_open(loc->file, dxpl_id, &ainfo, name))) HGOTO_ERROR(H5E_ATTR, H5E_CANTOPENOBJ, NULL, "can't open attribute") - } else { + } /* end if */ + else { H5O_iter_opn_t udata; /* User data for callback */ H5O_mesg_operator_t op; /* Wrapper for operator */ @@ -528,7 +536,12 @@ H5O_attr_open_by_name(const H5O_loc_t *loc, const char *name, hid_t dxpl_id) HDassert(udata.attr); ret_value = udata.attr; } /* end else */ - } + + /* Mark datatype as being on disk now */ + if(H5T_set_loc(ret_value->shared->dt, loc->file, H5T_LOC_DISK) < 0) + HGOTO_ERROR(H5E_ATTR, H5E_CANTINIT, NULL, "invalid datatype location") + + } /* end else */ done: if(oh && H5AC_unprotect(loc->file, dxpl_id, H5AC_OHDR, loc->addr, oh, H5AC__NO_FLAGS_SET) < 0) @@ -595,12 +608,11 @@ H5A_t * H5O_attr_open_by_idx(const H5O_loc_t *loc, H5_index_t idx_type, H5_iter_order_t order, hsize_t n, hid_t dxpl_id) { + H5O_t *oh = NULL; /* Object header */ H5A_attr_iter_op_t attr_op; /* Attribute operator */ H5A_t *exist_attr = NULL; /* Opened attribute object */ htri_t found_open_attr = FALSE; /* Whether opened object is found */ H5A_t *ret_value = NULL; /* Return value */ - H5O_t *oh = NULL; /* Object header */ - H5O_ainfo_t ainfo; /* Attribute information for object */ FUNC_ENTER_NOAPI_NOINIT(H5O_attr_open_by_idx) @@ -615,38 +627,35 @@ H5O_attr_open_by_idx(const H5O_loc_t *loc, H5_index_t idx_type, if(H5O_attr_iterate_real((hid_t)-1, loc, dxpl_id, idx_type, order, n, NULL, &attr_op, &ret_value) < 0) HGOTO_ERROR(H5E_ATTR, H5E_BADITER, NULL, "can't locate attribute") - /* Protect the object header to iterate over */ if(NULL == (oh = (H5O_t *)H5AC_protect(loc->file, dxpl_id, H5AC_OHDR, loc->addr, NULL, NULL, H5AC_READ))) HGOTO_ERROR(H5E_ATTR, H5E_CANTPROTECT, NULL, "unable to load object header") - /* Check for attribute info stored */ - ainfo.fheap_addr = HADDR_UNDEF; - if(oh->version > H5O_VERSION_1 && NULL == H5A_get_ainfo(loc->file, dxpl_id, oh, &ainfo)) - /* Clear error stack from not finding attribute info */ - H5E_clear_stack(NULL); - /* Find out whether it has already been opened. If it has, close the object - * and make a copy of the already opened object to share the object info. */ + * and make a copy of the already opened object to share the object info. + */ if(ret_value) { - if((found_open_attr = H5O_attr_find_opened_attr(loc, &exist_attr, - ret_value->shared->name)) < 0) + if((found_open_attr = H5O_attr_find_opened_attr(loc, &exist_attr, ret_value->shared->name)) < 0) HGOTO_ERROR(H5E_ATTR, H5E_CANTGET, NULL, "failed in finding opened attribute") - /* If found that the attribute is already opened, make a copy of it - and close the object just opened. */ + /* If found that the attribute is already opened, make a copy of it + * and close the object just opened. + */ if(found_open_attr && exist_attr) { if(H5A_close(ret_value) < 0) HGOTO_ERROR(H5E_ATTR, H5E_CANTCLOSEOBJ, NULL, "can't close attribute") - if(NULL == (ret_value = H5A_copy(NULL, exist_attr))) HGOTO_ERROR(H5E_ATTR, H5E_CANTCOPY, NULL, "can't copy existing attribute") - } - } + } else { + /* Mark datatype as being on disk now */ + if(H5T_set_loc(ret_value->shared->dt, loc->file, H5T_LOC_DISK) < 0) + HGOTO_ERROR(H5E_ATTR, H5E_CANTINIT, NULL, "invalid datatype location") + } /* end if */ + } /* end if */ done: if(oh && H5AC_unprotect(loc->file, H5AC_ind_dxpl_id, H5AC_OHDR, loc->addr, oh, H5AC__NO_FLAGS_SET) < 0) - HDONE_ERROR(H5E_ATTR, H5E_CANTUNPROTECT, NULL, "unable to release object header") + HDONE_ERROR(H5E_ATTR, H5E_CANTUNPROTECT, NULL, "unable to release object header") FUNC_LEAVE_NOAPI(ret_value) } /* end H5O_attr_open_by_idx() */ @@ -659,7 +668,7 @@ done: * the name. Return the pointer to the object if found. * * Return: TRUE: found the already opened object - * FALSE: didn't find the opened object + * FALSE: didn't find the opened object * FAIL: function failed. * * Programmer: Raymond Lu @@ -667,14 +676,13 @@ done: * *------------------------------------------------------------------------- */ -static -htri_t H5O_attr_find_opened_attr(const H5O_loc_t *loc, H5A_t **attr, const char* name_to_open) +static htri_t +H5O_attr_find_opened_attr(const H5O_loc_t *loc, H5A_t **attr, const char* name_to_open) { - htri_t ret_value = FALSE; - int num_open_attr = 0; - hid_t *attr_id_list = NULL; - unsigned long loc_fnum, attr_fnum; - int i; + hid_t *attr_id_list = NULL; /* List of IDs for opened attributes */ + unsigned long loc_fnum; /* File serial # for object */ + size_t num_open_attr; /* Number of opened attributes */ + htri_t ret_value = FALSE; /* Return value */ FUNC_ENTER_NOAPI_NOINIT(H5O_attr_find_opened_attr) @@ -683,39 +691,48 @@ htri_t H5O_attr_find_opened_attr(const H5O_loc_t *loc, H5A_t **attr, const char* HGOTO_ERROR(H5E_ATTR, H5E_BADVALUE, FAIL, "can't get file serial number") /* Count all opened attributes */ - if((num_open_attr = H5F_get_obj_count(loc->file, H5F_OBJ_ATTR | H5F_OBJ_LOCAL)) < 0) - HGOTO_ERROR(H5E_ATTR, H5E_CANTCOUNT, FAIL, "can't get number of opened attributes") + num_open_attr = H5F_get_obj_count(loc->file, H5F_OBJ_ATTR | H5F_OBJ_LOCAL, FALSE); /* Find out whether the attribute has been opened */ - if(num_open_attr) { - attr_id_list = (hid_t*)H5MM_malloc(num_open_attr*sizeof(hid_t)); + if(num_open_attr) { + size_t u; /* Local index variable */ + + /* Allocate space for the attribute ID list */ + if(NULL == (attr_id_list = (hid_t *)H5MM_malloc(num_open_attr * sizeof(hid_t)))) + HGOTO_ERROR(H5E_ATTR, H5E_NOSPACE, FAIL, "unable to allocate memory for attribute ID list") /* Retrieve the IDs of all opened attributes */ - if(H5F_get_obj_ids(loc->file, H5F_OBJ_ATTR | H5F_OBJ_LOCAL, num_open_attr, attr_id_list) < 0) - HGOTO_ERROR(H5E_ATTR, H5E_CANTGET, FAIL, "can't IDs of opened attributes") + H5F_get_obj_ids(loc->file, H5F_OBJ_ATTR | H5F_OBJ_LOCAL, num_open_attr, attr_id_list, FALSE); - for(i=0; i<num_open_attr; i++) { - if(NULL == (*attr = (H5A_t *)H5I_object_verify(attr_id_list[i], H5I_ATTR))) + /* Iterate over the attributes */ + for(u = 0; u < num_open_attr; u++) { + unsigned long attr_fnum; /* Attributes file serial number */ + + /* Get pointer to attribute */ + if(NULL == (*attr = (H5A_t *)H5I_object_verify(attr_id_list[u], H5I_ATTR))) HGOTO_ERROR(H5E_ATTR, H5E_BADTYPE, FAIL, "not an attribute") /* Get file serial number for attribute */ - if(H5F_get_fileno((*attr)->shared->oloc.file, &attr_fnum) < 0) + if(H5F_get_fileno((*attr)->oloc.file, &attr_fnum) < 0) HGOTO_ERROR(H5E_ATTR, H5E_BADVALUE, FAIL, "can't get file serial number") - /* Verify whether it's the right object. The attribute name, object address - * to which the attribute is attached, and file serial number should all - * match. */ - if(!strcmp(name_to_open, (*attr)->shared->name) && - loc->addr == (*attr)->shared->oloc.addr && - loc_fnum == attr_fnum) { + /* Verify whether it's the right object. The attribute name, object + * address to which the attribute is attached, and file serial + * number should all match. + */ + if(!HDstrcmp(name_to_open, (*attr)->shared->name) && + loc->addr == (*attr)->oloc.addr && + loc_fnum == attr_fnum) { ret_value = TRUE; break; - } - } - H5MM_free(attr_id_list); - } + } /* end if */ + } /* end for */ + } /* end if */ done: + if(attr_id_list) + H5MM_free(attr_id_list); + FUNC_LEAVE_NOAPI(ret_value) } /* end H5O_attr_find_opened_attr */ @@ -811,7 +828,7 @@ done: * Modification:Raymond Lu * 4 June 2008 * Took out the data copying part because the attribute data - * is shared between attribute handle and object header. + * is shared between attribute handle and object header. *------------------------------------------------------------------------- */ static herr_t @@ -885,9 +902,11 @@ H5O_attr_write(const H5O_loc_t *loc, hid_t dxpl_id, H5A_t *attr) /* Check for attribute info stored */ ainfo.fheap_addr = HADDR_UNDEF; - if(oh->version > H5O_VERSION_1 && NULL == H5A_get_ainfo(loc->file, dxpl_id, oh, &ainfo)) - /* Clear error stack from not finding attribute info */ - H5E_clear_stack(NULL); + if(oh->version > H5O_VERSION_1) { + /* Check for (& retrieve if available) attribute info */ + if(H5A_get_ainfo(loc->file, dxpl_id, oh, &ainfo) < 0) + HGOTO_ERROR(H5E_ATTR, H5E_CANTGET, FAIL, "can't check for attribute info message") + } /* end if */ /* Check for attributes stored densely */ if(H5F_addr_defined(ainfo.fheap_addr)) { @@ -1023,7 +1042,7 @@ H5O_attr_rename_mod_cb(H5O_t *oh, H5O_mesg_t *mesg/*in,out*/, /* Check for shared message */ if(mesg->flags & H5O_MSG_FLAG_SHARED) { /* Update the shared attribute in the SOHM storage */ - if(H5O_attr_update_shared(udata->f, udata->dxpl_id, oh, mesg->native, NULL) < 0) + if(H5O_attr_update_shared(udata->f, udata->dxpl_id, oh, (H5A_t *)mesg->native, NULL) < 0) HGOTO_ERROR(H5E_ATTR, H5E_CANTUPDATE, H5_ITER_ERROR, "unable to update attribute in shared storage") } /* end if */ else { @@ -1035,7 +1054,7 @@ H5O_attr_rename_mod_cb(H5O_t *oh, H5O_mesg_t *mesg/*in,out*/, old_version != ((H5A_t *)mesg->native)->shared->version) { H5A_t *attr; /* Attribute to re-add */ - /* Take ownership of the message's native info (the attribute) + /* Take ownership of the message's native info (the attribute) * so any shared objects in the file aren't adjusted (and * possibly deleted) when the message is released. */ @@ -1117,9 +1136,11 @@ H5O_attr_rename(const H5O_loc_t *loc, hid_t dxpl_id, const char *old_name, /* Check for attribute info stored */ ainfo.fheap_addr = HADDR_UNDEF; - if(oh->version > H5O_VERSION_1 && NULL == H5A_get_ainfo(loc->file, dxpl_id, oh, &ainfo)) - /* Clear error stack from not finding attribute info */ - H5E_clear_stack(NULL); + if(oh->version > H5O_VERSION_1) { + /* Check for (& retrieve if available) attribute info */ + if(H5A_get_ainfo(loc->file, dxpl_id, oh, &ainfo) < 0) + HGOTO_ERROR(H5E_ATTR, H5E_CANTGET, FAIL, "can't check for attribute info message") + } /* end if */ /* Check for attributes stored densely */ if(H5F_addr_defined(ainfo.fheap_addr)) { @@ -1210,9 +1231,11 @@ H5O_attr_iterate_real(hid_t loc_id, const H5O_loc_t *loc, hid_t dxpl_id, /* Check for attribute info stored */ ainfo.fheap_addr = HADDR_UNDEF; - if(oh->version > H5O_VERSION_1 && NULL == H5A_get_ainfo(loc->file, dxpl_id, oh, &ainfo)) - /* Clear error stack from not finding attribute info */ - H5E_clear_stack(NULL); + if(oh->version > H5O_VERSION_1) { + /* Check for (& retrieve if available) attribute info */ + if(H5A_get_ainfo(loc->file, dxpl_id, oh, &ainfo) < 0) + HGOTO_ERROR(H5E_ATTR, H5E_CANTGET, FAIL, "can't check for attribute info message") + } /* end if */ /* Check for attributes stored densely */ if(H5F_addr_defined(ainfo.fheap_addr)) { @@ -1226,8 +1249,7 @@ H5O_attr_iterate_real(hid_t loc_id, const H5O_loc_t *loc, hid_t dxpl_id, oh = NULL; /* Iterate over attributes in dense storage */ - if((ret_value = H5A_dense_iterate(loc->file, dxpl_id, loc_id, &ainfo, - idx_type, order, skip, last_attr, attr_op, op_data)) < 0) + if((ret_value = H5A_dense_iterate(loc->file, dxpl_id, loc_id, &ainfo, idx_type, order, skip, last_attr, attr_op, op_data)) < 0) HERROR(H5E_ATTR, H5E_BADITER, "error iterating over attributes"); } /* end if */ else { @@ -1310,9 +1332,9 @@ done: * * Modification:Raymond Lu * 24 June 2008 - * When converting storage from dense to compact, if found - * the attribute is already opened, use the opened message - * to insert. If not, still use the message in the attribute + * When converting storage from dense to compact, if found + * the attribute is already opened, use the opened message + * to insert. If not, still use the message in the attribute * table. This will guarantee that the attribute message is * shared between the object in metadata cache and the opened * object. @@ -1377,14 +1399,14 @@ H5O_attr_remove_update(const H5O_loc_t *loc, H5O_t *oh, H5O_ainfo_t *ainfo, (atable.attrs[u])->sh_loc.type = H5O_SHARE_TYPE_UNSHARED; } /* end else */ - /* Insert attribute message into object header (Will increment + /* Insert attribute message into object header (Will increment reference count on shared attributes) */ /* Find out whether the attribute has been opened */ if((found_open_attr = H5O_attr_find_opened_attr(loc, &exist_attr, (atable.attrs[u])->shared->name)) < 0) HGOTO_ERROR(H5E_ATTR, H5E_CANTGET, FAIL, "failed in finding opened attribute") /* If found the attribute is already opened, use the opened message to insert. - If not, still use the message in the attribute table. */ + If not, still use the message in the attribute table. */ if(found_open_attr && exist_attr) { if(H5O_msg_append_real(loc->file, dxpl_id, oh, H5O_MSG_ATTR, 0, 0, exist_attr) < 0) HGOTO_ERROR(H5E_ATTR, H5E_CANTINIT, FAIL, "can't create message") @@ -1488,7 +1510,7 @@ H5O_attr_remove(const H5O_loc_t *loc, const char *name, hid_t dxpl_id) { H5O_t *oh = NULL; /* Pointer to actual object header */ H5O_ainfo_t ainfo; /* Attribute information for object */ - H5O_ainfo_t *ainfo_ptr = NULL; /* Pointer to attribute information for object */ + htri_t ainfo_exists = FALSE; /* Whether the attribute info exists in the file */ unsigned oh_flags = H5AC__NO_FLAGS_SET; /* Metadata cache flags for object header */ herr_t ret_value = SUCCEED; /* Return value */ @@ -1504,9 +1526,11 @@ H5O_attr_remove(const H5O_loc_t *loc, const char *name, hid_t dxpl_id) /* Check for attribute info stored */ ainfo.fheap_addr = HADDR_UNDEF; - if(oh->version > H5O_VERSION_1 && NULL == (ainfo_ptr = H5A_get_ainfo(loc->file, dxpl_id, oh, &ainfo))) - /* Clear error stack from not finding attribute info */ - H5E_clear_stack(NULL); + if(oh->version > H5O_VERSION_1) { + /* Check for (& retrieve if available) attribute info */ + if((ainfo_exists = H5A_get_ainfo(loc->file, dxpl_id, oh, &ainfo)) < 0) + HGOTO_ERROR(H5E_ATTR, H5E_CANTGET, FAIL, "can't check for attribute info message") + } /* end if */ /* Check for attributes stored densely */ if(H5F_addr_defined(ainfo.fheap_addr)) { @@ -1536,7 +1560,7 @@ H5O_attr_remove(const H5O_loc_t *loc, const char *name, hid_t dxpl_id) } /* end else */ /* Update the attribute information after removing an attribute */ - if(ainfo_ptr) + if(ainfo_exists) if(H5O_attr_remove_update(loc, oh, &ainfo, dxpl_id) < 0) HGOTO_ERROR(H5E_ATTR, H5E_CANTUPDATE, FAIL, "unable to update attribute info") @@ -1574,7 +1598,7 @@ H5O_attr_remove_by_idx(const H5O_loc_t *loc, H5_index_t idx_type, { H5O_t *oh = NULL; /* Pointer to actual object header */ H5O_ainfo_t ainfo; /* Attribute information for object */ - H5O_ainfo_t *ainfo_ptr = NULL; /* Pointer to attribute information for object */ + htri_t ainfo_exists = FALSE; /* Whether the attribute info exists in the file */ unsigned oh_flags = H5AC__NO_FLAGS_SET; /* Metadata cache flags for object header */ H5A_attr_table_t atable = {0, NULL}; /* Table of attributes */ herr_t ret_value = SUCCEED; /* Return value */ @@ -1590,9 +1614,11 @@ H5O_attr_remove_by_idx(const H5O_loc_t *loc, H5_index_t idx_type, /* Check for attribute info stored */ ainfo.fheap_addr = HADDR_UNDEF; - if(oh->version > H5O_VERSION_1 && NULL == (ainfo_ptr = H5A_get_ainfo(loc->file, dxpl_id, oh, &ainfo))) - /* Clear error stack from not finding attribute info */ - H5E_clear_stack(NULL); + if(oh->version > H5O_VERSION_1) { + /* Check for (& retrieve if available) attribute info */ + if((ainfo_exists = H5A_get_ainfo(loc->file, dxpl_id, oh, &ainfo)) < 0) + HGOTO_ERROR(H5E_ATTR, H5E_CANTGET, FAIL, "can't check for attribute info message") + } /* end if */ /* Check for attributes stored densely */ if(H5F_addr_defined(ainfo.fheap_addr)) { @@ -1630,7 +1656,7 @@ H5O_attr_remove_by_idx(const H5O_loc_t *loc, H5_index_t idx_type, } /* end else */ /* Update the attribute information after removing an attribute */ - if(ainfo_ptr) + if(ainfo_exists) if(H5O_attr_remove_update(loc, oh, &ainfo, dxpl_id) < 0) HGOTO_ERROR(H5E_ATTR, H5E_CANTUPDATE, FAIL, "unable to update attribute info") @@ -1663,40 +1689,44 @@ done: * *------------------------------------------------------------------------- */ -hsize_t -H5O_attr_count_real(H5F_t *f, hid_t dxpl_id, H5O_t *oh) +herr_t +H5O_attr_count_real(H5F_t *f, hid_t dxpl_id, H5O_t *oh, hsize_t *nattrs) { - hsize_t ret_value; /* Return value */ + herr_t ret_value = SUCCEED; /* Return value */ - FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5O_attr_count_real) + FUNC_ENTER_NOAPI_NOINIT(H5O_attr_count_real) /* Check arguments */ HDassert(f); HDassert(oh); + HDassert(nattrs); /* Check for attributes stored densely */ if(oh->version > H5O_VERSION_1) { + htri_t ainfo_exists = FALSE; /* Whether the attribute info exists in the file */ H5O_ainfo_t ainfo; /* Attribute information for object */ /* Attempt to get the attribute information from the object header */ - if(H5A_get_ainfo(f, dxpl_id, oh, &ainfo)) - ret_value = ainfo.nattrs; - else { - /* Clear error stack from not finding attribute info */ - H5E_clear_stack(NULL); - - ret_value = 0; - } /* end else */ + if((ainfo_exists = H5A_get_ainfo(f, dxpl_id, oh, &ainfo)) < 0) + HGOTO_ERROR(H5E_ATTR, H5E_CANTGET, FAIL, "can't check for attribute info message") + else if(ainfo_exists > 0) + *nattrs = ainfo.nattrs; + else + *nattrs = 0; } /* end if */ else { + hsize_t attr_count; /* Number of attributes found */ unsigned u; /* Local index variable */ /* Loop over all messages, counting the attributes */ - for(u = ret_value = 0; u < oh->nmesgs; u++) + attr_count = 0; + for(u = 0; u < oh->nmesgs; u++) if(oh->mesg[u].type == H5O_MSG_ATTR) - ret_value++; + attr_count++; + *nattrs = attr_count; } /* end else */ +done: FUNC_LEAVE_NOAPI(ret_value) } /* end H5O_attr_count_real */ @@ -1772,9 +1802,11 @@ H5O_attr_exists(const H5O_loc_t *loc, const char *name, hid_t dxpl_id) /* Check for attribute info stored */ ainfo.fheap_addr = HADDR_UNDEF; - if(oh->version > H5O_VERSION_1 && NULL == H5A_get_ainfo(loc->file, dxpl_id, oh, &ainfo)) - /* Clear error stack from not finding attribute info */ - H5E_clear_stack(NULL); + if(oh->version > H5O_VERSION_1) { + /* Check for (& retrieve if available) attribute info */ + if(H5A_get_ainfo(loc->file, dxpl_id, oh, &ainfo) < 0) + HGOTO_ERROR(H5E_ATTR, H5E_CANTGET, FAIL, "can't check for attribute info message") + } /* end if */ /* Check for attributes stored densely */ if(H5F_addr_defined(ainfo.fheap_addr)) { @@ -1799,7 +1831,7 @@ H5O_attr_exists(const H5O_loc_t *loc, const char *name, hid_t dxpl_id) HGOTO_ERROR(H5E_ATTR, H5E_BADITER, FAIL, "error checking for existence of attribute") /* Check that we found the attribute */ - ret_value = udata.found; + ret_value = (htri_t)udata.found; } /* end else */ done: @@ -1826,6 +1858,8 @@ herr_t H5O_attr_bh_info(H5F_t *f, hid_t dxpl_id, H5O_t *oh, H5_ih_info_t *bh_info) { H5HF_t *fheap = NULL; /* Fractal heap handle */ + H5B2_t *bt2_name = NULL; /* v2 B-tree handle for name index */ + H5B2_t *bt2_corder = NULL; /* v2 B-tree handle for creation order index */ herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI(H5O_attr_bh_info, FAIL) @@ -1837,36 +1871,43 @@ H5O_attr_bh_info(H5F_t *f, hid_t dxpl_id, H5O_t *oh, H5_ih_info_t *bh_info) /* Attributes are only stored in fractal heap & indexed w/v2 B-tree in later versions */ if(oh->version > H5O_VERSION_1) { H5O_ainfo_t ainfo; /* Attribute information for object */ + htri_t ainfo_exists = FALSE; /* Whether the attribute info exists in the file */ + + /* Check for (& retrieve if available) attribute info */ + if((ainfo_exists = H5A_get_ainfo(f, dxpl_id, oh, &ainfo)) < 0) + HGOTO_ERROR(H5E_ATTR, H5E_CANTGET, FAIL, "can't check for attribute info message") + else if(ainfo_exists > 0) { + /* Check if name index available */ + if(H5F_addr_defined(ainfo.name_bt2_addr)) { + /* Open the name index v2 B-tree */ + if(NULL == (bt2_name = H5B2_open(f, dxpl_id, ainfo.name_bt2_addr, NULL))) + HGOTO_ERROR(H5E_ATTR, H5E_CANTOPENOBJ, FAIL, "unable to open v2 B-tree for name index") + + /* Get name index B-tree size */ + if(H5B2_size(bt2_name, dxpl_id, &(bh_info->index_size)) < 0) + HGOTO_ERROR(H5E_ATTR, H5E_CANTGET, FAIL, "can't retrieve B-tree storage info") + } /* end if */ - /* Check for attribute info stored */ - if(NULL == H5A_get_ainfo(f, dxpl_id, oh, &ainfo)) - /* Clear error stack from not finding attribute info */ - H5E_clear_stack(NULL); - else { - /* Get storage size of creation order index, if it's used */ - if(H5F_addr_defined(ainfo.corder_bt2_addr)) - if(H5B2_iterate_size(f, dxpl_id, H5A_BT2_CORDER, ainfo.corder_bt2_addr, &(bh_info->index_size)) < 0) - HGOTO_ERROR(H5E_BTREE, H5E_CANTGET, FAIL, "can't retrieve B-tree storage info") + /* Check if creation order index available */ + if(H5F_addr_defined(ainfo.corder_bt2_addr)) { + /* Open the creation order index v2 B-tree */ + if(NULL == (bt2_corder = H5B2_open(f, dxpl_id, ainfo.corder_bt2_addr, NULL))) + HGOTO_ERROR(H5E_ATTR, H5E_CANTOPENOBJ, FAIL, "unable to open v2 B-tree for creation order index") - /* Get storage size of name index, if it's used */ - if(H5F_addr_defined(ainfo.name_bt2_addr)) - if(H5B2_iterate_size(f, dxpl_id, H5A_BT2_NAME, ainfo.name_bt2_addr, &(bh_info->index_size)) < 0) - HGOTO_ERROR(H5E_BTREE, H5E_CANTGET, FAIL, "can't retrieve B-tree storage info") + /* Get creation order index B-tree size */ + if(H5B2_size(bt2_corder, dxpl_id, &(bh_info->index_size)) < 0) + HGOTO_ERROR(H5E_ATTR, H5E_CANTGET, FAIL, "can't retrieve B-tree storage info") + } /* end if */ /* Get storage size of fractal heap, if it's used */ if(H5F_addr_defined(ainfo.fheap_addr)) { /* Open the fractal heap for attributes */ if(NULL == (fheap = H5HF_open(f, dxpl_id, ainfo.fheap_addr))) - HGOTO_ERROR(H5E_HEAP, H5E_CANTOPENOBJ, FAIL, "unable to open fractal heap") + HGOTO_ERROR(H5E_ATTR, H5E_CANTOPENOBJ, FAIL, "unable to open fractal heap") /* Get heap storage size */ if(H5HF_size(fheap, dxpl_id, &(bh_info->heap_size)) < 0) - HGOTO_ERROR(H5E_BTREE, H5E_CANTGET, FAIL, "can't retrieve B-tree storage info") - - /* Release the fractal heap */ - if(H5HF_close(fheap, dxpl_id) < 0) - HGOTO_ERROR(H5E_HEAP, H5E_CLOSEERROR, FAIL, "can't close fractal heap") - fheap = NULL; + HGOTO_ERROR(H5E_ATTR, H5E_CANTGET, FAIL, "can't retrieve B-tree storage info") } /* end if */ } /* end else */ } /* end if */ @@ -1874,7 +1915,11 @@ H5O_attr_bh_info(H5F_t *f, hid_t dxpl_id, H5O_t *oh, H5_ih_info_t *bh_info) done: /* Release resources */ if(fheap && H5HF_close(fheap, dxpl_id) < 0) - HDONE_ERROR(H5E_HEAP, H5E_CLOSEERROR, FAIL, "can't close fractal heap") + HDONE_ERROR(H5E_ATTR, H5E_CANTCLOSEOBJ, FAIL, "can't close fractal heap") + if(bt2_name && H5B2_close(bt2_name, dxpl_id) < 0) + HDONE_ERROR(H5E_ATTR, H5E_CANTCLOSEOBJ, FAIL, "can't close v2 B-tree for name index") + if(bt2_corder && H5B2_close(bt2_corder, dxpl_id) < 0) + HDONE_ERROR(H5E_ATTR, H5E_CANTCLOSEOBJ, FAIL, "can't close v2 B-tree for creation order index") FUNC_LEAVE_NOAPI(ret_value) } /* H5O_attr_bh_info() */ @@ -1896,8 +1941,9 @@ done: int H5O_attr_count(const H5O_loc_t *loc, hid_t dxpl_id) { - H5O_t *oh = NULL; /* Pointer to actual object header */ - int ret_value; /* Return value */ + H5O_t *oh = NULL; /* Pointer to actual object header */ + hsize_t nattrs; /* Number of attributes */ + int ret_value; /* Return value */ FUNC_ENTER_NOAPI_NOINIT(H5O_attr_count) @@ -1909,7 +1955,11 @@ H5O_attr_count(const H5O_loc_t *loc, hid_t dxpl_id) HGOTO_ERROR(H5E_ATTR, H5E_CANTPROTECT, FAIL, "unable to load object header") /* Retrieve # of attributes on object */ - ret_value = (int)H5O_attr_count_real(loc->file, dxpl_id, oh); + if(H5O_attr_count_real(loc->file, dxpl_id, oh, &nattrs) < 0) + HGOTO_ERROR(H5E_ATTR, H5E_CANTGET, FAIL, "can't retrieve attribute count") + + /* Set return value */ + ret_value = (int)nattrs; done: if(oh && H5AC_unprotect(loc->file, dxpl_id, H5AC_OHDR, loc->addr, oh, H5AC__NO_FLAGS_SET) < 0) |