Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-04-19 08:55: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 template <std::size_t N>
0085 inline DataSet NodeTraits<Derivate>::createDataSet(const std::string& dataset_name,
0086                                                    const deprecated::FixedLenStringArray<N>& data,
0087                                                    const DataSetCreateProps& createProps,
0088                                                    const DataSetAccessProps& accessProps,
0089                                                    bool parents) {
0090     DataSet ds = createDataSet<char[N]>(
0091         dataset_name, DataSpace(data.size()), createProps, accessProps, parents);
0092     ds.write(data);
0093     return ds;
0094 }
0095 
0096 template <typename Derivate>
0097 inline DataSet NodeTraits<Derivate>::getDataSet(const std::string& dataset_name,
0098                                                 const DataSetAccessProps& accessProps) const {
0099     return DataSet(detail::h5d_open2(static_cast<const Derivate*>(this)->getId(),
0100                                      dataset_name.c_str(),
0101                                      accessProps.getId()));
0102 }
0103 
0104 template <typename Derivate>
0105 inline Group NodeTraits<Derivate>::createGroup(const std::string& group_name, 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                                                   H5P_DEFAULT,
0112                                                   H5P_DEFAULT));
0113 }
0114 
0115 template <typename Derivate>
0116 inline Group NodeTraits<Derivate>::createGroup(const std::string& group_name,
0117                                                const GroupCreateProps& createProps,
0118                                                bool parents) {
0119     LinkCreateProps lcpl;
0120     lcpl.add(CreateIntermediateGroup(parents));
0121     return detail::make_group(detail::h5g_create2(static_cast<Derivate*>(this)->getId(),
0122                                                   group_name.c_str(),
0123                                                   lcpl.getId(),
0124                                                   createProps.getId(),
0125                                                   H5P_DEFAULT));
0126 }
0127 
0128 template <typename Derivate>
0129 inline Group NodeTraits<Derivate>::getGroup(const std::string& group_name) const {
0130     return detail::make_group(detail::h5g_open2(static_cast<const Derivate*>(this)->getId(),
0131                                                 group_name.c_str(),
0132                                                 H5P_DEFAULT));
0133 }
0134 
0135 template <typename Derivate>
0136 inline DataType NodeTraits<Derivate>::getDataType(const std::string& type_name,
0137                                                   const DataTypeAccessProps& accessProps) const {
0138     return DataType(detail::h5t_open2(static_cast<const Derivate*>(this)->getId(),
0139                                       type_name.c_str(),
0140                                       accessProps.getId()));
0141 }
0142 
0143 template <typename Derivate>
0144 inline size_t NodeTraits<Derivate>::getNumberObjects() const {
0145     hsize_t res;
0146     detail::h5g_get_num_objs(static_cast<const Derivate*>(this)->getId(), &res);
0147     return static_cast<size_t>(res);
0148 }
0149 
0150 template <typename Derivate>
0151 inline std::string NodeTraits<Derivate>::getObjectName(size_t index) const {
0152     return details::get_name([&](char* buffer, size_t length) {
0153         return detail::h5l_get_name_by_idx(static_cast<const Derivate*>(this)->getId(),
0154                                            ".",
0155                                            H5_INDEX_NAME,
0156                                            H5_ITER_INC,
0157                                            index,
0158                                            buffer,
0159                                            length,
0160                                            H5P_DEFAULT);
0161     });
0162 }
0163 
0164 template <typename Derivate>
0165 inline bool NodeTraits<Derivate>::rename(const std::string& src_path,
0166                                          const std::string& dst_path,
0167                                          bool parents) const {
0168     LinkCreateProps lcpl;
0169     lcpl.add(CreateIntermediateGroup(parents));
0170     herr_t err = detail::h5l_move(static_cast<const Derivate*>(this)->getId(),
0171                                   src_path.c_str(),
0172                                   static_cast<const Derivate*>(this)->getId(),
0173                                   dst_path.c_str(),
0174                                   lcpl.getId(),
0175                                   H5P_DEFAULT);
0176 
0177     return err >= 0;
0178 }
0179 
0180 template <typename Derivate>
0181 inline std::vector<std::string> NodeTraits<Derivate>::listObjectNames(IndexType idx_type) const {
0182     std::vector<std::string> names;
0183     details::HighFiveIterateData iterateData(names);
0184 
0185     size_t num_objs = getNumberObjects();
0186     names.reserve(num_objs);
0187 
0188     detail::h5l_iterate(static_cast<const Derivate*>(this)->getId(),
0189                         static_cast<H5_index_t>(idx_type),
0190                         H5_ITER_INC,
0191                         NULL,
0192                         &details::internal_high_five_iterate<H5L_info_t>,
0193                         static_cast<void*>(&iterateData));
0194     return names;
0195 }
0196 
0197 template <typename Derivate>
0198 inline bool NodeTraits<Derivate>::_exist(const std::string& node_name, bool raise_errors) const {
0199     SilenceHDF5 silencer{};
0200     const auto val = detail::nothrow::h5l_exists(static_cast<const Derivate*>(this)->getId(),
0201                                                  node_name.c_str(),
0202                                                  H5P_DEFAULT);
0203     if (val < 0) {
0204         if (raise_errors) {
0205             HDF5ErrMapper::ToException<GroupException>("Invalid link for exist()");
0206         } else {
0207             return false;
0208         }
0209     }
0210 
0211     // The root path always exists, but H5Lexists return 0 or 1
0212     // depending of the version of HDF5, so always return true for it
0213     // We had to call H5Lexists anyway to check that there are no errors
0214     return (node_name == "/") ? true : (val > 0);
0215 }
0216 
0217 template <typename Derivate>
0218 inline bool NodeTraits<Derivate>::exist(const std::string& group_path) const {
0219     // When there are slashes, first check everything is fine
0220     // so that subsequent errors are only due to missing intermediate groups
0221     if (group_path.find('/') != std::string::npos) {
0222         _exist("/");  // Shall not throw under normal circumstances
0223         // Unless "/" (already checked), verify path exists (not throwing errors)
0224         return (group_path == "/") ? true : _exist(group_path, false);
0225     }
0226     return _exist(group_path);
0227 }
0228 
0229 
0230 template <typename Derivate>
0231 inline void NodeTraits<Derivate>::unlink(const std::string& node_name) const {
0232     detail::h5l_delete(static_cast<const Derivate*>(this)->getId(), node_name.c_str(), H5P_DEFAULT);
0233 }
0234 
0235 
0236 // convert internal link types to enum class.
0237 // This function is internal, so H5L_TYPE_ERROR shall be handled in the calling context
0238 static inline LinkType _convert_link_type(const H5L_type_t& ltype) noexcept {
0239     switch (ltype) {
0240     case H5L_TYPE_HARD:
0241         return LinkType::Hard;
0242     case H5L_TYPE_SOFT:
0243         return LinkType::Soft;
0244     case H5L_TYPE_EXTERNAL:
0245         return LinkType::External;
0246     default:
0247         // Other link types are possible but are considered strange to HighFive.
0248         // see https://support.hdfgroup.org/HDF5/doc/RM/H5L/H5Lregister.htm
0249         return LinkType::Other;
0250     }
0251 }
0252 
0253 template <typename Derivate>
0254 inline LinkType NodeTraits<Derivate>::getLinkType(const std::string& node_name) const {
0255     H5L_info_t linkinfo;
0256     detail::h5l_get_info(static_cast<const Derivate*>(this)->getId(),
0257                          node_name.c_str(),
0258                          &linkinfo,
0259                          H5P_DEFAULT);
0260 
0261     if (linkinfo.type == H5L_TYPE_ERROR) {
0262         HDF5ErrMapper::ToException<GroupException>(std::string("Link type of \"") + node_name +
0263                                                    "\" is H5L_TYPE_ERROR");
0264     }
0265     return _convert_link_type(linkinfo.type);
0266 }
0267 
0268 template <typename Derivate>
0269 inline ObjectType NodeTraits<Derivate>::getObjectType(const std::string& node_name) const {
0270     return _open(node_name).getType();
0271 }
0272 
0273 
0274 template <typename Derivate>
0275 inline void NodeTraits<Derivate>::createSoftLink(const std::string& link_name,
0276                                                  const std::string& obj_path,
0277                                                  LinkCreateProps linkCreateProps,
0278                                                  const LinkAccessProps& linkAccessProps,
0279                                                  const bool parents) {
0280     if (parents) {
0281         linkCreateProps.add(CreateIntermediateGroup{});
0282     }
0283     detail::h5l_create_soft(obj_path.c_str(),
0284                             static_cast<const Derivate*>(this)->getId(),
0285                             link_name.c_str(),
0286                             linkCreateProps.getId(),
0287                             linkAccessProps.getId());
0288 }
0289 
0290 
0291 template <typename Derivate>
0292 inline void NodeTraits<Derivate>::createExternalLink(const std::string& link_name,
0293                                                      const std::string& h5_file,
0294                                                      const std::string& obj_path,
0295                                                      LinkCreateProps linkCreateProps,
0296                                                      const LinkAccessProps& linkAccessProps,
0297                                                      const bool parents) {
0298     if (parents) {
0299         linkCreateProps.add(CreateIntermediateGroup{});
0300     }
0301     detail::h5l_create_external(h5_file.c_str(),
0302                                 obj_path.c_str(),
0303                                 static_cast<const Derivate*>(this)->getId(),
0304                                 link_name.c_str(),
0305                                 linkCreateProps.getId(),
0306                                 linkAccessProps.getId());
0307 }
0308 
0309 template <typename Derivate>
0310 template <typename T, typename>
0311 inline void NodeTraits<Derivate>::createHardLink(const std::string& link_name,
0312                                                  const T& target_obj,
0313                                                  LinkCreateProps linkCreateProps,
0314                                                  const LinkAccessProps& linkAccessProps,
0315                                                  const bool parents) {
0316     static_assert(!std::is_same<T, Attribute>::value,
0317                   "hdf5 doesn't support hard links to Attributes");
0318     if (parents) {
0319         linkCreateProps.add(CreateIntermediateGroup{});
0320     }
0321     detail::h5l_create_hard(target_obj.getId(),
0322                             ".",
0323                             static_cast<const Derivate*>(this)->getId(),
0324                             link_name.c_str(),
0325                             linkCreateProps.getId(),
0326                             linkAccessProps.getId());
0327 }
0328 
0329 
0330 template <typename Derivate>
0331 inline Object NodeTraits<Derivate>::_open(const std::string& node_name) const {
0332     const auto id = detail::h5o_open(static_cast<const Derivate*>(this)->getId(),
0333                                      node_name.c_str(),
0334                                      H5P_DEFAULT);
0335     return detail::make_object(id);
0336 }
0337 
0338 
0339 }  // namespace HighFive