summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBinh-Minh Ribler <bmribler@hdfgroup.org>2001-03-01 18:07:25 (GMT)
committerBinh-Minh Ribler <bmribler@hdfgroup.org>2001-03-01 18:07:25 (GMT)
commit6e7877db5e4f05e8f64dda968eb4c69d0d83d599 (patch)
tree9782d22433da73479ae53b42de9bcfc75184e8c5
parent0cb43aefd9fd58dbe2ae9b72dda305e0c10496ab (diff)
downloadhdf5-6e7877db5e4f05e8f64dda968eb4c69d0d83d599.zip
hdf5-6e7877db5e4f05e8f64dda968eb4c69d0d83d599.tar.gz
hdf5-6e7877db5e4f05e8f64dda968eb4c69d0d83d599.tar.bz2
[svn-r3532] Purpose:
Adding tests to the C++ API Description: The C++ API has no formal testing yet. Solution: Added tests for file and dataset interfaces. I'm still working on other tests. Platforms tested: Linux (gcc version egcs-2.91.66) I temporarily modified the Makefile on my local Linux machine and these tests work. I need Bill to help adding them permanently before I can test on an NCSA machine. I checked the files in now so Bill can do that.
-rw-r--r--c++/test/dsets.cpp1048
-rw-r--r--c++/test/testhdf5.cpp312
-rw-r--r--c++/test/tfile.cpp332
3 files changed, 1692 insertions, 0 deletions
diff --git a/c++/test/dsets.cpp b/c++/test/dsets.cpp
new file mode 100644
index 0000000..df5be42
--- /dev/null
+++ b/c++/test/dsets.cpp
@@ -0,0 +1,1048 @@
+/****************************************************************************
+ * NCSA HDF *
+ * Software Development Group *
+ * National Center for Supercomputing Applications *
+ * University of Illinois at Urbana-Champaign *
+ * 605 E. Springfield, Champaign IL 61820 *
+ * *
+ * For conditions of distribution and use, see the accompanying *
+ * hdf/COPYING file. *
+ * *
+ ****************************************************************************/
+
+/***********************************************************
+*
+* Test program: dsets
+*
+* Test the dataset interface (H5D)
+*
+*************************************************************/
+
+#include <h5test.h>
+#include <testhdf5.h>
+#include <H5Cpp.h>
+
+#ifndef H5_NO_NAMESPACE
+using namespace H5;
+#endif
+
+const char *FILENAME[] = {
+ "dataset",
+ NULL
+};
+
+#define DSET_DEFAULT_NAME "default"
+#define DSET_CHUNKED_NAME "chunked"
+#define DSET_SIMPLE_IO_NAME "simple_io"
+#define DSET_TCONV_NAME "tconv"
+#define DSET_COMPRESS_NAME "compressed"
+#define DSET_BOGUS_NAME "bogus"
+
+#define H5Z_BOGUS 305
+
+
+/*-------------------------------------------------------------------------
+ * Function: test_create
+ *
+ * Purpose: Attempts to create a dataset.
+ *
+ * Return: Success: 0
+ *
+ * Failure: -1
+ *
+ * Programmer: Binh-Minh Ribler
+ * Friday, January 5, 2001
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+test_create( H5File& file)
+{
+ TESTING("create, open, close");
+
+ try {
+ /* Create the data space */
+ hsize_t dims[2];
+ dims[0] = 256;
+ dims[1] = 512;
+ DataSpace space (2, dims, NULL);
+
+ /*
+ * Create a dataset using the default dataset creation properties.
+ * We're not sure what they are, so we won't check.
+ */
+ DataSet *dataset = new DataSet (file.createDataSet
+ (DSET_DEFAULT_NAME, PredType::NATIVE_DOUBLE, space));
+
+ /* Close the dataset */
+ delete dataset;
+
+ /* Add a comment to the dataset */
+ file.setComment (DSET_DEFAULT_NAME, "This is a dataset");
+
+ /*
+ * Try creating a dataset that already exists. This should fail since a
+ * dataset can only be created once. If an exception is not thrown
+ * for this action by createDataSet, then display failure information
+ * and jump to label error: to return.
+ */
+ try {
+ dataset = new DataSet (file.createDataSet
+ (DSET_DEFAULT_NAME, PredType::NATIVE_DOUBLE, space));
+ // continuation here, that means no exception has been thrown
+ FAILED();
+ cout << " Library allowed overwrite of existing dataset." << endl;
+ goto error;
+ }
+ catch (FileIException E ) // catching invalid creating dataset
+ {
+ // Exception is expected. Do nothing here.
+ }
+ /*
+ * Open the dataset we created above and then close it. This is how
+ * existing datasets are accessed.
+ */
+ dataset = new DataSet (file.openDataSet (DSET_DEFAULT_NAME));
+ delete dataset;
+
+ /*
+ * Try opening a non-existent dataset. This should fail so if an
+ * exception is not thrown for this action by openDataSet, then
+ * display failure information and jump to label error: to return.
+ */
+ try {
+ dataset = new DataSet (file.openDataSet( "does_not_exist" ));
+ // continuation here, that means no exception has been thrown
+ FAILED();
+ cout << " Opened a non-existent dataset." << endl;
+ goto error;
+ }
+ catch (FileIException E ) // catching creating non-existent dataset
+ {
+ // Exception is expected. Do nothing here.
+ }
+
+ /*
+ * Create a new dataset that uses chunked storage instead of the default
+ * layout.
+ */
+ DSetCreatPropList create_parms;
+ hsize_t csize[2];
+ csize[0] = 5;
+ csize[1] = 100;
+ create_parms.setChunk( 2, csize );
+
+ dataset = new DataSet (file.createDataSet
+ (DSET_CHUNKED_NAME, PredType::NATIVE_DOUBLE, space, create_parms));
+ // Note: this one has no error message in C when failure occurs?
+
+ /*
+ * Close the chunked dataset.
+ */
+ delete dataset;
+
+ PASSED();
+ return 0;
+ } // outer most try block
+
+ // catch all dataset, file, space, plist exceptions
+ catch (Exception E) { goto error; }
+
+ error:
+ return -1;
+}
+
+/*-------------------------------------------------------------------------
+ * Function: check_values
+ *
+ * Purpose: Checks a read value against the written value. If they are
+ * different, the function will
+ * print out a message and the different values. This function
+ * is made to reuse the code segment that is used in various
+ * places throughout test_compression and in test_simple_io.
+ * Where the C version
+ * of this code segment "goto error," this function will
+ * return -1, so that the caller can "goto error."
+ *
+ * Return: Success: 0
+ *
+ * Failure: -1
+ *
+ * Programmer: Binh-Minh Ribler (using C code segment for checking values)
+ * Friday, February 6, 2001
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static int
+check_values (hsize_t i, hsize_t j, int apoint, int acheck)
+{
+ if (apoint != acheck)
+ {
+ FAILED();
+ cout << " Read different values than written.\n" << endl;
+ cout << " At index " << (unsigned long)i << "," <<
+ (unsigned long)j << endl;
+ return -1;
+ }
+ return 0;
+} // check_values
+
+/*-------------------------------------------------------------------------
+ * Function: test_simple_io
+ *
+ * Purpose: Tests simple I/O. That is, reading and writing a complete
+ * multi-dimensional array without data type or data space
+ * conversions, without compression, and stored contiguously.
+ *
+ * Return: Success: 0
+ *
+ * Failure: -1
+ *
+ * Programmer: Binh-Minh Ribler (using Robb Matzke's C version)
+ * Friday, January 5, 2001
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+test_simple_io( H5File& file)
+{
+
+ TESTING("simple I/O");
+
+ int points[100][200];
+ int check[100][200];
+ int i, j, n;
+
+ /* Initialize the dataset */
+ for (i = n = 0; i < 100; i++)
+ {
+ for (j = 0; j < 200; j++) {
+ points[i][j] = n++;
+ }
+ }
+
+ void* tconv_buf = new char [1000];
+ try
+ {
+ /* Create the data space */
+ hsize_t dims[2];
+ dims[0] = 100;
+ dims[1] = 200;
+ DataSpace space (2, dims, NULL);
+
+ /* Create a small conversion buffer to test strip mining */
+ DSetMemXferPropList xfer;
+
+ //if (H5Pset_buffer (xfer, 1000, tconv_buf, NULL)<0) goto error;
+ xfer.setBuffer (1000, tconv_buf, NULL);
+
+ /* Create the dataset */
+ DataSet dataset (file.createDataSet (DSET_SIMPLE_IO_NAME, PredType::NATIVE_INT, space));
+
+ /* Write the data to the dataset */
+ dataset.write ((void*) points, PredType::NATIVE_INT, DataSpace::ALL, DataSpace::ALL, xfer);
+
+ /* Read the dataset back */
+ dataset.read ((void*) check, PredType::NATIVE_INT, DataSpace::ALL, DataSpace::ALL, xfer);
+
+ /* Check that the values read are the same as the values written */
+ for (i = 0; i < 100; i++)
+ for (j = 0; j < 200; j++)
+ {
+ int status = check_values (i, j, points[i][j], check[i][j]);
+ if (status == -1) goto error;
+ }
+
+ delete [] tconv_buf;
+ PASSED();
+ return 0;
+ } // end try
+
+ // catch all dataset, space, plist exceptions
+ catch (Exception E) { goto error; }
+
+ error:
+ // cleaning up
+ if (tconv_buf)
+ delete [] tconv_buf;
+ return -1;
+}
+
+/*-------------------------------------------------------------------------
+ * Function: test_tconv
+ *
+ * Purpose: Test some simple data type conversion stuff.
+ *
+ * Return: Success: 0
+ *
+ * Failure: -1
+ *
+ * Programmer: Binh-Minh Ribler (using Robb Matzke's C version)
+ * Friday, January 5, 2001
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+test_tconv( H5File& file)
+{
+ // Prepare buffers for input/output
+ char *out=NULL, *in=NULL;
+ out = new char [4*1000000];
+ // assert (out); - should use exception handler for new - BMR
+ in = new char [4*1000000];
+ //assert (in);
+
+ TESTING("data type conversion");
+
+ /* Initialize the dataset */
+ for (int i = 0; i < 1000000; i++) {
+ out[i*4+0] = 0x11;
+ out[i*4+1] = 0x22;
+ out[i*4+2] = 0x33;
+ out[i*4+3] = 0x44;
+ }
+
+ try
+ {
+ /* Create the data space */
+ hsize_t dims[1];
+ dims[0] = 1000000;
+ DataSpace space (1, dims, NULL);
+
+ /* Create the data set */
+ DataSet dataset (file.createDataSet (DSET_TCONV_NAME, PredType::STD_I32LE, space));
+
+ /* Write the data to the dataset */
+ dataset.write ((void*) out, PredType::STD_I32LE);
+
+ /* Read data with byte order conversion */
+ dataset.read ((void*) in, PredType::STD_I32BE);
+
+ /* Check */
+ for (i = 0; i < 1000000; i++) {
+ if (in[4*i+0]!=out[4*i+3] ||
+ in[4*i+1]!=out[4*i+2] ||
+ in[4*i+2]!=out[4*i+1] ||
+ in[4*i+3]!=out[4*i+0])
+ {
+ FAILED();
+ cout << " Read with byte order conversion failed." << endl;
+ goto error;
+ }
+ }
+
+ delete [] out;
+ delete [] in;
+ cout << " PASSED" << endl;
+ return 0;
+ } // end try
+
+ // catch all dataset and space exceptions
+ catch (Exception E) { goto error; }
+
+ error:
+ delete [] out;
+ delete [] in;
+ return -1;
+}
+
+/*-------------------------------------------------------------------------
+ * Function: bogus
+ *
+ * Purpose: A bogus compression method that doesn't do anything.
+ *
+ * Return: Success: Data chunk size
+ *
+ * Failure: 0
+ *
+ * Programmer: Robb Matzke
+ * Tuesday, April 21, 1998
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static size_t
+/*bogus(unsigned int UNUSED flags, size_t UNUSED cd_nelmts,
+ const unsigned int UNUSED cd_values[], size_t nbytes,
+ size_t UNUSED *buf_size, void UNUSED **buf)
+BMR: removed UNUSED for now until asking Q. or R. to pass compilation*/
+bogus(unsigned int flags, size_t cd_nelmts,
+ const unsigned int cd_values[], size_t nbytes,
+ size_t *buf_size, void **buf)
+{
+ return nbytes;
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function: test_compression
+ *
+ * Purpose: Tests dataset compression. If compression is requested when
+ * it hasn't been compiled into the library (such as when
+ * updating an existing compressed dataset) then data is sent to
+ * the file uncompressed but no errors are returned.
+ *
+ * Return: Success: 0
+ *
+ * Failure: -1
+ *
+ * Programmer: Binh-Minh Ribler (using Robb Matzke's C version)
+ * Friday, January 5, 2001
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+
+static herr_t
+test_compression(H5File& file)
+{
+ const char *not_supported;
+ not_supported = " Deflate compression is not supported.\n"
+ " The zlib was not found when hdf5 was configured.";
+
+ TESTING("compression (setup)");
+
+ int points[100][200];
+ int check[100][200];
+ hsize_t i, j, n;
+
+ /* Initialize the dataset */
+ for (i = n = 0; i < 100; i++)
+ {
+ for (j = 0; j < 200; j++) {
+ points[i][j] = n++;
+ }
+ }
+ void* tconv_buf = new char [1000];
+
+ try
+ {
+ const hsize_t size[2] = {100, 200};
+ /* Create the data space */
+ DataSpace space1(2, size, NULL);
+
+ /*
+ * Create a small conversion buffer to test strip mining. We
+ * might as well test all we can!
+ */
+ DSetMemXferPropList xfer;
+
+ xfer.setBuffer (1000, tconv_buf, NULL);
+
+ /* Use chunked storage with compression */
+ DSetCreatPropList dscreatplist;
+
+ const hsize_t chunk_size[2] = {2, 25};
+ dscreatplist.setChunk (2, chunk_size);
+ dscreatplist.setDeflate (6);
+
+ /* Create the dataset */
+ DataSet* dataset = new DataSet (file.createDataSet
+ (DSET_COMPRESS_NAME, PredType::NATIVE_INT, space1, dscreatplist));
+
+#ifdef H5_HAVE_COMPRESS2
+ PASSED();
+#else
+ SKIPPED();
+ cout << not_supported << endl;
+#endif
+
+ /*----------------------------------------------------------------------
+ * STEP 1: Read uninitialized data. It should be zero.
+ *----------------------------------------------------------------------
+ */
+ TESTING("compression (uninitialized read)");
+
+ dataset->read ((void*) check, PredType::NATIVE_INT, DataSpace::ALL, DataSpace::ALL, xfer);
+
+ for (i=0; i<size[0]; i++) {
+ for (j=0; j<size[1]; j++) {
+ if (0!=check[i][j]) {
+ FAILED();
+ cout << " Read a non-zero value." << endl;
+ cout << " At index " << (unsigned long)i << "," <<
+ (unsigned long)j << endl;
+ goto error;
+ }
+ }
+ }
+#ifdef H5_HAVE_COMPRESS2
+ PASSED();
+#else
+ SKIPPED();
+ cout << not_supported << endl;
+#endif
+
+ /*----------------------------------------------------------------------
+ * STEP 2: Test compression by setting up a chunked dataset and writing
+ * to it.
+ *----------------------------------------------------------------------
+ */
+ TESTING("compression (write)");
+
+ for (i=n=0; i<size[0]; i++)
+ {
+ for (j=0; j<size[1]; j++)
+ {
+ points[i][j] = n++;
+ }
+ }
+
+ //if (H5Dwrite(dataset, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, xfer, points)<0) goto error;
+ dataset->write ((void*) points, PredType::NATIVE_INT, DataSpace::ALL, DataSpace::ALL, xfer);
+#ifdef H5_HAVE_COMPRESS2
+
+ PASSED();
+#else
+ SKIPPED();
+ cout << not_supported << endl;
+#endif
+
+ /*----------------------------------------------------------------------
+ * STEP 3: Try to read the data we just wrote.
+ *----------------------------------------------------------------------
+ */
+ TESTING("compression (read)");
+
+ /* Read the dataset back */
+ dataset->read ((void*)check, PredType::NATIVE_INT, DataSpace::ALL, DataSpace::ALL, xfer);
+
+ /* Check that the values read are the same as the values written */
+ for (i = 0; i < size[0]; i++)
+ for (j = 0; j < size[1]; j++)
+ {
+ int status = check_values (i, j, points[i][j], check[i][j]);
+ if (status == -1) goto error;
+ }
+
+#ifdef H5_HAVE_COMPRESS2
+ PASSED();
+#else
+ SKIPPED();
+ cout << not_supported << endl;
+#endif
+
+ /*----------------------------------------------------------------------
+ * STEP 4: Write new data over the top of the old data. The new data is
+ * random thus not very compressible, and will cause the chunks to move
+ * around as they grow. We only change values for the left half of the
+ * dataset although we rewrite the whole thing.
+ *----------------------------------------------------------------------
+ */
+ TESTING("compression (modify)");
+
+ for (i=0; i<size[0]; i++)
+ {
+ for (j=0; j<size[1]/2; j++)
+ {
+ points[i][j] = rand ();
+ }
+ }
+ dataset->write ((void*)points, PredType::NATIVE_INT, DataSpace::ALL, DataSpace::ALL, xfer);
+
+ /* Read the dataset back and check it */
+ dataset->read ((void*)check, PredType::NATIVE_INT, DataSpace::ALL, DataSpace::ALL, xfer);
+
+ /* Check that the values read are the same as the values written */
+ for (i = 0; i < size[0]; i++)
+ for (j = 0; j < size[1]; j++)
+ {
+ int status = check_values (i, j, points[i][j], check[i][j]);
+ if (status == -1) goto error;
+ }
+
+#ifdef H5_HAVE_COMPRESS2
+ PASSED();
+#else
+ SKIPPED();
+ cout << not_supported << endl;
+#endif
+
+ /*----------------------------------------------------------------------
+ * STEP 5: Close the dataset and then open it and read it again. This
+ * insures that the compression message is picked up properly from the
+ * object header.
+ *----------------------------------------------------------------------
+ */
+ TESTING("compression (re-open)");
+
+ delete dataset;
+
+ //if ((dataset = H5Dopen (file, DSET_COMPRESS_NAME))<0) goto error;
+ dataset = new DataSet (file.openDataSet (DSET_COMPRESS_NAME));
+ dataset->read ((void*)check, PredType::NATIVE_INT, DataSpace::ALL, DataSpace::ALL, xfer);
+
+ /* Check that the values read are the same as the values written */
+ for (i = 0; i < size[0]; i++)
+ for (j = 0; j < size[1]; j++)
+ {
+ int status = check_values (i, j, points[i][j], check[i][j]);
+ if (status == -1) goto error;
+ }
+
+#ifdef H5_HAVE_COMPRESS2
+ PASSED();
+#else
+ SKIPPED();
+ cout << not_supported << endl;
+#endif
+
+
+ /*----------------------------------------------------------------------
+ * STEP 6: Test partial I/O by writing to and then reading from a
+ * hyperslab of the dataset. The hyperslab does not line up on chunk
+ * boundaries (we know that case already works from above tests).
+ *----------------------------------------------------------------------
+ */
+ TESTING("compression (partial I/O)");
+
+ const hsize_t hs_size[2] = {4, 50};
+ const hssize_t hs_offset[2] = {7, 30};
+ for (i = 0; i < hs_size[0]; i++) {
+ for (j = 0; j < hs_size[1]; j++) {
+ points[hs_offset[0]+i][hs_offset[1]+j] = rand ();
+ }
+ }
+ space1.selectHyperslab( H5S_SELECT_SET, hs_size, hs_offset );
+ dataset->write ((void*)points, PredType::NATIVE_INT, space1, space1, xfer);
+ dataset->read ((void*)check, PredType::NATIVE_INT, space1, space1, xfer);
+
+ /* Check that the values read are the same as the values written */
+ for (i=0; i<hs_size[0]; i++) {
+ for (j=0; j<hs_size[1]; j++) {
+ if (points[hs_offset[0]+i][hs_offset[1]+j] !=
+ check[hs_offset[0]+i][hs_offset[1]+j]) {
+ FAILED();
+ cout << " Read different values than written.\n" << endl;
+ cout << " At index " << (unsigned long)(hs_offset[0]+i) <<
+ "," << (unsigned long)(hs_offset[1]+j) << endl;
+
+ cout << " At original: " << (int)points[hs_offset[0]+i][hs_offset[1]+j] << endl;
+ cout << " At returned: " << (int)check[hs_offset[0]+i][hs_offset[1]+j] << endl;
+ goto error;
+ }
+ }
+ }
+#ifdef H5_HAVE_COMPRESS2
+ PASSED();
+#else
+ SKIPPED();
+ cout << not_supported << endl;
+#endif
+
+ /*----------------------------------------------------------------------
+ * STEP 7: Register an application-defined compression method and use it
+ * to write and then read the dataset.
+ *----------------------------------------------------------------------
+ */
+ TESTING("compression (app-defined method)");
+
+ // BMR: not sure how to handle this yet???
+ if (H5Zregister (H5Z_BOGUS, DSET_BOGUS_NAME, bogus)<0) goto error;
+ if (H5Pset_filter (dscreatplist.getId(), H5Z_BOGUS, 0, 0, NULL)<0) goto error;
+ dscreatplist.setFilter (H5Z_BOGUS, 0, 0, NULL);
+ delete dataset;
+
+ DataSpace space2 (2, size, NULL);
+ dataset = new DataSet (file.createDataSet (DSET_BOGUS_NAME, PredType::NATIVE_INT, space2, dscreatplist));
+
+ dataset->write ((void*)points, PredType::NATIVE_INT, DataSpace::ALL, DataSpace::ALL, xfer);
+ dataset->read ((void*)check, PredType::NATIVE_INT, DataSpace::ALL, DataSpace::ALL, xfer);
+
+ /* Check that the values read are the same as the values written */
+ for (i = 0; i < size[0]; i++)
+ for (j = 0; j < size[1]; j++)
+ {
+ int status = check_values (i, j, points[i][j], check[i][j]);
+ if (status == -1) goto error;
+ }
+
+ PASSED();
+
+ /*----------------------------------------------------------------------
+ * Cleanup
+ *----------------------------------------------------------------------
+ */
+ delete dataset;
+ delete [] tconv_buf;
+ return 0;
+ } // end try
+
+ // catch all dataset, file, space, and plist exceptions
+ catch (Exception E) { goto error; }
+
+ error:
+ // cleaning up
+ if (tconv_buf)
+ delete [] tconv_buf;
+ return -1;
+}
+
+/*-------------------------------------------------------------------------
+ * Function: test_multiopen
+ *
+ * Purpose: Tests that a bug no longer exists. If a dataset is opened
+ * twice and one of the handles is used to extend the dataset,
+ * then the other handle should return the new size when
+ * queried.
+ *
+ * Return: Success: 0
+ *
+ * Failure: -1
+ *
+ * Programmer: Binh-Minh Ribler (using Robb Matzke's C version)
+ * Saturday, February 17, 2001
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+test_multiopen (H5File& file)
+{
+
+ TESTING("multi-open with extending");
+ try {
+
+ // Create a dataset creation property list
+ DSetCreatPropList dcpl;
+
+ // Set chunk size to given size
+ hsize_t cur_size[1] = {10};
+ dcpl.setChunk (1, cur_size);
+
+ // Create a simple data space with unlimited size
+ static hsize_t max_size[1] = {H5S_UNLIMITED};
+ DataSpace* space = new DataSpace (1, cur_size, max_size);
+
+ // Create first dataset
+ DataSet dset1 = file.createDataSet ("multiopen", PredType::NATIVE_INT, *space, dcpl);
+
+ //BMR: Quincey said Rob gave a tweak to have dataset being the first
+ // argument in this call but actually shouldn't be valid, so just
+ // ignore the argument dset1. Just open the first dataset again
+ // from the file to another DataSet object.
+ // if ((dset2=H5Dopen (dset1, "."))<0) goto error;
+ DataSet dset2 = file.openDataSet ("multiopen");
+
+ // Relieve the dataspace
+ delete space;
+
+ // Extend the dimensionality of the first dataset
+ cur_size[0] = 20;
+ dset1.extend (cur_size);
+
+ /* Get the size from the second handle */
+ //if ((space = H5Dget_space (dset2))<0) goto error;
+ space = new DataSpace (dset2.getSpace());
+
+ hsize_t tmp_size[1];
+ //if (H5Sget_simple_extent_dims (space, tmp_size, NULL)<0) goto error;
+ space->getSimpleExtentDims (tmp_size);
+ if (cur_size[0]!=tmp_size[0])
+ {
+ FAILED();
+ cout << " Got " << (int)tmp_size[0] << " instead of "
+ << (int)cur_size[0] << "!" << endl;
+ delete space;
+ goto error;
+ }
+
+ delete space;
+ PASSED();
+ return 0;
+ } // end try block
+
+ // catch all dataset, file, space, and plist exceptions
+ catch (Exception E)
+ { goto error; }
+
+ error:
+ return -1;
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function: test_types
+ *
+ * Purpose: Make some datasets with various types so we can test h5ls.
+ *
+ * Return: Success: 0
+ *
+ * Failure: -1
+ *
+ * Programmer: Binh-Minh Ribler (using Robb Matzke's C version)
+ * February 17, 2001
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+test_types(H5File& file)
+{
+ size_t i;
+
+ TESTING("various datatypes");
+ try {
+
+ // Create a group in the file that was passed in from the caller
+ Group grp = file.createGroup ("typetests");
+
+ /* bitfield_1 */
+ unsigned char buf[32];
+ hsize_t nelmts = sizeof(buf);
+ DataType type;
+ try { // block 1
+ type.copy (PredType::STD_B8LE);
+ DataSpace space (1, &nelmts);
+ DataSet* dset = new DataSet(grp.createDataSet("bitfield_1", type, space));
+
+ // Fill buffer
+ for (i=0; i<sizeof buf; i++)
+ buf[i] = (unsigned char)0xff ^ (unsigned char)i;
+
+ // Write data from buf using all default dataspaces and property
+ // list; if writing fails, deallocate dset and return.
+ try { dset->write (buf, type); }
+ catch(DataSetIException E)
+ {
+ delete dset;
+ goto error;
+ }
+ delete dset;
+
+ } // end try block of bitfield_1
+
+ // catch exceptions thrown in try block of bitfield_1
+ catch (Exception E) { goto error; }
+
+ /* bitfield_2 */
+ nelmts = sizeof(buf)/2;
+ try { // bitfield_2 block
+
+ type.copy (PredType::STD_B16LE);
+ DataSpace space (1, &nelmts);
+ DataSet* dset = new DataSet(grp.createDataSet("bitfield_2", type, space));
+
+ // Fill buffer
+ for (i=0; i<sizeof(buf); i++)
+ buf[i] = (unsigned char)0xff ^ (unsigned char)i;
+
+ // Write data from buf using all default dataspaces and property
+ // list; if writing fails, deallocate dset and return.
+ try { dset->write (buf, type); }
+ catch(DataSetIException E)
+ {
+ delete dset;
+ goto error;
+ }
+ delete dset;
+ } // end try block of bitfield_2
+
+ // catch exceptions thrown in try block of bitfield_2
+ catch (Exception E) { goto error; }
+
+ /* opaque_1 */
+ DataType* optype = new DataType(H5T_OPAQUE, 1);
+ try { // opaque_1 block
+ nelmts = sizeof(buf);
+ DataSpace space (1, &nelmts);
+ optype->setTag ("testing 1-byte opaque type");
+ DataSet* dset = new DataSet(grp.createDataSet("opaque_1", *optype, space));
+
+ // Fill buffer
+ for (i=0; i<sizeof buf; i++)
+ buf[i] = (unsigned char)0xff ^ (unsigned char)i;
+
+ // Write data from buf using all default dataspaces and property
+ // list; if writing fails, deallocate dset and return.
+ try { dset->write (buf, *optype); }
+ catch(DataSetIException E)
+ {
+ delete dset;
+ goto error;
+ }
+ delete dset;
+ delete optype;
+ } // end try block of opaque_1
+
+ // catch exceptions thrown in try block of opaque_1
+ catch (DataSetIException E) { delete optype; goto error; }
+ catch (Exception E) { goto error; }
+
+ /* opaque_2 */
+ try { // block opaque_2
+ nelmts = sizeof(buf)/4;
+ DataSpace space (1, &nelmts);
+ optype = new DataType(H5T_OPAQUE, 4);
+ optype->setTag ("testing 4-byte opaque type");
+ DataSet* dset = new DataSet(grp.createDataSet("opaque_2", *optype, space));
+
+ // Fill buffer
+ for (i=0; i<sizeof(buf); i++)
+ buf[i] = (unsigned char)0xff ^ (unsigned char)i;
+
+ // Write data from buf using all default dataspaces and property
+ // list; if writing fails, deallocate dset and return.
+ try { dset->write (buf, *optype); }
+ catch(DataSetIException E)
+ {
+ delete dset;
+ goto error;
+ }
+ delete dset;
+ delete optype;
+ } //end try block of opaque_2
+ catch (DataSetIException E) { delete optype; goto error; }
+ catch (Exception E) { goto error; }
+
+ PASSED();
+ return 0;
+ } // end top try block
+ catch (Exception E) { goto error; } // Group and DataType exceptions
+
+ error:
+ return -1;
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function: test_report
+ *
+ * Purpose: Prints out the number of errors for dataset tests if there
+ * were any failures occurred. If no failure, test_report
+ * prints out the "All dataset tests passed" message
+ *
+ * Return: if any failure has occurred: 1
+ *
+ * if no failure occurs: 0
+ *
+ * Programmer: Binh-Minh Ribler (using C code segment for reporting tests)
+ * Friday, February 6, 2001
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+int test_report( int nerrors )
+{
+ if (nerrors)
+ {
+ nerrors = MAX(1, nerrors);
+ if (1 == nerrors)
+ cout << "***** " << nerrors << " DATASET TEST"
+ << " FAILED! *****" << endl;
+ else
+ cout << "***** " << nerrors << " DATASET TESTS"
+ << " FAILED! *****" << endl;
+ return 1;
+ }
+ else
+ {
+ cout << "All dataset tests passed." << endl;
+ return 0;
+ }
+}
+
+/*-------------------------------------------------------------------------
+ * Function: main
+ *
+ * Purpose: Tests the dataset interface (H5D)
+ *
+ * Return: Success: exit(0)
+ *
+ * Failure: exit(1)
+ *
+ * Programmer: Binh-Minh Ribler (using Robb Matzke's C version)
+ * Friday, January 5, 2001
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+int
+main(void)
+{
+
+ h5_reset(); // in h5test.c, resets the library by closing it
+
+ hid_t fapl_id;
+ fapl_id = h5_fileaccess(); // in h5test.c, returns a file access template
+ // should create an object from this id - BMR
+
+/* BMR: leave paralell stuff out!
+#if 0
+ {
+ // Turn off raw data cache
+ int mdc_nelmts;
+ (H5Pget_cache(fapl_id, &mdc_nelmts, NULL, NULL, NULL)<0) goto error;
+ (H5Pset_cache(fapl_id, mdc_nelmts, 0, 0, 0.0)<0) goto error;
+ }
+#endif
+*/
+
+ char filename[1024];
+ h5_fixname(FILENAME[0], fapl_id, filename, sizeof filename);
+
+ int nerrors=0; // keep track of number of failures occurr
+ try
+ {
+ // Turn of the auto-printing when failure occurs so that we can
+ // handle the errors appropriately since sometime failures are
+ // caused deliberately and expected.
+ Exception::dontPrint();
+
+ // Use the file access template id to create a file access prop.
+ // list object to pass in H5File::H5File
+ FileAccPropList* fapl = new FileAccPropList(fapl_id);
+
+ H5File file( filename, H5F_ACC_TRUNC, FileCreatPropList::DEFAULT, *fapl );
+
+ /* Cause the library to emit initial messages */
+ Group grp = file.createGroup( "emit diagnostics", 0);
+ grp.setComment( ".", "Causes diagnostic messages to be emitted");
+
+ nerrors += test_create(file)<0 ?1:0;
+ nerrors += test_simple_io(file)<0 ?1:0;
+ nerrors += test_tconv(file)<0 ?1:0;
+ nerrors += test_compression(file)<0 ?1:0;
+ nerrors += test_multiopen (file)<0 ?1:0;
+ nerrors += test_types(file)<0 ?1:0;
+
+ // BMR: this is a very unattractive workaround approach, but I used
+ // it for now, since I want to use already existing utility code from
+ // the C tests. h5_cleanup calls H5Pclose to close the fapl_id while
+ // the object 'fapl' is still opened. So, I dynamically allocated
+ // 'fapl' then deleted it before h5_cleanup, but after incrementing
+ // 'fapl's ref counter so that the prop list id will not be closed
+ // when 'fapl' is destroyed. Why did I need to create a
+ // FileCreatPropList object while I already had the prop list id?
+ // Because I need to pass it into the constructor H5File::H5File.
+ // We're trying to avoid introducing id's into the C++ API.
+ fapl->incRefCount();
+ delete fapl;
+ h5_cleanup(FILENAME, fapl_id);
+ return( test_report( nerrors ));
+ }
+ catch (FileIException error)
+ {
+ return( test_report( nerrors ));
+ }
+ catch (GroupIException error )
+ {
+ return( test_report( nerrors ));
+ }
+}
+
+
diff --git a/c++/test/testhdf5.cpp b/c++/test/testhdf5.cpp
new file mode 100644
index 0000000..28d6a54
--- /dev/null
+++ b/c++/test/testhdf5.cpp
@@ -0,0 +1,312 @@
+/****************************************************************************
+ * NCSA HDF *
+ * Software Development Group *
+ * National Center for Supercomputing Applications *
+ * University of Illinois at Urbana-Champaign *
+ * 605 E. Springfield, Champaign IL 61820 *
+ * *
+ * For conditions of distribution and use, see the accompanying *
+ * hdf/COPYING file. *
+ * *
+ ****************************************************************************/
+
+/*
+ FILE
+ testhdf5.c - HDF5 testing framework main file.
+
+ REMARKS
+ General test wrapper for HDF5 base library test programs
+
+ DESIGN
+ Each test function should be implemented as function having no
+ parameters and returning void (i.e. no return value). They should be put
+ into the list of InitTest() calls in main() below. Functions which depend
+ on other functionality should be placed below the InitTest() call for the
+ base functionality testing.
+ Each test module should include testhdf5.h and define a unique set of
+ names for test files they create.
+
+ BUGS/LIMITATIONS
+
+ EXPORTED ROUTINES/VARIABLES:
+ Two variables are exported: num_errs, and Verbosity.
+
+ */
+
+#if defined __MWERKS__
+#include <console.h>
+#endif
+
+#include <stdarg.h>
+
+#define MAXNUMOFTESTS 30
+#define HDF5_TEST_MASTER
+
+/* Internal Variables */
+static int Index = 0;
+
+/* Global variables */
+int num_errs = 0;
+int Verbosity;
+
+// Use C version of the header file testhdf5.h instead of re-coding it
+#include <testhdf5.h>
+#include <H5Cpp.h>
+
+#ifndef H5_NO_NAMESPACE
+using namespace H5;
+#endif
+
+struct TestStruct {
+ int NumErrors;
+ char Description[64];
+ int SkipFlag;
+ char Name[16];
+ void (*Call) (void);
+ void (*Cleanup) (void);
+} Test[MAXNUMOFTESTS];
+
+static void InitTest(const char *TheName, void (*TheCall) (void), void (*Cleanup) (void), const char *TheDescr);
+static void usage(void);
+
+static void
+InitTest(const char *TheName, void (*TheCall) (void), void (*Cleanup) (void), const char *TheDescr)
+{
+ if (Index >= MAXNUMOFTESTS) {
+ print_func("Uh-oh, too many tests added, increase MAXNUMOFTEST!\n");
+ exit(-1);
+ } /* end if */
+ HDstrcpy(Test[Index].Description, TheDescr);
+ HDstrcpy(Test[Index].Name, TheName);
+ Test[Index].Call = TheCall;
+ Test[Index].Cleanup = Cleanup;
+ Test[Index].NumErrors = -1;
+ Test[Index].SkipFlag = 0;
+ Index++;
+}
+
+static void
+usage(void)
+{
+ intn i;
+
+ print_func("Usage: testhdf5 [-v[erbose] (l[ow]|m[edium]|h[igh]|0-10)] \n");
+ print_func(" [-[e]x[clude] name+] \n");
+ print_func(" [-o[nly] name+] \n");
+ print_func(" [-b[egin] name] \n");
+ print_func(" [-s[ummary]] \n");
+ print_func(" [-c[leanoff]] \n");
+ print_func(" [-n[ocaching]] \n");
+ print_func(" [-h[elp]] \n");
+ print_func("\n\n");
+ print_func("verbose controls the amount of information displayed\n");
+ print_func("exclude to exclude tests by name\n");
+ print_func("only to name tests which should be run\n");
+ print_func("begin start at the name of the test givin\n");
+ print_func("summary prints a summary of test results at the end\n");
+ print_func("cleanoff does not delete *.hdf files after execution of tests\n");
+ print_func("nocaching do not turn on low-level DD caching\n");
+ print_func("help print out this information\n");
+ print_func("\n\n");
+ print_func("This program currently tests the following: \n\n");
+ print_func("%16s %s\n", "Name", "Description");
+ print_func("%16s %s\n", "----", "-----------");
+ for (i = 0; i < Index; i++)
+ print_func("%16s %s\n", Test[i].Name, Test[i].Description);
+ print_func("\n\n");
+} /* end usage() */
+
+/*
+ * This routine is designed to provide equivalent functionality to 'printf'
+ * and allow easy replacement for environments which don't have stdin/stdout
+ * available. (i.e. Windows & the Mac)
+ */
+int
+print_func(const char *format,...)
+{
+ va_list arglist;
+ int ret_value;
+
+ va_start(arglist, format);
+ ret_value = vprintf(format, arglist);
+ va_end(arglist);
+ return (ret_value);
+}
+
+void
+test_tbbt(void)
+{ }
+
+int
+main(int argc, char *argv[])
+{
+ int CLLoop; /* Command Line Loop */
+ int Loop, Loop1;
+ int Summary = 0;
+ int CleanUp = 1;
+ int Cache = 1;
+
+#if defined __MWERKS__
+ argc = ccommand(&argv);
+#endif
+
+#if !(defined MAC || defined __MWERKS__ || defined SYMANTEC_C)
+ /* Un-buffer the stdout and stderr */
+ setbuf(stderr, NULL);
+ setbuf(stdout, NULL);
+#endif
+
+ /*
+ * Turn off automatic error reporting since we do it ourselves. Besides,
+ * half the functions this test calls are private, so automatic error
+ * reporting wouldn't do much good since it's triggered at the API layer.
+ */
+ Exception::dontPrint();
+
+ // Tests are generally arranged from least to most complexity...
+ //InitTest("metadata", test_metadata, cleanup_metadata, "Encode/decode metadata code");
+
+ // C++ API doesn't need this test */
+ InitTest("tbbt", test_tbbt, NULL, "Threaded, Balanced, Binary Trees - not tested");
+
+ // testing file creation and opening in tfile.cpp
+ InitTest("file", test_file, cleanup_file, "Low-Level File I/O");
+
+ // Comment out tests that are not done yet. - BMR, Feb 2001
+ //InitTest("h5s", test_h5s, cleanup_h5s, "Dataspaces");
+ //InitTest("attr", test_attr, cleanup_attr, "Attributes");
+ //InitTest("select", test_select, cleanup_select, "Selections");
+ //InitTest("time", test_time, cleanup_time, "Time Datatypes");
+ //InitTest("reference", test_reference, cleanup_reference, "References");
+ //InitTest("vltypes", test_vltypes, cleanup_vltypes, "Variable-Length Datatypes");
+ //InitTest("vlstrings", test_vlstrings, cleanup_vlstrings, "Variable-Length Strings");
+ //InitTest("iterate", test_iterate, cleanup_iterate, "Group & Attribute Iteration");
+ //InitTest("array", test_array, cleanup_array, "Array Datatypes");
+ //InitTest("genprop", test_genprop, cleanup_genprop, "Generic Properties");
+
+ Verbosity = 4; /* Default Verbosity is Low */
+ uintn major, minor, release;
+ H5Library::getLibVersion( major, minor, release);
+
+ print_func("\nFor help use: testhdf5 -help\n");
+ print_func("Linked with hdf5 version %u.%u release %u\n",
+ (unsigned)major, (unsigned)minor, (unsigned)release);
+ for (CLLoop = 1; CLLoop < argc; CLLoop++) {
+ if ((argc > CLLoop + 1) && ((HDstrcmp(argv[CLLoop], "-verbose") == 0) ||
+ (HDstrcmp(argv[CLLoop], "-v") == 0))) {
+ if (argv[CLLoop + 1][0] == 'l')
+ Verbosity = 4;
+ else if (argv[CLLoop + 1][0] == 'm')
+ Verbosity = 6;
+ else if (argv[CLLoop + 1][0] == 'h')
+ Verbosity = 10;
+ else
+ Verbosity = atoi(argv[CLLoop + 1]);
+ } /* end if */
+ if ((argc > CLLoop) && ((HDstrcmp(argv[CLLoop], "-summary") == 0) ||
+ (HDstrcmp(argv[CLLoop], "-s") == 0)))
+ Summary = 1;
+
+ if ((argc > CLLoop) && ((HDstrcmp(argv[CLLoop], "-help") == 0) ||
+ (HDstrcmp(argv[CLLoop], "-h") == 0))) {
+ usage();
+ exit(0);
+ }
+ if ((argc > CLLoop) && ((HDstrcmp(argv[CLLoop], "-cleanoff") == 0) ||
+ (HDstrcmp(argv[CLLoop], "-c") == 0)))
+ CleanUp = 0;
+
+ if ((argc > CLLoop) && ((HDstrcmp(argv[CLLoop], "-nocache") == 0) ||
+ (HDstrcmp(argv[CLLoop], "-n") == 0))) {
+ Cache = 0;
+ printf ("Cache = %d\n", Cache);
+ }
+
+ if ((argc > CLLoop + 1) && ((HDstrcmp(argv[CLLoop], "-exclude") == 0) ||
+ (HDstrcmp(argv[CLLoop], "-x") == 0))) {
+ Loop = CLLoop + 1;
+ while ((Loop < argc) && (argv[Loop][0] != '-')) {
+ for (Loop1 = 0; Loop1 < Index; Loop1++)
+ if (HDstrcmp(argv[Loop], Test[Loop1].Name) == 0)
+ Test[Loop1].SkipFlag = 1;
+ Loop++;
+ } /* end while */
+ } /* end if */
+ if ((argc > CLLoop + 1) && ((HDstrcmp(argv[CLLoop], "-begin") == 0) ||
+ (HDstrcmp(argv[CLLoop], "-b") == 0))) {
+ Loop = CLLoop + 1;
+ while ((Loop < argc) && (argv[Loop][0] != '-')) {
+ for (Loop1 = 0; Loop1 < Index; Loop1++) {
+ if (HDstrcmp(argv[Loop], Test[Loop1].Name) != 0)
+ Test[Loop1].SkipFlag = 1;
+ if (HDstrcmp(argv[Loop], Test[Loop1].Name) == 0)
+ Loop1 = Index;
+ } /* end for */
+ Loop++;
+ } /* end while */
+ } /* end if */
+ if ((argc > CLLoop + 1) && ((HDstrcmp(argv[CLLoop], "-only") == 0) ||
+ (HDstrcmp(argv[CLLoop], "-o") == 0))) {
+ for (Loop = 0; Loop < Index; Loop++)
+ Test[Loop].SkipFlag = 1;
+ Loop = CLLoop + 1;
+ while ((Loop < argc) && (argv[Loop][0] != '-')) {
+ for (Loop1 = 0; Loop1 < Index; Loop1++)
+ if (HDstrcmp(argv[Loop], Test[Loop1].Name) == 0)
+ Test[Loop1].SkipFlag = 0;
+ Loop++;
+ } /* end while */
+ } /* end if */
+ } /* end for */
+
+#ifdef NOT_YET
+ if (Cache) /* turn on caching, unless we were instucted not to */
+ Hcache(CACHE_ALL_FILES, TRUE);
+#endif /* NOT_YET */
+
+ for (Loop = 0; Loop < Index; Loop++) {
+ if (Test[Loop].SkipFlag) {
+ MESSAGE(2, ("Skipping -- %s \n", Test[Loop].Description));
+ } else {
+ MESSAGE(2, ("Testing -- %s (%s) \n", Test[Loop].Description,
+ Test[Loop].Name));
+ MESSAGE(5, ("===============================================\n"));
+ Test[Loop].NumErrors = num_errs;
+ (*Test[Loop].Call) ();
+ Test[Loop].NumErrors = num_errs - Test[Loop].NumErrors;
+ MESSAGE(5, ("===============================================\n"));
+ MESSAGE(5, ("There were %d errors detected.\n\n", (int) Test[Loop].NumErrors));
+ } /* end else */
+ } /* end for */
+
+ MESSAGE(2, ("\n\n"))
+ if (num_errs)
+ print_func("!!! %d Error(s) were detected !!!\n\n", (int) num_errs);
+ else
+ print_func("All tests were successful. \n\n");
+
+ if (Summary) {
+ print_func("Summary of Test Results:\n");
+ print_func("Name of Test Errors Description of Test\n");
+ print_func("---------------- ------ --------------------------------------\n");
+
+ for (Loop = 0; Loop < Index; Loop++) {
+ if (Test[Loop].NumErrors == -1)
+ print_func("%16s %6s %s\n", Test[Loop].Name, "N/A", Test[Loop].Description);
+ else
+ print_func("%16s %6d %s\n", Test[Loop].Name, (int) Test[Loop].NumErrors,
+ Test[Loop].Description);
+ } /* end for */
+ print_func("\n\n");
+ } /* end if */
+ if (CleanUp && !getenv("HDF5_NOCLEANUP")) {
+ MESSAGE(2, ("\nCleaning Up temp files...\n\n"));
+
+ /* call individual cleanup routines in each source module */
+ for (Loop = 0; Loop < Index; Loop++)
+ if (!Test[Loop].SkipFlag && Test[Loop].Cleanup!=NULL)
+ (*Test[Loop].Cleanup) ();
+ }
+ return (num_errs);
+} /* end main() */
+
diff --git a/c++/test/tfile.cpp b/c++/test/tfile.cpp
new file mode 100644
index 0000000..f359eb7
--- /dev/null
+++ b/c++/test/tfile.cpp
@@ -0,0 +1,332 @@
+/****************************************************************************
+ * NCSA HDF *
+ * Software Development Group *
+ * National Center for Supercomputing Applications *
+ * University of Illinois at Urbana-Champaign *
+ * 605 E. Springfield, Champaign IL 61820 *
+ * *
+ * For conditions of distribution and use, see the accompanying *
+ * hdf/COPYING file. *
+ * *
+ ****************************************************************************/
+
+/***********************************************************
+*
+* Test program: tfile
+*
+* Test the low-level file I/O features.
+*
+*************************************************************/
+
+#include <testhdf5.h>
+#include <H5Cpp.h>
+
+#ifndef H5_NO_NAMESPACE
+using namespace H5;
+#endif
+
+#include <H5private.h>
+#include <H5Bprivate.h>
+#include <H5Pprivate.h>
+
+#define F1_USERBLOCK_SIZE (hsize_t)0
+#define F1_OFFSET_SIZE sizeof(haddr_t)
+#define F1_LENGTH_SIZE sizeof(hsize_t)
+#define F1_SYM_LEAF_K 4
+#define F1_SYM_INTERN_K 16
+#define FILE1 "tfile1.h5"
+
+#define F2_USERBLOCK_SIZE (hsize_t)512
+#define F2_OFFSET_SIZE 8
+#define F2_LENGTH_SIZE 8
+#define F2_SYM_LEAF_K 8
+#define F2_SYM_INTERN_K 32
+#define FILE2 "tfile2.h5"
+
+#define F3_USERBLOCK_SIZE (hsize_t)0
+#define F3_OFFSET_SIZE F2_OFFSET_SIZE
+#define F3_LENGTH_SIZE F2_LENGTH_SIZE
+#define F3_SYM_LEAF_K F2_SYM_LEAF_K
+#define F3_SYM_INTERN_K F2_SYM_INTERN_K
+#define FILE3 "tfile3.h5"
+
+
+/*-------------------------------------------------------------------------
+ * Function: test_file_create
+ *
+ * Purpose: Test file and template creations
+ *
+ * Return: None
+ *
+ * Programmer: Binh-Minh Ribler
+ * January, 2001
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static void
+test_file_create(void)
+{
+ hid_t tmpl1, tmpl2; /*file creation templates */
+ int iparm, iparm2;
+ herr_t ret; /*generic return value */
+
+ /* Output message about test being performed */
+ MESSAGE(5, ("Testing Low-Level File Creation I/O\n"));
+
+ /* Test create with various sequences of H5F_ACC_EXCL and */
+ /* H5F_ACC_TRUNC flags */
+
+ /* Create with H5F_ACC_EXCL */
+ /* First ensure the file does not exist */
+ //remove(FILE1);
+
+ try {
+ H5File* fid1 = new H5File (FILE1, H5F_ACC_EXCL);
+
+ /*
+ * try to create the same file with H5F_ACC_TRUNC. This should fail
+ * because fid1 is the same file and is currently open.
+ */
+ try { H5File fid2 (FILE1, H5F_ACC_TRUNC); }
+ catch( FileIException error ) {
+ // cannot use fid2 here (out of scope), but the exception was
+ // thrown only if file id was < 0, so -1 is used to verify - 1/15/01
+ VERIFY(-1, FAIL, "H5File constructor");
+ }
+ // Close file fid1
+ delete fid1;
+
+ /*
+ * Try again with H5F_ACC_EXCL. This should fail because the file already
+ * exists from the previous steps.
+ */
+ try { fid1 = new H5File( FILE1, H5F_ACC_EXCL ); }
+ catch( FileIException error ){ VERIFY(-1, FAIL, "H5File constructor"); }
+
+ // Test create with H5F_ACC_TRUNC. This will truncate the existing file.
+ fid1 = new H5File (FILE1, H5F_ACC_TRUNC);
+
+ /*
+ * Try to truncate first file again. This should fail because fid1 is the
+ * same file and is currently open.
+ */
+ try { H5File fid2 (FILE1, H5F_ACC_TRUNC); }
+ catch( FileIException error ) { VERIFY(-1, FAIL, "H5File constructor"); }
+
+ /*
+ * Try with H5F_ACC_EXCL. This should fail too because the file already
+ * exists.
+ */
+ try { H5File fid3 (FILE1, H5F_ACC_EXCL); }
+ catch( FileIException error ) { VERIFY(-1, FAIL, "H5File constructor"); }
+
+ /* Get the file-creation template */
+ FileCreatPropList tmpl1 = fid1->getCreatePlist();
+
+ hsize_t ublock = tmpl1.getUserblock();
+ VERIFY(ublock, F1_USERBLOCK_SIZE, "FileCreatPropList::H5Pget_userblock");
+
+ size_t parm1, parm2; /*file-creation parameters */
+ tmpl1.getSizes( parm1, parm2);
+ VERIFY(parm1, F1_OFFSET_SIZE, "FileCreatPropList::getSizes");
+ VERIFY(parm2, F1_LENGTH_SIZE, "FileCreatPropList::getSizes");
+
+ int iparm1, iparm2; /*file-creation parameters */
+ tmpl1.getSymk( iparm1, iparm2);
+ VERIFY(iparm1, F1_SYM_INTERN_K, "FileCreatPropList::getSymk");
+ VERIFY(iparm2, F1_SYM_LEAF_K, "FileCreatPropList::getSymk");
+
+ // tmpl1 is automatically closed; if error occurs, it'll be
+ // caught in the catch block
+
+ /* Close first file */
+ delete fid1;
+ }
+ catch( PropListIException error ) {
+ CHECK(-1, FAIL, error.getCDetailMesg());
+ }
+ catch( FileIException error ) {
+ CHECK(-1, FAIL, error.getCDetailMesg());
+ }
+
+ try
+ {
+ /* Create a new file with a non-standard file-creation template */
+ FileCreatPropList* tmpl1 = new FileCreatPropList;
+
+ /* Set the new file-creation parameters */
+ tmpl1->setUserblock (F2_USERBLOCK_SIZE);
+ tmpl1->setSizes( F2_OFFSET_SIZE, F2_LENGTH_SIZE );
+ tmpl1->setSymk( F2_SYM_INTERN_K, F2_SYM_LEAF_K );
+
+ /*
+ * Try to create second file, with non-standard file-creation template
+ * params.
+ */
+ H5File fid2( FILE2, H5F_ACC_TRUNC, *tmpl1 );
+
+ /* Release file-creation template */
+ delete tmpl1;
+
+ /* Get the file-creation template */
+ tmpl1 = new FileCreatPropList (fid2.getCreatePlist());
+
+ /* Get the file-creation parameters */
+ hsize_t ublock = tmpl1->getUserblock();
+ VERIFY(ublock, F2_USERBLOCK_SIZE, "FileCreatPropList::getUserblock");
+
+ size_t parm1, parm2; /*file-creation parameters */
+ tmpl1->getSizes( parm1, parm2);
+ VERIFY(parm1, F2_OFFSET_SIZE, "FileCreatPropList::getSizes");
+ VERIFY(parm2, F2_LENGTH_SIZE, "FileCreatPropList::getSizes");
+
+ int iparm1, iparm2; /*file-creation parameters */
+ tmpl1->getSymk( iparm1, iparm2);
+ VERIFY(iparm1, F2_SYM_INTERN_K, "FileCreatPropList::getSymk");
+ VERIFY(iparm2, F2_SYM_LEAF_K, "FileCreatPropList::getSymk");
+
+ /* Clone the file-creation template */
+ FileCreatPropList tmpl2;
+ tmpl2.copy (*tmpl1);
+
+ /* Dynamically release file-creation template */
+ delete tmpl1;
+
+ /* Set the new file-creation parameter */
+ tmpl2.setUserblock( F3_USERBLOCK_SIZE );
+
+ /*
+ * Try to create second file, with non-standard file-creation template
+ * params
+ */
+ H5File fid3( FILE3, H5F_ACC_TRUNC, tmpl2 );
+
+ /* Get the file-creation template */
+ tmpl1 = new FileCreatPropList (fid3.getCreatePlist());
+
+ /* Get the file-creation parameters */
+ ublock = tmpl1->getUserblock();
+ VERIFY(ublock, F3_USERBLOCK_SIZE, "FileCreatPropList::getUserblock");
+
+ tmpl1->getSizes( parm1, parm2);
+ VERIFY(parm1, F3_OFFSET_SIZE, "FileCreatPropList::getSizes");
+ VERIFY(parm2, F3_LENGTH_SIZE, "FileCreatPropList::getSizes");
+
+ tmpl1->getSymk( iparm1, iparm2);
+ VERIFY(iparm1, F3_SYM_INTERN_K, "FileCreatPropList::getSymk");
+ VERIFY(iparm2, F3_SYM_LEAF_K, "FileCreatPropList::getSymk");
+
+ /* Dynamically release file-creation template */
+ delete tmpl1;
+ }
+ catch( PropListIException error ) {
+ CHECK(-1, FAIL, error.getCDetailMesg());
+ }
+ catch( FileIException error ) {
+ CHECK(-1, FAIL, error.getCDetailMesg());
+ }
+} /* test_file_create() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: test_file_open
+ *
+ * Purpose: Test file accesses
+ *
+ * Return: None
+ *
+ * Programmer: Binh-Minh Ribler
+ * January, 2001
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static void
+test_file_open(void)
+{
+ /* Output message about test being performed */
+ MESSAGE(5, ("Testing Low-Level File Opening I/O\n"));
+
+ try {
+
+ /* Open first file */
+ H5File fid1 (FILE2, H5F_ACC_RDWR );
+
+ /* Get the file-creation template */
+ //FileCreatPropList tmpl1;
+ FileCreatPropList tmpl1 = fid1.getCreatePlist();
+
+ /* Get the file-creation parameters */
+ hsize_t ublock = tmpl1.getUserblock();
+ VERIFY(ublock, F2_USERBLOCK_SIZE, "FileCreatPropList::getUserblock");
+
+ size_t parm1, parm2; /*file-creation parameters */
+ tmpl1.getSizes( parm1, parm2);
+ VERIFY(parm1, F2_OFFSET_SIZE, "FileCreatPropList::getSizes");
+ VERIFY(parm2, F2_LENGTH_SIZE, "FileCreatPropList::getSizes");
+
+ int iparm1, iparm2; /*file-creation parameters */
+ tmpl1.getSymk( iparm1, iparm2);
+ VERIFY(iparm1, F2_SYM_INTERN_K, "FileCreatPropList::getSymk");
+ VERIFY(iparm2, F2_SYM_LEAF_K, "FileCreatPropList::getSymk");
+ } // end of try block
+
+ catch( FileIException error ) {
+ CHECK(FAIL, FAIL, error.getCDetailMesg());
+ }
+ catch( PropListIException error ) {
+ CHECK(FAIL, FAIL, error.getCDetailMesg());
+ }
+} /* test_file_open() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: test_file
+ *
+ * Purpose: Main program
+ *
+ * Return: None
+ *
+ * Programmer: Binh-Minh Ribler
+ * January, 2001
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+void
+test_file(void)
+{
+ /* Output message about test being performed */
+ MESSAGE(5, ("Testing Low-Level File I/O\n"));
+
+ test_file_create(); /* Test file creation (also creation templates) */
+ test_file_open(); /* Test file opening */
+} /* test_file() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: cleanup_file
+ *
+ * Purpose: Cleanup temporary test files
+ *
+ * Return: none
+ *
+ * Programmer: Albert Cheng
+ * July 2, 1998
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+void
+cleanup_file(void)
+{
+ remove(FILE1);
+ remove(FILE2);
+ remove(FILE3);
+}
+