[svn-r170] Changes since 19980123

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

./src/H5D.c
./src/H5T.c
./src/H5Tconv.c
./src/H5Tpkg.h
./src/H5Tprivate.h
./src/H5Tpublic.h
./test/cmpd_dset.c
        Added support to turn background buffer on/off to help speed
        up conversions.  Currently, every type of conversion turns it
        off except compound-->compound conversions which always turn
        it on.  In the future the compound-->compound conversions
        might be more frugal.
This commit is contained in:
Robb Matzke 1998-01-26 15:56:18 -05:00
parent 6cd8818b73
commit 5c6a3af396
7 changed files with 371 additions and 153 deletions

View File

@ -837,7 +837,7 @@ H5D_read(H5D_t *dataset, const H5T_t *mem_type, const H5P_t *mem_space,
hid_t src_id = -1, dst_id = -1;/*temporary type atoms */
const H5P_conv_t *sconv_func = NULL; /*space conversion funcs*/
H5P_number_t numbering; /*element numbering info*/
void *cdata = NULL; /*type conversion data */
H5T_cdata_t *cdata = NULL; /*type conversion data */
herr_t ret_value = FAIL;
FUNC_ENTER(H5D_read, FAIL);
@ -895,7 +895,7 @@ H5D_read(H5D_t *dataset, const H5T_t *mem_type, const H5P_t *mem_space,
size_t src_size = nelmts * H5T_get_size(dataset->type);
size_t dst_size = nelmts * H5T_get_size(mem_type);
tconv_buf = H5MM_xmalloc(MAX(src_size, dst_size));
bkg_buf = H5MM_xmalloc (dst_size);
if (cdata->need_bkg) bkg_buf = H5MM_xmalloc (dst_size);
}
#endif
@ -911,15 +911,18 @@ H5D_read(H5D_t *dataset, const H5T_t *mem_type, const H5P_t *mem_space,
tconv_buf/*out*/)!=nelmts) {
HGOTO_ERROR(H5E_IO, H5E_READERROR, FAIL, "file gather failed");
}
if ((sconv_func->mgath)(buf, H5T_get_size (mem_type), mem_space,
&numbering, 0, nelmts, bkg_buf/*out*/)!=nelmts) {
HGOTO_ERROR (H5E_IO, H5E_READERROR, FAIL, "mem gather failed");
if (H5T_BKG_YES==cdata->need_bkg) {
if ((sconv_func->mgath)(buf, H5T_get_size (mem_type), mem_space,
&numbering, 0, nelmts,
bkg_buf/*out*/)!=nelmts) {
HGOTO_ERROR (H5E_IO, H5E_READERROR, FAIL, "mem gather failed");
}
}
/*
* Perform data type conversion.
*/
if ((tconv_func) (src_id, dst_id, &cdata, nelmts, tconv_buf, bkg_buf)<0) {
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");
}
@ -970,7 +973,7 @@ H5D_write(H5D_t *dataset, const H5T_t *mem_type, const H5P_t *mem_space,
hid_t src_id = -1, dst_id = -1;/*temporary type atoms */
const H5P_conv_t *sconv_func = NULL; /*space conversion funcs*/
H5P_number_t numbering; /*element numbering info*/
void *cdata = NULL; /*type conversion data */
H5T_cdata_t *cdata = NULL; /*type conversion data */
herr_t ret_value = FAIL;
FUNC_ENTER(H5D_write, FAIL);
@ -1028,7 +1031,7 @@ H5D_write(H5D_t *dataset, const H5T_t *mem_type, const H5P_t *mem_space,
size_t src_size = nelmts * H5T_get_size(mem_type);
size_t dst_size = nelmts * H5T_get_size(dataset->type);
tconv_buf = H5MM_xmalloc(MAX(src_size, dst_size));
bkg_buf = H5MM_xmalloc (dst_size);
if (cdata->need_bkg) bkg_buf = H5MM_xmalloc (dst_size);
}
#endif
@ -1043,16 +1046,19 @@ H5D_write(H5D_t *dataset, const H5T_t *mem_type, const H5P_t *mem_space,
&numbering, 0, nelmts, tconv_buf/*out*/)!=nelmts) {
HGOTO_ERROR (H5E_IO, H5E_WRITEERROR, FAIL, "mem gather failed");
}
if ((sconv_func->fgath)(dataset->ent.file, &(dataset->layout),
H5T_get_size (dataset->type), file_space,
&numbering, 0, nelmts, bkg_buf/*out*/)!=nelmts) {
HGOTO_ERROR (H5E_IO, H5E_WRITEERROR, FAIL, "file gather failed");
if (H5T_BKG_YES==cdata->need_bkg) {
if ((sconv_func->fgath)(dataset->ent.file, &(dataset->layout),
H5T_get_size (dataset->type), file_space,
&numbering, 0, nelmts,
bkg_buf/*out*/)!=nelmts) {
HGOTO_ERROR (H5E_IO, H5E_WRITEERROR, FAIL, "file gather failed");
}
}
/*
* Perform data type conversion.
*/
if ((tconv_func) (src_id, dst_id, &cdata, nelmts, tconv_buf, bkg_buf)<0) {
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");
}

107
src/H5T.c
View File

@ -2068,9 +2068,10 @@ H5Tpack(hid_t type_id)
herr_t
H5Tregister_hard(hid_t src_id, hid_t dst_id, H5T_conv_t func)
{
H5T_t *src = NULL;
H5T_t *dst = NULL;
H5T_path_t *path = NULL;
H5T_t *src = NULL;
H5T_t *dst = NULL;
H5T_path_t *path = NULL;
intn i;
FUNC_ENTER(H5Tregister_hard, FAIL);
@ -2081,16 +2082,31 @@ H5Tregister_hard(hid_t src_id, hid_t dst_id, H5T_conv_t func)
NULL == (dst = H5A_object(dst_id))) {
HRETURN_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data type");
}
/* Locate or create a new conversion path */
if (NULL == (path = H5T_path_find(src, dst, TRUE))) {
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
* 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;
}
FUNC_LEAVE(SUCCEED);
}
/*-------------------------------------------------------------------------
* Function: H5Tregister_soft
*
@ -2114,6 +2130,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;
FUNC_ENTER(H5Tregister_soft, FAIL);
@ -2127,6 +2144,7 @@ H5Tregister_soft(H5T_class_t src_cls, H5T_class_t dst_cls, H5T_conv_t func)
HRETURN_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL,
"no soft conversion function specified");
}
/* Add function to end of master list */
if (H5T_nsoft_g >= H5T_asoft_g) {
H5T_asoft_g = MAX(32, 2 * H5T_asoft_g);
@ -2139,9 +2157,11 @@ H5Tregister_soft(H5T_class_t src_cls, H5T_class_t dst_cls, H5T_conv_t func)
H5T_nsoft_g++;
/* Replace soft functions of all appropriate paths */
for (i = 0; i < H5T_npath_g; i++) {
for (i=0; i<H5T_npath_g; i++) {
H5T_path_t *path = H5T_path_g + i;
void *cdata = NULL;
if (!cdata) {
cdata = H5MM_xcalloc (1, sizeof(H5T_cdata_t));
}
/*
* Type conversion functions are app-level, so we need to convert the
@ -2156,11 +2176,34 @@ H5Tregister_soft(H5T_class_t src_cls, H5T_class_t dst_cls, H5T_conv_t func)
HRETURN_ERROR(H5E_DATATYPE, H5E_CANTREGISTER, FAIL,
"unable to register data types for conv query");
}
if ((func) (src_id, dst_id, &cdata, 0, NULL, NULL) >= 0) {
HDmemset (&cdata, 0, sizeof cdata);
if ((func) (src_id, dst_id, cdata, H5T_CONV_INIT, 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;
}
path->soft = func;
H5MM_xfree (path->cdata);
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;
}
H5A_dec_ref(src_id);
H5A_dec_ref(dst_id);
H5ECLEAR;
@ -2168,7 +2211,7 @@ H5Tregister_soft(H5T_class_t src_cls, H5T_class_t dst_cls, H5T_conv_t func)
FUNC_LEAVE(SUCCEED);
}
/*-------------------------------------------------------------------------
* Function: H5Tunregister
*
@ -2222,15 +2265,22 @@ H5Tunregister(H5T_conv_t func)
/* Reset soft function */
if (path->soft == func) {
path->soft = NULL;
path->cdata = H5MM_xfree (path->cdata);
/*
* 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.
*/
(func)(FAIL, FAIL, path->cdata, H5T_CONV_FREE, NULL, NULL);
H5ECLEAR;
for (j=H5T_nsoft_g-1; j>=0 && !path->soft; --j) {
void *cdata = NULL;
if (path->src->type != H5T_soft_g[j].src ||
path->dst->type != H5T_soft_g[j].dst) {
continue;
}
/*
* Conversion functions are app-level, so temporarily create
* object id's for the data types.
@ -2242,15 +2292,22 @@ H5Tunregister(H5T_conv_t func)
HRETURN_ERROR(H5E_DATATYPE, H5E_CANTREGISTER, FAIL,
"unable to register conv types for query");
}
if ((H5T_soft_g[j].func)(src_id, dst_id, &cdata, 0,
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 = cdata;
}
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;
}
}
@ -2278,7 +2335,7 @@ H5Tunregister(H5T_conv_t func)
*-------------------------------------------------------------------------
*/
H5T_conv_t
H5Tfind(hid_t src_id, hid_t dst_id, void **pcdata)
H5Tfind(hid_t src_id, hid_t dst_id, H5T_cdata_t **pcdata)
{
H5T_conv_t ret_value = NULL;
H5T_t *src = NULL, *dst = NULL;
@ -2946,10 +3003,11 @@ H5T_cmp(const H5T_t *dt1, const H5T_t *dt2)
*-------------------------------------------------------------------------
*/
H5T_conv_t
H5T_find(const H5T_t *src, const H5T_t *dst, void **pcdata)
H5T_find(const H5T_t *src, const H5T_t *dst, H5T_cdata_t **pcdata)
{
H5T_path_t *path = NULL;
H5T_conv_t ret_value = NULL;
H5T_path_t *path = NULL;
H5T_conv_t ret_value = NULL;
static H5T_cdata_t noop_cdata;
FUNC_ENTER(H5T_find, NULL);
@ -2959,7 +3017,11 @@ H5T_find(const H5T_t *src, const H5T_t *dst, void **pcdata)
assert (pcdata);
/* No-op case */
if (0 == H5T_cmp(src, dst)) HRETURN(H5T_conv_noop);
if (0 == H5T_cmp(src, dst)) {
*pcdata = &noop_cdata;
HRETURN(H5T_conv_noop);
}
/* Find it */
if (NULL == (path = H5T_path_find(src, dst, TRUE))) {
@ -3000,7 +3062,7 @@ H5T_find(const H5T_t *src, const H5T_t *dst, void **pcdata)
*
*-------------------------------------------------------------------------
*/
H5T_path_t *
H5T_path_t *
H5T_path_find(const H5T_t *src, const H5T_t *dst, hbool_t create)
{
intn lt = 0; /*left edge (inclusive) */
@ -3052,10 +3114,10 @@ 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) {
void *cdata = NULL;
if (src->type!=H5T_soft_g[i].src ||
dst->type!=H5T_soft_g[i].dst) {
continue;
@ -3065,10 +3127,9 @@ H5T_path_find(const H5T_t *src, const H5T_t *dst, hbool_t create)
HRETURN_ERROR(H5E_DATATYPE, H5E_CANTREGISTER, NULL,
"unable to register conv types for query");
}
if ((H5T_soft_g[i].func) (src_id, dst_id, &cdata, 0,
NULL, NULL) >= 0) {
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;
path->cdata = cdata;
}
H5A_dec_ref(src_id);
H5A_dec_ref(dst_id);
@ -3077,7 +3138,7 @@ H5T_path_find(const H5T_t *src, const H5T_t *dst, hbool_t create)
}
FUNC_LEAVE(path);
}
/*-------------------------------------------------------------------------
* Function: H5T_debug
*

View File

@ -14,6 +14,15 @@
#include <H5MMprivate.h>
#include <H5Tpkg.h>
/* Conversion data for H5T_conv_struct() */
typedef struct H5T_conv_struct_t {
intn *src2dst; /*mapping from src to dst memb ID */
hid_t *src_memb_id; /*source member type ID's */
hid_t *dst_memb_id; /*destination member type ID's */
H5T_conv_t *memb_conv; /*array of membr conversion functions*/
H5T_cdata_t **memb_cdata; /*array of member cdata pointers */
} H5T_conv_struct_t;
/* Interface initialization */
static intn interface_initialize_g = FALSE;
#define INTERFACE_INIT NULL
@ -36,7 +45,7 @@ static intn interface_initialize_g = FALSE;
*-------------------------------------------------------------------------
*/
herr_t
H5T_conv_noop(hid_t src_id, hid_t dst_id, void **pcdata, size_t nelmts,
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);
@ -63,7 +72,7 @@ H5T_conv_noop(hid_t src_id, hid_t dst_id, void **pcdata, size_t nelmts,
*-------------------------------------------------------------------------
*/
herr_t
H5T_conv_order(hid_t src_id, hid_t dst_id, void **pcdata, size_t nelmts,
H5T_conv_order(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts,
void *_buf, void *background)
{
uint8 *buf = (uint8 *) _buf;
@ -133,6 +142,127 @@ H5T_conv_order(hid_t src_id, hid_t dst_id, void **pcdata, size_t nelmts,
FUNC_LEAVE(SUCCEED);
}
/*-------------------------------------------------------------------------
* Function: H5T_conv_struct_init
*
* Purpose: Initialize the `priv' field of `cdata' with conversion
* information that is relatively constant. If `priv' is
* already initialized then the member conversion functions
* are recalculated.
*
* Return: Success: SUCCEED
*
* Failure: FAIL
*
* Programmer: Robb Matzke
* Monday, January 26, 1998
*
* Modifications:
*
*-------------------------------------------------------------------------
*/
static herr_t
H5T_conv_struct_init (H5T_t *src, H5T_t *dst, H5T_cdata_t *cdata)
{
H5T_conv_struct_t *priv = (H5T_conv_struct_t*)(cdata->priv);
intn i, j, *src2dst = NULL;
H5T_t *type = NULL;
hid_t tid;
FUNC_ENTER (H5T_conv_struct_init, FAIL);
if (!priv) {
/*
* Notice: the thing marked with `!' below really is `dst' and not
* `src' because we're only interested in the members of the
* source type that are also in the destination type.
*/
cdata->priv = priv = H5MM_xcalloc (1, sizeof(H5T_conv_struct_t));
priv->src2dst = H5MM_xmalloc (src->u.compnd.nmembs * sizeof(intn));
priv->src_memb_id = H5MM_xmalloc (/*!*/dst->u.compnd.nmembs *
sizeof(hid_t));
priv->dst_memb_id = H5MM_xmalloc (dst->u.compnd.nmembs *
sizeof(hid_t));
/*
* Insure that members are sorted.
*/
H5T_sort_by_offset (src);
H5T_sort_by_offset (dst);
/*
* Build a mapping from source member number to destination member
* number. If some source member is not a destination member then that
* mapping element will be negative. Also create atoms for each
* source and destination member data type so we can look up the
* member data type conversion functions later.
*/
for (i=0; i<src->u.compnd.nmembs; i++) {
priv->src2dst[i] = -1;
for (j=0; j<dst->u.compnd.nmembs; j++) {
if (!HDstrcmp (src->u.compnd.memb[i].name,
dst->u.compnd.memb[j].name)) {
priv->src2dst[i] = j;
break;
}
}
if (priv->src2dst[i]>=0) {
type = &(src->u.compnd.memb[i].type);
tid = H5A_register (H5_DATATYPE, type);
assert (tid>=0);
priv->src_memb_id[priv->src2dst[i]] = tid;
type = &(dst->u.compnd.memb[priv->src2dst[i]].type);
tid = H5A_register (H5_DATATYPE, type);
assert (tid>=0);
priv->dst_memb_id[priv->src2dst[i]] = tid;
}
}
}
/*
* (Re)build the cache of member conversion functions and pointers to
* their cdata entries.
*/
priv->memb_conv = H5MM_xfree (priv->memb_conv);
priv->memb_cdata = H5MM_xfree (priv->memb_cdata);
priv->memb_conv = H5MM_xmalloc (dst->u.compnd.nmembs *
sizeof(H5T_conv_t));
priv->memb_cdata = H5MM_xcalloc (dst->u.compnd.nmembs,
sizeof(H5T_cdata_t*));
src2dst = priv->src2dst;
for (i=0; i<src->u.compnd.nmembs; i++) {
if (priv->src2dst[i]>=0) {
H5T_conv_t tconv_func = H5Tfind (priv->src_memb_id[src2dst[i]],
priv->dst_memb_id[src2dst[i]],
priv->memb_cdata+src2dst[i]);
if (!tconv_func) {
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_ERROR (H5E_DATATYPE, H5E_UNSUPPORTED, FAIL,
"unable to convert member data type");
}
priv->memb_conv[src2dst[i]] = tconv_func;
}
}
#ifndef LATER
/*
* Always use an initialized background buffer. Actually, we usually
* won't need it initialized but we'll almost always need a buffer to
* move the members around.
*/
cdata->need_bkg = H5T_BKG_YES;
#endif
cdata->recalc = FALSE;
FUNC_LEAVE (SUCCEED);
}
/*-------------------------------------------------------------------------
* Function: H5T_conv_struct
*
@ -163,38 +293,37 @@ H5T_conv_order(hid_t src_id, hid_t dst_id, void **pcdata, size_t nelmts,
*-------------------------------------------------------------------------
*/
herr_t
H5T_conv_struct(hid_t src_id, hid_t dst_id, void **_pcdata, size_t nelmts,
H5T_conv_struct(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts,
void *_buf, void *_bkg)
{
H5T_conv_struct_t **pcdata = (H5T_conv_struct_t **)_pcdata;
uint8 *buf = (uint8 *)_buf; /*cast for pointer arithmetic */
uint8 *bkg = (uint8 *)_bkg; /*background pointer arithmetic */
H5T_t *src = NULL; /*source data type */
H5T_t *dst = NULL; /*destination data type */
H5T_t *type = NULL; /*temporary type pointer */
hid_t tid; /*temporary type ID */
intn *src2dst = NULL; /*maps src member to dst member */
H5T_member_t *src_memb = NULL; /*source struct member descript.*/
H5T_member_t *dst_memb = NULL; /*destination struct memb desc. */
H5T_conv_t tconv_func = NULL; /*member data type conv. func. */
size_t offset; /*byte offset wrt struct */
size_t src_delta, dst_delta; /*source & destination stride */
intn elmtno, i, j; /*counters */
void *memb_cdata = NULL; /*member conversion data */
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);
/* 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");
}
/* Capability query? */
if (!buf) {
if (!buf && H5T_CONV_INIT==nelmts) {
/*
* First, determine if this conversion function applies to the
* conversion path SRC_ID-->DST_ID. If not, return failure;
* otherwise initialize the `priv' field of `cdata' with information
* that remains (almost) constant for this conversion path.
*/
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 (H5T_COMPOUND==src->type);
assert (H5T_COMPOUND==dst->type);
@ -203,84 +332,66 @@ H5T_conv_struct(hid_t src_id, hid_t dst_id, void **_pcdata, size_t nelmts,
* Struct members must be scalar for now.
*/
for (i=0; i<src->u.compnd.nmembs; i++) {
assert (0==src->u.compnd.memb[i].ndims);
if (src->u.compnd.memb[i].ndims>0) {
HRETURN_ERROR (H5E_DATATYPE, H5E_UNSUPPORTED, FAIL,
"array members are not supported yet");
}
}
for (i=0; i<dst->u.compnd.nmembs; i++) {
assert (0==dst->u.compnd.memb[i].ndims);
if (dst->u.compnd.memb[i].ndims>0) {
HRETURN_ERROR (H5E_DATATYPE, H5E_UNSUPPORTED, FAIL,
"array members are not supported yet");
}
}
#endif
/*
* Okay, we've determined that this conversion function applies to
* the data types supplied as arguments. Now we build information
* which is expensive to calculate but is constant for all
* conversions from SRC_ID to DST_ID. Notice: the thing marked with
* `!' really is `dst' and not `src' because we're only interested in
* the members of the source type that are also in the destination
* type.
*/
assert (pcdata);
*pcdata = H5MM_xcalloc (1, sizeof(H5T_conv_struct_t));
src2dst = H5MM_xmalloc (src->u.compnd.nmembs * sizeof(intn));
(*pcdata)->src2dst = src2dst;
(*pcdata)->src_memb_id = H5MM_xmalloc (/*!*/dst->u.compnd.nmembs *
sizeof(hid_t));
(*pcdata)->dst_memb_id = H5MM_xmalloc (dst->u.compnd.nmembs *
sizeof(hid_t));
/*
* Insure that members are sorted.
*/
H5T_sort_by_offset (src);
H5T_sort_by_offset (dst);
/*
* Build a mapping from source member number to destination member
* number. If some source member is not a destination member then that
* mapping element will be negative. Also create atoms for each
* source and destination member data type so we can look up the
* member data type conversion functions later.
*/
for (i=0; i<src->u.compnd.nmembs; i++) {
src2dst[i] = -1;
for (j=0; j<dst->u.compnd.nmembs; j++) {
if (!HDstrcmp (src->u.compnd.memb[i].name,
dst->u.compnd.memb[j].name)) {
src2dst[i] = j;
break;
}
}
if (src2dst[i]>=0) {
type = &(src->u.compnd.memb[i].type);
tid = H5A_register (H5_DATATYPE, type);
assert (tid>=0);
(*pcdata)->src_memb_id[i] = tid;
type = &(dst->u.compnd.memb[src2dst[i]].type);
tid = H5A_register (H5_DATATYPE, type);
assert (tid>=0);
(*pcdata)->dst_memb_id[i] = tid;
}
if (H5T_conv_struct_init (src, dst, cdata)<0) {
HRETURN_ERROR (H5E_DATATYPE, H5E_CANTINIT, FAIL,
"unable to initialize conversion data");
}
HRETURN (SUCCEED);
} else if (!buf && H5T_CONV_FREE==nelmts) {
/*
* Free the private conversion data.
*/
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);
/*
* Here comes the real conversion...
*/
assert (pcdata && *pcdata);
assert ((*pcdata)->src2dst);
assert ((*pcdata)->src_memb_id);
assert ((*pcdata)->dst_memb_id);
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 = (*pcdata)->src2dst;
src2dst = priv->src2dst;
/*
* Direction of conversion.
@ -309,15 +420,10 @@ H5T_conv_struct(hid_t src_id, hid_t dst_id, void **_pcdata, size_t nelmts,
dst_memb = dst->u.compnd.memb + src2dst[i];
if (dst_memb->type.size <= src_memb->type.size) {
tconv_func = H5T_find (&(dst_memb->type), &(src_memb->type),
&memb_cdata);
if (!tconv_func) {
HGOTO_ERROR (H5E_DATATYPE, H5E_UNSUPPORTED, FAIL,
"unable to convert member data type");
}
(tconv_func)((*pcdata)->src_memb_id[i],
(*pcdata)->dst_memb_id[i], &memb_cdata, 1,
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,
@ -343,15 +449,10 @@ H5T_conv_struct(hid_t src_id, hid_t dst_id, void **_pcdata, size_t nelmts,
offset -= dst_memb->type.size;
if (dst_memb->type.size > src_memb->type.size) {
tconv_func = H5T_find (&(src_memb->type), &(dst_memb->type),
&memb_cdata);
if (!tconv_func) {
HGOTO_ERROR (H5E_DATATYPE, H5E_UNSUPPORTED, FAIL,
"unable to convert member data type");
}
(tconv_func)((*pcdata)->src_memb_id[i],
(*pcdata)->dst_memb_id[i], &memb_cdata, 1,
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);
@ -371,7 +472,6 @@ H5T_conv_struct(hid_t src_id, hid_t dst_id, void **_pcdata, size_t nelmts,
HDmemcpy (_buf, _bkg, nelmts*dst->size);
ret_value = SUCCEED;
done:
FUNC_LEAVE (ret_value);
}

View File

@ -78,7 +78,7 @@ typedef struct H5T_path_t {
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 */
void *cdata; /*extra conversion data */
H5T_cdata_t *cdata; /*extra conversion data */
} H5T_path_t;
/* The master list of soft conversion functions */
@ -88,23 +88,16 @@ typedef struct H5T_soft_t {
H5T_conv_t func; /*the conversion function */
} H5T_soft_t;
/* Conversion data for H5T_conv_struct() */
typedef struct H5T_conv_struct_t {
intn *src2dst; /*mapping from src to dst memb ID */
hid_t *src_memb_id; /*source member type ID's */
hid_t *dst_memb_id; /*destination member type ID's */
} H5T_conv_struct_t;
/* Function prototypes for H5T package scope */
H5T_path_t *H5T_path_find (const H5T_t *src, const H5T_t *dst,
hbool_t create);
/* Conversion functions */
herr_t H5T_conv_noop (hid_t src_id, hid_t dst_id, void **pcdata,
herr_t H5T_conv_noop (hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata,
size_t nelmts, void *buf, void *bkg);
herr_t H5T_conv_order (hid_t src_id, hid_t dst_id, void **pcdata,
herr_t H5T_conv_order (hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata,
size_t nelmts, void *_buf, void *bkg);
herr_t H5T_conv_struct (hid_t src_id, hid_t dst_id, void **pcdata,
herr_t H5T_conv_struct (hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata,
size_t nelmts, void *_buf, void *bkg);

View File

@ -40,5 +40,5 @@ herr_t H5T_insert (H5T_t *parent, const char *name, off_t offset,
herr_t H5T_sort_by_offset (H5T_t *dt);
herr_t H5T_pack (H5T_t *dt);
herr_t H5T_debug (H5T_t *dt, FILE * stream);
H5T_conv_t H5T_find (const H5T_t *src, const H5T_t *dst, void **pcdata);
H5T_conv_t H5T_find (const H5T_t *src, const H5T_t *dst, H5T_cdata_t **pcdata);
#endif

View File

@ -23,6 +23,9 @@
#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 */
@ -92,8 +95,22 @@ typedef enum H5T_pad_t {
H5T_NPAD = 3 /*THIS MUST BE LAST */
} H5T_pad_t;
/* How is the `bkg' buffer used by the conversion function? */
typedef enum H5T_bkg_t {
H5T_BKG_NONE = 0, /*background buffer is not needed, send NULL */
H5T_BKG_TEMP = 1, /*bkg buffer used as temp storage only */
H5T_BKG_YES = 2, /*init bkg buf with data before conversion */
} H5T_bkg_t;
/* Type conversion client data */
typedef struct H5T_cdata_t {
H5T_bkg_t need_bkg;/*is the background buffer needed? */
hbool_t recalc; /*recalculate private data */
void *priv; /*private data */
} H5T_cdata_t;
/* All data type conversion functions are... */
typedef herr_t (*H5T_conv_t) (hid_t src_id, hid_t dst_id, void **pcdata,
typedef herr_t (*H5T_conv_t) (hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata,
size_t nelmts, void *buf, void *bkg);
/* The predefined types */
@ -209,7 +226,7 @@ herr_t H5Tset_strpad (hid_t type_id, H5T_str_t strpad);
herr_t H5Tregister_hard (hid_t src_id, hid_t dst_id, H5T_conv_t func);
herr_t H5Tregister_soft (H5T_class_t src, H5T_class_t dst, H5T_conv_t func);
herr_t H5Tunregister (H5T_conv_t func);
H5T_conv_t H5Tfind (hid_t src_id, hid_t dst_id, void **pcdata);
H5T_conv_t H5Tfind (hid_t src_id, hid_t dst_id, H5T_cdata_t **pcdata);
#ifdef __cplusplus
}

View File

@ -50,8 +50,8 @@ typedef struct s5_t {
} s5_t;
#define NX 10
#define NY 200
#define NX 100
#define NY 2000
static hid_t
@ -278,6 +278,7 @@ STEP 5: Read members into a superset which is partially initialized.\n");
/* Read the data */
status = H5Dread (dataset, s5_tid, H5P_ALL, H5P_ALL, H5C_DEFAULT, s5);
assert (status>=0);
/* Check that the data was read properly */
for (i=0; i<NX*NY; i++) {
@ -295,6 +296,46 @@ STEP 5: Read members into a superset which is partially initialized.\n");
assert (s5[i].mid2 == 1002+4*i);
assert (s5[i].post == 1003+4*i);
}
/*
*######################################################################
* STEP 6: Update fields `b' and `d' on the file leaving the other
* fields unchanged. This tests member alignment and background
* buffers.
*/
printf ("\
STEP 6: Update fields `b' and `d' on the file, leaving the other fields\n\
unchanged.\n");
fflush (stdout);
/* Initialize `s4' with new values */
for (i=0; i<NX*NY; i++) {
s4[i].b = 2000+2*i;
s4[i].d = 2001+2*i;
}
/* Write the data to file */
status = H5Dwrite (dataset, s4_tid, H5P_ALL, H5P_ALL, H5C_DEFAULT, s4);
assert (status>=0);
/* Read the data back */
status = H5Dread (dataset, s2_tid, H5P_ALL, H5P_ALL, H5C_DEFAULT, s2);
assert (status>=0);
/* Compare */
for (i=0; i<NX*NY; i++) {
assert (s2[i].a == s1[i].a);
assert (s2[i].b == s4[i].b);
assert (s2[i].c == s1[i].c);
assert (s2[i].d == s4[i].d);
assert (s2[i].e == s1[i].e);
}
/*