diff options
Diffstat (limited to 'src/H5Oattribute.c')
-rw-r--r-- | src/H5Oattribute.c | 139 |
1 files changed, 134 insertions, 5 deletions
diff --git a/src/H5Oattribute.c b/src/H5Oattribute.c index 7d22319..7d5e496 100644 --- a/src/H5Oattribute.c +++ b/src/H5Oattribute.c @@ -143,7 +143,7 @@ typedef struct { /*------------------------------------------------------------------------- - * Function: H5O_msg_attr_to_dense_cb + * Function: H5O_attr_to_dense_cb * * Purpose: Object header iterator callback routine to convert compact * attributes to dense attributes @@ -157,13 +157,13 @@ typedef struct { *------------------------------------------------------------------------- */ static herr_t -H5A_attr_to_dense_cb(H5O_t *oh, H5O_mesg_t *mesg/*in,out*/, +H5O_attr_to_dense_cb(H5O_t *oh, H5O_mesg_t *mesg/*in,out*/, unsigned UNUSED sequence, unsigned *oh_flags_ptr, void *_udata/*in,out*/) { H5O_iter_cvt_t *udata = (H5O_iter_cvt_t *)_udata; /* Operator user data */ herr_t ret_value = H5_ITER_CONT; /* Return value */ - FUNC_ENTER_NOAPI_NOINIT(H5A_attr_to_dense_cb) + FUNC_ENTER_NOAPI_NOINIT(H5O_attr_to_dense_cb) /* check args */ HDassert(oh); @@ -182,7 +182,7 @@ H5A_attr_to_dense_cb(H5O_t *oh, H5O_mesg_t *mesg/*in,out*/, done: FUNC_LEAVE_NOAPI(ret_value) -} /* end H5A_attr_to_dense_cb() */ +} /* end H5O_attr_to_dense_cb() */ /*------------------------------------------------------------------------- @@ -248,7 +248,7 @@ HDfprintf(stderr, "%s: converting attributes to dense storage\n", FUNC); /* Iterate over existing attributes, moving them to dense storage */ /* XXX: Test this with shared attributes */ - op.lib_op = H5A_attr_to_dense_cb; + op.lib_op = H5O_attr_to_dense_cb; if(H5O_msg_iterate_real(loc->file, oh, H5O_MSG_ATTR, TRUE, op, &udata, dxpl_id, &oh_flags) < 0) HGOTO_ERROR(H5E_ATTR, H5E_CANTCONVERT, FAIL, "error converting attributes to dense storage") } /* end if */ @@ -936,6 +936,7 @@ H5O_attr_remove_cb(H5O_t *oh, H5O_mesg_t *mesg/*in,out*/, /* check args */ HDassert(oh); HDassert(mesg); + HDassert(!udata->found); /* Check for shared message */ if(mesg->flags & H5O_MSG_FLAG_SHARED) { @@ -1151,3 +1152,131 @@ done: FUNC_LEAVE_NOAPI(ret_value) } /* end H5O_attr_count */ + +/*------------------------------------------------------------------------- + * Function: H5O_attr_exists_cb + * + * Purpose: Object header iterator callback routine to check for an + * attribute stored compactly, by name. + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Quincey Koziol + * koziol@hdfgroup.org + * Dec 11 2006 + * + *------------------------------------------------------------------------- + */ +static herr_t +H5O_attr_exists_cb(H5O_t *oh, H5O_mesg_t *mesg/*in,out*/, + unsigned UNUSED sequence, unsigned UNUSED *oh_flags_ptr, void *_udata/*in,out*/) +{ + H5O_iter_rm_t *udata = (H5O_iter_rm_t *)_udata; /* Operator user data */ + herr_t ret_value = H5_ITER_CONT; /* Return value */ + + FUNC_ENTER_NOAPI_NOINIT(H5O_attr_exists_cb) + + /* check args */ + HDassert(oh); + HDassert(mesg); + HDassert(!udata->found); + + /* Check for shared message */ + if(mesg->flags & H5O_MSG_FLAG_SHARED) { + H5A_t shared_attr; /* Copy of shared attribute */ + + /* + * If the message is shared then then the native pointer points to an + * H5O_MSG_SHARED message. We use that information to look up the real + * message in the global heap or some other object header. + */ + if(NULL == H5O_shared_read(udata->f, udata->dxpl_id, mesg->native, H5O_MSG_ATTR, &shared_attr)) + HGOTO_ERROR(H5E_ATTR, H5E_CANTINIT, H5_ITER_ERROR, "unable to read shared attribute") + + /* Check for correct attribute message */ + if(HDstrcmp(shared_attr.name, udata->name) == 0) + /* Indicate that this message is the attribute sought */ + udata->found = TRUE; + + /* Release copy of shared attribute */ + H5O_attr_reset(&shared_attr); + } /* end if */ + else { + /* Check for correct attribute message */ + if(HDstrcmp(((H5A_t *)mesg->native)->name, udata->name) == 0) + /* Indicate that this message is the attribute sought */ + udata->found = TRUE; + } /* end else */ + + /* Check for finding correct message to delete */ + if(udata->found) { + /* Stop iterating */ + ret_value = H5_ITER_STOP; + } /* end if */ + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5O_attr_exists_cb() */ + + +/*------------------------------------------------------------------------- + * Function: H5O_attr_exists + * + * Purpose: Determine if an attribute with a particular name exists on an object + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Quincey Koziol + * Monday, December 11, 2006 + * + *------------------------------------------------------------------------- + */ +htri_t +H5O_attr_exists(const H5O_loc_t *loc, const char *name, hid_t dxpl_id) +{ + H5O_t *oh = NULL; /* Pointer to actual object header */ + unsigned oh_flags = H5AC__NO_FLAGS_SET; /* Metadata cache flags for object header */ + htri_t ret_value; /* Return value */ + + FUNC_ENTER_NOAPI_NOINIT(H5O_attr_exists) + + /* Check arguments */ + HDassert(loc); + HDassert(name); + + /* Protect the object header to iterate over */ + if(NULL == (oh = H5AC_protect(loc->file, dxpl_id, H5AC_OHDR, loc->addr, NULL, NULL, H5AC_READ))) + HGOTO_ERROR(H5E_ATTR, H5E_CANTLOAD, FAIL, "unable to load object header") + + /* Check for attributes stored densely */ + if(H5F_addr_defined(oh->attr_fheap_addr)) { + /* Check if attribute exists in dense storage */ + if((ret_value = H5A_dense_exists(loc->file, dxpl_id, oh, name)) < 0) + HGOTO_ERROR(H5E_ATTR, H5E_BADITER, FAIL, "error checking for existence of attribute") + } /* end if */ + else { + H5O_iter_rm_t udata; /* User data for callback */ + H5O_mesg_operator_t op; /* Wrapper for operator */ + + /* Set up user data for callback */ + udata.f = loc->file; + udata.dxpl_id = dxpl_id; + udata.name = name; + udata.found = FALSE; + + /* Iterate over existing attributes, checking for attribute with same name */ + op.lib_op = H5O_attr_exists_cb; + if(H5O_msg_iterate_real(loc->file, oh, H5O_MSG_ATTR, TRUE, op, &udata, dxpl_id, &oh_flags) < 0) + HGOTO_ERROR(H5E_ATTR, H5E_BADITER, FAIL, "error checking for existence of attribute") + + /* Check that we found the attribute */ + ret_value = udata.found; + } /* end else */ + +done: + if(oh && H5AC_unprotect(loc->file, dxpl_id, H5AC_OHDR, loc->addr, oh, H5AC__NO_FLAGS_SET) < 0) + HDONE_ERROR(H5E_ATTR, H5E_PROTECT, FAIL, "unable to release object header") + + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5O_attr_exists */ + |