summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorQuincey Koziol <koziol@hdfgroup.org>2003-08-31 01:48:01 (GMT)
committerQuincey Koziol <koziol@hdfgroup.org>2003-08-31 01:48:01 (GMT)
commitf92d7f73df1846f4489fb6e2c2dd857b636b4deb (patch)
tree74d28cd355a39d0d9f8dc0c96484380b6b12628e
parentbd3510bea3638d5f4281bf9a6bbfe4c4a8b3ca9a (diff)
downloadhdf5-f92d7f73df1846f4489fb6e2c2dd857b636b4deb.zip
hdf5-f92d7f73df1846f4489fb6e2c2dd857b636b4deb.tar.gz
hdf5-f92d7f73df1846f4489fb6e2c2dd857b636b4deb.tar.bz2
[svn-r7434] Purpose:
Bug Fix and code cleanup Description: Correct error in H5T_detect_class that was causing nested compound datatypes with to not detect the datatype class of fields correctly, which caused errors with fill-values, variable-length datatypes and chunks later on. Return the rank of the array datatype from H5Tget_array_dims(), like H5Sget_dims(). Lots of cleanups to datatype code, to make the handling of arrays, compound types, variable-length strings and sequences and enumerated types more consistent and robust. Platforms tested: FreeBSD 4.9 (sleipnir) h5committest
-rw-r--r--doc/html/H5.intro.html2
-rw-r--r--doc/html/RM_H5T.html6
-rw-r--r--release_docs/RELEASE.txt5
-rw-r--r--src/H5Odtype.c13
-rw-r--r--src/H5T.c65
-rw-r--r--src/H5Tarray.c22
-rw-r--r--src/H5Tcompound.c9
-rw-r--r--src/H5Tcset.c16
-rw-r--r--src/H5Tfixed.c2
-rw-r--r--src/H5Tfloat.c16
-rw-r--r--src/H5Toffset.c31
-rw-r--r--src/H5Topaque.c5
-rw-r--r--src/H5Torder.c9
-rw-r--r--src/H5Tpad.c8
-rw-r--r--src/H5Tpkg.h11
-rw-r--r--src/H5Tprecis.c72
-rw-r--r--src/H5Tpublic.h2
-rw-r--r--src/H5Tstrpad.c16
-rw-r--r--src/H5Tvlen.c16
-rw-r--r--test/dtypes.c132
20 files changed, 307 insertions, 151 deletions
diff --git a/doc/html/H5.intro.html b/doc/html/H5.intro.html
index 2c0bb73..2b4d956 100644
--- a/doc/html/H5.intro.html
+++ b/doc/html/H5.intro.html
@@ -2356,7 +2356,7 @@ permutation of the array and the size of each dimension.
(<b>Note:</b> The permutation feature is not implemented in Release 1.4.)
<dir>
- <em>herr_t</em> <code>H5Tget_array_dims</code>(
+ <em>int</em> <code>H5Tget_array_dims</code>(
<em>hid_t</em> <code>adtype_id</code>,
<em>hsize_t *</em><code>dims[]</code>,
<em>int *</em><code>perm[]</code>
diff --git a/doc/html/RM_H5T.html b/doc/html/RM_H5T.html
index 4a3e334..a877ff5 100644
--- a/doc/html/RM_H5T.html
+++ b/doc/html/RM_H5T.html
@@ -2946,13 +2946,13 @@ zero.
<dl>
<dt><strong>Name:</strong> <a name="Datatype-GetArrayDims">H5Tget_array_dims</a>
<dt><strong>Signature:</strong>
- <dd><em>herr_t</em> <code>H5Tget_array_dims</code>(
+ <dd><em>int</em> <code>H5Tget_array_dims</code>(
<em>hid_t</em> <code>adtype_id</code>,
<em>hsize_t *</em><code>dims[]</code>,
<em>int *</em><code>perm[]</code>
)
<dt><strong>Purpose:</strong>
- <dd>Returns sizes of array dimensions and dimension permutations.
+ <dd>Retrieves sizes of array dimensions and dimension permutations.
<dt><strong>Description:</strong>
<dd><code>H5Tget_array_dims</code> returns the sizes of the dimensions
and the dimension permutations of the specified array datatype object.
@@ -2970,7 +2970,7 @@ zero.
<dd>OUT: Dimension permutations.
</dl>
<dt><strong>Returns:</strong>
- <dd>Returns a non-negative value if successful;
+ <dd>Returns the non-negative number of dimensions of the array type if successful;
otherwise returns a negative value.
<dt><strong>Non-C API(s):</strong>
<dd><a href="fortran/h5t_FORTRAN.html#h5tget_array_dims_f"
diff --git a/release_docs/RELEASE.txt b/release_docs/RELEASE.txt
index 158e722..0691f06 100644
--- a/release_docs/RELEASE.txt
+++ b/release_docs/RELEASE.txt
@@ -74,6 +74,11 @@ Bug Fixes since HDF5-1.6.0 release
Library
-------
+ - Return rank of the array datatype on successful call to
+ H5Tget_array_dims(). QAK - 2003/08/30
+ - Corrected bug in H5Tdetect_class which was not correctly detecting
+ datatype classes of fields in nested compound datatypes in some
+ circumstances. QAK - 2003/08/30
- Corrected bug in sieve buffer code which could cause loss of data
when a small dataset was created and deleted in quick succession.
QAK - 2003/08/27
diff --git a/src/H5Odtype.c b/src/H5Odtype.c
index 1e70ff9..d6de6f6 100644
--- a/src/H5Odtype.c
+++ b/src/H5Odtype.c
@@ -273,10 +273,6 @@ H5O_dtype_decode_helper(H5F_t *f, const uint8_t **pp, H5T_t *dt)
if(temp_type->force_conv==TRUE)
dt->force_conv=TRUE;
- /* Set the "has array" flag if array datatype fields exist in this type */
- if(temp_type->type==H5T_ARRAY)
- dt->u.compnd.has_array=TRUE;
-
/* Member size */
dt->u.compnd.memb[i].size = temp_type->size;
@@ -435,6 +431,7 @@ done:
static herr_t
H5O_dtype_encode_helper(uint8_t **pp, const H5T_t *dt)
{
+ htri_t has_array=FALSE; /* Whether a compound datatype has an array inside it */
unsigned flags = 0;
char *hdr = (char *)*pp;
int i, j;
@@ -624,6 +621,10 @@ H5O_dtype_encode_helper(uint8_t **pp, const H5T_t *dt)
break;
case H5T_COMPOUND:
+ /* Check for an array datatype somewhere within the compound type */
+ if((has_array=H5T_detect_class(dt,H5T_ARRAY))<0)
+ HGOTO_ERROR(H5E_DATATYPE, H5E_CANTENCODE, FAIL, "can't detect array class");
+
/*
* Compound data types...
*/
@@ -644,7 +645,7 @@ H5O_dtype_encode_helper(uint8_t **pp, const H5T_t *dt)
* member information, for better backward compatibility
* Write out all zeros for the array information, though...
*/
- if(!dt->u.compnd.has_array) {
+ if(!has_array) {
/* Dimensionality */
*(*pp)++ = 0;
@@ -768,7 +769,7 @@ H5O_dtype_encode_helper(uint8_t **pp, const H5T_t *dt)
}
/* Encode the type's class, version and bit field */
- *hdr++ = ((unsigned)(dt->type) & 0x0f) | (((dt->type==H5T_COMPOUND && dt->u.compnd.has_array) ? H5O_DTYPE_VERSION_UPDATED : H5O_DTYPE_VERSION_COMPAT )<<4);
+ *hdr++ = ((unsigned)(dt->type) & 0x0f) | (((dt->type==H5T_COMPOUND && has_array) ? H5O_DTYPE_VERSION_UPDATED : H5O_DTYPE_VERSION_COMPAT )<<4);
*hdr++ = (flags >> 0) & 0xff;
*hdr++ = (flags >> 8) & 0xff;
*hdr++ = (flags >> 16) & 0xff;
diff --git a/src/H5T.c b/src/H5T.c
index 77e585a..dafd219 100644
--- a/src/H5T.c
+++ b/src/H5T.c
@@ -2075,7 +2075,7 @@ H5Tcreate(H5T_class_t type, size_t size)
H5TRACE2("i","Ttz",type,size);
/* check args */
- if (size <= 0)
+ if (size == 0)
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid size");
/* create the type */
@@ -2486,13 +2486,16 @@ H5T_detect_class (const H5T_t *dt, H5T_class_t cls)
switch(dt->type) {
case H5T_COMPOUND:
for (i=0; i<dt->u.compnd.nmembs; i++) {
+ htri_t nested_ret; /* Return value from nested call */
+
/* Check if this field's type is the correct type */
if(dt->u.compnd.memb[i].type->type==cls)
HGOTO_DONE(TRUE);
- /* Recurse if it's VL, compound or array */
- if(dt->u.compnd.memb[i].type->type==H5T_COMPOUND || dt->u.compnd.memb[i].type->type==H5T_VLEN || dt->u.compnd.memb[i].type->type==H5T_ARRAY)
- HGOTO_DONE(H5T_detect_class(dt->u.compnd.memb[i].type,cls));
+ /* Recurse if it's VL, compound, enum or array */
+ if(H5T_IS_COMPLEX(dt->u.compnd.memb[i].type->type))
+ if((nested_ret=H5T_detect_class(dt->u.compnd.memb[i].type,cls))!=FALSE)
+ HGOTO_DONE(nested_ret);
} /* end for */
break;
@@ -2621,7 +2624,7 @@ done:
* Function: H5Tset_size
*
* Purpose: Sets the total size in bytes for a data type (this operation
- * is not permitted on compound data types). If the size is
+ * is not permitted on reference data types). If the size is
* decreased so that the significant bits of the data type
* extend beyond the edge of the new size, then the `offset'
* property is decreased toward zero. If the `offset' becomes
@@ -2663,9 +2666,9 @@ H5Tset_size(hid_t type_id, size_t size)
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "size must be positive");
if (size == H5T_VARIABLE && dt->type!=H5T_STRING)
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "only strings may be variable length");
- if (H5T_ENUM==dt->type && dt->u.enumer.nmembs>0)
+ if ((H5T_ENUM==dt->type && dt->u.enumer.nmembs>0) || (H5T_COMPOUND==dt->type && dt->u.compnd.nmembs>0))
HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "operation not allowed after members are defined");
- if (H5T_COMPOUND==dt->type || H5T_ARRAY==dt->type)
+ if (H5T_REFERENCE==dt->type)
HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "operation not defined for this datatype");
/* Do the work */
@@ -3322,7 +3325,7 @@ H5T_create(H5T_class_t type, size_t size)
FUNC_ENTER_NOAPI(H5T_create, NULL);
- assert(size > 0);
+ assert(size != 0);
switch (type) {
case H5T_INTEGER:
@@ -3932,8 +3935,7 @@ H5T_is_atomic(const H5T_t *dt)
assert(dt);
- if (H5T_COMPOUND!=dt->type && H5T_ENUM!=dt->type && H5T_VLEN!=dt->type &&
- H5T_OPAQUE!=dt->type && H5T_ARRAY!=dt->type)
+ if (!H5T_IS_COMPLEX(dt->type) && H5T_OPAQUE!=dt->type)
ret_value = TRUE;
else
ret_value = FALSE;
@@ -3947,7 +3949,7 @@ done:
* Function: H5T_set_size
*
* Purpose: Sets the total size in bytes for a data type (this operation
- * is not permitted on compound data types). If the size is
+ * is not permitted on reference data types). If the size is
* decreased so that the significant bits of the data type
* extend beyond the edge of the new size, then the `offset'
* property is decreased toward zero. If the `offset' becomes
@@ -3984,12 +3986,19 @@ H5T_set_size(H5T_t *dt, size_t size)
/* Check args */
assert(dt);
assert(size!=0);
- assert(H5T_ENUM!=dt->type || 0==dt->u.enumer.nmembs);
+ assert(H5T_REFERENCE!=dt->type);
+ assert(!(H5T_ENUM==dt->type && 0==dt->u.enumer.nmembs));
+ assert(!(H5T_COMPOUND==dt->type && 0==dt->u.compnd.nmembs));
if (dt->parent) {
if (H5T_set_size(dt->parent, size)<0)
HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to set size for parent data type");
- dt->size = dt->parent->size;
+
+ /* Adjust size of datatype appropriately */
+ if(dt->type==H5T_ARRAY)
+ dt->size = dt->parent->size * dt->u.array.nelem;
+ else if(dt->type!=H5T_VLEN)
+ dt->size = dt->parent->size;
} else {
if (H5T_is_atomic(dt)) {
offset = dt->u.atomic.offset;
@@ -4008,15 +4017,11 @@ H5T_set_size(H5T_t *dt, size_t size)
}
switch (dt->type) {
- case H5T_COMPOUND:
- case H5T_ARRAY:
- HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to set size of specified data type");
-
case H5T_INTEGER:
case H5T_TIME:
case H5T_BITFIELD:
- case H5T_ENUM:
case H5T_OPAQUE:
+ case H5T_COMPOUND:
/* nothing to check */
break;
@@ -4075,18 +4080,24 @@ H5T_set_size(H5T_t *dt, size_t size)
}
break;
+ case H5T_ENUM:
+ case H5T_VLEN:
+ case H5T_ARRAY:
+ assert("can't happen" && 0);
+ case H5T_REFERENCE:
+ assert("invalid type" && 0);
default:
assert("not implemented yet" && 0);
}
- /* Commit */
+ /* Commit (if we didn't convert this type to a VL string) */
if(dt->type!=H5T_VLEN) {
dt->size = size;
if (H5T_is_atomic(dt)) {
dt->u.atomic.offset = offset;
dt->u.atomic.prec = prec;
}
- }
+ } /* end if */
}
done:
@@ -5138,9 +5149,9 @@ H5T_set_loc(H5T_t *dt, H5F_t *f, H5T_loc_t loc)
/* Check the datatype of this element */
switch(dt->type) {
case H5T_ARRAY: /* Recurse on VL, compound and array base element type */
- /* Recurse if it's VL, compound or array */
+ /* Recurse if it's VL, compound, enum or array */
/* (If the force_conv flag is _not_ set, the type cannot change in size, so don't recurse) */
- if(dt->parent->force_conv && (dt->parent->type==H5T_COMPOUND || dt->parent->type==H5T_VLEN || dt->parent->type==H5T_ARRAY)) {
+ if(dt->parent->force_conv && H5T_IS_COMPLEX(dt->parent->type)) {
/* Keep the old base element size for later */
old_size=dt->parent->size;
@@ -5171,13 +5182,13 @@ H5T_set_loc(H5T_t *dt, H5F_t *f, H5T_loc_t loc)
/* Set the member type pointer (for convenience) */
memb_type=dt->u.compnd.memb[i].type;
- /* Recurse if it's VL, compound or array */
+ /* Recurse if it's VL, compound, enum or array */
/* (If the force_conv flag is _not_ set, the type cannot change in size, so don't recurse) */
- if(memb_type->force_conv && (memb_type->type==H5T_COMPOUND || memb_type->type==H5T_VLEN || memb_type->type==H5T_ARRAY)) {
+ if(memb_type->force_conv && H5T_IS_COMPLEX(memb_type->type)) {
/* Keep the old field size for later */
old_size=memb_type->size;
- /* Mark the VL, compound or array type */
+ /* Mark the VL, compound, enum or array type */
if((changed=H5T_set_loc(memb_type,f,loc))<0)
HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "Unable to set VL location");
if(changed>0)
@@ -5199,9 +5210,9 @@ H5T_set_loc(H5T_t *dt, H5F_t *f, H5T_loc_t loc)
break;
case H5T_VLEN: /* Recurse on the VL information if it's VL, compound or array, then free VL sequence */
- /* Recurse if it's VL, compound or array */
+ /* Recurse if it's VL, compound, enum or array */
/* (If the force_conv flag is _not_ set, the type cannot change in size, so don't recurse) */
- if(dt->parent->force_conv && (dt->parent->type==H5T_COMPOUND || dt->parent->type==H5T_VLEN || dt->parent->type==H5T_ARRAY)) {
+ if(dt->parent->force_conv && H5T_IS_COMPLEX(dt->parent->type)) {
if((changed=H5T_set_loc(dt->parent,f,loc))<0)
HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "Unable to set VL location");
if(changed>0)
diff --git a/src/H5Tarray.c b/src/H5Tarray.c
index 185561b..1fb01ea 100644
--- a/src/H5Tarray.c
+++ b/src/H5Tarray.c
@@ -181,10 +181,9 @@ H5T_array_create(H5T_t *base, int ndims, const hsize_t dim[/* ndims */],
ret_value->size = ret_value->parent->size * ret_value->u.array.nelem;
/*
- * Set the "force conversion" flag if a VL base datatype is used or
- * or if any components of the base datatype are VL types.
+ * Set the "force conversion" flag if the base datatype indicates
*/
- if(base->type==H5T_VLEN || base->force_conv==TRUE)
+ if(base->force_conv==TRUE)
ret_value->force_conv=TRUE;
done:
@@ -269,7 +268,7 @@ done:
*
* Purpose: Query the sizes of dimensions for an array datatype.
*
- * Return: Success: Non-negative
+ * Return: Success: Number of dimensions of the array type
* Failure: Negative
*
* Programmer: Quincey Koziol
@@ -279,11 +278,11 @@ done:
*
*-------------------------------------------------------------------------
*/
-herr_t
+int
H5Tget_array_dims(hid_t type_id, hsize_t dims[], int perm[])
{
H5T_t *dt = NULL; /* pointer to array data type */
- herr_t ret_value = SUCCEED; /* return value */
+ int ret_value; /* return value */
FUNC_ENTER_API(H5Tget_array_dims, FAIL);
H5TRACE3("e","i*h*Is",type_id,dims,perm);
@@ -295,7 +294,7 @@ H5Tget_array_dims(hid_t type_id, hsize_t dims[], int perm[])
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not an array datatype");
/* Retrieve the sizes of the dimensions */
- if(H5T_get_array_dims(dt, dims, perm)<0)
+ if((ret_value=H5T_get_array_dims(dt, dims, perm))<0)
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "unable to get dimension sizes");
done:
FUNC_LEAVE_API(ret_value);
@@ -308,7 +307,7 @@ done:
* Purpose: Private function for H5T_get_array_dims. Query the sizes
* of dimensions for an array datatype.
*
- * Return: Success: Non-negative
+ * Return: Success: Number of dimensions of the array type
* Failure: Negative
*
* Programmer: Raymond Lu
@@ -318,10 +317,10 @@ done:
*
*-------------------------------------------------------------------------
*/
-herr_t
+int
H5T_get_array_dims(H5T_t *dt, hsize_t dims[], int perm[])
{
- herr_t ret_value = SUCCEED; /* return value */
+ int ret_value; /* return value */
int i; /* Local index variable */
FUNC_ENTER_NOAPI(H5T_get_array_dims, FAIL);
@@ -339,6 +338,9 @@ H5T_get_array_dims(H5T_t *dt, hsize_t dims[], int perm[])
for(i=0; i<dt->u.array.ndims; i++)
perm[i]=dt->u.array.perm[i];
+ /* Pass along the array rank as the return value */
+ ret_value=dt->u.array.ndims;
+
done:
FUNC_LEAVE_NOAPI(ret_value);
} /* end H5T_get_array_dims */
diff --git a/src/H5Tcompound.c b/src/H5Tcompound.c
index b13788f..790de46 100644
--- a/src/H5Tcompound.c
+++ b/src/H5Tcompound.c
@@ -447,16 +447,11 @@ H5T_insert(H5T_t *parent, const char *name, size_t offset, const H5T_t *member)
parent->u.compnd.nmembs++;
/*
- * Set the "force conversion" flag if VL datatype fields exist in this type
- * or any component types
+ * Set the "force conversion" flag if the field's datatype indicates
*/
- if(member->type==H5T_VLEN || member->force_conv==TRUE)
+ if(member->force_conv==TRUE)
parent->force_conv=TRUE;
- /* Set the flag for this compound type, if the field is an array */
- if(member->type==H5T_ARRAY)
- parent->u.compnd.has_array=TRUE;
-
done:
FUNC_LEAVE_NOAPI(ret_value);
}
diff --git a/src/H5Tcset.c b/src/H5Tcset.c
index cb58afb..6814b9b 100644
--- a/src/H5Tcset.c
+++ b/src/H5Tcset.c
@@ -61,7 +61,7 @@ H5T_init_cset_interface(void)
* different nationalities and to convert between them to the
* extent possible.
*
- * Return: Success: The character set of an H5T_STRING type.
+ * Return: Success: The character set of a string type.
*
* Failure: H5T_CSET_ERROR (Negative)
*
@@ -86,10 +86,9 @@ H5Tget_cset(hid_t type_id)
/* Check args */
if (NULL == (dt = H5I_object_verify(type_id,H5I_DATATYPE)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5T_CSET_ERROR, "not a data type");
- /* Don't see any reason for this. Causes problem for variable-length
- * string. -SLU (& QAK) */
- /*if (dt->parent) dt = dt->parent;*/ /*defer to parent*/
- if (!(H5T_STRING == dt->type || (H5T_VLEN == dt->type && H5T_VLEN_STRING == dt->u.vlen.type)))
+ while (dt->parent && !H5T_IS_STRING(dt))
+ dt = dt->parent; /*defer to parent*/
+ if (!H5T_IS_STRING(dt))
HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, H5T_CSET_ERROR, "operation not defined for data type class");
/* result */
@@ -139,10 +138,9 @@ H5Tset_cset(hid_t type_id, H5T_cset_t cset)
HGOTO_ERROR(H5E_ARGS, H5E_CANTINIT, FAIL, "data type is read-only");
if (cset < 0 || cset >= H5T_NCSET)
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "illegal character set type");
- /* Don't see any reason for this. Causes problem for variable-length
- * string. -SLU (& QAK) */
- /*if (dt->parent) dt = dt->parent;*/ /*defer to parent*/
- if (!(H5T_STRING == dt->type || (H5T_VLEN == dt->type && H5T_VLEN_STRING == dt->u.vlen.type)))
+ while (dt->parent && !H5T_IS_STRING(dt))
+ dt = dt->parent; /*defer to parent*/
+ if (!H5T_IS_STRING(dt))
HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "operation not defined for data type class");
/* Commit */
diff --git a/src/H5Tfixed.c b/src/H5Tfixed.c
index 99bc12b..71c0321 100644
--- a/src/H5Tfixed.c
+++ b/src/H5Tfixed.c
@@ -168,7 +168,7 @@ H5Tset_sign(hid_t type_id, H5T_sign_t sign)
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "illegal sign type");
if (H5T_ENUM==dt->type && dt->u.enumer.nmembs>0)
HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "operation not allowed after members are defined");
- if (dt->parent)
+ while (dt->parent)
dt = dt->parent; /*defer to parent*/
if (H5T_INTEGER!=dt->type)
HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "operation not defined for data type class");
diff --git a/src/H5Tfloat.c b/src/H5Tfloat.c
index 1211d2b..ae520f7 100644
--- a/src/H5Tfloat.c
+++ b/src/H5Tfloat.c
@@ -91,7 +91,7 @@ H5Tget_fields(hid_t type_id, size_t *spos/*out*/,
/* Check args */
if (NULL == (dt = H5I_object_verify(type_id,H5I_DATATYPE)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data type");
- if (dt->parent)
+ while (dt->parent)
dt = dt->parent; /*defer to parent*/
if (H5T_FLOAT != dt->type)
HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "operation not defined for data type class");
@@ -145,7 +145,7 @@ H5Tset_fields(hid_t type_id, size_t spos, size_t epos, size_t esize,
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data type");
if (H5T_STATE_TRANSIENT!=dt->state)
HGOTO_ERROR(H5E_ARGS, H5E_CANTINIT, FAIL, "data type is read-only");
- if (dt->parent)
+ while (dt->parent)
dt = dt->parent; /*defer to parent*/
if (H5T_FLOAT != dt->type)
HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "operation not defined for data type class");
@@ -206,7 +206,7 @@ H5Tget_ebias(hid_t type_id)
/* Check args */
if (NULL == (dt = H5I_object_verify(type_id,H5I_DATATYPE)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, 0, "not a data type");
- if (dt->parent)
+ while (dt->parent)
dt = dt->parent; /*defer to parent*/
if (H5T_FLOAT != dt->type)
HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, 0, "operation not defined for data type class");
@@ -249,7 +249,7 @@ H5Tset_ebias(hid_t type_id, size_t ebias)
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data type");
if (H5T_STATE_TRANSIENT!=dt->state)
HGOTO_ERROR(H5E_ARGS, H5E_CANTINIT, FAIL, "data type is read-only");
- if (dt->parent)
+ while (dt->parent)
dt = dt->parent; /*defer to parent*/
if (H5T_FLOAT != dt->type)
HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "operation not defined for data type class");
@@ -293,7 +293,7 @@ H5Tget_norm(hid_t type_id)
/* Check args */
if (NULL == (dt = H5I_object_verify(type_id,H5I_DATATYPE)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5T_NORM_ERROR, "not a data type");
- if (dt->parent)
+ while (dt->parent)
dt = dt->parent; /*defer to parent*/
if (H5T_FLOAT != dt->type)
HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, H5T_NORM_ERROR, "operation not defined for data type class");
@@ -339,7 +339,7 @@ H5Tset_norm(hid_t type_id, H5T_norm_t norm)
HGOTO_ERROR(H5E_ARGS, H5E_CANTINIT, FAIL, "data type is read-only");
if (norm < 0 || norm > H5T_NORM_NONE)
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "illegal normalization");
- if (dt->parent)
+ while (dt->parent)
dt = dt->parent; /*defer to parent*/
if (H5T_FLOAT != dt->type)
HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "operation not defined for data type class");
@@ -385,7 +385,7 @@ H5Tget_inpad(hid_t type_id)
/* Check args */
if (NULL == (dt = H5I_object_verify(type_id,H5I_DATATYPE)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5T_PAD_ERROR, "not a data type");
- if (dt->parent)
+ while (dt->parent)
dt = dt->parent; /*defer to parent*/
if (H5T_FLOAT != dt->type)
HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, H5T_PAD_ERROR, "operation not defined for data type class");
@@ -433,7 +433,7 @@ H5Tset_inpad(hid_t type_id, H5T_pad_t pad)
HGOTO_ERROR(H5E_ARGS, H5E_CANTINIT, FAIL, "data type is read-only");
if (pad < 0 || pad >= H5T_NPAD)
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "illegal internal pad type");
- if (dt->parent)
+ while (dt->parent)
dt = dt->parent; /*defer to parent*/
if (H5T_FLOAT != dt->type)
HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "operation not defined for data type class");
diff --git a/src/H5Toffset.c b/src/H5Toffset.c
index 72d15fb..bd54e5c 100644
--- a/src/H5Toffset.c
+++ b/src/H5Toffset.c
@@ -103,9 +103,9 @@ H5Tget_offset(hid_t type_id)
/* Check args */
if (NULL == (dt = H5I_object_verify(type_id,H5I_DATATYPE)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not an atomic data type");
- if (dt->parent)
+ while (dt->parent)
dt = dt->parent; /*defer to parent*/
- if (H5T_COMPOUND==dt->type || H5T_OPAQUE==dt->type || H5T_ARRAY==dt->type)
+ if (H5T_COMPOUND==dt->type || H5T_OPAQUE==dt->type)
HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "operation not defined for specified data type");
/* Offset */
@@ -174,6 +174,8 @@ H5Tset_offset(hid_t type_id, size_t offset)
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "offset must be zero for this type");
if (H5T_ENUM==dt->type && dt->u.enumer.nmembs>0)
HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "operation not allowed after members are defined");
+ if (H5T_COMPOUND==dt->type || H5T_REFERENCE==dt->type || H5T_OPAQUE==dt->type)
+ HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "operation not defined for this datatype");
/* Do the real work */
if (H5T_set_offset(dt, offset)<0)
@@ -233,23 +235,24 @@ H5T_set_offset(H5T_t *dt, size_t offset)
/* Check args */
assert(dt);
assert(H5T_STRING!=dt->type || 0==offset);
- assert(H5T_ENUM!=dt->type || 0==dt->u.enumer.nmembs);
+ assert(H5T_REFERENCE!=dt->type);
+ assert(H5T_OPAQUE!=dt->type);
+ assert(H5T_COMPOUND!=dt->type);
+ assert(!(H5T_ENUM==dt->type && 0==dt->u.enumer.nmembs));
if (dt->parent) {
if (H5T_set_offset(dt->parent, offset)<0)
HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to set offset for base type");
- dt->size = dt->parent->size;
+
+ /* Adjust size of datatype appropriately */
+ if(dt->type==H5T_ARRAY)
+ dt->size = dt->parent->size * dt->u.array.nelem;
+ else if(dt->type!=H5T_VLEN)
+ dt->size = dt->parent->size;
} else {
- if (H5T_COMPOUND==dt->type || H5T_OPAQUE==dt->type || H5T_ARRAY==dt->type) {
- HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "operation not defined for specified data type");
- } else if (H5T_ENUM==dt->type) {
- /*nothing*/
- } else {
- if (offset+dt->u.atomic.prec > 8*dt->size) {
- dt->size = (offset + dt->u.atomic.prec + 7) / 8;
- }
- dt->u.atomic.offset = offset;
- }
+ if (offset+dt->u.atomic.prec > 8*dt->size)
+ dt->size = (offset + dt->u.atomic.prec + 7) / 8;
+ dt->u.atomic.offset = offset;
}
done:
diff --git a/src/H5Topaque.c b/src/H5Topaque.c
index 17f4e36..2697178 100644
--- a/src/H5Topaque.c
+++ b/src/H5Topaque.c
@@ -83,6 +83,8 @@ H5Tset_tag(hid_t type_id, const char *tag)
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data type");
if (H5T_STATE_TRANSIENT!=dt->state)
HGOTO_ERROR(H5E_ARGS, H5E_CANTINIT, FAIL, "data type is read-only");
+ while (dt->parent)
+ dt = dt->parent; /*defer to parent*/
if (H5T_OPAQUE!=dt->type)
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not an opaque data type");
if (!tag)
@@ -123,8 +125,7 @@ H5Tget_tag(hid_t type_id)
/* Check args */
if (NULL == (dt = H5I_object_verify(type_id,H5I_DATATYPE)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "not a data type");
-
- if (dt->parent)
+ while (dt->parent)
dt = dt->parent; /*defer to parent*/
if (H5T_OPAQUE != dt->type)
HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, NULL, "operation not defined for data type class");
diff --git a/src/H5Torder.c b/src/H5Torder.c
index 35e9c0d..214466c 100644
--- a/src/H5Torder.c
+++ b/src/H5Torder.c
@@ -84,10 +84,9 @@ H5Tget_order(hid_t type_id)
/* Check args */
if (NULL == (dt = H5I_object_verify(type_id,H5I_DATATYPE)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5T_ORDER_ERROR, "not a data type");
-
- if (dt->parent)
+ while (dt->parent)
dt = dt->parent; /*defer to parent*/
- if (H5T_COMPOUND==dt->type || H5T_OPAQUE==dt->type || H5T_ARRAY ==dt->type)
+ if (H5T_COMPOUND==dt->type || H5T_OPAQUE==dt->type)
HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, H5T_ORDER_ERROR, "operation not defined for specified data type");
/* Order */
@@ -133,9 +132,9 @@ H5Tset_order(hid_t type_id, H5T_order_t order)
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "illegal byte order");
if (H5T_ENUM==dt->type && dt->u.enumer.nmembs>0)
HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "operation not allowed after members are defined");
- if (dt->parent)
+ while (dt->parent)
dt = dt->parent; /*defer to parent*/
- if (H5T_COMPOUND==dt->type || H5T_OPAQUE==dt->type || H5T_ARRAY==dt->type)
+ if (H5T_COMPOUND==dt->type || H5T_OPAQUE==dt->type)
HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, H5T_ORDER_ERROR, "operation not defined for specified data type");
/* Commit */
diff --git a/src/H5Tpad.c b/src/H5Tpad.c
index afceade..532a920 100644
--- a/src/H5Tpad.c
+++ b/src/H5Tpad.c
@@ -84,9 +84,9 @@ H5Tget_pad(hid_t type_id, H5T_pad_t *lsb/*out*/, H5T_pad_t *msb/*out*/)
/* Check args */
if (NULL == (dt = H5I_object_verify(type_id,H5I_DATATYPE)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data type");
- if (dt->parent)
+ while (dt->parent)
dt = dt->parent; /*defer to parent*/
- if (H5T_COMPOUND==dt->type || H5T_OPAQUE==dt->type || H5T_ARRAY==dt->type)
+ if (H5T_COMPOUND==dt->type || H5T_OPAQUE==dt->type)
HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "operation not defined for specified data type");
/* Get values */
@@ -135,9 +135,9 @@ H5Tset_pad(hid_t type_id, H5T_pad_t lsb, H5T_pad_t msb)
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid pad type");
if (H5T_ENUM==dt->type && dt->u.enumer.nmembs>0)
HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "operation not allowed after members are defined");
- if (dt->parent)
+ while (dt->parent)
dt = dt->parent; /*defer to parent*/
- if (H5T_COMPOUND==dt->type || H5T_OPAQUE==dt->type || H5T_ARRAY==dt->type)
+ if (H5T_COMPOUND==dt->type || H5T_OPAQUE==dt->type)
HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "operation not defined for specified data type");
/* Commit */
diff --git a/src/H5Tpkg.h b/src/H5Tpkg.h
index 826bab2..fab832b 100644
--- a/src/H5Tpkg.h
+++ b/src/H5Tpkg.h
@@ -49,6 +49,12 @@
/* Length of debugging name buffer */
#define H5T_NAMELEN 32
+/* Macro to ease detecting "complex" datatypes (i.e. those with base types or fields) */
+#define H5T_IS_COMPLEX(t) ((t)==H5T_COMPOUND || (t)==H5T_ENUM || (t)==H5T_VLEN || (t)==H5T_ARRAY)
+
+/* Macro to ease detecting fixed or variable-length "string" datatypes */
+#define H5T_IS_STRING(dt) (H5T_STRING == (dt)->type || (H5T_VLEN == (dt)->type && H5T_VLEN_STRING == (dt)->u.vlen.type))
+
/* Statistics about a conversion function */
struct H5T_stats_t {
unsigned ncalls; /*num calls to conversion function */
@@ -113,9 +119,6 @@ typedef struct H5T_compnd_t {
int nalloc; /*num entries allocated in MEMB array*/
int nmembs; /*number of members defined in struct*/
H5T_sort_t sorted; /*how are members sorted? */
- hbool_t has_array; /* Set if this type has an array datatype member */
- /* and should be written with the new version of */
- /* the datatype object header message */
struct H5T_cmemb_t *memb; /*array of struct members */
} H5T_compnd_t;
@@ -305,7 +308,7 @@ H5_DLL herr_t H5T_insert(H5T_t *parent, const char *name, size_t offset,
H5_DLL H5T_t *H5T_enum_create(H5T_t *parent);
H5_DLL herr_t H5T_enum_insert(H5T_t *dt, const char *name, void *value);
H5_DLL int H5T_get_array_ndims(H5T_t *dt);
-H5_DLL herr_t H5T_get_array_dims(H5T_t *dt, hsize_t dims[], int perm[]);
+H5_DLL int H5T_get_array_dims(H5T_t *dt, hsize_t dims[], int perm[]);
H5_DLL herr_t H5T_sort_value(H5T_t *dt, int *map);
H5_DLL herr_t H5T_sort_name(H5T_t *dt, int *map);
H5_DLL herr_t H5T_set_size(H5T_t *dt, size_t size);
diff --git a/src/H5Tprecis.c b/src/H5Tprecis.c
index a692069..9f7f471 100644
--- a/src/H5Tprecis.c
+++ b/src/H5Tprecis.c
@@ -91,9 +91,9 @@ H5Tget_precision(hid_t type_id)
/* Check args */
if (NULL == (dt = H5I_object_verify(type_id,H5I_DATATYPE)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, 0, "not a data type");
- if (dt->parent)
+ while (dt->parent)
dt = dt->parent; /*defer to parent*/
- if (H5T_COMPOUND==dt->type || H5T_OPAQUE==dt->type || H5T_ARRAY==dt->type)
+ if (H5T_COMPOUND==dt->type || H5T_OPAQUE==dt->type)
HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, 0, "operation not defined for specified data type");
/* Precision */
@@ -152,6 +152,10 @@ H5Tset_precision(hid_t type_id, size_t prec)
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "precision must be positive");
if (H5T_ENUM==dt->type && dt->u.enumer.nmembs>0)
HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "operation not allowed after members are defined");
+ if (H5T_STRING==dt->type)
+ HGOTO_ERROR(H5E_ARGS, H5E_UNSUPPORTED, FAIL, "precision for this type is read-only");
+ if (H5T_COMPOUND==dt->type || H5T_OPAQUE==dt->type)
+ HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "operation not defined for specified data type");
/* Do the work */
if (H5T_set_precision(dt, prec)<0)
@@ -202,53 +206,55 @@ H5T_set_precision(H5T_t *dt, size_t prec)
/* Check args */
assert(dt);
assert(prec>0);
- assert(H5T_ENUM!=dt->type || 0==dt->u.enumer.nmembs);
+ assert(H5T_OPAQUE!=dt->type);
+ assert(H5T_COMPOUND!=dt->type);
+ assert(H5T_STRING!=dt->type);
+ assert(!(H5T_ENUM==dt->type && 0==dt->u.enumer.nmembs));
if (dt->parent) {
if (H5T_set_precision(dt->parent, prec)<0)
HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to set precision for base type");
- dt->size = dt->parent->size;
+
+ /* Adjust size of datatype appropriately */
+ if(dt->type==H5T_ARRAY)
+ dt->size = dt->parent->size * dt->u.array.nelem;
+ else if(dt->type!=H5T_VLEN)
+ dt->size = dt->parent->size;
} else {
- if (H5T_COMPOUND==dt->type || H5T_OPAQUE==dt->type || H5T_ARRAY==dt->type) {
- HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "operation not defined for specified data type");
- } else if (H5T_ENUM==dt->type) {
- /*nothing*/
- } else if (H5T_is_atomic(dt)) {
+ if (H5T_is_atomic(dt)) {
/* Adjust the offset and size */
offset = dt->u.atomic.offset;
size = dt->size;
if (prec > 8*size)
offset = 0;
- else if (offset+prec > 8 * size) offset = 8 * size - prec;
+ else if (offset+prec > 8 * size)
+ offset = 8 * size - prec;
if (prec > 8*size)
size = (prec+7) / 8;
/* Check that things are still kosher */
switch (dt->type) {
- case H5T_INTEGER:
- case H5T_TIME:
- case H5T_BITFIELD:
- /* nothing to check */
- break;
-
- case H5T_STRING:
- HGOTO_ERROR(H5E_ARGS, H5E_UNSUPPORTED, FAIL, "precision for this type is read-only");
+ case H5T_INTEGER:
+ case H5T_TIME:
+ case H5T_BITFIELD:
+ /* nothing to check */
+ break;
- case H5T_FLOAT:
- /*
- * The sign, mantissa, and exponent fields should be adjusted
- * first when decreasing the precision of a floating point
- * type.
- */
- if (dt->u.atomic.u.f.sign >= prec ||
- dt->u.atomic.u.f.epos + dt->u.atomic.u.f.esize > prec ||
- dt->u.atomic.u.f.mpos + dt->u.atomic.u.f.msize > prec) {
- HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "adjust sign, mantissa, and exponent fields first");
- }
- break;
+ case H5T_FLOAT:
+ /*
+ * The sign, mantissa, and exponent fields should be adjusted
+ * first when decreasing the precision of a floating point
+ * type.
+ */
+ if (dt->u.atomic.u.f.sign >= prec ||
+ dt->u.atomic.u.f.epos + dt->u.atomic.u.f.esize > prec ||
+ dt->u.atomic.u.f.mpos + dt->u.atomic.u.f.msize > prec) {
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "adjust sign, mantissa, and exponent fields first");
+ }
+ break;
- default:
- assert("not implemented yet" && 0);
+ default:
+ assert("not implemented yet" && 0);
}
/* Commit */
@@ -258,6 +264,8 @@ H5T_set_precision(H5T_t *dt, size_t prec)
dt->u.atomic.prec = prec;
}
}
+ else
+ HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "operation not defined for specified datatype");
}
done:
diff --git a/src/H5Tpublic.h b/src/H5Tpublic.h
index b9902d1..6842b63 100644
--- a/src/H5Tpublic.h
+++ b/src/H5Tpublic.h
@@ -498,7 +498,7 @@ H5_DLL hid_t H5Tvlen_create(hid_t base_id);
H5_DLL hid_t H5Tarray_create(hid_t base_id, int ndims,
const hsize_t dim[/* ndims */], const int perm[/* ndims */]);
H5_DLL int H5Tget_array_ndims(hid_t type_id);
-H5_DLL herr_t H5Tget_array_dims(hid_t type_id, hsize_t dims[], int perm[]);
+H5_DLL int H5Tget_array_dims(hid_t type_id, hsize_t dims[], int perm[]);
/* Operations defined on opaque data types */
H5_DLL herr_t H5Tset_tag(hid_t type, const char *tag);
diff --git a/src/H5Tstrpad.c b/src/H5Tstrpad.c
index 27936e7..c9e23f4 100644
--- a/src/H5Tstrpad.c
+++ b/src/H5Tstrpad.c
@@ -62,7 +62,7 @@ H5T_init_strpad_interface(void)
* Fortran left-justifies and space-pads strings. This property
* defines the storage mechanism for the string.
*
- * Return: Success: The character set of an H5T_STRING type.
+ * Return: Success: The character set of a string type.
*
* Failure: H5T_STR_ERROR (Negative)
*
@@ -87,10 +87,9 @@ H5Tget_strpad(hid_t type_id)
/* Check args */
if (NULL == (dt = H5I_object_verify(type_id,H5I_DATATYPE)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5T_STR_ERROR, "not a data type");
- /* Don't see any reason for this. Causes problem for variable-length
- * string. -SLU (& QAK) */
- /* if (dt->parent) dt = dt->parent;*/ /*defer to parent*/
- if (!(H5T_STRING == dt->type || (H5T_VLEN == dt->type && H5T_VLEN_STRING == dt->u.vlen.type)))
+ while (dt->parent && !H5T_IS_STRING(dt))
+ dt = dt->parent; /*defer to parent*/
+ if (!H5T_IS_STRING(dt))
HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, H5T_STR_ERROR, "operation not defined for data type class");
/* result */
@@ -151,10 +150,9 @@ H5Tset_strpad(hid_t type_id, H5T_str_t strpad)
HGOTO_ERROR(H5E_ARGS, H5E_CANTINIT, FAIL, "data type is read-only");
if (strpad < 0 || strpad >= H5T_NSTR)
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "illegal string pad type");
- /* Don't see any reason for this. Causes problem for variable-length
- * string. -SLU (& QAK) */
- /* if (dt->parent) dt = dt->parent;*/ /*defer to parent*/
- if (!(H5T_STRING == dt->type || (H5T_VLEN == dt->type && H5T_VLEN_STRING == dt->u.vlen.type)))
+ while (dt->parent && !H5T_IS_STRING(dt))
+ dt = dt->parent; /*defer to parent*/
+ if (!H5T_IS_STRING(dt))
HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "operation not defined for data type class");
/* Commit */
diff --git a/src/H5Tvlen.c b/src/H5Tvlen.c
index 1c0082b..5cc738a 100644
--- a/src/H5Tvlen.c
+++ b/src/H5Tvlen.c
@@ -727,8 +727,8 @@ H5T_vlen_reclaim_recurse(void *elem, const H5T_t *dt, H5MM_free_t free_func, voi
/* Check the datatype of this element */
switch(dt->type) {
case H5T_ARRAY:
- /* Recurse on each element, if the array's base type is array, VL or compound */
- if(dt->parent->type==H5T_COMPOUND || dt->parent->type==H5T_VLEN || dt->parent->type==H5T_ARRAY) {
+ /* Recurse on each element, if the array's base type is array, VL, enum or compound */
+ if(H5T_IS_COMPLEX(dt->parent->type)) {
void *off; /* offset of field */
/* Calculate the offset member and recurse on it */
@@ -741,10 +741,10 @@ H5T_vlen_reclaim_recurse(void *elem, const H5T_t *dt, H5MM_free_t free_func, voi
break;
case H5T_COMPOUND:
- /* Check each field and recurse on VL, compound or array ones */
+ /* Check each field and recurse on VL, compound, enum or array ones */
for (i=0; i<dt->u.compnd.nmembs; i++) {
- /* Recurse if it's VL, compound or array */
- if(dt->u.compnd.memb[i].type->type==H5T_COMPOUND || dt->u.compnd.memb[i].type->type==H5T_VLEN || dt->u.compnd.memb[i].type->type==H5T_ARRAY) {
+ /* Recurse if it's VL, compound, enum or array */
+ if(H5T_IS_COMPLEX(dt->u.compnd.memb[i].type->type)) {
void *off; /* offset of field */
/* Calculate the offset member and recurse on it */
@@ -756,14 +756,14 @@ H5T_vlen_reclaim_recurse(void *elem, const H5T_t *dt, H5MM_free_t free_func, voi
break;
case H5T_VLEN:
- /* Recurse on the VL information if it's VL, compound or array, then free VL sequence */
+ /* Recurse on the VL information if it's VL, compound, enum or array, then free VL sequence */
if(dt->u.vlen.type==H5T_VLEN_SEQUENCE) {
hvl_t *vl=(hvl_t *)elem; /* Temp. ptr to the vl info */
/* Check if there is anything actually in this sequence */
if(vl->len!=0) {
- /* Recurse if it's VL or compound */
- if(dt->parent->type==H5T_COMPOUND || dt->parent->type==H5T_VLEN || dt->parent->type==H5T_ARRAY) {
+ /* Recurse if it's VL, array, enum or compound */
+ if(H5T_IS_COMPLEX(dt->parent->type)) {
void *off; /* offset of field */
/* Calculate the offset of each array element and recurse on it */
diff --git a/test/dtypes.c b/test/dtypes.c
index f312909..fe954d8 100644
--- a/test/dtypes.c
+++ b/test/dtypes.c
@@ -383,6 +383,137 @@ test_copy(void)
/*-------------------------------------------------------------------------
+ * Function: test_detect
+ *
+ * Purpose: Are we able to detect datatype classes correctly? (Especially
+ * in nested types)
+ *
+ * Return: Success: 0
+ *
+ * Failure: number of errors
+ *
+ * Programmer: Quincey Koziol
+ * Saturday, August 30, 2003
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static int
+test_detect(void)
+{
+ struct atomic { /* Struct with atomic fields */
+ int i;
+ float f;
+ char c;
+ double d;
+ short s;
+ };
+ struct complex { /* Struct with complex fields */
+ hobj_ref_t arr_r[3][3];
+ int i;
+ hvl_t vl_f;
+ char c;
+ short s;
+ };
+ hid_t atom_cmpd_id; /* Atomic Compound datatype */
+ hid_t atom_arr_id; /* Atomic Array datatype */
+ hid_t atom_vl_id; /* Atomic VL datatype */
+ hid_t cplx_cmpd_id; /* Complex Compound datatype */
+ int rank=2; /* Rank for array datatype */
+ hsize_t dims[2]={3,3}; /* Dimensions for array datatype */
+
+ TESTING("H5Tdetect_class()");
+
+ /* Native integers should be in the integer class */
+ if(H5Tdetect_class(H5T_NATIVE_INT,H5T_INTEGER)!=TRUE) TEST_ERROR
+
+ /* Native integers should _not_ be in other classes */
+ if(H5Tdetect_class(H5T_NATIVE_INT,H5T_FLOAT)!=FALSE) TEST_ERROR
+ if(H5Tdetect_class(H5T_NATIVE_INT,H5T_ARRAY)!=FALSE) TEST_ERROR
+ if(H5Tdetect_class(H5T_NATIVE_INT,H5T_ENUM)!=FALSE) TEST_ERROR
+
+ /* Create a compound datatype and insert some atomic types */
+ if ((atom_cmpd_id = H5Tcreate(H5T_COMPOUND, sizeof(struct atomic)))<0) TEST_ERROR
+ if (H5Tinsert(atom_cmpd_id, "i", HOFFSET(struct atomic, i), H5T_NATIVE_INT)<0) TEST_ERROR
+ if (H5Tinsert(atom_cmpd_id, "f", HOFFSET(struct atomic, f), H5T_NATIVE_FLOAT)<0) TEST_ERROR
+ if (H5Tinsert(atom_cmpd_id, "c", HOFFSET(struct atomic, c), H5T_NATIVE_CHAR)<0) TEST_ERROR
+ if (H5Tinsert(atom_cmpd_id, "d", HOFFSET(struct atomic, d), H5T_NATIVE_DOUBLE)<0) TEST_ERROR
+ if (H5Tinsert(atom_cmpd_id, "s", HOFFSET(struct atomic, s), H5T_NATIVE_SHORT)<0) TEST_ERROR
+
+ /* Make certain that the correct classes can be detected */
+ if(H5Tdetect_class(atom_cmpd_id,H5T_COMPOUND)!=TRUE) TEST_ERROR
+ if(H5Tdetect_class(atom_cmpd_id,H5T_INTEGER)!=TRUE) TEST_ERROR
+ if(H5Tdetect_class(atom_cmpd_id,H5T_FLOAT)!=TRUE) TEST_ERROR
+
+ /* Make certain that an incorrect class is not detected */
+ if(H5Tdetect_class(atom_cmpd_id,H5T_VLEN)!=FALSE) TEST_ERROR
+
+ /* Create an array datatype with an atomic base type */
+ if((atom_arr_id=H5Tarray_create(H5T_STD_REF_OBJ, rank, dims, NULL))<0) TEST_ERROR
+
+ /* Make certain that the correct classes can be detected */
+ if(H5Tdetect_class(atom_arr_id,H5T_ARRAY)!=TRUE) TEST_ERROR
+ if(H5Tdetect_class(atom_arr_id,H5T_REFERENCE)!=TRUE) TEST_ERROR
+
+ /* Make certain that an incorrect class is not detected */
+ if(H5Tdetect_class(atom_arr_id,H5T_VLEN)!=FALSE) TEST_ERROR
+ if(H5Tdetect_class(atom_arr_id,H5T_FLOAT)!=FALSE) TEST_ERROR
+ if(H5Tdetect_class(atom_arr_id,H5T_INTEGER)!=FALSE) TEST_ERROR
+
+ /* Create a VL datatype with an atomic base type */
+ if((atom_vl_id=H5Tvlen_create(H5T_NATIVE_FLOAT))<0) TEST_ERROR
+
+ /* Make certain that the correct classes can be detected */
+ if(H5Tdetect_class(atom_vl_id,H5T_VLEN)!=TRUE) TEST_ERROR
+ if(H5Tdetect_class(atom_vl_id,H5T_FLOAT)!=TRUE) TEST_ERROR
+
+ /* Make certain that an incorrect class is not detected */
+ if(H5Tdetect_class(atom_vl_id,H5T_COMPOUND)!=FALSE) TEST_ERROR
+ if(H5Tdetect_class(atom_vl_id,H5T_INTEGER)!=FALSE) TEST_ERROR
+
+ /* Create a compound datatype and insert some atomic types */
+ if ((cplx_cmpd_id = H5Tcreate(H5T_COMPOUND, sizeof(struct complex)))<0) TEST_ERROR
+ if (H5Tinsert(cplx_cmpd_id, "arr_r", HOFFSET(struct complex, arr_r), atom_arr_id)<0) TEST_ERROR
+ if (H5Tinsert(cplx_cmpd_id, "i", HOFFSET(struct complex, i), H5T_NATIVE_INT)<0) TEST_ERROR
+ if (H5Tinsert(cplx_cmpd_id, "vl_f", HOFFSET(struct complex, vl_f), atom_vl_id)<0) TEST_ERROR
+ if (H5Tinsert(cplx_cmpd_id, "c", HOFFSET(struct complex, c), H5T_NATIVE_CHAR)<0) TEST_ERROR
+ if (H5Tinsert(cplx_cmpd_id, "s", HOFFSET(struct complex, s), H5T_NATIVE_SHORT)<0) TEST_ERROR
+
+ /* Make certain that the correct classes can be detected */
+ if(H5Tdetect_class(cplx_cmpd_id,H5T_COMPOUND)!=TRUE) TEST_ERROR
+ if(H5Tdetect_class(cplx_cmpd_id,H5T_ARRAY)!=TRUE) TEST_ERROR
+ if(H5Tdetect_class(cplx_cmpd_id,H5T_REFERENCE)!=TRUE) TEST_ERROR
+ if(H5Tdetect_class(cplx_cmpd_id,H5T_INTEGER)!=TRUE) TEST_ERROR
+ if(H5Tdetect_class(cplx_cmpd_id,H5T_FLOAT)!=TRUE) TEST_ERROR
+ if(H5Tdetect_class(cplx_cmpd_id,H5T_VLEN)!=TRUE) TEST_ERROR
+
+ /* Make certain that an incorrect class is not detected */
+ if(H5Tdetect_class(cplx_cmpd_id,H5T_TIME)!=FALSE) TEST_ERROR
+ if(H5Tdetect_class(cplx_cmpd_id,H5T_ENUM)!=FALSE) TEST_ERROR
+ if(H5Tdetect_class(cplx_cmpd_id,H5T_STRING)!=FALSE) TEST_ERROR
+
+ /* Close complex compound datatype */
+ if(H5Tclose(cplx_cmpd_id)<0) TEST_ERROR
+
+ /* Close atomic VL datatype */
+ if(H5Tclose(atom_vl_id)<0) TEST_ERROR
+
+ /* Close atomic array datatype */
+ if(H5Tclose(atom_arr_id)<0) TEST_ERROR
+
+ /* Close atomic compound datatype */
+ if(H5Tclose(atom_cmpd_id)<0) TEST_ERROR
+
+ PASSED();
+ return 0;
+
+error:
+ return 1;
+}
+
+
+/*-------------------------------------------------------------------------
* Function: test_compound_1
*
* Purpose: Tests various things about compound data types.
@@ -4216,6 +4347,7 @@ main(void)
/* Do the tests */
nerrors += test_classes();
nerrors += test_copy();
+ nerrors += test_detect();
nerrors += test_compound_1();
nerrors += test_query();
nerrors += test_transient (fapl);