Utopia  2
Framework for studying models of complex & adaptive systems.
hdfobject.hh
Go to the documentation of this file.
1 #ifndef UTOPIA_DATAIO_HDFOBJECT_HH
2 #define UTOPIA_DATAIO_HDFOBJECT_HH
3 
4 #include <hdf5.h>
5 #include <memory>
6 
7 #include "hdfidentifier.hh"
8 #include "hdfutilities.hh"
9 
10 #include <utopia/core/logging.hh>
11 
12 namespace Utopia
13 {
14 namespace DataIO
15 {
16 
35 template < HDFCategory objectcategory >
36 class HDFObject
37 {
38  protected:
45 
50  std::string _path;
51 
56  std::shared_ptr< spdlog::logger > _log;
57 
58  public:
63  static constexpr HDFCategory category = objectcategory;
64 
70  void
71  swap(HDFObject& other)
72  {
73  using std::swap;
74  swap(_id, other._id);
75  swap(_path, other._path);
76  swap(_log, other._log);
77  }
78 
79  // implement open and close in a sensible way here, preferably without crtp,
80  // and by employing the identifier's management abilities
81 
87  std::string
88  get_path() const
89  {
90  return _path;
91  }
92 
98  auto
99  get_id_object() const
100  {
101  return _id;
102  }
103 
109  auto
110  get_logger() const
111  {
112  return _log;
113  }
119  hid_t
120  get_C_id() const
121  {
122  return _id.get_id();
123  }
124 
130  auto
132  {
133  return _id.get_refcount();
134  }
135 
142  virtual bool
143  is_valid() const
144  {
145  if (get_C_id() == -1)
146  {
147  return false;
148  }
149  else
150  {
151  // use check_validity to provide correct name
152  return check_validity(H5Iis_valid(get_C_id()), _path);
153  }
154  }
155 
160  void
162  {
163 
164  if (is_valid())
165  {
166  _id.close();
167 
168  _path = "";
169  }
170  }
171 
172  // README: the 'bind_to' function is not named 'open' to avoid confusion wrt
173  // to 'open' functions in derived classes. The latter have vastly differing
174  // arguments and hence cannot be prototyped here. Furthermore their
175  // functionality is more high level than this function.
176 
185  void
186  bind_to(hid_t id,
187  std::function< herr_t(hid_t) > closing_func,
188  std::string path = {})
189  {
190  if (is_valid())
191  {
192  throw std::runtime_error("Error: Cannot bind object to new "
193  "identifier while the old is still valid");
194  }
195 
196  if (not check_validity(H5Iis_valid(id), path))
197  {
198  throw std::invalid_argument(
199  "Error: invalid argument! The id given "
200  "for an object of " +
201  generate_object_name(*this) +
202  " cannot be managed by an HDFObject instance!");
203  }
204 
205  _log->debug("Opening object of ", generate_object_name(*this));
206 
207  _id.open(id, closing_func);
208 
209  if (path.size() == 0)
210  {
211  // putting some stupid special treatments here because HDF5
212  // cannot handle things generically
213 
214  // attribute has to be treated separately
215  if constexpr (category == HDFCategory::attribute)
216  {
217  _path.resize(H5Aget_name(id, 0, NULL) + 1);
218 
219  H5Aget_name(id, _path.size(), _path.data());
220  }
221  else
222  {
223 
224  // a preliminary call to H5Iget_name will give the needed size.
225  // cumbersome, but works. The +1 is for the null terminator
226  _path.resize(H5Iget_name(id, NULL, 0)+1);
227 
228  // then, a second call will give the full name
229  H5Iget_name(id, _path.data(), _path.size());
230 
231  }
232 
233  // remove the final 0 character, as std::string does not require it
234  _path.pop_back();
235  }
236  else
237  {
238  _path = path;
239  }
240  }
241 
246  HDFObject() : _id(), _path(""), _log(spdlog::get("data_io"))
247  {
248  }
249 
254  HDFObject(HDFObject&& other) :
255  _id(std::move(other._id)), _path(std::move(other._path)),
256  _log(std::move(other._log))
257  {
258  other._id.set_id(-1);
259  }
260 
265  HDFObject(const HDFObject& other) = default;
266 
275  HDFObject(hid_t id,
276  std::function< herr_t(hid_t) > closing_func,
277  std::string path = {}) :
278  _log(spdlog::get("data_io"))
279  {
280  bind_to(id, closing_func, path);
281  }
282 
289  HDFObject&
290  operator=(const HDFObject& other)
291  {
292  _id = other._id;
293  _path = other._path;
294  _log = other._log;
295 
296  return *this;
297  }
298 
305  HDFObject&
307  {
308  _id = std::move(other._id);
309  _path = std::move(other._path);
310  _log = std::move(other._log);
311 
312  other._id.set_id(-1);
313 
314  return *this;
315  }
316 
321  virtual ~HDFObject()
322  {
323  close();
324  }
325 };
326 
334 template < HDFCategory cat >
335 void
337 {
338  lhs.swap(rhs);
339 }
340  // end of group HDF5 // end of group DataIO
343 }
344 }
345 #endif
Wrapper class around an hdf5 identifier, used to manage reference counts of the object this identifie...
Definition: hdfidentifier.hh:29
auto get_refcount() const
Get the number of references currently referring to the object identified by this ID.
Definition: hdfidentifier.hh:89
void close()
Close the identifier and render the C-Level id held invalid.
Definition: hdfidentifier.hh:134
hid_t get_id() const
Get the HDF5 id held by this object.
Definition: hdfidentifier.hh:53
void open(hid_t id, std::function< herr_t(hid_t) > closing_func)
Open the object and bind it to another C-Level id.
Definition: hdfidentifier.hh:156
Common base class for all HDF5 classes in the DATAIO Module i.e., for all classes that wrap HDF5-C-Li...
Definition: hdfobject.hh:37
static constexpr HDFCategory category
Named variable for template arg.
Definition: hdfobject.hh:63
HDFObject()
Construct HDFObject from the given arguments.
Definition: hdfobject.hh:246
auto get_logger() const
Get the logger object.
Definition: hdfobject.hh:110
auto get_id_object() const
Get the id object.
Definition: hdfobject.hh:99
HDFObject(hid_t id, std::function< herr_t(hid_t) > closing_func, std::string path={})
Construct HDFObject from the given argument.
Definition: hdfobject.hh:275
std::string _path
Name of the object.
Definition: hdfobject.hh:50
auto get_refcount()
Get the reference count of object.
Definition: hdfobject.hh:131
HDFObject & operator=(HDFObject &&other)
move assignment operator
Definition: hdfobject.hh:306
virtual ~HDFObject()
Destroy the HDFObject object. Has to be implemented in subclass!
Definition: hdfobject.hh:321
std::string get_path() const
Get the name or path object.
Definition: hdfobject.hh:88
HDFObject & operator=(const HDFObject &other)
Copy assignment operator.
Definition: hdfobject.hh:290
void close()
Close function which takes care of correctly closing the object and managing the reference counter.
Definition: hdfobject.hh:161
virtual bool is_valid() const
Check if the object is still valid.
Definition: hdfobject.hh:143
void swap(HDFObject &other)
swap the state of the caller with the state of the argument
Definition: hdfobject.hh:71
std::shared_ptr< spdlog::logger > _log
pointer to the logger for dataio
Definition: hdfobject.hh:56
HDFIdentifier _id
Identifier object that binds an instance of this class to an HDF5 object.
Definition: hdfobject.hh:44
HDFObject(HDFObject &&other)
Construct HDFObject by moving.
Definition: hdfobject.hh:254
hid_t get_C_id() const
Get the C id object.
Definition: hdfobject.hh:120
void bind_to(hid_t id, std::function< herr_t(hid_t) > closing_func, std::string path={})
Open the object and bind it to a HDF5 object identified by 'id' with name 'path'. Object should be cr...
Definition: hdfobject.hh:186
HDFObject(const HDFObject &other)=default
Construct HDFObject by copying another object.
void swap(WriteTask< BGB, DW, DB, AWG, AWD > &lhs, WriteTask< BGB, DW, DB, AWG, AWD > &rhs)
Swaps the state of lhs and rhs.
Definition: write_task.hh:240
void swap(HDFObject< cat > &lhs, HDFObject< cat > &rhs)
Exchange state of lhs and rhs.
Definition: hdfobject.hh:336
bool check_validity(htri_t valid, const std::string_view object_name)
Check for validity of a hdf5 htri_t type or similar.
Definition: hdfutilities.hh:73
std::string generate_object_name(const Object &object)
Use category and path variable of object to make a string that identifies the object it is applied to...
Definition: hdfutilities.hh:220
HDFCategory
Enumerate the different HDF5 object types for use in HDFObject class.
Definition: hdfutilities.hh:173
This file provides metafunctions for automatically determining the nature of a C/C++ types at compile...
Definition: agent.hh:11
Definition: parallel.hh:235