diff options
-rw-r--r-- | release_docs/RELEASE.txt | 3 | ||||
-rw-r--r-- | src/H5D.c | 1 | ||||
-rw-r--r-- | src/H5Tconv.c | 95 | ||||
-rw-r--r-- | test/Makefile.in | 2 | ||||
-rw-r--r-- | test/tarray.c | 39 | ||||
-rw-r--r-- | test/tmisc.c | 359 |
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 @@ -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); } |