summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--hl/src/H5DS.c329
-rw-r--r--hl/src/H5DS.h15
-rw-r--r--hl/test/test_ds.c304
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;
+}
+