Skip to content

Commit

Permalink
Wrap all used H5A functions. (#884)
Browse files Browse the repository at this point in the history
  • Loading branch information
1uc authored Dec 4, 2023
1 parent 1b50bc1 commit cb65179
Show file tree
Hide file tree
Showing 3 changed files with 157 additions and 53 deletions.
59 changes: 19 additions & 40 deletions include/highfive/bits/H5Annotate_traits_misc.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,23 +16,20 @@

#include "H5Attribute_misc.hpp"
#include "H5Iterables_misc.hpp"
#include "h5a_wrapper.hpp"

namespace HighFive {

template <typename Derivate>
inline Attribute AnnotateTraits<Derivate>::createAttribute(const std::string& attribute_name,
const DataSpace& space,
const DataType& dtype) {
auto attr_id = H5Acreate2(static_cast<Derivate*>(this)->getId(),
attribute_name.c_str(),
dtype.getId(),
space.getId(),
H5P_DEFAULT,
H5P_DEFAULT);
if (attr_id < 0) {
HDF5ErrMapper::ToException<AttributeException>(
std::string("Unable to create the attribute \"") + attribute_name + "\":");
}
auto attr_id = detail::h5a_create2(static_cast<Derivate*>(this)->getId(),
attribute_name.c_str(),
dtype.getId(),
space.getId(),
H5P_DEFAULT,
H5P_DEFAULT);
return detail::make_attribute(attr_id);
}

Expand All @@ -57,30 +54,20 @@ inline Attribute AnnotateTraits<Derivate>::createAttribute(const std::string& at

template <typename Derivate>
inline void AnnotateTraits<Derivate>::deleteAttribute(const std::string& attribute_name) {
if (H5Adelete(static_cast<const Derivate*>(this)->getId(), attribute_name.c_str()) < 0) {
HDF5ErrMapper::ToException<AttributeException>(
std::string("Unable to delete attribute \"") + attribute_name + "\":");
}
detail::h5a_delete(static_cast<const Derivate*>(this)->getId(), attribute_name.c_str());
}

template <typename Derivate>
inline Attribute AnnotateTraits<Derivate>::getAttribute(const std::string& attribute_name) const {
const auto attr_id =
H5Aopen(static_cast<const Derivate*>(this)->getId(), attribute_name.c_str(), H5P_DEFAULT);
if (attr_id < 0) {
HDF5ErrMapper::ToException<AttributeException>(
std::string("Unable to open the attribute \"") + attribute_name + "\":");
}
const auto attr_id = detail::h5a_open(static_cast<const Derivate*>(this)->getId(),
attribute_name.c_str(),
H5P_DEFAULT);
return detail::make_attribute(attr_id);
}

template <typename Derivate>
inline size_t AnnotateTraits<Derivate>::getNumberAttributes() const {
int res = H5Aget_num_attrs(static_cast<const Derivate*>(this)->getId());
if (res < 0) {
HDF5ErrMapper::ToException<AttributeException>(
std::string("Unable to count attributes in existing group or file"));
}
int res = detail::h5a_get_num_attrs(static_cast<const Derivate*>(this)->getId());
return static_cast<size_t>(res);
}

Expand All @@ -92,27 +79,19 @@ inline std::vector<std::string> AnnotateTraits<Derivate>::listAttributeNames() c
size_t num_objs = getNumberAttributes();
names.reserve(num_objs);

if (H5Aiterate2(static_cast<const Derivate*>(this)->getId(),
H5_INDEX_NAME,
H5_ITER_INC,
NULL,
&details::internal_high_five_iterate<H5A_info_t>,
static_cast<void*>(&iterateData)) < 0) {
HDF5ErrMapper::ToException<AttributeException>(
std::string("Unable to list attributes in group"));
}
detail::h5a_iterate2(static_cast<const Derivate*>(this)->getId(),
H5_INDEX_NAME,
H5_ITER_INC,
nullptr,
&details::internal_high_five_iterate<H5A_info_t>,
static_cast<void*>(&iterateData));

return names;
}

template <typename Derivate>
inline bool AnnotateTraits<Derivate>::hasAttribute(const std::string& attr_name) const {
int res = H5Aexists(static_cast<const Derivate*>(this)->getId(), attr_name.c_str());
if (res < 0) {
HDF5ErrMapper::ToException<AttributeException>(
std::string("Unable to check for attribute in group"));
}
return res;
return detail::h5a_exists(static_cast<const Derivate*>(this)->getId(), attr_name.c_str()) > 0;
}

} // namespace HighFive
20 changes: 7 additions & 13 deletions include/highfive/bits/H5Attribute_misc.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,36 +14,34 @@
#include <sstream>
#include <string>

#include <H5Apublic.h>
#include <H5Ppublic.h>

#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<size_t>(H5Aget_storage_size(_hid));
return static_cast<size_t>(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<AttributeException>("Unable to get DataSpace out of Attribute");
}
space._hid = detail::h5a_get_space(_hid);
return space;
}

Expand Down Expand Up @@ -107,9 +105,7 @@ inline void Attribute::read(T* array, const DataType& mem_datatype) const {
static_assert(!std::is_const<T>::value,
"read() requires a non-const structure to read data into");

if (H5Aread(getId(), mem_datatype.getId(), static_cast<void*>(array)) < 0) {
HDF5ErrMapper::ToException<AttributeException>("Error during HDF5 Read: ");
}
detail::h5a_read(getId(), mem_datatype.getId(), static_cast<void*>(array));
}

template <typename T>
Expand Down Expand Up @@ -147,9 +143,7 @@ inline void Attribute::write(const T& buffer) {

template <typename T>
inline void Attribute::write_raw(const T* buffer, const DataType& mem_datatype) {
if (H5Awrite(getId(), mem_datatype.getId(), buffer) < 0) {
HDF5ErrMapper::ToException<DataSetException>("Error during HDF5 Write: ");
}
detail::h5a_write(getId(), mem_datatype.getId(), buffer);
}

template <typename T>
Expand Down
131 changes: 131 additions & 0 deletions include/highfive/bits/h5a_wrapper.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
#pragma once

#include <H5Apublic.h>
#include <H5Ipublic.h>

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<AttributeException>(
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<AttributeException>(
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<AttributeException>(
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<AttributeException>(
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<AttributeException>(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<AttributeException>(
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<AttributeException>(
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<AttributeException>(
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<AttributeException>(
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<AttributeException>(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<AttributeException>(std::string("Unable to write attribute"));
}

return err;
}

} // namespace detail
} // namespace HighFive

0 comments on commit cb65179

Please sign in to comment.