From 036e799cf9efb1a8da3bf9ce7287177888ca9556 Mon Sep 17 00:00:00 2001 From: Quincey Koziol Date: Mon, 20 Nov 2006 20:49:55 -0500 Subject: [svn-r12955] Description: Finish implementing H5Oopen_by_idx() (still needs tests) Tested on: Linux/32 2.4 (chicago) Linux/64 2.4 (chicago2) --- src/H5Gloc.c | 20 +++++++++++++++++++- src/H5Gpkg.h | 3 +++ src/H5Gtraverse.c | 4 ++-- src/H5O.c | 8 ++++---- 4 files changed, 28 insertions(+), 7 deletions(-) diff --git a/src/H5Gloc.c b/src/H5Gloc.c index ca488cf..89f2861 100644 --- a/src/H5Gloc.c +++ b/src/H5Gloc.c @@ -58,6 +58,7 @@ typedef struct { /* User data for looking up an object in a group by index */ typedef struct { /* downward */ + hid_t lapl_id; /* LAPL to use for operation */ hid_t dxpl_id; /* DXPL to use for operation */ H5L_index_t idx_type; /* Index to use */ H5_iter_order_t order; /* Iteration order within index */ @@ -414,6 +415,8 @@ H5G_loc_find_by_idx_cb(H5G_loc_t UNUSED *grp_loc/*in*/, const char UNUSED *name, H5G_loc_fbi_t *udata = (H5G_loc_fbi_t *)_udata; /* User data passed in */ H5O_link_t fnd_lnk; /* Link within group */ hbool_t lnk_copied = FALSE; /* Whether the link was copied */ + size_t links_left = 1; /* # of links left to traverse (somewhat bogus... :-/ ) */ + hbool_t obj_loc_valid = FALSE; /* Flag to indicate that the object location is valid */ herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI_NOINIT(H5G_loc_find_by_idx_cb) @@ -428,13 +431,27 @@ H5G_loc_find_by_idx_cb(H5G_loc_t UNUSED *grp_loc/*in*/, const char UNUSED *name, HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "link not found") lnk_copied = TRUE; - /* Build the object location for the link */ + /* Build the initial object location for the link */ + if(H5G_link_to_loc(obj_loc, &fnd_lnk, udata->loc) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "cannot initialize object location") + obj_loc_valid = TRUE; + + /* Perform any special traversals that the link needs */ + /* (soft links, user-defined links, file mounting, etc.) */ + /* (may modify the object location) */ + if(H5G_traverse_special(obj_loc, &fnd_lnk, H5G_TARGET_NORMAL, &links_left, TRUE, udata->loc, udata->lapl_id, udata->dxpl_id) < 0) + HGOTO_ERROR(H5E_LINK, H5E_TRAVERSE, FAIL, "special link traversal failed") done: /* Reset the link information, if we have a copy */ if(lnk_copied) H5O_reset(H5O_LINK_ID, &fnd_lnk); + /* Release the object location if we failed after copying it */ + if(ret_value < 0 && obj_loc_valid) + if(H5G_loc_free(udata->loc) < 0) + HDONE_ERROR(H5E_SYM, H5E_CANTRELEASE, FAIL, "can't free location") + /* Indicate that this callback didn't take ownership of the group * * location for the object */ *own_loc = H5G_OWN_NONE; @@ -472,6 +489,7 @@ H5G_loc_find_by_idx(H5G_loc_t *loc, const char *group_name, H5L_index_t idx_type /* Set up user data for locating object */ udata.dxpl_id = dxpl_id; + udata.lapl_id = lapl_id; udata.idx_type = idx_type; udata.order = order; udata.n = n; diff --git a/src/H5Gpkg.h b/src/H5Gpkg.h index 411a8e7..06941a0 100644 --- a/src/H5Gpkg.h +++ b/src/H5Gpkg.h @@ -357,6 +357,9 @@ H5_DLL herr_t H5G_init(void); H5_DLL char * H5G_normalize(const char *name); H5_DLL const char * H5G_component(const char *name, size_t *size_p); H5_DLL herr_t H5G_traverse_term_interface(void); +H5_DLL 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); H5_DLL herr_t H5G_traverse(const H5G_loc_t *loc, const char *name, unsigned target, H5G_traverse_t op, void *op_data, hid_t lapl_id, hid_t dxpl_id); diff --git a/src/H5Gtraverse.c b/src/H5Gtraverse.c index 3cb66cc..ff5f9c0 100644 --- a/src/H5Gtraverse.c +++ b/src/H5Gtraverse.c @@ -445,14 +445,14 @@ done: * *------------------------------------------------------------------------- */ -static herr_t +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) { herr_t ret_value = SUCCEED; /* Return value */ - FUNC_ENTER_NOAPI_NOINIT(H5G_traverse_special) + FUNC_ENTER_NOAPI(H5G_traverse_special, FAIL) /* Sanity check */ HDassert(grp_loc); diff --git a/src/H5O.c b/src/H5O.c index ff18111..3e602b0 100644 --- a/src/H5O.c +++ b/src/H5O.c @@ -348,10 +348,10 @@ H5Oopen_by_idx(hid_t loc_id, const char *group_name, H5L_index_t idx_type, HGOTO_ERROR(H5E_SYM, H5E_CANTOPENOBJ, FAIL, "unable to open object") done: - if(ret_value < 0) - if(loc_found) - if(H5G_loc_free(&obj_loc) < 0) - HDONE_ERROR(H5E_SYM, H5E_CANTRELEASE, FAIL, "can't free location") + /* Release the object location if we failed after copying it */ + if(ret_value < 0 && loc_found) + if(H5G_loc_free(&obj_loc) < 0) + HDONE_ERROR(H5E_SYM, H5E_CANTRELEASE, FAIL, "can't free location") FUNC_LEAVE_API(ret_value) } /* end H5Oopen_by_idx() */ -- cgit v0.12