summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/H5Tnative.c190
-rw-r--r--test/dtypes.c13
-rw-r--r--test/ntypes.c120
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;