From a08f75b0737c86d51bbc91538e78b1455eb2cae7 Mon Sep 17 00:00:00 2001 From: Binh-Minh Ribler Date: Sun, 6 Apr 2014 17:36:15 -0500 Subject: [svn-r24969] Description: - Added wrappers to H5Object for H5Iget_name() to get object's name ssize_t getObjName(char *obj_name, size_t buf_size = 0) const; ssize_t getObjName(H5std_string& obj_name, size_t len = 0) const; H5std_string getObjName() const; - Added tests tobject.cpp - Added to various cleanup_* functions in tests to remove generated files - Added an overload H5I_type_t getHDFObjType() to get object's type Platforms tested: Linux/ppc64 (ostrich) Linux/32 2.6 (jam) SunOS 5.11 (emu) with gmake --- c++/src/H5Attribute.cpp | 6 +- c++/src/H5Attribute.h | 2 +- c++/src/H5IdComponent.cpp | 22 +++- c++/src/H5IdComponent.h | 3 + c++/src/H5Object.cpp | 112 +++++++++++++++++++ c++/src/H5Object.h | 8 +- c++/test/Makefile.am | 4 +- c++/test/Makefile.in | 9 +- c++/test/dsets.cpp | 32 +++--- c++/test/h5cpputil.h | 2 + c++/test/tattr.cpp | 8 +- c++/test/tcompound.cpp | 4 +- c++/test/tdspl.cpp | 5 +- c++/test/testhdf5.cpp | 71 +++++++----- c++/test/tfile.cpp | 1 + c++/test/tfilter.cpp | 2 +- c++/test/tobject.cpp | 269 ++++++++++++++++++++++++++++++++++++++++++++++ c++/test/tvlstr.cpp | 12 +-- 18 files changed, 498 insertions(+), 74 deletions(-) create mode 100644 c++/test/tobject.cpp diff --git a/c++/src/H5Attribute.cpp b/c++/src/H5Attribute.cpp index 9554f95..4625c2c 100644 --- a/c++/src/H5Attribute.cpp +++ b/c++/src/H5Attribute.cpp @@ -327,7 +327,7 @@ ssize_t Attribute::getName(char* attr_name, size_t buf_size) const { throw AttributeIException("Attribute::getName", "Attribute must have a name, name length is 0"); } - + // Return length of the name return(name_size); } @@ -357,7 +357,7 @@ H5std_string Attribute::getName() const { throw AttributeIException("Attribute::getName", "Attribute must have a name, name length is 0"); } - // If attribute's name exists, calls C routine again to get it + // Attribute's name exists, retrieve it else if (name_size > 0) { char* name_C = new char[name_size+1]; // temporary C-string @@ -391,7 +391,7 @@ H5std_string Attribute::getName() const // Programmer Binh-Minh Ribler - Nov, 2001 // Modification // Mar 2014 - BMR -// Revised to allow buf_size to be skipped +// Revised to allow the argument "len" to be skipped //-------------------------------------------------------------------------- ssize_t Attribute::getName(H5std_string& attr_name, size_t len) const { diff --git a/c++/src/H5Attribute.h b/c++/src/H5Attribute.h index 8332632..8ec04af 100644 --- a/c++/src/H5Attribute.h +++ b/c++/src/H5Attribute.h @@ -39,7 +39,7 @@ class H5_DLLCPP Attribute : public AbstractDs, public IdComponent { // Gets the name of this attribute. ssize_t getName(char* attr_name, size_t buf_size = 0) const; - ssize_t getName(H5std_string& attr_name, size_t buf_size = 0) const; + ssize_t getName(H5std_string& attr_name, size_t len = 0) const; H5std_string getName() const; // Gets a copy of the dataspace for this attribute. diff --git a/c++/src/H5IdComponent.cpp b/c++/src/H5IdComponent.cpp index cdf4272..99a8dc4 100644 --- a/c++/src/H5IdComponent.cpp +++ b/c++/src/H5IdComponent.cpp @@ -130,7 +130,7 @@ int IdComponent::getCounter() const } //-------------------------------------------------------------------------- -// Function: hdfObjectType +// Function: getHDFObjType (static) ///\brief Given an id, returns the type of the object. ///\return a valid HDF object type, which may be one of the following: /// \li \c H5I_FILE @@ -155,6 +155,26 @@ H5I_type_t IdComponent::getHDFObjType(const hid_t obj_id) } //-------------------------------------------------------------------------- +// Function: getHDFObjType +///\brief Returns the type of the object. It is an overloaded function +/// of the above function. +///\return a valid HDF object type, which may be one of the following: +/// \li \c H5I_FILE +/// \li \c H5I_GROUP +/// \li \c H5I_DATATYPE +/// \li \c H5I_DATASPACE +/// \li \c H5I_DATASET +/// \li \c H5I_ATTR +/// \li or \c H5I_BADID, if no valid type can be determined or the +/// input object id is invalid. +// Programmer Binh-Minh Ribler - Mar, 2014 +//-------------------------------------------------------------------------- +H5I_type_t IdComponent::getHDFObjType() const +{ + return(getHDFObjType(getId())); +} + +//-------------------------------------------------------------------------- // Function: IdComponent::operator= ///\brief Assignment operator. ///\param rhs - IN: Reference to the existing object diff --git a/c++/src/H5IdComponent.h b/c++/src/H5IdComponent.h index ca9352d..3208a39 100644 --- a/c++/src/H5IdComponent.h +++ b/c++/src/H5IdComponent.h @@ -46,6 +46,9 @@ class H5_DLLCPP IdComponent { // Returns an HDF5 object type, given the object id. static H5I_type_t getHDFObjType(const hid_t obj_id); + // Returns an HDF5 object type of this object. + H5I_type_t getHDFObjType() const; + // Assignment operator. IdComponent& operator=( const IdComponent& rhs ); diff --git a/c++/src/H5Object.cpp b/c++/src/H5Object.cpp index 1d96f2e..94b03ab 100644 --- a/c++/src/H5Object.cpp +++ b/c++/src/H5Object.cpp @@ -31,6 +31,7 @@ #include "H5File.h" #include "H5DataSet.h" #include "H5Attribute.h" +#include "H5private.h" // for HDmemset #ifndef H5_NO_NAMESPACE namespace H5 { @@ -53,6 +54,117 @@ H5Object::H5Object() : H5Location() {} H5Object::H5Object( const hid_t object_id ) : H5Location( object_id ) {} //-------------------------------------------------------------------------- +// Function: getObjName +///\brief Given an id, returns the type of the object. +///\return The name of the object +// Programmer Binh-Minh Ribler - Mar, 2014 +//-------------------------------------------------------------------------- +ssize_t H5Object::getObjName(char *obj_name, size_t buf_size) const +{ + // H5Iget_name will get buf_size-1 chars of the name to null terminate it + ssize_t name_size = H5Iget_name(getId(), obj_name, buf_size); + + // If H5Iget_name returns a negative value, raise an exception + if (name_size < 0) + { + throw Exception(inMemFunc("getObjName"), "H5Iget_name failed"); + } + else if (name_size == 0) + { + throw Exception(inMemFunc("getObjName"), "Object must have a name, but name length is 0"); + } + // Return length of the name + return(name_size); +} + +//-------------------------------------------------------------------------- +// Function: H5Object::getObjName +///\brief Returns the name of this object as an \a H5std_string. +///\return Name of the object +///\exception H5::Exception +// Programmer Binh-Minh Ribler - Mar, 2014 +// Modification +//-------------------------------------------------------------------------- +H5std_string H5Object::getObjName() const +{ + H5std_string obj_name(""); // object name to return + + // Preliminary call to get the size of the object name + ssize_t name_size = H5Iget_name(getId(), NULL, (size_t)0); + + // If H5Iget_name failed, throw exception + if (name_size < 0) + { + throw Exception(inMemFunc("getObjName"), "H5Iget_name failed"); + } + else if (name_size == 0) + { + throw Exception(inMemFunc("getObjName"), "Object must have a name, but name length is 0"); + } + // Object's name exists, retrieve it + else if (name_size > 0) + { + char* name_C = new char[name_size+1]; // temporary C-string + HDmemset(name_C, 0, name_size+1); // clear buffer + + // Use overloaded function + name_size = getObjName(name_C, name_size+1); + + // Convert the C object name to return + obj_name = name_C; + + // Clean up resource + delete []name_C; + } + // Return object's name + return(obj_name); +} + +//-------------------------------------------------------------------------- +// Function: H5Object::getObjName +///\brief Gets the name of this object, returning its length. +///\param obj_name - OUT: Buffer for the name string as \a H5std_string +///\param len - IN: Desired length of the name, default to 0 +///\return Actual length of the object name +///\exception H5::Exception +///\par Description +/// This function retrieves the object's name as an std string. +/// buf_size can specify a specific length or default to 0, in +/// which case the entire name will be retrieved. +// Programmer Binh-Minh Ribler - Mar, 2014 +//-------------------------------------------------------------------------- +ssize_t H5Object::getObjName(H5std_string& obj_name, size_t len) const +{ + ssize_t name_size = 0; + + // If no length is provided, get the entire object name + if (len == 0) + { + obj_name = getObjName(); + name_size = obj_name.length(); + } + // If length is provided, get that number of characters in name + else + { + char* name_C = new char[len+1]; // temporary C-string + HDmemset(name_C, 0, len+1); // clear buffer + + // Use overloaded function + name_size = getObjName(name_C, len+1); + + // Convert the C object name to return + obj_name = name_C; + + // Clean up resource + delete []name_C; + } + // Otherwise, keep obj_name intact + + // Return name size + return(name_size); +} + +//-------------------------------------------------------------------------- // Function: H5Object copy constructor ///\brief Copy constructor: makes a copy of the original H5Object /// instance. diff --git a/c++/src/H5Object.h b/c++/src/H5Object.h index 5c2ef98..5576d13 100644 --- a/c++/src/H5Object.h +++ b/c++/src/H5Object.h @@ -33,7 +33,7 @@ // H5Object is H5File is not an HDF5 object, and renaming H5Object // to H5Location will risk breaking user applications. // -BMR - +// Apr 2, 2014: Added wrapper getObjName for H5Iget_name #ifndef H5_NO_NAMESPACE namespace H5 { #endif @@ -50,6 +50,12 @@ class H5_DLLCPP H5Object : public H5Location { // Copy constructor: makes copy of an H5Object object. H5Object(const H5Object& original); + // Gets the name of this HDF5 object, i.e., Group, DataSet, or + // DataType. + ssize_t getObjName(char *obj_name, size_t buf_size = 0) const; + ssize_t getObjName(H5std_string& obj_name, size_t len = 0) const; + H5std_string getObjName() const; + // Noop destructor. virtual ~H5Object(); diff --git a/c++/test/Makefile.am b/c++/test/Makefile.am index 6cef381..2717e9c 100644 --- a/c++/test/Makefile.am +++ b/c++/test/Makefile.am @@ -38,8 +38,8 @@ check_PROGRAMS=$(TEST_PROG) LDADD=$(LIBH5TEST) $(LIBH5CPP) $(LIBHDF5) testhdf5_SOURCES=testhdf5.cpp dsets.cpp tattr.cpp tcompound.cpp \ - tdspl.cpp tfile.cpp tfilter.cpp th5s.cpp tlinks.cpp trefer.cpp \ - ttypes.cpp tvlstr.cpp h5cpputil.cpp + tdspl.cpp tfile.cpp tfilter.cpp th5s.cpp tlinks.cpp tobject.cpp \ + trefer.cpp ttypes.cpp tvlstr.cpp h5cpputil.cpp # Tell conclude.am that these are C++ tests. CXX_API=yes diff --git a/c++/test/Makefile.in b/c++/test/Makefile.in index 59cab8f..c1fd776 100644 --- a/c++/test/Makefile.in +++ b/c++/test/Makefile.in @@ -117,8 +117,8 @@ am__EXEEXT_1 = testhdf5$(EXEEXT) am_testhdf5_OBJECTS = testhdf5.$(OBJEXT) dsets.$(OBJEXT) \ tattr.$(OBJEXT) tcompound.$(OBJEXT) tdspl.$(OBJEXT) \ tfile.$(OBJEXT) tfilter.$(OBJEXT) th5s.$(OBJEXT) \ - tlinks.$(OBJEXT) trefer.$(OBJEXT) ttypes.$(OBJEXT) \ - tvlstr.$(OBJEXT) h5cpputil.$(OBJEXT) + tlinks.$(OBJEXT) tobject.$(OBJEXT) trefer.$(OBJEXT) \ + ttypes.$(OBJEXT) tvlstr.$(OBJEXT) h5cpputil.$(OBJEXT) testhdf5_OBJECTS = $(am_testhdf5_OBJECTS) testhdf5_LDADD = $(LDADD) testhdf5_DEPENDENCIES = $(LIBH5TEST) $(LIBH5CPP) $(LIBHDF5) @@ -681,8 +681,8 @@ TEST_PROG = testhdf5 # The tests depend on the hdf5 library, test library, and the c++ library LDADD = $(LIBH5TEST) $(LIBH5CPP) $(LIBHDF5) testhdf5_SOURCES = testhdf5.cpp dsets.cpp tattr.cpp tcompound.cpp \ - tdspl.cpp tfile.cpp tfilter.cpp th5s.cpp tlinks.cpp trefer.cpp \ - ttypes.cpp tvlstr.cpp h5cpputil.cpp + tdspl.cpp tfile.cpp tfilter.cpp th5s.cpp tlinks.cpp tobject.cpp \ + trefer.cpp ttypes.cpp tvlstr.cpp h5cpputil.cpp # Tell conclude.am that these are C++ tests. @@ -774,6 +774,7 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tfilter.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/th5s.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tlinks.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tobject.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@ diff --git a/c++/test/dsets.cpp b/c++/test/dsets.cpp index 72d7977..6824403 100644 --- a/c++/test/dsets.cpp +++ b/c++/test/dsets.cpp @@ -49,6 +49,7 @@ const H5std_string FILE1("dataset.h5"); const H5std_string DSET_DEFAULT_NAME("default"); +const H5std_string DSET_DEFAULT_NAME_PATH("/default"); const H5std_string DSET_CHUNKED_NAME("chunked"); const H5std_string DSET_SIMPLE_IO_NAME("simple_io"); const H5std_string DSET_TCONV_NAME ("tconv"); @@ -96,6 +97,7 @@ test_create( H5File& file) dataset = new DataSet (file.createDataSet (DSET_DEFAULT_NAME, PredType::NATIVE_DOUBLE, space)); + // Add a comment to the dataset file.setComment (DSET_DEFAULT_NAME, "This is a dataset"); @@ -120,10 +122,15 @@ test_create( H5File& file) // way to open an existing dataset for accessing. dataset = new DataSet (file.openDataSet (DSET_DEFAULT_NAME)); + // Get and verify the name of this dataset, using + // H5std_string getObjName() + H5std_string ds_name = dataset->getObjName(); + verify_val(ds_name, DSET_DEFAULT_NAME_PATH, "DataSet::getObjName", __LINE__, __FILE__); + // Get and verify the comment from this dataset, using // H5std_string getComment(const H5std_string& name, ) H5std_string comment = file.getComment(DSET_DEFAULT_NAME); - verify_val(comment, "This is a dataset", "H5Location::getComment", __LINE__, __FILE__); + verify_val(comment, "This is a dataset", "DataSet::getComment", __LINE__, __FILE__); // Close the dataset when accessing is completed delete dataset; @@ -1050,11 +1057,6 @@ void test_dset() 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(fapl_id); @@ -1065,18 +1067,12 @@ void test_dset() 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; - - // Get part of the comment, random length using - // ssize_t getComment(const char* name, const size_t buf_size, char* comment) - char* comment = new char[11]; - ssize_t comment_len = file.getComment("emit diagnostics", 11, comment); - verify_val((const char*)comment, "Causes dia", "H5Location::getComment", __LINE__, __FILE__); + 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; // Close group "emit diagnostics". grp.close(); diff --git a/c++/test/h5cpputil.h b/c++/test/h5cpputil.h index cc135bd..bea08d3 100644 --- a/c++/test/h5cpputil.h +++ b/c++/test/h5cpputil.h @@ -126,6 +126,7 @@ void test_file(); void test_filters(); void test_links(); void test_h5s(); +void test_object(); void test_reference(); void test_types(); void test_vlstrings(); @@ -140,6 +141,7 @@ void cleanup_file(); void cleanup_filters(); void cleanup_links(); void cleanup_h5s(); +void cleanup_object(); void cleanup_reference(); void cleanup_types(); void cleanup_vlstrings(); diff --git a/c++/test/tattr.cpp b/c++/test/tattr.cpp index e2e347b..aa412d9 100644 --- a/c++/test/tattr.cpp +++ b/c++/test/tattr.cpp @@ -292,6 +292,7 @@ static void test_attr_getname() HDmemset(fattr1_name, 0, buf_size+1); ssize_t name_size = 0; // actual length of attribute name name_size = fattr1.getName(fattr1_name, buf_size+1); + verify_val(name_size, FATTR1_NAME.length(), "Attribute::getName", __LINE__, __FILE__); verify_val((const char*)fattr1_name, FATTR1_NAME, "Attribute::getName", __LINE__, __FILE__); delete []fattr1_name; @@ -302,6 +303,7 @@ static void test_attr_getname() fattr1_name = new char[buf_size+1]; HDmemset(fattr1_name, 0, buf_size+1); name_size = fattr1.getName(fattr1_name, buf_size+1); + verify_val(name_size, FATTR1_NAME.length(), "Attribute::getName", __LINE__, __FILE__); verify_val((const char*)fattr1_name, (const char*)short_name, "Attribute::getName", __LINE__, __FILE__); delete []fattr1_name; @@ -1590,6 +1592,10 @@ extern "C" #endif void cleanup_attr() { - //HDremove(FILENAME.c_str()); + HDremove(FILE_BASIC.c_str()); + HDremove(FILE_COMPOUND.c_str()); + HDremove(FILE_SCALAR.c_str()); + HDremove(FILE_MULTI.c_str()); + HDremove(FILE_DTYPE.c_str()); } diff --git a/c++/test/tcompound.cpp b/c++/test/tcompound.cpp index 60d44b2..3258253 100644 --- a/c++/test/tcompound.cpp +++ b/c++/test/tcompound.cpp @@ -742,13 +742,12 @@ cerr << "test_compound_7 in catch" << endl; * *------------------------------------------------------------------------- */ -#define COMPFILE "tcompound_types.h5" +const H5std_string COMPFILE("tcompound_types.h5"); static void test_compound_set_size() { typedef struct { int a, b, c[4], d, e; } src_typ_t; - src_typ_t *s_ptr; // Output message about test being performed SUBTEST("Setting Size on Compound Datatype"); @@ -867,4 +866,5 @@ extern "C" #endif void cleanup_compound() { + HDremove(COMPFILE.c_str()); } // cleanup_file diff --git a/c++/test/tdspl.cpp b/c++/test/tdspl.cpp index 5944fb1..5c1d953 100644 --- a/c++/test/tdspl.cpp +++ b/c++/test/tdspl.cpp @@ -50,7 +50,6 @@ static void test_transfplist() const char* simple = "(4/2) * ( (2 + 4)/(5 - 2.5))"; /* this equals 4.8 */ /* inverses the utrans transform in init_test to get back original array */ const char* utrans_inv = "(x/3)*4 - 100"; - char *c_to_f_read=NULL, *simple_read=NULL, *utrans_inv_read=NULL; SUBTEST("DSetMemXferPropList::set/getDataTransform()"); try { @@ -75,7 +74,7 @@ static void test_transfplist() // Find out the length of the transform expression, allocate the buffer // for it, then read and verify the expression from the copied plist ssize_t tran_len = dxpl_c_to_f_copy.getDataTransform(NULL); - c_to_f_read = (char *)HDmalloc(tran_len+1); + char *c_to_f_read = (char *)HDmalloc(tran_len+1); HDmemset(c_to_f_read, 0, tran_len+1); dxpl_c_to_f_copy.getDataTransform(c_to_f_read, tran_len+1); verify_val((const char*)c_to_f_read, (const char*)c_to_f, @@ -106,7 +105,7 @@ static void test_transfplist() // Get and verify the expression with: // ssize_t getDataTransform(char* exp, const size_t buf_size) tran_len = dxpl_utrans_inv.getDataTransform(NULL, 0); - utrans_inv_read = (char *)HDmalloc(tran_len+1); + char *utrans_inv_read = (char *)HDmalloc(tran_len+1); HDmemset(utrans_inv_read, 0, tran_len+1); dxpl_utrans_inv.getDataTransform(utrans_inv_read, tran_len+1); verify_val((const char*)utrans_inv_read, (const char*)utrans_inv, diff --git a/c++/test/testhdf5.cpp b/c++/test/testhdf5.cpp index 57210d0..19b4f0d 100644 --- a/c++/test/testhdf5.cpp +++ b/c++/test/testhdf5.cpp @@ -67,41 +67,54 @@ int main(int argc, char *argv[]) { - /* Initialize testing framework */ - TestInit(argv[0], NULL, NULL); - - // testing file creation and opening in tfile.cpp - AddTest("tfile", test_file, cleanup_file, "File I/O Operations", NULL); - // testing dataset functionalities in dset.cpp - AddTest("dsets", test_dset, cleanup_dsets, "Dataset I/O Operations", NULL); - // testing dataspace functionalities in th5s.cpp - AddTest("th5s", test_h5s, cleanup_h5s, "Dataspaces", NULL); - // testing attribute functionalities in tattr.cpp - AddTest("tattr", test_attr, cleanup_attr, "Attributes", NULL); - // testing reference functionalities in trefer.cpp - AddTest("trefer", test_reference, cleanup_reference, "References", NULL); - // testing variable-length strings in tvlstr.cpp - AddTest("tvlstr", test_vlstrings, cleanup_vlstrings, "Variable-Length Strings", NULL); - AddTest("ttypes", test_types, cleanup_types, "Generic Data Types", NULL); - AddTest("tcompound", test_compound, cleanup_compound, "Compound Data Types", NULL); - AddTest("tdspl", test_dsproplist, cleanup_dsproplist, "Dataset Property List", NULL); - AddTest("tfilter", test_filters, cleanup_filters, "Various Filters", NULL); - AddTest("tlinks", test_links, cleanup_links, "Various Links", NULL); + 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(); + /* Initialize testing framework */ + TestInit(argv[0], NULL, NULL); + + // testing file creation and opening in tfile.cpp + AddTest("tfile", test_file, cleanup_file, "File I/O Operations", NULL); + // testing dataset functionalities in dset.cpp + AddTest("dsets", test_dset, cleanup_dsets, "Dataset I/O Operations", NULL); + // testing dataspace functionalities in th5s.cpp + AddTest("th5s", test_h5s, cleanup_h5s, "Dataspaces", NULL); + // testing attribute functionalities in tattr.cpp + AddTest("tattr", test_attr, cleanup_attr, "Attributes", NULL); + // testing object functionalities in tobject.cpp + AddTest("tobject", test_object, cleanup_object, "Objects", NULL); + // testing reference functionalities in trefer.cpp + AddTest("trefer", test_reference, cleanup_reference, "References", NULL); + // testing variable-length strings in tvlstr.cpp + AddTest("tvlstr", test_vlstrings, cleanup_vlstrings, "Variable-Length Strings", NULL); + AddTest("ttypes", test_types, cleanup_types, "Generic Data Types", NULL); + AddTest("tcompound", test_compound, cleanup_compound, "Compound Data Types", NULL); + AddTest("tdspl", test_dsproplist, cleanup_dsproplist, "Dataset Property List", NULL); + AddTest("tfilter", test_filters, cleanup_filters, "Various Filters", NULL); + AddTest("tlinks", test_links, cleanup_links, "Various Links", 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); - AddTest("vltypes", test_vltypes, cleanup_vltypes, "Variable-Length Datatypes", NULL); - 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); + AddTest("select", test_select, cleanup_select, "Selections", NULL); + AddTest("time", test_time, cleanup_time, "Time Datatypes", NULL); + AddTest("vltypes", test_vltypes, cleanup_vltypes, "Variable-Length Datatypes", NULL); + 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); + AddTest("enum", test_enum, cleanup_enum, "Enum Data Types", NULL); */ + } + catch (Exception E) + { + issue_fail_msg("Tests failed", __LINE__, __FILE__, E.getCDetailMsg()); + } + /* Display testing information */ TestInfo(argv[0]); diff --git a/c++/test/tfile.cpp b/c++/test/tfile.cpp index 965065a..1f53e61 100644 --- a/c++/test/tfile.cpp +++ b/c++/test/tfile.cpp @@ -654,4 +654,5 @@ void cleanup_file() HDremove(FILE2.c_str()); HDremove(FILE3.c_str()); HDremove(FILE4.c_str()); + HDremove(FILE5.c_str()); } // cleanup_file diff --git a/c++/test/tfilter.cpp b/c++/test/tfilter.cpp index 257e4be..854c7bb 100644 --- a/c++/test/tfilter.cpp +++ b/c++/test/tfilter.cpp @@ -165,7 +165,7 @@ static void test_null_filter() const H5std_string DSET_SZIP_NAME("szipped dataset"); -void test_szip_filter(H5File& file1) +static void test_szip_filter(H5File& file1) { #ifdef H5_HAVE_FILTER_SZIP int points[DSET_DIM1][DSET_DIM2], check[DSET_DIM1][DSET_DIM2]; diff --git a/c++/test/tobject.cpp b/c++/test/tobject.cpp new file mode 100644 index 0000000..e6ef69c --- /dev/null +++ b/c++/test/tobject.cpp @@ -0,0 +1,269 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * Copyright by The HDF Group. * + * Copyright by the Board of Trustees of the University of Illinois. * + * 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://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 + tobject.cpp - HDF5 C++ testing object related functionality + + ***************************************************************************/ + +#ifdef OLD_HEADER_FILENAME +#include +#else +#include +#endif +#include + +#ifndef H5_NO_NAMESPACE +#ifndef H5_NO_STD + using std::cerr; + using std::endl; +#endif // H5_NO_STD +#endif + +#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 FILE_OBJECTS("tobjects.h5"); +const H5std_string GROUP1("Top Group"); +const H5std_string GROUP1_PATH("/Top Group"); +const H5std_string GROUP1_1("Sub-Group 1.1"); +const H5std_string GROUP1_1_PATH("/Top Group/Sub-Group 1.1"); +const H5std_string GROUP1_2("Sub-Group 1.2"); +const H5std_string GROUP1_2_PATH("/Top Group/Sub-Group 1.2"); +const H5std_string DSET_DEFAULT_NAME("default"); +const H5std_string DSET_IN_FILE("Dataset in File"); +const H5std_string DSET_IN_FILE_PATH("/Dataset in File"); +const H5std_string DSET_IN_GRP1("Dataset in Group 1"); +const H5std_string DSET_IN_GRP1_PATH("/Top Group/Dataset in Group 1"); +const H5std_string DSET_IN_GRP1_2("Dataset in Group 1.2"); +const H5std_string DSET_IN_GRP1_2_PATH("/Top Group/Sub-Group 1.2/Dataset in Group 1.2"); + +/*------------------------------------------------------------------------- + * Function: test_get_objname + * + * Purpose: Tests getting object name of groups and datasets. + * + * Return: Success: 0 + * Failure: -1 + * + * Programmer: Binh-Minh Ribler + * Friday, March 4, 2014 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +static void test_get_objname() +{ + SUBTEST("H5Object::getObjName on Groups and Datasets"); + + try { + // Create file + H5File file(FILE_OBJECTS, H5F_ACC_TRUNC); + + // Create a top group and 2 subgroups + Group grp1 = file.createGroup(GROUP1, 0); + Group grp1_1 = grp1.createGroup(GROUP1_1, 0); + Group grp1_2 = grp1.createGroup(GROUP1_2, 0); + + // Get part of the group's name, random length using + // ssize_t getObjName(char* comment, size_t buf_size) + + // Get the length of the group's name first + ssize_t name_len = grp1.getObjName(NULL); + + // Random length is 4 + if (name_len > 4) + { + char* grp1_name = new char[5]; + name_len = grp1.getObjName(grp1_name, 5); + verify_val((const char*)grp1_name, "/Top", "Group::getObjName", __LINE__, __FILE__); + delete []grp1_name; + } + + // Create a data space + hsize_t dims[2]; + dims[0] = 2; + dims[1] = 5; + DataSpace space (2, dims, NULL); + + // Create a dataset in the file + DataSet dsinfile = file.createDataSet(DSET_IN_FILE, + PredType::NATIVE_DOUBLE, space); + + // Create a dataset in the group + DataSet dsingrp = grp1.createDataSet(DSET_IN_GRP1, + PredType::NATIVE_INT, space); + + // Get and verify the name of each dataset, using + // H5std_string getObjName() and + // ssize_t getObjName(H5std_string& obj_name, size_t len = 0) + H5std_string ds_name = dsinfile.getObjName(); + verify_val(ds_name, DSET_IN_FILE_PATH, "DataSet::getObjName", __LINE__, __FILE__); + + name_len = dsingrp.getObjName(ds_name); // default len + verify_val(ds_name, DSET_IN_GRP1_PATH, "DataSet::getObjName", __LINE__, __FILE__); + + // Close dataset + dsingrp.close(); + + // Create a dataset in sub-group 1.2 + dsingrp = grp1_2.createDataSet(DSET_IN_GRP1_2, PredType::NATIVE_INT, space); + + // Get and verify the name of the dataset that belongs to subgroup + // 1.2, using H5std_string getObjName() + ds_name = dsingrp.getObjName(); + verify_val(ds_name, DSET_IN_GRP1_2_PATH, "DataSet::getObjName", __LINE__, __FILE__); + + // Close dataset + dsingrp.close(); + + // Reopen that same dataset then check the name again with another + // overload: ssize_t getObjName(H5std_string& obj_name, size_t len = 0) + dsingrp = grp1_2.openDataSet(DSET_IN_GRP1_2); + name_len = dsingrp.getObjName(ds_name); + verify_val(ds_name, DSET_IN_GRP1_2_PATH, "DataSet::getObjName", __LINE__, __FILE__); + + // Everything will be closed as they go out of scope + + PASSED(); + } // try block + + // catch all other exceptions + catch (Exception E) + { + issue_fail_msg("test_get_objname", __LINE__, __FILE__); + } +} // test_get_objname + +/*------------------------------------------------------------------------- + * Function: test_get_objname_ontypes + * + * Purpose: Test getting object name from various committed types. + * + * Return: Success: 0 + * Failure: -1 + * + * Programmer: Binh-Minh Ribler + * March 4, 2014 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +static void test_get_objname_ontypes() +{ + SUBTEST("H5Object::getObjName on Committed Datatypes"); + + try { + // Create a file with default prop lists + H5File file(FILE_OBJECTS, H5F_ACC_RDWR); + + // Create a group + Group grp = file.createGroup ("typetests"); + + // Create a datatype and save it + DataType dtype(PredType::STD_B8LE); + dtype.commit(file, "STD_B8LE"); + + // Get and verify its name + H5std_string type_name = dtype.getObjName(); + verify_val(type_name, "/STD_B8LE", "DataSet::getObjName", __LINE__, __FILE__); + + // Test getting type's name from copied type + DataType copied_type; + copied_type.copy(dtype); + copied_type.commit(file, "copy of STD_B8LE"); + type_name = copied_type.getObjName(); + verify_val(type_name, "/copy of STD_B8LE", "DataSet::getObjName", __LINE__, __FILE__); + + // Test copying an integer predefined type + IntType new_int_type(PredType::NATIVE_INT); + + // Name this datatype + new_int_type.commit(grp, "IntType NATIVE_INT"); + ssize_t name_len = new_int_type.getObjName(type_name); // default len + verify_val(type_name, "/typetests/IntType NATIVE_INT", "DataSet::getObjName", __LINE__, __FILE__); + + // Close everything or they can be closed when objects go out of scope + dtype.close(); + copied_type.close(); + new_int_type.close(); + grp.close(); + file.close(); + + PASSED(); + } // end top try block + + catch (Exception E) + { + issue_fail_msg("test_get_objname_ontypes", __LINE__, __FILE__); + } +} // test_get_objname_ontypes + +/*------------------------------------------------------------------------- + * Function: test_objects + * + * Purpose: Tests HDF5 object related functionality + * + * Return: Success: 0 + * Failure: -1 + * + * Programmer: Binh-Minh Ribler + * Friday, Mar 4, 2014 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +#ifdef __cplusplus +extern "C" +#endif +void test_object() +{ + // Output message about test being performed + MESSAGE(5, ("Testing Object Functions\n")); + + test_get_objname(); // Test get object name from groups/datasets + test_get_objname_ontypes(); // Test get object name from types + +} // test_objects + +/*------------------------------------------------------------------------- + * Function: cleanup_objects + * + * Purpose: Cleanup temporary test files + * + * Return: none + * + * Programmer: (use C version) + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +#ifdef __cplusplus +extern "C" +#endif +void cleanup_object() +{ + HDremove(FILE_OBJECTS.c_str()); +} // cleanup_objects diff --git a/c++/test/tvlstr.cpp b/c++/test/tvlstr.cpp index 89f24f2..a2669db 100644 --- a/c++/test/tvlstr.cpp +++ b/c++/test/tvlstr.cpp @@ -50,10 +50,6 @@ const H5std_string FILENAME("tvlstr.h5"); const int SPACE1_RANK = 1; const hsize_t SPACE1_DIM1 = 4; -// Utility functions - not used now, later though. -void *test_vlstr_alloc_custom(size_t size, void *info); -void test_vlstr_free_custom(void *mem, void *info); - /**************************************************************** ** ** test_vlstr_alloc_custom(): Test VL datatype custom memory @@ -62,9 +58,9 @@ void test_vlstr_free_custom(void *mem, void *info); ** allocated. It is passed into setVlenMemManager. ** ** Note: exact copy from the C version. -** +** (Not used now) ****************************************************************/ -void *test_vlstr_alloc_custom(size_t size, void *info) +static void *test_vlstr_alloc_custom(size_t size, void *info) { void *ret_value=NULL; // Pointer to return size_t *mem_used=(size_t *)info; // Get the pointer to the memory used @@ -94,9 +90,9 @@ void *test_vlstr_alloc_custom(size_t size, void *info) ** allocated. It is passed into setVlenMemManager. ** ** Note: exact copy from the C version. -** +** (Not used now) ****************************************************************/ -void test_vlstr_free_custom(void *_mem, void *info) +static void test_vlstr_free_custom(void *_mem, void *info) { unsigned char *mem; size_t *mem_used=(size_t *)info; // Get the pointer to the memory used -- cgit v0.12