From a48c9c4024e7ede0021e1a9d8c1d4c197333e0d0 Mon Sep 17 00:00:00 2001 From: Binh-Minh Ribler Date: Mon, 13 Mar 2017 22:53:43 -0500 Subject: Purpose: Add new C++ wrappers Description: Added wrappers for H5Iis_valid, H5Ps/get_nlinks, H5Tget_create_plist, H5Oopen, H5Oclose and H5Pset_virtual // Checks if the given ID is valid. static bool isValid(hid_t an_id); // Sets the number of soft or user-defined links that can be // traversed before a failure occurs. void setNumLinks(size_t nlinks) const; // Gets the number of soft or user-defined link traversals allowed size_t getNumLinks() const; // Returns a copy of the creation property list of a datatype. PropList getCreatePlist() const; // Opens an object within a group or a file, i.e., root group. hid_t getObjId(const char* name,...); hid_t getObjId(const H5std_string& name,...); // Closes an object opened by getObjId(). void closeObjId(hid_t obj_id) const; // Maps elements of a virtual dataset to elements of the source dataset. void setVirtual(const DataSpace& vspace, const char *src_fname,...); void setVirtual(const DataSpace& vspace, const H5std_string src_fname,...); Platforms tested: Linux/32 2.6 (jam) Linux/64 (platypus) Darwin (osx1010test) --- c++/src/H5DataType.cpp | 25 ++++++++++ c++/src/H5DataType.h | 3 ++ c++/src/H5DcreatProp.cpp | 50 +++++++++++++++++++ c++/src/H5DcreatProp.h | 5 ++ c++/src/H5FaccProp.h | 6 +++ c++/src/H5Group.cpp | 50 ++++++++++++++++++- c++/src/H5Group.h | 7 +++ c++/src/H5IdComponent.cpp | 21 ++++++++ c++/src/H5IdComponent.h | 4 +- c++/src/H5LaccProp.cpp | 49 ++++++++++++++++--- c++/src/H5LaccProp.h | 7 +++ c++/test/dsets.cpp | 82 +++++++++++++++++++++++++++++++ c++/test/tlinks.cpp | 54 +++++++++++++++++++-- c++/test/tobject.cpp | 121 ++++++++++++++++++++++++++++++++++++++++++++++ c++/test/ttypes.cpp | 20 +++++++- 15 files changed, 490 insertions(+), 14 deletions(-) diff --git a/c++/src/H5DataType.cpp b/c++/src/H5DataType.cpp index ae48d16..1cfc259 100644 --- a/c++/src/H5DataType.cpp +++ b/c++/src/H5DataType.cpp @@ -744,6 +744,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 - March, 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 fd9c17d..6501bb9 100644 --- a/c++/src/H5DataType.h +++ b/c++/src/H5DataType.h @@ -113,6 +113,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/H5DcreatProp.cpp b/c++/src/H5DcreatProp.cpp index 86d4d9c..e1be3c4 100644 --- a/c++/src/H5DcreatProp.cpp +++ b/c++/src/H5DcreatProp.cpp @@ -18,6 +18,7 @@ #include "H5Include.h" #include "H5Exception.h" #include "H5IdComponent.h" +#include "H5DataSpace.h" #include "H5PropList.h" #include "H5OcreatProp.h" #include "H5DcreatProp.h" @@ -740,6 +741,55 @@ void DSetCreatPropList::getExternal(unsigned idx, size_t name_size, char* name, } //-------------------------------------------------------------------------- +// Function: DSetCreatPropList::setVirtual +///\brief Maps elements of a virtual dataset to elements of the source +/// dataset. +///\param vspace - IN: Dataspace the virtual dataset, possibly an +/// unlimited selection +///\param src_fname - IN: Name of the HDF5 file where the source dataset +/// is located (\a char*) +///\param src_fname - IN: Path to the dataset in the file specified by +/// \a src_file_name (\a char*) +///\param sspace - IN: Dataspace with a selection applied, possibly +/// an unlimited selection +///\exception H5::PropListIException +///\par Description +/// https://support.hdfgroup.org/HDF5/doc/RM/RM_H5P.html#Property-SetVirtual +// Programmer Binh-Minh Ribler - Mar, 2017 +//-------------------------------------------------------------------------- +void DSetCreatPropList::setVirtual(const DataSpace& vspace, const char *src_fname, const char *src_dsname, const DataSpace& sspace) const +{ + herr_t ret_value = H5Pset_virtual(id, vspace.getId(), src_fname, src_dsname, sspace.getId()); + if (ret_value < 0) + { + throw PropListIException("DSetCreatPropList::setVirtual", + "H5Pset_virtual failed"); + } +} + +//-------------------------------------------------------------------------- +// Function: DSetCreatPropList::setVirtual +///\brief Maps elements of a virtual dataset to elements of the source +/// dataset. +///\param vspace - IN: Dataspace the virtual dataset, possibly an +/// unlimited selection +///\param src_fname - IN: Name of the HDF5 file where the source dataset +/// is located (\a H5std_string) +///\param src_fname - IN: Path to the dataset in the file specified by +/// \a src_file_name (\a H5std_string) +///\param sspace - IN: Dataspace with a selection applied, possibly +/// an unlimited selection +///\exception H5::PropListIException +///\par Description +/// https://support.hdfgroup.org/HDF5/doc/RM/RM_H5P.html#Property-SetVirtual +// Programmer Binh-Minh Ribler - Mar, 2017 +//-------------------------------------------------------------------------- +void DSetCreatPropList::setVirtual(const DataSpace& vspace, const H5std_string src_fname, const H5std_string src_dsname, const DataSpace& sspace) const +{ + setVirtual(vspace, src_fname.c_str(), src_dsname.c_str(), sspace); +} + +//-------------------------------------------------------------------------- // Function: DSetCreatPropList destructor ///\brief Noop destructor. // Programmer Binh-Minh Ribler - 2000 diff --git a/c++/src/H5DcreatProp.h b/c++/src/H5DcreatProp.h index b536709..5371e03 100644 --- a/c++/src/H5DcreatProp.h +++ b/c++/src/H5DcreatProp.h @@ -20,6 +20,7 @@ namespace H5 { class DataType; +class DataSpace; /*! \class DSetCreatPropList \brief Class DSetCreatPropList inherits from ObjCreatPropList and provides @@ -116,6 +117,10 @@ class H5_DLLCPP DSetCreatPropList : public ObjCreatPropList { // Sets N-bit compression method. void setNbit() const; + // Maps elements of a virtual dataset to elements of the source dataset. + void setVirtual(const DataSpace& vspace, const char *src_fname, const char *src_dsname, const DataSpace& sspace) const; + void setVirtual(const DataSpace& vspace, const H5std_string src_fname, const H5std_string src_dsname, const DataSpace& sspace) const; + ///\brief Returns this class name. virtual H5std_string fromClass () const { return("DSetCreatPropList"); } diff --git a/c++/src/H5FaccProp.h b/c++/src/H5FaccProp.h index ae7c7f9..586dcf8 100644 --- a/c++/src/H5FaccProp.h +++ b/c++/src/H5FaccProp.h @@ -117,6 +117,12 @@ class H5_DLLCPP FileAccPropList : public PropList { // Returns the degree for the file close behavior. H5F_close_degree_t getFcloseDegree() const; + // Sets file access property list to use the H5FD_DIRECT driver. + void setFileAccDirect(size_t boundary, size_t block_size, size_t cbuf_size) const; + + // Retrieves information about the direct file access property list. + void getFileAccDirect(size_t &boundary, size_t &block_size, size_t &cbuf_size) const; + // Sets garbage collecting references flag. void setGcReferences(unsigned gc_ref = 0) const; diff --git a/c++/src/H5Group.cpp b/c++/src/H5Group.cpp index 6b143b5..6e5cdaa 100644 --- a/c++/src/H5Group.cpp +++ b/c++/src/H5Group.cpp @@ -64,8 +64,56 @@ Group::Group(const Group& original) : H5Object(), CommonFG(), id(original.id) } //-------------------------------------------------------------------------- +// Function: Group::getObjId +///\brief Opens an object via object header. +///\exception H5::FileIException or H5::GroupIException +///\par Description +/// This function opens an object in a group or file, using +/// H5Oopen. Thus, an object can be opened without knowing +/// the object's type. +// Programmer Binh-Minh Ribler - March, 2017 +//-------------------------------------------------------------------------- +hid_t Group::getObjId(const char* obj_name, const PropList& plist) const +{ + hid_t ret_value = H5Oopen(getId(), obj_name, plist.getId()); + if (ret_value < 0) + { + throwException("Group::getObjId", "H5Oopen failed"); + } + return(ret_value); +} + +//-------------------------------------------------------------------------- +// Function: Group::getObjId +///\brief This is an overloaded member function, provided for convenience. +/// It takes a reference to a \c H5std_string for the object's name. +///\param obj_name - IN: Path to the object +///\exception H5::FileIException or H5::GroupIException +// Programmer Binh-Minh Ribler - March, 2017 +//-------------------------------------------------------------------------- +hid_t Group::getObjId(const H5std_string& obj_name, const PropList& plist) const +{ + return(getObjId(obj_name.c_str(), plist)); +} + +//-------------------------------------------------------------------------- +// Function: Group::closeObjId +///\brief Closes an object, which was opened with Group::getObjId +///\exception H5::FileIException or H5::GroupIException +// Programmer Binh-Minh Ribler - March, 2017 +//-------------------------------------------------------------------------- +void Group::closeObjId(hid_t obj_id) const +{ + herr_t ret_value = H5Oclose(obj_id); + if (ret_value < 0) + { + throwException("Group::closeObjId", "H5Oclose failed"); + } +} + +//-------------------------------------------------------------------------- // Function: Group::getLocId -// Purpose: Get the id of this group +// Purpose: Get the id of this group // Programmer Binh-Minh Ribler - 2000 // Description // This function is a redefinition of CommonFG::getLocId. It diff --git a/c++/src/H5Group.h b/c++/src/H5Group.h index 96dc5c1..3118aa7 100644 --- a/c++/src/H5Group.h +++ b/c++/src/H5Group.h @@ -54,6 +54,13 @@ class H5_DLLCPP Group : public H5Object, public CommonFG { Group(const H5Location& loc, const void* ref, H5R_type_t ref_type = H5R_OBJECT, const PropList& plist = PropList::DEFAULT); // Group(const Attribute& attr, const void* ref, H5R_type_t ref_type = H5R_OBJECT, const PropList& plist = PropList::DEFAULT); + // Opens an object within a group or a file, i.e., root group. + hid_t getObjId(const char* name, const PropList& plist = PropList::DEFAULT) const; + hid_t getObjId(const H5std_string& name, const PropList& plist = PropList::DEFAULT) const; + + // Closes an object opened by getObjId(). + void closeObjId(hid_t obj_id) const; + // default constructor Group(); diff --git a/c++/src/H5IdComponent.cpp b/c++/src/H5IdComponent.cpp index 574b28a..0bcc67a 100644 --- a/c++/src/H5IdComponent.cpp +++ b/c++/src/H5IdComponent.cpp @@ -194,6 +194,27 @@ hsize_t IdComponent::getNumMembers(H5I_type_t type) } //-------------------------------------------------------------------------- +// Function: isValid (static) +///\brief Checks if the given ID is valid. +///\return true if the given identifier is valid, and false, otherwise. +///\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: typeExists (static) ///\brief Queries if a given type is currently registered with the /// library. diff --git a/c++/src/H5IdComponent.h b/c++/src/H5IdComponent.h index 6f57364..b449d4a 100644 --- a/c++/src/H5IdComponent.h +++ b/c++/src/H5IdComponent.h @@ -19,7 +19,6 @@ namespace H5 { -class DataSpace; /*! \class IdComponent \brief Class IdComponent provides wrappers of the C functions that operate on an HDF5 identifier. @@ -51,6 +50,9 @@ class H5_DLLCPP IdComponent { // Returns the number of members in a type. static hsize_t getNumMembers(H5I_type_t type); + // Checks if the given ID is valid. + static bool isValid(hid_t an_id); + // Determines if an type exists. static bool typeExists(H5I_type_t type); diff --git a/c++/src/H5LaccProp.cpp b/c++/src/H5LaccProp.cpp index e9adb12..e457e83 100644 --- a/c++/src/H5LaccProp.cpp +++ b/c++/src/H5LaccProp.cpp @@ -40,7 +40,7 @@ LinkAccPropList* LinkAccPropList::DEFAULT_ = 0; // If LinkAccPropList::DEFAULT_ already points to an allocated // object, throw a PropListIException. This scenario should not // happen. -// Programmer Binh-Minh Ribler - 2015 +// Programmer Binh-Minh Ribler - December, 2016 //-------------------------------------------------------------------------- LinkAccPropList* LinkAccPropList::getConstant() { @@ -66,7 +66,7 @@ LinkAccPropList* LinkAccPropList::getConstant() // Purpose: Deletes the constant object that LinkAccPropList::DEFAULT_ // points to. // exception H5::PropListIException -// Programmer Binh-Minh Ribler - 2015 +// Programmer Binh-Minh Ribler - December, 2016 //-------------------------------------------------------------------------- void LinkAccPropList::deleteConstants() { @@ -84,7 +84,7 @@ const LinkAccPropList& LinkAccPropList::DEFAULT = *getConstant(); //-------------------------------------------------------------------------- // Function: Default Constructor ///\brief Creates a file access property list -// Programmer Binh-Minh Ribler - 2000 +// Programmer Binh-Minh Ribler - December, 2016 //-------------------------------------------------------------------------- LinkAccPropList::LinkAccPropList() : PropList(H5P_LINK_ACCESS) {} @@ -92,7 +92,7 @@ LinkAccPropList::LinkAccPropList() : PropList(H5P_LINK_ACCESS) {} // Function: LinkAccPropList copy constructor ///\brief Copy Constructor: makes a copy of the original ///\param original - IN: LinkAccPropList instance to copy -// Programmer Binh-Minh Ribler - 2000 +// Programmer Binh-Minh Ribler - December, 2016 //-------------------------------------------------------------------------- LinkAccPropList::LinkAccPropList(const LinkAccPropList& original) : PropList(original) {} @@ -100,14 +100,51 @@ LinkAccPropList::LinkAccPropList(const LinkAccPropList& original) : PropList(ori // Function: LinkAccPropList overloaded constructor ///\brief Creates a file access property list using the id of an /// existing one. -// Programmer Binh-Minh Ribler - 2000 +// Programmer Binh-Minh Ribler - December, 2016 //-------------------------------------------------------------------------- LinkAccPropList::LinkAccPropList(const hid_t plist_id) : PropList(plist_id) {} //-------------------------------------------------------------------------- +// Function: LinkAccPropList::setNumLinks +///\brief Set the number of soft or user-defined link traversals allowed +/// before the library assumes it has found a cycle and aborts the +/// traversal. +///\exception H5::PropListIException +// Programmer Binh-Minh Ribler - March 1, 2017 +//-------------------------------------------------------------------------- +void LinkAccPropList::setNumLinks(size_t nlinks) const +{ + herr_t ret_value = H5Pset_nlinks(id, nlinks); + // Throw exception if H5Pset_nlinks returns failure + if (ret_value < 0) + { + throw PropListIException("setNumLinks", "H5Pset_nlinks failed"); + } +} + +//-------------------------------------------------------------------------- +// Function: LinkAccPropList::getNumLinks +///\brief Gets the number of soft or user-defined links that can be +/// traversed before a failure occurs. +///\exception H5::PropListIException +// Programmer Binh-Minh Ribler - March 1, 2017 +//-------------------------------------------------------------------------- +size_t LinkAccPropList::getNumLinks() const +{ + size_t nlinks = 0; + herr_t ret_value = H5Pget_nlinks(id, &nlinks); + // Throw exception if H5Pget_nlinks returns failure + if (ret_value < 0) + { + throw PropListIException("getNumLinks", "H5Pget_nlinks failed"); + } + return(nlinks); +} + +//-------------------------------------------------------------------------- // Function: LinkAccPropList destructor ///\brief Noop destructor -// Programmer Binh-Minh Ribler - 2000 +// Programmer Binh-Minh Ribler - December, 2016 //-------------------------------------------------------------------------- LinkAccPropList::~LinkAccPropList() {} diff --git a/c++/src/H5LaccProp.h b/c++/src/H5LaccProp.h index 8bcdd64..1cb80f7 100644 --- a/c++/src/H5LaccProp.h +++ b/c++/src/H5LaccProp.h @@ -46,6 +46,13 @@ class H5_DLLCPP LinkAccPropList : public PropList { // using the property list id. LinkAccPropList (const hid_t plist_id); + // Sets the number of soft or user-defined links that can be + // traversed before a failure occurs. + void setNumLinks(size_t nlinks) const; + + // Gets the number of soft or user-defined link traversals allowed + size_t getNumLinks() const; + // Noop destructor virtual ~LinkAccPropList(); diff --git a/c++/test/dsets.cpp b/c++/test/dsets.cpp index 48a0c4d..970f210 100644 --- a/c++/test/dsets.cpp +++ b/c++/test/dsets.cpp @@ -1148,6 +1148,87 @@ test_types(H5File& file) /*------------------------------------------------------------------------- + * Function: test_virtual + * + * Purpose: Tests fixed, unlimited, and printf selections in the same + * VDS + * + * Return: Success: 0 + * + * Failure: number of errors + * + * Programmer: Binh-Minh Ribler + * Friday, March 10, 2017 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +const int RANK = 2; +static herr_t +test_virtual() +{ + SUBTEST("DSetCreatPropList::setVirtual"); + + try { + // Create DCPLs + DSetCreatPropList dcpl; + DSetCreatPropList srcdcpl; + + // Set fill value + char *fill = NULL; + dcpl.setFillValue(PredType::NATIVE_INT, &fill); + + // Set chunk dimensions + hsize_t cdims[RANK]; + cdims[0] = 2; + cdims[1] = 2; + srcdcpl.setChunk(RANK, cdims); + + // Create memory space + hsize_t mdims[RANK]; + mdims[0] = 10; + mdims[1] = 10; + DataSpace memspace(RANK, mdims); + + // Get the current layout, should be default, H5D_CONTIGUOUS + H5D_layout_t layout = dcpl.getLayout(); + verify_val(layout, H5D_CONTIGUOUS, "DSetCreatPropList::getLayout", __LINE__, __FILE__); + + // Create fixed mapping + hsize_t dims[RANK]; + dims[0] = 6; + dims[1] = 6; + DataSpace vspace(RANK, dims, mdims); + + hsize_t start[RANK]; // Hyperslab start + hsize_t count[RANK]; // Hyperslab count + start[0] = start[1] = 3; + count[0] = count[1] = 3; + vspace.selectHyperslab(H5S_SELECT_SET, count, start); + + DataSpace srcspace(RANK, count); + + H5std_string src_file = "src_file_map.h5"; + H5std_string src_dset = "src_dset_fixed"; + dcpl.setVirtual(vspace, src_file, src_dset, srcspace); + + // Get and verify the new layout + layout = dcpl.getLayout(); + verify_val(layout, H5D_VIRTUAL, "DSetCreatPropList::getLayout", __LINE__, __FILE__); + + PASSED(); + return 0; + } // end top try block + + catch (Exception& E) + { + return -1; + } +} // test_virtual + + +/*------------------------------------------------------------------------- * Function: test_dset * * Purpose Tests the dataset interface (H5D) @@ -1195,6 +1276,7 @@ void test_dset() nerrors += test_nbit_compression(file) < 0 ? 1:0; nerrors += test_multiopen (file) < 0 ? 1:0; nerrors += test_types(file) < 0 ? 1:0; + nerrors += test_virtual() < 0 ? 1:0; // Close group "emit diagnostics". grp.close(); diff --git a/c++/test/tlinks.cpp b/c++/test/tlinks.cpp index c217718..0bf6ebf 100644 --- a/c++/test/tlinks.cpp +++ b/c++/test/tlinks.cpp @@ -142,11 +142,8 @@ const char *FILENAME[] = { #define H5L_DIM2 100 /* Creation order macros */ -#define CORDER_GROUP_NAME "corder_group" #define CORDER_SOFT_GROUP_NAME "corder_soft_group" #define CORDER_NLINKS 18 -#define CORDER_ITER_STOP 3 -#define CORDER_EST_ENTRY_LEN 9 /* Timestamp macros */ #define TIMESTAMP_GROUP_1 "timestamp1" @@ -341,7 +338,7 @@ static const char *FILENAME[] = { static void test_basic_links(hid_t fapl_id, hbool_t new_format) { hsize_t size[1] = {1}; - char filename[NAME_BUF_SIZE]; + char filename[NAME_BUF_SIZE]; // Use the file access template id to create a file access prop. list. FileAccPropList fapl(fapl_id); @@ -441,6 +438,55 @@ static void test_basic_links(hid_t fapl_id, hbool_t new_format) /*------------------------------------------------------------------------- + * Function: test_num_links + * + * Purpose Test setting and getting limit of number of links + * + * Return Success: 0 + * + * Failure: -1 + * + * Programmer Binh-Minh Ribler + * October 16, 2009 + * + * 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 * * Purpose Test links diff --git a/c++/test/tobject.cpp b/c++/test/tobject.cpp index 6003dd6..3c9c1b0 100644 --- a/c++/test/tobject.cpp +++ b/c++/test/tobject.cpp @@ -32,6 +32,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"); @@ -395,7 +396,126 @@ static void test_get_objtype() issue_fail_msg("test_get_objtype", __LINE__, __FILE__); } } // test_get_objtype + +/*------------------------------------------------------------------------- + * Function: test_open_object_header + * + * Purpose Test Group::getObjId function. + * + * Return None + * + * Programmer Binh-Minh Ribler (use C version) + * March, 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("Group::getObjId"); + + 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 getObjId can open all three types of objects + hid_t obj_grp = file1.getObjId(GROUPNAME); + hid_t obj_dtype = file1.getObjId(DTYPENAME); + hid_t obj_dset = file1.getObjId(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.getObjId(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_objects * @@ -421,6 +541,7 @@ void test_object() test_existance(); // Test check for object existance test_get_objname_ontypes(); // Test get object name from types test_get_objtype(); // Test get object type + test_open_object_header(); // Test object header functions (H5O) } // test_objects diff --git a/c++/test/ttypes.cpp b/c++/test/ttypes.cpp index 0cc8918..22db539 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("H5Object::createAttribute", "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("H5Object::createAttribute", "Datatype creation property list is not valid"); + } + tcpl.close(); tid2.close(); // Open the datatypes for query -- cgit v0.12