diff options
-rw-r--r-- | src/H5Gname.c | 10 | ||||
-rw-r--r-- | src/H5Gprivate.h | 2 | ||||
-rw-r--r-- | src/H5R.c | 152 | ||||
-rw-r--r-- | src/H5Rpublic.h | 2 | ||||
-rw-r--r-- | test/ref.c | 96 |
5 files changed, 208 insertions, 54 deletions
diff --git a/src/H5Gname.c b/src/H5Gname.c index efa7865..9b8eacf 100644 --- a/src/H5Gname.c +++ b/src/H5Gname.c @@ -83,8 +83,6 @@ static herr_t H5G_name_move_path(H5RS_str_t **path_r_ptr, static int H5G_name_replace_cb(void *obj_ptr, hid_t obj_id, void *key); static herr_t H5G_refname_iterator(hid_t group, const char *name, void *_iter); static herr_t H5G_free_ref_path_node(void *item, void *key, void *operator_data/*in,out*/); -static ssize_t H5G_get_refobj_name(hid_t fid, hid_t dxpl_id, const H5O_loc_t *loc, - char* name, size_t size); /*------------------------------------------------------------------------- @@ -462,8 +460,10 @@ H5G_get_name(hid_t id, char *name/*out*/, size_t size, hid_t dxpl_id) HGOTO_ERROR(H5E_SYM, H5E_CANTGET, FAIL, "can't retrieve file ID") /* Search for name of object */ - if((len = H5G_get_refobj_name(file, dxpl_id, loc.oloc, name, size)) < 0) + if((len = H5G_get_refobj_name(file, dxpl_id, loc.oloc, name, size)) < 0) { + H5I_dec_ref(file); HGOTO_ERROR(H5E_SYM, H5E_CANTGET, FAIL, "can't determine name") + } /* end if */ /* Close file ID used for search */ if(H5I_dec_ref(file) < 0) @@ -1194,7 +1194,7 @@ H5G_free_ref_path_node(void *item, void UNUSED *key, void UNUSED *operator_data/ * *------------------------------------------------------------------------- */ -static ssize_t +ssize_t H5G_get_refobj_name(hid_t file, hid_t dxpl_id, const H5O_loc_t *loc, char *name, size_t size) { @@ -1202,7 +1202,7 @@ H5G_get_refobj_name(hid_t file, hid_t dxpl_id, const H5O_loc_t *loc, herr_t status; /* Status from iteration */ ssize_t ret_value; /* Return value */ - FUNC_ENTER_NOAPI_NOINIT(H5G_get_refobj_name) + FUNC_ENTER_NOAPI(H5G_get_refobj_name, FAIL) /* Set up user data for iterator */ udata.file = file; diff --git a/src/H5Gprivate.h b/src/H5Gprivate.h index 23cc895..6552177 100644 --- a/src/H5Gprivate.h +++ b/src/H5Gprivate.h @@ -183,6 +183,8 @@ 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 dxpl_id); +H5_DLL ssize_t H5G_get_refobj_name(hid_t fid, hid_t dxpl_id, + const struct H5O_loc_t *loc, char* name, size_t size); /* * These functions operate on group "locations" @@ -38,6 +38,8 @@ static herr_t H5R_create(void *ref, H5G_loc_t *loc, const char *name, static hid_t H5R_dereference(H5F_t *file, hid_t dxpl_id, H5R_type_t ref_type, const void *_ref); static H5S_t * H5R_get_region(H5F_t *file, hid_t dxpl_id, const void *_ref); static H5G_obj_t H5R_get_obj_type(H5F_t *file, hid_t dxpl_id, H5R_type_t ref_type, const void *_ref); +static ssize_t H5R_get_name(H5F_t *file, hid_t dxpl_id, hid_t id, + H5R_type_t ref_type, const void *_ref, char *name, size_t size); /*-------------------------------------------------------------------------- @@ -338,7 +340,6 @@ H5R_dereference(H5F_t *file, hid_t dxpl_id, H5R_type_t ref_type, const void *_re H5O_loc_t oloc; /* Object location */ H5G_name_t path; /* Path of object */ H5G_loc_t loc; /* Group location */ - const uint8_t *p; /* Pointer to OID to store */ int oid_type; /* type of object being dereferenced */ hid_t ret_value; @@ -362,6 +363,7 @@ H5R_dereference(H5F_t *file, hid_t dxpl_id, H5R_type_t ref_type, const void *_re const hdset_reg_ref_t *ref = (const hdset_reg_ref_t *)_ref; /* Get pointer to correct type of reference struct */ H5HG_t hobjid; /* Heap object ID */ uint8_t *buf; /* Buffer to store serialized selection in */ + const uint8_t *p; /* Pointer to OID to store */ /* Get the heap ID for the dataset region */ p = (const uint8_t *)ref; @@ -772,3 +774,151 @@ done: FUNC_LEAVE_API(ret_value) } /* end H5Rget_obj_type() */ + +/*-------------------------------------------------------------------------- + NAME + H5R_get_name + PURPOSE + Internal routine to determine a name for the object referenced + USAGE + ssize_t H5R_get_name(f, dxpl_id, ref_type, ref, name, size) + H5F_t *f; IN: Pointer to the file that the reference is pointing + into + hid_t dxpl_id; IN: DXPL to use for operation + hid_t id; IN: Location ID given for reference + H5R_type_t ref_type; IN: Type of reference + void *ref; IN: Reference to query. + char *name; OUT: Buffer to place name of object referenced + size_t size; IN: Size of name buffer + + RETURNS + Non-negative length of the path on success, Negative on failure + DESCRIPTION + Given a reference to some object, determine a path to the object + referenced in the file. + GLOBAL VARIABLES + COMMENTS, BUGS, ASSUMPTIONS + This may not be the only path to that object. + EXAMPLES + REVISION LOG +--------------------------------------------------------------------------*/ +ssize_t +H5R_get_name(H5F_t *f, hid_t dxpl_id, hid_t id, H5R_type_t ref_type, + const void *_ref, char *name, size_t size) +{ + hid_t file_id = (-1); /* ID for file that the reference is in */ + H5O_loc_t oloc; /* Object location describing object for reference */ + const uint8_t *p; /* Pointer to reference to decode */ + ssize_t ret_value; /* Return value */ + + FUNC_ENTER_NOAPI_NOINIT(H5R_get_name) + + /* Check args */ + HDassert(f); + HDassert(_ref); + HDassert(name); + + /* Initialize the object location */ + H5O_loc_reset(&oloc); + oloc.file = f; + + /* Get address for reference */ + p = (const uint8_t *)_ref; + switch(ref_type) { + case H5R_OBJECT: + H5F_addr_decode(oloc.file, &p, &oloc.addr); + break; + + case H5R_DATASET_REGION: + { + /* Skip over the heap ID for the dataset region */ + p += H5F_SIZEOF_ADDR(f); + p += 4; + + /* Get the object oid for the dataset */ + H5F_addr_decode(oloc.file, &p, &oloc.addr); + } /* end case */ + break; + + case H5R_INTERNAL: + HGOTO_ERROR(H5E_REFERENCE, H5E_UNSUPPORTED, FAIL, "Internal references are not yet supported") + + case H5R_BADTYPE: + case H5R_MAXTYPE: + default: + HDassert("unknown reference type" && 0); + HGOTO_ERROR(H5E_REFERENCE, H5E_UNSUPPORTED, FAIL, "internal error (unknown reference type)") + } /* end switch */ + + /* Retrieve file ID for name search */ + if((file_id = H5I_get_file_id(id)) < 0) + HGOTO_ERROR(H5E_REFERENCE, H5E_CANTGET, FAIL, "can't retrieve file ID") + + /* Get name, length, etc. */ + if((ret_value = H5G_get_refobj_name(file_id, dxpl_id, &oloc, name, size)) < 0) + HGOTO_ERROR(H5E_REFERENCE, H5E_CANTGET, FAIL, "can't determine name") + +done: + /* Close file ID used for search */ + if(file_id > 0) + if(H5I_dec_ref(file_id) < 0) + HDONE_ERROR(H5E_REFERENCE, H5E_CANTCLOSEFILE, FAIL, "can't determine name") + + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5R_get_name() */ + + +/*-------------------------------------------------------------------------- + NAME + H5Rget_name + PURPOSE + Determines a name for the object referenced + USAGE + ssize_t H5Rget_name(loc_id, ref_type, ref, name, size) + hid_t loc_id; IN: Dataset reference object is in or location ID of + object that the dataset is located within. + H5R_type_t ref_type; IN: Type of reference + void *ref; IN: Reference to query. + char *name; OUT: Buffer to place name of object referenced + size_t size; IN: Size of name buffer + + RETURNS + Non-negative length of the path on success, Negative on failure + DESCRIPTION + Given a reference to some object, determine a path to the object + referenced in the file. + GLOBAL VARIABLES + COMMENTS, BUGS, ASSUMPTIONS + This may not be the only path to that object. + EXAMPLES + REVISION LOG +--------------------------------------------------------------------------*/ +ssize_t +H5Rget_name(hid_t id, H5R_type_t ref_type, const void *_ref, char *name, + size_t size) +{ + H5G_loc_t loc; /* Group location */ + H5F_t *file; /* File object */ + ssize_t ret_value; /* Return value */ + + FUNC_ENTER_API(H5Rget_name, FAIL) + + /* Check args */ + if(H5G_loc(id, &loc) < 0) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a location") + if(ref_type <= H5R_BADTYPE || ref_type >= H5R_MAXTYPE) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid reference type") + if(_ref == NULL) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid reference pointer") + + /* Get the file pointer from the entry */ + file = loc.oloc->file; + + /* Get name */ + if((ret_value = H5R_get_name(file, H5AC_dxpl_id, id, ref_type, _ref, name, size)) < 0) + HGOTO_ERROR(H5E_REFERENCE, H5E_CANTINIT, FAIL, "unable to determine object path") + +done: + FUNC_LEAVE_API(ret_value) +} /* end H5Rget_name() */ + diff --git a/src/H5Rpublic.h b/src/H5Rpublic.h index fdc1d27..de82a23 100644 --- a/src/H5Rpublic.h +++ b/src/H5Rpublic.h @@ -72,6 +72,8 @@ H5_DLL herr_t H5Rcreate(void *ref, hid_t loc_id, const char *name, H5_DLL hid_t H5Rdereference(hid_t dataset, H5R_type_t ref_type, const void *ref); H5_DLL hid_t H5Rget_region(hid_t dataset, H5R_type_t ref_type, const void *ref); H5_DLL H5G_obj_t H5Rget_obj_type(hid_t id, H5R_type_t ref_type, const void *_ref); +H5_DLL ssize_t H5Rget_name(hid_t loc_id, H5R_type_t ref_type, const void *ref, + char *name/*out*/, size_t size); #ifdef __cplusplus } @@ -193,91 +193,91 @@ main(void) TEST_ERROR TESTING("getting path to normal dataset in root group"); - i = H5Iget_name(H5Rdereference(dataset, H5R_OBJECT , &wbuf[0]), (char*)buf, (size_t)100); - if((HDstrcmp(buf, "/Dataset3") == 0) && (i == 10)) - PASSED() - else - TEST_ERROR + i = H5Iget_name(H5Rdereference(dataset, H5R_OBJECT, &wbuf[0]), (char*)buf, (size_t)100); + if(!((HDstrcmp(buf, "/Dataset3") == 0) && (i == 10))) TEST_ERROR + i = H5Rget_name(dataset, H5R_OBJECT, &wbuf[0], (char*)buf, (size_t)100); + if(!((HDstrcmp(buf, "/Dataset3") == 0) && (i == 10))) TEST_ERROR + PASSED() HDmemset(buf, 0, (size_t)100); TESTING("getting path to dataset in /Group1"); - i = H5Iget_name(H5Rdereference(dataset, H5R_OBJECT , &wbuf[1]), (char*)buf, (size_t)100); - if((HDstrcmp(buf, "/Group1/Dataset2") == 0) && (i == 17)) - PASSED() - else - TEST_ERROR + i = H5Iget_name(H5Rdereference(dataset, H5R_OBJECT, &wbuf[1]), (char*)buf, (size_t)100); + if(!((HDstrcmp(buf, "/Group1/Dataset2") == 0) && (i == 17))) TEST_ERROR + i = H5Rget_name(dataset, H5R_OBJECT, &wbuf[1], (char*)buf, (size_t)100); + if(!((HDstrcmp(buf, "/Group1/Dataset2") == 0) && (i == 17))) TEST_ERROR + PASSED() HDmemset(buf, 0, (size_t)100); TESTING("getting path to /Group1"); - i = H5Iget_name(H5Rdereference(dataset, H5R_OBJECT , &wbuf[2]), (char*)buf, 100); - if((HDstrcmp(buf, "/Group1") == 0) && (i == 8)) - PASSED() - else - TEST_ERROR + i = H5Iget_name(H5Rdereference(dataset, H5R_OBJECT, &wbuf[2]), (char*)buf, 100); + if(!((HDstrcmp(buf, "/Group1") == 0) && (i == 8))) TEST_ERROR + i = H5Rget_name(dataset, H5R_OBJECT, &wbuf[2], (char*)buf, 100); + if(!((HDstrcmp(buf, "/Group1") == 0) && (i == 8))) TEST_ERROR + PASSED() HDmemset(buf, 0, 100); TESTING("getting path to datatype in /Group1"); i = H5Iget_name(H5Rdereference(dataset, H5R_OBJECT , &wbuf[3]), (char*)buf, 100); - if((HDstrcmp(buf, "/Group1/Datatype1") == 0) && (i == 18)) - PASSED() - else - TEST_ERROR + if(!((HDstrcmp(buf, "/Group1/Datatype1") == 0) && (i == 18))) TEST_ERROR + i = H5Rget_name(dataset, H5R_OBJECT, &wbuf[3], (char*)buf, 100); + if(!((HDstrcmp(buf, "/Group1/Datatype1") == 0) && (i == 18))) TEST_ERROR + PASSED() HDmemset(buf, 0, 100); TESTING("getting path to dataset in nested group"); i = H5Iget_name(H5Rdereference(dataset, H5R_OBJECT , &wbuf[4]), (char*)buf, 100); - if((HDstrcmp(buf, "/Group1/Group2/Dataset4") == 0) && (i == 24)) - PASSED() - else - TEST_ERROR + if(!((HDstrcmp(buf, "/Group1/Group2/Dataset4") == 0) && (i == 24))) TEST_ERROR + i = H5Rget_name(dataset, H5R_OBJECT, &wbuf[4], (char*)buf, 100); + if(!((HDstrcmp(buf, "/Group1/Group2/Dataset4") == 0) && (i == 24))) TEST_ERROR + PASSED() HDmemset(buf, 0, 100); TESTING("getting path to nested group"); - i = H5Iget_name(H5Rdereference(dataset, H5R_OBJECT , &wbuf[5]), (char*)buf, 100); - if((HDstrcmp(buf, "/Group1/Group2") == 0) && (i == 15)) - PASSED() - else - TEST_ERROR + i = H5Iget_name(H5Rdereference(dataset, H5R_OBJECT, &wbuf[5]), (char*)buf, 100); + if(!((HDstrcmp(buf, "/Group1/Group2") == 0) && (i == 15))) TEST_ERROR + i = H5Rget_name(dataset, H5R_OBJECT, &wbuf[5], (char*)buf, 100); + if(!((HDstrcmp(buf, "/Group1/Group2") == 0) && (i == 15))) TEST_ERROR + PASSED() HDmemset(buf, 0, 100); TESTING("getting path to dataset created via hard link"); - i = H5Iget_name(H5Rdereference(dataset, H5R_OBJECT , &wbuf[6]), (char*)buf, 100); - if((HDstrcmp(buf, "/Group1/Dataset5") == 0) && (i == 17)) - PASSED() - else - TEST_ERROR + i = H5Iget_name(H5Rdereference(dataset, H5R_OBJECT, &wbuf[6]), (char*)buf, 100); + if(!((HDstrcmp(buf, "/Group1/Dataset5") == 0) && (i == 17))) TEST_ERROR + i = H5Rget_name(dataset, H5R_OBJECT, &wbuf[6], (char*)buf, 100); + if(!((HDstrcmp(buf, "/Group1/Dataset5") == 0) && (i == 17))) TEST_ERROR + PASSED() HDmemset(buf, 0, 100); TESTING("getting path to root group"); - i = H5Iget_name(H5Rdereference(dataset, H5R_OBJECT , &wbuf[7]), (char*)buf, 100); - if((HDstrcmp(buf, "/") == 0) && (i == 2)) - PASSED() - else - TEST_ERROR + i = H5Iget_name(H5Rdereference(dataset, H5R_OBJECT, &wbuf[7]), (char*)buf, 100); + if(!((HDstrcmp(buf, "/") == 0) && (i == 2))) TEST_ERROR + i = H5Rget_name(dataset, H5R_OBJECT, &wbuf[7], (char*)buf, 100); + if(!((HDstrcmp(buf, "/") == 0) && (i == 2))) TEST_ERROR + PASSED() /* Now we mount fid2 at /Group2 and look for dataset4. It shouldn't be found */ if(H5Fmount(fid1, "/Group1/Group2", fid2, H5P_DEFAULT) < 0) TEST_ERROR TESTING("getting path to dataset hidden by a mounted file"); - i = H5Iget_name(H5Rdereference(dataset, H5R_OBJECT , &wbuf[4]), (char*)buf, 100); - if(i == 0) - PASSED() - else - TEST_ERROR + i = H5Iget_name(H5Rdereference(dataset, H5R_OBJECT, &wbuf[4]), (char*)buf, 100); + if(i != 0) TEST_ERROR + i = H5Rget_name(dataset, H5R_OBJECT, &wbuf[4], (char*)buf, 100); + if(i != 0) TEST_ERROR + PASSED() /* Now we try unlinking dataset2 from the file and searching for it. It shouldn't be found */ - if((ref = H5Rdereference(dataset, H5R_OBJECT , &wbuf[1])) < 0) + if((ref = H5Rdereference(dataset, H5R_OBJECT, &wbuf[1])) < 0) TEST_ERROR if(H5Gunlink(fid1, "/Group1/Dataset2") < 0) TEST_ERROR TESTING("getting path to dataset that has been unlinked"); i = H5Iget_name(ref, (char*)buf, 100); - if(i == 0) - PASSED() - else - TEST_ERROR + if(i != 0) TEST_ERROR + i = H5Rget_name(dataset, H5R_OBJECT, &wbuf[1], (char*)buf, 100); + if(i != 0) TEST_ERROR + PASSED() /* Close disk dataspace */ if(H5Sclose(sid1) < 0) |