diff options
author | Robb Matzke <matzke@llnl.gov> | 1998-01-29 19:36:16 (GMT) |
---|---|---|
committer | Robb Matzke <matzke@llnl.gov> | 1998-01-29 19:36:16 (GMT) |
commit | 28e23330df9b9d35c1c13e1f983f66b4a98afe36 (patch) | |
tree | 99483b64cdc89e319b68d57c2ad99da250712529 | |
parent | 5761b90f63b5f3d69e914cfbe7a4619cce9bfc4b (diff) | |
download | hdf5-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.1 | 2 | ||||
-rw-r--r-- | config/irix64 | 4 | ||||
-rw-r--r-- | config/linux | 2 | ||||
-rw-r--r-- | src/H5D.c | 8 | ||||
-rw-r--r-- | src/H5T.c | 222 | ||||
-rw-r--r-- | src/H5Tconv.c | 310 | ||||
-rw-r--r-- | src/H5Tpkg.h | 15 | ||||
-rw-r--r-- | src/H5Tpublic.h | 13 |
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" @@ -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. @@ -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; |