2
0
mirror of https://github.com/HDFGroup/hdf5.git synced 2025-04-12 17:31:09 +08:00

[svn-r197] Changes since 19980129

----------------------

./config/freebds2.2.1
./config/irix64
./config/linux
	Added -DH5T_DEBUG to the debugging flags.  Also changed `true'
	to `:' for the Irix64 ranlib program.  This turns on printing
	of data type conversion statistics when the program exits.

./html/Datatypes.html
	Fixed documentation for data conversion functions and updated
	examples.

./src/H5D.c
	The I/O pipeline updates data type conversion statistics.

./src/H5T.c
./src/H5Tconv.c
./src/H5Tpkg.h
./src/H5Tpublic.h
	Cleaned up data type conversion registration interface.
This commit is contained in:
Robb Matzke 1998-01-29 14:36:16 -05:00
parent 5761b90f63
commit 28e23330df
8 changed files with 365 additions and 231 deletions

@ -41,7 +41,7 @@ warn="-Wall -Wshadow -Wpointer-arith -Wcast-qual -Wwrite-strings -Wstrict-protot
profile="-pg"
debug="-g -DH5AC_DEBUG -DH5B_DEBUG -DH5F_DEBUG -DH5G_DEBUG -UH5O_DEBUG -DH5F_OPT_SEEK=0 -fverbose-asm"
debug="-g -DH5AC_DEBUG -DH5B_DEBUG -DH5F_DEBUG -DH5G_DEBUG -UH5O_DEBUG -DH5T_DEBUG -DH5F_OPT_SEEK=0 -fverbose-asm"
production="-O3 -DNDEBUG -finline-functions -funroll-loops -malign-double -fomit-frame-pointer"

@ -41,13 +41,13 @@ warn="-fullwarn"
profile="-pg"
debug="-g -DH5AC_DEBUG -DH5B_DEBUG -DH5F_DEBUG -DH5G_DEBUG -UH5O_DEBUG -DH5F_OPT_SEEK=0"
debug="-g -DH5AC_DEBUG -DH5B_DEBUG -DH5F_DEBUG -DH5G_DEBUG -UH5O_DEBUG -DH5T_DEBUG -DH5F_OPT_SEEK=0"
production="-O -DNDEBUG"
default_mode='$debug $warn -DH5F_LOW_DFLT=H5F_LOW_SEC2'
RANLIB=true # SGI needs not ranlib
RANLIB=: # SGI needs not ranlib
# Don't set CFLAGS if the user already did.
if test -z "$CFLAGS"; then

@ -41,7 +41,7 @@ warn="-Wall -Wshadow -Wpointer-arith -Wcast-qual -Wwrite-strings -Wstrict-protot
profile="-pg"
debug="-g -DH5AC_DEBUG -DH5B_DEBUG -DH5F_DEBUG -DH5G_DEBUG -UH5O_DEBUG -DH5F_OPT_SEEK=0 -fverbose-asm"
debug="-g -DH5AC_DEBUG -DH5B_DEBUG -DH5F_DEBUG -DH5G_DEBUG -UH5O_DEBUG -DH5T_DEBUG -DH5F_OPT_SEEK=0 -fverbose-asm"
production="-O3 -DNDEBUG -finline-functions -funroll-loops -malign-double -fomit-frame-pointer"

