summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--release_docs/RELEASE.txt2
-rw-r--r--src/H5Torder.c82
-rw-r--r--src/H5Tprivate.h1
-rw-r--r--test/dsets.c16
-rw-r--r--test/dtypes.c135
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; i<nmemb; i++) {
+ if(H5T_set_order(dtype->shared->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 */