diff --git a/include/highfive/bits/H5DataType_misc.hpp b/include/highfive/bits/H5DataType_misc.hpp index 698d8fa28..0da4411e9 100644 --- a/include/highfive/bits/H5DataType_misc.hpp +++ b/include/highfive/bits/H5DataType_misc.hpp @@ -23,6 +23,7 @@ #include "H5Inspector_misc.hpp" #include "h5t_wrapper.hpp" +#include "h5i_wrapper.hpp" namespace HighFive { @@ -69,8 +70,8 @@ inline StringType DataType::asStringType() const { throw DataTypeException("Invalid conversion to StringType."); } - if (isValid() && H5Iinc_ref(_hid) < 0) { - throw ObjectException("Reference counter increase failure"); + if (isValid()) { + detail::h5i_inc_ref(_hid); } return StringType(_hid); diff --git a/include/highfive/bits/H5Object_misc.hpp b/include/highfive/bits/H5Object_misc.hpp index f477d7fdf..c5a1f3999 100644 --- a/include/highfive/bits/H5Object_misc.hpp +++ b/include/highfive/bits/H5Object_misc.hpp @@ -12,6 +12,7 @@ #include "../H5Exception.hpp" #include "../H5Utility.hpp" +#include "h5i_wrapper.hpp" namespace HighFive { namespace detail { @@ -29,8 +30,8 @@ inline Object::Object(hid_t hid) inline Object::Object(const Object& other) : _hid(other._hid) { - if (other.isValid() && H5Iinc_ref(_hid) < 0) { - throw ObjectException("Reference counter increase failure"); + if (other.isValid()) { + detail::h5i_inc_ref(_hid); } } @@ -41,25 +42,28 @@ inline Object::Object(Object&& other) noexcept inline Object& Object::operator=(const Object& other) { if (this != &other) { - if (isValid()) - H5Idec_ref(_hid); + if ((*this).isValid()) { + detail::h5i_dec_ref(_hid); + } _hid = other._hid; - if (other.isValid() && H5Iinc_ref(_hid) < 0) { - throw ObjectException("Reference counter increase failure"); + if (other.isValid()) { + detail::h5i_inc_ref(_hid); } } return *this; } inline Object::~Object() { - if (isValid() && H5Idec_ref(_hid) < 0) { - HIGHFIVE_LOG_ERROR("HighFive::~Object: reference counter decrease failure"); + if (isValid()) { + if (detail::nothrow::h5i_dec_ref(_hid) < 0) { + HIGHFIVE_LOG_ERROR("Failed to decrease reference count of HID"); + } } } inline bool Object::isValid() const noexcept { - return (_hid != H5I_INVALID_HID) && (H5Iis_valid(_hid) != false); + return (_hid > 0) && (detail::nothrow::h5i_is_valid(_hid) > 0); } inline hid_t Object::getId() const noexcept { @@ -87,11 +91,7 @@ static inline ObjectType _convert_object_type(const H5I_type_t& h5type) { inline ObjectType Object::getType() const { // H5Iget_type is a very lightweight func which extracts the type from the id - H5I_type_t h5type; - if ((h5type = H5Iget_type(_hid)) == H5I_BADID) { - HDF5ErrMapper::ToException("Invalid hid or object type"); - } - return _convert_object_type(h5type); + return _convert_object_type(detail::h5i_get_type(_hid)); } inline ObjectInfo Object::getInfo() const { diff --git a/include/highfive/bits/H5Path_traits_misc.hpp b/include/highfive/bits/H5Path_traits_misc.hpp index 444e9294b..acde06d1e 100644 --- a/include/highfive/bits/H5Path_traits_misc.hpp +++ b/include/highfive/bits/H5Path_traits_misc.hpp @@ -21,20 +21,16 @@ inline PathTraits::PathTraits() { std::is_same::value, "PathTraits can only be applied to Group, DataSet and Attribute"); const auto& obj = static_cast(*this); - if (!obj.isValid()) { - return; + if (obj.isValid()) { + const hid_t file_id = detail::h5i_get_file_id(obj.getId()); + _file_obj.reset(new File(file_id)); } - const hid_t file_id = H5Iget_file_id(obj.getId()); - if (file_id < 0) { - HDF5ErrMapper::ToException("getFile(): Could not obtain file of object"); - } - _file_obj.reset(new File(file_id)); } template inline std::string PathTraits::getPath() const { return details::get_name([this](char* buffer, size_t length) { - return H5Iget_name(static_cast(*this).getId(), buffer, length); + return detail::h5i_get_name(static_cast(*this).getId(), buffer, length); }); } diff --git a/include/highfive/bits/H5Reference_misc.hpp b/include/highfive/bits/H5Reference_misc.hpp index 98e1fb88e..c73deee2a 100644 --- a/include/highfive/bits/H5Reference_misc.hpp +++ b/include/highfive/bits/H5Reference_misc.hpp @@ -22,8 +22,9 @@ namespace HighFive { inline Reference::Reference(const Object& location, const Object& object) : parent_id(location.getId()) { - obj_name = details::get_name( - [&](char* buffer, size_t length) { return H5Iget_name(object.getId(), buffer, length); }); + obj_name = details::get_name([&](char* buffer, size_t length) { + return detail::h5i_get_name(object.getId(), buffer, length); + }); } inline void Reference::create_ref(hobj_ref_t* refptr) const { diff --git a/include/highfive/bits/h5i_wrapper.hpp b/include/highfive/bits/h5i_wrapper.hpp new file mode 100644 index 000000000..c81290b74 --- /dev/null +++ b/include/highfive/bits/h5i_wrapper.hpp @@ -0,0 +1,79 @@ +#pragma once + +#include + +namespace HighFive { +namespace detail { +inline int h5i_inc_ref(hid_t id) { + auto count = H5Iinc_ref(id); + + if (count < 0) { + throw ObjectException("Failed to increase reference count of HID"); + } + + return count; +} + +namespace nothrow { + +inline int h5i_dec_ref(hid_t id) { + return H5Idec_ref(id); +} + +} // namespace nothrow + +inline int h5i_dec_ref(hid_t id) { + int count = H5Idec_ref(id); + if (count < 0) { + throw ObjectException("Failed to decrease reference count of HID"); + } + + return count; +} + +namespace nothrow { +inline htri_t h5i_is_valid(hid_t id) { + return H5Iis_valid(id); +} + +} // namespace nothrow + +inline htri_t h5i_is_valid(hid_t id) { + htri_t tri = H5Iis_valid(id); + if (tri < 0) { + throw ObjectException("Failed to check if HID is valid"); + } + + return tri; +} + +inline H5I_type_t h5i_get_type(hid_t id) { + H5I_type_t type = H5Iget_type(id); + if (type == H5I_BADID) { + HDF5ErrMapper::ToException("Failed to get type of HID"); + } + + return type; +} + +template +inline hid_t h5i_get_file_id(hid_t id) { + hid_t file_id = H5Iget_file_id(id); + if (file_id < 0) { + HDF5ErrMapper::ToException("Failed not obtain file HID of object"); + } + + return file_id; +} + +inline ssize_t h5i_get_name(hid_t id, char* name, size_t size) { + ssize_t n_chars = H5Iget_name(id, name, size); + if (n_chars < 0) { + HDF5ErrMapper::ToException("Failed to get name of HID."); + } + + return n_chars; +} + +} // namespace detail +} // namespace HighFive