From 5560c64e256d3fc064072afbc0e3f14add0bc5a5 Mon Sep 17 00:00:00 2001 From: Quincey Koziol Date: Thu, 20 Dec 2001 15:51:30 -0500 Subject: [PATCH] [svn-r4747] Purpose: Bug Fix. Description: The H5Rget_object_type function could not get the object type for dataset region references. Solution: Added a new function, H5Rget_obj_type, to replace H5Rget_object_type. The new function requires the reference type as an additional parameter, in order to allow queries on different reference types to be performed correctly. Platforms tested: FreeBSD 4.4. (sleipnir) --- examples/h5_reference.c | 4 +- release_docs/RELEASE.txt | 5 ++ src/H5R.c | 162 ++++++++++++++++++++++++++++++++++++++- src/H5Rpublic.h | 5 +- test/trefer.c | 33 +++++++- tools/h5dump/h5dumptst.c | 10 --- tools/lib/h5tools_str.c | 2 +- 7 files changed, 201 insertions(+), 20 deletions(-) diff --git a/examples/h5_reference.c b/examples/h5_reference.c index ddf98acab7..0823df0e52 100644 --- a/examples/h5_reference.c +++ b/examples/h5_reference.c @@ -103,11 +103,11 @@ main(void) { /* * Find the type of referenced objects. */ - status = H5Rget_object_type(did_r, &rbuf[0]); + status = H5Rget_obj_type(did_r, H5R_OBJECT, &rbuf[0]); if ( status == H5G_GROUP ) printf("First dereferenced object is a group. \n"); - status = H5Rget_object_type(did_r, &rbuf[1]); + status = H5Rget_obj_type(did_r, H5R_OBJECT, &rbuf[1]); if ( status == H5G_DATASET ) printf("Second dereferenced object is a dataset. \n"); /* diff --git a/release_docs/RELEASE.txt b/release_docs/RELEASE.txt index 4fcad8765c..87690ebf46 100644 --- a/release_docs/RELEASE.txt +++ b/release_docs/RELEASE.txt @@ -204,6 +204,11 @@ New Features functions mentioned above. * Changed internal error handling macros to reduce code size of library by about 10-20%. + * Added H5Rget_obj_type() API function, which performs the same functionality + as H5Rget_object_type(), but requires the reference type as a parameter + in order to correctly handle dataset region references. Moved + H5Rget_object_type() to be only compiled into the library when v1.4 + compatibility is enabled. Platforms Tested ================ diff --git a/src/H5R.c b/src/H5R.c index 23d4184027..25c38dbe39 100644 --- a/src/H5R.c +++ b/src/H5R.c @@ -37,7 +37,7 @@ static herr_t H5R_create(void *ref, H5G_entry_t *loc, const char *name, H5R_type_t ref_type, H5S_t *space); static hid_t H5R_dereference(H5F_t *file, H5R_type_t ref_type, void *_ref); static H5S_t * H5R_get_region(H5F_t *file, H5R_type_t ref_type, void *_ref); -static int H5R_get_object_type(H5F_t *file, void *_ref); +static int H5R_get_obj_type(H5F_t *file, H5R_type_t ref_type, void *_ref); /*-------------------------------------------------------------------------- @@ -363,8 +363,8 @@ H5R_dereference(H5F_t *file, H5R_type_t ref_type, void *_ref) /* Get the object oid */ p=(uint8_t *)ref->oid; H5F_addr_decode(ent.file,(const uint8_t **)&p,&(ent.header)); - break; } /* end case */ + break; case H5R_DATASET_REGION: { @@ -388,8 +388,8 @@ H5R_dereference(H5F_t *file, H5R_type_t ref_type, void *_ref) /* Free the buffer allocated in H5HG_read() */ H5MM_xfree(buf); - break; } /* end case */ + break; case H5R_INTERNAL: HRETURN_ERROR(H5E_REFERENCE, H5E_UNSUPPORTED, FAIL, @@ -654,6 +654,7 @@ done: FUNC_LEAVE(ret_value); } /* end H5Rget_region() */ +#ifdef H5_WANT_H5_V1_4_COMPAT /*-------------------------------------------------------------------------- NAME @@ -758,4 +759,159 @@ H5Rget_object_type(hid_t id, void *_ref) done: FUNC_LEAVE(ret_value); } /* end H5Rget_object_type() */ +#endif /* H5_WANT_H5_V1_4_COMPAT */ + + +/*-------------------------------------------------------------------------- + NAME + H5R_get_obj_type + PURPOSE + Retrieves the type of object that an object reference points to + USAGE + int H5R_get_obj_type(file, ref_type, ref) + H5F_t *file; IN: File the object being dereferenced is within + H5R_type_t ref_type; IN: Type of reference to query + void *ref; IN: Reference to query. + + RETURNS + Success: An object type defined in H5Gpublic.h + Failure: H5G_UNKNOWN + DESCRIPTION + Given a reference to some object, this function returns the type of object + pointed to. + GLOBAL VARIABLES + COMMENTS, BUGS, ASSUMPTIONS + EXAMPLES + REVISION LOG +--------------------------------------------------------------------------*/ +static int +H5R_get_obj_type(H5F_t *file, H5R_type_t ref_type, void *_ref) +{ + H5G_entry_t ent; /* Symbol table entry */ + uint8_t *p; /* Pointer to OID to store */ + int ret_value = H5G_UNKNOWN; + + FUNC_ENTER(H5R_get_obj_type, H5G_UNKNOWN); + + assert(file); + assert(_ref); + + /* Initialize the symbol table entry */ + HDmemset(&ent,0,sizeof(H5G_entry_t)); + ent.type=H5G_NOTHING_CACHED; + ent.file=file; + + switch(ref_type) { + case H5R_OBJECT: + { + hobj_ref_t *ref=(hobj_ref_t *)_ref; /* Only object references currently supported */ + + /* Get the object oid */ + p=(uint8_t *)ref->oid; + H5F_addr_decode(ent.file,(const uint8_t **)&p,&(ent.header)); + } /* end case */ + break; + + case H5R_DATASET_REGION: + { + hdset_reg_ref_t *ref=(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 */ + + /* Get the heap ID for the dataset region */ + p=(uint8_t *)ref->heapid; + H5F_addr_decode(ent.file,(const uint8_t **)&p,&(hobjid.addr)); + INT32DECODE(p,hobjid.idx); + + /* Get the dataset region from the heap (allocate inside routine) */ + if((buf=H5HG_read(ent.file,&hobjid,NULL))==NULL) + HGOTO_ERROR(H5E_REFERENCE, H5E_READERROR, H5G_UNKNOWN, + "Unable to read dataset region information"); + + /* Get the object oid for the dataset */ + p=(uint8_t *)buf; + H5F_addr_decode(ent.file,(const uint8_t **)&p,&(ent.header)); + + /* Free the buffer allocated in H5HG_read() */ + H5MM_xfree(buf); + } /* end case */ + break; + + case H5R_INTERNAL: + HGOTO_ERROR(H5E_REFERENCE, H5E_UNSUPPORTED, H5G_UNKNOWN, + "Internal references are not yet supported"); + + case H5R_BADTYPE: + case H5R_MAXTYPE: + default: + assert("unknown reference type" && 0); + HGOTO_ERROR(H5E_REFERENCE, H5E_UNSUPPORTED, H5G_UNKNOWN, + "internal error (unknown reference type)"); + } /* end switch */ + + /* Check to make certain that this object hasn't been deleted since the reference was created */ + if(H5O_link(&ent,0)<=0) + HGOTO_ERROR(H5E_REFERENCE, H5E_LINKCOUNT, H5G_UNKNOWN, "dereferencing deleted object"); + + /* Get the OID type */ + ret_value=H5G_get_type(&ent); + +done: + FUNC_LEAVE(ret_value); +} /* end H5R_get_obj_type() */ + +/*-------------------------------------------------------------------------- + NAME + H5Rget_obj_type + PURPOSE + Retrieves the type of object that an object reference points to + USAGE + int H5Rget_obj_type(id, ref_type, ref) + hid_t 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 to query + void *ref; IN: Reference to query. + + RETURNS + Success: An object type defined in H5Gpublic.h + Failure: H5G_UNKNOWN + DESCRIPTION + Given a reference to some object, this function returns the type of object + pointed to. + GLOBAL VARIABLES + COMMENTS, BUGS, ASSUMPTIONS + EXAMPLES + REVISION LOG +--------------------------------------------------------------------------*/ +int +H5Rget_obj_type(hid_t id, H5R_type_t ref_type, void *_ref) +{ + H5G_entry_t *loc = NULL; /* Symbol table entry */ + H5F_t *file=NULL; /* File object */ + hid_t ret_value = H5G_UNKNOWN; + + FUNC_ENTER(H5Rget_obj_type, H5G_UNKNOWN); + H5TRACE2("Is","ix",id,_ref); + + /* Check args */ + if (NULL == (loc = H5G_loc(id))) + HRETURN_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a location"); + if(ref_type<=H5R_BADTYPE || ref_type>=H5R_MAXTYPE) + HRETURN_ERROR (H5E_ARGS, H5E_BADVALUE, FAIL, "invalid reference type"); + if(_ref==NULL) + HGOTO_ERROR (H5E_ARGS, H5E_BADVALUE, H5G_UNKNOWN, + "invalid reference pointer"); + + /* Get the file pointer from the entry */ + file=loc->file; + + /* Get the object information */ + if ((ret_value=H5R_get_obj_type(file,ref_type,_ref))<0) { + HGOTO_ERROR(H5E_REFERENCE, H5E_CANTINIT, H5G_UNKNOWN, + "unable to determine object type"); + } + +done: + FUNC_LEAVE(ret_value); +} /* end H5Rget_obj_type() */ diff --git a/src/H5Rpublic.h b/src/H5Rpublic.h index 443f6e441e..a33378ddd7 100644 --- a/src/H5Rpublic.h +++ b/src/H5Rpublic.h @@ -42,7 +42,7 @@ typedef struct { /* Note! Be careful with the sizes of the references because they should really * depend on the run-time values in the file. Unfortunately, the arrays need - * to be defined at run-time, so we have to go with the worst case sizes for + * to be defined at compile-time, so we have to go with the worst case sizes for * them. -QAK */ #define H5R_OBJ_REF_BUF_SIZE sizeof(haddr_t) @@ -70,7 +70,10 @@ __DLL__ herr_t H5Rcreate(void *ref, hid_t loc_id, const char *name, H5R_type_t ref_type, hid_t space_id); __DLL__ hid_t H5Rdereference(hid_t dataset, H5R_type_t ref_type, void *ref); __DLL__ hid_t H5Rget_region(hid_t dataset, H5R_type_t ref_type, void *ref); +#ifdef H5_WANT_H5_V1_4_COMPAT __DLL__ int H5Rget_object_type(hid_t dataset, void *_ref); +#endif /* H5_WANT_H5_V1_4_COMPAT */ +__DLL__ int H5Rget_obj_type(hid_t dataset, H5R_type_t ref_type, void *_ref); #ifdef __cplusplus } diff --git a/test/trefer.c b/test/trefer.c index 4d852d91ba..db5d558eed 100644 --- a/test/trefer.c +++ b/test/trefer.c @@ -155,26 +155,46 @@ test_reference_obj(void) /* Create reference to dataset */ ret = H5Rcreate(&wbuf[0],fid1,"/Group1/Dataset1",H5R_OBJECT,-1); CHECK(ret, FAIL, "H5Rcreate"); +#ifdef H5_WANT_H5_V1_4_COMPAT ret = H5Rget_object_type(dataset,&wbuf[0]); VERIFY(ret, H5G_DATASET, "H5Rget_object_type"); +#else /* H5_WANT_H5_V1_4_COMPAT */ + ret = H5Rget_obj_type(dataset,H5R_OBJECT,&wbuf[0]); + VERIFY(ret, H5G_DATASET, "H5Rget_obj_type"); +#endif /* H5_WANT_H5_V1_4_COMPAT */ /* Create reference to dataset */ ret = H5Rcreate(&wbuf[1],fid1,"/Group1/Dataset2",H5R_OBJECT,-1); CHECK(ret, FAIL, "H5Rcreate"); +#ifdef H5_WANT_H5_V1_4_COMPAT ret = H5Rget_object_type(dataset,&wbuf[1]); VERIFY(ret, H5G_DATASET, "H5Rget_object_type"); +#else /* H5_WANT_H5_V1_4_COMPAT */ + ret = H5Rget_obj_type(dataset,H5R_OBJECT,&wbuf[1]); + VERIFY(ret, H5G_DATASET, "H5Rget_obj_type"); +#endif /* H5_WANT_H5_V1_4_COMPAT */ /* Create reference to group */ ret = H5Rcreate(&wbuf[2],fid1,"/Group1",H5R_OBJECT,-1); CHECK(ret, FAIL, "H5Rcreate"); +#ifdef H5_WANT_H5_V1_4_COMPAT ret = H5Rget_object_type(dataset,&wbuf[2]); VERIFY(ret, H5G_GROUP, "H5Rget_object_type"); +#else /* H5_WANT_H5_V1_4_COMPAT */ + ret = H5Rget_obj_type(dataset,H5R_OBJECT,&wbuf[2]); + VERIFY(ret, H5G_GROUP, "H5Rget_obj_type"); +#endif /* H5_WANT_H5_V1_4_COMPAT */ /* Create reference to named datatype */ ret = H5Rcreate(&wbuf[3],fid1,"/Group1/Datatype1",H5R_OBJECT,-1); CHECK(ret, FAIL, "H5Rcreate"); +#ifdef H5_WANT_H5_V1_4_COMPAT ret = H5Rget_object_type(dataset,&wbuf[3]); VERIFY(ret, H5G_TYPE, "H5Rget_object_type"); +#else /* H5_WANT_H5_V1_4_COMPAT */ + ret = H5Rget_obj_type(dataset,H5R_OBJECT,&wbuf[3]); + VERIFY(ret, H5G_TYPE, "H5Rget_obj_type"); +#endif /* H5_WANT_H5_V1_4_COMPAT */ /* Write selection to disk */ ret=H5Dwrite(dataset,H5T_STD_REF_OBJ,H5S_ALL,H5S_ALL,H5P_DEFAULT,wbuf); @@ -365,6 +385,8 @@ test_reference_region(void) /* Store first dataset region */ ret = H5Rcreate(&wbuf[0],fid1,"/Dataset2",H5R_DATASET_REGION,sid2); CHECK(ret, FAIL, "H5Rcreate"); + ret = H5Rget_obj_type(dset1,H5R_DATASET_REGION,&wbuf[0]); + VERIFY(ret, H5G_DATASET, "H5Rget_obj_type"); /* Select sequence of ten points for second reference */ coord1[0][0]=6; coord1[0][1]=9; @@ -423,9 +445,9 @@ test_reference_region(void) dset2 = H5Rdereference(dset1,H5R_DATASET_REGION,&rbuf[0]); CHECK(dset2, FAIL, "H5Rdereference"); - /* Check what H5Rget_object_type function returns */ - ret = H5Rget_object_type(dset1, &rbuf[0]); - VERIFY(ret, H5G_UNKNOWN, "H5Rget_object_type"); + /* Check what H5Rget_obj_type function returns */ + ret = H5Rget_obj_type(dset1, H5R_DATASET_REGION,&rbuf[0]); + VERIFY(ret, H5G_DATASET, "H5Rget_obj_type"); /* Check information in referenced dataset */ sid1 = H5Dget_space(dset2); @@ -575,8 +597,13 @@ test_reference_obj_deleted(void) /* Create reference to dataset */ ret = H5Rcreate(&oref,fid1,"/Dataset1",H5R_OBJECT,-1); CHECK(ret, FAIL, "H5Rcreate"); +#ifdef H5_WANT_H5_V1_4_COMPAT ret = H5Rget_object_type(dataset,&oref); VERIFY(ret, H5G_DATASET, "H5Rget_object_type"); +#else /* H5_WANT_H5_V1_4_COMPAT */ + ret = H5Rget_obj_type(dataset,H5R_OBJECT,&oref); + VERIFY(ret, H5G_DATASET, "H5Rget_obj_type"); +#endif /* H5_WANT_H5_V1_4_COMPAT */ /* Write selection to disk */ ret=H5Dwrite(dataset,H5T_STD_REF_OBJ,H5S_ALL,H5S_ALL,H5P_DEFAULT,&oref); diff --git a/tools/h5dump/h5dumptst.c b/tools/h5dump/h5dumptst.c index 4399859724..3654ba0d9f 100644 --- a/tools/h5dump/h5dumptst.c +++ b/tools/h5dump/h5dumptst.c @@ -1509,29 +1509,19 @@ static void test_objref(void) /* Create reference to dataset */ H5Rcreate(&wbuf[0],fid1,"/Group1/Dataset1",H5R_OBJECT,-1); - H5Rget_object_type(dataset,&wbuf[0]); /* Create reference to dataset */ H5Rcreate(&wbuf[1],fid1,"/Group1/Dataset2",H5R_OBJECT,-1); - H5Rget_object_type(dataset,&wbuf[1]); - /* Create reference to group */ H5Rcreate(&wbuf[2],fid1,"/Group1",H5R_OBJECT,-1); - H5Rget_object_type(dataset,&wbuf[2]); - - /* Create reference to named datatype */ H5Rcreate(&wbuf[3],fid1,"/Group1/Datatype1",H5R_OBJECT,-1); - H5Rget_object_type(dataset,&wbuf[3]); - - /* Write selection to disk */ H5Dwrite(dataset,H5T_STD_REF_OBJ,H5S_ALL,H5S_ALL,H5P_DEFAULT,wbuf); - /* Close disk dataspace */ H5Sclose(sid1); diff --git a/tools/lib/h5tools_str.c b/tools/lib/h5tools_str.c index 2bc6305c8d..e75ac3dd2d 100644 --- a/tools/lib/h5tools_str.c +++ b/tools/lib/h5tools_str.c @@ -753,7 +753,7 @@ h5tools_str_sprint(h5tools_str_t *str, const h5dump_t *info, hid_t container, if (h5tools_is_zero(vp, H5Tget_size(type))) { h5tools_str_append(str, "NULL"); } else { - otype = H5Rget_object_type(container, vp); + otype = H5Rget_obj_type(container, H5R_OBJECT, vp); obj = H5Rdereference(container, H5R_OBJECT, vp); H5Gget_objinfo(obj, ".", FALSE, &sb);