From 75f65c15836248688110342528629039e40c1cd0 Mon Sep 17 00:00:00 2001 From: Raymond Lu Date: Wed, 20 Jan 2010 15:41:23 -0500 Subject: [svn-r18125] I added the support of bitfield in H5Tget_native_type. Bitfield is similar to unsigned integer. I also added a test. Tested on jam. But I tested the same change for 1.8 with h5committest. --- src/H5Tnative.c | 190 +++++++++++++++++++++++++++++++++++--------------------- test/dtypes.c | 13 +--- test/ntypes.c | 120 +++++++++++++++++++++++++---------- 3 files changed, 209 insertions(+), 114 deletions(-) diff --git a/src/H5Tnative.c b/src/H5Tnative.c index 75b5d03..8d8920b 100644 --- a/src/H5Tnative.c +++ b/src/H5Tnative.c @@ -38,6 +38,8 @@ static H5T_t *H5T_get_native_integer(size_t prec, H5T_sign_t sign, H5T_direction size_t *struct_align, size_t *offset, size_t *comp_size); static H5T_t *H5T_get_native_float(size_t size, H5T_direction_t direction, size_t *struct_align, size_t *offset, size_t *comp_size); +static H5T_t* H5T_get_native_bitfield(size_t prec, H5T_direction_t direction, + size_t *struct_align, size_t *offset, size_t *comp_size); static herr_t H5T_cmp_offset(size_t *comp_size, size_t *offset, size_t elem_size, size_t nelems, size_t align, size_t *struct_align); @@ -108,7 +110,7 @@ H5Tget_native_type(hid_t type_id, H5T_direction_t direction) H5TRACE2("i", "iTd", type_id, direction); /* check argument */ - if(NULL==(dt=H5I_object_verify(type_id, H5I_DATATYPE))) + if(NULL==(dt=(H5T_t *)H5I_object_verify(type_id, H5I_DATATYPE))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data type") if(direction!=H5T_DIR_DEFAULT && direction!=H5T_DIR_ASCEND @@ -210,13 +212,19 @@ H5T_get_native_type(H5T_t *dtype, H5T_direction_t direction, size_t *struct_alig } break; - /* These 2 types will be supported in the future. Simply return "not supported" + /* The time type will be supported in the future. Simply return "not supported" * message for now.*/ case H5T_TIME: HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "time type is not supported yet") case H5T_BITFIELD: - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "bit field type is not supported yet") + { + prec = dtype->shared->u.atomic.prec; + + if((ret_value = H5T_get_native_bitfield(prec, direction, struct_align, offset, comp_size))==NULL) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "cannot retrieve integer for bitfield type") + } + break; case H5T_OPAQUE: if((ret_value=H5T_copy(dtype, H5T_COPY_TRANSIENT))==NULL) @@ -237,7 +245,7 @@ H5T_get_native_type(H5T_t *dtype, H5T_direction_t direction, size_t *struct_alig HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "cannot retrieve float type") /* Decide if the data type is object or dataset region reference. */ - if(NULL==(dt=H5I_object(H5T_STD_REF_OBJ_g))) + if(NULL==(dt=(H5T_t *)H5I_object(H5T_STD_REF_OBJ_g))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "not a data type") not_equal = H5T_cmp(ret_value, dt, FALSE); @@ -556,46 +564,19 @@ H5T_get_native_integer(size_t prec, H5T_sign_t sign, H5T_direction_t direction, native_size = sizeof(long long); } } else if(direction == H5T_DIR_DESCEND) { - if(prec>=H5Tget_precision(H5T_NATIVE_LLONG)) { + if(prec>H5Tget_precision(H5T_NATIVE_LONG)) { match=H5T_NATIVE_INT_MATCH_LLONG; native_size = sizeof(long long); - } else if(prec>=H5Tget_precision(H5T_NATIVE_LONG)) { - if(prec==H5Tget_precision(H5T_NATIVE_LONG)) { - match=H5T_NATIVE_INT_MATCH_LONG; - native_size = sizeof(long); - } else { - match=H5T_NATIVE_INT_MATCH_LLONG; - native_size = sizeof(long long); - } - } - else if(prec>=H5Tget_precision(H5T_NATIVE_INT)) { - if(prec==H5Tget_precision(H5T_NATIVE_INT)) { - match=H5T_NATIVE_INT_MATCH_INT; - native_size = sizeof(int); - } else { - match=H5T_NATIVE_INT_MATCH_LONG; - native_size = sizeof(long); - } - } - else if(prec>=H5Tget_precision(H5T_NATIVE_SHORT)) { - if(prec==H5Tget_precision(H5T_NATIVE_SHORT)) { - match=H5T_NATIVE_INT_MATCH_SHORT; - native_size = sizeof(short); - } else { - match=H5T_NATIVE_INT_MATCH_INT; - native_size = sizeof(int); - } - } - else if(prec>=H5Tget_precision(H5T_NATIVE_SCHAR)) { - if(prec==H5Tget_precision(H5T_NATIVE_SCHAR)) { - match=H5T_NATIVE_INT_MATCH_CHAR; - native_size = sizeof(char); - } else { - match=H5T_NATIVE_INT_MATCH_SHORT; - native_size = sizeof(short); - } - } - else { /* If no native type matches the queried datatype, simply choose the type of smallest size. */ + } else if(prec>H5Tget_precision(H5T_NATIVE_INT)) { + match=H5T_NATIVE_INT_MATCH_LONG; + native_size = sizeof(long); + } else if(prec>H5Tget_precision(H5T_NATIVE_SHORT)) { + match=H5T_NATIVE_INT_MATCH_INT; + native_size = sizeof(int); + } else if(prec>H5Tget_precision(H5T_NATIVE_SCHAR)) { + match=H5T_NATIVE_INT_MATCH_SHORT; + native_size = sizeof(short); + } else { match=H5T_NATIVE_INT_MATCH_CHAR; native_size = sizeof(char); } @@ -654,7 +635,7 @@ H5T_get_native_integer(size_t prec, H5T_sign_t sign, H5T_direction_t direction, /* Create new native type */ assert(tid>=0); - if(NULL==(dt=H5I_object(tid))) + if(NULL==(dt=(H5T_t *)H5I_object(tid))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "not a data type") if((ret_value=H5T_copy(dt, H5T_COPY_TRANSIENT))==NULL) @@ -733,46 +714,23 @@ H5T_get_native_float(size_t size, H5T_direction_t direction, size_t *struct_alig } } else { #if H5_SIZEOF_LONG_DOUBLE !=0 - if(size>=sizeof(long double)) { + if(size>sizeof(double)) { match=H5T_NATIVE_FLOAT_MATCH_LDOUBLE; native_size = sizeof(long double); } - else if(size>=sizeof(double)) { - if(size==sizeof(double)) { - match=H5T_NATIVE_FLOAT_MATCH_DOUBLE; - native_size = sizeof(double); - } else { - match=H5T_NATIVE_FLOAT_MATCH_LDOUBLE; - native_size = sizeof(long double); - } - } - else if(size>=sizeof(float)) { - if(size==sizeof(float)) { - match=H5T_NATIVE_FLOAT_MATCH_FLOAT; - native_size = sizeof(float); - } else { - match=H5T_NATIVE_FLOAT_MATCH_DOUBLE; - native_size = sizeof(double); - } + else if(size>sizeof(float)) { + match=H5T_NATIVE_FLOAT_MATCH_DOUBLE; + native_size = sizeof(double); } else { match=H5T_NATIVE_FLOAT_MATCH_FLOAT; native_size = sizeof(float); } #else - if(size>=sizeof(double)) { + if(size>sizeof(float)) { match=H5T_NATIVE_FLOAT_MATCH_DOUBLE; native_size = sizeof(double); } - else if(size>=sizeof(float)) { - if(size==sizeof(float)) { - match=H5T_NATIVE_FLOAT_MATCH_FLOAT; - native_size = sizeof(float); - } else { - match=H5T_NATIVE_FLOAT_MATCH_DOUBLE; - native_size = sizeof(double); - } - } else { match=H5T_NATIVE_FLOAT_MATCH_FLOAT; native_size = sizeof(float); @@ -805,7 +763,7 @@ H5T_get_native_float(size_t size, H5T_direction_t direction, size_t *struct_alig /* Create new native type */ assert(tid>=0); - if(NULL==(dt=H5I_object(tid))) + if(NULL==(dt=(H5T_t *)H5I_object(tid))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "not a data type") if((ret_value=H5T_copy(dt, H5T_COPY_TRANSIENT))==NULL) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "cannot retrieve float type") @@ -820,6 +778,94 @@ done: /*------------------------------------------------------------------------- + * Function: H5T_get_native_bitfield + * + * Purpose: Returns the native bitfield type of a datatype. Bitfield + * is similar to unsigned integer. + * + * Return: Success: Returns the native data type if successful. + * + * Failure: negative + * + * Programmer: Raymond Lu + * 1 December 2009 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +static H5T_t* +H5T_get_native_bitfield(size_t prec, H5T_direction_t direction, size_t *struct_align, + size_t *offset, size_t *comp_size) +{ + H5T_t *dt; /* Appropriate native datatype to copy */ + hid_t tid=(-1); /* Datatype ID of appropriate native datatype */ + size_t align=0; /* Alignment necessary for native datatype */ + size_t native_size=0; /* Datatype size of the native type */ + H5T_t *ret_value; /* Return value */ + + FUNC_ENTER_NOAPI(H5T_get_native_bitfield, NULL); + + if(direction == H5T_DIR_DEFAULT || direction == H5T_DIR_ASCEND) { + if(prec<=H5Tget_precision(H5T_NATIVE_B8)) { + tid = H5T_NATIVE_B8; + native_size = 1; + align = H5T_NATIVE_UINT8_ALIGN_g; + } else if(prec<=H5Tget_precision(H5T_NATIVE_B16)) { + tid = H5T_NATIVE_B16; + native_size = 2; + align = H5T_NATIVE_UINT16_ALIGN_g; + } else if(prec<=H5Tget_precision(H5T_NATIVE_B32)) { + tid = H5T_NATIVE_B32; + native_size = 4; + align = H5T_NATIVE_UINT32_ALIGN_g; + } else if(prec<=H5Tget_precision(H5T_NATIVE_B64)) { + tid = H5T_NATIVE_B64; + native_size = 8; + align = H5T_NATIVE_UINT64_ALIGN_g; + } else { /* If no native type matches the querried datatype, simply choose the type of biggest size. */ + tid = H5T_NATIVE_B64; + native_size = 8; + align = H5T_NATIVE_UINT64_ALIGN_g; + } + } else if(direction == H5T_DIR_DESCEND) { + if(prec>H5Tget_precision(H5T_NATIVE_B32)) { + tid = H5T_NATIVE_B64; + native_size = 8; + align = H5T_NATIVE_UINT64_ALIGN_g; + } else if(prec>H5Tget_precision(H5T_NATIVE_B16)) { + tid = H5T_NATIVE_B32; + native_size = 4; + align = H5T_NATIVE_UINT32_ALIGN_g; + } else if(prec>H5Tget_precision(H5T_NATIVE_B8)) { + tid = H5T_NATIVE_B16; + native_size = 2; + align = H5T_NATIVE_UINT16_ALIGN_g; + } else { + tid = H5T_NATIVE_B8; + native_size = 1; + align = H5T_NATIVE_UINT8_ALIGN_g; + } + } + + /* Create new native type */ + assert(tid>=0); + if(NULL==(dt=(H5T_t *)H5I_object(tid))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "not a data type") + + if((ret_value=H5T_copy(dt, H5T_COPY_TRANSIENT))==NULL) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "cannot copy type") + + /* compute size and offset of compound type member. */ + if(H5T_cmp_offset(comp_size, offset, native_size, (size_t)1, align, struct_align)<0) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "cannot compute compound offset") + +done: + FUNC_LEAVE_NOAPI(ret_value) +} + + +/*------------------------------------------------------------------------- * Function: H5T_cmp_offset * * Purpose: This function is only for convenience. It computes the diff --git a/test/dtypes.c b/test/dtypes.c index 04f526a..020a603 100644 --- a/test/dtypes.c +++ b/test/dtypes.c @@ -4496,7 +4496,7 @@ test_conv_bitfield(void) static int test_bitfield_funcs(void) { - hid_t type=-1, super=-1; + hid_t type=-1, ntype=-1, super=-1; int size; char* tag; H5T_pad_t inpad; @@ -4521,6 +4521,7 @@ test_bitfield_funcs(void) if(H5Tset_pad(type, H5T_PAD_ONE, H5T_PAD_ONE)) goto error; if((size=H5Tget_size(type))==0) goto error; if(H5Tset_order(type, H5T_ORDER_BE) < 0) goto error; + if((ntype = H5Tget_native_type(type, H5T_DIR_ASCEND)) < 0) goto error; H5E_BEGIN_TRY { size=H5Tget_ebias(type); @@ -4585,16 +4586,8 @@ test_bitfield_funcs(void) goto error; } /* end if */ - H5E_BEGIN_TRY { - super = H5Tget_native_type(type, H5T_DIR_ASCEND); - } H5E_END_TRY; - if (super>=0) { - H5_FAILED(); - printf("Operation not allowed for this type.\n"); - goto error; - } /* end if */ - H5Tclose(type); + H5Tclose(ntype); PASSED(); reset_hdf5(); return 0; diff --git a/test/ntypes.c b/test/ntypes.c index 87484d9..6efabc6 100644 --- a/test/ntypes.c +++ b/test/ntypes.c @@ -52,14 +52,15 @@ int ipoints3[DIM0][DIM1][5], icheck3[DIM0][DIM1][5]; #define DSET_VLSTR_NAME "vlstr_type" #define DSET_STR_NAME "str_type" #define DSET_OPAQUE_NAME "opaque_type" -#define DSET_BITFIELD_NAME "bitfield_type" +#define DSET1_BITFIELD_NAME "bitfield_type_1" +#define DSET2_BITFIELD_NAME "bitfield_type_2" #define SPACE1_DIM1 4 #define SPACE1_RANK 1 #define SPACE2_RANK 2 #define SPACE2_DIM1 10 #define SPACE2_DIM2 10 - +#define BITFIELD_ENUMB 8 /*------------------------------------------------------------------------- @@ -2519,53 +2520,106 @@ error: * October 15, 2002 * * Modifications: - * + * Raymond Lu + * 1 December 2009 + * I added the support for bitfield and changed the test to + * compare the data being read back. *------------------------------------------------------------------------- */ static herr_t test_bitfield_dtype(hid_t file) { - hid_t type = -1, space = -1, dset = -1; - hid_t dataset = -1, dtype = -1, native_type = -1; - size_t i; - unsigned char wbuf[32]; - hsize_t nelmts; + hid_t type=-1, space=-1, dset1=-1, dset2=-1; + hid_t dataset1=-1, dataset2=-1, dtype=-1, native_type=-1; + size_t ntype_size, i; + unsigned char wbuf[BITFIELD_ENUMB*sizeof(int)]; + unsigned char *p=NULL; + void *rbuf = NULL; + unsigned int intw[BITFIELD_ENUMB], intr[BITFIELD_ENUMB]; + hsize_t nelmts; TESTING("bitfield datatype"); - /* opaque_1 */ - nelmts = sizeof(wbuf); - if((type = H5Tcopy(H5T_STD_B8LE)) < 0) TEST_ERROR; + nelmts = BITFIELD_ENUMB; + if((type = H5Tcopy(H5T_STD_B32BE)) < 0) TEST_ERROR; + if((space = H5Screate_simple(1, &nelmts, NULL)) < 0) TEST_ERROR; - if((dset = H5Dcreate2(file, DSET_BITFIELD_NAME, type, space, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) - TEST_ERROR; - for(i = 0; i < sizeof(wbuf); i++) - wbuf[i] = (unsigned char)0xff ^ (unsigned char)i; + /* Create and write to dataset1 with a unsigned char buffer */ + if((dset1 = H5Dcreate2(file, DSET1_BITFIELD_NAME, type, space, H5P_DEFAULT, H5P_DEFAULT, + H5P_DEFAULT)) < 0) TEST_ERROR; - if(H5Dwrite(dset, type, H5S_ALL, H5S_ALL, H5P_DEFAULT, wbuf) < 0) TEST_ERROR; + for(i = 0; i < BITFIELD_ENUMB*sizeof(int); i++) + wbuf[i] = (unsigned int)0xff ^ (unsigned int)i; + + if(H5Dwrite(dset1, H5T_NATIVE_B32, H5S_ALL, H5S_ALL, H5P_DEFAULT, wbuf) < 0) TEST_ERROR; + if(H5Dclose(dset1) < 0) TEST_ERROR; + + /* Create and write to dataset2 with a unsigned int buffer */ + if((dset2 = H5Dcreate2(file, DSET2_BITFIELD_NAME, type, space, H5P_DEFAULT, H5P_DEFAULT, + H5P_DEFAULT)) < 0) TEST_ERROR; + + for(i = 0; i < BITFIELD_ENUMB; i++) + intw[i] = (unsigned int)0xff << (unsigned int)((i*8)%32); + + if(H5Dwrite(dset2, H5T_NATIVE_B32, H5S_ALL, H5S_ALL, H5P_DEFAULT, intw) < 0) TEST_ERROR; + if(H5Dclose(dset2) < 0) TEST_ERROR; if(H5Sclose(space) < 0) TEST_ERROR; - if(H5Dclose(dset) < 0) TEST_ERROR; + if(H5Tclose(type) < 0) TEST_ERROR; + /* Open dataset1 again to check H5Tget_native_type */ + if((dataset1 = H5Dopen2(file, DSET1_BITFIELD_NAME, H5P_DEFAULT)) < 0) TEST_ERROR; - /* Open dataset again to check H5Tget_native_type */ - if((dataset = H5Dopen2(file, DSET_BITFIELD_NAME, H5P_DEFAULT)) < 0) TEST_ERROR; + if((dtype = H5Dget_type(dataset1)) < 0) TEST_ERROR; - if((dtype = H5Dget_type(dataset)) < 0) TEST_ERROR; + if((native_type = H5Tget_native_type(dtype, H5T_DIR_DEFAULT)) < 0) TEST_ERROR; - H5E_BEGIN_TRY { - native_type = H5Tget_native_type(dtype, H5T_DIR_DEFAULT); - } H5E_END_TRY; - if(native_type > 0) { - H5_FAILED(); - puts(" Bit field isn't supported. Should have failed."); - TEST_ERROR; - } /* end if */ + if((ntype_size = H5Tget_size(native_type)) == 0) TEST_ERROR; + + rbuf = malloc((size_t)nelmts*ntype_size); + + /* Read the data and compare them */ + if(H5Dread(dataset1, native_type, H5S_ALL, H5S_ALL, H5P_DEFAULT, rbuf) < 0) TEST_ERROR; + + p = (unsigned int*)rbuf; + for(i = 0; i < BITFIELD_ENUMB*4; i++) { + if(*p != wbuf[i]) { + H5_FAILED(); + printf(" Read different values than written.\n"); + printf(" At index %d\n", i); + TEST_ERROR; + } + p++; + } - if(H5Tclose(type) < 0) TEST_ERROR; if(H5Tclose(dtype) < 0) TEST_ERROR; - if(H5Dclose(dataset) < 0) TEST_ERROR; + if(H5Tclose(native_type) < 0) TEST_ERROR; + if(H5Dclose(dataset1) < 0) TEST_ERROR; + if(rbuf) free(rbuf); + + /* Open dataset2 again to check H5Tget_native_type */ + if((dataset2 = H5Dopen2(file, DSET2_BITFIELD_NAME, H5P_DEFAULT)) < 0) TEST_ERROR; + + if((dtype = H5Dget_type(dataset2)) < 0) TEST_ERROR; + + if((native_type = H5Tget_native_type(dtype, H5T_DIR_DEFAULT)) < 0) TEST_ERROR; + /* Read the data and compare them */ + if(H5Dread(dataset2, native_type, H5S_ALL, H5S_ALL, H5P_DEFAULT, intr) < 0) TEST_ERROR; + + for(i = 0; i < BITFIELD_ENUMB; i++) { + if(intr[i] != intw[i]) { + H5_FAILED(); + printf(" Read different values than written.\n"); + printf(" At index %d\n", i); + TEST_ERROR; + } + } + + if(H5Tclose(dtype) < 0) TEST_ERROR; + if(H5Tclose(native_type) < 0) TEST_ERROR; + if(H5Dclose(dataset2) < 0) TEST_ERROR; + PASSED(); return 0; @@ -2575,8 +2629,10 @@ error: H5Tclose(type); H5Tclose(dtype); H5Tclose(native_type); - H5Dclose(dset); - H5Dclose(dataset); + H5Dclose(dset1); + H5Dclose(dset2); + H5Dclose(dataset1); + H5Dclose(dataset2); } H5E_END_TRY; return -1; -- cgit v0.12