From f92d7f73df1846f4489fb6e2c2dd857b636b4deb Mon Sep 17 00:00:00 2001 From: Quincey Koziol Date: Sat, 30 Aug 2003 20:48:01 -0500 Subject: [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 --- doc/html/H5.intro.html | 2 +- doc/html/RM_H5T.html | 6 +-- release_docs/RELEASE.txt | 5 ++ src/H5Odtype.c | 13 ++--- src/H5T.c | 65 +++++++++++++---------- src/H5Tarray.c | 22 ++++---- src/H5Tcompound.c | 9 +--- src/H5Tcset.c | 16 +++--- src/H5Tfixed.c | 2 +- src/H5Tfloat.c | 16 +++--- src/H5Toffset.c | 31 ++++++----- src/H5Topaque.c | 5 +- src/H5Torder.c | 9 ++-- src/H5Tpad.c | 8 +-- src/H5Tpkg.h | 11 ++-- src/H5Tprecis.c | 72 ++++++++++++++------------ src/H5Tpublic.h | 2 +- src/H5Tstrpad.c | 16 +++--- src/H5Tvlen.c | 16 +++--- test/dtypes.c | 132 +++++++++++++++++++++++++++++++++++++++++++++++ 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. (Note: The permutation feature is not implemented in Release 1.4.) - herr_t H5Tget_array_dims( + int H5Tget_array_dims( hid_t adtype_id, hsize_t *dims[], int *perm[] 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.
Name: H5Tget_array_dims
Signature: -
herr_t H5Tget_array_dims( +
int H5Tget_array_dims( hid_t adtype_id, hsize_t *dims[], int *perm[] )
Purpose: -
Returns sizes of array dimensions and dimension permutations. +
Retrieves sizes of array dimensions and dimension permutations.
Description:
H5Tget_array_dims returns the sizes of the dimensions and the dimension permutations of the specified array datatype object. @@ -2970,7 +2970,7 @@ zero.
OUT: Dimension permutations.
Returns: -
Returns a non-negative value if successful; +
Returns the non-negative number of dimensions of the array type if successful; otherwise returns a negative value.
Non-C API(s):
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; iu.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; iu.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; iu.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); -- cgit v0.12