diff --git a/include/highfive/bits/H5Node_traits_misc.hpp b/include/highfive/bits/H5Node_traits_misc.hpp index 2cbda126a..fb7f0f06f 100644 --- a/include/highfive/bits/H5Node_traits_misc.hpp +++ b/include/highfive/bits/H5Node_traits_misc.hpp @@ -13,7 +13,6 @@ #include #include -#include #include #include @@ -26,6 +25,10 @@ #include "H5Selection_misc.hpp" #include "H5Slice_traits_misc.hpp" +#include "h5l_wrapper.hpp" +#include "h5g_wrapper.hpp" + + namespace HighFive { @@ -122,16 +125,11 @@ template inline Group NodeTraits::createGroup(const std::string& group_name, bool parents) { LinkCreateProps lcpl; lcpl.add(CreateIntermediateGroup(parents)); - const auto hid = H5Gcreate2(static_cast(this)->getId(), - group_name.c_str(), - lcpl.getId(), - H5P_DEFAULT, - H5P_DEFAULT); - if (hid < 0) { - HDF5ErrMapper::ToException(std::string("Unable to create the group \"") + - group_name + "\":"); - } - return detail::make_group(hid); + return detail::make_group(detail::h5g_create2(static_cast(this)->getId(), + group_name.c_str(), + lcpl.getId(), + H5P_DEFAULT, + H5P_DEFAULT)); } template @@ -140,27 +138,18 @@ inline Group NodeTraits::createGroup(const std::string& group_name, bool parents) { LinkCreateProps lcpl; lcpl.add(CreateIntermediateGroup(parents)); - const auto hid = H5Gcreate2(static_cast(this)->getId(), - group_name.c_str(), - lcpl.getId(), - createProps.getId(), - H5P_DEFAULT); - if (hid < 0) { - HDF5ErrMapper::ToException(std::string("Unable to create the group \"") + - group_name + "\":"); - } - return detail::make_group(hid); + return detail::make_group(detail::h5g_create2(static_cast(this)->getId(), + group_name.c_str(), + lcpl.getId(), + createProps.getId(), + H5P_DEFAULT)); } template inline Group NodeTraits::getGroup(const std::string& group_name) const { - const auto hid = - H5Gopen2(static_cast(this)->getId(), group_name.c_str(), H5P_DEFAULT); - if (hid < 0) { - HDF5ErrMapper::ToException(std::string("Unable to open the group \"") + - group_name + "\":"); - } - return detail::make_group(hid); + return detail::make_group(detail::h5g_open2(static_cast(this)->getId(), + group_name.c_str(), + H5P_DEFAULT)); } template @@ -174,24 +163,21 @@ inline DataType NodeTraits::getDataType(const std::string& type_name, template inline size_t NodeTraits::getNumberObjects() const { hsize_t res; - if (H5Gget_num_objs(static_cast(this)->getId(), &res) < 0) { - HDF5ErrMapper::ToException( - std::string("Unable to count objects in existing group or file")); - } + detail::h5g_get_num_objs(static_cast(this)->getId(), &res); return static_cast(res); } template inline std::string NodeTraits::getObjectName(size_t index) const { return details::get_name([&](char* buffer, size_t length) { - return H5Lget_name_by_idx(static_cast(this)->getId(), - ".", - H5_INDEX_NAME, - H5_ITER_INC, - index, - buffer, - length, - H5P_DEFAULT); + return detail::h5l_get_name_by_idx(static_cast(this)->getId(), + ".", + H5_INDEX_NAME, + H5_ITER_INC, + index, + buffer, + length, + H5P_DEFAULT); }); } @@ -201,18 +187,14 @@ inline bool NodeTraits::rename(const std::string& src_path, bool parents) const { LinkCreateProps lcpl; lcpl.add(CreateIntermediateGroup(parents)); - herr_t status = H5Lmove(static_cast(this)->getId(), - src_path.c_str(), - static_cast(this)->getId(), - dst_path.c_str(), - lcpl.getId(), - H5P_DEFAULT); - if (status < 0) { - HDF5ErrMapper::ToException(std::string("Unable to move link to \"") + - dst_path + "\":"); - return false; - } - return true; + herr_t err = detail::h5l_move(static_cast(this)->getId(), + src_path.c_str(), + static_cast(this)->getId(), + dst_path.c_str(), + lcpl.getId(), + H5P_DEFAULT); + + return err >= 0; } template @@ -223,23 +205,21 @@ inline std::vector NodeTraits::listObjectNames(IndexType size_t num_objs = getNumberObjects(); names.reserve(num_objs); - if (H5Literate(static_cast(this)->getId(), - static_cast(idx_type), - H5_ITER_INC, - NULL, - &details::internal_high_five_iterate, - static_cast(&iterateData)) < 0) { - HDF5ErrMapper::ToException(std::string("Unable to list objects in group")); - } - + detail::h5l_iterate(static_cast(this)->getId(), + static_cast(idx_type), + H5_ITER_INC, + NULL, + &details::internal_high_five_iterate, + static_cast(&iterateData)); return names; } template inline bool NodeTraits::_exist(const std::string& node_name, bool raise_errors) const { SilenceHDF5 silencer{}; - const auto val = - H5Lexists(static_cast(this)->getId(), node_name.c_str(), H5P_DEFAULT); + const auto val = detail::nothrow::h5l_exists(static_cast(this)->getId(), + node_name.c_str(), + H5P_DEFAULT); if (val < 0) { if (raise_errors) { HDF5ErrMapper::ToException("Invalid link for exist()"); @@ -269,11 +249,7 @@ inline bool NodeTraits::exist(const std::string& group_path) const { template inline void NodeTraits::unlink(const std::string& node_name) const { - const herr_t val = - H5Ldelete(static_cast(this)->getId(), node_name.c_str(), H5P_DEFAULT); - if (val < 0) { - HDF5ErrMapper::ToException(std::string("Invalid name for unlink() ")); - } + detail::h5l_delete(static_cast(this)->getId(), node_name.c_str(), H5P_DEFAULT); } @@ -297,13 +273,14 @@ static inline LinkType _convert_link_type(const H5L_type_t& ltype) noexcept { template inline LinkType NodeTraits::getLinkType(const std::string& node_name) const { H5L_info_t linkinfo; - if (H5Lget_info(static_cast(this)->getId(), - node_name.c_str(), - &linkinfo, - H5P_DEFAULT) < 0 || - linkinfo.type == H5L_TYPE_ERROR) { - HDF5ErrMapper::ToException(std::string("Unable to obtain info for link ") + - node_name); + detail::h5l_get_info(static_cast(this)->getId(), + node_name.c_str(), + &linkinfo, + H5P_DEFAULT); + + if (linkinfo.type == H5L_TYPE_ERROR) { + HDF5ErrMapper::ToException(std::string("Link type of \"") + node_name + + "\" is H5L_TYPE_ERROR"); } return _convert_link_type(linkinfo.type); } @@ -323,14 +300,11 @@ inline void NodeTraits::createSoftLink(const std::string& link_name, if (parents) { linkCreateProps.add(CreateIntermediateGroup{}); } - auto status = H5Lcreate_soft(obj_path.c_str(), - static_cast(this)->getId(), - link_name.c_str(), - linkCreateProps.getId(), - linkAccessProps.getId()); - if (status < 0) { - HDF5ErrMapper::ToException(std::string("Unable to create soft link: ")); - } + detail::h5l_create_soft(obj_path.c_str(), + static_cast(this)->getId(), + link_name.c_str(), + linkCreateProps.getId(), + linkAccessProps.getId()); } @@ -344,15 +318,12 @@ inline void NodeTraits::createExternalLink(const std::string& link_nam if (parents) { linkCreateProps.add(CreateIntermediateGroup{}); } - auto status = H5Lcreate_external(h5_file.c_str(), - obj_path.c_str(), - static_cast(this)->getId(), - link_name.c_str(), - linkCreateProps.getId(), - linkAccessProps.getId()); - if (status < 0) { - HDF5ErrMapper::ToException(std::string("Unable to create external link: ")); - } + detail::h5l_create_external(h5_file.c_str(), + obj_path.c_str(), + static_cast(this)->getId(), + link_name.c_str(), + linkCreateProps.getId(), + linkAccessProps.getId()); } template @@ -367,15 +338,12 @@ inline void NodeTraits::createHardLink(const std::string& link_name, if (parents) { linkCreateProps.add(CreateIntermediateGroup{}); } - auto status = H5Lcreate_hard(target_obj.getId(), - ".", - static_cast(this)->getId(), - link_name.c_str(), - linkCreateProps.getId(), - linkAccessProps.getId()); - if (status < 0) { - HDF5ErrMapper::ToException(std::string("Unable to create hard link: ")); - } + detail::h5l_create_hard(target_obj.getId(), + ".", + static_cast(this)->getId(), + link_name.c_str(), + linkCreateProps.getId(), + linkAccessProps.getId()); } diff --git a/include/highfive/bits/h5g_wrapper.hpp b/include/highfive/bits/h5g_wrapper.hpp new file mode 100644 index 000000000..eb77f9983 --- /dev/null +++ b/include/highfive/bits/h5g_wrapper.hpp @@ -0,0 +1,46 @@ +#pragma once + +#include +#include + +#include + +namespace HighFive { +namespace detail { + +inline hid_t h5g_create2(hid_t loc_id, + const char* name, + hid_t lcpl_id, + hid_t gcpl_id, + hid_t gapl_id) { + hid_t group_id = H5Gcreate2(loc_id, name, lcpl_id, gcpl_id, gapl_id); + if (group_id == H5I_INVALID_HID) { + HDF5ErrMapper::ToException(std::string("Unable to create the group \"") + + name + "\":"); + } + + return group_id; +} + +inline hid_t h5g_open2(hid_t loc_id, const char* name, hid_t gapl_id) { + hid_t group_id = H5Gopen2(loc_id, name, gapl_id); + if (group_id == H5I_INVALID_HID) { + HDF5ErrMapper::ToException(std::string("Unable to open the group \"") + + name + "\":"); + } + return group_id; +} + +inline herr_t h5g_get_num_objs(hid_t loc_id, hsize_t* num_objs) { + herr_t err = H5Gget_num_objs(loc_id, num_objs); + if (err < 0) { + HDF5ErrMapper::ToException( + std::string("Unable to count objects in existing group or file")); + } + + return err; +} + + +} // namespace detail +} // namespace HighFive diff --git a/include/highfive/bits/h5l_wrapper.hpp b/include/highfive/bits/h5l_wrapper.hpp new file mode 100644 index 000000000..0009fdcfd --- /dev/null +++ b/include/highfive/bits/h5l_wrapper.hpp @@ -0,0 +1,132 @@ +#pragma once + +#include + +namespace HighFive { +namespace detail { + +inline herr_t h5l_create_external(const char* file_name, + const char* obj_name, + hid_t link_loc_id, + const char* link_name, + hid_t lcpl_id, + hid_t lapl_id) { + herr_t err = H5Lcreate_external(file_name, obj_name, link_loc_id, link_name, lcpl_id, lapl_id); + if (err < 0) { + HDF5ErrMapper::ToException(std::string("Unable to create external link: ")); + } + + return err; +} + +inline herr_t h5l_create_soft(const char* link_target, + hid_t link_loc_id, + const char* link_name, + hid_t lcpl_id, + hid_t lapl_id) { + herr_t err = H5Lcreate_soft(link_target, link_loc_id, link_name, lcpl_id, lapl_id); + if (err < 0) { + HDF5ErrMapper::ToException(std::string("Unable to create soft link: ")); + } + + return err; +} + +inline herr_t h5l_create_hard(hid_t cur_loc, + const char* cur_name, + hid_t dst_loc, + const char* dst_name, + hid_t lcpl_id, + hid_t lapl_id) { + herr_t err = H5Lcreate_hard(cur_loc, cur_name, dst_loc, dst_name, lcpl_id, lapl_id); + if (err < 0) { + HDF5ErrMapper::ToException(std::string("Unable to create hard link: ")); + } + + return err; +} + +inline herr_t h5l_get_info(hid_t loc_id, const char* name, H5L_info_t* linfo, hid_t lapl_id) { + herr_t err = H5Lget_info(loc_id, name, linfo, lapl_id); + if (err < 0) { + HDF5ErrMapper::ToException(std::string("Unable to obtain info for link ")); + } + + return err; +} + +inline herr_t h5l_delete(hid_t loc_id, const char* name, hid_t lapl_id) { + herr_t err = H5Ldelete(loc_id, name, lapl_id); + if (err < 0) { + HDF5ErrMapper::ToException(std::string("Invalid name for unlink() ")); + } + + return err; +} + +inline htri_t h5l_exists(hid_t loc_id, const char* name, hid_t lapl_id) { + htri_t tri = H5Lexists(loc_id, name, lapl_id); + if (tri < 0) { + HDF5ErrMapper::ToException("Invalid link for exist()"); + } + + return tri; +} + +namespace nothrow { + +inline htri_t h5l_exists(hid_t loc_id, const char* name, hid_t lapl_id) { + return H5Lexists(loc_id, name, lapl_id); +} + +} // namespace nothrow + +inline herr_t h5l_iterate(hid_t grp_id, + H5_index_t idx_type, + H5_iter_order_t order, + hsize_t* idx, + H5L_iterate_t op, + void* op_data) { + herr_t err = H5Literate(grp_id, idx_type, order, idx, op, op_data); + if (err < 0) { + HDF5ErrMapper::ToException(std::string("Unable to list objects in group")); + } + return err; +} + +inline herr_t h5l_move(hid_t src_loc, + const char* src_name, + hid_t dst_loc, + const char* dst_name, + hid_t lcpl_id, + hid_t lapl_id) { + herr_t err = H5Lmove(src_loc, src_name, dst_loc, dst_name, lcpl_id, lapl_id); + + if (err < 0) { + HDF5ErrMapper::ToException(std::string("Unable to move link to \"") + + dst_name + "\":"); + } + return err; +} + +inline ssize_t h5l_get_name_by_idx(hid_t loc_id, + const char* group_name, + H5_index_t idx_type, + H5_iter_order_t order, + hsize_t n, + char* name, + size_t size, + hid_t lapl_id) { + ssize_t n_chars = + H5Lget_name_by_idx(loc_id, group_name, idx_type, order, n, name, size, lapl_id); + + if (n_chars < 0) { + HDF5ErrMapper::ToException( + std::string("Unable to obtain link name from index.")); + } + + return n_chars; +} + +} // namespace detail +} // namespace HighFive