diff options
author | Quincey Koziol <koziol@hdfgroup.org> | 2010-02-09 21:59:13 (GMT) |
---|---|---|
committer | Quincey Koziol <koziol@hdfgroup.org> | 2010-02-09 21:59:13 (GMT) |
commit | cc1c7331a5f57b1d8beae65c257164e11060ebef (patch) | |
tree | 8fa82792e82c57b48da65fce053c7b48339fd4a9 /src/H5Gtraverse.c | |
parent | 658c1b9e75291ea3dba584d93fda02f0079afc02 (diff) | |
download | hdf5-cc1c7331a5f57b1d8beae65c257164e11060ebef.zip hdf5-cc1c7331a5f57b1d8beae65c257164e11060ebef.tar.gz hdf5-cc1c7331a5f57b1d8beae65c257164e11060ebef.tar.bz2 |
[svn-r18223] Description:
Bring r18205 & r18222 from trunk to 1.8 branch:
Add new H5Oexists_by_name() routine.
Tested on:
Mac OS X/32 10.6.2 (amazon) w/debug & production
(daily tested on trunk already)
Diffstat (limited to 'src/H5Gtraverse.c')
-rw-r--r-- | src/H5Gtraverse.c | 104 |
1 files changed, 74 insertions, 30 deletions
diff --git a/src/H5Gtraverse.c b/src/H5Gtraverse.c index 4c287d5..e9f3010 100644 --- a/src/H5Gtraverse.c +++ b/src/H5Gtraverse.c @@ -43,8 +43,13 @@ /* User data for path traversal routine */ typedef struct { + /* down */ + hbool_t chk_exists; /* Flag to indicate we are checking if object exists */ + + /* up */ H5G_loc_t *obj_loc; /* Object location */ -} H5G_trav_ud1_t; + hbool_t exists; /* Indicate if object exists */ +} H5G_trav_slink_t; /* Private macros */ @@ -53,15 +58,15 @@ static char *H5G_comp_g = NULL; /*component buffer */ static size_t H5G_comp_alloc_g = 0; /*sizeof component buffer */ /* PRIVATE PROTOTYPES */ -static herr_t H5G_traverse_link_cb(H5G_loc_t *grp_loc, const char *name, +static herr_t H5G_traverse_slink_cb(H5G_loc_t *grp_loc, const char *name, const H5O_link_t *lnk, H5G_loc_t *obj_loc, void *_udata/*in,out*/, H5G_own_loc_t *own_loc/*out*/); static herr_t H5G_traverse_ud(const H5G_loc_t *grp_loc, const H5O_link_t *lnk, - H5G_loc_t *obj_loc/*in,out*/, size_t *nlinks/*in,out*/, hid_t lapl_id, - hid_t dxpl_id); + H5G_loc_t *obj_loc/*in,out*/, unsigned target, size_t *nlinks/*in,out*/, + hbool_t *obj_exists, hid_t lapl_id, hid_t dxpl_id); static herr_t H5G_traverse_slink(const H5G_loc_t *grp_loc, const H5O_link_t *lnk, - H5G_loc_t *obj_loc/*in,out*/, size_t *nlinks/*in,out*/, hid_t lapl_id, - hid_t dxpl_id); + H5G_loc_t *obj_loc/*in,out*/, unsigned target, size_t *nlinks/*in,out*/, + hbool_t *obj_exists, hid_t lapl_id, hid_t dxpl_id); static herr_t H5G_traverse_mount(H5G_loc_t *loc/*in,out*/); static herr_t H5G_traverse_real(const H5G_loc_t *loc, const char *name, unsigned target, size_t *nlinks, H5G_traverse_t op, void *op_data, @@ -97,9 +102,9 @@ H5G_traverse_term_interface(void) /*------------------------------------------------------------------------- - * Function: H5G_traverse_link_cb + * Function: H5G_traverse_slink_cb * - * Purpose: Callback for link traversal. This routine sets the + * Purpose: Callback for soft link traversal. This routine sets the * correct information for the object location. * * Return: Non-negative on success/Negative on failure @@ -110,20 +115,29 @@ H5G_traverse_term_interface(void) *------------------------------------------------------------------------- */ static herr_t -H5G_traverse_link_cb(H5G_loc_t UNUSED *grp_loc, const char UNUSED *name, const H5O_link_t UNUSED *lnk, - H5G_loc_t *obj_loc, void *_udata/*in,out*/, H5G_own_loc_t *own_loc/*out*/) +H5G_traverse_slink_cb(H5G_loc_t UNUSED *grp_loc, const char UNUSED *name, + const H5O_link_t UNUSED *lnk, H5G_loc_t *obj_loc, void *_udata/*in,out*/, + H5G_own_loc_t *own_loc/*out*/) { - H5G_trav_ud1_t *udata = (H5G_trav_ud1_t *)_udata; /* User data passed in */ + H5G_trav_slink_t *udata = (H5G_trav_slink_t *)_udata; /* User data passed in */ herr_t ret_value = SUCCEED; /* Return value */ - FUNC_ENTER_NOAPI_NOINIT(H5G_traverse_link_cb) + FUNC_ENTER_NOAPI_NOINIT(H5G_traverse_slink_cb) /* Check for dangling soft link */ - if(obj_loc == NULL) - HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "component not found") + if(obj_loc == NULL) { + if(udata->chk_exists) + udata->exists = FALSE; + else + HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "component not found") + } /* end if */ + else { + /* Copy new location information for resolved object */ + H5O_loc_copy(udata->obj_loc->oloc, obj_loc->oloc, H5_COPY_DEEP); - /* Copy new location information for resolved object */ - H5O_loc_copy(udata->obj_loc->oloc, obj_loc->oloc, H5_COPY_DEEP); + /* Indicate that the object exists */ + udata->exists = TRUE; + } /* end else */ done: /* Indicate that this callback didn't take ownership of the group * @@ -131,7 +145,7 @@ done: *own_loc = H5G_OWN_NONE; FUNC_LEAVE_NOAPI(ret_value) -} /* end H5G_traverse_link_cb() */ +} /* end H5G_traverse_slink_cb() */ /*------------------------------------------------------------------------- @@ -149,8 +163,8 @@ done: */ static herr_t H5G_traverse_ud(const H5G_loc_t *grp_loc/*in,out*/, const H5O_link_t *lnk, - H5G_loc_t *obj_loc/*in,out*/, size_t *nlinks/*in,out*/, hid_t _lapl_id, - hid_t dxpl_id) + H5G_loc_t *obj_loc/*in,out*/, unsigned target, size_t *nlinks/*in,out*/, + hbool_t *obj_exists, hid_t _lapl_id, hid_t dxpl_id) { const H5L_class_t *link_class; /* User-defined link class */ hid_t cb_return = -1; /* The ID the user-defined callback returned */ @@ -222,8 +236,25 @@ H5G_traverse_ud(const H5G_loc_t *grp_loc/*in,out*/, const H5O_link_t *lnk, HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set nlink info") /* User-defined callback function */ - if((cb_return = (link_class->trav_func)(lnk->name, cur_grp, lnk->u.ud.udata, lnk->u.ud.size, lapl_id)) < 0) - HGOTO_ERROR(H5E_ARGS, H5E_BADATOM, FAIL, "traversal callback returned invalid ID") + cb_return = (link_class->trav_func)(lnk->name, cur_grp, lnk->u.ud.udata, lnk->u.ud.size, lapl_id); + + /* Check for failing to locate the object */ + if(cb_return < 0) { + /* Check if we just needed to know if the object exists */ + if(target & H5G_TARGET_EXISTS) { + /* Clear any errors from the stack */ + H5E_clear_stack(NULL); + + /* Indicate that the object doesn't exist */ + *obj_exists = FALSE; + + /* Get out now */ + HGOTO_DONE(SUCCEED); + } /* end if */ + /* else, we really needed to open the object */ + else + HGOTO_ERROR(H5E_ARGS, H5E_BADATOM, FAIL, "traversal callback returned invalid ID") + } /* end if */ /* Get the oloc from the ID the user callback returned */ switch(H5I_get_type(cb_return)) { @@ -306,10 +337,10 @@ done: */ static herr_t H5G_traverse_slink(const H5G_loc_t *grp_loc, const H5O_link_t *lnk, - H5G_loc_t *obj_loc/*in,out*/, size_t *nlinks/*in,out*/, hid_t lapl_id, - hid_t dxpl_id) + H5G_loc_t *obj_loc/*in,out*/, unsigned target, size_t *nlinks/*in,out*/, + hbool_t *obj_exists, hid_t lapl_id, hid_t dxpl_id) { - H5G_trav_ud1_t udata; /* User data to pass to link traversal callback */ + H5G_trav_slink_t udata; /* User data to pass to link traversal callback */ H5G_name_t tmp_obj_path; /* Temporary copy of object's path */ hbool_t tmp_obj_path_set = FALSE; /* Flag to indicate that tmp object path is initialized */ H5O_loc_t tmp_grp_oloc; /* Temporary copy of group entry */ @@ -347,12 +378,17 @@ H5G_traverse_slink(const H5G_loc_t *grp_loc, const H5O_link_t *lnk, tmp_obj_path_set = TRUE; /* Set up user data for traversal callback */ + udata.chk_exists = (target & H5G_TARGET_EXISTS) ? TRUE : FALSE; + udata.exists = FALSE; udata.obj_loc = obj_loc; /* Traverse the link */ - if(H5G_traverse_real(&tmp_grp_loc, lnk->u.soft.name, H5G_TARGET_NORMAL, nlinks, H5G_traverse_link_cb, &udata, lapl_id, dxpl_id) < 0) + if(H5G_traverse_real(&tmp_grp_loc, lnk->u.soft.name, target, nlinks, H5G_traverse_slink_cb, &udata, lapl_id, dxpl_id) < 0) HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "unable to follow symbolic link") + /* Pass back information about whether the object exists */ + *obj_exists = udata.exists; + done: /* Restore object's group hier. path */ if(tmp_obj_path_set) { @@ -464,7 +500,7 @@ done: herr_t H5G_traverse_special(const H5G_loc_t *grp_loc, const H5O_link_t *lnk, unsigned target, size_t *nlinks, hbool_t last_comp, - H5G_loc_t *obj_loc, hid_t lapl_id, hid_t dxpl_id) + H5G_loc_t *obj_loc, hbool_t *obj_exists, hid_t lapl_id, hid_t dxpl_id) { herr_t ret_value = SUCCEED; /* Return value */ @@ -485,7 +521,7 @@ H5G_traverse_special(const H5G_loc_t *grp_loc, const H5O_link_t *lnk, (0 == (target & H5G_TARGET_SLINK) || !last_comp)) { if((*nlinks)-- <= 0) HGOTO_ERROR(H5E_LINK, H5E_NLINKS, FAIL, "too many links") - if(H5G_traverse_slink(grp_loc, lnk, obj_loc, nlinks, lapl_id, dxpl_id) < 0) + if(H5G_traverse_slink(grp_loc, lnk, obj_loc, (target & H5G_TARGET_EXISTS), nlinks, obj_exists, lapl_id, dxpl_id) < 0) HGOTO_ERROR(H5E_LINK, H5E_TRAVERSE, FAIL, "symbolic link traversal failed") } /* end if */ @@ -498,7 +534,7 @@ H5G_traverse_special(const H5G_loc_t *grp_loc, const H5O_link_t *lnk, (0 == (target & H5G_TARGET_UDLINK) || !last_comp) ) { if((*nlinks)-- <= 0) HGOTO_ERROR(H5E_LINK, H5E_NLINKS, FAIL, "too many links") - if(H5G_traverse_ud(grp_loc, lnk, obj_loc, nlinks, lapl_id, dxpl_id) < 0) + if(H5G_traverse_ud(grp_loc, lnk, obj_loc, (target & H5G_TARGET_EXISTS), nlinks, obj_exists, lapl_id, dxpl_id) < 0) HGOTO_ERROR(H5E_LINK, H5E_TRAVERSE, FAIL, "user-defined link traversal failed") } /* end if */ @@ -634,6 +670,7 @@ H5G_traverse_real(const H5G_loc_t *_loc, const char *name, unsigned target, while((name = H5G_component(name, &nchars)) && *name) { const char *s; /* Temporary string pointer */ htri_t lookup_status; /* Status from object lookup */ + hbool_t obj_exists; /* Whether the object exists */ /* * Copy the component name into a null-terminated buffer so @@ -663,6 +700,7 @@ H5G_traverse_real(const H5G_loc_t *_loc, const char *name, unsigned target, /* Get information for object in current group */ if((lookup_status = H5G_obj_lookup(grp_loc.oloc, H5G_comp_g, &lnk/*out*/, dxpl_id)) < 0) HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "can't look up component") + obj_exists = FALSE; /* If the lookup was OK, build object location and traverse special links, etc. */ if(lookup_status) { @@ -676,9 +714,12 @@ H5G_traverse_real(const H5G_loc_t *_loc, const char *name, unsigned target, HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "cannot initialize object location") obj_loc_valid = TRUE; + /* Assume object exists */ + obj_exists = TRUE; + /* Perform any special traversals that the link needs */ /* (soft links, user-defined links, file mounting, etc.) */ - if(H5G_traverse_special(&grp_loc, &lnk, target, nlinks, last_comp, &obj_loc, lapl_id, dxpl_id) < 0) + if(H5G_traverse_special(&grp_loc, &lnk, target, nlinks, last_comp, &obj_loc, &obj_exists, lapl_id, dxpl_id) < 0) HGOTO_ERROR(H5E_LINK, H5E_TRAVERSE, FAIL, "special link traversal failed") } /* end if */ @@ -690,7 +731,10 @@ H5G_traverse_real(const H5G_loc_t *_loc, const char *name, unsigned target, /* Set callback parameters appropriately, based on link being found */ if(lookup_status) { cb_lnk = &lnk; - cb_loc = &obj_loc; + if(obj_exists) + cb_loc = &obj_loc; + else + cb_loc = NULL; } /* end if */ else { HDassert(!obj_loc_valid); |