diff options
author | Robb Matzke <matzke@llnl.gov> | 1998-06-30 21:30:28 (GMT) |
---|---|---|
committer | Robb Matzke <matzke@llnl.gov> | 1998-06-30 21:30:28 (GMT) |
commit | 1b3a1f8014b630208013c7a18cfe8e7c0539e161 (patch) | |
tree | 442600fb6f75f8dbde490f48d2a8ccba7c823164 /src | |
parent | 030d46c078b7ef61468703dabb4861212ecb13ca (diff) | |
download | hdf5-1b3a1f8014b630208013c7a18cfe8e7c0539e161.zip hdf5-1b3a1f8014b630208013c7a18cfe8e7c0539e161.tar.gz hdf5-1b3a1f8014b630208013c7a18cfe8e7c0539e161.tar.bz2 |
[svn-r437] Changes since 19980612
----------------------
./src/H5Tbit.c
./src/H5Tpkg.h
Fixed a bug in H5T_bit_copy(). Added H5T_bit_get_d() and
H5T_bit_set_d() which treat portions of a bit vector as an
unsigned integer. Added H5T_bit_inc() that increments part of
a bit vector and returns an indication of overflow.
./src/H5Tconv.c
./src/H5Tpkg.h
./test/dtypes.c
Added a slow general floating point conversion which works so
far on Intel, MIPS, and DEC but the test is turned off because
a cast from double to float will cause a SIGFPE on some
systems if an overflow occurs.
Added fast hardware conversions between native floating point
types. This function is also subject to the SIGFPE problem.
./src/H5detect.c
Removed the exponent bias adjustment when the significand
isn't normalized. This is now handled in the conversion
functions instead.
./src/H5T.c
Register new conversion functions.
Plugged a memory leak in the library termination code.
./RELEASE
Added a list of major changes since the first alpha.
./src/H5.c
./src/H5private.h
./src/H5A.c
./src/H5AC.c
./src/H5D.c
./src/H5Ffamily.c
./src/H5Fistore.c
./src/H5G.c
./src/H5Gprivate.h
./src/H5HG.c
./src/H5O.c
./src/H5T.c
./src/H5Tbit.c
./src/H5Tconv.c
Fixed various compiler warnings on Irix64.
./src/H5MM.c
Added PABLO_MASK to this file.
./test/chunk.c
Removed a warning about memcpy().
Diffstat (limited to 'src')
-rw-r--r-- | src/H5.c | 8 | ||||
-rw-r--r-- | src/H5A.c | 14 | ||||
-rw-r--r-- | src/H5AC.c | 2 | ||||
-rw-r--r-- | src/H5D.c | 2 | ||||
-rw-r--r-- | src/H5Distore.c | 2 | ||||
-rw-r--r-- | src/H5Ffamily.c | 4 | ||||
-rw-r--r-- | src/H5Fistore.c | 2 | ||||
-rw-r--r-- | src/H5G.c | 4 | ||||
-rw-r--r-- | src/H5Gprivate.h | 2 | ||||
-rw-r--r-- | src/H5HG.c | 2 | ||||
-rw-r--r-- | src/H5MM.c | 1 | ||||
-rw-r--r-- | src/H5O.c | 10 | ||||
-rw-r--r-- | src/H5T.c | 23 | ||||
-rw-r--r-- | src/H5Tbit.c | 176 | ||||
-rw-r--r-- | src/H5Tconv.c | 500 | ||||
-rw-r--r-- | src/H5Tpkg.h | 9 | ||||
-rw-r--r-- | src/H5detect.c | 9 | ||||
-rw-r--r-- | src/H5private.h | 1 |
18 files changed, 721 insertions, 50 deletions
@@ -591,7 +591,7 @@ HDfprintf (FILE *stream, const char *fmt, ...) if (prec>0) { sprintf (template+strlen (template), ".%d", prec); } - if (modifier) { + if (*modifier) { sprintf (template+strlen (template), "%s", modifier); } sprintf (template+strlen (template), "%c", conv); @@ -1281,24 +1281,26 @@ H5_trace (hbool_t returning, const char *func, const char *type, ...) case 'M': switch (type[1]) { -#ifdef HAVE_PARALLEL case 'c': if (ptr) { fprintf (out, "0x%lx", (unsigned long)vp); } else { +#ifdef HAVE_PARALLEL MPI_Comm comm = va_arg (ap, MPI_Comm); fprintf (out, "%ld", (long)comm); +#endif } break; case 'i': if (ptr) { fprintf (out, "0x%lx", (unsigned long)vp); } else { +#ifdef HAVE_PARALLEL MPI_Info info = va_arg (ap, MPI_Info); fprintf (out, "%ld", (long)info); +#endif } break; -#endif default: goto error; } @@ -157,7 +157,6 @@ H5Acreate (hid_t loc_id, const char *name, hid_t datatype, hid_t dataspace, H5G_entry_t *ent = NULL; H5T_t *type = NULL; H5S_t *space = NULL; - const H5D_create_t *create_parms = NULL; hid_t ret_value = FAIL; FUNC_ENTER(H5Acreate, FAIL); @@ -195,14 +194,11 @@ H5Acreate (hid_t loc_id, const char *name, hid_t datatype, hid_t dataspace, NULL == (space = H5I_object(dataspace))) { HRETURN_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data space"); } - if (H5P_DEFAULT!=create_plist) { - if (H5P_DATASET_CREATE != H5Pget_class(create_plist) || - NULL == (create_parms = H5I_object(create_plist))) { - HRETURN_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, - "not a dataset creation property list"); - } - } else { - create_parms = &H5D_create_dflt; + if (H5P_DEFAULT!=create_plist && + (H5P_DATASET_CREATE != H5Pget_class(create_plist) || + NULL == H5I_object(create_plist))) { + HRETURN_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, + "not a dataset creation property list"); } /* Go do the real work for attaching the attribute to the dataset */ @@ -722,7 +722,7 @@ H5AC_protect(H5F_t *f, const H5AC_class_t *type, const haddr_t *addr, HRETURN_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed"); } - slot->aprots = na; + slot->aprots = (intn)na; slot->prot = x; } slot->prot[slot->nprots].type = type; @@ -972,7 +972,6 @@ H5D_open(H5G_t *loc, const char *name) H5D_t *dataset = NULL; /*the dataset which was found */ H5D_t *ret_value = NULL; /*return value */ intn i; - H5F_t *f = NULL; FUNC_ENTER(H5D_open, NULL); @@ -980,7 +979,6 @@ H5D_open(H5G_t *loc, const char *name) assert (loc); assert (name && *name); - f = H5G_fileof (loc); if (NULL==(dataset = H5MM_calloc(sizeof(H5D_t)))) { HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed"); diff --git a/src/H5Distore.c b/src/H5Distore.c index 2f23715..4cb808b 100644 --- a/src/H5Distore.c +++ b/src/H5Distore.c @@ -1086,7 +1086,7 @@ H5F_istore_lock (H5F_t *f, const H5O_layout_t *layout, HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed"); } - rdcc->nslots = na; + rdcc->nslots = (intn)na; rdcc->slot = x; } HDmemmove (rdcc->slot+1, rdcc->slot, diff --git a/src/H5Ffamily.c b/src/H5Ffamily.c index bed381f..fd876c0 100644 --- a/src/H5Ffamily.c +++ b/src/H5Ffamily.c @@ -161,7 +161,7 @@ H5F_fam_open(const char *name, const H5F_access_t *access_parms, HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed"); } - lf->u.fam.nalloc = na; + lf->u.fam.nalloc = (intn)na; lf->u.fam.memb = x; } lf->u.fam.memb[lf->u.fam.nmemb++] = member; @@ -425,7 +425,7 @@ H5F_fam_write(H5F_low_t *lf, const H5F_access_t *access_parms, HRETURN_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed"); } - lf->u.fam.nalloc = na; + lf->u.fam.nalloc = (intn)na; lf->u.fam.memb = x; } for (i = lf->u.fam.nmemb; i <= membno; i++) { diff --git a/src/H5Fistore.c b/src/H5Fistore.c index 2f23715..4cb808b 100644 --- a/src/H5Fistore.c +++ b/src/H5Fistore.c @@ -1086,7 +1086,7 @@ H5F_istore_lock (H5F_t *f, const H5O_layout_t *layout, HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed"); } - rdcc->nslots = na; + rdcc->nslots = (intn)na; rdcc->slot = x; } HDmemmove (rdcc->slot+1, rdcc->slot, @@ -1732,7 +1732,7 @@ H5G_loc (hid_t loc_id) *------------------------------------------------------------------------- */ herr_t -H5G_link (H5G_t *loc, H5G_type_t type, const char *cur_name, +H5G_link (H5G_t *loc, H5G_link_t type, const char *cur_name, const char *new_name) { H5G_entry_t cur_obj; /*entry for the link tail */ @@ -1882,7 +1882,7 @@ H5G_stat (H5G_t *loc, const char *name, hbool_t follow_link, /* * Initialize the stat buf. Symbolic links aren't normal objects and - * therefor don't have much of the normal info. However, the link value + * therefore don't have much of the normal info. However, the link value * length is specific to symbolic links. */ if (statbuf) { diff --git a/src/H5Gprivate.h b/src/H5Gprivate.h index 7c76f2d..ae3064a 100644 --- a/src/H5Gprivate.h +++ b/src/H5Gprivate.h @@ -110,7 +110,7 @@ herr_t H5G_set (H5G_t *grp); herr_t H5G_push (H5G_t *grp); herr_t H5G_pop (H5F_t *f); H5G_t *H5G_getcwg(H5F_t *f); -herr_t H5G_link (H5G_t *loc, H5G_type_t type, const char *cur_name, +herr_t H5G_link (H5G_t *loc, H5G_link_t type, const char *cur_name, const char *new_name); herr_t H5G_stat (H5G_t *loc, const char *name, hbool_t follow_link, H5G_stat_t *statbuf/*out*/); @@ -271,7 +271,7 @@ H5HG_load (H5F_t *f, const haddr_t *addr, const void __unused__ *udata1, HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed"); } - heap->nalloc = nalloc; + heap->nalloc = (intn)nalloc; while (p<heap->chunk+heap->size) { if (p+H5HG_SIZEOF_OBJHDR(f)>heap->chunk+heap->size) { /* @@ -19,6 +19,7 @@ #include <H5MMprivate.h> /* Interface initialization? */ +#define PABLO_MASK H5MM_mask static hbool_t interface_initialize_g = FALSE; #define INTERFACE_INIT NULL @@ -393,7 +393,7 @@ H5O_load(H5F_t *f, const haddr_t *addr, const void __unused__ *_udata1, HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed"); } - oh->alloc_nchunks = na; + oh->alloc_nchunks = (intn)na; oh->chunk = x; } @@ -1455,7 +1455,7 @@ H5O_alloc_extend_chunk(H5O_t *oh, intn chunkno, size_t size) HRETURN_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed"); } - oh->alloc_nmesgs = na; + oh->alloc_nmesgs = (intn)na; oh->mesg = x; } delta = MAX(H5O_MIN_SIZE, size+H5O_SIZEOF_MSGHDR(f)); @@ -1589,7 +1589,7 @@ H5O_alloc_new_chunk(H5F_t *f, H5O_t *oh, size_t size) HRETURN_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed"); } - oh->alloc_nchunks = na; + oh->alloc_nchunks = (intn)na; oh->chunk = x; } chunkno = oh->nchunks++; @@ -1613,7 +1613,7 @@ H5O_alloc_new_chunk(H5F_t *f, H5O_t *oh, size_t size) HRETURN_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed"); } - oh->alloc_nmesgs = na; + oh->alloc_nmesgs = (intn)na; oh->mesg = x; /* Set new object header info to zeros */ @@ -1770,7 +1770,7 @@ H5O_alloc(H5F_t *f, H5O_t *oh, const H5O_class_t *type, size_t size) HRETURN_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed"); } - oh->alloc_nmesgs = na; + oh->alloc_nmesgs = (intn)na; oh->mesg = x; /* Set new object header info to zeros */ @@ -572,6 +572,11 @@ H5T_init_interface(void) HRETURN_ERROR (H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to register conversion function"); } + if (H5Tregister_soft ("f_f", H5T_FLOAT, H5T_FLOAT, + H5T_conv_f_f) < 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, @@ -597,7 +602,16 @@ H5T_init_interface(void) HRETURN_ERROR (H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to register conversion function"); } - + if (H5Tregister_hard("flt_dbl", H5T_NATIVE_FLOAT, H5T_NATIVE_DOUBLE, + H5T_conv_float_double)<0) { + HRETURN_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, + "unable to register conversion function"); + } + if (H5Tregister_hard("dbl_flt", H5T_NATIVE_DOUBLE, H5T_NATIVE_FLOAT, + H5T_conv_double_float)<0) { + HRETURN_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, + "unable to register conversion function"); + } FUNC_LEAVE(ret_value); } @@ -2879,7 +2893,7 @@ H5Tregister_soft (const char *name, H5T_class_t src_cls, H5T_class_t dst_cls, HRETURN_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed"); } - H5T_asoft_g = na; + H5T_asoft_g = (intn)na; H5T_soft_g = x; } HDstrncpy (H5T_soft_g[H5T_nsoft_g].name, name, H5T_NAMELEN); @@ -3697,7 +3711,7 @@ H5T_insert(H5T_t *parent, const char *name, size_t offset, const H5T_t *member) HRETURN_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed"); } - parent->u.compnd.nalloc = na; + parent->u.compnd.nalloc = (intn)na; parent->u.compnd.memb = x; } @@ -4197,7 +4211,7 @@ H5T_path_find(const char *name, const H5T_t *src, const H5T_t *dst, HRETURN_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed"); } - H5T_apath_g = na; + H5T_apath_g = (intn)na; H5T_path_g = x; } if (cmp > 0) md++; @@ -4266,6 +4280,7 @@ H5T_path_find(const char *name, const H5T_t *src, const H5T_t *dst, } if ((H5T_soft_g[i].func) (src_id, dst_id, &(path->cdata), H5T_CONV_INIT, NULL, NULL) < 0) { + H5MM_xfree(path->cdata.stats); HDmemset (&(path->cdata), 0, sizeof(H5T_cdata_t)); H5E_clear(); /*ignore the error*/ } else { diff --git a/src/H5Tbit.c b/src/H5Tbit.c index b9a830d..d80c8b3 100644 --- a/src/H5Tbit.c +++ b/src/H5Tbit.c @@ -11,8 +11,15 @@ */ #define H5T_PACKAGE #include <H5private.h> +#include <H5Eprivate.h> +#include <H5Iprivate.h> #include <H5Tpkg.h> +/* Interface initialization */ +#define PABLO_MASK H5Tbit_mask +static intn interface_initialize_g = FALSE; +#define INTERFACE_INIT NULL + /*------------------------------------------------------------------------- * Function: H5T_bit_copy @@ -40,8 +47,8 @@ H5T_bit_copy (uint8 *dst, size_t dst_offset, const uint8 *src, * Normalize the offset to be a byte number and a bit offset within that * byte. */ - s_idx = src_offset / 8; - d_idx = dst_offset / 8; + s_idx = (intn)src_offset / 8; + d_idx = (intn)dst_offset / 8; src_offset %= 8; dst_offset %= 8; @@ -62,7 +69,7 @@ H5T_bit_copy (uint8 *dst, size_t dst_offset, const uint8 *src, * dst[d_idx+1] dst[d_idx] */ while (src_offset && size>0) { - unsigned nbits = MIN3 (size, 8-dst_offset, 8-src_offset); + unsigned nbits = (unsigned)MIN3 (size, 8-dst_offset, 8-src_offset); unsigned mask = (1<<nbits) - 1; dst[d_idx] &= ~(mask<<dst_offset); @@ -102,9 +109,9 @@ H5T_bit_copy (uint8 *dst, size_t dst_offset, const uint8 *src, * bits). SHIFT is three since the source must be shifted right three bits * to line up with the destination. */ - shift = dst_offset; + shift = (intn)dst_offset; mask_lo = (1<<(8-shift))-1; - mask_hi = ~mask_lo; + mask_hi = (~mask_lo) & 0xff; for (/*void*/; size>8; size-=8, d_idx++, s_idx++) { if (shift) { @@ -119,7 +126,7 @@ H5T_bit_copy (uint8 *dst, size_t dst_offset, const uint8 *src, /* Finish up */ while (size>0) { - unsigned nbits = MIN3 (size, 8-dst_offset, 8-src_offset); + unsigned nbits = (unsigned)MIN3 (size, 8-dst_offset, 8-src_offset); unsigned mask = (1<<nbits) - 1; dst[d_idx] &= ~(mask<<dst_offset); @@ -141,6 +148,94 @@ H5T_bit_copy (uint8 *dst, size_t dst_offset, const uint8 *src, /*------------------------------------------------------------------------- + * Function: H5T_bit_get_d + * + * Purpose: Return a small bit sequence as a number. + * + * Return: Success: The bit sequence interpretted as an unsigned + * integer. + * + * Failure: 0 + * + * Programmer: Robb Matzke + * Tuesday, June 23, 1998 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +hsize_t +H5T_bit_get_d (uint8 *buf, size_t offset, size_t size) +{ + hsize_t val=0; + size_t i, hs; + + FUNC_ENTER (H5T_bit_get_d, 0); + assert (8*sizeof(val)>=size); + + H5T_bit_copy ((uint8*)&val, 0, buf, offset, size); + switch (((H5T_t*)(H5I_object(H5T_NATIVE_INT_g)))->u.atomic.order) { + case H5T_ORDER_LE: + break; + + case H5T_ORDER_BE: + for (i=0, hs=sizeof(val)/2; i<hs; i++) { + uint8 tmp = ((uint8*)&val)[i]; + ((uint8*)&val)[i] = ((uint8*)&val)[sizeof(val)-(i+1)]; + ((uint8*)&val)[sizeof(val)-(i+1)] = tmp; + } + break; + + default: + abort (); + } + + FUNC_LEAVE (val); +} + + +/*------------------------------------------------------------------------- + * Function: H5T_bit_set_d + * + * Purpose: Sets part of a bit vector to the specified unsigned value. + * + * Return: void + * + * Programmer: Robb Matzke + * Wednesday, June 24, 1998 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +void +H5T_bit_set_d (uint8 *buf, size_t offset, size_t size, hsize_t val) +{ + size_t i, hs; + + assert (8*sizeof(val)>=size); + + switch (((H5T_t*)(H5I_object(H5T_NATIVE_INT_g)))->u.atomic.order) { + case H5T_ORDER_LE: + break; + + case H5T_ORDER_BE: + for (i=0, hs=sizeof(val)/2; i<hs; i++) { + uint8 tmp = ((uint8*)&val)[i]; + ((uint8*)&val)[i] = ((uint8*)&val)[sizeof(val)-(i+1)]; + ((uint8*)&val)[sizeof(val)-(i+1)] = tmp; + } + break; + + default: + abort (); + } + + H5T_bit_copy (buf, offset, (uint8*)&val, 0, size); +} + + +/*------------------------------------------------------------------------- * Function: H5T_bit_set * * Purpose: Sets or clears bits in a contiguous region of a vector @@ -161,7 +256,7 @@ H5T_bit_set (uint8 *buf, size_t offset, size_t size, hbool_t value) intn idx; /* Normalize */ - idx = offset / 8; + idx = (intn)offset / 8; offset %= 8; /* The first partial byte */ @@ -217,7 +312,7 @@ ssize_t H5T_bit_find (uint8 *buf, size_t offset, size_t size, H5T_sdir_t direction, hbool_t value) { - size_t base=offset; + ssize_t base=(ssize_t)offset; ssize_t idx, i; /* Some functions call this with value=TRUE */ @@ -300,3 +395,68 @@ H5T_bit_find (uint8 *buf, size_t offset, size_t size, H5T_sdir_t direction, return -1; } + + +/*------------------------------------------------------------------------- + * Function: H5T_bit_inc + * + * Purpose: Increment part of a bit field by adding 1. + * + * Return: Success: The carry-out value, one if overflow zero + * otherwise. + * + * Failure: FAIL + * + * Programmer: Robb Matzke + * Friday, June 26, 1998 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +hbool_t +H5T_bit_inc(uint8 *buf, size_t start, size_t size) +{ + size_t idx = start / 8; + unsigned carry = 1; + unsigned acc, mask; + + assert(buf); + start %= 8; + + /* The first partial byte */ + if (start) { + if (size+start<8) mask = (1<<size)-1; + else mask = (1<<(8-start))-1; + acc = (buf[idx]>>start) & mask; + acc += 1; + carry = acc & (1<<MIN(size, 8-start)); + buf[idx] &= ~(mask<<start); + buf[idx] |= (acc & mask) << start; + size -= MIN(size, 8-start); + start=0; + idx++; + } + + /* The middle */ + while (carry && size>=8) { + acc = buf[idx]; + acc += 1; + carry = acc & 0x100; + buf[idx] = acc & 0xff; + idx++; + size -= 8; + } + + /* The last bits */ + if (carry && size>0) { + mask = (1<<size)-1; + acc = buf[idx] & mask; + acc += 1; + carry = acc & (1<<size); + buf[idx] &= ~mask; + buf[idx] |= acc & mask; + } + + return carry ? TRUE : FALSE; +} diff --git a/src/H5Tconv.c b/src/H5Tconv.c index f994345..930b330 100644 --- a/src/H5Tconv.c +++ b/src/H5Tconv.c @@ -620,12 +620,14 @@ H5T_conv_i_i (hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, } else if (src->size>=dst->size) { sp = dp = (uint8*)buf; direction = 1; - olap = ceil((double)(src->size)/(src->size-dst->size))-1; + olap = (size_t)(ceil((double)(src->size)/ + (double)(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; + olap = (size_t)(ceil((double)(dst->size)/ + (double)(dst->size-src->size))-1); } /* The conversion loop */ @@ -871,6 +873,497 @@ H5T_conv_i_i (hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, /*------------------------------------------------------------------------- + * Function: H5T_conv_f_f + * + * Purpose: Convert one floating point type to another. This is a catch + * all for floating point conversions and is probably not + * particularly fast! + * + * Return: Success: SUCCEED + * + * Failure: FAIL + * + * Programmer: Robb Matzke + * Tuesday, June 23, 1998 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +herr_t +H5T_conv_f_f (hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, + size_t nelmts, void *buf, void __unused__ *bkg) +{ + /* Traversal-related variables */ + H5T_t *src_p; /*source data type */ + H5T_t *dst_p; /*destination data type */ + H5T_atomic_t src; /*atomic source info */ + H5T_atomic_t dst; /*atomic destination info */ + intn direction; /*forward or backward traversal */ + size_t elmtno; /*element number */ + size_t half_size; /*half the type size */ + size_t olap; /*num overlapping elements */ + ssize_t bitno; /*bit number */ + uint8 *s, *sp, *d, *dp; /*source and dest traversal ptrs*/ + uint8 dbuf[64]; /*temp destination buffer */ + + /* Conversion-related variables */ + hssize_t expo; /*exponent */ + hssize_t expo_max; /*maximum possible dst exponent */ + size_t msize; /*useful size of mantissa in src*/ + size_t mpos; /*offset to useful mant is src */ + size_t mrsh; /*amount to right shift mantissa*/ + hbool_t carry; /*carry after rounding mantissa */ + size_t i; /*miscellaneous counters */ + size_t implied; /*destination implied bits */ + + FUNC_ENTER (H5T_conv_f_f, FAIL); + + switch (cdata->command) { + case H5T_CONV_INIT: + if (H5_DATATYPE!=H5I_group (src_id) || + NULL==(src_p=H5I_object (src_id)) || + H5_DATATYPE!=H5I_group (dst_id) || + NULL==(dst_p=H5I_object (dst_id))) { + HRETURN_ERROR (H5E_ARGS, H5E_BADTYPE, FAIL, "not a data type"); + } + src = src_p->u.atomic; + dst = dst_p->u.atomic; + if (H5T_ORDER_LE!=src.order && + H5T_ORDER_BE!=src.order) { + HRETURN_ERROR (H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, + "unsupported byte order"); + } + if (H5T_ORDER_LE!=dst.order && + H5T_ORDER_BE!=dst.order) { + HRETURN_ERROR (H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, + "unsupported byte order"); + } + if (dst_p->size>sizeof(dbuf)) { + HRETURN_ERROR (H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, + "destination size is too large"); + } + if (8*sizeof(expo)-1<src.u.f.esize || + 8*sizeof(expo)-1<dst.u.f.esize) { + HRETURN_ERROR (H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, + "exponent field is too large"); + } + cdata->need_bkg = H5T_BKG_NO; + break; + + case H5T_CONV_FREE: + break; + + case H5T_CONV_CONV: + /* Get the data types */ + if (H5_DATATYPE!=H5I_group (src_id) || + NULL==(src_p=H5I_object (src_id)) || + H5_DATATYPE!=H5I_group (dst_id) || + NULL==(dst_p=H5I_object (dst_id))) { + HRETURN_ERROR (H5E_ARGS, H5E_BADTYPE, FAIL, "not a data type"); + } + src = src_p->u.atomic; + dst = dst_p->u.atomic; + expo_max = ((hssize_t)1 << dst.u.f.esize) - 1; + + /* + * 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_p->size==dst_p->size) { + sp = dp = (uint8*)buf; + direction = 1; + olap = nelmts; + } else if (src_p->size>=dst_p->size) { + sp = dp = (uint8*)buf; + direction = 1; + olap = (size_t)(ceil((double)(src_p->size)/ + (double)(src_p->size-dst_p->size))-1); + } else { + sp = (uint8*)buf + (nelmts-1) * src_p->size; + dp = (uint8*)buf + (nelmts-1) * dst_p->size; + direction = -1; + olap = (size_t)(ceil((double)(dst_p->size)/ + (double)(dst_p->size-src_p->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_p->size) || + (sp>=dp && sp<dp+dst_p->size)); + } else { + assert ((dp<sp && dp+dst_p->size<=sp) || + (sp<dp && sp+src_p->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.order) { + half_size = src_p->size/2; + for (i=0; i<half_size; i++) { + uint8 tmp = s[src_p->size-(i+1)]; + s[src_p->size-(i+1)] = s[i]; + s[i] = tmp; + } + } + + /* + * Check for special cases: +0, -0, +Inf, -Inf, NaN + */ + if (H5T_bit_find (s, src.u.f.mpos, src.u.f.msize, + H5T_BIT_LSB, TRUE)<0) { + if (H5T_bit_find (s, src.u.f.epos, src.u.f.esize, + H5T_BIT_LSB, TRUE)<0) { + /* +0 or -0 */ + H5T_bit_copy (d, dst.u.f.sign, s, src.u.f.sign, 1); + H5T_bit_set (d, dst.u.f.epos, dst.u.f.esize, FALSE); + H5T_bit_set (d, dst.u.f.mpos, dst.u.f.esize, FALSE); + goto padding; + } else if (H5T_bit_find (s, src.u.f.epos, src.u.f.esize, + H5T_BIT_LSB, FALSE)<0) { + /* +Inf or -Inf */ + H5T_bit_copy (d, dst.u.f.sign, s, src.u.f.sign, 1); + H5T_bit_set (d, dst.u.f.epos, dst.u.f.esize, TRUE); + H5T_bit_set (d, dst.u.f.mpos, dst.u.f.msize, FALSE); + goto padding; + } + } else if (H5T_bit_find (s, src.u.f.epos, src.u.f.esize, + H5T_BIT_LSB, FALSE)<0) { + /* + * NaN. There are many NaN values, so we just set all bits of + * the significand. + */ + H5T_bit_copy (d, dst.u.f.sign, s, src.u.f.sign, 1); + H5T_bit_set (d, dst.u.f.epos, dst.u.f.esize, TRUE); + H5T_bit_set(d, dst.u.f.mpos, dst.u.f.msize, TRUE); + goto padding; + } + + /* + * Get the exponent as an unsigned quantity from the section of + * the source bit field where it's located. Don't worry about + * the exponent bias yet. + */ + expo = H5T_bit_get_d(s, src.u.f.epos, src.u.f.esize); + + /* + * Set markers for the source mantissa, excluding the leading `1' + * (might be implied). + */ + implied = 1; + mpos = src.u.f.mpos; + mrsh = 0; + if (0==expo || H5T_NORM_NONE==src.u.f.norm) { + if ((bitno=H5T_bit_find(s, src.u.f.mpos, src.u.f.msize, + H5T_BIT_MSB, TRUE))>0) { + msize = bitno; + } else if (0==bitno) { + msize = 1; + H5T_bit_set(s, src.u.f.mpos, 1, FALSE); + } + } else if (H5T_NORM_IMPLIED==src.u.f.norm) { + msize = src.u.f.msize; + } else { + assert("normalization method not implemented yet" && 0); + abort(); + } + + /* + * The sign for the destination is the same as the sign for the + * source in all cases. + */ + H5T_bit_copy (d, dst.u.f.sign, s, src.u.f.sign, 1); + + /* + * Calculate the true source exponent by adjusting according to + * the source exponent bias. + */ + if (0==expo || H5T_NORM_NONE==src.u.f.norm) { + bitno = H5T_bit_find(s, src.u.f.mpos, src.u.f.msize, + H5T_BIT_MSB, TRUE); + assert(bitno>=0); + expo -= (src.u.f.ebias-1) + (src.u.f.msize-bitno); + } else if (H5T_NORM_IMPLIED==src.u.f.norm) { + expo -= src.u.f.ebias; + } else { + assert("normalization method not implemented yet" && 0); + abort(); + } + + /* + * If the destination is not normalized then right shift the + * mantissa by one. + */ + if (H5T_NORM_NONE==dst.u.f.norm) { + mrsh++; + } + + /* + * Calculate the destination exponent by adding the destination + * bias and clipping by the minimum and maximum possible + * destination exponent values. + */ + expo += dst.u.f.ebias; + if (expo < -(hssize_t)(dst.u.f.msize)) { + /* The exponent is way too small. Result is zero. */ + expo = 0; + H5T_bit_set(d, dst.u.f.mpos, dst.u.f.msize, FALSE); + msize = 0; + + } else if (expo<=0) { + /* + * The exponent is too small to fit in the exponent field, + * but by shifting the mantissa to the right we can + * accomodate that value. The mantissa of course is no + * longer normalized. + */ + mrsh += 1-expo; + expo = 0; + + } else if (expo>=expo_max) { + /* + * The exponent is too large to fit in the available region + * or it results in the maximum possible value. Use positive + * or negative infinity instead. + */ + expo = expo_max; + H5T_bit_set(d, dst.u.f.mpos, dst.u.f.msize, FALSE); + msize = 0; + + } + + /* + * If the destination mantissa is smaller than the source + * mantissa then round the source mantissa. Rounding may cause a + * carry in which case the exponent has to be re-evaluated for + * overflow. That is, if `carry' is clear then the implied + * mantissa bit is `1', else it is `10' binary. + */ + if (msize>0 && mrsh<=dst.u.f.msize && mrsh+msize>dst.u.f.msize) { + bitno = (ssize_t)(mrsh+msize - dst.u.f.msize); + assert(bitno>=0 && (size_t)bitno<=msize); + carry = H5T_bit_inc(s, mpos+bitno-1, 1+msize-bitno); + if (carry) implied = 2; + } + + /* + * Write the mantissa to the destination + */ + if (mrsh>dst.u.f.msize+1) { + H5T_bit_set(d, dst.u.f.mpos, dst.u.f.msize, FALSE); + } else if (mrsh==dst.u.f.msize+1) { + H5T_bit_set(d, dst.u.f.mpos+1, dst.u.f.msize-1, FALSE); + H5T_bit_set(d, dst.u.f.mpos, 1, TRUE); + } else if (mrsh==dst.u.f.msize) { + H5T_bit_set(d, dst.u.f.mpos, dst.u.f.msize, FALSE); + H5T_bit_set_d(d, dst.u.f.mpos, MIN(2, dst.u.f.msize), implied); + } else { + if (mrsh>0) { + H5T_bit_set(d, dst.u.f.mpos+dst.u.f.msize-mrsh, mrsh, + FALSE); + H5T_bit_set_d(d, dst.u.f.mpos+dst.u.f.msize-mrsh, 2, + implied); + } + if (mrsh+msize>=dst.u.f.msize) { + H5T_bit_copy(d, dst.u.f.mpos, + s, (mpos+msize+mrsh-dst.u.f.msize), + dst.u.f.msize-mrsh); + } else { + H5T_bit_copy(d, dst.u.f.mpos+dst.u.f.msize-(mrsh+msize), + s, mpos, msize); + H5T_bit_set(d, dst.u.f.mpos, dst.u.f.msize-(mrsh+msize), + FALSE); + } + } + + /* Write the exponent */ + H5T_bit_set_d(d, dst.u.f.epos, dst.u.f.esize, expo); + + padding: +#ifndef LATER + /* + * Set internal padding areas + */ +#endif + + /* + * Set external padding areas + */ + if (dst.offset>0) { + assert (H5T_PAD_ZERO==dst.lsb_pad || + H5T_PAD_ONE==dst.lsb_pad); + H5T_bit_set (d, 0, dst.offset, + H5T_PAD_ONE==dst.lsb_pad); + } + if (dst.offset+dst.prec!=8*dst_p->size) { + assert (H5T_PAD_ZERO==dst.msb_pad || + H5T_PAD_ONE==dst.msb_pad); + H5T_bit_set (d, dst.offset+dst.prec, + 8*dst_p->size - (dst.offset+dst.prec), + H5T_PAD_ONE==dst.msb_pad); + } + + /* + * Put the destination in the correct byte order. See note at + * beginning of loop. + */ + if (H5T_ORDER_BE==dst.order) { + half_size = dst_p->size/2; + for (i=0; i<half_size; i++) { + uint8 tmp = d[dst_p->size-(i+1)]; + d[dst_p->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_p->size); + sp += direction * src_p->size; + dp += direction * dst_p->size; + } + + break; + + default: + HRETURN_ERROR (H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, + "unknown conversion command"); + } + + FUNC_LEAVE (SUCCEED); +} + + +/*------------------------------------------------------------------------- + * Function: H5T_conv_float_double + * + * Purpose: Convert native `float' to native `double' using hardware. + * This is a fast special case. + * + * Return: Success: SUCCEED + * + * Failure: FAIL + * + * Programmer: Robb Matzke + * Tuesday, June 23, 1998 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +herr_t +H5T_conv_float_double (hid_t __unused__ src_id, hid_t __unused__ dst_id, + H5T_cdata_t *cdata, size_t nelmts, void *buf, + void __unused__ *bkg) +{ + size_t elmtno; /*element number */ + float *s; /*source buffer */ + double *d; /*destination buffer */ + + FUNC_ENTER (H5T_conv_float_double, FAIL); + + switch (cdata->command) { + case H5T_CONV_INIT: + cdata->need_bkg = H5T_BKG_NO; + break; + + case H5T_CONV_FREE: + break; + + case H5T_CONV_CONV: + s = (float*)buf + nelmts; + d = (double*)buf + nelmts; + + for (elmtno=0; elmtno<nelmts; elmtno++) { + *--d = *--s; + } + break; + + default: + HRETURN_ERROR (H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, + "unknown conversion command"); + } + + FUNC_LEAVE (SUCCEED); +} + + +/*------------------------------------------------------------------------- + * Function: H5T_conv_double_float + * + * Purpose: Convert native `double' to native `float' using hardware. + * This is a fast special case. + * + * Return: Success: SUCCEED + * + * Failure: FAIL + * + * Programmer: Robb Matzke + * Tuesday, June 23, 1998 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +herr_t +H5T_conv_double_float (hid_t __unused__ src_id, hid_t __unused__ dst_id, + H5T_cdata_t *cdata, size_t nelmts, void *buf, + void __unused__ *bkg) +{ + size_t elmtno; /*element number */ + double *s; /*source buffer */ + float *d; /*destination buffer */ + + FUNC_ENTER (H5T_conv_double_float, FAIL); + + switch (cdata->command) { + case H5T_CONV_INIT: + cdata->need_bkg = H5T_BKG_NO; + break; + + case H5T_CONV_FREE: + break; + + case H5T_CONV_CONV: + s = (double*)buf; + d = (float*)buf; + + for (elmtno=0; elmtno<nelmts; elmtno++) { + *d++ = *s++; + } + break; + + default: + HRETURN_ERROR (H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, + "unknown conversion command"); + } + + FUNC_LEAVE (SUCCEED); +} + + +/*------------------------------------------------------------------------- * Function: H5T_conv_i32le_f64le * * Purpose: Converts 4-byte little-endian integers (signed or unsigned) @@ -894,7 +1387,6 @@ H5T_conv_i32le_f64le (hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, 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 */ @@ -919,7 +1411,7 @@ H5T_conv_i32le_f64le (hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, 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))) { + NULL==H5I_object (dst_id)) { HRETURN_ERROR (H5E_ARGS, H5E_BADTYPE, FAIL, "not a data type"); } diff --git a/src/H5Tpkg.h b/src/H5Tpkg.h index 4257d52..a411916 100644 --- a/src/H5Tpkg.h +++ b/src/H5Tpkg.h @@ -127,6 +127,12 @@ 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_f_f (hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, + size_t nelmts, void *_buf, void __unused__ *bkg); +herr_t H5T_conv_float_double (hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, + size_t nelmts, void *buf, void __unused__ *bkg); +herr_t H5T_conv_double_float (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_f64le (hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, void *_buf, void __unused__ *bkg); @@ -134,7 +140,10 @@ herr_t H5T_conv_i32le_f64le (hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, 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); +hsize_t H5T_bit_get_d (uint8 *buf, size_t offset, size_t size); +void H5T_bit_set_d (uint8 *buf, size_t offset, size_t size, hsize_t val); ssize_t H5T_bit_find (uint8 *buf, size_t offset, size_t size, H5T_sdir_t direction, hbool_t value); +hbool_t H5T_bit_inc(uint8 *buf, size_t start, size_t size); #endif diff --git a/src/H5detect.c b/src/H5detect.c index b429caf..9e07688 100644 --- a/src/H5detect.c +++ b/src/H5detect.c @@ -71,7 +71,7 @@ static int byte_cmp(int, void *, void *); static int bit_cmp(int, int *, void *, void *); static void fix_order(int, int, int, int *, const char **); static int imp_bit(int, int *, void *, void *); -static unsigned long find_bias(int, int, int, int *, void *); +static unsigned long find_bias(int, int, int *, void *); static void precision (detected_t*); static void print_header(void); @@ -300,7 +300,7 @@ static detected_t Known[] = INFO.esize = INFO.sign - INFO.epos; \ \ _v1 = 1.0; \ - INFO.bias = find_bias (INFO.epos, INFO.esize, INFO.imp, INFO.perm, &_v1); \ + INFO.bias = find_bias (INFO.epos, INFO.esize, INFO.perm, &_v1); \ precision (&(INFO)); \ } @@ -755,7 +755,7 @@ imp_bit(int n, int *perm, void *_a, void *_b) *------------------------------------------------------------------------- */ static unsigned long -find_bias(int epos, int esize, int imp, int *perm, void *_a) +find_bias(int epos, int esize, int *perm, void *_a) { unsigned char *a = (unsigned char *) _a; unsigned char mask; @@ -771,8 +771,7 @@ find_bias(int epos, int esize, int imp, int *perm, void *_a) esize -= nbits; epos += nbits; } - - return bias - (imp ? 0 : 1); + return bias; } diff --git a/src/H5private.h b/src/H5private.h index e079682..82f0add 100644 --- a/src/H5private.h +++ b/src/H5private.h @@ -517,7 +517,6 @@ extern char *strdup(const char *s); #define H5TRACE_RETURN(V) /*void*/ #endif -extern FILE *H5_trace_g; void H5_trace (hbool_t returning, const char *func, const char *type, ...); |