summaryrefslogtreecommitdiffstats
path: root/c++
diff options
context:
space:
mode:
Diffstat (limited to 'c++')
-rw-r--r--c++/test/Makefile.am4
-rw-r--r--c++/test/Makefile.in13
-rw-r--r--c++/test/h5cpputil.cpp4
-rw-r--r--c++/test/h5cpputil.h46
-rw-r--r--c++/test/tcompound.cpp762
-rw-r--r--c++/test/testhdf5.cpp12
-rw-r--r--c++/test/trefer.cpp17
-rw-r--r--c++/test/ttypes.cpp810
8 files changed, 1648 insertions, 20 deletions
diff --git a/c++/test/Makefile.am b/c++/test/Makefile.am
index 61933f5..103d55b 100644
--- a/c++/test/Makefile.am
+++ b/c++/test/Makefile.am
@@ -37,8 +37,8 @@ check_PROGRAMS=$(TEST_PROG)
LDADD=$(LIBH5CPP) $(LIBH5TEST) $(LIBHDF5)
dsets_SOURCES=dsets.cpp h5cpputil.cpp
-testhdf5_SOURCES=testhdf5.cpp tattr.cpp tfile.cpp th5s.cpp trefer.cpp \
- tvlstr.cpp h5cpputil.cpp
+testhdf5_SOURCES=testhdf5.cpp tattr.cpp tcompound.cpp tfile.cpp th5s.cpp \
+ trefer.cpp ttypes.cpp tvlstr.cpp h5cpputil.cpp
# Tell conclude.am that these are C++ tests.
HDF_CXX=yes
diff --git a/c++/test/Makefile.in b/c++/test/Makefile.in
index 2fa6a03..51bc77d 100644
--- a/c++/test/Makefile.in
+++ b/c++/test/Makefile.in
@@ -73,8 +73,9 @@ am__DEPENDENCIES_3 = $(top_builddir)/src/libhdf5.la
dsets_DEPENDENCIES = $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_2) \
$(am__DEPENDENCIES_3)
am_testhdf5_OBJECTS = testhdf5.$(OBJEXT) tattr.$(OBJEXT) \
- tfile.$(OBJEXT) th5s.$(OBJEXT) trefer.$(OBJEXT) \
- tvlstr.$(OBJEXT) h5cpputil.$(OBJEXT)
+ tcompound.$(OBJEXT) tfile.$(OBJEXT) th5s.$(OBJEXT) \
+ trefer.$(OBJEXT) ttypes.$(OBJEXT) tvlstr.$(OBJEXT) \
+ h5cpputil.$(OBJEXT)
testhdf5_OBJECTS = $(am_testhdf5_OBJECTS)
testhdf5_LDADD = $(LDADD)
testhdf5_DEPENDENCIES = $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_2) \
@@ -229,7 +230,6 @@ SIZE_T = @SIZE_T@
STATIC_SHARED = @STATIC_SHARED@
STRIP = @STRIP@
TESTPARALLEL = @TESTPARALLEL@
-TIME = @TIME@
TR = @TR@
TRACE_API = @TRACE_API@
USE_FILTER_DEFLATE = @USE_FILTER_DEFLATE@
@@ -293,6 +293,7 @@ target_alias = @target_alias@
# Shell commands used in Makefiles
RM = rm -f
CP = cp
+TIME = time
# Some machines need a command to run executables; this is that command
# so that our tests will run.
@@ -345,8 +346,8 @@ TEST_PROG = dsets testhdf5
# The tests depend on the hdf5 library, test library, and the c++ library
LDADD = $(LIBH5CPP) $(LIBH5TEST) $(LIBHDF5)
dsets_SOURCES = dsets.cpp h5cpputil.cpp
-testhdf5_SOURCES = testhdf5.cpp tattr.cpp tfile.cpp th5s.cpp trefer.cpp \
- tvlstr.cpp h5cpputil.cpp
+testhdf5_SOURCES = testhdf5.cpp tattr.cpp tcompound.cpp tfile.cpp th5s.cpp \
+ trefer.cpp ttypes.cpp tvlstr.cpp h5cpputil.cpp
# Tell conclude.am that these are C++ tests.
@@ -424,10 +425,12 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dsets.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/h5cpputil.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tattr.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tcompound.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/testhdf5.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tfile.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/th5s.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/trefer.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ttypes.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tvlstr.Po@am__quote@
.cpp.o:
diff --git a/c++/test/h5cpputil.cpp b/c++/test/h5cpputil.cpp
index 03f0c9f..e1c3468 100644
--- a/c++/test/h5cpputil.cpp
+++ b/c++/test/h5cpputil.cpp
@@ -97,9 +97,9 @@ int test_report( int nerrors, const H5std_string& testname )
void issue_fail_msg(const char* where, int line, const char* file_name,
const char* message)
{
- if (GetTestVerbosity()>=VERBO_HI)
+ //if (GetTestVerbosity()>=VERBO_HI)
{
- cerr << "--> From " << where << " at line " << line
+ cerr << "ERROR>>> From " << where << " at line " << line
<< " in " << file_name << " - " << message << endl << endl;
}
}
diff --git a/c++/test/h5cpputil.h b/c++/test/h5cpputil.h
index 0173d2f..7aa77a9 100644
--- a/c++/test/h5cpputil.h
+++ b/c++/test/h5cpputil.h
@@ -34,8 +34,9 @@ using std::cerr;
using std::endl;
#endif
-int test_report (int, const H5std_string&);
+#define SUBTEST(WHAT) {printf(" Subtest: %-52s",WHAT); fflush(stdout);}
+int test_report (int, const H5std_string&);
void issue_fail_msg(const char* where, int line, const char* file_name,
const char* message="");
@@ -68,6 +69,22 @@ template <class Type1, class Type2>
}
}
+template <class Type1, class Type2>
+ void verify_val_noteq(Type1 x, Type2 value, const char* where, int line, const char* file_name)
+{
+ if (GetTestVerbosity()>=VERBO_HI)
+ {
+ cerr << " Call to routine: " << where << " at line " << line
+ << " in " << file_name << " had value " << x << endl;
+ }
+ if (x == value)
+ {
+ cerr << "*** UNEXPECTED VALUE from " << where << " should not be "
+ << value << " at line " << line << " in " << file_name << endl;
+ IncTestNumErrs();
+ }
+}
+
class InvalidActionException : public Exception {
public:
InvalidActionException(const H5std_string func_name, const H5std_string message = DEFAULT_MSG);
@@ -75,4 +92,31 @@ class InvalidActionException : public Exception {
virtual ~InvalidActionException();
};
+/* Prototypes for the test routines */
+void test_attr(void);
+void test_compound(void);
+void test_file(void);
+void test_h5s(void);
+void test_reference(void);
+void test_types(void);
+void test_vlstrings(void);
+
+/* Prototypes for the cleanup routines */
+void cleanup_attr(void);
+void cleanup_compound(void);
+void cleanup_file(void);
+void cleanup_h5s(void);
+void cleanup_reference(void);
+void cleanup_types(void);
+void cleanup_vlstrings(void);
+/* not yet
+void cleanup_select(void);
+void cleanup_time(void);
+void cleanup_vltypes(void);
+void cleanup_iterate(void);
+void cleanup_array(void);
+void cleanup_genprop(void);
+void cleanup_misc(void);
+*/
+
#endif
diff --git a/c++/test/tcompound.cpp b/c++/test/tcompound.cpp
new file mode 100644
index 0000000..27c759b
--- /dev/null
+++ b/c++/test/tcompound.cpp
@@ -0,0 +1,762 @@
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * Copyright by The HDF Group (THG). *
+ * All rights reserved. *
+ * *
+ * This file is part of HDF5. The full HDF5 copyright notice, including *
+ * terms governing use, modification, and redistribution, is contained in *
+ * the files COPYING and Copyright.html. COPYING can be found at the root *
+ * of the source code distribution tree; Copyright.html can be found at the *
+ * root level of an installed copy of the electronic HDF5 document set and *
+ * is linked from the top-level documents page. It can also be found at *
+ * http://www.hdfgroup.org/HDF5/doc/Copyright.html. If you do not have *
+ * access to either file, you may request a copy from help@hdfgroup.org. *
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+/*****************************************************************************
+ FILE
+ tcompound.cpp - HDF5 C++ testing the compound data type functionality
+
+ ***************************************************************************/
+
+#ifdef OLD_HEADER_FILENAME
+#include <iostream.h>
+#else
+#include <iostream>
+#endif
+#include <string>
+
+#ifndef H5_NO_NAMESPACE
+#ifndef H5_NO_STD
+ using std::cerr;
+ using std::endl;
+#endif // H5_NO_STD
+#endif
+
+#include "testhdf5.h" // C test header file
+#include "H5Cpp.h" // C++ API header file
+
+#ifndef H5_NO_NAMESPACE
+ using namespace H5;
+#endif
+
+#include "h5cpputil.h" // C++ utilility header file
+
+/* Number of elements in each test */
+#define NTESTELEM 100000
+
+typedef struct complex_t {
+ double re;
+ double im;
+} complex_t;
+
+
+/*-------------------------------------------------------------------------
+ * Function: test_compound_1
+ *
+ * Purpose: Tests various things about compound data types.
+ *
+ * Return: None
+ *
+ * Programmer: Binh-Minh Ribler (using C version)
+ * January, 2007
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static void test_compound_1(void)
+{
+ // Output message about test being performed
+ SUBTEST("Compound Data Types");
+ try
+ {
+ // Create an empty compound datatype
+ CompType complex_type(sizeof(complex_t));
+
+ // Add a couple of fields
+ complex_type.insertMember("real", HOFFSET(complex_t, re), PredType::NATIVE_DOUBLE);
+ complex_type.insertMember("imaginary", HOFFSET(complex_t, im), PredType::NATIVE_DOUBLE);
+
+ PASSED();
+ } // end of try block
+
+ catch (Exception E) {
+ issue_fail_msg(E.getCFuncName(), __LINE__, __FILE__, E.getCDetailMsg());
+ }
+} // test_compound_1()
+
+
+/*-------------------------------------------------------------------------
+ * Function: test_compound_2
+ *
+ * Purpose: Tests a compound type conversion where the source and
+ * destination are the same except for the order of the
+ * elements.
+ *
+ * Return: None
+ *
+ * Programmer: Binh-Minh Ribler (use C version)
+ * January, 2007
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static void test_compound_2(void)
+{
+ typedef struct {
+ int a, b, c[4], d, e;
+ } src_typ_t;
+ typedef struct {
+ int e, d, c[4], b, a;
+ } dst_typ_t;
+
+ src_typ_t *s_ptr;
+ dst_typ_t *d_ptr;
+ const int nelmts = NTESTELEM;
+ const hsize_t four = 4;
+ int i;
+ unsigned char *buf=NULL, *orig=NULL, *bkg=NULL;
+
+ // Output message about test being performed
+ SUBTEST("Compound Element Reordering");
+ try
+ {
+ /* Sizes should be the same, but be careful just in case */
+ buf = (unsigned char*)malloc(nelmts * MAX(sizeof(src_typ_t), sizeof(dst_typ_t)));
+ bkg = (unsigned char*)malloc(nelmts * sizeof(dst_typ_t));
+ orig = (unsigned char*)malloc(nelmts * sizeof(src_typ_t));
+ for (i=0; i<nelmts; i++) {
+ s_ptr = ((src_typ_t*)orig) + i;
+ s_ptr->a = i*8+0;
+ s_ptr->b = i*8+1;
+ s_ptr->c[0] = i*8+2;
+ s_ptr->c[1] = i*8+3;
+ s_ptr->c[2] = i*8+4;
+ s_ptr->c[3] = i*8+5;
+ s_ptr->d = i*8+6;
+ s_ptr->e = i*8+7;
+ }
+ memcpy(buf, orig, nelmts*sizeof(src_typ_t));
+
+ /* Build hdf5 datatypes */
+ ArrayType* array_dt = new ArrayType(PredType::NATIVE_INT, 1, &four);
+
+ // Create an empty compound datatype
+ CompType st(sizeof(src_typ_t));
+ st.insertMember("a", HOFFSET(src_typ_t, a), PredType::NATIVE_INT);
+ st.insertMember("b", HOFFSET(src_typ_t, b), PredType::NATIVE_INT);
+ st.insertMember("c", HOFFSET(src_typ_t, c), *array_dt);
+ st.insertMember("d", HOFFSET(src_typ_t, d), PredType::NATIVE_INT);
+ st.insertMember("e", HOFFSET(src_typ_t, e), PredType::NATIVE_INT);
+ array_dt->close();
+
+ array_dt = new ArrayType(PredType::NATIVE_INT, 1, &four);
+
+ // Create an empty compound datatype
+ CompType dt(sizeof(dst_typ_t));
+ dt.insertMember("a", HOFFSET(dst_typ_t, a), PredType::NATIVE_INT);
+ dt.insertMember("b", HOFFSET(dst_typ_t, b), PredType::NATIVE_INT);
+ dt.insertMember("c", HOFFSET(dst_typ_t, c), *array_dt);
+ dt.insertMember("d", HOFFSET(dst_typ_t, d), PredType::NATIVE_INT);
+ dt.insertMember("e", HOFFSET(dst_typ_t, e), PredType::NATIVE_INT);
+ array_dt->close();
+
+ /* Perform the conversion */
+ st.convert(dt, (size_t)nelmts, buf, bkg);
+
+ /* Compare results */
+ for (i=0; i<nelmts; i++) {
+ s_ptr = ((src_typ_t*)orig) + i;
+ d_ptr = ((dst_typ_t*)buf) + i;
+ if (s_ptr->a != d_ptr->a ||
+ s_ptr->b != d_ptr->b ||
+ s_ptr->c[0] != d_ptr->c[0] ||
+ s_ptr->c[1] != d_ptr->c[1] ||
+ s_ptr->c[2] != d_ptr->c[2] ||
+ s_ptr->c[3] != d_ptr->c[3] ||
+ s_ptr->d != d_ptr->d ||
+ s_ptr->e != d_ptr->e) {
+ H5_FAILED();
+ cerr << " i=" << i << endl;
+ cerr << " src={a=" << s_ptr->a << ", b=" << s_ptr->b
+ << "c=[" << s_ptr->c[0] << "," << s_ptr->c[1] << ","
+ << s_ptr->c[2] << "," << s_ptr->c[3] << ", d="
+ << s_ptr->d << ", e=" << s_ptr->e << "}" << endl;
+ cerr << " dst={a=" << s_ptr->a << ", b=" << s_ptr->b
+ << "c=[" << s_ptr->c[0] << "," << s_ptr->c[1] << ","
+ << s_ptr->c[2] << "," << s_ptr->c[3] << ", d="
+ << s_ptr->d << ", e=" << s_ptr->e << "}" << endl;
+ }
+ }
+
+ /* Release resources */
+ free(buf);
+ free(bkg);
+ free(orig);
+ s_ptr = NULL;
+ d_ptr = NULL;
+ st.close();
+ dt.close();
+
+ PASSED();
+ } // end of try block
+
+ catch (Exception E) {
+ issue_fail_msg(E.getCFuncName(), __LINE__, __FILE__, E.getCDetailMsg());
+ }
+} // test_compound_2()
+
+
+/*-------------------------------------------------------------------------
+ * Function: test_compound_3
+ *
+ * Purpose: Tests compound conversions where the source and destination
+ * are the same except the destination is missing a couple
+ * members which appear in the source.
+ *
+ * Return: None
+ *
+ * Programmer: Binh-Minh Ribler (use C version)
+ * January, 2007
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static void test_compound_3(void)
+{
+ typedef struct {
+ int a, b, c[4], d, e;
+ } src_typ_t;
+ typedef struct {
+ int a, c[4], e;
+ } dst_typ_t;
+
+ src_typ_t *s_ptr;
+ dst_typ_t *d_ptr;
+ int i;
+ const int nelmts = NTESTELEM;
+ const hsize_t four = 4;
+ unsigned char *buf=NULL, *orig=NULL, *bkg=NULL;
+
+ // Output message about test being performed
+ SUBTEST("Compound Datatype Subset Conversions");
+ try
+ {
+ /* Initialize */
+ buf = (unsigned char*)malloc(nelmts * MAX(sizeof(src_typ_t), sizeof(dst_typ_t)));
+ bkg = (unsigned char*)malloc(nelmts * sizeof(dst_typ_t));
+ orig = (unsigned char*)malloc(nelmts * sizeof(src_typ_t));
+ for (i=0; i<nelmts; i++) {
+ s_ptr = ((src_typ_t*)orig) + i;
+ s_ptr->a = i*8+0;
+ s_ptr->b = i*8+1;
+ s_ptr->c[0] = i*8+2;
+ s_ptr->c[1] = i*8+3;
+ s_ptr->c[2] = i*8+4;
+ s_ptr->c[3] = i*8+5;
+ s_ptr->d = i*8+6;
+ s_ptr->e = i*8+7;
+ }
+ memcpy(buf, orig, nelmts*sizeof(src_typ_t));
+
+ /* Build hdf5 datatypes */
+ ArrayType* array_dt = new ArrayType(PredType::NATIVE_INT, 1, &four);
+
+ // Create an empty compound datatype
+ CompType st(sizeof(src_typ_t));
+ st.insertMember("a", HOFFSET(src_typ_t, a), PredType::NATIVE_INT);
+ st.insertMember("b", HOFFSET(src_typ_t, b), PredType::NATIVE_INT);
+ st.insertMember("c", HOFFSET(src_typ_t, c), *array_dt);
+ st.insertMember("d", HOFFSET(src_typ_t, d), PredType::NATIVE_INT);
+ st.insertMember("e", HOFFSET(src_typ_t, e), PredType::NATIVE_INT);
+ array_dt->close();
+
+ array_dt = new ArrayType(PredType::NATIVE_INT, 1, &four);
+
+ // Create an empty compound datatype
+ CompType dt(sizeof(dst_typ_t));
+ dt.insertMember("a", HOFFSET(dst_typ_t, a), PredType::NATIVE_INT);
+ dt.insertMember("c", HOFFSET(dst_typ_t, c), *array_dt);
+ dt.insertMember("e", HOFFSET(dst_typ_t, e), PredType::NATIVE_INT);
+ array_dt->close();
+
+ /* Perform the conversion */
+ st.convert(dt, (size_t)nelmts, buf, bkg);
+
+ /* Compare results */
+ for (i=0; i<nelmts; i++) {
+ s_ptr = ((src_typ_t*)orig) + i;
+ d_ptr = ((dst_typ_t*)buf) + i;
+ if (s_ptr->a != d_ptr->a ||
+ s_ptr->c[0] != d_ptr->c[0] ||
+ s_ptr->c[1] != d_ptr->c[1] ||
+ s_ptr->c[2] != d_ptr->c[2] ||
+ s_ptr->c[3] != d_ptr->c[3] ||
+ s_ptr->e != d_ptr->e) {
+ H5_FAILED();
+ cerr << " i=" << i << endl;
+ cerr << " src={a=" << s_ptr->a << ", b=" << s_ptr->b
+ << ", c=[" << s_ptr->c[0] << "," << s_ptr->c[1] << ","
+ << s_ptr->c[2] << "," << s_ptr->c[3] << "], d="
+ << s_ptr->d << ", e=" << s_ptr->e << "}" << endl;
+ cerr << " dst={a=" << d_ptr->a
+ << ", c=[" << d_ptr->c[0] << "," << d_ptr->c[1] << ","
+ << d_ptr->c[2] << "," << d_ptr->c[3] << "], e="
+ << d_ptr->e << "}" << endl;
+ } // if
+ } // for
+
+ /* Release resources */
+ free(buf);
+ free(bkg);
+ free(orig);
+ s_ptr = NULL;
+ d_ptr = NULL;
+ st.close();
+ dt.close();
+
+ PASSED();
+ } // end of try block
+
+ catch (Exception E) {
+ issue_fail_msg(E.getCFuncName(), __LINE__, __FILE__, E.getCDetailMsg());
+ }
+} // test_compound_3()
+
+
+/*-------------------------------------------------------------------------
+ * Function: test_compound_4
+ *
+ * Purpose: Tests compound conversions when the destination has the same
+ * fields as the source but one or more of the fields are
+ * smaller.
+ *
+ * Return: None
+ *
+ * Programmer: Binh-Minh Ribler (use C version)
+ * January, 2007
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static void test_compound_4(void)
+{
+
+ typedef struct {
+ int a, b, c[4], d, e;
+ } src_typ_t;
+
+ typedef struct {
+ short b;
+ int a, c[4];
+ short d;
+ int e;
+ } dst_typ_t;
+
+ src_typ_t *s_ptr;
+ dst_typ_t *d_ptr;
+ int i;
+ const int nelmts = NTESTELEM;
+ const hsize_t four = 4;
+ unsigned char *buf=NULL, *orig=NULL, *bkg=NULL;
+
+ // Output message about test being performed
+ SUBTEST("Compound Element Shrinking & Reordering");
+ try
+ {
+ /* Sizes should be the same, but be careful just in case */
+ buf = (unsigned char*)malloc(nelmts * MAX(sizeof(src_typ_t), sizeof(dst_typ_t)));
+ bkg = (unsigned char*)malloc(nelmts * sizeof(dst_typ_t));
+ orig = (unsigned char*)malloc(nelmts * sizeof(src_typ_t));
+ for (i=0; i<nelmts; i++) {
+ s_ptr = ((src_typ_t*)orig) + i;
+ s_ptr->a = i*8+0;
+ s_ptr->b = (i*8+1) & 0x7fff;
+ s_ptr->c[0] = i*8+2;
+ s_ptr->c[1] = i*8+3;
+ s_ptr->c[2] = i*8+4;
+ s_ptr->c[3] = i*8+5;
+ s_ptr->d = (i*8+6) & 0x7fff;
+ s_ptr->e = i*8+7;
+ }
+ memcpy(buf, orig, nelmts*sizeof(src_typ_t));
+
+ /* Build hdf5 datatypes */
+ ArrayType* array_dt = new ArrayType(PredType::NATIVE_INT, 1, &four);
+
+ // Create an empty compound datatype
+ CompType st(sizeof(src_typ_t));
+ st.insertMember("a", HOFFSET(src_typ_t, a), PredType::NATIVE_INT);
+ st.insertMember("b", HOFFSET(src_typ_t, b), PredType::NATIVE_INT);
+ st.insertMember("c", HOFFSET(src_typ_t, c), *array_dt);
+ st.insertMember("d", HOFFSET(src_typ_t, d), PredType::NATIVE_INT);
+ st.insertMember("e", HOFFSET(src_typ_t, e), PredType::NATIVE_INT);
+ array_dt->close();
+
+ array_dt = new ArrayType(PredType::NATIVE_INT, 1, &four);
+
+ // Create an empty compound datatype
+ CompType dt(sizeof(dst_typ_t));
+ dt.insertMember("a", HOFFSET(dst_typ_t, a), PredType::NATIVE_INT);
+ dt.insertMember("b", HOFFSET(dst_typ_t, b), PredType::NATIVE_SHORT);
+ dt.insertMember("c", HOFFSET(dst_typ_t, c), *array_dt);
+ dt.insertMember("d", HOFFSET(dst_typ_t, d), PredType::NATIVE_SHORT);
+ dt.insertMember("e", HOFFSET(dst_typ_t, e), PredType::NATIVE_INT);
+ array_dt->close();
+
+ /* Perform the conversion */
+ st.convert(dt, (size_t)nelmts, buf, bkg);
+
+ /* Compare results */
+ for (i=0; i<nelmts; i++) {
+ s_ptr = ((src_typ_t*)orig) + i;
+ d_ptr = ((dst_typ_t*)buf) + i;
+ if (s_ptr->a != d_ptr->a ||
+ s_ptr->b != d_ptr->b ||
+ s_ptr->c[0] != d_ptr->c[0] ||
+ s_ptr->c[1] != d_ptr->c[1] ||
+ s_ptr->c[2] != d_ptr->c[2] ||
+ s_ptr->c[3] != d_ptr->c[3] ||
+ s_ptr->d != d_ptr->d ||
+ s_ptr->e != d_ptr->e)
+ {
+ H5_FAILED();
+ cerr << " i=" << i << endl;
+ cerr << " src={a=" << s_ptr->a << ", b=" << s_ptr->b
+ << "c=[" << s_ptr->c[0] << "," << s_ptr->c[1] << ","
+ << s_ptr->c[2] << "," << s_ptr->c[3] << ", d="
+ << s_ptr->d << ", e=" << s_ptr->e << "}" << endl;
+ cerr << " dst={a=" << d_ptr->a << ", b=" << d_ptr->b
+ << "c=[" << d_ptr->c[0] << "," << d_ptr->c[1] << ","
+ << d_ptr->c[2] << "," << d_ptr->c[3] << ", d="
+ << d_ptr->d << ", e=" << d_ptr->e << "}" << endl;
+ } // if
+ } // for
+
+ /* Release resources */
+ free(buf);
+ free(bkg);
+ free(orig);
+ s_ptr = NULL;
+ d_ptr = NULL;
+ st.close();
+ dt.close();
+
+ PASSED();
+ } // end of try block
+
+ catch (Exception E) {
+ issue_fail_msg(E.getCFuncName(), __LINE__, __FILE__, E.getCDetailMsg());
+ }
+} // test_compound_4()
+
+
+/*-------------------------------------------------------------------------
+ * Function: test_compound_5
+ *
+ * Purpose: Many versions of HDF5 have a bug in the optimized compound
+ * datatype conversion function, H5T_conv_struct_opt(), which
+ * is triggered when the top-level type contains a struct
+ * which must undergo a conversion.
+ *
+ * Return: None
+ *
+ * Programmer: Binh-Minh Ribler (use C version)
+ * January, 2007
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static void test_compound_5(void)
+{
+ typedef struct {
+ char name[16];
+ short tdim;
+ short coll_ids[4];
+ } src_typ_t;
+
+ typedef struct {
+ char name[16];
+ short tdim;
+ int coll_ids[4];
+ } dst_typ_t;
+
+ hsize_t dims[1] = {4};
+ src_typ_t src[2] = {{"one", 102, {104, 105, 106, 107}},
+ {"two", 202, {204, 205, 206, 207}}};
+ dst_typ_t *dst;
+ void *buf = calloc(2, sizeof(dst_typ_t));
+ void *bkg = calloc(2, sizeof(dst_typ_t));
+
+ // Output message about test being performed
+ SUBTEST("Optimized Struct Converter");
+ try
+ {
+
+ /* Build datatypes */
+ ArrayType* array_dt = new ArrayType(PredType::NATIVE_SHORT, 1, dims);
+ CompType short_array(4*sizeof(short));
+ short_array.insertMember("_", 0, *array_dt);
+ array_dt->close();
+
+ CompType int_array(4*sizeof(int));
+ array_dt = new ArrayType(PredType::NATIVE_INT, 1, dims);
+ int_array.insertMember("_", 0, *array_dt);
+ array_dt->close();
+
+ StrType strg(PredType::C_S1, 16);
+ CompType src_type(sizeof(src_typ_t));
+ src_type.insertMember("name", HOFFSET(src_typ_t, name), strg);
+ src_type.insertMember("tdim", HOFFSET(src_typ_t, tdim), PredType::NATIVE_SHORT);
+ src_type.insertMember("coll_ids", HOFFSET(src_typ_t, coll_ids), short_array);
+
+ CompType dst_type(sizeof(dst_typ_t));
+ dst_type.insertMember("name", HOFFSET(dst_typ_t, name), strg);
+ dst_type.insertMember("tdim", HOFFSET(dst_typ_t, tdim), PredType::NATIVE_SHORT);
+ dst_type.insertMember("coll_ids", HOFFSET(dst_typ_t, coll_ids), int_array);
+
+ /* Convert data */
+ memcpy(buf, src, sizeof(src));
+ src_type.convert(dst_type, (size_t)2, buf, bkg);
+ dst = (dst_typ_t*)buf;
+
+ /* Cleanup */
+ src_type.close();
+ dst_type.close();
+ strg.close();
+ short_array.close();
+ int_array.close();
+
+ /* Check results */
+ if (memcmp(src[1].name, dst[1].name, sizeof(src[1].name)) ||
+ src[1].tdim!=dst[1].tdim ||
+ src[1].coll_ids[0]!=dst[1].coll_ids[0] ||
+ src[1].coll_ids[1]!=dst[1].coll_ids[1] ||
+ src[1].coll_ids[2]!=dst[1].coll_ids[2] ||
+ src[1].coll_ids[3]!=dst[1].coll_ids[3])
+ { H5_FAILED(); }
+
+ /* Free memory buffers */
+ free(buf);
+ free(bkg);
+ dst = NULL;
+ PASSED();
+ } // end of try block
+
+ catch (Exception E) {
+ issue_fail_msg(E.getCFuncName(), __LINE__, __FILE__, E.getCDetailMsg());
+ }
+} // test_compound_5()
+
+
+/*-------------------------------------------------------------------------
+ * Function: test_compound_6
+ *
+ * Purpose: Tests compound conversions when the destination has the same
+ * fields as the source but one or more of the fields are
+ * larger.
+ *
+ * Return: None
+ *
+ * Programmer: Binh-Minh Ribler (use C version)
+ * January, 2007
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static void test_compound_6(void)
+{
+ typedef struct {
+ short b;
+ short d;
+ } src_typ_t;
+
+ typedef struct {
+ long b;
+ long d;
+ } dst_typ_t;
+
+ src_typ_t *s_ptr;
+ dst_typ_t *d_ptr;
+ int i;
+ const int nelmts = NTESTELEM;
+ unsigned char *buf=NULL, *orig=NULL, *bkg=NULL;
+
+ // Output message about test being performed
+ SUBTEST("Compound Element Growing");
+ try
+ {
+ /* Sizes should be the same, but be careful just in case */
+ buf = (unsigned char*)malloc(nelmts * MAX(sizeof(src_typ_t), sizeof(dst_typ_t)));
+ bkg = (unsigned char*)malloc(nelmts * sizeof(dst_typ_t));
+ orig = (unsigned char*)malloc(nelmts * sizeof(src_typ_t));
+ for (int i=0; i<nelmts; i++) {
+ s_ptr = ((src_typ_t*)orig) + i;
+ s_ptr->b = (i*8+1) & 0x7fff;
+ s_ptr->d = (i*8+6) & 0x7fff;
+ }
+ memcpy(buf, orig, nelmts*sizeof(src_typ_t));
+
+ /* Build hdf5 datatypes */
+ CompType st(sizeof(src_typ_t));
+ st.insertMember("b", HOFFSET(src_typ_t, b), PredType::NATIVE_SHORT);
+ st.insertMember("d", HOFFSET(src_typ_t, d), PredType::NATIVE_SHORT);
+
+ CompType dt(sizeof(dst_typ_t));
+ dt.insertMember("b", HOFFSET(dst_typ_t, b), PredType::NATIVE_LONG);
+ dt.insertMember("d", HOFFSET(dst_typ_t, d), PredType::NATIVE_LONG);
+
+ /* Perform the conversion */
+ st.convert(dt, (size_t)nelmts, buf, bkg);
+
+ /* Compare results */
+ for (i=0; i<nelmts; i++) {
+ s_ptr = ((src_typ_t*)orig) + i;
+ d_ptr = ((dst_typ_t*)buf) + i;
+ if (s_ptr->b != d_ptr->b ||
+ s_ptr->d != d_ptr->d)
+ {
+ H5_FAILED();
+ cerr << " i=" << i << endl;
+ cerr << " src={b=" << s_ptr->b << ", d=" << s_ptr->d
+ << "}" << endl;
+ cerr << " dst={b=" << d_ptr->b << ", d=" << d_ptr->d
+ << "}" << endl;
+ } // if
+ } // for
+
+ /* Release resources */
+ free(buf);
+ free(bkg);
+ free(orig);
+ s_ptr = NULL;
+ d_ptr = NULL;
+ st.close();
+ dt.close();
+
+ PASSED();
+ } // end of try block
+
+ catch (Exception E) {
+ issue_fail_msg(E.getCFuncName(), __LINE__, __FILE__, E.getCDetailMsg());
+ }
+} // test_compound_6()
+
+/*-------------------------------------------------------------------------
+ * Function: test_compound_7
+ *
+ * Purpose: Tests inserting fields into compound datatypes when the field
+ * overlaps the end of the compound datatype.
+ *
+ * Return: None
+ *
+ * Programmer: Binh-Minh Ribler (use C version)
+ * January, 2007
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static void test_compound_7(void)
+{
+ typedef struct {
+ int a;
+ float b;
+ long c;
+ } s1_typ_t;
+
+ typedef struct {
+ int a;
+ float b;
+ long c;
+ double d;
+ } s2_typ_t;
+
+ // Output message about test being performed
+ SUBTEST("Compound Element Insertion");
+ try
+ {
+ CompType tid1(sizeof(s1_typ_t));
+
+ tid1.insertMember("a", HOFFSET(s1_typ_t,a),PredType::NATIVE_INT);
+ tid1.insertMember("b", HOFFSET(s1_typ_t,b),PredType::NATIVE_FLOAT);
+ tid1.insertMember("c", HOFFSET(s1_typ_t,c),PredType::NATIVE_LONG);
+
+ size_t type_size = tid1.getSize();
+ verify_val(type_size, sizeof(s1_typ_t), "DataType::getSize", __LINE__, __FILE__);
+
+ CompType tid2;
+ tid2.copy(tid1);
+
+ type_size = tid2.getSize();
+ verify_val_noteq(type_size, sizeof(s2_typ_t), "DataType::getSize", __LINE__, __FILE__);
+
+ /* Should not be able to insert field past end of compound datatype */
+ try {
+ tid2.insertMember("d", HOFFSET(s2_typ_t, d), PredType::NATIVE_DOUBLE);
+ // Should FAIL but didn't, so throw an invalid action exception
+ throw InvalidActionException("CompType::insertMember", "Attempted to insert field past end of compound data type.");
+ } catch (DataTypeIException err) {}
+
+ /* Release resources */
+ tid1.close();
+ tid2.close();
+
+ PASSED();
+ } // end of try block
+
+ catch (Exception E) {
+ issue_fail_msg(E.getCFuncName(), __LINE__, __FILE__, E.getCDetailMsg());
+ }
+} // test_compound_7()
+
+
+/*-------------------------------------------------------------------------
+ * Function: test_compound
+ *
+ * Purpose: Main compound datatype testing routine
+ *
+ * Return: None
+ *
+ * Programmer: Binh-Minh Ribler
+ * January 2007
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+void test_compound(void)
+{
+ // Output message about test being performed
+ MESSAGE(5, ("Testing Compound Data Type operations\n"));
+
+ test_compound_1(); // various things about compound data types
+ test_compound_2(); // compound element reordering
+ test_compound_3(); // compound datatype subset conversions
+ test_compound_4(); // compound element shrinking & reordering
+ test_compound_5(); // optimized struct converter
+ test_compound_6(); // compound element growing
+ test_compound_7(); // compound element insertion
+} // test_compound()
+
+
+/*-------------------------------------------------------------------------
+ * Function: cleanup_compound
+ *
+ * Purpose: Cleanup temporary test files - nothing at this time.
+ *
+ * Return: none
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+void
+cleanup_compound(void)
+{
+} // cleanup_file
diff --git a/c++/test/testhdf5.cpp b/c++/test/testhdf5.cpp
index f157000..22d14b1 100644
--- a/c++/test/testhdf5.cpp
+++ b/c++/test/testhdf5.cpp
@@ -60,9 +60,11 @@
#include "H5Cpp.h" // C++ API header file
#ifndef H5_NO_NAMESPACE
-using namespace H5;
+ using namespace H5;
#endif /* !H5_NO_NAMESPACE */
+#include "h5cpputil.h" // C++ utilility header file
+
int
main(int argc, char *argv[])
{
@@ -79,6 +81,8 @@ main(int argc, char *argv[])
AddTest("reference", test_reference, cleanup_reference, "References", NULL);
// testing variable-length strings in tvlstr.cpp
AddTest("vlstrings", test_vlstrings, cleanup_vlstrings, "Variable-Length Strings", NULL);
+ AddTest("types", test_types, cleanup_types, "Generic Data Types", NULL);
+ AddTest("compound", test_compound, cleanup_compound, "Compound Data Types", NULL);
/* Comment out tests that are not done yet. - BMR, Feb 2001
AddTest("select", test_select, cleanup_select, "Selections", NULL);
AddTest("time", test_time, cleanup_time, "Time Datatypes", NULL);
@@ -86,8 +90,14 @@ main(int argc, char *argv[])
AddTest("iterate", test_iterate, cleanup_iterate, "Group & Attribute Iteration", NULL);
AddTest("array", test_array, cleanup_array, "Array Datatypes", NULL);
AddTest("genprop", test_genprop, cleanup_genprop, "Generic Properties", NULL);
+ AddTest("id", test_ids, NULL, "User-Created Identifiers", NULL);
+
Comment out tests that are not done yet */
+/* Tentative - BMR 2007/1/12
+ AddTest("datatypes", test_dtypes, cleanup_dtypes, "Data Types", NULL);
+ AddTest("enum", test_enum, cleanup_enum, "Enum Data Types", NULL);
+*/
/* Display testing information */
TestInfo(argv[0]);
diff --git a/c++/test/trefer.cpp b/c++/test/trefer.cpp
index 9ef6240..19a8a6b 100644
--- a/c++/test/trefer.cpp
+++ b/c++/test/trefer.cpp
@@ -12,13 +12,12 @@
* access to either file, you may request a copy from help@hdfgroup.org. *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
-/***********************************************************
-*
-* Test program: trefer
-*
-* Test the Reference functionality
-*
-*************************************************************/
+/*****************************************************************************
+ FILE
+ trefer.cpp - HDF5 C++ testing the functionalities associated with the C
+ Reference interface (H5R)
+
+ ***************************************************************************/
#ifdef OLD_HEADER_FILENAME
#include <iostream.h>
@@ -38,7 +37,7 @@
#include "H5Cpp.h" // C++ API header file
#ifndef H5_NO_NAMESPACE
-using namespace H5;
+ using namespace H5;
#endif
#include "h5cpputil.h" // C++ utilility header file
@@ -230,7 +229,7 @@ test_reference_obj(void)
// Dereference group object by ctor and using dataset to specify
// location
Group new_group(dataset, &rbuf[2]);
- H5std_string read_comment3 = group.getComment(".", 10);
+ H5std_string read_comment3 = new_group.getComment(".", 10);
verify_val(read_comment3, write_comment, "Group::getComment", __LINE__, __FILE__);
group.close();
diff --git a/c++/test/ttypes.cpp b/c++/test/ttypes.cpp
new file mode 100644
index 0000000..906ed23
--- /dev/null
+++ b/c++/test/ttypes.cpp
@@ -0,0 +1,810 @@
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * Copyright by The HDF Group (THG). *
+ * All rights reserved. *
+ * *
+ * This file is part of HDF5. The full HDF5 copyright notice, including *
+ * terms governing use, modification, and redistribution, is contained in *
+ * the files COPYING and Copyright.html. COPYING can be found at the root *
+ * of the source code distribution tree; Copyright.html can be found at the *
+ * root level of an installed copy of the electronic HDF5 document set and *
+ * is linked from the top-level documents page. It can also be found at *
+ * http://www.hdfgroup.org/HDF5/doc/Copyright.html. If you do not have *
+ * access to either file, you may request a copy from help@hdfgroup.org. *
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+/*****************************************************************************
+ FILE
+ ttypes.cpp - HDF5 C++ testing the general data type functionality
+
+ ***************************************************************************/
+
+#ifdef OLD_HEADER_FILENAME
+#include <iostream.h>
+#else
+#include <iostream>
+#endif
+#include <string>
+
+#ifndef H5_NO_NAMESPACE
+#ifndef H5_NO_STD
+ using std::cerr;
+ using std::endl;
+#endif // H5_NO_STD
+#endif
+
+#include "testhdf5.h" // C test header file
+#include "H5Cpp.h" // C++ API header file
+
+#ifndef H5_NO_NAMESPACE
+ using namespace H5;
+#endif
+
+#include "h5cpputil.h" // C++ utilility header file
+
+const H5std_string DATAFILE("ttypes.h5");
+
+#define NTESTS 1
+
+/* Number of elements in each test */
+#define NTESTELEM 100000
+
+/* Define if you want to see a count of overflows */
+#undef SHOW_OVERFLOWS
+
+/*
+ * Offset from alinged memory returned by malloc(). This can be used to test
+ * that type conversions handle non-aligned buffers correctly.
+ */
+#define ALIGNMENT 1
+
+/*
+ * Define if you want to test alignment code on a machine that doesn't
+ * normally require alignment. When set, all native data types must be aligned
+ * on a byte boundary equal to the data size.
+ */
+#define TEST_ALIGNMENT
+
+/* Alignment test stuff */
+#ifdef TEST_ALIGNMENT
+#define H5T_PACKAGE
+#include "H5Tpkg.h"
+#endif
+#define SET_ALIGNMENT(TYPE,VAL) \
+ H5T_NATIVE_##TYPE##_ALIGN_g=MAX(H5T_NATIVE_##TYPE##_ALIGN_g, VAL)
+
+const char *FILENAME[] = {
+ "dtypes1.h5",
+ "dtypes2.h5",
+ "dtypes3.h5",
+ NULL
+};
+
+/*
+ * Count up or down depending on whether the machine is big endian or little
+ * endian. If local variable `endian' is H5T_ORDER_BE then the result will
+ * be I, otherwise the result will be Z-(I+1).
+ */
+#define ENDIAN(Z,I) (H5T_ORDER_BE==endian?(I):(Z)-((I)+1))
+
+
+typedef enum flt_t {
+ FLT_FLOAT, FLT_DOUBLE, FLT_LDOUBLE, FLT_OTHER
+} flt_t;
+
+typedef enum int_t {
+ INT_CHAR, INT_UCHAR, INT_SHORT, INT_USHORT, INT_INT, INT_UINT,
+ INT_LONG, INT_ULONG, INT_LLONG, INT_ULLONG, INT_OTHER
+} int_t;
+
+/* Count the number of overflows */
+#ifdef SHOW_OVERFLOWS
+static int noverflows_g = 0;
+#endif
+
+/* Skip overflow tests if non-zero */
+static int skip_overflow_tests_g = 0;
+
+/* Don't use hardware conversions if set */
+static int without_hardware_g = 0;
+
+/* Count opaque conversions */
+static int num_opaque_conversions_g = 0;
+
+/*
+ * Although we check whether a floating point overflow generates a SIGFPE and
+ * turn off overflow tests in that case, it might still be possible for an
+ * overflow condition to occur. Once a SIGFPE is raised the program cannot
+ * be allowed to continue (cf. Posix signals) so in order to recover from a
+ * SIGFPE we run tests that might generate one in a child process.
+ */
+#if defined(H5_HAVE_FORK) && defined(H5_HAVE_WAITPID)
+# define HANDLE_SIGFPE
+#endif
+
+/* Allocates memory aligned on a certain boundary. */
+#define aligned_malloc(Z) ((void*)((char*)malloc(ALIGNMENT+Z)+ALIGNMENT))
+#define aligned_free(M) free((char*)(M)-ALIGNMENT)
+
+
+/*-------------------------------------------------------------------------
+ * Function: fpe_handler
+ *
+ * Purpose: Exit with 255
+ *
+ * Return: void
+ *
+ * Programmer: Robb Matzke
+ * Monday, July 6, 1998
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static void
+fpe_handler(int UNUSED signo)
+{
+ SKIPPED();
+ puts(" Test skipped due to SIGFPE.");
+#ifndef HANDLE_SIGFPE
+ puts(" Remaining tests could not be run.");
+ puts(" Please turn off SIGFPE on overflows and try again.");
+#endif
+ exit(255);
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function: overflow_handler
+ *
+ * Purpose: Gets called for all data type conversion overflows.
+ *
+ * Return: Success: 0
+ *
+ * Failure: -1
+ *
+ * Programmer: Robb Matzke
+ * Tuesday, July 7, 1998
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+#ifdef SHOW_OVERFLOWS
+static herr_t
+overflow_handler(hid_t UNUSED src_id, hid_t UNUSED dst_id,
+ void UNUSED *src_buf, void UNUSED *dst_buf)
+{
+ noverflows_g++;
+ return -1;
+}
+#endif
+
+
+/*-------------------------------------------------------------------------
+ * Function: test_classes
+ *
+ * Purpose: Test type classes
+ *
+ * Return: Success: 0
+ *
+ * Failure: number of errors
+ *
+ * Programmer: Binh-Minh Ribler (using C version)
+ * January, 2007
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static void test_classes(void)
+{
+ SUBTEST("PredType::getClass()");
+ try {
+ // PredType::NATIVE_INT should be in H5T_INTEGER class
+ H5T_class_t tcls = PredType::NATIVE_INT.getClass();
+ if (H5T_INTEGER!=tcls) {
+ H5_FAILED();
+ puts(" Invalid type class for H5T_NATIVE_INT");
+ }
+
+ // PredType::NATIVE_DOUBLE should be in H5T_FLOAT class
+ tcls = PredType::NATIVE_DOUBLE.getClass();
+ if (H5T_FLOAT!=tcls) {
+ H5_FAILED();
+ puts(" Invalid type class for H5T_NATIVE_DOUBLE");
+ }
+ PASSED();
+ } // end of try block
+ catch (DataTypeIException E) {
+ issue_fail_msg(E.getCFuncName(), __LINE__, __FILE__, E.getCDetailMsg());
+ }
+}
+
+/*-------------------------------------------------------------------------
+ * Function: test_copy
+ *
+ * Purpose: Test datatype copy functionality
+ *
+ * Return: Success: 0
+ *
+ * Failure: number of errors
+ *
+ * Programmer: Binh-Minh Ribler (using C version)
+ * January, 2007
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static void test_copy(void)
+{
+ hid_t a_copy;
+ herr_t status;
+
+ //MESSAGE(5, ("DataType::copy() and DataType::operator="));
+ SUBTEST("DataType::copy() and DataType::operator=");
+ try {
+ // Test copying from a predefined datatype using DataType::operator=
+ DataType assigned_type;
+ assigned_type = PredType::NATIVE_SHORT;
+
+ // Test copying a predefined type using DataType::copy
+ DataType copied_type;
+ copied_type.copy (PredType::STD_B8LE);
+
+ // Test copying a user-defined type using DataType::operator=
+ DataType assigned_usertype;
+ assigned_usertype = copied_type;
+
+ // Test copying from a user-defined datatype using DataType::copy
+ DataType copied_usertype;
+ copied_usertype.copy(copied_type);
+
+ // Test copying a user-defined int type using DataType::operator=
+ IntType orig_int(PredType::STD_B8LE);
+ DataType generic_type;
+ generic_type = orig_int;
+
+ // Test copying an integer predefined type
+ IntType new_int_type(PredType::STD_B8LE);
+
+ // Test copying an int predefined type using DataType::operator=
+ IntType another_int_type;
+ another_int_type = new_int_type;
+
+ PASSED();
+ }
+ catch (DataTypeIException E) {
+ issue_fail_msg(E.getCFuncName(), __LINE__, __FILE__, E.getCDetailMsg());
+ }
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function: test_query
+ *
+ * Purpose: Tests query functions of compound and enumeration types.
+ *
+ * Return: Success: 0
+ *
+ * Failure: number of errors
+ *
+ * Programmer: Binh-Minh Ribler (use C version)
+ * January, 2007
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+
+const H5std_string CompT_NAME("Compound_type");
+const H5std_string EnumT_NAME("Enum_type");
+
+static void test_query(void)
+{
+ typedef struct {
+ int a;
+ float b;
+ long c;
+ double d;
+ } s_type_t;
+ char filename[1024];
+ short enum_val;
+
+ // Output message about test being performed
+ SUBTEST("Query functions of compound and enumeration types");
+ try
+ {
+ /* Create File */
+ H5File file(FILENAME[2], H5F_ACC_TRUNC);
+
+ /* Create a compound datatype */
+ CompType tid1(sizeof(s_type_t));
+
+ tid1.insertMember("a", HOFFSET(s_type_t, a), PredType::NATIVE_INT);
+ tid1.insertMember("b", HOFFSET(s_type_t, b), PredType::NATIVE_FLOAT);
+ tid1.insertMember("c", HOFFSET(s_type_t, c), PredType::NATIVE_LONG);
+ tid1.insertMember("d", HOFFSET(s_type_t, d), PredType::NATIVE_DOUBLE);
+
+ /* Create a enumerate datatype */
+ EnumType tid2(sizeof(short));
+
+ tid2.insert("RED", (enum_val=0,&enum_val));
+ tid2.insert("GREEN", (enum_val=1,&enum_val));
+ tid2.insert("BLUE", (enum_val=2,&enum_val));
+ tid2.insert("ORANGE", (enum_val=3,&enum_val));
+ tid2.insert("YELLOW", (enum_val=4,&enum_val));
+
+ /* Query member number and member index by name, for compound type */
+ int nmembs = tid1.getNmembers();
+ verify_val(nmembs, 4, "CompType::getNmembers()", __LINE__, __FILE__);
+
+ int index = tid1.getMemberIndex("c");
+ verify_val(index, 2, "CompType::getMemberIndex()", __LINE__, __FILE__);
+
+ /* Query member number and member index by name, for enumeration type. */
+ nmembs = tid2.getNmembers();
+ verify_val(nmembs, 5, "EnumType::getNmembers()", __LINE__, __FILE__);
+
+ index = tid2.getMemberIndex("ORANGE");
+ verify_val(index, 3, "EnumType::getMemberIndex()", __LINE__, __FILE__);
+
+ /* Commit compound datatype and close it */
+ tid1.commit(file, CompT_NAME);
+ tid1.close();
+
+ /* Commit enumeration datatype and close it */
+ tid2.commit(file, EnumT_NAME);
+ tid2.close();
+
+ /* Open the datatype for query */
+ tid1 = file.openCompType(CompT_NAME);
+
+ tid2 = file.openEnumType(EnumT_NAME);
+
+ /* Query member number and member index by name, for compound type */
+ nmembs = tid1.getNmembers();
+ verify_val(nmembs, 4, "CompType::getNmembers()", __LINE__, __FILE__);
+
+ index = tid1.getMemberIndex("c");
+ verify_val(index, 2, "CompType::getMemberIndex()", __LINE__, __FILE__);
+
+ /* Query member number and member index by name, for enumeration type */
+ nmembs = tid2.getNmembers();
+ verify_val(nmembs, 5, "EnumType::getNmembers()", __LINE__, __FILE__);
+
+ index = tid2.getMemberIndex("ORANGE");
+ verify_val(index, 3, "EnumType::getMemberIndex()", __LINE__, __FILE__);
+
+ /* Close data types and file */
+ tid1.close();
+ tid2.close();
+ file.close();
+
+ PASSED();
+ } // end of try block
+ catch (Exception E) {
+ issue_fail_msg(E.getCFuncName(), __LINE__, __FILE__, E.getCDetailMsg());
+ }
+} // test_query
+
+
+/*-------------------------------------------------------------------------
+ * Function: test_transient
+ *
+ * Purpose: Tests transient data types.
+ *
+ * Return: Success: 0
+ *
+ * Failure: number of errors
+ *
+ * Programmer: Binh-Minh Ribler (use C version)
+ * January, 2007
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+const char* filename1("dtypes1.h5");
+static void test_transient ()
+{
+ static hsize_t ds_size[2] = {10, 20};
+
+ //MESSAGE(5, ("transient data types"));
+ SUBTEST("Transient data types");
+ try {
+
+ H5File file(filename1, H5F_ACC_TRUNC);
+ DataSpace space(2, ds_size, ds_size);
+
+ /* Predefined types cannot be modified or closed */
+// PredType::NATIVE_INT is a constant and cannot make a call, don't need these tests
+
+ /* Copying a predefined type results in a modifiable copy */
+ IntType type(PredType::NATIVE_INT);
+ type.setPrecision(256);
+
+ /* It should not be possible to create an attribute for a transient type */
+ try {
+ Attribute attr(type.createAttribute("attr1", PredType::NATIVE_INT, space));
+ // Should FAIL but didn't, so throw an invalid action exception
+ throw InvalidActionException("H5Object::createAttribute", "Attempted to commit a predefined datatype.");
+ } catch (AttributeIException err) {}
+
+ /* Create a dataset from a transient data type */
+// type.close(); - put printf in H5Tclose to make sure it's closed
+ type.copy(PredType::NATIVE_INT);
+ DataSet dset(file.createDataSet("dset1", type, space));
+
+ /* The type returned from a dataset should not be modifiable */
+ IntType itype(dset);
+ try {
+ itype.setPrecision(256);
+
+ // Should FAIL but didn't, so throw an invalid action exception
+ throw InvalidActionException("PredType::setPrecision", "Dataset data types should not be modifiable!");
+ } catch (DataTypeIException err) {}
+
+ itype.close();
+
+ /*
+ * Get the dataset data type by applying H5Tcopy() to the dataset. The
+ * result should be modifiable.
+ */
+ itype.copy(dset);
+ itype.setPrecision(256);
+
+ /*
+ * Close the dataset and reopen it, testing that its type is still
+ * read-only. <--- how come modifiable below?
+ */
+ dset.close();
+ //if (H5Dclose (dset)<0) printf("goto error in C\n");
+ dset = file.openDataSet("dset1");
+ //if ((dset=H5Dopen (file, "dset1"))<0) printf("goto error in C\n");
+
+ /*
+ * Get the dataset data type by applying H5Tcopy() to the dataset. The
+ * result should be modifiable.
+ */
+ itype.copy(dset);
+ itype.setPrecision(256);
+ itype.close();
+
+ // Close objects and file.
+ dset.close();
+ file.close();
+ type.close();
+ space.close();
+ PASSED();
+ } // end of try block
+ catch (Exception E) {
+ issue_fail_msg(E.getCFuncName(), __LINE__, __FILE__, E.getCDetailMsg());
+ }
+} // test_transient
+
+
+/*-------------------------------------------------------------------------
+ * Function: test_named
+ *
+ * Purpose: Tests named data types.
+ *
+ * Return: Success: 0
+ *
+ * Failure: number of errors
+ *
+ * Programmer: Binh-Minh Ribler (use C version)
+ * January, 2007
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+const H5std_string filename2("dtypes2.h5");
+static void test_named ()
+{
+ herr_t status;
+ static hsize_t ds_size[2] = {10, 20};
+ hsize_t i;
+ unsigned attr_data[10][20];
+ char filename[1024];
+
+ //MESSAGE(5, ("named data types"));
+ SUBTEST("Named data types");
+ try {
+
+// h5_fixname(FILENAME[1], fapl_id, filename, sizeof filename);
+ H5File file(filename2, H5F_ACC_TRUNC);
+
+ DataSpace space(2, ds_size, ds_size);
+
+ /* Predefined types cannot be committed */
+ try {
+PredType nativeint(PredType::NATIVE_INT);
+nativeint.commit(file, "test_named_1 (should not exist)");
+ //PredType::NATIVE_INT.commit(file, "test_named_1 (should not exist)");
+ // Should FAIL but didn't, so throw an invalid action exception
+ throw InvalidActionException("PredType::commit", "Attempted to commit a predefined datatype.");
+ } catch (DataTypeIException err) {}
+
+/*
+ H5E_BEGIN_TRY {
+ status = H5Tcommit (file, "test_named_1 (should not exist)",
+ H5T_NATIVE_INT);
+ } H5E_END_TRY;
+ if (status>=0) {
+ H5_FAILED();
+ puts (" Predefined types should not be committable!");
+ printf("goto error in C\n");
+ }
+*/
+
+ /* Copy a predefined data type and commit the copy */
+ IntType itype(PredType::NATIVE_INT);
+ //if ((type = H5Tcopy (H5T_NATIVE_INT))<0) printf("goto error in C\n");
+
+ itype.commit(file, "native-int");
+ //if (H5Tcommit (file, "native-int", type)<0) printf("goto error in C\n");0,
+
+ if (itype.committed() <= 0)
+ cerr << "IntType::committed() returned false" << endl;
+
+/*
+ if ((status=H5Tcommitted (type))<0) printf("goto error in C\n");
+ if (0==status) {
+ H5_FAILED();
+ puts (" H5Tcommitted() returned false!");
+ printf("goto error in C\n");
+ }
+*/
+
+ /* We should not be able to modify a type after it has been committed. */
+ try {
+ itype.setPrecision(256);
+
+ // Should FAIL but didn't, so throw an invalid action exception
+ throw InvalidActionException("IntType::setPrecision", "Attempted to modify a committed datatype.");
+ } catch (DataTypeIException err) {}
+
+/*
+ H5E_BEGIN_TRY {
+ status = H5Tset_precision (type, 256);
+ } H5E_END_TRY;
+ if (status>=0) {
+ H5_FAILED();
+ puts (" Committed type is not constant!");
+ printf("goto error in C\n");
+ }
+*/
+ /* We should not be able to re-commit a committed type */
+ try {
+ itype.commit(file, "test_named_2 (should not exist)");
+
+ // Should FAIL but didn't, so throw an invalid action exception
+ throw InvalidActionException("IntType::commit", "Attempted to re-commit a committed data type.");
+ } catch (DataTypeIException err) {}
+
+/*
+ H5E_BEGIN_TRY {
+ status = H5Tcommit(file, "test_named_2 (should not exist)", type);
+ } H5E_END_TRY;
+ if (status>=0) {
+ H5_FAILED();
+ puts (" Committed types should not be recommitted!");
+ printf("goto error in C\n");
+ }
+*/
+
+ /* It should be possible to define an attribute for the named type */
+ Attribute attr1 = itype.createAttribute("attr1", PredType::NATIVE_UCHAR, space);
+ //if ((attr1=H5Acreate (type, "attr1", H5T_NATIVE_UCHAR, space,
+// H5P_DEFAULT))<0) printf("goto error in C\n");
+
+
+ for (i=0; i<ds_size[0]*ds_size[1]; i++) attr_data[0][i] = (int)i;/*tricky*/
+
+ attr1.write(PredType::NATIVE_UINT, attr_data);
+ attr1.close();
+ //if (H5Awrite(attr1, H5T_NATIVE_UINT, attr_data)<0) printf("goto error in C\n");
+ //if (H5Aclose (attr1)<0) printf("goto error in C\n");
+
+ /*
+ * Copying a committed type should result in a transient type which is
+ * not locked.
+ */
+ IntType trans_type;
+ trans_type.copy(itype);
+ bool iscommitted = trans_type.committed();
+ verify_val(iscommitted, 0, "DataType::committed() - Copying a named type should result in a transient type!", __LINE__, __FILE__);
+/*
+ if ((t2 = H5Tcopy (type))<0) printf("goto error in C\n");
+ if ((status=H5Tcommitted (t2))<0) printf("goto error in C\n");
+ if (status) {
+ H5_FAILED();
+ puts (" Copying a named type should result in a transient type!");
+ printf("goto error in C\n");
+ }
+*/
+ trans_type.setPrecision(256);
+ trans_type.close();
+ //if (H5Tset_precision (t2, 256)<0) printf("goto error in C\n");
+ //if (H5Tclose (t2)<0) printf("goto error in C\n");
+
+ /*
+ * Close the committed type and reopen it. It should return a named type.
+ */
+/* This had something to do with the way IntType was returned and assigned
+and caused itype.committed not working correctly. So, use another_type for
+now.
+ itype = file.openIntType("native-int");
+ iscommitted = itype.committed();
+*/
+ IntType another_type = file.openIntType("native-int");
+ iscommitted = another_type.committed();
+ if (!iscommitted)
+ throw InvalidActionException("IntType::committed()", "Opened named types should be named types!");
+
+/*
+ if (H5Tclose (type)<0) printf("goto error in C\n");
+ if ((type=H5Topen (file, "native-int"))<0) printf("goto error in C\n");
+ if ((status=H5Tcommitted (type))<0) printf("goto error in C\n");
+ if (!status) {
+ H5_FAILED();
+ puts (" Opened named types should be named types!");
+ printf("goto error in C\n");
+ }
+ */
+ /* Create a dataset that uses the named type */
+ DataSet dset = file.createDataSet("dset1", itype, space);
+ //if ((dset = H5Dcreate (file, "dset1", type, space, H5P_DEFAULT))<0)
+
+ /* Get the dataset's data type and make sure it's a named type */
+ DataType *ds_type = new DataType(dset.getDataType());
+ iscommitted = ds_type->committed();
+ if (!iscommitted)
+ throw InvalidActionException("IntType::committed()", "1 Dataset type should be named type!");
+
+/*
+ if ((t2 = H5Dget_type (dset))<0) printf("goto error in C\n");
+ if ((status=H5Tcommitted (t2))<0) printf("goto error in C\n");
+ if (!status) {
+ H5_FAILED();
+ puts (" Dataset type should be a named type!");
+ printf("goto error in C\n");
+ }
+*/
+
+ /* Close the dataset, then close its type, then reopen the dataset */
+ dset.close();
+ ds_type->close();
+ //if (H5Dclose (dset)<0) printf("goto error in C\n");
+ //if (H5Tclose (t2)<0) printf("goto error in C\n");
+
+ dset = file.openDataSet("dset1");
+ //if ((dset = H5Dopen (file, "dset1"))<0) printf("goto error in C\n");
+
+ /* Get the dataset's type and make sure it's named */
+ /* Get the dataset's data type and make sure it's a named type */
+ ds_type = new DataType(dset.getDataType());
+ iscommitted = ds_type->committed();
+ if (!iscommitted)
+ throw InvalidActionException("IntType::committed()", "Dataset type should be named type!");
+/*
+ if ((t2 = H5Dget_type (dset))<0) printf("goto error in C\n");
+ if ((status=H5Tcommitted (t2))<0) printf("goto error in C\n");
+ if (!status) {
+ H5_FAILED();
+ puts (" Dataset type should be a named type!");
+ printf("goto error in C\n");
+ }
+*/
+
+ /*
+ * Close the dataset and create another with the type returned from the
+ * first dataset.
+ */
+ dset.close();
+ //if (H5Dclose (dset)<0) printf("goto error in C\n");
+ dset = file.createDataSet("dset2", *ds_type, space);
+ //if ((dset=H5Dcreate (file, "dset2", t2, space, H5P_DEFAULT))<0)
+
+ /* Reopen the second dataset and make sure the type is shared */
+ ds_type->close();
+ dset.close();
+ dset = file.openDataSet("dset2");
+ ds_type = new DataType(dset.getDataType());
+ iscommitted = ds_type->committed();
+ if (!iscommitted)
+ throw InvalidActionException("IntType::committed()", "Dataset type should be named type!");
+
+/*
+ if (H5Tclose (t2)<0) printf("goto error in C\n");
+ if (H5Dclose (dset)<0) printf("goto error in C\n");
+ if ((dset = H5Dopen (file, "dset2"))<0) printf("goto error in C\n");
+ if ((t2 = H5Dget_type (dset))<0) printf("goto error in C\n");
+ if ((status=H5Tcommitted (t2))<0) printf("goto error in C\n");
+ if (!status) {
+ H5_FAILED();
+ puts (" Dataset type should be a named type!");
+ printf("goto error in C\n");
+ }
+*/
+ ds_type->close();
+ //if (H5Tclose (t2)<0) printf("goto error in C\n");
+
+ /*
+ * Get the dataset data type by applying H5Tcopy() to the dataset. The
+ * result should be modifiable.
+ */
+ //DataType copied_type = dset.copyType();
+ IntType copied_type;
+ copied_type.copy(dset);
+ //if ((t2=H5Tcopy (dset))<0) printf("goto error in C\n");
+
+// find another function that can be in DataType
+ copied_type.setPrecision(256);
+// if (H5Tset_precision (t2, 256)<0) printf("goto error in C\n");
+ //copied_type.close();
+ copied_type.close();
+ //if (H5Tclose (t2)<0) printf("goto error in C\n");
+
+ /* Clean up */
+ dset.close();
+ itype.close();
+ space.close();
+ file.close();
+/*
+ if (H5Dclose (dset)<0) printf("goto error in C\n");
+ if (H5Tclose (type)<0) printf("goto error in C\n");
+ if (H5Sclose (space)<0) printf("goto error in C\n");
+ if (H5Fclose (file)<0) printf("goto error in C\n");
+*/
+ PASSED();
+ } // end of try block
+ catch (Exception E) {
+cerr << "all the way here?" << endl;
+ issue_fail_msg(E.getCFuncName(), __LINE__, __FILE__, E.getCDetailMsg());
+ }
+} // test_named
+
+
+/****************************************************************
+**
+** test_types(): Main data types testing routine.
+**
+****************************************************************/
+void test_types(void)
+{
+ // Output message about test being performed
+ MESSAGE(5, ("Testing Generic Data Types\n"));
+
+ // Test basic datatypes
+ test_classes();
+ test_copy();
+ test_query();
+ test_transient();
+ test_named();
+
+} // test_types()
+
+
+/*-------------------------------------------------------------------------
+ * Function: cleanup_types
+ *
+ * Purpose: Cleanup temporary test files
+ *
+ * Return: none
+ *
+ * Programmer: Quincey Koziol
+ * September 10, 1999
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+void
+cleanup_types(void)
+{
+ for (int i = 0; i < 3; i++)
+ HDremove(FILENAME[i]);
+}