diff options
-rw-r--r-- | c++/src/H5DataType.cpp | 25 | ||||
-rw-r--r-- | c++/src/H5DataType.h | 3 | ||||
-rw-r--r-- | c++/src/H5File.cpp | 19 | ||||
-rw-r--r-- | c++/src/H5File.h | 3 | ||||
-rw-r--r-- | c++/src/H5Group.cpp | 7 | ||||
-rw-r--r-- | c++/src/H5Group.h | 3 | ||||
-rw-r--r-- | c++/src/H5IdComponent.cpp | 21 | ||||
-rw-r--r-- | c++/src/H5IdComponent.h | 3 | ||||
-rw-r--r-- | c++/src/H5Library.cpp | 1 | ||||
-rw-r--r-- | c++/src/H5Location.cpp | 135 | ||||
-rw-r--r-- | c++/src/H5Location.h | 10 | ||||
-rw-r--r-- | c++/src/H5Object.cpp | 2 | ||||
-rw-r--r-- | c++/test/tfile.cpp | 213 | ||||
-rw-r--r-- | c++/test/tlinks.cpp | 49 | ||||
-rw-r--r-- | c++/test/tobject.cpp | 185 | ||||
-rw-r--r-- | c++/test/trefer.cpp | 26 | ||||
-rw-r--r-- | c++/test/ttypes.cpp | 20 |
17 files changed, 661 insertions, 64 deletions
diff --git a/c++/src/H5DataType.cpp b/c++/src/H5DataType.cpp index 84e59e8..679f42f 100644 --- a/c++/src/H5DataType.cpp +++ b/c++/src/H5DataType.cpp @@ -681,6 +681,31 @@ bool DataType::isVariableStr() const } //-------------------------------------------------------------------------- +// Function: DataType::getCreatePlist +///\brief Returns a copy of the property list, which is for datatype +/// creation. +///\return A property list object +///\exception H5::DataTypeIException +// Programmer Binh-Minh Ribler - May, 2017 +// Description +// Currently, there is no datatype creation property list class +// in the C++ API because there is no associated functionality. +//-------------------------------------------------------------------------- +PropList DataType::getCreatePlist() const +{ + hid_t create_plist_id = H5Tget_create_plist(id); + if (create_plist_id < 0) + { + throw DataTypeIException(inMemFunc("getCreatePlist"), + "H5Tget_create_plist returns negative value"); + } + // create and return the DSetCreatPropList object + PropList create_plist; + f_PropList_setId(&create_plist, create_plist_id); + return(create_plist); +} + +//-------------------------------------------------------------------------- // Function: DataType::getId ///\brief Get the id of this datatype ///\return Datatype identifier diff --git a/c++/src/H5DataType.h b/c++/src/H5DataType.h index 1118dcf..ac998ef 100644 --- a/c++/src/H5DataType.h +++ b/c++/src/H5DataType.h @@ -111,6 +111,9 @@ class H5_DLLCPP DataType : public H5Object { // Checks whether this datatype is a variable-length string. bool isVariableStr() const; + // Returns a copy of the creation property list of a datatype. + PropList getCreatePlist() const; + ///\brief Returns this class name. virtual H5std_string fromClass () const { return("DataType"); } diff --git a/c++/src/H5File.cpp b/c++/src/H5File.cpp index 4d7177a..e84717c 100644 --- a/c++/src/H5File.cpp +++ b/c++/src/H5File.cpp @@ -349,6 +349,25 @@ FileAccPropList H5File::getAccessPlist() const } //-------------------------------------------------------------------------- +// Function: H5File::getFileInfo +///\brief Retrieves the general information of this file. +/// +///\exception H5::FileIException +///\par Description +/// The retrieved information may include information about +/// superblock extension, free space management, and shared object +// Programmer Binh-Minh Ribler - May 2017 +//-------------------------------------------------------------------------- +void H5File::getFileInfo(H5F_info_t& file_info) const +{ + herr_t ret_value = H5Fget_info(id, &file_info); + if (ret_value < 0) + { + throw FileIException("H5File::getFileInfo", "H5Fget_info failed"); + } +} + +//-------------------------------------------------------------------------- // Function: H5File::getFreeSpace ///\brief Returns the amount of free space in the file. ///\return Amount of free space diff --git a/c++/src/H5File.h b/c++/src/H5File.h index e06a942..06c4edc 100644 --- a/c++/src/H5File.h +++ b/c++/src/H5File.h @@ -54,6 +54,9 @@ class H5_DLLCPP H5File : public Group { // Gets the creation property list of this file. FileCreatPropList getCreatePlist() const; + // Gets general information about this file. + void getFileInfo(H5F_info_t& file_info) const; + // Retrieves the file size of an opened file. hsize_t getFileSize() const; diff --git a/c++/src/H5Group.cpp b/c++/src/H5Group.cpp index a5d052c..07e76a2 100644 --- a/c++/src/H5Group.cpp +++ b/c++/src/H5Group.cpp @@ -105,11 +105,16 @@ Group::Group(const H5Location& loc, const void* ref, H5R_type_t ref_type) : H5Ob ///\param ref_type - IN: Reference type - default to H5R_OBJECT ///\exception H5::ReferenceException // Programmer Binh-Minh Ribler - Oct, 2006 +// Modification +// May, 2017 +// Removed in 1.8.19 because H5Location is Attribute's baseclass +// now. -BMR //-------------------------------------------------------------------------- -Group::Group(const Attribute& attr, const void* ref, H5R_type_t ref_type) : H5Object(), id(H5I_INVALID_HID) +/*Group::Group(const Attribute& attr, const void* ref, H5R_type_t ref_type) : H5Object(), id(H5I_INVALID_HID) { id = H5Location::p_dereference(attr.getId(), ref, ref_type, "constructor - by dereference"); } +*/ //-------------------------------------------------------------------------- // Function: Group::getId diff --git a/c++/src/H5Group.h b/c++/src/H5Group.h index 0d26b27..c01652b 100644 --- a/c++/src/H5Group.h +++ b/c++/src/H5Group.h @@ -39,7 +39,8 @@ class H5_DLLCPP Group : public H5Object, public CommonFG { // Creates a group by way of dereference. Group(const H5Location& loc, const void* ref, H5R_type_t ref_type = H5R_OBJECT); - Group(const Attribute& attr, const void* ref, H5R_type_t ref_type = H5R_OBJECT); + // Removed in 1.8.19, because H5Location is baseclass + //Group(const Attribute& attr, const void* ref, H5R_type_t ref_type = H5R_OBJECT); // default constructor Group(); diff --git a/c++/src/H5IdComponent.cpp b/c++/src/H5IdComponent.cpp index 7054369..a8e8ba4 100644 --- a/c++/src/H5IdComponent.cpp +++ b/c++/src/H5IdComponent.cpp @@ -163,6 +163,27 @@ H5I_type_t IdComponent::getHDFObjType() const } //-------------------------------------------------------------------------- +// Function: isValid (static) +///\brief Checks if the given ID is valid. +///\return true if the given identifier is valid, and false, otherwise. +///\par Description +/// A valid ID is one that is in use and has an application +/// reference count of at least 1. +// Programmer Binh-Minh Ribler - Mar 1, 2017 +//-------------------------------------------------------------------------- +bool IdComponent::isValid(hid_t an_id) +{ + // Call C function + htri_t ret_value = H5Iis_valid(an_id); + if (ret_value > 0) + return true; + else if (ret_value == 0) + return false; + else // Raise exception when H5Iis_valid returns a negative value + throw IdComponentException("isValid", "H5Iis_valid failed"); +} + +//-------------------------------------------------------------------------- // 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 e9d0c84..1ada605 100644 --- a/c++/src/H5IdComponent.h +++ b/c++/src/H5IdComponent.h @@ -47,6 +47,9 @@ class H5_DLLCPP IdComponent { // Returns an HDF5 object type of this object. H5I_type_t getHDFObjType() const; + // Checks if the given ID is valid. + static bool isValid(hid_t an_id); + // Assignment operator. IdComponent& operator=(const IdComponent& rhs); diff --git a/c++/src/H5Library.cpp b/c++/src/H5Library.cpp index 7adc508..3e656e5 100644 --- a/c++/src/H5Library.cpp +++ b/c++/src/H5Library.cpp @@ -27,7 +27,6 @@ #include "H5DcreatProp.h" #include "H5DxferProp.h" #include "H5LaccProp.h" -#include "H5LaccProp.h" #include "H5Location.h" #include "H5Object.h" #include "H5DataType.h" diff --git a/c++/src/H5Location.cpp b/c++/src/H5Location.cpp index f10ad0d..ec57a5c 100644 --- a/c++/src/H5Location.cpp +++ b/c++/src/H5Location.cpp @@ -65,7 +65,7 @@ H5Location::H5Location() : IdComponent() {} // been moved to the sub-classes. It will be removed in 1.10 release. If its // removal does not raise any problems in 1.10, it will be removed from 1.8 in // subsequent releases. -// Removed in 1.10.1 - Aug 2016 +// Removed in 1.8.18 and 1.10.1 - Aug 2016 //-------------------------------------------------------------------------- // H5Location::H5Location(const hid_t object_id) : IdComponent() {} @@ -251,23 +251,6 @@ int H5Location::iterateAttrs(attr_operator_t user_op, unsigned *_idx, void *op_d } //-------------------------------------------------------------------------- -// Function: H5Location::getNumAttrs -///\brief Deprecated - Returns the number of attributes attached to this HDF5 object. -///\return Number of attributes -///\exception H5::AttributeIException -// Programmer Binh-Minh Ribler - 2000 -//-------------------------------------------------------------------------- -int H5Location::getNumAttrs() const -{ - H5O_info_t oinfo; /* Object info */ - - if(H5Oget_info(getId(), &oinfo) < 0) - throw AttributeIException(inMemFunc("getNumAttrs"), "H5Oget_info failed"); - else - return(static_cast<int>(oinfo.num_attrs)); -} - -//-------------------------------------------------------------------------- // Function: H5Location::attrExists ///\brief Deprecated - Checks whether the named attribute exists at this location. ///\param name - IN: Name of the attribute to be queried @@ -346,6 +329,8 @@ void H5Location::renameAttr(const char* oldname, const char* newname) const ///\brief Deprecated - This is an overloaded member function, provided for convenience. /// It differs from the above function in that it takes /// a reference to an \c H5std_string for the names. +/// +///\exception H5::AttributeIException // Programmer Binh-Minh Ribler - Mar, 2005 //-------------------------------------------------------------------------- void H5Location::renameAttr(const H5std_string& oldname, const H5std_string& newname) const @@ -354,6 +339,23 @@ void H5Location::renameAttr(const H5std_string& oldname, const H5std_string& new } //-------------------------------------------------------------------------- +// Function: H5Location::getNumAttrs +///\brief Returns the number of attributes attached to this HDF5 object. +///\return Number of attributes +///\exception H5::AttributeIException +// Programmer Binh-Minh Ribler - 2000 +//-------------------------------------------------------------------------- +int H5Location::getNumAttrs() const +{ + H5O_info_t oinfo; /* Object info */ + + if(H5Oget_info(getId(), &oinfo) < 0) + throw AttributeIException(inMemFunc("getNumAttrs"), "H5Oget_info failed"); + else + return(static_cast<int>(oinfo.num_attrs)); +} + +//-------------------------------------------------------------------------- // Function: H5Location::nameExists ///\brief Checks if a link of a given name exists in a location ///\param name - IN: Searched name @@ -396,7 +398,7 @@ bool H5Location::nameExists(const H5std_string& name, const LinkAccPropList& lap /// 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 @@ -431,6 +433,39 @@ H5std_string H5Location::getFileName() const } //-------------------------------------------------------------------------- +// Function: H5Location::objVersion +///\brief Returns the header version of this HDF5 object. +///\return Object version, which can have the following values: +/// \li \c H5O_VERSION_1 +/// \li \c H5O_VERSION_2 +///\exception H5::LocationException +/// Exception will be thrown when: +/// - an error returned by the C API +/// - version number is not one of the valid values above +// Programmer Binh-Minh Ribler - May, 2017 +//-------------------------------------------------------------------------- +unsigned H5Location::objVersion() const +{ + H5O_info_t objinfo; + unsigned version = 0; + + // Use C API to get information of the object + herr_t ret_value = H5Oget_info(getId(), &objinfo); + + // Throw exception if C API returns failure + if (ret_value < 0) + throw LocationException(inMemFunc("objVersion"), "H5Oget_info failed"); + // Return a valid version or throw an exception for invalid value + else + { + version = objinfo.hdr.version; + if (version != H5O_VERSION_1 && version != H5O_VERSION_2) + throw LocationException(inMemFunc("objVersion"), "Invalid version for object"); + } + return(version); +} + +//-------------------------------------------------------------------------- // Function: H5Location::setComment ///\brief Sets or resets the comment for an object specified by its name. ///\param name - IN: Name of the object @@ -551,7 +586,7 @@ ssize_t H5Location::getComment(const char* name, size_t buf_size, char* comment) // If H5Oget_comment_by_name returns a negative value, raise an exception if (comment_len < 0) { - throw LocationException("H5Location::getComment", "H5Oget_comment_by_name failed"); + throw LocationException(inMemFunc("getComment"), "H5Oget_comment_by_name failed"); } // If the comment is longer than the provided buffer size, the C library // will not null terminate it @@ -584,7 +619,7 @@ H5std_string H5Location::getComment(const char* name, size_t buf_size) const // If H5Oget_comment_by_name returns a negative value, raise an exception if (comment_len < 0) { - throw LocationException("H5Location::getComment", "H5Oget_comment_by_name failed"); + throw LocationException(inMemFunc("getComment"), "H5Oget_comment_by_name failed"); } // If comment exists, calls C routine again to get it @@ -605,7 +640,7 @@ H5std_string H5Location::getComment(const char* name, size_t buf_size) const if (temp_len < 0) { delete []comment_C; - throw LocationException("H5Location::getComment", "H5Oget_comment_by_name failed"); + throw LocationException(inMemFunc("getComment"), "H5Oget_comment_by_name failed"); } // Convert the C comment to return @@ -630,6 +665,61 @@ H5std_string H5Location::getComment(const H5std_string& name, size_t buf_size) c { return(getComment(name.c_str(), buf_size)); } + +//-------------------------------------------------------------------------- +// Function: H5Location::openObjId +///\brief Opens an object without knowing the object type. +///\param obj_name - IN: Path to the object +///\param lapl - IN: Access property list for the link pointing +/// to the object +///\exception H5::LocationException +///\par Description +/// This function opens an object at this location, using +/// H5Oopen. Thus, an object can be opened without knowing +/// the object's type. +// Programmer Binh-Minh Ribler - May, 2017 +//-------------------------------------------------------------------------- +hid_t H5Location::openObjId(const char* obj_name, const LinkAccPropList& lapl) const +{ + hid_t ret_value = H5Oopen(getId(), obj_name, lapl.getId()); + if (ret_value < 0) + { + throw LocationException(inMemFunc("openObjId"), "H5Oopen failed"); + } + return(ret_value); +} + +//-------------------------------------------------------------------------- +// Function: H5Location::openObjId +///\brief This is an overloaded member function, provided for convenience. +/// It takes a reference to a \c H5std_string for the object's path. +///\param obj_name - IN: Path to the object +///\param lapl - IN: Access property list for the link pointing to +/// the object +///\exception H5::LocationException +// Programmer Binh-Minh Ribler - May, 2017 +//-------------------------------------------------------------------------- +hid_t H5Location::openObjId(const H5std_string& obj_name, const LinkAccPropList& lapl) const +{ + return(openObjId(obj_name.c_str(), lapl)); +} + +//-------------------------------------------------------------------------- +// Function: H5Location::closeObjId +///\brief Closes an object, which was opened with H5Location::openObjId +/// +///\exception H5::LocationException +// Programmer Binh-Minh Ribler - May, 2017 +//-------------------------------------------------------------------------- +void H5Location::closeObjId(hid_t obj_id) const +{ + herr_t ret_value = H5Oclose(obj_id); + if (ret_value < 0) + { + throw LocationException(inMemFunc("closeObjId"), "H5Oclose failed"); + } +} + #ifndef DOXYGEN_SHOULD_SKIP_THIS //-------------------------------------------------------------------------- @@ -958,7 +1048,6 @@ DataSpace H5Location::getRegion(void *ref, H5R_type_t ref_type) const } } - //-------------------------------------------------------------------------- // Function: H5Location destructor ///\brief Noop destructor. diff --git a/c++/src/H5Location.h b/c++/src/H5Location.h index 11f8f87..d202328 100644 --- a/c++/src/H5Location.h +++ b/c++/src/H5Location.h @@ -95,6 +95,9 @@ class H5_DLLCPP H5Location : public IdComponent { virtual void removeAttr(const char* name) const; virtual void removeAttr(const H5std_string& name) const; + // Returns the object header version of an object + unsigned objVersion() const; + // Sets the comment for an HDF5 object specified by its name. void setComment(const char* name, const char* comment) const; void setComment(const H5std_string& name, const H5std_string& comment) const; @@ -129,6 +132,13 @@ class H5_DLLCPP H5Location : public IdComponent { // Retrieves a dataspace with the region pointed to selected. DataSpace getRegion(void *ref, H5R_type_t ref_type = H5R_DATASET_REGION) const; + // Opens an object at this location, without knowing the object type. + hid_t openObjId(const char* name, const LinkAccPropList& lapl = LinkAccPropList::DEFAULT) const; + hid_t openObjId(const H5std_string& name, const LinkAccPropList& lapl = LinkAccPropList::DEFAULT) const; + + // Closes an object opened by openObjId(). + void closeObjId(hid_t obj_id) const; + ///\brief Returns an identifier. (pure virtual) virtual hid_t getId() const = 0; diff --git a/c++/src/H5Object.cpp b/c++/src/H5Object.cpp index 91d0f82..2e67e6e 100644 --- a/c++/src/H5Object.cpp +++ b/c++/src/H5Object.cpp @@ -48,7 +48,7 @@ H5Object::H5Object() : H5Location() {} // been moved to the sub-classes. It will be removed in 1.10 release. If its // removal does not raise any problems in 1.10, it will be removed from 1.8 in // subsequent releases. -// Removed in 1.10.1 - Aug 2016 +// Removed in 1.8.18 and 1.10.1 - Aug 2016 //-------------------------------------------------------------------------- //H5Object::H5Object(const hid_t object_id) : H5Location() {} diff --git a/c++/test/tfile.cpp b/c++/test/tfile.cpp index 6e12dfd..de62cf5 100644 --- a/c++/test/tfile.cpp +++ b/c++/test/tfile.cpp @@ -28,13 +28,10 @@ #else #include <iostream> #endif -#include <string> - -#ifndef H5_NO_STD - using std::cerr; - using std::endl; -#endif // H5_NO_STD +using std::cerr; +using std::endl; +#include <string> #include "H5Cpp.h" // C++ API header file using namespace H5; @@ -52,6 +49,7 @@ const size_t F2_OFFSET_SIZE = 8; const size_t F2_LENGTH_SIZE = 8; const unsigned F2_SYM_LEAF_K = 8; const unsigned F2_SYM_INTERN_K = 32; +const unsigned F2_ISTORE = 64; const H5std_string FILE2("tfile2.h5"); const hsize_t F3_USERBLOCK_SIZE = (hsize_t)0; @@ -510,15 +508,13 @@ static void test_file_name() } // test_file_name() -#define NUM_OBJS 4 -#define NUM_ATTRS 3 const int RANK1 = 1; const int ATTR1_DIM1 = 3; const H5std_string FILE5("tfattrs.h5"); const H5std_string FATTR1_NAME ("file attribute 1"); const H5std_string FATTR2_NAME ("file attribute 2"); -int fattr_data[ATTR1_DIM1]={512,-234,98123}; /* Test data for file attribute */ -int dattr_data[ATTR1_DIM1]={256,-123,1000}; /* Test data for dataset attribute */ +int fattr_data[ATTR1_DIM1]={512,-234,98123}; // Test data for file attribute +int dattr_data[ATTR1_DIM1]={256,-123,1000}; // Test data for dataset attribute static void test_file_attribute() { @@ -691,8 +687,8 @@ static void test_libver_bounds_real( */ Group group = file.createGroup(GROUP1); - obj_version = file.childObjVersion(GROUP1); - verify_val(obj_version, oh_vers_mod, "H5File::childObjVersion", __LINE__, __FILE__); + obj_version = group.objVersion(); + verify_val(obj_version, oh_vers_mod, "Group::objVersion", __LINE__, __FILE__); group.close(); // close "/G1" @@ -702,8 +698,8 @@ static void test_libver_bounds_real( */ group = file.createGroup(SUBGROUP3); - obj_version = group.childObjVersion(SUBGROUP3); - verify_val(obj_version, oh_vers_mod, "H5File::childObjVersion", __LINE__, __FILE__); + obj_version = group.objVersion(); + verify_val(obj_version, oh_vers_mod, "Group::objVersion", __LINE__, __FILE__); group.close(); // close "/G1/G3" @@ -747,15 +743,175 @@ static void test_libver_bounds() test_libver_bounds_real(H5F_LIBVER_LATEST, H5O_VERSION_2, H5F_LIBVER_EARLIEST, H5O_VERSION_1); PASSED(); } /* end test_libver_bounds() */ + + +/*------------------------------------------------------------------------- + * Function: test_commonfg + * + * Purpose Verify that H5File works as a root group. + * + * Return None + * + * Programmer Binh-Minh Ribler (use C version) + * March, 2015 + * + *------------------------------------------------------------------------- + */ +static void test_commonfg() +{ + // Output message about test being performed + SUBTEST("Root group"); + + try { + // Create a file using default properties. + H5File file4(FILE4, H5F_ACC_TRUNC); + + // Try opening the root group. + Group rootgroup(file4.openGroup(ROOTGROUP)); + + // Create a group in the root group. + Group group(rootgroup.createGroup(GROUPNAME, 0)); + + // Create the data space. + hsize_t dims[RANK] = {NX, NY}; + DataSpace space(RANK, dims); + + // Create a new dataset. + DataSet dataset(group.createDataSet (DSETNAME, PredType::NATIVE_INT, space)); + + // Get and verify file name via a dataset. + H5std_string file_name = dataset.getFileName(); + verify_val(file_name, FILE4, "DataSet::getFileName", __LINE__, __FILE__); + + // Create an attribute for the dataset. + Attribute attr(dataset.createAttribute(DATTRNAME, PredType::NATIVE_INT, space)); + + // Get and verify file name via an attribute. + file_name = attr.getFileName(); + verify_val(file_name, FILE4, "Attribute::getFileName", __LINE__, __FILE__); + + // Create an attribute for the file via root group. + Attribute rootg_attr(rootgroup.createAttribute(FATTRNAME, PredType::NATIVE_INT, space)); + + // Get and verify file name via an attribute. + file_name = attr.getFileName(); + verify_val(file_name, FILE4, "Attribute::getFileName", __LINE__, __FILE__); + + PASSED(); + } // end of try block + + catch (Exception& E) + { + issue_fail_msg("test_commonfg()", __LINE__, __FILE__, E.getCDetailMsg()); + } + +} /* end test_commonfg() */ + + +const H5std_string FILE7("tfile7.h5"); + +/*------------------------------------------------------------------------- + * Function: test_file_info + * + * Purpose Verify that various properties in a file creation property + * lists are stored correctly in the file and can be retrieved + * when the file is re-opened. + * + * Return None + * + * Programmer Binh-Minh Ribler + * February, 2017 + * + *------------------------------------------------------------------------- + */ +const hsize_t FSP_SIZE_DEF = 4096; +const hsize_t FSP_SIZE512 = 512; +static void test_file_info() +{ + // Output message about test being performed + SUBTEST("File general information"); + + hsize_t out_threshold = 0; // Free space section threshold to get + hbool_t out_persist = FALSE;// Persist free-space read + + try { + // Create a file using default properties. + H5File tempfile(FILE7, H5F_ACC_TRUNC); + + // Get the file's version information. + H5F_info_t finfo; + tempfile.getFileInfo(finfo); // there's no C test for H5Fget_info + + // Close the file. + tempfile.close(); + + // Create file creation property list. + FileCreatPropList fcpl; + + // Set various file information. + fcpl.setUserblock(F2_USERBLOCK_SIZE); + fcpl.setSizes(F2_OFFSET_SIZE, F2_LENGTH_SIZE); + fcpl.setSymk(F2_SYM_INTERN_K, F2_SYM_LEAF_K); + fcpl.setIstorek(F2_ISTORE); + + // Creating a file with the non-default file creation property list + // should create a version 1 superblock + + // Create file with custom file creation property list. + H5File file7(FILE7, H5F_ACC_TRUNC, fcpl); + + // Close the file creation property list. + fcpl.close(); + + // Get the file's version information. + file7.getFileInfo(finfo); // there's no C test for H5Fget_info + + // Close the file. + file7.close(); + + // Re-open the file. + file7.openFile(FILE7, H5F_ACC_RDONLY); + + // Get the file's creation property list. + FileCreatPropList fcpl2 = file7.getCreatePlist(); + + // Get the file's version information. + file7.getFileInfo(finfo); // there's no C test for H5Fget_info + + // Retrieve the property values & check them. + hsize_t userblock = fcpl2.getUserblock(); + verify_val(userblock, F2_USERBLOCK_SIZE, "FileCreatPropList::getUserblock", __LINE__, __FILE__); + + size_t off_size = 0, len_size = 0; + fcpl2.getSizes(off_size, len_size); + verify_val(off_size, F2_OFFSET_SIZE, "FileCreatPropList::getSizes", __LINE__, __FILE__); + verify_val(len_size, F2_LENGTH_SIZE, "FileCreatPropList::getSizes", __LINE__, __FILE__); + + unsigned sym_ik = 0, sym_lk = 0; + fcpl2.getSymk(sym_ik, sym_lk); + verify_val(sym_ik, F2_SYM_INTERN_K, "FileCreatPropList::getSymk", __LINE__, __FILE__); + verify_val(sym_lk, F2_SYM_LEAF_K, "FileCreatPropList::getSymk", __LINE__, __FILE__); + + unsigned istore_ik = fcpl2.getIstorek(); + verify_val(istore_ik, F2_ISTORE, "FileCreatPropList::getIstorek", __LINE__, __FILE__); + + PASSED(); + } // end of try block + catch (Exception& E) + { + issue_fail_msg("test_filespace_info()", __LINE__, __FILE__, E.getCDetailMsg()); + } +} /* test_file_info() */ + /*------------------------------------------------------------------------- * Function: test_file * - * Purpose: Main file testing routine + * Purpose Main file testing routine * - * Return: None + * Return None * - * Programmer: Binh-Minh Ribler (use C version) + * Programmer Binh-Minh Ribler (use C version) * January 2001 * * Modifications: @@ -768,29 +924,33 @@ void test_file() // Output message about test being performed MESSAGE(5, ("Testing File I/O Operations\n")); - test_file_create(); // Test file creation (also creation templates) - test_file_open(); // Test file opening - test_file_size(); // Test file size - test_file_name(); // Test getting file's name - test_file_attribute(); // Test file attribute feature - test_libver_bounds(); // Test format version + test_file_create(); // Test file creation (also creation templates) + test_file_open(); // Test file opening + test_file_size(); // Test file size + test_file_name(); // Test getting file's name + test_file_attribute(); // Test file attribute feature + test_libver_bounds(); // Test format version + test_commonfg(); // Test H5File as a root group + test_file_info(); // Test various file info } // test_file() /*------------------------------------------------------------------------- * Function: cleanup_file * - * Purpose: Cleanup temporary test files + * Purpose Cleanup temporary test files * - * Return: none + * Return none * - * Programmer: (use C version) + * Programmer (use C version) * * Modifications: * *------------------------------------------------------------------------- */ +#ifdef __cplusplus extern "C" +#endif void cleanup_file() { HDremove(FILE1.c_str()); @@ -799,4 +959,5 @@ void cleanup_file() HDremove(FILE4.c_str()); HDremove(FILE5.c_str()); HDremove(FILE6.c_str()); + HDremove(FILE7.c_str()); } // cleanup_file diff --git a/c++/test/tlinks.cpp b/c++/test/tlinks.cpp index 0786bb5..58dd63a 100644 --- a/c++/test/tlinks.cpp +++ b/c++/test/tlinks.cpp @@ -441,7 +441,55 @@ static void test_basic_links(hid_t fapl_id, hbool_t new_format) issue_fail_msg("test_basic_links()", __LINE__, __FILE__, E.getCDetailMsg()); } } + +/*------------------------------------------------------------------------- + * Function: test_num_links + * + * Purpose Test setting and getting limit of number of links + * + * Return Success: 0 + * + * Failure: -1 + * + * Programmer Binh-Minh Ribler + * Mar, 2017 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +static void test_num_links(hid_t fapl_id, hbool_t new_format) +{ + char filename[NAME_BUF_SIZE]; + + if(new_format) + SUBTEST("Setting number of links (w/new group format)") + else + SUBTEST("Setting number of links") + try + { + // Use the file access template id to create a file access prop. list. + FileAccPropList fapl(fapl_id); + + h5_fixname(FILENAME[0], fapl_id, filename, sizeof filename); + H5File file(filename, H5F_ACC_RDWR, FileCreatPropList::DEFAULT, fapl); + + LinkAccPropList lapl; + size_t nlinks = 5; + lapl.setNumLinks(nlinks); + + // Read it back and verify + size_t read_nlinks = lapl.getNumLinks(); + verify_val(read_nlinks, nlinks, "LinkAccPropList::setNumLinks", __LINE__, __FILE__); + + PASSED(); + } // end of try block + catch (Exception& E) + { + issue_fail_msg("test_num_links()", __LINE__, __FILE__, E.getCDetailMsg()); + } +} // test_num_links /*------------------------------------------------------------------------- * Function: test_links @@ -494,6 +542,7 @@ void test_links() /* General tests... (on both old & new format groups */ // FileAccPropList may be passed in instead of fapl id test_basic_links(my_fapl_id, new_format); + test_num_links(my_fapl_id, new_format); #if 0 // these tests are from the C test links.c and left here for future // implementation of H5L API diff --git a/c++/test/tobject.cpp b/c++/test/tobject.cpp index 2639092..10012fc 100644 --- a/c++/test/tobject.cpp +++ b/c++/test/tobject.cpp @@ -37,6 +37,7 @@ using namespace H5; #include "h5cpputil.h" // C++ utilility header file const H5std_string FILE_OBJECTS("tobjects.h5"); +const H5std_string FILE_OBJHDR("tobject_header.h5"); const H5std_string GROUP1("Top Group"); const H5std_string GROUP1_PATH("/Top Group"); const H5std_string GROUP1_1("Sub-Group 1.1"); @@ -267,25 +268,25 @@ static void test_get_objtype() // Get and verify object type with // H5O_type_t childObjType(const H5std_string& objname) H5O_type_t objtype = file.childObjType(DSET_IN_FILE); - verify_val(objtype, H5O_TYPE_DATASET, "DataSet::childObjType", __LINE__, __FILE__); + verify_val(objtype, H5O_TYPE_DATASET, "H5File::childObjType", __LINE__, __FILE__); // Get and verify object type with // H5O_type_t childObjType(const char* objname) objtype = grp1.childObjType(GROUP1_1.c_str()); - verify_val(objtype, H5O_TYPE_GROUP, "DataSet::childObjType", __LINE__, __FILE__); + verify_val(objtype, H5O_TYPE_GROUP, "Group::childObjType", __LINE__, __FILE__); // Get and verify object type with // H5O_type_t childObjType(hsize_t index, H5_index_t index_type, // H5_iter_order_t order, const char* objname=".") objtype = grp1.childObjType((hsize_t)1, H5_INDEX_NAME, H5_ITER_INC); - verify_val(objtype, H5O_TYPE_NAMED_DATATYPE, "DataSet::childObjType", __LINE__, __FILE__); + verify_val(objtype, H5O_TYPE_NAMED_DATATYPE, "Group::childObjType", __LINE__, __FILE__); // Get and verify object type with // H5O_type_t childObjType(hsize_t index, // H5_index_t index_type=H5_INDEX_NAME, // H5_iter_order_t order=H5_ITER_INC, const char* objname=".") objtype = grp1.childObjType((hsize_t)2); - verify_val(objtype, H5O_TYPE_GROUP, "DataSet::childObjType", __LINE__, __FILE__); + verify_val(objtype, H5O_TYPE_GROUP, "Group::childObjType", __LINE__, __FILE__); // Everything will be closed as they go out of scope @@ -298,6 +299,180 @@ static void test_get_objtype() issue_fail_msg("test_get_objtype", __LINE__, __FILE__); } } // test_get_objtype + +/*------------------------------------------------------------------------- + * Function: test_open_object_header + * + * Purpose Test H5Location::openObjId function. + * + * Return None + * + * Programmer Binh-Minh Ribler (use C version) + * May 15, 2017 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +const H5std_string GROUPNAME("group"); +const H5std_string DTYPENAME("group/datatype"); +const H5std_string DTYPENAME_INGRP("datatype"); +const H5std_string DSETNAME("dataset"); +#define RANK 2 +#define DIM0 5 +#define DIM1 10 +static void test_open_object_header() +{ + hsize_t dims[2]; + H5G_info_t ginfo; /* Group info struct */ + + // Output message about test being performed + SUBTEST("H5Location::openObjId and H5Location::closeObjId"); + + try { + // Create file FILE1 + H5File file1(FILE_OBJHDR, H5F_ACC_TRUNC); + /* Create a group, dataset, and committed datatype within the file */ + + // Create a group in the root group + Group grp(file1.createGroup(GROUPNAME)); + grp.close(); + + // Commit the type inside the file + IntType dtype(PredType::NATIVE_INT); + dtype.commit(file1, DTYPENAME); + dtype.close(); + + // Create a new dataset + dims[0] = DIM0; + dims[1] = DIM1; + DataSpace dspace(RANK, dims); + DataSet dset(file1.createDataSet(DSETNAME, PredType::NATIVE_INT, dspace)); + + // Close dataset and dataspace + dset.close(); + dspace.close(); + + // Now make sure that openObjId can open all three types of objects + hid_t obj_grp = file1.openObjId(GROUPNAME); + hid_t obj_dtype = file1.openObjId(DTYPENAME); + hid_t obj_dset = file1.openObjId(DSETNAME); + + // Make sure that each is the right kind of ID + H5I_type_t id_type = IdComponent::getHDFObjType(obj_grp); + verify_val(id_type, H5I_GROUP, "H5Iget_type for group ID", __LINE__, __FILE__); + id_type = IdComponent::getHDFObjType(obj_dtype); + verify_val(id_type, H5I_DATATYPE, "H5Iget_type for datatype ID", __LINE__, __FILE__); + id_type = IdComponent::getHDFObjType(obj_dset); + verify_val(id_type, H5I_DATASET, "H5Iget_type for dataset ID", __LINE__, __FILE__); + + /* Do something more complex with each of the IDs to make sure */ + + Group grp2(obj_grp); + hsize_t num_objs = grp2.getNumObjs(); + verify_val(num_objs, 1, "H5Gget_info", __LINE__, __FILE__); + // There should be one object, the datatype + + // Close datatype object opened from the file + file1.closeObjId(obj_dtype); + + dset.setId(obj_dset); + dspace = dset.getSpace(); + bool is_simple = dspace.isSimple(); + dspace.close(); + + // Open datatype object from the group + obj_dtype = grp2.openObjId(DTYPENAME_INGRP); + + dtype.setId(obj_dtype); + H5T_class_t type_class = dtype.getClass(); + verify_val(type_class, H5T_INTEGER, "H5Tget_class", __LINE__, __FILE__); + dtype.close(); + + // Close datatype object + grp2.closeObjId(obj_dtype); + + // Close the group object + file1.closeObjId(obj_grp); + + // Try doing something with group, the ID should still work + num_objs = grp2.getNumObjs(); + verify_val(num_objs, 1, "H5Gget_info", __LINE__, __FILE__); + + // Close the cloned group + grp2.close(); + + PASSED(); + } // end of try block + // catch invalid action exception + catch (InvalidActionException& E) + { + cerr << " in InvalidActionException" << endl; + cerr << " *FAILED*" << endl; + cerr << " <<< " << E.getDetailMsg() << " >>>" << endl << endl; + } + // catch all other exceptions + catch (Exception& E) + { + cerr << " in Exception" << endl; + issue_fail_msg("test_file_name()", __LINE__, __FILE__, E.getCDetailMsg()); + } +} /* test_open_object_header() */ + +/*------------------------------------------------------------------------- + * Function: test_is_valid + * + * Purpose: Tests validating IDs. + * + * Return: Success: 0 + * Failure: -1 + * + * Programmer: Binh-Minh Ribler + * May 15, 2017 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +static void test_is_valid() +{ + SUBTEST("IdComponent::isValid"); + + try { + // Create a datatype + IntType int1(PredType::NATIVE_INT); + + // Check that the ID is valid + hid_t int1_id = int1.getId(); + bool is_valid = IdComponent::isValid(int1_id); + verify_val(is_valid, true, "IdComponent::isValid", __LINE__, __FILE__); + + // Create another datatype + FloatType float1(PredType::NATIVE_FLOAT); + + // Check that the ID is valid + is_valid = IdComponent::isValid(float1.getId()); + verify_val(is_valid, true, "IdComponent::isValid", __LINE__, __FILE__); + + // Close the integer type, then check the id, it should no longer be valid + int1.close(); + is_valid = IdComponent::isValid(int1_id); + verify_val(is_valid, false, "IdComponent::isValid", __LINE__, __FILE__); + + // Check that an id of -1 is invalid + is_valid = IdComponent::isValid((hid_t)-1); + verify_val(is_valid, false, "IdComponent::isValid", __LINE__, __FILE__); + + PASSED(); + } // try block + + // catch all other exceptions + catch (Exception& E) + { + cerr << " in catch " << endl; + issue_fail_msg("test_get_objtype", __LINE__, __FILE__, E.getCDetailMsg()); + } +} // test_is_valid /*------------------------------------------------------------------------- * Function: test_objects @@ -323,6 +498,8 @@ void test_object() test_get_objname(); // Test get object name from groups/datasets test_get_objname_ontypes(); // Test get object name from types test_get_objtype(); // Test get object type + test_is_valid(); // Test validating IDs + test_open_object_header(); // Test object header functions (H5O) } // test_objects diff --git a/c++/test/trefer.cpp b/c++/test/trefer.cpp index b4efe40..deb664c 100644 --- a/c++/test/trefer.cpp +++ b/c++/test/trefer.cpp @@ -383,6 +383,7 @@ static void test_reference_obj(void) #define GROUPNAME3 "group3" #define DSETNAME "/dset" #define DSETNAME2 "dset2" +#define ATTRNAME "some attribute" #define NAME_SIZE 16 static void @@ -434,7 +435,6 @@ test_reference_group(void) // Close resources dset2.close(); - sid1.close(); file1->close(); /* @@ -450,9 +450,15 @@ test_reference_group(void) // Read in the reference dset1.read(&rref, PredType::STD_REF_OBJ); - // Dereference to get the group + // Create an attribute for the dataset + Attribute ds_attr1 = dset1.createAttribute(ATTRNAME, PredType::NATIVE_INT, sid1); + + // Dereference to get the group using constructor, with dataset as loc Group refgroup(dset1, &rref); + // Dereference to get the group using constructor, with attribute as loc + Group attrrefgroup(ds_attr1, &rref); + // Dereference group object the other way group.dereference(dset1, &rref); @@ -464,14 +470,22 @@ test_reference_group(void) hsize_t nobjs = refgroup.getNumObjs(); verify_val(nobjs, (hsize_t)3, "H5Group::getNumObjs",__LINE__,__FILE__); - // Check number of objects in the group dereferenced by ::reference - nobjs = group.getNumObjs(); + // Check getting file name given the group dereferenced via constructor + H5std_string fname = refgroup.getFileName(); + verify_val(fname, FILE1, "H5Group::getFileName",__LINE__,__FILE__); + + // Check number of objects in the group dereferenced by constructor + nobjs = attrrefgroup.getNumObjs(); verify_val(nobjs, (hsize_t)3, "H5Group::getNumObjs",__LINE__,__FILE__); // Check getting file name given the group dereferenced via constructor - H5std_string fname = refgroup.getFileName(); + fname = attrrefgroup.getFileName(); verify_val(fname, FILE1, "H5Group::getFileName",__LINE__,__FILE__); + // Check number of objects in the group dereferenced by ::reference + nobjs = group.getNumObjs(); + verify_val(nobjs, (hsize_t)3, "H5Group::getNumObjs",__LINE__,__FILE__); + // Check getting file name given the group dereferenced by ::reference fname = group.getFileName(); verify_val(fname, FILE1, "H5Group::getFileName",__LINE__,__FILE__); @@ -484,7 +498,9 @@ test_reference_group(void) // Close resources group.close(); refgroup.close(); + attrrefgroup.close(); dset1.close(); + sid1.close(); file1->close(); PASSED(); diff --git a/c++/test/ttypes.cpp b/c++/test/ttypes.cpp index 9da05e6..384e913 100644 --- a/c++/test/ttypes.cpp +++ b/c++/test/ttypes.cpp @@ -248,12 +248,28 @@ static void test_query() index = tid2.getMemberIndex("ORANGE"); verify_val(index, 3, "EnumType::getMemberIndex()", __LINE__, __FILE__); - // Commit compound datatype and close it + // Commit compound datatype, and test getting the datatype creation + // prop list, then close it tid1.commit(file, CompT_NAME); + PropList tcpl = tid1.getCreatePlist(); + if (!IdComponent::isValid(tcpl.getId())) + { + // Throw an invalid action exception + throw InvalidActionException("IdComponent::isValid", "Datatype creation property list is not valid"); + } + tcpl.close(); tid1.close(); - // Commit enumeration datatype and close it + // Commit enumeration datatype, and test getting the datatype creation + // prop list, then close it tid2.commit(file, EnumT_NAME); + tcpl = tid2.getCreatePlist(); + if (!IdComponent::isValid(tcpl.getId())) + { + // Throw an invalid action exception + throw InvalidActionException("IdComponent::isValid", "Datatype creation property list is not valid"); + } + tcpl.close(); tid2.close(); // Open the datatypes for query |