diff options
Diffstat (limited to 'src/H5Pint.c')
-rw-r--r-- | src/H5Pint.c | 1089 |
1 files changed, 670 insertions, 419 deletions
diff --git a/src/H5Pint.c b/src/H5Pint.c index 226e4a4..26431eb 100644 --- a/src/H5Pint.c +++ b/src/H5Pint.c @@ -76,6 +76,22 @@ typedef struct { int cmp_value; /* Value from property comparison */ } H5P_plist_cmp_ud_t; +/* Typedef for property list set/poke callbacks */ +typedef struct { + const void *value; /* Pointer to value to set */ +} H5P_prop_set_ud_t; + +/* Typedef for property list get/peek callbacks */ +typedef struct { + void *value; /* Pointer for retrieved value */ +} H5P_prop_get_ud_t; + +/* Typedef for H5P__do_prop() callbacks */ +typedef herr_t (*H5P_do_plist_op_t)(H5P_genplist_t *plist, const char *name, H5P_genprop_t *prop, + void *udata); +typedef herr_t (*H5P_do_pclass_op_t)(H5P_genplist_t *plist, const char *name, H5P_genprop_t *prop, + void *udata); + /********************/ /* Local Prototypes */ @@ -85,6 +101,8 @@ typedef struct { static H5P_genprop_t *H5P_dup_prop(H5P_genprop_t *oprop, H5P_prop_within_t type); static herr_t H5P_free_prop(H5P_genprop_t *prop); static int H5P_cmp_prop(const H5P_genprop_t *prop1, const H5P_genprop_t *prop2); +static herr_t H5P__do_prop(H5P_genplist_t *plist, const char *name, H5P_do_plist_op_t plist_op, + H5P_do_pclass_op_t pclass_op, void *udata); /*********************/ @@ -561,45 +579,47 @@ H5P_term_package(void) static herr_t H5P_do_prop_cb1(H5SL_t *slist, H5P_genprop_t *prop, H5P_prp_cb1_t cb) { - void *tmp_value=NULL; /* Temporary value buffer */ - H5P_genprop_t *pcopy=NULL; /* Copy of property to insert into skip list */ - herr_t ret_value=SUCCEED; /* Return value */ + void *tmp_value = NULL; /* Temporary value buffer */ + H5P_genprop_t *pcopy = NULL; /* Copy of property to insert into skip list */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI_NOINIT + /* Sanity check */ + HDassert(slist); + HDassert(prop); + HDassert(prop->cmp); + HDassert(cb); + /* Allocate space for a temporary copy of the property value */ if(NULL == (tmp_value = H5MM_malloc(prop->size))) - HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed for temporary property value") - HDmemcpy(tmp_value,prop->value,prop->size); + HGOTO_ERROR(H5E_PLIST, H5E_CANTALLOC, FAIL, "memory allocation failed for temporary property value") + HDmemcpy(tmp_value, prop->value, prop->size); /* Call "type 1" callback ('create', 'copy' or 'close') */ - if(cb(prop->name,prop->size,tmp_value) < 0) + if(cb(prop->name, prop->size, tmp_value) < 0) HGOTO_ERROR(H5E_PLIST, H5E_CANTINIT, FAIL,"Property callback failed") - /* Check if the property value changed */ - if((prop->cmp)(tmp_value,prop->value,prop->size)) { - /* Make a copy of the class's property */ - if((pcopy=H5P_dup_prop(prop,H5P_PROP_WITHIN_LIST)) == NULL) - HGOTO_ERROR(H5E_PLIST, H5E_CANTCOPY, FAIL,"Can't copy property") + /* Make a copy of the class's property */ + if(NULL == (pcopy = H5P_dup_prop(prop, H5P_PROP_WITHIN_LIST))) + HGOTO_ERROR(H5E_PLIST, H5E_CANTCOPY, FAIL, "Can't copy property") - /* Copy the changed value into the new property */ - HDmemcpy(pcopy->value,tmp_value,prop->size); + /* Copy the changed value into the new property */ + HDmemcpy(pcopy->value, tmp_value, prop->size); - /* Insert the changed property into the property list */ - if(H5P_add_prop(slist,pcopy) < 0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL,"Can't insert property into skip list") - } /* end if */ + /* Insert the changed property into the property list */ + if(H5P_add_prop(slist, pcopy) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL, "Can't insert property into skip list") done: /* Release the temporary value buffer */ - if(tmp_value!=NULL) + if(tmp_value) H5MM_xfree(tmp_value); /* Cleanup on failure */ - if(ret_value<0) { - if(pcopy!=NULL) + if(ret_value < 0) + if(pcopy) H5P_free_prop(pcopy); - } /* end if */ FUNC_LEAVE_NOAPI(ret_value) } /* end H5P_do_prop_cb1() */ @@ -825,7 +845,7 @@ H5P_copy_plist(const H5P_genplist_t *old_plist, hbool_t app_ref) /* Only "copy" properties we haven't seen before */ if(nseen==0 || H5SL_search(seen,tmp->name) == NULL) { - /* Call property creation callback, if it exists */ + /* Call property copy callback, if it exists */ if(tmp->copy) { /* Call the callback & insert changed value into skip list (if necessary) */ if(H5P_do_prop_cb1(new_plist->props,tmp,tmp->copy) < 0) @@ -2548,162 +2568,449 @@ done: /*-------------------------------------------------------------------------- NAME - H5P_set + H5P__do_prop PURPOSE - Internal routine to set a property's value in a property list. + Internal routine to perform an operation on a property in a property list USAGE - herr_t H5P_set(plist, name, value) + herr_t H5P__do_prop(plist, name, cb, udata) H5P_genplist_t *plist; IN: Property list to find property in const char *name; IN: Name of property to set - void *value; IN: Pointer to the value for the property + H5P_do_plist_op_t plist_op; IN: Pointer to the callback to invoke when the + property is found in the property list + H5P_do_pclass_op_t pclass_op; IN: Pointer to the callback to invoke when the + property is found in the property class + void *udata; IN: Pointer to the user data for the callback RETURNS Returns non-negative on success, negative on failure. DESCRIPTION - Sets a new value for a property in a property list. The property name - must exist or this routine will fail. If there is a 'set' callback routine - registered for this property, the 'value' will be passed to that routine and - any changes to the 'value' will be used when setting the property value. - The information pointed at by the 'value' pointer (possibly modified by the - 'set' callback) is copied into the property list value and may be changed - by the application making the H5Pset call without affecting the property - value. - - If the 'set' callback routine returns an error, the property value will - not be modified. This routine may not be called for zero-sized properties - and will return an error in that case. - + Finds a property in a property list and calls the callback with it. GLOBAL VARIABLES COMMENTS, BUGS, ASSUMPTIONS EXAMPLES REVISION LOG --------------------------------------------------------------------------*/ -herr_t -H5P_set(H5P_genplist_t *plist, const char *name, const void *value) +static herr_t +H5P__do_prop(H5P_genplist_t *plist, const char *name, H5P_do_plist_op_t plist_op, + H5P_do_pclass_op_t pclass_op, void *udata) { H5P_genclass_t *tclass; /* Temporary class pointer */ H5P_genprop_t *prop; /* Temporary property pointer */ - herr_t ret_value=SUCCEED; /* Return value */ + herr_t ret_value = SUCCEED; /* Return value */ - FUNC_ENTER_NOAPI(FAIL) + FUNC_ENTER_STATIC + /* Sanity check */ HDassert(plist); HDassert(name); - HDassert(value); + HDassert(plist_op); + HDassert(pclass_op); /* Check if the property has been deleted */ - if(H5SL_search(plist->del,name)!=NULL) + if(NULL != H5SL_search(plist->del, name)) HGOTO_ERROR(H5E_PLIST, H5E_NOTFOUND, FAIL, "property doesn't exist") /* Find property in changed list */ if(NULL != (prop = (H5P_genprop_t *)H5SL_search(plist->props, name))) { - /* Check for property size >0 */ - if(prop->size==0) - HGOTO_ERROR(H5E_PLIST, H5E_BADVALUE, FAIL, "property has zero size") - - /* Make a copy of the value and pass to 'set' callback */ - if(prop->set!=NULL) { - void *tmp_value; /* Temporary value for property */ - - /* Make a copy of the current value, in case the callback fails */ - if(NULL==(tmp_value=H5MM_malloc(prop->size))) - HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed temporary property value") - HDmemcpy(tmp_value,value,prop->size); - - /* Call user's callback */ - if((*(prop->set))(plist->plist_id,name,prop->size,tmp_value) < 0) { - H5MM_xfree(tmp_value); - HGOTO_ERROR(H5E_PLIST, H5E_CANTINIT, FAIL, "can't set property value") - } /* end if */ - - /* Copy new [possibly unchanged] value into property value */ - HDmemcpy(prop->value,tmp_value,prop->size); - - /* Free the temporary value buffer */ - H5MM_xfree(tmp_value); - } /* end if */ - /* No 'set' callback, just copy value */ - else - HDmemcpy(prop->value,value,prop->size); + /* Call the 'found in propery list' callback */ + if((*plist_op)(plist, name, prop, udata) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTOPERATE, FAIL, "can't operate on property") } /* end if */ else { /* * Check if we should set class properties (up through list of parent classes also), * & make property 'set' callback. */ - tclass=plist->pclass; - while(tclass!=NULL) { - if(tclass->nprops>0) { + tclass = plist->pclass; + while(NULL != tclass) { + if(tclass->nprops > 0) { /* Find the property in the class */ - if((prop = (H5P_genprop_t *)H5SL_search(tclass->props,name))!=NULL) { - H5P_genprop_t *pcopy; /* Copy of property to insert into skip list */ - - /* Check for property size >0 */ - if(prop->size==0) - HGOTO_ERROR(H5E_PLIST,H5E_BADVALUE,FAIL,"property has zero size") - - /* Make a copy of the value and pass to 'set' callback */ - if(prop->set!=NULL) { - void *tmp_value; /* Temporary value for property */ - - /* Make a copy of the current value, in case the callback fails */ - if(NULL==(tmp_value=H5MM_malloc(prop->size))) - HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed temporary property value") - HDmemcpy(tmp_value,value,prop->size); - - /* Call user's callback */ - if((*(prop->set))(plist->plist_id,name,prop->size,tmp_value) < 0) { - H5MM_xfree(tmp_value); - HGOTO_ERROR(H5E_PLIST, H5E_CANTINIT, FAIL, "can't set property value") - } /* end if */ - - if((prop->cmp)(tmp_value,prop->value,prop->size)) { - /* Make a copy of the class's property */ - if((pcopy=H5P_dup_prop(prop,H5P_PROP_WITHIN_LIST)) == NULL) - HGOTO_ERROR(H5E_PLIST,H5E_CANTCOPY,FAIL,"Can't copy property") - - /* Copy new value into property value */ - HDmemcpy(pcopy->value,tmp_value,pcopy->size); - - /* Insert the changed property into the property list */ - if(H5P_add_prop(plist->props,pcopy) < 0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL,"Can't insert changed property into skip list") - } /* end if */ - - /* Free the temporary value buffer */ - H5MM_xfree(tmp_value); - } /* end if */ - /* No 'set' callback, just copy value */ - else { - if((prop->cmp)(value,prop->value,prop->size)) { - /* Make a copy of the class's property */ - if((pcopy=H5P_dup_prop(prop,H5P_PROP_WITHIN_LIST)) == NULL) - HGOTO_ERROR(H5E_PLIST,H5E_CANTCOPY,FAIL,"Can't copy property") - - HDmemcpy(pcopy->value,value,pcopy->size); - - /* Insert the changed property into the property list */ - if(H5P_add_prop(plist->props,pcopy) < 0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL,"Can't insert changed property into skip list") - } /* end if */ - } /* end else */ + if(NULL != (prop = (H5P_genprop_t *)H5SL_search(tclass->props, name))) { + /* Call the 'found in class' callback */ + if((*pclass_op)(plist, name, prop, udata) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTOPERATE, FAIL, "can't operate on property") /* Leave */ - HGOTO_DONE(SUCCEED); - } /* end while */ + break; + } /* end if */ } /* end if */ /* Go up to parent class */ - tclass=tclass->parent; + tclass = tclass->parent; } /* end while */ /* If we get this far, then it wasn't in the list of changed properties, * nor in the properties in the class hierarchy, indicate an error */ - HGOTO_ERROR(H5E_PLIST,H5E_NOTFOUND,FAIL,"can't find property in skip list") + if(NULL == tclass) + HGOTO_ERROR(H5E_PLIST, H5E_NOTFOUND, FAIL, "can't find property in skip list") } /* end else */ done: FUNC_LEAVE_NOAPI(ret_value) +} /* H5P__do_prop() */ + + +/*-------------------------------------------------------------------------- + NAME + H5P__poke_plist_cb + PURPOSE + Internal callback for H5P__do_prop, to overwrite a property's value in a property list. + USAGE + herr_t H5P__poke_plist_cb(plist, name, value) + H5P_genplist_t *plist; IN: Property list to overwrite property in + const char *name; IN: Name of property to overwrite + H5P_genprop_t *prop; IN: Property to overwrite + void *udata; IN: User data for operation + RETURNS + Returns non-negative on success, negative on failure. + DESCRIPTION + Overwrite a value for a property in a property list. + GLOBAL VARIABLES + COMMENTS, BUGS, ASSUMPTIONS + Called when the property is found in the property list. + EXAMPLES + REVISION LOG +--------------------------------------------------------------------------*/ +static herr_t +H5P__poke_plist_cb(H5P_genplist_t *plist, const char *name, H5P_genprop_t *prop, + void *_udata) +{ + H5P_prop_set_ud_t *udata = (H5P_prop_set_ud_t *)_udata; /* User data for callback */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_STATIC + + /* Sanity check */ + HDassert(plist); + HDassert(name); + HDassert(prop); + + /* Check for property size >0 */ + if(0 == prop->size) + HGOTO_ERROR(H5E_PLIST, H5E_BADVALUE, FAIL, "property has zero size") + + /* Overwrite value in property */ + HDmemcpy(prop->value, udata->value, prop->size); + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* H5P__poke_plist_cb() */ + + +/*-------------------------------------------------------------------------- + NAME + H5P__poke_pclass_cb + PURPOSE + Internal callback for H5P__do_prop, to overwrite a property's value in a property list. + USAGE + herr_t H5P__poke_pclass_cb(plist, name, value) + H5P_genplist_t *plist; IN: Property list to overwrite property in + const char *name; IN: Name of property to overwrite + H5P_genprop_t *prop; IN: Property to overwrite + void *udata; IN: User data for operation + RETURNS + Returns non-negative on success, negative on failure. + DESCRIPTION + Overwrite a value for a property in a property list. + GLOBAL VARIABLES + COMMENTS, BUGS, ASSUMPTIONS + Called when the property is found in the property class. + EXAMPLES + REVISION LOG +--------------------------------------------------------------------------*/ +static herr_t +H5P__poke_pclass_cb(H5P_genplist_t *plist, const char *name, H5P_genprop_t *prop, + void *_udata) +{ + H5P_prop_set_ud_t *udata = (H5P_prop_set_ud_t *)_udata; /* User data for callback */ + H5P_genprop_t *pcopy = NULL; /* Copy of property to insert into skip list */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_STATIC + + /* Sanity check */ + HDassert(plist); + HDassert(name); + HDassert(prop); + HDassert(prop->cmp); + + /* Check for property size >0 */ + if(0 == prop->size) + HGOTO_ERROR(H5E_PLIST, H5E_BADVALUE, FAIL, "property has zero size") + + /* Make a copy of the class's property */ + if(NULL == (pcopy = H5P_dup_prop(prop, H5P_PROP_WITHIN_LIST))) + HGOTO_ERROR(H5E_PLIST, H5E_CANTCOPY, FAIL, "Can't copy property") + + HDmemcpy(pcopy->value, udata->value, pcopy->size); + + /* Insert the changed property into the property list */ + if(H5P_add_prop(plist->props, pcopy) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL,"Can't insert changed property into skip list") + +done: + /* Cleanup on failure */ + if(ret_value < 0) + if(pcopy) + H5P_free_prop(pcopy); + + FUNC_LEAVE_NOAPI(ret_value) +} /* H5P__poke_pclass_cb() */ + + +/*-------------------------------------------------------------------------- + NAME + H5P_poke + PURPOSE + Internal routine to overwrite a property's value in a property list. + USAGE + herr_t H5P_poke(plist, name, value) + H5P_genplist_t *plist; IN: Property list to find property in + const char *name; IN: Name of property to overwrite + void *value; IN: Pointer to the value for the property + RETURNS + Returns non-negative on success, negative on failure. + DESCRIPTION + Overwrites a property in a property list (i.e. a "shallow" copy over + the property value). The property name must exist or this routine will + fail. If there is a setget' callback routine registered for this property, + it is _NOT_ called. + GLOBAL VARIABLES + COMMENTS, BUGS, ASSUMPTIONS + This routine may not be called for zero-sized properties and will + return an error in that case. + EXAMPLES + REVISION LOG +--------------------------------------------------------------------------*/ +herr_t +H5P_poke(H5P_genplist_t *plist, const char *name, const void *value) +{ + H5P_prop_set_ud_t udata; /* User data for callback */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI(FAIL) + + /* Sanity check */ + HDassert(plist); + HDassert(name); + HDassert(value); + + /* Find the property and set the value */ + udata.value = value; + if(H5P__do_prop(plist, name, H5P__poke_plist_cb, H5P__poke_pclass_cb, &udata) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTOPERATE, FAIL, "can't operate on plist to overwrite value") + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* H5P_poke() */ + + +/*-------------------------------------------------------------------------- + NAME + H5P__set_plist_cb + PURPOSE + Internal callback for H5P__do_prop, to set a property's value in a property list. + USAGE + herr_t H5P__set_plist_cb(plist, name, value) + H5P_genplist_t *plist; IN: Property list to set property in + const char *name; IN: Name of property to set + H5P_genprop_t *prop; IN: Property to set + void *udata; IN: User data for operation + RETURNS + Returns non-negative on success, negative on failure. + DESCRIPTION + Sets a new value for a property in a property list. + GLOBAL VARIABLES + COMMENTS, BUGS, ASSUMPTIONS + Called when the property is found in the property list. + EXAMPLES + REVISION LOG +--------------------------------------------------------------------------*/ +static herr_t +H5P__set_plist_cb(H5P_genplist_t *plist, const char *name, H5P_genprop_t *prop, + void *_udata) +{ + H5P_prop_set_ud_t *udata = (H5P_prop_set_ud_t *)_udata; /* User data for callback */ + void *tmp_value = NULL; /* Temporary value for property */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_STATIC + + /* Sanity check */ + HDassert(plist); + HDassert(name); + HDassert(prop); + + /* Check for property size >0 */ + if(0 == prop->size) + HGOTO_ERROR(H5E_PLIST, H5E_BADVALUE, FAIL, "property has zero size") + + /* Make a copy of the value and pass to 'set' callback */ + if(NULL != prop->set) { + /* Make a copy of the current value, in case the callback fails */ + if(NULL == (tmp_value = H5MM_malloc(prop->size))) + HGOTO_ERROR(H5E_PLIST, H5E_CANTALLOC, FAIL, "memory allocation failed temporary property value") + HDmemcpy(tmp_value, udata->value, prop->size); + + /* Call user's callback */ + if((*(prop->set))(plist->plist_id, name, prop->size, tmp_value) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTINIT, FAIL, "can't set property value") + } /* end if */ + /* No 'set' callback, just copy value */ + else + tmp_value = (void *)udata->value; /* Casting away const OK -QAK */ + + /* Free any previous value for the property */ + if(NULL != prop->del) { + /* Call user's 'delete' callback */ + if((*(prop->del))(plist->plist_id, name, prop->size, prop->value) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTFREE, FAIL, "can't release property value") + } /* end if */ + + /* Copy new [possibly unchanged] value into property value */ + HDmemcpy(prop->value, tmp_value, prop->size); + +done: + /* Free the temporary value buffer */ + if(tmp_value != NULL && tmp_value != udata->value) + H5MM_xfree(tmp_value); + + FUNC_LEAVE_NOAPI(ret_value) +} /* H5P__set_plist_cb() */ + + +/*-------------------------------------------------------------------------- + NAME + H5P__set_pclass_cb + PURPOSE + Internal callback for H5P__do_prop, to set a property's value in a property list. + USAGE + herr_t H5P__set_pclass_cb(plist, name, value) + H5P_genplist_t *plist; IN: Property list to set property in + const char *name; IN: Name of property to set + H5P_genprop_t *prop; IN: Property to set + void *udata; IN: User data for operation + RETURNS + Returns non-negative on success, negative on failure. + DESCRIPTION + Sets a new value for a property in a property list. + GLOBAL VARIABLES + COMMENTS, BUGS, ASSUMPTIONS + Called when the property is found in the property class. + EXAMPLES + REVISION LOG +--------------------------------------------------------------------------*/ +static herr_t +H5P__set_pclass_cb(H5P_genplist_t *plist, const char *name, H5P_genprop_t *prop, + void *_udata) +{ + H5P_prop_set_ud_t *udata = (H5P_prop_set_ud_t *)_udata; /* User data for callback */ + H5P_genprop_t *pcopy = NULL; /* Copy of property to insert into skip list */ + void *tmp_value = NULL; /* Temporary value for property */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_STATIC + + /* Sanity check */ + HDassert(plist); + HDassert(name); + HDassert(prop); + HDassert(prop->cmp); + + /* Check for property size >0 */ + if(0 == prop->size) + HGOTO_ERROR(H5E_PLIST, H5E_BADVALUE, FAIL, "property has zero size") + + /* Make a copy of the value and pass to 'set' callback */ + if(NULL != prop->set) { + /* Make a copy of the current value, in case the callback fails */ + if(NULL == (tmp_value = H5MM_malloc(prop->size))) + HGOTO_ERROR(H5E_PLIST, H5E_CANTALLOC, FAIL, "memory allocation failed temporary property value") + HDmemcpy(tmp_value, udata->value, prop->size); + + /* Call user's callback */ + if((*(prop->set))(plist->plist_id, name, prop->size, tmp_value) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTINIT, FAIL, "can't set property value") + } /* end if */ + /* No 'set' callback, just copy value */ + else + tmp_value = (void *)udata->value; /* Casting away const OK -QAK */ + + /* Make a copy of the class's property */ + if(NULL == (pcopy = H5P_dup_prop(prop, H5P_PROP_WITHIN_LIST))) + HGOTO_ERROR(H5E_PLIST, H5E_CANTCOPY, FAIL, "Can't copy property") + + HDmemcpy(pcopy->value, tmp_value, pcopy->size); + + /* Insert the changed property into the property list */ + if(H5P_add_prop(plist->props, pcopy) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL,"Can't insert changed property into skip list") + +done: + /* Free the temporary value buffer */ + if(tmp_value != NULL && tmp_value != udata->value) + H5MM_xfree(tmp_value); + + /* Cleanup on failure */ + if(ret_value < 0) + if(pcopy) + H5P_free_prop(pcopy); + + FUNC_LEAVE_NOAPI(ret_value) +} /* H5P__set_pclass_cb() */ + + +/*-------------------------------------------------------------------------- + NAME + H5P_set + PURPOSE + Internal routine to set a property's value in a property list. + USAGE + herr_t H5P_set(plist, name, value) + H5P_genplist_t *plist; IN: Property list to find property in + const char *name; IN: Name of property to set + void *value; IN: Pointer to the value for the property + RETURNS + Returns non-negative on success, negative on failure. + DESCRIPTION + Sets a new value for a property in a property list. The property name + must exist or this routine will fail. If there is a 'set' callback routine + registered for this property, the 'value' will be passed to that routine and + any changes to the 'value' will be used when setting the property value. + The information pointed at by the 'value' pointer (possibly modified by the + 'set' callback) is copied into the property list value and may be changed + by the application making the H5Pset call without affecting the property + value. + + If the 'set' callback routine returns an error, the property value will + not be modified. This routine may not be called for zero-sized properties + and will return an error in that case. + + GLOBAL VARIABLES + COMMENTS, BUGS, ASSUMPTIONS + EXAMPLES + REVISION LOG +--------------------------------------------------------------------------*/ +herr_t +H5P_set(H5P_genplist_t *plist, const char *name, const void *value) +{ + H5P_prop_set_ud_t udata; /* User data for callback */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI(FAIL) + + /* Sanity check */ + HDassert(plist); + HDassert(name); + HDassert(value); + + /* Find the property and set the value */ + udata.value = value; + if(H5P__do_prop(plist, name, H5P__set_plist_cb, H5P__set_pclass_cb, &udata) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTOPERATE, FAIL, "can't operate on plist to set value") + +done: + FUNC_LEAVE_NOAPI(ret_value) } /* H5P_set() */ @@ -3843,330 +4150,359 @@ done: /*-------------------------------------------------------------------------- NAME - H5P_peek_unsigned + H5P__peek_cb PURPOSE - Internal routine to quickly retrieve the value of a property in a property list. + Internal callback for H5P__do_prop, to peek at a property's value in a property list. USAGE - int H5P_peek_unsigned(plist, name) - H5P_genplist_t *plist; IN: Property list to check - const char *name; IN: Name of property to query + herr_t H5P__peek_plist_cb(plist, name, value) + H5P_genplist_t *plist; IN: Property list to peek property in + const char *name; IN: Name of property to peek + H5P_genprop_t *prop; IN: Property to peek + void *udata; IN: User data for operation RETURNS - Directly returns the value of the property in the list + Returns non-negative on success, negative on failure. DESCRIPTION - This function directly returns the value of a property in a property - list. Because this function is only able to just copy a particular property - value to the return value, there is no way to check for errors. We attempt - to make certain that bad things don't happen by validating that the size of - the property is the same as the size of the return type, but that can't - catch all errors. - This function does call the user's 'get' callback routine still. - + Peeks at a new value for a property in a property list. GLOBAL VARIABLES COMMENTS, BUGS, ASSUMPTIONS - No error checking! - Use with caution! + Called when the property is found in the property list and when it's found + for the property class. EXAMPLES REVISION LOG --------------------------------------------------------------------------*/ -unsigned -H5P_peek_unsigned(H5P_genplist_t *plist, const char *name) +static herr_t +H5P__peek_cb(H5P_genplist_t *plist, const char *name, H5P_genprop_t *prop, + void *_udata) { - unsigned ret_value; /* return value */ + H5P_prop_get_ud_t *udata = (H5P_prop_get_ud_t *)_udata; /* User data for callback */ + herr_t ret_value = SUCCEED; /* Return value */ - FUNC_ENTER_NOAPI(UFAIL) + FUNC_ENTER_STATIC + /* Sanity check */ HDassert(plist); HDassert(name); + HDassert(prop); - /* Get the value to return, don't worry about the return value, we can't return it */ - H5P_get(plist,name,&ret_value); + /* Check for property size >0 */ + if(0 == prop->size) + HGOTO_ERROR(H5E_PLIST, H5E_BADVALUE, FAIL, "property has zero size") + + /* Make a (shallow) copy of the value */ + HDmemcpy(udata->value, prop->value, prop->size); done: FUNC_LEAVE_NOAPI(ret_value) -} /* H5P_peek_unsigned() */ +} /* H5P__peek_cb() */ /*-------------------------------------------------------------------------- NAME - H5P_peek_hid_t + H5P_peek PURPOSE - Internal routine to quickly retrieve the value of a property in a property list. + Internal routine to look at the value of a property in a property list. USAGE - hid_t H5P_peek_hid_t(plist, name) + herr_t H5P_peek(plist, name, value) H5P_genplist_t *plist; IN: Property list to check const char *name; IN: Name of property to query + void *value; OUT: Pointer to the buffer for the property value RETURNS - Directly returns the value of the property in the list + Returns non-negative on success, negative on failure. DESCRIPTION - This function directly returns the value of a property in a property - list. Because this function is only able to just copy a particular property - value to the return value, there is no way to check for errors. We attempt - to make certain that bad things don't happen by validating that the size of - the property is the same as the size of the return type, but that can't - catch all errors. - This function does call the user's 'get' callback routine still. - + Retrieves a "shallow" copy of the value for a property in a property + list. The property name must exist or this routine will fail. If there + is a 'get' callback routine registered for this property, it is _NOT_ + called. GLOBAL VARIABLES COMMENTS, BUGS, ASSUMPTIONS - No error checking! - Use with caution! + This routine may not be called for zero-sized properties and will + return an error in that case. EXAMPLES REVISION LOG --------------------------------------------------------------------------*/ -hid_t -H5P_peek_hid_t(H5P_genplist_t *plist, const char *name) +herr_t +H5P_peek(H5P_genplist_t *plist, const char *name, void *value) { - hid_t ret_value; /* return value */ + H5P_prop_get_ud_t udata; /* User data for callback */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI(FAIL) + /* Sanity check */ HDassert(plist); HDassert(name); + HDassert(value); - /* Get the value to return, don't worry about the return value, we can't return it */ - H5P_get(plist,name,&ret_value); + /* Find the property and peek at the value */ + udata.value = value; + if(H5P__do_prop(plist, name, H5P__peek_cb, H5P__peek_cb, &udata) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTOPERATE, FAIL, "can't operate on plist to peek at value") done: FUNC_LEAVE_NOAPI(ret_value) -} /* H5P_peek_hid_t() */ +} /* H5P_peek() */ /*-------------------------------------------------------------------------- NAME - H5P_peek_voidp + H5P__get_cb PURPOSE - Internal routine to quickly retrieve the value of a property in a property list. + Internal callback for H5P__do_prop, to get a property's value in a property list. USAGE - void *H5P_peek_voidp(plist, name) - H5P_genplist_t *plist; IN: Property list to check - const char *name; IN: Name of property to query + herr_t H5P__get_plist_cb(plist, name, value) + H5P_genplist_t *plist; IN: Property list to get property in + const char *name; IN: Name of property to get + H5P_genprop_t *prop; IN: Property to get + void *udata; IN: User data for operation RETURNS - Directly returns the value of the property in the list + Returns non-negative on success, negative on failure. DESCRIPTION - This function directly returns the value of a property in a property - list. Because this function is only able to just copy a particular property - value to the return value, there is no way to check for errors. We attempt - to make certain that bad things don't happen by validating that the size of - the property is the same as the size of the return type, but that can't - catch all errors. - This function does call the user's 'get' callback routine still. - + Gets a new value for a property in a property list. GLOBAL VARIABLES COMMENTS, BUGS, ASSUMPTIONS - No error checking! - Use with caution! + Called when the property is found in the property list and when it's found + for the property class. EXAMPLES REVISION LOG --------------------------------------------------------------------------*/ -void * -H5P_peek_voidp(H5P_genplist_t *plist, const char *name) +static herr_t +H5P__get_cb(H5P_genplist_t *plist, const char *name, H5P_genprop_t *prop, + void *_udata) { - void * ret_value; /* return value */ + H5P_prop_get_ud_t *udata = (H5P_prop_get_ud_t *)_udata; /* User data for callback */ + void *tmp_value = NULL; /* Temporary value for property */ + herr_t ret_value = SUCCEED; /* Return value */ - FUNC_ENTER_NOAPI(NULL) + FUNC_ENTER_STATIC + /* Sanity check */ HDassert(plist); HDassert(name); + HDassert(prop); + + /* Check for property size >0 */ + if(0 == prop->size) + HGOTO_ERROR(H5E_PLIST, H5E_BADVALUE, FAIL, "property has zero size") - /* Get the value to return, don't worry about the return value, we can't return it */ - H5P_get(plist,name,&ret_value); + /* Call the 'get' callback, if there is one */ + if(NULL != prop->get) { + /* Make a copy of the current value, in case the callback fails */ + if(NULL == (tmp_value = H5MM_malloc(prop->size))) + HGOTO_ERROR(H5E_PLIST, H5E_CANTALLOC, FAIL, "memory allocation failed temporary property value") + HDmemcpy(tmp_value, prop->value, prop->size); + + /* Call user's callback */ + if((*(prop->get))(plist->plist_id, name, prop->size, tmp_value) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTINIT, FAIL, "can't set property value") + + /* Copy new [possibly unchanged] value into return value */ + HDmemcpy(udata->value, tmp_value, prop->size); + } /* end if */ + /* No 'get' callback, just copy value */ + else + HDmemcpy(udata->value, prop->value, prop->size); done: + /* Free the temporary value buffer */ + if(tmp_value) + H5MM_xfree(tmp_value); + FUNC_LEAVE_NOAPI(ret_value) -} /* H5P_peek_voidp() */ +} /* H5P__get_cb() */ /*-------------------------------------------------------------------------- NAME - H5P_peek_size_t + H5P_get PURPOSE - Internal routine to quickly retrieve the value of a property in a property list. + Internal routine to query the value of a property in a property list. USAGE - hsize_t H5P_peek_size_t(plist, name) + herr_t H5P_get(plist, name, value) H5P_genplist_t *plist; IN: Property list to check const char *name; IN: Name of property to query + void *value; OUT: Pointer to the buffer for the property value RETURNS - Directly returns the value of the property in the list + Returns non-negative on success, negative on failure. DESCRIPTION - This function directly returns the value of a property in a property - list. Because this function is only able to just copy a particular property - value to the return value, there is no way to check for errors. We attempt - to make certain that bad things don't happen by validating that the size of - the property is the same as the size of the return type, but that can't - catch all errors. - This function does call the user's 'get' callback routine still. + Retrieves a copy of the value for a property in a property list. The + property name must exist or this routine will fail. If there is a + 'get' callback routine registered for this property, the copy of the + value of the property will first be passed to that routine and any changes + to the copy of the value will be used when returning the property value + from this routine. + If the 'get' callback routine returns an error, 'value' will not be + modified and this routine will return an error. This routine may not be + called for zero-sized properties. GLOBAL VARIABLES COMMENTS, BUGS, ASSUMPTIONS - No error checking! - Use with caution! EXAMPLES REVISION LOG --------------------------------------------------------------------------*/ -size_t -H5P_peek_size_t(H5P_genplist_t *plist, const char *name) +herr_t +H5P_get(H5P_genplist_t *plist, const char *name, void *value) { - size_t ret_value; /* return value */ + H5P_prop_get_ud_t udata; /* User data for callback */ + herr_t ret_value = SUCCEED; /* Return value */ - FUNC_ENTER_NOAPI(UFAIL) + FUNC_ENTER_NOAPI(FAIL) + /* Sanity check */ HDassert(plist); HDassert(name); + HDassert(value); - /* Get the value to return, don't worry about the return value, we can't return it */ - H5P_get(plist,name,&ret_value); + /* Find the property and get the value */ + udata.value = value; + if(H5P__do_prop(plist, name, H5P__get_cb, H5P__get_cb, &udata) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTOPERATE, FAIL, "can't operate on plist to get value") done: FUNC_LEAVE_NOAPI(ret_value) -} /* H5P_peek_size_t() */ +} /* H5P_get() */ /*-------------------------------------------------------------------------- NAME - H5P_get + H5P__del_plist_cb PURPOSE - Internal routine to query the value of a property in a property list. + Internal callback for H5P__do_prop, to remove a property's value in a property list. USAGE - herr_t H5P_get(plist, name, value) - H5P_genplist_t *plist; IN: Property list to check - const char *name; IN: Name of property to query - void *value; OUT: Pointer to the buffer for the property value + herr_t H5P__del_plist_cb(plist, name, value) + H5P_genplist_t *plist; IN: Property list to remove property from + const char *name; IN: Name of property to remove + H5P_genprop_t *prop; IN: Property to remove + void *udata; IN: User data for operation RETURNS Returns non-negative on success, negative on failure. DESCRIPTION - Retrieves a copy of the value for a property in a property list. The - property name must exist or this routine will fail. If there is a - 'get' callback routine registered for this property, the copy of the - value of the property will first be passed to that routine and any changes - to the copy of the value will be used when returning the property value - from this routine. - If the 'get' callback routine returns an error, 'value' will not be - modified and this routine will return an error. This routine may not be - called for zero-sized properties. - + Remove a property in a property list. Called when the + property is found in the property list. GLOBAL VARIABLES COMMENTS, BUGS, ASSUMPTIONS EXAMPLES REVISION LOG --------------------------------------------------------------------------*/ -herr_t -H5P_get(const H5P_genplist_t *plist, const char *name, void *value) +static herr_t +H5P__del_plist_cb(H5P_genplist_t *plist, const char *name, H5P_genprop_t *prop, + void H5_ATTR_UNUSED *_udata) { - H5P_genclass_t *tclass; /* Temporary class pointer */ - H5P_genprop_t *prop; /* Temporary property pointer */ - herr_t ret_value=SUCCEED; /* Return value */ + char *del_name = NULL; /* Pointer to deleted name */ + herr_t ret_value = SUCCEED; /* Return value */ - FUNC_ENTER_NOAPI(FAIL) + FUNC_ENTER_STATIC + /* Sanity check */ HDassert(plist); HDassert(name); - HDassert(value); + HDassert(prop); - /* Check if the property has been deleted */ - if(H5SL_search(plist->del,name)!=NULL) - HGOTO_ERROR(H5E_PLIST, H5E_NOTFOUND, FAIL, "property doesn't exist") + /* Pass value to 'close' callback, if it exists */ + if(NULL != prop->del) { + /* Call user's callback */ + if((*(prop->del))(plist->plist_id, name, prop->size, prop->value) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTFREE, FAIL, "can't release property value") + } /* end if */ - /* Find property */ - if((prop = (H5P_genprop_t *)H5SL_search(plist->props,name))!=NULL) { - /* Check for property size >0 */ - if(prop->size==0) - HGOTO_ERROR(H5E_PLIST, H5E_BADVALUE, FAIL, "property has zero size") + /* Duplicate string for insertion into new deleted property skip list */ + if(NULL == (del_name = H5MM_xstrdup(name))) + HGOTO_ERROR(H5E_PLIST, H5E_CANTALLOC, FAIL, "memory allocation failed") - /* Make a copy of the value and pass to 'get' callback */ - if(prop->get!=NULL) { - void *tmp_value; /* Temporary value for property */ + /* Insert property name into deleted list */ + if(H5SL_insert(plist->del, del_name, del_name) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL, "can't insert property into deleted skip list") - /* Make a copy of the current value, in case the callback fails */ - if(NULL==(tmp_value=H5MM_malloc(prop->size))) - HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed temporary property value") - HDmemcpy(tmp_value,prop->value,prop->size); + /* Remove the property from the skip list */ + if(NULL == H5SL_remove(plist->props, prop->name)) + HGOTO_ERROR(H5E_PLIST, H5E_CANTDELETE, FAIL, "can't remove property from skip list") - /* Call user's callback */ - if((*(prop->get))(plist->plist_id,name,prop->size,tmp_value) < 0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTINIT, FAIL, "can't get property value") + /* Free the property, ignoring return value, nothing we can do */ + H5P_free_prop(prop); - /* Copy new [possibly unchanged] value into return value */ - HDmemcpy(value,tmp_value,prop->size); + /* Decrement the number of properties in list */ + plist->nprops--; - /* Free the temporary value buffer */ - H5MM_xfree(tmp_value); - } /* end if */ - /* No 'get' callback, just copy value */ - else - HDmemcpy(value,prop->value,prop->size); - } /* end if */ - else { - /* - * Check if we should get class properties (up through list of parent classes also), - * & make property 'get' callback. - */ - tclass=plist->pclass; - while(tclass!=NULL) { - if(tclass->nprops>0) { - /* Find the property in the class */ - if((prop = (H5P_genprop_t *)H5SL_search(tclass->props,name))!=NULL) { - /* Check for property size >0 */ - if(prop->size==0) - HGOTO_ERROR(H5E_PLIST,H5E_BADVALUE,FAIL,"property has zero size") - - /* Call the 'get' callback, if there is one */ - if(prop->get!=NULL) { - void *tmp_value; /* Temporary value for property */ +done: + /* Error cleanup */ + if(ret_value < 0) + if(del_name) + H5MM_xfree(del_name); - /* Make a copy of the current value, in case the callback fails */ - if(NULL==(tmp_value=H5MM_malloc(prop->size))) - HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed temporary property value") - HDmemcpy(tmp_value,prop->value,prop->size); + FUNC_LEAVE_NOAPI(ret_value) +} /* H5P__del_plist_cb() */ - /* Call user's callback */ - if((*(prop->get))(plist->plist_id,name,prop->size,tmp_value) < 0) { - H5MM_xfree(tmp_value); - HGOTO_ERROR(H5E_PLIST, H5E_CANTINIT, FAIL, "can't set property value") - } /* end if */ + +/*-------------------------------------------------------------------------- + NAME + H5P__del_pclass_cb + PURPOSE + Internal callback for H5P__do_prop, to remove a property's value in a property list. + USAGE + herr_t H5P__del_pclass_cb(plist, name, value) + H5P_genplist_t *plist; IN: Property list to remove property from + const char *name; IN: Name of property to remove + H5P_genprop_t *prop; IN: Property to remove + void *udata; IN: User data for operation + RETURNS + Returns non-negative on success, negative on failure. + DESCRIPTION + Remove a property in a property list. Called when the + property is found in the property class. + GLOBAL VARIABLES + COMMENTS, BUGS, ASSUMPTIONS + EXAMPLES + REVISION LOG +--------------------------------------------------------------------------*/ +static herr_t +H5P__del_pclass_cb(H5P_genplist_t *plist, const char *name, H5P_genprop_t *prop, + void H5_ATTR_UNUSED *_udata) +{ + char *del_name = NULL; /* Pointer to deleted name */ + void *tmp_value = NULL; /* Temporary value for property */ + herr_t ret_value = SUCCEED; /* Return value */ - if((prop->cmp)(tmp_value,prop->value,prop->size)) { - H5P_genprop_t *pcopy; /* Copy of property to insert into skip list */ + FUNC_ENTER_STATIC - /* Make a copy of the class's property */ - if((pcopy=H5P_dup_prop(prop,H5P_PROP_WITHIN_LIST)) == NULL) - HGOTO_ERROR(H5E_PLIST,H5E_CANTCOPY,FAIL,"Can't copy property") + /* Sanity check */ + HDassert(plist); + HDassert(name); + HDassert(prop); - /* Copy new value into property value */ - HDmemcpy(pcopy->value,tmp_value,prop->size); + /* Pass value to 'del' callback, if it exists */ + if(NULL != prop->del) { + /* Allocate space for a temporary copy of the property value */ + if(NULL == (tmp_value = H5MM_malloc(prop->size))) + HGOTO_ERROR(H5E_PLIST, H5E_CANTALLOC, FAIL, "memory allocation failed for temporary property value") + HDmemcpy(tmp_value, prop->value, prop->size); - /* Insert the changed property into the property list */ - if(H5P_add_prop(plist->props,pcopy) < 0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL,"Can't insert changed property into skip list") - } /* end if */ + /* Call user's callback */ + if((*(prop->del))(plist->plist_id, name, prop->size, tmp_value) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTINIT, FAIL, "can't close property value") + } /* end if */ - /* Copy new [possibly unchanged] value into return value */ - HDmemcpy(value,tmp_value,prop->size); + /* Duplicate string for insertion into new deleted property skip list */ + if(NULL == (del_name = H5MM_xstrdup(name))) + HGOTO_ERROR(H5E_PLIST, H5E_CANTALLOC, FAIL, "memory allocation failed") - /* Free the temporary value buffer */ - H5MM_xfree(tmp_value); - } /* end if */ - /* No 'get' callback, just copy value */ - else - HDmemcpy(value,prop->value,prop->size); + /* Insert property name into deleted list */ + if(H5SL_insert(plist->del, del_name, del_name) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL, "can't insert property into deleted skip list") - /* Leave */ - HGOTO_DONE(SUCCEED); - } /* end while */ - } /* end if */ + /* Decrement the number of properties in list */ + plist->nprops--; - /* Go up to parent class */ - tclass=tclass->parent; - } /* end while */ +done: + /* Free the temporary value buffer */ + if(tmp_value) + H5MM_xfree(tmp_value); - /* If we get this far, then it wasn't in the list of changed properties, - * nor in the properties in the class hierarchy, indicate an error - */ - HGOTO_ERROR(H5E_PLIST,H5E_NOTFOUND,FAIL,"can't find property in skip list") - } /* end else */ + /* Error cleanup */ + if(ret_value < 0) + if(del_name) + H5MM_xfree(del_name); -done: FUNC_LEAVE_NOAPI(ret_value) -} /* H5P_get() */ +} /* H5P__del_pclass_cb() */ /*-------------------------------------------------------------------------- @@ -4196,104 +4532,19 @@ done: REVISION LOG --------------------------------------------------------------------------*/ herr_t -H5P_remove(hid_t plist_id, H5P_genplist_t *plist, const char *name) +H5P_remove(H5P_genplist_t *plist, const char *name) { - H5P_genclass_t *tclass; /* Temporary class pointer */ - H5P_genprop_t *prop; /* Temporary property pointer */ - char *del_name; /* Pointer to deleted name */ - herr_t ret_value=SUCCEED; /* Return value */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI(FAIL) + /* Sanity check */ HDassert(plist); HDassert(name); - /* Indicate that the property isn't in the list if it has been deleted already */ - if(H5SL_search(plist->del,name)!=NULL) - HGOTO_ERROR(H5E_PLIST,H5E_NOTFOUND,FAIL,"can't find property in skip list") - - /* Get the property node from the changed property skip list */ - if((prop = (H5P_genprop_t *)H5SL_search(plist->props,name))!=NULL) { - /* Pass value to 'close' callback, if it exists */ - if(prop->del!=NULL) { - /* Call user's callback */ - if((*(prop->del))(plist_id,name,prop->size,prop->value) < 0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTINIT, FAIL, "can't close property value") - } /* end if */ - - /* Duplicate string for insertion into new deleted property skip list */ - if((del_name=H5MM_xstrdup(name)) == NULL) - HGOTO_ERROR(H5E_RESOURCE,H5E_NOSPACE,FAIL,"memory allocation failed") - - /* Insert property name into deleted list */ - if(H5SL_insert(plist->del,del_name,del_name) < 0) - HGOTO_ERROR(H5E_PLIST,H5E_CANTINSERT,FAIL,"can't insert property into deleted skip list") - - /* Remove the property from the skip list */ - if(H5SL_remove(plist->props,prop->name) == NULL) - HGOTO_ERROR(H5E_PLIST,H5E_CANTDELETE,FAIL,"can't remove property from skip list") - - /* Free the property, ignoring return value, nothing we can do */ - H5P_free_prop(prop); - - /* Decrement the number of properties in list */ - plist->nprops--; - } /* end if */ - /* Walk through all the properties in the class hierarchy, looking for the property */ - else { - /* - * Check if we should delete class properties (up through list of parent classes also), - * & make property 'delete' callback. - */ - tclass=plist->pclass; - while(tclass!=NULL) { - if(tclass->nprops>0) { - /* Find the property in the class */ - if((prop=H5P_find_prop_pclass(tclass,name))!=NULL) { - /* Pass value to 'del' callback, if it exists */ - if(prop->del!=NULL) { - void *tmp_value; /* Temporary value buffer */ - - /* Allocate space for a temporary copy of the property value */ - if(NULL==(tmp_value=H5MM_malloc(prop->size))) - HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed for temporary property value") - HDmemcpy(tmp_value,prop->value,prop->size); - - /* Call user's callback */ - if((*(prop->del))(plist_id,name,prop->size,tmp_value) < 0) { - H5MM_xfree(tmp_value); - HGOTO_ERROR(H5E_PLIST, H5E_CANTINIT, FAIL, "can't close property value") - } /* end if */ - - /* Release the temporary value buffer */ - H5MM_xfree(tmp_value); - } /* end if */ - - /* Duplicate string for insertion into new deleted property skip list */ - if((del_name=H5MM_xstrdup(name)) == NULL) - HGOTO_ERROR(H5E_RESOURCE,H5E_NOSPACE,FAIL,"memory allocation failed") - - /* Insert property name into deleted list */ - if(H5SL_insert(plist->del,del_name,del_name) < 0) - HGOTO_ERROR(H5E_PLIST,H5E_CANTINSERT,FAIL,"can't insert property into deleted skip list") - - /* Decrement the number of properties in list */ - plist->nprops--; - - /* Leave */ - HGOTO_DONE(SUCCEED); - } /* end while */ - } /* end if */ - - /* Go up to parent class */ - tclass=tclass->parent; - } /* end while */ - - /* If we get this far, then it wasn't in the list of changed properties, - * nor in the properties in the class hierarchy, indicate an error - */ - HGOTO_ERROR(H5E_PLIST,H5E_NOTFOUND,FAIL,"can't find property in skip list") - } /* end else */ + /* Find the property and get the value */ + if(H5P__do_prop(plist, name, H5P__del_plist_cb, H5P__del_pclass_cb, NULL) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTOPERATE, FAIL, "can't operate on plist to remove value") done: FUNC_LEAVE_NOAPI(ret_value) @@ -4351,7 +4602,7 @@ H5P_copy_prop_plist(hid_t dst_id, hid_t src_id, const char *name) /* If the property exists in the destination alread */ if(NULL != H5P__find_prop_plist(dst_plist, name)) { /* Delete the property from the destination list, calling the 'close' callback if necessary */ - if(H5P_remove(dst_id,dst_plist,name) < 0) + if(H5P_remove(dst_plist, name) < 0) HGOTO_ERROR(H5E_PLIST, H5E_CANTDELETE, FAIL, "unable to remove property") /* Get the pointer to the source property */ |