HighFive 2.3.1
HighFive - Header-only C++ HDF5 interface
Loading...
Searching...
No Matches
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"
30
31namespace HighFive {
32
33
34template <typename Derivate>
35inline DataSet
36NodeTraits<Derivate>::createDataSet(const std::string& dataset_name,
37 const DataSpace& space,
38 const DataType& dtype,
39 const DataSetCreateProps& createProps,
40 const DataSetAccessProps& accessProps,
41 bool parents) {
42 LinkCreateProps lcpl;
43 lcpl.add(CreateIntermediateGroup(parents));
44 const auto hid = H5Dcreate2(static_cast<Derivate*>(this)->getId(),
45 dataset_name.c_str(), dtype._hid, space._hid,
46 lcpl.getId(), createProps.getId(), accessProps.getId());
47 if (hid < 0) {
48 HDF5ErrMapper::ToException<DataSetException>(
49 std::string("Unable to create the dataset \"") + dataset_name + "\":");
50 }
51 return DataSet(hid);
52}
53
54template <typename Derivate>
55template <typename Type>
56inline DataSet
57NodeTraits<Derivate>::createDataSet(const std::string& dataset_name,
58 const DataSpace& space,
59 const DataSetCreateProps& createProps,
60 const DataSetAccessProps& accessProps,
61 bool parents) {
62 return createDataSet(dataset_name, space,
63 create_and_check_datatype<Type>(),
64 createProps, accessProps, parents);
65}
66
67template <typename Derivate>
68template <typename T>
69inline DataSet
70NodeTraits<Derivate>::createDataSet(const std::string& dataset_name,
71 const T& data,
72 const DataSetCreateProps& createProps,
73 const DataSetAccessProps& accessProps,
74 bool parents) {
75 DataSet ds = createDataSet(
76 dataset_name, DataSpace::From(data),
77 create_and_check_datatype<typename details::inspector<T>::base_type>(),
78 createProps, accessProps, parents);
79 ds.write(data);
80 return ds;
82
83template <typename Derivate>
84template <std::size_t N>
85inline DataSet
86NodeTraits<Derivate>::createDataSet(const std::string& dataset_name,
87 const FixedLenStringArray<N>& data,
88 const DataSetCreateProps& createProps,
89 const DataSetAccessProps& accessProps,
90 bool parents) {
91 DataSet ds = createDataSet<char[N]>(
92 dataset_name, DataSpace(data.size()), createProps, accessProps, parents);
93 ds.write(data);
94 return ds;
95}
96
97template <typename Derivate>
98inline DataSet
99NodeTraits<Derivate>::getDataSet(const std::string& dataset_name,
100 const DataSetAccessProps& accessProps) const {
101 const auto hid = H5Dopen2(static_cast<const Derivate*>(this)->getId(),
102 dataset_name.c_str(), accessProps.getId());
103 if (hid < 0) {
104 HDF5ErrMapper::ToException<DataSetException>(
105 std::string("Unable to open the dataset \"") + dataset_name + "\":");
106 }
107 return DataSet(hid);
108}
109
110template <typename Derivate>
111inline Group NodeTraits<Derivate>::createGroup(const std::string& group_name,
112 bool parents) {
113
114 LinkCreateProps lcpl;
115 lcpl.add(CreateIntermediateGroup(parents));
116 const auto hid = H5Gcreate2(static_cast<Derivate*>(this)->getId(),
117 group_name.c_str(), lcpl.getId(), H5P_DEFAULT, H5P_DEFAULT);
118 if (hid < 0) {
119 HDF5ErrMapper::ToException<GroupException>(
120 std::string("Unable to create the group \"") + group_name + "\":");
121 }
122 return Group(hid);
123}
124
125template <typename Derivate>
126inline Group
127NodeTraits<Derivate>::getGroup(const std::string& group_name) const {
128 const auto hid = H5Gopen2(static_cast<const Derivate*>(this)->getId(),
129 group_name.c_str(), H5P_DEFAULT);
130 if (hid < 0) {
131 HDF5ErrMapper::ToException<GroupException>(
132 std::string("Unable to open the group \"") + group_name + "\":");
133 }
134 return Group(hid);
135}
136
137template <typename Derivate>
139 hsize_t res;
140 if (H5Gget_num_objs(static_cast<const Derivate*>(this)->getId(), &res) < 0) {
141 HDF5ErrMapper::ToException<GroupException>(
142 std::string("Unable to count objects in existing group or file"));
144 return static_cast<size_t>(res);
145}
146
147template <typename Derivate>
148inline std::string NodeTraits<Derivate>::getObjectName(size_t index) const {
149 return details::get_name([&](char* buffer, hsize_t length) {
150 return H5Lget_name_by_idx(
151 static_cast<const Derivate*>(this)->getId(), ".", H5_INDEX_NAME, H5_ITER_INC,
152 index, buffer, static_cast<size_t>(length), H5P_DEFAULT);
153 });
154}
155
156template <typename Derivate>
157inline bool NodeTraits<Derivate>::rename(const std::string& src_path,
158 const std::string& dst_path,
159 bool parents) const {
160 LinkCreateProps lcpl;
161 lcpl.add(CreateIntermediateGroup(parents));
162 herr_t status = H5Lmove(static_cast<const Derivate*>(this)->getId(), src_path.c_str(),
163 static_cast<const Derivate*>(this)->getId(), dst_path.c_str(), lcpl.getId(), H5P_DEFAULT);
164 if (status < 0) {
165 HDF5ErrMapper::ToException<GroupException>(
166 std::string("Unable to move link to \"") + dst_path + "\":");
167 return false;
168 }
169 return true;
170}
171
172template <typename Derivate>
173inline std::vector<std::string> NodeTraits<Derivate>::listObjectNames() const {
174
175 std::vector<std::string> names;
176 details::HighFiveIterateData iterateData(names);
177
178 size_t num_objs = getNumberObjects();
179 names.reserve(num_objs);
180
181 if (H5Literate(static_cast<const Derivate*>(this)->getId(), H5_INDEX_NAME,
182 H5_ITER_INC, NULL,
183 &details::internal_high_five_iterate<H5L_info_t>,
184 static_cast<void*>(&iterateData)) < 0) {
185 HDF5ErrMapper::ToException<GroupException>(
186 std::string("Unable to list objects in group"));
187 }
188
189 return names;
190}
191
192template <typename Derivate>
193inline bool NodeTraits<Derivate>::_exist(const std::string& node_name,
194 bool raise_errors) const {
195 SilenceHDF5 silencer{};
196 const auto val = H5Lexists(static_cast<const Derivate*>(this)->getId(),
197 node_name.c_str(), H5P_DEFAULT);
198 if (val < 0) {
199 if (raise_errors) {
200 HDF5ErrMapper::ToException<GroupException>("Invalid link for exist()");
201 } else {
202 return false;
203 }
204 }
205
206 // The root path always exists, but H5Lexists return 0 or 1
207 // depending of the version of HDF5, so always return true for it
208 // We had to call H5Lexists anyway to check that there are no errors
209 return (node_name == "/") ? true : (val > 0);
210}
211
212template <typename Derivate>
213inline bool NodeTraits<Derivate>::exist(const std::string& group_path) const {
214 // When there are slashes, first check everything is fine
215 // so that subsequent errors are only due to missing intermediate groups
216 if (group_path.find('/') != std::string::npos) {
217 _exist("/"); // Shall not throw under normal circumstances
218 // Unless "/" (already checked), verify path exists (not throwing errors)
219 return (group_path == "/") ? true : _exist(group_path, false);
220 }
221 return _exist(group_path);
222}
223
224
225template <typename Derivate>
226inline void NodeTraits<Derivate>::unlink(const std::string& node_name) const {
227 const herr_t val = H5Ldelete(static_cast<const Derivate*>(this)->getId(),
228 node_name.c_str(), H5P_DEFAULT);
229 if (val < 0) {
230 HDF5ErrMapper::ToException<GroupException>(
231 std::string("Invalid name for unlink() "));
232 }
233
234}
235
236
237
238// convert internal link types to enum class.
239// This function is internal, so H5L_TYPE_ERROR shall be handled in the calling context
240static inline LinkType _convert_link_type(const H5L_type_t& ltype) noexcept {
241 switch (ltype) {
242 case H5L_TYPE_HARD:
243 return LinkType::Hard;
244 case H5L_TYPE_SOFT:
245 return LinkType::Soft;
246 case H5L_TYPE_EXTERNAL:
247 return LinkType::External;
248 default:
249 // Other link types are possible but are considered strange to HighFive.
250 // see https://support.hdfgroup.org/HDF5/doc/RM/H5L/H5Lregister.htm
251 return LinkType::Other;
252 }
253}
254
255template <typename Derivate>
256inline LinkType NodeTraits<Derivate>::getLinkType(const std::string& node_name) const {
257 H5L_info_t linkinfo;
258 if (H5Lget_info(static_cast<const Derivate*>(this)->getId(),
259 node_name.c_str(), &linkinfo, H5P_DEFAULT) < 0
260 || linkinfo.type == H5L_TYPE_ERROR) {
261 HDF5ErrMapper::ToException<GroupException>(
262 std::string("Unable to obtain info for link ") + node_name);
263 }
264 return _convert_link_type(linkinfo.type);
265}
266
267template <typename Derivate>
268inline ObjectType NodeTraits<Derivate>::getObjectType(const std::string& node_name) const {
269 return _open(node_name).getType();
270}
271
272
273template <typename Derivate>
274inline void NodeTraits<Derivate>::createSoftLink(const std::string& link_name,
275 const std::string& obj_path,
276 LinkCreateProps linkCreateProps,
277 const LinkAccessProps& linkAccessProps,
278 const bool parents) {
279 if (parents) {
280 linkCreateProps.add(CreateIntermediateGroup{});
281 }
282 auto status = H5Lcreate_soft(obj_path.c_str(),
283 static_cast<const Derivate*>(this)->getId(),
284 link_name.c_str(),
285 linkCreateProps.getId(), linkAccessProps.getId());
286 if (status < 0) {
287 HDF5ErrMapper::ToException<GroupException>(
288 std::string("Unable to create soft link: "));
289 }
290}
291
292
293template <typename Derivate>
294inline void NodeTraits<Derivate>::createExternalLink(const std::string& link_name,
295 const std::string& h5_file,
296 const std::string& obj_path,
297 LinkCreateProps linkCreateProps,
298 const LinkAccessProps& linkAccessProps,
299 const bool parents) {
300 if (parents) {
301 linkCreateProps.add(CreateIntermediateGroup{});
302 }
303 auto status = H5Lcreate_external(h5_file.c_str(),
304 obj_path.c_str(),
305 static_cast<const Derivate*>(this)->getId(),
306 link_name.c_str(),
307 linkCreateProps.getId(), linkAccessProps.getId());
308 if (status < 0) {
309 HDF5ErrMapper::ToException<GroupException>(
310 std::string("Unable to create external link: "));
311 }
312}
313
314
315template <typename Derivate>
316inline Object NodeTraits<Derivate>::_open(const std::string& node_name,
317 const DataSetAccessProps& accessProps) const {
318 const auto id = H5Oopen(static_cast<const Derivate*>(this)->getId(),
319 node_name.c_str(),
320 accessProps.getId());
321 if (id < 0) {
322 HDF5ErrMapper::ToException<GroupException>(
323 std::string("Unable to open \"") + node_name + "\":");
324 }
325 return Object(id);
326}
327
328
329
330} // namespace HighFive
331
332#endif // H5NODE_TRAITS_MISC_HPP
Definition H5PropertyList.hpp:196
Class representing a dataset.
Definition H5DataSet.hpp:31
Class representing the space (dimensions) of a dataset.
Definition H5DataSpace.hpp:37
static DataSpace From(const T &value)
Create a dataspace matching a type accepted by details::inspector.
Definition H5Dataspace_misc.hpp:133
HDF5 Data Type.
Definition H5DataType.hpp:42
A structure representing a set of fixed-length strings.
Definition H5DataType.hpp:239
std::size_t size() const noexcept
Definition H5DataType.hpp:281
Represents an hdf5 group.
Definition H5Group.hpp:25
NodeTraits: Base class for Group and File.
Definition H5Node_traits.hpp:23
Group getGroup(const std::string &group_name) const
open an existing group with the name group_name
Definition H5Node_traits_misc.hpp:127
void unlink(const std::string &node_name) const
unlink the given dataset or group
Definition H5Node_traits_misc.hpp:226
void createExternalLink(const std::string &link_name, const std::string &h5_file, const std::string &obj_path, LinkCreateProps linkCreateProps=LinkCreateProps(), const LinkAccessProps &linkAccessProps=LinkAccessProps(), const bool parents=true)
Definition H5Node_traits_misc.hpp:294
DataSet getDataSet(const std::string &dataset_name, const DataSetAccessProps &accessProps=DataSetAccessProps::Default()) const
get an existing dataset in the current file
Definition H5Node_traits_misc.hpp:99
void createSoftLink(const std::string &linkName, const T &obj)
A shorthand to create softlink to any object which provides getPath The link will be created with def...
Definition H5Node_traits.hpp:159
Group createGroup(const std::string &group_name, bool parents=true)
create a new group, and eventually intermediate groups
Definition H5Node_traits_misc.hpp:111
DataSet createDataSet(const std::string &dataset_name, const DataSpace &space, const DataType &type, const DataSetCreateProps &createProps=DataSetCreateProps::Default(), const DataSetAccessProps &accessProps=DataSetAccessProps::Default(), bool parents=true)
createDataSet Create a new dataset in the current file of datatype type and of size space
Definition H5Node_traits_misc.hpp:36
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:157
bool exist(const std::string &node_name) const
check a dataset or group exists in the current node / group
Definition H5Node_traits_misc.hpp:213
std::vector< std::string > listObjectNames() const
list all leaf objects name of the node / group
Definition H5Node_traits_misc.hpp:173
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:268
size_t getNumberObjects() const
return the number of leaf objects of the node / group
Definition H5Node_traits_misc.hpp:138
std::string getObjectName(size_t index) const
return the name of the object with the given index
Definition H5Node_traits_misc.hpp:148
LinkType getLinkType(const std::string &node_name) const
Returns the kind of link of the given name (soft, hard...)
Definition H5Node_traits_misc.hpp:256
Definition H5Object.hpp:36
hid_t getId() const noexcept
getId
Definition H5Object_misc.hpp:55
hid_t _hid
Definition H5Object.hpp:87
HDF5 property Lists.
Definition H5PropertyList.hpp:62
void add(const P &property)
Definition H5PropertyList_misc.hpp:77
void write(const T &buffer)
Definition H5Slice_traits_misc.hpp:214
Definition H5_definitions.hpp:15
DataType create_and_check_datatype()
Create a DataType instance representing type T and perform a sanity check on its size.
Definition H5DataType_misc.hpp:434
LinkType
The possible types of group entries (link concept)
Definition H5Node_traits.hpp:202
ObjectType
Enum of the types of objects (H5O api)
Definition H5Object.hpp:25