[svn-r30308] Fix for HDFFV-7991--error when copying dataset with attribute which is a compound datatype consisting of

a variable length string.
Tested on mayll, platypus, osx1010test, emu, kituo, kite, quail, moohan, ostrich.
This commit is contained in:
Vailin Choi 2016-08-19 15:58:16 -05:00
parent c58ca9e28b
commit c8af99f530
6 changed files with 418 additions and 4 deletions

View File

@ -1926,6 +1926,7 @@ H5A_attr_copy_file(const H5A_t *attr_src, H5F_t *file_dst, hbool_t *recompute_si
hid_t tid_mem = -1; /* Datatype ID for memory datatype */
void *buf = NULL; /* Buffer for copying data */
void *reclaim_buf = NULL; /* Buffer for reclaiming data */
void *bkg_buf = NULL; /* Background buffer */
hid_t buf_sid = -1; /* ID for buffer dataspace */
hssize_t sdst_nelmts; /* # of elements in destination attribute (signed) */
size_t dst_nelmts; /* # of elements in destination attribute */
@ -2104,14 +2105,24 @@ H5A_attr_copy_file(const H5A_t *attr_src, H5F_t *file_dst, hbool_t *recompute_si
HDmemcpy(buf, attr_src->shared->data, attr_src->shared->data_size);
/* Allocate background memory */
if(H5T_path_bkg(tpath_src_mem) || H5T_path_bkg(tpath_mem_dst)) {
if(NULL == (bkg_buf = H5FL_BLK_CALLOC(attr_buf, buf_size)))
HGOTO_ERROR(H5E_ATTR, H5E_CANTALLOC, 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_buf, dxpl_id) < 0)
HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, NULL, "datatype conversion NULLed")
HDmemcpy(reclaim_buf, buf, buf_size);
/* Set background buffer to all zeros */
if(bkg_buf)
HDmemset(bkg_buf, 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, NULL, dxpl_id) < 0)
if(H5T_convert(tpath_mem_dst, tid_mem, tid_dst, nelmts, (size_t)0, (size_t)0, buf, bkg_buf, dxpl_id) < 0)
HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, NULL, "datatype conversion NULLed")
HDmemcpy(attr_dst->shared->data, buf, attr_dst->shared->data_size);
@ -2158,6 +2169,8 @@ done:
buf = H5FL_BLK_FREE(attr_buf, buf);
if(reclaim_buf)
reclaim_buf = H5FL_BLK_FREE(attr_buf, reclaim_buf);
if(bkg_buf)
bkg_buf = H5FL_BLK_FREE(attr_buf, bkg_buf);
/* Release destination attribute information on failure */
if(!ret_value && attr_dst && H5A_close(attr_dst) < 0)

View File

