summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--release_docs/RELEASE.txt5
-rw-r--r--src/H5Torder.c62
-rw-r--r--src/H5Tpublic.h3
-rw-r--r--test/dtypes.c70
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; i<nmemb; i++) {
+ if((memb_order = H5T_get_order(dtype->shared->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; i<nmemb; i++) {
if(H5T_set_order(dtype->shared->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;