summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/H5Dchunk.c12
-rw-r--r--src/H5Dint.c27
-rw-r--r--src/H5Pdcpl.c7
-rw-r--r--src/H5S.c30
-rw-r--r--src/H5Spoint.c4
-rw-r--r--test/th5s.c546
6 files changed, 575 insertions, 51 deletions
diff --git a/src/H5Dchunk.c b/src/H5Dchunk.c
index e7a5bf1..64efc8a 100644
--- a/src/H5Dchunk.c
+++ b/src/H5Dchunk.c
@@ -378,8 +378,9 @@ done:
static herr_t
H5D_chunk_construct(H5F_t UNUSED *f, H5D_t *dset)
{
- const H5T_t *type = dset->shared->type; /* Convenience pointer to dataset's datatype */
- hsize_t max_dim[H5O_LAYOUT_NDIMS]; /* Maximum size of data in elements */
+ const H5T_t *type = dset->shared->type; /* Convenience pointer to dataset's datatype */
+ hsize_t max_dims[H5O_LAYOUT_NDIMS]; /* Maximum size of data in elements */
+ hsize_t dims[H5O_LAYOUT_NDIMS]; /* Dimension size of data in elements */
uint64_t chunk_size; /* Size of chunk in bytes */
int ndims; /* Rank of dataspace */
unsigned u; /* Local index variable */
@@ -413,7 +414,7 @@ H5D_chunk_construct(H5F_t UNUSED *f, H5D_t *dset)
dset->shared->layout.u.chunk.dim[dset->shared->layout.u.chunk.ndims - 1] = (uint32_t)H5T_GET_SIZE(type);
/* Get local copy of dataset dimensions (for sanity checking) */
- if(H5S_get_simple_extent_dims(dset->shared->space, NULL, max_dim) < 0)
+ if(H5S_get_simple_extent_dims(dset->shared->space, dims, max_dims) < 0)
HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to query maximum dimensions")
/* Sanity check dimensions */
@@ -424,9 +425,10 @@ H5D_chunk_construct(H5F_t UNUSED *f, H5D_t *dset)
/*
* The chunk size of a dimension with a fixed size cannot exceed
- * the maximum dimension size
+ * the maximum dimension size. If any dimension size is zero, there
+ * will be no such restriction.
*/
- if(max_dim[u] != H5S_UNLIMITED && max_dim[u] < dset->shared->layout.u.chunk.dim[u])
+ if(dims[u] && max_dims[u] != H5S_UNLIMITED && max_dims[u] < dset->shared->layout.u.chunk.dim[u])
HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "chunk size must be <= maximum dimension size for fixed-sized dimensions")
} /* end for */
diff --git a/src/H5Dint.c b/src/H5Dint.c
index 40f262c..8c73888 100644
--- a/src/H5Dint.c
+++ b/src/H5Dint.c
@@ -1628,16 +1628,23 @@ H5D_alloc_storage(H5D_t *dset/*in,out*/, hid_t dxpl_id, H5D_time_alloc_t time_al
case H5D_COMPACT:
/* Check if space is already allocated */
if(NULL == layout->storage.u.compact.buf) {
- /* Reserve space in layout header message for the entire array. */
- HDassert(layout->storage.u.compact.size > 0);
- if(NULL == (layout->storage.u.compact.buf = H5MM_malloc(layout->storage.u.compact.size)))
- HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "unable to allocate memory for compact dataset")
- if(!full_overwrite)
- HDmemset(layout->storage.u.compact.buf, 0, layout->storage.u.compact.size);
- layout->storage.u.compact.dirty = TRUE;
-
- /* Indicate that we should initialize storage space */
- must_init_space = TRUE;
+ /* Reserve space in layout header message for the entire array.
+ * Starting from the 1.8.7 release, we allow dataspace to have
+ * zero dimension size. So the storage size can be zero.
+ * SLU 2011/4/4 */
+ if(layout->storage.u.compact.size > 0) {
+ if(NULL == (layout->storage.u.compact.buf = H5MM_malloc(layout->storage.u.compact.size)))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "unable to allocate memory for compact dataset")
+ if(!full_overwrite)
+ HDmemset(layout->storage.u.compact.buf, 0, layout->storage.u.compact.size);
+ layout->storage.u.compact.dirty = TRUE;
+
+ /* Indicate that we should initialize storage space */
+ must_init_space = TRUE;
+ } else {
+ layout->storage.u.compact.dirty = FALSE;
+ must_init_space = FALSE;
+ }
} /* end if */
break;
diff --git a/src/H5Pdcpl.c b/src/H5Pdcpl.c
index d2aa8d5..6e20aed 100644
--- a/src/H5Pdcpl.c
+++ b/src/H5Pdcpl.c
@@ -966,6 +966,11 @@ done:
* Changed the way to check parameter and set property for
* generic property list.
*
+ * Raymond Lu
+ * 7 April 2011
+ * Starting from the 1.8.7 release, we allow dataspace to have
+ * zero dimension size. So the external storage size for
+ * dataset can be zero.
*-------------------------------------------------------------------------
*/
herr_t
@@ -985,8 +990,6 @@ H5Pset_external(hid_t plist_id, const char *name, off_t offset, hsize_t size)
HGOTO_ERROR (H5E_ARGS, H5E_BADVALUE, FAIL, "no name given")
if (offset<0)
HGOTO_ERROR (H5E_ARGS, H5E_BADVALUE, FAIL, "negative external file offset")
- if (size<=0)
- HGOTO_ERROR (H5E_ARGS, H5E_BADVALUE, FAIL, "zero size")
/* Get the plist structure */
if(NULL == (plist = H5P_object_verify(plist_id, H5P_DATASET_CREATE)))
diff --git a/src/H5S.c b/src/H5S.c
index e7cac9d..94fd72b 100644
--- a/src/H5S.c
+++ b/src/H5S.c
@@ -1160,14 +1160,17 @@ H5Sis_simple(hid_t space_id)
Christian Chilan 01/17/2007
Verifies that each element of DIMS is not equal to H5S_UNLIMITED.
+ Raymond Lu 03/30/2011
+ We allow 0-dimension for non-unlimited dimension starting from 1.8.7
+ release.
--------------------------------------------------------------------------*/
herr_t
H5Sset_extent_simple(hid_t space_id, int rank, const hsize_t dims[/*rank*/],
const hsize_t max[/*rank*/])
{
H5S_t *space; /* dataspace to modify */
- int u; /* local counting variable */
- herr_t ret_value=SUCCEED; /* Return value */
+ int u; /* local counting variable */
+ herr_t ret_value=SUCCEED; /* Return value */
FUNC_ENTER_API(H5Sset_extent_simple, FAIL)
H5TRACE4("e", "iIs*[a1]h*[a1]h", space_id, rank, dims, max);
@@ -1183,8 +1186,6 @@ H5Sset_extent_simple(hid_t space_id, int rank, const hsize_t dims[/*rank*/],
for (u=0; u<rank; u++) {
if (H5S_UNLIMITED==dims[u])
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "current dimension must have a specific size, not H5S_UNLIMITED")
- if (((max!=NULL && max[u]!=H5S_UNLIMITED) || max==NULL) && dims[u]==0)
- HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid dimension size")
}
}
if (max!=NULL) {
@@ -1303,6 +1304,11 @@ done:
* Programmer: Quincey Koziol
* Tuesday, January 27, 1998
*
+ * Modification:
+ * Raymond Lu 03/30/2011
+ * We allow 0-dimension for non-unlimited dimension starting
+ * from 1.8.7 release.
+ *
*-------------------------------------------------------------------------
*/
hid_t
@@ -1332,17 +1338,9 @@ H5Screate_simple(int rank, const hsize_t dims[/*rank*/],
for(i = 0; i < rank; i++) {
if(H5S_UNLIMITED == dims[i])
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "current dimension must have a specific size, not H5S_UNLIMITED")
- if(maxdims) {
- if(H5S_UNLIMITED != maxdims[i] && maxdims[i]<dims[i])
- HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "maxdims is smaller than dims")
- if(H5S_UNLIMITED != maxdims[i] && dims[i] == 0)
- HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "zero sized dimension for non-unlimited dimension")
- } /* end if */
- else {
- if(dims[i] == 0)
- HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "zero sized dimension for non-unlimited dimension")
- } /* end else */
- } /* end else */
+ if(maxdims && H5S_UNLIMITED != maxdims[i] && maxdims[i]<dims[i])
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "maxdims is smaller than dims")
+ } /* end for */
/* Create the space and set the extent */
if(NULL == (space = H5S_create_simple((unsigned)rank,dims,maxdims)))
@@ -1906,7 +1904,7 @@ H5S_set_extent_real(H5S_t *space, const hsize_t *size)
/* Change the dataspace size & re-compute the number of elements in the extent */
for(u = 0, nelem = 1; u < space->extent.rank; u++ ) {
space->extent.size[u] = size[u];
- nelem *= space->extent.size[u];
+ nelem *= size[u];
} /* end for */
space->extent.nelem = nelem;
diff --git a/src/H5Spoint.c b/src/H5Spoint.c
index cb7e98f..e544371 100644
--- a/src/H5Spoint.c
+++ b/src/H5Spoint.c
@@ -1551,8 +1551,8 @@ herr_t
H5Sselect_elements(hid_t spaceid, H5S_seloper_t op, size_t num_elem,
const hsize_t *coord)
{
- H5S_t *space; /* Dataspace to modify selection of */
- herr_t ret_value; /* Return value */
+ H5S_t *space; /* Dataspace to modify selection of */
+ herr_t ret_value; /* Return value */
FUNC_ENTER_API(H5Sselect_elements, FAIL)
H5TRACE4("e", "iSsz*h", spaceid, op, num_elem, coord);
diff --git a/test/th5s.c b/test/th5s.c
index 52fbe76..2aa4a92 100644
--- a/test/th5s.c
+++ b/test/th5s.c
@@ -33,11 +33,16 @@
#define DATAFILE "th5s1.h5"
#define NULLFILE "th5s2.h5"
#define BASICFILE "th5s3.h5"
-#define BASICDATASET "basic_dataset"
+#define ZEROFILE "th5s4.h5"
+#define BASICDATASET "basic_dataset"
+#define BASICDATASET1 "basic_dataset1"
#define BASICDATASET2 "basic_dataset2"
+#define BASICDATASET3 "basic_dataset3"
+#define BASICDATASET4 "basic_dataset4"
#define BASICATTR "basic_attribute"
#define NULLDATASET "null_dataset"
#define NULLATTR "null_attribute"
+#define EXTFILE_NAME "ext_file"
/* 3-D dataset with fixed dimensions */
#define SPACE1_RANK 3
@@ -87,7 +92,7 @@ test_h5s_basic(void)
hid_t fid1; /* HDF5 File IDs */
hid_t sid1, sid2; /* Dataspace ID */
hid_t dset1; /* Dataset ID */
- hid_t aid1; /* Attribute ID */
+ hid_t aid1; /* Attribute ID */
int rank; /* Logical rank of dataspace */
hsize_t dims1[] = {SPACE1_DIM1, SPACE1_DIM2, SPACE1_DIM3};
hsize_t dims2[] = {SPACE2_DIM1, SPACE2_DIM2, SPACE2_DIM3,
@@ -190,24 +195,10 @@ test_h5s_basic(void)
}
/* Verify that incorrect dimensions don't work */
- dims1[0]=0;
- sid1 = H5Screate_simple(SPACE1_RANK, dims1, NULL);
- VERIFY(sid1, FAIL, "H5Screate_simple");
-
dims1[0] = H5S_UNLIMITED;
sid1 = H5Screate_simple(SPACE1_RANK, dims1, NULL);
VERIFY(sid1, FAIL, "H5Screate_simple");
- dims1[0]=0;
- sid1 = H5Screate(H5S_SIMPLE);
- CHECK(sid1, FAIL, "H5Screate");
-
- ret = H5Sset_extent_simple(sid1,SPACE1_RANK,dims1,NULL);
- VERIFY(ret, FAIL, "H5Sset_extent_simple");
-
- ret = H5Sclose(sid1);
- CHECK_I(ret, "H5Sclose");
-
dims1[0] = H5S_UNLIMITED;
sid1 = H5Screate(H5S_SIMPLE);
CHECK(sid1, FAIL, "H5Screate");
@@ -524,6 +515,528 @@ test_h5s_null(void)
/****************************************************************
**
+** test_h5s_zero_dim(): Test the code for dataspace with zero dimension size
+**
+****************************************************************/
+static void
+test_h5s_zero_dim(void)
+{
+ hid_t fid1; /* HDF5 File IDs */
+ hid_t sid1, attr_sid; /* Dataspace ID */
+ hid_t dset1; /* Dataset ID */
+ hid_t plist_id; /* Dataset creation property list */
+ hid_t attr; /* Attribute ID */
+ int rank; /* Logical rank of dataspace */
+ hsize_t dims1[] = {SPACE1_DIM1, SPACE1_DIM2, SPACE1_DIM3};
+ hsize_t chunk_dims[] = {SPACE1_DIM1, SPACE1_DIM2/3, SPACE1_DIM3};
+ hsize_t tdims[SPACE1_RANK]; /* Dimension array to test with */
+ int wdata[SPACE1_DIM2][SPACE1_DIM3];
+ int rdata[SPACE1_DIM2][SPACE1_DIM3];
+ short wdata_short[SPACE1_DIM2][SPACE1_DIM3];
+ short rdata_short[SPACE1_DIM2][SPACE1_DIM3];
+ int wdata_real[SPACE1_DIM1][SPACE1_DIM2][SPACE1_DIM3];
+ int rdata_real[SPACE1_DIM1][SPACE1_DIM2][SPACE1_DIM3];
+ int val = 3;
+ hsize_t start[] = {0, 0, 0};
+ hsize_t count[] = {3, 15, 13};
+ hsize_t coord[1][3]; /* Coordinates for point selection */
+ hssize_t nelem; /* Number of elements */
+ H5S_sel_type sel_type; /* Type of selection currently */
+ H5S_class_t stype; /* dataspace type */
+ herr_t ret; /* Generic return value */
+ unsigned int i, j, k;
+
+ /* Output message about test being performed */
+ MESSAGE(5, ("Testing Dataspace with zero dimension size\n"));
+
+ /* Make sure we can create the space with the dimension size 0 (starting from v1.8.7).
+ * The dimension doesn't need to be unlimited. */
+ dims1[0]=0;
+ sid1 = H5Screate_simple(SPACE1_RANK, dims1, NULL);
+ CHECK(sid1, FAIL, "H5Screate_simple");
+
+ ret = H5Sclose(sid1);
+ CHECK(ret, FAIL, "H5Sclose");
+
+ sid1 = H5Screate(H5S_SIMPLE);
+ CHECK(sid1, FAIL, "H5Screate");
+
+ ret = H5Sset_extent_simple(sid1,SPACE1_RANK,dims1,NULL);
+ CHECK(ret, FAIL, "H5Sset_extent_simple");
+
+ /* Check that the dataspace actually has 0 elements */
+ nelem = H5Sget_simple_extent_npoints(sid1);
+ VERIFY(nelem, 0, "H5Sget_simple_extent_npoints");
+
+ /* Check that the dataspace was created with an "all" selection */
+ sel_type = H5Sget_select_type(sid1);
+ VERIFY(sel_type, H5S_SEL_ALL, "H5Sget_select_type");
+
+ /* Check that the dataspace has 0 elements selected */
+ nelem = H5Sget_select_npoints(sid1);
+ VERIFY(nelem, 0, "H5Sget_select_npoints");
+
+ /* Change to "none" selection */
+ ret = H5Sselect_none(sid1);
+ CHECK(ret, FAIL, "H5Sselect_none");
+
+ /* Check that the dataspace has 0 elements selected */
+ nelem = H5Sget_select_npoints(sid1);
+ VERIFY(nelem, 0, "H5Sget_select_npoints");
+
+ /* Try to select all dataspace */
+ ret = H5Sselect_all(sid1);
+ CHECK(ret, FAIL, "H5Sselect_all");
+
+ /* Check that the dataspace has 0 elements selected */
+ nelem = H5Sget_select_npoints(sid1);
+ VERIFY(nelem, 0, "H5Sget_select_npoints");
+
+ /*============================================
+ * Make sure we can use 0-dimension to create
+ * contiguous, chunked, compact, and external
+ * datasets, and also attribute.
+ *============================================
+ */
+ fid1 = H5Fcreate(ZEROFILE, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT);
+ CHECK(fid1, FAIL, "H5Fcreate");
+
+ /* Initialize the data */
+ for(i=0; i<SPACE1_DIM2; i++)
+ for(j=0; j<SPACE1_DIM3; j++) {
+ wdata[i][j] = i + j;
+ rdata[i][j] = 7;
+ wdata_short[i][j] = i + j;
+ rdata_short[i][j] = 7;
+ }
+
+ /* Contiguous dataset */
+ dset1 = H5Dcreate2(fid1, BASICDATASET, H5T_NATIVE_INT, sid1, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
+ CHECK(dset1, FAIL, "H5Dcreate2");
+
+ /* Write "nothing" to the dataset */
+ ret = H5Dwrite(dset1, H5T_NATIVE_INT, sid1, H5S_ALL, H5P_DEFAULT, wdata);
+ CHECK(ret, FAIL, "H5Dwrite");
+
+ ret = H5Fflush(fid1, H5F_SCOPE_GLOBAL);
+ CHECK(ret, FAIL, "H5Fflush");
+
+ /* Try reading from the dataset (make certain our buffer is unmodified) */
+ ret = H5Dread(dset1, H5T_NATIVE_INT, sid1, H5S_ALL, H5P_DEFAULT, rdata);
+ CHECK(ret, FAIL, "H5Dread");
+
+ /* Check results */
+ for(i=0; i<SPACE1_DIM2; i++) {
+ for(j=0; j<SPACE1_DIM3; j++) {
+ if(rdata[i][j] != 7) {
+ H5_FAILED();
+ printf("element [%d][%d] is %d but should have been 7\n",
+ i, j, rdata[i][j]);
+ }
+ }
+ }
+
+ /* Write "nothing" to the dataset (with type conversion :-) */
+ ret = H5Dwrite(dset1, H5T_NATIVE_SHORT, H5S_ALL, H5S_ALL, H5P_DEFAULT, wdata_short);
+ CHECK(ret, FAIL, "H5Dwrite");
+
+ ret = H5Fflush(fid1, H5F_SCOPE_GLOBAL);
+ CHECK(ret, FAIL, "H5Fflush");
+
+ /* Try reading from the dataset (make certain our buffer is unmodified) */
+ ret = H5Dread(dset1, H5T_NATIVE_INT, sid1, H5S_ALL, H5P_DEFAULT, rdata_short);
+ CHECK(ret, FAIL, "H5Dread");
+
+ /* Check results */
+ for(i=0; i<SPACE1_DIM2; i++) {
+ for(j=0; j<SPACE1_DIM3; j++) {
+ if(rdata_short[i][j] != 7) {
+ H5_FAILED();
+ printf("element [%d][%d] is %d but should have been 7\n",
+ i, j, rdata_short[i][j]);
+ }
+ }
+ }
+
+ /* Select a hyperslab beyond its current dimension sizes, then try to write
+ * the data. It should fail. */
+ ret = H5Sselect_hyperslab(sid1, H5S_SELECT_SET, start, NULL, count, NULL);
+ CHECK(ret, FAIL, "H5Sselect_hyperslab");
+
+ H5E_BEGIN_TRY {
+ ret = H5Dwrite(dset1, H5T_NATIVE_INT, H5S_ALL, sid1, H5P_DEFAULT, wdata);
+ } H5E_END_TRY;
+ VERIFY(ret, FAIL, "H5Dwrite");
+
+ /* Change to "none" selection */
+ ret = H5Sselect_none(sid1);
+ CHECK(ret, FAIL, "H5Sselect_none");
+
+ /* Select a point beyond the dimension size, then try to write the data.
+ * It should fail. */
+ coord[0][0]=2; coord[0][1]=5; coord[0][2]=3;
+ ret = H5Sselect_elements(sid1, H5S_SELECT_SET, (size_t)1, (const hsize_t *)coord);
+ CHECK(ret, FAIL, "H5Sselect_elements");
+
+ H5E_BEGIN_TRY {
+ ret = H5Dwrite(dset1, H5T_NATIVE_INT, H5S_ALL, sid1, H5P_DEFAULT, &val);
+ } H5E_END_TRY;
+ VERIFY(ret, FAIL, "H5Dwrite");
+
+ /* Restore the selection to all */
+ ret = H5Sselect_all(sid1);
+ CHECK(ret, FAIL, "H5Sselect_all");
+
+ ret = H5Dclose(dset1);
+ CHECK(ret, FAIL, "H5Dclose");
+
+ /* Chunked dataset */
+ plist_id = H5Pcreate(H5P_DATASET_CREATE);
+ CHECK(plist_id, FAIL, "H5Pcreate");
+
+ ret = H5Pset_chunk(plist_id, SPACE1_RANK, chunk_dims);
+ CHECK(ret, FAIL, "H5Pset_chunk");
+
+ dset1 = H5Dcreate2(fid1, BASICDATASET1, H5T_NATIVE_INT, sid1, H5P_DEFAULT, plist_id, H5P_DEFAULT);
+ CHECK(dset1, FAIL, "H5Dcreate2");
+
+ /* Write "nothing" to the dataset */
+ ret = H5Dwrite(dset1, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, wdata);
+ CHECK(ret, FAIL, "H5Dwrite");
+
+ ret = H5Fflush(fid1, H5F_SCOPE_GLOBAL);
+ CHECK(ret, FAIL, "H5Fflush");
+
+ /* Try reading from the dataset (make certain our buffer is unmodified) */
+ ret = H5Dread(dset1, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, rdata);
+ CHECK(ret, FAIL, "H5Dread");
+
+ /* Check results */
+ for(i=0; i<SPACE1_DIM2; i++)
+ for(j=0; j<SPACE1_DIM3; j++) {
+ if(rdata[i][j] != 7) {
+ H5_FAILED();
+ printf("element [%d][%d] is %d but should have been 7\n",
+ i, j, rdata[i][j]);
+ }
+ }
+
+ ret = H5Pclose(plist_id);
+ CHECK(ret, FAIL, "H5Pclose");
+
+ ret = H5Dclose(dset1);
+ CHECK(ret, FAIL, "H5Dclose");
+
+ /* Compact dataset */
+ plist_id = H5Pcreate(H5P_DATASET_CREATE);
+ CHECK(plist_id, FAIL, "H5Pcreate");
+
+ ret = H5Pset_layout(plist_id, H5D_COMPACT);
+ CHECK(ret, FAIL, "H5Pset_layout");
+
+ ret = H5Pset_alloc_time(plist_id, H5D_ALLOC_TIME_EARLY);
+ CHECK(ret, FAIL, "H5Pset_alloc_time");
+
+ dset1 = H5Dcreate2(fid1, BASICDATASET2, H5T_NATIVE_INT, sid1, H5P_DEFAULT, plist_id, H5P_DEFAULT);
+ CHECK(dset1, FAIL, "H5Dcreate2");
+
+ /* Write "nothing" to the dataset */
+ ret = H5Dwrite(dset1, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, wdata);
+ CHECK(ret, FAIL, "H5Dwrite");
+
+ ret = H5Fflush(fid1, H5F_SCOPE_GLOBAL);
+ CHECK(ret, FAIL, "H5Fflush");
+
+ /* Try reading from the dataset (make certain our buffer is unmodified) */
+ ret = H5Dread(dset1, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, rdata);
+ CHECK(ret, FAIL, "H5Dread");
+
+ /* Check results */
+ for(i=0; i<SPACE1_DIM2; i++)
+ for(j=0; j<SPACE1_DIM3; j++) {
+ if(rdata[i][j] != 7) {
+ H5_FAILED();
+ printf("element [%d][%d] is %d but should have been 7\n",
+ i, j, rdata[i][j]);
+ }
+ }
+
+ ret = H5Pclose(plist_id);
+ CHECK(ret, FAIL, "H5Pclose");
+
+ ret = H5Dclose(dset1);
+ CHECK(ret, FAIL, "H5Dclose");
+
+ /* Contiguous dataset with external storage */
+ plist_id = H5Pcreate(H5P_DATASET_CREATE);
+ CHECK(plist_id, FAIL, "H5Pcreate");
+
+ ret = H5Pset_layout(plist_id, H5D_CONTIGUOUS);
+ CHECK(ret, FAIL, "H5Pset_layout");
+
+ /* Change the DCPL for contiguous layout with external storage. The size of the reserved
+ * space in the external file is the size of the dataset (zero because one dimension size is zero).
+ * There's no need to clean up the external file since the library doesn't create it
+ * until the data is written to it. */
+ ret = H5Pset_external(plist_id, EXTFILE_NAME, (off_t)0, (hsize_t)0);
+ CHECK(ret, FAIL, "H5Pset_external");
+
+ dset1 = H5Dcreate2(fid1, BASICDATASET3, H5T_NATIVE_INT, sid1, H5P_DEFAULT, plist_id, H5P_DEFAULT);
+ CHECK(dset1, FAIL, "H5Dcreate2");
+
+ /* Write "nothing" to the dataset */
+ ret = H5Dwrite(dset1, H5T_NATIVE_INT, sid1, H5S_ALL, H5P_DEFAULT, wdata);
+ CHECK(ret, FAIL, "H5Dwrite");
+
+ ret = H5Fflush(fid1, H5F_SCOPE_GLOBAL);
+ CHECK(ret, FAIL, "H5Fflush");
+
+ /* Try reading from the dataset (make certain our buffer is unmodified) */
+ ret = H5Dread(dset1, H5T_NATIVE_INT, sid1, H5S_ALL, H5P_DEFAULT, rdata);
+ CHECK(ret, FAIL, "H5Dread");
+
+ /* Check results */
+ for(i=0; i<SPACE1_DIM2; i++) {
+ for(j=0; j<SPACE1_DIM3; j++) {
+ if(rdata[i][j] != 7) {
+ H5_FAILED();
+ printf("element [%d][%d] is %d but should have been 7\n",
+ i, j, rdata[i][j]);
+ }
+ }
+ }
+
+ ret = H5Pclose(plist_id);
+ CHECK(ret, FAIL, "H5Pclose");
+
+ ret = H5Dclose(dset1);
+ CHECK(ret, FAIL, "H5Dclose");
+
+ /* Create an attribute for the file */
+ attr = H5Acreate2(fid1, NULLATTR, H5T_NATIVE_INT, sid1, H5P_DEFAULT, H5P_DEFAULT);
+ CHECK(attr, FAIL, "H5Acreate2");
+
+ /* Write "nothing" to the attribute */
+ ret = H5Awrite(attr, H5T_NATIVE_INT, wdata);
+ CHECK(ret, FAIL, "H5Awrite");
+
+ ret = H5Fflush(fid1, H5F_SCOPE_GLOBAL);
+ CHECK(ret, FAIL, "H5Fflush");
+
+ /* Try reading from the attribute (make certain our buffer is unmodified) */
+ ret = H5Aread(attr, H5T_NATIVE_INT, rdata);
+ CHECK(ret, FAIL, "H5Aread");
+
+ /* Check results */
+ for(i=0; i<SPACE1_DIM2; i++) {
+ for(j=0; j<SPACE1_DIM3; j++) {
+ if(rdata[i][j] != 7) {
+ H5_FAILED();
+ printf("element [%d][%d] is %d but should have been 7\n",
+ i, j, rdata[i][j]);
+ }
+ }
+ }
+
+ /* Write "nothing" to the attribute (with type conversion :-) */
+ ret = H5Awrite(attr, H5T_NATIVE_SHORT, wdata_short);
+ CHECK(ret, FAIL, "H5Awrite");
+
+ ret = H5Fflush(fid1, H5F_SCOPE_GLOBAL);
+ CHECK(ret, FAIL, "H5Fflush");
+
+ /* Try reading from the attribute (with type conversion :-) (make certain our buffer is unmodified) */
+ ret = H5Aread(attr, H5T_NATIVE_SHORT, rdata_short);
+ CHECK(ret, FAIL, "H5Aread");
+
+ /* Check results */
+ for(i=0; i<SPACE1_DIM2; i++) {
+ for(j=0; j<SPACE1_DIM3; j++) {
+ if(rdata_short[i][j] != 7) {
+ H5_FAILED();
+ printf("element [%d][%d] is %d but should have been 7\n",
+ i, j, rdata_short[i][j]);
+ }
+ }
+ }
+
+ /* Extend the dimension to make it a normal dataspace (3x15x13). Verify that
+ * data can be written to and read from the dataset now. */
+ dims1[0]=3;
+ ret = H5Sset_extent_simple(sid1,SPACE1_RANK,dims1,NULL);
+ CHECK(ret, FAIL, "H5Sset_extent_simple");
+
+ nelem = H5Sget_simple_extent_npoints(sid1);
+ CHECK(nelem, FAIL, "H5Sget_simple_extent_npoints");
+ VERIFY(nelem, SPACE1_DIM1 * SPACE1_DIM2 * SPACE1_DIM3,
+ "H5Sget_simple_extent_npoints");
+
+ rank = H5Sget_simple_extent_ndims(sid1);
+ CHECK(rank, FAIL, "H5Sget_simple_extent_ndims");
+ VERIFY(rank, SPACE1_RANK, "H5Sget_simple_extent_ndims");
+
+ rank = H5Sget_simple_extent_dims(sid1, tdims, NULL);
+ CHECK(rank, FAIL, "H5Sget_simple_extent_dims");
+ VERIFY(HDmemcmp(tdims, dims1, SPACE1_RANK * sizeof(hsize_t)), 0,
+ "H5Sget_simple_extent_dims");
+
+ dset1 = H5Dcreate2(fid1, BASICDATASET4, H5T_NATIVE_INT, sid1, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
+ CHECK(dset1, FAIL, "H5Dcreate2");
+
+ for(i=0; i<SPACE1_DIM1; i++)
+ for(j=0; j<SPACE1_DIM2; j++)
+ for(k=0; k<SPACE1_DIM3; k++)
+ wdata_real[i][j][k] = i + j + k;
+
+
+ ret = H5Dwrite(dset1, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, wdata_real);
+ CHECK(ret, FAIL, "H5Dwrite");
+
+ ret = H5Fflush(fid1, H5F_SCOPE_GLOBAL);
+ CHECK(ret, FAIL, "H5Fflush");
+
+ ret = H5Dread(dset1, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, rdata_real);
+ CHECK(ret, FAIL, "H5Dread");
+
+ /* Check results */
+ for(i=0; i<SPACE1_DIM1; i++) {
+ for(j=0; j<SPACE1_DIM2; j++) {
+ for(k=0; k<SPACE1_DIM3; k++) {
+ if(rdata_real[i][j][k] != wdata_real[i][j][k]) {
+ H5_FAILED();
+ printf("element [%d][%d][%d] is %d but should have been %d\n",
+ i, j, k, rdata_real[i][j][k], wdata_real[i][j][k]);
+ }
+ }
+ }
+ }
+
+ ret = H5Dclose(dset1);
+ CHECK(ret, FAIL, "H5Dclose");
+
+ /* Change the dimensions to make them zero size again (0x0x0). Verify that
+ * no element is in the dataspace. */
+ dims1[0]=dims1[1]=dims1[2]=0;
+ ret = H5Sset_extent_simple(sid1,SPACE1_RANK,dims1,NULL);
+ CHECK(ret, FAIL, "H5Sset_extent_simple");
+
+ /* Check that the dataspace actually has 0 elements */
+ nelem = H5Sget_simple_extent_npoints(sid1);
+ VERIFY(nelem, 0, "H5Sget_simple_extent_npoints");
+
+ /* Check that the dataspace was created with an "all" selection */
+ sel_type = H5Sget_select_type(sid1);
+ VERIFY(sel_type, H5S_SEL_ALL, "H5Sget_select_type");
+
+ /* Check that the dataspace has 0 elements selected */
+ nelem = H5Sget_select_npoints(sid1);
+ VERIFY(nelem, 0, "H5Sget_select_npoints");
+
+ /* Change to "none" selection */
+ ret = H5Sselect_none(sid1);
+ CHECK(ret, FAIL, "H5Sselect_none");
+
+ /* Check that the dataspace has 0 elements selected */
+ nelem = H5Sget_select_npoints(sid1);
+ VERIFY(nelem, 0, "H5Sget_select_npoints");
+
+ ret = H5Sclose(sid1);
+ CHECK(ret, FAIL, "H5Sclose");
+
+ ret = H5Fclose(fid1);
+ CHECK(ret, FAIL, "H5Fclose");
+
+ /*============================================
+ * Reopen the file to check the data space
+ *============================================
+ */
+ fid1 = H5Fopen(ZEROFILE, H5F_ACC_RDONLY, H5P_DEFAULT);
+ CHECK(fid1, FAIL, "H5Fopen");
+
+ /* Reopen the chunked dataset */
+ dset1 = H5Dopen2(fid1, BASICDATASET1, H5P_DEFAULT);
+ CHECK(dset1, FAIL, "H5Dopen2");
+
+ /* Get the space of the dataset and querry it */
+ sid1 = H5Dget_space(dset1);
+ CHECK(sid1, FAIL, "H5Dget_space");
+
+ /* Verify the class type of dataspace */
+ stype = H5Sget_simple_extent_type(sid1);
+ VERIFY(stype, H5S_SIMPLE, "H5Sget_simple_extent_type");
+
+ /* Verify there is zero element in the dataspace */
+ nelem = H5Sget_simple_extent_npoints(sid1);
+ VERIFY(nelem, 0, "H5Sget_simple_extent_npoints");
+
+ /* Try reading from the dataset (make certain our buffer is unmodified) */
+ ret = H5Dread(dset1, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, rdata);
+ CHECK(ret, FAIL, "H5Dread");
+
+ /* Check results */
+ for(i=0; i<SPACE1_DIM2; i++) {
+ for(j=0; j<SPACE1_DIM3; j++) {
+ if(rdata[i][j] != 7) {
+ H5_FAILED();
+ printf("element [%d][%d] is %d but should have been 7\n",
+ i, j, rdata[i][j]);
+ }
+ }
+ }
+
+ /* Close the dataset and its dataspace */
+ ret = H5Dclose(dset1);
+ CHECK(ret, FAIL, "H5Dclose");
+
+ ret = H5Sclose(sid1);
+ CHECK(ret, FAIL, "H5Sclose");
+
+ /* Open the attribute for the file */
+ attr = H5Aopen(fid1, NULLATTR, H5P_DEFAULT);
+ CHECK(attr, FAIL, "H5Aopen");
+
+ /* Get the space of the dataset */
+ attr_sid = H5Aget_space(attr);
+ CHECK(attr_sid, FAIL, "H5Aget_space");
+
+ /* Verify the class type of dataspace */
+ stype = H5Sget_simple_extent_type(attr_sid);
+ VERIFY(stype, H5S_SIMPLE, "H5Sget_simple_extent_type");
+
+ /* Verify there is zero element in the dataspace */
+ nelem = H5Sget_simple_extent_npoints(attr_sid);
+ VERIFY(nelem, 0, "H5Sget_simple_extent_npoints");
+
+ /* Try reading from the attribute (make certain our buffer is unmodified) */
+ ret = H5Aread(attr, H5T_NATIVE_SHORT, rdata_short);
+ CHECK(ret, FAIL, "H5Aread");
+
+ /* Check results */
+ for(i=0; i<SPACE1_DIM2; i++) {
+ for(j=0; j<SPACE1_DIM3; j++) {
+ if(rdata_short[i][j] != 7) {
+ H5_FAILED();
+ printf("element [%d][%d] is %d but should have been 7\n",
+ i, j, rdata_short[i][j]);
+ }
+ }
+ }
+
+ /* Close attribute */
+ ret=H5Aclose(attr);
+ CHECK(ret, FAIL, "H5Aclose");
+
+ /* Close the dataspace */
+ ret = H5Sclose(attr_sid);
+ CHECK(ret, FAIL, "H5Sclose");
+
+ ret = H5Fclose(fid1);
+ CHECK(ret, FAIL, "H5Fclose");
+} /* test_h5s_zero_dim() */
+
+
+/****************************************************************
+**
** test_h5s_encode(): Test H5S (dataspace) encoding and decoding.
**
****************************************************************/
@@ -1591,6 +2104,7 @@ test_h5s(void)
test_h5s_basic(); /* Test basic H5S code */
test_h5s_null(); /* Test Null dataspace H5S code */
+ test_h5s_zero_dim(); /* Test dataspace with zero dimension size */
test_h5s_encode(); /* Test encoding and decoding */
test_h5s_scalar_write(); /* Test scalar H5S writing code */
test_h5s_scalar_read(); /* Test scalar H5S reading code */