summaryrefslogtreecommitdiffstats
path: root/src/H5Tconv.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/H5Tconv.c')
-rw-r--r--src/H5Tconv.c95
1 files changed, 63 insertions, 32 deletions
diff --git a/src/H5Tconv.c b/src/H5Tconv.c
index 16fc719..00cde28 100644
--- a/src/H5Tconv.c
+++ b/src/H5Tconv.c
@@ -45,6 +45,9 @@ static int interface_initialize_g = 0;
/* Declare a free list to manage pieces of vlen data */
H5FL_BLK_DEFINE_STATIC(vlen_seq);
+/* Declare a free list to manage pieces of array data */
+H5FL_BLK_DEFINE_STATIC(array_seq);
+
/*
* These macros are for the bodies of functions that convert buffers of one
* integer type to another using hardware. They all start with `H5T_CONV_'
@@ -1175,10 +1178,7 @@ H5T_conv_b_b(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, hsize_t nelmts,
* Purpose: Check whether the source or destination datatypes require a
* background buffer for the conversion.
*
- * Currently, only compound datatypes require a background buffer,
- * but since they can be embedded in variable-length or array datatypes,
- * those types must ask for a background buffer if they have compound
- * components.
+ * Currently, only compound datatypes require a background buffer.
*
* Return: Non-negative on success/Negative on failure
*
@@ -1198,14 +1198,8 @@ H5T_conv_need_bkg (H5T_t *src, H5T_t *dst, H5T_cdata_t *cdata)
assert(dst);
assert(cdata);
- /* Compound datatypes only need a "temp" buffer */
+ /* Compound datatypes need a buffer */
if (H5T_detect_class(src,H5T_COMPOUND)==TRUE || H5T_detect_class(dst,H5T_COMPOUND)==TRUE)
- cdata->need_bkg = H5T_BKG_TEMP;
-
- /* Compound datatypes need a "yes" buffer though */
- if (H5T_detect_class(src,H5T_VLEN)==TRUE || H5T_detect_class(dst,H5T_VLEN)==TRUE)
- cdata->need_bkg = H5T_BKG_YES;
- if (H5T_detect_class(src,H5T_ARRAY)==TRUE || H5T_detect_class(dst,H5T_ARRAY)==TRUE)
cdata->need_bkg = H5T_BKG_YES;
FUNC_LEAVE (SUCCEED);
@@ -2200,7 +2194,7 @@ H5T_conv_enum(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, hsize_t nelmts,
herr_t
H5T_conv_vlen(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, hsize_t nelmts,
size_t buf_stride, size_t bkg_stride, void *_buf,
- void *_bkg, hid_t dset_xfer_plist)
+ void UNUSED *_bkg, hid_t dset_xfer_plist)
{
H5T_path_t *tpath; /* Type conversion path */
hid_t tsrc_id = -1, tdst_id = -1;/*temporary type atoms */
@@ -2208,15 +2202,17 @@ H5T_conv_vlen(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, hsize_t nelmts,
H5T_t *dst = NULL; /*destination data type */
hsize_t olap; /*num overlapping elements */
uint8_t *s, *sp, *d, *dp; /*source and dest traversal ptrs */
- uint8_t **dptr; /*pointer to correct destination pointer*/
+ uint8_t **dptr; /*pointer to correct destination pointer*/
size_t src_delta, dst_delta; /*source & destination stride */
- hssize_t seq_len; /*the number of elements in the current sequence*/
+ hssize_t seq_len; /*the number of elements in the current sequence*/
size_t src_base_size, dst_base_size;/*source & destination base size*/
- size_t src_size, dst_size;/*source & destination total size in bytes*/
+ size_t src_size, dst_size; /*source & destination total size in bytes*/
void *conv_buf=NULL; /*temporary conversion buffer */
- size_t conv_buf_size; /*size of conversion buffer in bytes */
+ hsize_t conv_buf_size=0; /*size of conversion buffer in bytes */
+ void *bkg_buf=NULL; /*temporary background buffer */
+ hsize_t bkg_buf_size=0; /*size of background buffer in bytes */
uint8_t dbuf[64],*dbuf_ptr=dbuf;/*temp destination buffer */
- int direction; /*direction of traversal */
+ int direction; /*direction of traversal */
hsize_t elmtno; /*element number counter */
FUNC_ENTER (H5T_conv_vlen, FAIL);
@@ -2239,8 +2235,8 @@ H5T_conv_vlen(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, hsize_t nelmts,
assert (H5T_VLEN==src->type);
assert (H5T_VLEN==dst->type);
- /* Check if we need a background buffer */
- H5T_conv_need_bkg (src, dst, cdata);
+ /* Variable-length types don't need a background buffer */
+ cdata->need_bkg = H5T_BKG_NO;
break;
@@ -2320,6 +2316,14 @@ H5T_conv_vlen(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, hsize_t nelmts,
}
}
+ /* Check if we need a background buffer for this conversion */
+ if(tpath->cdata.need_bkg) {
+ /* Set up initial background buffer */
+ bkg_buf_size=MAX(src_base_size,dst_base_size);
+ if ((bkg_buf=H5FL_BLK_ALLOC(vlen_seq,bkg_buf_size,0))==NULL)
+ HRETURN_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed for type conversion");
+ } /* end if */
+
for (elmtno=0; elmtno<nelmts; elmtno++) {
s = sp;
d = *dptr;
@@ -2345,10 +2349,19 @@ H5T_conv_vlen(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, hsize_t nelmts,
HRETURN_ERROR(H5E_DATATYPE, H5E_READERROR, FAIL,
"can't read VL data");
+ /* Check if background buffer is large enough, resize if necessary */
+ /* (Chain off the conversion buffer size) */
+ if(tpath->cdata.need_bkg && bkg_buf_size<conv_buf_size) {
+ /* Set up initial background buffer */
+ bkg_buf_size=conv_buf_size;
+ if((bkg_buf=H5FL_BLK_REALLOC(vlen_seq,bkg_buf,bkg_buf_size))==NULL)
+ HRETURN_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed for type conversion");
+ } /* end if */
+
/* Convert VL sequence */
H5_CHECK_OVERFLOW(seq_len,hssize_t,hsize_t);
if (H5T_convert(tpath, tsrc_id, tdst_id, (hsize_t)seq_len, 0, bkg_stride,
- conv_buf, _bkg, dset_xfer_plist)<0)
+ conv_buf, bkg_buf, dset_xfer_plist)<0)
HRETURN_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL,
"datatype conversion failed");
@@ -2376,9 +2389,13 @@ H5T_conv_vlen(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, hsize_t nelmts,
} /* end if */
}
- /* Release the conversion buffer */
+ /* Release the conversion buffer (always allocated) */
H5FL_BLK_FREE(vlen_seq,conv_buf);
+ /* Release the background buffer, if we have one */
+ if(bkg_buf!=NULL)
+ H5FL_BLK_FREE(vlen_seq,bkg_buf);
+
/* Release the temporary datatype IDs used */
if (tsrc_id >= 0)
H5I_dec_ref(tsrc_id);
@@ -2413,17 +2430,19 @@ H5T_conv_vlen(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, hsize_t nelmts,
herr_t
H5T_conv_array(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, hsize_t nelmts,
size_t buf_stride, size_t bkg_stride, void *_buf,
- void *_bkg, hid_t dset_xfer_plist)
+ void UNUSED *_bkg, hid_t dset_xfer_plist)
{
- 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 */
+ 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 */
- int direction; /*direction of traversal */
+ int direction; /*direction of traversal */
hsize_t elmtno; /*element number counter */
- int i; /* local index variable */
+ int i; /* local index variable */
+ void *bkg_buf=NULL; /*temporary background buffer */
+ hsize_t bkg_buf_size=0; /*size of background buffer in bytes */
FUNC_ENTER (H5T_conv_array, FAIL);
@@ -2457,8 +2476,8 @@ H5T_conv_array(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, hsize_t nelmts,
HRETURN_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, "array datatypes do not have the same dimension permutations");
#endif /* LATER */
- /* Check if we need a background buffer */
- H5T_conv_need_bkg (src, dst, cdata);
+ /* Array datatypes don't need a background buffer */
+ cdata->need_bkg = H5T_BKG_NO;
break;
@@ -2509,13 +2528,21 @@ H5T_conv_array(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, hsize_t nelmts,
}
}
+ /* Check if we need a background buffer for this conversion */
+ if(tpath->cdata.need_bkg) {
+ /* Allocate background buffer */
+ bkg_buf_size=src->u.array.nelem*MAX(src->size,dst->size);
+ if ((bkg_buf=H5FL_BLK_ALLOC(array_seq,bkg_buf_size,0))==NULL)
+ HRETURN_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed for type conversion");
+ } /* end if */
+
/* 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, (hsize_t)src->u.array.nelem, 0, bkg_stride, dp, _bkg, dset_xfer_plist)<0)
+ if (H5T_convert(tpath, tsrc_id, tdst_id, (hsize_t)src->u.array.nelem, 0, bkg_stride, dp, bkg_buf, dset_xfer_plist)<0)
HRETURN_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "datatype conversion failed");
/* Advance the source & destination pointers */
@@ -2523,6 +2550,10 @@ H5T_conv_array(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, hsize_t nelmts,
dp += dst_delta;
}
+ /* Release the background buffer, if we have one */
+ if(bkg_buf!=NULL)
+ H5FL_BLK_FREE(array_seq,bkg_buf);
+
/* Release the temporary datatype IDs used */
if (tsrc_id >= 0)
H5I_dec_ref(tsrc_id);