h5gt 0.2.0
C++ wrapper for HDF5 library (based on HighFive project)
Loading...
Searching...
No Matches
H5Object_misc.hpp
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 H5OBJECT_MISC_HPP
10#define H5OBJECT_MISC_HPP
11
12#include <iostream>
13#include <H5Ppublic.h>
14
15#include "H5Utils.hpp"
16
17namespace h5gt {
18
19static inline ObjectType _convert_object_type(const H5I_type_t& h5type) {
20 switch (h5type) {
21 case H5I_FILE:
22 return ObjectType::File;
23 case H5I_GROUP:
24 return ObjectType::Group;
25 case H5I_DATATYPE:
26 return ObjectType::UserDataType;
27 case H5I_DATASPACE:
28 return ObjectType::DataSpace;
29 case H5I_DATASET:
30 return ObjectType::Dataset;
31 case H5I_ATTR:
32 return ObjectType::Attribute;
33 default:
34 return ObjectType::Other;
35 }
36}
37
38// convert internal link types to enum class.
39// This function is internal, so H5L_TYPE_ERROR shall be handled in the calling context
40static inline LinkType _convert_link_type(const H5L_type_t& ltype) noexcept {
41 switch (ltype) {
42 case H5L_TYPE_HARD:
43 return LinkType::Hard;
44 case H5L_TYPE_SOFT:
45 return LinkType::Soft;
46 case H5L_TYPE_EXTERNAL:
47 return LinkType::External;
48 default:
49 // Other link types are possible but are considered strange to h5gt.
50 // see https://support.hdfgroup.org/HDF5/doc/RM/H5L/H5Lregister.htm
51 return LinkType::Other;
52 }
53}
54
55inline Object::Object() : _hid(H5I_INVALID_HID) {}
56
57inline Object::Object(const hid_t& hid) : _hid(hid) {}
58
59inline Object::Object(const Object& other) : _hid(other._hid) {
60 if (other.isValid() && H5Iinc_ref(_hid) < 0) {
61 throw ObjectException("Reference counter increase failure");
62 }
63}
64
65inline Object::Object(Object&& other) noexcept
66 : _hid(other._hid) {
67 other._hid = H5I_INVALID_HID;
68}
69
70inline Object::Object(const hid_t& hid,
71 const ObjectType& objType,
72 const bool& increaseRefCount) {
73 if (hid < 0) {
74 HDF5ErrMapper::ToException<ObjectException>(
75 std::string("Invalid id to initialize the object"));
76 return;
77 }
78
79 ObjectType objType_from_id = _convert_object_type(H5Iget_type(hid));
80 if (objType_from_id != objType){
81 HDF5ErrMapper::ToException<ObjectException>(
82 std::string("Given ID doesn't belong to the requested type (or it is invalid)"));
83 return;
84 }
85
86 if (increaseRefCount)
87 H5Iinc_ref(hid);
88
89 _hid = hid;
90}
91
92inline Object& Object::operator=(const Object& other) {
93 if (this != &other) {
94 if (_hid != H5I_INVALID_HID)
95 H5Idec_ref(_hid);
96
97 _hid = other._hid;
98 if (other.isValid() && H5Iinc_ref(_hid) < 0) {
99 throw ObjectException("Reference counter increase failure");
100 }
101 }
102 return *this;
103}
104
105inline bool Object::operator==(const Object& other) const {
106 ObjectInfo leftOInfo = getObjectInfo();
107 ObjectInfo rightOInfo = other.getObjectInfo();
108
109 if (leftOInfo.getFileNumber() != rightOInfo.getFileNumber() ||
110 leftOInfo.getFileNumber() == 0 ||
111 rightOInfo.getFileNumber() == 0)
112 return false;
114#if (H5Oget_info_vers < 3)
115 return getObjectInfo().getAddress() == other.getObjectInfo().getAddress();
116#else
117 int tokenCMP;
118 H5O_token_t leftToken = leftOInfo.getHardLinkToken();
119 H5O_token_t rightToken = rightOInfo.getHardLinkToken();
120
121 hid_t fileId = H5Iget_file_id(_hid);
122 bool closeFileId = true;
123 if (!H5Iis_valid(fileId)){
124 closeFileId = false;
125 HDF5ErrMapper::ToException<ObjectException>(
126 std::string("File ID is invalid. Probably the object doesn't belong to any file"));
127 }
128
129 if (H5Otoken_cmp(fileId, &leftToken, &rightToken, &tokenCMP) < 0){
130 HDF5ErrMapper::ToException<ObjectException>(
131 "Unable compare tokens");
132 }
133
134 // important: close opened File ID
135 if (closeFileId){
136 H5Idec_ref(fileId);
137 }
138
139 return !tokenCMP;
140#endif
141}
142
143inline Object::~Object() {
144 if (isValid() && H5Idec_ref(_hid) < 0) {
145 std::cerr << "h5gt::~Object: reference counter decrease failure"
146 << std::endl;
147 }
148}
149
150inline void Object::flush(bool globalScope) {
151 H5F_scope_t scope;
152 if (globalScope)
153 scope = H5F_scope_t::H5F_SCOPE_GLOBAL;
154 else
155 scope = H5F_scope_t::H5F_SCOPE_LOCAL;
156 if (H5Fflush(_hid, scope) < 0) {
157 HDF5ErrMapper::ToException<ObjectException>(
158 std::string("Unable to flush object " + getPath()));
159 }
160}
161
162inline bool Object::isValid() const noexcept {
163 return (_hid != H5I_INVALID_HID) && (H5Iis_valid(_hid) != false);
164}
165
166#if (H5_VERS_MAJOR >= 1 && H5_VERS_MINOR >= 10)
167inline bool Object::refresh() const noexcept {
168 return (H5Orefresh(_hid) < 0) ? false : true;
169}
170#endif
171
172inline hid_t Object::getId(const bool& increaseRefCount) const noexcept {
173 if (increaseRefCount)
174 H5Iinc_ref(_hid);
175
176 return _hid;
177}
178
179inline std::string Object::getFileName() const {
180 return details::get_name([&](char *buffer, hsize_t length) {
181 return H5Fget_name(_hid, buffer, length);
182 });
183}
184
185inline std::string Object::getPath() const {
186 return details::get_name([&](char *buffer, hsize_t length) {
187 return H5Iget_name(_hid, buffer, length);
188 });
189}
190
191inline int Object::getIdRefCount() const noexcept {
192 return H5Iget_ref(_hid);
193}
194
195inline ObjectType Object::getObjectType() const {
196 // H5Iget_type is a very lightweight func which extracts the type from the id
197 H5I_type_t h5type;
198 if ((h5type = H5Iget_type(_hid)) == H5I_BADID) {
199 HDF5ErrMapper::ToException<ObjectException>("Invalid hid or object type");
200 }
201 return _convert_object_type(h5type);
202}
203
204inline ObjectInfo Object::getObjectInfo() const {
205 ObjectInfo info;
206#if (H5Oget_info_vers < 3)
207 if (H5Oget_info(_hid, &info.raw_info) < 0) {
208#else
209 if (H5Oget_info3(_hid, &info.raw_info, H5O_INFO_ALL) < 0) {
210#endif
211 HDF5ErrMapper::ToException<ObjectException>("Unable to obtain info for object");
212 }
213 return info;
214}
215
216inline LinkInfo Object::_getLinkInfo(const std::string& objPath) const {
217 LinkInfo info;
218#if (H5Lget_info_vers < 2)
219 if (H5Lget_info(_hid, objPath.c_str(), &info.link_info, H5P_DEFAULT) < 0) {
220#else
221 if (H5Lget_info2(_hid, objPath.c_str(), &info.link_info, H5P_DEFAULT) < 0) {
222#endif
223 HDF5ErrMapper::ToException<ObjectException>("Unable to obtain info for link");
224 }
225 return info;
226}
227
228inline std::string Object::_unpackSoftLink(
229 const std::string& objName) const
230{
231 h5gt::LinkInfo linkInfo = _getLinkInfo(objName);
232 // to avoid segfault check the type of a link
233 if (linkInfo.getLinkType() != LinkType::Soft){
234 HDF5ErrMapper::ToException<ObjectException>(
235 std::string("The link is not Soft"));
236 return std::string();
237 }
238
239 size_t n = linkInfo.getSoftLinkSize();
240 if (n < 1){
241 HDF5ErrMapper::ToException<ObjectException>(
242 std::string("Link size is too small (n < 1)"));
243 return std::string();
244 }
245 std::vector<char> v(n);
246 if (H5Lget_val(getId(false), objName.c_str(),
247 v.data(), n, H5P_DEFAULT) < 0){
248 HDF5ErrMapper::ToException<ObjectException>(
249 std::string("Unable to get path to which the link points to"));
250 }
251 return std::string(v.data(), n-1);
252}
253
254inline std::string Object::_unpackExternalLink(
255 const std::string& objName,
256 std::string& fileName_out) const
257{
258 h5gt::LinkInfo linkInfo = _getLinkInfo(objName);
259 // to avoid segfault check the type of a link
260 if (linkInfo.getLinkType() != LinkType::External){
261 HDF5ErrMapper::ToException<ObjectException>(
262 std::string("The link is not External"));
263 return std::string();
264 }
265
266 size_t n = linkInfo.getSoftLinkSize();
267 if (n < 1){
268 HDF5ErrMapper::ToException<ObjectException>(
269 std::string("Link size is too small (n < 1)"));
270 return std::string();
271 }
272 std::vector<char> v(n);
273 if (H5Lget_val(getId(false), objName.c_str(),
274 v.data(), n, H5P_DEFAULT) < 0){
275 HDF5ErrMapper::ToException<ObjectException>(
276 std::string("Unable to get path to which the link points to"));
277 }
278
279 const char* f_out;
280 const char* o_out;
281 unsigned flags = 0;
282 if (H5Lunpack_elink_val(v.data(), n, &flags, &f_out, &o_out) < 0){
283 HDF5ErrMapper::ToException<ObjectException>(
284 std::string("Unable to get path to which the link points to"));
285 }
286
287 fileName_out = std::string(f_out);
288 return std::string(o_out);
289}
290
291inline void Object::_unlink(const std::string& objName) const
292{
293 const herr_t val = H5Ldelete(getId(false), objName.c_str(), H5P_DEFAULT);
294 if (val < 0) {
295 HDF5ErrMapper::ToException<ObjectException>(
296 std::string("Invalid name for unlink() "));
297 }
298}
299
300#if (H5Lget_info_vers < 2)
301inline haddr_t ObjectInfo::getAddress() const noexcept {
302 return raw_info.addr;
303}
304#else
305inline H5O_token_t ObjectInfo::getHardLinkToken() const noexcept{
306 return raw_info.token;
307}
308#endif
309
310inline unsigned long ObjectInfo::getFileNumber() const noexcept {
311 return raw_info.fileno;
312}
313
314inline size_t ObjectInfo::getHardLinkRefCount() const noexcept {
315 return raw_info.rc;
316}
317inline time_t ObjectInfo::getAccessTime() const noexcept {
318 return raw_info.atime;
319}
320inline time_t ObjectInfo::getModificationTime() const noexcept {
321 return raw_info.mtime;
322}
323inline time_t ObjectInfo::getChangeTime() const noexcept {
324 return raw_info.ctime;
325}
326inline time_t ObjectInfo::getCreationTime() const noexcept {
327 return raw_info.btime;
328}
329inline hsize_t ObjectInfo::getNumAttr() const noexcept {
330 return raw_info.num_attrs;
331}
332
333
334inline LinkType LinkInfo::getLinkType() const noexcept{
335 return _convert_link_type(link_info.type);
336}
337inline hbool_t LinkInfo::creationOrderValid() const noexcept{
338 return link_info.corder_valid;
339}
340inline int64_t LinkInfo::getCreationOrder() const noexcept{
341 return link_info.corder;
342}
343inline H5T_cset_t LinkInfo::getLinkNameCharacterSet() const noexcept{
344 return link_info.cset;
345}
346#if (H5Lget_info_vers < 2)
347inline haddr_t LinkInfo::getAddress() const noexcept{
348 return link_info.u.address;
349}
350#else
351inline H5O_token_t LinkInfo::getHardLinkToken() const noexcept{
352 return link_info.u.token;
353}
354#endif
355inline size_t LinkInfo::getSoftLinkSize() const noexcept{
356 return link_info.u.val_size;
357}
358
359} // namespace
360
361#endif // H5OBJECT_MISC_HPP
Definition H5Object.hpp:55
ObjectInfo getObjectInfo() const
Retrieve several infos about the current object (address, dates, etc)
Definition H5Object_misc.hpp:204
A class for accessing hdf5 objects info.
Definition H5Object.hpp:168
haddr_t getAddress() const noexcept
Retrieve the address of the object (within its file)
Definition H5Object_misc.hpp:301