Back to home page

EIC code displayed by LXR

 
 

    


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

0001 /*
0002  *  Copyright (c), 2017, Adrien Devresse <adrien.devresse@epfl.ch>
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 <string>
0012 #include <vector>
0013 
0014 #include <H5Apublic.h>
0015 #include <H5Fpublic.h>
0016 #include <H5Ppublic.h>
0017 #include <H5Tpublic.h>
0018 
0019 #include "../H5DataSet.hpp"
0020 #include "../H5Group.hpp"
0021 #include "../H5Selection.hpp"
0022 #include "../H5Utility.hpp"
0023 #include "H5DataSet_misc.hpp"
0024 #include "H5Iterables_misc.hpp"
0025 #include "H5Selection_misc.hpp"
0026 #include "H5Slice_traits_misc.hpp"
0027 
0028 #include "h5l_wrapper.hpp"
0029 #include "h5g_wrapper.hpp"
0030 #include "h5o_wrapper.hpp"
0031 
0032 
0033 namespace HighFive {
0034 
0035 
0036 template <typename Derivate>
0037 inline DataSet NodeTraits<Derivate>::createDataSet(const std::string& dataset_name,
0038                                                    const DataSpace& space,
0039                                                    const DataType& dtype,
0040                                                    const DataSetCreateProps& createProps,
0041                                                    const DataSetAccessProps& accessProps,
0042                                                    bool parents) {
0043     LinkCreateProps lcpl;
0044     lcpl.add(CreateIntermediateGroup(parents));
0045     return DataSet(detail::h5d_create2(static_cast<Derivate*>(this)->getId(),
0046                                        dataset_name.c_str(),
0047                                        dtype.getId(),
0048                                        space.getId(),
0049                                        lcpl.getId(),
0050                                        createProps.getId(),
0051                                        accessProps.getId()));
0052 }
0053 
0054 template <typename Derivate>
0055 template <typename T>
0056 inline DataSet NodeTraits<Derivate>::createDataSet(const std::string& dataset_name,
0057                                                    const DataSpace& space,
0058                                                    const DataSetCreateProps& createProps,
0059                                                    const DataSetAccessProps& accessProps,
0060                                                    bool parents) {
0061     return createDataSet(
0062         dataset_name, space, create_and_check_datatype<T>(), createProps, accessProps, parents);
0063 }
0064 
0065 template <typename Derivate>
0066 template <typename T>
0067 inline DataSet NodeTraits<Derivate>::createDataSet(const std::string& dataset_name,
0068                                                    const T& data,
0069                                                    const DataSetCreateProps& createProps,
0070                                                    const DataSetAccessProps& accessProps,
0071                                                    bool parents) {
0072     DataSet ds =
0073         createDataSet(dataset_name,
0074                       DataSpace::From(data),
0075                       create_and_check_datatype<typename details::inspector<T>::base_type>(),
0076                       createProps,
0077                       accessProps,
0078                       parents);
0079     ds.write(data);
0080     return ds;
0081 }
0082 
0083 template <typename Derivate>
0084 inline DataSet NodeTraits<Derivate>::getDataSet(const std::string& dataset_name,
0085                                                 const DataSetAccessProps& accessProps) const {
0086     return DataSet(detail::h5d_open2(static_cast<const Derivate*>(this)->getId(),
0087                                      dataset_name.c_str(),
0088                                      accessProps.getId()));
0089 }
0090 
0091 template <typename Derivate>
0092 inline Group NodeTraits<Derivate>::createGroup(const std::string& group_name, bool parents) {
0093     LinkCreateProps lcpl;
0094     lcpl.add(CreateIntermediateGroup(parents));
0095     return detail::make_group(detail::h5g_create2(static_cast<Derivate*>(this)->getId(),
0096                                                   group_name.c_str(),
0097                                                   lcpl.getId(),
0098                                                   H5P_DEFAULT,
0099                                                   H5P_DEFAULT));
0100 }
0101 
0102 template <typename Derivate>
0103 inline Group NodeTraits<Derivate>::createGroup(const std::string& group_name,
0104                                                const GroupCreateProps& createProps,
0105                                                bool parents) {
0106     LinkCreateProps lcpl;
0107     lcpl.add(CreateIntermediateGroup(parents));
0108     return detail::make_group(detail::h5g_create2(static_cast<Derivate*>(this)->getId(),
0109                                                   group_name.c_str(),
0110                                                   lcpl.getId(),
0111                                                   createProps.getId(),
0112                                                   H5P_DEFAULT));
0113 }
0114 
0115 template <typename Derivate>
0116 inline Group NodeTraits<Derivate>::getGroup(const std::string& group_name) const {
0117     return detail::make_group(detail::h5g_open2(static_cast<const Derivate*>(this)->getId(),
0118                                                 group_name.c_str(),
0119                                                 H5P_DEFAULT));
0120 }
0121 
0122 template <typename Derivate>
0123 inline DataType NodeTraits<Derivate>::getDataType(const std::string& type_name,
0124                                                   const DataTypeAccessProps& accessProps) const {
0125     return DataType(detail::h5t_open2(static_cast<const Derivate*>(this)->getId(),
0126                                       type_name.c_str(),
0127                                       accessProps.getId()));
0128 }
0129 
0130 template <typename Derivate>
0131 inline size_t NodeTraits<Derivate>::getNumberObjects() const {
0132     hsize_t res;
0133     detail::h5g_get_num_objs(static_cast<const Derivate*>(this)->getId(), &res);
0134     return static_cast<size_t>(res);
0135 }
0136 
0137 template <typename Derivate>
0138 inline std::string NodeTraits<Derivate>::getObjectName(size_t index) const {
0139     return details::get_name([&](char* buffer, size_t length) {
0140         return detail::h5l_get_name_by_idx(static_cast<const Derivate*>(this)->getId(),
0141                                            ".",
0142                                            H5_INDEX_NAME,
0143                                            H5_ITER_INC,
0144                                            index,
0145                                            buffer,
0146                                            length,
0147                                            H5P_DEFAULT);
0148     });
0149 }
0150 
0151 template <typename Derivate>
0152 inline bool NodeTraits<Derivate>::rename(const std::string& src_path,
0153                                          const std::string& dst_path,
0154                                          bool parents) const {
0155     LinkCreateProps lcpl;
0156     lcpl.add(CreateIntermediateGroup(parents));
0157     herr_t err = detail::h5l_move(static_cast<const Derivate*>(this)->getId(),
0158                                   src_path.c_str(),
0159                                   static_cast<const Derivate*>(this)->getId(),
0160                                   dst_path.c_str(),
0161                                   lcpl.getId(),
0162                                   H5P_DEFAULT);
0163 
0164     return err >= 0;
0165 }
0166 
0167 template <typename Derivate>
0168 inline std::vector<std::string> NodeTraits<Derivate>::listObjectNames(IndexType idx_type) const {
0169     std::vector<std::string> names;
0170     details::HighFiveIterateData iterateData(names);
0171 
0172     size_t num_objs = getNumberObjects();
0173     names.reserve(num_objs);
0174 
0175     detail::h5l_iterate(static_cast<const Derivate*>(this)->getId(),
0176                         static_cast<H5_index_t>(idx_type),
0177                         H5_ITER_INC,
0178                         NULL,
0179                         &details::internal_high_five_iterate<H5L_info_t>,
0180                         static_cast<void*>(&iterateData));
0181     return names;
0182 }
0183 
0184 template <typename Derivate>
0185 inline bool NodeTraits<Derivate>::_exist(const std::string& node_path, bool raise_errors) const {
0186     SilenceHDF5 silencer{};
0187     const auto val = detail::nothrow::h5l_exists(static_cast<const Derivate*>(this)->getId(),
0188                                                  node_path.c_str(),
0189                                                  H5P_DEFAULT);
0190     if (val < 0) {
0191         if (raise_errors) {
0192             HDF5ErrMapper::ToException<GroupException>("Invalid link for exist()");
0193         } else {
0194             return false;
0195         }
0196     }
0197 
0198     // The root path always exists, but H5Lexists return 0 or 1
0199     // depending of the version of HDF5, so always return true for it
0200     // We had to call H5Lexists anyway to check that there are no errors
0201     return (node_path == "/") ? true : (val > 0);
0202 }
0203 
0204 template <typename Derivate>
0205 inline bool NodeTraits<Derivate>::exist(const std::string& node_path) const {
0206     // When there are slashes, first check everything is fine
0207     // so that subsequent errors are only due to missing intermediate groups
0208     if (node_path.find('/') != std::string::npos) {
0209         _exist("/");  // Shall not throw under normal circumstances
0210         // Unless "/" (already checked), verify path exists (not throwing errors)
0211         return (node_path == "/") ? true : _exist(node_path, false);
0212     }
0213     return _exist(node_path);
0214 }
0215 
0216 
0217 template <typename Derivate>
0218 inline void NodeTraits<Derivate>::unlink(const std::string& node_path) const {
0219     detail::h5l_delete(static_cast<const Derivate*>(this)->getId(), node_path.c_str(), H5P_DEFAULT);
0220 }
0221 
0222 
0223 // convert internal link types to enum class.
0224 // This function is internal, so H5L_TYPE_ERROR shall be handled in the calling context
0225 static inline LinkType _convert_link_type(const H5L_type_t& ltype) noexcept {
0226     switch (ltype) {
0227     case H5L_TYPE_HARD:
0228         return LinkType::Hard;
0229     case H5L_TYPE_SOFT:
0230         return LinkType::Soft;
0231     case H5L_TYPE_EXTERNAL:
0232         return LinkType::External;
0233     default:
0234         // Other link types are possible but are considered strange to HighFive.
0235         // see https://support.hdfgroup.org/HDF5/doc/RM/H5L/H5Lregister.htm
0236         return LinkType::Other;
0237     }
0238 }
0239 
0240 template <typename Derivate>
0241 inline LinkType NodeTraits<Derivate>::getLinkType(const std::string& node_path) const {
0242     H5L_info_t linkinfo;
0243     detail::h5l_get_info(static_cast<const Derivate*>(this)->getId(),
0244                          node_path.c_str(),
0245                          &linkinfo,
0246                          H5P_DEFAULT);
0247 
0248     if (linkinfo.type == H5L_TYPE_ERROR) {
0249         HDF5ErrMapper::ToException<GroupException>(std::string("Link type of \"") + node_path +
0250                                                    "\" is H5L_TYPE_ERROR");
0251     }
0252     return _convert_link_type(linkinfo.type);
0253 }
0254 
0255 template <typename Derivate>
0256 inline ObjectType NodeTraits<Derivate>::getObjectType(const std::string& node_path) const {
0257     const auto id = detail::h5o_open(static_cast<const Derivate*>(this)->getId(),
0258                                      node_path.c_str(),
0259                                      H5P_DEFAULT);
0260     auto object_type = _convert_object_type(detail::h5i_get_type(id));
0261     detail::h5o_close(id);
0262     return object_type;
0263 }
0264 
0265 
0266 template <typename Derivate>
0267 inline void NodeTraits<Derivate>::createSoftLink(const std::string& link_name,
0268                                                  const std::string& obj_path,
0269                                                  LinkCreateProps linkCreateProps,
0270                                                  const LinkAccessProps& linkAccessProps,
0271                                                  const bool parents) {
0272     if (parents) {
0273         linkCreateProps.add(CreateIntermediateGroup{});
0274     }
0275     detail::h5l_create_soft(obj_path.c_str(),
0276                             static_cast<const Derivate*>(this)->getId(),
0277                             link_name.c_str(),
0278                             linkCreateProps.getId(),
0279                             linkAccessProps.getId());
0280 }
0281 
0282 
0283 template <typename Derivate>
0284 inline void NodeTraits<Derivate>::createExternalLink(const std::string& link_name,
0285                                                      const std::string& h5_file,
0286                                                      const std::string& obj_path,
0287                                                      LinkCreateProps linkCreateProps,
0288                                                      const LinkAccessProps& linkAccessProps,
0289                                                      const bool parents) {
0290     if (parents) {
0291         linkCreateProps.add(CreateIntermediateGroup{});
0292     }
0293     detail::h5l_create_external(h5_file.c_str(),
0294                                 obj_path.c_str(),
0295                                 static_cast<const Derivate*>(this)->getId(),
0296                                 link_name.c_str(),
0297                                 linkCreateProps.getId(),
0298                                 linkAccessProps.getId());
0299 }
0300 
0301 template <typename Derivate>
0302 template <typename T, typename>
0303 inline void NodeTraits<Derivate>::createHardLink(const std::string& link_name,
0304                                                  const T& target_obj,
0305                                                  LinkCreateProps linkCreateProps,
0306                                                  const LinkAccessProps& linkAccessProps,
0307                                                  const bool parents) {
0308     static_assert(!std::is_same<T, Attribute>::value,
0309                   "hdf5 doesn't support hard links to Attributes");
0310     if (parents) {
0311         linkCreateProps.add(CreateIntermediateGroup{});
0312     }
0313     detail::h5l_create_hard(target_obj.getId(),
0314                             ".",
0315                             static_cast<const Derivate*>(this)->getId(),
0316                             link_name.c_str(),
0317                             linkCreateProps.getId(),
0318                             linkAccessProps.getId());
0319 }
0320 
0321 
0322 }  // namespace HighFive