diff options
author | Raymond Lu <songyulu@hdfgroup.org> | 2004-04-27 19:16:54 (GMT) |
---|---|---|
committer | Raymond Lu <songyulu@hdfgroup.org> | 2004-04-27 19:16:54 (GMT) |
commit | b3d2f04490363a24f1d43581116a61356ca89f77 (patch) | |
tree | 71b91e09d8fe1e0475e2da5fe39f487c9db5eba9 /test | |
parent | 85b599e9332c1d7d6f454425b66ad43e78954814 (diff) | |
download | hdf5-b3d2f04490363a24f1d43581116a61356ca89f77.zip hdf5-b3d2f04490363a24f1d43581116a61356ca89f77.tar.gz hdf5-b3d2f04490363a24f1d43581116a61356ca89f77.tar.bz2 |
[svn-r8424] *** empty log message ***
Diffstat (limited to 'test')
-rw-r--r-- | test/dtypes.c | 128 |
1 files changed, 113 insertions, 15 deletions
diff --git a/test/dtypes.c b/test/dtypes.c index 17fdc33..27b4874 100644 --- a/test/dtypes.c +++ b/test/dtypes.c @@ -171,6 +171,46 @@ overflow_handler(hid_t UNUSED src_id, hid_t UNUSED dst_id, /*------------------------------------------------------------------------- + * Function: except_func + * + * Purpose: Gets called for all data type conversion exceptions. + * + * Return: H5T_CONV_ABORT: -1 + * + * H5T_CONV_UNHANDLED 0 + * + * H5T_CONV_HANDLED 1 + * + * Programmer: Raymond Lu + * April 19, 2004 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +static H5T_conv_ret_t +except_func(int except_type, hid_t src_id, hid_t dst_id, void *src_buf, + void *dst_buf, void *user_data) +{ + H5T_conv_ret_t ret = H5T_CONV_HANDLED; + + if(except_type == H5T_CONV_EXCEPT_RANGE_HI) + /*only test integer case*/ + *(int*)dst_buf = *(int*)user_data; + else if(except_type == H5T_CONV_EXCEPT_RANGE_LOW) + /*only test integer case*/ + *(int*)dst_buf = *(int*)user_data; + else if(except_type == H5T_CONV_EXCEPT_TRUNCATE) { + ret = H5T_CONV_UNHANDLED; + } else if(except_type == H5T_CONV_EXCEPT_PRECISION) { + ret = H5T_CONV_UNHANDLED; + } + + return ret; +} + + +/*------------------------------------------------------------------------- * Function: some_dummy_func * * Purpose: A dummy function to help check for overflow. @@ -3796,6 +3836,11 @@ test_conv_int_2(void) static int test_conv_int_float(const char *name, hid_t src, hid_t dst) { + hid_t dxpl_id; /*dataset transfer property list*/ + int fill_value=9; /*fill value for conversion exception*/ + H5T_conv_except_func_t op; /*returned callback function for conversion exception*/ + void *user_data; /*returned pointer to user data passed in to the callback*/ + hbool_t except_set = FALSE; /*whether user's exception handling is set*/ const size_t ntests=NTESTS; /*number of tests */ const size_t nelmts=NTESTELEM; /*num values per test */ const size_t max_fails=40; /*max number of failures*/ @@ -3974,6 +4019,31 @@ test_conv_int_float(const char *name, hid_t src, hid_t dst) noverflows_g = 0; #endif + /* Create a dataset transfer property list and datatype conversion + * exception handler function and pass in fill value. This is mainly + * for NetCDF compatibility, which requests fill in fill value when + * conversion exception happens. We only test (unsigned) int - float + * and float - (unsigned) int conversions, which should cover more cases. + */ + if((dxpl_id = H5Pcreate(H5P_DATASET_XFER))<0) + goto error; + + if((src_type == INT_INT && dst_type == FLT_FLOAT) || + (src_type == INT_UINT && dst_type == FLT_FLOAT) || + (src_type == FLT_FLOAT && dst_type == INT_UINT) || + (src_type == FLT_FLOAT && dst_type == INT_INT)) { + if(H5Pset_type_conv_cb(dxpl_id, except_func, &fill_value)<0) + goto error; + else + except_set = TRUE; + + if(H5Pget_type_conv_cb(dxpl_id, &op, &user_data)<0) + goto error; + + if(op != except_func || *(int*)user_data != fill_value) + goto error; + } + /* The tests */ for (i=0; i<ntests; i++) { if (ntests>1) { @@ -3996,7 +4066,7 @@ test_conv_int_float(const char *name, hid_t src, hid_t dst) buf[j] = saved[j] = HDrand(); /* Perform the conversion */ - if (H5Tconvert(src, dst, (hsize_t)nelmts, buf, NULL, H5P_DEFAULT)<0) + if (H5Tconvert(src, dst, (hsize_t)nelmts, buf, NULL, dxpl_id)<0) goto error; /* Check the results from the library against hardware */ @@ -4347,10 +4417,14 @@ test_conv_int_float(const char *name, hid_t src, hid_t dst) for (k=0; k<dst_size; k++) dst_bits[dst_size-(k+1)] = buf[j*dst_size+ENDIAN(dst_size, k)]; - /* + /* Test library's default overflow handling: * Hardware usually doesn't handle overflows too gracefully. The * hardware conversion result during overflows is usually garbage * so we must handle those cases differetly when checking results. + * + * Test user's exception handler when overflows: + * Try to follow the except_func callback function to check if the + * desired value was set. */ if ((FLT_FLOAT==src_type || FLT_DOUBLE==src_type || FLT_LDOUBLE==src_type) && (INT_CHAR==dst_type || INT_SHORT==dst_type || INT_INT==dst_type @@ -4362,9 +4436,15 @@ test_conv_int_float(const char *name, hid_t src, hid_t dst) * the destination. The destination should be set to the * maximum possible value: 0x7f...f */ - if (0==H5T_bit_get_d(dst_bits, dst_nbits-1, 1) && - H5T_bit_find(dst_bits, 0, dst_nbits-1, H5T_BIT_LSB, 0)<0) - continue; /*no error*/ + if(!except_set) { + if (0==H5T_bit_get_d(dst_bits, dst_nbits-1, 1) && + H5T_bit_find(dst_bits, 0, dst_nbits-1, H5T_BIT_LSB, 0)<0) + continue; /*no error*/ + } else { + /* fill_value is small so we know only the 1st byte is set */ + if (dst_bits[0] == fill_value) + continue; /*no error*/ + } } else if (1==H5T_bit_get_d(src_bits, src_nbits-1, 1) && overflows(src_bits, src_type, src_size, dst_nbits-1)) { /* @@ -4372,9 +4452,14 @@ test_conv_int_float(const char *name, hid_t src, hid_t dst) * the destination. The destination should be set to the * smallest possible value: 0x80...0 */ - if (1==H5T_bit_get_d(dst_bits, dst_nbits-1, 1) && - H5T_bit_find(dst_bits, 0, dst_nbits-1, H5T_BIT_LSB, 1)<0) - continue; /*no error*/ + if(!except_set) { + if (1==H5T_bit_get_d(dst_bits, dst_nbits-1, 1) && + H5T_bit_find(dst_bits, 0, dst_nbits-1, H5T_BIT_LSB, 1)<0) + continue; /*no error*/ + } else { + if (dst_bits[0] == fill_value) + continue; /*no error*/ + } } } @@ -4387,16 +4472,26 @@ test_conv_int_float(const char *name, hid_t src, hid_t dst) * The source is negative if the most significant bit is * set. The destination is zero if all bits are zero. */ - if (H5T_bit_find(dst_bits, 0, dst_nbits, H5T_BIT_LSB, 1)<0) - continue; /*no error*/ + if(!except_set) { + if (H5T_bit_find(dst_bits, 0, dst_nbits, H5T_BIT_LSB, 1)<0) + continue; /*no error*/ + } else { + if (dst_bits[0] == fill_value) + continue; /*no error*/ + } } else if (overflows(src_bits, src_type, src_size, dst_nbits)) { /* * The source is a value with a magnitude too large for * the destination. The destination should be the * largest possible value: 0xff...f */ - if (H5T_bit_find(dst_bits, 0, dst_nbits, H5T_BIT_LSB, 0)<0) - continue; /*no error*/ + if(!except_set) { + if (H5T_bit_find(dst_bits, 0, dst_nbits, H5T_BIT_LSB, 0)<0) + continue; /*no error*/ + } else { + if (dst_bits[0] == fill_value) + continue; /*no error*/ + } } } @@ -4610,10 +4705,13 @@ test_conv_int_float(const char *name, hid_t src, hid_t dst) /*------------------------------------------------------------------------- * Function: overflows * - * Purpose: return the index of the most significant digit in a bit - * vector. + * Purpose: When convert from float or double to any integer type, + * check if overflow occurs. + * + * + * Return: TRUE: overflow happens * - * Return: index + * FALSE: no overflow * * Programmer: Raymond Lu * Monday, Nov 17, 2003 |