From 522e714273faf7e8b1bbd0510a2a921ad6276ab3 Mon Sep 17 00:00:00 2001 From: Quincey Koziol Date: Thu, 1 Nov 2007 17:19:04 -0500 Subject: [svn-r14234] Description: Add H5Aexists and H5Aexists_by_name API routines, to match H5Lexists. Tested on: FreeBSD/32 6.2 (duty) in debug mode FreeBSD/64 6.2 (liberty) w/C++ & FORTRAN, in debug mode Linux/32 2.6 (kagiso) w/PGI compilers, w/C++ & FORTRAN, w/threadsafe, in debug mode Linux/64-amd64 2.6 (smirom) w/default API=1.6.x, w/C++ & FORTRAN, in production mode Linux/64-ia64 2.6 (cobalt) w/Intel compilers, w/C++ & FORTRAN, in production mode Solaris/32 2.10 (linew) w/deprecated symbols disabled, w/C++ & FORTRAN, w/szip filter, in production mode Mac OS X/32 10.4.10 (amazon) in debug mode Linux/64-ia64 2.4 (tg-login3) w/parallel, w/FORTRAN, in production mode --- src/H5A.c | 105 +++++++++++++++++++++++++++++++++++++++++++++++++++++ src/H5Apublic.h | 5 ++- src/H5L.c | 6 +-- src/H5Oattribute.c | 13 +++++-- test/tattr.c | 67 ++++++++++++++++++++++++++++++---- 5 files changed, 180 insertions(+), 16 deletions(-) diff --git a/src/H5A.c b/src/H5A.c index acd6307..4a09fde 100644 --- a/src/H5A.c +++ b/src/H5A.c @@ -2486,3 +2486,108 @@ done: FUNC_LEAVE_NOAPI(ret_value) } /* end H5A_nameof() */ + +/*------------------------------------------------------------------------- + * Function: H5Aexists + * + * Purpose: Checks if an attribute with a given name exists on an opened + * object. + * + * Return: Success: TRUE/FALSE + * Failure: Negative + * + * Programmer: Quincey Koziol + * Thursday, November 1, 2007 + * + *------------------------------------------------------------------------- + */ +htri_t +H5Aexists(hid_t obj_id, const char *attr_name) +{ + H5G_loc_t loc; /* Object location */ + htri_t ret_value; /* Return value */ + + FUNC_ENTER_API(H5Aexists, FAIL) + H5TRACE2("t", "i*s", obj_id, attr_name); + + /* check arguments */ + if(H5I_ATTR == H5I_get_type(obj_id)) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "location is not valid for an attribute") + if(H5G_loc(obj_id, &loc) < 0) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a location") + if(!attr_name || !*attr_name) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no attribute name") + + /* Check if the attribute exists */ + if((ret_value = H5O_attr_exists(loc.oloc, attr_name, H5AC_ind_dxpl_id)) < 0) + HGOTO_ERROR(H5E_ATTR, H5E_CANTGET, FAIL, "unable to determine if attribute exists") + +done: + FUNC_LEAVE_API(ret_value) +} /* H5Aexists() */ + + +/*------------------------------------------------------------------------- + * Function: H5Aexists_by_name + * + * Purpose: Checks if an attribute with a given name exists on an object. + * + * Return: Success: TRUE/FALSE + * Failure: Negative + * + * Programmer: Quincey Koziol + * Thursday, November 1, 2007 + * + *------------------------------------------------------------------------- + */ +htri_t +H5Aexists_by_name(hid_t loc_id, const char *obj_name, const char *attr_name, + hid_t lapl_id) +{ + H5G_loc_t loc; /* Object location */ + H5G_loc_t obj_loc; /* Location used to open group */ + H5G_name_t obj_path; /* Opened object group hier. path */ + H5O_loc_t obj_oloc; /* Opened object object location */ + hbool_t loc_found = FALSE; /* Entry at 'obj_name' found */ + htri_t ret_value; /* Return value */ + + FUNC_ENTER_API(H5Aexists_by_name, FAIL) + H5TRACE4("t", "i*s*si", loc_id, obj_name, attr_name, lapl_id); + + /* check arguments */ + if(H5I_ATTR == H5I_get_type(loc_id)) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "location is not valid for an attribute") + if(H5G_loc(loc_id, &loc) < 0) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a location") + if(!obj_name || !*obj_name) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no object name") + if(!attr_name || !*attr_name) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no attribute name") + if(H5P_DEFAULT == lapl_id) + lapl_id = H5P_LINK_ACCESS_DEFAULT; + else + if(TRUE != H5P_isa_class(lapl_id, H5P_LINK_ACCESS)) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not link access property list ID") + + /* Set up opened group location to fill in */ + obj_loc.oloc = &obj_oloc; + obj_loc.path = &obj_path; + H5G_loc_reset(&obj_loc); + + /* Find the object's location */ + if(H5G_loc_find(&loc, obj_name, &obj_loc/*out*/, lapl_id, H5AC_ind_dxpl_id) < 0) + HGOTO_ERROR(H5E_ATTR, H5E_NOTFOUND, FAIL, "object not found") + loc_found = TRUE; + + /* Check if the attribute exists */ + if((ret_value = H5O_attr_exists(obj_loc.oloc, attr_name, H5AC_ind_dxpl_id)) < 0) + HGOTO_ERROR(H5E_ATTR, H5E_CANTGET, FAIL, "unable to determine if attribute exists") + +done: + /* Release resources */ + if(loc_found && H5G_loc_free(&obj_loc) < 0) + HDONE_ERROR(H5E_ATTR, H5E_CANTRELEASE, FAIL, "can't free location") + + FUNC_LEAVE_API(ret_value) +} /* H5Aexists_by_name() */ + diff --git a/src/H5Apublic.h b/src/H5Apublic.h index c320a91..3586bad 100644 --- a/src/H5Apublic.h +++ b/src/H5Apublic.h @@ -45,7 +45,7 @@ H5_DLL hid_t H5Acreate2(hid_t loc_id, const char *attr_name, hid_t type_id, hid_t space_id, hid_t acpl_id, hid_t aapl_id); H5_DLL hid_t H5Acreate_by_name(hid_t loc_id, const char *obj_name, const char *attr_name, hid_t type_id, hid_t space_id, hid_t acpl_id, hid_t aapl_id, hid_t lapl_id); -H5_DLL hid_t H5Aopen(hid_t loc_id, const char *attr_name, hid_t aapl_id); +H5_DLL hid_t H5Aopen(hid_t obj_id, const char *attr_name, hid_t aapl_id); H5_DLL hid_t H5Aopen_by_name(hid_t loc_id, const char *obj_name, const char *attr_name, hid_t aapl_id, hid_t lapl_id); H5_DLL hid_t H5Aopen_by_idx(hid_t loc_id, const char *obj_name, @@ -81,6 +81,9 @@ H5_DLL herr_t H5Adelete_by_name(hid_t loc_id, const char *obj_name, const char *attr_name, hid_t lapl_id); H5_DLL herr_t H5Adelete_by_idx(hid_t loc_id, const char *obj_name, H5_index_t idx_type, H5_iter_order_t order, hsize_t n, hid_t lapl_id); +H5_DLL htri_t H5Aexists(hid_t obj_id, const char *attr_name); +H5_DLL htri_t H5Aexists_by_name(hid_t obj_id, const char *obj_name, + const char *attr_name, hid_t lapl_id); /* Symbols defined for compatibility with previous versions of the HDF5 API. * diff --git a/src/H5L.c b/src/H5L.c index d8fb0eb..78a78f2 100644 --- a/src/H5L.c +++ b/src/H5L.c @@ -794,14 +794,14 @@ done: * *------------------------------------------------------------------------- */ -herr_t +htri_t H5Lexists(hid_t loc_id, const char *name, hid_t lapl_id) { H5G_loc_t loc; - herr_t ret_value = SUCCEED; + htri_t ret_value; FUNC_ENTER_API(H5Lexists, FAIL) - H5TRACE3("e", "i*si", loc_id, name, lapl_id); + H5TRACE3("t", "i*si", loc_id, name, lapl_id); /* Check arguments */ if(H5G_loc(loc_id, &loc)) diff --git a/src/H5Oattribute.c b/src/H5Oattribute.c index 5c0a91a..5c9f875 100644 --- a/src/H5Oattribute.c +++ b/src/H5Oattribute.c @@ -61,8 +61,6 @@ typedef struct { /* User data for iteration when opening an attribute */ typedef struct { /* down */ - H5F_t *f; /* Pointer to file attribute is in */ - hid_t dxpl_id; /* DXPL for operation */ const char *name; /* Name of attribute to open */ /* up */ @@ -117,6 +115,15 @@ typedef struct { hbool_t found; /* Found attribute to delete */ } H5O_iter_rm_t; +/* User data for iteration when checking if an attribute exists */ +typedef struct { + /* down */ + const char *name; /* Name of attribute to open */ + + /* up */ + hbool_t found; /* Found attribute */ +} H5O_iter_xst_t; + /********************/ /* Package Typedefs */ @@ -483,8 +490,6 @@ H5O_attr_open_by_name(const H5O_loc_t *loc, const char *name, hid_t dxpl_id) H5O_mesg_operator_t op; /* Wrapper for operator */ /* Set up user data for callback */ - udata.f = loc->file; - udata.dxpl_id = dxpl_id; udata.name = name; udata.attr = NULL; diff --git a/test/tattr.c b/test/tattr.c index 6d9e83d..a6ea79e 100644 --- a/test/tattr.c +++ b/test/tattr.c @@ -129,7 +129,8 @@ float attr_data5=(float)-5.123; /* Test data for 5th attribute */ #define ATTR7_NAME "attr 1 - 000000" #define ATTR8_NAME "attr 2" -#define NATTR_MANY 35000 +#define NATTR_MANY_OLD 350 +#define NATTR_MANY_NEW 35000 /* Attribute iteration struct */ typedef struct { @@ -3348,12 +3349,15 @@ test_attr_deprec(hid_t fcpl, hid_t fapl) ** ****************************************************************/ static void -test_attr_many(hid_t fcpl, hid_t fapl) +test_attr_many(hbool_t new_format, hid_t fcpl, hid_t fapl) { hid_t fid; /* HDF5 File ID */ + hid_t gid; /* Group ID */ hid_t sid; /* Dataspace ID */ hid_t aid; /* Attribute ID */ char attrname[NAME_BUF_SIZE]; /* Name of attribute */ + unsigned nattr = (new_format ? NATTR_MANY_NEW : NATTR_MANY_OLD); /* Number of attributes */ + htri_t exists; /* Whether the attribute exists or not */ unsigned u; /* Local index variable */ herr_t ret; /* Generic return value */ @@ -3368,20 +3372,46 @@ test_attr_many(hid_t fcpl, hid_t fapl) sid = H5Screate(H5S_SCALAR); CHECK(sid, FAIL, "H5Screate"); - /* Create many attributes (on root group) */ - for(u = 0; u < NATTR_MANY; u++) { + /* Create group for attributes */ + gid = H5Gcreate2(fid, GROUP1_NAME, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); + CHECK(gid, FAIL, "H5Gcreate2"); + + /* Create many attributes */ + for(u = 0; u < nattr; u++) { sprintf(attrname, "a-%06u", u); - aid = H5Acreate2(fid, attrname, H5T_NATIVE_UINT, sid, H5P_DEFAULT, H5P_DEFAULT); + exists = H5Aexists(gid, attrname); + VERIFY(exists, FALSE, "H5Aexists"); + + exists = H5Aexists_by_name(fid, GROUP1_NAME, attrname, H5P_DEFAULT); + VERIFY(exists, FALSE, "H5Aexists_by_name"); + + aid = H5Acreate2(gid, attrname, H5T_NATIVE_UINT, sid, H5P_DEFAULT, H5P_DEFAULT); CHECK(aid, FAIL, "H5Acreate2"); + exists = H5Aexists(gid, attrname); + VERIFY(exists, TRUE, "H5Aexists"); + + exists = H5Aexists_by_name(fid, GROUP1_NAME, attrname, H5P_DEFAULT); + VERIFY(exists, TRUE, "H5Aexists_by_name"); + ret = H5Awrite(aid, H5T_NATIVE_UINT, &u); CHECK(ret, FAIL, "H5Awrite"); ret = H5Aclose(aid); CHECK(ret, FAIL, "H5Aclose"); + + exists = H5Aexists(gid, attrname); + VERIFY(exists, TRUE, "H5Aexists"); + + exists = H5Aexists_by_name(fid, GROUP1_NAME, attrname, H5P_DEFAULT); + VERIFY(exists, TRUE, "H5Aexists_by_name"); } /* end for */ + /* Close group */ + ret = H5Gclose(gid); + CHECK(ret, FAIL, "H5Gclose"); + /* Close file */ ret = H5Fclose(fid); CHECK(ret, FAIL, "H5Fclose"); @@ -3393,15 +3423,31 @@ test_attr_many(hid_t fcpl, hid_t fapl) fid = H5Fopen(FILENAME, H5F_ACC_RDONLY, fapl); CHECK(fid, FAIL, "H5Fopen"); + /* Re-open group */ + gid = H5Gopen2(fid, GROUP1_NAME, H5P_DEFAULT); + CHECK(gid, FAIL, "H5Gopen2"); + /* Verify attributes */ - for(u = 0; u < NATTR_MANY; u++) { + for(u = 0; u < nattr; u++) { unsigned value; /* Attribute value */ sprintf(attrname, "a-%06u", u); - aid = H5Aopen(fid, attrname, H5P_DEFAULT); + exists = H5Aexists(gid, attrname); + VERIFY(exists, TRUE, "H5Aexists"); + + exists = H5Aexists_by_name(fid, GROUP1_NAME, attrname, H5P_DEFAULT); + VERIFY(exists, TRUE, "H5Aexists_by_name"); + + aid = H5Aopen(gid, attrname, H5P_DEFAULT); CHECK(aid, FAIL, "H5Aopen"); + exists = H5Aexists(gid, attrname); + VERIFY(exists, TRUE, "H5Aexists"); + + exists = H5Aexists_by_name(fid, GROUP1_NAME, attrname, H5P_DEFAULT); + VERIFY(exists, TRUE, "H5Aexists_by_name"); + ret = H5Aread(aid, H5T_NATIVE_UINT, &value); CHECK(ret, FAIL, "H5Aread"); VERIFY(value, u, "H5Aread"); @@ -3410,6 +3456,10 @@ test_attr_many(hid_t fcpl, hid_t fapl) CHECK(ret, FAIL, "H5Aclose"); } /* end for */ + /* Close group */ + ret = H5Gclose(gid); + CHECK(ret, FAIL, "H5Gclose"); + /* Close file */ ret = H5Fclose(fid); CHECK(ret, FAIL, "H5Fclose"); @@ -8897,7 +8947,7 @@ test_attr(void) test_attr_big(my_fcpl, my_fapl); /* Test storing big attribute */ test_attr_null_space(my_fcpl, my_fapl); /* Test storing attribute with NULL dataspace */ test_attr_deprec(fcpl, my_fapl); /* Test deprecated API routines */ - test_attr_many(my_fcpl, my_fapl); /* Test storing lots of attributes */ + test_attr_many(new_format, my_fcpl, my_fapl); /* Test storing lots of attributes */ /* Attribute creation order tests */ test_attr_corder_create_basic(my_fcpl, my_fapl);/* Test creating an object w/attribute creation order info */ @@ -8932,6 +8982,7 @@ test_attr(void) test_attr_big(fcpl, my_fapl); /* Test storing big attribute */ test_attr_null_space(fcpl, my_fapl); /* Test storing attribute with NULL dataspace */ test_attr_deprec(fcpl, my_fapl); /* Test deprecated API routines */ + test_attr_many(new_format, fcpl, my_fapl); /* Test storing lots of attributes */ /* New attribute API routine tests, on old-format storage */ test_attr_info_by_idx(new_format, fcpl, my_fapl); /* Test querying attribute info by index */ -- cgit v0.12