From c7b27a76749fa0c299fd33299ac59b36348ada5f Mon Sep 17 00:00:00 2001 From: Binh-Minh Ribler Date: Tue, 12 Sep 2017 14:46:06 -0500 Subject: New overloaded functions and tests Description: - Added VarLenType::VarLenType(const DataType& base_type) - Marked VarLenType::VarLenType(const DataType* base_type) deprecated - Added a static wrapper for H5Tdetect_class for PredType static bool DataType::detectClass(const PredType& pred_type, ...) - Removed the deprecated function Exception::printError() from code - Miscellaneous improvements in comments - Added test functions test_detect_type_class() and test_vltype() Platforms tested: Linux/32 2.6 (jam) Linux/64 (jelly) Darwin (osx1010test) --- c++/src/H5AbstractDs.h | 2 +- c++/src/H5CommonFG.h | 14 ++- c++/src/H5CompType.cpp | 1 - c++/src/H5DataType.cpp | 22 ++++ c++/src/H5DataType.h | 1 + c++/src/H5DcreatProp.h | 1 + c++/src/H5DxferProp.h | 2 +- c++/src/H5Exception.cpp | 9 +- c++/src/H5Exception.h | 4 +- c++/src/H5IdComponent.cpp | 6 +- c++/src/H5Location.cpp | 67 ++++++----- c++/src/H5Location.h | 6 +- c++/src/H5Object.cpp | 2 +- c++/src/H5Object.h | 8 +- c++/src/H5PropList.h | 1 - c++/src/H5VarLenType.cpp | 23 +++- c++/src/H5VarLenType.h | 3 + c++/test/titerate.cpp | 77 ++++--------- c++/test/ttypes.cpp | 276 ++++++++++++++++++++++++++++++++++++++++++++++ 19 files changed, 416 insertions(+), 109 deletions(-) diff --git a/c++/src/H5AbstractDs.h b/c++/src/H5AbstractDs.h index 73a18b8..16bef66 100644 --- a/c++/src/H5AbstractDs.h +++ b/c++/src/H5AbstractDs.h @@ -31,7 +31,7 @@ class DataSpace; and DataSet. It provides a collection of services that are common to both Attribute - and DataSet. AbstractDs inherits from H5Object. + and DataSet. */ class H5_DLLCPP AbstractDs { public: diff --git a/c++/src/H5CommonFG.h b/c++/src/H5CommonFG.h index 3cbad76..68e3f19 100644 --- a/c++/src/H5CommonFG.h +++ b/c++/src/H5CommonFG.h @@ -24,10 +24,9 @@ class ArrayType; class VarLenType; /*! \class CommonFG - \brief \a CommonFG is an abstract base class of H5File and H5Group. - - It provides common operations of H5File and H5Group. + \brief \a CommonFG is an abstract base class of H5Group. */ +/* Note: This class is being deprecated gradually. */ class H5_DLLCPP CommonFG { public: // Opens a generic named datatype in this location. @@ -87,3 +86,12 @@ class H5_DLLCPP CommonFG { #endif // __CommonFG_H +/*************************************************************************** + Design Note + =========== + +September 2017: + + This class used to be base class of H5File as well, until the + restructure that moved H5File to be subclass of H5Group. +*/ diff --git a/c++/src/H5CompType.cpp b/c++/src/H5CompType.cpp index da7e3e2..d357fbc 100644 --- a/c++/src/H5CompType.cpp +++ b/c++/src/H5CompType.cpp @@ -216,7 +216,6 @@ int CompType::getMemberIndex(const H5std_string& name) const /// respect to the beginning of the compound data type datum. ///\param member_num - IN: Zero-based index of the member ///\return Byte offset -///\exception H5::DataTypeIException // Programmer Binh-Minh Ribler - 2000 // Description /// Members are stored in no particular order with numbers 0 diff --git a/c++/src/H5DataType.cpp b/c++/src/H5DataType.cpp index 28a670e..90211b9 100644 --- a/c++/src/H5DataType.cpp +++ b/c++/src/H5DataType.cpp @@ -797,6 +797,28 @@ bool DataType::detectClass(H5T_class_t cls) const } //-------------------------------------------------------------------------- +// Function: DataType::detectClass (static) +///\brief Checks whether a predtype is a certain class of datatype. +///\return true if this predtype is the specified type class, and false, +/// otherwise. +///\exception H5::DataTypeIException +// Programmer Binh-Minh Ribler - August, 2017 +//-------------------------------------------------------------------------- +bool DataType::detectClass(const PredType& pred_type, H5T_class_t cls) +{ + htri_t ret_value = H5Tdetect_class(pred_type.getId(), cls); + if (ret_value > 0) + return true; + else if (ret_value == 0) + return false; + else + { + throw DataTypeIException("detectClass on PredType", + "H5Tdetect_class returns negative value"); + } +} + +//-------------------------------------------------------------------------- // Function: DataType::isVariableStr ///\brief Check whether this datatype is a variable-length string. ///\return true if this datatype is a variable-length string, and diff --git a/c++/src/H5DataType.h b/c++/src/H5DataType.h index 50d2fc1..6833a06 100644 --- a/c++/src/H5DataType.h +++ b/c++/src/H5DataType.h @@ -114,6 +114,7 @@ class H5_DLLCPP DataType : public H5Object { // Checks whether this datatype contains (or is) a certain type class. bool detectClass(H5T_class_t cls) const; + static bool detectClass(const PredType& pred_type, H5T_class_t cls); // Checks whether this datatype is a variable-length string. bool isVariableStr() const; diff --git a/c++/src/H5DcreatProp.h b/c++/src/H5DcreatProp.h index 5d5714a..ebd2678 100644 --- a/c++/src/H5DcreatProp.h +++ b/c++/src/H5DcreatProp.h @@ -17,6 +17,7 @@ namespace H5 { +// Class forwarding class DataType; class DataSpace; diff --git a/c++/src/H5DxferProp.h b/c++/src/H5DxferProp.h index 4a38bd0..4a66671 100644 --- a/c++/src/H5DxferProp.h +++ b/c++/src/H5DxferProp.h @@ -21,7 +21,7 @@ namespace H5 { \brief Class DSetCreatPropList inherits from PropList and provides wrappers for the HDF5 dataset memory and transfer property list. - Inheritance: ObjCreatPropList -> PropList -> IdComponent + Inheritance: PropList -> IdComponent */ class H5_DLLCPP DSetMemXferPropList : public PropList { public: diff --git a/c++/src/H5Exception.cpp b/c++/src/H5Exception.cpp index c9a1323..c52a279 100644 --- a/c++/src/H5Exception.cpp +++ b/c++/src/H5Exception.cpp @@ -317,11 +317,12 @@ void Exception::printErrorStack(FILE* stream, hid_t err_stack) // This function can be removed in next major release. // -BMR, 2014/04/24 // Removed from documentation. -BMR, 2016/03/23 +// Removed from code. -BMR, 2017/08/11 1.8.20 and 1.10.2 //-------------------------------------------------------------------------- -void Exception::printError(FILE* stream) const -{ - Exception::printErrorStack(stream, H5E_DEFAULT); -} +//void Exception::printError(FILE* stream) const +//{ +// Exception::printErrorStack(stream, H5E_DEFAULT); +//} //-------------------------------------------------------------------------- // Function: Exception destructor diff --git a/c++/src/H5Exception.h b/c++/src/H5Exception.h index 2cc2dd6..cb14a4c 100644 --- a/c++/src/H5Exception.h +++ b/c++/src/H5Exception.h @@ -70,7 +70,9 @@ class H5_DLLCPP Exception { // Prints the error stack in a default manner. static void printErrorStack(FILE* stream = stderr, hid_t err_stack = H5E_DEFAULT); - virtual void printError(FILE* stream = NULL) const; + // Deprecated in favor of printErrorStack. + // Removed from code. -BMR, 2017/08/11 1.8.20 and 1.10.2 + // virtual void printError(FILE* stream = NULL) const; // Default constructor Exception(); diff --git a/c++/src/H5IdComponent.cpp b/c++/src/H5IdComponent.cpp index 284c6c5..fe2d27e 100644 --- a/c++/src/H5IdComponent.cpp +++ b/c++/src/H5IdComponent.cpp @@ -368,8 +368,10 @@ IdComponent::IdComponent() // Exception: H5::IdComponentException // Description: // This function is protected so that the user applications can -// only have access to its code via allowable classes, namely, -// Attribute and H5Location subclasses. +// only have access to its code via H5Location subclasses. +// September 2017 +// This function should be moved to H5Location now that Attribute +// inherits from H5Location. // Programmer Binh-Minh Ribler - Jul, 2004 //-------------------------------------------------------------------------- H5std_string IdComponent::p_get_file_name() const diff --git a/c++/src/H5Location.cpp b/c++/src/H5Location.cpp index 9f2d7d5..35a4828 100644 --- a/c++/src/H5Location.cpp +++ b/c++/src/H5Location.cpp @@ -93,7 +93,7 @@ bool H5Location::exists(const char* name, const LinkAccPropList& lapl) const return false; else // Raise exception when H5Lexists returns a negative value { - throwException("exists", "H5Lexists failed"); + throw LocationException(inMemFunc("exists"), "H5Lexists failed"); } } @@ -118,7 +118,7 @@ bool H5Location::exists(const H5std_string& name, const LinkAccPropList& lapl) c /// which can be either of these values: /// \li \c H5F_SCOPE_GLOBAL - Flushes the entire virtual file /// \li \c H5F_SCOPE_LOCAL - Flushes only the specified file -///\exception H5::Exception +///\exception H5::LocationException ///\par Description /// This location is used to identify the file to be flushed. // Programmer Binh-Minh Ribler - 2012 @@ -147,8 +147,8 @@ H5std_string H5Location::getFileName() const try { return(p_get_file_name()); } - catch (LocationException& E) { - throw FileIException(inMemFunc("getFileName"), E.getDetailMsg()); + catch (IdComponentException& E) { + throw LocationException(inMemFunc("getFileName"), E.getDetailMsg()); } } @@ -495,7 +495,7 @@ hid_t H5Location::p_dereference(hid_t loc_id, const void* ref, H5R_type_t ref_ty hid_t temp_id = H5Rdereference2(loc_id, plist_id, ref_type, ref); if (temp_id < 0) { - throw ReferenceException(inMemFunc(from_func), "H5Rdereference failed"); + throw ReferenceException(inMemFunc(from_func), "H5Rdereference2 failed"); } return(temp_id); @@ -557,7 +557,7 @@ void H5Location::dereference(const H5Location& loc, const void* ref, H5R_type_t /// \li \c H5G_TYPE Object - is a named datatype /// \li \c H5G_LINK - Object is a symbolic link. /// \li \c H5G_UDLINK - Object is a user-defined link. -///\exception H5::ReferenceException +///\exception H5::LocationException // Programmer Binh-Minh Ribler - May, 2004 // Modification // Sep 2012: Moved up from H5File, Group, DataSet, and DataType @@ -717,19 +717,21 @@ DataSpace H5Location::getRegion(void *ref, H5R_type_t ref_type) const // ***Updated: after HDFFV-9920, methods in classes H5Location and Group // use throwException to distinguish the FileIException and GroupIException. // CommonFG is no longer used in the library. Aug 18, 2016 -BMR +// H5Location::throwException is changed to throw LocationException for any +// subclass that is not H5File or Group. Aug 14, 2017 -BMR // ***Note: following the changes in HDFFV-9920, some of the methods could // throw different exceptions, but for backward-compatibility, throwException // is kept in those methods as well. Sep 17, 2016 -BMR +// //-------------------------------------------------------------------------- // Function: H5Location::createGroup -///\brief Creates a new group at this location which can be a file -/// or another group. +///\brief Creates a new group at this location. ///\param name - IN: Name of the group to create ///\param size_hint - IN: Indicates the number of bytes to reserve for /// the names that will appear in the group ///\return Group instance -///\exception H5::FileIException or H5::GroupIException +///\exception H5::FileIException/H5::GroupIException/H5::LocationException ///\par Description /// The optional \a size_hint specifies how much file space to /// reserve for storing the names that will appear in this new @@ -793,7 +795,7 @@ Group H5Location::createGroup(const H5std_string& name, size_t size_hint) const /// or another group. ///\param name - IN: Name of the group to open ///\return Group instance -///\exception H5::FileIException or H5::GroupIException +///\exception H5::FileIException/H5::GroupIException/H5::LocationException // Programmer Binh-Minh Ribler - 2000 //-------------------------------------------------------------------------- Group H5Location::openGroup(const char* name) const @@ -834,7 +836,7 @@ Group H5Location::openGroup(const H5std_string& name) const ///\param data_space - IN: Dataspace for the dataset ///\param create_plist - IN: Creation properly list for the dataset ///\return DataSet instance -///\exception H5::FileIException or H5::GroupIException +///\exception H5::FileIException/H5::GroupIException/H5::LocationException // Programmer Binh-Minh Ribler - 2000 //-------------------------------------------------------------------------- DataSet H5Location::createDataSet(const char* name, const DataType& data_type, const DataSpace& data_space, const DSetCreatPropList& create_plist) const @@ -874,7 +876,7 @@ DataSet H5Location::createDataSet(const H5std_string& name, const DataType& data ///\brief Opens an existing dataset at this location. ///\param name - IN: Name of the dataset to open ///\return DataSet instance -///\exception H5::FileIException or H5::GroupIException +///\exception H5::FileIException/H5::GroupIException/H5::LocationException // Programmer Binh-Minh Ribler - 2000 //-------------------------------------------------------------------------- DataSet H5Location::openDataSet(const char* name) const @@ -915,7 +917,7 @@ DataSet H5Location::openDataSet(const H5std_string& name) const ///\param curr_name - IN: Name of the existing object if link is a hard /// link; can be anything for the soft link ///\param new_name - IN: New name for the object -///\exception H5::FileIException or H5::GroupIException +///\exception H5::FileIException/H5::GroupIException/H5::LocationException ///\par Description /// Note that both names are interpreted relative to the /// specified location. @@ -968,7 +970,7 @@ void H5Location::link(H5L_type_t link_type, const H5std_string& curr_name, const // Function: H5Location::unlink ///\brief Removes the specified name at this location. ///\param name - IN: Name of the object to be removed -///\exception H5::FileIException or H5::GroupIException +///\exception H5::FileIException/H5::GroupIException/H5::LocationException // Programmer Binh-Minh Ribler - 2000 // Modification // 2007: QAK modified to use H5L APIs - BMR @@ -997,7 +999,7 @@ void H5Location::unlink(const H5std_string& name) const ///\brief Renames an object at this location. ///\param src - IN: Object's original name ///\param dst - IN: Object's new name -///\exception H5::FileIException or H5::GroupIException +///\exception H5::FileIException/H5::GroupIException/H5::LocationException ///\note /// Exercise care in moving groups as it is possible to render /// data in a file inaccessible with H5Location::move. Please refer @@ -1033,7 +1035,7 @@ void H5Location::move(const H5std_string& src, const H5std_string& dst) const ///\param name - IN: Name of the object ///\param follow_link - IN: Link flag ///\param statbuf - OUT: Buffer to return information about the object -///\exception H5::FileIException or H5::GroupIException +///\exception H5::FileIException/H5::GroupIException/H5::LocationException ///\par Description /// For more information, please refer to the C layer Reference /// Manual at: @@ -1093,7 +1095,7 @@ void H5Location::getObjinfo(const H5std_string& name, H5G_stat_t& statbuf) const ///\param name - IN: Symbolic link to the object ///\param size - IN: Maximum number of characters of value to be returned ///\return Name of the object -///\exception H5::FileIException or H5::GroupIException +///\exception H5::FileIException/H5::GroupIException/H5::LocationException // Programmer Binh-Minh Ribler - 2000 //-------------------------------------------------------------------------- H5std_string H5Location::getLinkval(const char* name, size_t size) const @@ -1219,7 +1221,7 @@ void H5Location::mount(const H5std_string& name, const H5File& child, const Prop // Function: H5Location::unmount ///\brief Unmounts the specified file. ///\param name - IN: Name of the file to unmount -///\exception H5::FileIException or H5::GroupIException +///\exception H5::FileIException/H5::GroupIException/H5::LocationException // Programmer Binh-Minh Ribler - 2000 //-------------------------------------------------------------------------- void H5Location::unmount(const char* name) const @@ -1255,7 +1257,7 @@ void H5Location::unmount(const H5std_string& name) const ///\return The return value of the first operator that returns non-zero, /// or zero if all members were processed with no operator /// returning non-zero. -///\exception H5::FileIException or H5::GroupIException +///\exception H5::FileIException/H5::GroupIException/H5::LocationException // Programmer Binh-Minh Ribler - 2000 //-------------------------------------------------------------------------- int H5Location::iterateElems(const char* name, int *idx, H5G_iterate_t op , void* op_data) @@ -1304,7 +1306,7 @@ hsize_t H5Location::getNumObjs() const /// object's index. ///\param idx - IN: Transient index of the object ///\return Object name -///\exception H5::FileIException or H5::GroupIException +///\exception H5::FileIException/H5::GroupIException/H5::LocationException ///\par Description /// The value of idx can be any nonnegative number less than the /// total number of objects in the group, which is returned by @@ -1346,7 +1348,7 @@ H5std_string H5Location::getObjnameByIdx(hsize_t idx) const ///\param name - IN/OUT: Retrieved name of the object ///\param size - IN: Length to retrieve ///\return Actual size of the object name or 0, if object has no name -///\exception H5::FileIException or H5::GroupIException +///\exception H5::FileIException/H5::GroupIException/H5::LocationException ///\par Description /// The value of idx can be any nonnegative number less than the /// total number of objects in the group, which is returned by @@ -1402,7 +1404,7 @@ ssize_t H5Location::getObjnameByIdx(hsize_t idx, H5std_string& name, size_t size /// \li \c H5O_TYPE_NAMED_DATATYPE /// Refer to the C API documentation for more details: /// http://www.hdfgroup.org/HDF5/doc/RM/RM_H5O.html#Object-GetInfo -///\exception H5::FileIException or H5::GroupIException +///\exception H5::FileIException/H5::GroupIException/H5::LocationException /// Exception will be thrown when: /// - an error returned by the C API /// - object type is not one of the valid values above @@ -1443,7 +1445,7 @@ H5O_type_t H5Location::childObjType(const char* objname) const ///\brief Returns the type of an object in this group, given the /// object's name. ///\param objname - IN: Name of the object (H5std_string&) -///\exception H5::FileIException or H5::GroupIException +///\exception H5::FileIException/H5::GroupIException/H5::LocationException // Programmer Binh-Minh Ribler - April, 2014 //-------------------------------------------------------------------------- H5O_type_t H5Location::childObjType(const H5std_string& objname) const @@ -1468,7 +1470,7 @@ H5O_type_t H5Location::childObjType(const H5std_string& objname) const /// \li \c H5O_TYPE_NAMED_DATATYPE /// Refer to the C API documentation for more details: /// http://www.hdfgroup.org/HDF5/doc/RM/RM_H5O.html#Object-GetInfo -///\exception H5::FileIException or H5::GroupIException +///\exception H5::FileIException/H5::GroupIException/H5::LocationException /// Exception will be thrown when: /// - an error returned by the C API /// - object type is not one of the valid values above @@ -1519,7 +1521,7 @@ H5O_type_t H5Location::childObjType(hsize_t index, H5_index_t index_type, H5_ite ///\return Object version, which can have the following values: /// \li \c H5O_VERSION_1 /// \li \c H5O_VERSION_2 -///\exception H5::FileIException or H5::GroupIException +///\exception H5::FileIException/H5::GroupIException/H5::LocationException /// Exception will be thrown when: /// - an error returned by the C API /// - version number is not one of the valid values above @@ -1553,7 +1555,7 @@ unsigned H5Location::childObjVersion(const char* objname) const ///\brief Returns the type of an object in this group, given the /// object's name. ///\param objname - IN: Name of the object (H5std_string&) -///\exception H5::FileIException or H5::GroupIException +///\exception H5::FileIException/H5::GroupIException/H5::LocationException // Programmer Binh-Minh Ribler - April, 2014 //-------------------------------------------------------------------------- unsigned H5Location::childObjVersion(const H5std_string& objname) const @@ -1571,7 +1573,7 @@ unsigned H5Location::childObjVersion(const H5std_string& objname) const /// object's index. ///\param idx - IN: Transient index of the object ///\return Object type -///\exception H5::FileIException or H5::GroupIException +///\exception H5::FileIException/H5::GroupIException/H5::LocationException // Programmer Binh-Minh Ribler - January, 2003 //-------------------------------------------------------------------------- H5G_obj_t H5Location::getObjTypeByIdx(hsize_t idx) const @@ -1591,7 +1593,7 @@ H5G_obj_t H5Location::getObjTypeByIdx(hsize_t idx) const ///\param idx - IN: Transient index of the object ///\param type_name - OUT: Object type in text ///\return Object type -///\exception H5::FileIException or H5::GroupIException +///\exception H5::FileIException/H5::GroupIException/H5::LocationException // Programmer Binh-Minh Ribler - May, 2010 // Modification // Modified to use the other function. -BMR, 2016/03/07 @@ -1609,7 +1611,7 @@ H5G_obj_t H5Location::getObjTypeByIdx(hsize_t idx, char* type_name) const ///\param idx - IN: Transient index of the object ///\param type_name - OUT: Object type in text ///\return Object type -///\exception H5::FileIException or H5::GroupIException +///\exception H5::FileIException/H5::GroupIException/H5::LocationException // Programmer Binh-Minh Ribler - January, 2003 //-------------------------------------------------------------------------- H5G_obj_t H5Location::getObjTypeByIdx(hsize_t idx, H5std_string& type_name) const @@ -1642,10 +1644,15 @@ H5G_obj_t H5Location::getObjTypeByIdx(hsize_t idx, H5std_string& type_name) cons ///\param msg - Message describing the failure ///\exception H5::GroupIException // Programmer Binh-Minh Ribler - 2000 +// Modification +// August 2017 - BMR +// Keep Group::throwException and H5File::throwException to +// maintain backward compatibility. For other subclasses, throw +// LocationException. //-------------------------------------------------------------------------- void H5Location::throwException(const H5std_string& func_name, const H5std_string& msg) const { - throwException(func_name, msg); + throw LocationException(inMemFunc(func_name.c_str()), msg); } //-------------------------------------------------------------------------- diff --git a/c++/src/H5Location.h b/c++/src/H5Location.h index 3dfa5d5..f9c5a47 100644 --- a/c++/src/H5Location.h +++ b/c++/src/H5Location.h @@ -30,9 +30,9 @@ namespace H5 { Inheritance: IdComponent */ // Class forwarding -class H5_DLLCPP ArrayType; -class H5_DLLCPP LinkAccPropList; -class H5_DLLCPP VarLenType; +//class H5_DLLCPP ArrayType; +//class H5_DLLCPP LinkAccPropList; +//class H5_DLLCPP VarLenType; class H5_DLLCPP H5Location : public IdComponent { public: // Checks if a link of a given name exists in a location diff --git a/c++/src/H5Object.cpp b/c++/src/H5Object.cpp index 81e61e8..3eed168 100644 --- a/c++/src/H5Object.cpp +++ b/c++/src/H5Object.cpp @@ -391,7 +391,6 @@ void H5Object::renameAttr(const H5std_string& oldname, const H5std_string& newna renameAttr (oldname.c_str(), newname.c_str()); } -#ifndef DOXYGEN_SHOULD_SKIP_THIS //-------------------------------------------------------------------------- // Function: getObjName ///\brief Given an id, returns the type of the object. @@ -503,6 +502,7 @@ ssize_t H5Object::getObjName(H5std_string& obj_name, size_t len) const return(name_size); } +#ifndef DOXYGEN_SHOULD_SKIP_THIS //-------------------------------------------------------------------------- // Function: H5Object destructor ///\brief Noop destructor. diff --git a/c++/src/H5Object.h b/c++/src/H5Object.h index fdaead2..ba32b3e 100644 --- a/c++/src/H5Object.h +++ b/c++/src/H5Object.h @@ -39,9 +39,6 @@ namespace H5 { Inheritance: H5Location -> IdComponent */ -// Class forwarding -class H5_DLLCPP H5Object; -class H5_DLLCPP Attribute; // Define the operator function pointer for H5Aiterate(). typedef void (*attr_operator_t)(H5Object& loc/*in*/, @@ -96,13 +93,14 @@ class H5_DLLCPP H5Object : public H5Location { // Returns an identifier. virtual hid_t getId() const = 0; -#ifndef DOXYGEN_SHOULD_SKIP_THIS // Gets the name of this HDF5 object, i.e., Group, DataSet, or - // DataType. These should have const but are retiring anyway. + // 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; +#ifndef DOXYGEN_SHOULD_SKIP_THIS + protected: // Default constructor H5Object(); diff --git a/c++/src/H5PropList.h b/c++/src/H5PropList.h index 154d7b2..e1fe5b8 100644 --- a/c++/src/H5PropList.h +++ b/c++/src/H5PropList.h @@ -17,7 +17,6 @@ namespace H5 { -//! Class PropList provides operations for generic property lists. /*! \class PropList \brief Class PropList inherits from IdComponent and provides wrappers for the HDF5 generic property list. diff --git a/c++/src/H5VarLenType.cpp b/c++/src/H5VarLenType.cpp index b5ca9c4..5b29682 100644 --- a/c++/src/H5VarLenType.cpp +++ b/c++/src/H5VarLenType.cpp @@ -51,13 +51,14 @@ VarLenType::VarLenType(const VarLenType& original) : DataType(original) {} //-------------------------------------------------------------------------- // Function: VarLenType overloaded constructor -///\brief Creates a new variable-length datatype based on the specified -/// \a base_type. +///\brief Deprecated - will be removed after 1.10.2 ///\param base_type - IN: Pointer to existing datatype ///\exception H5::DataTypeIException // Description // DataType passed by pointer to avoid clashing with copy // constructor. +// Updated: this is unnecessary. +// -BMR, Sep, 2017 // Programmer Binh-Minh Ribler - May, 2004 //-------------------------------------------------------------------------- VarLenType::VarLenType(const DataType* base_type) : DataType() @@ -72,6 +73,24 @@ VarLenType::VarLenType(const DataType* base_type) : DataType() //-------------------------------------------------------------------------- // Function: VarLenType overloaded constructor +///\brief Creates a new variable-length datatype based on the specified +/// \a base_type. +///\param base_type - IN: An existing datatype +///\exception H5::DataTypeIException +// Programmer Binh-Minh Ribler - May, 2004 +//-------------------------------------------------------------------------- +VarLenType::VarLenType(const DataType& base_type) : DataType() +{ + id = H5Tvlen_create(base_type.getId()); + if (id < 0) + { + throw DataTypeIException("VarLenType constructor", + "H5Tvlen_create returns negative value"); + } +} + +//-------------------------------------------------------------------------- +// Function: VarLenType overloaded constructor ///\brief Creates an VarLenType instance by opening an HDF5 variable /// length datatype given its name, provided as a C char*. ///\param loc - IN: Location of the type diff --git a/c++/src/H5VarLenType.h b/c++/src/H5VarLenType.h index 17d812f..2524cf8 100644 --- a/c++/src/H5VarLenType.h +++ b/c++/src/H5VarLenType.h @@ -27,6 +27,9 @@ class H5_DLLCPP VarLenType : public DataType { public: // Constructor that creates a variable-length datatype based // on the specified base type. + VarLenType(const DataType& base_type); + + // Deprecated - will be removed after 1.10.2 VarLenType(const DataType* base_type); // Returns an VarLenType object via DataType* by decoding the diff --git a/c++/test/titerate.cpp b/c++/test/titerate.cpp index f75d92e..5c760f3 100644 --- a/c++/test/titerate.cpp +++ b/c++/test/titerate.cpp @@ -12,8 +12,8 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /***************************************************************************** - FILE - titerate.cpp - HDF5 C++ testing iterate related functionality + FILE + titerate.cpp - HDF5 C++ testing iterate related functionality ***************************************************************************/ #ifdef OLD_HEADER_FILENAME @@ -94,8 +94,7 @@ int iter_strcmp(const void *s1, const void *s2) ** ****************************************************************/ static herr_t -liter_cb(hid_t H5_ATTR_UNUSED group, const char *name, const H5L_info_t H5_ATTR_UNUSED *link_info, - void *op_data) +liter_cb(hid_t H5_ATTR_UNUSED group, const char *name, const H5L_info_t H5_ATTR_UNUSED *link_info, void *op_data) { iter_info *info = (iter_info *)op_data; static int count = 0; @@ -208,7 +207,7 @@ static void test_iter_group(FileAccPropList& fapl) H5std_string obj_name; for (i = 0; i < nobjs; i++) { - //H5O_info_t oinfo; /* Object info */ + //H5O_info_t oinfo; /* Object info */ obj_name = root_group.getObjnameByIdx(i); //ret = (herr_t)H5Lget_name_by_idx(root_group, ".", H5_INDEX_NAME, H5_ITER_INC, (hsize_t)i, dataset_name, (size_t)NAMELEN, H5P_DEFAULT); @@ -380,23 +379,11 @@ void printelems(const Group& group, const H5std_string& dsname, const H5std_stri a1.close(); } - // catch failure caused by the DataSpace operations - catch( DataSpaceIException error ) - { - error.printError(); - } - - // catch failure caused by the Group operations - catch( GroupIException error ) - { - error.printError(); - } - - // catch failure caused by the DataSet operations - catch( DataSetIException error ) - { - error.printError(); - } + // Catch all exceptions and rethrow so caller can handle + catch (Exception& E) + { + throw; + } } /*------------------------------------------------------------------------- @@ -413,11 +400,11 @@ void printelems(const Group& group, const H5std_string& dsname, const H5std_stri */ static void test_HDFFV_9920() { - int attr_data[2] = { 100, 200}; - hsize_t dims[1] = { DIM1 }; - - try - { + int attr_data[2] = { 100, 200}; + hsize_t dims[1] = { DIM1 }; + + try + { // Create a new file and a group in it H5File file( FILE_NAME, H5F_ACC_TRUNC ); @@ -448,31 +435,13 @@ static void test_HDFFV_9920() printelems(file, FDATASET_NAME, FATTR_NAME); printelems(gr1, GDATASET_NAME, GATTR_NAME); - } // end of try block - - // catch failure caused by the H5File operations - catch( DataSpaceIException error ) - { - error.printError(); - } - - // catch failure caused by the H5File operations - catch( AttributeIException error ) - { - error.printError(); - } - - // catch failure caused by the H5File operations - catch( FileIException error ) - { - error.printError(); - } - - // catch failure caused by the DataSet operations - catch( DataSetIException error ) - { - error.printError(); - } + } // end of try block + + // Catch all failures for handling in the same way + catch (Exception& E) + { + issue_fail_msg("test_HDFFV_9920()", __LINE__, __FILE__, E.getCDetailMsg()); + } } @@ -503,9 +472,9 @@ void test_iterate() test_iter_group(fapl); // Test iterating groups test_HDFFV_9920(); // Test the fix of HDFFV-9920 - //test_iter_attr(fapl); // Test iterating attributes + //test_iter_attr(fapl); // Test iterating attributes -} // test_iterate +} // test_iterate /*------------------------------------------------------------------------- * Function: cleanup_iterate diff --git a/c++/test/ttypes.cpp b/c++/test/ttypes.cpp index ec644a8..3cf0920 100644 --- a/c++/test/ttypes.cpp +++ b/c++/test/ttypes.cpp @@ -60,6 +60,7 @@ const char *FILENAME[] = { "dtypes1.h5", "dtypes2.h5", "dtypes3.h5", + "dtypes4.h5", NULL }; @@ -183,6 +184,279 @@ static void test_copy() /*------------------------------------------------------------------------- + * Function: test_detect_type_class + * + * Purpose Test DataType::detectClass() + * + * Return None + * + * Programmer Binh-Minh Ribler (using C version) + * August, 2017 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +typedef struct { /* Struct with atomic fields */ + int i; + float f; + char c; + double d; + short s; +} atomic_typ_t; + +typedef struct { /* Struct with complex fields */ + hobj_ref_t arr_r[3][3]; + int i; + hvl_t vl_f; + hvl_t vl_s; + char c; + short s; +} complex_typ_t; + +static void test_detect_type_class() +{ + + SUBTEST("DataType::detectClass()"); + try { + bool in_class = false; // indicates whether a datatype is in a class + + /* + * Test class of some atomic types. + */ + + // Native integers should be in the integer class + in_class = DataType::detectClass(PredType::NATIVE_INT, H5T_INTEGER); + verify_val(in_class, true, "DataType::detectClass() with H5T_INTEGER", __LINE__, __FILE__); + + // Native integers should _not_ be in other classes + in_class = DataType::detectClass(PredType::NATIVE_INT, H5T_FLOAT); + verify_val(in_class, false, "DataType::detectClass() with H5T_FLOAT", __LINE__, __FILE__); + in_class = DataType::detectClass(PredType::NATIVE_INT, H5T_ARRAY); + verify_val(in_class, false, "DataType::detectClass() with H5T_ARRAY", __LINE__, __FILE__); + in_class = DataType::detectClass(PredType::NATIVE_INT, H5T_ENUM); + verify_val(in_class, false, "DataType::detectClass() with H5T_ENUM", __LINE__, __FILE__); + + /* + * Test class of a compound type with some atomic types as fields. + */ + + // Create a compound datatype and insert some atomic types + CompType atom_cmpd(sizeof(atomic_typ_t)); + atom_cmpd.insertMember("i", HOFFSET(atomic_typ_t, i), PredType::NATIVE_INT); + atom_cmpd.insertMember("f", HOFFSET(atomic_typ_t, f), PredType::NATIVE_FLOAT); + atom_cmpd.insertMember("c", HOFFSET(atomic_typ_t, c), PredType::NATIVE_CHAR); + atom_cmpd.insertMember("d", HOFFSET(atomic_typ_t, d), PredType::NATIVE_DOUBLE); + atom_cmpd.insertMember("s", HOFFSET(atomic_typ_t, s), PredType::NATIVE_SHORT); + + // Make certain that atom_cmpd is a compound type, + in_class = atom_cmpd.detectClass(H5T_COMPOUND); + verify_val(in_class, true, "CompType::detectClass() with H5T_COMPOUND", __LINE__, __FILE__); + // and that it contains a field of type integer + in_class = atom_cmpd.detectClass(H5T_INTEGER); + verify_val(in_class, true, "CompType::detectClass() with H5T_INTEGER", __LINE__, __FILE__); + // and a field of type float, + in_class = atom_cmpd.detectClass(H5T_FLOAT); + verify_val(in_class, true, "CompType::detectClass() with H5T_FLOAT", __LINE__, __FILE__); + // and that it doesn't contain any field of variable-length + in_class = atom_cmpd.detectClass(H5T_VLEN); + verify_val(in_class, false, "CompType::detectClass() with H5T_VLEN", __LINE__, __FILE__); + + /* + * Test class of array datatype + */ + + // Create an array datatype with an atomic base type + unsigned rank = 2; // Rank for array datatype + hsize_t dims[2] = {3,3}; // Dimensions for array datatype + ArrayType atom_arr(PredType::STD_REF_OBJ, rank, dims); + + // Make certain that the correct classes can be detected + in_class = atom_arr.detectClass(H5T_ARRAY); + verify_val(in_class, true, "CompType::detectClass() with H5T_ARRAY", __LINE__, __FILE__); + in_class = atom_arr.detectClass(H5T_REFERENCE); + verify_val(in_class, true, "CompType::detectClass() with H5T_REFERENCE", __LINE__, __FILE__); + + // Make certain that an incorrect class is not detected + in_class = atom_arr.detectClass(H5T_VLEN); + verify_val(in_class, false, "CompType::detectClass() with H5T_VLEN", __LINE__, __FILE__); + in_class = atom_arr.detectClass(H5T_FLOAT); + verify_val(in_class, false, "CompType::detectClass() with H5T_FLOAT", __LINE__, __FILE__); + in_class = atom_arr.detectClass(H5T_INTEGER); + verify_val(in_class, false, "CompType::detectClass() with H5T_INTEGER", __LINE__, __FILE__); + + /* + * Test class of VL datatype + */ + + // Create a VL datatype with an atomic base type of float + VarLenType atom_vlf(PredType::NATIVE_FLOAT); + + // Make certain that the correct classes can be detected + in_class = atom_vlf.detectClass(H5T_VLEN); + verify_val(in_class, true, "CompType::detectClass() with H5T_VLEN", __LINE__, __FILE__); + in_class = atom_vlf.detectClass(H5T_FLOAT); + verify_val(in_class, true, "CompType::detectClass() with H5T_FLOAT", __LINE__, __FILE__); + + // Make certain that an incorrect class is not detected + in_class = atom_vlf.detectClass(H5T_COMPOUND); + verify_val(in_class, false, "CompType::detectClass() with H5T_COMPOUND", __LINE__, __FILE__); + in_class = atom_vlf.detectClass(H5T_INTEGER); + verify_val(in_class, false, "CompType::detectClass() with H5T_INTEGER", __LINE__, __FILE__); + + /* + * Test class of VL datatype + */ + + // Create a VL datatype with an atomic base type of char. It should be a VL + // but not a string class. + VarLenType atom_vlc(PredType::NATIVE_CHAR); + + // Make certain that the correct classes can be detected + in_class = atom_vlc.detectClass(H5T_VLEN); + verify_val(in_class, true, "CompType::detectClass() with H5T_VLEN", __LINE__, __FILE__); + in_class = atom_vlc.detectClass(H5T_INTEGER); + verify_val(in_class, true, "CompType::detectClass() with H5T_INTEGER", __LINE__, __FILE__); + + // Make certain that an incorrect class is not detected + in_class = atom_vlc.detectClass(H5T_STRING); + verify_val(in_class, false, "CompType::detectClass() with H5T_STRING", __LINE__, __FILE__); + + /* + * Test class of VL string datatype + */ + + // Create a VL string. It should be a string, not a VL class. + StrType atom_vls(0, H5T_VARIABLE); + + // Make certain that the correct classes can be detected + in_class = atom_vls.detectClass(H5T_STRING); + verify_val(in_class, true, "CompType::detectClass() with H5T_STRING", __LINE__, __FILE__); + + // Make certain that an incorrect class is not detected + in_class = atom_vls.detectClass(H5T_VLEN); + verify_val(in_class, false, "CompType::detectClass() with H5T_VLEN", __LINE__, __FILE__); + + /* + * Test class of a compound type with some complex types as fields. + */ + + // Create a compound datatype with complex type fields + CompType cplx_cmpd(sizeof(complex_typ_t)); + cplx_cmpd.insertMember("arr_r", HOFFSET(complex_typ_t, arr_r), atom_arr); + cplx_cmpd.insertMember("i", HOFFSET(complex_typ_t, i), PredType::NATIVE_INT); + cplx_cmpd.insertMember("vl_f", HOFFSET(complex_typ_t, vl_f), atom_vlf); + cplx_cmpd.insertMember("vl_s", HOFFSET(complex_typ_t, vl_s), atom_vls); + cplx_cmpd.insertMember("c", HOFFSET(complex_typ_t, c), PredType::NATIVE_CHAR); + cplx_cmpd.insertMember("s", HOFFSET(complex_typ_t, s), PredType::NATIVE_SHORT); + + // Make certain that the correct classes can be detected + in_class = cplx_cmpd.detectClass(H5T_COMPOUND); + verify_val(in_class, true, "CompType::detectClass() with H5T_COMPOUND", __LINE__, __FILE__); + in_class = cplx_cmpd.detectClass(H5T_ARRAY); + verify_val(in_class, true, "CompType::detectClass() with H5T_ARRAY", __LINE__, __FILE__); + in_class = cplx_cmpd.detectClass(H5T_REFERENCE); + verify_val(in_class, true, "CompType::detectClass() with H5T_REFERENCE", __LINE__, __FILE__); + in_class = cplx_cmpd.detectClass(H5T_INTEGER); + verify_val(in_class, true, "CompType::detectClass() with H5T_INTEGER", __LINE__, __FILE__); + in_class = cplx_cmpd.detectClass(H5T_FLOAT); + verify_val(in_class, true, "CompType::detectClass() with H5T_FLOAT", __LINE__, __FILE__); + in_class = cplx_cmpd.detectClass(H5T_STRING); + verify_val(in_class, true, "CompType::detectClass() with H5T_STRING", __LINE__, __FILE__); + in_class = cplx_cmpd.detectClass(H5T_VLEN); + verify_val(in_class, true, "CompType::detectClass() with H5T_VLEN", __LINE__, __FILE__); + + // Make certain that an incorrect class is not detected + in_class = cplx_cmpd.detectClass(H5T_TIME); + verify_val(in_class, false, "CompType::detectClass() with H5T_TIME", __LINE__, __FILE__); + in_class = cplx_cmpd.detectClass(H5T_ENUM); + verify_val(in_class, false, "CompType::detectClass() with H5T_ENUM", __LINE__, __FILE__); + + PASSED(); + } + catch (Exception& E) + { + issue_fail_msg("test_detect_type_class", __LINE__, __FILE__, E.getCDetailMsg()); + } +} + + +/*------------------------------------------------------------------------- + * Function: test_vltype + * + * Purpose Tests VarLenType class + * + * Return None + * + * Programmer Binh-Minh Ribler (use C version) + * August, 2017 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +static void test_vltype() +{ + // Output message about test being performed + SUBTEST("VarLenType functions"); + try + { + VarLenType vltype(PredType::NATIVE_INT); + + bool in_class = vltype.detectClass(H5T_VLEN); + verify_val(in_class, true, "VarLenType::detectClass() with H5T_VLEN", __LINE__, __FILE__); + in_class = vltype.detectClass(H5T_INTEGER); + verify_val(in_class, true, "VarLenType::detectClass() with H5T_INTEGER", __LINE__, __FILE__); + + // Test copy constructor + VarLenType vltype2(vltype); + + // Verify that the copied type has a valid id + bool is_valid = IdComponent::isValid(vltype2.getId()); + verify_val(in_class, true, "isValid on vltype2", __LINE__, __FILE__); + + in_class = vltype2.detectClass(H5T_VLEN); + verify_val(in_class, true, "VarLenType::detectClass() with H5T_VLEN for vltype2", __LINE__, __FILE__); + in_class = vltype2.detectClass(H5T_INTEGER); + verify_val(in_class, true, "VarLenType::detectClass() with H5T_INTEGER for vltype2", __LINE__, __FILE__); + in_class = vltype2.detectClass(H5T_FLOAT); + verify_val(in_class, false, "VarLenType::detectClass() with H5T_FLOAT for vltype2", __LINE__, __FILE__); + + // Create a new file to use in this test + H5File file(FILENAME[3], H5F_ACC_TRUNC); + + // Create a group in the file, to hold some varlentype + Group top_group(file.createGroup("top group")); + + // Create a variable-length type + VarLenType first_vlt(PredType::NATIVE_FLOAT); + + // Commit the type to the group + first_vlt.commit(top_group, "first variable-length type"); + + // Close it + first_vlt.close(); + + // Reopen it + VarLenType first_vlt_again(top_group, "first variable-length type"); + + // Trying to detect H5T_VLEN and H5T_FLOAT classes on this type, + // should both be true + in_class = vltype2.detectClass(H5T_VLEN); + verify_val(in_class, true, "VarLenType::detectClass() with H5T_VLEN for vltype2", __LINE__, __FILE__); + in_class = first_vlt_again.detectClass(H5T_FLOAT); + verify_val(in_class, true, "VarLenType::detectClass() with H5T_FLOAT for first_vlt_again", __LINE__, __FILE__); + + PASSED(); + } // end of try block + catch (Exception& E) + { + issue_fail_msg("test_vltype", __LINE__, __FILE__, E.getCDetailMsg()); + } +} // test_vltype + + +/*------------------------------------------------------------------------- * Function: test_query * * Purpose Tests query functions of compound and enumeration types. @@ -785,6 +1059,8 @@ void test_types() // Test basic datatypes test_classes(); test_copy(); + test_detect_type_class(); + test_vltype(); test_query(); test_transient(); test_named(); -- cgit v0.12