From 9fbdf8f07aeb41e04108e369196c426b7403881a Mon Sep 17 00:00:00 2001 From: Raymond Lu Date: Tue, 24 Aug 2010 11:00:20 -0500 Subject: [svn-r19288] Bug 1934 - I added support of all data types for H5Tget_order. I added a new byte order H5T_ORDER_MIXED specifically for compound types and its derived types. They report mixed orders if they have members of different orders. There is no change to configure.in, config, and Makefile.am in the top directory. They have some property changes when I merged the code from 1.8. Tested on jam. I tested the same change for 1.8 with h5committest. --- release_docs/RELEASE.txt | 5 ++-- src/H5Torder.c | 62 +++++++++++++++++++++++++++++++++--------- src/H5Tpublic.h | 3 ++- test/dtypes.c | 70 +++++++++++++++++++++++++++++++++++------------- 4 files changed, 105 insertions(+), 35 deletions(-) diff --git a/release_docs/RELEASE.txt b/release_docs/RELEASE.txt index 9696ec7..dc2d398 100644 --- a/release_docs/RELEASE.txt +++ b/release_docs/RELEASE.txt @@ -76,8 +76,9 @@ New Features Library: -------- - - H5Tset_order now supports all data types. Please see bug #1934. - (SLU - 2010/8/18) + - H5Tset_order and H5Tget_order now support all data types. A new byte + order H5T_ORDER_MIXED has been added specifically for compound datatype + and its derived type. Please see bug #1934. (SLU - 2010/8/23) - 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 86a725b..ba8aa1b 100644 --- a/src/H5Torder.c +++ b/src/H5Torder.c @@ -63,8 +63,13 @@ H5T_init_order_interface(void) * * Programmer: Robb Matzke * Wednesday, January 7, 1998 -s - * + * + * Modifications: + * Raymond Lu + * 23 August 2010 + * I added support for all data types. If the type is compound + * and its members have mixed orders, this function returns + * H5T_ORDER_MIXED. *------------------------------------------------------------------------- */ H5T_order_t @@ -103,20 +108,49 @@ done: *------------------------------------------------------------------------- */ H5T_order_t -H5T_get_order(const H5T_t *dt) +H5T_get_order(const H5T_t *dtype) { - H5T_order_t ret_value; /* Return value */ + int nmemb; /* Number of members in compound & enum types */ + int i; /* Local index variable */ + H5T_order_t ret_value = H5T_ORDER_NONE; /* Return value */ FUNC_ENTER_NOAPI(H5T_get_order, H5T_ORDER_ERROR) /*defer to parent*/ - while(dt->shared->parent) - dt = dt->shared->parent; - if(!H5T_IS_ATOMIC(dt->shared)) - HGOTO_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, H5T_ORDER_ERROR, "operation not defined for specified datatype") + while(dtype->shared->parent) + dtype = dtype->shared->parent; + + /* Set order for atomic type. */ + if(H5T_IS_ATOMIC(dtype->shared)) { + ret_value = dtype->shared->u.atomic.order; + HGOTO_DONE(ret_value) + } + + /* Loop through all fields of compound type */ + if(H5T_COMPOUND == dtype->shared->type) { + H5T_order_t memb_order = H5T_ORDER_NONE; + if((nmemb = H5T_get_nmembers(dtype)) < 0) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "can't get number of members from compound data type") + + /* Get order for each compound member type. */ + for(i=0; ishared->u.compnd.memb[i].type)) == H5T_ORDER_ERROR) + HGOTO_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, "can't get order for compound member") + + /* Ignore the H5T_ORDER_NONE, write down the first non H5T_ORDER_NONE order. */ + if(memb_order != H5T_ORDER_NONE && ret_value == H5T_ORDER_NONE) + ret_value = memb_order; + + /* If the orders are mixed, stop the loop and report it. + * H5T_ORDER_NONE is ignored*/ + if(memb_order != H5T_ORDER_NONE && ret_value != H5T_ORDER_NONE && + memb_order != ret_value) { + ret_value = H5T_ORDER_MIXED; + break; + } + } + } - /* Order */ - ret_value = dt->shared->u.atomic.order; done: FUNC_LEAVE_NOAPI(ret_value) @@ -159,7 +193,7 @@ 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 (order < H5T_ORDER_LE || order > H5T_ORDER_NONE) + if (order < H5T_ORDER_LE || order > H5T_ORDER_NONE || order == H5T_ORDER_MIXED) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "illegal byte order") if (H5T_STATE_TRANSIENT!=dt->shared->state) HGOTO_ERROR(H5E_ARGS, H5E_CANTINIT, FAIL, "datatype is read-only") @@ -189,8 +223,7 @@ done: 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 nmemb; /* Number of members in compound & enum types */ int i; /* Local index variable */ herr_t ret_value=SUCCEED; /* Return value */ @@ -218,6 +251,9 @@ H5T_set_order(H5T_t *dtype, H5T_order_t order) if((nmemb = H5T_get_nmembers(dtype)) < 0) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "can't get number of members from compound data type") + if(nmemb == 0) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "no member is in the compound data type") + /* Set order for each compound member type. */ for(i=0; ishared->u.compnd.memb[i].type, order) < 0) diff --git a/src/H5Tpublic.h b/src/H5Tpublic.h index 330a731..d646ef1 100644 --- a/src/H5Tpublic.h +++ b/src/H5Tpublic.h @@ -50,7 +50,8 @@ typedef enum H5T_order_t { H5T_ORDER_LE = 0, /*little endian */ H5T_ORDER_BE = 1, /*bit endian */ H5T_ORDER_VAX = 2, /*VAX mixed endian */ - H5T_ORDER_NONE = 3 /*no particular order (strings, bits,..) */ + H5T_ORDER_MIXED = 3, /*Compound type with mixed member orders */ + H5T_ORDER_NONE = 4 /*no particular order (strings, bits,..) */ /*H5T_ORDER_NONE must be last */ } H5T_order_t; diff --git a/test/dtypes.c b/test/dtypes.c index f766e6e..dfa19dd 100644 --- a/test/dtypes.c +++ b/test/dtypes.c @@ -585,12 +585,11 @@ test_compound_1(void) FAIL_PUTS_ERROR("Operation not allowed for this type."); } /* end if */ - H5E_BEGIN_TRY { - order = H5Tget_order(complex_id); - } H5E_END_TRY; - if (order>-1) { - FAIL_PUTS_ERROR("Operation not allowed for this type."); - } /* end if */ + /* We started to support this function for compound type in 1.8.6 release. */ + if((order = H5Tget_order(complex_id)) == H5T_ORDER_ERROR) + FAIL_PUTS_ERROR("Can't get order for compound type."); + if(order != H5T_ORDER_LE && order != H5T_ORDER_BE) + FAIL_PUTS_ERROR("Wrong order for this type."); H5E_BEGIN_TRY { sign = H5Tget_sign(complex_id); @@ -5851,11 +5850,12 @@ test_set_order(void) /* 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 - order = H5Tget_order(dtype); + ret = H5Tset_order(dtype, H5T_ORDER_BE); H5E_END_TRY - if (order >= 0) TEST_ERROR + if (ret >= 0) TEST_ERROR + if ((order = H5Tget_order(dtype)) == H5T_ORDER_ERROR) TEST_ERROR + if (order != H5T_ORDER_NONE) TEST_ERROR if (H5Tclose(dtype) < 0) TEST_ERROR /* Object reference */ @@ -5951,7 +5951,7 @@ test_set_order_compound(hid_t fapl) } complex_cmpd; hid_t file; - hid_t cmpd, memb_cmpd, memb_array1, memb_array2; + hid_t cmpd, memb_cmpd, memb_array1, memb_array2, cmpd_array; hid_t vl_id; H5T_order_t order; /* Byte order */ hsize_t dims[2] = {3, 4}; /* Array dimenstions */ @@ -5961,24 +5961,39 @@ test_set_order_compound(hid_t fapl) 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 + 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 + + /* Set the order to little-endian. */ + if (H5Tset_order(memb_cmpd, H5T_ORDER_BE) < 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); + /* Set the order to big-endian. */ + if (H5Tset_order(memb_array1, H5T_ORDER_LE) < 0) TEST_ERROR + /* 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 + 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 + + /* The order should be mixed now. */ + if((order = H5Tget_order(cmpd)) != H5T_ORDER_MIXED) TEST_ERROR + + /* Create an array of the compound type above */ + cmpd_array = H5Tarray_create2(cmpd, 2, dims); + + /* The order of the array type should be the same as the compound type */ + if((order = H5Tget_order(cmpd_array)) != H5T_ORDER_MIXED) TEST_ERROR /* Verify that the order can't be 'none'. */ H5E_BEGIN_TRY @@ -5986,9 +6001,24 @@ test_set_order_compound(hid_t fapl) H5E_END_TRY if (ret >= 0) TEST_ERROR - /* Change the order */ + /* Verify that the order can't be 'mixed'. */ + H5E_BEGIN_TRY + ret = H5Tset_order(cmpd, H5T_ORDER_MIXED); + H5E_END_TRY + if (ret >= 0) TEST_ERROR + + /* Change the order of the compound type to big-endian*/ if (H5Tset_order(cmpd, H5T_ORDER_BE) < 0) TEST_ERROR + /* Verify that the order of the compound type is big-endian */ + if ((order = H5Tget_order(cmpd)) != H5T_ORDER_BE) TEST_ERROR + + /* Change the order of the array type to little-endian*/ + if (H5Tset_order(cmpd_array, H5T_ORDER_LE) < 0) TEST_ERROR + + /* Verify that the order of the array type is little-endian */ + if ((order = H5Tget_order(cmpd_array)) != H5T_ORDER_LE) TEST_ERROR + /* Create file */ h5_fixname(FILENAME[1], fapl, filename, sizeof filename); @@ -6008,6 +6038,7 @@ test_set_order_compound(hid_t fapl) if (H5Tclose(memb_array2) < 0) TEST_ERROR if (H5Tclose(vl_id) < 0) TEST_ERROR if (H5Tclose(cmpd) < 0) TEST_ERROR + if (H5Tclose(cmpd_array) < 0) TEST_ERROR if (H5Fclose(file) < 0) TEST_ERROR PASSED(); @@ -6020,6 +6051,7 @@ error: H5Tclose(memb_array2); H5Tclose(vl_id); H5Tclose(cmpd); + H5Tclose(cmpd_array); H5Fclose(file); H5E_END_TRY; return 1; -- cgit v0.12