diff --git a/src/H5T.c b/src/H5T.c index ec8d4f96174..9ae7c301e54 100644 --- a/src/H5T.c +++ b/src/H5T.c @@ -2919,7 +2919,9 @@ H5Tset_size(hid_t type_id, size_t size) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "only strings may be variable length"); if (H5T_ENUM == dt->shared->type && dt->shared->u.enumer.nmembs > 0) HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "operation not allowed after members are defined"); - if (H5T_REFERENCE == dt->shared->type) + if (H5T_ARRAY == dt->shared->type || H5T_REFERENCE == dt->shared->type || H5T_COMPLEX == dt->shared->type) + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "operation not defined for this datatype"); + if (H5T_VLEN == dt->shared->type && H5T_VLEN_STRING != dt->shared->u.vlen.type) HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "operation not defined for this datatype"); /* Modify the datatype */ @@ -4726,30 +4728,15 @@ H5T__set_size(H5T_t *dt, size_t size) assert(dt); assert(dt->shared); assert(size != 0); + assert(H5T_ARRAY != dt->shared->type); assert(H5T_REFERENCE != dt->shared->type); + assert(H5T_COMPLEX != dt->shared->type); + assert(H5T_VLEN != dt->shared->type || H5T_VLEN_STRING == dt->shared->u.vlen.type); assert(!(H5T_ENUM == dt->shared->type && 0 == dt->shared->u.enumer.nmembs)); if (dt->shared->parent) { - size_t new_size = size; - - if (dt->shared->type == H5T_COMPLEX) { - if ((new_size % 2) != 0) - HGOTO_ERROR(H5E_DATATYPE, H5E_BADVALUE, FAIL, - "new datatype size is not evenly divisible by 2"); - - new_size /= 2; - } - - if (H5T__set_size(dt->shared->parent, new_size) < 0) + if (H5T__set_size(dt->shared->parent, size) < 0) HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to set size for parent data type"); - - /* Adjust size of datatype appropriately */ - if (dt->shared->type == H5T_ARRAY) - dt->shared->size = dt->shared->parent->shared->size * dt->shared->u.array.nelem; - else if (dt->shared->type == H5T_COMPLEX) - dt->shared->size = 2 * dt->shared->parent->shared->size; - else if (dt->shared->type != H5T_VLEN) - dt->shared->size = dt->shared->parent->shared->size; } else { if (H5T_IS_ATOMIC(dt->shared)) { diff --git a/src/H5Tpublic.h b/src/H5Tpublic.h index 7ee092fe2c4..8f53e35ce56 100644 --- a/src/H5Tpublic.h +++ b/src/H5Tpublic.h @@ -846,7 +846,7 @@ H5_DLLVAR hid_t H5T_VAX_F64_g; #define H5T_NATIVE_ULLONG (H5OPEN H5T_NATIVE_ULLONG_g) /** * \ingroup PDTNAT - * C-style \TText{_Float16} (May be \Code{H5I_INVALID_HID} if platform doesn't support \Code{_Float16} type) + * C-style \TText{_Float16} (May be \TText{H5I_INVALID_HID} if platform doesn't support \TText{_Float16} type) */ #define H5T_NATIVE_FLOAT16 (H5OPEN H5T_NATIVE_FLOAT16_g) /** @@ -866,20 +866,20 @@ H5_DLLVAR hid_t H5T_VAX_F64_g; #define H5T_NATIVE_LDOUBLE (H5OPEN H5T_NATIVE_LDOUBLE_g) /** * \ingroup PDTNAT - * C-style \Code{float _Complex} / (MSVC) \Code{_Fcomplex} (May be \Code{H5I_INVALID_HID} if platform doesn't - * support \Code{float _Complex}/\Code{_Fcomplex} type) + * C-style \TText{float _Complex} / (MSVC) \TText{_Fcomplex} (May be \TText{H5I_INVALID_HID} if platform + * doesn't support \TText{float _Complex}/\TText{_Fcomplex} type) */ #define H5T_NATIVE_FLOAT_COMPLEX (H5OPEN H5T_NATIVE_FLOAT_COMPLEX_g) /** * \ingroup PDTNAT - * C-style \Code{double _Complex} / (MSVC) \Code{_Dcomplex} (May be \Code{H5I_INVALID_HID} if platform doesn't - * support \Code{double _Complex}/\Code{_Dcomplex} type) + * C-style \TText{double _Complex} / (MSVC) \TText{_Dcomplex} (May be \TText{H5I_INVALID_HID} if platform + * doesn't support \TText{double _Complex}/\TText{_Dcomplex} type) */ #define H5T_NATIVE_DOUBLE_COMPLEX (H5OPEN H5T_NATIVE_DOUBLE_COMPLEX_g) /** * \ingroup PDTNAT - * C-style \Code{long double _Complex} / (MSVC) \Code{_Lcomplex} (May be \Code{H5I_INVALID_HID} if platform - * doesn't support \Code{long double _Complex}/\Code{_Lcomplex} type) + * C-style \TText{long double _Complex} / (MSVC) \TText{_Lcomplex} (May be \TText{H5I_INVALID_HID} if platform + * doesn't support \TText{long double _Complex}/\TText{_Lcomplex} type) */ #define H5T_NATIVE_LDOUBLE_COMPLEX (H5OPEN H5T_NATIVE_LDOUBLE_COMPLEX_g) /** @@ -2508,22 +2508,10 @@ H5_DLL hid_t H5Tget_native_type(hid_t type_id, H5T_direction_t direction); * decrease the size of a compound datatype, but the function will * fail if the new size is too small to accommodate all member fields. * - * \li Variable-length datatypes: This function sets the size of - * the base datatype for the variable-length datatype. - * - * \li Array datatypes: This function sets the size of the base - * datatype for the array datatype. The array datatype's size is - * then adjusted to be the size of the base datatype multiplied - * by the number of elements in the array datatype's dimensions. - * - * \li Complex number datatypes: The size set for a complex number - * datatype is the size for the entire datatype, which is shared - * evenly among the datatype's real and imaginary parts. Thus, - * the specified size must be a multiple of 2. - * * \li Ineligible datatypes: This function cannot be used with - * enumerated datatypes (#H5T_ENUM) or reference datatypes - * (#H5T_REFERENCE). + * enumerated datatypes (#H5T_ENUM), array datatypes (#H5T_ARRAY), + * variable-length array datatypes (#H5T_VLEN), reference datatypes + * (#H5T_REFERENCE), or complex number datatypes (#H5T_COMPLEX). * * \see H5Tget_size() * diff --git a/test/dtypes.c b/test/dtypes.c index 7c9452fe983..5c9abe2ff03 100644 --- a/test/dtypes.c +++ b/test/dtypes.c @@ -6770,7 +6770,6 @@ test_complex_type(void) const char *driver_name; char filename[256]; hsize_t dims[1]; - herr_t status; hid_t fid = H5I_INVALID_HID; hid_t space_id = H5I_INVALID_HID; hid_t dset_id = H5I_INVALID_HID; @@ -6996,60 +6995,29 @@ test_complex_type(void) } /* - * Check that H5Tset_size and H5Tset_offset work correctly on a complex - * number type (H5Tset_size sets the size for the whole datatype with - * each of the two parts of the type sharing half the size, while - * H5Tset_offset sets the offset for the base datatype) + * Check that H5Tset_offset works correctly on a complex number type + * (H5Tset_offset sets the offset for the base datatype) */ if ((complex_type = H5Tcopy(H5T_NATIVE_FLOAT_COMPLEX)) < 0) { H5_FAILED(); printf("Can't copy H5T_NATIVE_FLOAT_COMPLEX datatype\n"); goto error; } - - H5E_BEGIN_TRY - { - /* Size must be a multiple of 2 since the real and - * imaginary parts will each share half the datatype size - */ - status = H5Tset_size(complex_type, 13); - } - H5E_END_TRY - if (status >= 0) { - H5_FAILED(); - printf("Changed the size of complex number type to a size that isn't a multiple of 2\n"); - goto error; - } - if (H5Tset_offset(complex_type, 3) < 0) { H5_FAILED(); printf("Can't set offset for complex number type's base datatype\n"); goto error; } - if (H5Tset_size(complex_type, 128) < 0) { - H5_FAILED(); - printf("Can't change size of complex number type\n"); - goto error; - } - if ((base_type = H5Tget_super(complex_type)) < 0) { H5_FAILED(); printf("Can't get base datatype of complex number datatype\n"); goto error; } - - type_size = H5Tget_size(base_type); - if (0 == type_size || 64 != type_size) { - H5_FAILED(); - printf("Invalid size for complex number type's base datatype\n"); - goto error; - } if (3 != H5Tget_offset(base_type)) { H5_FAILED(); printf("Invalid offset value for complex number type's base datatype\n"); goto error; } - if (H5Tclose(base_type) < 0) { H5_FAILED(); printf("Can't close datatype\n"); @@ -8821,6 +8789,131 @@ test_array_cmpd_vl(void) return 1; } /* end test_array_cmpd_vl() */ +/*------------------------------------------------------------------------- + * Function: test_set_size_invalid + * + * Purpose: Tests that H5Tset_size fails when called on an array, + * variable-length, reference or complex number datatype. + * + * Return: Success: 0 + * Failure: number of errors + * + *------------------------------------------------------------------------- + */ +static int +test_set_size_invalid(void) +{ + hsize_t array_dims[] = {10}; + hid_t array_tid = H5I_INVALID_HID; + hid_t vlen_tid = H5I_INVALID_HID; + hid_t ref_tid = H5I_INVALID_HID; + hid_t complex_tid = H5I_INVALID_HID; + hid_t string_tid = H5I_INVALID_HID; + herr_t status; + + TESTING("H5Tset_size on ineligible datatypes"); + + if ((array_tid = H5Tarray_create2(H5T_NATIVE_INT, 1, array_dims)) < 0) + TEST_ERROR; + if ((vlen_tid = H5Tvlen_create(array_tid)) < 0) + TEST_ERROR; + if ((ref_tid = H5Tcopy(H5T_STD_REF)) < 0) + TEST_ERROR; + if ((complex_tid = H5Tcomplex_create(H5T_NATIVE_FLOAT)) < 0) + TEST_ERROR; + if ((string_tid = H5Tcopy(H5T_C_S1)) < 0) + TEST_ERROR; + + H5E_BEGIN_TRY + { + status = H5Tset_size(array_tid, 100); + } + H5E_END_TRY; + if (status >= 0) { + H5_FAILED(); + AT(); + printf("Set size on array datatype\n"); + goto error; + } + + H5E_BEGIN_TRY + { + status = H5Tset_size(vlen_tid, 100); + } + H5E_END_TRY; + if (status >= 0) { + H5_FAILED(); + AT(); + printf("Set size on variable-length datatype\n"); + goto error; + } + + H5E_BEGIN_TRY + { + status = H5Tset_size(ref_tid, 100); + } + H5E_END_TRY; + if (status >= 0) { + H5_FAILED(); + AT(); + printf("Set size on reference datatype\n"); + goto error; + } + + H5E_BEGIN_TRY + { + status = H5Tset_size(complex_tid, 100); + } + H5E_END_TRY; + if (status >= 0) { + H5_FAILED(); + AT(); + printf("Set size on complex number datatype\n"); + goto error; + } + + /* Should still be able to convert a variable-length string datatype + * back into a fixed-length string datatype even though variable-length + * string datatypes are tested as H5T_VLEN + */ + if (H5Tset_size(string_tid, H5T_VARIABLE) < 0) + TEST_ERROR; + if (H5Tset_size(string_tid, 100) < 0) { + H5_FAILED(); + AT(); + printf("Unable to set size on variable-length string datatype\n"); + goto error; + } + + if (H5Tclose(array_tid) < 0) + TEST_ERROR; + if (H5Tclose(vlen_tid) < 0) + TEST_ERROR; + if (H5Tclose(ref_tid) < 0) + TEST_ERROR; + if (H5Tclose(complex_tid) < 0) + TEST_ERROR; + if (H5Tclose(string_tid) < 0) + TEST_ERROR; + + PASSED(); + + return 0; + +error: + H5E_BEGIN_TRY + { + H5Tclose(array_tid); + H5Tclose(vlen_tid); + H5Tclose(ref_tid); + H5Tclose(complex_tid); + H5Tclose(string_tid); + } + H5E_END_TRY + + return 1; +} /* end test_set_size_invalid() */ + /*------------------------------------------------------------------------- * Function: test_encode * @@ -12785,6 +12878,7 @@ main(void) nerrors += test_opaque(); nerrors += test_set_order(); nerrors += test_array_cmpd_vl(); + nerrors += test_set_size_invalid(); nerrors += test__Float16(); nerrors += test_complex_type();