hops
H5Node_traits_misc.hpp
Go to the documentation of this file.
1  /*
2  * Copyright (c), 2017, Adrien Devresse <adrien.devresse@epfl.ch>
3  *
4  * Distributed under the Boost Software License, Version 1.0.
5  * (See accompanying file LICENSE_1_0.txt or copy at
6  * http://www.boost.org/LICENSE_1_0.txt)
7  *
8  */
9 #ifndef H5NODE_TRAITS_MISC_HPP
10 #define H5NODE_TRAITS_MISC_HPP
11 
12 #include <string>
13 #include <vector>
14 
15 #include <H5Apublic.h>
16 #include <H5Dpublic.h>
17 #include <H5Fpublic.h>
18 #include <H5Gpublic.h>
19 #include <H5Ppublic.h>
20 #include <H5Tpublic.h>
21 
22 #include "../H5DataSet.hpp"
23 #include "../H5Group.hpp"
24 #include "../H5Selection.hpp"
25 #include "../H5Utility.hpp"
26 #include "H5DataSet_misc.hpp"
27 #include "H5Iterables_misc.hpp"
28 #include "H5Selection_misc.hpp"
29 #include "H5Slice_traits_misc.hpp"
30 
31 namespace HighFive {
32 
33 
34 template <typename Derivate>
35 inline DataSet
37  const DataSpace& space,
38  const DataType& dtype,
39  const DataSetCreateProps& createProps,
40  const DataSetAccessProps& accessProps) {
41  DataSet ds{H5Dcreate2(static_cast<Derivate*>(this)->getId(),
42  dataset_name.c_str(), dtype._hid, space._hid,
43  H5P_DEFAULT, createProps.getId(), accessProps.getId())};
44  if (ds._hid < 0) {
45  HDF5ErrMapper::ToException<DataSetException>(
46  std::string("Unable to create the dataset \"") + dataset_name +
47  "\":");
48  }
49  return ds;
50 }
51 
52 template <typename Derivate>
53 template <typename Type>
54 inline DataSet
56  const DataSpace& space,
57  const DataSetCreateProps& createProps,
58  const DataSetAccessProps& accessProps)
59 {
60  return createDataSet(dataset_name, space,
61  create_and_check_datatype<Type>(),
62  createProps, accessProps);
63 }
64 
65 template <typename Derivate>
66 template <typename T>
67 inline DataSet
69  const T& data,
70  const DataSetCreateProps& createProps,
71  const DataSetAccessProps& accessProps) {
72  DataSet ds = createDataSet(
73  dataset_name, DataSpace::From(data),
75  createProps, accessProps);
76  ds.write(data);
77  return ds;
78 }
79 
80 template <typename Derivate>
81 template <std::size_t N>
82 inline DataSet
84  const FixedLenStringArray<N>& data,
85  const DataSetCreateProps& createProps,
86  const DataSetAccessProps& accessProps) {
87  DataSet ds = createDataSet<char[N]>(
88  dataset_name, DataSpace(data.size()), createProps, accessProps);
89  ds.write(data);
90  return ds;
91 }
92 
93 template <typename Derivate>
94 inline DataSet
96  const DataSetAccessProps& accessProps) const {
97  DataSet ds{H5Dopen2(static_cast<const Derivate*>(this)->getId(),
98  dataset_name.c_str(), accessProps.getId())};
99  if (ds._hid < 0) {
100  HDF5ErrMapper::ToException<DataSetException>(
101  std::string("Unable to open the dataset \"") + dataset_name + "\":");
102  }
103  return ds;
104 }
105 
106 template <typename Derivate>
108  bool parents) {
110  if (parents) {
111  lcpl.add(H5Pset_create_intermediate_group, 1u);
112  }
113  Group group{H5Gcreate2(static_cast<Derivate*>(this)->getId(),
114  group_name.c_str(), lcpl.getId(), H5P_DEFAULT, H5P_DEFAULT)};
115  if (group._hid < 0) {
116  HDF5ErrMapper::ToException<GroupException>(
117  std::string("Unable to create the group \"") + group_name + "\":");
118  }
119  return group;
120 }
121 
122 template <typename Derivate>
123 inline Group
124 NodeTraits<Derivate>::getGroup(const std::string& group_name) const {
125  Group group{H5Gopen2(static_cast<const Derivate*>(this)->getId(),
126  group_name.c_str(), H5P_DEFAULT)};
127  if (group._hid < 0) {
128  HDF5ErrMapper::ToException<GroupException>(
129  std::string("Unable to open the group \"") + group_name + "\":");
130  }
131  return group;
132 }
133 
134 template <typename Derivate>
136  hsize_t res;
137  if (H5Gget_num_objs(static_cast<const Derivate*>(this)->getId(), &res) < 0) {
138  HDF5ErrMapper::ToException<GroupException>(
139  std::string("Unable to count objects in existing group or file"));
140  }
141  return static_cast<size_t>(res);
142 }
143 
144 template <typename Derivate>
146  return details::get_name([&](char* buffer, hsize_t length) {
147  return H5Lget_name_by_idx(
148  static_cast<const Derivate*>(this)->getId(), ".", H5_INDEX_NAME, H5_ITER_INC,
149  index, buffer, length, H5P_DEFAULT);
150  });
151 }
152 
153 template <typename Derivate>
155  return details::get_name([&](char* buffer, hsize_t length) {
156  return H5Iget_name(static_cast<const Derivate*>(this)->getId(), buffer, length);
157  });
158 }
159 
160 template <typename Derivate>
161 inline bool NodeTraits<Derivate>::rename(const std::string& src_path,
162  const std::string& dst_path, bool parents) const {
164  if (parents) {
165  lcpl.add(H5Pset_create_intermediate_group, 1u);
166  }
167  herr_t status = H5Lmove(static_cast<const Derivate*>(this)->getId(), src_path.c_str(),
168  static_cast<const Derivate*>(this)->getId(), dst_path.c_str(), lcpl.getId(), H5P_DEFAULT);
169  if (status < 0) {
170  HDF5ErrMapper::ToException<GroupException>(
171  std::string("Unable to move link to \"") + dst_path + "\":");
172  return false;
173  }
174  return true;
175 }
176 
177 template <typename Derivate>
178 inline std::vector<std::string> NodeTraits<Derivate>::listObjectNames() const {
179 
180  std::vector<std::string> names;
181  details::HighFiveIterateData iterateData(names);
182 
183  size_t num_objs = getNumberObjects();
184  names.reserve(num_objs);
185 
186  if (H5Literate(static_cast<const Derivate*>(this)->getId(), H5_INDEX_NAME,
187  H5_ITER_INC, NULL,
188  &details::internal_high_five_iterate<H5L_info_t>,
189  static_cast<void*>(&iterateData)) < 0) {
190  HDF5ErrMapper::ToException<GroupException>(
191  std::string("Unable to list objects in group"));
192  }
193 
194  return names;
195 }
196 
197 template <typename Derivate>
198 inline bool NodeTraits<Derivate>::_exist(const std::string& node_name,
199  bool raise_errors) const {
200  SilenceHDF5 silencer{!raise_errors};
201  const auto val = H5Lexists(static_cast<const Derivate*>(this)->getId(),
202  node_name.c_str(), H5P_DEFAULT);
203  if (val < 0) {
204  if (raise_errors) {
205  HDF5ErrMapper::ToException<GroupException>("Invalid link for exist()");
206  } else {
207  return false;
208  }
209  }
210 
211  // The root path always exists, but H5Lexists return 0 or 1
212  // depending of the version of HDF5, so always return true for it
213  // We had to call H5Lexists anyway to check that there are no errors
214  return (node_name == "/") ? true : (val > 0);
215 }
216 
217 template <typename Derivate>
218 inline bool NodeTraits<Derivate>::exist(const std::string& group_path) const {
219  // When there are slashes, first check everything is fine
220  // so that subsequent errors are only due to missing intermediate groups
221  if (group_path.find('/') != std::string::npos) {
222  _exist("/"); // Shall not throw under normal circumstances
223  // Unless "/" (already checked), verify path exists (not thowing errors)
224  return (group_path == "/") ? true : _exist(group_path, false);
225  }
226  return _exist(group_path);
227 }
228 
229 
230 template <typename Derivate>
231 inline void NodeTraits<Derivate>::unlink(const std::string& node_name) const {
232  const herr_t val = H5Ldelete(static_cast<const Derivate*>(this)->getId(),
233  node_name.c_str(), H5P_DEFAULT);
234  if (val < 0) {
235  HDF5ErrMapper::ToException<GroupException>(
236  std::string("Invalid name for unlink() "));
237  }
238 
239 }
240 
241 
242 
243 // convert internal link types to enum class.
244 // This function is internal, so H5L_TYPE_ERROR shall be handled in the calling context
245 static inline LinkType _convert_link_type(const H5L_type_t& ltype) noexcept {
246  switch (ltype) {
247  case H5L_TYPE_HARD:
248  return LinkType::Hard;
249  case H5L_TYPE_SOFT:
250  return LinkType::Soft;
251  case H5L_TYPE_EXTERNAL:
252  return LinkType::External;
253  default:
254  // Other link types are possible but are considered strange to HighFive.
255  // see https://support.hdfgroup.org/HDF5/doc/RM/H5L/H5Lregister.htm
256  return LinkType::Other;
257  }
258 }
259 
260 template <typename Derivate>
262  H5L_info_t linkinfo;
263  if (H5Lget_info(static_cast<const Derivate*>(this)->getId(),
264  node_name.c_str(), &linkinfo, H5P_DEFAULT) < 0
265  || linkinfo.type == H5L_TYPE_ERROR) {
266  HDF5ErrMapper::ToException<GroupException>(
267  std::string("Unable to obtain info for link ") + node_name);
268  }
269  return _convert_link_type(linkinfo.type);
270 }
271 
272 template <typename Derivate>
274  return _open(node_name).getType();
275 }
276 
277 
278 template <typename Derivate>
279 inline Object NodeTraits<Derivate>::_open(const std::string& node_name,
280  const DataSetAccessProps& accessProps) const {
281  hid_t id = H5Oopen(static_cast<const Derivate*>(this)->getId(),
282  node_name.c_str(),
283  accessProps.getId());
284  if (id < 0) {
285  HDF5ErrMapper::ToException<GroupException>(
286  std::string("Unable to open \"") + node_name + "\":");
287  }
288  return Object(id);
289 }
290 
291 
292 
293 } // namespace HighFive
294 
295 #endif // H5NODE_TRAITS_MISC_HPP
HighFive::details::get_name
std::string get_name(T fct)
Definition: H5Utils.hpp:252
HighFive::NodeTraits::getLinkType
LinkType getLinkType(const std::string &node_name) const
Returns the kind of link of the given name (soft, hard...)
Definition: H5Node_traits_misc.hpp:261
HighFive::NodeTraits::getPath
std::string getPath() const
return the path to the current object
Definition: H5Node_traits_misc.hpp:154
H5Slice_traits_misc.hpp
HighFive::DataType
HDF5 Data Type.
Definition: H5DataType.hpp:42
HighFive::RawPropertyList::add
void add(const F &funct, const Args &... args)
Definition: H5PropertyList_misc.hpp:106
H5Selection_misc.hpp
HighFive::NodeTraits::getDataSet
DataSet getDataSet(const std::string &dataset_name, const DataSetAccessProps &accessProps=DataSetAccessProps()) const
get an existing dataset in the current file
Definition: H5Node_traits_misc.hpp:95
HighFive::LinkType::Soft
@ Soft
HighFive::LinkType::External
@ External
HighFive::SilenceHDF5
Utility class to disable HDF5 stack printing inside a scope.
Definition: H5Utility.hpp:20
HighFive::LinkType::Hard
@ Hard
HighFive::_convert_link_type
static LinkType _convert_link_type(const H5L_type_t &ltype) noexcept
Definition: H5Node_traits_misc.hpp:245
HighFive::PropertyList
Base HDF5 property List.
Definition: H5_definitions.hpp:48
HighFive::LinkType::Other
@ Other
HighFive::DataSpace::From
static DataSpace From(const ScalarValue &scalar_value)
Definition: H5Dataspace_misc.hpp:129
H5DataSet_misc.hpp
HighFive::Object
Definition: H5Object.hpp:36
HighFive::NodeTraits::getObjectType
ObjectType getObjectType(const std::string &node_name) const
A shorthand to get the kind of object pointed to (group, dataset, type...)
Definition: H5Node_traits_misc.hpp:273
HighFive::FixedLenStringArray
A structure representing a set of fixed-length strings.
Definition: H5_definitions.hpp:42
HighFive::NodeTraits
NodeTraits: Base class for Group and File.
Definition: H5_definitions.hpp:45
HighFive::NodeTraits::getNumberObjects
size_t getNumberObjects() const
return the number of leaf objects of the node / group
Definition: H5Node_traits_misc.hpp:135
HighFive::SliceTraits::write
void write(const T &buffer)
Definition: H5Slice_traits_misc.hpp:200
HighFive::ObjectType
ObjectType
Enum of the types of objects (H5O api)
Definition: H5Object.hpp:25
HighFive::NodeTraits::getObjectName
std::string getObjectName(size_t index) const
return the name of the object with the given index
Definition: H5Node_traits_misc.hpp:145
HighFive::FixedLenStringArray::size
std::size_t size() const noexcept
Definition: H5DataType.hpp:281
HighFive::Group
Represents an hdf5 group.
Definition: H5Group.hpp:21
HighFive::details::HighFiveIterateData
Definition: H5Iterables_misc.hpp:24
H5Iterables_misc.hpp
HighFive::NodeTraits::getGroup
Group getGroup(const std::string &group_name) const
open an existing group with the name group_name
Definition: H5Node_traits_misc.hpp:124
HighFive::RawPropertyList
Definition: H5PropertyList.hpp:88
HighFive::PropertyList::getId
hid_t getId() const
Definition: H5PropertyList.hpp:56
HighFive::details::type_of_array::type
unqualified_t< T > type
Definition: H5Utils.hpp:137
HighFive::NodeTraits::unlink
void unlink(const std::string &node_name) const
unlink the given dataset or group
Definition: H5Node_traits_misc.hpp:231
HighFive::NodeTraits::rename
bool rename(const std::string &src_path, const std::string &dest_path, bool parents=true) const
moves an object and its content within an HDF5 file.
Definition: H5Node_traits_misc.hpp:161
HighFive::Object::_hid
hid_t _hid
Definition: H5Object.hpp:81
HighFive::create_and_check_datatype
DataType create_and_check_datatype()
Create a DataType instance representing type T and perform a sanity check on its size.
Definition: H5DataType_misc.hpp:406
HighFive::DataSpace
Class representing the space (dimensions) of a dataset.
Definition: H5DataSpace.hpp:37
HighFive::NodeTraits::createGroup
Group createGroup(const std::string &group_name, bool parents=true)
create a new group, and eventually intermediate groups
Definition: H5Node_traits_misc.hpp:107
string
NAME string(REPLACE ".cpp" "_bin" example_name ${example_filename}) if($
Definition: hops/Third-party/HighFive/src/examples/CMakeLists.txt:6
HighFive::NodeTraits::exist
bool exist(const std::string &node_name) const
check a dataset or group exists in the current node / group
Definition: H5Node_traits_misc.hpp:218
HighFive::NodeTraits::createDataSet
DataSet createDataSet(const std::string &dataset_name, const DataSpace &space, const DataType &type, const DataSetCreateProps &createProps=DataSetCreateProps(), const DataSetAccessProps &accessProps=DataSetAccessProps())
createDataSet Create a new dataset in the current file of datatype type and of size space
Definition: H5Node_traits_misc.hpp:36
HighFive::DataSet
Class representing a dataset.
Definition: H5DataSet.hpp:27
HighFive
Definition: H5_definitions.hpp:15
HighFive::LinkType
LinkType
The possible types of group entries (link concept)
Definition: H5Node_traits.hpp:173
HighFive::NodeTraits::listObjectNames
std::vector< std::string > listObjectNames() const
list all leaf objects name of the node / group
Definition: H5Node_traits_misc.hpp:178