HighFive  2.3.1
HighFive - Header-only C++ HDF5 interface
H5Easy_misc.hpp
Go to the documentation of this file.
1 /*
2  * Copyright (c), 2017, Adrien Devresse <adrien.devresse@epfl.ch>
3  *
4  * Distributed under the Boost Software License, Version 1.0.
5  * (See accompanying file LICENSE_1_0.txt or copy at
6  * http://www.boost.org/LICENSE_1_0.txt)
7  *
8  */
9 #ifndef H5EASY_BITS_MISC_HPP
10 #define H5EASY_BITS_MISC_HPP
11 
12 #include "../H5Easy.hpp"
13 
14 namespace H5Easy {
15 
16 namespace detail {
17 
18 // Generate error-stream and return "Exception" (not yet thrown).
19 inline Exception error(const File& file,
20  const std::string& path,
21  const std::string& message) {
22  std::ostringstream ss;
23  ss << message << std::endl
24  << "Path: " << path << std::endl
25  << "Filename: " << file.getName() << std::endl;
26  return Exception(ss.str());
27 }
28 
29 // Generate specific dump error
30 inline Exception dump_error(File& file, const std::string& path)
31 {
32  if (file.getObjectType(path) == ObjectType::Dataset) {
33  return error(file, path,
34  "H5Easy: Dataset already exists, dump with H5Easy::DumpMode::Overwrite "
35  "to overwrite (with an array of the same shape).");
36  } else {
37  return error(file, path,
38  "H5Easy: path exists, but does not correspond to a Dataset. Dump not possible.");
39  }
40 }
41 
42 // get a opened DataSet: nd-array
43 template <class T>
44 inline DataSet initDataset(File& file,
45  const std::string& path,
46  const std::vector<size_t>& shape,
47  const DumpOptions& options)
48 {
49  if (!file.exist(path)) {
50  if (!options.compress() && !options.isChunked()) {
51  return file.createDataSet<T>(path, DataSpace(shape), {}, {}, true);
52  } else {
53  std::vector<hsize_t> chunks(shape.begin(), shape.end());
54  if (options.isChunked()) {
55  chunks = options.getChunkSize();
56  if (chunks.size() != shape.size()) {
57  throw error(file, path, "H5Easy::dump: Incorrect rank ChunkSize");
58  }
59  }
60  DataSetCreateProps props;
61  props.add(Chunking(chunks));
62  if (options.compress()) {
63  props.add(Shuffle());
64  props.add(Deflate(options.getCompressionLevel()));
65  }
66  return file.createDataSet<T>(path, DataSpace(shape), props, {}, true);
67  }
68  } else if (options.overwrite() && file.getObjectType(path) == ObjectType::Dataset) {
69  DataSet dataset = file.getDataSet(path);
70  if (dataset.getDimensions() != shape) {
71  throw error(file, path, "H5Easy::dump: Inconsistent dimensions");
72  }
73  return dataset;
74  }
75  throw dump_error(file, path);
76 }
77 
78 // get a opened DataSet: scalar
79 template <class T>
80 inline DataSet initScalarDataset(File& file,
81  const std::string& path,
82  const T& data,
83  const DumpOptions& options)
84 {
85  if (!file.exist(path)) {
86  return file.createDataSet<T>(path, DataSpace::From(data), {}, {}, true);
87  } else if (options.overwrite() && file.getObjectType(path) == ObjectType::Dataset) {
88  DataSet dataset = file.getDataSet(path);
89  if (dataset.getElementCount() != 1) {
90  throw error(file, path, "H5Easy::dump: Existing field not a scalar");
91  }
92  return dataset;
93  }
94  throw dump_error(file, path);
95 }
96 
97 // get a opened Attribute: nd-array
98 template <class T>
99 inline Attribute initAttribute(File& file,
100  const std::string& path,
101  const std::string& key,
102  const std::vector<size_t>& shape,
103  const DumpOptions& options)
104 {
105  if (!file.exist(path)) {
106  throw error(file, path, "H5Easy::dumpAttribute: DataSet does not exist");
107  }
108  if (file.getObjectType(path) != ObjectType::Dataset) {
109  throw error(file, path, "H5Easy::dumpAttribute: path not a DataSet");
110  }
111  DataSet dataset = file.getDataSet(path);
112  if (!dataset.hasAttribute(key)) {
113  return dataset.createAttribute<T>(key, DataSpace(shape));
114  } else if (options.overwrite()) {
115  Attribute attribute = dataset.getAttribute(key);
116  DataSpace dataspace = attribute.getSpace();
117  if (dataspace.getDimensions() != shape) {
118  throw error(file, path, "H5Easy::dumpAttribute: Inconsistent dimensions");
119  }
120  return attribute;
121  }
122  throw error(file, path,
123  "H5Easy: Attribute exists, overwrite with H5Easy::DumpMode::Overwrite.");
124 }
125 
126 // get a opened Attribute: scalar
127 template <class T>
128 inline Attribute initScalarAttribute(File& file,
129  const std::string& path,
130  const std::string& key,
131  const T& data,
132  const DumpOptions& options)
133 {
134  if (!file.exist(path)) {
135  throw error(file, path, "H5Easy::dumpAttribute: DataSet does not exist");
136  }
137  if (file.getObjectType(path) != ObjectType::Dataset) {
138  throw error(file, path, "H5Easy::dumpAttribute: path not a DataSet");
139  }
140  DataSet dataset = file.getDataSet(path);
141  if (!dataset.hasAttribute(key)) {
142  return dataset.createAttribute<T>(key, DataSpace::From(data));
143  } else if (options.overwrite()) {
144  Attribute attribute = dataset.getAttribute(key);
145  DataSpace dataspace = attribute.getSpace();
146  if (dataspace.getElementCount() != 1) {
147  throw error(file, path, "H5Easy::dumpAttribute: Existing field not a scalar");
148  }
149  return attribute;
150  }
151  throw error(file, path,
152  "H5Easy: Attribute exists, overwrite with H5Easy::DumpMode::Overwrite.");
153 }
154 
155 } // namespace detail
156 } // namespace H5Easy
157 
158 #endif // H5EASY_BITS_MISC_HPP
static DataSpace From(const T &value)
Create a dataspace matching a type accepted by details::inspector.
Definition: H5Dataspace_misc.hpp:133
Read/dump DataSets or Attribute using a minimalistic syntax. To this end, the functions are templated...
Definition: H5Easy.hpp:60
PropertyList< PropertyType::DATASET_CREATE > DataSetCreateProps
Definition: H5PropertyList.hpp:93