@ -20,7 +20,7 @@
* Purpose: Test H5Ocopy().
*/
#include "h5test.h"
#include "testhdf5.h"
#include "H5srcdir.h"
/*
@ -165,6 +165,13 @@ compare_groups(hid_t gid, hid_t gid2, hid_t pid, int depth, unsigned copy_flags)
static int
compare_idx_type(hid_t fapl, hid_t did, H5D_chunk_index_t new_type, H5D_chunk_index_t old_type);
static int
test_copy_attribute_compound_vlstr(hid_t fcpl_src, hid_t fcpl_dst, hid_t src_fapl, hid_t dst_fapl);
static int
attach_attribute_compound_vlstr(hid_t loc_id);
static int
compare_attribute_compound_vlstr(hid_t loc, hid_t loc2);
/*-------------------------------------------------------------------------
* Function: addr_insert
@ -544,6 +551,7 @@ done:
return ret_value;
} /* end of attach_attribute_vl */
/*-------------------------------------------------------------------------
* Function: test_copy_attach_attributes
@ -5527,6 +5535,312 @@ error:
return 1;
} /* end test_copy_dataset_simple_empty */
/*-------------------------------------------------------------------------
* Function: attach_attribute_compound_vlstr
*
* Purpose: Attach a compound datatype with a variable length string to the object
*
* Return: Non-negative on success/Negative on failure
*
* Programmer: Vailin Choi; Aug 2016
*
*-------------------------------------------------------------------------
*/
static int
attach_attribute_compound_vlstr(hid_t loc_id)
{
hid_t aid = -1; /* Attribute ID */
hid_t sid = -1; /* Dataspace ID */
hid_t tid = -1; /* Datatype ID */
hid_t vl_str_tid = -1; /* Variable length string datatype ID */
hid_t cmpd_tid = -1; /* Compound datatype ID */
hsize_t dim1 = 1; /* Dimension size */
typedef struct { /* Compound structure for the attribute */
int i;
char *v;
} s1;
s1 buf; /* Buffer */
int ret_value = -1; /* Return value */
/* Create dataspace */
if((sid = H5Screate_simple(1, &dim1, NULL)) < 0 )
goto done;
/* Create an integer datatype */
if((tid = H5Tcopy(H5T_NATIVE_INT)) < 0)
goto done;
/* Create a variable length string */
if((vl_str_tid = H5Tcopy(H5T_C_S1)) < 0)
goto done;
if(H5Tset_size(vl_str_tid, H5T_VARIABLE) < 0)
goto done;
/* Create a compound datatype with a variable length string and an integer */
if((cmpd_tid = H5Tcreate(H5T_COMPOUND, sizeof(s1))) < 0)
goto done;
if(H5Tinsert(cmpd_tid, "i", HOFFSET(s1, i), tid) < 0)
goto done;
if(H5Tinsert(cmpd_tid, "v", HOFFSET(s1, v), vl_str_tid) < 0)
goto done;
/* Attach an attribute to the object */
if((aid = H5Acreate2(loc_id, "attr_cmpd_vlstr", cmpd_tid, sid, H5P_DEFAULT, H5P_DEFAULT)) < 0)
goto done;
/* Write to the attribute */
buf.i = 9;
buf.v = "ThisIsAString";
if(H5Awrite(aid, cmpd_tid, &buf) < 0)
goto done;
ret_value = 0;
done:
if(sid > 0)
H5Sclose(sid);
if(tid > 0)
H5Tclose(tid);
if(vl_str_tid > 0)
H5Tclose(vl_str_tid);
if(cmpd_tid > 0)
H5Tclose(cmpd_tid);
if(aid > 0)
H5Aclose(aid);
return ret_value;
} /* attach_attribute_compound_vlstr */
/*-------------------------------------------------------------------------
* Function: compare_attribute_compound_vlstr
*
* Purpose: Compare data of the attributes attached to the two objects.
* The attribute is a compound datatype with a variable length string.
*
* Return: Non-negative on success/Negative on failure
*
* Programmer: Vailin Choi; Aug 2016
*
*-------------------------------------------------------------------------
*/
static int
compare_attribute_compound_vlstr(hid_t loc, hid_t loc2)
{
hid_t aid = -1, aid2 = -1; /* Attribute IDs */
hid_t tid = -1, tid2 = -1; /* Datatype IDs */
typedef struct { /* Compound structure for the attribute */
int i;
char *v;
} s1;
s1 rbuf; /* Buffer for data read */
s1 rbuf2; /* Buffer for data read */
/* Open the attributes attached to the objects */
if((aid = H5Aopen_by_idx(loc, ".", H5_INDEX_CRT_ORDER, H5_ITER_INC, (hsize_t)0, H5P_DEFAULT, H5P_DEFAULT)) < 0)
FAIL_STACK_ERROR
if((aid2 = H5Aopen_by_idx(loc2, ".", H5_INDEX_CRT_ORDER, H5_ITER_INC, (hsize_t)0, H5P_DEFAULT, H5P_DEFAULT)) < 0)
FAIL_STACK_ERROR
/* Get the attributes' datatypes */
if((tid = H5Aget_type(aid)) < 0)
FAIL_STACK_ERROR
if((tid2 = H5Aget_type(aid2)) < 0)
FAIL_STACK_ERROR
/* Read the attributes */
if(H5Aread(aid, tid, &rbuf) < 0)
FAIL_STACK_ERROR
if(H5Aread(aid2, tid2, &rbuf2) < 0)
FAIL_STACK_ERROR
/* Compare the attributes' data */
if(rbuf.i != rbuf2.i)
FAIL_STACK_ERROR
if(HDstrlen(rbuf.v) != HDstrlen(rbuf2.v))
FAIL_STACK_ERROR
if(HDmemcmp(rbuf.v, rbuf2.v, HDstrlen(rbuf.v)))
FAIL_STACK_ERROR
/* Close the attributes */
if(H5Aclose(aid) < 0)
FAIL_STACK_ERROR
if(H5Aclose(aid2) < 0)
FAIL_STACK_ERROR
return TRUE;
error:
H5E_BEGIN_TRY {
H5Aclose(aid);
H5Aclose(aid2);
H5Tclose(tid);
H5Tclose(tid2);
} H5E_END_TRY;
return FALSE;
} /* compare_attribute_compound_vlstr() */
/*-------------------------------------------------------------------------
* Function: test_copy_attribute_compound_vlstr
*
* Purpose: Create a simple dataset and a group in SRC file.
* Both has an attribute with a compound datatype consisting
* of a variable length string
* Copy the dataset and the group to DST file
* This is for HDFFV-7991
*
* Return: Success: 0
* Failure: number of errors
*
* Programmer:
*
*-------------------------------------------------------------------------
*/
static int
test_copy_attribute_compound_vlstr(hid_t fcpl_src, hid_t fcpl_dst, hid_t src_fapl, hid_t dst_fapl)
{
hid_t fid_src = -1, fid_dst = -1; /* File IDs */
hid_t sid = -1; /* Dataspace ID */
hid_t did = -1, did2 = -1; /* Dataset IDs */
hid_t aid = -1, aid2 = -1; /* Attribute IDs */
hid_t gid = -1, gid2 = -1; /* Group IDs */
hsize_t dim2d[2]; /* Dataset dimensions */
char src_filename[NAME_BUF_SIZE]; /* Source file name */
char dst_filename[NAME_BUF_SIZE]; /* Destination file name */
TESTING("H5Ocopy(): attribute with compound datatype consisting of variable length string");
/* Initialize the filenames */
h5_fixname(FILENAME[0], src_fapl, src_filename, sizeof src_filename);
h5_fixname(FILENAME[1], dst_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, src_fapl)) < 0)
FAIL_STACK_ERROR
/* set dataspace dimensions */
dim2d[0] = DIM_SIZE_1;
dim2d[1] = DIM_SIZE_2;
/* create 2D dataspace */
if((sid = H5Screate_simple(2, dim2d, NULL)) < 0)
FAIL_STACK_ERROR
/* create 2D int dataset at SRC file */
if((did = H5Dcreate2(fid_src, NAME_DATASET_SIMPLE, H5T_NATIVE_INT, sid, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0)
FAIL_STACK_ERROR
/* close dataspace */
if(H5Sclose(sid) < 0)
FAIL_STACK_ERROR
/* attach an attribute to the dataset */
if(attach_attribute_compound_vlstr(did) < 0)
FAIL_STACK_ERROR
/* close the dataset */
if(H5Dclose(did) < 0)
FAIL_STACK_ERROR
/* create a group */
if((gid = H5Gcreate2(fid_src, NAME_GROUP_EMPTY, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0)
FAIL_STACK_ERROR
/* attach attribute to the group */
if(attach_attribute_compound_vlstr(gid) < 0)
FAIL_STACK_ERROR
/* close the group */
if(H5Gclose(gid) < 0)
FAIL_STACK_ERROR
/* close the SRC file */
if(H5Fclose(fid_src) < 0)
FAIL_STACK_ERROR
/* open the source file with read-only */
if((fid_src = H5Fopen(src_filename, H5F_ACC_RDONLY, src_fapl)) < 0)
FAIL_STACK_ERROR
/* create destination file */
if((fid_dst = H5Fcreate(dst_filename, H5F_ACC_TRUNC, fcpl_dst, dst_fapl)) < 0)
FAIL_STACK_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)
FAIL_STACK_ERROR
/* copy the dataset from SRC to DST */
if(H5Ocopy(fid_src, NAME_DATASET_SIMPLE, fid_dst, NAME_DATASET_SIMPLE, H5P_DEFAULT, H5P_DEFAULT) < 0)
FAIL_STACK_ERROR
/* open the src dataset */
if((did = H5Dopen2(fid_src, NAME_DATASET_SIMPLE, H5P_DEFAULT)) < 0)
FAIL_STACK_ERROR
/* open the destination dataset */
if((did2 = H5Dopen2(fid_dst, NAME_DATASET_SIMPLE, H5P_DEFAULT)) < 0)
FAIL_STACK_ERROR
/* compare the data of the attributes attached to the two datasets */
if(compare_attribute_compound_vlstr(did, did2) < 0)
FAIL_STACK_ERROR
/* close the datasets */
if(H5Dclose(did2) < 0)
FAIL_STACK_ERROR
if(H5Dclose(did) < 0)
FAIL_STACK_ERROR
/* Copy the group */
if(H5Ocopy(fid_src, NAME_GROUP_EMPTY, fid_dst, NAME_GROUP_EMPTY, H5P_DEFAULT, H5P_DEFAULT) < 0)
FAIL_STACK_ERROR
/* Open the src group */
if((gid = H5Gopen2(fid_src, NAME_GROUP_EMPTY, H5P_DEFAULT)) < 0)
FAIL_STACK_ERROR
/* Open the destination group */
if((gid2 = H5Gopen2(fid_dst, NAME_GROUP_EMPTY, H5P_DEFAULT)) < 0)
FAIL_STACK_ERROR
/* compare the data of the attributes attached to the two groups */
if(compare_attribute_compound_vlstr(gid, gid2) < 0)
FAIL_STACK_ERROR
/* close the groups */
if(H5Gclose(gid) < 0)
FAIL_STACK_ERROR
if(H5Gclose(gid2) < 0)
FAIL_STACK_ERROR
/* close the SRC file */
if(H5Fclose(fid_src) < 0)
FAIL_STACK_ERROR
/* close the DST file */
if(H5Fclose(fid_dst) < 0)
FAIL_STACK_ERROR
PASSED();
return 0;
error:
H5E_BEGIN_TRY {
H5Aclose(aid2);
H5Aclose(aid);
H5Dclose(did2);
H5Dclose(did);
H5Gclose(gid);
H5Gclose(gid2);
H5Sclose(sid);
H5Fclose(fid_dst);
H5Fclose(fid_src);
} H5E_END_TRY;
return 1;
} /* end test_copy_attribute_compound_vlstr() */
/*-------------------------------------------------------------------------
* Function: test_copy_dataset_compressed_vl
@ -10233,7 +10547,7 @@ test_copy_committed_dt_merge_attr(hid_t fcpl_src, hid_t fcpl_dst, hid_t src_fapl
if((aid = H5Acreate2(gid, "attr", tid, sid, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR
/* write data into file */
if(H5Awrite(aid, tid, buf) < 0) TEST_ERROR
//if(H5Awrite(aid, tid, buf) < 0) TEST_ERROR
/* close the datatype */
if(H5Tclose(tid) < 0) TEST_ERROR
@ -13479,6 +13793,7 @@ main(void)
nerrors += test_copy_dataset_compact_vl(fcpl_src, fcpl_dst, src_fapl, dst_fapl);
nerrors += test_copy_dataset_compressed_vl(fcpl_src, fcpl_dst, src_fapl, dst_fapl);
nerrors += test_copy_attribute_vl(fcpl_src, fcpl_dst, src_fapl, dst_fapl);
nerrors += test_copy_attribute_compound_vlstr(fcpl_src, fcpl_dst, src_fapl, dst_fapl);
nerrors += test_copy_dataset_compact_named_vl(fcpl_src, fcpl_dst, src_fapl, dst_fapl);
nerrors += test_copy_dataset_contig_named_vl(fcpl_src, fcpl_dst, src_fapl, dst_fapl);
nerrors += test_copy_dataset_chunked_named_vl(fcpl_src, fcpl_dst, src_fapl, dst_fapl);

View File

@ -35,9 +35,12 @@
#define DATASET_COMPRESSED "compressed"
#define DATASET_NAMED_VL "named_vl"
#define DATASET_NESTED_VL "nested_vl"
#define DATASET_ATTR "dset_attr"
#define ATTR "attr"
#define GROUP_EMPTY "grp_empty"
#define GROUP_DATASETS "grp_dsets"
#define GROUP_NESTED "grp_nested"
#define GROUP_ATTR "grp_attr"
/* Obj reference */
#define OBJ_REF_DS "Dset1"
@ -322,6 +325,86 @@ static void gent_nested_vl(hid_t loc_id)
}
/*-------------------------------------------------------------------------
* Function: gent_att_compound_vlstr
*
* Purpose: Generate a dataset and a group.
* Both has an attribute with a compound datatype consisting
* of a variable length string
*
*-------------------------------------------------------------------------
*/
static void gent_att_compound_vlstr(hid_t loc_id)
{
typedef struct { /* Compound structure for the attribute */
int i;
char *v;
} s1;
hsize_t dim[1] = {1}; /* Dimension size */
hid_t sid = -1; /* Dataspace ID */
hid_t tid = -1; /* Datatype ID */
hid_t aid = -1; /* Attribute ID */
hid_t did = -1; /* Dataset ID */
hid_t gid = -1; /* Group ID */
hid_t vl_str_tid = -1; /* Variable length datatype ID */
hid_t cmpd_tid = -1; /* Compound datatype ID */
hid_t null_sid = -1; /* Null dataspace ID */
s1 buf; /* Buffer */
buf.i = 9;
buf.v = "ThisIsAString";
/* Create an integer datatype */
tid = H5Tcopy(H5T_NATIVE_INT);
/* Create a variable length string */
vl_str_tid = H5Tcopy(H5T_C_S1);
H5Tset_size(vl_str_tid, H5T_VARIABLE);
/* Create a compound datatype with a variable length string and an integer */
cmpd_tid = H5Tcreate(H5T_COMPOUND, sizeof(s1));
H5Tinsert(cmpd_tid, "i", HOFFSET(s1, i), tid);
H5Tinsert(cmpd_tid, "v", HOFFSET(s1, v), vl_str_tid);
/* Create a dataset */
null_sid = H5Screate(H5S_NULL);
did = H5Dcreate(loc_id, DATASET_ATTR, H5T_NATIVE_INT, null_sid, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
/* Attach an attribute with the compound datatype to the dataset */
sid = H5Screate_simple(1, dim, dim);
aid = H5Acreate2(did, ATTR, cmpd_tid, sid, H5P_DEFAULT, H5P_DEFAULT);
/* Write the attribute */
buf.i = 9;
buf.v = "ThisIsAString";
H5Awrite(aid, cmpd_tid, &buf);
/* Close the dataset and its attribute */
H5Dclose(did);
H5Aclose(aid);
/* Create a group */
gid = H5Gcreate2(loc_id, GROUP_ATTR, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
/* Attach an attribute with the compound datatype to the group */
aid = H5Acreate2(gid, ATTR, cmpd_tid, sid, H5P_DEFAULT, H5P_DEFAULT);
H5Awrite(aid, cmpd_tid, &buf);
/* Close the group and its attribute */
H5Aclose(aid);
H5Gclose(gid);
/* Close dataspaces */
H5Sclose(sid);
H5Sclose(null_sid);
/* Close datatypes */
H5Tclose(tid);
H5Tclose(vl_str_tid);
H5Tclose(cmpd_tid);
} /* gen_att_compound_vlstr() */
/*-------------------------------------------------------------------------
* Function: gent_datasets
*
@ -676,6 +759,7 @@ static void Test_Obj_Copy(void)
gent_empty_group(fid);
gent_nested_datasets(fid);
gent_nested_group(fid);
gent_att_compound_vlstr(fid);
H5Fclose(fid);
fid = (-1);

Binary file not shown.

View File

@ -490,6 +490,7 @@ COPY_OBJECTS()
TOOLTEST -i $TESTFILE -o $TESTDIR/compressed.out.h5 -v -s compressed -d compressed
TOOLTEST -i $TESTFILE -o $TESTDIR/named_vl.out.h5 -v -s named_vl -d named_vl
TOOLTEST -i $TESTFILE -o $TESTDIR/nested_vl.out.h5 -v -s nested_vl -d nested_vl
TOOLTEST -i $TESTFILE -o $TESTDIR/dset_attr.out.h5 -v -s /dset_attr -d /dset_attr
echo "Test copying dataset within group in source file to root of destination"
TOOLTEST -i $TESTFILE -o $TESTDIR/simple_top.out.h5 -v -s grp_dsets/simple -d simple_top
@ -501,6 +502,7 @@ COPY_OBJECTS()
TOOLTEST -i $TESTFILE -o $TESTDIR/grp_empty.out.h5 -v -s grp_empty -d grp_empty
TOOLTEST -i $TESTFILE -o $TESTDIR/grp_dsets.out.h5 -v -s grp_dsets -d grp_dsets
TOOLTEST -i $TESTFILE -o $TESTDIR/grp_nested.out.h5 -v -s grp_nested -d grp_nested
TOOLTEST -i $TESTFILE -o $TESTDIR/grp_attr.out.h5 -v -s grp_attr -d grp_attr
echo "Test copying dataset within group in source file to group in destination"
TOOLTEST_PREFILL -i $TESTFILE -o $TESTDIR/simple_group.out.h5 grp_dsets grp_dsets /grp_dsets/simple /grp_dsets/simple_group