summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--release_docs/RELEASE.txt3
-rw-r--r--src/H5Dio.c31
-rw-r--r--src/H5Ofill.c4
-rw-r--r--test/Makefile.in12
-rw-r--r--test/tvlstr.c133
5 files changed, 160 insertions, 23 deletions
diff --git a/release_docs/RELEASE.txt b/release_docs/RELEASE.txt
index 35259ad..21f768f 100644
--- a/release_docs/RELEASE.txt
+++ b/release_docs/RELEASE.txt
@@ -78,6 +78,9 @@ Bug Fixes since HDF5-1.6.1 release
Library
-------
+ - Fixed bug that caused variable-length datatypes (strings or sequences)
+ used for datasets in files with objects that were unlinked to
+ fail to be read/written to a file. QAK - 2004/01/13
- Fixed small internal memory leak of fill-value information.
QAK - 2004/01/06
- Detect situation where szip 'pixels per block' is larger than the
diff --git a/src/H5Dio.c b/src/H5Dio.c
index 17382dd..7be69fb 100644
--- a/src/H5Dio.c
+++ b/src/H5Dio.c
@@ -220,14 +220,11 @@ H5D_fill(const void *fill, const H5T_t *fill_type, void *buf, const H5T_t *buf_t
FUNC_ENTER_NOAPI_NOINIT(H5D_fill);
/* Check args */
+ assert(fill_type);
assert(buf);
assert(buf_type);
assert(space);
- /* Check for "default" fill value */
- if(fill_type==NULL)
- fill_type=buf_type;
-
/* Get the memory and file datatype sizes */
src_type_size = H5T_get_size(fill_type);
dst_type_size = H5T_get_size(buf_type);
@@ -244,19 +241,20 @@ H5D_fill(const void *fill, const H5T_t *fill_type, void *buf, const H5T_t *buf_t
/* Copy the user's data into the buffer for conversion */
HDmemcpy(tconv_buf,fill,src_type_size);
- /* Convert memory buffer into disk buffer */
/* Set up type conversion function */
- if (NULL == (tpath = H5T_path_find(fill_type, buf_type, NULL, NULL, dxpl_id))) {
+ if (NULL == (tpath = H5T_path_find(fill_type, buf_type, NULL, NULL, dxpl_id)))
HGOTO_ERROR(H5E_DATASET, H5E_UNSUPPORTED, FAIL, "unable to convert between src and dest data types");
- } else if (!H5T_path_noop(tpath)) {
+
+ /* Convert memory buffer into disk buffer */
+ if (!H5T_path_noop(tpath)) {
if ((src_id = H5I_register(H5I_DATATYPE, H5T_copy(fill_type, H5T_COPY_ALL)))<0 ||
(dst_id = H5I_register(H5I_DATATYPE, H5T_copy(buf_type, H5T_COPY_ALL)))<0)
HGOTO_ERROR(H5E_DATASET, H5E_CANTREGISTER, FAIL, "unable to register types for conversion");
- }
- /* Perform data type conversion */
- if (H5T_convert(tpath, src_id, dst_id, (hsize_t)1, 0, 0, tconv_buf, bkg_buf, dxpl_id)<0)
- HGOTO_ERROR(H5E_DATASET, H5E_CANTCONVERT, FAIL, "data type conversion failed");
+ /* Perform data type conversion */
+ if (H5T_convert(tpath, src_id, dst_id, (hsize_t)1, 0, 0, tconv_buf, bkg_buf, dxpl_id)<0)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTCONVERT, FAIL, "data type conversion failed");
+ } /* end if */
} /* end if */
/* Fill the selection in the memory buffer */
@@ -599,7 +597,7 @@ H5D_read(H5D_t *dataset, const H5T_t *mem_type, const H5S_t *mem_space,
HGOTO_DONE(SUCCEED);
/* Go fill the user's selection with the dataset's fill value */
- if(H5D_fill(fill.buf,fill.type,buf,mem_type,mem_space, dxpl_id)<0) {
+ if(H5D_fill(fill.buf,dataset->type,buf,mem_type,mem_space, dxpl_id)<0) {
HGOTO_ERROR(H5E_DATASET, H5E_READERROR, FAIL, "filling buf failed");
} else
HGOTO_DONE(SUCCEED);
@@ -815,13 +813,20 @@ H5D_write(H5D_t *dataset, const H5T_t *mem_type, const H5S_t *mem_space,
if(nelmts > 0 && dataset->efl.nused==0 && dataset->layout.type!=H5D_COMPACT
&& dataset->layout.addr==HADDR_UNDEF) {
hssize_t file_nelmts; /* Number of elements in file dataset's dataspace */
+ hbool_t full_overwrite; /* Whether we are over-writing all the elements */
/* Get the number of elements in file dataset's dataspace */
if((file_nelmts=H5S_get_simple_extent_npoints(file_space))<0)
HGOTO_ERROR (H5E_DATASET, H5E_BADVALUE, FAIL, "can't retrieve number of elements in file dataset");
+ /* Always allow fill values to be written if the dataset has a VL datatype */
+ if(H5T_detect_class(dataset->type, H5T_VLEN))
+ full_overwrite=FALSE;
+ else
+ full_overwrite=(hsize_t)file_nelmts==nelmts ? TRUE : FALSE;
+
/* Allocate storage */
- if(H5D_alloc_storage(dataset->ent.file,dxpl_id,dataset,H5D_ALLOC_WRITE, TRUE, (hbool_t)((hsize_t)file_nelmts==nelmts ? TRUE : FALSE))<0)
+ if(H5D_alloc_storage(dataset->ent.file,dxpl_id,dataset,H5D_ALLOC_WRITE, TRUE, full_overwrite)<0)
HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to initialize storage");
} /* end if */
diff --git a/src/H5Ofill.c b/src/H5Ofill.c
index a2ffdb1..b0716f6 100644
--- a/src/H5Ofill.c
+++ b/src/H5Ofill.c
@@ -882,9 +882,9 @@ H5O_fill_convert(void *_fill, H5T_t *dset_type, hid_t dxpl_id)
/* Don't bother doing anything if there will be no actual conversion */
if (!H5T_path_noop(tpath)) {
if ((src_id = H5I_register(H5I_DATATYPE,
- H5T_copy(fill->type, H5T_COPY_TRANSIENT)))<0 ||
+ H5T_copy(fill->type, H5T_COPY_ALL)))<0 ||
(dst_id = H5I_register(H5I_DATATYPE,
- H5T_copy(dset_type, H5T_COPY_TRANSIENT)))<0)
+ H5T_copy(dset_type, H5T_COPY_ALL)))<0)
HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to copy/register data type");
/*
diff --git a/test/Makefile.in b/test/Makefile.in
index ed2ad16..c5e7073 100644
--- a/test/Makefile.in
+++ b/test/Makefile.in
@@ -55,12 +55,12 @@ MOSTLYCLEAN=cmpd_dset.h5 compact_dataset.h5 dataset.h5 extend.h5 istore.h5 \
big[0-9][0-9][0-9][0-9][0-9].h5 dtypes[1-3].h5 tattr.h5 \
tselect.h5 mtime.h5 unlink.h5 fillval_[0-9].h5 fillval.raw \
mount_[0-9].h5 testmeta.h5 ttime.h5 trefer[1-3].h5 tvltypes.h5 \
- tvlstr.h5 flush.h5 enum1.h5 titerate.h5 ttsafe.h5 tarray1.h5 \
- tgenprop.h5 tmisc1.h5 tmisc2a.h5 tmisc2b.h5 tmisc3.h5 tmisc4a.h5 \
- tmisc4b.h5 tmisc5.h5 tmisc6.h5 tmisc7.h5 tmisc8.h5 tmisc9.h5 \
- tmisc10.h5 tmisc11.h5 tmisc12.h5 tmisc13a.h5 tmisc13b.h5 \
- tmisc14.h5 set_extent_read.h5 set_extent_create.h5 getname.h5 \
- getname1.h5 getname2.h5 getname3.h5 sec2_file.h5 \
+ tvlstr.h5 tvlstr2.h5 flush.h5 enum1.h5 titerate.h5 ttsafe.h5 \
+ tarray1.h5 tgenprop.h5 tmisc1.h5 tmisc2a.h5 tmisc2b.h5 tmisc3.h5 \
+ tmisc4a.h5 tmisc4b.h5 tmisc5.h5 tmisc6.h5 tmisc7.h5 tmisc8.h5 \
+ tmisc9.h5 tmisc10.h5 tmisc11.h5 tmisc12.h5 tmisc13a.h5 \
+ tmisc13b.h5 tmisc14.h5 set_extent_read.h5 set_extent_create.h5 \
+ getname.h5 getname1.h5 getname2.h5 getname3.h5 sec2_file.h5 \
family_file000[0-3][0-9].h5 multi_file-[rs].h5 core_file \
new_move_[ab].h5 ntypes.h5 dangle.h5
diff --git a/test/tvlstr.c b/test/tvlstr.c
index f22f04d..60773f1 100644
--- a/test/tvlstr.c
+++ b/test/tvlstr.c
@@ -31,6 +31,7 @@
#include "hdf5.h"
#define DATAFILE "tvlstr.h5"
+#define DATAFILE2 "tvlstr2.h5"
/* 1-D dataset with fixed dimensions */
#define SPACE1_NAME "Space1"
@@ -45,6 +46,9 @@
#define VLSTR_TYPE "vl_string_type"
+/* Definitions for the VL re-writing test */
+#define REWRITE_NDATASETS 32
+
/* String for testing attributes */
static const char *string_att = "This is the string for the attribute";
static char *string_att_write=NULL;
@@ -725,6 +729,127 @@ static void test_read_vl_string_attribute(void)
return;
}
+/* Helper routine for test_vl_rewrite() */
+static void write_scalar_dset(hid_t file, hid_t type, hid_t space, char *name, char *data)
+{
+ hid_t dset;
+ herr_t ret;
+
+ dset = H5Dcreate (file, name, type, space, H5P_DEFAULT);
+ CHECK(dset, FAIL, "H5Dcreate");
+
+ ret = H5Dwrite(dset, type, space, space, H5P_DEFAULT, &data);
+ CHECK(ret, FAIL, "H5Dwrite");
+
+ ret = H5Dclose(dset);
+ CHECK(ret, FAIL, "H5Dclose");
+}
+
+/* Helper routine for test_vl_rewrite() */
+static void read_scalar_dset(hid_t file, hid_t type, hid_t space, char *name, char *data)
+{
+ hid_t dset;
+ herr_t ret;
+ char *data_read;
+
+ dset = H5Dopen (file, name);
+ CHECK(dset, FAIL, "H5Dopen");
+
+ ret = H5Dread(dset, type, space, space, H5P_DEFAULT, &data_read);
+ CHECK(ret, FAIL, "H5Dread");
+
+ ret = H5Dclose(dset);
+ CHECK(ret, FAIL, "H5Dclose");
+
+ if(HDstrcmp(data, data_read))
+ TestErrPrintf("Expected %s for dataset %s but read %s\n", data, name, data_read);
+
+ HDfree(data_read);
+}
+
+/****************************************************************
+**
+** test_vl_rewrite(): Test basic VL string code.
+** Tests I/O on VL strings when lots of objects in the file
+** have been linked/unlinked.
+**
+****************************************************************/
+static void test_vl_rewrite(void)
+{
+ hid_t file1, file2; /* File IDs */
+ hid_t type; /* VL string datatype ID */
+ hid_t space; /* Scalar dataspace */
+ char name[256]; /* Buffer for names & data */
+ int i; /* Local index variable */
+ herr_t ret; /* Generic return value */
+
+ /* Create the VL string datatype */
+ type = H5Tcopy(H5T_C_S1);
+ CHECK(type, FAIL, "H5Tcopy");
+
+ ret = H5Tset_size(type, H5T_VARIABLE);
+ CHECK(ret, FAIL, "H5Tset_size");
+
+ /* Create the scalar dataspace */
+ space = H5Screate(H5S_SCALAR);
+ CHECK(space, FAIL, "H5Screate");
+
+ /* Open the files */
+ file1 = H5Fcreate(DATAFILE, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT);
+ CHECK(file1, FAIL, "H5Fcreate");
+
+ file2 = H5Fcreate(DATAFILE2, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT);
+ CHECK(file1, FAIL, "H5Fcreate");
+
+ /* Create in file 1 */
+ for(i=0; i<REWRITE_NDATASETS; i++) {
+ sprintf(name, "/set_%d", i);
+ write_scalar_dset(file1, type, space, name, name);
+ }
+
+ /* Effectively copy data from file 1 to 2 */
+ for(i=0; i<REWRITE_NDATASETS; i++) {
+ sprintf(name, "/set_%d", i);
+ read_scalar_dset(file1, type, space, name, name);
+ write_scalar_dset(file2, type, space, name, name);
+ }
+
+ /* Read back from file 2 */
+ for(i=0; i<REWRITE_NDATASETS; i++) {
+ sprintf(name, "/set_%d", i);
+ read_scalar_dset(file2, type, space, name, name);
+ }
+
+ /* Remove from file 2. */
+ for(i=0; i<REWRITE_NDATASETS; i++) {
+ sprintf(name, "/set_%d", i);
+ ret = H5Gunlink(file2, name);
+ CHECK(ret, FAIL, "H5Gunlink");
+ }
+
+ /* Effectively copy from file 1 to file 2 */
+ for(i=0; i<REWRITE_NDATASETS; i++) {
+ sprintf(name, "/set_%d", i);
+ read_scalar_dset(file1, type, space, name, name);
+ write_scalar_dset(file2, type, space, name, name);
+ }
+
+ /* Close everything */
+ ret = H5Tclose(type);
+ CHECK(ret, FAIL, "H5Tclose");
+
+ ret = H5Sclose(space);
+ CHECK(ret, FAIL, "H5Sclose");
+
+ ret = H5Fclose(file1);
+ CHECK(ret, FAIL, "H5Fclose");
+
+ ret = H5Fclose(file2);
+ CHECK(ret, FAIL, "H5Fclose");
+
+ return;
+} /* end test_vl_rewrite() */
+
/****************************************************************
**
** test_vlstrings(): Main VL string testing routine.
@@ -736,7 +861,7 @@ test_vlstrings(void)
/* Output message about test being performed */
MESSAGE(5, ("Testing Variable-Length Strings\n"));
- /* These tests use the same file */
+/* These tests use the same file */
/* Test basic VL string datatype */
test_vlstrings_basic();
test_vlstrings_special();
@@ -746,6 +871,9 @@ test_vlstrings(void)
/* Test using VL strings in attributes */
test_write_vl_string_attribute();
test_read_vl_string_attribute();
+
+ /* Test writing VL datasets in files with lots of unlinking */
+ test_vl_rewrite();
} /* test_vlstrings() */
@@ -766,6 +894,7 @@ test_vlstrings(void)
void
cleanup_vlstrings(void)
{
- remove(DATAFILE);
+ HDremove(DATAFILE);
+ HDremove(DATAFILE2);
}