h5cpp  0.4.1
A modern C++ wrapper for the HDF5 C library
attribute.hpp
Go to the documentation of this file.
1 //
2 // (c) Copyright 2017 DESY,ESS
3 //
4 // This file is part of h5cpp.
5 //
6 // This library is free software; you can redistribute it and/or modify it
7 // under the terms of the GNU Lesser General Public License as published
8 // by the Free Software Foundation; either version 2.1 of the License, or
9 // (at your option) any later version.
10 //
11 // This library is distributed in the hope that it will be useful, but
12 // WITHOUT ANY WARRANTY; without even the implied warranty ofMERCHANTABILITY
13 // or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
14 // License for more details.
15 //
16 // You should have received a copy of the GNU Lesser General Public License
17 // along with this library; if not, write to the
18 // Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor
19 // Boston, MA 02110-1301 USA
20 // ===========================================================================
21 //
22 // Authors:
23 // Eugen Wintersberger <eugen.wintersberger@desy.de>
24 // Jan Kotanski <jan.kotanski@desy.de>
25 // Created on: Sep 14, 2017
26 //
27 #pragma once
28 
35 #include <h5cpp/core/windows.hpp>
38 #include <h5cpp/core/types.hpp>
39 #include <h5cpp/node/link.hpp>
40 #include <h5cpp/error/error.hpp>
41 #include <initializer_list>
42 
43 namespace hdf5 {
44 namespace attribute {
45 
47 {
48  public:
55  Attribute(ObjectHandle &&handle,const node::Link &parent_link);
56 
62  Attribute() = default;
63 
69  Attribute(const Attribute &) = default;
70 
76  datatype::Datatype datatype() const;
77 
83  dataspace::Dataspace dataspace() const;
84 
88  std::string name() const;
89 
93  bool is_valid() const;
94 
102  void close();
103 
104 
108  operator hid_t() const
109  {
110  return static_cast<hid_t>(handle_);
111  }
112 
118  const node::Link &parent_link() const noexcept;
119 
132  template<typename T>
133  void write(const T& data) const;
134 
151  void write(const char *data) const;
152 
170  template<typename T>
171  void write(const std::initializer_list<T> &list) const
172  {
173  write(std::vector<T>{list});
174  }
175 
200  template<typename T>
201  void write(const T& data,const datatype::Datatype &mem_type) const;
202  void write(const char *data,const datatype::Datatype &mem_type) const;
203 
204  template<typename T>
205  void read(T &data) const;
206 
207  template<typename T>
208  void read(T &data,const datatype::Datatype &mem_type) const;
209 
210  private:
211  ObjectHandle handle_;
212  node::Link parent_link_;
213 
214  template<typename T>
215  void read(T &data,const datatype::Datatype &mem_type, const datatype::Datatype &file_type) const;
216 
217  template<typename T>
218  void write_fixed_length_string(const T &data,
219  const datatype::Datatype &mem_type) const
220  {
221  using Trait = FixedLengthStringTrait<T>;
222  using SpaceTrait = hdf5::dataspace::TypeTrait<T>;
223  auto buffer = Trait::to_buffer(data,mem_type,SpaceTrait::create(data));
224 
225  if(H5Awrite(static_cast<hid_t>(handle_),
226  static_cast<hid_t>(mem_type),
227  buffer.data())<0)
228  {
229  error::Singleton::instance().throw_with_stack("Failure to write data to attribute!");
230  }
231 
232  }
233 
234  template<typename T>
235  void write_variable_length_string(const T &data,
236  const datatype::Datatype &mem_type) const
237  {
238  using Trait = VarLengthStringTrait<T>;
239  auto buffer = Trait::to_buffer(data);
240 
241  if(H5Awrite(static_cast<hid_t>(handle_),
242  static_cast<hid_t>(mem_type),
243  buffer.data())<0)
244  {
245  error::Singleton::instance().throw_with_stack("Failure to write data to attribute!");
246  }
247 
248  }
249 
250  template<typename T>
251  void write_contiguous_data(const T &data,
252  const datatype::Datatype &mem_type) const
253  {
254  const void *ptr = dataspace::cptr(data);
255  if(H5Awrite(static_cast<hid_t>(handle_),static_cast<hid_t>(mem_type),ptr)<0)
256  {
257  error::Singleton::instance().throw_with_stack("Failure to write data to attribute!");
258  }
259  }
260 
261  template<typename T>
262  void read_fixed_length_string(T &data,
263  const datatype::Datatype &mem_type) const
264  {
265  using Trait = FixedLengthStringTrait<T>;
266  using SpaceTrait = hdf5::dataspace::TypeTrait<T>;
267 
268  auto buffer = Trait::BufferType::create(mem_type,SpaceTrait::create(data));
269 
270  if(H5Aread(static_cast<hid_t>(handle_),
271  static_cast<hid_t>(mem_type),
272  buffer.data())<0)
273  {
274  error::Singleton::instance().throw_with_stack("Failure to read data from attribute!");
275  }
276 
277  data = Trait::from_buffer(buffer,mem_type,SpaceTrait::create(data));
278 
279  }
280 
281  template<typename T>
282  void read_variable_length_string(T &data,
283  const datatype::Datatype &mem_type) const
284  {
285  using Trait = VarLengthStringTrait<T>;
286 
287  typename Trait::BufferType buffer(dataspace().size());
288 
289  if(H5Aread(static_cast<hid_t>(handle_),
290  static_cast<hid_t>(mem_type),
291  buffer.data())<0)
292  {
293  error::Singleton::instance().throw_with_stack("Failure to read data from attribute!");
294  }
295 
296  Trait::from_buffer(buffer,data);
297 
298  if(H5Dvlen_reclaim(static_cast<hid_t>(mem_type),
299  static_cast<hid_t>(dataspace()),
300  static_cast<hid_t>(property::DatasetTransferList()),
301  buffer.data())<0)
302  {
303  std::stringstream ss;
304  ss<<"Failure to reclaim buffer for variable length string"
305  <<" string read on attribute!";
307  }
308 
309  }
310 
311  template<typename T>
312  void read_contiguous_data(T &data,
313  const datatype::Datatype &mem_type) const
314  {
315  void *ptr = dataspace::ptr(data);
316 
317  if(H5Aread(static_cast<hid_t>(handle_),static_cast<hid_t>(mem_type),ptr)<0)
318  {
319  error::Singleton::instance().throw_with_stack("Failure to read data from attribute!");
320  }
321  }
322 
323  void check_size(const dataspace::Dataspace &mem_space,
324  const dataspace::Dataspace &file_space,
325  const std::string &operation) const;
326 
327 };
328 
329 template<typename T>
330 void Attribute::write(const T &data,const datatype::Datatype &mem_type) const
331 {
332  datatype::Datatype file_type = datatype();
333 
334  check_size(dataspace::create(data),dataspace(),"write");
335 
336  if(file_type.get_class()==datatype::Class::STRING)
337  {
338  datatype::String string_type(file_type);
339 
340  if(string_type.is_variable_length())
341  {
342  write_variable_length_string(data,mem_type);
343  }
344  else
345  {
346  write_fixed_length_string(data,mem_type);
347  }
348  }
349  else
350  {
351  write_contiguous_data(data,mem_type);
352  }
353 }
354 
355 template<typename T>
356 void Attribute::write(const T &data) const
357 {
358  auto mem_type = datatype::create<T>(data);
359 
360  write(data,mem_type);
361 }
362 
363 template<typename T>
364 void Attribute::read(T &data) const
365 {
366  auto file_type = datatype();
367  if(file_type.get_class() == datatype::Class::STRING)
368  {
369  read(data, file_type);
370  }
371  else
372  {
373  auto mem_type = datatype::create<T>(data);
374  read(data, mem_type, file_type);
375  }
376 }
377 
378 template<typename T>
379 void Attribute::read(T &data,const datatype::Datatype &mem_type) const
380 {
381  datatype::Datatype file_type = datatype();
382  read(data, mem_type, file_type);
383 }
384 
385 template<typename T>
386 void Attribute::read(T &data, const datatype::Datatype &mem_type, const datatype::Datatype &file_type) const
387 {
388  check_size(dataspace::create(data),dataspace(),"read");
389 
390  if(file_type.get_class()==datatype::Class::STRING)
391  {
392  datatype::String string_type(file_type);
393 
394  if(string_type.is_variable_length())
395  {
396  read_variable_length_string(data,mem_type);
397  }
398  else
399  {
400  read_fixed_length_string(data,mem_type);
401  }
402  }
403  else
404  {
405  read_contiguous_data(data,mem_type);
406  }
407 }
408 
409 
410 
411 } // namespace attribute
412 } // namespace hdf5
void read(T &data) const
Definition: attribute.hpp:364
TypeTrait< T >::DataspaceType create(const T &value)
factory function for dataspaces
Definition: type_trait.hpp:115
dataspace base class
Definition: dataspace.hpp:41
static Singleton & instance()
reference to singleton
Definition: error.hpp:50
void throw_with_stack(const std::string &message)
throws an exception, potentially nested with error stack
string datatype
Definition: string.hpp:39
Wrapper for hid_t object identifiers.
Definition: object_handle.hpp:66
File from_buffer(T &data, ImageFlags flags=ImageFlags::READONLY)
load an image file from a buffer
Definition: functions.hpp:120
const void * cptr(const T &value)
Definition: type_trait.hpp:125
bool is_variable_length() const
return true if type is a variable length string
Definition: attribute.hpp:43
type trait for dataspace construction
Definition: type_trait.hpp:51
void write(const T &data) const
write data to attribute
Definition: attribute.hpp:356
Definition: dataset_transfer.hpp:53
void * ptr(T &value)
Definition: type_trait.hpp:120
#define DLL_EXPORT
Definition: windows.hpp:35
Class get_class() const
returns the datatypes class
indicates a string type
Definition: fixed_length_string.hpp:56
Definition: attribute.hpp:46
variable length string buffer trait
Definition: variable_length_string.hpp:53
base class for all data types
Definition: datatype.hpp:41
void write(const std::initializer_list< T > &list) const
write from initializer list
Definition: attribute.hpp:171