From 70c0ba03cec20ad3c353fcf776f4b48f2ac8da9f Mon Sep 17 00:00:00 2001 From: Raymond Lu Date: Tue, 8 Feb 2005 13:30:29 -0500 Subject: [svn-r9959] Purpose: Bug fix Description: For variable-length string, H5Tget_class returned H5T_STRING as its class. But H5Tdetect_class and H5Tget_member_class considered it as H5T_VLEN. This is fixed to let all these 3 functions treat it as H5T_STRING. Some test cases have been added to dtypes.c Platforms tested: heping - already tested for v1.6 with h5committest Misc. update: RELEASE.txt --- release_docs/RELEASE.txt | 4 ++ src/H5Dio.c | 2 +- src/H5T.c | 22 +++++-- src/H5Tcompound.c | 5 +- src/H5Tnative.c | 2 +- src/H5Tprivate.h | 2 +- test/dtypes.c | 149 +++++++++++++++++++++++++++++++++++++++-------- 7 files changed, 152 insertions(+), 34 deletions(-) diff --git a/release_docs/RELEASE.txt b/release_docs/RELEASE.txt index c1faa5c..511cf3a 100644 --- a/release_docs/RELEASE.txt +++ b/release_docs/RELEASE.txt @@ -201,6 +201,10 @@ Bug Fixes since HDF5-1.6.0 release Library ------- + - For variable-length string, H5Tget_class returned H5T_STRING as its + class. But H5Tdetect_class and H5Tget_member_class considered it + as H5T_VLEN. This is fixed to let all these 3 functions treat it + as H5T_STRING. SLU - 2005/02/08 - The byte order of 1-byte integer types was fixed as little endian even on a big-endian machine. This has been corrected. SLU - 2005/02/07 diff --git a/src/H5Dio.c b/src/H5Dio.c index 7fda7b1..62afb22 100644 --- a/src/H5Dio.c +++ b/src/H5Dio.c @@ -919,7 +919,7 @@ H5D_write(H5D_t *dataset, hid_t mem_type_id, const H5S_t *mem_space, * to detect the type of the reference if it is nested... -QAK */ if (IS_H5FD_MPI(dataset->ent.file) && - H5T_get_class(mem_type)==H5T_REFERENCE && + H5T_get_class(mem_type, TRUE)==H5T_REFERENCE && H5T_get_ref_type(mem_type)==H5R_DATASET_REGION) HGOTO_ERROR (H5E_DATASET, H5E_UNSUPPORTED, FAIL, "Parallel IO does not support writing region reference datatypes yet") diff --git a/src/H5T.c b/src/H5T.c index 42c6714..69cf02b 100644 --- a/src/H5T.c +++ b/src/H5T.c @@ -1752,7 +1752,7 @@ H5Tget_class(hid_t type_id) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5T_NO_CLASS, "not a data type"); /* Set return value */ - ret_value= H5T_get_class(dt); + ret_value= H5T_get_class(dt, FALSE); done: FUNC_LEAVE_API(ret_value); @@ -1778,7 +1778,7 @@ done: *------------------------------------------------------------------------- */ H5T_class_t -H5T_get_class(const H5T_t *dt) +H5T_get_class(const H5T_t *dt, htri_t internal) { H5T_class_t ret_value; @@ -1792,6 +1792,16 @@ H5T_get_class(const H5T_t *dt) else ret_value=dt->shared->type; + /* Externally, a VL string is a string; internally, a VL string is a VL. */ + if(internal) { + ret_value=dt->shared->type; + } else { + if(H5T_IS_VL_STRING(dt->shared)) + ret_value=H5T_STRING; + else + ret_value=dt->shared->type; + } + done: FUNC_LEAVE_NOAPI(ret_value); } /* end H5T_get_class() */ @@ -1827,8 +1837,12 @@ H5Tdetect_class(hid_t type, H5T_class_t cls) if (!(cls>H5T_NO_CLASS && clsshared)) + ret_value = (H5T_STRING==cls); + else + ret_value=H5T_detect_class(dt,cls); done: FUNC_LEAVE_API(ret_value); diff --git a/src/H5Tcompound.c b/src/H5Tcompound.c index 46b1773..37c79ed 100644 --- a/src/H5Tcompound.c +++ b/src/H5Tcompound.c @@ -170,8 +170,9 @@ H5Tget_member_class(hid_t type_id, unsigned membno) if (membno >= dt->shared->u.compnd.nmembs) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, H5T_NO_CLASS, "invalid member number") - /* Value */ - ret_value = dt->shared->u.compnd.memb[membno].type->shared->type; + /* Get the type's class. We have to use this function to get type class + * because of the concern of variable-length string. */ + ret_value = H5T_get_class(dt->shared->u.compnd.memb[membno].type, FALSE); done: FUNC_LEAVE_API(ret_value) diff --git a/src/H5Tnative.c b/src/H5Tnative.c index 1ffa45b..686e1e3 100644 --- a/src/H5Tnative.c +++ b/src/H5Tnative.c @@ -167,7 +167,7 @@ H5T_get_native_type(H5T_t *dtype, H5T_direction_t direction, size_t *struct_alig assert(dtype); - if((h5_class = H5T_get_class(dtype))==H5T_NO_CLASS) + if((h5_class = H5T_get_class(dtype, FALSE))==H5T_NO_CLASS) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "not a valid class") if((size = H5T_get_size(dtype))==0) diff --git a/src/H5Tprivate.h b/src/H5Tprivate.h index e09be78..be4110c 100644 --- a/src/H5Tprivate.h +++ b/src/H5Tprivate.h @@ -71,7 +71,7 @@ H5_DLL H5T_t *H5T_open(H5G_entry_t *ent, hid_t dxpl_id); H5_DLL H5T_t *H5T_copy(const H5T_t *old_dt, H5T_copy_t method); H5_DLL herr_t H5T_lock(H5T_t *dt, hbool_t immutable); H5_DLL herr_t H5T_close(H5T_t *dt); -H5_DLL H5T_class_t H5T_get_class(const H5T_t *dt); +H5_DLL H5T_class_t H5T_get_class(const H5T_t *dt, htri_t internal); H5_DLL htri_t H5T_detect_class (const H5T_t *dt, H5T_class_t cls); H5_DLL size_t H5T_get_size(const H5T_t *dt); H5_DLL int H5T_cmp(const H5T_t *dt1, const H5T_t *dt2); diff --git a/test/dtypes.c b/test/dtypes.c index 01d0bc2..77254ea 100644 --- a/test/dtypes.c +++ b/test/dtypes.c @@ -370,22 +370,80 @@ reset_hdf5(void) static int test_classes(void) { - H5T_class_t tcls; - + struct complex { /* Struct with complex fields */ + hvl_t vl_c; + hvl_t vl_s; + }; + hid_t cmpd_id; /* Compound datatype */ + hid_t vlc_id; /* VL type of char */ + hid_t vls_id; /* VL string */ + hid_t memb_id; /* Compound member datatype */ + H5T_class_t memb_cls; + H5T_class_t tcls; + int nmembs, i; + TESTING("H5Tget_class()"); - if ((tcls=H5Tget_class(H5T_NATIVE_INT))<0) goto error; - if (H5T_INTEGER!=tcls) { - H5_FAILED(); - HDputs(" Invalid type class for H5T_NATIVE_INT"); - goto error; - } - if ((tcls=H5Tget_class(H5T_NATIVE_DOUBLE))<0) goto error; - if (H5T_FLOAT!=tcls) { - H5_FAILED(); - HDputs(" Invalid type class for H5T_NATIVE_DOUBLE"); - goto error; + /*------------------------------------------------------------- + * Check class of some atomic types. + *-----------------------------------------------------------*/ + if ((tcls=H5Tget_class(H5T_NATIVE_INT))<0) TEST_ERROR + if (H5T_INTEGER!=tcls) TEST_ERROR + + if ((tcls=H5Tget_class(H5T_NATIVE_DOUBLE))<0) TEST_ERROR + if (H5T_FLOAT!=tcls) TEST_ERROR + + /* Create a VL datatype of char. It should be a VL, not a string class. */ + if((vlc_id=H5Tvlen_create(H5T_NATIVE_CHAR))<0) TEST_ERROR + + /* Make certain that the correct classes can be detected */ + if ((tcls=H5Tget_class(vlc_id))<0) TEST_ERROR + if (H5T_VLEN!=tcls) TEST_ERROR + + /* Make certain that an incorrect class is not detected */ + if (H5T_STRING==tcls) TEST_ERROR + + /* Create a VL string. It should be a string, not a VL class. */ + if((vls_id=H5Tcopy(H5T_C_S1))<0) TEST_ERROR + if(H5Tset_size(vls_id, H5T_VARIABLE)<0) TEST_ERROR; + + /* Make certain that the correct classes can be detected */ + if ((tcls=H5Tget_class(vls_id))<0) TEST_ERROR + if (H5T_STRING!=tcls) TEST_ERROR + + /* Make certain that an incorrect class is not detected */ + if (H5T_VLEN==tcls) TEST_ERROR + + /*------------------------------------------------------------- + * Check class for member types of compound type. + *-----------------------------------------------------------*/ + /* Create a compound datatype and insert some complex types */ + if ((cmpd_id = H5Tcreate(H5T_COMPOUND, sizeof(struct complex)))<0) TEST_ERROR + if (H5Tinsert(cmpd_id, "vl_c", HOFFSET(struct complex, vl_c), vlc_id)<0) TEST_ERROR + if (H5Tinsert(cmpd_id, "vl_s", HOFFSET(struct complex, vl_s), vls_id)<0) TEST_ERROR + + nmembs = H5Tget_nmembers(cmpd_id); + + for (i=0;i