h5cpp  0.3.3
A modern C++ wrapper for the HDF5 C library
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
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:
54  Attribute(ObjectHandle &&handle,const node::Link &parent_link);
55 
61  Attribute() = default;
62 
68  Attribute(const Attribute &) = default;
69 
75  datatype::Datatype datatype() const;
76 
82  dataspace::Dataspace dataspace() const;
83 
87  std::string name() const;
88 
92  bool is_valid() const;
93 
101  void close();
102 
103 
107  operator hid_t() const
108  {
109  return static_cast<hid_t>(handle_);
110  }
111 
117  const node::Link &parent_link() const noexcept;
118 
131  template<typename T>
132  void write(const T& data) const;
133 
150  void write(const char *data) const;
151 
169  template<typename T>
170  void write(const std::initializer_list<T> &list) const
171  {
172  write(std::vector<T>{list});
173  }
174 
199  template<typename T>
200  void write(const T& data,const datatype::Datatype &mem_type) const;
201  void write(const char *data,const datatype::Datatype &mem_type) const;
202 
203  template<typename T>
204  void read(T &data) const;
205 
206  template<typename T>
207  void read(T &data,const datatype::Datatype &mem_type) const;
208 
209  private:
210  ObjectHandle handle_;
211  node::Link parent_link_;
212 
213  template<typename T>
214  void read(T &data,const datatype::Datatype &mem_type, const datatype::Datatype &file_type) const;
215 
216  template<typename T>
217  void write_fixed_length_string(const T &data,
218  const datatype::Datatype &mem_type) const
219  {
220  using Trait = FixedLengthStringTrait<T>;
221  using SpaceTrait = hdf5::dataspace::TypeTrait<T>;
222  auto buffer = Trait::to_buffer(data,mem_type,SpaceTrait::create(data));
223 
224  if(H5Awrite(static_cast<hid_t>(handle_),
225  static_cast<hid_t>(mem_type),
226  buffer.data())<0)
227  {
228  error::Singleton::instance().throw_with_stack("Failure to write data to attribute!");
229  }
230 
231  }
232 
233  template<typename T>
234  void write_variable_length_string(const T &data,
235  const datatype::Datatype &mem_type) const
236  {
237  using Trait = VarLengthStringTrait<T>;
238  auto buffer = Trait::to_buffer(data);
239 
240  if(H5Awrite(static_cast<hid_t>(handle_),
241  static_cast<hid_t>(mem_type),
242  buffer.data())<0)
243  {
244  error::Singleton::instance().throw_with_stack("Failure to write data to attribute!");
245  }
246 
247  }
248 
249  template<typename T>
250  void write_contiguous_data(const T &data,
251  const datatype::Datatype &mem_type) const
252  {
253  const void *ptr = dataspace::cptr(data);
254  if(H5Awrite(static_cast<hid_t>(handle_),static_cast<hid_t>(mem_type),ptr)<0)
255  {
256  error::Singleton::instance().throw_with_stack("Failure to write data to attribute!");
257  }
258  }
259 
260  template<typename T>
261  void read_fixed_length_string(T &data,
262  const datatype::Datatype &mem_type) const
263  {
264  using Trait = FixedLengthStringTrait<T>;
265  using SpaceTrait = hdf5::dataspace::TypeTrait<T>;
266 
267  auto buffer = Trait::BufferType::create(mem_type,SpaceTrait::create(data));
268 
269  if(H5Aread(static_cast<hid_t>(handle_),
270  static_cast<hid_t>(mem_type),
271  buffer.data())<0)
272  {
273  error::Singleton::instance().throw_with_stack("Failure to read data from attribute!");
274  }
275 
276  data = Trait::from_buffer(buffer,mem_type,SpaceTrait::create(data));
277 
278  }
279 
280  template<typename T>
281  void read_variable_length_string(T &data,
282  const datatype::Datatype &mem_type) const
283  {
284  using Trait = VarLengthStringTrait<T>;
285 
286  typename Trait::BufferType buffer(dataspace().size());
287 
288  if(H5Aread(static_cast<hid_t>(handle_),
289  static_cast<hid_t>(mem_type),
290  buffer.data())<0)
291  {
292  error::Singleton::instance().throw_with_stack("Failure to read data from attribute!");
293  }
294 
295  Trait::from_buffer(buffer,data);
296 
297  if(H5Dvlen_reclaim(static_cast<hid_t>(mem_type),
298  static_cast<hid_t>(dataspace()),
299  static_cast<hid_t>(property::DatasetTransferList()),
300  buffer.data())<0)
301  {
302  std::stringstream ss;
303  ss<<"Failure to reclaim buffer for variable length string"
304  <<" string read on attribute!";
306  }
307 
308  }
309 
310  template<typename T>
311  void read_contiguous_data(T &data,
312  const datatype::Datatype &mem_type) const
313  {
314  void *ptr = dataspace::ptr(data);
315 
316  if(H5Aread(static_cast<hid_t>(handle_),static_cast<hid_t>(mem_type),ptr)<0)
317  {
318  error::Singleton::instance().throw_with_stack("Failure to read data from attribute!");
319  }
320  }
321 
322  void check_size(const dataspace::Dataspace &mem_space,
323  const dataspace::Dataspace &file_space,
324  const std::string &operation) const;
325 
326 };
327 
328 template<typename T>
329 void Attribute::write(const T &data,const datatype::Datatype &mem_type) const
330 {
331  datatype::Datatype file_type = datatype();
332 
333  check_size(dataspace::create(data),dataspace(),"write");
334 
335  if(file_type.get_class()==datatype::Class::STRING)
336  {
337  datatype::String string_type(file_type);
338 
339  if(string_type.is_variable_length())
340  {
341  write_variable_length_string(data,mem_type);
342  }
343  else
344  {
345  write_fixed_length_string(data,mem_type);
346  }
347  }
348  else
349  {
350  write_contiguous_data(data,mem_type);
351  }
352 }
353 
354 template<typename T>
355 void Attribute::write(const T &data) const
356 {
357  auto mem_type = datatype::create<T>(data);
358 
359  write(data,mem_type);
360 }
361 
362 template<typename T>
363 void Attribute::read(T &data) const
364 {
365  auto file_type = datatype();
366  if(file_type.get_class() == datatype::Class::STRING)
367  {
368  read(data, file_type);
369  }
370  else
371  {
372  auto mem_type = datatype::create<T>(data);
373  read(data, mem_type, file_type);
374  }
375 }
376 
377 template<typename T>
378 void Attribute::read(T &data,const datatype::Datatype &mem_type) const
379 {
380  datatype::Datatype file_type = datatype();
381  read(data, mem_type, file_type);
382 }
383 
384 template<typename T>
385 void Attribute::read(T &data, const datatype::Datatype &mem_type, const datatype::Datatype &file_type) const
386 {
387  check_size(dataspace::create(data),dataspace(),"read");
388 
389  if(file_type.get_class()==datatype::Class::STRING)
390  {
391  datatype::String string_type(file_type);
392 
393  if(string_type.is_variable_length())
394  {
395  read_variable_length_string(data,mem_type);
396  }
397  else
398  {
399  read_fixed_length_string(data,mem_type);
400  }
401  }
402  else
403  {
404  read_contiguous_data(data,mem_type);
405  }
406 }
407 
408 
409 
410 } // namespace attribute
411 } // namespace hdf5
void read(T &data) const
Definition: attribute.hpp:363
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
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:355
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:170