[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
This commit is contained in:
Quincey Koziol 2010-07-28 07:27:56 -05:00
parent ad2f3285b3
commit 0b7306beed
12 changed files with 339 additions and 157 deletions

View File

@ -638,6 +638,7 @@
./src/H5Ipkg.h
./src/H5Iprivate.h
./src/H5Ipublic.h
./src/H5Itest.c
./src/H5L.c
./src/H5Lexternal.c
./src/H5Lpkg.h

View File

@ -14,7 +14,7 @@
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/* Programmer: Quincey Koziol <koziol@ncsa.uiuc.edu>
* Thusdayr, May 27, 2004
* Thursday, May 27, 2004
*
* Purpose: Dataset testing functions.
*/

View File

@ -426,49 +426,57 @@ H5G_name_copy(H5G_name_t *dst, const H5G_name_t *src, H5_copy_depth_t depth)
*-------------------------------------------------------------------------
*/
ssize_t
H5G_get_name(hid_t id, char *name/*out*/, size_t size, hid_t lapl_id,
hid_t dxpl_id)
H5G_get_name(const H5G_loc_t *loc, char *name/*out*/, size_t size,
hbool_t *cached, hid_t lapl_id, hid_t dxpl_id)
{
H5G_loc_t loc; /* Object location */
ssize_t ret_value = FAIL;
ssize_t len = 0; /* Length of object's name */
ssize_t ret_value; /* Return value */
FUNC_ENTER_NOAPI(H5G_get_name, FAIL)
/* get object location */
if(H5G_loc(id, &loc) >= 0) {
ssize_t len = 0;
/* Sanity check */
HDassert(loc);
/* If the user path is available and it's not "hidden", use it */
if(loc.path->user_path_r != NULL && loc.path->obj_hidden == 0) {
len = H5RS_len(loc.path->user_path_r);
/* If the user path is available and it's not "hidden", use it */
if(loc->path->user_path_r != NULL && loc->path->obj_hidden == 0) {
len = H5RS_len(loc->path->user_path_r);
if(name) {
HDstrncpy(name, H5RS_get_str(loc.path->user_path_r), MIN((size_t)(len + 1), size));
if((size_t)len >= size)
name[size - 1] = '\0';
} /* end if */
if(name) {
HDstrncpy(name, H5RS_get_str(loc->path->user_path_r), MIN((size_t)(len + 1), size));
if((size_t)len >= size)
name[size - 1] = '\0';
} /* end if */
else if(!loc.path->obj_hidden) {
hid_t file;
/* Retrieve file ID for name search */
if((file = H5I_get_file_id(id, FALSE)) < 0)
HGOTO_ERROR(H5E_SYM, H5E_CANTGET, FAIL, "can't retrieve file ID")
/* Search for name of object */
if((len = H5G_get_name_by_addr(file, lapl_id, dxpl_id, loc.oloc, name, size)) < 0) {
H5I_dec_ref(file, FALSE);
HGOTO_ERROR(H5E_SYM, H5E_CANTGET, FAIL, "can't determine name")
} /* end if */
/* Close file ID used for search */
if(H5I_dec_ref(file, FALSE) < 0)
HGOTO_ERROR(H5E_SYM, H5E_CANTCLOSEFILE, FAIL, "can't determine name")
} /* end else */
/* Set return value */
ret_value = len;
/* Indicate that the name is cached, if requested */
/* (Currently only used for testing - QAK, 2010/07/26) */
if(cached)
*cached = TRUE;
} /* end if */
else if(!loc->path->obj_hidden) {
hid_t file;
/* Retrieve file ID for name search */
if((file = H5F_get_id(loc->oloc->file, FALSE)) < 0)
HGOTO_ERROR(H5E_SYM, H5E_CANTGET, FAIL, "can't get file ID")
/* Search for name of object */
if((len = H5G_get_name_by_addr(file, lapl_id, dxpl_id, loc->oloc, name, size)) < 0) {
H5I_dec_ref(file, FALSE);
HGOTO_ERROR(H5E_SYM, H5E_CANTGET, FAIL, "can't determine name")
} /* end if */
/* Close file ID used for search */
if(H5I_dec_ref(file, FALSE) < 0)
HGOTO_ERROR(H5E_SYM, H5E_CANTCLOSEFILE, FAIL, "can't determine name")
/* Indicate that the name is _not_ cached, if requested */
/* (Currently only used for testing - QAK, 2010/07/26) */
if(cached)
*cached = FALSE;
} /* end else */
/* Set return value */
ret_value = len;
done:
FUNC_LEAVE_NOAPI(ret_value)

View File

@ -196,8 +196,8 @@ H5_DLL herr_t H5G_name_replace(const struct H5O_link_t *lnk, H5G_names_op_t op,
H5_DLL herr_t H5G_name_reset(H5G_name_t *name);
H5_DLL herr_t H5G_name_copy(H5G_name_t *dst, const H5G_name_t *src, H5_copy_depth_t depth);
H5_DLL herr_t H5G_name_free(H5G_name_t *name);
H5_DLL ssize_t H5G_get_name(hid_t id, char *name/*out*/, size_t size,
hid_t lapl_id, hid_t dxpl_id);
H5_DLL ssize_t H5G_get_name(const H5G_loc_t *loc, char *name/*out*/, size_t size,
hbool_t *cached, hid_t lapl_id, hid_t dxpl_id);
H5_DLL ssize_t H5G_get_name_by_addr(hid_t fid, hid_t lapl_id, hid_t dxpl_id,
const struct H5O_loc_t *loc, char* name, size_t size);

View File

@ -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;
/* 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")
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;
/* Release any previous location information for the object */
H5G_loc_free(obj_loc);
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")
/* 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")

View File

@ -896,7 +896,7 @@ H5I_register(H5I_type_t type, const void *object, hbool_t app_ref)
/* new ID to check for */
next_id = H5I_MAKE(type, type_ptr->nextid);
hash_loc = H5I_LOC(type_ptr->nextid, type_ptr->hash_size);
hash_loc = (unsigned)H5I_LOC(type_ptr->nextid, type_ptr->hash_size);
curr_id = type_ptr->id_list[hash_loc];
if(curr_id == NULL)
break; /* Ha! this is not likely... */
@ -1421,15 +1421,16 @@ H5I_dec_ref(hid_t id, hbool_t app_ref)
if(!type_ptr->free_func || (type_ptr->free_func)((void *)id_ptr->obj_ptr) >= 0) {
H5I_remove(id);
ret_value = 0;
} else {
} /* end if */
else
ret_value = FAIL;
}
} else {
} /* end if */
else {
--(id_ptr->count);
if (app_ref)
if(app_ref)
--(id_ptr->app_count);
HDassert(id_ptr->count >= id_ptr->app_count);
ret_value = app_ref ? id_ptr->app_count : id_ptr->count;
ret_value = (int)(app_ref ? id_ptr->app_count : id_ptr->count);
}
done:
@ -1525,7 +1526,7 @@ H5I_inc_ref(hid_t id, hbool_t app_ref)
++(id_ptr->app_count);
/* Set return value */
ret_value = app_ref ? id_ptr->app_count : id_ptr->count;
ret_value = (int)(app_ref ? id_ptr->app_count : id_ptr->count);
done:
FUNC_LEAVE_NOAPI(ret_value)
@ -1615,7 +1616,7 @@ H5I_get_ref(hid_t id, hbool_t app_ref)
HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't locate ID")
/* Set return value */
ret_value = app_ref ? id_ptr->app_count : id_ptr->count;
ret_value = (int)(app_ref ? id_ptr->app_count : id_ptr->count);
done:
FUNC_LEAVE_NOAPI(ret_value)
@ -1696,7 +1697,7 @@ H5I_inc_type_ref(H5I_type_t type)
HGOTO_ERROR(H5E_ATOM, H5E_BADGROUP, FAIL, "invalid type")
/* Set return value */
ret_value = ++(type_ptr->count);
ret_value = (int)(++(type_ptr->count));
done:
FUNC_LEAVE_NOAPI(ret_value)
@ -1797,7 +1798,7 @@ H5I_dec_type_ref(H5I_type_t type)
} /* end if */
else {
--(type_ptr->count);
ret_value = type_ptr->count;
ret_value = (herr_t)type_ptr->count;
} /* end else */
done:
@ -1879,7 +1880,7 @@ H5I_get_type_ref(H5I_type_t type)
HGOTO_ERROR(H5E_ATOM, H5E_BADGROUP, FAIL, "invalid type")
/* Set return value */
ret_value = type_ptr->count;
ret_value = (int)type_ptr->count;
done:
FUNC_LEAVE_NOAPI(ret_value)
@ -2133,13 +2134,18 @@ done:
ssize_t
H5Iget_name(hid_t id, char *name/*out*/, size_t size)
{
H5G_loc_t loc; /* Object location */
ssize_t ret_value; /* Return value */
FUNC_ENTER_API(H5Iget_name, FAIL)
H5TRACE3("Zs", "ixz", id, name, size);
/* Get object location */
if(H5G_loc(id, &loc) < 0)
HGOTO_ERROR(H5E_ATOM, H5E_CANTGET, FAIL, "can't retrieve object location")
/* Call internal group routine to retrieve object's name */
if((ret_value = H5G_get_name(id, name, size, H5P_DEFAULT, H5AC_ind_dxpl_id)) < 0)
if((ret_value = H5G_get_name(&loc, name, size, NULL, H5P_DEFAULT, H5AC_ind_dxpl_id)) < 0)
HGOTO_ERROR(H5E_ATOM, H5E_CANTGET, FAIL, "can't retrieve object name")
done:
@ -2187,7 +2193,6 @@ done:
* ID given an object ID.
*
* Return: Success: file ID
*
* Failure: a negative value
*
* Programmer: Raymond Lu
@ -2198,7 +2203,6 @@ done:
hid_t
H5I_get_file_id(hid_t obj_id, hbool_t app_ref)
{
H5G_loc_t loc; /* Location of object */
H5I_type_t type; /* ID type */
hid_t ret_value; /* Return value */
@ -2207,18 +2211,24 @@ H5I_get_file_id(hid_t obj_id, hbool_t app_ref)
/* Get object type */
type = H5I_TYPE(obj_id);
if(type == H5I_FILE) {
ret_value = obj_id;
/* Increment reference count on atom. */
if(H5I_inc_ref(ret_value, app_ref) < 0)
/* Increment reference count on file ID */
if(H5I_inc_ref(obj_id, app_ref) < 0)
HGOTO_ERROR(H5E_ATOM, H5E_CANTSET, FAIL, "incrementing file ID failed")
}
/* Set return value */
ret_value = obj_id;
} /* end if */
else if(type == H5I_DATATYPE || type == H5I_GROUP || type == H5I_DATASET || type == H5I_ATTR) {
H5G_loc_t loc; /* Location of object */
/* Get the object location information */
if(H5G_loc(obj_id, &loc) < 0)
HGOTO_ERROR(H5E_ATOM, H5E_CANTGET, FAIL, "can't get object location")
/* Get the file ID for the object */
if((ret_value = H5F_get_id(loc.oloc->file, app_ref)) < 0)
HGOTO_ERROR(H5E_ATOM, H5E_CANTGET, FAIL, "can't get file ID")
}
} /* end if */
else
HGOTO_ERROR(H5E_ARGS, H5E_BADRANGE, FAIL, "invalid object ID")

View File

@ -67,4 +67,10 @@
/* Package Private Prototypes */
/******************************/
/* Testing functions */
#ifdef H5I_TESTING
H5_DLL ssize_t H5I_get_name_test(hid_t id, char *name/*out*/, size_t size,
hbool_t *cached);
#endif /* H5I_TESTING */
#endif /*_H5Ipkg_H*/

98
src/H5Itest.c Normal file
View File

@ -0,0 +1,98 @@
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* Copyright by The HDF Group. *
* Copyright by the Board of Trustees of the University of Illinois. *
* All rights reserved. *
* *
* This file is part of HDF5. The full HDF5 copyright notice, including *
* terms governing use, modification, and redistribution, is contained in *
* the files COPYING and Copyright.html. COPYING can be found at the root *
* of the source code distribution tree; Copyright.html can be found at the *
* root level of an installed copy of the electronic HDF5 document set and *
* is linked from the top-level documents page. It can also be found at *
* http://hdfgroup.org/HDF5/doc/Copyright.html. If you do not have *
* access to either file, you may request a copy from help@hdfgroup.org. *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/* Programmer: Quincey Koziol <koziol@hdfgoup.org>
* Tuesday, July 27, 2010
*
* Purpose: ID testing functions.
*/
/****************/
/* Module Setup */
/****************/
#define H5I_PACKAGE /*suppress error about including H5Ipkg */
#define H5I_TESTING /*suppress warning about H5I testing funcs*/
/***********/
/* Headers */
/***********/
#include "H5private.h" /* Generic Functions */
#include "H5ACprivate.h" /* Metadata cache */
#include "H5Eprivate.h" /* Error handling */
#include "H5Gprivate.h" /* Groups */
#include "H5Ipkg.h" /* IDs */
/****************/
/* Local Macros */
/****************/
/******************/
/* Local Typedefs */
/******************/
/********************/
/* Local Prototypes */
/********************/
/*********************/
/* Package Variables */
/*********************/
/*******************/
/* Local Variables */
/*******************/
/*-------------------------------------------------------------------------
* Function: H5I_get_name_test
*
* Purpose: Testing version of H5Iget_name()
*
* Return: Success: The length of name.
* Failure: -1
*
* Programmer: Quincey Koziol
* Tuesday, July 27, 2010
*
*-------------------------------------------------------------------------
*/
ssize_t
H5I_get_name_test(hid_t id, char *name/*out*/, size_t size, hbool_t *cached)
{
H5G_loc_t loc; /* Object location */
ssize_t ret_value; /* Return value */
FUNC_ENTER_NOAPI(H5I_get_name_test, FAIL)
/* Get object location */
if(H5G_loc(id, &loc) < 0)
HGOTO_ERROR(H5E_ATOM, H5E_CANTGET, FAIL, "can't retrieve object location")
/* Call internal group routine to retrieve object's name */
if((ret_value = H5G_get_name(&loc, name, size, cached, H5P_DEFAULT, H5AC_ind_dxpl_id)) < 0)
HGOTO_ERROR(H5E_ATOM, H5E_CANTGET, FAIL, "can't retrieve object name")
done:
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5I_get_name_test() */

View File

@ -53,6 +53,9 @@ const H5L_class_t H5L_EXTERN_LINK_CLASS[1] = {{
/* Valid flags for external links */
#define H5L_EXT_FLAGS_ALL 0
/* Size of local link name buffer for traversing external links */
#define H5L_EXT_TRAVERSE_BUF_SIZE 256
/*--------------------------------------------------------------------------
NAME
@ -205,7 +208,8 @@ H5L_extern_traverse(const char UNUSED *link_name, hid_t cur_group,
H5L_elink_cb_t cb_info; /* Callback info struct */
hid_t fapl_id = -1; /* File access property list for external link's file */
hid_t ext_obj = -1; /* ID for external link's object */
char *temp_group_name = NULL;/* Temporary pointer to group name */
char *parent_group_name = NULL;/* Temporary pointer to group name */
char local_group_name[H5L_EXT_TRAVERSE_BUF_SIZE]; /* Local buffer to hold group name */
char *temp_file_name = NULL; /* Temporary pointer to file name */
char *actual_file_name = NULL; /* Parent file's actual name */
H5P_genplist_t *fa_plist; /* File access property list pointer */
@ -264,41 +268,34 @@ H5L_extern_traverse(const char UNUSED *link_name, hid_t cur_group,
/* Make callback if it exists */
if(cb_info.func) {
const char *parent_file_name; /* Parent file name */
const char *parent_group_name; /* Parent group name */
ssize_t group_name_len; /* Length of parent group name */
/* Get parent file name */
parent_file_name = H5F_OPEN_NAME(loc.oloc->file);
/* Query length of parent group name */
if((group_name_len = H5G_get_name(&loc, NULL, (size_t) 0, NULL, lapl_id, H5AC_ind_dxpl_id)) < 0)
HGOTO_ERROR(H5E_LINK, H5E_CANTGET, FAIL, "unable to retrieve length of group name")
/* Account for null terminator */
group_name_len++;
/* Check if we need to allocate larger buffer */
if((size_t)group_name_len > sizeof(local_group_name)) {
if(NULL == (parent_group_name = (char *)H5MM_malloc((size_t)group_name_len)))
HGOTO_ERROR(H5E_LINK, H5E_CANTALLOC, FAIL, "can't allocate buffer to hold group name, group_name_len = %Zu", group_name_len)
} /* end if */
else
parent_group_name = local_group_name;
/* Get parent group name */
if(loc.path->user_path_r != NULL && loc.path->obj_hidden == 0)
/* Use user_path_r if possible */
parent_group_name = H5RS_get_str(loc.path->user_path_r);
else {
/* Otherwise use H5G_get_name */
ssize_t group_name_len; /* Length of parent group name */
/* Get length of parent group name */
if((group_name_len = H5G_get_name(cur_group, NULL, (size_t) 0, lapl_id, H5AC_ind_dxpl_id)) < 0)
HGOTO_ERROR(H5E_LINK, H5E_CANTGET, FAIL, "unable to retrieve length of group name")
/* account for null terminator */
group_name_len++;
/* Copy parent group name */
if(NULL == (temp_group_name = (char *)H5MM_malloc((size_t)group_name_len)))
HGOTO_ERROR(H5E_LINK, H5E_NOSPACE, FAIL, "memory allocation failed")
if(H5G_get_name(cur_group, temp_group_name, (size_t) group_name_len, lapl_id, H5AC_ind_dxpl_id) < 0)
HGOTO_ERROR(H5E_LINK, H5E_CANTGET, FAIL, "unable to retrieve group name")
parent_group_name = temp_group_name;
} /* end else */
if(H5G_get_name(&loc, parent_group_name, (size_t) group_name_len, NULL, lapl_id, H5AC_ind_dxpl_id) < 0)
HGOTO_ERROR(H5E_LINK, H5E_CANTGET, FAIL, "unable to retrieve group name")
/* Make callback */
if((cb_info.func)(parent_file_name, parent_group_name, file_name, obj_name, &intent, fapl_id, cb_info.user_data) < 0)
HGOTO_ERROR(H5E_LINK, H5E_CALLBACK, FAIL, "traversal operator failed")
/* Free temp_group_name */
temp_group_name = (char *)H5MM_xfree(temp_group_name);
/* Check access flags */
if((intent & H5F_ACC_TRUNC) || (intent & H5F_ACC_EXCL))
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid file open flags")
@ -460,8 +457,9 @@ done:
HDONE_ERROR(H5E_ATOM, H5E_CANTRELEASE, FAIL, "unable to close atom for file access property list")
if(ext_file && H5F_try_close(ext_file) < 0)
HDONE_ERROR(H5E_LINK, H5E_CANTCLOSEFILE, FAIL, "problem closing external file")
if(parent_group_name && parent_group_name != local_group_name)
parent_group_name = (char *)H5MM_xfree(parent_group_name);
full_name = (char *)H5MM_xfree(full_name);
temp_group_name = (char *)H5MM_xfree(temp_group_name);
temp_file_name = (char *)H5MM_xfree(temp_file_name);
actual_file_name = (char *)H5MM_xfree(actual_file_name);

View File

@ -72,7 +72,7 @@ libhdf5_la_SOURCES= H5.c H5checksum.c H5dbg.c H5system.c H5timer.c H5trace.c \
H5HFspace.c H5HFstat.c H5HFtest.c H5HFtiny.c \
H5HG.c H5HGcache.c H5HGdbg.c \
H5HL.c H5HLcache.c H5HLdbg.c H5HLint.c \
H5HP.c H5I.c H5L.c H5Lexternal.c H5lib_settings.c \
H5HP.c H5I.c H5Itest.c H5L.c H5Lexternal.c H5lib_settings.c \
H5MF.c H5MFaggr.c H5MFdbg.c H5MFsection.c \
H5MM.c H5MP.c H5MPtest.c \
H5O.c H5Oainfo.c H5Oalloc.c H5Oattr.c \

View File

@ -122,7 +122,7 @@ am_libhdf5_la_OBJECTS = H5.lo H5checksum.lo H5dbg.lo H5system.lo \
H5HFdtable.lo H5HFhdr.lo H5HFhuge.lo H5HFiblock.lo H5HFiter.lo \
H5HFman.lo H5HFsection.lo H5HFspace.lo H5HFstat.lo H5HFtest.lo \
H5HFtiny.lo H5HG.lo H5HGcache.lo H5HGdbg.lo H5HL.lo \
H5HLcache.lo H5HLdbg.lo H5HLint.lo H5HP.lo H5I.lo H5L.lo \
H5HLcache.lo H5HLdbg.lo H5HLint.lo H5HP.lo H5I.lo H5Itest.lo H5L.lo \
H5Lexternal.lo H5lib_settings.lo H5MF.lo H5MFaggr.lo \
H5MFdbg.lo H5MFsection.lo H5MM.lo H5MP.lo H5MPtest.lo H5O.lo \
H5Oainfo.lo H5Oalloc.lo H5Oattr.lo H5Oattribute.lo H5Obogus.lo \
@ -492,7 +492,7 @@ libhdf5_la_SOURCES = H5.c H5checksum.c H5dbg.c H5system.c H5timer.c H5trace.c \
H5HFspace.c H5HFstat.c H5HFtest.c H5HFtiny.c \
H5HG.c H5HGcache.c H5HGdbg.c \
H5HL.c H5HLcache.c H5HLdbg.c H5HLint.c \
H5HP.c H5I.c H5L.c H5Lexternal.c H5lib_settings.c \
H5HP.c H5I.c H5Itest.c H5L.c H5Lexternal.c H5lib_settings.c \
H5MF.c H5MFaggr.c H5MFdbg.c H5MFsection.c \
H5MM.c H5MP.c H5MPtest.c \
H5O.c H5Oainfo.c H5Oalloc.c H5Oattr.c \
@ -803,6 +803,7 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5HLint.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5HP.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5I.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5Itest.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5L.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5Lexternal.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5MF.Plo@am__quote@

View File

@ -21,12 +21,15 @@
*/
#define H5G_PACKAGE /*suppress error about including H5Gpkg */
#define H5I_PACKAGE /*suppress error about including H5Ipkg */
/* Define this macro to indicate that the testing APIs should be available */
/* Define these macros to indicate that the testing APIs should be available */
#define H5G_TESTING
#define H5I_TESTING
#include "h5test.h"
#include "H5Gpkg.h" /* Groups */
#include "H5Ipkg.h" /* IDs */
/* Compound datatype */
@ -1145,7 +1148,7 @@ test_main(hid_t file_id, hid_t fapl)
/* Get name */
*name2 = '\0';
name_len=H5Iget_name(group_id, name2, SMALL_NAME_BUF_SIZE);
name_len=(size_t)H5Iget_name(group_id, name2, SMALL_NAME_BUF_SIZE);
/* Check that name is longer */
if(name_len <= SMALL_NAME_BUF_SIZE) TEST_ERROR
@ -1172,14 +1175,14 @@ test_main(hid_t file_id, hid_t fapl)
if((group_id = H5Gopen2(file_id, "/g17", H5P_DEFAULT)) < 0) FAIL_STACK_ERROR
/* Get name */
name_len = H5Iget_name(group_id, NULL, NAME_BUF_SIZE);
name_len = (size_t)H5Iget_name(group_id, NULL, NAME_BUF_SIZE);
{
/* dynamic buffer to hold name */
char *name3;
/* Include the extra null character */
name3 = HDmalloc(name_len + 1);
name3 = (char *)HDmalloc(name_len + 1);
if(!name3) TEST_ERROR
/* Get name with dynamic buffer */
@ -2679,7 +2682,7 @@ test_reg_ref(hid_t fapl)
hsize_t count[2];
hsize_t coord[2][3] = {{0, 0, 1}, {6, 0, 8}};
unsigned num_points = 3;
size_t name_size1, name_size2;
ssize_t name_size1, name_size2;
char buf1[NAME_BUF_SIZE], buf2[NAME_BUF_SIZE];
/* Initialize the file name */
@ -2808,6 +2811,101 @@ error:
return 1;
}
/*-------------------------------------------------------------------------
* Function: test_elinks
*
* Purpose: Verify that querying names of objects reached via external
* links uses cached path/name information for object and doesn't
* search the file.
*
* Return: Success: 0
* Failure: 1
*
* Programmer: Quincey Koziol
* Tuesday, July 27, 2010
*
*-------------------------------------------------------------------------
*/
static int
test_elinks(hid_t fapl)
{
char filename1[1024], filename2[1024]; /* Filenames */
hid_t fid1, fid2; /* HDF5 File IDs */
hid_t group, group2; /* Group IDs */
char name[NAME_BUF_SIZE]; /* Buffer for storing object's name */
ssize_t namelen; /* Length of object's name */
hbool_t name_cached; /* Indicate if name is cached */
unsigned u; /* Counting variables */
/* Initialize the file names */
h5_fixname(FILENAME[1], fapl, filename1, sizeof filename1);
h5_fixname(FILENAME[2], fapl, filename2, sizeof filename2);
/* Create files */
if((fid1 = H5Fcreate(filename1, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0)
FAIL_STACK_ERROR
if((fid2 = H5Fcreate(filename2, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0)
FAIL_STACK_ERROR
/* Create a group in the second file */
if((group2 = H5Gcreate2(fid2, "Group2", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0)
FAIL_STACK_ERROR
/* Close Group */
if(H5Gclose(group2) < 0)
FAIL_STACK_ERROR
/* Create an external link in first file to the group in the second file */
if(H5Lcreate_external(filename2, "Group2", fid1, "Link_to_Group2", H5P_DEFAULT, H5P_DEFAULT) < 0)
FAIL_STACK_ERROR
/* Create an external link in second file to the external link in the first file */
if(H5Lcreate_external(filename1, "Link_to_Group2", fid2, "Link_to_Link_to_Group2", H5P_DEFAULT, H5P_DEFAULT) < 0)
FAIL_STACK_ERROR
/* Open the group in thesecond file through the external link */
if((group = H5Gopen2(fid1, "Link_to_Group2", H5P_DEFAULT)) < 0)
FAIL_STACK_ERROR
/* Query the external link object's name */
*name = '\0';
name_cached = FALSE;
namelen = H5I_get_name_test(group, (char*)name, sizeof(name), &name_cached);
if(!((HDstrcmp(name, "/Group2") == 0) && (namelen == 7) && name_cached))
TEST_ERROR
/* Close Group */
if(H5Gclose(group) < 0)
FAIL_STACK_ERROR
/* Open the group in the second file through the external link to the external link */
if((group = H5Gopen2(fid2, "Link_to_Link_to_Group2", H5P_DEFAULT)) < 0)
FAIL_STACK_ERROR
/* Query the external link to external link object's name */
*name = '\0';
name_cached = FALSE;
namelen = H5I_get_name_test(group, (char*)name, sizeof(name), &name_cached);
if(!((HDstrcmp(name, "/Group2") == 0) && (namelen == 7) && name_cached))
TEST_ERROR
/* Close Group */
if(H5Gclose(group) < 0)
FAIL_STACK_ERROR
/* Close files */
if(H5Fclose(fid1) < 0)
FAIL_STACK_ERROR
if(H5Fclose(fid2) < 0)
FAIL_STACK_ERROR
return 0;
error:
return 1;
}
int
main(void)
{
@ -2830,6 +2928,7 @@ main(void)
nerrors += test_main(file_id, fapl);
nerrors += test_obj_ref(fapl);
nerrors += test_reg_ref(fapl);
nerrors += test_elinks(fapl);
/* Close file */
H5Fclose(file_id);