From f8fb310610ca222ca44fabf4311e3af24d660b9d Mon Sep 17 00:00:00 2001 From: Binh-Minh Ribler Date: Sun, 22 Sep 2013 19:39:44 -0500 Subject: [svn-r24188] Purpose: Fixed bug introduced in r24163 Description: - The failure in daily test was caused by missing initialization of member "id" in a few constructors. This is now fixed. - Added two overloaded H5Location::setComment - Improved some error reporting in H5Location - Improved error reporting in tests Platforms tested: Linux/32 2.6 (jam) SunOS 5.11 (emu) Linux/64 2.6 (koala)/PGI compilers --- c++/src/H5Attribute.cpp | 1 + c++/src/H5CommonFG.cpp | 131 --------- c++/src/H5CommonFG.h | 12 - c++/src/H5DataSet.cpp | 52 +--- c++/src/H5DataSet.h | 8 +- c++/src/H5DataSpace.cpp | 2 +- c++/src/H5DataType.cpp | 59 ++-- c++/src/H5DataType.h | 8 +- c++/src/H5File.cpp | 4 +- c++/src/H5File.h | 3 - c++/src/H5Group.cpp | 37 +-- c++/src/H5Group.h | 10 +- c++/src/H5IdComponent.cpp | 7 +- c++/src/H5Location.cpp | 459 +++++++++++++++++++++---------- c++/src/H5Location.h | 53 ++-- c++/src/H5Object.cpp | 1 - c++/src/H5PropList.cpp | 5 +- c++/test/dsets.cpp | 2 +- c++/test/h5cpputil.cpp | 24 ++ c++/test/h5cpputil.h | 2 + c++/test/trefer.cpp | 676 ++++++++++++++++++++++++++++++++++++++-------- 21 files changed, 996 insertions(+), 560 deletions(-) diff --git a/c++/src/H5Attribute.cpp b/c++/src/H5Attribute.cpp index d684b8f..a98a970 100644 --- a/c++/src/H5Attribute.cpp +++ b/c++/src/H5Attribute.cpp @@ -44,6 +44,7 @@ namespace H5 { #endif // H5_NO_STD #endif +class H5_DLLCPP H5Object; // forward declaration for UserData4Aiterate //-------------------------------------------------------------------------- // Function: Attribute default constructor ///\brief Default constructor: Creates a stub attribute diff --git a/c++/src/H5CommonFG.cpp b/c++/src/H5CommonFG.cpp index d6fe5dc..3bf4b4f 100644 --- a/c++/src/H5CommonFG.cpp +++ b/c++/src/H5CommonFG.cpp @@ -460,137 +460,6 @@ H5std_string CommonFG::getLinkval( const H5std_string& name, size_t size ) const } //-------------------------------------------------------------------------- -// Function: CommonFG::setComment -///\brief Sets or resets the comment for an object specified by its name. -///\param name - IN: Name of the object -///\param comment - IN: New comment -///\exception H5::FileIException or H5::GroupIException -///\par Description -/// If \a comment is an empty string or a null pointer, the comment -/// message is removed from the object. -/// Comments should be relatively short, null-terminated, ASCII -/// strings. They can be attached to any object that has an -/// object header, e.g., data sets, groups, named data types, -/// and data spaces, but not symbolic links. -// Programmer Binh-Minh Ribler - 2000 -// Modification -// 2007: QAK modified to use H5O APIs; however the first parameter is -// no longer just file or group, this function should be moved -// to another class to accommodate attribute, dataset, and named -// datatype. - BMR -//-------------------------------------------------------------------------- -void CommonFG::setComment( const char* name, const char* comment ) const -{ - herr_t ret_value = H5Oset_comment_by_name( getLocId(), name, comment, H5P_DEFAULT ); - if( ret_value < 0 ) - throwException("setComment", "H5Oset_comment_by_name failed"); -} - -//-------------------------------------------------------------------------- -// Function: CommonFG::setComment -///\brief This is an overloaded member function, provided for convenience. -/// It differs from the above function in that it takes an -/// \c H5std_string for \a name and \a comment. -// Programmer Binh-Minh Ribler - 2000 -//-------------------------------------------------------------------------- -void CommonFG::setComment( const H5std_string& name, const H5std_string& comment ) const -{ - setComment( name.c_str(), comment.c_str() ); -} - -//-------------------------------------------------------------------------- -// Function: CommonFG::removeComment -///\brief Removes the comment from an object specified by its name. -///\param name - IN: Name of the object -///\exception H5::FileIException or H5::GroupIException -// Programmer Binh-Minh Ribler - May 2005 -// 2007: QAK modified to use H5O APIs; however the first parameter is -// no longer just file or group, this function should be moved -// to another class to accommodate attribute, dataset, and named -// datatype. - BMR -//-------------------------------------------------------------------------- -void CommonFG::removeComment(const char* name) const -{ - herr_t ret_value = H5Oset_comment_by_name(getLocId(), name, NULL, H5P_DEFAULT); - if( ret_value < 0 ) - throwException("removeComment", "H5Oset_comment_by_name failed"); -} - -//-------------------------------------------------------------------------- -// Function: CommonFG::removeComment -///\brief This is an overloaded member function, provided for convenience. -/// It differs from the above function in that it takes an -/// \c H5std_string for \a name. -// Programmer Binh-Minh Ribler - May 2005 -//-------------------------------------------------------------------------- -void CommonFG::removeComment(const H5std_string& name) const -{ - removeComment (name.c_str()); -} - -//-------------------------------------------------------------------------- -// Function: CommonFG::getComment -///\brief Retrieves comment for the specified object and its comment's -/// length. -///\param name - IN: Name of the object -///\param bufsize - IN: Length of the comment to retrieve -///\return Comment string -///\exception H5::FileIException or H5::GroupIException -// Programmer Binh-Minh Ribler - 2000 -// 2007: QAK modified to use H5O APIs; however the first parameter is -// no longer just file or group, this function should be moved -// to another class to accommodate attribute, dataset, and named -// datatype. - BMR -//-------------------------------------------------------------------------- -H5std_string CommonFG::getComment( const char* name, size_t bufsize ) const -{ - // bufsize is default to 256 - // temporary variable - hid_t loc_id = getLocId(); // temporary variable - - // temporary C-string for the object's comment; bufsize already including - // null character - char* comment_C = new char[bufsize]; - ssize_t ret_value = H5Oget_comment_by_name(loc_id, name, comment_C, bufsize, H5P_DEFAULT); - - // if the actual length of the comment is longer than bufsize and bufsize - // was the default value, i.e., not given by the user, then call - // H5Oget_comment_by_name again with the correct value. - // If the call to H5Oget_comment_by_name returned an error, skip this block - // and throw an exception below. - if (ret_value >= 0 && (size_t)ret_value > bufsize && bufsize == 256) - { - size_t new_size = ret_value; - delete []comment_C; - comment_C = new char[new_size]; // new_size including null terminator - ret_value = H5Oget_comment_by_name(loc_id, name, comment_C, new_size, H5P_DEFAULT); - } - - // if H5Oget_comment_by_name returns SUCCEED, return the string comment, - // otherwise, throw an exception - if( ret_value < 0 ) { - delete []comment_C; - throwException("getComment", "H5Oget_comment_by_name failed"); - } - - H5std_string comment = H5std_string(comment_C); - delete []comment_C; - return (comment); -} - -//-------------------------------------------------------------------------- -// Function: CommonFG::getComment -///\brief This is an overloaded member function, provided for convenience. -/// It differs from the above function in that it takes an -/// \c H5std_string for \a name. -// Programmer Binh-Minh Ribler - 2000 -//-------------------------------------------------------------------------- -H5std_string CommonFG::getComment( const H5std_string& name, size_t bufsize ) const -{ - return( getComment( name.c_str(), bufsize )); -} - -//-------------------------------------------------------------------------- // Function: CommonFG::mount ///\brief Mounts the file \a child onto this group. ///\param name - IN: Name of the group diff --git a/c++/src/H5CommonFG.h b/c++/src/H5CommonFG.h index 22e193a..b02b05b 100644 --- a/c++/src/H5CommonFG.h +++ b/c++/src/H5CommonFG.h @@ -49,18 +49,6 @@ class H5_DLLCPP CommonFG { DataSet openDataSet(const char* name) const; DataSet openDataSet(const H5std_string& name) const; - // Retrieves comment for the HDF5 object specified by its name. - H5std_string getComment(const char* name, size_t bufsize=256) const; - H5std_string getComment(const H5std_string& name, size_t bufsize=256) const; - - // Removes the comment for the HDF5 object specified by its name. - void removeComment(const char* name) const; - void removeComment(const H5std_string& name) 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; - // Returns the value of a symbolic link. H5std_string getLinkval(const char* link_name, size_t size=0) const; H5std_string getLinkval(const H5std_string& link_name, size_t size=0) const; diff --git a/c++/src/H5DataSet.cpp b/c++/src/H5DataSet.cpp index 3e3893c..0722ef9 100644 --- a/c++/src/H5DataSet.cpp +++ b/c++/src/H5DataSet.cpp @@ -79,57 +79,29 @@ DataSet::DataSet(const DataSet& original) : AbstractDs(original), H5Object(origi //-------------------------------------------------------------------------- // Function: DataSet overload constructor - dereference -///\brief Given a reference, ref, to an hdf5 dataset, creates a +///\brief Given a reference, ref, to an hdf5 location, creates a /// DataSet object -///\param obj - IN: Dataset reference object is in or location of +///\param loc - IN: Dataset reference object is in or location of /// object that the dataset is located within. ///\param ref - IN: Reference pointer ///\param ref_type - IN: Reference type - default to H5R_OBJECT ///\exception H5::DataSetIException ///\par Description -/// \c obj can be DataSet, Group, H5File, or named DataType, that +/// \c loc can be DataSet, Group, H5File, or named DataType, that /// is a datatype that has been named by DataType::commit. // Programmer Binh-Minh Ribler - Oct, 2006 // Modification // Jul, 2008 // Added for application convenience. //-------------------------------------------------------------------------- -DataSet::DataSet(H5Object& obj, const void* ref, H5R_type_t ref_type) : AbstractDs(), H5Object() +DataSet::DataSet(const H5Location& loc, const void* ref, H5R_type_t ref_type, const PropList& plist) : AbstractDs(), H5Object(), id(0) { - try { - id = p_dereference(obj.getId(), ref, ref_type); - } catch (ReferenceException deref_error) { - throw ReferenceException("DataSet constructor - located by object", - deref_error.getDetailMsg()); - } + id = H5Location::p_dereference(loc.getId(), ref, ref_type, plist, "constructor - by dereferenced"); } //-------------------------------------------------------------------------- // Function: DataSet overload constructor - dereference -///\brief Given a reference, ref, to an hdf5 dataset, creates a -/// DataSet object -///\param h5file - IN: Location referenced object is in -///\param ref - IN: Reference pointer -///\param ref_type - IN: Reference type - default to H5R_OBJECT -///\exception H5::DataSetIException -// Programmer Binh-Minh Ribler - Oct, 2006 -// Modification -// Jul, 2008 -// Added for application convenience. -//-------------------------------------------------------------------------- -DataSet::DataSet(H5File& h5file, const void* ref, H5R_type_t ref_type) : AbstractDs(), H5Object() -{ - try { - id = p_dereference(h5file.getId(), ref, ref_type); - } catch (ReferenceException deref_error) { - throw ReferenceException("DataSet constructor - located by HDF5 file", - deref_error.getDetailMsg()); - } -} - -//-------------------------------------------------------------------------- -// Function: DataSet overload constructor - dereference -///\brief Given a reference, ref, to an hdf5 dataset, creates a +///\brief Given a reference, ref, to an hdf5 attribute, creates a /// DataSet object ///\param attr - IN: Specifying location where the referenced object is in ///\param ref - IN: Reference pointer @@ -140,14 +112,9 @@ DataSet::DataSet(H5File& h5file, const void* ref, H5R_type_t ref_type) : Abstrac // Jul, 2008 // Added for application convenience. //-------------------------------------------------------------------------- -DataSet::DataSet(Attribute& attr, const void* ref, H5R_type_t ref_type) : AbstractDs(), H5Object() +DataSet::DataSet(const Attribute& attr, const void* ref, H5R_type_t ref_type, const PropList& plist) : AbstractDs(), H5Object(), id(0) { - try { - id = p_dereference(attr.getId(), ref, ref_type); - } catch (ReferenceException deref_error) { - throw ReferenceException("DataSet constructor - located by attribute", - deref_error.getDetailMsg()); - } + id = H5Location::p_dereference(attr.getId(), ref, ref_type, plist, "constructor - by dereference"); } //-------------------------------------------------------------------------- @@ -751,9 +718,6 @@ void DataSet::p_setId(const hid_t new_id) } // reset object's id to the given id id = new_id; - - // increment the reference counter of the new id - //incRefCount(); } #endif // DOXYGEN_SHOULD_SKIP_THIS diff --git a/c++/src/H5DataSet.h b/c++/src/H5DataSet.h index bc80046..e2fe702 100644 --- a/c++/src/H5DataSet.h +++ b/c++/src/H5DataSet.h @@ -76,16 +76,12 @@ class H5_DLLCPP DataSet : public H5Object, public AbstractDs { // Iterates the selected elements in the specified dataspace - not implemented in C++ style yet int iterateElems( void* buf, const DataType& type, const DataSpace& space, H5D_operator_t op, void* op_data = NULL ); - // Retrieves a dataspace with the region pointed to selected. - DataSpace getRegion(void *ref, H5R_type_t ref_type = H5R_DATASET_REGION) const; - ///\brief Returns this class name. virtual H5std_string fromClass () const { return("DataSet"); } // Creates a dataset by way of dereference. - DataSet(H5Object& obj, const void* ref, H5R_type_t ref_type = H5R_OBJECT); - DataSet(H5File& h5file, const void* ref, H5R_type_t ref_type = H5R_OBJECT); - DataSet(Attribute& attr, const void* ref, H5R_type_t ref_type = H5R_OBJECT); + DataSet(const H5Location& loc, const void* ref, H5R_type_t ref_type = H5R_OBJECT, const PropList& plist = PropList::DEFAULT); + DataSet(const Attribute& attr, const void* ref, H5R_type_t ref_type = H5R_OBJECT, const PropList& plist = PropList::DEFAULT); // Default constructor. DataSet(); diff --git a/c++/src/H5DataSpace.cpp b/c++/src/H5DataSpace.cpp index 2e2bb35..059c812 100644 --- a/c++/src/H5DataSpace.cpp +++ b/c++/src/H5DataSpace.cpp @@ -446,7 +446,7 @@ void DataSpace::getSelectBounds ( hsize_t* start, hsize_t* end ) const } //-------------------------------------------------------------------------- -// Function: DataSpace::H5Sselect_elements +// Function: DataSpace::selectElements ///\brief Selects array elements to be included in the selection for /// this dataspace. ///\param op - IN: Operator specifying how the new selection is to be diff --git a/c++/src/H5DataType.cpp b/c++/src/H5DataType.cpp index 8a62471..be05623 100644 --- a/c++/src/H5DataType.cpp +++ b/c++/src/H5DataType.cpp @@ -49,6 +49,13 @@ namespace H5 { #endif //-------------------------------------------------------------------------- +// Function: DataType default constructor +///\brief Default constructor: Creates a stub datatype +// Programmer Binh-Minh Ribler - 2000 +//-------------------------------------------------------------------------- +DataType::DataType() : H5Object(), id(0) {} + +//-------------------------------------------------------------------------- // Function: DataType overloaded constructor ///\brief Creates a datatype using an existing datatype's id ///\param existing_id - IN: Id of the existing datatype @@ -88,32 +95,6 @@ DataType::DataType( const H5T_class_t type_class, size_t size ) : H5Object() // Function: DataType overload constructor - dereference ///\brief Given a reference, ref, to an hdf5 group, creates a /// DataType object -///\param obj - IN: Specifying location referenced object is in -///\param ref - IN: Reference pointer -///\param ref_type - IN: Reference type - default to H5R_OBJECT -///\exception H5::ReferenceException -///\par Description -/// \c obj can be DataSet, Group, or named DataType, that -/// is a datatype that has been named by DataType::commit. -// Programmer Binh-Minh Ribler - Oct, 2006 -// Modification -// Jul, 2008 -// Added for application convenience. -//-------------------------------------------------------------------------- -DataType::DataType(H5Object& obj, const void* ref, H5R_type_t ref_type) : H5Object() -{ - try { - id = p_dereference(obj.getId(), ref, ref_type); - } catch (ReferenceException deref_error) { - throw ReferenceException("DataType constructor - located by an H5Object", - deref_error.getDetailMsg()); - } -} - -//-------------------------------------------------------------------------- -// Function: DataType overload constructor - dereference -///\brief Given a reference, ref, to an hdf5 group, creates a -/// DataType object ///\param h5file - IN: Location referenced object is in ///\param ref - IN: Reference pointer ///\param ref_type - IN: Reference type - default to H5R_OBJECT @@ -123,14 +104,11 @@ DataType::DataType(H5Object& obj, const void* ref, H5R_type_t ref_type) : H5Obje // Jul, 2008 // Added for application convenience. //-------------------------------------------------------------------------- -DataType::DataType(H5File& h5file, const void* ref, H5R_type_t ref_type) : H5Object() +DataType::DataType(const H5Location& loc, const void* ref, H5R_type_t ref_type, const PropList& plist) : H5Object(), id(0) { - try { - id = p_dereference(h5file.getId(), ref, ref_type); - } catch (ReferenceException deref_error) { - throw ReferenceException("DataType constructor - located by an H5File", - deref_error.getDetailMsg()); - } + /* H5Location::dereference(loc, ref, ref_type, plist); + */ + id = H5Location::p_dereference(loc.getId(), ref, ref_type, plist, "constructor - by dereference"); } //-------------------------------------------------------------------------- @@ -146,24 +124,19 @@ DataType::DataType(H5File& h5file, const void* ref, H5R_type_t ref_type) : H5Obj // Jul, 2008 // Added for application convenience. //-------------------------------------------------------------------------- -DataType::DataType(Attribute& attr, const void* ref, H5R_type_t ref_type) : H5Object() +DataType::DataType(const Attribute& attr, const void* ref, H5R_type_t ref_type, const PropList& plist) : H5Object(), id(0) { - try { - id = p_dereference(attr.getId(), ref, ref_type); + id = H5Location::p_dereference(attr.getId(), ref, ref_type, plist, "constructor - by dereference"); + /* try { + id = p_dereference(attr.getId(), ref, ref_type, plist); } catch (ReferenceException deref_error) { throw ReferenceException("DataType constructor - located by an Attribute", deref_error.getDetailMsg()); } + */ } //-------------------------------------------------------------------------- -// Function: DataType default constructor -///\brief Default constructor: Creates a stub datatype -// Programmer Binh-Minh Ribler - 2000 -//-------------------------------------------------------------------------- -DataType::DataType() : H5Object(), id(0) {} - -//-------------------------------------------------------------------------- // Function: DataType copy constructor ///\brief Copy constructor: makes a copy of the original DataType object. // Programmer Binh-Minh Ribler - 2000 diff --git a/c++/src/H5DataType.h b/c++/src/H5DataType.h index 6e56622..e4254b0 100644 --- a/c++/src/H5DataType.h +++ b/c++/src/H5DataType.h @@ -30,9 +30,8 @@ class H5_DLLCPP DataType : public H5Object { DataType( const DataType& original ); // Creates a datatype by way of dereference. - DataType(H5Object& obj, const void* ref, H5R_type_t ref_type = H5R_OBJECT); - DataType(H5File& h5file, const void* ref, H5R_type_t ref_type = H5R_OBJECT); - DataType(Attribute& attr, const void* ref, H5R_type_t ref_type = H5R_OBJECT); + DataType(const H5Location& loc, const void* ref, H5R_type_t ref_type = H5R_OBJECT, const PropList& plist = PropList::DEFAULT); + DataType(const Attribute& attr, const void* ref, H5R_type_t ref_type = H5R_OBJECT, const PropList& plist = PropList::DEFAULT); // Closes this datatype. virtual void close(); @@ -101,9 +100,6 @@ class H5_DLLCPP DataType : public H5Object { // Checks whether this datatype is a variable-length string. bool isVariableStr() const; - // Retrieves a dataspace with the region pointed to selected. - DataSpace getRegion(void *ref, H5R_type_t ref_type = H5R_DATASET_REGION) 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 65191ae..77dd7be 100644 --- a/c++/src/H5File.cpp +++ b/c++/src/H5File.cpp @@ -82,7 +82,7 @@ H5File::H5File() : H5Location(), id(0) {} // to catch then re-throw it. -BMR 2013/03/21 // Programmer Binh-Minh Ribler - 2000 //-------------------------------------------------------------------------- -H5File::H5File( const char* name, unsigned int flags, const FileCreatPropList& create_plist, const FileAccPropList& access_plist ) : H5Location(0) +H5File::H5File( const char* name, unsigned int flags, const FileCreatPropList& create_plist, const FileAccPropList& access_plist ) : H5Location(), id(0) { try { p_get_file(name, flags, create_plist, access_plist); @@ -107,7 +107,7 @@ H5File::H5File( const char* name, unsigned int flags, const FileCreatPropList& c // to catch then re-throw it. -BMR 2013/03/21 // Programmer Binh-Minh Ribler - 2000 //-------------------------------------------------------------------------- -H5File::H5File( const H5std_string& name, unsigned int flags, const FileCreatPropList& create_plist, const FileAccPropList& access_plist ) : H5Location(0) +H5File::H5File( const H5std_string& name, unsigned int flags, const FileCreatPropList& create_plist, const FileAccPropList& access_plist ) : H5Location(), id(0) { try { p_get_file(name.c_str(), flags, create_plist, access_plist); diff --git a/c++/src/H5File.h b/c++/src/H5File.h index f906de6..2abffea 100644 --- a/c++/src/H5File.h +++ b/c++/src/H5File.h @@ -61,9 +61,6 @@ class H5_DLLCPP H5File : public H5Location, public CommonFG { // and datatypes) in the same file. void getObjIDs(unsigned types, size_t max_objs, hid_t *oid_list) const; - // Retrieves a dataspace with the region pointed to selected. - DataSpace getRegion(void *ref, H5R_type_t ref_type = H5R_DATASET_REGION) const; - // Returns the pointer to the file handle of the low-level file driver. void getVFDHandle(FileAccPropList& fapl, void **file_handle) const; void getVFDHandle(void **file_handle) const; diff --git a/c++/src/H5Group.cpp b/c++/src/H5Group.cpp index eff7e50..6299ea3 100644 --- a/c++/src/H5Group.cpp +++ b/c++/src/H5Group.cpp @@ -99,33 +99,11 @@ Group::Group(const hid_t existing_id) : H5Object() /// is a datatype that has been named by DataType::commit. // Programmer Binh-Minh Ribler - Oct, 2006 //-------------------------------------------------------------------------- -Group::Group(H5Object& obj, const void* ref, H5R_type_t ref_type) : H5Object() +Group::Group(const H5Location& loc, const void* ref, H5R_type_t ref_type, const PropList& plist) : H5Object(), id(0) { - try { - id = p_dereference(obj.getId(), ref, ref_type); - } catch (ReferenceException deref_error) { - throw ReferenceException("Group constructor - located by an H5Object", - deref_error.getDetailMsg()); - } -} - -//-------------------------------------------------------------------------- -// Function: Group overload constructor - dereference -///\brief Given a reference, ref, to an hdf5 group, creates a Group object -///\param h5file - IN: Location referenced object is in -///\param ref - IN: Reference pointer -///\param ref_type - IN: Reference type - default to H5R_OBJECT -///\exception H5::ReferenceException -// Programmer Binh-Minh Ribler - Oct, 2006 -//-------------------------------------------------------------------------- -Group::Group(H5File& h5file, const void* ref, H5R_type_t ref_type) : H5Object() -{ - try { - id = p_dereference(h5file.getId(), ref, ref_type); - } catch (ReferenceException deref_error) { - throw ReferenceException("Group constructor - located by an H5File", - deref_error.getDetailMsg()); - } + /* H5Location::dereference(loc, ref, ref_type, plist); + */ + id = H5Location::p_dereference(loc.getId(), ref, ref_type, plist, "constructor - by dereference"); } //-------------------------------------------------------------------------- @@ -137,14 +115,17 @@ Group::Group(H5File& h5file, const void* ref, H5R_type_t ref_type) : H5Object() ///\exception H5::ReferenceException // Programmer Binh-Minh Ribler - Oct, 2006 //-------------------------------------------------------------------------- -Group::Group(Attribute& attr, const void* ref, H5R_type_t ref_type) : H5Object() +Group::Group(const Attribute& attr, const void* ref, H5R_type_t ref_type, const PropList& plist) : H5Object(), id(0) { + id = H5Location::p_dereference(attr.getId(), ref, ref_type, plist, "constructor - by dereference"); +/* try { - id = p_dereference(attr.getId(), ref, ref_type); + id = p_dereference(attr.getId(), ref, ref_type, plist); } catch (ReferenceException deref_error) { throw ReferenceException("Group constructor - located by an Attribute", deref_error.getDetailMsg()); } +*/ } //-------------------------------------------------------------------------- diff --git a/c++/src/H5Group.h b/c++/src/H5Group.h index 3b53293..4003c21 100644 --- a/c++/src/H5Group.h +++ b/c++/src/H5Group.h @@ -26,9 +26,6 @@ class H5_DLLCPP Group : public H5Object, public CommonFG { // Close this group. virtual void close(); - // Retrieves a dataspace with the region pointed to selected. - DataSpace getRegion(void *ref, H5R_type_t ref_type = H5R_DATASET_REGION) const; - ///\brief Returns this class name. virtual H5std_string fromClass () const { return("Group"); } @@ -39,9 +36,10 @@ class H5_DLLCPP Group : public H5Object, public CommonFG { virtual hid_t getLocId() const; // Creates a group by way of dereference. - Group(H5Object& obj, const void* ref, H5R_type_t ref_type = H5R_OBJECT); - Group(H5File& h5file, const void* ref, H5R_type_t ref_type = H5R_OBJECT); - Group(Attribute& attr, const void* ref, H5R_type_t ref_type = H5R_OBJECT); + Group(const H5Location& loc, const void* ref, H5R_type_t ref_type = H5R_OBJECT, const PropList& plist = PropList::DEFAULT); + /* Group(H5File& h5file, const void* ref, H5R_type_t ref_type = H5R_OBJECT); + */ + Group(const Attribute& attr, const void* ref, H5R_type_t ref_type = H5R_OBJECT, const PropList& plist = PropList::DEFAULT); // default constructor Group(); diff --git a/c++/src/H5IdComponent.cpp b/c++/src/H5IdComponent.cpp index 4a997ab..c60d05c 100644 --- a/c++/src/H5IdComponent.cpp +++ b/c++/src/H5IdComponent.cpp @@ -144,6 +144,8 @@ int IdComponent::getCounter() const //-------------------------------------------------------------------------- H5I_type_t IdComponent::getHDFObjType(const hid_t obj_id) { + if (obj_id == 0) + return H5I_BADID; // invalid H5I_type_t id_type = H5Iget_type(obj_id); if (id_type <= H5I_BADID || id_type >= H5I_NTYPES) return H5I_BADID; // invalid @@ -269,7 +271,7 @@ IdComponent::IdComponent() {} // Description: // This function is protected so that the user applications can // only have access to its code via allowable classes, namely, -// H5File and H5Object subclasses. +// Attribute and H5Location subclasses. // Programmer Binh-Minh Ribler - Jul, 2004 //-------------------------------------------------------------------------- H5std_string IdComponent::p_get_file_name() const @@ -314,6 +316,9 @@ H5std_string IdComponent::p_get_file_name() const //-------------------------------------------------------------------------- bool IdComponent::p_valid_id(const hid_t obj_id) { + if (obj_id == 0) + return false; + H5I_type_t id_type = H5Iget_type(obj_id); if (id_type <= H5I_BADID || id_type >= H5I_NTYPES) return false; diff --git a/c++/src/H5Location.cpp b/c++/src/H5Location.cpp index fcf7ff4..22db85c 100644 --- a/c++/src/H5Location.cpp +++ b/c++/src/H5Location.cpp @@ -55,17 +55,17 @@ extern "C" herr_t userAttrOpWrpr(hid_t loc_id, const char *attr_name, } //-------------------------------------------------------------------------- -// Function: H5Location default constructor (protected) -// Programmer Binh-Minh Ribler - 2000 +// Function: H5Location default constructor (protected) +// Programmer Binh-Minh Ribler - 2000 //-------------------------------------------------------------------------- -H5Location::H5Location() : IdComponent(0) {} +H5Location::H5Location() : IdComponent() {} //-------------------------------------------------------------------------- -// Function: H5Location overloaded constructor (protected) -// Purpose Creates an H5Location object using the id of an existing HDF5 -// object. -// Parameters object_id - IN: Id of an existing HDF5 object -// Programmer Binh-Minh Ribler - 2000 +// Function: H5Location overloaded constructor (protected) +// Purpose Creates an H5Location object using the id of an existing HDF5 +// object. +// Parameters object_id - IN: Id of an existing HDF5 object +// Programmer Binh-Minh Ribler - 2000 //-------------------------------------------------------------------------- H5Location::H5Location(const hid_t object_id) : IdComponent(object_id) {} @@ -342,7 +342,7 @@ void H5Location::renameAttr(const H5std_string& oldname, const H5std_string& new /// 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::FileIException +///\exception H5::Exception ///\par Description /// This location is used to identify the file to be flushed. // Programmer Binh-Minh Ribler - 2012 @@ -355,7 +355,7 @@ void H5Location::flush(H5F_scope_t scope) const herr_t ret_value = H5Fflush(getId(), scope); if( ret_value < 0 ) { - throw FileIException(inMemFunc("flush"), "H5Fflush failed"); + throw Exception(inMemFunc("flush"), "H5Fflush failed"); } } @@ -376,41 +376,199 @@ H5std_string H5Location::getFileName() const } } +//-------------------------------------------------------------------------- +// Function: H5Location::setComment +///\brief Sets or resets the comment for an object specified by its name. +///\param name - IN: Name of the object +///\param comment - IN: New comment +///\exception H5::Exception +///\par Description +/// If \a comment is an empty string or a null pointer, the comment +/// message is removed from the object. +/// Comments should be relatively short, null-terminated, ASCII +/// strings. They can be attached to any object that has an +/// object header, e.g., data sets, groups, named data types, +/// and data spaces, but not symbolic links. +// Programmer Binh-Minh Ribler - 2000 (moved from CommonFG, Sep 2013) +// Modification +// 2007: QAK modified to use H5O APIs; however the first parameter is +// no longer just file or group, this function should be moved +// to another class to accommodate attribute, dataset, and named +// datatype. - BMR +//-------------------------------------------------------------------------- +void H5Location::setComment(const char* name, const char* comment) const +{ + herr_t ret_value = H5Oset_comment_by_name(getId(), name, comment, H5P_DEFAULT); + if( ret_value < 0 ) + throw Exception(inMemFunc("setComment"), "H5Oset_comment_by_name failed"); +} + +//-------------------------------------------------------------------------- +// Function: H5Location::setComment +///\brief This is an overloaded member function, provided for convenience. +/// It differs from the above function in that it takes an +/// \c H5std_string for \a name and \a comment. +// Programmer Binh-Minh Ribler - 2000 (moved from CommonFG, Sep 2013) +//-------------------------------------------------------------------------- +void H5Location::setComment(const H5std_string& name, const H5std_string& comment) const +{ + setComment(name.c_str(), comment.c_str()); +} + +//-------------------------------------------------------------------------- +// Function: H5Location::setComment +///\brief This is an overloaded member function, provided for convenience. +/// It differs from the above function in that it doesn't take +/// an object name. +// Programmer Binh-Minh Ribler - Sep 2013 +// Modification +//-------------------------------------------------------------------------- +void H5Location::setComment(const char* comment) const +{ + herr_t ret_value = H5Oset_comment_by_name(getId(), ".", comment, H5P_DEFAULT); + if( ret_value < 0 ) + throw Exception(inMemFunc("setComment"), "H5Oset_comment_by_name failed"); +} + +//-------------------------------------------------------------------------- +// Function: H5Location::setComment +///\brief This is an overloaded member function, provided for convenience. +/// It differs from the above function in that it takes an +/// \c H5std_string for \a comment. +// Programmer Binh-Minh Ribler - Sep 2013 +//-------------------------------------------------------------------------- +void H5Location::setComment(const H5std_string& comment) const +{ + setComment(comment.c_str()); +} + +//-------------------------------------------------------------------------- +// Function: H5Location::removeComment +///\brief Removes the comment from an object specified by its name. +///\param name - IN: Name of the object +///\exception H5::Exception +// Programmer Binh-Minh Ribler - May 2005 (moved from CommonFG, Sep 2013) +// 2007: QAK modified to use H5O APIs; however the first parameter is +// no longer just file or group, this function should be moved +// to another class to accommodate attribute, dataset, and named +// datatype. - BMR +//-------------------------------------------------------------------------- +void H5Location::removeComment(const char* name) const +{ + herr_t ret_value = H5Oset_comment_by_name(getId(), name, NULL, H5P_DEFAULT); + if( ret_value < 0 ) + throw Exception(inMemFunc("removeComment"), "H5Oset_comment_by_name failed"); +} + +//-------------------------------------------------------------------------- +// Function: H5Location::removeComment +///\brief This is an overloaded member function, provided for convenience. +/// It differs from the above function in that it takes an +/// \c H5std_string for \a name. +// Programmer Binh-Minh Ribler - May 2005 (moved from CommonFG, Sep 2013) +//-------------------------------------------------------------------------- +void H5Location::removeComment(const H5std_string& name) const +{ + removeComment (name.c_str()); +} + +//-------------------------------------------------------------------------- +// Function: H5Location::getComment +///\brief Retrieves comment for the specified object and its comment's +/// length. +///\param name - IN: Name of the object +///\param bufsize - IN: Length of the comment to retrieve +///\return Comment string +///\exception H5::Exception +// Programmer Binh-Minh Ribler - 2000 (moved from CommonFG, Sep 2013) +// 2007: QAK modified to use H5O APIs; however the first parameter is +// no longer just file or group, this function should be moved +// to another class to accommodate attribute, dataset, and named +// datatype. - BMR +//-------------------------------------------------------------------------- +H5std_string H5Location::getComment(const char* name, size_t bufsize) const +{ + // bufsize is default to 256 + // temporary variable + hid_t loc_id = getId(); // temporary variable + + // temporary C-string for the object's comment; bufsize already including + // null character + char* comment_C = new char[bufsize]; + ssize_t ret_value = H5Oget_comment_by_name(loc_id, name, comment_C, bufsize, H5P_DEFAULT); + + // if the actual length of the comment is longer than bufsize and bufsize + // was the default value, i.e., not given by the user, then call + // H5Oget_comment_by_name again with the correct value. + // If the call to H5Oget_comment_by_name returned an error, skip this block + // and throw an exception below. + if (ret_value >= 0 && (size_t)ret_value > bufsize && bufsize == 256) + { + size_t new_size = ret_value; + delete []comment_C; + comment_C = new char[new_size]; // new_size including null terminator + ret_value = H5Oget_comment_by_name(loc_id, name, comment_C, new_size, H5P_DEFAULT); + } + + // if H5Oget_comment_by_name returns SUCCEED, return the string comment, + // otherwise, throw an exception + if (ret_value < 0) { + delete []comment_C; + throw Exception(inMemFunc("getComment"), "H5Oget_comment_by_name failed"); + } + + H5std_string comment = H5std_string(comment_C); + delete []comment_C; + return (comment); +} + +//-------------------------------------------------------------------------- +// Function: H5Location::getComment +///\brief This is an overloaded member function, provided for convenience. +/// It differs from the above function in that it takes an +/// \c H5std_string for \a name. +// Programmer Binh-Minh Ribler - 2000 (moved from CommonFG, Sep 2013) +//-------------------------------------------------------------------------- +H5std_string H5Location::getComment(const H5std_string& name, size_t bufsize) const +{ + return(getComment(name.c_str(), bufsize)); +} #ifndef DOXYGEN_SHOULD_SKIP_THIS //-------------------------------------------------------------------------- -// Function: H5Location::p_reference (protected) -// Purpose Creates a reference to an HDF5 object or a dataset region. +// Function: H5Location::p_reference (protected) +// Purpose Creates a reference to an HDF5 object or a dataset region. // Parameters -// name - IN: Name of the object to be referenced -// dataspace - IN: Dataspace with selection -// ref_type - IN: Type of reference; default to \c H5R_DATASET_REGION -// Exception H5::IdComponentException -// Programmer Binh-Minh Ribler - May, 2004 +// name - IN: Name of the object to be referenced +// dataspace - IN: Dataspace with selection +// ref_type - IN: Type of reference; default to \c H5R_DATASET_REGION +// Exception H5::IdComponentException +// Programmer Binh-Minh Ribler - May, 2004 //-------------------------------------------------------------------------- void H5Location::p_reference(void* ref, const char* name, hid_t space_id, H5R_type_t ref_type) const { herr_t ret_value = H5Rcreate(ref, getId(), name, ref_type, space_id); if (ret_value < 0) { - throw ReferenceException("", "H5Rcreate failed"); + throw ReferenceException(inMemFunc("reference"), "H5Rcreate failed"); } } #endif // DOXYGEN_SHOULD_SKIP_THIS //-------------------------------------------------------------------------- -// Function: H5Location::reference -///\brief Creates a reference to an HDF5 object or a dataset region. -///\param ref - IN: Reference pointer -///\param name - IN: Name of the object to be referenced -///\param dataspace - IN: Dataspace with selection -///\param ref_type - IN: Type of reference to query, valid values are: +// Function: H5Location::reference +///\brief Creates a reference to an HDF5 object or a dataset region. +///\param ref - IN: Reference pointer +///\param name - IN: Name of the object to be referenced +///\param dataspace - IN: Dataspace with selection +///\param ref_type - IN: Type of reference to query, valid values are: /// \li \c H5R_OBJECT - Reference is an object reference. /// \li \c H5R_DATASET_REGION - Reference is a dataset region /// reference. - this is the default -///\exception H5::ReferenceException -// Programmer Binh-Minh Ribler - May, 2004 +///\exception H5::ReferenceException +///\notes This method is more suitable for a dataset region reference. +// Programmer Binh-Minh Ribler - May, 2004 //-------------------------------------------------------------------------- void H5Location::reference(void* ref, const char* name, const DataSpace& dataspace, H5R_type_t ref_type) const { @@ -418,46 +576,76 @@ void H5Location::reference(void* ref, const char* name, const DataSpace& dataspa p_reference(ref, name, dataspace.getId(), ref_type); } catch (ReferenceException E) { - throw ReferenceException("H5Location::reference", E.getDetailMsg()); + throw ReferenceException(inMemFunc("reference"), E.getDetailMsg()); } } //-------------------------------------------------------------------------- -// Function: H5Location::reference -///\brief This is an overloaded function, provided for your convenience. -/// It differs from the above function in that it only creates -/// a reference to an HDF5 object, not to a dataset region. -///\param ref - IN: Reference pointer -///\param name - IN: Name of the object to be referenced - \c char pointer -///\exception H5::ReferenceException -///\par Description -// This function passes H5R_OBJECT and -1 to the protected -// function for it to pass to the C API H5Rcreate -// to create a reference to the named object. -// Programmer Binh-Minh Ribler - May, 2004 +// Function: H5Location::reference +///\brief This is an overloaded member function, provided for convenience. +/// It differs from the above function in that it takes an +/// \c H5std_string for \a name. +///\param ref - IN: Reference pointer +///\param name - IN: Name of the object to be referenced +///\param dataspace - IN: Dataspace with selection +///\param ref_type - IN: Type of reference to query, valid values are: +/// \li \c H5R_OBJECT - Reference is an object reference. +/// \li \c H5R_DATASET_REGION - Reference is a dataset region +/// reference. - this is the default +///\exception H5::ReferenceException +///\notes This method is more suitable for a dataset region reference. +// Programmer Binh-Minh Ribler - May, 2004 //-------------------------------------------------------------------------- -void H5Location::reference(void* ref, const char* name) const +void H5Location::reference(void* ref, const H5std_string& name, const DataSpace& dataspace, H5R_type_t ref_type) const { try { - p_reference(ref, name, -1, H5R_OBJECT); + p_reference(ref, name.c_str(), dataspace.getId(), ref_type); } catch (ReferenceException E) { - throw ReferenceException("H5Location::reference", E.getDetailMsg()); + throw ReferenceException(inMemFunc("reference"), E.getDetailMsg()); } } //-------------------------------------------------------------------------- -// Function: H5Location::reference -///\brief This is an overloaded function, provided for your convenience. -/// It differs from the above function in that it takes an -/// \c H5std_string for the object's name. -///\param ref - IN: Reference pointer -///\param name - IN: Name of the object to be referenced - \c H5std_string -// Programmer Binh-Minh Ribler - May, 2004 +// Function: H5Location::reference +///\brief This is an overloaded function, provided for your convenience. +/// It differs from the above function in that it does not take +/// a DataSpace object and the reference type must be specified. +///\param ref - IN: Reference pointer +///\param name - IN: Name of the object to be referenced +///\param ref_type - IN: Type of reference to query, valid values are: +/// \li \c H5R_OBJECT - Reference is an object reference. +/// \li \c H5R_DATASET_REGION - Reference is a dataset region +///\exception H5::ReferenceException +///\notes This method is more suitable for an object reference. +// Programmer Binh-Minh Ribler - May, 2004 +//-------------------------------------------------------------------------- +void H5Location::reference(void* ref, const char* name, H5R_type_t ref_type) const +{ + try { + p_reference(ref, name, -1, ref_type); + } + catch (ReferenceException E) { + throw ReferenceException(inMemFunc("reference"), E.getDetailMsg()); + } +} + +//-------------------------------------------------------------------------- +// Function: H5Location::reference +///\brief This is an overloaded function, provided for your convenience. +/// It differs from the above function in that it takes an +/// \c H5std_string for the object's name. +///\param ref - IN: Reference pointer +///\param name - IN: Name of the object to be referenced - \c H5std_string +///\param ref_type - IN: Type of reference to query, valid values are: +/// \li \c H5R_OBJECT - Reference is an object reference. +/// \li \c H5R_DATASET_REGION - Reference is a dataset region +///\notes This method is more suitable for an object reference. +// Programmer Binh-Minh Ribler - May, 2004 //-------------------------------------------------------------------------- -void H5Location::reference(void* ref, const H5std_string& name) const +void H5Location::reference(void* ref, const H5std_string& name, H5R_type_t ref_type) const { - reference(ref, name.c_str()); + reference(ref, name.c_str(), ref_type); } #ifndef DOXYGEN_SHOULD_SKIP_THIS @@ -475,16 +663,20 @@ void H5Location::reference(void* ref, const H5std_string& name) const // May 2008 - BMR // Moved from IdComponent. //-------------------------------------------------------------------------- -hid_t H5Location::p_dereference(hid_t loc_id, const void* ref, H5R_type_t ref_type) +hid_t H5Location::p_dereference(hid_t loc_id, const void* ref, H5R_type_t ref_type, const PropList& plist, const char* from_func) { - hid_t temp_id; - temp_id = H5Rdereference2(loc_id, H5P_DEFAULT, ref_type, ref); + hid_t plist_id; + if (p_valid_id(plist.getId())) + plist_id = plist.getId(); + else + plist_id = H5P_DEFAULT; + + hid_t temp_id = H5Rdereference2(loc_id, plist_id, ref_type, ref); if (temp_id < 0) { - throw ReferenceException("", "H5Rdereference failed"); + throw ReferenceException(inMemFunc(from_func), "H5Rdereference failed"); } - // No failure, set id to the object return(temp_id); } #endif // DOXYGEN_SHOULD_SKIP_THIS @@ -496,45 +688,14 @@ hid_t H5Location::p_dereference(hid_t loc_id, const void* ref, H5R_type_t ref_ty ///\param ref - IN: Reference pointer ///\param ref_type - IN: Reference type ///\exception H5::ReferenceException -// Programmer Binh-Minh Ribler - Oct, 2006 -// Modification -// May, 2008 -// Corrected missing parameters. - BMR -//-------------------------------------------------------------------------- -void H5Location::dereference(H5Object& obj, const void* ref, H5R_type_t ref_type) -{ - hid_t temp_id; - try { - temp_id = p_dereference(obj.getId(), ref, ref_type); - } - catch (ReferenceException E) { - throw ReferenceException("H5Location::dereference - located by object", E.getDetailMsg()); - } - p_setId(temp_id); -} - -//-------------------------------------------------------------------------- -// Function: H5Location::dereference -///\brief Dereferences a reference into an HDF5 object, given an HDF5 file. -///\param h5file - IN: HDF5 file specifying the location of the referenced object -///\param ref - IN: Reference pointer -///\param ref_type - IN: Reference type -///\exception H5::ReferenceException -// Programmer Binh-Minh Ribler - Oct, 2006 +// Programmer Binh-Minh Ribler - Oct, 2006 // Modification // May, 2008 // Corrected missing parameters. - BMR //-------------------------------------------------------------------------- -void H5Location::dereference(H5File& h5file, const void* ref, H5R_type_t ref_type) +void H5Location::dereference(const H5Location& loc, const void* ref, H5R_type_t ref_type, const PropList& plist) { - hid_t temp_id; - try { - temp_id = p_dereference(h5file.getId(), ref, ref_type); - } - catch (ReferenceException E) { - throw ReferenceException("H5Location::dereference - located by file", E.getDetailMsg()); - } - p_setId(temp_id); + p_setId(p_dereference(loc.getId(), ref, ref_type, plist, "dereference")); } //-------------------------------------------------------------------------- @@ -544,21 +705,14 @@ void H5Location::dereference(H5File& h5file, const void* ref, H5R_type_t ref_typ ///\param ref - IN: Reference pointer ///\param ref_type - IN: Reference type ///\exception H5::ReferenceException -// Programmer Binh-Minh Ribler - Oct, 2006 +// Programmer Binh-Minh Ribler - Oct, 2006 // Modification // May, 2008 // Corrected missing parameters. - BMR //-------------------------------------------------------------------------- -void H5Location::dereference(Attribute& attr, const void* ref, H5R_type_t ref_type) +void H5Location::dereference(const Attribute& attr, const void* ref, H5R_type_t ref_type, const PropList& plist) { - hid_t temp_id; - try { - temp_id = p_dereference(attr.getId(), ref, ref_type); - } - catch (ReferenceException E) { - throw ReferenceException("H5Location::dereference - located by attribute", E.getDetailMsg()); - } - p_setId(temp_id); + p_setId(p_dereference(attr.getId(), ref, ref_type, plist, "dereference")); } #ifndef H5_NO_DEPRECATED_SYMBOLS @@ -587,26 +741,26 @@ H5G_obj_t H5Location::getObjType(void *ref, H5R_type_t ref_type) const return(p_get_obj_type(ref, ref_type)); } catch (ReferenceException E) { - throw ReferenceException("H5Location::getObjType", E.getDetailMsg()); + throw ReferenceException(inMemFunc("getObjType"), E.getDetailMsg()); } } #ifndef DOXYGEN_SHOULD_SKIP_THIS //-------------------------------------------------------------------------- -// Function: H5Location::p_get_obj_type (protected) -// Purpose Retrieves the type of object that an object reference points to. +// Function: H5Location::p_get_obj_type (protected) +// Purpose Retrieves the type of object that an object reference points to. // Parameters -// ref - IN: Reference to query -// ref_type - IN: Type of reference to query -// Return An object type, which can be one of the following: -// H5G_UNKNOWN \tFailure occurs (-1) -// H5G_GROUP \tObject is a group. -// H5G_DATASET \tObject is a dataset. -// H5G_TYPE Object \tis a named datatype. -// H5G_LINK \tObject is a symbolic link. -// H5G_UDLINK \tObject is a user-defined link. -// Exception H5::ReferenceException -// Programmer Binh-Minh Ribler - May, 2004 +// ref - IN: Reference to query +// ref_type - IN: Type of reference to query +// Return An object type, which can be one of the following: +// H5G_UNKNOWN \tFailure occurs (-1) +// H5G_GROUP \tObject is a group. +// H5G_DATASET \tObject is a dataset. +// H5G_TYPE Object \tis a named datatype. +// H5G_LINK \tObject is a symbolic link. +// H5G_UDLINK \tObject is a user-defined link. +// Exception H5::ReferenceException +// Programmer Binh-Minh Ribler - May, 2004 //-------------------------------------------------------------------------- H5G_obj_t H5Location::p_get_obj_type(void *ref, H5R_type_t ref_type) const { @@ -614,7 +768,7 @@ H5G_obj_t H5Location::p_get_obj_type(void *ref, H5R_type_t ref_type) const if (obj_type == H5G_UNKNOWN) { - throw ReferenceException("", "H5Rget_obj_type1 failed"); + throw ReferenceException(inMemFunc("getObjType"), "H5Rget_obj_type1 failed"); } return(obj_type); } @@ -622,20 +776,20 @@ H5G_obj_t H5Location::p_get_obj_type(void *ref, H5R_type_t ref_type) const #endif /* H5_NO_DEPRECATED_SYMBOLS */ //-------------------------------------------------------------------------- -// Function: H5Location::getRefObjType -///\brief Retrieves the type of object that an object reference points to. -///\param ref - IN: Reference to query -///\param ref_type - IN: Type of reference to query, valid values are: -/// \li \c H5R_OBJECT - Reference is an object reference. -/// \li \c H5R_DATASET_REGION - Reference is a dataset region reference. -///\return An object type, which can be one of the following: -/// \li \c H5O_TYPE_UNKNOWN - Unknown object type (-1) -/// \li \c H5O_TYPE_GROUP - Object is a group -/// \li \c H5O_TYPE_DATASET - Object is a dataset -/// \li \c H5O_TYPE_NAMED_DATATYPE - Object is a named datatype -/// \li \c H5O_TYPE_NTYPES - Number of different object types -///\exception H5::ReferenceException -// Programmer Binh-Minh Ribler - May, 2004 +// Function: H5Location::getRefObjType +///\brief Retrieves the type of object that an object reference points to. +///\param ref - IN: Reference to query +///\param ref_type - IN: Type of reference to query, valid values are: +/// \li \c H5R_OBJECT - Reference is an object reference. +/// \li \c H5R_DATASET_REGION - Reference is a dataset region reference. +///\return An object type, which can be one of the following: +/// \li \c H5O_TYPE_UNKNOWN - Unknown object type (-1) +/// \li \c H5O_TYPE_GROUP - Object is a group +/// \li \c H5O_TYPE_DATASET - Object is a dataset +/// \li \c H5O_TYPE_NAMED_DATATYPE - Object is a named datatype +/// \li \c H5O_TYPE_NTYPES - Number of different object types +///\exception H5::ReferenceException +// Programmer Binh-Minh Ribler - May, 2004 //-------------------------------------------------------------------------- H5O_type_t H5Location::getRefObjType(void *ref, H5R_type_t ref_type) const { @@ -643,25 +797,25 @@ H5O_type_t H5Location::getRefObjType(void *ref, H5R_type_t ref_type) const return(p_get_ref_obj_type(ref, ref_type)); } catch (ReferenceException E) { - throw ReferenceException("H5Location::getRefObjType", E.getDetailMsg()); + throw ReferenceException(inMemFunc("getRefObjType"), E.getDetailMsg()); } } #ifndef DOXYGEN_SHOULD_SKIP_THIS //-------------------------------------------------------------------------- -// Function: H5Location::p_get_ref_obj_type (protected) -// Purpose Retrieves the type of object that an object reference points to. +// Function: H5Location::p_get_ref_obj_type (protected) +// Purpose Retrieves the type of object that an object reference points to. // Parameters -// ref - IN: Reference to query -// ref_type - IN: Type of reference to query -// Return An object type, which can be one of the following: +// ref - IN: Reference to query +// ref_type - IN: Type of reference to query +// Return An object type, which can be one of the following: // H5O_TYPE_UNKNOWN - Unknown object type (-1) // H5O_TYPE_GROUP - Object is a group // H5O_TYPE_DATASET - Object is a dataset // H5O_TYPE_NAMED_DATATYPE - Object is a named datatype // H5O_TYPE_NTYPES - Number of object types -// Exception H5::ReferenceException -// Programmer Binh-Minh Ribler - May, 2004 +// Exception H5::ReferenceException +// Programmer Binh-Minh Ribler - May, 2004 //-------------------------------------------------------------------------- H5O_type_t H5Location::p_get_ref_obj_type(void *ref, H5R_type_t ref_type) const { @@ -670,31 +824,36 @@ H5O_type_t H5Location::p_get_ref_obj_type(void *ref, H5R_type_t ref_type) const if (obj_type == H5O_TYPE_UNKNOWN || obj_type >= H5O_TYPE_NTYPES) { - throw ReferenceException("", "H5Rget_obj_type2 failed"); + throw ReferenceException(inMemFunc("getRefObjType"), "H5Rget_obj_type2 failed"); } return(obj_type); } //-------------------------------------------------------------------------- -// Function: H5Location::p_get_region (protected) -// Purpose Retrieves a dataspace with the region pointed to selected. -// Parameters -// ref_type - IN: Type of reference to get region of - default -// to H5R_DATASET_REGION -// ref - IN: Reference to get region of -// Return Dataspace id -// Exception H5::ReferenceException -// Programmer Binh-Minh Ribler - May, 2004 +// Function: H5Location::getRegion +///\brief Retrieves a dataspace with the region pointed to selected. +///\param ref - IN: Reference to get region of +///\param ref_type - IN: Type of reference to get region of - default +// to H5R_DATASET_REGION +///\return DataSpace object +///\exception H5::ReferenceException +// Programmer Binh-Minh Ribler - May, 2004 //-------------------------------------------------------------------------- -hid_t H5Location::p_get_region(void *ref, H5R_type_t ref_type) const +DataSpace H5Location::getRegion(void *ref, H5R_type_t ref_type) const { hid_t space_id = H5Rget_region(getId(), ref_type, ref); if (space_id < 0) { - throw ReferenceException("", "H5Rget_region failed"); + throw ReferenceException(inMemFunc("getRegion"), "H5Rget_region failed"); + } + try { + DataSpace dataspace(space_id); + return(dataspace); + } + catch (DataSpaceIException E) { + throw ReferenceException(inMemFunc("getRegion"), E.getDetailMsg()); } - return(space_id); } diff --git a/c++/src/H5Location.h b/c++/src/H5Location.h index 1f54439..50278db 100644 --- a/c++/src/H5Location.h +++ b/c++/src/H5Location.h @@ -36,12 +36,12 @@ typedef void (*attr_operator_t)( H5Location& loc/*in*/, class UserData4Aiterate { // user data for attribute iteration public: - attr_operator_t op; - void* opData; - H5Location* location; + attr_operator_t op; + void* opData; + H5Location* location; }; -// An H5Location can be a file, group, dataset, named datatype, or attribute. +// An H5Location can be a file, group, dataset, or committed datatype. class H5_DLLCPP H5Location : public IdComponent { public: @@ -85,29 +85,49 @@ class H5_DLLCPP H5Location : public IdComponent { bool attrExists(const char* name) const; bool attrExists(const H5std_string& name) const; + // Renames the named attribute to a new name. + void renameAttr(const char* oldname, const char* newname) const; + void renameAttr(const H5std_string& oldname, const H5std_string& newname) const; + // Removes the named attribute from this location. void removeAttr(const char* name) const; void removeAttr(const H5std_string& name) const; - // Renames the named attribute to a new name. - void renameAttr(const char* oldname, const char* newname) const; - void renameAttr(const H5std_string& oldname, const H5std_string& newname) 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; + void setComment(const char* comment) const; + void setComment(const H5std_string& comment) const; + + // Retrieves comment for the HDF5 object specified by its name. + H5std_string getComment(const char* name, size_t bufsize=256) const; + H5std_string getComment(const H5std_string& name, size_t bufsize=256) const; + + // Removes the comment for the HDF5 object specified by its name. + void removeComment(const char* name) const; + void removeComment(const H5std_string& name) const; // Creates a reference to a named object or to a dataset region // in this object. + void reference(void* ref, const char* name, + H5R_type_t ref_type = H5R_OBJECT) const; + void reference(void* ref, const H5std_string& name, + H5R_type_t ref_type = H5R_DATASET_REGION) const; void reference(void* ref, const char* name, const DataSpace& dataspace, H5R_type_t ref_type = H5R_DATASET_REGION) const; - void reference(void* ref, const char* name) const; - void reference(void* ref, const H5std_string& name) const; + void reference(void* ref, const H5std_string& name, const DataSpace& dataspace, + H5R_type_t ref_type = H5R_DATASET_REGION) const; // Open a referenced object whose location is specified by either // a file, an HDF5 object, or an attribute. - void dereference(H5File& h5file, const void* ref, H5R_type_t ref_type = H5R_OBJECT); - void dereference(H5Object& obj, const void* ref, H5R_type_t ref_type = H5R_OBJECT); - void dereference(Attribute& attr, const void* ref, H5R_type_t ref_type = H5R_OBJECT); + void dereference(const H5Location& loc, const void* ref, H5R_type_t ref_type = H5R_OBJECT, const PropList& plist = PropList::DEFAULT); + void dereference(const Attribute& attr, const void* ref, H5R_type_t ref_type = H5R_OBJECT, const PropList& plist = PropList::DEFAULT); - ///\brief Returns an identifier. (pure virtual) - virtual hid_t getId() const = 0; + // Retrieves a dataspace with the region pointed to selected. + DataSpace getRegion(void *ref, H5R_type_t ref_type = H5R_DATASET_REGION) const; + + ///\brief Returns an identifier. (pure virtual) + virtual hid_t getId() const = 0; protected: #ifndef DOXYGEN_SHOULD_SKIP_THIS @@ -124,7 +144,7 @@ class H5_DLLCPP H5Location : public IdComponent { void p_reference(void* ref, const char* name, hid_t space_id, H5R_type_t ref_type) const; // Dereferences a ref into an HDF5 id. - hid_t p_dereference(hid_t loc_id, const void* ref, H5R_type_t ref_type); + hid_t p_dereference(hid_t loc_id, const void* ref, H5R_type_t ref_type, const PropList& plist, const char* from_func); #ifndef H5_NO_DEPRECATED_SYMBOLS // Retrieves the type of object that an object reference points to. @@ -134,9 +154,6 @@ class H5_DLLCPP H5Location : public IdComponent { // Retrieves the type of object that an object reference points to. H5O_type_t p_get_ref_obj_type(void *ref, H5R_type_t ref_type) const; - // Retrieves a dataspace with the region pointed to selected. - hid_t p_get_region(void *ref, H5R_type_t ref_type) const; - // Noop destructor. virtual ~H5Location(); diff --git a/c++/src/H5Object.cpp b/c++/src/H5Object.cpp index b596092..1d96f2e 100644 --- a/c++/src/H5Object.cpp +++ b/c++/src/H5Object.cpp @@ -52,7 +52,6 @@ H5Object::H5Object() : H5Location() {} //-------------------------------------------------------------------------- H5Object::H5Object( const hid_t object_id ) : H5Location( object_id ) {} - //-------------------------------------------------------------------------- // Function: H5Object copy constructor ///\brief Copy constructor: makes a copy of the original H5Object diff --git a/c++/src/H5PropList.cpp b/c++/src/H5PropList.cpp index c14d74f..9476d46 100644 --- a/c++/src/H5PropList.cpp +++ b/c++/src/H5PropList.cpp @@ -39,7 +39,7 @@ namespace H5 { //-------------------------------------------------------------------------- ///\brief Constant for default property. //-------------------------------------------------------------------------- -const PropList PropList::DEFAULT( H5P_DEFAULT ); +const PropList PropList::DEFAULT; //-------------------------------------------------------------------------- // Function Default constructor @@ -74,6 +74,9 @@ PropList::PropList(const PropList& original) : IdComponent(original) //-------------------------------------------------------------------------- PropList::PropList( const hid_t plist_id ) : IdComponent() { + if (plist_id == 0) + id = H5P_DEFAULT; + H5I_type_t id_type = H5Iget_type(plist_id); switch (id_type) { case H5I_GENPROP_CLS: diff --git a/c++/test/dsets.cpp b/c++/test/dsets.cpp index 58436f1..811d8c7 100644 --- a/c++/test/dsets.cpp +++ b/c++/test/dsets.cpp @@ -1058,7 +1058,7 @@ void test_dset() // Cause the library to emit initial messages Group grp = file.createGroup( "emit diagnostics", 0); - grp.setComment( ".", "Causes diagnostic messages to be emitted"); + grp.setComment("Causes diagnostic messages to be emitted"); nerrors += test_create(file)<0 ?1:0; nerrors += test_simple_io(file)<0 ?1:0; diff --git a/c++/test/h5cpputil.cpp b/c++/test/h5cpputil.cpp index c6a7a2a..cd85b6e 100644 --- a/c++/test/h5cpputil.cpp +++ b/c++/test/h5cpputil.cpp @@ -107,6 +107,30 @@ void issue_fail_msg(const char* where, int line, const char* file_name, } /*------------------------------------------------------------------------- + * Function: issue_fail_msg + * + * Purpose: Displays that a function has failed with its location. + * + * Return: None + * + * Programmer: Binh-Minh Ribler (copied and modified macro CHECK from C) + * Monday, December 20, 2004 + * + *------------------------------------------------------------------------- + */ +void issue_fail_msg(const char* where, int line, const char* file_name, + const char* func_name, const char* message) +{ + //if (GetTestVerbosity()>=VERBO_HI) + { + cerr << endl; + cerr << ">>> FAILED in " << where << ": " << func_name << endl << + " at line " << line << " in " << file_name << endl << + " C library detail: " << message << endl << endl; + } +} + +/*------------------------------------------------------------------------- * Function: check_values * * Purpose: Checks a read value against the written value. If they are diff --git a/c++/test/h5cpputil.h b/c++/test/h5cpputil.h index 02f3d0d..e6aba79 100644 --- a/c++/test/h5cpputil.h +++ b/c++/test/h5cpputil.h @@ -42,6 +42,8 @@ int check_values (hsize_t i, hsize_t j, int apoint, int acheck); int test_report (int, const H5std_string&); void issue_fail_msg(const char* where, int line, const char* file_name, const char* message=""); +void issue_fail_msg(const char* where, int line, const char* file_name, + const char* func_name, const char* message); class InvalidActionException : public Exception { public: diff --git a/c++/test/trefer.cpp b/c++/test/trefer.cpp index ce18e58..36c2ee4 100644 --- a/c++/test/trefer.cpp +++ b/c++/test/trefer.cpp @@ -27,13 +27,6 @@ #endif #include -#ifndef H5_NO_NAMESPACE -#ifndef H5_NO_STD - using std::cerr; - using std::endl; -#endif // H5_NO_STD -#endif - #include "H5Cpp.h" // C++ API header file #ifndef H5_NO_NAMESPACE @@ -44,27 +37,25 @@ const H5std_string FILE1("trefer1.h5"); const H5std_string FILE2("trefer2.h5"); -const H5std_string FILE3("trefer3.h5"); -const H5std_string DSET_DEFAULT_NAME("default"); // Dataset 1 const H5std_string DSET1_NAME("Dataset1"); -const int DSET1_LEN = 8; +const H5std_string DSET2_NAME("Dataset2"); const H5std_string MEMBER1( "a_name" ); const H5std_string MEMBER2( "b_name" ); const H5std_string MEMBER3( "c_name" ); // 1-D dataset with fixed dimensions -const H5std_string SPACE1_NAME("Space1"); const int SPACE1_RANK = 1; const int SPACE1_DIM1 = 4; -// 2-D dataset with fixed dimensions -const H5std_string SPACE2_NAME("Space2"); +/* Larger 1-D dataset with fixed dimensions */ +const int SPACE3_RANK = 1; +const int SPACE3_DIM1 = 100; -// Larger 1-D dataset with fixed dimensions -const H5std_string SPACE3_NAME("Space3"); +/* Element selection information */ +const int POINT1_NPOINTS = 10; // Compound datatype typedef struct s1_t { @@ -75,8 +66,123 @@ typedef struct s1_t { /**************************************************************** ** -** test_reference_obj(): Test basic object reference functionality. -** Tests references to various kinds of objects +** test_reference_params(): Test basic H5R (reference) parameters +** for correct processing +** +****************************************************************/ +static void +test_reference_params(void) +{ + const char *write_comment = "Foo!"; /* Comments for group */ + + // Output message about test being performed + SUBTEST("Object Reference Parameters"); + + H5File* file1 = NULL; + try { + hobj_ref_t *wbuf, // buffer to write to disk + *rbuf, // buffer read from disk + *tbuf; // temp. buffer read from disk + + // Allocate write & read buffers + int temp_size = MAX(sizeof(unsigned),sizeof(hobj_ref_t)); + wbuf=(hobj_ref_t*)HDmalloc(temp_size*SPACE1_DIM1); + rbuf=(hobj_ref_t*)HDmalloc(temp_size*SPACE1_DIM1); + tbuf=(hobj_ref_t*)HDmalloc(temp_size*SPACE1_DIM1); + + // Create file FILE1 + file1 = new H5File (FILE1, H5F_ACC_TRUNC); + + // Create dataspace for datasets + hsize_t dims1[] = {SPACE1_DIM1}; + DataSpace sid1(SPACE1_RANK, dims1); + + // Create a group + Group group = file1->createGroup("Group1"); + + // Set group's comment + group.setComment(".", write_comment); + + // Create a dataset (inside /Group1) + DataSet dataset = group.createDataSet(DSET1_NAME, PredType::NATIVE_UINT, sid1); + + unsigned *tu32; // Temporary pointer to uint32 data + int i; + for (tu32=(unsigned *)wbuf, i=0; icreateDataSet("Dataset3", PredType::STD_REF_OBJ, sid1); + + /* Test parameters to H5Location::reference */ + try { + file1->reference(NULL, "/Group1/Dataset1"); + } catch (ReferenceException E) {} // We expect this to fail + try { + file1->reference(&wbuf[0], NULL); + } catch (ReferenceException E) {} // We expect this to fail + try { + file1->reference(&wbuf[0], ""); + } catch (ReferenceException E) {} // We expect this to fail + try { + file1->reference(&wbuf[0], "/Group1/Dataset1", H5R_MAXTYPE); + } catch (ReferenceException E) {} // We expect this to fail + try { + file1->reference(&wbuf[0], "/Group1/Dataset1", H5R_DATASET_REGION); + } catch (ReferenceException E) {} // We expect this to fail + + // Close resources + dataset.close(); + file1->close(); + // Let sid1 go out of scope + + // Free memory buffers + HDfree(wbuf); + HDfree(rbuf); + HDfree(tbuf); + + PASSED(); + } // end try + catch (Exception E) { + issue_fail_msg("test_reference_param()",__LINE__,__FILE__, + E.getCFuncName(), E.getCDetailMsg()); + } + + if(file1) + delete file1; +} /* test_reference_param() */ + +/**************************************************************** +** +** test_reference_obj(): Test basic object reference functions +** to various kinds of objects ** ****************************************************************/ static void test_reference_obj(void) @@ -106,8 +212,11 @@ static void test_reference_obj(void) hsize_t dims1[] = {SPACE1_DIM1}; DataSpace sid1(SPACE1_RANK, dims1); + // Create dataset access property list + PropList dapl(H5P_DATASET_ACCESS); + // Create a group - Group group = file1->createGroup("Group1", (size_t)-1); + Group group = file1->createGroup("Group1"); // Set group's comment group.setComment(".", write_comment); @@ -116,7 +225,7 @@ static void test_reference_obj(void) DataSet dataset = group.createDataSet(DSET1_NAME, PredType::NATIVE_UINT, sid1); unsigned *tu32; // Temporary pointer to uint32 data - for (tu32=(unsigned *)wbuf, i=0; ireference(&wbuf[0], "/Group1/Dataset1"); H5O_type_t refobj_type = dataset.getRefObjType(&wbuf[0], H5R_OBJECT); - verify_val(refobj_type, H5O_TYPE_DATASET, "DataSet::getRefObjType", __LINE__, __FILE__); + verify_val(refobj_type, H5O_TYPE_DATASET, "DataSet::getRefObjType",__LINE__,__FILE__); // Create reference to dataset and test getRefObjType file1->reference(&wbuf[1], "/Group1/Dataset2"); refobj_type = dataset.getRefObjType(&wbuf[1], H5R_OBJECT); - verify_val(refobj_type, H5O_TYPE_DATASET, "DataSet::getRefObjType", __LINE__, __FILE__); + verify_val(refobj_type, H5O_TYPE_DATASET, "DataSet::getRefObjType",__LINE__,__FILE__); // Create reference to group file1->reference(&wbuf[2], "/Group1"); refobj_type = dataset.getRefObjType(&wbuf[2], H5R_OBJECT); - verify_val(refobj_type, H5O_TYPE_GROUP, "DataSet::getRefObjType", __LINE__, __FILE__); + verify_val(refobj_type, H5O_TYPE_GROUP, "DataSet::getRefObjType",__LINE__,__FILE__); // Create reference to named datatype file1->reference(&wbuf[3], "/Group1/Datatype1"); refobj_type = dataset.getRefObjType(&wbuf[3], H5R_OBJECT); - verify_val(refobj_type, H5O_TYPE_NAMED_DATATYPE, "DataSet::getRefObjType", __LINE__, __FILE__); + verify_val(refobj_type, H5O_TYPE_NAMED_DATATYPE, "DataSet::getRefObjType",__LINE__,__FILE__); // Write selection to disk dataset.write(wbuf, PredType::STD_REF_OBJ); @@ -188,18 +297,18 @@ static void test_reference_obj(void) // Dereference dataset object by ctor, from the location where // 'dataset' is located - DataSet dset2(dataset, &rbuf[0]); + DataSet dset2(dataset, &rbuf[0], H5R_OBJECT, dapl); // Check information in the referenced dataset sid1 = dset2.getSpace(); hssize_t n_elements = sid1.getSimpleExtentNpoints(); - verify_val((long)n_elements, 4, "DataSpace::getSimpleExtentNpoints", __LINE__, __FILE__); + verify_val((long)n_elements, 4, "DataSpace::getSimpleExtentNpoints",__LINE__,__FILE__); // Read from disk dset2.read(tbuf, PredType::NATIVE_UINT); - for(tu32=(unsigned *)tbuf,i=0; iclose(); - // Free memory buffers + // Free allocated buffers HDfree(wbuf); HDfree(rbuf); HDfree(tbuf); @@ -314,13 +356,431 @@ static void test_reference_obj(void) PASSED(); } // end try catch (Exception E) { - issue_fail_msg("test_reference_obj()", __LINE__, __FILE__, E.getCDetailMsg()); + issue_fail_msg("test_reference_obj()",__LINE__,__FILE__, + E.getCFuncName(), E.getCDetailMsg()); } if(file1) delete file1; } // test_reference_obj() + +/**************************************************************** +** +** test_reference_group(): Test object reference functionality +** Tests for correct behavior of various routines on +** dereferenced group +** +****************************************************************/ +#define GROUPNAME "/group" +#define GROUPNAME2 "group2" +#define GROUPNAME3 "group3" +#define DSETNAME "/dset" +#define DSETNAME2 "dset2" +#define NAME_SIZE 16 + +static void +test_reference_group(void) +{ + hobj_ref_t wref; /* Reference to write */ + hobj_ref_t rref; /* Reference to read */ + const H5std_string write_comment="Foo!"; // Comments for group + + // Output message about test being performed + SUBTEST("Object Reference to Group"); + + H5File* file1 = NULL; + try { + /* + * Create file with a group and a dataset containing an object + * reference to the group + */ + + // Create file FILE1 + file1 = new H5File (FILE1, H5F_ACC_TRUNC); + + // Create scalar dataspace + DataSpace sid1; + + // Create a group + Group group = file1->createGroup(GROUPNAME); + + /* Create nested groups */ + Group group2 = group.createGroup(GROUPNAME2); + group2.close(); + group2 = group.createGroup(GROUPNAME3); + group2.close(); + + // Create bottom dataset + DataSet dset1 = group.createDataSet(DSETNAME2, PredType::NATIVE_INT, sid1); + dset1.close(); + + // Close group 1 + group.close(); + + // Create dataset + DataSet dset2 = file1->createDataSet(DSETNAME, PredType::STD_REF_OBJ, sid1); + + file1->reference(&wref, GROUPNAME); + + // Write selection to disk + dset2.write(&wref, PredType::STD_REF_OBJ); + + // Close resources + dset2.close(); + sid1.close(); + file1->close(); + + /* + * Re-open the file and test deferencing group + */ + + // Re-open file + file1->openFile(FILE1, H5F_ACC_RDWR); + + // Re-open dataset + dset1 = file1->openDataSet(DSETNAME); + + // Read in the reference + dset1.read(&rref, PredType::STD_REF_OBJ); + + // Dereference to get the group + Group refgroup(dset1, &rref); + + // Dereference group object the other way + group.dereference(dset1, &rref); + + /* + * Various queries on the group opened + */ + + // Check number of objects in the group dereferenced by constructor + hsize_t nobjs = refgroup.getNumObjs(); + verify_val(nobjs, 3, "H5Group::getNumObjs",__LINE__,__FILE__); + + // Check number of objects in the group dereferenced by ::reference + nobjs = group.getNumObjs(); + verify_val(nobjs, 3, "H5Group::getNumObjs",__LINE__,__FILE__); + + // Check getting file name given the group dereferenced via constructor + H5std_string fname = refgroup.getFileName(); + verify_val(fname, FILE1, "H5Group::getFileName",__LINE__,__FILE__); + + // Check getting file name given the group dereferenced by ::reference + fname = group.getFileName(); + verify_val(fname, FILE1, "H5Group::getFileName",__LINE__,__FILE__); + + // Unlink one of the objects in the dereferenced group, and re-check + refgroup.unlink(GROUPNAME2); + nobjs = refgroup.getNumObjs(); + verify_val(nobjs, 2, "H5Group::getNumObjs",__LINE__,__FILE__); + + // Close resources + group.close(); + refgroup.close(); + dset1.close(); + file1->close(); + + PASSED(); + } // end try + catch (Exception E) { + issue_fail_msg("test_reference_group()",__LINE__,__FILE__, + E.getCFuncName(), E.getCDetailMsg()); + } + + if(file1) + delete file1; +} /* test_reference_group() */ + +/**************************************************************** +** +** test_reference_region_1D(): Test 1-D reference functionality +** Tests 1-D references to various kinds of objects +** +****************************************************************/ +static void +test_reference_region_1D(void) +{ + hsize_t start[SPACE3_RANK]; /* Starting location of hyperslab */ + hsize_t stride[SPACE3_RANK]; /* Stride of hyperslab */ + hsize_t count[SPACE3_RANK]; /* Element count of hyperslab */ + hsize_t block[SPACE3_RANK]; /* Block size of hyperslab */ + hsize_t coord1[POINT1_NPOINTS][SPACE3_RANK]; /* Coordinates for point selection */ + hsize_t * coords; /* Coordinate buffer */ + hsize_t low[SPACE3_RANK]; /* Selection bounds */ + hsize_t high[SPACE3_RANK]; /* Selection bounds */ + int i; /* counting variables */ + + // Output message about test being performed + SUBTEST("1-D Dataset Region Reference Functions"); + + try { + hdset_reg_ref_t *wbuf, // buffer to write to disk + *rbuf; // buffer read from disk + uint8_t *dwbuf, // Buffer for writing numeric data to disk + *drbuf; // Buffer for reading numeric data from disk + + // Allocate write & read buffers + wbuf = (hdset_reg_ref_t *)HDcalloc(sizeof(hdset_reg_ref_t), (size_t)SPACE1_DIM1); + rbuf = (hdset_reg_ref_t *)HDmalloc(sizeof(hdset_reg_ref_t) * SPACE1_DIM1); + dwbuf = (uint8_t *)HDmalloc(sizeof(uint8_t) * SPACE3_DIM1); + drbuf = (uint8_t *)HDcalloc(sizeof(uint8_t), (size_t)SPACE3_DIM1); + + // Create file FILE1 + H5File file1(FILE2, H5F_ACC_TRUNC); + + // Create dataspace for datasets + hsize_t dims3[] = {SPACE3_DIM1}; + DataSpace sid3(SPACE3_RANK, dims3); + + // Create dataset access property list + PropList dapl(H5P_DATASET_ACCESS); + + // Create a dataset + DataSet dset3 = file1.createDataSet(DSET2_NAME, PredType::STD_U8LE, sid3); + + uint8_t *tu8; // Temporary pointer to uint8 data + for (tu8 = dwbuf, i = 0; i < SPACE3_DIM1; i++) + *tu8++ = i * 3; // from C test + + // Write selection to disk + dset3.write(dwbuf, PredType::STD_U8LE); + + // Close Dataset + dset3.close(); + + // Create dataspace for datasets + hsize_t dims1[] = {SPACE1_DIM1}; + DataSpace sid1(SPACE1_RANK, dims1); + + // Create a dataset + DataSet dset1 = file1.createDataSet(DSET1_NAME, PredType::STD_REF_DSETREG, sid1); + + /* + * Create references and prepare for testing + */ + + /* Select 15 2x1 hyperslabs for first reference */ + start[0] = 2; + stride[0] = 5; + count[0] = 15; + block[0] = 2; + + // Select a hyperslab region to add to the current selected region + sid3.selectHyperslab(H5S_SELECT_SET, count, start, stride, block); + + // Get and verify the number of elements in a dataspace selection + hssize_t nelms = sid3.getSelectNpoints(); + verify_val(nelms, 30, "DataSet::getRefObjType",__LINE__,__FILE__); + + // Store first dataset region + file1.reference(&wbuf[0], "/Dataset2", sid3); + + // Get and verify object type + H5O_type_t obj_type = dset1.getRefObjType(&wbuf[0], H5R_DATASET_REGION); + verify_val(obj_type, H5O_TYPE_DATASET, "DataSet::getRefObjType",__LINE__,__FILE__); + + /* Select sequence of ten points for second reference */ + coord1[0][0] = 16; + coord1[1][0] = 22; + coord1[2][0] = 38; + coord1[3][0] = 41; + coord1[4][0] = 52; + coord1[5][0] = 63; + coord1[6][0] = 70; + coord1[7][0] = 89; + coord1[8][0] = 97; + coord1[9][0] = 3; + + // Selects array elements to be included in the selection for sid3 + sid3.selectElements(H5S_SELECT_SET, (size_t)POINT1_NPOINTS, (const hsize_t *)coord1); + + // Get and verify the number of elements in a dataspace selection + nelms = sid3.getSelectNpoints(); + verify_val(nelms, 10, "DataSet::getRefObjType",__LINE__,__FILE__); + + // Store first dataset region + file1.reference(&wbuf[1], "/Dataset2", sid3); + + // Write selection to disk + dset1.write(wbuf, PredType::STD_REF_DSETREG); + + // Close disk dataspace, dataset, and file + sid1.close(); + dset1.close(); + sid3.close(); + file1.close(); + + /* + * Testing various dereference functions + */ + + // Re-open the file + file1.openFile(FILE2, H5F_ACC_RDWR); + + // Open the dataset + dset1 = file1.openDataSet("/Dataset1"); + + // Read selection from disk + dset1.read(rbuf, PredType::STD_REF_DSETREG); + + { // Test DataSet::dereference + dset3.dereference(dset1, &rbuf[0], H5R_DATASET_REGION, dapl); + + // Get and verify object type + obj_type = dset1.getRefObjType(&rbuf[0], H5R_DATASET_REGION); + verify_val(obj_type, H5O_TYPE_DATASET, "DataSet::getRefObjType",__LINE__,__FILE__); + + // Get dataspace of dset3 the verify number of elements + sid1 = dset3.getSpace(); + nelms = sid1.getSimpleExtentNpoints(); + verify_val((long)nelms, 100, "DataSpace::getSimpleExtentNpoints",__LINE__,__FILE__); + } // End of test DataSet::dereference + + { // Test DataSet constructor -by dereference + // Dereference dataset object by ctor, from the location where + // 'dset1' is located + DataSet newds(dset1, &rbuf[0], H5R_DATASET_REGION, dapl); + + // Get dataspace of newds then verify number of elements + sid1 = newds.getSpace(); + nelms = sid1.getSimpleExtentNpoints(); + verify_val((long)nelms, 100, "DataSpace::getSimpleExtentNpoints",__LINE__,__FILE__); + + // Close objects for this mini test + newds.close(); + sid1.close(); + } // End of test DataSet constructor -by dereference + + // Read from disk + dset3.read(drbuf, PredType::STD_U8LE); + + for(tu8 = (uint8_t *)drbuf, i = 0; i < SPACE3_DIM1; i++, tu8++) + verify_val(*tu8, (uint8_t)(i * 3), "DataSpace::getSimpleExtentNpoints",__LINE__,__FILE__); + + /* + * Test getting the referenced region + */ + + // Get region + DataSpace reg_sp = dset1.getRegion(&rbuf[0]); + + // Get and verify number of elements in a dataspace selection + nelms = reg_sp.getSelectNpoints(); + verify_val((long)nelms, 30, "DataSpace::getSelectNpoints",__LINE__,__FILE__); + + // Get and verify number of hyperslab blocks + nelms = reg_sp.getSelectHyperNblocks(); + verify_val((long)nelms, 15, "DataSpace::getSelectNpoints",__LINE__,__FILE__); + + /* Allocate space for the hyperslab blocks */ + coords = (hsize_t *)HDmalloc(nelms * SPACE3_RANK * sizeof(hsize_t) * 2); + + // Get the list of hyperslab blocks currently selected + reg_sp.getSelectHyperBlocklist((hsize_t)0, (hsize_t)nelms, coords); + + // Verify values in the list + verify_val(coords[0], 2, "Hyperslab Coordinates",__LINE__,__FILE__); + verify_val(coords[1], 3, "Hyperslab Coordinates",__LINE__,__FILE__); + verify_val(coords[2], 7, "Hyperslab Coordinates",__LINE__,__FILE__); + verify_val(coords[3], 8, "Hyperslab Coordinates",__LINE__,__FILE__); + verify_val(coords[4], 12, "Hyperslab Coordinates",__LINE__,__FILE__); + verify_val(coords[5], 13, "Hyperslab Coordinates",__LINE__,__FILE__); + verify_val(coords[6], 17, "Hyperslab Coordinates",__LINE__,__FILE__); + verify_val(coords[7], 18, "Hyperslab Coordinates",__LINE__,__FILE__); + verify_val(coords[8], 22, "Hyperslab Coordinates",__LINE__,__FILE__); + verify_val(coords[9], 23, "Hyperslab Coordinates",__LINE__,__FILE__); + verify_val(coords[10], 27, "Hyperslab Coordinates",__LINE__,__FILE__); + verify_val(coords[11], 28, "Hyperslab Coordinates",__LINE__,__FILE__); + verify_val(coords[12], 32, "Hyperslab Coordinates",__LINE__,__FILE__); + verify_val(coords[13], 33, "Hyperslab Coordinates",__LINE__,__FILE__); + verify_val(coords[14], 37, "Hyperslab Coordinates",__LINE__,__FILE__); + verify_val(coords[15], 38, "Hyperslab Coordinates",__LINE__,__FILE__); + verify_val(coords[16], 42, "Hyperslab Coordinates",__LINE__,__FILE__); + verify_val(coords[17], 43, "Hyperslab Coordinates",__LINE__,__FILE__); + verify_val(coords[18], 47, "Hyperslab Coordinates",__LINE__,__FILE__); + verify_val(coords[19], 48, "Hyperslab Coordinates",__LINE__,__FILE__); + verify_val(coords[20], 52, "Hyperslab Coordinates",__LINE__,__FILE__); + verify_val(coords[21], 53, "Hyperslab Coordinates",__LINE__,__FILE__); + verify_val(coords[22], 57, "Hyperslab Coordinates",__LINE__,__FILE__); + verify_val(coords[23], 58, "Hyperslab Coordinates",__LINE__,__FILE__); + verify_val(coords[24], 62, "Hyperslab Coordinates",__LINE__,__FILE__); + verify_val(coords[25], 63, "Hyperslab Coordinates",__LINE__,__FILE__); + verify_val(coords[26], 67, "Hyperslab Coordinates",__LINE__,__FILE__); + verify_val(coords[27], 68, "Hyperslab Coordinates",__LINE__,__FILE__); + verify_val(coords[28], 72, "Hyperslab Coordinates",__LINE__,__FILE__); + verify_val(coords[29], 73, "Hyperslab Coordinates",__LINE__,__FILE__); + + HDfree(coords); + + // Check boundaries + reg_sp.getSelectBounds(low, high); + verify_val(low[0], 2, "DataSpace::getSelectBounds",__LINE__,__FILE__); + verify_val(high[0], 73, "DataSpace::getSelectBounds",__LINE__,__FILE__); + + /* Close region space */ + reg_sp.close(); + + /* + * Another test on getting the referenced region + */ + + // Get region + DataSpace elm_sp = dset1.getRegion(&rbuf[1]); + + // Get and verify number of element points in the current selection + hssize_t nelmspts = elm_sp.getSelectElemNpoints(); + verify_val((long)nelmspts, 10, "DataSpace::getSelectNpoints",__LINE__,__FILE__); + + /* Allocate space for the hyperslab blocks */ + coords = (hsize_t *)HDmalloc(nelmspts * SPACE3_RANK * sizeof(hsize_t)); + + // Get the list of element points currently selected + elm_sp.getSelectElemPointlist((hsize_t)0, (hsize_t)nelmspts, coords); + + // Verify points + verify_val(coords[0], coord1[0][0], "Element Coordinates",__LINE__,__FILE__); + verify_val(coords[1], coord1[1][0], "Element Coordinates",__LINE__,__FILE__); + verify_val(coords[2], coord1[2][0], "Element Coordinates",__LINE__,__FILE__); + verify_val(coords[3], coord1[3][0], "Element Coordinates",__LINE__,__FILE__); + verify_val(coords[4], coord1[4][0], "Element Coordinates",__LINE__,__FILE__); + verify_val(coords[5], coord1[5][0], "Element Coordinates",__LINE__,__FILE__); + verify_val(coords[6], coord1[6][0], "Element Coordinates",__LINE__,__FILE__); + verify_val(coords[7], coord1[7][0], "Element Coordinates",__LINE__,__FILE__); + verify_val(coords[8], coord1[8][0], "Element Coordinates",__LINE__,__FILE__); + verify_val(coords[9], coord1[9][0], "Element Coordinates",__LINE__,__FILE__); + + HDfree(coords); + + // Check boundaries + elm_sp.getSelectBounds(low, high); + verify_val(low[0], 3, "DataSpace::getSelectBounds",__LINE__,__FILE__); + verify_val(high[0], 97, "DataSpace::getSelectBounds",__LINE__,__FILE__); + + // Close element space + elm_sp.close(); + + // Close resources + sid1.close(); + dset3.close(); + dset1.close(); + file1.close(); + + // Free memory buffers + HDfree(wbuf); + HDfree(rbuf); + HDfree(dwbuf); + HDfree(drbuf); + + PASSED(); + } // end try + catch (Exception E) { + issue_fail_msg("test_reference_region_1D()",__LINE__,__FILE__, + E.getCFuncName(), E.getCDetailMsg()); + } +} /* test_reference_region_1D() */ + + /**************************************************************** ** ** test_reference_compat(): Test basic object reference functionality. @@ -346,7 +806,10 @@ void test_reference(void) // Output message about test being performed MESSAGE(5, ("Testing References\n")); + test_reference_params(); // Test basic parameters of reference functionality test_reference_obj(); // Test basic object reference functionality + test_reference_group(); // Test group reference functionality + test_reference_region_1D(); // Test 1-D reference functionality test_reference_compat(); // Tests deprecated reference routines (not yet) } // test_reference() @@ -363,5 +826,6 @@ extern "C" void cleanup_reference(void) { HDremove(FILE1.c_str()); + HDremove(FILE2.c_str()); } -- cgit v0.12