/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Copyright by The HDF Group. * * All rights reserved. * * * * This file is part of HDF5. The full HDF5 copyright notice, including * * terms governing use, modification, and redistribution, is contained in * * the COPYING file, which can be found at the root of the source code * * distribution tree, or in https://www.hdfgroup.org/licenses. * * If you do not have access to either file, you may request a copy from * * help@hdfgroup.org. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #include #include #include #include "H5Include.h" #include "H5Exception.h" #include "H5IdComponent.h" #include "H5DataSpace.h" #include "H5PropList.h" #include "H5FaccProp.h" #include "H5FcreatProp.h" #include "H5OcreatProp.h" #include "H5DcreatProp.h" #include "H5DxferProp.h" #include "H5LcreatProp.h" #include "H5LaccProp.h" #include "H5DaccProp.h" #include "H5Location.h" #include "H5Object.h" #include "H5DataType.h" #include "H5AtomType.h" #include "H5PredType.h" #include "H5AbstractDs.h" #include "H5DataSet.h" #include "H5Attribute.h" namespace H5 { using std::cerr; using std::endl; //-------------------------------------------------------------------------- // Function: DataType default constructor ///\brief Default constructor: Creates a stub datatype // Programmer Binh-Minh Ribler - 2000 //-------------------------------------------------------------------------- DataType::DataType() : H5Object(), id(H5I_INVALID_HID), encoded_buf(NULL), buf_size(0) { } //-------------------------------------------------------------------------- // Function: DataType overloaded constructor ///\brief Creates a datatype using an existing datatype's id ///\param existing_id - IN: Id of the existing datatype // Description // Constructor creates a copy of an existing DataType using // its id. // Programmer Binh-Minh Ribler - 2000 // Modification // Dec, 2005 // Removed second argument, "predefined", after changing to the // new ref counting mechanism that relies on C's ref counting. //-------------------------------------------------------------------------- DataType::DataType(const hid_t existing_id) : H5Object(), id(existing_id), encoded_buf(NULL), buf_size(0) { incRefCount(); // increment number of references to this id } //-------------------------------------------------------------------------- // Function: DataType overloaded constructor ///\brief Creates a object given its class and size ///\param type_class - IN: Class of datatype to create ///\param size - IN: Number of bytes in the datatype to create ///\exception H5::DataTypeIException // Programmer Binh-Minh Ribler - 2000 //-------------------------------------------------------------------------- DataType::DataType(const H5T_class_t type_class, size_t size) : H5Object(), encoded_buf(NULL), buf_size(0) { id = H5Tcreate(type_class, size); if (id < 0) { throw DataTypeIException("DataType constructor", "H5Tcreate failed"); } } //-------------------------------------------------------------------------- // Function: DataType overload constructor - dereference ///\brief Given a reference, ref, to an hdf5 group, creates a /// DataType object ///\param loc - IN: Location referenced object is in ///\param ref - IN: Reference pointer ///\param ref_type - IN: Reference type - default to H5R_OBJECT ///\param plist - IN: Property list - default to PropList::DEFAULT ///\exception H5::ReferenceException // Programmer Binh-Minh Ribler - Oct, 2006 //-------------------------------------------------------------------------- DataType::DataType(const H5Location &loc, const void *ref, H5R_type_t ref_type, const PropList &plist) : H5Object(), encoded_buf(NULL), buf_size(0) { id = H5Location::p_dereference(loc.getId(), ref, ref_type, plist, "constructor - by dereference"); } //-------------------------------------------------------------------------- // Function: DataType overload constructor - dereference // brief Given a reference, ref, to an hdf5 group, creates a // DataType object // param attr - IN: Specifying location where the referenced object is in // param ref - IN: Reference pointer // param ref_type - IN: Reference type - default to H5R_OBJECT // param plist - IN: Property list - default to PropList::DEFAULT // exception H5::ReferenceException // Programmer Binh-Minh Ribler - Oct, 2006 // Modification // Jul, 2008 // Added for application convenience. //-------------------------------------------------------------------------- /* DataType::DataType(const Attribute& attr, const void* ref, H5R_type_t ref_type, const PropList& plist) : H5Object(), id(H5I_INVALID_HID), encoded_buf(NULL), buf_size(0) { id = H5Location::p_dereference(attr.getId(), ref, ref_type, plist, "constructor - by dereference"); } */ //-------------------------------------------------------------------------- // Function: DataType copy constructor ///\brief Copy constructor: same HDF5 object as \a original // Programmer Binh-Minh Ribler - 2000 //-------------------------------------------------------------------------- DataType::DataType(const DataType &original) : H5Object(), id(original.id), encoded_buf(NULL), buf_size(0) { incRefCount(); // increment number of references to this id } //-------------------------------------------------------------------------- // Function: DataType overloaded constructor ///\brief Creates a DataType instance using a predefined type ///\param pred_type - IN: Predefined datatype ///\exception H5::DataTypeIException // Programmer Binh-Minh Ribler - 2015 // Description // Copying the type so that when a predefined type is passed in, // a copy of it is made, not just a duplicate of the HDF5 id. // Note: calling DataType::copy will invoke DataType::close() // unnecessarily and will produce undefined behavior. // -BMR, Apr 2015 //-------------------------------------------------------------------------- DataType::DataType(const PredType &pred_type) : H5Object(), encoded_buf(NULL), buf_size(0) { id = H5Tcopy(pred_type.getId()); if (id < 0) throw DataTypeIException("DataType constructor", "H5Tcopy failed"); } //-------------------------------------------------------------------------- // Function: DataType overloaded constructor ///\brief Creates a DataType instance by opening an HDF5 datatype given /// its name as a char*. ///\param loc - IN: Location of the type ///\param dtype_name - IN: Datatype name ///\exception H5::DataTypeIException // Programmer Binh-Minh Ribler - Dec 2016 // Description // In 1.10.1, this constructor was introduced and may replace the // existing function CommonFG::openDataType(const char*) to // improve usability. // -BMR, Dec 2016 //-------------------------------------------------------------------------- DataType::DataType(const H5Location &loc, const char *dtype_name) : H5Object(), encoded_buf(NULL), buf_size(0) { id = p_opentype(loc, dtype_name); } //-------------------------------------------------------------------------- // Function: DataType overloaded constructor ///\brief Creates a DataType instance by opening an HDF5 datatype given /// its name as an \c H5std_string. ///\param loc - IN: Location of the type ///\param dtype_name - IN: Datatype name ///\exception H5::DataTypeIException // Programmer Binh-Minh Ribler - Dec 2016 // Description // In 1.10.1, this constructor was introduced and may replace the // existing function CommonFG::openDataType(const H5std_string&) to // improve usability. // -BMR, Dec 2016 //-------------------------------------------------------------------------- DataType::DataType(const H5Location &loc, const H5std_string &dtype_name) : H5Object(), encoded_buf(NULL), buf_size(0) { id = p_opentype(loc, dtype_name.c_str()); } //-------------------------------------------------------------------------- // Function: DataType::copy ///\brief Copies an existing datatype to this datatype object ///\param like_type - IN: Datatype to be copied ///\exception H5::DataTypeIException // Programmer Binh-Minh Ribler - 2000 // Modification // - Replaced resetIdComponent() with decRefCount() to use C // library ID reference counting mechanism - BMR, Jun 1, 2004 // - Replaced decRefCount with close() to let the C library // handle the reference counting - BMR, Jun 1, 2006 //-------------------------------------------------------------------------- void DataType::copy(const DataType &like_type) { // close the current data type before copying like_type to this object try { close(); } catch (Exception &close_error) { throw DataTypeIException(inMemFunc("copy"), close_error.getDetailMsg()); } // call C routine to copy the datatype id = H5Tcopy(like_type.getId()); if (id < 0) throw DataTypeIException(inMemFunc("copy"), "H5Tcopy failed"); } //-------------------------------------------------------------------------- // Function: DataType::copy ///\brief Copies the datatype of the given dataset to this datatype object ///\param dset - IN: Dataset ///\exception H5::DataTypeIException // Programmer Binh-Minh Ribler - Jan, 2007 ///\par Description /// The resulted dataset will be transient and modifiable. //-------------------------------------------------------------------------- void DataType::copy(const DataSet &dset) { // close the current data type before copying dset's datatype to this object try { close(); } catch (Exception &close_error) { throw DataTypeIException(inMemFunc("copy"), close_error.getDetailMsg()); } // call C routine to copy the datatype id = H5Tcopy(dset.getId()); if (id < 0) throw DataTypeIException(inMemFunc("copy"), "H5Tcopy failed"); } #ifndef DOXYGEN_SHOULD_SKIP_THIS //-------------------------------------------------------------------------- // Function: DataType::p_decode // Purpose Returns an id of a type by decoding the binary object /// description of this datatype. ///\exception H5::DataTypeIException // Programmer Binh-Minh Ribler - Aug 2017 //-------------------------------------------------------------------------- hid_t DataType::p_decode() const { // Make sure that the buffer can be decoded if (encoded_buf == NULL) { throw DataTypeIException("DataType::p_decode", "No encoded buffer"); } // Call C function to decode the binary object description hid_t encoded_dtype_id = H5Tdecode(encoded_buf); // If H5Tdecode fails, raise exception if (encoded_dtype_id < 0) { throw DataTypeIException("DataType::p_decode", "H5Tdecode failed"); } else { return (encoded_dtype_id); } } #endif // DOXYGEN_SHOULD_SKIP_THIS //-------------------------------------------------------------------------- // Function: DataType::decode ///\brief Returns a DataType instance by decoding the binary object /// description of this datatype. /// ///\exception H5::DataTypeIException // Programmer Binh-Minh Ribler - Aug 2017 //-------------------------------------------------------------------------- DataType * DataType::decode() const { hid_t encoded_dtype_id = H5I_INVALID_HID; try { encoded_dtype_id = p_decode(); } catch (DataTypeIException &err) { throw; } DataType *encoded_dtype = new DataType; encoded_dtype->p_setId(encoded_dtype_id); return (encoded_dtype); } //-------------------------------------------------------------------------- // Function: DataType::encode ///\brief Creates a binary object description of this datatype. /// ///\exception H5::DataTypeIException // Programmer Binh-Minh Ribler - Aug 2017 //-------------------------------------------------------------------------- void DataType::encode() { // Call H5Tencode passing in null to determine the size of the buffer herr_t ret_value = H5Tencode(id, NULL, &buf_size); if (ret_value < 0) { throw DataTypeIException("DataType::encode", "Failed to get buf_size"); } // Allocate buffer and call C function again to encode if (buf_size > 0) { encoded_buf = (unsigned char *)calloc((size_t)1, buf_size); ret_value = H5Tencode(id, encoded_buf, &buf_size); if (ret_value < 0) { throw DataTypeIException("DataType::encode", "H5Tencode failed"); } } else { throw DataTypeIException("DataType::encode", "Failed to allocate buffer for encoding"); } } //-------------------------------------------------------------------------- // Function: DataType::hasBinaryDesc ///\brief Determines whether this datatype has a binary object /// description. /// ///\exception H5::DataTypeIException // Programmer Binh-Minh Ribler - Aug 2017 //-------------------------------------------------------------------------- bool DataType::hasBinaryDesc() const { return encoded_buf != NULL; } //-------------------------------------------------------------------------- // Function: DataType::operator= ///\brief Assignment operator ///\param rhs - IN: Reference to the existing datatype ///\return Reference to DataType instance ///\exception H5::DataTypeIException // Description // Makes a copy of the type on the right hand side and stores // the new id in the left hand side object. // Programmer Binh-Minh Ribler - 2000 // Modification // Changed operator= to simply copy the id of rhs instead of // calling H5Tcopy because, when the operator= is invoked, a // different datatype id is created and it won't have the same // characteristics as the original one, specifically, if the // rhs represents a named datatype, "this" would still be a // transient datatype. // BMR - Mar, 2015 //-------------------------------------------------------------------------- DataType & DataType::operator=(const DataType &rhs) { if (this != &rhs) { setId(rhs.id); } return (*this); } //-------------------------------------------------------------------------- // Function: DataType::operator== ///\brief Compares this DataType against the given one to determines /// whether the two objects refer to the same actual datatype. ///\param compared_type - IN: Reference to the datatype to compare ///\return true if the datatypes are equal, and false, otherwise. ///\exception H5::DataTypeIException // Programmer Binh-Minh Ribler - 2000 //-------------------------------------------------------------------------- bool DataType::operator==(const DataType &compared_type) const { // Call C routine H5Tequal to determines whether two datatype // identifiers refer to the same datatype htri_t ret_value = H5Tequal(id, compared_type.getId()); if (ret_value > 0) return true; else if (ret_value == 0) return false; else { throw DataTypeIException(inMemFunc("operator=="), "H5Tequal returns negative value"); } } //-------------------------------------------------------------------------- // Function: DataType::operator!= ///\brief Compares this DataType against the given one to determines /// whether the two objects refer to different actual datatypes. ///\param compared_type - IN: Reference to the datatype to compare ///\return true if the datatypes are not equal, and false, otherwise. ///\exception H5::DataTypeIException // July, 2018 //-------------------------------------------------------------------------- bool DataType::operator!=(const DataType &compared_type) const { return !operator==(compared_type); } //-------------------------------------------------------------------------- // Function: DataType::p_commit (private) //\brief Commits a transient datatype to a file, creating a new // named datatype //\param loc_id - IN: The id of either a file, group, dataset, named // datatype, or attribute. //\param name - IN: Name of the datatype //\exception H5::DataTypeIException // Programmer Binh-Minh Ribler - 2000 // Modification: // Copied from DataType::commit and made into private function // to be commonly used by several overloads of DataType::commit. // BMR - Jan, 2007 //-------------------------------------------------------------------------- void DataType::p_commit(hid_t loc_id, const char *name) { // Call C routine to commit the transient datatype herr_t ret_value = H5Tcommit2(loc_id, name, id, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); if (ret_value < 0) throw DataTypeIException(inMemFunc("p_commit"), "H5Tcommit2 failed"); } //-------------------------------------------------------------------------- // Function: DataType::commit ///\brief Commits a transient datatype to a file, creating a new /// named datatype ///\param loc - IN: A location (file, dataset, datatype, or group) ///\param name - IN: Name of the datatype ///\exception H5::DataTypeIException // Programmer Binh-Minh Ribler - Jan, 2007 //-------------------------------------------------------------------------- void DataType::commit(const H5Location &loc, const char *name) { p_commit(loc.getId(), name); } //-------------------------------------------------------------------------- // Function: DataType::commit // Purpose This is an overloaded member function, kept for backward // compatibility. It differs from the above function in that it // misses const's. This wrapper will be removed in future release. // Param loc - IN: A location (file, dataset, datatype, or group) // Param name - IN: Name of the datatype // Exception H5::DataTypeIException // Programmer Binh-Minh Ribler - Jan, 2007 // Modification // Planned for removal. -BMR, 2014/04/16 // Removed from documentation. -BMR, 2016/03/07 1.8.17 and 1.10.0 // Removed from code. -BMR, 2016/08/11 1.8.18 and 1.10.1 //-------------------------------------------------------------------------- // void DataType::commit(H5Location& loc, const char* name) //{ // p_commit(loc.getId(), name); //} //-------------------------------------------------------------------------- // Function: DataType::commit ///\brief This is an overloaded member function, provided for convenience. /// It differs from the above function only in the type of the /// argument \a name. // Programmer Binh-Minh Ribler - 2000 //-------------------------------------------------------------------------- void DataType::commit(const H5Location &loc, const H5std_string &name) { p_commit(loc.getId(), name.c_str()); } //-------------------------------------------------------------------------- // Function: DataType::commit // Purpose This is an overloaded member function, kept for backward // compatibility. It differs from the above function in that it // misses const's. This wrapper will be removed in future release. // Param loc - IN: A location (file, dataset, datatype, or group) // Param name - IN: Name of the datatype // Exception H5::DataTypeIException // Programmer Binh-Minh Ribler - Jan, 2007 // Modification // Planned for removal. -BMR, 2014/04/16 // Removed from documentation. -BMR, 2016/03/07 1.8.17 and 1.10.0 // Removed from code. -BMR, 2016/08/11 1.8.18 and 1.10.1 //-------------------------------------------------------------------------- // void DataType::commit(H5Location& loc, const H5std_string& name) //{ // p_commit(loc.getId(), name.c_str()); //} //-------------------------------------------------------------------------- // Function: DataType::committed ///\brief Determines whether a datatype is a named type or a /// transient type. ///\return \c true if the datatype is a named type, and \c false, /// otherwise. ///\exception H5::DataTypeIException // Programmer Binh-Minh Ribler - 2000 //-------------------------------------------------------------------------- bool DataType::committed() const { // Call C function to determine if a datatype is a named one htri_t is_committed = H5Tcommitted(id); if (is_committed > 0) return true; else if (is_committed == 0) return false; else { throw DataTypeIException(inMemFunc("committed"), "H5Tcommitted return negative value"); } } //-------------------------------------------------------------------------- // Function: DataType::find ///\brief Finds a conversion function that can handle a conversion /// from this datatype to the specified datatype, \a dest. ///\param dest - IN: Destination datatype ///\param pcdata - IN: Pointer to type conversion data ///\return Pointer to a suitable conversion function ///\exception H5::DataTypeIException // Programmer Binh-Minh Ribler - 2000 //-------------------------------------------------------------------------- H5T_conv_t DataType::find(const DataType &dest, H5T_cdata_t **pcdata) const { // Call C routine to find the conversion function H5T_conv_t func = H5Tfind(id, dest.getId(), pcdata); if (func == NULL) { throw DataTypeIException(inMemFunc("find"), "H5Tfind returns a NULL function"); } return (func); } //-------------------------------------------------------------------------- // Function: DataType::convert ///\brief Converts data from this datatype to the specified datatypes. ///\param dest - IN: Destination datatype ///\param nelmts - IN: Size of array \a buf ///\param buf - IN/OUT: Array containing pre- and post-conversion /// values ///\param background - IN: Optional background buffer ///\param plist - IN: Property list - default to PropList::DEFAULT ///\return Pointer to a suitable conversion function ///\exception H5::DataTypeIException // Programmer Binh-Minh Ribler - 2000 //-------------------------------------------------------------------------- void DataType::convert(const DataType &dest, size_t nelmts, void *buf, void *background, const PropList &plist) const { // Get identifiers for C API hid_t dest_id = dest.getId(); hid_t plist_id = plist.getId(); // Call C routine H5Tconvert to convert the data herr_t ret_value; ret_value = H5Tconvert(id, dest_id, nelmts, buf, background, plist_id); if (ret_value < 0) { throw DataTypeIException(inMemFunc("convert"), "H5Tconvert failed"); } } //-------------------------------------------------------------------------- // Function: DataType::lock ///\brief Locks a datatype, making it read-only and non-destructible. /// ///\exception H5::DataTypeIException ///\par Description /// This is normally done by the library for predefined data /// types so the application doesn't inadvertently change or /// delete a predefined type. /// /// Once a data type is locked it can never be unlocked unless /// the entire library is closed. // Programmer Binh-Minh Ribler - 2000 //-------------------------------------------------------------------------- void DataType::lock() const { // Call C routine to lock the datatype herr_t ret_value = H5Tlock(id); if (ret_value < 0) { throw DataTypeIException(inMemFunc("lock"), "H5Tlock failed"); } } //-------------------------------------------------------------------------- // Function: DataType::getClass ///\brief Returns the datatype class identifier. ///\return Datatype class identifier ///\exception H5::DataTypeIException // Programmer Binh-Minh Ribler - 2000 //-------------------------------------------------------------------------- H5T_class_t DataType::getClass() const { H5T_class_t type_class = H5Tget_class(id); // Return datatype class identifier if successful if (type_class == H5T_NO_CLASS) { throw DataTypeIException(inMemFunc("getClass"), "H5Tget_class returns H5T_NO_CLASS"); } return (type_class); } //-------------------------------------------------------------------------- // Function: DataType::getSize ///\brief Returns the size of a datatype. ///\return Datatype size in bytes ///\exception H5::DataTypeIException // Programmer Binh-Minh Ribler - 2000 //-------------------------------------------------------------------------- size_t DataType::getSize() const { // Call C routine to get the datatype size size_t type_size = H5Tget_size(id); if (type_size <= 0) // valid data types are never zero size { throw DataTypeIException(inMemFunc("getSize"), "H5Tget_size returns invalid datatype size"); } return (type_size); } //-------------------------------------------------------------------------- // Function: DataType::getSuper ///\brief Returns the base datatype from which a datatype is derived. ///\return DataType object ///\exception H5::DataTypeIException // Programmer Binh-Minh Ribler - 2000 //-------------------------------------------------------------------------- DataType DataType::getSuper() const { // Call C routine to get the base datatype from which the specified // datatype is derived. hid_t base_type_id = H5Tget_super(id); // If H5Tget_super returns a valid datatype id, create and return // the base type, otherwise, raise exception if (base_type_id > 0) { DataType base_type; base_type.p_setId(base_type_id); return (base_type); } else { throw DataTypeIException(inMemFunc("getSuper"), "H5Tget_super failed"); } } //-------------------------------------------------------------------------- // Function: DataType::registerFunc ///\brief Registers the specified conversion function. ///\param pers - IN: Conversion option /// \li \c H5T_PERS_HARD for hard conversion functions /// \li \c H5T_PERS_SOFT for soft conversion functions. ///\param name - IN: Name displayed in diagnostic output. ///\param dest - IN: Destination datatype. ///\param func - IN: Function to convert between source and /// destination datatypes. ///\exception H5::DataTypeIException ///\par Description /// For information, please refer to the H5Tregister API in /// the HDF5 C Reference Manual. // Programmer Binh-Minh Ribler - 2000 //-------------------------------------------------------------------------- void DataType::registerFunc(H5T_pers_t pers, const char *name, const DataType &dest, H5T_conv_t func) const { hid_t dest_id = dest.getId(); // get id of the destination datatype // Call C routine H5Tregister to register the conversion function herr_t ret_value = H5Tregister(pers, name, id, dest_id, func); if (ret_value < 0) { throw DataTypeIException(inMemFunc("registerFunc"), "H5Tregister failed"); } } //-------------------------------------------------------------------------- // Function: DataType::registerFunc ///\brief This is an overloaded member function, provided for convenience. /// It differs from the above function only in the type of the /// argument \a name. // Programmer Binh-Minh Ribler - 2000 //-------------------------------------------------------------------------- void DataType::registerFunc(H5T_pers_t pers, const H5std_string &name, const DataType &dest, H5T_conv_t func) const { registerFunc(pers, name.c_str(), dest, func); } //-------------------------------------------------------------------------- // Function: DataType::unregister ///\brief Removes a conversion function from all conversion paths. ///\param pers - IN: Conversion option /// \li \c H5T_PERS_HARD for hard conversion functions /// \li \c H5T_PERS_SOFT for soft conversion functions. ///\param name - IN: Name displayed in diagnostic output. ///\param dest - IN: Destination datatype. ///\param func - IN: Function to convert between source and /// destination datatypes. ///\exception H5::DataTypeIException // Programmer Binh-Minh Ribler - 2000 //-------------------------------------------------------------------------- void DataType::unregister(H5T_pers_t pers, const char *name, const DataType &dest, H5T_conv_t func) const { hid_t dest_id = dest.getId(); // get id of the dest datatype for C API // Call C routine H5Tunregister to remove the conversion function herr_t ret_value = H5Tunregister(pers, name, id, dest_id, func); if (ret_value < 0) { throw DataTypeIException(inMemFunc("unregister"), "H5Tunregister failed"); } } //-------------------------------------------------------------------------- // Function: DataType::unregister ///\brief This is an overloaded member function, provided for convenience. /// It differs from the above function only in the type of the /// argument \a name. // Programmer Binh-Minh Ribler - 2000 //-------------------------------------------------------------------------- void DataType::unregister(H5T_pers_t pers, const H5std_string &name, const DataType &dest, H5T_conv_t func) const { unregister(pers, name.c_str(), dest, func); } //-------------------------------------------------------------------------- // Function: DataType::setTag ///\brief Tags an opaque datatype. ///\param tag - IN: Descriptive ASCII string with which the opaque /// datatype is to be tagged. ///\exception H5::DataTypeIException // Programmer Binh-Minh Ribler - 2000 //-------------------------------------------------------------------------- void DataType::setTag(const char *tag) const { // Call C routine H5Tset_tag to tag an opaque datatype. herr_t ret_value = H5Tset_tag(id, tag); if (ret_value < 0) { throw DataTypeIException(inMemFunc("setTag"), "H5Tset_tag failed"); } } //-------------------------------------------------------------------------- // Function: DataType::setTag ///\brief This is an overloaded member function, provided for convenience. /// It differs from the above function only in the type of the /// argument \a name. // Programmer Binh-Minh Ribler - 2000 //-------------------------------------------------------------------------- void DataType::setTag(const H5std_string &tag) const { setTag(tag.c_str()); } //-------------------------------------------------------------------------- // Function: DataType::getTag ///\brief Gets the tag associated with an opaque datatype. ///\return Tag associated with the opaque datatype ///\exception H5::DataTypeIException // Programmer Binh-Minh Ribler - 2000 //-------------------------------------------------------------------------- H5std_string DataType::getTag() const { char *tag_Cstr = H5Tget_tag(id); // if the tag C-string returned is not NULL, convert it to C++ string // and return it, otherwise, raise an exception if (tag_Cstr != NULL) { H5std_string tag = H5std_string(tag_Cstr); // C string to string object H5free_memory(tag_Cstr); // free the C string return (tag); // return the tag } else { throw DataTypeIException(inMemFunc("getTag"), "H5Tget_tag returns NULL for tag"); } } //-------------------------------------------------------------------------- // Function: DataType::detectClass ///\brief Checks whether a datatype contains (or is) a certain type of /// datatype. ///\return true if this datatype contains or is the specified type, /// and false, otherwise. ///\exception H5::DataTypeIException // Programmer Binh-Minh Ribler - May, 2004 //-------------------------------------------------------------------------- bool DataType::detectClass(H5T_class_t cls) const { htri_t ret_value = H5Tdetect_class(id, cls); if (ret_value > 0) return true; else if (ret_value == 0) return false; else { throw DataTypeIException(inMemFunc("detectClass"), "H5Tdetect_class returns negative value"); } } //-------------------------------------------------------------------------- // Function: DataType::detectClass (static) ///\brief Checks whether a predtype is a certain class of datatype. ///\return true if this predtype is the specified type class, and false, /// otherwise. ///\exception H5::DataTypeIException // Programmer Binh-Minh Ribler - August, 2017 //-------------------------------------------------------------------------- bool DataType::detectClass(const PredType &pred_type, H5T_class_t cls) { htri_t ret_value = H5Tdetect_class(pred_type.getId(), cls); if (ret_value > 0) return true; else if (ret_value == 0) return false; else { throw DataTypeIException("detectClass on PredType", "H5Tdetect_class returns negative value"); } } //-------------------------------------------------------------------------- // Function: DataType::isVariableStr ///\brief Check whether this datatype is a variable-length string. ///\return true if this datatype is a variable-length string, and /// false, otherwise. ///\exception H5::DataTypeIException // Programmer Binh-Minh Ribler - May, 2004 //-------------------------------------------------------------------------- bool DataType::isVariableStr() const { htri_t is_varlen_str = H5Tis_variable_str(id); if (is_varlen_str == 1) return true; else if (is_varlen_str == 0) return false; else { throw DataTypeIException(inMemFunc("isVariableStr"), "H5Tis_variable_str returns negative value"); } } //-------------------------------------------------------------------------- // 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 // Modification: // May 2008 - BMR // Class hierarchy is revised to address bugzilla 1068. Class // AbstractDS and Attribute are moved out of H5Object. In // addition, member IdComponent::id is moved into subclasses, and // IdComponent::getId now becomes pure virtual function. // Programmer Binh-Minh Ribler - May, 2008 //-------------------------------------------------------------------------- hid_t DataType::getId() const { return (id); } #ifndef DOXYGEN_SHOULD_SKIP_THIS //-------------------------------------------------------------------------- // Function: DataType::p_opentype (private) ///\brief Opens an HDF5 datatype given its name ///\param loc - IN: Location of the type ///\param dtype_name - IN: Datatype name ///\exception H5::DataTypeIException // Programmer Binh-Minh Ribler - Dec 2016 // Description // This function was introduced in 1.10.1 to be used by the new // XxxType constructors that open a datatype. -BMR, Dec 2016 //-------------------------------------------------------------------------- hid_t DataType::p_opentype(const H5Location &loc, const char *dtype_name) const { // Call C function to open the named datatype at this location hid_t ret_value = H5Topen2(loc.getId(), dtype_name, H5P_DEFAULT); if (ret_value < 0) throw DataTypeIException(inMemFunc("constructor"), "H5Topen2 failed"); return (ret_value); } //-------------------------------------------------------------------------- // Function: DataType::p_setId ///\brief Sets the identifier of this object to a new value. /// ///\exception H5::IdComponentException when the attempt to close the HDF5 /// object fails // Description: // The underlying reference counting in the C library ensures // that the current valid id of this object is properly closed. // Then the object's id is reset to the new id. // Programmer Binh-Minh Ribler - 2000 //-------------------------------------------------------------------------- void DataType::p_setId(const hid_t new_id) { // handling references to this old id try { close(); } catch (Exception &close_error) { throw DataTypeIException(inMemFunc("p_setId"), close_error.getDetailMsg()); } // reset object's id to the given id id = new_id; } #endif // DOXYGEN_SHOULD_SKIP_THIS //-------------------------------------------------------------------------- // Function: DataType::close ///\brief Closes the datatype if it is not a predefined type. /// ///\exception H5::DataTypeIException // Programmer Binh-Minh Ribler - Mar 9, 2005 //-------------------------------------------------------------------------- void DataType::close() { if (p_valid_id(id)) { herr_t ret_value = H5Tclose(id); if (ret_value < 0) { throw DataTypeIException(inMemFunc("close"), "H5Tclose failed"); } // Reset the id id = H5I_INVALID_HID; // Free and reset buffer of encoded object description if it's been used if (encoded_buf != NULL) { free(encoded_buf); buf_size = 0; } } } //-------------------------------------------------------------------------- // Function: DataType destructor ///\brief Properly terminates access to this datatype. // Programmer Binh-Minh Ribler - 2000 // Modification // - Replaced resetIdComponent() with decRefCount() to use C // library ID reference counting mechanism - BMR, Jun 1, 2004 // - Replaced decRefCount with close() to let the C library // handle the reference counting - BMR, Jun 1, 2006 // - Added the use of H5CPP_EXITED to terminate the HDF5 library // and eliminate previous memory leaks. See comments in the // header file "H5PredType.h" for details. - BMR, Mar 30, 2012 // - Major re-implementation of the global constants was done // to avoid relying on the order of the creation and deletion // of the global constants. Hence, H5CPP_EXITED was removed. // See Design Notes in "H5PredType.cpp" for details. // - BMR, Sep 30, 2015 //-------------------------------------------------------------------------- DataType::~DataType() { try { close(); } catch (Exception &close_error) { cerr << inMemFunc("~DataType - ") << close_error.getDetailMsg() << endl; } } } // namespace H5