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:
parent
5761b90f63
commit
28e23330df
@ -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
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);
|
||||
|
330
src/H5Tconv.c
330
src/H5Tconv.c
@ -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);
|
||||
}
|
||||
|
||||
|
15
src/H5Tpkg.h
15
src/H5Tpkg.h
@ -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;
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user