diff --git a/include/highfive/bits/H5Annotate_traits_misc.hpp b/include/highfive/bits/H5Annotate_traits_misc.hpp index 85d2798fe..bf2be8a45 100644 --- a/include/highfive/bits/H5Annotate_traits_misc.hpp +++ b/include/highfive/bits/H5Annotate_traits_misc.hpp @@ -16,6 +16,7 @@ #include "H5Attribute_misc.hpp" #include "H5Iterables_misc.hpp" +#include "h5a_wrapper.hpp" namespace HighFive { @@ -23,16 +24,12 @@ template inline Attribute AnnotateTraits::createAttribute(const std::string& attribute_name, const DataSpace& space, const DataType& dtype) { - auto attr_id = H5Acreate2(static_cast(this)->getId(), - attribute_name.c_str(), - dtype.getId(), - space.getId(), - H5P_DEFAULT, - H5P_DEFAULT); - if (attr_id < 0) { - HDF5ErrMapper::ToException( - std::string("Unable to create the attribute \"") + attribute_name + "\":"); - } + auto attr_id = detail::h5a_create2(static_cast(this)->getId(), + attribute_name.c_str(), + dtype.getId(), + space.getId(), + H5P_DEFAULT, + H5P_DEFAULT); return detail::make_attribute(attr_id); } @@ -57,30 +54,20 @@ inline Attribute AnnotateTraits::createAttribute(const std::string& at template inline void AnnotateTraits::deleteAttribute(const std::string& attribute_name) { - if (H5Adelete(static_cast(this)->getId(), attribute_name.c_str()) < 0) { - HDF5ErrMapper::ToException( - std::string("Unable to delete attribute \"") + attribute_name + "\":"); - } + detail::h5a_delete(static_cast(this)->getId(), attribute_name.c_str()); } template inline Attribute AnnotateTraits::getAttribute(const std::string& attribute_name) const { - const auto attr_id = - H5Aopen(static_cast(this)->getId(), attribute_name.c_str(), H5P_DEFAULT); - if (attr_id < 0) { - HDF5ErrMapper::ToException( - std::string("Unable to open the attribute \"") + attribute_name + "\":"); - } + const auto attr_id = detail::h5a_open(static_cast(this)->getId(), + attribute_name.c_str(), + H5P_DEFAULT); return detail::make_attribute(attr_id); } template inline size_t AnnotateTraits::getNumberAttributes() const { - int res = H5Aget_num_attrs(static_cast(this)->getId()); - if (res < 0) { - HDF5ErrMapper::ToException( - std::string("Unable to count attributes in existing group or file")); - } + int res = detail::h5a_get_num_attrs(static_cast(this)->getId()); return static_cast(res); } @@ -92,27 +79,19 @@ inline std::vector AnnotateTraits::listAttributeNames() c size_t num_objs = getNumberAttributes(); names.reserve(num_objs); - if (H5Aiterate2(static_cast(this)->getId(), - H5_INDEX_NAME, - H5_ITER_INC, - NULL, - &details::internal_high_five_iterate, - static_cast(&iterateData)) < 0) { - HDF5ErrMapper::ToException( - std::string("Unable to list attributes in group")); - } + detail::h5a_iterate2(static_cast(this)->getId(), + H5_INDEX_NAME, + H5_ITER_INC, + nullptr, + &details::internal_high_five_iterate, + static_cast(&iterateData)); return names; } template inline bool AnnotateTraits::hasAttribute(const std::string& attr_name) const { - int res = H5Aexists(static_cast(this)->getId(), attr_name.c_str()); - if (res < 0) { - HDF5ErrMapper::ToException( - std::string("Unable to check for attribute in group")); - } - return res; + return detail::h5a_exists(static_cast(this)->getId(), attr_name.c_str()) > 0; } } // namespace HighFive diff --git a/include/highfive/bits/H5Attribute_misc.hpp b/include/highfive/bits/H5Attribute_misc.hpp index 939e111fd..7be83cb01 100644 --- a/include/highfive/bits/H5Attribute_misc.hpp +++ b/include/highfive/bits/H5Attribute_misc.hpp @@ -14,36 +14,34 @@ #include #include -#include #include #include "../H5DataSpace.hpp" #include "H5Converter_misc.hpp" #include "H5ReadWrite_misc.hpp" #include "H5Utils.hpp" +#include "h5a_wrapper.hpp" namespace HighFive { inline std::string Attribute::getName() const { return details::get_name( - [&](char* buffer, size_t length) { return H5Aget_name(_hid, length, buffer); }); + [&](char* buffer, size_t length) { return detail::h5a_get_name(_hid, length, buffer); }); } inline size_t Attribute::getStorageSize() const { - return static_cast(H5Aget_storage_size(_hid)); + return static_cast(detail::h5a_get_storage_size(_hid)); } inline DataType Attribute::getDataType() const { DataType res; - res._hid = H5Aget_type(_hid); + res._hid = detail::h5a_get_type(_hid); return res; } inline DataSpace Attribute::getSpace() const { DataSpace space; - if ((space._hid = H5Aget_space(_hid)) < 0) { - HDF5ErrMapper::ToException("Unable to get DataSpace out of Attribute"); - } + space._hid = detail::h5a_get_space(_hid); return space; } @@ -107,9 +105,7 @@ inline void Attribute::read(T* array, const DataType& mem_datatype) const { static_assert(!std::is_const::value, "read() requires a non-const structure to read data into"); - if (H5Aread(getId(), mem_datatype.getId(), static_cast(array)) < 0) { - HDF5ErrMapper::ToException("Error during HDF5 Read: "); - } + detail::h5a_read(getId(), mem_datatype.getId(), static_cast(array)); } template @@ -147,9 +143,7 @@ inline void Attribute::write(const T& buffer) { template inline void Attribute::write_raw(const T* buffer, const DataType& mem_datatype) { - if (H5Awrite(getId(), mem_datatype.getId(), buffer) < 0) { - HDF5ErrMapper::ToException("Error during HDF5 Write: "); - } + detail::h5a_write(getId(), mem_datatype.getId(), buffer); } template diff --git a/include/highfive/bits/h5a_wrapper.hpp b/include/highfive/bits/h5a_wrapper.hpp new file mode 100644 index 000000000..76f4e56fc --- /dev/null +++ b/include/highfive/bits/h5a_wrapper.hpp @@ -0,0 +1,131 @@ +#pragma once + +#include +#include + +namespace HighFive { +namespace detail { + +inline hid_t h5a_create2(hid_t loc_id, + char const* const attr_name, + hid_t type_id, + hid_t space_id, + hid_t acpl_id, + hid_t aapl_id) { + auto attr_id = H5Acreate2(loc_id, attr_name, type_id, space_id, acpl_id, aapl_id); + if (attr_id < 0) { + HDF5ErrMapper::ToException( + std::string("Unable to create the attribute \"") + attr_name + "\":"); + } + + return attr_id; +} + +inline void h5a_delete(hid_t loc_id, char const* const attr_name) { + if (H5Adelete(loc_id, attr_name) < 0) { + HDF5ErrMapper::ToException( + std::string("Unable to delete attribute \"") + attr_name + "\":"); + } +} + +inline hid_t h5a_open(hid_t loc_id, char const* const attr_name, hid_t aapl_id) { + const auto attr_id = H5Aopen(loc_id, attr_name, aapl_id); + if (attr_id < 0) { + HDF5ErrMapper::ToException( + std::string("Unable to open the attribute \"") + attr_name + "\":"); + } + + return attr_id; +} + + +inline int h5a_get_num_attrs(hid_t loc_id) { + int res = H5Aget_num_attrs(loc_id); + if (res < 0) { + HDF5ErrMapper::ToException( + std::string("Unable to count attributes in existing group or file")); + } + + return res; +} + + +inline void h5a_iterate2(hid_t loc_id, + H5_index_t idx_type, + H5_iter_order_t order, + hsize_t* idx, + H5A_operator2_t op, + void* op_data) { + if (H5Aiterate2(loc_id, idx_type, order, idx, op, op_data) < 0) { + HDF5ErrMapper::ToException(std::string("Failed H5Aiterate2.")); + } +} + +inline int h5a_exists(hid_t obj_id, char const* const attr_name) { + int res = H5Aexists(obj_id, attr_name); + if (res < 0) { + HDF5ErrMapper::ToException( + std::string("Unable to check for attribute in group")); + } + + return res; +} + +inline ssize_t h5a_get_name(hid_t attr_id, size_t buf_size, char* buf) { + ssize_t name_length = H5Aget_name(attr_id, buf_size, buf); + if (name_length < 0) { + HDF5ErrMapper::ToException( + std::string("Unable to get name of attribute")); + } + + return name_length; +} + + +inline hid_t h5a_get_space(hid_t attr_id) { + hid_t attr = H5Aget_space(attr_id); + if (attr < 0) { + HDF5ErrMapper::ToException( + std::string("Unable to get dataspace of attribute")); + } + + return attr; +} + +inline hsize_t h5a_get_storage_size(hid_t attr_id) { + // Docs: + // Returns the amount of storage size allocated for the attribute; + // otherwise returns 0 (zero). + return H5Aget_storage_size(attr_id); +} + +inline hid_t h5a_get_type(hid_t attr_id) { + hid_t type_id = H5Aget_type(attr_id); + if (type_id == H5I_INVALID_HID) { + HDF5ErrMapper::ToException( + std::string("Unable to get datatype of attribute")); + } + + return type_id; +} + +inline herr_t h5a_read(hid_t attr_id, hid_t type_id, void* buf) { + herr_t err = H5Aread(attr_id, type_id, buf); + if (err < 0) { + HDF5ErrMapper::ToException(std::string("Unable to read attribute")); + } + + return err; +} + +inline herr_t h5a_write(hid_t attr_id, hid_t type_id, void const* buf) { + herr_t err = H5Awrite(attr_id, type_id, buf); + if (err < 0) { + HDF5ErrMapper::ToException(std::string("Unable to write attribute")); + } + + return err; +} + +} // namespace detail +} // namespace HighFive