HighFive 2.9.0
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#pragma once
10
11#include <string>
12#include <vector>
13
14#include <H5Apublic.h>
15#include <H5Fpublic.h>
16#include <H5Ppublic.h>
17#include <H5Tpublic.h>
18
19#include "../H5DataSet.hpp"
20#include "../H5Group.hpp"
21#include "../H5Selection.hpp"
22#include "../H5Utility.hpp"
23#include "H5DataSet_misc.hpp"
24#include "H5Iterables_misc.hpp"
25#include "H5Selection_misc.hpp"
27
28#include "h5l_wrapper.hpp"
29#include "h5g_wrapper.hpp"
30#include "h5o_wrapper.hpp"
31
32
33namespace HighFive {
34
35
36template <typename Derivate>
37inline DataSet NodeTraits<Derivate>::createDataSet(const std::string& dataset_name,
38 const DataSpace& space,
39 const DataType& dtype,
40 const DataSetCreateProps& createProps,
41 const DataSetAccessProps& accessProps,
42 bool parents) {
43 LinkCreateProps lcpl;
44 lcpl.add(CreateIntermediateGroup(parents));
45 return DataSet(detail::h5d_create2(static_cast<Derivate*>(this)->getId(),
46 dataset_name.c_str(),
47 dtype.getId(),
48 space.getId(),
49 lcpl.getId(),
50 createProps.getId(),
51 accessProps.getId()));
52}
53
54template <typename Derivate>
55template <typename T>
56inline DataSet NodeTraits<Derivate>::createDataSet(const std::string& dataset_name,
57 const DataSpace& space,
58 const DataSetCreateProps& createProps,
59 const DataSetAccessProps& accessProps,
60 bool parents) {
61 return createDataSet(
62 dataset_name, space, create_and_check_datatype<T>(), createProps, accessProps, parents);
63}
64
65template <typename Derivate>
66template <typename T>
67inline DataSet NodeTraits<Derivate>::createDataSet(const std::string& dataset_name,
68 const T& data,
69 const DataSetCreateProps& createProps,
70 const DataSetAccessProps& accessProps,
71 bool parents) {
72 DataSet ds =
73 createDataSet(dataset_name,
75 create_and_check_datatype<typename details::inspector<T>::base_type>(),
76 createProps,
77 accessProps,
78 parents);
79 ds.write(data);
80 return ds;
81}
82
83template <typename Derivate>
84template <std::size_t N>
85inline DataSet NodeTraits<Derivate>::createDataSet(const std::string& dataset_name,
87 const DataSetCreateProps& createProps,
88 const DataSetAccessProps& accessProps,
89 bool parents) {
90 DataSet ds = createDataSet<char[N]>(
91 dataset_name, DataSpace(data.size()), createProps, accessProps, parents);
92 ds.write(data);
93 return ds;
95
96template <typename Derivate>
97inline DataSet NodeTraits<Derivate>::getDataSet(const std::string& dataset_name,
98 const DataSetAccessProps& accessProps) const {
99 return DataSet(detail::h5d_open2(static_cast<const Derivate*>(this)->getId(),
100 dataset_name.c_str(),
101 accessProps.getId()));
103
104template <typename Derivate>
105inline Group NodeTraits<Derivate>::createGroup(const std::string& group_name, bool parents) {
106 LinkCreateProps lcpl;
107 lcpl.add(CreateIntermediateGroup(parents));
108 return detail::make_group(detail::h5g_create2(static_cast<Derivate*>(this)->getId(),
109 group_name.c_str(),
110 lcpl.getId(),
111 H5P_DEFAULT,
112 H5P_DEFAULT));
113}
114
115template <typename Derivate>
116inline Group NodeTraits<Derivate>::createGroup(const std::string& group_name,
117 const GroupCreateProps& createProps,
118 bool parents) {
119 LinkCreateProps lcpl;
120 lcpl.add(CreateIntermediateGroup(parents));
121 return detail::make_group(detail::h5g_create2(static_cast<Derivate*>(this)->getId(),
122 group_name.c_str(),
123 lcpl.getId(),
124 createProps.getId(),
125 H5P_DEFAULT));
126}
127
128template <typename Derivate>
129inline Group NodeTraits<Derivate>::getGroup(const std::string& group_name) const {
130 return detail::make_group(detail::h5g_open2(static_cast<const Derivate*>(this)->getId(),
131 group_name.c_str(),
132 H5P_DEFAULT));
133}
134
135template <typename Derivate>
136inline DataType NodeTraits<Derivate>::getDataType(const std::string& type_name,
137 const DataTypeAccessProps& accessProps) const {
138 return DataType(detail::h5t_open2(static_cast<const Derivate*>(this)->getId(),
139 type_name.c_str(),
140 accessProps.getId()));
141}
142
143template <typename Derivate>
145 hsize_t res;
146 detail::h5g_get_num_objs(static_cast<const Derivate*>(this)->getId(), &res);
147 return static_cast<size_t>(res);
148}
149
150template <typename Derivate>
151inline std::string NodeTraits<Derivate>::getObjectName(size_t index) const {
152 return details::get_name([&](char* buffer, size_t length) {
153 return detail::h5l_get_name_by_idx(static_cast<const Derivate*>(this)->getId(),
154 ".",
155 H5_INDEX_NAME,
156 H5_ITER_INC,
157 index,
158 buffer,
159 length,
160 H5P_DEFAULT);
161 });
162}
163
164template <typename Derivate>
165inline bool NodeTraits<Derivate>::rename(const std::string& src_path,
166 const std::string& dst_path,
167 bool parents) const {
168 LinkCreateProps lcpl;
169 lcpl.add(CreateIntermediateGroup(parents));
170 herr_t err = detail::h5l_move(static_cast<const Derivate*>(this)->getId(),
171 src_path.c_str(),
172 static_cast<const Derivate*>(this)->getId(),
173 dst_path.c_str(),
174 lcpl.getId(),
175 H5P_DEFAULT);
176
177 return err >= 0;
178}
179
180template <typename Derivate>
181inline std::vector<std::string> NodeTraits<Derivate>::listObjectNames(IndexType idx_type) const {
182 std::vector<std::string> names;
183 details::HighFiveIterateData iterateData(names);
184
185 size_t num_objs = getNumberObjects();
186 names.reserve(num_objs);
187
188 detail::h5l_iterate(static_cast<const Derivate*>(this)->getId(),
189 static_cast<H5_index_t>(idx_type),
190 H5_ITER_INC,
191 NULL,
192 &details::internal_high_five_iterate<H5L_info_t>,
193 static_cast<void*>(&iterateData));
194 return names;
195}
196
197template <typename Derivate>
198inline bool NodeTraits<Derivate>::_exist(const std::string& node_name, bool raise_errors) const {
199 SilenceHDF5 silencer{};
200 const auto val = detail::nothrow::h5l_exists(static_cast<const Derivate*>(this)->getId(),
201 node_name.c_str(),
202 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);
216
217template <typename Derivate>
218inline 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 throwing errors)
224 return (group_path == "/") ? true : _exist(group_path, false);
225 }
226 return _exist(group_path);
227}
228
229
230template <typename Derivate>
231inline void NodeTraits<Derivate>::unlink(const std::string& node_name) const {
232 detail::h5l_delete(static_cast<const Derivate*>(this)->getId(), node_name.c_str(), H5P_DEFAULT);
233}
234
235
236// convert internal link types to enum class.
237// This function is internal, so H5L_TYPE_ERROR shall be handled in the calling context
238static inline LinkType _convert_link_type(const H5L_type_t& ltype) noexcept {
239 switch (ltype) {
240 case H5L_TYPE_HARD:
241 return LinkType::Hard;
242 case H5L_TYPE_SOFT:
243 return LinkType::Soft;
244 case H5L_TYPE_EXTERNAL:
245 return LinkType::External;
246 default:
247 // Other link types are possible but are considered strange to HighFive.
248 // see https://support.hdfgroup.org/HDF5/doc/RM/H5L/H5Lregister.htm
249 return LinkType::Other;
250 }
251}
252
253template <typename Derivate>
254inline LinkType NodeTraits<Derivate>::getLinkType(const std::string& node_name) const {
255 H5L_info_t linkinfo;
256 detail::h5l_get_info(static_cast<const Derivate*>(this)->getId(),
257 node_name.c_str(),
258 &linkinfo,
259 H5P_DEFAULT);
260
261 if (linkinfo.type == H5L_TYPE_ERROR) {
262 HDF5ErrMapper::ToException<GroupException>(std::string("Link type of \"") + node_name +
263 "\" is H5L_TYPE_ERROR");
264 }
265 return _convert_link_type(linkinfo.type);
266}
267
268template <typename Derivate>
269inline ObjectType NodeTraits<Derivate>::getObjectType(const std::string& node_name) const {
270 return _open(node_name).getType();
271}
272
273
274template <typename Derivate>
275inline void NodeTraits<Derivate>::createSoftLink(const std::string& link_name,
276 const std::string& obj_path,
277 LinkCreateProps linkCreateProps,
278 const LinkAccessProps& linkAccessProps,
279 const bool parents) {
280 if (parents) {
281 linkCreateProps.add(CreateIntermediateGroup{});
282 }
283 detail::h5l_create_soft(obj_path.c_str(),
284 static_cast<const Derivate*>(this)->getId(),
285 link_name.c_str(),
286 linkCreateProps.getId(),
287 linkAccessProps.getId());
288}
289
290
291template <typename Derivate>
292inline void NodeTraits<Derivate>::createExternalLink(const std::string& link_name,
293 const std::string& h5_file,
294 const std::string& obj_path,
295 LinkCreateProps linkCreateProps,
296 const LinkAccessProps& linkAccessProps,
297 const bool parents) {
298 if (parents) {
299 linkCreateProps.add(CreateIntermediateGroup{});
300 }
301 detail::h5l_create_external(h5_file.c_str(),
302 obj_path.c_str(),
303 static_cast<const Derivate*>(this)->getId(),
304 link_name.c_str(),
305 linkCreateProps.getId(),
306 linkAccessProps.getId());
307}
308
309template <typename Derivate>
310template <typename T, typename>
311inline void NodeTraits<Derivate>::createHardLink(const std::string& link_name,
312 const T& target_obj,
313 LinkCreateProps linkCreateProps,
314 const LinkAccessProps& linkAccessProps,
315 const bool parents) {
316 static_assert(!std::is_same<T, Attribute>::value,
317 "hdf5 doesn't support hard links to Attributes");
318 if (parents) {
319 linkCreateProps.add(CreateIntermediateGroup{});
320 }
321 detail::h5l_create_hard(target_obj.getId(),
322 ".",
323 static_cast<const Derivate*>(this)->getId(),
324 link_name.c_str(),
325 linkCreateProps.getId(),
326 linkAccessProps.getId());
327}
328
329
330template <typename Derivate>
331inline Object NodeTraits<Derivate>::_open(const std::string& node_name) const {
332 const auto id = detail::h5o_open(static_cast<const Derivate*>(this)->getId(),
333 node_name.c_str(),
334 H5P_DEFAULT);
335 return detail::make_object(id);
336}
337
338
339} // namespace HighFive
Definition H5PropertyList.hpp:605
Class representing a dataset.
Definition H5DataSet.hpp:30
Class representing the space (dimensions) of a DataSet.
Definition H5DataSpace.hpp:31
static DataSpace From(const T &value)
Automatically deduce the DataSpace from a container/value.
Definition H5Dataspace_misc.hpp:122
HDF5 Data Type.
Definition H5DataType.hpp:61
Represents an hdf5 group.
Definition H5Group.hpp:46
NodeTraits: Base class for Group and File.
Definition H5Node_traits.hpp:28
Group getGroup(const std::string &group_name) const
open an existing group with the name group_name
Definition H5Node_traits_misc.hpp:129
std::vector< std::string > listObjectNames(IndexType idx_type=IndexType::NAME) const
list all leaf objects name of the node / group
Definition H5Node_traits_misc.hpp:181
void unlink(const std::string &node_name) const
unlink the given dataset or group
Definition H5Node_traits_misc.hpp:231
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:292
DataType getDataType(const std::string &type_name, const DataTypeAccessProps &accessProps=DataTypeAccessProps::Default()) const
open a commited datatype with the name type_name
Definition H5Node_traits_misc.hpp:136
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:97
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:181
void createHardLink(const std::string &link_name, const T &target_obj, LinkCreateProps linkCreateProps=LinkCreateProps(), const LinkAccessProps &linkAccessProps=LinkAccessProps(), const bool parents=true)
Creates hardlinks.
Definition H5Node_traits_misc.hpp:311
Group createGroup(const std::string &group_name, bool parents=true)
create a new group, and eventually intermediate groups
Definition H5Node_traits_misc.hpp:105
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:37
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:165
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
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:269
size_t getNumberObjects() const
return the number of leaf objects of the node / group
Definition H5Node_traits_misc.hpp:144
std::string getObjectName(size_t index) const
return the name of the object with the given index
Definition H5Node_traits_misc.hpp:151
LinkType getLinkType(const std::string &node_name) const
Returns the kind of link of the given name (soft, hard...)
Definition H5Node_traits_misc.hpp:254
Definition H5Object.hpp:54
hid_t getId() const noexcept
getId
Definition H5Object_misc.hpp:69
HDF5 property Lists.
Definition H5PropertyList.hpp:160
void add(const P &property)
Definition H5PropertyList_misc.hpp:72
Utility class to disable HDF5 stack printing inside a scope.
Definition H5Utility.hpp:24
void write(const T &buffer, const DataTransferProps &xfer_props=DataTransferProps())
Definition H5Slice_traits_misc.hpp:256
A structure representing a set of fixed-length strings.
Definition H5DataType.hpp:356
std::size_t size() const noexcept
Definition H5DataType.hpp:400
Definition H5_definitions.hpp:22
DataType create_and_check_datatype()
Create a DataType instance representing type T and perform a sanity check on its size.
Definition H5DataType_misc.hpp:486
LinkType
The possible types of group entries (link concept)
Definition H5Node_traits.hpp:237
ObjectType
Enum of the types of objects (H5O api)
Definition H5Object.hpp:24
IndexType
Definition H5Node_traits.hpp:19
static void ToException(const std::string &prefix_msg)
Definition H5Exception_misc.hpp:43