File indexing completed on 2025-04-19 08:55:32
0001
0002
0003
0004
0005
0006
0007
0008
0009 #pragma once
0010
0011 #include <algorithm>
0012 #include <functional>
0013 #include <numeric>
0014 #include <sstream>
0015 #include <string>
0016
0017 #include <H5Ppublic.h>
0018
0019 #include "../H5DataSpace.hpp"
0020 #include "H5Converter_misc.hpp"
0021 #include "H5ReadWrite_misc.hpp"
0022 #include "H5Utils.hpp"
0023 #include "h5a_wrapper.hpp"
0024 #include "h5d_wrapper.hpp"
0025
0026 namespace HighFive {
0027
0028 inline std::string Attribute::getName() const {
0029 return details::get_name(
0030 [&](char* buffer, size_t length) { return detail::h5a_get_name(_hid, length, buffer); });
0031 }
0032
0033 inline size_t Attribute::getStorageSize() const {
0034 return static_cast<size_t>(detail::h5a_get_storage_size(_hid));
0035 }
0036
0037 inline DataType Attribute::getDataType() const {
0038 DataType res;
0039 res._hid = detail::h5a_get_type(_hid);
0040 return res;
0041 }
0042
0043 inline DataSpace Attribute::getSpace() const {
0044 DataSpace space;
0045 space._hid = detail::h5a_get_space(_hid);
0046 return space;
0047 }
0048
0049 inline DataSpace Attribute::getMemSpace() const {
0050 return getSpace();
0051 }
0052
0053 template <typename T>
0054 inline T Attribute::read() const {
0055 T array;
0056 read(array);
0057 return array;
0058 }
0059
0060 template <typename T>
0061 inline void Attribute::read(T& array) const {
0062 const DataSpace& mem_space = getMemSpace();
0063 auto file_datatype = getDataType();
0064 const details::BufferInfo<T> buffer_info(
0065 file_datatype,
0066 [this]() -> std::string { return this->getName(); },
0067 details::BufferInfo<T>::Operation::read);
0068
0069 if (!details::checkDimensions(mem_space, buffer_info.n_dimensions)) {
0070 std::ostringstream ss;
0071 ss << "Impossible to read Attribute of dimensions " << mem_space.getNumberDimensions()
0072 << " into arrays of dimensions " << buffer_info.n_dimensions;
0073 throw DataSpaceException(ss.str());
0074 }
0075 auto dims = mem_space.getDimensions();
0076
0077 if (mem_space.getElementCount() == 0) {
0078 auto effective_dims = details::squeezeDimensions(dims,
0079 details::inspector<T>::recursive_ndim);
0080
0081 details::inspector<T>::prepare(array, effective_dims);
0082 return;
0083 }
0084
0085 auto r = details::data_converter::get_reader<T>(dims, array, file_datatype);
0086 read_raw(r.getPointer(), buffer_info.data_type);
0087
0088 r.unserialize(array);
0089
0090 auto t = buffer_info.data_type;
0091 auto c = t.getClass();
0092
0093 if (c == DataTypeClass::VarLen || t.isVariableStr()) {
0094 #if H5_VERSION_GE(1, 12, 0)
0095
0096 (void) detail::h5t_reclaim(t.getId(), mem_space.getId(), H5P_DEFAULT, r.getPointer());
0097 #else
0098
0099 (void) detail::h5d_vlen_reclaim(t.getId(), mem_space.getId(), H5P_DEFAULT, r.getPointer());
0100 #endif
0101 }
0102 }
0103
0104 template <typename T>
0105 inline void Attribute::read(T* array, const DataType& mem_datatype) const {
0106 read_raw(array, mem_datatype);
0107 }
0108
0109 template <typename T>
0110 inline void Attribute::read_raw(T* array, const DataType& mem_datatype) const {
0111 static_assert(!std::is_const<T>::value,
0112 "read() requires a non-const structure to read data into");
0113
0114 detail::h5a_read(getId(), mem_datatype.getId(), static_cast<void*>(array));
0115 }
0116
0117 template <typename T>
0118 inline void Attribute::read(T* array) const {
0119 read_raw(array);
0120 }
0121
0122 template <typename T>
0123 inline void Attribute::read_raw(T* array) const {
0124 using element_type = typename details::inspector<T>::base_type;
0125 const DataType& mem_datatype = create_and_check_datatype<element_type>();
0126
0127 read_raw(array, mem_datatype);
0128 }
0129
0130 template <typename T>
0131 inline void Attribute::write(const T& buffer) {
0132 const DataSpace& mem_space = getMemSpace();
0133
0134 if (mem_space.getElementCount() == 0) {
0135 return;
0136 }
0137
0138 auto file_datatype = getDataType();
0139
0140 const details::BufferInfo<T> buffer_info(
0141 file_datatype,
0142 [this]() -> std::string { return this->getName(); },
0143 details::BufferInfo<T>::Operation::write);
0144
0145 if (!details::checkDimensions(mem_space, buffer_info.n_dimensions)) {
0146 std::ostringstream ss;
0147 ss << "Impossible to write buffer of dimensions " << buffer_info.n_dimensions
0148 << " into dataset of dimensions " << mem_space.getNumberDimensions();
0149 throw DataSpaceException(ss.str());
0150 }
0151 auto w = details::data_converter::serialize<T>(buffer, file_datatype);
0152 write_raw(w.getPointer(), buffer_info.data_type);
0153 }
0154
0155 template <typename T>
0156 inline void Attribute::write_raw(const T* buffer, const DataType& mem_datatype) {
0157 detail::h5a_write(getId(), mem_datatype.getId(), buffer);
0158 }
0159
0160 template <typename T>
0161 inline void Attribute::write_raw(const T* buffer) {
0162 using element_type = typename details::inspector<T>::base_type;
0163 const auto& mem_datatype = create_and_check_datatype<element_type>();
0164
0165 write_raw(buffer, mem_datatype);
0166 }
0167
0168 }