@ -402,7 +402,7 @@ H5Dget_space (hid_t dataset_id)
*/
herr_t
H5Dread(hid_t dataset_id, hid_t mem_type_id, hid_t mem_space_id,
hid_t file_space_id, hid_t xfer_parms_id, void *buf /*out */ )
hid_t file_space_id, hid_t xfer_parms_id, void *buf/*out*/)
{
H5D_t *dataset = NULL;
const H5T_t *mem_type = NULL;
@ -967,10 +967,13 @@ H5D_read(H5D_t *dataset, const H5T_t *mem_type, const H5P_t *mem_space,
/*
* Perform data type conversion.
*/
cdata->command = H5T_CONV_CONV;
cdata->ncalls++;
if ((tconv_func) (src_id, dst_id, cdata, nelmts, tconv_buf, bkg_buf)<0) {
HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL,
"data type conversion failed");
}
cdata->nelmts += nelmts;
/*
* Scatter the data into memory.
@ -1104,10 +1107,13 @@ H5D_write(H5D_t *dataset, const H5T_t *mem_type, const H5P_t *mem_space,
/*
* Perform data type conversion.
*/
cdata->command = H5T_CONV_CONV;
cdata->ncalls++;
if ((tconv_func) (src_id, dst_id, cdata, nelmts, tconv_buf, bkg_buf)<0) {
HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL,
"data type conversion failed");
}
cdata->nelmts += nelmts;
/*
* Scatter the data out to the file.

222
src/H5T.c

@ -272,6 +272,42 @@ H5T_init_interface(void)
static void
H5T_term_interface(void)
{
int i;
H5T_path_t *path = NULL;
H5T_cdata_t *pcdata = NULL;
H5T_conv_t cfunc = NULL;
/* Unregister all conversion functions */
for (i=0; i<H5T_npath_g; i++) {
path = H5T_path_g + i;
if (path->func) {
path->cdata.command = H5T_CONV_FREE;
if ((path->func)(FAIL, FAIL, &(path->cdata), 0, NULL, NULL)<0) {
#ifdef H5T_DEBUG
fprintf (stderr, "HDF5-DIAG: conversion function failed "
"to free private data\n");
#endif
H5ECLEAR; /*ignore the error*/
}
}
}
/* Clear conversion tables */
H5T_apath_g = 0;
H5T_npath_g = 0;
H5T_path_g = H5MM_xfree (H5T_path_g);
H5T_asoft_g = 0;
H5T_nsoft_g = 0;
H5T_soft_g = H5MM_xfree (H5T_soft_g);
/* Clear noop function */
if ((cfunc=H5T_find (NULL, NULL, &pcdata))) {
pcdata->command = H5T_CONV_FREE;
(cfunc)(FAIL, FAIL, pcdata, 0, NULL, NULL);
}
H5A_destroy_group(H5_DATATYPE);
}
@ -1748,7 +1784,7 @@ H5Tget_nmembers(hid_t type_id)
*
*-------------------------------------------------------------------------
*/
char *
char *
H5Tget_member_name(hid_t type_id, int membno)
{
H5T_t *dt = NULL;
@ -2051,25 +2087,23 @@ H5Tregister_hard(hid_t src_id, hid_t dst_id, H5T_conv_t func)
}
/* Locate or create a new conversion path */
if (NULL == (path = H5T_path_find(src, dst, TRUE))) {
if (NULL == (path = H5T_path_find(src, dst, TRUE, func))) {
HRETURN_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL,
"unable to locate/allocate conversion path");
}
/* Initialize the hard function */
path->hard = func;
/*
* Notify all soft functions to recalculate private data since some
* Notify all other functions to recalculate private data since some
* functions might cache a list of conversion functions. For instance,
* the compound type converter caches a list of conversion functions for
* the members, so adding a new function should cause the list to be
* recalculated to use the new function.
*/
for (i=0; i<H5T_npath_g; i++) {
H5T_path_g[i].cdata->recalc = TRUE;
if (path != H5T_path_g+i) {
H5T_path_g[i].cdata.recalc = TRUE;
}
}
FUNC_LEAVE(SUCCEED);
}
@ -2097,7 +2131,7 @@ H5Tregister_soft(H5T_class_t src_cls, H5T_class_t dst_cls, H5T_conv_t func)
{
intn i;
hid_t src_id, dst_id;
H5T_cdata_t *cdata = NULL;
H5T_cdata_t cdata;
FUNC_ENTER(H5Tregister_soft, FAIL);
@ -2126,8 +2160,11 @@ H5Tregister_soft(H5T_class_t src_cls, H5T_class_t dst_cls, H5T_conv_t func)
/* Replace soft functions of all appropriate paths */
for (i=0; i<H5T_npath_g; i++) {
H5T_path_t *path = H5T_path_g + i;
if (!cdata) {
cdata = H5MM_xcalloc (1, sizeof(H5T_cdata_t));
path->cdata.recalc = TRUE;
if (path->is_hard ||
path->src->type!=src_cls || path->dst->type!=dst_cls) {
continue;
}
/*
@ -2135,9 +2172,6 @@ H5Tregister_soft(H5T_class_t src_cls, H5T_class_t dst_cls, H5T_conv_t func)
* 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 = H5A_register(H5_DATATYPE, H5T_copy(path->src))) < 0 ||
(dst_id = H5A_register(H5_DATATYPE, H5T_copy(path->dst))) < 0) {
HRETURN_ERROR(H5E_DATATYPE, H5E_CANTREGISTER, FAIL,
@ -2145,32 +2179,29 @@ H5Tregister_soft(H5T_class_t src_cls, H5T_class_t dst_cls, H5T_conv_t func)
}
HDmemset (&cdata, 0, sizeof cdata);
if ((func) (src_id, dst_id, cdata, H5T_CONV_INIT, NULL, NULL) >= 0) {
cdata.command = H5T_CONV_INIT;
if ((func) (src_id, dst_id, &cdata, 0, NULL, NULL) >= 0) {
/*
* Free resources used by the previous conversion function. We
* don't really care if this fails since at worst we'll just leak
* some memory. Then initialize the path with new info.
*/
if (path->soft) {
(path->soft)(src_id, dst_id, path->cdata, H5T_CONV_FREE,
NULL, NULL);
H5ECLEAR;
if (path->func) {
path->cdata.command = H5T_CONV_FREE;
if ((path->func)(src_id, dst_id, &(path->cdata),
0, NULL, NULL)<0) {
#ifdef H5T_DEBUG
fprintf (stderr, "HDF5-DIAG: conversion function failed "
"to free private data.\n");
#endif
H5ECLEAR;
}
}
path->soft = func;
H5MM_xfree (path->cdata);
path->func = func;
path->cdata = cdata;
cdata = NULL;
} else {
/*
* Notify soft function that it should recalculate its private
* data at the next opportunity. This is necessary because some
* functions cache a list of conversion functions in their
* private data area (see compound data type converters).
*/
path->cdata->recalc = TRUE;
}
/* Release temporary atoms */
H5A_dec_ref(src_id);
H5A_dec_ref(dst_id);
H5ECLEAR;
@ -2182,10 +2213,7 @@ H5Tregister_soft(H5T_class_t src_cls, H5T_class_t dst_cls, H5T_conv_t func)
/*-------------------------------------------------------------------------
* 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.
* Purpose: Removes FUNC from all conversion paths.
*
* Return: Success: SUCCEED
*
@ -2211,6 +2239,7 @@ H5Tunregister(H5T_conv_t func)
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) {
@ -2224,24 +2253,27 @@ H5Tunregister(H5T_conv_t func)
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;
if (path->func == func) {
path->func = NULL;
path->is_hard = FALSE;
/*
* Free old cdata entry. The conversion function is responsible
* for freeing the `priv' member and all it points to, but we'll
* free the rest of cdata here.
* Reset cdata.
*/
(func)(FAIL, FAIL, path->cdata, H5T_CONV_FREE, NULL, NULL);
H5ECLEAR;
for (j=H5T_nsoft_g-1; j>=0 && !path->soft; --j) {
path->cdata.command = H5T_CONV_FREE;
if ((func)(FAIL, FAIL, &(path->cdata), 0, NULL, NULL)<0) {
#ifdef H5T_DEBUG
fprintf (stderr, "HDF5-DIAG: conversion function failed to "
"free private data.\n");
#endif
H5ECLEAR;
}
HDmemset (&(path->cdata), 0, sizeof(H5T_cdata_t));
/*
* Choose a new function.
*/
for (j=H5T_nsoft_g-1; j>=0 && !path->func; --j) {
if (path->src->type != H5T_soft_g[j].src ||
path->dst->type != H5T_soft_g[j].dst) {
@ -2260,21 +2292,23 @@ H5Tunregister(H5T_conv_t func)
"unable to register conv types for query");
}
HDmemset (path->cdata, 0, sizeof(H5T_cdata_t));
if ((H5T_soft_g[j].func)(src_id, dst_id, path->cdata, 0,
NULL, NULL) >= 0) {
path->soft = H5T_soft_g[j].func;
path->cdata.command = H5T_CONV_INIT;
if ((H5T_soft_g[j].func)(src_id, dst_id, &(path->cdata),
0, NULL, NULL) >= 0) {
path->func = H5T_soft_g[j].func;
} else {
H5ECLEAR;
HDmemset (&(path->cdata), 0, sizeof(H5T_cdata_t));
}
H5A_dec_ref(src_id);
H5A_dec_ref(dst_id);
H5ECLEAR;
}
} else {
/*
* If the soft function didn't change then make sure it
* recalculates its private data at the next opportunity.
*/
path->cdata->recalc = TRUE;
path->cdata.recalc = TRUE;
}
}
@ -2732,12 +2766,10 @@ H5T_cmp(const H5T_t *dt1, const H5T_t *dt2)
FUNC_ENTER(H5T_equal, 0);
/* check args */
assert(dt1);
assert(dt2);
/* the easy case */
if (dt1 == dt2) HGOTO_DONE(0);
assert(dt1);
assert(dt2);
/* compare */
if (dt1->type < dt2->type) HGOTO_DONE(-1);
@ -2780,7 +2812,7 @@ H5T_cmp(const H5T_t *dt1, const H5T_t *dt2)
}
}
#ifndef NDEBUG
#ifdef H5T_DEBUG
/* I don't quite trust the code above yet :-) --RPM */
for (i=0; i<dt1->u.compnd.nmembs-1; i++) {
assert(HDstrcmp(dt1->u.compnd.memb[idx1[i]].name,
@ -2978,11 +3010,6 @@ H5T_find(const H5T_t *src, const H5T_t *dst, H5T_cdata_t **pcdata)
FUNC_ENTER(H5T_find, NULL);
/* Check args */
assert(src);
assert(dst);
assert (pcdata);
/* No-op case */
if (0 == H5T_cmp(src, dst)) {
*pcdata = &noop_cdata;
@ -2991,17 +3018,13 @@ H5T_find(const H5T_t *src, const H5T_t *dst, H5T_cdata_t **pcdata)
/* Find it */
if (NULL == (path = H5T_path_find(src, dst, TRUE))) {
if (NULL == (path = H5T_path_find(src, dst, TRUE, NULL))) {
HRETURN_ERROR(H5E_DATATYPE, H5E_CANTINIT, NULL,
"unable to create conversion path");
}
if (path->hard) {
ret_value = path->hard;
*pcdata = NULL;
} else if (path->soft) {
ret_value = path->soft;
*pcdata = path->cdata;
if ((ret_value=path->func)) {
*pcdata = &(path->cdata);
} else {
HRETURN_ERROR(H5E_DATATYPE, H5E_NOTFOUND, NULL,
"no conversion function for that path");
@ -3015,7 +3038,8 @@ H5T_find(const H5T_t *src, const H5T_t *dst, H5T_cdata_t **pcdata)
*
* 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.
* is created. If FUNC is non-null then it is registered as the
* hard function for that path.
*
* Return: Success: Pointer to the path, valid until the path
* database is modified.
@ -3030,7 +3054,8 @@ H5T_find(const H5T_t *src, const H5T_t *dst, H5T_cdata_t **pcdata)
*-------------------------------------------------------------------------
*/
H5T_path_t *
H5T_path_find(const H5T_t *src, const H5T_t *dst, hbool_t create)
H5T_path_find(const H5T_t *src, const H5T_t *dst, hbool_t create,
H5T_conv_t func)
{
intn lt = 0; /*left edge (inclusive) */
intn rt = H5T_npath_g; /*right edge (exclusive) */
@ -3081,26 +3106,51 @@ H5T_path_find(const H5T_t *src, const H5T_t *dst, hbool_t create)
HDmemset(path, 0, sizeof(H5T_path_t));
path->src = H5T_copy(src);
path->dst = H5T_copy(dst);
path->cdata = H5MM_xcalloc (1, sizeof(H5T_cdata_t));
/* 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;
}
/* Associate a function with the path if possible */
if (func) {
path->func = func;
path->is_hard = TRUE;
path->cdata.command = H5T_CONV_INIT;
if ((src_id=H5A_register(H5_DATATYPE, H5T_copy(path->src))) < 0 ||
(dst_id=H5A_register(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, path->cdata,
H5T_CONV_INIT, NULL, NULL) >= 0) {
path->soft = H5T_soft_g[i].func;
if ((func)(src_id, dst_id, &(path->cdata), 0, NULL, NULL)<0) {
#ifdef H5T_DEBUG
fprintf (stderr, "HDF5-DIAG: conversion function init "
"failed\n");
#endif
H5ECLEAR; /*ignore the failure*/
}
H5A_dec_ref(src_id);
H5A_dec_ref(dst_id);
H5ECLEAR;
} else {
/* Locate a soft function */
for (i=H5T_nsoft_g-1; i>=0 && !path->func; --i) {
if (src->type!=H5T_soft_g[i].src ||
dst->type!=H5T_soft_g[i].dst) {
continue;
}
if ((src_id=H5A_register(H5_DATATYPE,
H5T_copy(path->src))) < 0 ||
(dst_id=H5A_register(H5_DATATYPE,
H5T_copy(path->dst))) < 0) {
HRETURN_ERROR(H5E_DATATYPE, H5E_CANTREGISTER, NULL,
"unable to register conv types for query");
}
path->cdata.command = H5T_CONV_INIT;
if ((H5T_soft_g[i].func) (src_id, dst_id, &(path->cdata),
H5T_CONV_INIT, NULL, NULL) < 0) {
HDmemset (&(path->cdata), 0, sizeof(H5T_cdata_t));
H5ECLEAR; /*ignore the error*/
} else {
path->func = H5T_soft_g[i].func;
}
H5A_dec_ref(src_id);
H5A_dec_ref(dst_id);
}
}
}
FUNC_LEAVE(path);

@ -49,6 +49,31 @@ H5T_conv_noop(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts,
void *buf, void *background)
{
FUNC_ENTER(H5T_conv_noop, FAIL);
switch (cdata->command) {
case H5T_CONV_INIT:
/* Nothing to initialize */
break;
case H5T_CONV_CONV:
/* Nothing to convert */
break;
case H5T_CONV_FREE:
/* Nothing to free */
#ifdef H5T_DEBUG
if (cdata->ncalls>0) {
fprintf (stderr, "HDF5-DIAG: H5T_conv_noop statistics...\n");
fprintf (stderr, " Number of calls: %lu\n", cdata->ncalls);
fprintf (stderr, " Data points converted: %lu\n", cdata->nelmts);
}
#endif
default:
HRETURN_ERROR (H5E_DATATYPE, H5E_UNSUPPORTED, FAIL,
"unknown conversion command");
}
FUNC_LEAVE(SUCCEED);
}
@ -83,16 +108,15 @@ H5T_conv_order(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts,
FUNC_ENTER(H5T_conv_order, FAIL);
/* Check args */
if (H5_DATATYPE != H5A_group(src_id) ||
NULL == (src = H5A_object(src_id)) ||
H5_DATATYPE != H5A_group(dst_id) ||
NULL == (dst = H5A_object(dst_id))) {
HRETURN_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data type");
}
if (!buf) {
switch (cdata->command) {
case H5T_CONV_INIT:
/* Capability query */
if (H5_DATATYPE != H5A_group(src_id) ||
NULL == (src = H5A_object(src_id)) ||
H5_DATATYPE != H5A_group(dst_id) ||
NULL == (dst = H5A_object(dst_id))) {
HRETURN_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data type");
}
if (src->size != dst->size ||
0 != src->u.atomic.offset ||
0 != dst->u.atomic.offset ||
@ -126,17 +150,40 @@ H5T_conv_order(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts,
HRETURN_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, FAIL,
"conversion not supported");
}
HRETURN(SUCCEED);
}
/* The conversion */
md = src->size / 2;
for (i = 0; i < nelmts; i++, buf += src->size) {
for (j = 0; j < md; j++) {
tmp = buf[j];
buf[j] = buf[src->size - (j + 1)];
buf[src->size - (j + 1)] = tmp;
}
break;
case H5T_CONV_CONV:
/* The conversion */
if (H5_DATATYPE != H5A_group(src_id) ||
NULL == (src = H5A_object(src_id)) ||
H5_DATATYPE != H5A_group(dst_id) ||
NULL == (dst = H5A_object(dst_id))) {
HRETURN_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data type");
}
md = src->size / 2;
for (i = 0; i < nelmts; i++, buf += src->size) {
for (j = 0; j < md; j++) {
tmp = buf[j];
buf[j] = buf[src->size - (j + 1)];
buf[src->size - (j + 1)] = tmp;
}
}
break;
case H5T_CONV_FREE:
/* Free private data */
#ifdef H5T_DEBUG
if (cdata->ncalls>0) {
fprintf (stderr, "HDF5-DIAG: H5T_conv_order statistics...\n");
fprintf (stderr, " Number of calls: %lu\n", cdata->ncalls);
fprintf (stderr, " Data points converted: %lu\n", cdata->nelmts);
}
#endif
break;
default:
HRETURN_ERROR (H5E_DATATYPE, H5E_UNSUPPORTED, FAIL,
"unknown conversion command");
}
FUNC_LEAVE(SUCCEED);
@ -306,12 +353,12 @@ H5T_conv_struct(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts,
size_t offset; /*byte offset wrt struct */
size_t src_delta, dst_delta; /*source & destination stride */
intn elmtno, i; /*counters */
herr_t ret_value = FAIL;
H5T_conv_struct_t *priv = (H5T_conv_struct_t *)(cdata->priv);
FUNC_ENTER (H5T_conv_struct, FAIL);
if (!buf && H5T_CONV_INIT==nelmts) {
switch (cdata->command) {
case H5T_CONV_INIT:
/*
* First, determine if this conversion function applies to the
* conversion path SRC_ID-->DST_ID. If not, return failure;
@ -349,129 +396,146 @@ H5T_conv_struct(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts,
HRETURN_ERROR (H5E_DATATYPE, H5E_CANTINIT, FAIL,
"unable to initialize conversion data");
}
HRETURN (SUCCEED);
} else if (!buf && H5T_CONV_FREE==nelmts) {
break;
case H5T_CONV_FREE:
/*
* Free the private conversion data.
*/
#ifdef H5T_DEBUG
if (cdata->ncalls>0) {
fprintf (stderr, "HDF5-DIAG: H5T_conv_struct statistics...\n");
fprintf (stderr, " Number of calls: %lu\n", cdata->ncalls);
fprintf (stderr, " Data points converted: %lu\n", cdata->nelmts);
}
#endif
H5MM_xfree (priv->src2dst);
H5MM_xfree (priv->src_memb_id);
H5MM_xfree (priv->dst_memb_id);
H5MM_xfree (priv->memb_conv);
cdata->priv = priv = H5MM_xfree (priv);
HRETURN (SUCCEED);
} else if (!buf) {
break;
case H5T_CONV_CONV:
/*
* Conversion.
*/
if (H5_DATATYPE != H5A_group(src_id) ||
NULL == (src = H5A_object(src_id)) ||
H5_DATATYPE != H5A_group(dst_id) ||
NULL == (dst = H5A_object(dst_id))) {
HRETURN_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data type");
}
assert (priv);
assert (bkg && cdata->need_bkg>=H5T_BKG_TEMP);
if (cdata->recalc &&
H5T_conv_struct_init (src, dst, cdata)<0) {
HRETURN_ERROR (H5E_DATATYPE, H5E_CANTINIT, FAIL,
"unable to initialize conversion data");
}
/*
* Insure that members are sorted.
*/
H5T_sort_by_offset (src);
H5T_sort_by_offset (dst);
src2dst = priv->src2dst;
/*
* Direction of conversion.
*/
if (dst->size <= src->size) {
src_delta = src->size;
dst_delta = dst->size;
} else {
src_delta = -(src->size);
dst_delta = -(dst->size);
buf += (nelmts-1) * src->size;
bkg += (nelmts-1) * dst->size;
}
for (elmtno=0; elmtno<nelmts; elmtno++) {
/*
* For each source member which will be present in the
* destination, convert the member to the destination type unless
* it is larger than the source type. Then move the member to the
* left-most unoccupied position in the buffer. This makes the
* data point as small as possible with all the free space on the
* right side.
*/
for (i=0, offset=0; i<src->u.compnd.nmembs; i++) {
if (src2dst[i]<0) continue;
src_memb = src->u.compnd.memb + i;
dst_memb = dst->u.compnd.memb + src2dst[i];
if (dst_memb->type.size <= src_memb->type.size) {
H5T_conv_t tconv_func = priv->memb_conv[src2dst[i]];
H5T_cdata_t *memb_cdata = priv->memb_cdata[src2dst[i]];
memb_cdata->command = H5T_CONV_CONV;
(tconv_func)(priv->src_memb_id[src2dst[i]],
priv->dst_memb_id[src2dst[i]],
memb_cdata,
1,
buf + src_memb->offset,
bkg + dst_memb->offset);
HDmemmove (buf + offset, buf + src_memb->offset,
dst_memb->type.size);
offset += dst_memb->type.size;
} else {
HDmemmove (buf + offset, buf + src_memb->offset,
src_memb->type.size);
offset += src_memb->type.size;
}
}
/*
* For each source member which will be present in the
* destination, convert the member to the destination type if it
* is larger than the source type (that is, has not been converted
* yet). Then copy the member to the destination offset in the
* background buffer.
*/
for (i=src->u.compnd.nmembs-1; i>=0; --i) {
if (src2dst[i]<0) continue;
src_memb = src->u.compnd.memb + i;
dst_memb = dst->u.compnd.memb + src2dst[i];
offset -= dst_memb->type.size;
if (dst_memb->type.size > src_memb->type.size) {
H5T_conv_t tconv_func = priv->memb_conv[src2dst[i]];
H5T_cdata_t *memb_cdata = priv->memb_cdata[src2dst[i]];
memb_cdata->command = H5T_CONV_CONV;
(tconv_func)(priv->src_memb_id[src2dst[i]],
priv->dst_memb_id[src2dst[i]], memb_cdata, 1,
buf + offset, bkg + dst_memb->offset);
}
HDmemmove (bkg+dst_memb->offset, buf+offset,
dst_memb->type.size);
}
assert (0==offset);
/*
* Update buf and background.
*/
buf += src_delta;
bkg += dst_delta;
}
/*
* Copy the background buffer back into the in-place conversion
* buffer.
*/
HDmemcpy (_buf, _bkg, nelmts*dst->size);
break;
default:
/* Some other command we don't know about yet.*/
HRETURN_ERROR (H5E_DATATYPE, H5E_UNSUPPORTED, FAIL,
"unknown conversion command");
}
/* Check args */
if (H5_DATATYPE != H5A_group(src_id) ||
NULL == (src = H5A_object(src_id)) ||
H5_DATATYPE != H5A_group(dst_id) ||
NULL == (dst = H5A_object(dst_id))) {
HRETURN_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data type");
}
assert (priv);
assert (bkg && cdata->need_bkg>=H5T_BKG_TEMP);
if (cdata->recalc &&
H5T_conv_struct_init (src, dst, cdata)<0) {
HRETURN_ERROR (H5E_DATATYPE, H5E_CANTINIT, FAIL,
"unable to initialize conversion data");
}
/*
* Insure that members are sorted.
*/
H5T_sort_by_offset (src);
H5T_sort_by_offset (dst);
src2dst = priv->src2dst;
/*
* Direction of conversion.
*/
if (dst->size <= src->size) {
src_delta = src->size;
dst_delta = dst->size;
} else {
src_delta = -(src->size);
dst_delta = -(dst->size);
buf += (nelmts-1) * src->size;
bkg += (nelmts-1) * dst->size;
}
for (elmtno=0; elmtno<nelmts; elmtno++) {
/*
* For each source member which will be present in the destination,
* convert the member to the destination type unless it is larger than
* the source type. Then move the member to the left-most unoccupied
* position in the buffer. This makes the data point as small as
* possible with all the free space on the right side.
*/
for (i=0, offset=0; i<src->u.compnd.nmembs; i++) {
if (src2dst[i]<0) continue;
src_memb = src->u.compnd.memb + i;
dst_memb = dst->u.compnd.memb + src2dst[i];
if (dst_memb->type.size <= src_memb->type.size) {
H5T_conv_t tconv_func = priv->memb_conv[src2dst[i]];
H5T_cdata_t *memb_cdata = priv->memb_cdata[src2dst[i]];
(tconv_func)(priv->src_memb_id[src2dst[i]],
priv->dst_memb_id[src2dst[i]], memb_cdata, 1,
buf + src_memb->offset, bkg + dst_memb->offset);
HDmemmove (buf + offset, buf + src_memb->offset,
dst_memb->type.size);
offset += dst_memb->type.size;
} else {
HDmemmove (buf + offset, buf + src_memb->offset,
src_memb->type.size);
offset += src_memb->type.size;
}
}
/*
* For each source member which will be present in the destination,
* convert the member to the destination type if it is larger than the
* source type (that is, has not been converted yet). Then copy the
* member to the destination offset in the background buffer.
*/
for (i=src->u.compnd.nmembs-1; i>=0; --i) {
if (src2dst[i]<0) continue;
src_memb = src->u.compnd.memb + i;
dst_memb = dst->u.compnd.memb + src2dst[i];
offset -= dst_memb->type.size;
if (dst_memb->type.size > src_memb->type.size) {
H5T_conv_t tconv_func = priv->memb_conv[src2dst[i]];
H5T_cdata_t *memb_cdata = priv->memb_cdata[src2dst[i]];
(tconv_func)(priv->src_memb_id[src2dst[i]],
priv->dst_memb_id[src2dst[i]], memb_cdata, 1,
buf + offset, bkg + dst_memb->offset);
}
HDmemmove (bkg+dst_memb->offset, buf+offset, dst_memb->type.size);
}
assert (0==offset);
/*
* Update buf and background.
*/
buf += src_delta;
bkg += dst_delta;
}
/*
* Copy the background buffer back into the in-place conversion buffer.
*/
HDmemcpy (_buf, _bkg, nelmts*dst->size);
ret_value = SUCCEED;
FUNC_LEAVE (ret_value);
FUNC_LEAVE (SUCCEED);
}

@ -16,6 +16,13 @@
#ifndef _H5Tpkg_H
#define _H5Tpkg_H
/*
* Define this to enable debugging.
*/
#ifdef NDEBUG
# undef H5T_DEBUG
#endif
#include <H5Tprivate.h>
typedef struct H5T_atomic_t {
@ -76,9 +83,9 @@ typedef struct H5T_member_t {
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_cdata_t *cdata; /*extra conversion data */
H5T_conv_t func; /*data conversion function */
hbool_t is_hard; /*is it a hard function? */
H5T_cdata_t cdata; /*data for this function */
} H5T_path_t;
/* The master list of soft conversion functions */
@ -90,7 +97,7 @@ typedef struct H5T_soft_t {
/* Function prototypes for H5T package scope */
H5T_path_t *H5T_path_find (const H5T_t *src, const H5T_t *dst,
hbool_t create);
hbool_t create, H5T_conv_t func);
/* Conversion functions */
herr_t H5T_conv_noop (hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata,

@ -23,9 +23,6 @@
#define HOFFSET(S,M) ((const char*)&S.M-(const char*)&S)
#define HPOFFSET(P,M) ((const char*)&(P->M)-(const char*)P)
#define H5T_CONV_INIT 0
#define H5T_CONV_FREE 1
/* These are the various classes of data types */
typedef enum H5T_class_t {
H5T_NO_CLASS = -1, /*error */
@ -102,10 +99,20 @@ typedef enum H5T_bkg_t {
H5T_BKG_YES = 2 /*init bkg buf with data before conversion */
} H5T_bkg_t;
/* Commands sent to conversion functions */
typedef enum H5T_cmd_t {
H5T_CONV_INIT = 0, /*query and/or initialize private data */
H5T_CONV_CONV = 1, /*convert data from source to dest data type */
H5T_CONV_FREE = 2 /*function is being removed from path */
} H5T_cmd_t;
/* Type conversion client data */
typedef struct H5T_cdata_t {
H5T_cmd_t command;/*what should the conversion function do? */
H5T_bkg_t need_bkg;/*is the background buffer needed? */
hbool_t recalc; /*recalculate private data */
unsigned long ncalls; /*number of calls to conversion function */
unsigned long nelmts; /*total number of data points converted */
void *priv; /*private data */
} H5T_cdata_t;