summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNeil Fortner <nfortne2@hdfgroup.org>2009-10-02 20:40:01 (GMT)
committerNeil Fortner <nfortne2@hdfgroup.org>2009-10-02 20:40:01 (GMT)
commiteed2ea424b233c451c81569aa2df48c99bc8c79e (patch)
treea555761e54042fe829b05539874d081fc4fa76d8
parentc53e577d1485c4d3e1985c3b7fb38a67fa42ec3f (diff)
downloadhdf5-eed2ea424b233c451c81569aa2df48c99bc8c79e.zip
hdf5-eed2ea424b233c451c81569aa2df48c99bc8c79e.tar.gz
hdf5-eed2ea424b233c451c81569aa2df48c99bc8c79e.tar.bz2
[svn-r17585] Purpose: Fix bug 1597
Description: When copying a dataset using a vlen inside a compound, the various dataset copying callbacks would allocate a background buffer but would not use it when converting from disk to memory, only memory to disk. This caused an assertion failure as compounds always need a background buffer. These callbacks have been modified to use the background buffer for both conversions. Tested: jam, linew, smirom (h5committest)
-rw-r--r--release_docs/RELEASE.txt2
-rw-r--r--src/H5Dchunk.c2
-rw-r--r--src/H5Dcompact.c12
-rw-r--r--src/H5Dcontig.c2
-rw-r--r--src/H5Tconv.c85
-rwxr-xr-xtest/objcopy.c521
6 files changed, 571 insertions, 53 deletions
diff --git a/release_docs/RELEASE.txt b/release_docs/RELEASE.txt
index 39b7641..e7185a8 100644
--- a/release_docs/RELEASE.txt
+++ b/release_docs/RELEASE.txt
@@ -191,6 +191,8 @@ Bug Fixes since HDF5-1.8.0 release
Library
-------
+ - Fixed an assertion failure that occurred when H5Ocopy was called on a
+ dataset using a vlen inside a compound. (NAF - 2009/10/02 - 1597)
- Fixed incorrect return value for H5Pget_filter_by_id1/2 in H5Ppublic.h.
(NAF - 2009/09/25 - 1620)
- Fixed a bug where properties weren't being compared with the registered
diff --git a/src/H5Dchunk.c b/src/H5Dchunk.c
index 62a3941..8788d86 100644
--- a/src/H5Dchunk.c
+++ b/src/H5Dchunk.c
@@ -4210,7 +4210,7 @@ H5D_chunk_copy_cb(const H5D_chunk_rec_t *chunk_rec, void *_udata)
/* Convert from source file to memory */
H5_CHECK_OVERFLOW(udata->nelmts, uint32_t, size_t);
- if(H5T_convert(tpath_src_mem, tid_src, tid_mem, (size_t)udata->nelmts, (size_t)0, (size_t)0, buf, NULL, udata->idx_info_dst->dxpl_id) < 0)
+ if(H5T_convert(tpath_src_mem, tid_src, tid_mem, (size_t)udata->nelmts, (size_t)0, (size_t)0, buf, bkg, udata->idx_info_dst->dxpl_id) < 0)
HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, H5_ITER_ERROR, "datatype conversion failed")
/* Copy into another buffer, to reclaim memory later */
diff --git a/src/H5Dcompact.c b/src/H5Dcompact.c
index b52bd2c..33b92de 100644
--- a/src/H5Dcompact.c
+++ b/src/H5Dcompact.c
@@ -484,15 +484,19 @@ H5D_compact_copy(H5F_t *f_src, H5O_storage_compact_t *storage_src, H5F_t *f_dst,
HDmemcpy(buf, storage_src->buf, storage_src->size);
+ /* allocate temporary bkg buff for data conversion */
+ if(NULL == (bkg = H5FL_BLK_MALLOC(type_conv, buf_size)))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed")
+
/* Convert from source file to memory */
- if(H5T_convert(tpath_src_mem, tid_src, tid_mem, nelmts, (size_t)0, (size_t)0, buf, NULL, dxpl_id) < 0)
+ if(H5T_convert(tpath_src_mem, tid_src, tid_mem, nelmts, (size_t)0, (size_t)0, buf, bkg, dxpl_id) < 0)
HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "datatype conversion failed")
+ /* Copy into another buffer, to reclaim memory later */
HDmemcpy(reclaim_buf, buf, buf_size);
- /* allocate temporary bkg buff for data conversion */
- if(NULL == (bkg = H5FL_BLK_CALLOC(type_conv, buf_size)))
- HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed")
+ /* Set background buffer to all zeros */
+ HDmemset(bkg, 0, buf_size);
/* Convert from memory to destination file */
if(H5T_convert(tpath_mem_dst, tid_mem, tid_dst, nelmts, (size_t)0, (size_t)0, buf, bkg, dxpl_id) < 0)
diff --git a/src/H5Dcontig.c b/src/H5Dcontig.c
index 0ff3964..3e88be6 100644
--- a/src/H5Dcontig.c
+++ b/src/H5Dcontig.c
@@ -1396,7 +1396,7 @@ H5D_contig_copy(H5F_t *f_src, const H5O_storage_contig_t *storage_src,
/* Perform datatype conversion, if necessary */
if(is_vlen) {
/* Convert from source file to memory */
- if(H5T_convert(tpath_src_mem, tid_src, tid_mem, nelmts, (size_t)0, (size_t)0, buf, NULL, dxpl_id) < 0)
+ if(H5T_convert(tpath_src_mem, tid_src, tid_mem, nelmts, (size_t)0, (size_t)0, buf, bkg, dxpl_id) < 0)
HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "datatype conversion failed")
/* Copy into another buffer, to reclaim memory later */
diff --git a/src/H5Tconv.c b/src/H5Tconv.c
index 08e7fa1..ab9e703 100644
--- a/src/H5Tconv.c
+++ b/src/H5Tconv.c
@@ -1935,51 +1935,48 @@ H5T_conv_struct_init(H5T_t *src, H5T_t *dst, H5T_cdata_t *cdata, hid_t dxpl_id)
} /* end if */
} /* end for */
- /* Check if we need a background buffer */
- if(H5T_detect_class(src, H5T_COMPOUND) == TRUE || H5T_detect_class(dst, H5T_COMPOUND) == TRUE) {
- cdata->need_bkg = H5T_BKG_YES;
-
- if(src_nmembs < dst_nmembs) {
- priv->subset_info.subset = H5T_SUBSET_SRC;
- for(i = 0; i < src_nmembs; i++) {
- /* If any of source members doesn't have counterpart in the same
- * order or there's conversion between members, don't do the
- * optimization.
- */
- if(src2dst[i] != i || (src->shared->u.compnd.memb[i].offset != dst->shared->u.compnd.memb[i].offset) || (priv->memb_path[i])->is_noop == FALSE) {
- priv->subset_info.subset = H5T_SUBSET_FALSE;
- break;
- } /* end if */
- } /* end for */
- /* Compute the size of the data to be copied for each element. It
- * may be smaller than either src or dst if there is extra space at
- * the end of src.
- */
- if(priv->subset_info.subset == H5T_SUBSET_SRC)
- priv->subset_info.copy_size = src->shared->u.compnd.memb[src_nmembs-1].offset
- + src->shared->u.compnd.memb[src_nmembs-1].size;
- } else if(dst_nmembs < src_nmembs) {
- priv->subset_info.subset = H5T_SUBSET_DST;
- for(i = 0; i < dst_nmembs; i++) {
- /* If any of source members doesn't have counterpart in the same order or
- * there's conversion between members, don't do the optimization. */
- if(src2dst[i] != i || (src->shared->u.compnd.memb[i].offset != dst->shared->u.compnd.memb[i].offset) || (priv->memb_path[i])->is_noop == FALSE) {
- priv->subset_info.subset = H5T_SUBSET_FALSE;
- break;
- }
- } /* end for */
- /* Compute the size of the data to be copied for each element. It
- * may be smaller than either src or dst if there is extra space at
- * the end of dst.
- */
- if(priv->subset_info.subset == H5T_SUBSET_DST)
- priv->subset_info.copy_size = dst->shared->u.compnd.memb[dst_nmembs-1].offset
- + dst->shared->u.compnd.memb[dst_nmembs-1].size;
- } else /* If the numbers of source and dest members are equal and no conversion is needed,
- * the case should have been handled as noop earlier in H5Dio.c. */
- ;
+ /* The compound conversion functions need a background buffer */
+ cdata->need_bkg = H5T_BKG_YES;
- } /* end if */
+ if(src_nmembs < dst_nmembs) {
+ priv->subset_info.subset = H5T_SUBSET_SRC;
+ for(i = 0; i < src_nmembs; i++) {
+ /* If any of source members doesn't have counterpart in the same
+ * order or there's conversion between members, don't do the
+ * optimization.
+ */
+ if(src2dst[i] != i || (src->shared->u.compnd.memb[i].offset != dst->shared->u.compnd.memb[i].offset) || (priv->memb_path[i])->is_noop == FALSE) {
+ priv->subset_info.subset = H5T_SUBSET_FALSE;
+ break;
+ } /* end if */
+ } /* end for */
+ /* Compute the size of the data to be copied for each element. It
+ * may be smaller than either src or dst if there is extra space at
+ * the end of src.
+ */
+ if(priv->subset_info.subset == H5T_SUBSET_SRC)
+ priv->subset_info.copy_size = src->shared->u.compnd.memb[src_nmembs-1].offset
+ + src->shared->u.compnd.memb[src_nmembs-1].size;
+ } else if(dst_nmembs < src_nmembs) {
+ priv->subset_info.subset = H5T_SUBSET_DST;
+ for(i = 0; i < dst_nmembs; i++) {
+ /* If any of source members doesn't have counterpart in the same order or
+ * there's conversion between members, don't do the optimization. */
+ if(src2dst[i] != i || (src->shared->u.compnd.memb[i].offset != dst->shared->u.compnd.memb[i].offset) || (priv->memb_path[i])->is_noop == FALSE) {
+ priv->subset_info.subset = H5T_SUBSET_FALSE;
+ break;
+ }
+ } /* end for */
+ /* Compute the size of the data to be copied for each element. It
+ * may be smaller than either src or dst if there is extra space at
+ * the end of dst.
+ */
+ if(priv->subset_info.subset == H5T_SUBSET_DST)
+ priv->subset_info.copy_size = dst->shared->u.compnd.memb[dst_nmembs-1].offset
+ + dst->shared->u.compnd.memb[dst_nmembs-1].size;
+ } else /* If the numbers of source and dest members are equal and no conversion is needed,
+ * the case should have been handled as noop earlier in H5Dio.c. */
+ ;
cdata->recalc = FALSE;
diff --git a/test/objcopy.c b/test/objcopy.c
index 4bd4662..50dabcc 100755
--- a/test/objcopy.c
+++ b/test/objcopy.c
@@ -82,6 +82,7 @@ const char *FILENAME[] = {
#define NAME_DATASET_MULTI_OHDR2 "dataset_multi_ohdr2"
#define NAME_DATASET_VL "dataset_vl"
#define NAME_DATASET_VL_VL "dataset_vl_vl"
+#define NAME_DATASET_CMPD_VL "dataset_cmpd_vl"
#define NAME_DATASET_SUB_SUB "/g0/g00/g000/dataset_simple"
#define NAME_GROUP_UNCOPIED "/uncopied"
#define NAME_GROUP_EMPTY "/empty"
@@ -842,8 +843,82 @@ compare_data(hid_t parent1, hid_t parent2, hid_t pid, hid_t tid, size_t nelmts,
/* Check size of each element */
if((elmt_size = H5Tget_size(tid)) == 0) TEST_ERROR
- /* Check for vlen datatype */
- if(H5Tdetect_class(tid, H5T_VLEN) == TRUE) {
+ /* If the type is a compound containing a vlen, loop over all elements for
+ * each compound member. Compounds containing reference are not supported
+ * yet. */
+ if((H5Tget_class(tid) == H5T_COMPOUND)
+ && (H5Tdetect_class(tid, H5T_VLEN) == TRUE)) {
+ hid_t memb_id; /* Member id */
+ const uint8_t *memb1; /* Pointer to current member */
+ const uint8_t *memb2; /* Pointer to current member */
+ int nmembs; /* Number of members */
+ size_t memb_off; /* Member offset */
+ size_t memb_size; /* Member size */
+ unsigned memb_idx; /* Member index */
+ size_t elmt; /* Current element */
+
+ /* Get number of members in compound */
+ if((nmembs = H5Tget_nmembers(tid)) < 0) TEST_ERROR
+
+ /* Loop over members */
+ for(memb_idx=0; memb_idx<(unsigned)nmembs; memb_idx++) {
+ /* Get member offset. Note that we cannot check for an error here.
+ */
+ memb_off = H5Tget_member_offset(tid, memb_idx);
+
+ /* Get member id */
+ if((memb_id = H5Tget_member_type(tid, memb_idx)) < 0) TEST_ERROR
+
+ /* Get member size */
+ if((memb_size = H5Tget_size(memb_id)) == 0) TEST_ERROR
+
+ /* Set up pointers to member in the first element */
+ memb1 = (const uint8_t *)buf1 + memb_off;
+ memb2 = (const uint8_t *)buf2 + memb_off;
+
+ /* Check if this member contains (or is) a vlen */
+ if(H5Tget_class(memb_id) == H5T_VLEN) {
+ hid_t base_id; /* vlen base type id */
+
+ /* Get base type of vlen datatype */
+ if((base_id = H5Tget_super(memb_id)) < 0) TEST_ERROR
+
+ /* Iterate over all elements, recursively calling this function
+ * for each */
+ for(elmt=0; elmt<nelmts; elmt++) {
+ /* Check vlen lengths */
+ if(((const hvl_t *)memb1)->len
+ != ((const hvl_t *)memb2)->len)
+ TEST_ERROR
+
+ /* Check vlen data */
+ if(!compare_data(parent1, parent2, pid, base_id,
+ ((const hvl_t *)memb1)->len,
+ ((const hvl_t *)memb1)->p,
+ ((const hvl_t *)memb2)->p, obj_owner))
+ TEST_ERROR
+
+ /* Update member pointers */
+ memb1 += elmt_size;
+ memb2 += elmt_size;
+ } /* end for */
+ } else {
+ /* vlens cannot currently be nested below the top layer of a
+ * compound */
+ HDassert(H5Tdetect_class(memb_id, H5T_VLEN) == FALSE);
+
+ /* Iterate over all elements, calling memcmp() for each */
+ for(elmt=0; elmt<nelmts; elmt++) {
+ if(HDmemcmp(memb1, memb2, memb_size))
+ TEST_ERROR
+
+ /* Update member pointers */
+ memb1 += elmt_size;
+ memb2 += elmt_size;
+ } /* end for */
+ } /* end else */
+ } /* end for */
+ } else if(H5Tdetect_class(tid, H5T_VLEN) == TRUE) {
const hvl_t *vl_buf1, *vl_buf2; /* Aliases for buffers to compare */
hid_t base_tid; /* Base type of vlen datatype */
size_t u; /* Local index variable */
@@ -870,7 +945,7 @@ compare_data(hid_t parent1, hid_t parent2, hid_t pid, hid_t tid, size_t nelmts,
else if(H5Tdetect_class(tid, H5T_REFERENCE) == TRUE) {
size_t u; /* Local index variable */
- /* Check for "simple" vlen datatype */
+ /* Check for "simple" reference datatype */
if(H5Tget_class(tid) != H5T_REFERENCE) TEST_ERROR
/* Check for object or region reference */
@@ -7144,6 +7219,443 @@ error:
return 1;
} /* end test_copy_dataset_compressed_vl_vl */
+/*
+ * Common data structure for the copy_dataset_*_cmpd_vl tests.
+ */
+typedef struct cmpd_vl_t {
+ int a;
+ hvl_t b;
+ double c;
+} cmpd_vl_t;
+
+
+/*-------------------------------------------------------------------------
+ * Function: test_copy_dataset_contig_cmpd_vl
+ *
+ * Purpose: Create a contiguous dataset w/VLEN datatype contained in
+ * a compound in SRC file and copy it to DST file
+ *
+ * Return: Success: 0
+ * Failure: number of errors
+ *
+ * Programmer: Neil Fortner
+ * Tuseday, September 29, 2009
+ *
+ *-------------------------------------------------------------------------
+ */
+static int
+test_copy_dataset_contig_cmpd_vl(hid_t fcpl_src, hid_t fcpl_dst, hid_t fapl)
+{
+ hid_t fid_src = -1, fid_dst = -1; /* File IDs */
+ hid_t tid = -1, tid2; /* Datatype IDs */
+ hid_t sid = -1; /* Dataspace ID */
+ hid_t did = -1, did2 = -1; /* Dataset IDs */
+ unsigned int i, j; /* Local index variables */
+ hsize_t dim1d[1]; /* Dataset dimensions */
+ cmpd_vl_t buf[DIM_SIZE_1]; /* Buffer for writing data */
+ char src_filename[NAME_BUF_SIZE];
+ char dst_filename[NAME_BUF_SIZE];
+
+ TESTING("H5Ocopy(): contiguous dataset with compound VLEN datatype");
+
+ /* set initial data values */
+ for(i = 0; i < DIM_SIZE_1; i++) {
+ buf[i].a = i * (i - 1);
+ buf[i].b.len = i+1;
+ buf[i].b.p = (int *)HDmalloc(buf[i].b.len * sizeof(int));
+ for(j = 0; j < buf[i].b.len; j++)
+ ((int *)buf[i].b.p)[j] = (int)(i * 10 + j);
+ buf[i].c = 1. / (i + 1.);
+ } /* end for */
+
+ /* Initialize the filenames */
+ h5_fixname(FILENAME[0], fapl, src_filename, sizeof src_filename);
+ h5_fixname(FILENAME[1], fapl, dst_filename, sizeof dst_filename);
+
+ /* Reset file address checking info */
+ addr_reset();
+
+ /* create source file */
+ if((fid_src = H5Fcreate(src_filename, H5F_ACC_TRUNC, fcpl_src, fapl)) < 0) TEST_ERROR
+
+ /* Set dataspace dimensions */
+ dim1d[0]=DIM_SIZE_1;
+
+ /* create dataspace */
+ if((sid = H5Screate_simple(1, dim1d, NULL)) < 0) TEST_ERROR
+
+ /* create datatype */
+ if((tid2 = H5Tvlen_create(H5T_NATIVE_INT)) < 0) TEST_ERROR
+ if((tid = H5Tcreate(H5T_COMPOUND, sizeof(cmpd_vl_t))) < 0) TEST_ERROR
+ if(H5Tinsert(tid, "a", HOFFSET(cmpd_vl_t, a), H5T_NATIVE_INT) < 0) TEST_ERROR
+ if(H5Tinsert(tid, "b", HOFFSET(cmpd_vl_t, b), tid2) < 0) TEST_ERROR
+ if(H5Tinsert(tid, "c", HOFFSET(cmpd_vl_t, c), H5T_NATIVE_DOUBLE) < 0) TEST_ERROR
+
+ /* create dataset at SRC file */
+ if((did = H5Dcreate2(fid_src, NAME_DATASET_CMPD_VL, tid, sid, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR
+
+ /* write data into file */
+ if(H5Dwrite(did, tid, H5S_ALL, H5S_ALL, H5P_DEFAULT, buf) < 0) TEST_ERROR
+
+ /* close the dataset */
+ if(H5Dclose(did) < 0) TEST_ERROR
+
+ /* close the SRC file */
+ if(H5Fclose(fid_src) < 0) TEST_ERROR
+
+
+ /* open the source file with read-only */
+ if((fid_src = H5Fopen(src_filename, H5F_ACC_RDONLY, fapl)) < 0) TEST_ERROR
+
+ /* create destination file */
+ if((fid_dst = H5Fcreate(dst_filename, H5F_ACC_TRUNC, fcpl_dst, fapl)) < 0) TEST_ERROR
+
+ /* Create an uncopied object in destination file so that addresses in source and destination files aren't the same */
+ if(H5Gclose(H5Gcreate2(fid_dst, NAME_GROUP_UNCOPIED, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR
+
+ /* copy the dataset from SRC to DST */
+ if(H5Ocopy(fid_src, NAME_DATASET_CMPD_VL, fid_dst, NAME_DATASET_CMPD_VL, H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR
+
+ /* open the dataset for copy */
+ if((did = H5Dopen2(fid_src, NAME_DATASET_CMPD_VL, H5P_DEFAULT)) < 0) TEST_ERROR
+
+ /* open the destination dataset */
+ if((did2 = H5Dopen2(fid_dst, NAME_DATASET_CMPD_VL, H5P_DEFAULT)) < 0) TEST_ERROR
+
+ /* Check if the datasets are equal */
+ if(compare_datasets(did, did2, H5P_DEFAULT, buf) != TRUE) TEST_ERROR
+
+ /* close the destination dataset */
+ if(H5Dclose(did2) < 0) TEST_ERROR
+
+ /* close the source dataset */
+ if(H5Dclose(did) < 0) TEST_ERROR
+
+ /* close the SRC file */
+ if(H5Fclose(fid_src) < 0) TEST_ERROR
+
+ /* close the DST file */
+ if(H5Fclose(fid_dst) < 0) TEST_ERROR
+
+
+ /* Reclaim vlen buffer */
+ if(H5Dvlen_reclaim(tid, sid, H5P_DEFAULT, buf) < 0) TEST_ERROR
+
+ /* close datatype */
+ if(H5Tclose(tid2) < 0) TEST_ERROR
+ if(H5Tclose(tid) < 0) TEST_ERROR
+
+ /* close dataspace */
+ if(H5Sclose(sid) < 0) TEST_ERROR
+
+ PASSED();
+ return 0;
+
+error:
+ H5E_BEGIN_TRY {
+ H5Dclose(did2);
+ H5Dclose(did);
+ H5Dvlen_reclaim(tid, sid, H5P_DEFAULT, buf);
+ H5Tclose(tid2);
+ H5Tclose(tid);
+ H5Sclose(sid);
+ H5Fclose(fid_dst);
+ H5Fclose(fid_src);
+ } H5E_END_TRY;
+ return 1;
+} /* end test_copy_dataset_contig_cmpd_vl */
+
+
+/*-------------------------------------------------------------------------
+ * Function: test_copy_dataset_chunked_cmpd_vl
+ *
+ * Purpose: Create a chunked dataset w/VLEN datatype contained in a
+ * compound in SRC file and copy it to DST file
+ *
+ * Return: Success: 0
+ * Failure: number of errors
+ *
+ * Programmer: Neil Fortner
+ * Wednesdat, September 30 , 2009
+ *
+ *-------------------------------------------------------------------------
+ */
+static int
+test_copy_dataset_chunked_cmpd_vl(hid_t fcpl_src, hid_t fcpl_dst, hid_t fapl)
+{
+ hid_t fid_src = -1, fid_dst = -1; /* File IDs */
+ hid_t tid = -1, tid2 = -1; /* Datatype IDs */
+ hid_t sid = -1; /* Dataspace ID */
+ hid_t pid = -1; /* Dataset creation property list ID */
+ hid_t did = -1, did2 = -1; /* Dataset IDs */
+ unsigned int i, j; /* Local index variables */
+ hsize_t dim1d[1]; /* Dataset dimensions */
+ hsize_t chunk_dim1d[1] = {CHUNK_SIZE_1}; /* Chunk dimensions */
+ cmpd_vl_t buf[DIM_SIZE_1]; /* Buffer for writing data */
+ char src_filename[NAME_BUF_SIZE];
+ char dst_filename[NAME_BUF_SIZE];
+
+ TESTING("H5Ocopy(): chunked dataset with compound VLEN datatype");
+
+ /* set initial data values */
+ for(i = 0; i < DIM_SIZE_1; i++) {
+ buf[i].a = i * (i - 1);
+ buf[i].b.len = i+1;
+ buf[i].b.p = (int *)HDmalloc(buf[i].b.len * sizeof(int));
+ for(j = 0; j < buf[i].b.len; j++)
+ ((int *)buf[i].b.p)[j] = (int)(i * 10 + j);
+ buf[i].c = 1. / (i + 1.);
+ } /* end for */
+
+ /* Initialize the filenames */
+ h5_fixname(FILENAME[0], fapl, src_filename, sizeof src_filename);
+ h5_fixname(FILENAME[1], fapl, dst_filename, sizeof dst_filename);
+
+ /* Reset file address checking info */
+ addr_reset();
+
+ /* create source file */
+ if((fid_src = H5Fcreate(src_filename, H5F_ACC_TRUNC, fcpl_src, fapl)) < 0) TEST_ERROR
+
+ /* Set dataspace dimensions */
+ dim1d[0]=DIM_SIZE_1;
+
+ /* create dataspace */
+ if((sid = H5Screate_simple(1, dim1d, NULL)) < 0) TEST_ERROR
+
+ /* create datatype */
+ if((tid2 = H5Tvlen_create(H5T_NATIVE_INT)) < 0) TEST_ERROR
+ if((tid = H5Tcreate(H5T_COMPOUND, sizeof(cmpd_vl_t))) < 0) TEST_ERROR
+ if(H5Tinsert(tid, "a", HOFFSET(cmpd_vl_t, a), H5T_NATIVE_INT) < 0) TEST_ERROR
+ if(H5Tinsert(tid, "b", HOFFSET(cmpd_vl_t, b), tid2) < 0) TEST_ERROR
+ if(H5Tinsert(tid, "c", HOFFSET(cmpd_vl_t, c), H5T_NATIVE_DOUBLE) < 0) TEST_ERROR
+
+ /* create and set chunk plist */
+ if((pid = H5Pcreate(H5P_DATASET_CREATE)) < 0) TEST_ERROR
+ if(H5Pset_chunk(pid, 1, chunk_dim1d) < 0) TEST_ERROR
+
+ /* create dataset at SRC file */
+ if((did = H5Dcreate2(fid_src, NAME_DATASET_CMPD_VL, tid, sid, H5P_DEFAULT, pid, H5P_DEFAULT)) < 0) TEST_ERROR
+
+ /* close chunk plist */
+ if(H5Pclose(pid) < 0) TEST_ERROR
+
+ /* write data into file */
+ if(H5Dwrite(did, tid, H5S_ALL, H5S_ALL, H5P_DEFAULT, buf) < 0) TEST_ERROR
+
+ /* close the dataset */
+ if(H5Dclose(did) < 0) TEST_ERROR
+
+ /* close the SRC file */
+ if(H5Fclose(fid_src) < 0) TEST_ERROR
+
+
+ /* open the source file with read-only */
+ if((fid_src = H5Fopen(src_filename, H5F_ACC_RDONLY, fapl)) < 0) TEST_ERROR
+
+ /* create destination file */
+ if((fid_dst = H5Fcreate(dst_filename, H5F_ACC_TRUNC, fcpl_dst, fapl)) < 0) TEST_ERROR
+
+ /* Create an uncopied object in destination file so that addresses in source and destination files aren't the same */
+ if(H5Gclose(H5Gcreate2(fid_dst, NAME_GROUP_UNCOPIED, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR
+
+ /* copy the dataset from SRC to DST */
+ if(H5Ocopy(fid_src, NAME_DATASET_CMPD_VL, fid_dst, NAME_DATASET_CMPD_VL, H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR
+
+ /* open the dataset for copy */
+ if((did = H5Dopen2(fid_src, NAME_DATASET_CMPD_VL, H5P_DEFAULT)) < 0) TEST_ERROR
+
+ /* open the destination dataset */
+ if((did2 = H5Dopen2(fid_dst, NAME_DATASET_CMPD_VL, H5P_DEFAULT)) < 0) TEST_ERROR
+
+ /* Check if the datasets are equal */
+ if(compare_datasets(did, did2, H5P_DEFAULT, buf) != TRUE) TEST_ERROR
+
+ /* close the destination dataset */
+ if(H5Dclose(did2) < 0) TEST_ERROR
+
+ /* close the source dataset */
+ if(H5Dclose(did) < 0) TEST_ERROR
+
+ /* close the SRC file */
+ if(H5Fclose(fid_src) < 0) TEST_ERROR
+
+ /* close the DST file */
+ if(H5Fclose(fid_dst) < 0) TEST_ERROR
+
+
+ /* Reclaim vlen buffer */
+ if(H5Dvlen_reclaim(tid, sid, H5P_DEFAULT, buf) < 0) TEST_ERROR
+
+ /* close datatype */
+ if(H5Tclose(tid2) < 0) TEST_ERROR
+ if(H5Tclose(tid) < 0) TEST_ERROR
+
+ /* close dataspace */
+ if(H5Sclose(sid) < 0) TEST_ERROR
+
+ PASSED();
+ return 0;
+
+error:
+ H5E_BEGIN_TRY {
+ H5Dclose(did2);
+ H5Dclose(did);
+ H5Dvlen_reclaim(tid, sid, H5P_DEFAULT, buf);
+ H5Tclose(tid2);
+ H5Tclose(tid);
+ H5Sclose(sid);
+ H5Fclose(fid_dst);
+ H5Fclose(fid_src);
+ } H5E_END_TRY;
+ return 1;
+} /* end test_copy_dataset_chunked_cmpd_vl */
+
+
+/*-------------------------------------------------------------------------
+ * Function: test_copy_dataset_compact_cmpd_vl
+ *
+ * Purpose: Create a compact dataset w/VLEN datatype contained in a
+ * compound in SRC file and copy it to DST file
+ *
+ * Return: Success: 0
+ * Failure: number of errors
+ *
+ * Programmer: Peter Cao
+ * Sunday, December 11, 2005
+ *
+ *-------------------------------------------------------------------------
+ */
+static int
+test_copy_dataset_compact_cmpd_vl(hid_t fcpl_src, hid_t fcpl_dst, hid_t fapl)
+{
+ hid_t fid_src = -1, fid_dst = -1; /* File IDs */
+ hid_t tid = -1, tid2 = -1; /* Datatype IDs */
+ hid_t sid = -1; /* Dataspace ID */
+ hid_t pid = -1; /* Dataset creation property list ID */
+ hid_t did = -1, did2 = -1; /* Dataset IDs */
+ unsigned int i, j; /* Local index variables */
+ hsize_t dim1d[1]; /* Dataset dimensions */
+ cmpd_vl_t buf[DIM_SIZE_1]; /* Buffer for writing data */
+ char src_filename[NAME_BUF_SIZE];
+ char dst_filename[NAME_BUF_SIZE];
+
+ TESTING("H5Ocopy(): compact dataset with compound VLEN datatype");
+
+ /* set initial data values */
+ for(i = 0; i < DIM_SIZE_1; i++) {
+ buf[i].a = i * (i - 1);
+ buf[i].b.len = i+1;
+ buf[i].b.p = (int *)HDmalloc(buf[i].b.len * sizeof(int));
+ for(j = 0; j < buf[i].b.len; j++)
+ ((int *)buf[i].b.p)[j] = (int)(i * 10 + j);
+ buf[i].c = 1. / (i + 1.);
+ } /* end for */
+
+ /* Initialize the filenames */
+ h5_fixname(FILENAME[0], fapl, src_filename, sizeof src_filename);
+ h5_fixname(FILENAME[1], fapl, dst_filename, sizeof dst_filename);
+
+ /* Reset file address checking info */
+ addr_reset();
+
+ /* create source file */
+ if((fid_src = H5Fcreate(src_filename, H5F_ACC_TRUNC, fcpl_src, fapl)) < 0) TEST_ERROR
+
+ /* Set dataspace dimensions */
+ dim1d[0]=DIM_SIZE_1;
+
+ /* create dataspace */
+ if((sid = H5Screate_simple(1, dim1d, NULL)) < 0) TEST_ERROR
+
+ /* create datatype */
+ if((tid2 = H5Tvlen_create(H5T_NATIVE_INT)) < 0) TEST_ERROR
+ if((tid = H5Tcreate(H5T_COMPOUND, sizeof(cmpd_vl_t))) < 0) TEST_ERROR
+ if(H5Tinsert(tid, "a", HOFFSET(cmpd_vl_t, a), H5T_NATIVE_INT) < 0) TEST_ERROR
+ if(H5Tinsert(tid, "b", HOFFSET(cmpd_vl_t, b), tid2) < 0) TEST_ERROR
+ if(H5Tinsert(tid, "c", HOFFSET(cmpd_vl_t, c), H5T_NATIVE_DOUBLE) < 0) TEST_ERROR
+
+ /* create and set compact plist */
+ if((pid = H5Pcreate(H5P_DATASET_CREATE)) < 0) TEST_ERROR
+ if(H5Pset_layout(pid, H5D_COMPACT) < 0) TEST_ERROR
+
+ /* create dataset at SRC file */
+ if((did = H5Dcreate2(fid_src, NAME_DATASET_CMPD_VL, tid, sid, H5P_DEFAULT, pid, H5P_DEFAULT)) < 0) TEST_ERROR
+
+ /* write data into file */
+ if(H5Dwrite(did, tid, H5S_ALL, H5S_ALL, H5P_DEFAULT, buf) < 0) TEST_ERROR
+
+ /* close compact plist */
+ if(H5Pclose(pid) < 0) TEST_ERROR
+
+ /* close the dataset */
+ if(H5Dclose(did) < 0) TEST_ERROR
+
+ /* close the SRC file */
+ if(H5Fclose(fid_src) < 0) TEST_ERROR
+
+
+ /* open the source file with read-only */
+ if((fid_src = H5Fopen(src_filename, H5F_ACC_RDONLY, fapl)) < 0) TEST_ERROR
+
+ /* create destination file */
+ if((fid_dst = H5Fcreate(dst_filename, H5F_ACC_TRUNC, fcpl_dst, fapl)) < 0) TEST_ERROR
+
+ /* Create an uncopied object in destination file so that addresses in source and destination files aren't the same */
+ if(H5Gclose(H5Gcreate2(fid_dst, NAME_GROUP_UNCOPIED, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR
+
+ /* copy the dataset from SRC to DST */
+ if(H5Ocopy(fid_src, NAME_DATASET_CMPD_VL, fid_dst, NAME_DATASET_CMPD_VL, H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR
+
+ /* open the dataset for copy */
+ if((did = H5Dopen2(fid_src, NAME_DATASET_CMPD_VL, H5P_DEFAULT)) < 0) TEST_ERROR
+
+ /* open the destination dataset */
+ if((did2 = H5Dopen2(fid_dst, NAME_DATASET_CMPD_VL, H5P_DEFAULT)) < 0) TEST_ERROR
+
+ /* Check if the datasets are equal */
+ if(compare_datasets(did, did2, H5P_DEFAULT, buf) != TRUE) TEST_ERROR
+
+ /* close the destination dataset */
+ if(H5Dclose(did2) < 0) TEST_ERROR
+
+ /* close the source dataset */
+ if(H5Dclose(did) < 0) TEST_ERROR
+
+ /* close the SRC file */
+ if(H5Fclose(fid_src) < 0) TEST_ERROR
+
+ /* close the DST file */
+ if(H5Fclose(fid_dst) < 0) TEST_ERROR
+
+
+ /* Reclaim vlen buffer */
+ if(H5Dvlen_reclaim(tid, sid, H5P_DEFAULT, buf) < 0) TEST_ERROR
+
+ /* close datatype */
+ if(H5Tclose(tid2) < 0) TEST_ERROR
+ if(H5Tclose(tid) < 0) TEST_ERROR
+
+ /* close dataspace */
+ if(H5Sclose(sid) < 0) TEST_ERROR
+
+ PASSED();
+ return 0;
+
+error:
+ H5E_BEGIN_TRY {
+ H5Dclose(did2);
+ H5Dclose(did);
+ H5Dvlen_reclaim(tid, sid, H5P_DEFAULT, buf);
+ H5Tclose(tid2);
+ H5Tclose(tid);
+ H5Sclose(sid);
+ H5Fclose(fid_dst);
+ H5Fclose(fid_src);
+ } H5E_END_TRY;
+ return 1;
+} /* end test_copy_dataset_compact_cmpd_vl */
+
/*-------------------------------------------------------------------------
* Function: test_copy_option
@@ -7561,6 +8073,9 @@ main(void)
nerrors += test_copy_dataset_contig_vl_vl(fcpl_src, fcpl_dst, my_fapl);
nerrors += test_copy_dataset_chunked_vl_vl(fcpl_src, fcpl_dst, my_fapl);
nerrors += test_copy_dataset_compressed_vl_vl(fcpl_src, fcpl_dst, my_fapl);
+ nerrors += test_copy_dataset_contig_cmpd_vl(fcpl_src, fcpl_dst, my_fapl);
+ nerrors += test_copy_dataset_chunked_cmpd_vl(fcpl_src, fcpl_dst, my_fapl);
+ nerrors += test_copy_dataset_compact_cmpd_vl(fcpl_src, fcpl_dst, my_fapl);
nerrors += test_copy_same_file_named_datatype(fcpl_src, my_fapl);
nerrors += test_copy_old_layout(fcpl_dst, my_fapl);