From 9d68049cc6a6062a95a57d7f2b01ae21ef6ac1eb Mon Sep 17 00:00:00 2001 From: Raymond Lu Date: Mon, 23 Aug 2010 16:37:10 -0500 Subject: [svn-r19279] 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. Tested on heiwa, jam, and amani. --- 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 75f8238..aa62d49 100644 --- a/release_docs/RELEASE.txt +++ b/release_docs/RELEASE.txt @@ -63,8 +63,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 metadata I/O by changing the default algorithm to perform I/O from all processes (instead of just process 0) when using parallel I/O drivers. (QAK - 2010/07/19) 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 bb6f5e4..997d57a 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); @@ -5852,11 +5851,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 */ @@ -5952,7 +5952,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 */ @@ -5962,24 +5962,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 @@ -5987,9 +6002,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); @@ -6009,6 +6039,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(); @@ -6021,6 +6052,7 @@ error: H5Tclose(memb_array2); H5Tclose(vl_id); H5Tclose(cmpd); + H5Tclose(cmpd_array); H5Fclose(file); H5E_END_TRY; return 1; -- cgit v0.12