summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRaymond Lu <songyulu@hdfgroup.org>2011-04-13 16:14:16 (GMT)
committerRaymond Lu <songyulu@hdfgroup.org>2011-04-13 16:14:16 (GMT)
commit2815eefb6b0ea608712e0abbc1d3db0910b4cd80 (patch)
tree94051a5190c521b35601a023cec1509867a72742
parent49a607c438d7e0135be61d4cb98d5de013f73fa3 (diff)
downloadhdf5-2815eefb6b0ea608712e0abbc1d3db0910b4cd80.zip
hdf5-2815eefb6b0ea608712e0abbc1d3db0910b4cd80.tar.gz
hdf5-2815eefb6b0ea608712e0abbc1d3db0910b4cd80.tar.bz2
[svn-r20489] Bug 1386 - allow dimension size to be zero even though it isn't unlimited. I brought the changes from the trunk as below:
1. I added test cases for contiguous, compact, and chunked, and external storage datasets, and also attribute. The test includes dataspace selections. 2. I added a test case of extending dataset of zero dimension size and shrinking back to zero dimension size. 3. I updated the Makefile to include the new data file to be cleaned up. 4. The dataspace code has another bug - when the maximal dimension isn't passed in for H5Sset_extent_simple, it is supposed to be same as the dimension. The current library sets NULL to it. I corrected it and added a test case to it. 5. I corrected the tests of Fortran and C++ for the problem in point 3. Tested on jam, heiwa, and amani.
-rw-r--r--c++/test/th5s.cpp25
-rwxr-xr-xconfigure2
-rw-r--r--fortran/test/tH5S.f908
-rw-r--r--src/H5Aint.c5
-rw-r--r--src/H5Dchunk.c12
-rw-r--r--src/H5Dint.c27
-rw-r--r--src/H5Oefl.c6
-rw-r--r--src/H5Pdcpl.c7
-rw-r--r--src/H5S.c55
-rw-r--r--src/H5Spoint.c4
-rw-r--r--test/Makefile.am2
-rw-r--r--test/Makefile.in4
-rw-r--r--test/th5s.c635
13 files changed, 702 insertions, 90 deletions
diff --git a/c++/test/th5s.cpp b/c++/test/th5s.cpp
index 7e9c9c3..e6ed440 100644
--- a/c++/test/th5s.cpp
+++ b/c++/test/th5s.cpp
@@ -110,6 +110,9 @@ int space5_data = 7;
* passed to verify_val to 'long' as well. If problems
* arises later, this will have to be specificly handled
* with a special routine.
+ * April 12, 2011: Raymond Lu
+ * Starting from the 1.8.7 release, we allow dimension
+ * size to be zero. So I took out the test against it.
*-------------------------------------------------------------------------
*/
static void test_h5s_basic()
@@ -210,28 +213,6 @@ static void test_h5s_basic()
// CHECK_I(ret, "H5Fclose"); // leave this here, later, fake a failure
// in the p_close see how this will handle it. - BMR
- // Verify that incorrect dimensions don't work
- dims1[0] = 0;
- try {
- DataSpace wrongdim_ds (SPACE1_RANK, dims1);
-
- // Should FAIL but didn't, so throw an invalid action exception
- throw InvalidActionException("DataSpace constructor", "Attempted to use incorrect dimensions");
- }
- catch( DataSpaceIException E ) // catching use of incorrect dimensions
- {} // do nothing, exception expected
-
- // Another incorrect dimension case
- DataSpace sid3 (H5S_SIMPLE);
- try {
- sid3.setExtentSimple( SPACE1_RANK, dims1 );
-
- // Should FAIL but didn't, so throw an invalid action exception
- throw InvalidActionException("DataSpace::setExtentSimple", "Attempted to use incorrect dimensions");
- }
- catch (DataSpaceIException E) // catching use of incorrect dimensions
- {} // do nothing, exception expected
-
PASSED();
} // end of try block
diff --git a/configure b/configure
index 5d7ffb4..f597aa2 100755
--- a/configure
+++ b/configure
@@ -1,5 +1,5 @@
#! /bin/sh
-# From configure.in Id: configure.in 20181 2011-03-03 15:50:04Z songyulu .
+# From configure.in Id: configure.in 20481 2011-04-12 17:58:28Z koziol .
# Guess values for system-dependent variables and create Makefiles.
# Generated by GNU Autoconf 2.68 for HDF5 1.8.7-snap2.
#
diff --git a/fortran/test/tH5S.f90 b/fortran/test/tH5S.f90
index 29943bb..b56d3a7 100644
--- a/fortran/test/tH5S.f90
+++ b/fortran/test/tH5S.f90
@@ -163,7 +163,13 @@
IF (classtype .NE. 1) write(*,*)"class type not H5S_SIMPLE_f"
!
- !set the copied space to dim2 size.
+ !set the copied space to none before extend the dimensions.
+ !
+ CALL h5sset_extent_none_f(space2_id, error)
+ CALL check("h5sset_extent_none_f", error, total_error)
+
+ !
+ !set the copied space to dim2 size.
!
CALL h5sset_extent_simple_f(space2_id, rank2, dims2, maxdims2, error)
CALL check("h5sset_extent_simple_f", error, total_error)
diff --git a/src/H5Aint.c b/src/H5Aint.c
index e48873c..10b7257 100644
--- a/src/H5Aint.c
+++ b/src/H5Aint.c
@@ -888,8 +888,9 @@ H5A_attr_copy_file(const H5A_t *attr_src, H5F_t *file_dst, hbool_t *recompute_si
HGOTO_ERROR(H5E_OHDR, H5E_CANTINIT, NULL, "unable to reset datatype sharing")
} /* end else */
- /* Copy the dataspace for the attribute */
- attr_dst->shared->ds = H5S_copy(attr_src->shared->ds, FALSE, FALSE);
+ /* Copy the dataspace for the attribute. Make sure the maximal dimension is also copied.
+ * Otherwise the comparison in the test may complain about it. SLU 2011/4/12 */
+ attr_dst->shared->ds = H5S_copy(attr_src->shared->ds, FALSE, TRUE);
HDassert(attr_dst->shared->ds);
/* Reset the dataspace's sharing in the source file before trying to share
diff --git a/src/H5Dchunk.c b/src/H5Dchunk.c
index ab1a975..39613f5 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 3821b78..0b4392e 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/H5Oefl.c b/src/H5Oefl.c
index 25cac88..db25e82 100644
--- a/src/H5Oefl.c
+++ b/src/H5Oefl.c
@@ -81,6 +81,11 @@ const H5O_msg_class_t H5O_MSG_EFL[1] = {{
* Programmer: Robb Matzke
* Tuesday, November 25, 1997
*
+ * Modification:
+ * Raymond Lu
+ * 11 April 2011
+ * We allow zero dimension size starting from the 1.8.7 release.
+ * The dataset size of external storage can be zero.
*-------------------------------------------------------------------------
*/
static void *
@@ -156,7 +161,6 @@ H5O_efl_decode(H5F_t *f, hid_t dxpl_id, H5O_t UNUSED *open_oh,
/* Size */
H5F_DECODE_LENGTH (f, p, mesg->slot[u].size);
- HDassert(mesg->slot[u].size > 0);
} /* end for */
if(H5HL_unprotect(heap) < 0)
diff --git a/src/H5Pdcpl.c b/src/H5Pdcpl.c
index a06304c..8680edb 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..f002500 100644
--- a/src/H5S.c
+++ b/src/H5S.c
@@ -1160,14 +1160,22 @@ 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.
+
+ Raymond Lu 04/11/2011
+ I added a condition check to make sure the new size won't exceed the
+ current maximal size when this function is called to change the
+ dimension size of an existent dataspace.
--------------------------------------------------------------------------*/
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 +1191,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) {
@@ -1196,6 +1202,14 @@ H5Sset_extent_simple(hid_t space_id, int rank, const hsize_t dims[/*rank*/],
}
}
+ /* Check through all the dimensions to see if the new dimension size exceeds the current
+ * size or if the new maximal size exceeds the current maximal size */
+ for(u = 0; u < space->extent.rank; u++) {
+ if(space->extent.max && H5S_UNLIMITED!=space->extent.max[u] &&
+ (space->extent.max[u]<dims[u] || (max && space->extent.max[u]<max[u])))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "new size exceeds current maximal size")
+ } /* end for */
+
/* Do it */
if (H5S_set_extent_simple(space, (unsigned)rank, dims, max)<0)
HGOTO_ERROR(H5E_DATASPACE, H5E_CANTINIT, FAIL, "unable to set simple extent")
@@ -1258,13 +1272,15 @@ H5S_set_extent_simple(H5S_t *space, unsigned rank, const hsize_t *dims,
} /* end for */
space->extent.nelem = nelem;
- /* Copy the maximum dimensions if specified */
+ /* Copy the maximum dimensions if specified. Otherwise, the maximal dimensions are the
+ * same as the dimension */
+ space->extent.max = (hsize_t *)H5FL_ARR_MALLOC(hsize_t, (size_t)rank);
if(max != NULL) {
- space->extent.max = (hsize_t *)H5FL_ARR_MALLOC(hsize_t, (size_t)rank);
HDmemcpy(space->extent.max, max, sizeof(hsize_t) * rank);
- } /* end if */
- else
- space->extent.max = NULL;
+ } else {
+ for(u = 0; u < space->extent.rank; u++)
+ space->extent.max[u] = dims[u];
+ }
} /* end else */
/* Selection related cleanup */
@@ -1303,6 +1319,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 +1353,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 +1919,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/Makefile.am b/test/Makefile.am
index e00da7a..65bf872 100644
--- a/test/Makefile.am
+++ b/test/Makefile.am
@@ -107,7 +107,7 @@ CHECK_CLEANFILES+=accum.h5 cmpd_dset.h5 compact_dataset.h5 dataset.h5 dset_offse
max_compact_dataset.h5 simple.h5 set_local.h5 random_chunks.h5 \
huge_chunks.h5 chunk_cache.h5 big_chunk.h5 chunk_expand.h5 \
copy_dcpl_newfile.h5 extend.h5 istore.h5 extlinks*.h5 frspace.h5 links*.h5 \
- sys_file1 tfile[1-5].h5 th5s[1-3].h5 lheap.h5 fheap.h5 ohdr.h5 \
+ sys_file1 tfile[1-5].h5 th5s[1-4].h5 lheap.h5 fheap.h5 ohdr.h5 \
stab.h5 extern_[1-3].h5 extern_[1-4][ab].raw gheap[0-4].h5 \
dt_arith[1-2] links.h5 links[0-6]*.h5 extlinks[0-15].h5 tmp \
big.data big[0-9][0-9][0-9][0-9][0-9].h5 \
diff --git a/test/Makefile.in b/test/Makefile.in
index 5fda2e5..f6b8fed 100644
--- a/test/Makefile.in
+++ b/test/Makefile.in
@@ -696,7 +696,7 @@ CHECK_CLEANFILES = *.chkexe *.chklog *.clog accum.h5 cmpd_dset.h5 \
max_compact_dataset.h5 simple.h5 set_local.h5 random_chunks.h5 \
huge_chunks.h5 chunk_cache.h5 big_chunk.h5 chunk_expand.h5 \
copy_dcpl_newfile.h5 extend.h5 istore.h5 extlinks*.h5 \
- frspace.h5 links*.h5 sys_file1 tfile[1-5].h5 th5s[1-3].h5 \
+ frspace.h5 links*.h5 sys_file1 tfile[1-5].h5 th5s[1-4].h5 \
lheap.h5 fheap.h5 ohdr.h5 stab.h5 extern_[1-3].h5 \
extern_[1-4][ab].raw gheap[0-4].h5 dt_arith[1-2] links.h5 \
links[0-6]*.h5 extlinks[0-15].h5 tmp big.data \
@@ -714,7 +714,7 @@ CHECK_CLEANFILES = *.chkexe *.chklog *.clog accum.h5 cmpd_dset.h5 \
tstint[1-2].h5 unlink_chunked.h5 btree2.h5 objcopy_src.h5 \
objcopy_dst.h5 objcopy_ext.dat trefer1.h5 trefer2.h5 \
app_ref.h5 tcheck_version_*.out tcheck_version_*.err \
- efc[0-5].h5
+ efc[0-5].h5 log_vfd_out.log
INCLUDES = -I$(top_srcdir)/src -I$(top_builddir)/src
# Test script for error_test and err_compat
diff --git a/test/th5s.c b/test/th5s.c
index 3b37e78..7c7a95a 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,
@@ -103,7 +108,7 @@ test_h5s_basic(void)
/* Output message about test being performed */
MESSAGE(5, ("Testing Dataspace Manipulation\n"));
- sid1 = H5Screate_simple(SPACE1_RANK, dims1, NULL);
+ sid1 = H5Screate_simple(SPACE1_RANK, dims1, max2);
CHECK(sid1, FAIL, "H5Screate_simple");
n = H5Sget_simple_extent_npoints(sid1);
@@ -139,9 +144,7 @@ test_h5s_basic(void)
VERIFY(HDmemcmp(tmax, max2, SPACE2_RANK * sizeof(hsize_t)), 0,
"H5Sget_simple_extent_dims");
- /* Change max dims from zero to non-zero and back again */
- ret = H5Sset_extent_simple(sid1, SPACE1_RANK, dims1, max2);
- CHECK(ret, FAIL, "H5Sset_extent_simple");
+ /* Change max dims to be equal to the dimensions */
ret = H5Sset_extent_simple(sid1, SPACE1_RANK, dims1, NULL);
CHECK(ret, FAIL, "H5Sset_extent_simple");
rank = H5Sget_simple_extent_dims(sid1, tdims, tmax);
@@ -195,24 +198,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");
@@ -529,6 +518,610 @@ 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 sid_chunk; /* Dataspace ID for chunked dataset */
+ 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[] = {0, SPACE1_DIM2, SPACE1_DIM3};
+ hsize_t max_dims[] = {SPACE1_DIM1+1, SPACE1_DIM2, SPACE1_DIM3};
+ hsize_t extend_dims[] = {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. */
+ 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");
+
+ /* SID1 has the 1st dimension size as zero. The maximal dimension will be
+ * the same as the dimension because of the NULL passed in. */
+ 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");
+
+ /* Create the dataspace for chunked dataset with the first dimension size as zero.
+ * The maximal dimensions are bigger than the dimensions for later expansion. */
+ sid_chunk = H5Screate_simple(SPACE1_RANK, dims1, max_dims);
+ CHECK(sid_chunk, FAIL, "H5Screate_simple");
+
+ /*============================================
+ * 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;
+ }
+
+ 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;
+
+
+ /*===================== 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, sid_chunk, 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]);
+ }
+ }
+
+ /* Now extend the dataset to SPACE1_DIM1*SPACE1_DIM2*SPACE1_DIM3 and make sure
+ * we can write data to it */
+ ret = H5Dset_extent(dset1, extend_dims);
+ CHECK(ret, FAIL, "H5Dset_extent");
+
+ 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]);
+ }
+ }
+ }
+ }
+
+ /* Now shrink the first dimension size of the dataset to 0 and make sure no data is in it */
+ extend_dims[0] = 0;
+ ret = H5Dset_extent(dset1, extend_dims);
+ CHECK(ret, FAIL, "H5Dset_extent");
+
+ 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 chunked
+ * dataset now.
+ *===============================================================
+ */
+ dims1[0]=SPACE1_DIM1;
+ ret = H5Sset_extent_simple(sid_chunk,SPACE1_RANK,dims1,max_dims);
+ CHECK(ret, FAIL, "H5Sset_extent_simple");
+
+ nelem = H5Sget_simple_extent_npoints(sid_chunk);
+ CHECK(nelem, FAIL, "H5Sget_simple_extent_npoints");
+ VERIFY(nelem, SPACE1_DIM1 * SPACE1_DIM2 * SPACE1_DIM3,
+ "H5Sget_simple_extent_npoints");
+
+ rank = H5Sget_simple_extent_ndims(sid_chunk);
+ CHECK(rank, FAIL, "H5Sget_simple_extent_ndims");
+ VERIFY(rank, SPACE1_RANK, "H5Sget_simple_extent_ndims");
+
+ rank = H5Sget_simple_extent_dims(sid_chunk, tdims, NULL);
+ CHECK(rank, FAIL, "H5Sget_simple_extent_dims");
+ VERIFY(HDmemcmp(tdims, dims1, SPACE1_RANK * sizeof(hsize_t)), 0,
+ "H5Sget_simple_extent_dims");
+
+ /* Set it to 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, BASICDATASET4, H5T_NATIVE_INT, sid_chunk, H5P_DEFAULT, plist_id, H5P_DEFAULT);
+ CHECK(dset1, FAIL, "H5Dcreate2");
+
+ 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 = H5Pclose(plist_id);
+ CHECK(ret, FAIL, "H5Pclose");
+
+ 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(sid_chunk,SPACE1_RANK,dims1,NULL);
+ CHECK(ret, FAIL, "H5Sset_extent_simple");
+
+ /* Check that the dataspace actually has 0 elements */
+ nelem = H5Sget_simple_extent_npoints(sid_chunk);
+ VERIFY(nelem, 0, "H5Sget_simple_extent_npoints");
+
+ /* Check that the dataspace was created with an "all" selection */
+ sel_type = H5Sget_select_type(sid_chunk);
+ VERIFY(sel_type, H5S_SEL_ALL, "H5Sget_select_type");
+
+ /* Check that the dataspace has 0 elements selected */
+ nelem = H5Sget_select_npoints(sid_chunk);
+ VERIFY(nelem, 0, "H5Sget_select_npoints");
+
+ /* Change to "none" selection */
+ ret = H5Sselect_none(sid_chunk);
+ CHECK(ret, FAIL, "H5Sselect_none");
+
+ /* Check that the dataspace has 0 elements selected */
+ nelem = H5Sget_select_npoints(sid_chunk);
+ VERIFY(nelem, 0, "H5Sget_select_npoints");
+
+ ret = H5Sclose(sid_chunk);
+ CHECK(ret, FAIL, "H5Sclose");
+
+ 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");
+
+ /* Verify the dimension sizes are correct */
+ rank = H5Sget_simple_extent_dims(sid1, tdims, NULL);
+ CHECK(rank, FAIL, "H5Sget_simple_extent_dims");
+ VERIFY(tdims[0], 0, "H5Sget_simple_extent_dims");
+ VERIFY(tdims[1], SPACE1_DIM2, "H5Sget_simple_extent_dims");
+ VERIFY(tdims[2], SPACE1_DIM3, "H5Sget_simple_extent_dims");
+
+ /* 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.
**
****************************************************************/
@@ -1596,6 +2189,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 */
@@ -1630,4 +2224,5 @@ cleanup_h5s(void)
remove(DATAFILE);
remove(NULLFILE);
remove(BASICFILE);
+ remove(ZEROFILE);
}