diff options
author | Robb Matzke <matzke@llnl.gov> | 1998-01-14 19:42:59 (GMT) |
---|---|---|
committer | Robb Matzke <matzke@llnl.gov> | 1998-01-14 19:42:59 (GMT) |
commit | d70c7d7a64b821f9d3532cc01c7a7fa934f2a17d (patch) | |
tree | 5b7750fffd98153d874bb28daad40c49ac977eeb | |
parent | 1063eb8a1ea0cbdbdc4244f0627b94b3096d65ab (diff) | |
download | hdf5-d70c7d7a64b821f9d3532cc01c7a7fa934f2a17d.zip hdf5-d70c7d7a64b821f9d3532cc01c7a7fa934f2a17d.tar.gz hdf5-d70c7d7a64b821f9d3532cc01c7a7fa934f2a17d.tar.bz2 |
[svn-r153] Changes since 19980108
----------------------
./MANIFEST
./src/H5Dconv.c [REMOVED]
./src/H5Tconv.c [NEW]
./src/Makefile.in
Changed H5Dconv.c to H5Tconv.c
./html/Datatypes.html
Updated data type conversion section.
./html/H5.apiv2.html
Removed sections about datasets and data types since they're
covered in their own chapters.
./src/H5D.c
Supports data type conversion.
./src/H5Odtype.c
./src/H5Tpkg.h
Changed `lo_pad' and `hi_pad' to `lsb_pad' and `msb_pad'.
./src/H5T.c
./src/H5Tpkg.h
./src/H5Tprivate.h
./src/H5Tpublic.h
./src/H5detect.c
Added predefined data types. Added query/set more
properties. Added type conversion infrastructure.
./test/dsets.c
Tests data type conversion during read.
-rw-r--r-- | MANIFEST | 2 | ||||
-rw-r--r-- | src/H5D.c | 157 | ||||
-rw-r--r-- | src/H5Dconv.c | 133 | ||||
-rw-r--r-- | src/H5Odtype.c | 34 | ||||
-rw-r--r-- | src/H5T.c | 1046 | ||||
-rw-r--r-- | src/H5Tpkg.h | 28 | ||||
-rw-r--r-- | src/H5Tprivate.h | 2 | ||||
-rw-r--r-- | src/H5Tpublic.h | 75 | ||||
-rw-r--r-- | src/H5detect.c | 31 | ||||
-rw-r--r-- | src/Makefile.in | 10 | ||||
-rw-r--r-- | test/dsets.c | 87 |
11 files changed, 1338 insertions, 267 deletions
@@ -41,7 +41,6 @@ ./src/H5Cprivate.h ./src/H5Cpublic.h ./src/H5D.c -./src/H5Dconv.c ./src/H5Dprivate.h ./src/H5Dpublic.h ./src/H5E.c @@ -94,6 +93,7 @@ ./src/H5private.h ./src/H5public.h ./src/H5T.c +./src/H5Tconv.c ./src/H5Tpkg.h ./src/H5Tprivate.h ./src/H5Tpublic.h @@ -856,10 +856,14 @@ herr_t H5D_read (H5D_t *dataset, const H5T_t *type, const H5P_t *space, const H5D_xfer_t *xfer_parms, void *buf/*out*/) { - size_t nbytes; + size_t nelmts, src_size, dst_size; size_t offset[H5O_ISTORE_NDIMS]; size_t size[H5O_ISTORE_NDIMS]; intn i; + herr_t ret_value = FAIL; + uint8 *conv_buf = NULL; /*data type conv buffer */ + H5T_conv_t conv_func = NULL; /*conversion function */ + hid_t src_id=-1, dst_id=-1; /*temporary type atoms */ FUNC_ENTER (H5D_read, FAIL); @@ -870,52 +874,81 @@ H5D_read (H5D_t *dataset, const H5T_t *type, const H5P_t *space, assert (buf); if (H5D_CONTIGUOUS!=dataset->create_parms.layout) { - HRETURN_ERROR (H5E_DATASET, H5E_UNSUPPORTED, FAIL, - "layout is not supported yet"); - } - if (H5T_cmp (type, dataset->type)) { - HRETURN_ERROR (H5E_DATASET, H5E_UNSUPPORTED, FAIL, - "type conversion not supported yet"); + HGOTO_ERROR (H5E_DATASET, H5E_UNSUPPORTED, FAIL, + "layout is not supported yet"); } if (space && H5P_cmp (space, dataset->space)) { - HRETURN_ERROR (H5E_DATASET, H5E_UNSUPPORTED, FAIL, - "space conversion not supported yet"); + HGOTO_ERROR (H5E_DATASET, H5E_UNSUPPORTED, FAIL, + "space conversion not supported yet"); } - /* Compute the size of the request */ - nbytes = H5T_get_size (dataset->type) * H5P_get_npoints (dataset->space); + /* + * Convert data types to atoms because the conversion functions are + * application-level functions. + */ + if ((src_id=H5Aregister_atom (H5_DATATYPE, H5T_copy (dataset->type)))<0 || + (dst_id=H5Aregister_atom (H5_DATATYPE, H5T_copy (type)))<0) { + HGOTO_ERROR (H5E_DATASET, H5E_CANTREGISTER, FAIL, + "unable to register types for conversion"); + } + /* Compute the size of the request and allocate scratch buffers */ + nelmts = H5P_get_npoints (dataset->space); + src_size = nelmts * H5T_get_size (dataset->type); + dst_size = nelmts * H5T_get_size (type); + conv_buf = H5MM_xmalloc (MAX (src_size, dst_size)); + if (NULL==(conv_func=H5T_find (dataset->type, type))) { + HGOTO_ERROR (H5E_DATASET, H5E_UNSUPPORTED, FAIL, + "unable to convert between src and dest data types"); + } + + /* + * Read data into the data type conversion buffer. + */ switch (dataset->create_parms.layout) { case H5D_CONTIGUOUS: - /* - * Read a block of contiguous data. - */ + /* Read a block of contiguous data */ if (H5F_block_read (dataset->ent.file, &(dataset->storage.cstore.addr), - nbytes, buf)<0) { - HRETURN_ERROR (H5E_IO, H5E_READERROR, FAIL, "read failed"); + src_size, conv_buf)<0) { + HGOTO_ERROR (H5E_IO, H5E_READERROR, FAIL, "read failed"); } break; case H5D_CHUNKED: - /* - * Read one or more chunks from indexed storage. - */ + /* Read one or more chunks from indexed storage */ for (i=0; i<dataset->storage.istore.ndims; i++) offset[i] = 0; H5P_get_dims (dataset->space, size); size[dataset->storage.istore.ndims-1] = H5T_get_size (dataset->type); if (H5F_istore_read (dataset->ent.file, &(dataset->storage.istore), - offset, size, buf)<0) { - HRETURN_ERROR (H5E_IO, H5E_READERROR, FAIL, "read failed"); + offset, size, conv_buf)<0) { + HGOTO_ERROR (H5E_IO, H5E_READERROR, FAIL, "read failed"); } break; default: assert ("not implemented yet" && 0); - HRETURN_ERROR (H5E_INTERNAL, H5E_UNSUPPORTED, FAIL, - "not implemented yet"); + HGOTO_ERROR (H5E_INTERNAL, H5E_UNSUPPORTED, FAIL, "not implemented yet"); } - FUNC_LEAVE (SUCCEED); + /* + * Perform data type conversion. + */ + if ((conv_func)(src_id, dst_id, nelmts, conv_buf, NULL)<0) { + HGOTO_ERROR (H5E_DATASET, H5E_CANTINIT, FAIL, + "data type conversion failed"); + } + + /* + * Copy conversion buffer into destination. + */ + HDmemcpy (buf, conv_buf, dst_size); + + ret_value = SUCCEED; + done: + if (src_id>=0) H5A_dec_ref (src_id); + if (dst_id>=0) H5A_dec_ref (dst_id); + conv_buf = H5MM_xfree (conv_buf); + FUNC_LEAVE (ret_value); } @@ -945,10 +978,14 @@ herr_t H5D_write (H5D_t *dataset, const H5T_t *type, const H5P_t *space, const H5D_xfer_t *xfer_parms, const void *buf) { - size_t nbytes; + size_t nelmts, src_size, dst_size; size_t offset[H5O_ISTORE_NDIMS]; size_t size[H5O_ISTORE_NDIMS]; intn i; + herr_t ret_value = FAIL; + uint8 *conv_buf = NULL; /*data type conversion buffer */ + H5T_conv_t conv_func = NULL; /*data type conversion function */ + hid_t src_id=-1, dst_id=-1; /*temporary type atoms */ FUNC_ENTER (H5D_write, FAIL); @@ -962,49 +999,79 @@ H5D_write (H5D_t *dataset, const H5T_t *type, const H5P_t *space, HRETURN_ERROR (H5E_DATASET, H5E_UNSUPPORTED, FAIL, "layout is not supported yet"); } - if (H5T_cmp (type, dataset->type)) { - HRETURN_ERROR (H5E_DATASET, H5E_UNSUPPORTED, FAIL, - "type conversion not supported yet"); - } if (space && H5P_cmp (space, dataset->space)) { HRETURN_ERROR (H5E_DATASET, H5E_UNSUPPORTED, FAIL, "space conversion not supported yet"); } - /* Compute the size of the request */ - nbytes = H5T_get_size (dataset->type) * H5P_get_npoints (dataset->space); + /* + * Convert data types to atoms because the conversion functions are + * application-level functions. + */ + if ((src_id=H5Aregister_atom (H5_DATATYPE, H5T_copy (dataset->type)))<0 || + (dst_id=H5Aregister_atom (H5_DATATYPE, H5T_copy (type)))<0) { + HGOTO_ERROR (H5E_DATASET, H5E_CANTREGISTER, FAIL, + "unable to register types for conversion"); + } + + + /* Compute the size of the request and allocate scratch buffers */ + nelmts = H5P_get_npoints (dataset->space); + src_size = nelmts * H5T_get_size (type); + dst_size = nelmts * H5T_get_size (dataset->type); + conv_buf = H5MM_xmalloc (MAX (src_size, dst_size)); + if (NULL==(conv_func=H5T_find (type, dataset->type))) { + HGOTO_ERROR (H5E_DATASET, H5E_UNSUPPORTED, FAIL, + "unable to convert between src and dest data types"); + } + /* + * Read data into the data type conversion buffer. + */ + HDmemcpy (conv_buf, buf, src_size); + + /* + * Perform data type conversion. + */ + if ((conv_func)(src_id, dst_id, nelmts, conv_buf, NULL)<0) { + HGOTO_ERROR (H5E_DATASET, H5E_CANTINIT, FAIL, + "data type conversion failed"); + } + + /* + * Write data into the file. + */ switch (dataset->create_parms.layout) { case H5D_CONTIGUOUS: - /* - * Write a contiguous chunk of data. - */ + /* Write a contiguous chunk of data */ if (H5F_block_write (dataset->ent.file, &(dataset->storage.cstore.addr), - nbytes, buf)<0) { - HRETURN_ERROR (H5E_IO, H5E_WRITEERROR, FAIL, "write failed"); + dst_size, conv_buf)<0) { + HGOTO_ERROR (H5E_IO, H5E_WRITEERROR, FAIL, "write failed"); } break; case H5D_CHUNKED: - /* - * Write one or more chunks to indexed storage. - */ + /* Write one or more chunks to indexed storage */ for (i=0; i<dataset->storage.istore.ndims; i++) offset[i] = 0; H5P_get_dims (dataset->space, size); size[dataset->storage.istore.ndims-1] = H5T_get_size (dataset->type); if (H5F_istore_write (dataset->ent.file, &(dataset->storage.istore), - offset, size, buf)<0) { - HRETURN_ERROR (H5E_IO, H5E_WRITEERROR, FAIL, "write failed"); + offset, size, conv_buf)<0) { + HGOTO_ERROR (H5E_IO, H5E_WRITEERROR, FAIL, "write failed"); } break; default: assert ("not implemented yet" && 0); - HRETURN_ERROR (H5E_INTERNAL, H5E_UNSUPPORTED, FAIL, - "not implemented yet"); + HGOTO_ERROR (H5E_INTERNAL, H5E_UNSUPPORTED, FAIL, "not implemented yet"); } - - FUNC_LEAVE (SUCCEED); + + ret_value = SUCCEED; + done: + if (src_id>=0) H5A_dec_ref (src_id); + if (dst_id>=0) H5A_dec_ref (dst_id); + conv_buf = H5MM_xfree (conv_buf); + FUNC_LEAVE (ret_value); } diff --git a/src/H5Dconv.c b/src/H5Dconv.c deleted file mode 100644 index 5f9ee36..0000000 --- a/src/H5Dconv.c +++ /dev/null @@ -1,133 +0,0 @@ -/**************************************************************************** -* NCSA HDF * -* Software Development Group * -* National Center for Supercomputing Applications * -* University of Illinois at Urbana-Champaign * -* 605 E. Springfield, Champaign IL 61820 * -* * -* For conditions of distribution and use, see the accompanying * -* hdf/COPYING file. * -* * -****************************************************************************/ - -#ifdef RCSID -static char RcsId[] = "@(#)$Revision$"; -#endif - -/* $Id$ */ - -/*LINTLIBRARY */ -/*+ - FILE - H5Dconv.c - HDF5 trivial datatype converion routines - - EXPORTED ROUTINES - - LIBRARY-SCOPED ROUTINES - - LOCAL ROUTINES - + */ - -#include <H5private.h> /* Generic Functions */ -#include <H5Dprivate.h> /* Dataset functions */ -#include <H5Eprivate.h> /* Error handling */ - -#define PABLO_MASK H5D_mask - -/*--------------------- Locally scoped variables -----------------------------*/ - -/* Interface initialization */ -static intn interface_initialize_g = FALSE; -#define INTERFACE_INIT NULL - -/*-------------------------------------------------------------------------- - NAME - H5D_convert_buf - PURPOSE - Byte-Swap a buffer of data - USAGE - herr_t H5D_convert_buf(dst, src, len, size) - VOIDP dst; OUT: Buffer to fill with converted data - VOIDP src; IN: Buffer to converted data from - uintn len; IN: Number of bytes to convert - uintn size; IN: Size of quantity to byte-swap - RETURNS - SUCCEED/FAIL - DESCRIPTION - This function is a byte-swapping memcpy. ---------------------------------------------------------------------------*/ -herr_t H5D_convert_buf(void *dst, const void *src, uintn len, uintn size) -{ - const char *s=(const char *)src; - char *d=(char *)dst; - herr_t ret_value = SUCCEED; - - FUNC_ENTER(H5D_convert_buf, FAIL); - - /* Clear errors and check args and all the boring stuff. */ - H5ECLEAR; - assert(dst); - assert(src); - assert(len>0); - assert(size==8 || size==4 || size==2 || size==1); - - switch(size) - { - case 1: /* straight memcpy() */ - HDmemcpy(d,s,len); - break; - - case 2: /* 2-byte swapping */ - while(len>0) - { - *d++=*(s+1); - *d++=*s; - s+=2; - len-=2; - } /* end while */ - break; - - case 4: /* 4-byte swapping */ - while(len>0) - { - *d++=*(s+3); - *d++=*(s+2); - *d++=*(s+1); - *d++=*s; - s+=4; - len-=4; - } /* end while */ - break; - - case 8: /* 8-byte swapping */ - while(len>0) - { - *d++=*(s+7); - *d++=*(s+6); - *d++=*(s+5); - *d++=*(s+4); - *d++=*(s+3); - *d++=*(s+2); - *d++=*(s+1); - *d++=*s; - s+=8; - len-=8; - } /* end while */ - break; - - default: - HGOTO_ERROR(H5E_INTERNAL, H5E_UNSUPPORTED, FAIL, - "not implemented yet"); - } /* end switch */ - -done: - if(ret_value == FAIL) - { /* Error condition cleanup */ - - } /* end if */ - - /* Normal function cleanup */ - - FUNC_LEAVE(ret_value); -} /* end H5D_convert_buf() */ diff --git a/src/H5Odtype.c b/src/H5Odtype.c index 2d830e9..35105de 100644 --- a/src/H5Odtype.c +++ b/src/H5Odtype.c @@ -95,8 +95,8 @@ H5O_dtype_decode_helper (const uint8 **pp, H5T_t *dt) * 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; - dt->u.atomic.hi_pad = (flags & 0x4) ? H5T_PAD_ONE : H5T_PAD_ZERO; + 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; dt->u.atomic.u.i.sign = (flags & 0x8) ? H5T_SGN_2 : H5T_SGN_NONE; UINT16DECODE (*pp, dt->u.atomic.offset); UINT16DECODE (*pp, dt->u.atomic.prec); @@ -107,8 +107,8 @@ H5O_dtype_decode_helper (const uint8 **pp, H5T_t *dt) * Floating-point 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; - dt->u.atomic.hi_pad = (flags & 0x4) ? H5T_PAD_ONE : H5T_PAD_ZERO; + 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; dt->u.atomic.u.f.pad = (flags & 0x8) ? H5T_PAD_ONE : H5T_PAD_ZERO; switch ((flags>>4) & 0x03) { case 0: @@ -232,7 +232,7 @@ H5O_dtype_encode_helper (uint8 **pp, const H5T_t *dt) "byte order is not supported in file format yet"); } - switch (dt->u.atomic.lo_pad) { + switch (dt->u.atomic.lsb_pad) { case H5T_PAD_ZERO: break; /*nothing*/ case H5T_PAD_ONE: @@ -243,7 +243,7 @@ H5O_dtype_encode_helper (uint8 **pp, const H5T_t *dt) "bit padding is not supported in file format yet"); } - switch (dt->u.atomic.hi_pad) { + switch (dt->u.atomic.msb_pad) { case H5T_PAD_ZERO: break; /*nothing*/ case H5T_PAD_ONE: @@ -284,7 +284,7 @@ H5O_dtype_encode_helper (uint8 **pp, const H5T_t *dt) "byte order is not supported in file format yet"); } - switch (dt->u.atomic.lo_pad) { + switch (dt->u.atomic.lsb_pad) { case H5T_PAD_ZERO: break; /*nothing*/ case H5T_PAD_ONE: @@ -295,7 +295,7 @@ H5O_dtype_encode_helper (uint8 **pp, const H5T_t *dt) "bit padding is not supported in file format yet"); } - switch (dt->u.atomic.hi_pad) { + switch (dt->u.atomic.msb_pad) { case H5T_PAD_ZERO: break; /*nothing*/ case H5T_PAD_ONE: @@ -739,7 +739,7 @@ H5O_dtype_debug (H5F_t *f, const void *mesg, FILE *stream, (unsigned long)(dt->u.atomic.offset), 1==dt->u.atomic.offset?"":"s"); - switch (dt->u.atomic.lo_pad) { + switch (dt->u.atomic.lsb_pad) { case H5T_PAD_ZERO: s = "zero"; break; @@ -747,18 +747,13 @@ H5O_dtype_debug (H5F_t *f, const void *mesg, FILE *stream, s = "one"; break; default: - if (dt->u.atomic.lo_pad<0) { - sprintf (buf, "H5T_PAD_%d", -(dt->u.atomic.lo_pad)); - } else { - sprintf (buf, "bit-%d", dt->u.atomic.lo_pad); - } - s = buf; + s = "pad?"; break; } fprintf (stream, "%*s%-*s %s\n", indent, "", fwidth, "Low pad type:", s); - switch (dt->u.atomic.hi_pad) { + switch (dt->u.atomic.msb_pad) { case H5T_PAD_ZERO: s = "zero"; break; @@ -766,12 +761,7 @@ H5O_dtype_debug (H5F_t *f, const void *mesg, FILE *stream, s = "one"; break; default: - if (dt->u.atomic.hi_pad<0) { - sprintf (buf, "H5T_PAD_%d", -(dt->u.atomic.hi_pad)); - } else { - sprintf (buf, "bit-%d", dt->u.atomic.hi_pad); - } - s = buf; + s = "pad?"; break; } fprintf (stream, "%*s%-*s %s\n", indent, "", fwidth, @@ -33,6 +33,44 @@ static intn interface_initialize_g = FALSE; #define INTERFACE_INIT H5T_init_interface static void H5T_term_interface (void); +/* Predefined types */ +hid_t H5T_NATIVE_CHAR_g = FAIL; +hid_t H5T_NATIVE_UCHAR_g = FAIL; +hid_t H5T_NATIVE_SHORT_g = FAIL; +hid_t H5T_NATIVE_USHORT_g = FAIL; +hid_t H5T_NATIVE_INT_g = FAIL; +hid_t H5T_NATIVE_UINT_g = FAIL; +hid_t H5T_NATIVE_LONG_g = FAIL; +hid_t H5T_NATIVE_LLONG_g = FAIL; +hid_t H5T_NATIVE_ULLONG_g = FAIL; +hid_t H5T_NATIVE_HYPER_g = FAIL; +hid_t H5T_NATIVE_UHYPER_g = FAIL; +hid_t H5T_NATIVE_INT8_g = FAIL; +hid_t H5T_NATIVE_UINT8_g = FAIL; +hid_t H5T_NATIVE_INT16_g = FAIL; +hid_t H5T_NATIVE_UINT16_g = FAIL; +hid_t H5T_NATIVE_INT32_g = FAIL; +hid_t H5T_NATIVE_UINT32_g = FAIL; +hid_t H5T_NATIVE_INT64_g = FAIL; +hid_t H5T_NATIVE_UINT64_g = FAIL; +hid_t H5T_NATIVE_ULONG_g = FAIL; +hid_t H5T_NATIVE_FLOAT_g = FAIL; +hid_t H5T_NATIVE_DOUBLE_g = FAIL; +hid_t H5T_NATIVE_TIME_g = FAIL; +hid_t H5T_NATIVE_STRING_g = FAIL; +hid_t H5T_NATIVE_BITFIELD_g = FAIL; +hid_t H5T_NATIVE_OPAQUE_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 */ + +/* The soft conversion function master list */ +static intn H5T_nsoft_g = 0; /*num soft funcs defined*/ +static intn H5T_asoft_g = 0; /*num slots allocated */ +static H5T_soft_t *H5T_soft_g = NULL; /*master soft list */ + /*-------------------------------------------------------------------------- NAME H5T_init_interface -- Initialize interface-specific information @@ -48,7 +86,10 @@ DESCRIPTION herr_t H5T_init_interface (void) { - herr_t ret_value = SUCCEED; + H5T_t *dt = NULL; + herr_t ret_value = SUCCEED; + + interface_initialize_g = TRUE; FUNC_ENTER (H5T_init_interface, FAIL); /* Initialize the atom group for the file IDs */ @@ -58,8 +99,153 @@ H5T_init_interface (void) ret_value=H5_add_exit (&H5T_term_interface); } - /* Initialize pre-defined data types */ + /* + * Initialize pre-defined data types that depend on the architecture. + */ ret_value = H5T_init (); + + /* + * Initialize pre-define data types that can be derived from + * architecture-dependent types. + */ + + /* INT8 */ + H5T_NATIVE_INT8_g = H5Tcopy (H5T_NATIVE_INT_g); + H5Tset_size (H5T_NATIVE_INT8_g, 1); + H5Tset_precision (H5T_NATIVE_INT8_g, 8); + H5Tlock (H5T_NATIVE_INT8_g); + + /* UINT8 */ + H5T_NATIVE_UINT8_g = H5Tcopy (H5T_NATIVE_UINT_g); + H5Tset_size (H5T_NATIVE_UINT8_g, 1); + H5Tset_precision (H5T_NATIVE_UINT8_g, 8); + H5Tlock (H5T_NATIVE_UINT8_g); + + /* INT16 */ + H5T_NATIVE_INT16_g = H5Tcopy (H5T_NATIVE_INT_g); + H5Tset_size (H5T_NATIVE_INT16_g, 2); + H5Tset_precision (H5T_NATIVE_INT16_g, 16); + H5Tlock (H5T_NATIVE_INT16_g); + + /* UINT16 */ + H5T_NATIVE_UINT16_g = H5Tcopy (H5T_NATIVE_UINT_g); + H5Tset_size (H5T_NATIVE_UINT16_g, 2); + H5Tset_precision (H5T_NATIVE_UINT16_g, 16); + H5Tlock (H5T_NATIVE_UINT16_g); + + /* INT32 */ + H5T_NATIVE_INT32_g = H5Tcopy (H5T_NATIVE_INT_g); + H5Tset_size (H5T_NATIVE_INT32_g, 4); + H5Tset_precision (H5T_NATIVE_INT32_g, 32); + H5Tlock (H5T_NATIVE_INT32_g); + + /* UINT32 */ + H5T_NATIVE_UINT32_g = H5Tcopy (H5T_NATIVE_UINT_g); + H5Tset_size (H5T_NATIVE_UINT32_g, 4); + H5Tset_precision (H5T_NATIVE_UINT32_g, 32); + H5Tlock (H5T_NATIVE_UINT32_g); + + /* INT64 */ + H5T_NATIVE_INT64_g = H5Tcopy (H5T_NATIVE_INT_g); + H5Tset_size (H5T_NATIVE_INT64_g, 8); + H5Tset_precision (H5T_NATIVE_INT64_g, 64); + H5Tlock (H5T_NATIVE_INT64_g); + + /* UINT64 */ + H5T_NATIVE_UINT64_g = H5Tcopy (H5T_NATIVE_UINT_g); + H5Tset_size (H5T_NATIVE_UINT64_g, 8); + H5Tset_precision (H5T_NATIVE_UINT64_g, 64); + H5Tlock (H5T_NATIVE_UINT64_g); + + + /* + * Initialize pre-defined data types that don't depend on architecture. + */ + + /* TIME */ + dt = H5MM_xcalloc (1, sizeof(H5T_t)); + dt->locked = TRUE; + dt->type = H5T_TIME; + dt->size = 1; + dt->u.atomic.order = H5Tget_order (H5T_NATIVE_INT_g); + 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; + if ((H5T_NATIVE_TIME_g = H5Aregister_atom (H5_DATATYPE, dt))<0) { + HRETURN_ERROR (H5E_DATATYPE, H5E_CANTINIT, FAIL, + "can't initialize H5T layer"); + } + + /* STRING */ + dt = H5MM_xcalloc (1, sizeof(H5T_t)); + dt->locked = TRUE; + dt->type = H5T_STRING; + 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.atomic.u.s.cset = H5T_CSET_ASCII; + dt->u.atomic.u.s.pad = H5T_STR_NULL; + if ((H5T_NATIVE_STRING_g = H5Aregister_atom (H5_DATATYPE, dt))<0) { + HRETURN_ERROR (H5E_DATATYPE, H5E_CANTINIT, FAIL, + "can't initialize H5T layer"); + } + + /* BITFIELD */ + dt = H5MM_xcalloc (1, sizeof(H5T_t)); + dt->locked = TRUE; + dt->type = H5T_BITFIELD; + dt->size = 1; + dt->u.atomic.order = H5Tget_order (H5T_NATIVE_INT_g); + 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; + if ((H5T_NATIVE_BITFIELD_g = H5Aregister_atom (H5_DATATYPE, dt))<0) { + HRETURN_ERROR (H5E_DATATYPE, H5E_CANTINIT, FAIL, + "unable to initialize H5T layer"); + } + + /* OPAQUE */ + dt = H5MM_xcalloc (1, sizeof(H5T_t)); + dt->locked = TRUE; + 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; + if ((H5T_NATIVE_OPAQUE_g = H5Aregister_atom (H5_DATATYPE, dt))<0) { + HRETURN_ERROR (H5E_DATATYPE, H5E_CANTINIT, FAIL, + "unable to initialize H5T layer"); + } + + /* + * Define aliases. + */ + H5T_NATIVE_HYPER_g = H5Tcopy (H5T_NATIVE_LLONG_g); + H5Tlock (H5T_NATIVE_HYPER_g); + + H5T_NATIVE_UHYPER_g = H5Tcopy (H5T_NATIVE_ULLONG_g); + H5Tlock (H5T_NATIVE_UHYPER_g); + + /* + * Register conversion functions beginning with the most general and + * ending with the most specific. + */ + + if (H5Tregister_soft (H5T_INTEGER, H5T_INTEGER, H5T_conv_order)<0) { + HRETURN_ERROR (H5E_DATATYPE, H5E_CANTINIT, FAIL, + "unable to register conversion function"); + } + if (H5Tregister_soft (H5T_FLOAT, H5T_FLOAT, H5T_conv_order)<0) { + HRETURN_ERROR (H5E_DATATYPE, H5E_CANTINIT, FAIL, + "unable to register conversion function"); + } FUNC_LEAVE (ret_value); } @@ -272,6 +458,45 @@ H5Tequal (hid_t type1_id, hid_t type2_id) /*------------------------------------------------------------------------- + * Function: H5Tlock + * + * Purpose: Locks a type, making it read only and non-destructable. This + * is normally done by the library for predefined data types so + * the application doesn't inadvertently change or delete a + * predefined type. + * + * Once a data type is locked it can never be unlocked. + * + * Return: Success: SUCCEED + * + * Failure: FAIL + * + * Programmer: Robb Matzke + * Friday, January 9, 1998 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +herr_t +H5Tlock (hid_t type_id) +{ + H5T_t *dt = NULL; + + FUNC_ENTER (H5Tlock, FAIL); + + /* 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"); + } + + dt->locked = TRUE; + FUNC_LEAVE (SUCCEED); +} + + +/*------------------------------------------------------------------------- * Function: H5Tget_class * * Purpose: Returns the data type class identifier for data type TYPE_ID. @@ -358,6 +583,9 @@ H5Tget_size (hid_t type_id) * hang over the edge of the new size, then the number of * significant bits is decreased. * + * Adjusting the size of an H5T_STRING automatically sets the + * precision to 8*size. + * * All data types have a positive size. * * Return: Success: SUCCEED @@ -405,11 +633,15 @@ H5Tset_size (hid_t type_id, size_t size) switch (dt->type) { case H5T_INTEGER: case H5T_TIME: - case H5T_STRING: case H5T_BITFIELD: /* nothing to check */ break; + case H5T_STRING: + prec = 8*size; + offset = 0; + break; + case H5T_FLOAT: /* * The sign, mantissa, and exponent fields should be adjusted first @@ -585,6 +817,9 @@ H5Tget_precision (hid_t type_id) * and then the size is increased to insure that significant * bits do not "hang over" the edge of the data type. * + * Changing the precision of an H5T_STRING automatically changes + * the size as well. The precision must be a multiple of 8. + * * When decreasing the precision of a floating point type, set * the locations and sizes of the sign, mantissa, and exponent * fields first. @@ -634,12 +869,20 @@ H5Tset_precision (hid_t type_id, size_t prec) switch (dt->type) { case H5T_INTEGER: case H5T_TIME: - case H5T_STRING: case H5T_BITFIELD: case H5T_OPAQUE: /* nothing to check */ break; + case H5T_STRING: + if (prec % 8) { + HRETURN_ERROR (H5E_ARGS, H5E_BADVALUE, FAIL, + "precision for this type must be a multiple of 8"); + } + offset = 0; + size = prec / 8; + break; + case H5T_FLOAT: /* * The sign, mantissa, and exponent fields should be adjusted first @@ -746,6 +989,8 @@ H5Tget_offset (hid_t type_id) * incremented also if necessary to prevent significant bits of * the value from hanging over the edge of the data type. * + * The offset of an H5T_STRING cannot be set to anything but + * zero. * * Return: Success: SUCCEED * @@ -761,7 +1006,6 @@ H5Tget_offset (hid_t type_id) herr_t H5Tset_offset (hid_t type_id, size_t offset) { - H5T_t *dt = NULL; FUNC_ENTER (H5Tset_offset, FAIL); @@ -776,9 +1020,9 @@ H5Tset_offset (hid_t type_id, size_t offset) if (dt->locked) { HRETURN_ERROR (H5E_ARGS, H5E_CANTINIT, FAIL, "data type is read-only"); } - if (offset<=0) { + if (H5T_STRING==dt->type && offset!=0) { HRETURN_ERROR (H5E_ARGS, H5E_BADVALUE, FAIL, - "precision must be positive"); + "offset must be zero for this type"); } /* Adjust the size */ @@ -794,6 +1038,91 @@ H5Tset_offset (hid_t type_id, size_t offset) /*------------------------------------------------------------------------- + * Function: H5Tget_pad + * + * Purpose: Gets the least significant pad type and the most significant + * pad type and returns their values through the LSB and MSB + * arguments, either of which may be the null pointer. + * + * Return: Success: SUCCEED + * + * Failure: FAIL + * + * Programmer: Robb Matzke + * Friday, January 9, 1998 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +herr_t +H5Tget_pad (hid_t type_id, H5T_pad_t *lsb/*out*/, H5T_pad_t *msb/*out*/) +{ + H5T_t *dt = NULL; + + FUNC_ENTER (H5Tget_pad, 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"); + } + + /* Get values */ + if (lsb) *lsb = dt->u.atomic.lsb_pad; + if (msb) *msb = dt->u.atomic.msb_pad; + + FUNC_LEAVE (SUCCEED); +} + + +/*------------------------------------------------------------------------- + * Function: H5Tset_pad + * + * Purpose: Sets the LSB and MSB pad types. + * + * Return: Success: + * + * Failure: + * + * Programmer: Robb Matzke + * Friday, January 9, 1998 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +herr_t +H5Tset_pad (hid_t type_id, H5T_pad_t lsb, H5T_pad_t msb) +{ + H5T_t *dt = NULL; + + FUNC_ENTER (H5Tset_pad, 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 (lsb<0 || lsb>=H5T_NPAD || msb<0 || msb>=H5T_NPAD) { + HRETURN_ERROR (H5E_ARGS, H5E_BADVALUE, FAIL, "invalid pad type"); + } + + dt->u.atomic.lsb_pad = lsb; + dt->u.atomic.msb_pad = msb; + + FUNC_LEAVE (SUCCEED); +} + + +/*------------------------------------------------------------------------- * Function: H5Tget_sign * * Purpose: Retrieves the sign type for an integer type. @@ -866,7 +1195,7 @@ H5Tset_sign (hid_t type_id, H5T_sign_t sign) if (dt->locked) { HRETURN_ERROR (H5E_ARGS, H5E_CANTINIT, FAIL, "data type is read-only"); } - if (sign<0 || sign>=H5T_SGN_N) { + if (sign<0 || sign>=H5T_NSGN) { HRETURN_ERROR (H5E_ARGS, H5E_BADVALUE, FAIL, "illegal sign type"); } @@ -1175,6 +1504,274 @@ H5Tset_norm (hid_t type_id, H5T_norm_t norm) /*------------------------------------------------------------------------- + * Function: H5Tget_inpad + * + * Purpose: If any internal bits of a floating point type are unused + * (that is, those significant bits which are not part of the + * sign, exponent, or mantissa) then they will be filled + * according to the value of this property. + * + * Return: Success: The internal padding type. + * + * Failure: H5T_PAD_ERROR (-1, same as FAIL) + * + * Programmer: Robb Matzke + * Friday, January 9, 1998 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +H5T_pad_t +H5Tget_inpad (hid_t type_id) +{ + H5T_t *dt = NULL; + H5T_pad_t pad; + + FUNC_ENTER (H5Tget_inpad, H5T_PAD_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_PAD_ERROR, + "not a floating-point data type"); + } + + /* pad */ + pad = dt->u.atomic.u.f.pad; + + FUNC_LEAVE (pad); +} + + +/*------------------------------------------------------------------------- + * Function: H5Tset_inpad + * + * Purpose: If any internal bits of a floating point type are unused + * (that is, those significant bits which are not part of the + * sign, exponent, or mantissa) then they will be filled + * according to the value of this property. + * + * Return: Success: + * + * Failure: + * + * Programmer: Robb Matzke + * Friday, January 9, 1998 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +herr_t +H5Tset_inpad (hid_t type_id, H5T_pad_t pad) +{ + H5T_t *dt = NULL; + + FUNC_ENTER (H5Tset_inpad, 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 (pad<0 || pad>=H5T_NPAD) { + HRETURN_ERROR (H5E_ARGS, H5E_BADVALUE, FAIL, + "illegal internal pad type"); + } + + /* pad */ + dt->u.atomic.u.f.pad = pad; + FUNC_LEAVE (SUCCEED); +} + + +/*------------------------------------------------------------------------- + * Function: H5Tget_cset + * + * Purpose: HDF5 is able to distinguish between character sets of + * different nationalities and to convert between them to the + * extent possible. + * + * Return: Success: The character set of an H5T_STRING type. + * + * Failure: H5T_CSET_ERROR (-1, same as FAIL) + * + * Programmer: Robb Matzke + * Friday, January 9, 1998 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +H5T_cset_t +H5Tget_cset (hid_t type_id) +{ + H5T_t *dt = NULL; + H5T_cset_t cset; + + FUNC_ENTER (H5Tget_cset, H5T_CSET_ERROR); + H5ECLEAR; + + /* Check args */ + if (H5_DATATYPE!=H5Aatom_group (type_id) || + NULL==(dt=H5Aatom_object (type_id)) || + H5T_STRING!=dt->type) { + HRETURN_ERROR (H5E_ARGS, H5E_BADTYPE, H5T_CSET_ERROR, + "not a string data type"); + } + + /* result */ + cset = dt->u.atomic.u.s.cset; + + FUNC_LEAVE (cset); +} + + +/*------------------------------------------------------------------------- + * Function: H5Tset_cset + * + * Purpose: HDF5 is able to distinguish between character sets of + * different nationalities and to convert between them to the + * extent possible. + * + * Return: Success: SUCCEED + * + * Failure: FAIL + * + * Programmer: Robb Matzke + * Friday, January 9, 1998 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +herr_t +H5Tset_cset (hid_t type_id, H5T_cset_t cset) +{ + H5T_t *dt = NULL; + + FUNC_ENTER (H5Tset_cset, FAIL); + H5ECLEAR; + + /* Check args */ + if (H5_DATATYPE!=H5Aatom_group (type_id) || + NULL==(dt=H5Aatom_object (type_id)) || + H5T_STRING!=dt->type) { + HRETURN_ERROR (H5E_ARGS, H5E_BADTYPE, FAIL, "not a string data type"); + } + if (dt->locked) { + HRETURN_ERROR (H5E_ARGS, H5E_CANTINIT, FAIL, "data type is read-only"); + } + if (cset<0 || cset>=H5T_NCSET) { + HRETURN_ERROR (H5E_ARGS, H5E_BADVALUE, FAIL, + "illegal character set type"); + } + + /* set */ + dt->u.atomic.u.s.cset = cset; + FUNC_LEAVE (SUCCEED); +} + + +/*------------------------------------------------------------------------- + * Function: H5Tget_strpad + * + * Purpose: The method used to store character strings differs with the + * programming language: C usually null terminates strings while + * Fortran left-justifies and space-pads strings. This property + * defines the storage mechanism for the string. + * + * Return: Success: The character set of an H5T_STRING type. + * + * Failure: H5T_STR_ERROR (-1, same as FAIL) + * + * Programmer: Robb Matzke + * Friday, January 9, 1998 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +H5T_str_t +H5Tget_strpad (hid_t type_id) +{ + H5T_t *dt = NULL; + H5T_str_t strpad; + + FUNC_ENTER (H5Tget_strpad, H5T_STR_ERROR); + H5ECLEAR; + + /* Check args */ + if (H5_DATATYPE!=H5Aatom_group (type_id) || + NULL==(dt=H5Aatom_object (type_id)) || + H5T_STRING!=dt->type) { + HRETURN_ERROR (H5E_ARGS, H5E_BADTYPE, H5T_STR_ERROR, + "not a string data type"); + } + + /* result */ + strpad = dt->u.atomic.u.s.pad; + + FUNC_LEAVE (strpad); +} + + +/*------------------------------------------------------------------------- + * Function: H5Tset_strpad + * + * Purpose: The method used to store character strings differs with the + * programming language: C usually null terminates strings while + * Fortran left-justifies and space-pads strings. This property + * defines the storage mechanism for the string. + * + * Return: Success: SUCCEED + * + * Failure: FAIL + * + * Programmer: Robb Matzke + * Friday, January 9, 1998 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +herr_t +H5Tset_strpad (hid_t type_id, H5T_str_t strpad) +{ + H5T_t *dt = NULL; + + FUNC_ENTER (H5Tset_strpad, FAIL); + H5ECLEAR; + + /* Check args */ + if (H5_DATATYPE!=H5Aatom_group (type_id) || + NULL==(dt=H5Aatom_object (type_id)) || + H5T_STRING!=dt->type) { + HRETURN_ERROR (H5E_ARGS, H5E_BADTYPE, FAIL, "not a string data type"); + } + if (dt->locked) { + HRETURN_ERROR (H5E_ARGS, H5E_CANTINIT, FAIL, "data type is read-only"); + } + if (strpad<0 || strpad>=H5T_NSTR) { + HRETURN_ERROR (H5E_ARGS, H5E_BADVALUE, FAIL, "illegal string pad type"); + } + + /* set */ + dt->u.atomic.u.s.pad = strpad; + FUNC_LEAVE (SUCCEED); +} + + +/*------------------------------------------------------------------------- * Function: H5Tget_nmembers * * Purpose: Determines how many members compound data type TYPE_ID has. @@ -1510,7 +2107,264 @@ H5Tpack (hid_t type_id) FUNC_LEAVE (SUCCEED); } + +/*------------------------------------------------------------------------- + * Function: H5Tregister_hard + * + * Purpose: Register a hard conversion function for a data type + * conversion path. The path is specified by the source and + * destination data types SRC_ID and DST_ID. A conversion path + * can only have one hard function, so FUNC replaces any + * previous hard function. + * + * If FUNC is the null pointer then any hard function registered + * for this path is removed from this path. The soft functions + * are then used when determining which conversion function is + * appropriate for this path. + * + * Return: Success: SUCCEED + * + * Failure: FAIL + * + * Programmer: Robb Matzke + * Friday, January 9, 1998 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +herr_t +H5Tregister_hard (hid_t src_id, hid_t dst_id, H5T_conv_t func) +{ + H5T_t *src = NULL; + H5T_t *dst = NULL; + H5T_path_t *path = NULL; + + FUNC_ENTER (H5Tregister_hard, FAIL); + + /* Check args */ + if (H5_DATATYPE!=H5Aatom_group (src_id) || + NULL==(src=H5Aatom_object (src_id)) || + H5_DATATYPE!=H5Aatom_group (dst_id) || + NULL==(dst=H5Aatom_object (dst_id))) { + HRETURN_ERROR (H5E_ARGS, H5E_BADTYPE, FAIL, "not a data type"); + } + + /* Locate or create a new conversion path */ + if (NULL==(path=H5T_path_find (src, dst, TRUE))) { + HRETURN_ERROR (H5E_DATATYPE, H5E_CANTINIT, FAIL, + "unable to locate/allocate conversion path"); + } + + /* Initialize the hard function */ + path->hard = func; + FUNC_LEAVE (SUCCEED); +} + + +/*------------------------------------------------------------------------- + * Function: H5Tregister_soft + * + * Purpose: Registers a soft conversion function by adding it to the end + * of the master soft list and replacing the soft function in + * all applicable existing conversion paths. + * + * Return: Success: SUCCEED + * + * Failure: FAIL + * + * Programmer: Robb Matzke + * Tuesday, January 13, 1998 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +herr_t +H5Tregister_soft (H5T_class_t src_cls, H5T_class_t dst_cls, H5T_conv_t func) +{ + intn i; + hid_t src_id, dst_id; + + FUNC_ENTER (H5Tregister_soft, FAIL); + + /* Check args */ + if (src_cls<0 || src_cls>=H5T_NCLASSES || + dst_cls<0 || dst_cls>=H5T_NCLASSES) { + HRETURN_ERROR (H5E_ARGS, H5E_BADVALUE, FAIL, + "illegal source or destination data type class"); + } + if (!func) { + HRETURN_ERROR (H5E_ARGS, H5E_BADVALUE, FAIL, + "no soft conversion function specified"); + } + + /* Add function to end of master list */ + if (H5T_nsoft_g>=H5T_asoft_g) { + H5T_asoft_g = MAX (32, 2*H5T_asoft_g); + H5T_soft_g = H5MM_xrealloc (H5T_soft_g, H5T_asoft_g*sizeof(H5T_soft_t)); + } + H5T_soft_g[H5T_nsoft_g].src = src_cls; + H5T_soft_g[H5T_nsoft_g].dst = dst_cls; + H5T_soft_g[H5T_nsoft_g].func = func; + H5T_nsoft_g++; + + /* Replace soft functions of all appropriate paths */ + for (i=0; i<H5T_npath_g; i++) { + H5T_path_t *path = H5T_path_g + i; + + /* + * Type conversion functions are app-level, so we need to convert the + * data type temporarily to an object id before we query the functions + * capabilities. + */ + if (path->src->type!=src_cls || path->dst->type!=dst_cls) continue; + if ((src_id = H5Aregister_atom (H5_DATATYPE, H5T_copy (path->src)))<0 || + (dst_id = H5Aregister_atom (H5_DATATYPE, H5T_copy (path->dst)))<0) { + HRETURN_ERROR (H5E_DATATYPE, H5E_CANTREGISTER, FAIL, + "unable to register data types for conv query"); + } + if ((func)(src_id, dst_id, 0, NULL, NULL)>=0) { + path->soft = func; + } + H5A_dec_ref (src_id); + H5A_dec_ref (dst_id); + H5ECLEAR; + } + + FUNC_LEAVE (SUCCEED); +} + + +/*------------------------------------------------------------------------- + * Function: H5Tunregister + * + * Purpose: Removes FUNC from all conversion paths. If FUNC is + * registered as the soft conversion function of a path then it + * is replaced with some other soft conversion function from the + * master soft list if one applies. + * + * Return: Success: SUCCEED + * + * Failure: FAIL + * + * Programmer: Robb Matzke + * Tuesday, January 13, 1998 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +herr_t +H5Tunregister (H5T_conv_t func) +{ + intn i, j; + H5T_path_t *path = NULL; + hid_t src_id, dst_id; + + FUNC_ENTER (H5Tunregister, FAIL); + + /* Check args */ + if (!func) { + HRETURN_ERROR (H5E_ARGS, H5E_BADVALUE, FAIL, "no conversion function"); + } + + /* Remove function from master soft list */ + for (i=H5T_nsoft_g-1; i>=0; --i) { + if (H5T_soft_g[i].func==func) { + HDmemmove (H5T_soft_g+i, H5T_soft_g+i+1, + (H5T_nsoft_g-(i+1))*sizeof(H5T_soft_t)); + --H5T_nsoft_g; + } + } + + /* Remove function from all conversion paths */ + for (i=0; i<H5T_npath_g; i++) { + path = H5T_path_g + i; + + /* Reset hard function */ + if (path->hard==func) { + path->hard = NULL; + } + + /* Reset soft function */ + if (path->soft==func) { + path->soft = NULL; + for (j=H5T_nsoft_g-1; j>=0 && !path->soft; --j) { + if (path->src->type!=H5T_soft_g[j].src || + path->dst->type!=H5T_soft_g[j].dst) { + continue; + } + + /* + * Conversion functions are app-level, so temporarily create + * object id's for the data types. + */ + if ((src_id=H5Aregister_atom (H5_DATATYPE, + H5T_copy (path->src)))<0 || + (dst_id=H5Aregister_atom (H5_DATATYPE, + H5T_copy (path->dst)))<0) { + HRETURN_ERROR (H5E_DATATYPE, H5E_CANTREGISTER, FAIL, + "unable to register conv types for query"); + } + if ((H5T_soft_g[j].func)(src_id, dst_id, 0, NULL, NULL)>=0) { + path->soft = H5T_soft_g[j].func; + } + H5A_dec_ref (src_id); + H5A_dec_ref (dst_id); + H5ECLEAR; + } + } + } + + FUNC_LEAVE (SUCCEED); +} + + +/*------------------------------------------------------------------------- + * Function: H5Tfind + * + * Purpose: Finds a conversion function that can handle a conversion from + * type SRC_ID to type DST_ID. + * + * Return: Success: A pointer to a suitable conversion function. + * + * Failure: NULL + * + * Programmer: Robb Matzke + * Tuesday, January 13, 1998 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +H5T_conv_t +H5Tfind (hid_t src_id, hid_t dst_id) +{ + H5T_conv_t ret_value = NULL; + H5T_t *src=NULL, *dst=NULL; + FUNC_ENTER (H5Tfind, NULL); + + /* Check args */ + if (H5_DATATYPE!=H5Aatom_group (src_id) || + NULL==(src=H5Aatom_object (src_id)) || + H5_DATATYPE!=H5Aatom_group (dst_id) || + NULL==(dst=H5Aatom_object (dst_id))) { + HRETURN_ERROR (H5E_ARGS, H5E_BADTYPE, NULL, "not a data type"); + } + + /* Find it */ + if (NULL==(ret_value = H5T_find (src, dst))) { + HRETURN_ERROR (H5E_DATATYPE, H5E_NOTFOUND, NULL, + "conversion function not found"); + } + + FUNC_LEAVE (ret_value); +} + + + /*------------------------------------------------------------------------- @@ -1553,28 +2407,13 @@ H5T_create (H5T_class_t type, size_t size) switch (type) { 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, - "can't derive type from native int"); - } - break; - case H5T_FLOAT: - /* Default type is a native `double' */ - if (NULL==(dt=H5T_copy (H5Aatom_object (H5T_NATIVE_DOUBLE)))) { - HRETURN_ERROR (H5E_DATATYPE, H5E_CANTINIT, NULL, - "can't derive type from native double"); - } - break; - case H5T_TIME: case H5T_STRING: case H5T_BITFIELD: case H5T_OPAQUE: - assert ("not implemented yet" && 0); HRETURN_ERROR (H5E_DATATYPE, H5E_UNSUPPORTED, NULL, - "not implemented yet"); + "type class is not appropriate - use H5Tcopy()"); case H5T_COMPOUND: dt = H5MM_xcalloc (1, sizeof(H5T_t)); @@ -2057,11 +2896,11 @@ H5T_cmp (const H5T_t *dt1, const H5T_t *dt2) if (dt1->u.atomic.offset < dt2->u.atomic.offset) HGOTO_DONE (-1); if (dt1->u.atomic.offset > dt2->u.atomic.offset) HGOTO_DONE (1); - if (dt1->u.atomic.lo_pad < dt2->u.atomic.lo_pad) HGOTO_DONE (-1); - if (dt1->u.atomic.lo_pad > dt2->u.atomic.lo_pad) HGOTO_DONE (1); + if (dt1->u.atomic.lsb_pad < dt2->u.atomic.lsb_pad) HGOTO_DONE (-1); + if (dt1->u.atomic.lsb_pad > dt2->u.atomic.lsb_pad) HGOTO_DONE (1); - if (dt1->u.atomic.hi_pad < dt2->u.atomic.hi_pad) HGOTO_DONE (-1); - if (dt1->u.atomic.hi_pad > dt2->u.atomic.hi_pad) HGOTO_DONE (1); + if (dt1->u.atomic.msb_pad < dt2->u.atomic.msb_pad) HGOTO_DONE (-1); + if (dt1->u.atomic.msb_pad > dt2->u.atomic.msb_pad) HGOTO_DONE (1); switch (dt1->type) { case H5T_INTEGER: @@ -2110,8 +2949,8 @@ H5T_cmp (const H5T_t *dt1, const H5T_t *dt2) if (dt1->u.atomic.u.s.cset < dt1->u.atomic.u.s.cset) HGOTO_DONE (-1); if (dt1->u.atomic.u.s.cset > dt1->u.atomic.u.s.cset) HGOTO_DONE (1); - if (dt1->u.atomic.u.s.spad < dt1->u.atomic.u.s.spad) HGOTO_DONE (-1); - if (dt1->u.atomic.u.s.spad > dt1->u.atomic.u.s.spad) HGOTO_DONE (1); + if (dt1->u.atomic.u.s.pad < dt1->u.atomic.u.s.pad) HGOTO_DONE (-1); + if (dt1->u.atomic.u.s.pad > dt1->u.atomic.u.s.pad) HGOTO_DONE (1); break; @@ -2134,7 +2973,152 @@ H5T_cmp (const H5T_t *dt1, const H5T_t *dt2) FUNC_LEAVE (ret_value); } - + + +/*------------------------------------------------------------------------- + * Function: H5T_find + * + * Purpose: Finds a conversion function for the specified path. + * + * Return: Success: A pointer to an appropriate conversion + * function. + * + * Failure: NULL + * + * Programmer: Robb Matzke + * Wednesday, January 14, 1998 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +H5T_conv_t +H5T_find (const H5T_t *src, const H5T_t *dst) +{ + H5T_path_t *path = NULL; + H5T_conv_t ret_value = NULL; + + FUNC_ENTER (H5T_find, NULL); + + /* Check args */ + assert (src); + assert (dst); + + /* No-op case */ + if (0==H5T_cmp (src, dst)) HRETURN (H5T_conv_noop); + + /* Find it */ + if (NULL==(path=H5T_path_find (src, dst, TRUE))) { + HRETURN_ERROR (H5E_DATATYPE, H5E_CANTINIT, NULL, + "unable to create conversion path"); + } + ret_value = path->hard; + if (!ret_value) ret_value = path->soft; + + if (!ret_value) { + HRETURN_ERROR (H5E_DATATYPE, H5E_NOTFOUND, NULL, + "no conversion function for that path"); + } + + FUNC_LEAVE (ret_value); +} + + +/*------------------------------------------------------------------------- + * Function: H5T_path_find + * + * Purpose: Finds the path which converts type SRC_ID to type DST_ID. If + * the path isn't found and CREATE is non-zero then a new path + * is created. + * + * Return: Success: Pointer to the path, valid until the path + * database is modified. + * + * Failure: NULL + * + * Programmer: Robb Matzke + * Tuesday, January 13, 1998 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +H5T_path_t * +H5T_path_find (const H5T_t *src, const H5T_t *dst, hbool_t create) +{ + intn lt = 0; /*left edge (inclusive) */ + intn rt = H5T_npath_g; /*right edge (exclusive) */ + intn md = 0; /*middle */ + intn cmp = -1; /*comparison result */ + H5T_path_t *path = NULL; /*path found */ + int i; + hid_t src_id, dst_id; + + FUNC_ENTER (H5T_path_find, NULL); + + /* Check args */ + assert (src); + assert (dst); + + /* Binary search */ + while (lt<rt) { + md = (lt+rt)/2; + + 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); + } + } + + /* Insert */ + if (create) { + 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)); + } + 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++; + + /* insert */ + path = H5T_path_g + md; + HDmemset (path, 0, sizeof(H5T_path_t)); + path->src = H5T_copy (src); + path->dst = H5T_copy (dst); + + /* Locate soft function */ + for (i=H5T_nsoft_g-1; i>=0 && !path->soft; --i) { + if (src->type!=H5T_soft_g[i].src || dst->type!=H5T_soft_g[i].dst) { + continue; + } + + if ((src_id=H5Aregister_atom (H5_DATATYPE, H5T_copy (path->src)))<0 || + (dst_id=H5Aregister_atom (H5_DATATYPE, H5T_copy (path->dst)))<0) { + HRETURN_ERROR (H5E_DATATYPE, H5E_CANTREGISTER, NULL, + "unable to register conv types for query"); + } + if ((H5T_soft_g[i].func)(src_id, dst_id, 0, NULL, NULL)>=0) { + path->soft = H5T_soft_g[i].func; + } + H5A_dec_ref (src_id); + H5A_dec_ref (dst_id); + H5ECLEAR; + } + } + + FUNC_LEAVE (path); +} + /*------------------------------------------------------------------------- * Function: H5T_debug diff --git a/src/H5Tpkg.h b/src/H5Tpkg.h index 1a75c59..4668db4 100644 --- a/src/H5Tpkg.h +++ b/src/H5Tpkg.h @@ -22,8 +22,8 @@ typedef struct H5T_atomic_t { H5T_order_t order; /*byte order */ size_t prec; /*precision in bits */ size_t offset; /*bit position of lsb of value */ - intn lo_pad; /*type of lsb padding */ - intn hi_pad; /*type of msb padding */ + intn lsb_pad;/*type of lsb padding */ + intn msb_pad;/*type of msb padding */ union { struct { H5T_sign_t sign; /*type of integer sign */ @@ -42,7 +42,7 @@ typedef struct H5T_atomic_t { struct { H5T_cset_t cset; /*character set */ - H5T_str_t spad; /*space or null padding of extra bytes */ + H5T_str_t pad; /*space or null padding of extra bytes */ } s; } u; } H5T_atomic_t; @@ -72,5 +72,27 @@ typedef struct H5T_member_t { struct H5T_t type; /*type of this member */ } H5T_member_t; +/* The data type conversion database */ +typedef struct H5T_path_t { + H5T_t *src; /*source data type ID */ + H5T_t *dst; /*destination data type ID */ + H5T_conv_t hard; /*hard conversion function or null */ + H5T_conv_t soft; /*soft conversion function or null */ +} H5T_path_t; + +/* The master list of soft conversion functions */ +typedef struct H5T_soft_t { + H5T_class_t src; /*source data type class */ + H5T_class_t dst; /*destination data type class */ + H5T_conv_t func; /*the conversion function */ +} H5T_soft_t; + +H5T_path_t *H5T_path_find (const H5T_t *src, const H5T_t *dst, hbool_t create); + +/* Conversion functions */ +herr_t H5T_conv_noop (hid_t src_id, hid_t dst_id, size_t nelmts, + void *buf, const void *background); +herr_t H5T_conv_order (hid_t src_id, hid_t dst_id, size_t nelmts, + void *_buf, const void *background); #endif diff --git a/src/H5Tprivate.h b/src/H5Tprivate.h index f92dba5..e857a91 100644 --- a/src/H5Tprivate.h +++ b/src/H5Tprivate.h @@ -45,6 +45,6 @@ herr_t H5T_insert (H5T_t *parent, const char *name, off_t offset, 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); - +H5T_conv_t H5T_find (const H5T_t *src, const H5T_t *dst); #endif diff --git a/src/H5Tpublic.h b/src/H5Tpublic.h index 907aff1..291282a 100644 --- a/src/H5Tpublic.h +++ b/src/H5Tpublic.h @@ -32,7 +32,9 @@ typedef enum H5T_class_t { H5T_STRING =3, /*character string types */ H5T_BITFIELD =4, /*bit field types */ H5T_OPAQUE =5, /*opaque types */ - H5T_COMPOUND =6 /*compound types */ + H5T_COMPOUND =6, /*compound types */ + + H5T_NCLASSES =7 /*This must be last */ } H5T_class_t; /* Byte orders */ @@ -51,7 +53,7 @@ typedef enum H5T_sign_t { H5T_SGN_NONE =0, /*this is an unsigned type */ H5T_SGN_2 =1, /*two's complement */ - H5T_SGN_N =2 /*this must be last */ + H5T_NSGN =2 /*this must be last! */ } H5T_sign_t; /* Floating-point normalization schemes */ @@ -66,14 +68,18 @@ typedef enum H5T_norm_t { /* Character set to use for text strings */ typedef enum H5T_cset_t { H5T_CSET_ERROR =-1, /*error */ - H5T_CSET_ASCII =0 /*US ASCII */ + H5T_CSET_ASCII =0, /*US ASCII */ + + H5T_NCSET =1 /*this must be last! */ } H5T_cset_t; /* Type of padding to use in character strings */ typedef enum H5T_str_t { H5T_STR_ERROR =-1, /*error */ H5T_STR_NULL =0, /*pad with null term like in C */ - H5T_STR_SPACE =1 /*pad with spaces like in Fortran */ + H5T_STR_SPACE =1, /*pad with spaces like in Fortran */ + + H5T_NSTR =2 /*this must be last! */ } H5T_str_t; /* Type of padding to use in other atomic types */ @@ -86,6 +92,9 @@ typedef enum H5T_pad_t { H5T_NPAD =3 /*THIS MUST BE LAST */ } H5T_pad_t; +/* All data type conversion functions are... */ +typedef herr_t (*H5T_conv_t)(hid_t, hid_t, size_t, void*, const void*); + #define HOFFSET(S,M) ((const char*)&S.M-(const char*)&S) #define HPOFFSET(P,M) ((const char*)&(P->M)-(const char*)P) @@ -98,8 +107,29 @@ typedef enum H5T_pad_t { #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_LLONG (H5init(), H5T_NATIVE_LLONG_g) +#define H5T_NATIVE_ULLONG (H5init(), H5T_NATIVE_ULLONG_g) +#define H5T_NATIVE_HYPER (H5init(), H5T_NATIVE_HYPER_g) +#define H5T_NATIVE_UHYPER (H5init(), H5T_NATIVE_UHYPER_g) +#define H5T_NATIVE_INT8 (H5init(), H5T_NATIVE_INT8_g) +#define H5T_NATIVE_UINT8 (H5init(), H5T_NATIVE_UINT8_g) +#define H5T_NATIVE_INT16 (H5init(), H5T_NATIVE_INT16_g) +#define H5T_NATIVE_UINT16 (H5init(), H5T_NATIVE_UINT16_g) +#define H5T_NATIVE_INT32 (H5init(), H5T_NATIVE_INT32_g) +#define H5T_NATIVE_UINT32 (H5init(), H5T_NATIVE_UINT32_g) +#define H5T_NATIVE_INT64 (H5init(), H5T_NATIVE_INT64_g) +#define H5T_NATIVE_UINT64 (H5init(), H5T_NATIVE_UINT64_g) #define H5T_NATIVE_FLOAT (H5init(), H5T_NATIVE_FLOAT_g) #define H5T_NATIVE_DOUBLE (H5init(), H5T_NATIVE_DOUBLE_g) +#define H5T_NATIVE_TIME (H5init(), H5T_NATIVE_TIME_g) +#define H5T_NATIVE_STRING (H5init(), H5T_NATIVE_STRING_g) +#define H5T_NATIVE_BITFIELD (H5init(), H5T_NATIVE_BITFIELD_g) +#define H5T_NATIVE_OPAQUE (H5init(), H5T_NATIVE_OPAQUE_g) + + +#ifdef __cplusplus +extern "C" { +#endif extern hid_t H5T_NATIVE_CHAR_g; extern hid_t H5T_NATIVE_UCHAR_g; @@ -108,19 +138,32 @@ 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_INT8_g; +extern hid_t H5T_NATIVE_UINT8_g; +extern hid_t H5T_NATIVE_INT16_g; +extern hid_t H5T_NATIVE_UINT16_g; +extern hid_t H5T_NATIVE_INT32_g; +extern hid_t H5T_NATIVE_UINT32_g; +extern hid_t H5T_NATIVE_INT64_g; +extern hid_t H5T_NATIVE_UINT64_g; extern hid_t H5T_NATIVE_ULONG_g; +extern hid_t H5T_NATIVE_LLONG_g; +extern hid_t H5T_NATIVE_ULLONG_g; +extern hid_t H5T_NATIVE_HYPER_g; +extern hid_t H5T_NATIVE_UHYPER_g; extern hid_t H5T_NATIVE_FLOAT_g; extern hid_t H5T_NATIVE_DOUBLE_g; - -#ifdef __cplusplus -extern "C" { -#endif +extern hid_t H5T_NATIVE_TIME_g; +extern hid_t H5T_NATIVE_STRING_g; +extern hid_t H5T_NATIVE_BITFIELD_g; +extern hid_t H5T_NATIVE_OPAQUE_g; /* 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); +herr_t H5Tlock (hid_t type_id); /* Operations defined on compound data types */ herr_t H5Tinsert (hid_t parent_id, const char *name, off_t offset, @@ -133,30 +176,44 @@ 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); +herr_t H5Tget_pad (hid_t type_id, H5T_pad_t *lsb/*out*/, + H5T_pad_t *msb/*out*/); 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); +H5T_pad_t H5Tget_inpad (hid_t type_id); +H5T_str_t H5Tget_strpad (hid_t type_id); intn H5Tget_nmembers (hid_t type_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); +H5T_cset_t H5Tget_cset (hid_t type_id); /* 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_pad (hid_t type_id, H5T_pad_t lsb, H5T_pad_t msb); 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); - +herr_t H5Tset_inpad (hid_t type_id, H5T_pad_t pad); +herr_t H5Tset_cset (hid_t type_id, H5T_cset_t cset); +herr_t H5Tset_strpad (hid_t type_id, H5T_str_t strpad); + +/* Type conversion database */ +herr_t H5Tregister_hard (hid_t src_id, hid_t dst_id, H5T_conv_t func); +herr_t H5Tregister_soft (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); #ifdef __cplusplus } diff --git a/src/H5detect.c b/src/H5detect.c index 82b662f..a5e3cef 100644 --- a/src/H5detect.c +++ b/src/H5detect.c @@ -282,11 +282,6 @@ static hbool_t interface_initialize_g = FALSE;\n\ \n"); - /* Global definitions for each type */ - for (i=0; i<nd; i++) { - printf ("hid_t H5T_NATIVE_%s_g = FAIL;\n", d[i].varname); - } - /* Function declaration */ printf ("\n\ herr_t\n\ @@ -316,8 +311,8 @@ H5T_init (void)\n\ dt->size = %d;\n\ dt->u.atomic.order = H5T_ORDER_%s;\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", + dt->u.atomic.lsb_pad = H5T_PAD_ZERO;\n\ + dt->u.atomic.lsb_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 */ @@ -922,16 +917,18 @@ main (int argc, char *argv[]) { print_header(); - DETECT_I (signed char, CHAR, d[nd]); nd++; - DETECT_I (unsigned char, UCHAR, d[nd]); nd++; - DETECT_I (short, SHORT, d[nd]); nd++; - DETECT_I (unsigned short, USHORT, d[nd]); nd++; - DETECT_I (int, INT, d[nd]); nd++; - DETECT_I (unsigned int, UINT, d[nd]); nd++; - DETECT_I (long, LONG, d[nd]); nd++; - DETECT_I (unsigned long, ULONG, d[nd]); nd++; - DETECT_F (float, FLOAT, d[nd]); nd++; - DETECT_F (double, DOUBLE, d[nd]); nd++; + DETECT_I (signed char, CHAR, d[nd]); nd++; + DETECT_I (unsigned char, UCHAR, d[nd]); nd++; + DETECT_I (short, SHORT, d[nd]); nd++; + DETECT_I (unsigned short, USHORT, d[nd]); nd++; + DETECT_I (int, INT, d[nd]); nd++; + DETECT_I (unsigned int, UINT, d[nd]); nd++; + DETECT_I (long, LONG, d[nd]); nd++; + DETECT_I (unsigned long, ULONG, d[nd]); nd++; + DETECT_I (long long, LLONG, d[nd]); nd++; + DETECT_I (unsigned long long, ULLONG, d[nd]); nd++; + DETECT_F (float, FLOAT, d[nd]); nd++; + DETECT_F (double, DOUBLE, d[nd]); nd++; print_results (nd, d); exit (0); diff --git a/src/Makefile.in b/src/Makefile.in index 0304868..b0dc57f 100644 --- a/src/Makefile.in +++ b/src/Makefile.in @@ -14,11 +14,11 @@ LIB=libhdf5.a PROGS=debug # Source and object files for the library (lexicographically)... -LIB_SRC=H5.c H5A.c H5AC.c H5B.c H5C.c H5D.c H5Dconv.c H5E.c H5F.c H5Fcore.c \ - H5Ffamily.c H5Fistore.c H5Flow.c H5Fsec2.c H5Fsplit.c H5Fstdio.c \ - H5G.c H5Gent.c H5Gnode.c H5Gstab.c H5H.c H5M.c H5MF.c H5MM.c H5O.c \ - H5Ocont.c H5Ocstore.c H5Odtype.c H5Oefl.c H5Oistore.c H5Oname.c \ - H5Onull.c H5Osdspace.c H5Ostab.c H5P.c H5T.c H5Tinit.c H5V.c +LIB_SRC=H5.c H5A.c H5AC.c H5B.c H5C.c H5D.c H5E.c H5F.c H5Fcore.c H5Ffamily.c \ + H5Fistore.c H5Flow.c H5Fsec2.c H5Fsplit.c H5Fstdio.c H5G.c H5Gent.c \ + H5Gnode.c H5Gstab.c H5H.c H5M.c H5MF.c H5MM.c H5O.c H5Ocont.c \ + H5Ocstore.c H5Odtype.c H5Oefl.c H5Oistore.c H5Oname.c H5Onull.c \ + H5Osdspace.c H5Ostab.c H5P.c H5T.c H5Tconv.c H5Tinit.c H5V.c LIB_OBJ=$(LIB_SRC:.c=.o) diff --git a/test/dsets.c b/test/dsets.c index c5ad49c..45aff80 100644 --- a/test/dsets.c +++ b/test/dsets.c @@ -22,6 +22,7 @@ #define DSET_DEFAULT_NAME "default" #define DSET_CHUNKED_NAME "chunked" #define DSET_SIMPLE_IO_NAME "simple_io" +#define DSET_TCONV_NAME "tconv" /*------------------------------------------------------------------------- @@ -277,6 +278,89 @@ test_simple_io (hid_t file) /*------------------------------------------------------------------------- + * Function: test_tconv + * + * Purpose: Test some simple data type conversion stuff. + * + * Return: Success: SUCCEED + * + * Failure: FAIL + * + * Programmer: Robb Matzke + * Wednesday, January 14, 1998 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +static herr_t +test_tconv (hid_t file) +{ + uint8 out[4*1000000]; + uint8 in[4*1000000]; + intn i; + size_t dims[1]; + hid_t space, dataset, type; + herr_t status; + + printf ("%-70s", "Testing data type conversion"); + + /* Initialize the dataset */ + for (i=0; i<1000000; i++) ((int32*)out)[i] = 0x11223344; + + /* Create the data space */ + space = H5Pcreate (H5P_SIMPLE); + assert (space>=0); + dims[0] = 1000000; + status = H5Pset_space (space, 1, dims); + assert (status>=0); + + /* Create the data set */ + dataset = H5Dcreate (file, DSET_TCONV_NAME, H5T_NATIVE_INT32, space, + H5C_DEFAULT); + assert (dataset>=0); + + /* Write the data to the dataset */ + status = H5Dwrite (dataset, H5T_NATIVE_INT32, H5P_ALL, H5C_DEFAULT, out); + assert (status>=0); + + /* Create a new type with the opposite byte order */ + type = H5Tcopy (H5T_NATIVE_INT32); + switch (H5Tget_order (type)) { + case H5T_ORDER_BE: + H5Tset_order (type, H5T_ORDER_LE); + break; + case H5T_ORDER_LE: + H5Tset_order (type, H5T_ORDER_BE); + break; + default: + assert ("funny byte order" && 0); + break; + } + + /* Read data with byte order conversion */ + status = H5Dread (dataset, type, H5P_ALL, H5C_DEFAULT, in); + assert (status>=0); + + /* Check */ + for (i=0; i<1000000; i++) { + assert (in[4*i+0] == out[4*i+3]); + assert (in[4*i+1] == out[4*i+2]); + assert (in[4*i+2] == out[4*i+1]); + assert (in[4*i+3] == out[4*i+0]); + } + + H5Dclose (dataset); + H5Tclose (type); + + puts (" PASSED"); + return SUCCEED; +} + + + + +/*------------------------------------------------------------------------- * Function: main * * Purpose: Tests the dataset interface (H5D) @@ -310,6 +394,9 @@ main (void) status = test_simple_io (file); nerrors += status<0 ? 1 : 0; + status = test_tconv (file); + nerrors += status<0 ? 1 : 0; + status = H5Fclose (file); if (nerrors) { |