summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/H5Odtype.c18
-rw-r--r--src/H5Oprivate.h4
-rw-r--r--src/H5T.c1472
-rw-r--r--src/H5Tpkg.h4
-rw-r--r--src/H5Tprivate.h10
-rw-r--r--src/H5Tpublic.h93
-rw-r--r--src/H5detect.c12
-rw-r--r--test/dtypes.c87
8 files changed, 1607 insertions, 93 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<epos+esize) {
+ HRETURN_ERROR (H5E_ARGS, H5E_BADVALUE, FAIL,
+ "sign bit appears within exponent field");
+ }
+ if (spos>=mpos && spos<mpos+msize) {
+ HRETURN_ERROR (H5E_ARGS, H5E_BADVALUE, FAIL,
+ "sign bit appears within mantissa field");
+ }
+ if ((mpos<epos && mpos+msize>epos) ||
+ (epos<mpos && epos+esize>mpos)) {
+ 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.
@@ -311,82 +1214,198 @@ H5Tget_nmembers (hid_t type_id)
/*-------------------------------------------------------------------------
- * Function: H5Tget_class
+ * Function: H5Tget_member_name
*
- * Purpose: Returns the data type class identifier for data type TYPE_ID.
+ * 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: One of the non-negative data type class
- * constants.
+ * Return: Success: Ptr to a string allocated with malloc(). The
+ * caller is responsible for freeing the string.
*
- * Failure: H5T_NO_CLASS (-1)
+ * Failure: NULL
*
* Programmer: Robb Matzke
- * Monday, December 8, 1997
+ * Wednesday, January 7, 1998
*
* Modifications:
*
*-------------------------------------------------------------------------
*/
-H5T_class_t
-H5Tget_class (hid_t type_id)
+char *
+H5Tget_member_name (hid_t type_id, int membno)
{
H5T_t *dt = NULL;
-
- FUNC_ENTER (H5Tget_class, FAIL);
+ 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))) {
- 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, NULL, "not a compound data type");
+ }
+ if (membno<0 || membno>=dt->u.compnd.nmembs) {
+ HRETURN_ERROR (H5E_ARGS, H5E_BADVALUE, NULL, "invalid member number");
}
- FUNC_LEAVE (dt->type);
+ s = H5MM_xstrdup (dt->u.compnd.memb[membno].name);
+ FUNC_LEAVE (s);
}
/*-------------------------------------------------------------------------
- * Function: H5Tget_size
+ * Function: H5Tget_member_offset
*
- * Purpose: Determines the total size of a data type in bytes.
+ * Purpose: Returns the byte offset of the beginning of a member with
+ * respect to the beginning of the compound data type datum.
*
- * 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: Byte offset.
*
- * Failure: 0 (valid data types are never zero size)
+ * 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
- * Monday, December 8, 1997
+ * Wednesday, January 7, 1998
*
* Modifications:
*
*-------------------------------------------------------------------------
*/
size_t
-H5Tget_size (hid_t type_id)
+H5Tget_member_offset (hid_t type_id, int membno)
{
H5T_t *dt = NULL;
- size_t size;
-
- FUNC_ENTER (H5Tget_size, 0);
+ size_t offset = 0;
+
+ FUNC_ENTER (H5Tget_member_offset, 0);
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, 0, "not a compound data type");
+ }
+ if (membno<0 || membno>=dt->u.compnd.nmembs) {
+ HRETURN_ERROR (H5E_ARGS, H5E_BADVALUE, 0, "invalid member number");
}
- /* size */
- size = H5T_get_size (dt);
+ offset = dt->u.compnd.memb[membno].offset;
+ FUNC_LEAVE (offset);
+}
- FUNC_LEAVE (size);
+
+/*-------------------------------------------------------------------------
+ * Function: H5Tget_member_dims
+ *
+ * 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: A value between zero and four, inclusive.
+ *
+ * Failure: -1
+ *
+ * Programmer: Robb Matzke
+ * Wednesday, January 7, 1998
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+int
+H5Tget_member_dims (hid_t type_id, int membno,
+ int dims[]/*out*/, int perm[]/*out*/)
+{
+ H5T_t *dt = NULL;
+ 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)) ||
+ 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");
+ }
+
+ ndims = dt->u.compnd.memb[membno].ndims;
+ for (i=0; i<ndims; i++) {
+ if (dims[i]) dims[i] = dt->u.compnd.memb[membno].dim[i];
+ if (perm[i]) perm[i] = dt->u.compnd.memb[membno].perm[i];
+ }
+
+ FUNC_LEAVE (ndims);
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5Tget_member_type
+ *
+ * Purpose: Returns the data type of the specified member. The caller
+ * should invoke H5Tclose() to release resources associated with
+ * the 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: FAIL
+ *
+ * Programmer: Robb Matzke
+ * Wednesday, January 7, 1998
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+hid_t
+H5Tget_member_type (hid_t type_id, int membno)
+{
+ 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)) ||
+ 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");
+ }
+
+ 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; i<parent->u.compnd.nmembs; i++) {
+ if ((offset<parent->u.compnd.memb[i].offset &&
+ offset+member->size>parent->u.compnd.memb[i].offset) ||
+ (parent->u.compnd.memb[i].offset<offset &&
+ parent->u.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; i<dt->u.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; i<dt->u.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; j<i; j++) {
+ if (dt->u.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; i<dt->u.compnd.nmembs-1; i++) {
+ assert (dt->u.compnd.memb[i].offset<dt->u.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; i<dt->u.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; j<dt->u.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; i<nd; i++) {
- printf ("hid_t H5T_NATIVE_%s;\n", d[i].varname);
+ printf ("hid_t H5T_NATIVE_%s_g = FAIL;\n", d[i].varname);
}
/* Function declaration */
@@ -318,7 +318,7 @@ H5T_init (void)\n\
dt->u.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 <stdio.h>
#include <unistd.h>
+#include <H5Tprivate.h>
+
#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) {