summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--release_docs/RELEASE.txt3
-rw-r--r--src/H5D.c1
-rw-r--r--src/H5Tconv.c95
-rw-r--r--test/Makefile.in2
-rw-r--r--test/tarray.c39
-rw-r--r--test/tmisc.c359
6 files changed, 463 insertions, 36 deletions
diff --git a/release_docs/RELEASE.txt b/release_docs/RELEASE.txt
index f9acb56..e103899 100644
--- a/release_docs/RELEASE.txt
+++ b/release_docs/RELEASE.txt
@@ -35,6 +35,9 @@ Bug Fixes since HDF5-1.4.2
Library
-------
+ * Fixed bug where the data for several level deep nested compound &
+ variable-length datatypes used for datasets were getting corrupted when
+ written to the file. QAK - 2002/04/17
* Fixed bug where selection offset was being ignored for certain hyperslab
selections when optimized I/O was being performed. QAK - 2002/04/02
* Added serial multi-gigabyte file size test. "test/big -h" shows
diff --git a/src/H5D.c b/src/H5D.c
index 63e6e06..26cc9e3 100644
--- a/src/H5D.c
+++ b/src/H5D.c
@@ -3007,6 +3007,7 @@ printf("%s: check 2.0, src_type_size=%d, dst_type_size=%d, target_size=%d\n",FUN
#ifdef QAK
printf("%s: check 4.0, nelmts=%d, request_nelmts=%d, need_bkg=%d\n", FUNC,(int)nelmts,(int)request_nelmts,(int)need_bkg);
+ printf("%s: check 4.1, tconv_buf=%p, bkg_buf=%p\n",FUNC,tconv_buf,bkg_buf);
#endif
/* Start strip mining... */
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);
diff --git a/test/Makefile.in b/test/Makefile.in
index 97d8302..5707005 100644
--- a/test/Makefile.in
+++ b/test/Makefile.in
@@ -50,7 +50,7 @@ MOSTLYCLEAN=cmpd_dset.h5 dataset.h5 extend.h5 istore.h5 tfile1.h5 tfile2.h5 \
mount_[0-9].h5 testmeta.h5 ttime.h5 trefer[12].h5 tvltypes.h5 \
tvlstr.h5 flush.h5 enum1.h5 titerate.h5 ttsafe.h5 tarray1.h5 \
tgenprop.h5 tmisc.h5 tmisc2a.h5 tmisc2b.h5 tmisc3.h5 tmisc4a.h5 \
- tmisc4b.h5 set_extent_read.h5 set_extent_create.h5
+ tmisc4b.h5 tmisc5.h5 set_extent_read.h5 set_extent_create.h5
CLEAN=$(TIMINGS)
## Source and object files for programs... The TEST_SRC list contains all the
diff --git a/test/tarray.c b/test/tarray.c
index 6b5e556..05bc8e0 100644
--- a/test/tarray.c
+++ b/test/tarray.c
@@ -1684,6 +1684,7 @@ test_array_bkg(void)
status = H5Dwrite (dataset, type, H5S_ALL, H5S_ALL, H5P_DEFAULT, fld);
CHECK(status, FAIL, "H5Dwrite");
+ /* Read just the field changed */
status = H5Dread (dataset, type, H5S_ALL, H5S_ALL, H5P_DEFAULT, fldr);
CHECK(status, FAIL, "H5Dread");
@@ -1695,15 +1696,47 @@ test_array_bkg(void)
continue;
}
- status = H5Dclose(dataset);
- CHECK(status, FAIL, "H5Dclose");
-
status = H5Tclose (type);
CHECK(status, FAIL, "H5Tclose");
status = H5Tclose (array_dt);
CHECK(status, FAIL, "H5Tclose");
+ type = H5Dget_type(dataset);
+ CHECK(type, FAIL, "H5Dget_type");
+
+ /* Read the entire dataset again */
+ status = H5Dread(dataset, type, H5S_ALL, H5S_ALL, H5P_DEFAULT, cfr);
+ CHECK(status, FAIL, "H5Dread");
+
+ /* Verify correct data */
+ /* ------------------- */
+ for (i = 0; i < LENGTH; i++) {
+ for (j = 0; j < ALEN; j++) {
+ if(cf[i].a[j]!=cfr[i].a[j]) {
+ num_errs++;
+ printf("Field a data doesn't match, cf[%d].a[%d]=%d, cfr[%d].a[%d]=%d\n",(int)i,(int)j,(int)cf[i].a[j],(int)i,(int)j,(int)cfr[i].a[j]);
+ continue;
+ }
+ if(cf[i].b[j]!=cfr[i].b[j]) {
+ num_errs++;
+ printf("Field b data doesn't match, cf[%d].b[%d]=%f, cfr[%d].b[%d]=%f\n",(int)i,(int)j,(float)cf[i].b[j],(int)i,(int)j,(float)cfr[i].b[j]);
+ continue;
+ }
+ if(cf[i].c[j]!=cfr[i].c[j]) {
+ num_errs++;
+ printf("Field c data doesn't match, cf[%d].b[%d]=%f, cfr[%d].b[%d]=%f\n",(int)i,(int)j,(float)cf[i].c[j],(int)i,(int)j,(float)cfr[i].c[j]);
+ continue;
+ }
+ }
+ }
+
+ status = H5Dclose(dataset);
+ CHECK(status, FAIL, "H5Dclose");
+
+ status = H5Tclose (type);
+ CHECK(status, FAIL, "H5Tclose");
+
status = H5Fclose(fid);
CHECK(status, FAIL, "H5Fclose");
diff --git a/test/tmisc.c b/test/tmisc.c
index 03ce311..3112e98 100644
--- a/test/tmisc.c
+++ b/test/tmisc.c
@@ -57,6 +57,55 @@ typedef struct {
#define MISC4_GROUP_1 "/Group1"
#define MISC4_GROUP_2 "/Group2"
+/* Definitions for misc. test #5 */
+#define MISC5_FILE "tmisc5.h5"
+#define MISC5_DSETNAME "dset1"
+#define MISC5_DSETRANK 1
+#define MISC5_NELMTOPLVL 1
+#define MISC5_DBGNELM1 2
+#define MISC5_DBGNELM2 1
+#define MISC5_DBGNELM3 1
+#define MISC5_DBGELVAL1 999999999
+#define MISC5_DBGELVAL2 888888888
+#define MISC5_DBGELVAL3 777777777
+
+typedef struct
+{
+ int st1_el1;
+ hvl_t st1_el2;
+} misc5_struct1;
+
+typedef struct
+{
+ int st2_el1;
+ hvl_t st2_el2;
+} misc5_struct2;
+
+typedef struct
+{
+ int st3_el1;
+} misc5_struct3;
+
+typedef struct
+{
+ hid_t st3h_base;
+ hid_t st3h_id;
+} misc5_struct3_hndl;
+
+typedef struct
+{
+ hid_t st2h_base;
+ hid_t st2h_id;
+ misc5_struct3_hndl *st2h_st3hndl;
+} misc5_struct2_hndl;
+
+typedef struct
+{
+ hid_t st1h_base;
+ hid_t st1h_id;
+ misc5_struct2_hndl *st1h_st2hndl;
+} misc5_struct1_hndl;
+
/****************************************************************
**
** test_misc1(): test unlinking a dataset from a group and immediately
@@ -440,6 +489,314 @@ test_misc4(void)
/****************************************************************
**
+** test_misc5(): Test several level deep nested compound & VL datatypes
+**
+****************************************************************/
+
+/*********************** struct3 ***********************/
+
+static misc5_struct3_hndl *
+create_struct3(void)
+{
+ misc5_struct3_hndl *str3hndl; /* New 'struct3' created */
+ herr_t ret; /* For error checking */
+
+ str3hndl=malloc(sizeof(misc5_struct3_hndl));
+ CHECK(str3hndl,NULL,"malloc");
+
+ str3hndl->st3h_base=H5Tcreate( H5T_COMPOUND, sizeof(misc5_struct3));
+ CHECK(str3hndl->st3h_base,FAIL,"H5Tcreate");
+
+ ret=H5Tinsert(str3hndl->st3h_base, "st3_el1", HOFFSET( misc5_struct3, st3_el1), H5T_NATIVE_INT);
+ CHECK(ret,FAIL,"H5Tinsert");
+
+ str3hndl->st3h_id=H5Tvlen_create(str3hndl->st3h_base);
+ CHECK(str3hndl->st3h_id,FAIL,"H5Tvlen_create");
+
+ return(str3hndl);
+}
+
+static void
+delete_struct3(misc5_struct3_hndl *str3hndl)
+{
+ herr_t ret; /* For error checking */
+
+ ret=H5Tclose(str3hndl->st3h_id);
+ CHECK(ret,FAIL,"H5Tclose");
+
+ ret=H5Tclose(str3hndl->st3h_base);
+ CHECK(ret,FAIL,"H5Tclose");
+
+ free(str3hndl);
+}
+
+static void
+set_struct3(misc5_struct3 *buf)
+{
+ buf->st3_el1=MISC5_DBGELVAL3;
+}
+
+/*********************** struct2 ***********************/
+
+static misc5_struct2_hndl *
+create_struct2(void)
+{
+ misc5_struct2_hndl *str2hndl; /* New 'struct2' created */
+ herr_t ret; /* For error checking */
+
+ str2hndl=malloc(sizeof(misc5_struct2_hndl));
+ CHECK(str2hndl,NULL,"malloc");
+
+ str2hndl->st2h_base=H5Tcreate( H5T_COMPOUND, sizeof(misc5_struct2));
+ CHECK(str2hndl->st2h_base,FAIL,"H5Tcreate");
+
+ ret=H5Tinsert(str2hndl->st2h_base, "st2_el1", HOFFSET( misc5_struct2, st2_el1), H5T_NATIVE_INT);
+ CHECK(ret,FAIL,"H5Tinsert");
+
+ str2hndl->st2h_st3hndl=create_struct3();
+ CHECK(str2hndl->st2h_st3hndl,NULL,"create_struct3");
+
+ ret=H5Tinsert(str2hndl->st2h_base, "st2_el2", HOFFSET(misc5_struct2, st2_el2), str2hndl->st2h_st3hndl->st3h_id);
+ CHECK(ret,FAIL,"H5Tinsert");
+
+ str2hndl->st2h_id= H5Tvlen_create(str2hndl->st2h_base);
+ CHECK(str2hndl->st2h_id,FAIL,"H5Tvlen_create");
+
+ return(str2hndl);
+}
+
+static void
+delete_struct2(misc5_struct2_hndl *str2hndl)
+{
+ herr_t ret; /* For error checking */
+
+ ret=H5Tclose(str2hndl->st2h_id);
+ CHECK(ret,FAIL,"H5Tclose");
+
+ delete_struct3(str2hndl->st2h_st3hndl);
+
+ H5Tclose(str2hndl->st2h_base);
+ CHECK(ret,FAIL,"H5Tclose");
+
+ free(str2hndl);
+}
+
+static void
+set_struct2(misc5_struct2 *buf)
+{
+ unsigned i; /* Local index variable */
+
+ buf->st2_el1=MISC5_DBGELVAL2;
+ buf->st2_el2.len=MISC5_DBGNELM3;
+
+ buf->st2_el2.p=malloc((buf->st2_el2.len)*sizeof(misc5_struct3));
+ CHECK(buf->st2_el2.p,NULL,"malloc");
+
+ for(i=0; i<(buf->st2_el2.len); i++)
+ set_struct3(&(((misc5_struct3 *)(buf->st2_el2.p))[i]));
+}
+
+static void
+clear_struct2(misc5_struct2 *buf)
+{
+ free(buf->st2_el2.p);
+}
+
+/*********************** struct1 ***********************/
+
+static misc5_struct1_hndl *
+create_struct1(void)
+{
+ misc5_struct1_hndl *str1hndl; /* New 'struct1' created */
+ herr_t ret; /* For error checking */
+
+ str1hndl=malloc(sizeof(misc5_struct1_hndl));
+ CHECK(str1hndl,NULL,"malloc");
+
+ str1hndl->st1h_base=H5Tcreate(H5T_COMPOUND, sizeof(misc5_struct1));
+ CHECK(str1hndl->st1h_base,FAIL,"H5Tcreate");
+
+ ret=H5Tinsert(str1hndl->st1h_base, "st1_el1", HOFFSET(misc5_struct1, st1_el1), H5T_NATIVE_INT);
+ CHECK(ret,FAIL,"H5Tinsert");
+
+ str1hndl->st1h_st2hndl=create_struct2();
+ CHECK(str1hndl->st1h_st2hndl,NULL,"create_struct2");
+
+ ret=H5Tinsert(str1hndl->st1h_base, "st1_el2", HOFFSET(misc5_struct1, st1_el2), str1hndl->st1h_st2hndl->st2h_id);
+ CHECK(ret,FAIL,"H5Tinsert");
+
+ str1hndl->st1h_id=H5Tvlen_create(str1hndl->st1h_base);
+ CHECK(str1hndl->st1h_id,FAIL,"H5Tvlen_create");
+
+ return(str1hndl);
+}
+
+static void
+delete_struct1(misc5_struct1_hndl *str1hndl)
+{
+ herr_t ret; /* For error checking */
+
+ ret=H5Tclose(str1hndl->st1h_id);
+ CHECK(ret,FAIL,"H5Tclose");
+
+ delete_struct2(str1hndl->st1h_st2hndl);
+
+ ret=H5Tclose(str1hndl->st1h_base);
+ CHECK(ret,FAIL,"H5Tclose");
+
+ free(str1hndl);
+}
+
+static void
+set_struct1(misc5_struct1 *buf)
+{
+ unsigned i; /* Local index variable */
+
+ buf->st1_el1=MISC5_DBGELVAL1;
+ buf->st1_el2.len=MISC5_DBGNELM2;
+
+ buf->st1_el2.p=malloc((buf->st1_el2.len)*sizeof(misc5_struct2));
+ CHECK(buf->st1_el2.p,NULL,"malloc");
+
+ for(i=0; i<(buf->st1_el2.len); i++)
+ set_struct2(&(((misc5_struct2 *)(buf->st1_el2.p))[i]));
+}
+
+static void
+clear_struct1(misc5_struct1 *buf)
+{
+ unsigned i;
+
+ for(i=0;i<buf->st1_el2.len;i++)
+ clear_struct2(&((( misc5_struct2 *)(buf->st1_el2.p))[i]));
+ free(buf->st1_el2.p);
+}
+
+static void
+test_misc5(void)
+{
+ hid_t loc_id, space_id, dataset_id;
+ hid_t mem_type_id;
+ misc5_struct1_hndl *str1hndl;
+ hsize_t dims[MISC5_DSETRANK];
+ hvl_t buf;
+ unsigned i,j,k;
+ herr_t ret;
+
+ /* Output message about test being performed */
+ MESSAGE(5, ("Testing several level deep nested compound & VL datatypes \n"));
+
+ /* Write the dataset out */
+ loc_id=H5Fcreate(MISC5_FILE, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT);
+ CHECK(loc_id,FAIL,"H5Fcreate");
+
+ /* Create the memory structure to write */
+ str1hndl=create_struct1();
+ CHECK(str1hndl,NULL,"create_struct1");
+
+ /* Create the dataspace */
+ dims[0]=MISC5_NELMTOPLVL;
+ space_id=H5Screate_simple(MISC5_DSETRANK, dims, NULL);
+ CHECK(space_id,FAIL,"H5Screate_simple");
+
+ /* Create the dataset */
+ dataset_id=H5Dcreate(loc_id, MISC5_DSETNAME, str1hndl->st1h_id, space_id, H5P_DEFAULT);
+ CHECK(dataset_id,FAIL,"H5Dcreate");
+
+ /* Create the variable-length buffer */
+ buf.len=MISC5_DBGNELM1;
+ buf.p=malloc((buf.len)*sizeof(misc5_struct1));
+ CHECK(buf.p,NULL,"malloc");
+
+ /* Create the top-level VL information */
+ for(i=0; i<MISC5_DBGNELM1; i++)
+ set_struct1(&(((misc5_struct1 *) (buf.p))[i]));
+
+ /* Write the data out */
+ ret=H5Dwrite(dataset_id, str1hndl->st1h_id, H5S_ALL, H5S_ALL, H5P_DEFAULT, &buf);
+ CHECK(ret,FAIL,"H5Dwrite");
+
+ /* Release the top-level VL information */
+ for(j=0; j<MISC5_DBGNELM1; j++)
+ clear_struct1(&((( misc5_struct1 *)(buf.p))[j]));
+
+ /* Free the variable-length buffer */
+ free(buf.p);
+
+ /* Close dataset */
+ ret=H5Dclose(dataset_id);
+ CHECK(ret,FAIL,"H5Dclose");
+
+ /* Close dataspace */
+ ret=H5Sclose(space_id);
+ CHECK(ret,FAIL,"H5Sclose");
+
+ /* Delete memory structures */
+ delete_struct1(str1hndl);
+
+ /* Close file */
+ ret=H5Fclose(loc_id);
+ CHECK(ret,FAIL,"H5Fclose");
+
+
+ /* Read the dataset back in & verify it */
+ loc_id=H5Fopen(MISC5_FILE, H5F_ACC_RDONLY, H5P_DEFAULT);
+ CHECK(loc_id,FAIL,"H5Fopen");
+
+ /* Open dataset again */
+ dataset_id=H5Dopen(loc_id, MISC5_DSETNAME);
+ CHECK(dataset_id,FAIL,"H5Dopen");
+
+ /* Get the dataset's datatype */
+ mem_type_id=H5Dget_type(dataset_id);
+ CHECK(mem_type_id,FAIL,"H5Dget_type");
+
+ /* Get the dataset's dataspace */
+ space_id=H5Dget_space(dataset_id);
+ CHECK(space_id,FAIL,"H5Dget_space");
+
+ /* Read the data back in */
+ ret=H5Dread(dataset_id, mem_type_id, H5S_ALL, H5S_ALL, H5P_DEFAULT, &buf);
+ CHECK(ret,FAIL,"H5Dread");
+
+ /* Verify the correct information was read in */
+ for(i=0; i<(buf.len); i++) {
+ /* printf("[%d]=%d\n",i, ((misc5_struct1 *)(buf.p))[i].st1_el1); */
+ VERIFY(((misc5_struct1 *)(buf.p))[i].st1_el1,MISC5_DBGELVAL1,"H5Dread");
+ for(j=0; j<(((misc5_struct1 *)(buf.p)) [i].st1_el2.len); j++) {
+ /* printf(" [%d]=%d\n",j, ((misc5_struct2 *)(((misc5_struct1 *) (buf.p))[i].st1_el2.p))[j].st2_el1); */
+ VERIFY(((misc5_struct2 *)(((misc5_struct1 *) (buf.p))[i].st1_el2.p))[j].st2_el1, MISC5_DBGELVAL2,"H5Dread");
+ for(k=0; k<(((misc5_struct2 *) (((misc5_struct1 *)(buf.p))[i]. st1_el2.p))[j].st2_el2.len); k++) {
+ /* printf(" [%d]=%d\n",k, ((misc5_struct3 *)(((misc5_struct2 *) (((misc5_struct1 *)(buf.p))[i]. st1_el2.p))[j].st2_el2.p))[k].st3_el1); */
+ VERIFY(((misc5_struct3 *)(((misc5_struct2 *) (((misc5_struct1 *)(buf.p))[i]. st1_el2.p))[j].st2_el2.p))[k].st3_el1, MISC5_DBGELVAL3,"H5Dread");
+ } /* end for */
+ }
+ }
+
+ /* Reclaim the memory for the VL information */
+ ret=H5Dvlen_reclaim(mem_type_id, space_id, H5P_DEFAULT, &buf);
+ CHECK(ret,FAIL,"H5Dvlen_reclaim");
+
+ /* Close dataspace */
+ ret=H5Sclose(space_id);
+ CHECK(ret,FAIL,"H5Sclose");
+
+ /* Close dataset */
+ ret=H5Tclose(mem_type_id);
+ CHECK(ret,FAIL,"H5Tclose");
+
+ /* Close dataset */
+ ret=H5Dclose(dataset_id);
+ CHECK(ret,FAIL,"H5Dclose");
+
+ /* Close file */
+ ret=H5Fclose(loc_id);
+ CHECK(ret,FAIL,"H5Fclose");
+
+} /* end test_misc5() */
+
+/****************************************************************
+**
** test_misc(): Main misc. test routine.
**
****************************************************************/
@@ -453,6 +810,7 @@ test_misc(void)
test_misc2(); /* Test storing a VL-derived datatype in two different files */
test_misc3(); /* Test reading from chunked dataset with non-zero fill value */
test_misc4(); /* Test retrieving the fileno for various objects with H5Gget_objinfo() */
+ test_misc5(); /* Test several level deep nested compound & VL datatypes */
} /* test_misc() */
@@ -480,4 +838,5 @@ cleanup_misc(void)
remove(MISC3_FILE);
remove(MISC4_FILE_1);
remove(MISC4_FILE_2);
+ remove(MISC5_FILE);
}