diff options
author | Robb Matzke <matzke@llnl.gov> | 1998-08-10 18:15:14 (GMT) |
---|---|---|
committer | Robb Matzke <matzke@llnl.gov> | 1998-08-10 18:15:14 (GMT) |
commit | 9754e9373b731856dbf61fdb9c99501f452ca552 (patch) | |
tree | 0bb99d2caf87b9ec8e4dfd2a52bf03b5c7d06055 /src/H5Tconv.c | |
parent | 1d0b2915c2d492ecf35b83ff65287d5d95bf5f7c (diff) | |
download | hdf5-9754e9373b731856dbf61fdb9c99501f452ca552.zip hdf5-9754e9373b731856dbf61fdb9c99501f452ca552.tar.gz hdf5-9754e9373b731856dbf61fdb9c99501f452ca552.tar.bz2 |
[svn-r584] Changes since 19980806
----------------------
./doc/html/Datatypes.html
./doc/html/H5.format.html
./src/H5.c
./src/H5Odtype.c
./src/H5T.c
./src/H5Tconv.c
./src/H5Tpkg.h
./src/H5Tpublic.h
./test/dtypes.c
Changed the values of the H5T_str_t type in order to make a
distinction between C's null terminated strings and strings
which are not null terminated.
The string character set and padding method are saved to the
hdf5 file instead of using defaults.
Added conversion function from one fixed-length string type
to another.
./test/chunk.c
Fixed to work with new filter API
Diffstat (limited to 'src/H5Tconv.c')
-rw-r--r-- | src/H5Tconv.c | 228 |
1 files changed, 228 insertions, 0 deletions
diff --git a/src/H5Tconv.c b/src/H5Tconv.c index c940474..ce0df3e 100644 --- a/src/H5Tconv.c +++ b/src/H5Tconv.c @@ -1321,6 +1321,234 @@ H5T_conv_f_f (hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, /*------------------------------------------------------------------------- + * Function: H5T_conv_s_s + * + * Purpose: Convert one fixed-length string type to another. + * + * Return: Success: SUCCEED + * + * Failure: FAIL + * + * Programmer: Robb Matzke + * Friday, August 7, 1998 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +herr_t +H5T_conv_s_s (hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, + void *buf, void __unused__ *bkg) +{ + H5T_t *src=NULL; /*source data type */ + H5T_t *dst=NULL; /*destination data type */ + intn direction; /*direction of traversal */ + size_t elmtno; /*element number */ + size_t olap; /*num overlapping elements */ + size_t nchars; /*number of characters copied */ + uint8 *s, *sp, *d, *dp; /*src and dst traversal pointers*/ + uint8 *dbuf=NULL; /*temp buf for overlap convers. */ + herr_t ret_value=FAIL; /*return value */ + + FUNC_ENTER(H5T_conv_s_s, FAIL); + + switch (cdata->command) { + case H5T_CONV_INIT: + if (H5_DATATYPE!=H5I_group(src_id) || + NULL==(src=H5I_object(src_id)) || + H5_DATATYPE!=H5I_group(dst_id) || + NULL==(dst=H5I_object(dst_id))) { + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data type"); + } + if (8*src->size != src->u.atomic.prec || + 8*dst->size != dst->u.atomic.prec) { + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "bad precision"); + } + if (0 != src->u.atomic.offset || + 0 != dst->u.atomic.offset) { + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "bad offset"); + } + if (H5T_CSET_ASCII != src->u.atomic.u.s.cset || + H5T_CSET_ASCII != dst->u.atomic.u.s.cset) { + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "bad character set"); + } + if (src->u.atomic.u.s.pad<0 || src->u.atomic.u.s.pad>=H5T_NPAD || + dst->u.atomic.u.s.pad<0 || dst->u.atomic.u.s.pad>=H5T_NPAD) { + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "bad character padding"); + } + 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=H5I_object(src_id)) || + H5_DATATYPE!=H5I_group(dst_id) || + NULL==(dst=H5I_object(dst_id))) { + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data type"); + } + + /* + * Do we process the values from beginning to end or vice versa? Also, + * how many of the elements have the source and destination areas + * overlapping? + */ + if (src->size==dst->size) { + /* + * When the source and destination are the same size we can do + * all the conversions in place. + */ + sp = dp = (uint8*)buf; + direction = 1; + olap = 0; + } else if (src->size>=dst->size) { + sp = dp = (uint8*)buf; + direction = 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 = (size_t)(ceil((double)(dst->size)/ + (double)(dst->size-src->size))-1); + } + + /* Allocate the overlap buffer */ + if (NULL==(dbuf=H5MM_malloc(dst->size))) { + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, + "memory allocation failed for string conversion"); + } + + /* The conversion loop. */ + for (elmtno=0; elmtno<nelmts; elmtno++) { + + /* + * If the source and destination buffers overlap then use a + * temporary buffer fot eh 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 (src->size==dst->size) { + assert(s==d); + } else if (d==dbuf) { + assert((dp>=sp && dp<sp+src->size) || + (sp>=dp && sp<dp+dst->size)); + } else { + assert((dp<sp && dp+dst->size<=sp) || + (sp<dp && sp+src->size<=dp)); + } +#endif + + /* Copy characters from source to destination */ + switch (src->u.atomic.u.s.pad) { + case H5T_STR_NULLTERM: + for (nchars=0; + nchars<dst->size && nchars<src->size && s[nchars]; + nchars++) { + d[nchars] = s[nchars]; + } + break; + + case H5T_STR_NULLPAD: + for (nchars=0; + nchars<dst->size && nchars<src->size && s[nchars]; + nchars++) { + d[nchars] = s[nchars]; + } + break; + + case H5T_STR_SPACEPAD: + nchars = src->size; + while (nchars>0 && ' '==s[nchars-1]) --nchars; + nchars = MIN(dst->size, nchars); + memcpy(d, s, nchars); + break; + + case H5T_STR_RESERVED_3: + case H5T_STR_RESERVED_4: + case H5T_STR_RESERVED_5: + case H5T_STR_RESERVED_6: + case H5T_STR_RESERVED_7: + case H5T_STR_RESERVED_8: + case H5T_STR_RESERVED_9: + case H5T_STR_RESERVED_10: + case H5T_STR_RESERVED_11: + case H5T_STR_RESERVED_12: + case H5T_STR_RESERVED_13: + case H5T_STR_RESERVED_14: + case H5T_STR_RESERVED_15: + case H5T_STR_ERROR: + HGOTO_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, + "source string padding method not supported"); + } + + /* Terminate or pad the destination */ + switch (dst->u.atomic.u.s.pad) { + case H5T_STR_NULLTERM: + while (nchars<dst->size) d[nchars++] = '\0'; + d[dst->size-1] = '\0'; + break; + + case H5T_STR_NULLPAD: + while (nchars<dst->size) d[nchars++] = '\0'; + break; + + case H5T_STR_SPACEPAD: + while (nchars<dst->size) d[nchars++] = ' '; + break; + + case H5T_STR_RESERVED_3: + case H5T_STR_RESERVED_4: + case H5T_STR_RESERVED_5: + case H5T_STR_RESERVED_6: + case H5T_STR_RESERVED_7: + case H5T_STR_RESERVED_8: + case H5T_STR_RESERVED_9: + case H5T_STR_RESERVED_10: + case H5T_STR_RESERVED_11: + case H5T_STR_RESERVED_12: + case H5T_STR_RESERVED_13: + case H5T_STR_RESERVED_14: + case H5T_STR_RESERVED_15: + case H5T_STR_ERROR: + HGOTO_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, + "destination string padding method not supported"); + } + + /* + * If we used a temporary buffer for the destination then we + * should copy the value to the true destination buffer. + */ + if (d==dbuf) HDmemcpy(dp, d, dst->size); + sp += direction * src->size; + dp += direction * dst->size; + } + break; + + default: + HGOTO_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, + "unknown converson command"); + } + ret_value = SUCCEED; + + done: + H5MM_xfree(dbuf); + FUNC_LEAVE(ret_value); +} + + +/*------------------------------------------------------------------------- * Function: H5T_conv_float_double * * Purpose: Convert native `float' to native `double' using hardware. |