summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRobb Matzke <matzke@llnl.gov>1998-01-29 19:36:16 (GMT)
committerRobb Matzke <matzke@llnl.gov>1998-01-29 19:36:16 (GMT)
commit28e23330df9b9d35c1c13e1f983f66b4a98afe36 (patch)
tree99483b64cdc89e319b68d57c2ad99da250712529
parent5761b90f63b5f3d69e914cfbe7a4619cce9bfc4b (diff)
downloadhdf5-28e23330df9b9d35c1c13e1f983f66b4a98afe36.zip
hdf5-28e23330df9b9d35c1c13e1f983f66b4a98afe36.tar.gz
hdf5-28e23330df9b9d35c1c13e1f983f66b4a98afe36.tar.bz2
[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.
-rw-r--r--config/freebsd2.2.12
-rw-r--r--config/irix644
-rw-r--r--config/linux2
-rw-r--r--src/H5D.c8
-rw-r--r--src/H5T.c222
-rw-r--r--src/H5Tconv.c310
-rw-r--r--src/H5Tpkg.h15
-rw-r--r--src/H5Tpublic.h13
8 files changed, 355 insertions, 221 deletions
diff --git a/config/freebsd2.2.1 b/config/freebsd2.2.1
index b4bbae6..42c82cf 100644
--- a/config/freebsd2.2.1
+++ b/config/freebsd2.2.1
@@ -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"
diff --git a/config/irix64 b/config/irix64
index f06e9e7..203cdef 100644
--- a/config/irix64
+++ b/config/irix64
@@ -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
diff --git a/config/linux b/config/linux
index 59d5abb..bdf4143 100644
--- a/config/linux
+++ b/config/linux
@@ -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"
diff --git a/src/H5D.c b/src/H5D.c
index 7d1a781..5e31e3f 100644
--- a/src/H5D.c
+++ b/src/H5D.c
@@ -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.
diff --git a/src/H5T.c b/src/H5T.c
index 4cc405f..74a93af 100644
--- a/src/H5T.c
+++ b/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;
+
+ /*
+ * Reset cdata.
+ */
+ 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));
/*
- * 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.
+ * Choose a new function.
*/
- (func)(FAIL, FAIL, path->cdata, H5T_CONV_FREE, NULL, NULL);
- H5ECLEAR;
-
- for (j=H5T_nsoft_g-1; j>=0 && !path->soft; --j) {
+ 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);
diff --git a/src/H5Tconv.c b/src/H5Tconv.c
index c30f8d7..0368fcb 100644
--- a/src/H5Tconv.c
+++ b/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) {
- /* 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);
+ break;
- 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;
+ 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);
- /*
- * 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;
- }
+ if (cdata->recalc &&
+ H5T_conv_struct_init (src, dst, cdata)<0) {
+ HRETURN_ERROR (H5E_DATATYPE, H5E_CANTINIT, FAIL,
+ "unable to initialize conversion data");
+ }
- 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.
+ * Insure that members are sorted.
*/
- 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;
- }
- }
+ H5T_sort_by_offset (src);
+ H5T_sort_by_offset (dst);
+ src2dst = priv->src2dst;
/*
- * 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.
+ * Direction of conversion.
*/
- 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);
+ 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;
+ }
}
- HDmemmove (bkg+dst_memb->offset, buf+offset, dst_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;
}
- assert (0==offset);
/*
- * Update buf and background.
+ * Copy the background buffer back into the in-place conversion
+ * buffer.
*/
- buf += src_delta;
- bkg += dst_delta;
+ 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");
}
- /*
- * 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);
}
diff --git a/src/H5Tpkg.h b/src/H5Tpkg.h
index 90aa54a..f1679bb 100644
--- a/src/H5Tpkg.h
+++ b/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,
diff --git a/src/H5Tpublic.h b/src/H5Tpublic.h
index 1f40151..03becfa 100644
--- a/src/H5Tpublic.h
+++ b/src/H5Tpublic.h
@@ -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;