mirror of
https://github.com/HDFGroup/hdf5.git
synced 2025-01-18 15:15:56 +08:00
[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:
parent
6cd8818b73
commit
5c6a3af396
32
src/H5D.c
32
src/H5D.c
@ -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
107
src/H5T.c
@ -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
|
||||
*
|
||||
|
302
src/H5Tconv.c
302
src/H5Tconv.c
@ -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);
|
||||
}
|
||||
|
||||
|
15
src/H5Tpkg.h
15
src/H5Tpkg.h
@ -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);
|
||||
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
|
Loading…
Reference in New Issue
Block a user