summaryrefslogtreecommitdiffstats
path: root/src/H5Gtraverse.c
diff options
context:
space:
mode:
authorQuincey Koziol <koziol@hdfgroup.org>2010-07-28 12:27:56 (GMT)
committerQuincey Koziol <koziol@hdfgroup.org>2010-07-28 12:27:56 (GMT)
commit0b7306beed3616d5e259ce3efa1dd0105f436fdb (patch)
tree4d5d467a608e5fc9ada867f913136de744750860 /src/H5Gtraverse.c
parentad2f3285b3a0e55aab2014c9e395009df758fef6 (diff)
downloadhdf5-0b7306beed3616d5e259ce3efa1dd0105f436fdb.zip
hdf5-0b7306beed3616d5e259ce3efa1dd0105f436fdb.tar.gz
hdf5-0b7306beed3616d5e259ce3efa1dd0105f436fdb.tar.bz2
[svn-r19133] Description:
Correct traversal of user-defined links (including external links) to retain path information of object, allowing H5Iget_name() queries to work quickly (without searching entire destination file). This required some refactoring and addition of a mechanism to detect if a "fast" query was performed (for the tests). Minor code cleanups, etc. Tested on: FreeBSD/32 6.3 (duty) in debug mode FreeBSD/64 6.3 (liberty) w/C++ & FORTRAN, in debug mode Linux/32 2.6 (jam) w/PGI compilers, w/default API=1.8.x, w/C++ & FORTRAN, w/threadsafe, in debug mode Linux/64-amd64 2.6 (amani) w/Intel compilers, w/default API=1.6.x, w/C++ & FORTRAN, in production mode Solaris/32 2.10 (linew) w/deprecated symbols disabled, w/C++ & FORTRAN, w/szip filter, w/threadsafe, in production mode Linux/PPC 2.6 (heiwa) w/C++ & FORTRAN, w/threadsafe, in debug mode Linux/64-ia64 2.6 (cobalt) w/Intel compilers, w/C++ & FORTRAN, in production mode Linux/64-amd64 2.6 (abe) w/parallel, w/FORTRAN, in debug mode Mac OS X/32 10.6.4 (amazon) in debug mode Mac OS X/32 10.6.4 (amazon) w/C++ & FORTRAN, w/threadsafe, in production mode Mac OS X/32 10.6.4 (amazon) w/parallel, in debug mode
Diffstat (limited to 'src/H5Gtraverse.c')
-rw-r--r--src/H5Gtraverse.c95
1 files changed, 28 insertions, 67 deletions
diff --git a/src/H5Gtraverse.c b/src/H5Gtraverse.c
index 5b1f71c..61c08fa 100644
--- a/src/H5Gtraverse.c
+++ b/src/H5Gtraverse.c
@@ -171,8 +171,7 @@ H5G_traverse_ud(const H5G_loc_t *grp_loc/*in,out*/, const H5O_link_t *lnk,
H5G_loc_t grp_loc_copy;
H5G_name_t grp_path_copy;
H5O_loc_t grp_oloc_copy;
- H5O_loc_t *new_oloc = NULL;
- H5F_t *temp_file = NULL;
+ H5G_loc_t new_loc; /* Group location for newly opened external object */
H5G_t *grp;
hid_t lapl_id = (-1); /* LAPL local to this routine */
H5P_genplist_t *lapl; /* LAPL with nlinks set */
@@ -189,13 +188,9 @@ H5G_traverse_ud(const H5G_loc_t *grp_loc/*in,out*/, const H5O_link_t *lnk,
HDassert(nlinks);
HDassert(_lapl_id >= 0);
- /* Reset the object's path information, because we can't detect any changes
- * in the "path" the user-defined callback takes */
- H5G_name_free(obj_loc->path);
-
/* Get the link class for this type of link. */
if(NULL == (link_class = H5L_find_class(lnk->type)))
- HGOTO_ERROR(H5E_LINK, H5E_NOTREGISTERED, FAIL, "unable to get UD link class")
+ HGOTO_ERROR(H5E_SYM, H5E_NOTREGISTERED, FAIL, "unable to get UD link class")
/* Set up location for user-defined callback. Use a copy of our current
* grp_loc. */
@@ -203,37 +198,37 @@ H5G_traverse_ud(const H5G_loc_t *grp_loc/*in,out*/, const H5O_link_t *lnk,
grp_loc_copy.oloc = &grp_oloc_copy;
H5G_loc_reset(&grp_loc_copy);
if(H5G_loc_copy(&grp_loc_copy, grp_loc, H5_COPY_DEEP) < 0)
- HGOTO_ERROR(H5E_FILE, H5E_CANTCOPY, FAIL, "unable to copy object location")
+ HGOTO_ERROR(H5E_SYM, H5E_CANTCOPY, FAIL, "unable to copy object location")
- /* Create a group to pass to the user-defined callback */
- if((grp = H5G_open(&grp_loc_copy, dxpl_id)) == NULL)
+ /* Create a group ID to pass to the user-defined callback */
+ if(NULL == (grp = H5G_open(&grp_loc_copy, dxpl_id)))
HGOTO_ERROR(H5E_SYM, H5E_CANTOPENOBJ, FAIL, "unable to open group")
if((cur_grp = H5I_register(H5I_GROUP, grp, FALSE)) < 0)
- HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL, "unable to register group")
+ HGOTO_ERROR(H5E_SYM, H5E_CANTREGISTER, FAIL, "unable to register group")
/* Check for generic default property list and use link access default if so */
if(_lapl_id == H5P_DEFAULT) {
HDassert(H5P_LINK_ACCESS_DEFAULT != -1);
if(NULL == (lapl = (H5P_genplist_t *)H5I_object(H5P_LINK_ACCESS_DEFAULT)))
- HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "unable to get default property list")
+ HGOTO_ERROR(H5E_SYM, H5E_BADATOM, FAIL, "unable to get default property list")
} /* end if */
else {
/* Get the underlying property list passed in */
if(NULL == (lapl = (H5P_genplist_t *)H5I_object(_lapl_id)))
- HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "unable to get property list from ID")
+ HGOTO_ERROR(H5E_SYM, H5E_BADATOM, FAIL, "unable to get property list from ID")
} /* end else */
/* Copy the property list passed in */
if((lapl_id = H5P_copy_plist(lapl, FALSE)) < 0)
- HGOTO_ERROR(H5E_PLIST, H5E_BADVALUE, FAIL, "unable to copy property list")
+ HGOTO_ERROR(H5E_SYM, H5E_CANTCOPY, FAIL, "unable to copy property list")
/* Get the underlying property list copy */
if(NULL == (lapl = (H5P_genplist_t *)H5I_object(lapl_id)))
- HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "unable to get property list from ID")
+ HGOTO_ERROR(H5E_SYM, H5E_BADATOM, FAIL, "unable to get property list from ID")
/* Record number of soft links left to traverse in the property list. */
if(H5P_set(lapl, H5L_ACS_NLINKS_NAME, nlinks) < 0)
- HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set nlink info")
+ HGOTO_ERROR(H5E_SYM, H5E_CANTSET, FAIL, "can't set nlink info")
/* User-defined callback function */
cb_return = (link_class->trav_func)(lnk->name, cur_grp, lnk->u.ud.udata, lnk->u.ud.size, lapl_id);
@@ -253,79 +248,45 @@ H5G_traverse_ud(const H5G_loc_t *grp_loc/*in,out*/, const H5O_link_t *lnk,
} /* end if */
/* else, we really needed to open the object */
else
- HGOTO_ERROR(H5E_ARGS, H5E_BADATOM, FAIL, "traversal callback returned invalid ID")
+ HGOTO_ERROR(H5E_SYM, 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)) {
- case H5I_GROUP:
- if((new_oloc = H5G_oloc((H5G_t *)H5I_object(cb_return))) == NULL)
- HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "unable to get object location from group ID")
- break;
-
- case H5I_DATASET:
- if((new_oloc = H5D_oloc((H5D_t *)H5I_object(cb_return))) ==NULL)
- HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "unable to get object location from dataset ID")
- break;
-
- case H5I_DATATYPE:
- if((new_oloc = H5T_oloc((H5T_t *)H5I_object(cb_return))) ==NULL)
- HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "unable to get object location from datatype ID")
- break;
-
- case H5I_FILE:
- if((temp_file = (H5F_t *)H5I_object(cb_return)) == NULL)
- HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "couldn't get file from ID")
- if((new_oloc = H5G_oloc(temp_file->shared->root_grp)) ==NULL)
- HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "unable to get root group location from file ID")
- break;
-
- case H5I_UNINIT:
- case H5I_BADID:
- case H5I_DATASPACE:
- case H5I_ATTR:
- case H5I_REFERENCE:
- case H5I_VFL:
- case H5I_GENPROP_CLS:
- case H5I_GENPROP_LST:
- case H5I_ERROR_CLASS:
- case H5I_ERROR_MSG:
- case H5I_ERROR_STACK:
- case H5I_NTYPES:
- default:
- HGOTO_ERROR(H5E_ATOM, H5E_BADTYPE, FAIL, "not a valid location or object ID")
- } /* end switch */
-
- /* Copy the location the user returned to us */
- if(H5O_loc_copy(obj_loc->oloc, new_oloc, H5_COPY_DEEP) < 0)
- HGOTO_ERROR(H5E_FILE, H5E_CANTCOPY, FAIL, "unable to copy object location")
+ /* Get the object location information from the ID the user callback returned */
+ if(H5G_loc(cb_return, &new_loc) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_BADVALUE, FAIL, "unable to get object location from ID")
+
+ /* Release any previous location information for the object */
+ H5G_loc_free(obj_loc);
+
+ /* Copy new object's location information */
+ H5G_loc_copy(obj_loc, &new_loc, H5_COPY_DEEP);
/* Hold the file open until we free this object header (otherwise the
* object location will be invalidated when the file closes).
*/
if(H5O_loc_hold_file(obj_loc->oloc) < 0)
- HGOTO_ERROR(H5E_OHDR, H5E_LINKCOUNT, FAIL, "unable to hold file open")
+ HGOTO_ERROR(H5E_SYM, H5E_CANTOPENOBJ, FAIL, "unable to hold file open")
/* We have a copy of the location and we're holding the file open.
* Close the open ID the user passed back.
*/
if(H5I_dec_ref(cb_return, FALSE) < 0)
- HGOTO_ERROR(H5E_ATOM, H5E_CANTRELEASE, FAIL, "unable to close atom from UD callback")
+ HGOTO_ERROR(H5E_SYM, H5E_CANTRELEASE, FAIL, "unable to close atom from UD callback")
cb_return = (-1);
done:
/* Close location given to callback. */
if(cur_grp > 0)
if(H5I_dec_ref(cur_grp, FALSE) < 0)
- HDONE_ERROR(H5E_ATOM, H5E_CANTRELEASE, FAIL, "unable to close atom for current location")
+ HDONE_ERROR(H5E_SYM, H5E_CANTRELEASE, FAIL, "unable to close atom for current location")
if(ret_value < 0 && cb_return > 0)
if(H5I_dec_ref(cb_return, FALSE) < 0)
- HDONE_ERROR(H5E_ATOM, H5E_CANTRELEASE, FAIL, "unable to close atom from UD callback")
+ HDONE_ERROR(H5E_SYM, H5E_CANTRELEASE, FAIL, "unable to close atom from UD callback")
/* Close the LAPL, if we copied one */
if(lapl_id > 0 && H5I_dec_ref(lapl_id, FALSE) < 0)
- HDONE_ERROR(H5E_ATOM, H5E_CANTRELEASE, FAIL, "unable to close copied link access property list")
+ HDONE_ERROR(H5E_SYM, H5E_CANTRELEASE, FAIL, "unable to close copied link access property list")
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5G_traverse_ud() */
@@ -573,7 +534,7 @@ H5G_traverse_special(const H5G_loc_t *grp_loc, const H5O_link_t *lnk,
*/
if(grp_loc->oloc->holding_file && grp_loc->oloc->file == obj_loc->oloc->file)
if(H5O_loc_hold_file(obj_loc->oloc) < 0)
- HGOTO_ERROR(H5E_OHDR, H5E_LINKCOUNT, FAIL, "unable to hold file open")
+ HGOTO_ERROR(H5E_SYM, H5E_CANTOPENOBJ, FAIL, "unable to hold file open")
done:
FUNC_LEAVE_NOAPI(ret_value)
@@ -845,7 +806,7 @@ H5G_traverse_real(const H5G_loc_t *_loc, const char *name, unsigned target,
*/
if(grp_loc.oloc->holding_file)
if(H5O_loc_hold_file(obj_loc.oloc) < 0)
- HGOTO_ERROR(H5E_OHDR, H5E_LINKCOUNT, FAIL, "unable to hold file open")
+ HGOTO_ERROR(H5E_SYM, H5E_CANTOPENOBJ, FAIL, "unable to hold file open")
} /* end if */
else
HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "component not found")