h5cpp  0.6
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 #include <h5cpp/core/utilities.hpp>
44 
45 namespace hdf5 {
46 namespace attribute {
47 
49 {
50  public:
57  Attribute(ObjectHandle &&handle,const node::Link &parent_link);
58 
64  Attribute() = default;
65 
72 
79 
83  std::string name() const;
84 
88  bool is_valid() const;
89 
97  void close();
98 
99 
103  operator hid_t() const
104  {
105  return static_cast<hid_t>(handle_);
106  }
107 
113  const node::Link &parent_link() const noexcept;
114 
127  template<typename T>
128  void write(const T& data) const;
129 
146  void write(const char *data) const;
147 
165  template<typename T>
166  void write(const std::initializer_list<T> &list) const
167  {
168  write(std::vector<T>{list});
169  }
170 
195  template<typename T>
196  void write(const T& data,const datatype::Datatype &mem_type) const;
197  void write(const char *data,const datatype::Datatype &mem_type) const;
198 
199  template<typename T>
200  void read(T &data) const;
201 
202  template<typename T>
203  void read(T &data,const datatype::Datatype &mem_type) const;
204 
205  private:
206  ObjectHandle handle_;
207  node::Link parent_link_;
208 
209  template<typename T>
210  void read(T &data,const datatype::Datatype &mem_type, const datatype::Datatype &file_type) const;
211 
212  template<typename T>
213  void write_fixed_length_string(const T &data,
214  const datatype::Datatype &mem_type) const
215  {
216  using Trait = FixedLengthStringTrait<T>;
217  using SpaceTrait = hdf5::dataspace::TypeTrait<T>;
218  auto buffer = Trait::to_buffer(data,mem_type,SpaceTrait::create(data));
219 
220  if(H5Awrite(static_cast<hid_t>(handle_),
221  static_cast<hid_t>(mem_type),
222  buffer.data())<0)
223  {
224  error::Singleton::instance().throw_with_stack("Failure to write data to attribute!");
225  }
226 
227  }
228 
229  template<typename T>
230  void write_variable_length_string(const T &data,
231  const datatype::Datatype &mem_type) const
232  {
233  using Trait = VarLengthStringTrait<T>;
234  auto buffer = Trait::to_buffer(data);
235 
236  if(H5Awrite(static_cast<hid_t>(handle_),
237  static_cast<hid_t>(mem_type),
238  buffer.data())<0)
239  {
240  error::Singleton::instance().throw_with_stack("Failure to write data to attribute!");
241  }
242 
243  }
244 
245  template<typename T>
246  void write_contiguous_data(const T &data,
247  const datatype::Datatype &mem_type) const
248  {
249  const void *ptr = dataspace::cptr(data);
250  if(H5Awrite(static_cast<hid_t>(handle_),static_cast<hid_t>(mem_type),ptr)<0)
251  {
252  error::Singleton::instance().throw_with_stack("Failure to write data to attribute!");
253  }
254  }
255 
256  template<typename T>
257  void read_fixed_length_string(T &data,
258  const datatype::Datatype &mem_type) const
259  {
260  using Trait = FixedLengthStringTrait<T>;
261  using SpaceTrait = hdf5::dataspace::TypeTrait<T>;
262 
263  auto buffer = Trait::BufferType::create(mem_type,SpaceTrait::create(data));
264 
265  if(H5Aread(static_cast<hid_t>(handle_),
266  static_cast<hid_t>(mem_type),
267  buffer.data())<0)
268  {
269  error::Singleton::instance().throw_with_stack("Failure to read data from attribute!");
270  }
271 
272  data = Trait::from_buffer(buffer,mem_type,SpaceTrait::create(data));
273 
274  }
275 
276  template<typename T>
277  void read_variable_length_string(T &data,
278  const datatype::Datatype &mem_type) const
279  {
280  using Trait = VarLengthStringTrait<T>;
281 
282  typename Trait::BufferType buffer(signed2unsigned<typename std::vector<T>::size_type>(dataspace().size()));
283 
284  if(H5Aread(static_cast<hid_t>(handle_),
285  static_cast<hid_t>(mem_type),
286  buffer.data())<0)
287  {
288  error::Singleton::instance().throw_with_stack("Failure to read data from attribute!");
289  }
290 
291  Trait::from_buffer(buffer,data);
292 
293  if(H5Dvlen_reclaim(static_cast<hid_t>(mem_type),
294  static_cast<hid_t>(dataspace()),
295  static_cast<hid_t>(property::DatasetTransferList()),
296  buffer.data())<0)
297  {
298  std::stringstream ss;
299  ss<<"Failure to reclaim buffer for variable length string"
300  <<" string read on attribute!";
302  }
303 
304  }
305 
306  template<typename T>
307  void read_contiguous_data(T &data,
308  const datatype::Datatype &mem_type) const
309  {
310  void *ptr = dataspace::ptr(data);
311 
312  if(H5Aread(static_cast<hid_t>(handle_),static_cast<hid_t>(mem_type),ptr)<0)
313  {
314  error::Singleton::instance().throw_with_stack("Failure to read data from attribute!");
315  }
316  }
317 
318  void check_size(const dataspace::Dataspace &mem_space,
319  const dataspace::Dataspace &file_space,
320  const std::string &operation) const;
321 
322 };
323 
324 template<typename T>
325 void Attribute::write(const T &data,const datatype::Datatype &mem_type) const
326 {
327  datatype::Datatype file_type = datatype();
328 
329  check_size(dataspace::create(data),dataspace(),"write");
330 
331  if(file_type.get_class()==datatype::Class::String)
332  {
333  datatype::String string_type(file_type);
334 
335  if(string_type.is_variable_length())
336  {
337  write_variable_length_string(data,mem_type);
338  }
339  else
340  {
341  write_fixed_length_string(data,mem_type);
342  }
343  }
344  else
345  {
346  write_contiguous_data(data,mem_type);
347  }
348 }
349 
350 template<typename T>
351 void Attribute::write(const T &data) const
352 {
353  hdf5::datatype::DatatypeHolder mem_type_holder;
354 
355  write(data,mem_type_holder.get<T>());
356 }
357 
358 template<typename T>
359 void Attribute::read(T &data) const
360 {
361  auto file_type = datatype();
362  if(file_type.get_class() == datatype::Class::String)
363  {
364  read(data, file_type);
365  }
366  else
367  {
368  hdf5::datatype::DatatypeHolder mem_type_holder;
369  read(data, mem_type_holder.get<T>(), file_type);
370  }
371 }
372 
373 template<typename T>
374 void Attribute::read(T &data,const datatype::Datatype &mem_type) const
375 {
376  datatype::Datatype file_type = datatype();
377  read(data, mem_type, file_type);
378 }
379 
380 template<typename T>
381 void Attribute::read(T &data, const datatype::Datatype &mem_type, const datatype::Datatype &file_type) const
382 {
383  check_size(dataspace::create(data),dataspace(),"read");
384 
385  if(file_type.get_class()==datatype::Class::String)
386  {
387  datatype::String string_type(file_type);
388 
389  if(string_type.is_variable_length())
390  {
391  read_variable_length_string(data,mem_type);
392  }
393  else
394  {
395  read_fixed_length_string(data,mem_type);
396  }
397  }
398  else
399  {
400  read_contiguous_data(data,mem_type);
401  }
402 }
403 
404 
405 
406 } // namespace attribute
407 } // namespace hdf5
Wrapper for hid_t object identifiers.
Definition: object_handle.hpp:67
Definition: attribute.hpp:49
datatype::Datatype datatype() const
return the data type of the attribute
void write(const char *data, const datatype::Datatype &mem_type) const
Attribute(ObjectHandle &&handle, const node::Link &parent_link)
constructor
void close()
close the attribute
Attribute()=default
default constructor
bool is_valid() const
check if object is valid
void write(const T &data) const
write data to attribute
Definition: attribute.hpp:351
const node::Link & parent_link() const noexcept
get the parent ndoe
void read(T &data) const
Definition: attribute.hpp:359
dataspace::Dataspace dataspace() const
return the dataspace of the attribute
std::string name() const
return the name of the attribute
dataspace base class
Definition: dataspace.hpp:41
type trait for dataspace construction
Definition: type_trait.hpp:54
data type object holder
Definition: factory.hpp:54
const Datatype & get(const T &v=T{})
factory holder method for getting reference of data types
Definition: factory.hpp:74
base class for all data types
Definition: datatype.hpp:42
Class get_class() const
returns the datatypes class
string datatype
Definition: string.hpp:40
bool is_variable_length() const
return true if type is a variable length string
static Singleton & instance()
reference to singleton
Definition: error.hpp:59
void throw_with_stack(const std::string &message)
throws an exception, potentially nested with error stack
const void * cptr(const T &value)
Definition: type_trait.hpp:116
void * ptr(T &value)
Definition: type_trait.hpp:111
TypeTrait< T >::DataspaceType create(const T &value)
factory function for dataspaces
Definition: type_trait.hpp:89
@ String
indicates a string type
File from_buffer(T &data, ImageFlags flags=ImageFlags::ReadOnly)
load an image file from a buffer
Definition: functions.hpp:126
top-level namespace of the entire library
Definition: attribute.hpp:45
Definition: fixed_length_string.hpp:58
variable length string buffer trait
Definition: variable_length_string.hpp:54
TType signed2unsigned(SType &&source_value)
Definition: utilities.hpp:79
#define DLL_EXPORT
Definition: windows.hpp:29