h5cpp 0.8.0
A modern C++ wrapper for the HDF5 C library
Loading...
Searching...
No Matches
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 void read(std::string &data, bool trim = false) const;
206
207 void read(std::string &data, const datatype::Datatype &mem_type, bool trim = false) const;
208
209 private:
210 node::Link parent_link_;
211 ObjectHandle handle_;
212
213 template<typename T>
214 void read(T &data,const datatype::Datatype &mem_type, const datatype::Datatype &file_type) const;
215
216 void read(std::string &data, const datatype::Datatype &mem_type, const datatype::Datatype &file_type, bool trim = false) const;
217
218 template<typename T>
219 void write_fixed_length_string(const T &data,
220 const datatype::Datatype &mem_type) const
221 {
222 using Trait = FixedLengthStringTrait<T>;
223 using SpaceTrait = hdf5::dataspace::TypeTrait<T>;
224 auto buffer = Trait::to_buffer(data,mem_type,SpaceTrait::create(data));
225
226 if(H5Awrite(static_cast<hid_t>(handle_),
227 static_cast<hid_t>(mem_type),
228 buffer.data())<0)
229 {
230 error::Singleton::instance().throw_with_stack("Failure to write data to attribute!");
231 }
232
233 }
234
235 template<typename T>
236 void write_variable_length_string(const T &data,
237 const datatype::Datatype &mem_type) const
238 {
239 using Trait = VarLengthStringTrait<T>;
240 auto buffer = Trait::to_buffer(data);
241
242 if(H5Awrite(static_cast<hid_t>(handle_),
243 static_cast<hid_t>(mem_type),
244 buffer.data())<0)
245 {
246 error::Singleton::instance().throw_with_stack("Failure to write data to attribute!");
247 }
248
249 }
250
251 template<typename T>
252 void write_contiguous_data(const T &data,
253 const datatype::Datatype &mem_type) const
254 {
255 const void *ptr = dataspace::cptr(data);
256 if(H5Awrite(static_cast<hid_t>(handle_),static_cast<hid_t>(mem_type),ptr)<0)
257 {
258 error::Singleton::instance().throw_with_stack("Failure to write data to attribute!");
259 }
260 }
261
262 template<typename T>
263 void read_fixed_length_string(T &data,
264 const datatype::Datatype &mem_type) const
265 {
266 using Trait = FixedLengthStringTrait<T>;
267 using SpaceTrait = hdf5::dataspace::TypeTrait<T>;
268
269 auto buffer = Trait::BufferType::create(mem_type,SpaceTrait::create(data));
270
271 if(H5Aread(static_cast<hid_t>(handle_),
272 static_cast<hid_t>(mem_type),
273 buffer.data())<0)
274 {
275 error::Singleton::instance().throw_with_stack("Failure to read data from attribute!");
276 }
277
278 data = Trait::from_buffer(buffer,mem_type,SpaceTrait::create(data));
279
280 }
281
282 void read_fixed_length_string(std::string &data,
283 const datatype::Datatype &mem_type, bool trim = false) const
284 {
285 using Trait = FixedLengthStringTrait<std::string>;
287
288 auto buffer = Trait::BufferType::create(mem_type, SpaceTrait::create(data));
289
290 if (H5Aread(static_cast<hid_t>(handle_),
291 static_cast<hid_t>(mem_type),
292 buffer.data()) < 0)
293 {
294 error::Singleton::instance().throw_with_stack("Failure to read data from attribute!");
295 }
296
297 if (trim)
298 {
299 data = Trait::from_buffer_trimmed(buffer, mem_type, SpaceTrait::create(data));
300 }
301 else
302 {
303 data = Trait::from_buffer(buffer, mem_type, SpaceTrait::create(data));
304 }
305 }
306
307 template <typename T>
308 void read_variable_length_string(T &data,
309 const datatype::Datatype &mem_type) const
310 {
311 using Trait = VarLengthStringTrait<T>;
312
313 typename Trait::BufferType buffer(signed2unsigned<typename std::vector<T>::size_type>(dataspace().size()));
314
315 if(H5Aread(static_cast<hid_t>(handle_),
316 static_cast<hid_t>(mem_type),
317 buffer.data())<0)
318 {
319 error::Singleton::instance().throw_with_stack("Failure to read data from attribute!");
320 }
321
322 Trait::from_buffer(buffer,data);
323
324 if(H5Dvlen_reclaim(static_cast<hid_t>(mem_type),
325 static_cast<hid_t>(dataspace()),
326 static_cast<hid_t>(property::DatasetTransferList()),
327 buffer.data())<0)
328 {
329 std::stringstream ss;
330 ss<<"Failure to reclaim buffer for variable length string"
331 <<" string read on attribute!";
332 error::Singleton::instance().throw_with_stack(ss.str());
333 }
334
335 }
336
337 template<typename T>
338 void read_contiguous_data(T &data,
339 const datatype::Datatype &mem_type) const
340 {
341 void *ptr = dataspace::ptr(data);
342
343 if(H5Aread(static_cast<hid_t>(handle_),static_cast<hid_t>(mem_type),ptr)<0)
344 {
345 error::Singleton::instance().throw_with_stack("Failure to read data from attribute!");
346 }
347 }
348
349 void check_size(const dataspace::Dataspace &mem_space,
350 const dataspace::Dataspace &file_space,
351 const std::string &operation) const;
352
353};
354
355template<typename T>
356void Attribute::write(const T &data,const datatype::Datatype &mem_type) const
357{
358 datatype::Datatype file_type = datatype();
359
360 check_size(dataspace::create(data),dataspace(),"write");
361
362 if(file_type.get_class()==datatype::Class::String)
363 {
364 datatype::String string_type(file_type);
365
366 if(string_type.is_variable_length())
367 {
368 write_variable_length_string(data,mem_type);
369 }
370 else
371 {
372 write_fixed_length_string(data,mem_type);
373 }
374 }
375 else
376 {
377 write_contiguous_data(data,mem_type);
378 }
379}
380
381template<typename T>
382void Attribute::write(const T &data) const
383{
384 auto file_type = datatype();
385 if(file_type.get_class() == datatype::Class::String)
386 {
387 write(data,file_type);
388 }
389 else
390 {
391 hdf5::datatype::DatatypeHolder mem_type_holder;
392 write(data,mem_type_holder.get<T>());
393 }
394}
395
396template<typename T>
397void Attribute::read(T &data) const
398{
399 auto file_type = datatype();
400 if(file_type.get_class() == datatype::Class::String)
401 {
402 read(data, file_type);
403 }
404 else
405 {
406 hdf5::datatype::DatatypeHolder mem_type_holder;
407 read(data, mem_type_holder.get<T>(), file_type);
408 }
409}
410
411template<typename T>
412void Attribute::read(T &data,const datatype::Datatype &mem_type) const
413{
414 datatype::Datatype file_type = datatype();
415 read(data, mem_type, file_type);
416}
417
418template<typename T>
419void Attribute::read(T &data, const datatype::Datatype &mem_type, const datatype::Datatype &file_type) const
420{
421 check_size(dataspace::create(data),dataspace(),"read");
422
423 if(file_type.get_class()==datatype::Class::String)
424 {
425 datatype::String string_type(file_type);
426
427 if(string_type.is_variable_length())
428 {
429 read_variable_length_string(data,mem_type);
430 }
431 else
432 {
433 read_fixed_length_string(data,mem_type);
434 }
435 }
436 else
437 {
438 read_contiguous_data(data,mem_type);
439 }
440}
441
442
443
444} // namespace attribute
445} // 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
void read(std::string &data, bool trim=false) 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:382
void read(std::string &data, const datatype::Datatype &mem_type, bool trim=false) const
void read(T &data) const
Definition attribute.hpp:397
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
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
top-level namespace of the entire library
Definition attribute.hpp:45
Definition fixed_length_string.hpp:59
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