Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-09-15 09:12:33

0001 /*
0002  *  Copyright (c), 2017, Ali Can Demiralp <ali.demiralp@rwth-aachen.de>
0003  *
0004  *  Distributed under the Boost Software License, Version 1.0.
0005  *    (See accompanying file LICENSE_1_0.txt or copy at
0006  *          http://www.boost.org/LICENSE_1_0.txt)
0007  *
0008  */
0009 #pragma once
0010 
0011 #include <H5Ipublic.h>
0012 #include <algorithm>
0013 #include <functional>
0014 #include <numeric>
0015 #include <sstream>
0016 #include <string>
0017 
0018 #include <H5Ppublic.h>
0019 
0020 #include "../H5DataSpace.hpp"
0021 #include "H5Converter_misc.hpp"
0022 #include "H5Inspector_misc.hpp"
0023 #include "H5ReadWrite_misc.hpp"
0024 #include "H5Utils.hpp"
0025 #include "h5a_wrapper.hpp"
0026 #include "h5d_wrapper.hpp"
0027 #include "squeeze.hpp"
0028 #include "assert_compatible_spaces.hpp"
0029 
0030 namespace HighFive {
0031 
0032 inline std::string Attribute::getName() const {
0033     return details::get_name(
0034         [&](char* buffer, size_t length) { return detail::h5a_get_name(_hid, length, buffer); });
0035 }
0036 
0037 inline size_t Attribute::getStorageSize() const {
0038     if (!this->isValid()) {
0039         throw AttributeException("Invalid call to `DataSet::getFile` for invalid object");
0040     }
0041 
0042     return static_cast<size_t>(detail::h5a_get_storage_size(_hid));
0043 }
0044 
0045 inline DataType Attribute::getDataType() const {
0046     DataType res;
0047     res._hid = detail::h5a_get_type(_hid);
0048     return res;
0049 }
0050 
0051 inline DataSpace Attribute::getSpace() const {
0052     DataSpace space;
0053     space._hid = detail::h5a_get_space(_hid);
0054     return space;
0055 }
0056 
0057 inline DataSpace Attribute::getMemSpace() const {
0058     return _mem_space.getId() == H5I_INVALID_HID ? getSpace() : _mem_space;
0059 }
0060 
0061 template <typename T>
0062 inline T Attribute::read() const {
0063     T array;
0064     read(array);
0065     return array;
0066 }
0067 
0068 template <typename T>
0069 inline void Attribute::read(T& array) const {
0070     const DataSpace& mem_space = getMemSpace();
0071     auto file_datatype = getDataType();
0072     const details::BufferInfo<T> buffer_info(
0073         file_datatype,
0074         [this]() -> std::string { return this->getName(); },
0075         details::BufferInfo<T>::Operation::read);
0076 
0077     if (!details::checkDimensions(mem_space, buffer_info.getMinRank(), buffer_info.getMaxRank())) {
0078         std::ostringstream ss;
0079         ss << "Impossible to read attribute of dimensions " << mem_space.getNumberDimensions()
0080            << " into arrays of dimensions: " << buffer_info.getMinRank() << "(min) to "
0081            << buffer_info.getMaxRank() << "(max)";
0082         throw DataSpaceException(ss.str());
0083     }
0084     auto dims = mem_space.getDimensions();
0085 
0086     if (mem_space.getElementCount() == 0) {
0087         details::inspector<T>::prepare(array, dims);
0088         return;
0089     }
0090 
0091     auto r = details::data_converter::get_reader<T>(dims, array, file_datatype);
0092     read_raw(r.getPointer(), buffer_info.data_type);
0093     // re-arrange results
0094     r.unserialize(array);
0095 
0096     auto t = buffer_info.data_type;
0097     auto c = t.getClass();
0098 
0099     if (c == DataTypeClass::VarLen || t.isVariableStr()) {
0100 #if H5_VERSION_GE(1, 12, 0)
0101         // This one have been created in 1.12.0
0102         (void) detail::h5t_reclaim(t.getId(), mem_space.getId(), H5P_DEFAULT, r.getPointer());
0103 #else
0104         // This one is deprecated since 1.12.0
0105         (void) detail::h5d_vlen_reclaim(t.getId(), mem_space.getId(), H5P_DEFAULT, r.getPointer());
0106 #endif
0107     }
0108 }
0109 
0110 template <typename T>
0111 inline void Attribute::read_raw(T* array, const DataType& mem_datatype) const {
0112     static_assert(!std::is_const<T>::value,
0113                   "read() requires a non-const structure to read data into");
0114 
0115     detail::h5a_read(getId(), mem_datatype.getId(), static_cast<void*>(array));
0116 }
0117 
0118 template <typename T>
0119 inline void Attribute::read_raw(T* array) const {
0120     using element_type = typename details::inspector<T>::base_type;
0121     const DataType& mem_datatype = create_and_check_datatype<element_type>();
0122 
0123     read_raw(array, mem_datatype);
0124 }
0125 
0126 template <typename T>
0127 inline void Attribute::write(const T& buffer) {
0128     const DataSpace& mem_space = getMemSpace();
0129     auto dims = mem_space.getDimensions();
0130 
0131     if (mem_space.getElementCount() == 0) {
0132         return;
0133     }
0134 
0135     auto file_datatype = getDataType();
0136 
0137     const details::BufferInfo<T> buffer_info(
0138         file_datatype,
0139         [this]() -> std::string { return this->getName(); },
0140         details::BufferInfo<T>::Operation::write);
0141 
0142     if (!details::checkDimensions(mem_space, buffer_info.getMinRank(), buffer_info.getMaxRank())) {
0143         std::ostringstream ss;
0144         ss << "Impossible to write attribute of dimensions " << mem_space.getNumberDimensions()
0145            << " into arrays of dimensions: " << buffer_info.getMinRank() << "(min) to "
0146            << buffer_info.getMaxRank() << "(max)";
0147         throw DataSpaceException(ss.str());
0148     }
0149     auto w = details::data_converter::serialize<T>(buffer, dims, file_datatype);
0150     write_raw(w.getPointer(), buffer_info.data_type);
0151 }
0152 
0153 template <typename T>
0154 inline void Attribute::write_raw(const T* buffer, const DataType& mem_datatype) {
0155     detail::h5a_write(getId(), mem_datatype.getId(), buffer);
0156 }
0157 
0158 template <typename T>
0159 inline void Attribute::write_raw(const T* buffer) {
0160     using element_type = typename details::inspector<T>::base_type;
0161     const auto& mem_datatype = create_and_check_datatype<element_type>();
0162 
0163     write_raw(buffer, mem_datatype);
0164 }
0165 
0166 inline Attribute Attribute::squeezeMemSpace(const std::vector<size_t>& axes) const {
0167     auto mem_dims = this->getMemSpace().getDimensions();
0168     auto squeezed_dims = detail::squeeze(mem_dims, axes);
0169 
0170     auto attr = *this;
0171     attr._mem_space = DataSpace(squeezed_dims);
0172     return attr;
0173 }
0174 
0175 inline Attribute Attribute::reshapeMemSpace(const std::vector<size_t>& new_dims) const {
0176     detail::assert_compatible_spaces(this->getMemSpace(), new_dims);
0177 
0178     auto attr = *this;
0179     attr._mem_space = DataSpace(new_dims);
0180     return attr;
0181 }
0182 
0183 }  // namespace HighFive