diff options
author | Robb Matzke <matzke@llnl.gov> | 1999-06-02 13:59:35 (GMT) |
---|---|---|
committer | Robb Matzke <matzke@llnl.gov> | 1999-06-02 13:59:35 (GMT) |
commit | e352d29757c1600e8d7c9ab7c42588b0873682a2 (patch) | |
tree | c4c5d53901b06c3ad42ff59454b15ff866b48633 | |
parent | 5992a71fe026ab86845e2f7c662a52fb53e4b0ca (diff) | |
download | hdf5-e352d29757c1600e8d7c9ab7c42588b0873682a2.zip hdf5-e352d29757c1600e8d7c9ab7c42588b0873682a2.tar.gz hdf5-e352d29757c1600e8d7c9ab7c42588b0873682a2.tar.bz2 |
[svn-r1292] Changes since 19990430
----------------------
Remove changes from CVS
./bin/release
Added a `--nocheck' switch which causes the script to not
check the contents of the MANIFEST file against CVS. This is
sometimes useful when you need to make a quick snapshot but
the MANIFEST file is not quite up to date.
./src/H5D.c
Removed warnings for unused variables
./src/H5Fprivate.h
Removed the WIN32 definition for `uint' and changed the data
type for `eof_written' from `uint' to `uintn'. Shouldn't this
really be `hbool_t'?
./src/H5Odtype.c
./src/H5T.c
./src/H5Tconv.c
./src/H5Tpkg.h
./src/H5Tpublic.h
./test/dtypes.c
./doc/html/H5.format.html
Added support for bitfields and opaque data types.
-rw-r--r-- | README | 2 | ||||
-rwxr-xr-x | bin/release | 37 | ||||
-rw-r--r-- | configure.in | 1 | ||||
-rw-r--r-- | doc/html/H5.format.html | 54 | ||||
-rw-r--r-- | src/H5D.c | 4 | ||||
-rw-r--r-- | src/H5Fprivate.h | 5 | ||||
-rw-r--r-- | src/H5Odtype.c | 106 | ||||
-rw-r--r-- | src/H5T.c | 174 | ||||
-rw-r--r-- | src/H5Tconv.c | 207 | ||||
-rw-r--r-- | src/H5Tpkg.h | 14 | ||||
-rw-r--r-- | src/H5Tpublic.h | 4 | ||||
-rw-r--r-- | test/dtypes.c | 127 |
12 files changed, 676 insertions, 59 deletions
@@ -1,4 +1,4 @@ -This is hdf5-1.1.105 released on Wed May 26 04:21:01 CDT 1999 +This is hdf5-1.1.106 released on Wed Jun 2 08:19:36 CDT 1999 Please refer to the INSTALL file for installation instructions. ------------------------------------------------------------------------------ diff --git a/bin/release b/bin/release index 5ab6e79..96addbd 100755 --- a/bin/release +++ b/bin/release @@ -4,6 +4,8 @@ # # -d DIR The name of the directory where the releas(es) should be # placed. By default, the directory is ./releases +# +# --nocheck Ignore errors in MANIFEST file. # # The other command-line options are the names of the programs to use # for compressing the resulting tar archive (if none are given then @@ -34,17 +36,36 @@ DEST=releases VERS=`perl bin/h5vers` test "$VERS" || exit 1 verbose=yes +check=yes # Command-line arguments -if [ "X$1" = "X-d" ]; then - DEST="$2" - shift +while [ -n "$1" ]; do + arg=$1 shift -fi -methods="$*" + case "$arg" in + -d) + DEST=$1 + shift + ;; + --nocheck) + check=no + ;; + -*) + echo "Unknown switch: $arg" 1>&2 + exit 1 + ;; + *) + methods="$methods $arg" + ;; + esac +done + +# Default method is tar if [ "X$methods" = "X" ]; then methods=tar fi + + test "$verbose" && echo "Releasing hdf5-$VERS to $DEST" 1>&2 if [ ! -d $DEST ]; then echo " Destination directory $DEST does not exist" 1>&2 @@ -94,7 +115,11 @@ The MANIFEST is out of date. Files marked with a minus sign (-) no longer exist; files marked with a plus sign (+) are CVS-managed but do not appear in the MANIFEST. Please remedy the situation and try again. EOF - exit 1 + if [ $check = yes ]; then + exit 1 + else + echo "Continuing anyway..." + fi fi # Create a manifest that contains only files for distribution. diff --git a/configure.in b/configure.in index ebfda0b..887ad5e 100644 --- a/configure.in +++ b/configure.in @@ -1,4 +1,3 @@ -n dnl Process this file with autoconf to produce configure. dnl dnl Copyright (C) 1997 National Center for Supercomputing Applications. diff --git a/doc/html/H5.format.html b/doc/html/H5.format.html index 2b0d70f..25d2cc7 100644 --- a/doc/html/H5.format.html +++ b/doc/html/H5.format.html @@ -2268,6 +2268,60 @@ </table> </center> + <p> + <center> + <table border cellpadding=4 width="80%"> + <caption align=top> + <b>Bit Field for Bitfield types (Class 4)</b> + </caption> + + <tr align=center> + <th width="10%">Bits</th> + <th width="90%">Meaning</th> + </tr> + + <tr valign=top> + <td>0</td> + <td><b>Byte Order.</b> If zero, byte order is little-endian; + otherwise, byte order is big endian.</td> + </tr> + + <tr valign=top> + <td>1, 2</td> + <td><b>Padding type.</b> Bit 1 is the lo_pad type and bit 2 + is the hi_pad type. If a datum has unused bits at either + end, then the lo_pad or hi_pad bit is copied to those + locations.</td> + </tr> + + <tr valign=top> + <td>3-23</td> + <td>Reserved (zero).</td> + </tr> + </table> + </center> + + <p> + <center> + <table border cellpadding=4 width="80%"> + <caption align=top> + <b>Properties for Bitfield types (Class 4)</b> + </caption> + + <tr align=center> + <th width="25%">Byte</th> + <th width="25%">Byte</th> + <th width="25%">Byte</th> + <th width="25%">Byte</th> + </tr> + + <tr align=center> + <td colspan=2>Bit Offset</td> + <td colspan=2>Bit Precision</td> + </tr> + </table> + </center> + <p>Data type examples are <a href="Datatypes.html">here</a>. @@ -1455,7 +1455,7 @@ H5D_read(H5D_t *dataset, const H5T_t *mem_type, const H5S_t *mem_space, H5T_bkg_t need_bkg; /*type of background buf*/ H5S_t *free_this_space=NULL; /*data space to free */ hbool_t must_convert; /*have to xfer the slow way*/ -#if defined(H5S_DEBUG) || defined(H5T_DEBUG) +#ifdef H5S_DEBUG H5_timer_t timer; #endif @@ -1827,7 +1827,7 @@ H5D_write(H5D_t *dataset, const H5T_t *mem_type, const H5S_t *mem_space, H5T_bkg_t need_bkg; /*type of background buf*/ H5S_t *free_this_space=NULL; /*data space to free */ hbool_t must_convert; /*have to xfer the slow way*/ -#if defined(H5S_DEBUG) || defined(H5T_DEBUG) +#ifdef H5S_DEBUG H5_timer_t timer; #endif diff --git a/src/H5Fprivate.h b/src/H5Fprivate.h index 21fb762..2110bd3 100644 --- a/src/H5Fprivate.h +++ b/src/H5Fprivate.h @@ -378,13 +378,10 @@ typedef struct H5F_low_class_t { * whether that storage is file, local memory, shared memory, network * distributed global memory, etc. */ -#if defined WIN32 -typedef UINT uint; -#endif typedef struct H5F_low_t { const H5F_low_class_t *type;/* What type of file is this? */ haddr_t eof; /* Address of logical end-of-file */ - uint eof_written; /* whether the last byte is written */ + uintn eof_written; /* whether the last byte is written */ union { /* File families */ diff --git a/src/H5Odtype.c b/src/H5Odtype.c index a0da1ac..5d3ac32 100644 --- a/src/H5Odtype.c +++ b/src/H5Odtype.c @@ -72,14 +72,16 @@ static intn interface_initialize_g = 0; * Monday, December 8, 1997 * * Modifications: - * + * Robb Matzke, Thursday, May 20, 1999 + * Added support for bitfields and opaque data types. *------------------------------------------------------------------------- */ static herr_t H5O_dtype_decode_helper(const uint8_t **pp, H5T_t *dt) { - uintn flags, perm_word, version; - intn i, j; + uintn flags, perm_word, version; + intn i, j; + size_t z; FUNC_ENTER(H5O_dtype_decode_helper, FAIL); @@ -111,6 +113,32 @@ H5O_dtype_decode_helper(const uint8_t **pp, H5T_t *dt) UINT16DECODE(*pp, dt->u.atomic.prec); break; + case H5T_BITFIELD: + /* + * Bit fields... + */ + dt->u.atomic.order = (flags & 0x1) ? H5T_ORDER_BE : H5T_ORDER_LE; + dt->u.atomic.lsb_pad = (flags & 0x2) ? H5T_PAD_ONE : H5T_PAD_ZERO; + dt->u.atomic.msb_pad = (flags & 0x4) ? H5T_PAD_ONE : H5T_PAD_ZERO; + UINT16DECODE(*pp, dt->u.atomic.offset); + UINT16DECODE(*pp, dt->u.atomic.prec); + break; + + case H5T_OPAQUE: + /* + * Opaque types... + */ + z = flags & 0xff; + assert(0==(z&0x7)); /*must be aligned*/ + if (NULL==(dt->u.opaque.tag=H5MM_malloc(z+1))) { + HRETURN_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, + "memory allocation failed"); + } + HDmemcpy(dt->u.opaque.tag, *pp, z); + dt->u.opaque.tag[z] = '\0'; + *pp += z; + break; + case H5T_STRING: /* * Character string types... @@ -283,7 +311,8 @@ H5O_dtype_decode_helper(const uint8_t **pp, H5T_t *dt) * Monday, December 8, 1997 * * Modifications: - * + * Robb Matzke, Thursday, May 20, 1999 + * Added support for bitfields and opaque types. *------------------------------------------------------------------------- */ static herr_t @@ -293,7 +322,7 @@ H5O_dtype_encode_helper(uint8_t **pp, const H5T_t *dt) uintn perm_word; char *hdr = (char *)*pp; intn i, j; - size_t n, z; + size_t n, z, aligned; FUNC_ENTER(H5O_dtype_encode_helper, FAIL); @@ -358,6 +387,61 @@ H5O_dtype_encode_helper(uint8_t **pp, const H5T_t *dt) UINT16ENCODE(*pp, dt->u.atomic.prec); break; + case H5T_BITFIELD: + /* + * Bitfield data types... + */ + switch (dt->u.atomic.order) { + case H5T_ORDER_LE: + break; /*nothing */ + case H5T_ORDER_BE: + flags |= 0x01; + break; + default: + HRETURN_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, + "byte order is not supported in file format yet"); + } + + switch (dt->u.atomic.lsb_pad) { + case H5T_PAD_ZERO: + break; /*nothing */ + case H5T_PAD_ONE: + flags |= 0x02; + break; + default: + HRETURN_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, + "bit padding is not supported in file format yet"); + } + + switch (dt->u.atomic.msb_pad) { + case H5T_PAD_ZERO: + break; /*nothing */ + case H5T_PAD_ONE: + flags |= 0x04; + break; + default: + HRETURN_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, + "bit padding is not supported in file format yet"); + } + + UINT16ENCODE(*pp, dt->u.atomic.offset); + UINT16ENCODE(*pp, dt->u.atomic.prec); + break; + + case H5T_OPAQUE: + /* + * Opaque data types... The tag is stored in a field which is a + * multiple of eight characters and null padded (not necessarily + * null terminated). + */ + z = HDstrlen(dt->u.opaque.tag); + aligned = (z+7) & 0xf8; + flags |= aligned; + HDmemcpy(*pp, dt->u.opaque.tag, MIN(z,aligned)); + for (n=MIN(z,aligned); n<aligned; n++) (*pp)[n] = 0; + *pp += aligned; + break; + case H5T_STRING: /* * Character string types... (not fully implemented) @@ -694,6 +778,14 @@ H5O_dtype_size(H5F_t *f, const void *mesg) ret_value += 4; break; + case H5T_BITFIELD: + ret_value += 4; + break; + + case H5T_OPAQUE: + ret_value += (HDstrlen(dt->u.opaque.tag)+7) & 0xf8; + break; + case H5T_FLOAT: ret_value += 12; break; @@ -964,6 +1056,10 @@ H5O_dtype_debug(H5F_t *f, const void *mesg, FILE *stream, fprintf(stream, "\n"); } + } else if (H5T_OPAQUE==dt->type) { + fprintf(stream, "%*s%-*s \"%s\"\n", indent, "", fwidth, + "Tag:", dt->u.opaque.tag); + } else { switch (dt->u.atomic.order) { case H5T_ORDER_LE: @@ -176,6 +176,7 @@ H5T_init_interface(void) { H5T_t *dt = NULL; hid_t fixedpt=-1, floatpt=-1, string=-1, compound=-1, enum_type=-1; + hid_t bitfield=-1; herr_t status; herr_t ret_value=FAIL; @@ -239,11 +240,7 @@ H5T_init_interface(void) H5F_addr_undef (&(dt->ent.header)); dt->type = H5T_OPAQUE; dt->size = 1; - dt->u.atomic.order = H5T_ORDER_NONE; - dt->u.atomic.offset = 0; - dt->u.atomic.prec = 8 * dt->size; - dt->u.atomic.lsb_pad = H5T_PAD_ZERO; - dt->u.atomic.msb_pad = H5T_PAD_ZERO; + dt->u.opaque.tag = H5MM_strdup(""); if ((H5T_NATIVE_OPAQUE_g = H5I_register(H5I_DATATYPE, dt)) < 0) { HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to initialize H5T layer"); @@ -702,6 +699,7 @@ H5T_init_interface(void) fixedpt = H5T_NATIVE_INT; floatpt = H5T_NATIVE_FLOAT; string = H5T_C_S1; + bitfield = H5T_STD_B8LE; compound = H5Tcreate(H5T_COMPOUND, 1); enum_type = H5Tcreate(H5T_ENUM, 1); status = 0; @@ -718,6 +716,9 @@ H5T_init_interface(void) status |= H5Tregister(H5T_PERS_SOFT, "s_s", string, string, H5T_conv_s_s); + status |= H5Tregister(H5T_PERS_SOFT, "b_b", + bitfield, bitfield, + H5T_conv_b_b); status |= H5Tregister(H5T_PERS_SOFT, "ibo", fixedpt, fixedpt, H5T_conv_order); @@ -1718,9 +1719,9 @@ H5Tget_order(hid_t type_id) "not a data type"); } if (dt->parent) dt = dt->parent; /*defer to parent*/ - if (H5T_COMPOUND==dt->type) { + if (H5T_COMPOUND==dt->type || H5T_OPAQUE==dt->type) { HRETURN_ERROR(H5E_DATATYPE, H5E_CANTINIT, H5T_ORDER_ERROR, - "operation not defined for compound data types"); + "operation not defined for specified data type"); } /* Order */ @@ -1771,9 +1772,9 @@ H5Tset_order(hid_t type_id, H5T_order_t order) "operation not allowed after members are defined"); } if (dt->parent) dt = dt->parent; /*defer to parent*/ - if (H5T_COMPOUND==dt->type) { + if (H5T_COMPOUND==dt->type || H5T_OPAQUE==dt->type) { HRETURN_ERROR(H5E_DATATYPE, H5E_CANTINIT, H5T_ORDER_ERROR, - "operation not defined for compound data types"); + "operation not defined for specified data type"); } /* Commit */ @@ -1820,9 +1821,9 @@ H5Tget_precision(hid_t type_id) HRETURN_ERROR(H5E_ARGS, H5E_BADTYPE, 0, "not a data type"); } if (dt->parent) dt = dt->parent; /*defer to parent*/ - if (H5T_COMPOUND==dt->type) { + if (H5T_COMPOUND==dt->type || H5T_OPAQUE==dt->type) { HRETURN_ERROR(H5E_DATATYPE, H5E_CANTINIT, H5T_ORDER_ERROR, - "operation not defined for compound data types"); + "operation not defined for specified data type"); } /* Precision */ @@ -1946,9 +1947,9 @@ H5Tget_offset(hid_t type_id) HRETURN_ERROR(H5E_ARGS, H5E_BADTYPE, 0, "not an atomic data type"); } if (dt->parent) dt = dt->parent; /*defer to parent*/ - if (H5T_COMPOUND==dt->type) { + if (H5T_COMPOUND==dt->type || H5T_OPAQUE==dt->type) { HRETURN_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, - "operation not defined for compound data types"); + "operation not defined for specified data type"); } /* Offset */ @@ -2065,9 +2066,9 @@ H5Tget_pad(hid_t type_id, H5T_pad_t *lsb/*out*/, H5T_pad_t *msb/*out*/) HRETURN_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data type"); } if (dt->parent) dt = dt->parent; /*defer to parent*/ - if (H5T_COMPOUND==dt->type) { + if (H5T_COMPOUND==dt->type || H5T_OPAQUE==dt->type) { HRETURN_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, - "operation not defined for compound data types"); + "operation not defined for specified data type"); } /* Get values */ @@ -2119,9 +2120,9 @@ H5Tset_pad(hid_t type_id, H5T_pad_t lsb, H5T_pad_t msb) "operation not allowed after members are defined"); } if (dt->parent) dt = dt->parent; /*defer to parent*/ - if (H5T_COMPOUND==dt->type) { + if (H5T_COMPOUND==dt->type || H5T_OPAQUE==dt->type) { HRETURN_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, - "operation not defined for compound data types"); + "operation not defined for specified data type"); } /* Commit */ @@ -3603,7 +3604,94 @@ H5Tenum_valueof(hid_t type, const char *name, void *value/*out*/) } FUNC_LEAVE(SUCCEED); } + + +/*------------------------------------------------------------------------- + * Function: H5Tset_tag + * + * Purpose: Tag an opaque datatype with a unique ASCII identifier. + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Robb Matzke + * Thursday, May 20, 1999 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +herr_t +H5Tset_tag(hid_t type_id, const char *tag) +{ + H5T_t *dt=NULL; + + FUNC_ENTER(H5Tset_tag, FAIL); + H5TRACE2("e","is",type_id,tag); + + /* Check args */ + if (H5I_DATATYPE != H5I_get_type(type_id) || + NULL == (dt = H5I_object(type_id))) { + HRETURN_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data type"); + } + if (H5T_STATE_TRANSIENT!=dt->state) { + HRETURN_ERROR(H5E_ARGS, H5E_CANTINIT, FAIL, "data type is read-only"); + } + if (H5T_OPAQUE!=dt->type) { + HRETURN_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not an opaque data type"); + } + if (!tag) { + HRETURN_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no tag"); + } + + /* Commit */ + H5MM_xfree(dt->u.opaque.tag); + dt->u.opaque.tag = H5MM_strdup(tag); + FUNC_LEAVE(SUCCEED); +} + + +/*------------------------------------------------------------------------- + * Function: H5Tget_tag + * + * Purpose: Get tha tag associated with an opaque datatype. + * + * Return: A pointer to an allocated string. The caller should free + * the string. NULL is returned for errors. + * + * Programmer: Robb Matzke + * Thursday, May 20, 1999 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +char * +H5Tget_tag(hid_t type_id) +{ + H5T_t *dt=NULL; + char *ret_value=NULL; + + FUNC_ENTER(H5Tget_tag, NULL); + + /* Check args */ + if (H5I_DATATYPE != H5I_get_type(type_id) || + NULL == (dt = H5I_object(type_id))) { + HRETURN_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "not a data type"); + } + if (dt->parent) dt = dt->parent; /*defer to parent*/ + if (H5T_OPAQUE != dt->type) { + HRETURN_ERROR(H5E_DATATYPE, H5E_CANTINIT, NULL, + "operation not defined for data type class"); + } + /* result */ + if (NULL==(ret_value=H5MM_strdup(dt->u.opaque.tag))) { + HRETURN_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, + "memory allocation failed"); + } + FUNC_LEAVE(ret_value); +} + /*------------------------------------------------------------------------- * Function: H5Tregister @@ -4104,10 +4192,10 @@ H5T_create(H5T_class_t type, size_t size) case H5T_TIME: case H5T_STRING: case H5T_BITFIELD: - case H5T_OPAQUE: HRETURN_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, NULL, "type class is not appropriate - use H5Tcopy()"); + case H5T_OPAQUE: case H5T_COMPOUND: if (NULL==(dt = H5MM_calloc(sizeof(H5T_t)))) { HRETURN_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL, @@ -4304,6 +4392,9 @@ H5T_open_oid (H5G_entry_t *ent) * Robb Matzke, 22 Dec 1998 * Now able to copy enumeration data types. * + * Robb Matzke, 20 May 1999 + * Now able to copy opaque types. + * *------------------------------------------------------------------------- */ H5T_t * @@ -4410,6 +4501,12 @@ H5T_copy(const H5T_t *old_dt, H5T_copy_t method) s = old_dt->u.enumer.name[i]; new_dt->u.enumer.name[i] = H5MM_xstrdup(s); } + + } else if (H5T_OPAQUE == new_dt->type) { + /* + * Copy the tag name. + */ + new_dt->u.opaque.tag = HDstrdup(new_dt->u.opaque.tag); } FUNC_LEAVE(new_dt); @@ -4550,6 +4647,8 @@ H5T_lock (H5T_t *dt, hbool_t immutable) * Robb Matzke, 1999-04-27 * This function fails if the datatype state is IMMUTABLE. * + * Robb Matzke, 1999-05-20 + * Closes opaque types also. *------------------------------------------------------------------------- */ herr_t @@ -4601,6 +4700,11 @@ H5T_close(H5T_t *dt) H5MM_xfree(dt); break; + case H5T_OPAQUE: + H5MM_xfree(dt->u.opaque.tag); + H5MM_xfree(dt); + break; + default: H5MM_xfree(dt); } @@ -4639,7 +4743,7 @@ H5T_is_atomic(const H5T_t *dt) FUNC_ENTER(H5T_is_atomic, FAIL); assert(dt); - if (H5T_COMPOUND!=dt->type && H5T_ENUM!=dt->type) { + if (H5T_COMPOUND!=dt->type && H5T_ENUM!=dt->type && H5T_OPAQUE!=dt->type) { ret_value = TRUE; } else { ret_value = FALSE; @@ -4718,6 +4822,7 @@ H5T_set_size(H5T_t *dt, size_t size) case H5T_TIME: case H5T_BITFIELD: case H5T_ENUM: + case H5T_OPAQUE: /* nothing to check */ break; @@ -4740,17 +4845,6 @@ H5T_set_size(H5T_t *dt, size_t size) } 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); } @@ -4845,9 +4939,9 @@ H5T_set_precision(H5T_t *dt, size_t prec) } dt->size = dt->parent->size; } else { - if (H5T_COMPOUND==dt->type) { + if (H5T_COMPOUND==dt->type || H5T_OPAQUE==dt->type) { HRETURN_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, - "operation not defined for compound data types"); + "operation not defined for specified data type"); } else if (H5T_ENUM==dt->type) { /*nothing*/ @@ -4865,7 +4959,6 @@ H5T_set_precision(H5T_t *dt, size_t prec) case H5T_INTEGER: case H5T_TIME: case H5T_BITFIELD: - case H5T_OPAQUE: /* nothing to check */ break; @@ -4961,9 +5054,9 @@ H5T_set_offset(H5T_t *dt, size_t offset) } dt->size = dt->parent->size; } else { - if (H5T_COMPOUND==dt->type) { + if (H5T_COMPOUND==dt->type || H5T_OPAQUE==dt->type) { HRETURN_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, - "operation not defined for compound data types"); + "operation not defined for specified data type"); } else if (H5T_ENUM==dt->type) { /*nothing*/ } else { @@ -5574,6 +5667,8 @@ H5T_enum_valueof(H5T_t *dt, const char *name, void *value/*out*/) * Robb Matzke, 22 Dec 1998 * Able to compare enumeration data types. * + * Robb Matzke, 20 May 1999 + * Compares bitfields and opaque types. *------------------------------------------------------------------------- */ intn @@ -5758,6 +5853,9 @@ H5T_cmp(const H5T_t *dt1, const H5T_t *dt2) if (tmp>0) HGOTO_DONE(1); } + } else if (H5T_OPAQUE==dt1->type) { + HGOTO_DONE(HDstrcmp(dt1->u.opaque.tag,dt2->u.opaque.tag)); + } else { /* * Atomic data types... @@ -6425,8 +6523,7 @@ H5T_debug(H5T_t *dt, FILE *stream) s1 = "sign?"; break; } - if (s1) - fprintf(stream, ", %s", s1); + if (s1) fprintf(stream, ", %s", s1); break; case H5T_FLOAT: @@ -6501,6 +6598,9 @@ H5T_debug(H5T_t *dt, FILE *stream) } } fprintf(stream, "\n"); + + } else if (H5T_OPAQUE==dt->type) { + fprintf(stream, ", tag=\"%s\"", dt->u.opaque.tag); } else { /* Unknown */ diff --git a/src/H5Tconv.c b/src/H5Tconv.c index 7aad1e1..fe4e6c3 100644 --- a/src/H5Tconv.c +++ b/src/H5Tconv.c @@ -496,6 +496,213 @@ H5T_conv_order(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, } /*------------------------------------------------------------------------- + * Function: H5T_conv_b_b + * + * Purpose: Convert from one bitfield to any other bitfield. + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Robb Matzke + * Thursday, May 20, 1999 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +herr_t +H5T_conv_b_b(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, + void *_buf, void UNUSED *background) +{ + uint8_t *buf = (uint8_t*)_buf; + H5T_t *src=NULL, *dst=NULL; /*source and dest data types */ + intn direction; /*direction of traversal */ + size_t elmtno; /*element number */ + size_t olap; /*num overlapping elements */ + size_t half_size; /*1/2 of total size for swapping*/ + uint8_t *s, *sp, *d, *dp; /*source and dest traversal ptrs*/ + uint8_t dbuf[256]; /*temp destination buffer */ + size_t msb_pad_offset; /*offset for dest MSB padding */ + size_t i; + + FUNC_ENTER(H5T_conv_b_b, FAIL); + + switch(cdata->command) { + case H5T_CONV_INIT: + /* Capability query */ + if (H5I_DATATYPE != H5I_get_type(src_id) || + NULL == (src = H5I_object(src_id)) || + H5I_DATATYPE != H5I_get_type(dst_id) || + NULL == (dst = H5I_object(dst_id))) { + HRETURN_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data type"); + } + if (H5T_ORDER_LE!=src->u.atomic.order && + H5T_ORDER_BE!=src->u.atomic.order) { + HRETURN_ERROR (H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, + "unsupported byte order"); + } + if (H5T_ORDER_LE!=dst->u.atomic.order && + H5T_ORDER_BE!=dst->u.atomic.order) { + HRETURN_ERROR (H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, + "unsupported byte order"); + } + cdata->need_bkg = H5T_BKG_NO; + break; + + case H5T_CONV_FREE: + break; + + case H5T_CONV_CONV: + /* Get the data types */ + if (H5I_DATATYPE!=H5I_get_type (src_id) || + NULL==(src=H5I_object (src_id)) || + H5I_DATATYPE!=H5I_get_type (dst_id) || + NULL==(dst=H5I_object (dst_id))) { + HRETURN_ERROR (H5E_ARGS, H5E_BADTYPE, FAIL, "not a data type"); + } + + /* + * Do we process the values from beginning to end or vice versa? Also, + * how many of the elements have the source and destination areas + * overlapping? + */ + if (src->size==dst->size) { + sp = dp = (uint8_t*)buf; + direction = 1; + olap = nelmts; + } else if (src->size>=dst->size) { + double olap_d = HDceil((double)(dst->size)/ + (double)(src->size-dst->size)); + + olap = (size_t)olap_d; + sp = dp = (uint8_t*)buf; + direction = 1; + } else { + double olap_d = HDceil((double)(src->size)/ + (double)(dst->size-src->size)); + olap = (size_t)olap_d; + sp = (uint8_t*)buf + (nelmts-1) * src->size; + dp = (uint8_t*)buf + (nelmts-1) * dst->size; + direction = -1; + } + + /* The conversion loop */ + for (elmtno=0; elmtno<nelmts; elmtno++) { + + /* + * If the source and destination buffers overlap then use a + * temporary buffer for the destination. + */ + if (direction>0) { + s = sp; + d = elmtno<olap ? dbuf : dp; + } else { + s = sp; + d = elmtno+olap >= nelmts ? dbuf : dp; + } +#ifndef NDEBUG + /* I don't quite trust the overlap calculations yet --rpm */ + if (d==dbuf) { + assert ((dp>=sp && dp<sp+src->size) || + (sp>=dp && sp<dp+dst->size)); + } else { + assert ((dp<sp && dp+dst->size<=sp) || + (sp<dp && sp+src->size<=dp)); + } +#endif + + /* + * Put the data in little endian order so our loops aren't so + * complicated. We'll do all the conversion stuff assuming + * little endian and then we'll fix the order at the end. + */ + if (H5T_ORDER_BE==src->u.atomic.order) { + half_size = src->size/2; + for (i=0; i<half_size; i++) { + uint8_t tmp = s[src->size-(i+1)]; + s[src->size-(i+1)] = s[i]; + s[i] = tmp; + } + } + + /* + * Copy the significant part of the value. If the source is larger + * than the destination then invoke the overflow function or copy + * as many bits as possible. + */ + if (src->u.atomic.prec>dst->u.atomic.prec) { + if (!H5T_overflow_g || + (H5T_overflow_g)(src_id, dst_id, s, d)<0) { + H5T_bit_copy(d, dst->u.atomic.offset, + s, src->u.atomic.offset, dst->u.atomic.prec); + } + } else { + H5T_bit_copy(d, dst->u.atomic.offset, + s, src->u.atomic.offset, + src->u.atomic.prec); + } + + /* + * Fill the destination padding areas. + */ + switch (dst->u.atomic.lsb_pad) { + case H5T_PAD_ZERO: + H5T_bit_set(d, 0, dst->u.atomic.offset, FALSE); + break; + case H5T_PAD_ONE: + H5T_bit_set(d, 0, dst->u.atomic.offset, TRUE); + break; + default: + HRETURN_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, + "unsupported LSB padding"); + } + msb_pad_offset = dst->u.atomic.offset + dst->u.atomic.prec; + switch (dst->u.atomic.msb_pad) { + case H5T_PAD_ZERO: + H5T_bit_set(d, msb_pad_offset, 8*dst->size-msb_pad_offset, + FALSE); + break; + case H5T_PAD_ONE: + H5T_bit_set(d, msb_pad_offset, 8*dst->size-msb_pad_offset, + TRUE); + break; + default: + HRETURN_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, + "unsupported MSB padding"); + } + + /* + * Put the destination in the correct byte order. See note at + * beginning of loop. + */ + if (H5T_ORDER_BE==dst->u.atomic.order) { + half_size = dst->size/2; + for (i=0; i<half_size; i++) { + uint8_t tmp = d[dst->size-(i+1)]; + d[dst->size-(i+1)] = d[i]; + d[i] = tmp; + } + } + + /* + * If we had used a temporary buffer for the destination then we + * should copy the value to the true destination buffer. + */ + if (d==dbuf) HDmemcpy (dp, d, dst->size); + sp += direction * src->size; + dp += direction * dst->size; + } + + break; + + default: + HRETURN_ERROR (H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, + "unknown conversion command"); + } + + FUNC_LEAVE (SUCCEED); +} + +/*------------------------------------------------------------------------- * Function: H5T_conv_struct_init * * Purpose: Initialize the `priv' field of `cdata' with conversion diff --git a/src/H5Tpkg.h b/src/H5Tpkg.h index f0906d7..ac37243 100644 --- a/src/H5Tpkg.h +++ b/src/H5Tpkg.h @@ -53,11 +53,11 @@ typedef struct H5T_atomic_t { struct { H5T_cset_t cset; /*character set */ H5T_str_t pad; /*space or null padding of extra bytes */ - } s; + } s; /*string types */ struct { - H5R_type_t rtype; /* Type of reference stored */ - } r; + H5R_type_t rtype; /*type of reference stored */ + } r; /*reference types */ } u; } H5T_atomic_t; @@ -85,6 +85,11 @@ typedef struct H5T_enum_t { char **name; /*array of symbol names */ } H5T_enum_t; +/* An opaque data type */ +typedef struct H5T_opaque_t { + char *tag; /*short type description string */ +} H5T_opaque_t; + typedef enum H5T_state_t { H5T_STATE_TRANSIENT, /*type is a modifiable transient */ H5T_STATE_RDONLY, /*transient, not modifiable, closable*/ @@ -104,6 +109,7 @@ struct H5T_t { H5T_atomic_t atomic; /*an atomic data type */ H5T_compnd_t compnd; /*a compound data type (struct) */ H5T_enum_t enumer; /*an enumeration type (enum) */ + H5T_opaque_t opaque; /*an opaque data type */ } u; }; @@ -171,6 +177,8 @@ __DLL__ herr_t H5T_conv_f_f(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, void *_buf, void *bkg); __DLL__ herr_t H5T_conv_s_s(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, void *_buf, void *bkg); +__DLL__ herr_t H5T_conv_b_b(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, + size_t nelmts, void *_buf, void *bkg); __DLL__ herr_t H5T_conv_schar_uchar(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, diff --git a/src/H5Tpublic.h b/src/H5Tpublic.h index e3b6248..4b76131 100644 --- a/src/H5Tpublic.h +++ b/src/H5Tpublic.h @@ -401,6 +401,10 @@ __DLL__ hid_t H5Tenum_nameof(hid_t type, void *value, char *name/*out*/, __DLL__ hid_t H5Tenum_valueof(hid_t type, const char *name, void *value/*out*/); +/* Operations defined on opaque data types */ +__DLL__ herr_t H5Tset_tag(hid_t type, const char *tag); +__DLL__ char *H5Tget_tag(hid_t type); + /* Querying property values */ __DLL__ hid_t H5Tget_super(hid_t type); __DLL__ H5T_class_t H5Tget_class(hid_t type_id); diff --git a/test/dtypes.c b/test/dtypes.c index 5f1e25a..eaff31d 100644 --- a/test/dtypes.c +++ b/test/dtypes.c @@ -1133,6 +1133,131 @@ test_conv_enum_1(void) /*------------------------------------------------------------------------- + * Function: test_conv_bitfield + * + * Purpose: Test bitfield conversions. + * + * Return: Success: 0 + * + * Failure: -1 + * + * Programmer: Robb Matzke + * Thursday, May 20, 1999 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +static int +test_conv_bitfield(void) +{ + unsigned char buf[4]; + hid_t st=-1, dt=-1; + + TESTING("bitfield conversions"); + + /* + * First test a simple bitfield conversion: + * 1010101010101010 + * ________________1010101010101010 + */ + st = H5Tcopy(H5T_STD_B16LE); + dt = H5Tcopy(H5T_STD_B32LE); + buf[0] = buf[1] = 0xAA; + buf[2] = buf[3] = 0x55; /*irrelevant*/ + if (H5Tconvert(st, dt, 1, buf, NULL)<0) goto error; + if (buf[0]!=0xAA || buf[1]!=0xAA || buf[2]!=0 || buf[3]!=0) { + FAILED(); + printf(" s=0xaaaa, d=0x%02x%02x%02x%02x (test 1)\n", + buf[3], buf[2], buf[1], buf[0]); + goto error; + } + + /* + * Test2: Offset a 12-byte value in the middle of a 16 and 32 byte + * field. + * __10 1010 1010 10__ + * ____ ____ __10 1010 1010 10__ ____ ____ + */ + H5Tset_precision(st, 12); + H5Tset_offset(st, 2); + H5Tset_precision(dt, 12); + H5Tset_offset(dt, 10); + buf[0] = 0xA8; buf[1] = 0x2A; buf[2] = buf[3] = 0; + if (H5Tconvert(st, dt, 1, buf, NULL)<0) goto error; + if (buf[0]!=0 || buf[1]!=0xA8 || buf[2]!=0x2A || buf[3]!=0) { + FAILED(); + printf(" s=0x2AA8 d=0x%02x%02x%02x%02x (test 2)\n", + buf[3], buf[2], buf[1], buf[0]); + goto error; + } + + /* + * Same as previous test except unused bits of the destination will + * be filled with ones. + */ + H5Tset_pad(dt, H5T_PAD_ONE, H5T_PAD_ONE); + buf[0] = 0xA8; buf[1] = 0x2A; buf[2] = buf[3] = 0; + if (H5Tconvert(st, dt, 1, buf, NULL)<0) goto error; + if (buf[0]!=0xff || buf[1]!=0xAB || buf[2]!=0xEA || buf[3]!=0xff) { + FAILED(); + printf(" s=0x2AA8 d=0x%02x%02x%02x%02x (test 3)\n", + buf[3], buf[2], buf[1], buf[0]); + goto error; + } + + H5Tclose(st); + H5Tclose(dt); + PASSED(); + reset_hdf5(); + return 0; + + error: + H5Tclose(st); + H5Tclose(dt); + reset_hdf5(); + return -1; +} + + +/*------------------------------------------------------------------------- + * Function: test_opaque + * + * Purpose: Test opaque datatypes + * + * Return: Success: 0 + * + * Failure: -1 + * + * Programmer: Robb Matzke + * Thursday, May 20, 1999 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +static int +test_opaque(void) +{ + hid_t st=-1, dt=-1; + + TESTING("opaque datatypes"); + + if ((st=H5Tcreate(H5T_OPAQUE, 4))<0) goto error; + + H5Tclose(st); + PASSED(); + return 0; + + error: + if (st>0) H5Tclose(st); + if (dt>0) H5Tclose(dt); + FAILED(); + return -1; +} + + +/*------------------------------------------------------------------------- * Function: test_conv_int * * Purpose: Test atomic number conversions. @@ -3016,6 +3141,8 @@ main(void) nerrors += test_conv_str_2()<0 ? 1 : 0; nerrors += test_conv_int ()<0 ? 1 : 0; nerrors += test_conv_enum_1()<0 ? 1 : 0; + nerrors += test_conv_bitfield()<0 ? 1 : 0; + nerrors += test_opaque()<0 ? 1 : 0; /* Does floating point overflow generate a SIGFPE? */ generates_sigfpe(); |