diff options
-rw-r--r-- | hl/src/H5DS.c | 329 | ||||
-rw-r--r-- | hl/src/H5DS.h | 15 | ||||
-rw-r--r-- | hl/test/test_ds.c | 304 |
3 files changed, 606 insertions, 42 deletions
diff --git a/hl/src/H5DS.c b/hl/src/H5DS.c index 3bec833..e3b9014 100644 --- a/hl/src/H5DS.c +++ b/hl/src/H5DS.c @@ -10,6 +10,7 @@ * * ****************************************************************************/ + #include "H5DS.h" #include "H5LT.h" #include <stdlib.h> @@ -139,6 +140,10 @@ herr_t H5DSattach_scale(hid_t did, if (H5Sclose(sid)<0) goto out; + /* parameter range checking */ + if (idx>(unsigned)rank-1) + goto out; + /*------------------------------------------------------------------------- * two references are created: one to the DS, saved in "DIMENSION_LIST" * and one to the dataset, saved in "REFERENCE_LIST" @@ -1212,28 +1217,34 @@ herr_t H5DShas_scale(hid_t did) { /* get the reference */ ref = ((hobj_ref_t *)buf[i].p)[0]; - - /* get the DS id */ - if ((dsid = H5Rdereference(did,H5R_OBJECT,&ref))<0) - goto out; - - /* check information in referenced dataset */ - if ((dssid = H5Dget_space(dsid))<0) - goto out; - - /* get size of the DS array */ - if ((dsnelmts = H5Sget_simple_extent_npoints(dssid))<0) - goto out; - - /* the size of the DS array must match the dimension of the dataset */ - if (dsnelmts != (hssize_t)dims[i]) + + if (ref==0) has_ds = 0; - - /* close the dereferenced dataset */ - if (H5Dclose(dsid)<0) - goto out; - if (H5Sclose(dssid)<0) - goto out; + + if (ref) + { + /* get the DS id */ + if ((dsid = H5Rdereference(did,H5R_OBJECT,&ref))<0) + goto out; + + /* check information in referenced dataset */ + if ((dssid = H5Dget_space(dsid))<0) + goto out; + + /* get size of the DS array */ + if ((dsnelmts = H5Sget_simple_extent_npoints(dssid))<0) + goto out; + + /* the size of the DS array must match the dimension of the dataset */ + if (dsnelmts != (hssize_t)dims[i]) + has_ds = 0; + + /* close the dereferenced dataset */ + if (H5Dclose(dsid)<0) + goto out; + if (H5Sclose(dssid)<0) + goto out; + } } } @@ -1265,3 +1276,279 @@ out: } + + +/*------------------------------------------------------------------------- + * Function: H5DSget_nscales + * + * Purpose: get the number of scales linked to the IDX dimension of DNAME + * + * Return: + * Success: SUCCESS: both the DS and the dataset exist + * Failure: FAIL: if either one of them does not exist + * + * Programmer: pvn@ncsa.uiuc.edu + * + * Date: January 13, 2005 + * + * Comments: + * + * Modifications: + * + *------------------------------------------------------------------------- + */ + +herr_t H5DSget_nscales(hid_t did, + unsigned int dim, + int *nscales) +{ + int has_dimlist; + hid_t sid; /* space ID */ + hid_t tid; /* attribute type ID */ + hid_t aid; /* attribute ID */ + int rank; /* rank of dataset */ + hvl_t *buf; /* VL buffer to store in the attribute */ + hobj_ref_t ref; /* reference to the DS */ + int i, n; + +/*------------------------------------------------------------------------- + * the attribute "DIMENSION_LIST" on the >>data<< dataset must exist + *------------------------------------------------------------------------- + */ + /* get dataset space */ + if ((sid = H5Dget_space(did))<0) + goto out; + + /* get rank */ + if ((rank=H5Sget_simple_extent_ndims(sid))<0) + goto out; + + /* close dataset space */ + if (H5Sclose(sid)<0) + goto out; + + /* DIM range checking */ + if (dim>=(unsigned int )rank) + goto out; + + /* try to find the attribute "DIMENSION_LIST" on the >>data<< dataset */ + if ((has_dimlist = H5LT_find_attribute(did,DIMENSION_LIST))<0) + return FAIL; + + /* it does not exist */ + if (has_dimlist == 0) + goto out; + +/*------------------------------------------------------------------------- + * the attribute exists, open it + *------------------------------------------------------------------------- + */ + + else if ( has_dimlist == 1 ) + { + if ((aid = H5Aopen_name(did,DIMENSION_LIST))<0) + goto out; + if ((tid = H5Aget_type(aid))<0) + goto out; + if ((sid = H5Aget_space(aid))<0) + goto out; + + /* allocate and initialize the VL */ + buf = (hvl_t*)malloc((size_t)rank * sizeof(hvl_t)); + + if (buf == NULL) + goto out; + + /* read */ + if (H5Aread(aid,tid,buf)<0) + goto out; + + for(i=0,n=0; i<buf[dim].len; i++) + { + ref = ((hobj_ref_t *)buf[dim].p)[i]; + if (ref) n++; + } + /* return value */ + *nscales =n; + + /* close */ + if (H5Dvlen_reclaim(tid,sid,H5P_DEFAULT,buf)<0) + goto out; + if (H5Sclose(sid)<0) + goto out; + if (H5Tclose(tid)<0) + goto out; + if (H5Aclose(aid)<0) + goto out; + if (buf) + free(buf); + + } /* has_dimlist */ + + return SUCCESS; + +/* error zone, gracefully close */ +out: + H5E_BEGIN_TRY { + H5Dclose(did); + H5Sclose(sid); + H5Aclose(aid); + H5Tclose(tid); + } H5E_END_TRY; + return FAIL; + +} + +/*------------------------------------------------------------------------- + * Function: H5DSiterate_scales + * + * Purpose: H5DSiterate_scales iterates over the scales attached to dimension dim + * of dataset dset. For each scale in the list, the visitor_data and some + * additional information, specified below, are passed to the visitor function. + * The iteration begins with the idx object in the group and the next element + * to be processed by the operator is returned in idx. If idx is NULL, then the + * iterator starts at zero. + * + * Parameters: + * + * hid_t DID; IN: the dataset + * unsigned int dim; IN: the dimension of dset + * int *idx; IN/OUT: input the index to start iterating, output the next index + * to visit. If NULL, start at the first position. + * H5DS_iterate_t visitor; IN: the visitor function + * void *visitor_data; IN: arbitrary data to pass to the visitor function. + * + * Programmer: pvn@ncsa.uiuc.edu + * + * Date: January 31, 2005 + * + * Comments: + * + * Modifications: + * + *------------------------------------------------------------------------- + */ + +herr_t H5DSiterate_scales(hid_t did, + unsigned int dim, + int *idx, + H5DS_iterate_t visitor, + void *visitor_data ) +{ + hid_t scale_id; + int rank; + hobj_ref_t ref; /* reference to the DS */ + hid_t sid; /* space ID */ + hid_t tid; /* attribute type ID */ + hid_t aid; /* attribute ID */ + hvl_t *buf=NULL; /* VL buffer to store in the attribute */ + herr_t ret_value=0; + int j_idx; + int nscales; + int has_dimlist; + int i; + + /* get the number of scales assotiated with this DIM */ + if (H5DSget_nscales(did,dim,&nscales)<0) + goto out; + + /* get dataset space */ + if ((sid = H5Dget_space(did))<0) + goto out; + + /* get rank */ + if ((rank=H5Sget_simple_extent_ndims(sid))<0) + goto out; + + /* close dataset space */ + if (H5Sclose(sid)<0) + goto out; + + /* try to find the attribute "DIMENSION_LIST" on the >>data<< dataset */ + if ((has_dimlist = H5LT_find_attribute(did,DIMENSION_LIST))<0) + goto out; + + if (has_dimlist == 0) + return SUCCESS; + + else if (has_dimlist == 1 ) + { + if ((aid = H5Aopen_name(did,DIMENSION_LIST))<0) + goto out; + if ((tid = H5Aget_type(aid))<0) + goto out; + if ((sid = H5Aget_space(aid))<0) + goto out; + + /* allocate and initialize the VL */ + buf = (hvl_t*)malloc((size_t)rank * sizeof(hvl_t)); + + if (buf == NULL) + goto out; + + /* read */ + if (H5Aread(aid,tid,buf)<0) + goto out; + + if ( buf[dim].len > 0 ) + { + if (idx!=NULL) + j_idx = *idx; + else + j_idx=0; + + /* iterate */ + for(i=j_idx; i<nscales; i++) + { + /* get the reference */ + ref = ((hobj_ref_t *)buf[dim].p)[j_idx]; + + /* get the DS id */ + if ((scale_id = H5Rdereference(did,H5R_OBJECT,&ref))<0) + goto out; + + if((ret_value=(visitor)(did,dim,scale_id,visitor_data))==1) + { + /* close */ + if (H5Dvlen_reclaim(tid,sid,H5P_DEFAULT,buf)<0) + goto out; + if (H5Sclose(sid)<0) + goto out; + if (H5Tclose(tid)<0) + goto out; + if (H5Aclose(aid)<0) + goto out; + if (H5Dclose(scale_id)<0) + goto out; + if (buf) + free(buf); + return SUCCESS; + } /* if */ + } /* i */ + } /* if */ + + /* close */ + if (H5Dvlen_reclaim(tid,sid,H5P_DEFAULT,buf)<0) + goto out; + if (H5Sclose(sid)<0) + goto out; + if (H5Tclose(tid)<0) + goto out; + if (H5Aclose(aid)<0) + goto out; + if (H5Dclose(scale_id)<0) + goto out; + if (buf) + free(buf); + + if (ret_value<0) + goto out; + + } /* if has_dimlist */ + + return 0; + +out: + return FAIL; +} + diff --git a/hl/src/H5DS.h b/hl/src/H5DS.h index 0b4842f..d75e707 100644 --- a/hl/src/H5DS.h +++ b/hl/src/H5DS.h @@ -26,6 +26,8 @@ #define REFERENCE_LIST "REFERENCE_LIST" #define DIMENSION_LABELS "DIMENSION_LABELS" +typedef herr_t (*H5DS_iterate_t)(hid_t dset, unsigned dim, hid_t scale, void *visitor_data); + /* attribute type of a DS dataset */ typedef struct ds_list_t { @@ -38,7 +40,7 @@ typedef struct ds_list_t { extern "C" { #endif - herr_t H5DSset_scale(hid_t did, +herr_t H5DSset_scale(hid_t did, char *dimname); herr_t H5DSattach_scale(hid_t did, @@ -65,6 +67,17 @@ herr_t H5DSis_scale(hid_t did); herr_t H5DShas_scale(hid_t did); +herr_t H5DSget_nscales(hid_t did, + unsigned int dim, + int *nscales); + + +herr_t H5DSiterate_scales(hid_t did, + unsigned int dim, + int *idx, + H5DS_iterate_t visitor, + void *visitor_data); + #ifdef __cplusplus } diff --git a/hl/test/test_ds.c b/hl/test/test_ds.c index 0f91e7f..64f8cff 100644 --- a/hl/test/test_ds.c +++ b/hl/test/test_ds.c @@ -17,6 +17,10 @@ #include "H5LT.h" #include <stdlib.h> +/* operator functions */ +static herr_t verifiy_scale(hid_t dset, unsigned dim, hid_t scale, void *visitor_data); +static herr_t read_scale(hid_t dset, unsigned dim, hid_t scale, void *visitor_data); + /*------------------------------------------------------------------------- @@ -34,8 +38,6 @@ #define DIM1_SIZE 3 #define DIM2_SIZE 4 - - /*------------------------------------------------------------------------- * the main program *------------------------------------------------------------------------- @@ -56,7 +58,9 @@ int main(void) int s1_wbuf[DIM1_SIZE] = {10,20,30}; /* data of DS 1 dataset */ int s2_wbuf[DIM2_SIZE] = {100,200,300,400}; /* data of DS 2 dataset */ char s1_label[16]; /* read label for DS 1 */ - char s2_label[16]; /* read label for DS 1 */ + char s2_label[16]; /* read label for DS 2 */ + unsigned int dim; /* dataset dimension index */ + int scale_idx; /* scale index */ /*------------------------------------------------------------------------- * create a file for the test @@ -293,32 +297,95 @@ int main(void) * test 3: detach scales *------------------------------------------------------------------------- */ - + TESTING("detach scales "); - + +/*------------------------------------------------------------------------- + * create 3 datasets: one "data" dataset and 2 dimension scales + *------------------------------------------------------------------------- + */ + + /* make a dataset */ + if (H5LTmake_dataset_int(fid,"dset_c",rank,dims,buf)<0) + goto out; + + /* make a DS dataset for the first dimension */ + if (H5LTmake_dataset_int(fid,"ds3",rankds,s1_dim,s1_wbuf)<0) + goto out; + + /* make a DS dataset for the second dimension */ + if (H5LTmake_dataset_int(fid,"ds4",rankds,s2_dim,s2_wbuf)<0) + goto out; + /*------------------------------------------------------------------------- - * detach the "ds21" dimension scale to "dset_a" + * attach "ds3" and "ds4" to "dset_c" *------------------------------------------------------------------------- */ - /* get the dataset id for "dset_a" */ - if ((did = H5Dopen(fid,"dset_a"))<0) + if ((did = H5Dopen(fid,"dset_c"))<0) + goto out; + if ((dsid = H5Dopen(fid,"ds3"))<0) + goto out; + if (H5DSattach_scale(did,dsid,0)<0) + goto out; + if (H5Dclose(dsid)<0) + goto out; + if ((dsid = H5Dopen(fid,"ds4"))<0) + goto out; + if (H5DSattach_scale(did,dsid,1)<0) + goto out; + if (H5Dclose(dsid)<0) + goto out; + if (H5Dclose(did)<0) + goto out; + +/*------------------------------------------------------------------------- + * verify if "dset_c" has dimension scales + *------------------------------------------------------------------------- + */ + + if ((did = H5Dopen(fid,"dset_c"))<0) + goto out; + if ((H5DShas_scale(did))==0) + goto out; + if (H5Dclose(did)<0) + goto out; + +/*------------------------------------------------------------------------- + * detach the "ds3" dimension scale to "dset_c" + *------------------------------------------------------------------------- + */ + + /* get the dataset id for "dset_c" */ + if ((did = H5Dopen(fid,"dset_c"))<0) goto out; /* get the DS dataset id */ - if ((dsid = H5Dopen(fid,"ds21"))<0) + if ((dsid = H5Dopen(fid,"ds3"))<0) goto out; - /* detach the "ds21" dimension scale to "dset_a" at index 1 */ - if (H5DSdetach_scale(did,dsid,1)<0) + /* detach the "ds3" dimension scale to "dset_c" at index 0 */ + if (H5DSdetach_scale(did,dsid,0)<0) goto out; /* close DS id */ if (H5Dclose(dsid)<0) goto out; - /* close dataset ID of "dset_a" */ + /* close dataset ID of "dset_c" */ + if (H5Dclose(did)<0) + goto out; + +/*------------------------------------------------------------------------- + * verify that "dset_c" has NOT dimension scales + *------------------------------------------------------------------------- + */ + + if ((did = H5Dopen(fid,"dset_c"))<0) + goto out; + if ((H5DShas_scale(did))==1) + goto out; if (H5Dclose(did)<0) goto out; @@ -365,19 +432,19 @@ int main(void) TESTING("set scale/get scale name"); /*------------------------------------------------------------------------- - * make a dataset named "ds3" and convert it to a DS dataset + * make a dataset named "ds5" and convert it to a DS dataset *------------------------------------------------------------------------- */ - if (H5LTmake_dataset_int(fid,"ds3",rankds,s1_dim,s1_wbuf)<0) + if (H5LTmake_dataset_int(fid,"ds5",rankds,s1_dim,s1_wbuf)<0) goto out; - if ((did = H5Dopen(fid,"ds3"))<0) + if ((did = H5Dopen(fid,"ds5"))<0) goto out; if (H5DSset_scale(did,"scale 1")<0) goto out; - /* verify that "ds3" is a dimension scale dataset */ + /* verify that "ds5" is a dimension scale dataset */ if ((H5DSis_scale(did))==0) goto out; @@ -397,8 +464,68 @@ int main(void) PASSED(); +/*------------------------------------------------------------------------- + * test 6: test iterate scales with a function verifiy_scale + *------------------------------------------------------------------------- + */ + TESTING("iterate scales"); + + /* get the dataset id for "dset_a" */ + if ((did = H5Dopen(fid,"dset_a"))<0) + goto out; + + dim = 0; + + /* iterate trough the 1st dimension of "dset_a" and verify that its DS is valid */ + if (H5DSiterate_scales(did,dim,NULL,verifiy_scale,NULL)<0) + goto out; + + /* iterate trough the 2nd dimension of "dset_a" and verify that its DS is valid + start at DS index 2 */ + dim = 1; + scale_idx = 2; + + if (H5DSiterate_scales(did,dim,&scale_idx,verifiy_scale,NULL)<0) + goto out; + + /* close dataset ID of "dset_a" */ + if (H5Dclose(did)<0) + goto out; + + PASSED(); + + +/*------------------------------------------------------------------------- + * test 6: test iterate scales with a function read_scale + *------------------------------------------------------------------------- + */ + TESTING("read scale values with iterate scales"); + + /* get the dataset id for "dset_a" */ + if ((did = H5Dopen(fid,"dset_a"))<0) + goto out; + + dim = 0; + + /* iterate trough the 1st dimension of "dset_a" and read the DS */ + if (H5DSiterate_scales(did,dim,NULL,read_scale,s1_wbuf)<0) + goto out; + + /* iterate trough the 2nd dimension of "dset_a" and read the DS + start at DS index 2 */ + dim = 1; + scale_idx = 2; + + if (H5DSiterate_scales(did,dim,&scale_idx,read_scale,s2_wbuf)<0) + goto out; + + /* close dataset ID of "dset_a" */ + if (H5Dclose(did)<0) + goto out; + + PASSED(); + - /*------------------------------------------------------------------------- * end *------------------------------------------------------------------------- @@ -407,10 +534,7 @@ int main(void) /* close */ H5Fclose(fid); - - return 0; - /* error zone, gracefully close */ out: @@ -422,3 +546,143 @@ out: return 1; } + + + +/*------------------------------------------------------------------------- + * Function: verifiy_scale + * + * Purpose: example operator function used by H5DSiterate_scales, used + * to veify that SCALE_ID refers to a valid DS dataset + * + * Return: + * The return values from an operator are: + * Zero causes the iterator to continue, returning zero when all group members have been processed. + * Positive causes the iterator to immediately return that positive value, indicating + * short-circuit success. The iterator can be restarted at the next group member. + * Negative causes the iterator to immediately return that value, indicating failure. + * The iterator can be restarted at the next group member. + * + *------------------------------------------------------------------------- + */ + +static herr_t verifiy_scale(hid_t dset, unsigned dim, hid_t scale_id, void *visitor_data) +{ + + /* define a default zero value for return. This will cause the iterator to continue */ + + int ret = 0; + + /* unused */ + dset=dset; + dim=dim; + visitor_data=visitor_data; + + /* define a positive value for return value. This will cause the iterator to + immediately return that positive value, indicating short-circuit success + */ + + /* the parameter DS dataset must be a valid DS dataset */ + if ((H5DSis_scale(scale_id))==1) + { + ret = 1; + } + + return ret; +} + + +/*------------------------------------------------------------------------- + * Function: read_scale + * + * Purpose: example operator function used by H5DSiterate_scales, used + * to read data from DS dataset. compare read and write buffers + * + * Return: + * The return values from an operator are: + * Zero causes the iterator to continue, returning zero when all group members have been processed. + * Positive causes the iterator to immediately return that positive value, indicating + * short-circuit success. The iterator can be restarted at the next group member. + * Negative causes the iterator to immediately return that value, indicating failure. + * The iterator can be restarted at the next group member + * + * + *------------------------------------------------------------------------- + */ + +static herr_t read_scale(hid_t dset, unsigned dim, hid_t scale_id, void *visitor_data) +{ + int ret = 0; /* define a default zero value for return. This will cause the iterator to continue */ + hid_t sid; /* space ID */ + hid_t tid; /* file type ID */ + hid_t mtid; /* memory type ID */ + hssize_t nelmts; /* number of data elements */ + char *buf=NULL; /* data buffer */ + size_t size; + int i; + char *data=visitor_data; + + /* unused */ + dset=dset; + dim=dim; + + /* get space */ + if ((sid = H5Dget_space(scale_id))<0) + goto out; + /* get type */ + if ((tid = H5Dget_type(scale_id))<0) + goto out; + /* get size of the DS array */ + if ((nelmts = H5Sget_simple_extent_npoints(sid))<0) + goto out; + /* get type */ + if ((mtid=H5Tget_native_type(tid,H5T_DIR_DEFAULT))<0) + goto out; + /* get type size */ + if ((size=H5Tget_size(mtid))==0) + goto out; + + if (nelmts) + { + buf=(char *) malloc((unsigned)(nelmts*size)); + if ( buf==NULL) + goto out; + if (H5Dread(scale_id,mtid,H5S_ALL,H5S_ALL,H5P_DEFAULT,buf)<0) + goto out; + + for(i=0; i<nelmts; i++) + { + if (buf[i] != data[i]) + { + printf("read and write buffers differ\n"); + goto out; + } + } + + } /* if */ + + if (H5Sclose(sid)<0) + goto out; + if (H5Tclose(tid)<0) + goto out; + if (H5Tclose(mtid)<0) + goto out; + if (buf) + free(buf); + + + return ret; + + /* error zone, gracefully close */ + out: + H5E_BEGIN_TRY { + H5Sclose(sid); + H5Tclose(tid); + H5Tclose(mtid); + if (buf) + free(buf); + } H5E_END_TRY; + + return FAIL; +} + |