From 1063eb8a1ea0cbdbdc4244f0627b94b3096d65ab Mon Sep 17 00:00:00 2001 From: Robb Matzke Date: Fri, 9 Jan 1998 12:49:23 -0500 Subject: [svn-r152] Changes since 19980107 ---------------------- ./html/Datatypes.html Updated to match code. ./src/H5Odtype.c ./src/H5Oprivate.h ./src/H5Tpkg.h ./src/H5detect.c Changed H5T_FIXED to H5T_INTEGER. ./src/H5T.c ./src/H5Tprivate.h ./src/H5Tpublic.h ./test/dtypes.c Implemented lots of type properties. ./src/H5detect.c ./src/H5Tpublic.h It is no longer necessary to call H5init() before using a predefined data type. --- src/H5Odtype.c | 18 +- src/H5Oprivate.h | 4 - src/H5T.c | 1486 ++++++++++++++++++++++++++++++++++++++++++++++++++++-- src/H5Tpkg.h | 4 +- src/H5Tprivate.h | 10 +- src/H5Tpublic.h | 93 +++- src/H5detect.c | 12 +- test/dtypes.c | 87 +++- 8 files changed, 1614 insertions(+), 100 deletions(-) diff --git a/src/H5Odtype.c b/src/H5Odtype.c index be401c1..2d830e9 100644 --- a/src/H5Odtype.c +++ b/src/H5Odtype.c @@ -90,9 +90,9 @@ H5O_dtype_decode_helper (const uint8 **pp, H5T_t *dt) UINT32DECODE (*pp, dt->size); switch (dt->type) { - case H5T_FIXED: + case H5T_INTEGER: /* - * Fixed-point types... + * Integer types... */ dt->u.atomic.order = (flags & 0x1) ? H5T_ORDER_BE : H5T_ORDER_LE; dt->u.atomic.lo_pad = (flags & 0x2) ? H5T_PAD_ONE : H5T_PAD_ZERO; @@ -217,9 +217,9 @@ H5O_dtype_encode_helper (uint8 **pp, const H5T_t *dt) UINT32ENCODE (*pp, dt->size); switch (dt->type) { - case H5T_FIXED: + case H5T_INTEGER: /* - * Fixed-point data types... + * Integer data types... */ switch (dt->u.atomic.order) { case H5T_ORDER_LE: @@ -538,7 +538,7 @@ H5O_dtype_size (H5F_t *f, const void *mesg) assert (mesg); switch (dt->type) { - case H5T_FIXED: + case H5T_INTEGER: ret_value += 4; break; @@ -637,13 +637,13 @@ H5O_dtype_debug (H5F_t *f, const void *mesg, FILE *stream, assert (fwidth>=0); switch (dt->type) { - case H5T_FIXED: - s = "fixed-point"; + case H5T_INTEGER: + s = "integer"; break; case H5T_FLOAT: s = "floating-point"; break; - case H5T_DATE: + case H5T_TIME: s = "date and time"; break; case H5T_STRING: @@ -838,7 +838,7 @@ H5O_dtype_debug (H5F_t *f, const void *mesg, FILE *stream, "Mantissa size:", (unsigned long)(dt->u.atomic.u.f.msize)); - } else if (H5T_FIXED==dt->type) { + } else if (H5T_INTEGER==dt->type) { switch (dt->u.atomic.u.i.sign) { case H5T_SGN_NONE: s = "none"; diff --git a/src/H5Oprivate.h b/src/H5Oprivate.h index 108fb30..fade4b4 100644 --- a/src/H5Oprivate.h +++ b/src/H5Oprivate.h @@ -52,10 +52,6 @@ typedef struct H5O_class_t { size_t native_size; /*size of native message */ void *(*decode)(H5F_t*,size_t,const uint8*); herr_t (*encode)(H5F_t*,size_t,uint8*,const void*); -#if 0 - void *(*fast)(const H5G_cache_t*, void*);/*get from of entry */ - hbool_t (*cache)(H5G_type_t*, H5G_cache_t*,const void*); /*into entry*/ -#endif void *(*copy)(const void*,void*); /*copy native value */ size_t (*raw_size)(H5F_t*,const void*); /*sizeof raw val */ herr_t (*reset)(void*); /*free nested data structures */ diff --git a/src/H5T.c b/src/H5T.c index 414349a..5863a24 100644 --- a/src/H5T.c +++ b/src/H5T.c @@ -272,6 +272,909 @@ H5Tequal (hid_t type1_id, hid_t type2_id) /*------------------------------------------------------------------------- + * Function: H5Tget_class + * + * Purpose: Returns the data type class identifier for data type TYPE_ID. + * + * Return: Success: One of the non-negative data type class + * constants. + * + * Failure: H5T_NO_CLASS (-1, same as FAIL) + * + * Programmer: Robb Matzke + * Monday, December 8, 1997 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +H5T_class_t +H5Tget_class (hid_t type_id) +{ + H5T_t *dt = NULL; + + FUNC_ENTER (H5Tget_class, H5T_NO_CLASS); + H5ECLEAR; + + /* Check args */ + if (H5_DATATYPE!=H5Aatom_group (type_id) || + NULL==(dt=H5Aatom_object (type_id))) { + HRETURN_ERROR (H5E_ARGS, H5E_BADTYPE, H5T_NO_CLASS, "not a data type"); + } + + FUNC_LEAVE (dt->type); +} + + +/*------------------------------------------------------------------------- + * Function: H5Tget_size + * + * Purpose: Determines the total size of a data type in bytes. + * + * Return: Success: Size of the data type in bytes. The size of + * data type is the size of an instance of that + * data type. + * + * Failure: 0 (valid data types are never zero size) + * + * Programmer: Robb Matzke + * Monday, December 8, 1997 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +size_t +H5Tget_size (hid_t type_id) +{ + H5T_t *dt = NULL; + size_t size; + + FUNC_ENTER (H5Tget_size, 0); + H5ECLEAR; + + /* Check args */ + if (H5_DATATYPE!=H5Aatom_group (type_id) || + NULL==(dt=H5Aatom_object (type_id))) { + HRETURN_ERROR (H5E_ARGS, H5E_BADTYPE, 0, "not a data type"); + } + + /* size */ + size = H5T_get_size (dt); + + FUNC_LEAVE (size); +} + + +/*------------------------------------------------------------------------- + * Function: H5Tset_size + * + * Purpose: Sets the total size in bytes for an atomic data type (this + * operation is not permitted on compound 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 zero and the significant bits of the data type still + * hang over the edge of the new size, then the number of + * significant bits is decreased. + * + * All data types have a positive size. + * + * Return: Success: SUCCEED + * + * Failure: FAIL + * + * Programmer: Robb Matzke + * Wednesday, January 7, 1998 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +herr_t +H5Tset_size (hid_t type_id, size_t size) +{ + H5T_t *dt = NULL; + size_t prec, offset; + + FUNC_ENTER (H5Tset_size, FAIL); + H5ECLEAR; + + /* Check args */ + if (H5_DATATYPE!=H5Aatom_group (type_id) || + NULL==(dt=H5Aatom_object (type_id)) || + !H5T_is_atomic (dt)) { + HRETURN_ERROR (H5E_ARGS, H5E_BADTYPE, FAIL, "not an atomic data type"); + } + if (dt->locked) { + HRETURN_ERROR (H5E_ARGS, H5E_CANTINIT, FAIL, "data type is read-only"); + } + if (size<=0) { + HRETURN_ERROR (H5E_ARGS, H5E_BADVALUE, FAIL, "size must be positive"); + } + + offset = dt->u.atomic.offset; + prec = dt->u.atomic.prec; + + /* Decrement the offset and precision if necessary */ + if (prec > 8*size) offset = 0; + else if (offset + prec > 8*size) offset = 8*size - prec; + if (prec > 8*size) prec = 8*size; + + /* Make sure that other values are still okay */ + switch (dt->type) { + case H5T_INTEGER: + case H5T_TIME: + case H5T_STRING: + case H5T_BITFIELD: + /* nothing to check */ + break; + + case H5T_FLOAT: + /* + * The sign, mantissa, and exponent fields should be adjusted first + * when decreasing the size 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) { + HRETURN_ERROR (H5E_ARGS, H5E_BADVALUE, FAIL, + "adjust sign, mantissa, and exponent fields first"); + } + break; + + case H5T_OPAQUE: + /* + * The significant bits of an opaque type are not allowed to change + * implicitly. + */ + if (prec != dt->u.atomic.prec) { + HRETURN_ERROR (H5E_ARGS, H5E_BADVALUE, FAIL, + "unable to change precision of an opaque type"); + } + break; + + default: + assert ("not implemented yet" && 0); + } + + /* Commit */ + dt->size = size; + dt->u.atomic.offset = offset; + dt->u.atomic.prec = prec; + + FUNC_LEAVE (SUCCEED); +} + + +/*------------------------------------------------------------------------- + * Function: H5Tget_order + * + * Purpose: Returns the byte order of an atomic data type. + * + * Return: Success: A byte order constant + * + * Failure: H5T_ORDER_ERROR (-1, same as FAIL) + * + * Programmer: Robb Matzke + * Wednesday, January 7, 1998 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +H5T_order_t +H5Tget_order (hid_t type_id) +{ + H5T_t *dt = NULL; + H5T_order_t order; + + FUNC_ENTER (H5Tget_order, H5T_ORDER_ERROR); + H5ECLEAR; + + /* Check args */ + if (H5_DATATYPE!=H5Aatom_group (type_id) || + NULL==(dt=H5Aatom_object (type_id)) || + !H5T_is_atomic (dt)) { + HRETURN_ERROR (H5E_ARGS, H5E_BADTYPE, H5T_ORDER_ERROR, + "not an atomic data type"); + } + + /* order */ + order = dt->u.atomic.order; + + FUNC_LEAVE (order); +} + + +/*------------------------------------------------------------------------- + * Function: H5Tset_order + * + * Purpose: Sets the byte order for an atomic data type. + * + * Return: Success: SUCCEED + * + * Failure: FAIL + * + * Programmer: Robb Matzke + * Wednesday, January 7, 1998 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +herr_t +H5Tset_order (hid_t type_id, H5T_order_t order) +{ + H5T_t *dt = NULL; + + FUNC_ENTER (H5Tset_order, FAIL); + H5ECLEAR; + + /* Check args */ + if (H5_DATATYPE!=H5Aatom_group (type_id) || + NULL==(dt=H5Aatom_object (type_id)) || + !H5T_is_atomic (dt)) { + HRETURN_ERROR (H5E_ARGS, H5E_BADTYPE, FAIL, "not an atomic data type"); + } + if (dt->locked) { + HRETURN_ERROR (H5E_ARGS, H5E_CANTINIT, FAIL, "data type is read-only"); + } + if (order<0 || order>H5T_ORDER_NONE) { + HRETURN_ERROR (H5E_ARGS, H5E_BADVALUE, FAIL, "illegal byte order"); + } + + /* order */ + dt->u.atomic.order = order; + FUNC_LEAVE (SUCCEED); +} + + +/*------------------------------------------------------------------------- + * Function: H5Tget_precision + * + * Purpose: Gets the precision of an atomic data type. The precision is + * the number of significant bits which, unless padding is + * present, is 8 times larger than the value returned by + * H5Tget_size(). + * + * Return: Success: Number of significant bits + * + * Failure: 0 (all atomic types have at least one + * significant bit) + * + * Programmer: Robb Matzke + * Wednesday, January 7, 1998 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +size_t +H5Tget_precision (hid_t type_id) +{ + H5T_t *dt = NULL; + size_t prec; + + FUNC_ENTER (H5Tget_precision, 0); + H5ECLEAR; + + /* Check args */ + if (H5_DATATYPE!=H5Aatom_group (type_id) || + NULL==(dt=H5Aatom_object (type_id)) || + !H5T_is_atomic (dt)) { + HRETURN_ERROR (H5E_ARGS, H5E_BADTYPE, 0, "not an atomic data type"); + } + + /* precision */ + prec = dt->u.atomic.prec; + + FUNC_LEAVE (prec); +} + + +/*------------------------------------------------------------------------- + * Function: H5Tset_precision + * + * Purpose: Sets the precision of an atomic data type. The precision is + * the number of significant bits which, unless padding is + * present, is 8 times larger than the value returned by + * H5Tget_size(). + * + * If the precision is increased then the offset is decreased + * and then the size is increased to insure that significant + * bits do not "hang over" the edge of the data type. + * + * When decreasing the precision of a floating point type, set + * the locations and sizes of the sign, mantissa, and exponent + * fields first. + * + * Return: Success: SUCCEED + * + * Failure: FAIL + * + * Programmer: Robb Matzke + * Wednesday, January 7, 1998 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +herr_t +H5Tset_precision (hid_t type_id, size_t prec) +{ + H5T_t *dt = NULL; + size_t offset, size; + + FUNC_ENTER (H5Tset_prec, FAIL); + H5ECLEAR; + + /* Check args */ + if (H5_DATATYPE!=H5Aatom_group (type_id) || + NULL==(dt=H5Aatom_object (type_id)) || + !H5T_is_atomic (dt)) { + HRETURN_ERROR (H5E_ARGS, H5E_BADTYPE, FAIL, "not an atomic data type"); + } + if (dt->locked) { + HRETURN_ERROR (H5E_ARGS, H5E_CANTINIT, FAIL, "data type is read-only"); + } + if (prec<=0) { + HRETURN_ERROR (H5E_ARGS, H5E_BADVALUE, FAIL, + "precision must be positive"); + } + + /* 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; + 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_STRING: + case H5T_BITFIELD: + case H5T_OPAQUE: + /* 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) { + HRETURN_ERROR (H5E_ARGS, H5E_BADVALUE, FAIL, + "adjust sign, mantissa, and exponent fields first"); + } + break; + + default: + assert ("not implemented yet" && 0); + } + + /* Commit */ + dt->size = size; + dt->u.atomic.offset = offset; + dt->u.atomic.prec = prec; + + FUNC_LEAVE (SUCCEED); +} + + +/*------------------------------------------------------------------------- + * Function: H5Tget_offset + * + * Purpose: Retrieves the bit offset of the first significant bit. The + * signficant bits of an atomic datum can be offset from the + * beginning of the memory for that datum by an amount of + * padding. The `offset' property specifies the number of bits + * of padding that appear to the "right of" the value. That is, + * if we have a 32-bit datum with 16-bits of precision having + * the value 0x1122 then it will be layed out in memory as (from + * small byte address toward larger byte addresses): + * + * Big Big Little Little + * Endian Endian Endian Endian + * offset=0 offset=16 offset=0 offset=16 + * + * 0: [ pad] [0x11] [0x22] [ pad] + * 1: [ pad] [0x22] [0x11] [ pad] + * 2: [0x11] [ pad] [ pad] [0x22] + * 3: [0x22] [ pad] [ pad] [0x11] + * + * Return: Success: The offset + * + * Failure: 0 + * + * Programmer: Robb Matzke + * Wednesday, January 7, 1998 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +size_t +H5Tget_offset (hid_t type_id) +{ + H5T_t *dt = NULL; + size_t offset; + + FUNC_ENTER (H5Tget_offset, 0); + H5ECLEAR; + + /* Check args */ + if (H5_DATATYPE!=H5Aatom_group (type_id) || + NULL==(dt=H5Aatom_object (type_id)) || + !H5T_is_atomic (dt)) { + HRETURN_ERROR (H5E_ARGS, H5E_BADTYPE, 0, "not an atomic data type"); + } + + /* offset */ + offset = dt->u.atomic.offset; + + FUNC_LEAVE (offset); +} + + +/*------------------------------------------------------------------------- + * Function: H5Tset_offset + * + * Purpose: Sets the bit offset of the first significant bit. The + * signficant bits of an atomic datum can be offset from the + * beginning of the memory for that datum by an amount of + * padding. The `offset' property specifies the number of bits + * of padding that appear to the "right of" the value. That is, + * if we have a 32-bit datum with 16-bits of precision having + * the value 0x1122 then it will be layed out in memory as (from + * small byte address toward larger byte addresses): + * + * Big Big Little Little + * Endian Endian Endian Endian + * offset=0 offset=16 offset=0 offset=16 + * + * 0: [ pad] [0x11] [0x22] [ pad] + * 1: [ pad] [0x22] [0x11] [ pad] + * 2: [0x11] [ pad] [ pad] [0x22] + * 3: [0x22] [ pad] [ pad] [0x11] + * + * If the offset is incremented then the total size is + * incremented also if necessary to prevent significant bits of + * the value from hanging over the edge of the data type. + * + * + * Return: Success: SUCCEED + * + * Failure: FAIL + * + * Programmer: Robb Matzke + * Wednesday, January 7, 1998 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +herr_t +H5Tset_offset (hid_t type_id, size_t offset) +{ + + H5T_t *dt = NULL; + + FUNC_ENTER (H5Tset_offset, FAIL); + H5ECLEAR; + + /* Check args */ + if (H5_DATATYPE!=H5Aatom_group (type_id) || + NULL==(dt=H5Aatom_object (type_id)) || + !H5T_is_atomic (dt)) { + HRETURN_ERROR (H5E_ARGS, H5E_BADTYPE, FAIL, "not an atomic data type"); + } + if (dt->locked) { + HRETURN_ERROR (H5E_ARGS, H5E_CANTINIT, FAIL, "data type is read-only"); + } + if (offset<=0) { + HRETURN_ERROR (H5E_ARGS, H5E_BADVALUE, FAIL, + "precision must be positive"); + } + + /* Adjust the size */ + if (offset + dt->u.atomic.prec > 8*dt->size) { + dt->size = (offset + dt->u.atomic.prec + 7) / 8; + } + + /* Commit */ + dt->u.atomic.offset = offset; + + FUNC_LEAVE (SUCCEED); +} + + +/*------------------------------------------------------------------------- + * Function: H5Tget_sign + * + * Purpose: Retrieves the sign type for an integer type. + * + * Return: Success: The sign type. + * + * Failure: H5T_SGN_ERROR (-1, same as FAIL) + * + * Programmer: Robb Matzke + * Wednesday, January 7, 1998 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +H5T_sign_t +H5Tget_sign (hid_t type_id) +{ + H5T_t *dt = NULL; + H5T_sign_t sign; + + FUNC_ENTER (H5Tget_sign, H5T_SGN_ERROR); + H5ECLEAR; + + /* Check args */ + if (H5_DATATYPE!=H5Aatom_group (type_id) || + NULL==(dt=H5Aatom_object (type_id)) || + H5T_INTEGER!=dt->type) { + HRETURN_ERROR (H5E_ARGS, H5E_BADTYPE, H5T_SGN_ERROR, + "not an integer data type"); + } + + /* sign */ + sign = dt->u.atomic.u.i.sign; + + FUNC_LEAVE (sign); +} + + +/*------------------------------------------------------------------------- + * Function: H5Tset_sign + * + * Purpose: Sets the sign property for an integer. + * + * Return: Success: SUCCEED + * + * Failure: FAIL + * + * Programmer: Robb Matzke + * Wednesday, January 7, 1998 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +herr_t +H5Tset_sign (hid_t type_id, H5T_sign_t sign) +{ + H5T_t *dt = NULL; + + FUNC_ENTER (H5Tset_sign, FAIL); + H5ECLEAR; + + /* Check args */ + if (H5_DATATYPE!=H5Aatom_group (type_id) || + NULL==(dt=H5Aatom_object (type_id)) || + H5T_INTEGER!=dt->type) { + HRETURN_ERROR (H5E_ARGS, H5E_BADTYPE, FAIL, "not an integer data type"); + } + if (dt->locked) { + HRETURN_ERROR (H5E_ARGS, H5E_CANTINIT, FAIL, "data type is read-only"); + } + if (sign<0 || sign>=H5T_SGN_N) { + HRETURN_ERROR (H5E_ARGS, H5E_BADVALUE, FAIL, "illegal sign type"); + } + + /* sign */ + dt->u.atomic.u.i.sign = sign; + FUNC_LEAVE (SUCCEED); +} + + +/*------------------------------------------------------------------------- + * Function: H5Tget_fields + * + * Purpose: Returns information about the locations of the various bit + * fields of a floating point data type. The field positions + * are bit positions in the significant region of the data type. + * Bits are numbered with the least significant bit number zero. + * + * Any (or even all) of the arguments can be null pointers. + * + * Return: Success: SUCCEED, field locations and sizes are + * returned through the arguments. + * + * Failure: FAIL + * + * Programmer: Robb Matzke + * Wednesday, January 7, 1998 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +herr_t +H5Tget_fields (hid_t type_id, size_t *spos/*out*/, + size_t *epos/*out*/, size_t *esize/*out*/, + size_t *mpos/*out*/, size_t *msize/*out*/) +{ + H5T_t *dt = NULL; + + FUNC_ENTER (H5Tget_fields, FAIL); + H5ECLEAR; + + /* Check args */ + if (H5_DATATYPE!=H5Aatom_group (type_id) || + NULL==(dt=H5Aatom_object (type_id)) || + H5T_FLOAT!=dt->type) { + HRETURN_ERROR (H5E_ARGS, H5E_BADTYPE, FAIL, + "not a floating-point data type"); + } + + /* Get values */ + if (spos) *spos = dt->u.atomic.u.f.sign; + if (epos) *epos = dt->u.atomic.u.f.epos; + if (esize) *esize = dt->u.atomic.u.f.esize; + if (mpos) *mpos = dt->u.atomic.u.f.mpos; + if (msize) *msize = dt->u.atomic.u.f.msize; + + FUNC_LEAVE (SUCCEED); +} + + +/*------------------------------------------------------------------------- + * Function: H5Tset_fields + * + * Purpose: Sets the locations and sizes of the various floating point + * bit fields. The field positions are bit positions in the + * significant region of the data type. Bits are numbered with + * the least significant bit number zero. + * + * Fields are not allowed to extend beyond the number of bits of + * precision, nor are they allowed to overlap with one another. + * + * Return: Success: SUCCEED + * + * Failure: FAIL + * + * Programmer: Robb Matzke + * Wednesday, January 7, 1998 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +herr_t +H5Tset_fields (hid_t type_id, size_t spos, size_t epos, size_t esize, + size_t mpos, size_t msize) +{ + H5T_t *dt = NULL; + + FUNC_ENTER (H5Tset_fields, FAIL); + H5ECLEAR; + + /* Check args */ + if (H5_DATATYPE!=H5Aatom_group (type_id) || + NULL==(dt=H5Aatom_object (type_id)) || + H5T_FLOAT!=dt->type) { + HRETURN_ERROR (H5E_ARGS, H5E_BADTYPE, FAIL, + "not a floating-point data type"); + } + if (dt->locked) { + HRETURN_ERROR (H5E_ARGS, H5E_CANTINIT, FAIL, "data type is read-only"); + } + if (epos<0 || epos+esize>dt->u.atomic.prec) { + HRETURN_ERROR (H5E_ARGS, H5E_BADVALUE, FAIL, + "exponent bit field size/location is invalid"); + } + if (mpos<0 || mpos+msize>dt->u.atomic.prec) { + HRETURN_ERROR (H5E_ARGS, H5E_BADVALUE, FAIL, + "mantissa bit field size/location is invalid"); + } + if (spos<0 || spos>=dt->u.atomic.prec) { + HRETURN_ERROR (H5E_ARGS, H5E_BADVALUE, FAIL, + "sign location is not valid"); + } + + /* Check for overlap */ + if (spos>=epos && spos=mpos && sposepos) || + (eposmpos)) { + HRETURN_ERROR (H5E_ARGS, H5E_BADVALUE, FAIL, + "exponent and mantissa fields overlap"); + } + + /* Commit */ + dt->u.atomic.u.f.sign = spos; + dt->u.atomic.u.f.epos = epos; + dt->u.atomic.u.f.mpos = mpos; + dt->u.atomic.u.f.esize = esize; + dt->u.atomic.u.f.msize = msize; + + FUNC_LEAVE (SUCCEED); +} + + +/*------------------------------------------------------------------------- + * Function: H5Tget_ebias + * + * Purpose: Retrieves the exponent bias of a floating-point type. + * + * Return: Success: The bias + * + * Failure: 0 + * + * Programmer: Robb Matzke + * Wednesday, January 7, 1998 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +size_t +H5Tget_ebias (hid_t type_id) +{ + H5T_t *dt = NULL; + size_t ebias; + + FUNC_ENTER (H5Tget_ebias, 0); + H5ECLEAR; + + /* Check args */ + if (H5_DATATYPE!=H5Aatom_group (type_id) || + NULL==(dt=H5Aatom_object (type_id)) || + H5T_FLOAT!=dt->type) { + HRETURN_ERROR (H5E_ARGS, H5E_BADTYPE, 0, + "not a floating-point data type"); + } + + /* bias */ + ebias = dt->u.atomic.u.f.ebias; + + FUNC_LEAVE (ebias); +} + + +/*------------------------------------------------------------------------- + * Function: H5Tset_ebias + * + * Purpose: Sets the exponent bias of a floating-point type. + * + * Return: Success: SUCCEED + * + * Failure: FAIL + * + * Programmer: Robb Matzke + * Wednesday, January 7, 1998 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +herr_t +H5Tset_ebias (hid_t type_id, size_t ebias) +{ + H5T_t *dt = NULL; + + FUNC_ENTER (H5Tset_ebias, FAIL); + H5ECLEAR; + + /* Check args */ + if (H5_DATATYPE!=H5Aatom_group (type_id) || + NULL==(dt=H5Aatom_object (type_id)) || + H5T_FLOAT!=dt->type) { + HRETURN_ERROR (H5E_ARGS, H5E_BADTYPE, FAIL, + "not a floating-point data type"); + } + if (dt->locked) { + HRETURN_ERROR (H5E_ARGS, H5E_CANTINIT, FAIL, "data type is read-only"); + } + + dt->u.atomic.u.f.ebias = ebias; + + FUNC_LEAVE (SUCCEED); +} + + +/*------------------------------------------------------------------------- + * Function: H5Tget_norm + * + * Purpose: Returns the mantisssa normalization of a floating-point data + * type. + * + * Return: Success: Normalization ID + * + * Failure: H5T_NORM_ERROR (-1, same as FAIL) + * + * Programmer: Robb Matzke + * Wednesday, January 7, 1998 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +H5T_norm_t +H5Tget_norm (hid_t type_id) +{ + H5T_t *dt = NULL; + H5T_norm_t norm; + + FUNC_ENTER (H5Tget_norm, H5T_NORM_ERROR); + H5ECLEAR; + + /* Check args */ + if (H5_DATATYPE!=H5Aatom_group (type_id) || + NULL==(dt=H5Aatom_object (type_id)) || + H5T_FLOAT!=dt->type) { + HRETURN_ERROR (H5E_ARGS, H5E_BADTYPE, H5T_NORM_ERROR, + "not a floating-point data type"); + } + + /* norm */ + norm = dt->u.atomic.u.f.norm; + + FUNC_LEAVE (norm); +} + + +/*------------------------------------------------------------------------- + * Function: H5Tset_norm + * + * Purpose: Sets the mantissa normalization method for a floating point + * data type. + * + * Return: Success: SUCCEED + * + * Failure: FAIL + * + * Programmer: Robb Matzke + * Wednesday, January 7, 1998 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +herr_t +H5Tset_norm (hid_t type_id, H5T_norm_t norm) +{ + H5T_t *dt = NULL; + + FUNC_ENTER (H5Tset_norm, FAIL); + H5ECLEAR; + + /* Check args */ + if (H5_DATATYPE!=H5Aatom_group (type_id) || + NULL==(dt=H5Aatom_object (type_id)) || + H5T_FLOAT!=dt->type) { + HRETURN_ERROR (H5E_ARGS, H5E_BADTYPE, FAIL, + "not a floating-point data type"); + } + if (dt->locked) { + HRETURN_ERROR (H5E_ARGS, H5E_CANTINIT, FAIL, "data type is read-only"); + } + if (norm<0 || norm>H5T_NORM_NONE) { + HRETURN_ERROR (H5E_ARGS, H5E_BADVALUE, FAIL, "illegal normalization"); + } + + /* norm */ + dt->u.atomic.u.f.norm = norm; + FUNC_LEAVE (SUCCEED); +} + + +/*------------------------------------------------------------------------- * Function: H5Tget_nmembers * * Purpose: Determines how many members compound data type TYPE_ID has. @@ -293,100 +1196,216 @@ H5Tequal (hid_t type1_id, hid_t type2_id) intn H5Tget_nmembers (hid_t type_id) { - + + H5T_t *dt = NULL; + + FUNC_ENTER (H5Tget_num_members, FAIL); + H5ECLEAR; + + /* Check args */ + if (H5_DATATYPE!=H5Aatom_group (type_id) || + NULL==(dt=H5Aatom_object (type_id)) || + H5T_COMPOUND!=dt->type) { + HRETURN_ERROR (H5E_ARGS, H5E_BADTYPE, FAIL, "not a compound data type"); + } + + FUNC_LEAVE (dt->u.compnd.nmembs); +} + + +/*------------------------------------------------------------------------- + * Function: H5Tget_member_name + * + * Purpose: Returns the name of a member of a compound data type. + * Members are stored in no particular order with numbers 0 + * through N-1 where N is the value returned by + * H5Tget_nmembers(). + * + * Return: Success: Ptr to a string allocated with malloc(). The + * caller is responsible for freeing the string. + * + * Failure: NULL + * + * Programmer: Robb Matzke + * Wednesday, January 7, 1998 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +char * +H5Tget_member_name (hid_t type_id, int membno) +{ + H5T_t *dt = NULL; + char *s = NULL; + + FUNC_ENTER (H5Tget_member_name, NULL); + H5ECLEAR; + + /* Check args */ + if (H5_DATATYPE!=H5Aatom_group (type_id) || + NULL==(dt=H5Aatom_object (type_id)) || + H5T_COMPOUND!=dt->type) { + HRETURN_ERROR (H5E_ARGS, H5E_BADTYPE, NULL, "not a compound data type"); + } + if (membno<0 || membno>=dt->u.compnd.nmembs) { + HRETURN_ERROR (H5E_ARGS, H5E_BADVALUE, NULL, "invalid member number"); + } + + s = H5MM_xstrdup (dt->u.compnd.memb[membno].name); + FUNC_LEAVE (s); +} + + +/*------------------------------------------------------------------------- + * Function: H5Tget_member_offset + * + * Purpose: Returns the byte offset of the beginning of a member with + * respect to the beginning of the compound data type datum. + * + * Return: Success: Byte offset. + * + * Failure: Zero. Zero is a valid offset, but this + * function will fail only if a call to + * H5Tget_member_dims() fails with the same + * arguments. + * + * Programmer: Robb Matzke + * Wednesday, January 7, 1998 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +size_t +H5Tget_member_offset (hid_t type_id, int membno) +{ H5T_t *dt = NULL; + size_t offset = 0; - FUNC_ENTER (H5Tget_num_members, FAIL); + FUNC_ENTER (H5Tget_member_offset, 0); H5ECLEAR; /* Check args */ if (H5_DATATYPE!=H5Aatom_group (type_id) || NULL==(dt=H5Aatom_object (type_id)) || H5T_COMPOUND!=dt->type) { - HRETURN_ERROR (H5E_ARGS, H5E_BADTYPE, FAIL, "not a compound data type"); + HRETURN_ERROR (H5E_ARGS, H5E_BADTYPE, 0, "not a compound data type"); + } + if (membno<0 || membno>=dt->u.compnd.nmembs) { + HRETURN_ERROR (H5E_ARGS, H5E_BADVALUE, 0, "invalid member number"); } - FUNC_LEAVE (dt->u.compnd.nmembs); + offset = dt->u.compnd.memb[membno].offset; + FUNC_LEAVE (offset); } /*------------------------------------------------------------------------- - * Function: H5Tget_class + * Function: H5Tget_member_dims * - * Purpose: Returns the data type class identifier for data type TYPE_ID. + * Purpose: Returns the dimensionality of the member. The dimensions and + * permuation vector are returned through arguments DIMS and + * PERM, both arrays of at least four elements. Either (or even + * both) may be null pointers. * - * Return: Success: One of the non-negative data type class - * constants. + * Return: Success: A value between zero and four, inclusive. * - * Failure: H5T_NO_CLASS (-1) + * Failure: -1 * * Programmer: Robb Matzke - * Monday, December 8, 1997 + * Wednesday, January 7, 1998 * * Modifications: * *------------------------------------------------------------------------- */ -H5T_class_t -H5Tget_class (hid_t type_id) +int +H5Tget_member_dims (hid_t type_id, int membno, + int dims[]/*out*/, int perm[]/*out*/) { H5T_t *dt = NULL; - - FUNC_ENTER (H5Tget_class, FAIL); + intn ndims, i; + + FUNC_ENTER (H5Tget_member_dims, FAIL); H5ECLEAR; /* Check args */ if (H5_DATATYPE!=H5Aatom_group (type_id) || - NULL==(dt=H5Aatom_object (type_id))) { - HRETURN_ERROR (H5E_ARGS, H5E_BADTYPE, FAIL, "not a data type"); + NULL==(dt=H5Aatom_object (type_id)) || + H5T_COMPOUND!=dt->type) { + HRETURN_ERROR (H5E_ARGS, H5E_BADTYPE, FAIL, "not a compound data type"); + } + if (membno<0 || membno>=dt->u.compnd.nmembs) { + HRETURN_ERROR (H5E_ARGS, H5E_BADVALUE, FAIL, "invalid member number"); } - FUNC_LEAVE (dt->type); + ndims = dt->u.compnd.memb[membno].ndims; + for (i=0; iu.compnd.memb[membno].dim[i]; + if (perm[i]) perm[i] = dt->u.compnd.memb[membno].perm[i]; + } + + FUNC_LEAVE (ndims); } /*------------------------------------------------------------------------- - * Function: H5Tget_size + * Function: H5Tget_member_type * - * Purpose: Determines the total size of a data type in bytes. + * Purpose: Returns the data type of the specified member. The caller + * should invoke H5Tclose() to release resources associated with + * the type. * - * Return: Success: Size of the data type in bytes. The size of - * data type is the size of an instance of that - * data type. + * Return: Success: An OID of a copy of the member data type; + * modifying the returned data type does not + * modify the member type. * - * Failure: 0 (valid data types are never zero size) + * Failure: FAIL * * Programmer: Robb Matzke - * Monday, December 8, 1997 + * Wednesday, January 7, 1998 * * Modifications: * *------------------------------------------------------------------------- */ -size_t -H5Tget_size (hid_t type_id) +hid_t +H5Tget_member_type (hid_t type_id, int membno) { - H5T_t *dt = NULL; - size_t size; - - FUNC_ENTER (H5Tget_size, 0); + H5T_t *dt = NULL, *memb_dt = NULL; + hid_t memb_type_id; + + FUNC_ENTER (H5Tget_member_type, FAIL); H5ECLEAR; /* Check args */ if (H5_DATATYPE!=H5Aatom_group (type_id) || - NULL==(dt=H5Aatom_object (type_id))) { - HRETURN_ERROR (H5E_ARGS, H5E_BADTYPE, FAIL, "not a data type"); + NULL==(dt=H5Aatom_object (type_id)) || + H5T_COMPOUND!=dt->type) { + HRETURN_ERROR (H5E_ARGS, H5E_BADTYPE, FAIL, "not a compound data type"); + } + if (membno<0 || membno>=dt->u.compnd.nmembs) { + HRETURN_ERROR (H5E_ARGS, H5E_BADVALUE, FAIL, "invalid member number"); + } + + /* Copy data type into an atom */ + if (NULL==(memb_dt=H5T_copy (&(dt->u.compnd.memb[membno].type)))) { + HRETURN_ERROR (H5E_DATATYPE, H5E_CANTINIT, FAIL, + "unable to copy member data type"); + } + if ((memb_type_id=H5Aregister_atom (H5_DATATYPE, memb_dt))<0) { + H5T_close (memb_dt); + HRETURN_ERROR (H5E_DATATYPE, H5E_CANTREGISTER, FAIL, + "can't register data type atom"); } - /* size */ - size = H5T_get_size (dt); - - FUNC_LEAVE (size); + FUNC_LEAVE (memb_type_id); } /*------------------------------------------------------------------------- - * Function: H5Tinsert_member + * Function: H5Tinsert * * Purpose: Adds another member to the compound data type PARENT_ID. The * new member has a NAME which must be unique within the @@ -414,13 +1433,12 @@ H5Tget_size (hid_t type_id) *------------------------------------------------------------------------- */ herr_t -H5Tinsert_member (hid_t parent_id, const char *name, off_t offset, - hid_t member_id) +H5Tinsert (hid_t parent_id, const char *name, off_t offset, hid_t member_id) { H5T_t *parent = NULL; /*the compound parent data type */ H5T_t *member = NULL; /*the atomic member type */ - FUNC_ENTER (H5Tinsert_member, FAIL); + FUNC_ENTER (H5Tinsert, FAIL); H5ECLEAR; /* Check args */ @@ -430,18 +1448,17 @@ H5Tinsert_member (hid_t parent_id, const char *name, off_t offset, HRETURN_ERROR (H5E_ARGS, H5E_BADTYPE, FAIL, "not a compound data type"); } if (parent->locked) { - HRETURN_ERROR (H5E_ARGS, H5E_BADVALUE, FAIL, "parent is locked"); + HRETURN_ERROR (H5E_ARGS, H5E_BADVALUE, FAIL, "parent type read-only"); } if (!name || !*name) { HRETURN_ERROR (H5E_ARGS, H5E_BADVALUE, FAIL, "no member name"); } if (H5_DATATYPE!=H5Aatom_group (member_id) || - NULL==(member=H5Aatom_object (member_id)) || - H5T_COMPOUND==member->type) { - HRETURN_ERROR (H5E_ARGS, H5E_BADTYPE, FAIL, "not an atomic data type"); + NULL==(member=H5Aatom_object (member_id))) { + HRETURN_ERROR (H5E_ARGS, H5E_BADTYPE, FAIL, "not a data type"); } - if (H5T_insert_member (parent, name, offset, member)<0) { + if (H5T_insert (parent, name, offset, member)<0) { HRETURN_ERROR (H5E_DATATYPE, H5E_CANTINSERT, FAIL, "can't insert member"); } @@ -449,6 +1466,51 @@ H5Tinsert_member (hid_t parent_id, const char *name, off_t offset, FUNC_LEAVE (SUCCEED); } + +/*------------------------------------------------------------------------- + * Function: H5Tpack + * + * Purpose: Recursively removes padding from within a compound data type + * to make it more efficient (space-wise) to store that data. + * + * Return: Success: SUCCEED + * + * Failure: FAIL + * + * Programmer: Robb Matzke + * Wednesday, January 7, 1998 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +herr_t +H5Tpack (hid_t type_id) +{ + H5T_t *dt = NULL; + + FUNC_ENTER (H5Tpack, FAIL); + H5ECLEAR; + + /* Check args */ + if (H5_DATATYPE!=H5Aatom_group (type_id) || + NULL==(dt=H5Aatom_object (type_id)) || + H5T_COMPOUND!=dt->type) { + HRETURN_ERROR (H5E_ARGS, H5E_BADTYPE, FAIL, "not a compound data type"); + } + if (dt->locked) { + HRETURN_ERROR (H5E_ARGS, H5E_BADVALUE, FAIL, "data type is read-only"); + } + + if (H5T_pack (dt)<0) { + HRETURN_ERROR (H5E_DATATYPE, H5E_CANTINIT, FAIL, + "unable to pack compound data type"); + } + + FUNC_LEAVE (SUCCEED); +} + + /*------------------------------------------------------------------------- @@ -490,7 +1552,7 @@ H5T_create (H5T_class_t type, size_t size) assert (size>0); switch (type) { - case H5T_FIXED: + case H5T_INTEGER: /* Default type is a native `int' */ if (NULL==(dt=H5T_copy (H5Aatom_object (H5T_NATIVE_INT)))) { HRETURN_ERROR (H5E_DATATYPE, H5E_CANTINIT, NULL, @@ -506,7 +1568,7 @@ H5T_create (H5T_class_t type, size_t size) } break; - case H5T_DATE: + case H5T_TIME: case H5T_STRING: case H5T_BITFIELD: case H5T_OPAQUE: @@ -620,6 +1682,33 @@ H5T_close (H5T_t *dt) /*------------------------------------------------------------------------- + * Function: H5T_is_atomic + * + * Purpose: Determines if a data type is an atomic type. + * + * Return: Success: TRUE, FALSE + * + * Failure: FAIL + * + * Programmer: Robb Matzke + * Wednesday, January 7, 1998 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +hbool_t +H5T_is_atomic (const H5T_t *dt) +{ + FUNC_ENTER (H5T_is_atomic, FAIL); + + assert (dt); + + FUNC_LEAVE (H5T_COMPOUND==dt->type ? FALSE : TRUE); +} + + +/*------------------------------------------------------------------------- * Function: H5T_get_size * * Purpose: Determines the total size of a data type in bytes. @@ -650,7 +1739,7 @@ H5T_get_size (const H5T_t *dt) /*------------------------------------------------------------------------- - * Function: H5T_insert_member + * Function: H5T_insert * * Purpose: Adds a new MEMBER to the compound data type PARENT. The new * member will have a NAME that is unique within PARENT and an @@ -669,18 +1758,17 @@ H5T_get_size (const H5T_t *dt) *------------------------------------------------------------------------- */ herr_t -H5T_insert_member (H5T_t *parent, const char *name, off_t offset, - const H5T_t *member) +H5T_insert (H5T_t *parent, const char *name, off_t offset, const H5T_t *member) { intn i; H5T_t *tmp = NULL; - FUNC_ENTER (H5T_insert_member, FAIL); + FUNC_ENTER (H5T_insert, FAIL); /* check args */ assert (parent && H5T_COMPOUND==parent->type); assert (!parent->locked); - assert (member && H5T_COMPOUND!=member->type); + assert (member); assert (name && *name); /* Does NAME already exist in PARENT? */ @@ -690,7 +1778,19 @@ H5T_insert_member (H5T_t *parent, const char *name, off_t offset, "member name is not unique"); } } - + + /* Does the new member overlap any existing member ? */ + for (i=0; iu.compnd.nmembs; i++) { + if ((offsetu.compnd.memb[i].offset && + offset+member->size>parent->u.compnd.memb[i].offset) || + (parent->u.compnd.memb[i].offsetu.compnd.memb[i].offset+ + parent->u.compnd.memb[i].type.size > offset)) { + HRETURN_ERROR (H5E_DATATYPE, H5E_CANTINSERT, FAIL, + "member overlaps with another member"); + } + } + /* Increase member array if necessary */ if (parent->u.compnd.nmembs>=parent->u.compnd.nalloc) { parent->u.compnd.nalloc += H5T_COMPND_INC; @@ -709,9 +1809,117 @@ H5T_insert_member (H5T_t *parent, const char *name, off_t offset, parent->u.compnd.memb[i].type = *tmp; H5MM_xfree (tmp); + parent->u.compnd.nmembs++; + FUNC_LEAVE (SUCCEED); +} + + +/*------------------------------------------------------------------------- + * Function: H5T_pack + * + * Purpose: Recursively packs a compound data type by removing padding + * bytes. This is done in place (that is, destructively). + * + * Return: Success: SUCCEED + * + * Failure: FAIL + * + * Programmer: Robb Matzke + * Wednesday, January 7, 1998 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +herr_t +H5T_pack (H5T_t *dt) +{ + int i; + size_t offset; + + FUNC_ENTER (H5T_pack, FAIL); + + assert (dt); + assert (!dt->locked); + + if (H5T_COMPOUND==dt->type) { + /* Recursively pack the members */ + for (i=0; iu.compnd.nmembs; i++) { + if (H5T_pack (&(dt->u.compnd.memb[i].type))<0) { + HRETURN_ERROR (H5E_DATATYPE, H5E_CANTINIT, FAIL, + "unable to pack part of a compound data type"); + } + } + + /* Remove padding between members */ + H5T_sort_by_offset (dt); + for (i=0, offset=0; iu.compnd.nmembs; i++) { + dt->u.compnd.memb[i].offset = offset; + offset += dt->u.compnd.memb[i].type.size; + } + + /* Change total size */ + dt->size = MAX (1, offset); + } + + FUNC_LEAVE (SUCCEED); +} + + +/*------------------------------------------------------------------------- + * Function: H5T_sort_by_offset + * + * Purpose: Sorts the members of a compound data type by their offsets. + * This even works for locked data types since it doesn't change + * the value of the type. + * + * Return: Success: SUCCEED + * + * Failure: FAIL + * + * Programmer: Robb Matzke + * Wednesday, January 7, 1998 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +herr_t +H5T_sort_by_offset (H5T_t *dt) +{ + int i, j, nmembs; + hbool_t swapped; + + FUNC_ENTER (H5T_sort_by_offset, FAIL); + + /* Check args */ + assert (dt); + assert (H5T_COMPOUND==dt->type); + + /* Use a bubble sort because we can short circuit */ + nmembs = dt->u.compnd.nmembs; + for (i=nmembs-1, swapped=TRUE; i>0 && swapped; --i) { + for (j=0, swapped=FALSE; ju.compnd.memb[j].offset>dt->u.compnd.memb[j+1].offset) { + H5T_member_t tmp = dt->u.compnd.memb[j]; + dt->u.compnd.memb[j] = dt->u.compnd.memb[j+1]; + dt->u.compnd.memb[j+1] = tmp; + swapped = 1; + } + } + } + +#ifndef NDEBUG + /* I never trust a sort :-) */ + for (i=0; iu.compnd.nmembs-1; i++) { + assert (dt->u.compnd.memb[i].offsetu.compnd.memb[i+1].offset); + } +#endif + FUNC_LEAVE (SUCCEED); } + /*------------------------------------------------------------------------- * Function: H5T_cmp @@ -856,7 +2064,7 @@ H5T_cmp (const H5T_t *dt1, const H5T_t *dt2) if (dt1->u.atomic.hi_pad > dt2->u.atomic.hi_pad) HGOTO_DONE (1); switch (dt1->type) { - case H5T_FIXED: + case H5T_INTEGER: if (dt1->u.atomic.u.i.sign < dt2->u.atomic.u.i.sign) HGOTO_DONE (-1); if (dt1->u.atomic.u.i.sign > dt2->u.atomic.u.i.sign) HGOTO_DONE (1); break; @@ -894,7 +2102,7 @@ H5T_cmp (const H5T_t *dt1, const H5T_t *dt2) break; - case H5T_DATE: + case H5T_TIME: /*void*/ break; @@ -927,3 +2135,171 @@ H5T_cmp (const H5T_t *dt1, const H5T_t *dt2) FUNC_LEAVE (ret_value); } + +/*------------------------------------------------------------------------- + * Function: H5T_debug + * + * Purpose: Prints information about a data type. + * + * Return: Success: SUCCEED + * + * Failure: FAIL + * + * Programmer: Robb Matzke + * Wednesday, January 7, 1998 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +herr_t +H5T_debug (H5T_t *dt, FILE *stream) +{ + const char *s = ""; + int i, j; + uint64 tmp; + + FUNC_ENTER (H5T_debug, FAIL); + + /* Check args */ + assert (dt); + assert (stream); + + switch (dt->type) { + case H5T_INTEGER: + s = "int"; + break; + case H5T_FLOAT: + s = "float"; + break; + case H5T_TIME: + s = "time"; + break; + case H5T_STRING: + s = "str"; + break; + case H5T_BITFIELD: + s = "bits"; + break; + case H5T_OPAQUE: + s = "opaque"; + break; + case H5T_COMPOUND: + s = "struct"; + break; + default: + s = ""; + break; + } + + fprintf (stream, "%s%s {nbytes=%d", + s, dt->locked?"[!]":"", dt->size); + + if (H5T_is_atomic (dt)) { + switch (dt->u.atomic.order) { + case H5T_ORDER_BE: + s = "BE"; + break; + case H5T_ORDER_LE: + s = "LE"; + break; + case H5T_ORDER_VAX: + s = "VAX"; + break; + case H5T_ORDER_NONE: + s = "NONE"; + break; + default: + s = "order?"; + break; + } + fprintf (stream, ", %s", s); + + if (dt->u.atomic.offset) { + fprintf (stream, ", offset=%lu", + (unsigned long)(dt->u.atomic.offset)); + } + if (dt->u.atomic.prec!=8*dt->size) { + fprintf (stream, ", prec=%lu", + (unsigned long)(dt->u.atomic.prec)); + } + + switch (dt->type) { + case H5T_INTEGER: + switch (dt->u.atomic.u.i.sign) { + case H5T_SGN_NONE: + s = "unsigned"; + break; + case H5T_SGN_2: + s = NULL; + break; + default: + s = "sign?"; + break; + } + if (s) fprintf (stream, ", %s", s); + break; + + case H5T_FLOAT: + switch (dt->u.atomic.u.f.norm) { + case H5T_NORM_IMPLIED: + s = "implied"; + break; + case H5T_NORM_MSBSET: + s = "msbset"; + break; + case H5T_NORM_NONE: + s = "no-norm"; + break; + default: + s = "norm?"; + break; + } + fprintf (stream, ", sign=%lu+1", + (unsigned long)(dt->u.atomic.u.f.sign)); + fprintf (stream, ", mant=%lu+%lu (%s)", + (unsigned long)(dt->u.atomic.u.f.mpos), + (unsigned long)(dt->u.atomic.u.f.msize), s); + fprintf (stream, ", exp=%lu+%lu", + (unsigned long)(dt->u.atomic.u.f.epos), + (unsigned long)(dt->u.atomic.u.f.esize)); + tmp = dt->u.atomic.u.f.ebias >> 32; + if (tmp) { + uintn hi = tmp; + uintn lo = dt->u.atomic.u.f.ebias & 0xffffffff; + fprintf (stream, " bias=0x%08x%08x", hi, lo); + } else { + uintn lo = dt->u.atomic.u.f.ebias & 0xffffffff; + fprintf (stream, " bias=0x%08x", lo); + } + break; + + default: + /* No additional info */ + break; + } + } else { + for (i=0; iu.compnd.nmembs; i++) { + fprintf (stream, "\n\"%s\" @%lu", + dt->u.compnd.memb[i].name, + (unsigned long)(dt->u.compnd.memb[i].offset)); + if (dt->u.compnd.memb[i].ndims) { + fprintf (stream, "["); + for (j=0; ju.compnd.memb[i].ndims; j++) { + fprintf (stream, "%s%d", j?", ":"", + dt->u.compnd.memb[i].dim[j]); + } + fprintf (stream, "]"); + } + fprintf (stream, " "); + H5T_debug (&(dt->u.compnd.memb[i].type), stream); + } + fprintf (stream, "\n"); + } + fprintf (stream, "}"); + + FUNC_LEAVE (SUCCEED); +} + + + diff --git a/src/H5Tpkg.h b/src/H5Tpkg.h index 1267e83..1a75c59 100644 --- a/src/H5Tpkg.h +++ b/src/H5Tpkg.h @@ -26,8 +26,8 @@ typedef struct H5T_atomic_t { intn hi_pad; /*type of msb padding */ union { struct { - H5T_sign_t sign; /*type of fixed-point sign */ - } i; /*integer; fixed-point types */ + H5T_sign_t sign; /*type of integer sign */ + } i; /*integer; integer types */ struct { size_t sign; /*bit position of sign bit */ diff --git a/src/H5Tprivate.h b/src/H5Tprivate.h index 5a9fbcb..f92dba5 100644 --- a/src/H5Tprivate.h +++ b/src/H5Tprivate.h @@ -38,7 +38,13 @@ H5T_t *H5T_copy (const H5T_t *old_dt); herr_t H5T_close (H5T_t *dt); size_t H5T_get_size (const H5T_t *dt); intn H5T_cmp (const H5T_t *dt1, const H5T_t *dt2); +hbool_t H5T_is_atomic (const H5T_t *dt); + +herr_t H5T_insert (H5T_t *parent, const char *name, off_t offset, + const H5T_t *member); +herr_t H5T_sort_by_offset (H5T_t *dt); +herr_t H5T_pack (H5T_t *dt); +herr_t H5T_debug (H5T_t *dt, FILE *stream); + -herr_t H5T_insert_member (H5T_t *parent, const char *name, off_t offset, - const H5T_t *member); #endif diff --git a/src/H5Tpublic.h b/src/H5Tpublic.h index e2c1163..907aff1 100644 --- a/src/H5Tpublic.h +++ b/src/H5Tpublic.h @@ -26,9 +26,9 @@ /* These are the various classes of data types */ typedef enum H5T_class_t { H5T_NO_CLASS =-1, /*error */ - H5T_FIXED =0, /*fixed-point types */ + H5T_INTEGER =0, /*integer types */ H5T_FLOAT =1, /*floating-point types */ - H5T_DATE =2, /*date and time types */ + H5T_TIME =2, /*date and time types */ H5T_STRING =3, /*character string types */ H5T_BITFIELD =4, /*bit field types */ H5T_OPAQUE =5, /*opaque types */ @@ -42,13 +42,16 @@ typedef enum H5T_order_t { H5T_ORDER_BE =1, /*bit endian */ H5T_ORDER_VAX =2, /*VAX mixed endian */ H5T_ORDER_NONE =3 /*no particular order (strings, bits,..)*/ + /*H5T_ORDER_NONE must be last*/ } H5T_order_t; -/* Types of fixed-point sign schemes */ +/* Types of integer sign schemes */ typedef enum H5T_sign_t { H5T_SGN_ERROR =-1, /*error */ H5T_SGN_NONE =0, /*this is an unsigned type */ - H5T_SGN_2 =1 /*two's complement */ + H5T_SGN_2 =1, /*two's complement */ + + H5T_SGN_N =2 /*this must be last */ } H5T_sign_t; /* Floating-point normalization schemes */ @@ -57,6 +60,7 @@ typedef enum H5T_norm_t { H5T_NORM_IMPLIED =0, /*msb of mantissa isn't stored, always 1*/ H5T_NORM_MSBSET =1, /*msb of mantissa is always 1 */ H5T_NORM_NONE =2 /*not normalized */ + /*H5T_NORM_NONE must be last*/ } H5T_norm_t; /* Character set to use for text strings */ @@ -72,39 +76,86 @@ typedef enum H5T_str_t { H5T_STR_SPACE =1 /*pad with spaces like in Fortran */ } H5T_str_t; +/* Type of padding to use in other atomic types */ +typedef enum H5T_pad_t { + H5T_PAD_ERROR =-1, /*error */ + H5T_PAD_ZERO =0, /*always set to zero */ + H5T_PAD_ONE =1, /*always set to one */ + H5T_PAD_BACKGROUND =2, /*set to background value */ + + H5T_NPAD =3 /*THIS MUST BE LAST */ +} H5T_pad_t; - -#define H5T_PAD_ZERO (-1) /*pad with all zeros */ -#define H5T_PAD_ONE (-2) /*pad with all ones */ -#define H5T_PAD_FROM(X) (X) /*pad with value of bit X */ +#define HOFFSET(S,M) ((const char*)&S.M-(const char*)&S) +#define HPOFFSET(P,M) ((const char*)&(P->M)-(const char*)P) /* The predefined types */ -extern hid_t H5T_NATIVE_CHAR; -extern hid_t H5T_NATIVE_UCHAR; -extern hid_t H5T_NATIVE_SHORT; -extern hid_t H5T_NATIVE_USHORT; -extern hid_t H5T_NATIVE_INT; -extern hid_t H5T_NATIVE_UINT; -extern hid_t H5T_NATIVE_LONG; -extern hid_t H5T_NATIVE_ULONG; -extern hid_t H5T_NATIVE_FLOAT; -extern hid_t H5T_NATIVE_DOUBLE; +#define H5T_NATIVE_CHAR (H5init(), H5T_NATIVE_CHAR_g) +#define H5T_NATIVE_UCHAR (H5init(), H5T_NATIVE_UCHAR_g) +#define H5T_NATIVE_SHORT (H5init(), H5T_NATIVE_SHORT_g) +#define H5T_NATIVE_USHORT (H5init(), H5T_NATIVE_USHORT_g) +#define H5T_NATIVE_INT (H5init(), H5T_NATIVE_INT_g) +#define H5T_NATIVE_UINT (H5init(), H5T_NATIVE_UINT_g) +#define H5T_NATIVE_LONG (H5init(), H5T_NATIVE_LONG_g) +#define H5T_NATIVE_ULONG (H5init(), H5T_NATIVE_ULONG_g) +#define H5T_NATIVE_FLOAT (H5init(), H5T_NATIVE_FLOAT_g) +#define H5T_NATIVE_DOUBLE (H5init(), H5T_NATIVE_DOUBLE_g) + +extern hid_t H5T_NATIVE_CHAR_g; +extern hid_t H5T_NATIVE_UCHAR_g; +extern hid_t H5T_NATIVE_SHORT_g; +extern hid_t H5T_NATIVE_USHORT_g; +extern hid_t H5T_NATIVE_INT_g; +extern hid_t H5T_NATIVE_UINT_g; +extern hid_t H5T_NATIVE_LONG_g; +extern hid_t H5T_NATIVE_ULONG_g; +extern hid_t H5T_NATIVE_FLOAT_g; +extern hid_t H5T_NATIVE_DOUBLE_g; #ifdef __cplusplus extern "C" { #endif +/* Operations defined on all data types */ hid_t H5Tcreate (H5T_class_t type, size_t size); hid_t H5Tcopy (hid_t type_id); herr_t H5Tclose (hid_t type_id); hbool_t H5Tequal (hid_t type1_id, hid_t type2_id); +/* Operations defined on compound data types */ +herr_t H5Tinsert (hid_t parent_id, const char *name, off_t offset, + hid_t member_id); +herr_t H5Tpack (hid_t type_id); + +/* Querying property values */ H5T_class_t H5Tget_class (hid_t type_id); size_t H5Tget_size (hid_t type_id); +H5T_order_t H5Tget_order (hid_t type_id); +size_t H5Tget_precision (hid_t type_id); +size_t H5Tget_offset (hid_t type_id); +H5T_sign_t H5Tget_sign (hid_t type_id); +herr_t H5Tget_fields (hid_t type_id, size_t *spos/*out*/, + size_t *epos/*out*/, size_t *esize/*out*/, + size_t *mpos/*out*/, size_t *msize/*out*/); +size_t H5Tget_ebias (hid_t type_id); +H5T_norm_t H5Tget_norm (hid_t type_id); intn H5Tget_nmembers (hid_t type_id); - -herr_t H5Tinsert_member (hid_t parent_id, const char *name, off_t offset, - hid_t member_id); +char *H5Tget_member_name (hid_t type_id, int membno); +size_t H5Tget_member_offset (hid_t type_id, int membno); +int H5Tget_member_dims (hid_t type_id, int membno, + int dims[]/*out*/, int perm[]/*out*/); +hid_t H5Tget_member_type (hid_t type_id, int membno); + +/* Setting property values */ +herr_t H5Tset_size (hid_t type_id, size_t size); +herr_t H5Tset_order (hid_t type_id, H5T_order_t order); +herr_t H5Tset_precision (hid_t type_id, size_t prec); +herr_t H5Tset_offset (hid_t type_id, size_t offset); +herr_t H5Tset_sign (hid_t type_id, H5T_sign_t sign); +herr_t H5Tset_fields (hid_t type_id, size_t spos, size_t epos, size_t esize, + size_t mpos, size_t msize); +herr_t H5Tset_ebias (hid_t type_id, size_t ebias); +herr_t H5Tset_norm (hid_t type_id, H5T_norm_t norm); #ifdef __cplusplus diff --git a/src/H5detect.c b/src/H5detect.c index 43464c4..82b662f 100644 --- a/src/H5detect.c +++ b/src/H5detect.c @@ -98,13 +98,13 @@ static detected_t Known[] = { {"Byte addressable", 1, 0, LE_1, INTEGER}, - /* Little-endian fixed-point */ + /* Little-endian integer */ {"Little-endian", 2, 0, LE_2, INTEGER}, {"Little-endian", 4, 0, LE_4, INTEGER}, - /* Big-endian fixed-point */ + /* Big-endian integer */ {"Big-endian", 2, 0, BE_2, INTEGER}, {"Big-endian", @@ -284,7 +284,7 @@ static hbool_t interface_initialize_g = FALSE;\n\ /* Global definitions for each type */ for (i=0; iu.atomic.prec = %d;\n\ dt->u.atomic.lo_pad = H5T_PAD_ZERO;\n\ dt->u.atomic.hi_pad = H5T_PAD_ZERO;\n", - d[i].msize?"FLOAT":"FIXED", /*class */ + d[i].msize?"FLOAT":"INTEGER", /*class */ d[i].size+abs (d[i].padding), /*size */ d[i].perm[0]?"BE":"LE", /*byte order */ 8*d[i].size); /*precision */ @@ -350,7 +350,7 @@ H5T_init (void)\n\ /* Atomize the type */ printf ("\ - if ((H5T_NATIVE_%s = H5Aregister_atom (H5_DATATYPE, dt))<0) {\n\ + if ((H5T_NATIVE_%s_g = H5Aregister_atom (H5_DATATYPE, dt))<0) {\n\ HRETURN_ERROR (H5E_DATATYPE, H5E_CANTINIT, FAIL,\n\ \"can't initialize type system (atom registration \"\n\ \"failure\");\n\ @@ -829,7 +829,7 @@ true exponent. The radix point is assumed\n\ to be before the first `M' bit. Any bit\n\ of a floating-point value not falling into one\n\ of these categories is printed as a question\n\ -mark. Bits of fixed-point types are printed as\n\ +mark. Bits of integer types are printed as\n\ `I' for 2's complement and `U' for magnitude.\n\ \n\ If the most significant bit of the normalized\n\ diff --git a/test/dtypes.c b/test/dtypes.c index 6ff118f..bd180e0 100644 --- a/test/dtypes.c +++ b/test/dtypes.c @@ -11,6 +11,8 @@ #include #include +#include + #ifndef HAVE_FUNCTION #define __FUNCTION__ "" @@ -18,6 +20,10 @@ #define AT() printf (" at %s:%d in %s()...\n", \ __FILE__, __LINE__, __FUNCTION__); +typedef struct complex_t { + double re; + double im; +} complex_t; /*------------------------------------------------------------------------- @@ -43,7 +49,7 @@ test_classes (void) printf ("%-70s", "Testing H5Tget_class()"); - if (H5T_FIXED!=(type_class=H5Tget_class (H5T_NATIVE_INT))) { + if (H5T_INTEGER!=(type_class=H5Tget_class (H5T_NATIVE_INT))) { puts ("*FAILED*"); if (!isatty (1)) { AT (); @@ -131,6 +137,82 @@ test_copy (void) /*------------------------------------------------------------------------- + * Function: test_compound + * + * Purpose: Tests various things about compound data types. + * + * Return: Success: SUCCEED + * + * Failure: FAIL + * + * Programmer: Robb Matzke + * Wednesday, January 7, 1998 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +static herr_t +test_compound (void) +{ + complex_t tmp; + hid_t complex_id; + herr_t status; + + printf ("%-70s", "Testing compound data types"); + + /* Create the empty type */ + complex_id = H5Tcreate (H5T_COMPOUND, sizeof tmp); + if (complex_id<0) { + puts ("*FAILED*"); + if (!isatty (1)) { + AT (); + printf (" Cannot create empty compound data type.\n"); + } + goto error; + } + + /* Add a coupld fields */ + status = H5Tinsert (complex_id, "real", HOFFSET (tmp, re), + H5T_NATIVE_DOUBLE); + if (status<0) { + puts ("*FAILED*"); + if (!isatty (1)) { + AT (); + printf (" Cannot insert real component.\n"); + } + goto error; + } + + status = H5Tinsert (complex_id, "imaginary", HOFFSET (tmp, im), + H5T_NATIVE_DOUBLE); + if (status<0) { + puts ("*FAILED*"); + if (!isatty (1)) { + AT (); + printf (" Cannot insert imaginary component.\n"); + } + goto error; + } + + puts (" PASSED"); + + /* Just for debugging... */ + H5T_debug (H5Aatom_object (complex_id), stdout); + printf ("\n"); + + + return SUCCEED; + + error: + return FAIL; +} + + + + + +/*------------------------------------------------------------------------- * Function: main * * Purpose: Test the data type interface. @@ -159,6 +241,9 @@ main (void) status = test_copy (); nerrors += status<0 ? 1 : 0; + + status = test_compound (); + nerrors += status<0 ? 1 : 0; if (nerrors) { -- cgit v0.12