diff options
author | Quincey Koziol <koziol@hdfgroup.org> | 2000-11-09 21:45:27 (GMT) |
---|---|---|
committer | Quincey Koziol <koziol@hdfgroup.org> | 2000-11-09 21:45:27 (GMT) |
commit | e32c78d023348c70255c3835a4f904862414fb0d (patch) | |
tree | bec2363f2d5cd8811522f80114e70efa72d2c196 /src/H5Tconv.c | |
parent | 796b4daf83110a1e61f754eeb0ab7be625b0e98a (diff) | |
download | hdf5-e32c78d023348c70255c3835a4f904862414fb0d.zip hdf5-e32c78d023348c70255c3835a4f904862414fb0d.tar.gz hdf5-e32c78d023348c70255c3835a4f904862414fb0d.tar.bz2 |
[svn-r2843] Purpose:
New Feature
Description:
Added array datatype to library. See documentation at:
http://hdf.ncsa.uiuc.edu/HDF5/planning/DP/ArrayType.html
for complete details on the impact to the library.
Solution:
Changes to the base library include removing the ability of compound
datatype fields to be an array (they can use an array type for the field,
to duplicate the functionality) and adding in the new array datatype
everywhere appropriate. (I hope :-)
Platforms tested:
FreeBSD 4.1.1 (hawkwind)
Diffstat (limited to 'src/H5Tconv.c')
-rw-r--r-- | src/H5Tconv.c | 353 |
1 files changed, 227 insertions, 126 deletions
diff --git a/src/H5Tconv.c b/src/H5Tconv.c index 66fa3e2..4d3c2ba 100644 --- a/src/H5Tconv.c +++ b/src/H5Tconv.c @@ -23,7 +23,6 @@ typedef struct H5T_conv_struct_t { hid_t *src_memb_id; /*source member type ID's */ hid_t *dst_memb_id; /*destination member type ID's */ H5T_path_t **memb_path; /*conversion path for each member */ - size_t *memb_nelmts; /*member element count */ } H5T_conv_struct_t; /* Conversion data for H5T_conv_enum() */ @@ -803,9 +802,7 @@ H5T_conv_struct_init (H5T_t *src, H5T_t *dst, H5T_cdata_t *cdata) NULL==(priv->src_memb_id=H5MM_malloc(src->u.compnd.nmembs * sizeof(hid_t))) || NULL==(priv->dst_memb_id=H5MM_malloc(dst->u.compnd.nmembs * - sizeof(hid_t))) || - NULL==(priv->memb_nelmts=H5MM_malloc(src->u.compnd.nmembs * - sizeof(size_t)))) { + sizeof(hid_t)))) { HRETURN_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed"); } @@ -846,44 +843,6 @@ H5T_conv_struct_init (H5T_t *src, H5T_t *dst, H5T_cdata_t *cdata) priv->dst_memb_id[src2dst[i]] = tid; } } - - /* - * Those members which are in both the source and destination must be - * the same size and shape arrays. - */ - for (i=0; i<src->u.compnd.nmembs; i++) { - if (src2dst[i]>=0) { - H5T_cmemb_t *src_memb = src->u.compnd.memb + i; - H5T_cmemb_t *dst_memb = dst->u.compnd.memb + src2dst[i]; - if (src_memb->ndims != dst_memb->ndims) { - HRETURN_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, - "source and dest members have incompatible " - "size or shape"); - } - for (j=0; j<src_memb->ndims; j++) { - if (src_memb->dim[j] != dst_memb->dim[j]) { - HRETURN_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, - "source and dest members have " - "incompatible size or shape"); - } -#ifndef LATER - /* Their permutation vectors must be equal */ - if (src_memb->perm[j]!=dst_memb->perm[j]) { - HRETURN_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, - "member permutations must be equal"); - } -#endif - } - } - } - - /* Calculate number of elements of each member */ - for (i=0; i<src->u.compnd.nmembs; i++) { - priv->memb_nelmts[i] = 1; - for (j=0; j<src->u.compnd.memb[i].ndims; j++) { - priv->memb_nelmts[i] *= src->u.compnd.memb[i].dim[j]; - } - } } /* @@ -908,7 +867,6 @@ H5T_conv_struct_init (H5T_t *src, H5T_t *dst, H5T_cdata_t *cdata) H5MM_xfree(priv->src_memb_id); H5MM_xfree(priv->dst_memb_id); H5MM_xfree(priv->memb_path); - H5MM_xfree(priv->memb_nelmts); cdata->priv = priv = H5MM_xfree (priv); HRETURN_ERROR (H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, "unable to convert member data type"); @@ -1013,7 +971,6 @@ H5T_conv_struct(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, H5MM_xfree(priv->src_memb_id); H5MM_xfree(priv->dst_memb_id); H5MM_xfree(priv->memb_path); - H5MM_xfree(priv->memb_nelmts); cdata->priv = priv = H5MM_xfree (priv); break; @@ -1078,8 +1035,7 @@ H5T_conv_struct(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, if (H5T_convert(priv->memb_path[i], priv->src_memb_id[i], priv->dst_memb_id[src2dst[i]], - priv->memb_nelmts[i], - 0, 0, /*no striding (packed array)*/ + 1, 0, 0, /*no striding (packed array)*/ xbuf+src_memb->offset, xbkg+dst_memb->offset, dset_xfer_plist)<0) { @@ -1114,8 +1070,7 @@ H5T_conv_struct(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, if (H5T_convert(priv->memb_path[i], priv->src_memb_id[i], priv->dst_memb_id[src2dst[i]], - priv->memb_nelmts[i], - 0, 0, /*no striding (packed array)*/ + 1, 0, 0, /*no striding (packed array)*/ xbuf+offset, xbkg+dst_memb->offset, dset_xfer_plist)<0) { HRETURN_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, @@ -1224,11 +1179,9 @@ H5T_conv_struct_opt(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, intn *src2dst = NULL; /*maps src member to dst member */ H5T_cmemb_t *src_memb = NULL; /*source struct member descript.*/ H5T_cmemb_t *dst_memb = NULL; /*destination struct memb desc. */ - size_t src_memb_size; /*sizeof single source member */ - size_t dst_memb_size; /*sizeof single destination memb*/ size_t offset; /*byte offset wrt struct */ uintn elmtno; /*element counter */ - intn i, j; /*counters */ + intn i; /*counters */ H5T_conv_struct_t *priv = NULL; /*private data */ FUNC_ENTER (H5T_conv_struct_opt, FAIL); @@ -1270,41 +1223,31 @@ H5T_conv_struct_opt(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, */ if (dst->size > src->size) { 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]; - src_memb_size = src_memb->size / priv->memb_nelmts[i]; - dst_memb_size = dst_memb->size / priv->memb_nelmts[i]; - for (j=0; j<(intn)(priv->memb_nelmts[i]); j++) { - if (dst_memb_size > src_memb_size) - offset += src_memb_size; - } + if (src2dst[i]<0) + continue; + src_memb = src->u.compnd.memb + i; + dst_memb = dst->u.compnd.memb + src2dst[i]; + if (dst_memb->size > src_memb->size) + offset += src_memb->size; } 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]; - src_memb_size = src_memb->size / priv->memb_nelmts[i]; - dst_memb_size = dst_memb->size / priv->memb_nelmts[i]; - - for (j=(intn)(priv->memb_nelmts[i]-1); j>=0; --j) { - if (dst_memb_size > src_memb_size) { - offset -= src_memb_size; - if (dst_memb_size > src->size-offset) { - H5MM_xfree(priv->src2dst); - H5MM_xfree(priv->src_memb_id); - H5MM_xfree(priv->dst_memb_id); - H5MM_xfree(priv->memb_path); - H5MM_xfree(priv->memb_nelmts); - cdata->priv = priv = H5MM_xfree (priv); - HRETURN_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, - "convertion is unsupported by this " - "function"); - } - } - } + if (src2dst[i]<0) + continue; + src_memb = src->u.compnd.memb + i; + dst_memb = dst->u.compnd.memb + src2dst[i]; + if (dst_memb->size > src_memb->size) { + offset -= src_memb->size; + if (dst_memb->size > src->size-offset) { + H5MM_xfree(priv->src2dst); + H5MM_xfree(priv->src_memb_id); + H5MM_xfree(priv->dst_memb_id); + H5MM_xfree(priv->memb_path); + cdata->priv = priv = H5MM_xfree (priv); + HRETURN_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, + "convertion is unsupported by this " + "function"); + } + } } } break; @@ -1318,7 +1261,6 @@ H5T_conv_struct_opt(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, H5MM_xfree(priv->src_memb_id); H5MM_xfree(priv->dst_memb_id); H5MM_xfree(priv->memb_path); - H5MM_xfree(priv->memb_nelmts); cdata->priv = priv = H5MM_xfree (priv); break; @@ -1372,38 +1314,33 @@ H5T_conv_struct_opt(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, if (src2dst[i]<0) continue; /*subsetting*/ src_memb = src->u.compnd.memb + i; dst_memb = dst->u.compnd.memb + src2dst[i]; - src_memb_size = src_memb->size / priv->memb_nelmts[i]; - dst_memb_size = dst_memb->size / priv->memb_nelmts[i]; - for (j=0; j<(intn)(priv->memb_nelmts[i]); j++) { - if (dst_memb_size <= src_memb_size) { - xbuf = buf + src_memb->offset + j*src_memb_size; - xbkg = bkg + dst_memb->offset + j*dst_memb_size; - if (H5T_convert(priv->memb_path[i], - priv->src_memb_id[i], - priv->dst_memb_id[src2dst[i]], nelmts, - buf_stride?buf_stride:src->size, - bkg_stride, xbuf, xbkg, - dset_xfer_plist)<0) { - HRETURN_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, - "unable to convert compound data " - "type member"); - } - for (elmtno=0; elmtno<nelmts; elmtno++) { - HDmemmove(xbkg, xbuf, dst_memb_size); - xbuf += buf_stride ? buf_stride : src->size; - xbkg += bkg_stride; - } - } else { - for (xbuf=buf, elmtno=0; elmtno<nelmts; elmtno++) { - HDmemmove(xbuf+offset, - xbuf+src_memb->offset+j*src_memb_size, - src_memb_size); - xbuf += buf_stride ? buf_stride : src->size; - } - offset += src_memb_size; - } - } + if (dst_memb->size <= src_memb->size) { + xbuf = buf + src_memb->offset; + xbkg = bkg + dst_memb->offset; + if (H5T_convert(priv->memb_path[i], + priv->src_memb_id[i], + priv->dst_memb_id[src2dst[i]], nelmts, + buf_stride ? buf_stride : src->size, + bkg_stride, xbuf, xbkg, + dset_xfer_plist)<0) { + HRETURN_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, + "unable to convert compound data " + "type member"); + } + for (elmtno=0; elmtno<nelmts; elmtno++) { + HDmemmove(xbkg, xbuf, dst_memb->size); + xbuf += buf_stride ? buf_stride : src->size; + xbkg += bkg_stride; + } + } else { + for (xbuf=buf, elmtno=0; elmtno<nelmts; elmtno++) { + HDmemmove(xbuf+offset, xbuf+src_memb->offset, + src_memb->size); + xbuf += buf_stride ? buf_stride : src->size; + } + offset += src_memb->size; + } } /* @@ -1414,21 +1351,18 @@ H5T_conv_struct_opt(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, */ for (i=src->u.compnd.nmembs-1; i>=0; --i) { if (src2dst[i]<0) - continue; + continue; src_memb = src->u.compnd.memb + i; dst_memb = dst->u.compnd.memb + src2dst[i]; - src_memb_size = src_memb->size / priv->memb_nelmts[i]; - dst_memb_size = dst_memb->size / priv->memb_nelmts[i]; - for (j=(intn)(priv->memb_nelmts[i]-1); j>=0; --j) { - if (dst_memb_size > src_memb_size) { - offset -= src_memb_size; + if (dst_memb->size > src_memb->size) { + offset -= src_memb->size; xbuf = buf + offset; - xbkg = bkg + dst_memb->offset + j*dst_memb_size; + xbkg = bkg + dst_memb->offset; if (H5T_convert(priv->memb_path[i], priv->src_memb_id[i], priv->dst_memb_id[src2dst[i]], nelmts, - buf_stride?buf_stride:src->size, + buf_stride ? buf_stride : src->size, bkg_stride, xbuf, xbkg, dset_xfer_plist)<0) { HRETURN_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, @@ -1436,11 +1370,10 @@ H5T_conv_struct_opt(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, "member"); } for (elmtno=0; elmtno<nelmts; elmtno++) { - HDmemmove(xbkg, xbuf, dst_memb_size); + HDmemmove(xbkg, xbuf, dst_memb->size); xbuf += buf_stride ? buf_stride : src->size; xbkg += bkg_stride; } - } } } @@ -2027,6 +1960,174 @@ H5T_conv_vlen(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, /*------------------------------------------------------------------------- + * Function: H5T_conv_array + * + * Purpose: Converts between array data types in memory and on disk. + * This is a soft conversion function. + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Quincey Koziol + * Monday, November 6, 2000 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +herr_t +H5T_conv_array(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, + size_t buf_stride, size_t UNUSED bkg_stride, void *_buf, + void UNUSED *_bkg, hid_t dset_xfer_plist) +{ + const H5D_xfer_t *xfer_parms = NULL; + H5T_path_t *tpath; /* Type conversion path */ + hid_t tsrc_id = -1, tdst_id = -1;/*temporary type atoms */ + H5T_t *src = NULL; /*source data type */ + H5T_t *dst = NULL; /*destination data type */ + uint8_t *sp, *dp; /*source and dest traversal ptrs */ + size_t src_delta, dst_delta; /*source & destination stride */ + intn direction; /*direction of traversal */ + uintn elmtno; /*element number counter */ + intn i; /* local index variable */ + + FUNC_ENTER (H5T_conv_array, FAIL); + + 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; + * otherwise initialize the `priv' field of `cdata' with + * information that remains (almost) constant for this + * conversion path. + */ + if (H5I_DATATYPE != H5I_get_type(src_id) || + NULL == (src = H5I_object(src_id)) || + H5I_DATATYPE != H5I_get_type(dst_id) || + NULL == (dst = H5I_object(dst_id))) { + HRETURN_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data type"); + } + assert (H5T_ARRAY==src->type); + assert (H5T_ARRAY==dst->type); + + /* Check the number and sizes of the dimensions */ + if(src->u.array.ndims!=dst->u.array.ndims) + HRETURN_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, "array datatypes do not have the same number of dimensions"); + for(i=0; i<src->u.array.ndims; i++) + if(src->u.array.dim[i]!=dst->u.array.dim[i]) + HRETURN_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, "array datatypes do not have the same sizes of dimensions"); +#ifdef LATER + for(i=0; i<src->u.array.ndims; i++) + if(src->u.array.perm[i]!=dst->u.array.perm[i]) + HRETURN_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, "array datatypes do not have the same dimension permutations"); +#endif /* LATER */ + +#ifdef LATER + /* QAK - Set up conversion function? */ + if (H5T_conv_array_init (src, dst, cdata)<0) { + HRETURN_ERROR (H5E_DATATYPE, H5E_CANTINIT, FAIL, + "unable to initialize conversion data"); + } +#endif /* LATER */ + break; + + case H5T_CONV_FREE: + /* QAK - Nothing to do currently */ + break; + + case H5T_CONV_CONV: + /* + * Conversion. + */ + if (H5I_DATATYPE != H5I_get_type(src_id) || + NULL == (src = H5I_object(src_id)) || + H5I_DATATYPE != H5I_get_type(dst_id) || + NULL == (dst = H5I_object(dst_id))) { + HRETURN_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data type"); + } + + /* Get the dataset transfer property list */ + if (H5P_DEFAULT == dset_xfer_plist) { + xfer_parms = &H5D_xfer_dflt; + } else if (H5P_DATA_XFER != H5P_get_class(dset_xfer_plist) || + NULL == (xfer_parms = H5I_object(dset_xfer_plist))) { + HRETURN_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not xfer parms"); + } + + /* + * Do we process the values from beginning to end or vice + * versa? Also, how many of the elements have the source and + * destination areas overlapping? + */ + if (src->size>=dst->size || buf_stride>0) { + sp = dp = (uint8_t*)_buf; + direction = 1; + } else { + sp = (uint8_t*)_buf + (nelmts-1) * + (buf_stride ? buf_stride : src->size); + dp = (uint8_t*)_buf + (nelmts-1) * + (buf_stride ? buf_stride : dst->size); + direction = -1; + } + + /* + * Direction & size of buffer traversal. + */ + src_delta = direction * (buf_stride ? buf_stride : src->size); + dst_delta = direction * (buf_stride ? buf_stride : dst->size); + + /* Set up conversion path for base elements */ + tpath = H5T_path_find(src->parent, dst->parent, NULL, NULL); + if (NULL==(tpath=H5T_path_find(src->parent, dst->parent, + NULL, NULL))) { + HRETURN_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, + "unable to convert between src and dest " + "datatypes"); + } else if (!H5T_IS_NOOP(tpath)) { + if ((tsrc_id = H5I_register(H5I_DATATYPE, + H5T_copy(src->parent, + H5T_COPY_ALL)))<0 || + (tdst_id = H5I_register(H5I_DATATYPE, + H5T_copy(dst->parent, + H5T_COPY_ALL)))<0) { + HRETURN_ERROR(H5E_DATASET, H5E_CANTREGISTER, FAIL, + "unable to register types for conversion"); + } + } + + /* Perform the actual conversion */ + for (elmtno=0; elmtno<nelmts; elmtno++) { + /* Copy the source array into the correct location for the destination */ + HDmemmove(dp, sp, src->size); + + /* Convert array */ + if (H5T_convert(tpath, tsrc_id, tdst_id, src->u.array.nelem, 0, 0, + dp, NULL, dset_xfer_plist)<0) + HRETURN_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, + "datatype conversion failed"); + + /* Advance the source & destination pointers */ + sp += src_delta; + dp += dst_delta; + } + + /* Release the temporary datatype IDs used */ + if (tsrc_id >= 0) + H5I_dec_ref(tsrc_id); + if (tdst_id >= 0) + H5I_dec_ref(tdst_id); + break; + + default: /* Some other command we don't know about yet.*/ + HRETURN_ERROR (H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, + "unknown conversion command"); + } /* end switch */ + + FUNC_LEAVE (SUCCEED); +} /* end H5T_conv_array() */ + + +/*------------------------------------------------------------------------- * Function: H5T_conv_i_i * * Purpose: Convert one integer type to another. This is the catch-all |