diff options
author | Robb Matzke <matzke@llnl.gov> | 1998-06-12 17:31:06 (GMT) |
---|---|---|
committer | Robb Matzke <matzke@llnl.gov> | 1998-06-12 17:31:06 (GMT) |
commit | dd58a3ec29a061f42609669ff633c0763f834af9 (patch) | |
tree | 82c95ae74cc9730a1920862f183cd98f8371e0f5 /src | |
parent | 674198fcc7454b962670010b0e3b120fa792f216 (diff) | |
download | hdf5-dd58a3ec29a061f42609669ff633c0763f834af9.zip hdf5-dd58a3ec29a061f42609669ff633c0763f834af9.tar.gz hdf5-dd58a3ec29a061f42609669ff633c0763f834af9.tar.bz2 |
[svn-r425] Changes since 19980610
----------------------
THIS CHECKIN IS FOR QUINCEY -- NOT EVERYTHING WORKS (but it compiles)
MOST OF THE CHANGES ARE FOR BETTER TYPE CONVERSION IN THE NEXT ALPHA
./MANIFEST
./src/H5Tbit.c NEW
./src/Makefile.in
Bit vector operations (not done yet)
./configure.in
Added -lm to the library list, needed by bit-vector operations
and conversion functions.
Removed vestiges of PARALLEL_SRC no longer used by the
makefiles. Albert came up with a better way (that actually
works :-)
./src/H5D.c
No code changes. Split a couple of long lines, refilled a
couple multi-line comments.
./src/H5T.c
./src/H5Tpublic.h
Fixed a bug reported by Jim Reus regarding conversion of
compound data types whose members require conversions which
are satisfied by as-yet unregistered soft conversion
functions.
Added H5T_IEEE architecture, but the funny-looking integer
types will be changed to H5T_BE_ and H5T_LE_ architectures
with the type names changed to match the H5T_NATIVE_ integers.
Added an H5Tconvert() but it hasn't been documented or tested
yet.
./src/H5Tconv.c
./src/H5Tpkg.h
Registered conversion functions integer->integer (a general
case) and integer->float (for a specific case). The
integer->integer conversion depends on the bitvector
operations which aren't finished yet and the int->float
conversion hasn't been retested since it was borrowed from
AIO. Don't look at them yet, they're ugly :-)
./src/H5detect.c
Fixed a typo which caused the msb_pad field of an atomic type
to not be initialized.
./test/dtypes.c
Added a test for number conversions but it's commented out
until the conversion stuff is truly working.
Diffstat (limited to 'src')
-rw-r--r-- | src/H5D.c | 46 | ||||
-rw-r--r-- | src/H5T.c | 382 | ||||
-rw-r--r-- | src/H5Tbit.c | 154 | ||||
-rw-r--r-- | src/H5Tconv.c | 679 | ||||
-rw-r--r-- | src/H5Tpkg.h | 18 | ||||
-rw-r--r-- | src/H5Tpublic.h | 44 | ||||
-rw-r--r-- | src/H5detect.c | 2 | ||||
-rw-r--r-- | src/Makefile.in | 12 |
8 files changed, 1272 insertions, 65 deletions
@@ -1182,14 +1182,15 @@ H5D_read(H5D_t *dataset, const H5T_t *mem_type, const H5S_t *mem_space, * Check if collective data transfer requested. */ if (xfer_parms->xfer_mode == H5D_XFER_COLLECTIVE){ - /* verify that the file can support collective access. */ - /* The check may not be necessarily since collective access */ - /* can always be simulated by independent access. */ - /* Nevertheless, must check driver is MPIO before using those */ - /* access_mode which exists only for MPIO case. */ + /* + * Verify that the file can support collective access. The check may + * not be necessarily since collective access can always be simulated + * by independent access. Nevertheless, must check driver is MPIO + * before using those access_mode which exists only for MPIO case. + */ if (dataset->ent.file->shared->access_parms->driver != H5F_LOW_MPIO) HGOTO_ERROR (H5E_DATASET, H5E_UNSUPPORTED, FAIL, - "collective access not permissible"); + "collective access not permissible"); } #endif /*HAVE_PARALLEL*/ @@ -1232,11 +1233,11 @@ H5D_read(H5D_t *dataset, const H5T_t *mem_type, const H5S_t *mem_space, if (H5T_conv_noop==tconv_func && NULL!=sconv_func->read) { status = (sconv_func->read)(dataset->ent.file, &(dataset->layout), - &(dataset->create_parms->compress), - &(dataset->create_parms->efl), - H5T_get_size (dataset->type), file_space, - mem_space, xfer_parms->xfer_mode, - buf/*out*/); + &(dataset->create_parms->compress), + &(dataset->create_parms->efl), + H5T_get_size (dataset->type), + file_space, mem_space, + xfer_parms->xfer_mode, buf/*out*/); if (status>=0) goto succeed; HGOTO_ERROR (H5E_DATASET, H5E_READERROR, FAIL, "collective read failed"); @@ -1469,14 +1470,15 @@ H5D_write(H5D_t *dataset, const H5T_t *mem_type, const H5S_t *mem_space, * Check if collective data transfer requested. */ if (xfer_parms->xfer_mode == H5D_XFER_COLLECTIVE){ - /* verify that the file can support collective access. */ - /* The check may not be necessarily since collective access */ - /* can always be simulated by independent access. */ - /* Nevertheless, must check driver is MPIO before using those */ - /* access_mode which exists only for MPIO case. */ + /* + * Verify that the file can support collective access. The check may + * not be necessarily since collective access can always be simulated + * by independent access. Nevertheless, must check driver is MPIO + * before using those access_mode which exists only for MPIO case. + */ if (dataset->ent.file->shared->access_parms->driver != H5F_LOW_MPIO) HGOTO_ERROR (H5E_DATASET, H5E_UNSUPPORTED, FAIL, - "collective access not permissible"); + "collective access not permissible"); } #endif /*HAVE_PARALLEL*/ @@ -1518,14 +1520,16 @@ H5D_write(H5D_t *dataset, const H5T_t *mem_type, const H5S_t *mem_space, /* Supports only no conversion, type or space, for now. */ if (H5T_conv_noop==tconv_func && NULL!=sconv_func->write) { - status = (sconv_func->write)(dataset->ent.file, &(dataset->layout), + status = (sconv_func->write)(dataset->ent.file, + &(dataset->layout), &(dataset->create_parms->compress), &(dataset->create_parms->efl), - H5T_get_size (dataset->type), file_space, - mem_space, xfer_parms->xfer_mode, buf); + H5T_get_size (dataset->type), + file_space, mem_space, + xfer_parms->xfer_mode, buf); if (status>=0) goto succeed; HGOTO_ERROR (H5E_DATASET, H5E_WRITEERROR, FAIL, - "collective write failed"); + "collective write failed"); } } #endif /*HAVE_PARALLEL*/ @@ -30,7 +30,7 @@ static intn interface_initialize_g = FALSE; #define INTERFACE_INIT H5T_init_interface static void H5T_term_interface(void); -/* Predefined types */ +/* Predefined native types */ hid_t H5T_NATIVE_CHAR_g = FAIL; hid_t H5T_NATIVE_UCHAR_g = FAIL; hid_t H5T_NATIVE_SHORT_g = FAIL; @@ -58,10 +58,29 @@ hid_t H5T_NATIVE_STRING_g = FAIL; hid_t H5T_NATIVE_BITFIELD_g = FAIL; hid_t H5T_NATIVE_OPAQUE_g = FAIL; +/* Predefined standard types */ +hid_t H5T_IEEE_R32LE_g = FAIL; +hid_t H5T_IEEE_R32BE_g = FAIL; +hid_t H5T_IEEE_R64LE_g = FAIL; +hid_t H5T_IEEE_R64BE_g = FAIL; +hid_t H5T_IEEE_U16LE_g = FAIL; +hid_t H5T_IEEE_U16BE_g = FAIL; +hid_t H5T_IEEE_U32LE_g = FAIL; +hid_t H5T_IEEE_U32BE_g = FAIL; +hid_t H5T_IEEE_U64LE_g = FAIL; +hid_t H5T_IEEE_U64BE_g = FAIL; +hid_t H5T_IEEE_S16LE_g = FAIL; +hid_t H5T_IEEE_S16BE_g = FAIL; +hid_t H5T_IEEE_S32LE_g = FAIL; +hid_t H5T_IEEE_S32BE_g = FAIL; +hid_t H5T_IEEE_S64LE_g = FAIL; +hid_t H5T_IEEE_S64BE_g = FAIL; + + /* The path database */ static intn H5T_npath_g = 0; /*num paths defined */ static intn H5T_apath_g = 0; /*num slots allocated */ -static H5T_path_t *H5T_path_g = NULL; /*path array */ +static H5T_path_t **H5T_path_g = NULL; /*path array */ /* The soft conversion function master list */ static intn H5T_nsoft_g = 0; /*num soft funcs defined */ @@ -155,6 +174,215 @@ H5T_init_interface(void) H5Tlock(H5T_NATIVE_UINT64_g); /* + * Standard data types in big and little endian flavors. + */ + + /* IEEE 4-byte little-endian float */ + dt = H5I_object (H5T_IEEE_R32LE_g = H5Tcopy (H5T_NATIVE_DOUBLE)); + dt->state = H5T_STATE_IMMUTABLE; + dt->size = 4; + dt->u.atomic.offset = 0; + dt->u.atomic.prec = 32; + dt->u.atomic.order = H5T_ORDER_LE; + dt->u.atomic.lsb_pad = H5T_PAD_ZERO; + dt->u.atomic.msb_pad = H5T_PAD_ZERO; + dt->u.atomic.u.f.sign = 31; + dt->u.atomic.u.f.epos = 23; + dt->u.atomic.u.f.esize = 8; + dt->u.atomic.u.f.ebias = 0x7f; + dt->u.atomic.u.f.mpos = 0; + dt->u.atomic.u.f.msize = 23; + dt->u.atomic.u.f.norm = H5T_NORM_IMPLIED; + dt->u.atomic.u.f.pad = H5T_PAD_ZERO; + + /* IEEE 4-byte big-endian float */ + dt = H5I_object (H5T_IEEE_R32BE_g = H5Tcopy (H5T_NATIVE_DOUBLE)); + dt->state = H5T_STATE_IMMUTABLE; + dt->size = 4; + dt->u.atomic.offset = 0; + dt->u.atomic.prec = 32; + dt->u.atomic.order = H5T_ORDER_BE; + dt->u.atomic.lsb_pad = H5T_PAD_ZERO; + dt->u.atomic.msb_pad = H5T_PAD_ZERO; + dt->u.atomic.u.f.sign = 31; + dt->u.atomic.u.f.epos = 23; + dt->u.atomic.u.f.esize = 8; + dt->u.atomic.u.f.ebias = 0x7f; + dt->u.atomic.u.f.mpos = 0; + dt->u.atomic.u.f.msize = 23; + dt->u.atomic.u.f.norm = H5T_NORM_IMPLIED; + dt->u.atomic.u.f.pad = H5T_PAD_ZERO; + + /* IEEE 8-byte little-endian float */ + dt = H5I_object (H5T_IEEE_R64LE_g = H5Tcopy (H5T_NATIVE_DOUBLE)); + dt->state = H5T_STATE_IMMUTABLE; + dt->size = 8; + dt->u.atomic.offset = 0; + dt->u.atomic.prec = 64; + dt->u.atomic.order = H5T_ORDER_LE; + dt->u.atomic.lsb_pad = H5T_PAD_ZERO; + dt->u.atomic.msb_pad = H5T_PAD_ZERO; + dt->u.atomic.u.f.sign = 63; + dt->u.atomic.u.f.epos = 52; + dt->u.atomic.u.f.esize = 11; + dt->u.atomic.u.f.ebias = 0x03ff; + dt->u.atomic.u.f.mpos = 0; + dt->u.atomic.u.f.msize = 52; + dt->u.atomic.u.f.norm = H5T_NORM_IMPLIED; + dt->u.atomic.u.f.pad = H5T_PAD_ZERO; + + /* IEEE 8-byte big-endian float */ + dt = H5I_object (H5T_IEEE_R64BE_g = H5Tcopy (H5T_NATIVE_DOUBLE)); + dt->state = H5T_STATE_IMMUTABLE; + dt->size = 8; + dt->u.atomic.offset = 0; + dt->u.atomic.prec = 64; + dt->u.atomic.order = H5T_ORDER_BE; + dt->u.atomic.lsb_pad = H5T_PAD_ZERO; + dt->u.atomic.msb_pad = H5T_PAD_ZERO; + dt->u.atomic.u.f.sign = 63; + dt->u.atomic.u.f.epos = 52; + dt->u.atomic.u.f.esize = 11; + dt->u.atomic.u.f.ebias = 0x03ff; + dt->u.atomic.u.f.mpos = 0; + dt->u.atomic.u.f.msize = 52; + dt->u.atomic.u.f.norm = H5T_NORM_IMPLIED; + dt->u.atomic.u.f.pad = H5T_PAD_ZERO; + + /* IEEE 2-byte little-endian signed integer */ + dt = H5I_object (H5T_IEEE_S16LE_g = H5Tcopy (H5T_NATIVE_INT)); + dt->state = H5T_STATE_IMMUTABLE; + dt->size = 2; + dt->u.atomic.offset = 0; + dt->u.atomic.prec = 16; + dt->u.atomic.order = H5T_ORDER_LE; + dt->u.atomic.lsb_pad = H5T_PAD_ZERO; + dt->u.atomic.msb_pad = H5T_PAD_ZERO; + dt->u.atomic.u.i.sign = H5T_SGN_2; + + /* IEEE 2-byte big-endian signed integer */ + dt = H5I_object (H5T_IEEE_S16BE_g = H5Tcopy (H5T_NATIVE_INT)); + dt->state = H5T_STATE_IMMUTABLE; + dt->size = 2; + dt->u.atomic.offset = 0; + dt->u.atomic.prec = 16; + dt->u.atomic.order = H5T_ORDER_BE; + dt->u.atomic.lsb_pad = H5T_PAD_ZERO; + dt->u.atomic.msb_pad = H5T_PAD_ZERO; + dt->u.atomic.u.i.sign = H5T_SGN_2; + + /* IEEE 4-byte little-endian signed integer */ + dt = H5I_object (H5T_IEEE_S32LE_g = H5Tcopy (H5T_NATIVE_INT)); + dt->state = H5T_STATE_IMMUTABLE; + dt->size = 4; + dt->u.atomic.offset = 0; + dt->u.atomic.prec = 32; + dt->u.atomic.order = H5T_ORDER_LE; + dt->u.atomic.lsb_pad = H5T_PAD_ZERO; + dt->u.atomic.msb_pad = H5T_PAD_ZERO; + dt->u.atomic.u.i.sign = H5T_SGN_2; + + /* IEEE 4-byte big-endian signed integer */ + dt = H5I_object (H5T_IEEE_S32BE_g = H5Tcopy (H5T_NATIVE_INT)); + dt->state = H5T_STATE_IMMUTABLE; + dt->size = 4; + dt->u.atomic.offset = 0; + dt->u.atomic.prec = 32; + dt->u.atomic.order = H5T_ORDER_BE; + dt->u.atomic.lsb_pad = H5T_PAD_ZERO; + dt->u.atomic.msb_pad = H5T_PAD_ZERO; + dt->u.atomic.u.i.sign = H5T_SGN_2; + + /* IEEE 8-byte little-endian signed integer */ + dt = H5I_object (H5T_IEEE_S64LE_g = H5Tcopy (H5T_NATIVE_INT)); + dt->state = H5T_STATE_IMMUTABLE; + dt->size = 8; + dt->u.atomic.offset = 0; + dt->u.atomic.prec = 64; + dt->u.atomic.order = H5T_ORDER_LE; + dt->u.atomic.lsb_pad = H5T_PAD_ZERO; + dt->u.atomic.msb_pad = H5T_PAD_ZERO; + dt->u.atomic.u.i.sign = H5T_SGN_2; + + /* IEEE 8-byte big-endian signed integer */ + dt = H5I_object (H5T_IEEE_S64BE_g = H5Tcopy (H5T_NATIVE_INT)); + dt->state = H5T_STATE_IMMUTABLE; + dt->size = 8; + dt->u.atomic.offset = 0; + dt->u.atomic.prec = 64; + dt->u.atomic.order = H5T_ORDER_BE; + dt->u.atomic.lsb_pad = H5T_PAD_ZERO; + dt->u.atomic.msb_pad = H5T_PAD_ZERO; + dt->u.atomic.u.i.sign = H5T_SGN_2; + + /* IEEE 2-byte little-endian unsigned integer */ + dt = H5I_object (H5T_IEEE_U16LE_g = H5Tcopy (H5T_NATIVE_INT)); + dt->state = H5T_STATE_IMMUTABLE; + dt->size = 2; + dt->u.atomic.offset = 0; + dt->u.atomic.prec = 16; + dt->u.atomic.order = H5T_ORDER_LE; + dt->u.atomic.lsb_pad = H5T_PAD_ZERO; + dt->u.atomic.msb_pad = H5T_PAD_ZERO; + dt->u.atomic.u.i.sign = H5T_SGN_NONE; + + /* IEEE 2-byte big-endian unsigned integer */ + dt = H5I_object (H5T_IEEE_U16BE_g = H5Tcopy (H5T_NATIVE_INT)); + dt->state = H5T_STATE_IMMUTABLE; + dt->size = 2; + dt->u.atomic.offset = 0; + dt->u.atomic.prec = 16; + dt->u.atomic.order = H5T_ORDER_BE; + dt->u.atomic.lsb_pad = H5T_PAD_ZERO; + dt->u.atomic.msb_pad = H5T_PAD_ZERO; + dt->u.atomic.u.i.sign = H5T_SGN_NONE; + + /* IEEE 4-byte little-endian unsigned integer */ + dt = H5I_object (H5T_IEEE_U32LE_g = H5Tcopy (H5T_NATIVE_INT)); + dt->state = H5T_STATE_IMMUTABLE; + dt->size = 4; + dt->u.atomic.offset = 0; + dt->u.atomic.prec = 32; + dt->u.atomic.order = H5T_ORDER_LE; + dt->u.atomic.lsb_pad = H5T_PAD_ZERO; + dt->u.atomic.msb_pad = H5T_PAD_ZERO; + dt->u.atomic.u.i.sign = H5T_SGN_NONE; + + /* IEEE 4-byte big-endian unsigned integer */ + dt = H5I_object (H5T_IEEE_U32BE_g = H5Tcopy (H5T_NATIVE_INT)); + dt->state = H5T_STATE_IMMUTABLE; + dt->size = 4; + dt->u.atomic.offset = 0; + dt->u.atomic.prec = 32; + dt->u.atomic.order = H5T_ORDER_BE; + dt->u.atomic.lsb_pad = H5T_PAD_ZERO; + dt->u.atomic.msb_pad = H5T_PAD_ZERO; + dt->u.atomic.u.i.sign = H5T_SGN_NONE; + + /* IEEE 8-byte little-endian unsigned integer */ + dt = H5I_object (H5T_IEEE_U64LE_g = H5Tcopy (H5T_NATIVE_INT)); + dt->state = H5T_STATE_IMMUTABLE; + dt->size = 8; + dt->u.atomic.offset = 0; + dt->u.atomic.prec = 64; + dt->u.atomic.order = H5T_ORDER_LE; + dt->u.atomic.lsb_pad = H5T_PAD_ZERO; + dt->u.atomic.msb_pad = H5T_PAD_ZERO; + dt->u.atomic.u.i.sign = H5T_SGN_NONE; + + /* IEEE 8-byte big-endian unsigned integer */ + dt = H5I_object (H5T_IEEE_U64BE_g = H5Tcopy (H5T_NATIVE_INT)); + dt->state = H5T_STATE_IMMUTABLE; + dt->size = 8; + dt->u.atomic.offset = 0; + dt->u.atomic.prec = 64; + dt->u.atomic.order = H5T_ORDER_BE; + dt->u.atomic.lsb_pad = H5T_PAD_ZERO; + dt->u.atomic.msb_pad = H5T_PAD_ZERO; + dt->u.atomic.u.i.sign = H5T_SGN_NONE; + + + /* * Initialize pre-defined data types that don't depend on architecture. */ @@ -237,6 +465,11 @@ H5T_init_interface(void) * Register conversion functions beginning with the most general and * ending with the most specific. */ + if (H5Tregister_soft ("i_i", H5T_INTEGER, H5T_INTEGER, + H5T_conv_i_i) < 0) { + HRETURN_ERROR (H5E_DATATYPE, H5E_CANTINIT, FAIL, + "unable to register conversion function"); + } if (H5Tregister_soft("ibo", H5T_INTEGER, H5T_INTEGER, H5T_conv_order) < 0) { HRETURN_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, @@ -252,6 +485,17 @@ H5T_init_interface(void) "unable to register conversion function"); } + if (H5Tregister_hard ("i32le_r64le", H5T_IEEE_U32LE_g, H5T_IEEE_R64LE_g, + H5T_conv_i32le_r64le)<0) { + HRETURN_ERROR (H5E_DATATYPE, H5E_CANTINIT, FAIL, + "unable to register conversion function"); + } + if (H5Tregister_hard ("i32le_r64le", H5T_IEEE_S32LE_g, H5T_IEEE_R64LE_g, + H5T_conv_i32le_r64le)<0) { + HRETURN_ERROR (H5E_DATATYPE, H5E_CANTINIT, FAIL, + "unable to register conversion function"); + } + FUNC_LEAVE(ret_value); } @@ -304,6 +548,10 @@ H5T_unlock_cb (void *_dt, const void __unused__ *key) Can't report errors... EXAMPLES REVISION LOG + * Robb Matzke, 1998-06-11 + * Statistics are only printed for conversion functions that were + * called. + * --------------------------------------------------------------------------*/ static void H5T_term_interface(void) @@ -319,7 +567,8 @@ H5T_term_interface(void) /* Unregister all conversion functions */ for (i=0; i<H5T_npath_g; i++) { - path = H5T_path_g + i; + path = H5T_path_g[i]; + assert (path); if (path->func) { path->cdata.command = H5T_CONV_FREE; @@ -331,31 +580,37 @@ H5T_term_interface(void) H5E_clear(); /*ignore the error*/ } #ifdef H5T_DEBUG - if (0==nprint++) { - HDfprintf (stderr, "H5T: type conversion statistics " - "accumulated over life of library:\n"); - HDfprintf (stderr, " %-*s %8s/%-5s %8s %8s %8s %15s\n", - H5T_NAMELEN-1, "Name", "Elmts", "Calls", "User", - "System", "Elapsed", "Bandwidth"); - HDfprintf (stderr, " %-*s %8s-%-5s %8s %8s %8s %15s\n", - H5T_NAMELEN-1, "----", "-----", "-----", "----", - "------", "-------", "---------"); + if (path->cdata.stats->ncalls>0) { + if (0==nprint++) { + HDfprintf (stderr, "H5T: type conversion statistics " + "accumulated over life of library:\n"); + HDfprintf (stderr, " %-*s %8s/%-5s %8s %8s %8s %15s\n", + H5T_NAMELEN-1, "Name", "Elmts", "Calls", "User", + "System", "Elapsed", "Bandwidth"); + HDfprintf (stderr, " %-*s %8s-%-5s %8s %8s %8s %15s\n", + H5T_NAMELEN-1, "----", "-----", "-----", "----", + "------", "-------", "---------"); + } + nbytes = MAX (H5T_get_size (path->src), + H5T_get_size (path->dst)); + nbytes *= path->cdata.stats->nelmts; + HDfprintf (stderr, + " %-*s %8Hd/%-5d %8.2f %8.2f %8.2f %15g\n", + H5T_NAMELEN-1, path->name, + path->cdata.stats->nelmts, + path->cdata.stats->ncalls, + path->cdata.stats->timer.utime, + path->cdata.stats->timer.stime, + path->cdata.stats->timer.etime, + nbytes / path->cdata.stats->timer.etime); } - nbytes = MAX (H5T_get_size (path->src), H5T_get_size (path->dst)); - nbytes *= path->cdata.stats->nelmts; - HDfprintf (stderr, " %-*s %8Hd/%-5d %8.2f %8.2f %8.2f %15g\n", - H5T_NAMELEN-1, path->name, - path->cdata.stats->nelmts, - path->cdata.stats->ncalls, - path->cdata.stats->timer.utime, - path->cdata.stats->timer.stime, - path->cdata.stats->timer.etime, - nbytes / path->cdata.stats->timer.etime); #endif H5T_close (path->src); H5T_close (path->dst); H5MM_xfree (path->cdata.stats); } + H5MM_xfree (path); + H5T_path_g[i] = NULL; } /* Clear conversion tables */ @@ -2424,8 +2679,8 @@ H5Tregister_hard(const char *name, hid_t src_id, hid_t dst_id, H5T_conv_t func) * recalculated to use the new function. */ for (i=0; i<H5T_npath_g; i++) { - if (path != H5T_path_g+i) { - H5T_path_g[i].cdata.recalc = TRUE; + if (path != H5T_path_g[i]) { + H5T_path_g[i]->cdata.recalc = TRUE; } } @@ -2490,7 +2745,8 @@ H5Tregister_soft(const char *name, H5T_class_t src_cls, H5T_class_t dst_cls, /* Replace soft functions of all appropriate paths */ for (i=0; i<H5T_npath_g; i++) { - H5T_path_t *path = H5T_path_g + i; + H5T_path_t *path = H5T_path_g[i]; + assert (path); path->cdata.recalc = TRUE; if (path->is_hard || @@ -2590,7 +2846,8 @@ H5Tunregister(H5T_conv_t func) /* Remove function from all conversion paths */ for (i=0; i<H5T_npath_g; i++) { - path = H5T_path_g + i; + path = H5T_path_g[i]; + assert (path); if (path->func == func) { path->func = NULL; @@ -2709,6 +2966,65 @@ H5Tfind(hid_t src_id, hid_t dst_id, H5T_cdata_t **pcdata) FUNC_LEAVE(ret_value); } + +/*------------------------------------------------------------------------- + * Function: H5Tconvert + * + * Purpose: Convert NELMTS elements from type SRC_ID to type DST_ID. The + * source elements are packed in BUF and on return the + * destination will be packed in BUF. That is, the conversion + * is performed in place. The optional background buffer is an + * array of NELMTS values of destination type which are merged + * with the converted values to fill in cracks (for instance, + * BACKGROUND might be an array of structs with the `a' and `b' + * fields already initialized and the conversion of BUF supplies + * the `c' and `d' field values). + * + * Return: Success: SUCCEED + * + * Failure: FAIL + * + * Programmer: Robb Matzke + * Wednesday, June 10, 1998 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +herr_t +H5Tconvert (hid_t src_id, hid_t dst_id, size_t nelmts, void *buf, + void *background) +{ + H5T_cdata_t *cdata = NULL; /*conversion data */ + H5T_conv_t tconv_func = NULL; /*conversion function */ + herr_t status; /*func return status */ +#ifdef H5T_DEBUG + H5_timer_t timer; /*conversion timer */ +#endif + + FUNC_ENTER (H5Tconvert, FAIL); + + if (NULL==(tconv_func=H5Tfind (src_id, dst_id, &cdata))) { + HRETURN_ERROR (H5E_DATATYPE, H5E_CANTINIT, FAIL, + "unable to convert between src and dst data types"); + } + +#ifdef H5T_DEBUG + H5T_timer_begin (&timer, cdata); +#endif + cdata->command = H5T_CONV_CONV; + status = (tconv_func)(src_id, dst_id, cdata, nelmts, buf, background); +#ifdef H5T_DEBUG + H5T_timer_end (&timer, cdata, nelmts); +#endif + if (status<0) { + HRETURN_ERROR (H5E_DATATYPE, H5E_CANTINIT, FAIL, + "data type conversion failed"); + } + + FUNC_LEAVE (SUCCEED); +} + /*------------------------------------------------------------------------- * API functions are above; library-private functions are below... *------------------------------------------------------------------------- @@ -3682,16 +3998,17 @@ H5T_path_find(const char *name, const H5T_t *src, const H5T_t *dst, /* Binary search */ while (lt < rt) { md = (lt + rt) / 2; + assert (H5T_path_g[md]); - cmp = H5T_cmp(src, H5T_path_g[md].src); - if (0 == cmp) cmp = H5T_cmp(dst, H5T_path_g[md].dst); + cmp = H5T_cmp(src, H5T_path_g[md]->src); + if (0 == cmp) cmp = H5T_cmp(dst, H5T_path_g[md]->dst); if (cmp < 0) { rt = md; } else if (cmp > 0) { lt = md + 1; } else { - HRETURN(H5T_path_g + md); + HRETURN(H5T_path_g[md]); } } @@ -3700,18 +4017,17 @@ H5T_path_find(const char *name, const H5T_t *src, const H5T_t *dst, if (H5T_npath_g >= H5T_apath_g) { H5T_apath_g = MAX(64, 2 * H5T_apath_g); H5T_path_g = H5MM_xrealloc(H5T_path_g, - H5T_apath_g * sizeof(H5T_path_t)); + H5T_apath_g * sizeof(H5T_path_t*)); } if (cmp > 0) md++; /* make room */ HDmemmove(H5T_path_g + md + 1, H5T_path_g + md, - (H5T_npath_g - md) * sizeof(H5T_path_t)); + (H5T_npath_g - md) * sizeof(H5T_path_t*)); H5T_npath_g++; /* insert */ - path = H5T_path_g + md; - HDmemset(path, 0, sizeof(H5T_path_t)); + path = H5T_path_g[md] = H5MM_xcalloc (1, sizeof(H5T_path_t)); path->src = H5T_copy(src, H5T_COPY_ALL); path->dst = H5T_copy(dst, H5T_COPY_ALL); diff --git a/src/H5Tbit.c b/src/H5Tbit.c new file mode 100644 index 0000000..0524dcc --- /dev/null +++ b/src/H5Tbit.c @@ -0,0 +1,154 @@ +/* + * Copyright (C) 1998 NCSA + * All rights reserved. + * + * Programmer: Robb Matzke <matzke@llnl.gov> + * Wednesday, June 10, 1998 + * + * Purpose: Operations on bit vectors. A bit vector is an array of bytes + * with the least-significant bits in the first byte. That is, + * the bytes are in little-endian order. + */ +#define H5T_PACKAGE +#include <H5private.h> +#include <H5Tpkg.h> + + +/*------------------------------------------------------------------------- + * Function: H5T_bit_copy + * + * Purpose: Copies bits from one vector to another. + * + * Return: void + * + * Programmer: Robb Matzke + * Wednesday, June 10, 1998 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +void +H5T_bit_copy (uint8 *dst, size_t dst_offset, const uint8 *src, + size_t src_offset, size_t size) +{ + uintn shift; + uintn mask_lo, mask_hi; + intn s_idx, d_idx; + + /* + * Calculate shifts and masks. See diagrams below. MASK_LO in this + * example is 0x1f (the low five bits) and MASK_HI is 0xe0 (the high three + * bits). SHIFT is three since the source must be shifted right three bits + * to line up with the destination. + */ + shift = (dst_offset%8)-(src_offset%8); + mask_lo = (1<<(8-shift))-1; + mask_hi = ((1<<shift)-1) << (8-shift); + s_idx = src_offset / 8; + d_idx = dst_offset / 8; + + /* + * Get things rolling. This means copying bits until we're aligned on a + * source byte. This the following example, four bits are copied to the + * destination. + * + * src[s_idx] + * +---------------+---------------+ + * |7 6 5 4 3 2 1 0|7 6 5 4 3 2 1 0| + * +---------------+---------------+ + * ... : : : : : | | | | | + * ... v v v v v V V V V V + * ...+---------------+---------------+ + * ...|7 6 5 4 3 2 1 0|7 6 5 4 3 2 1 0| + * ...+---------------+---------------+ + * dst[d_idx+1] dst[d_idx] + */ + if (src_offset%8 && size>0) { + } + + + + /* + * The middle bits. We are aligned on a source byte which needs to be + * copied to two (or one in the degenerate case) destination bytes. + * + * src[s_idx] + * +---------------+ + * |7 6 5 4 3 2 1 0| + * +---------------+ + * | | | | | | | | + * V V V V V V V V + * +---------------+---------------+ + * |7 6 5 4 3 2 1 0|7 6 5 4 3 2 1 0| + * +---------------+---------------+ + * dst[d_idx+1] dst[d_idx] + * + */ + for (/*void*/; size>8; size-=8, d_idx++, s_idx++) { + if (shift) { + dst[d_idx+0] &= mask_lo; + dst[d_idx+0] |= (src[s_idx] << shift) & mask_hi; + dst[d_idx+1] &= mask_hi; + dst[d_idx+1] |= (src[s_idx] >> (8-shift)) & mask_lo; + } else { + dst[d_idx] = src[s_idx]; + } + } + + + + + /* Finish up */ + + +} + + +/*------------------------------------------------------------------------- + * Function: H5T_bit_set + * + * Purpose: Sets or clears bits in a contiguous region of a vector + * beginning at bit OFFSET and continuing for SIZE bits. + * + * Return: void + * + * Programmer: Robb Matzke + * Wednesday, June 10, 1998 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +void +H5T_bit_set (uint8 *buf, size_t offset, size_t size, hbool_t value) +{ +} + + +/*------------------------------------------------------------------------- + * Function: H5T_bit_find + * + * Purpose: Finds the first bit with the specified VALUE within a region + * of a bit vector. The region begins at OFFSET and continues + * for SIZE bits, but the region can be searched from the least + * significat end toward the most significant end with + * + * Return: Success: The position of the bit found, relative to + * the offset. + * + * Failure: -1 + * + * Programmer: Robb Matzke + * Wednesday, June 10, 1998 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +ssize_t +H5T_bit_find (uint8 *buf, size_t offset, size_t size, H5T_sdir_t direction, + hbool_t value) +{ + return -1; +} diff --git a/src/H5Tconv.c b/src/H5Tconv.c index 626859d..1f2a2a5 100644 --- a/src/H5Tconv.c +++ b/src/H5Tconv.c @@ -7,12 +7,13 @@ * * Purpose: Data type conversions. */ -#define H5T_PACKAGE /*suppress error about including H5Tpkg */ +#define H5T_PACKAGE /*suppress error about including H5Tpkg */ #include <H5Iprivate.h> #include <H5Eprivate.h> #include <H5MMprivate.h> #include <H5Tpkg.h> +#include <math.h> /*for ceil() */ /* Conversion data for H5T_conv_struct() */ typedef struct H5T_conv_struct_t { @@ -518,3 +519,679 @@ H5T_conv_struct(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, FUNC_LEAVE (SUCCEED); } + +/*------------------------------------------------------------------------- + * Function: H5T_conv_i_i + * + * Purpose: Convert one integer type to another. This is the catch-all + * function for integer conversions and is probably not + * particularly fast. + * + * Return: Success: SUCCEED + * + * Failure: FAIL + * + * Programmer: Robb Matzke + * Wednesday, June 10, 1998 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +herr_t +H5T_conv_i_i (hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, + size_t nelmts, void *buf, void __unused__ *bkg) +{ + H5T_t *src = NULL; /*source data type */ + H5T_t *dst = NULL; /*destination data type */ + intn direction; /*direction of traversal */ + size_t elmtno; /*element number */ + size_t half_size; /*half the type size */ + size_t olap; /*num overlapping elements */ + uint8 *s, *sp, *d, *dp; /*source and dest traversal ptrs*/ + uint8 dbuf[64]; /*temp destination buffer */ + size_t first; + ssize_t sfirst; /*a signed version of `first' */ + size_t i; + + FUNC_ENTER (H5T_conv_i_i, FAIL); + + switch (cdata->command) { + case H5T_CONV_INIT: + if (H5_DATATYPE!=H5I_group (src_id) || + NULL==(src=H5I_object (src_id)) || + H5_DATATYPE!=H5I_group (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"); + } + if (dst->size>sizeof dbuf) { + HRETURN_ERROR (H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, + "destination size is too large"); + } + break; + + case H5T_CONV_FREE: + break; + + case H5T_CONV_CONV: + /* Get the data types */ + if (H5_DATATYPE!=H5I_group (src_id) || + NULL==(src=H5I_object (src_id)) || + H5_DATATYPE!=H5I_group (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*)buf; + direction = 1; + olap = nelmts; + } else if (src->size>=dst->size) { + sp = dp = (uint8*)buf; + direction = 1; + olap = ceil((double)(src->size)/(src->size-dst->size))-1; + } else { + sp = (uint8*)buf + (nelmts-1) * src->size; + dp = (uint8*)buf + (nelmts-1) * dst->size; + direction = -1; + olap = ceil((double)(dst->size)/(dst->size-src->size))-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 >= nelmts-olap ? 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 tmp = s[src->size-(i+1)]; + s[src->size-(i+1)] = s[i]; + s[i] = tmp; + } + } + + /* + * What is the bit number for the msb bit of S which is set? The + * bit number is relative to the significant part of the number. + */ + sfirst = H5T_bit_find (s, src->u.atomic.offset, src->u.atomic.prec, + H5T_BIT_MSB, TRUE); + first = (size_t)first; + + if (sfirst<0) { + /* + * The source has no bits set and must therefore be zero. + * Set the destination to zero. + */ + H5T_bit_set (d, dst->u.atomic.offset, dst->u.atomic.prec, + FALSE); + + } else if (H5T_SGN_NONE==src->u.atomic.u.i.sign && + H5T_SGN_NONE==dst->u.atomic.u.i.sign) { + /* + * Source and destination are both unsigned, but if the + * source has more precision bits than the destination then + * it's possible to overflow. When overflow occurs the + * destination will be set to the maximum possible value. + */ + if (src->u.atomic.prec <= dst->u.atomic.prec) { + H5T_bit_copy (d, dst->u.atomic.offset, + s, src->u.atomic.offset, + src->u.atomic.prec); + H5T_bit_set (d, dst->u.atomic.offset+src->u.atomic.prec, + dst->u.atomic.prec-src->u.atomic.prec, FALSE); + } else if (first>=dst->u.atomic.prec) { + /*overflow*/ + H5T_bit_set (d, dst->u.atomic.offset, dst->u.atomic.prec, + TRUE); + } else { + H5T_bit_copy (d, dst->u.atomic.offset, + s, src->u.atomic.offset, + dst->u.atomic.prec); + } + + } else if (H5T_SGN_2==src->u.atomic.u.i.sign && + H5T_SGN_NONE==dst->u.atomic.u.i.sign) { + /* + * If the source is signed and the destination isn't then we + * can have overflow if the source contains more bits than + * the destination (destination is set to the maximum + * possible value) or underflow if the source is negative + * (destination is set to zero). + */ + if (first+1 == src->u.atomic.prec) { + /*underflow*/ + H5T_bit_set (d, dst->u.atomic.offset, dst->u.atomic.prec, + FALSE); + } else if (src->u.atomic.prec < dst->u.atomic.prec) { + H5T_bit_copy (d, dst->u.atomic.offset, + s, src->u.atomic.offset, + src->u.atomic.prec-1); + H5T_bit_set (d, dst->u.atomic.offset+src->u.atomic.prec-1, + (dst->u.atomic.prec-src->u.atomic.prec)+1, + FALSE); + } else if (first>=dst->u.atomic.prec) { + /*overflow*/ + H5T_bit_set (d, dst->u.atomic.offset, dst->u.atomic.prec, + TRUE); + } else { + H5T_bit_copy (d, dst->u.atomic.offset, + s, src->u.atomic.offset, + dst->u.atomic.prec); + } + + } else if (H5T_SGN_NONE==src->u.atomic.u.i.sign && + H5T_SGN_2==dst->u.atomic.u.i.sign) { + /* + * If the source is not signed but the destination is then + * overflow can occur in which case the destination is set to + * the largest possible value (all bits set except the msb). + */ + if (first+1 >= dst->u.atomic.prec) { + /*overflow*/ + H5T_bit_set (d, dst->u.atomic.offset, + dst->u.atomic.prec-1, TRUE); + H5T_bit_set (d, dst->u.atomic.offset+dst->u.atomic.prec-1, + 1, FALSE); + } else if (src->u.atomic.prec<dst->u.atomic.prec) { + H5T_bit_copy (d, dst->u.atomic.offset, + s, src->u.atomic.offset, + src->u.atomic.prec); + H5T_bit_set (d, dst->u.atomic.offset+src->u.atomic.prec, + dst->u.atomic.prec-src->u.atomic.prec, FALSE); + } else { + H5T_bit_copy (d, dst->u.atomic.offset, + s, src->u.atomic.offset, + dst->u.atomic.prec); + } + + } else if (first+1 == src->u.atomic.prec) { + /* + * Both the source and the destination are signed and the + * source value is negative. We could experience underflow + * if the destination isn't wide enough in which case the + * destination is set to a negative number with the largest + * possible magnitude. + */ + ssize_t sfz = H5T_bit_find (s, src->u.atomic.offset, + src->u.atomic.prec-1, H5T_BIT_MSB, + FALSE); + size_t fz = (size_t)sfz; + + if (sfz>=0 && fz+2>=dst->u.atomic.prec) { + /*underflow*/ + H5T_bit_set (d, dst->u.atomic.offset, dst->u.atomic.prec-1, + FALSE); + H5T_bit_set (d, dst->u.atomic.offset+dst->u.atomic.prec-1, + 1, TRUE); + } else if (src->u.atomic.prec<dst->u.atomic.prec) { + H5T_bit_copy (d, dst->u.atomic.offset, + s, src->u.atomic.offset, + src->u.atomic.prec); + H5T_bit_set (d, dst->u.atomic.offset+src->u.atomic.prec, + dst->u.atomic.prec-src->u.atomic.prec, TRUE); + } else { + H5T_bit_copy (d, dst->u.atomic.offset, + s, src->u.atomic.offset, + dst->u.atomic.prec); + } + + } else { + /* + * Source and destination are both signed but the source + * value is positive. We could have an overflow in which + * case the destination is set to the largest possible + * positive value. + */ + if (first+2>=dst->u.atomic.prec) { + /*overflow*/ + H5T_bit_set (d, dst->u.atomic.offset, dst->u.atomic.prec-1, + TRUE); + H5T_bit_set (d, dst->u.atomic.offset+dst->u.atomic.prec-1, + 1, FALSE); + } else if (src->u.atomic.prec<dst->u.atomic.prec) { + H5T_bit_copy (d, dst->u.atomic.offset, + s, src->u.atomic.offset, + src->u.atomic.prec); + H5T_bit_set (d, dst->u.atomic.offset+src->u.atomic.prec, + dst->u.atomic.prec-src->u.atomic.prec, FALSE); + } + } + + /* + * Set padding areas in destination. + */ + if (dst->u.atomic.offset>0) { + assert (H5T_PAD_ZERO==dst->u.atomic.lsb_pad || + H5T_PAD_ONE==dst->u.atomic.lsb_pad); + H5T_bit_set (d, 0, dst->u.atomic.offset, + H5T_PAD_ONE==dst->u.atomic.lsb_pad); + } + if (dst->u.atomic.offset+dst->u.atomic.prec!=8*dst->size) { + assert (H5T_PAD_ZERO==dst->u.atomic.msb_pad || + H5T_PAD_ONE==dst->u.atomic.msb_pad); + H5T_bit_set (d, dst->u.atomic.offset+dst->u.atomic.prec, + 8*dst->size - (dst->u.atomic.offset+ + dst->u.atomic.prec), + H5T_PAD_ONE==dst->u.atomic.msb_pad); + } + + /* + * 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 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); + + next: + 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_i32le_r64le + * + * Purpose: Converts 4-byte little-endian integers (signed or unsigned) + * to 8-byte litte-endian IEEE floating point. + * + * Return: Success: SUCCEED + * + * Failure: FAIL + * + * Programmer: Robb Matzke + * Wednesday, June 10, 1998 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +herr_t +H5T_conv_i32le_r64le (hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, + size_t nelmts, void *buf, void __unused__ *bkg) +{ + uint8 *s=NULL, *d=NULL; /*src and dst buf pointers */ + uint8 tmp[8]; /*temporary destination buffer */ + H5T_t *src = NULL; /*source data type */ + H5T_t *dst = NULL; /*destination data type */ + size_t elmtno; /*element counter */ + uintn sign; /*sign bit */ + uintn cin, cout; /*carry in/out */ + uintn mbits=0; /*mantissa bits */ + uintn exponent; /*exponent */ + intn i; /*counter */ + + FUNC_ENTER (H5T_conv_i32le_r64le, FAIL); + + switch (cdata->command) { + case H5T_CONV_INIT: + assert (sizeof(intn)>=4); + break; + + case H5T_CONV_FREE: + /* Free private data */ + break; + + case H5T_CONV_CONV: + /* The conversion */ + if (H5_DATATYPE!=H5I_group (src_id) || + NULL==(src=H5I_object (src_id)) || + H5_DATATYPE!=H5I_group (dst_id) || + NULL==(dst=H5I_object (dst_id))) { + HRETURN_ERROR (H5E_ARGS, H5E_BADTYPE, FAIL, "not a data type"); + } + + s = (uint8*)buf + 4*(nelmts-1); + d = (uint8*)buf + 8*(nelmts-1); + for (elmtno=0; elmtno<nelmts; elmtno++, s-=4, d-=8) { + + /* + * If this is the last element to convert (that is, the first + * element of the buffer) then the source and destination areas + * overlap so we need to use a temp buf for the destination. + */ + if (s==buf) d = tmp; + + /* Convert the integer to a sign and magnitude */ + switch (src->u.atomic.u.i.sign) { + case H5T_SGN_NONE: + sign = 0; + break; + case H5T_SGN_2: + if (s[3] & 0x80) { + sign = 1 ; + for (i=0,cin=1; i<4; i++,cin=cout) { + s[i] = ~s[i] ; + cout = ((unsigned)(s[i])+cin > 0xff) ? 1 : 0 ; + s[i] += cin ; + } + } else { + sign = 0; + } + break; + default: + HRETURN_ERROR (H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, + "unsupported integer sign method"); + } + + /* + * Where is the most significant bit that is set? We could do + * this in a loop, but testing it this way might be faster. + */ + if (s[3]) { + if (s[3] & 0x80) mbits = 32 ; + else if (s[3] & 0x40) mbits = 31 ; + else if (s[3] & 0x20) mbits = 30 ; + else if (s[3] & 0x10) mbits = 29 ; + else if (s[3] & 0x08) mbits = 28 ; + else if (s[3] & 0x04) mbits = 27 ; + else if (s[3] & 0x02) mbits = 26 ; + else if (s[3] & 0x01) mbits = 25 ; + } else if (s[2]) { + if (s[2] & 0x80) mbits = 24 ; + else if (s[2] & 0x40) mbits = 23 ; + else if (s[2] & 0x20) mbits = 22 ; + else if (s[2] & 0x10) mbits = 21 ; + else if (s[2] & 0x08) mbits = 20 ; + else if (s[2] & 0x04) mbits = 19 ; + else if (s[2] & 0x02) mbits = 18 ; + else if (s[2] & 0x01) mbits = 17 ; + } else if (s[1]) { + if (s[1] & 0x80) mbits = 16 ; + else if (s[1] & 0x40) mbits = 15 ; + else if (s[1] & 0x20) mbits = 14 ; + else if (s[1] & 0x10) mbits = 13 ; + else if (s[1] & 0x08) mbits = 12 ; + else if (s[1] & 0x04) mbits = 11 ; + else if (s[1] & 0x02) mbits = 10 ; + else if (s[1] & 0x01) mbits = 9 ; + } else if (s[0]) { + if (s[0] & 0x80) mbits = 8 ; + else if (s[0] & 0x40) mbits = 7 ; + else if (s[0] & 0x20) mbits = 6 ; + else if (s[0] & 0x10) mbits = 5 ; + else if (s[0] & 0x08) mbits = 4 ; + else if (s[0] & 0x04) mbits = 3 ; + else if (s[0] & 0x02) mbits = 2 ; + else if (s[0] & 0x01) mbits = 1 ; + } else { + /*zero*/ + d[7] = d[6] = d[5] = d[4] = d[3] = d[2] = d[1] = d[0] = 0 ; + continue ; + } + + /* + * The sign and exponent. + */ + exponent = (mbits - 1) + 1023 ; + d[7] = (sign<<7) | ((exponent>>4) & 0x7f) ; + d[6] = (exponent & 0x0f) << 4 ; + + /* + * The mantissa. + */ + switch (mbits) { + case 32: + d[5] = d[4] = d[3] = d[1] = d[0] = 0 ; + break ; + case 31: + d[6] |= 0x0f & (s[3]>>2) ; + d[5] = (s[3]<<6) | (s[2]>>2) ; + d[4] = (s[2]<<6) | (s[1]>>2) ; + d[3] = (s[1]<<6) | (s[0]>>2) ; + d[2] = (s[0]<<6) ; + d[1] = d[0] = 0 ; + break ; + case 30: + d[6] |= 0x0f & (s[3]>>1) ; + d[5] = (s[3]<<7) | (s[2]>>1) ; + d[4] = (s[2]<<7) | (s[1]>>1) ; + d[3] = (s[1]<<7) | (s[0]>>1) ; + d[2] = (s[0]<<7) ; + d[1] = d[0] = 0 ; + break ; + case 29: + d[6] |= 0x0f & s[3] ; + d[5] = s[2] ; + d[4] = s[1] ; + d[3] = s[0] ; + d[2] = d[1] = d[0] = 0 ; + break ; + case 28: + d[6] |= ((s[3]<<1) | (s[2]>>7)) & 0x0f ; + d[5] = (s[2]<<1) | (s[1]>>7) ; + d[4] = (s[1]<<1) | (s[0]>>7) ; + d[3] = (s[0]<<1) ; + d[2] = d[1] = d[0] = 0 ; + break ; + case 27: + d[6] |= ((s[3]<<2) | (s[2]>>6)) & 0x0f ; + d[5] = (s[2]<<2) | (s[1]>>6) ; + d[4] = (s[1]<<2) | (s[0]>>6) ; + d[3] = (s[0]<<2) ; + d[2] = d[1] = d[0] = 0 ; + break ; + case 26: + d[6] |= ((s[3]<<3) | (s[2]>>5)) & 0x0f ; + d[5] = (s[2]<<3) | (s[1]>>5) ; + d[4] = (s[1]<<3) | (s[0]>>5) ; + d[3] = (s[0]<<3) ; + d[2] = d[1] = d[0] = 0 ; + break ; + case 25: + d[6] |= 0x0f & (s[2]>>4) ; + d[5] = (s[2]<<4) | (s[1]>>4) ; + d[4] = (s[1]<<4) | (s[0]>>4) ; + d[3] = (s[0]<<4) ; + d[2] = d[1] = d[0] = 0 ; + break ; + case 24: + d[6] |= 0x0f & (s[2]>>3) ; + d[5] = (s[2]<<5) | (s[1]>>3) ; + d[4] = (s[1]<<5) | (s[0]>>3) ; + d[3] = (s[0]<<5) ; + d[2] = d[1] = d[0] = 0 ; + break ; + case 23: + d[6] |= 0x0f & (s[2]>>2) ; + d[5] = (s[2]<<6) | (s[1]>>2) ; + d[4] = (s[1]<<6) | (s[0]>>2) ; + d[3] = (s[0]<<6) ; + d[2] = d[1] = d[0] = 0 ; + break ; + case 22: + d[6] |= 0x0f & (s[2]>>1) ; + d[5] = (s[2]<<7) | (s[1]>>1) ; + d[4] = (s[1]<<7) | (s[0]>>1) ; + d[3] = (s[0]<<7) ; + d[2] = d[1] = d[0] = 0 ; + break ; + case 21: + d[6] |= 0x0f & s[2] ; + d[5] = s[1] ; + d[4] = s[0] ; + d[3] = d[2] = d[1] = d[0] = 0 ; + break ; + case 20: + d[6] |= ((s[2]<<1) | (s[1]>>7)) & 0x0f ; + d[5] = (s[1]<<1) | (s[0]>>7) ; + d[4] = (s[0]<<1) ; + d[3] = d[2] = d[1] = d[0] = 0 ; + break ; + case 19: + d[6] |= ((s[2]<<2) | (s[1]>>6)) & 0x0f ; + d[5] = (s[1]<<2) | (s[0]>>6) ; + d[4] = (s[0]<<2) ; + d[3] = d[2] = d[1] = d[0] = 0 ; + break ; + case 18: + d[6] |= ((s[2]<<3) | (s[1]>>5)) & 0x0f ; + d[5] = (s[1]<<3) | (s[0]>>5) ; + d[4] = (s[0]<<3) ; + d[3] = d[2] = d[1] = d[0] = 0 ; + break ; + case 17: + d[6] |= 0x0f & (s[1]>>4) ; + d[5] = (s[1]<<4) | (s[0]>>4) ; + d[4] = (s[0]<<4) ; + d[3] = d[2] = d[1] = d[0] = 0 ; + break ; + case 16: + d[6] |= 0x0f & (s[1]>>3) ; + d[5] = (s[1]<<5) | (s[0]>>3) ; + d[4] = (s[0]<<5) ; + d[3] = d[2] = d[1] = d[0] = 0 ; + break ; + case 15: + d[6] |= 0x0f & (s[1]>>2) ; + d[5] = (s[1]<<6) | (s[0]>>2) ; + d[4] = (s[0]<<6) ; + d[3] = d[2] = d[1] = d[0] = 0 ; + break ; + case 14: + d[6] |= 0x0f & (s[1]>>1) ; + d[5] = (s[1]<<7) | (s[0]>>1) ; + d[4] = (s[0]<<7) ; + d[3] = d[2] = d[1] = d[0] = 0 ; + break ; + case 13: + d[6] |= 0x0f & s[1] ; + d[5] = s[0] ; + d[4] = d[3] = d[2] = d[1] = d[0] = 0 ; + break ; + case 12: + d[6] |= ((s[1]<<1) | (s[0]>>7)) & 0x0f ; + d[5] = (s[0]<<1) ; + d[4] = d[3] = d[2] = d[1] = d[0] = 0 ; + break ; + case 11: + d[6] |= ((s[1]<<2) | (s[0]>>6)) & 0x0f ; + d[5] = (s[0]<<2) ; + d[4] = d[3] = d[2] = d[1] = d[0] = 0 ; + break ; + case 10: + d[6] |= ((s[1]<<3) | (s[0]>>5)) & 0x0f ; + d[5] = (s[0]<<3) ; + d[4] = d[3] = d[2] = d[1] = d[0] = 0 ; + break ; + case 9: + d[6] |= 0x0f & (s[0]>>4) ; + d[5] = (s[0]<<4) ; + d[4] = d[3] = d[2] = d[1] = d[0] = 0 ; + break ; + case 8: + d[6] |= 0x0f & (s[0]>>3) ; + d[5] = (s[0]<<5) ; + d[4] = d[3] = d[2] = d[1] = d[0] = 0 ; + break ; + case 7: + d[6] |= 0x0f & (s[0]>>2) ; + d[5] = (s[0]<<6) ; + d[4] = d[3] = d[2] = d[1] = d[0] = 0 ; + break ; + case 6: + d[6] |= 0x0f & (s[0]>>1) ; + d[5] = (s[0]<<7) ; + d[4] = d[3] = d[2] = d[1] = d[0] = 0 ; + break ; + case 5: + d[6] |= 0x0f & s[0] ; + d[5] = d[4] = d[3] = d[2] = d[1] = d[0] = 0 ; + break ; + case 4: + d[6] |= (s[0]<<1) & 0x0f ; + d[5] = d[4] = d[3] = d[2] = d[1] = d[0] = 0 ; + break ; + case 3: + d[6] |= (s[0]<<2) & 0x0f ; + d[5] = d[4] = d[3] = d[2] = d[1] = d[0] = 0 ; + break ; + case 2: + d[6] |= (s[0]<<3) & 0x0f ; + d[5] = d[4] = d[3] = d[2] = d[1] = d[0] = 0 ; + break ; + case 1: + d[5] = d[4] = d[3] = d[2] = d[1] = d[0] = 0 ; + break ; + } + + /* + * Copy temp buffer to the destination. This only happens for + * the first value in the array, the last value processed. See + * beginning of loop. + */ + if (d==tmp) HDmemcpy (s, d, 8); + } + break; + + default: + /* Some other command we don't know about yet.*/ + HRETURN_ERROR (H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, + "unknown conversion command"); + } + + FUNC_LEAVE (SUCCEED); +} diff --git a/src/H5Tpkg.h b/src/H5Tpkg.h index dea8b48..fc67908 100644 --- a/src/H5Tpkg.h +++ b/src/H5Tpkg.h @@ -110,6 +110,12 @@ typedef struct H5T_soft_t { H5T_conv_t func; /*the conversion function */ } H5T_soft_t; +/* Bit search direction */ +typedef enum H5T_sdir_t { + H5T_BIT_LSB, /*search lsb toward msb */ + H5T_BIT_MSB /*search msb toward lsb */ +} H5T_sdir_t; + /* Function prototypes for H5T package scope */ H5T_path_t *H5T_path_find (const char *name, const H5T_t *src, const H5T_t *dst, hbool_t create, H5T_conv_t func); @@ -119,6 +125,16 @@ herr_t H5T_conv_order (hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, void *_buf, void *bkg); herr_t H5T_conv_struct (hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, void *_buf, void *bkg); - +herr_t H5T_conv_i_i (hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, + size_t nelmts, void *_buf, void __unused__ *bkg); +herr_t H5T_conv_i32le_r64le (hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, + size_t nelmts, void *_buf, void __unused__ *bkg); + +/* Bit twiddling functions */ +void H5T_bit_copy (uint8 *dst, size_t dst_offset, const uint8 *src, + size_t src_offset, size_t size); +void H5T_bit_set (uint8 *buf, size_t offset, size_t size, hbool_t value); +ssize_t H5T_bit_find (uint8 *buf, size_t offset, size_t size, + H5T_sdir_t direction, hbool_t value); #endif diff --git a/src/H5Tpublic.h b/src/H5Tpublic.h index 1d7885a..bc1d9bd 100644 --- a/src/H5Tpublic.h +++ b/src/H5Tpublic.h @@ -119,7 +119,7 @@ typedef struct H5T_cdata_t { typedef herr_t (*H5T_conv_t) (hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, void *buf, void *bkg); -/* The predefined types */ +/* The predefined native types */ #define H5T_NATIVE_CHAR (H5open(), H5T_NATIVE_CHAR_g) #define H5T_NATIVE_UCHAR (H5open(), H5T_NATIVE_UCHAR_g) #define H5T_NATIVE_SHORT (H5open(), H5T_NATIVE_SHORT_g) @@ -147,9 +147,29 @@ typedef herr_t (*H5T_conv_t) (hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, #define H5T_NATIVE_BITFIELD (H5open(), H5T_NATIVE_BITFIELD_g) #define H5T_NATIVE_OPAQUE (H5open(), H5T_NATIVE_OPAQUE_g) +/* The predefined standard types */ +#define H5T_IEEE_R32LE (H5open(), H5T_IEEE_R32LE_g) +#define H5T_IEEE_R32BE (H5open(), H5T_IEEE_R32BE_g) +#define H5T_IEEE_R64LE (H5open(), H5T_IEEE_R64LE_g) +#define H5T_IEEE_R64BE (H5open(), H5T_IEEE_R64BE_g) +#define H5T_IEEE_U16LE (H5open(), H5T_IEEE_U16LE_g) +#define H5T_IEEE_U16BE (H5open(), H5T_IEEE_U16BE_g) +#define H5T_IEEE_U32LE (H5open(), H5T_IEEE_U32LE_g) +#define H5T_IEEE_U32BE (H5open(), H5T_IEEE_U32BE_g) +#define H5T_IEEE_U64LE (H5open(), H5T_IEEE_U64LE_g) +#define H5T_IEEE_U64BE (H5open(), H5T_IEEE_U64BE_g) +#define H5T_IEEE_S16LE (H5open(), H5T_IEEE_S16LE_g) +#define H5T_IEEE_S16BE (H5open(), H5T_IEEE_S16BE_g) +#define H5T_IEEE_S32LE (H5open(), H5T_IEEE_S32LE_g) +#define H5T_IEEE_S32BE (H5open(), H5T_IEEE_S32BE_g) +#define H5T_IEEE_S64LE (H5open(), H5T_IEEE_S64LE_g) +#define H5T_IEEE_S64BE (H5open(), H5T_IEEE_S64BE_g) + #ifdef __cplusplus extern "C" { #endif + +/* Native types */ extern hid_t H5T_NATIVE_CHAR_g; extern hid_t H5T_NATIVE_UCHAR_g; extern hid_t H5T_NATIVE_SHORT_g; @@ -177,6 +197,26 @@ extern hid_t H5T_NATIVE_STRING_g; extern hid_t H5T_NATIVE_BITFIELD_g; extern hid_t H5T_NATIVE_OPAQUE_g; +/* Standard types */ +extern hid_t H5T_IEEE_R32LE_g; /*IEEE 4-byte little-endian float */ +extern hid_t H5T_IEEE_R32BE_g; /*IEEE 4-byte big-endian float */ +extern hid_t H5T_IEEE_R64LE_g; /*IEEE 8-byte little-endian float */ +extern hid_t H5T_IEEE_R64BE_g; /*IEEE 8-byte big endian float */ +extern hid_t H5T_IEEE_U16LE_g; /*IEEE 2-byte little-endian unsigned int */ +extern hid_t H5T_IEEE_U16BE_g; /*IEEE 2-byte big-endian unsigned int */ +extern hid_t H5T_IEEE_U32LE_g; /*IEEE 4-byte little-endian unsigned int */ +extern hid_t H5T_IEEE_U32BE_g; /*IEEE 4-byte big-endian unsigned int */ +extern hid_t H5T_IEEE_U64LE_g; /*IEEE 8-byte little-endian unsigned int */ +extern hid_t H5T_IEEE_U64BE_g; /*IEEE 8-byte big-endian unsigned int */ +extern hid_t H5T_IEEE_S16LE_g; /*IEEE 2-byte little-endian signed int */ +extern hid_t H5T_IEEE_S16BE_g; /*IEEE 2-byte big-endian signed int */ +extern hid_t H5T_IEEE_S32LE_g; /*IEEE 4-byte little-endian signed int */ +extern hid_t H5T_IEEE_S32BE_g; /*IEEE 4-byte big-endian signed int */ +extern hid_t H5T_IEEE_S64LE_g; /*IEEE 8-byte little-endian signed int */ +extern hid_t H5T_IEEE_S64BE_g; /*IEEE 8-byte big-endian signed int */ + + + /* Operations defined on all data types */ hid_t H5Topen (hid_t loc_id, const char *name); hid_t H5Tcreate (H5T_class_t type, size_t size); @@ -238,6 +278,8 @@ herr_t H5Tregister_soft (const char *name, H5T_class_t src, H5T_class_t dst, H5T_conv_t func); herr_t H5Tunregister (H5T_conv_t func); H5T_conv_t H5Tfind (hid_t src_id, hid_t dst_id, H5T_cdata_t **pcdata); +herr_t H5Tconvert (hid_t src_id, hid_t dst_id, size_t nelmts, void *buf, + void *background); #ifdef __cplusplus } diff --git a/src/H5detect.c b/src/H5detect.c index 9b7959b..6b47a85 100644 --- a/src/H5detect.c +++ b/src/H5detect.c @@ -313,7 +313,7 @@ H5T_init (void)\n\ dt->u.atomic.order = H5T_ORDER_%s;\n\ dt->u.atomic.prec = %d;\n\ dt->u.atomic.lsb_pad = H5T_PAD_ZERO;\n\ - dt->u.atomic.lsb_pad = H5T_PAD_ZERO;\n", + dt->u.atomic.msb_pad = H5T_PAD_ZERO;\n", d[i].msize ? "FLOAT" : "INTEGER", /*class */ d[i].size + abs(d[i].padding), /*size */ d[i].perm[0] ? "BE" : "LE", /*byte order */ diff --git a/src/Makefile.in b/src/Makefile.in index 451a66d..2ac1511 100644 --- a/src/Makefile.in +++ b/src/Makefile.in @@ -14,14 +14,12 @@ LIB=libhdf5.a PROGS=debug h5ls h5repart # Source and object files for the library (lexicographically)... -PARALLEL_SRC= - LIB_SRC=H5.c H5A.c H5AC.c H5B.c H5D.c H5E.c H5F.c H5Farray.c H5Fcore.c \ - H5Ffamily.c H5Fistore.c H5Flow.c H5Fmpio.c H5Fsec2.c H5Fsplit.c H5Fstdio.c \ - H5G.c H5Gent.c H5Gnode.c H5Gstab.c H5HG.c H5HL.c H5I.c H5MF.c H5MM.c H5O.c \ - H5Oattr.c H5Ocomp.c H5Ocont.c H5Odtype.c H5Oefl.c H5Olayout.c H5Oname.c \ - H5Onull.c H5Osdspace.c H5Oshared.c H5Ostab.c H5P.c H5S.c H5Ssimp.c H5T.c \ - H5Tconv.c H5Tinit.c H5V.c H5Z.c @PARALLEL_SRC@ + H5Ffamily.c H5Fistore.c H5Flow.c H5Fmpio.c H5Fsec2.c H5Fsplit.c \ + H5Fstdio.c H5G.c H5Gent.c H5Gnode.c H5Gstab.c H5HG.c H5HL.c H5I.c H5MF.c \ + H5MM.c H5O.c H5Oattr.c H5Ocomp.c H5Ocont.c H5Odtype.c H5Oefl.c \ + H5Olayout.c H5Oname.c H5Onull.c H5Osdspace.c H5Oshared.c H5Ostab.c H5P.c \ + H5S.c H5Ssimp.c H5T.c H5Tbit.c H5Tconv.c H5Tinit.c H5V.c H5Z.c LIB_OBJ=$(LIB_SRC:.c=.o) |