From e56b6f6c4019ad7dddf2325c91b134646fcb55e6 Mon Sep 17 00:00:00 2001 From: Raymond Lu Date: Thu, 19 Aug 2010 10:27:56 -0500 Subject: [svn-r19251] New feature(bug #1934): I made H5Tset_order support all data types with some restictions: 1. For enum type, members shouldn't be defined yet. 2. H5T_ORDER_NONE only works for reference and fixed-length string. 3. For opaque type, the order will be ignored. 4. For compound type, all restrictions above apply to the members. I'll change H5Tget_order and do another commit. There is no change to configure.in, config, and Makefile.am. There is some property change for these files when I did a merge from 1.8. Tested on jam. But I tested the 1.8 on heiwa, and amani. --- release_docs/RELEASE.txt | 2 + src/H5Torder.c | 82 +++++++++++++++++++++++----- src/H5Tprivate.h | 1 + test/dsets.c | 16 +++--- test/dtypes.c | 135 +++++++++++++++++++++++++++++++++++++++++------ 5 files changed, 197 insertions(+), 39 deletions(-) diff --git a/release_docs/RELEASE.txt b/release_docs/RELEASE.txt index 125fcce..9696ec7 100644 --- a/release_docs/RELEASE.txt +++ b/release_docs/RELEASE.txt @@ -76,6 +76,8 @@ New Features Library: -------- + - H5Tset_order now supports all data types. Please see bug #1934. + (SLU - 2010/8/18) - Improved performance of the chunk cache by avoiding unnecessary b-tree lookups of chunks already in cache. (NAF - 2010/06/15) - Greatly improved performance of extending a dataset with early diff --git a/src/H5Torder.c b/src/H5Torder.c index 6c0667b..86a725b 100644 --- a/src/H5Torder.c +++ b/src/H5Torder.c @@ -63,6 +63,7 @@ H5T_init_order_interface(void) * * Programmer: Robb Matzke * Wednesday, January 7, 1998 +s * *------------------------------------------------------------------------- */ @@ -136,6 +137,14 @@ done: * Robb Matzke, 22 Dec 1998 * Also works for derived datatypes. * + * Raymond Lu, 18 Aug 2010 + * Now it works for all data types with some restrictions: + * 1. For enum type, members shouldn't be defined yet. + * 2. H5T_ORDER_NONE only works for reference and fixed-length + * string. + * 3. For opaque type, the order will be ignored. + * 4. For compound type, all restrictions above apply to the + * members. *------------------------------------------------------------------------- */ herr_t @@ -150,23 +159,72 @@ H5Tset_order(hid_t type_id, H5T_order_t order) /* Check args */ if (NULL == (dt = H5I_object_verify(type_id,H5I_DATATYPE))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a datatype") - if (H5T_STATE_TRANSIENT!=dt->shared->state) - HGOTO_ERROR(H5E_ARGS, H5E_CANTINIT, FAIL, "datatype is read-only") if (order < H5T_ORDER_LE || order > H5T_ORDER_NONE) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "illegal byte order") - 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") - while (dt->shared->parent) - dt = dt->shared->parent; /*defer to parent*/ - if (order == H5T_ORDER_NONE && !(H5T_REFERENCE == dt->shared->type || H5T_IS_FIXED_STRING(dt->shared))) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "illegal byte order") - if (!H5T_IS_ATOMIC(dt->shared)) - HGOTO_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, "operation not defined for specified datatype") + if (H5T_STATE_TRANSIENT!=dt->shared->state) + HGOTO_ERROR(H5E_ARGS, H5E_CANTINIT, FAIL, "datatype is read-only") - /* Commit */ - dt->shared->u.atomic.order = order; + if (H5T_set_order(dt, order) < 0) + HGOTO_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, "can't set order") done: FUNC_LEAVE_API(ret_value) } + +/*------------------------------------------------------------------------- + * Function: H5T_set_order + * + * Purpose: Private function to set the byte order for a datatype. + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Raymond Lu + * 13 August 2010 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +herr_t +H5T_set_order(H5T_t *dtype, H5T_order_t order) +{ + H5T_t *memb_type; /* Datatype of compound members */ + int nmemb; /* Number of members in compound & enum types */ + int i; /* Local index variable */ + herr_t ret_value=SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI(H5T_set_order, FAIL) + + if (H5T_ENUM==dtype->shared->type && dtype->shared->u.enumer.nmembs>0) + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "operation not allowed after enum members are defined") + + /* For derived data type, defer to parent */ + while (dtype->shared->parent) + dtype = dtype->shared->parent; + + if (order == H5T_ORDER_NONE && !(H5T_REFERENCE == dtype->shared->type || + H5T_OPAQUE == dtype->shared->type || H5T_IS_FIXED_STRING(dtype->shared))) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "illegal byte order") + + /* For atomic data type */ + if (H5T_IS_ATOMIC(dtype->shared)) { + dtype->shared->u.atomic.order = order; + HGOTO_DONE(ret_value) + } + + /* Loop through all fields of compound type */ + if(H5T_COMPOUND == dtype->shared->type) { + if((nmemb = H5T_get_nmembers(dtype)) < 0) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "can't get number of members from compound data type") + + /* Set order for each compound member type. */ + for(i=0; ishared->u.compnd.memb[i].type, order) < 0) + HGOTO_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, "can't set order for compound member") + } + } + +done: + FUNC_LEAVE_NOAPI(ret_value) +} diff --git a/src/H5Tprivate.h b/src/H5Tprivate.h index c70eea0..8dac972 100644 --- a/src/H5Tprivate.h +++ b/src/H5Tprivate.h @@ -110,6 +110,7 @@ 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_t *H5T_get_super(const H5T_t *dt); +H5_DLL herr_t H5T_set_order(H5T_t *dtype, H5T_order_t order); 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, hbool_t from_api); H5_DLL size_t H5T_get_size(const H5T_t *dt); diff --git a/test/dsets.c b/test/dsets.c index 1b66dfd..f424a57 100644 --- a/test/dsets.c +++ b/test/dsets.c @@ -3253,11 +3253,6 @@ test_nbit_compound(hid_t file) if(H5Tinsert(mem_cmpd_tid, "s", HOFFSET(atomic, s), s_tid) < 0) goto error; if(H5Tinsert(mem_cmpd_tid, "f", HOFFSET(atomic, f), H5T_NATIVE_FLOAT) < 0) goto error; - /* Set order of dataset compound member datatype */ - if(H5Tset_order(i_tid, H5T_ORDER_BE) < 0) goto error; - if(H5Tset_order(c_tid, H5T_ORDER_BE) < 0) goto error; - if(H5Tset_order(s_tid, H5T_ORDER_BE) < 0) goto error; - /* Create a dataset compound datatype and insert some atomic types */ cmpd_tid = H5Tcreate(H5T_COMPOUND, sizeof(atomic)); if(H5Tinsert(cmpd_tid, "i", HOFFSET(atomic, i), i_tid) < 0) goto error; @@ -3265,6 +3260,9 @@ test_nbit_compound(hid_t file) if(H5Tinsert(cmpd_tid, "s", HOFFSET(atomic, s), s_tid) < 0) goto error; if(H5Tinsert(cmpd_tid, "f", HOFFSET(atomic, f), f_tid) < 0) goto error; + /* Set order of dataset compound datatype */ + if(H5Tset_order(cmpd_tid, H5T_ORDER_BE) < 0) goto error; + /* Create the data space */ if((space = H5Screate_simple(2, size, NULL)) < 0) goto error; @@ -3469,11 +3467,6 @@ test_nbit_compound_2(hid_t file) if(H5Tinsert(mem_cmpd_tid1, "s", HOFFSET(atomic, s), s_tid) < 0) goto error; if(H5Tinsert(mem_cmpd_tid1, "f", HOFFSET(atomic, f), H5T_NATIVE_FLOAT) < 0) goto error; - /* Set order of dataset atomic compound member datatype */ - if(H5Tset_order(i_tid, H5T_ORDER_BE) < 0) goto error; - if(H5Tset_order(c_tid, H5T_ORDER_BE) < 0) goto error; - if(H5Tset_order(s_tid, H5T_ORDER_BE) < 0) goto error; - /* Create a dataset atomic compound datatype and insert some atomic types */ cmpd_tid1 = H5Tcreate(H5T_COMPOUND, sizeof(atomic)); if(H5Tinsert(cmpd_tid1, "i", HOFFSET(atomic, i), i_tid) < 0) goto error; @@ -3481,6 +3474,9 @@ test_nbit_compound_2(hid_t file) if(H5Tinsert(cmpd_tid1, "s", HOFFSET(atomic, s), s_tid) < 0) goto error; if(H5Tinsert(cmpd_tid1, "f", HOFFSET(atomic, f), f_tid) < 0) goto error; + /* Set order of dataset compound datatype */ + if(H5Tset_order(cmpd_tid1, H5T_ORDER_BE) < 0) goto error; + /* Set precision and offset of the other data member */ if(H5Tset_precision(v_tid,precision[3]) < 0) goto error; if(H5Tset_offset(v_tid,offset[3]) < 0) goto error; diff --git a/test/dtypes.c b/test/dtypes.c index e42c243..caa5ac0 100644 --- a/test/dtypes.c +++ b/test/dtypes.c @@ -4859,13 +4859,8 @@ opaque_funcs(void) TEST_ERROR } /* end if */ - H5E_BEGIN_TRY { - ret=H5Tset_order(type, H5T_ORDER_BE); - } H5E_END_TRY; - if (ret>=0) { - printf("Operation not allowed for this type.\n"); - TEST_ERROR - } /* end if */ + /* No effect on opaque type */ + if(H5Tset_order(type, H5T_ORDER_BE) < 0) TEST_ERROR H5E_BEGIN_TRY { sign = H5Tget_sign(type); @@ -5846,23 +5841,18 @@ test_set_order(void) if (H5T_ORDER_BE != H5Tget_order(dtype)) TEST_ERROR; if (H5Tclose(dtype) < 0) TEST_ERROR - /* Opaque - functions should fail */ + /* Opaque - No effect on the order */ if ((dtype = H5Tcreate(H5T_OPAQUE, (size_t)96)) < 0) TEST_ERROR - H5E_BEGIN_TRY - ret = H5Tset_order(dtype, H5T_ORDER_LE); - order = H5Tget_order(dtype); - H5E_END_TRY - if (ret >= 0) TEST_ERROR - if (order >= 0) TEST_ERROR + if (H5Tset_order(dtype, H5T_ORDER_NONE) < 0) TEST_ERROR + if (H5Tset_order(dtype, H5T_ORDER_BE) < 0) TEST_ERROR if (H5Tclose(dtype) < 0) TEST_ERROR - /* Compound - functions should fail */ + /* Compound */ if ((dtype = H5Tcreate(H5T_COMPOUND, (size_t)48)) < 0) TEST_ERROR + if (H5Tset_order(dtype, H5T_ORDER_BE) < 0) TEST_ERROR H5E_BEGIN_TRY - ret = H5Tset_order(dtype, H5T_ORDER_LE); order = H5Tget_order(dtype); H5E_END_TRY - if (ret >= 0) TEST_ERROR if (order >= 0) TEST_ERROR if (H5Tclose(dtype) < 0) TEST_ERROR @@ -5925,6 +5915,116 @@ error: /*------------------------------------------------------------------------- + * Function: test_set_order_compound + * + * Purpose: Tests H5Tset_order/H5Tget_order for complicated compound + * type. + * + * Return: Success: 0 + * + * Failure: number of errors + * + * Programmer: Raymond Lu + * 18 August 2010 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +static int +test_set_order_compound(hid_t fapl) +{ + typedef struct { /* Struct with atomic fields */ + int i; + char c; + short s; + float f; + } atomic_cmpd; + + typedef struct { /* Struct with complex fields */ + atomic_cmpd a; + hvl_t vl; + double b[3][4]; + atomic_cmpd d[3][4]; + } complex_cmpd; + + hid_t file; + hid_t cmpd, memb_cmpd, memb_array1, memb_array2; + hid_t vl_id; + H5T_order_t order; /* Byte order */ + hsize_t dims[2] = {3, 4}; /* Array dimenstions */ + char filename[1024]; + herr_t ret; /* Generic return value */ + + TESTING("H5Tset/get_order for compound type"); + + if ((memb_cmpd = H5Tcreate(H5T_COMPOUND, sizeof(atomic_cmpd))) < 0) TEST_ERROR + if(H5Tinsert(memb_cmpd, "i", HOFFSET(atomic_cmpd, i), H5T_NATIVE_INT) < 0) TEST_ERROR + if(H5Tinsert(memb_cmpd, "c", HOFFSET(atomic_cmpd, c), H5T_NATIVE_CHAR) < 0) TEST_ERROR + if(H5Tinsert(memb_cmpd, "s", HOFFSET(atomic_cmpd, s), H5T_NATIVE_SHORT) < 0) TEST_ERROR + if(H5Tinsert(memb_cmpd, "f", HOFFSET(atomic_cmpd, f), H5T_NATIVE_FLOAT) < 0) TEST_ERROR + + /* Create the simple array datatype */ + memb_array1 = H5Tarray_create2(H5T_NATIVE_DOUBLE, 2, dims); + memb_array2 = H5Tarray_create2(memb_cmpd, 2, dims); + + /* Create a variable-length datatype */ + if ((vl_id = H5Tvlen_create(H5T_NATIVE_UINT)) < 0) TEST_ERROR + + /* Create a compound type using the types above. */ + if ((cmpd = H5Tcreate(H5T_COMPOUND, sizeof(complex_cmpd))) < 0) TEST_ERROR + if(H5Tinsert(cmpd, "a", HOFFSET(complex_cmpd, a), memb_cmpd) < 0) TEST_ERROR + if(H5Tinsert(cmpd, "vl_type", HOFFSET(complex_cmpd, vl), vl_id) < 0) TEST_ERROR + if(H5Tinsert(cmpd, "b", HOFFSET(complex_cmpd, b), memb_array1) < 0) TEST_ERROR + if(H5Tinsert(cmpd, "d", HOFFSET(complex_cmpd, d), memb_array2) < 0) TEST_ERROR + + /* Verify that the order can't be 'none'. */ + H5E_BEGIN_TRY + ret = H5Tset_order(cmpd, H5T_ORDER_NONE); + H5E_END_TRY + if (ret >= 0) TEST_ERROR + + /* Change the order */ + if (H5Tset_order(cmpd, H5T_ORDER_BE) < 0) TEST_ERROR + + /* Create file */ + h5_fixname(FILENAME[1], fapl, filename, sizeof filename); + + if ((file=H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR + + /* Commit the data type */ + if(H5Tcommit2(file, "compound", cmpd, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR + + /* Verify that committed type can't change order */ + H5E_BEGIN_TRY + ret = H5Tset_order(cmpd, H5T_ORDER_LE); + H5E_END_TRY + if (ret >= 0) TEST_ERROR + + if (H5Tclose(memb_cmpd) < 0) TEST_ERROR + if (H5Tclose(memb_array1) < 0) TEST_ERROR + if (H5Tclose(memb_array2) < 0) TEST_ERROR + if (H5Tclose(vl_id) < 0) TEST_ERROR + if (H5Tclose(cmpd) < 0) TEST_ERROR + if (H5Fclose(file) < 0) TEST_ERROR + + PASSED(); + return 0; + +error: + H5E_BEGIN_TRY + H5Tclose(memb_cmpd); + H5Tclose(memb_array1); + H5Tclose(memb_array2); + H5Tclose(vl_id); + H5Tclose(cmpd); + H5Fclose(file); + H5E_END_TRY; + return 1; +} /* end test_set_order_compound() */ + + +/*------------------------------------------------------------------------- * Function: test_named_indirect_reopen * * Purpose: Tests that open named datatypes can be reopened indirectly @@ -6320,6 +6420,7 @@ main(void) nerrors += test_latest(); nerrors += test_int_float_except(); nerrors += test_named_indirect_reopen(fapl); + nerrors += test_set_order_compound(fapl); #ifndef H5_NO_DEPRECATED_SYMBOLS nerrors += test_deprec(fapl); #endif /* H5_NO_DEPRECATED_SYMBOLS */ -- cgit v0.12