h5cpp 0.7.0
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
38#include <h5cpp/core/types.hpp>
39#include <h5cpp/node/link.hpp>
40#include <h5cpp/error/error.hpp>
41#include <initializer_list>
44
45namespace hdf5 {
46namespace 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 node::Link parent_link_;
207 ObjectHandle handle_;
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
324template<typename T>
325void 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
350template<typename T>
351void Attribute::write(const T &data) const
352{
353 auto file_type = datatype();
354 if(file_type.get_class() == datatype::Class::String)
355 {
356 write(data,file_type);
357 }
358 else
359 {
360 hdf5::datatype::DatatypeHolder mem_type_holder;
361 write(data,mem_type_holder.get<T>());
362 }
363}
364
365template<typename T>
366void Attribute::read(T &data) const
367{
368 auto file_type = datatype();
369 if(file_type.get_class() == datatype::Class::String)
370 {
371 read(data, file_type);
372 }
373 else
374 {
375 hdf5::datatype::DatatypeHolder mem_type_holder;
376 read(data, mem_type_holder.get<T>(), file_type);
377 }
378}
379
380template<typename T>
381void Attribute::read(T &data,const datatype::Datatype &mem_type) const
382{
383 datatype::Datatype file_type = datatype();
384 read(data, mem_type, file_type);
385}
386
387template<typename T>
388void Attribute::read(T &data, const datatype::Datatype &mem_type, const datatype::Datatype &file_type) const
389{
390 check_size(dataspace::create(data),dataspace(),"read");
391
392 if(file_type.get_class()==datatype::Class::String)
393 {
394 datatype::String string_type(file_type);
395
396 if(string_type.is_variable_length())
397 {
398 read_variable_length_string(data,mem_type);
399 }
400 else
401 {
402 read_fixed_length_string(data,mem_type);
403 }
404 }
405 else
406 {
407 read_contiguous_data(data,mem_type);
408 }
409}
410
411
412
413} // namespace attribute
414} // 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
const node::Link & parent_link() const noexcept
get the parent ndoe
bool is_valid() const
check if object is valid
void write(const T &data) const
write data to attribute
Definition: attribute.hpp:351
void read(T &data) const
Definition: attribute.hpp:366
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
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
const void * cptr(const T &value)
Definition: type_trait.hpp:116
@ 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