icedb  version 0.5.1
Snow particle scattering database API
Attributes.cpp
Go to the documentation of this file.
1 #include "../icedb/Attribute.hpp"
2 #include "../private/Attribute_impl.hpp"
3 #include "../private/hdf5_load.h"
4 #include "../private/hdf5_supplemental.hpp"
5 #include "../icedb/compat/gsl/gsl_assert"
6 #include <stdexcept>
7 
8 namespace icedb {
9  namespace Attributes {
10 
13 
14 
16  CanHaveAttributes_impl::CanHaveAttributes_impl(std::shared_ptr<H5::H5Object> parent) : parent(parent) {}
18 
19  bool CanHaveAttributes::valid() const {
20  if (!_getAttributeParent()) return false;
21  return true;
22  }
23 
24  void CanHaveAttributes_impl::_setAttributeParent(std::shared_ptr<H5::H5Object> obj)
25  {
26  parent = obj;
27  }
28 
29  std::shared_ptr<H5::H5Object> CanHaveAttributes_impl::_getAttributeParent() const
30  {
31  return parent;
32  }
33 
34  std::type_index CanHaveAttributes::getAttributeTypeId(gsl::not_null<const H5::H5Object*> parent, const std::string &attributeName) {
35  if (fs::hdf5::isType<uint64_t, H5::H5Object>(parent.get(), attributeName)) return (typeid(uint64_t));
36  if (fs::hdf5::isType<int64_t, H5::H5Object>(parent.get(), attributeName)) return (typeid(int64_t));
37  if (fs::hdf5::isType<uint32_t, H5::H5Object>(parent.get(), attributeName)) return (typeid(uint32_t));
38  if (fs::hdf5::isType<int32_t, H5::H5Object>(parent.get(), attributeName)) return (typeid(int32_t));
39  if (fs::hdf5::isType<uint16_t, H5::H5Object>(parent.get(), attributeName)) return (typeid(uint16_t));
40  if (fs::hdf5::isType<int16_t, H5::H5Object>(parent.get(), attributeName)) return (typeid(int16_t));
41  if (fs::hdf5::isType<uint8_t, H5::H5Object>(parent.get(), attributeName)) return (typeid(uint8_t));
42  if (fs::hdf5::isType<int8_t, H5::H5Object>(parent.get(), attributeName)) return (typeid(int8_t));
43  if (fs::hdf5::isType<double, H5::H5Object>(parent.get(), attributeName)) return (typeid(double));
44  if (fs::hdf5::isType<float, H5::H5Object>(parent.get(), attributeName)) return (typeid(float));
45  if (fs::hdf5::isType<char, H5::H5Object>(parent.get(), attributeName)) return (typeid(char));
46  if (fs::hdf5::isType<std::string, H5::H5Object>(parent.get(), attributeName)) return (typeid(std::string));
47  throw;
48  }
49 
50  std::type_index CanHaveAttributes::getAttributeTypeId(const std::string &attributeName) const {
51  auto parent = _getAttributeParent();
52  return getAttributeTypeId(parent.get(), attributeName);
53  }
54 
55  void CanHaveAttributes::deleteAttribute(const std::string &attributeName)
56  {
57  Expects(valid());
58  _getAttributeParent()->removeAttr(attributeName);
59  }
60 
61  bool CanHaveAttributes::doesAttributeExist(const std::string &attributeName) const
62  {
67  Expects(valid());
68 #if ICEDB_H5_HASH5OBJECTATTREXISTS == 1
69  return _getAttributeParent()->attrExists(attributeName);
70 #else
71  hid_t objid = _getAttributeParent()->getId();
72  htri_t res = H5Aexists(objid, attributeName.c_str());
73  if (res < 0) throw;
74  return (res > 0) ? true : false;
75 #endif
76  }
77 
79  gsl::not_null<const H5::H5Object*> parent, const std::string &attributeName)
80  {
85 #if ICEDB_H5_HASH5OBJECTATTREXISTS == 1
86  return parent->attrExists(attributeName);
87 #else
88  hid_t objid = parent->getId();
89  htri_t res = H5Aexists(objid, attributeName.c_str());
90  if (res < 0) throw;
91  return (res > 0) ? true : false;
92 #endif
93  }
94 
95  std::set<std::string> CanHaveAttributes::getAttributeNames() const {
96  Expects(valid());
97  //icedb::fs::hdf5::
98  std::set<std::string> anames;
99  int numAttrs = _getAttributeParent()->getNumAttrs();
100  for (int i = 0; i < numAttrs; ++i) {
101  H5::Attribute attr = _getAttributeParent()->openAttribute(i);
102  anames.insert(attr.getName());
103  }
104  return anames;
105  }
106 
108  template <class DataType>
109  constexpr bool isString() { return false; }
110  template<> constexpr bool isString<std::string>() { return true; }
111 
118  template <class DataType>
119  void pullData(
120  const std::string &attributeName,
121  std::vector<size_t> &dims,
122  std::vector<DataType> &tdata,
123  gsl::not_null<const H5::H5Object*> obj)
124  {
128 
129  const icedb::fs::hdf5::DataContainerType datatype = icedb::fs::hdf5::getAttributeGroupingType(obj, attributeName.c_str());
131  icedb::fs::hdf5::readAttrVector(obj, attributeName.c_str(), tdata);
132  dims.resize(1, tdata.size());
133  }
134  else if (datatype == icedb::fs::hdf5::DataContainerType::ARRAY) {
135  icedb::fs::hdf5::readAttrArray(obj, attributeName.c_str(), dims, tdata);
136  }
137  else if (datatype == icedb::fs::hdf5::DataContainerType::STRING) {
139  tdata.resize(1);
140  icedb::fs::hdf5::readAttr(obj, attributeName.c_str(), tdata[0]);
141  //throw;
142  }
143  else if (datatype == icedb::fs::hdf5::DataContainerType::VLEN) {
144  throw;
145  }
146  else throw;
147  }
148 
149  template <class DataType>
151  gsl::not_null<const H5::H5Object*> parent,
152  const std::string &attributeName,
153  std::vector<size_t> &dims,
154  std::vector<DataType> &data)
155  {
156  Expects(doesAttributeExist(parent,attributeName));
157 
158  if (icedb::fs::hdf5::isType<DataType, H5::H5Object>(parent.get(), attributeName))
159  pullData<DataType>(attributeName, dims, data, parent.get());
160  else throw(std::invalid_argument("Unhandled data type"));
161  }
162 
163  template <class DataType>
165  const std::string &attributeName,
166  std::vector<size_t> &dims,
167  std::vector<DataType> &data) const
168  {
169  Expects(valid());
170  Expects(doesAttributeExist(attributeName));
171  auto parent = _getAttributeParent();
172 
173  readAttributeData<DataType>(parent.get(), attributeName, dims, data);
174  }
175 
176 
177 
178 #define INST_READ_ATTR_TYPE(x) \
179  template void CanHaveAttributes::readAttributeData<x>( \
180  gsl::not_null<const H5::H5Object*> parent, \
181  const std::string &attributeName, \
182  std::vector<size_t> &dims, \
183  std::vector<x> &data) ; \
184  template void CanHaveAttributes::readAttributeData<x>( \
185  const std::string &attributeName,\
186  std::vector<size_t> &dims, \
187  std::vector<x> &data) const;
188 
189  //INST_READ_ATTR_TYPE(double);
191 
192  template <class DataType, class ObjectType>
193  void pushData(
194  const std::string &attributeName,
195  const std::vector<size_t> &dimensionality,
196  std::shared_ptr<ObjectType> obj,
197  const std::vector<DataType> &data,
198  bool forceArray = false
199  )
200  {
201  size_t numElems = 1;
202  for (const auto &s : dimensionality) numElems *= s;
203  Expects(numElems > 0);
204 
205  if (isString<DataType>()) {
207  Expects(dimensionality.size() == 1);
208  Expects(dimensionality[0] == 1);
209  icedb::fs::hdf5::addAttr<DataType, ObjectType>(obj.get(), attributeName.c_str(), data[0]);
210  }
211  else {
212  if ((dimensionality.size() == 1) && !forceArray)
213  icedb::fs::hdf5::addAttrVector<DataType, ObjectType>(obj.get(), attributeName.c_str(), data);
214  else icedb::fs::hdf5::addAttrArray<DataType, ObjectType>(obj.get(), attributeName.c_str(), dimensionality, data);
215  }
216  }
217 
218  template <class DataType>
220  const std::string &attributeName,
221  const std::vector<size_t> &dimensionality,
222  const std::vector<DataType> &data)
223  {
224  Expects(valid());
225  if (doesAttributeExist(attributeName)) deleteAttribute(attributeName);
226  auto parent = _getAttributeParent();
227  // Need to copy from the variant structure into an array of the exact data type
228 
229  //if (icedb::fs::hdf5::isType<DataType, H5::H5Object>(parent.get(), attributeName))
230  //pullData<DataType>(attributeName, dims, data, parent.get());
231  pushData<DataType, H5::H5Object>(attributeName, dimensionality, parent, data);
232  }
233 
234 #define INST_WRITE_ATTR_TYPE(x) \
235  template void CanHaveAttributes::writeAttributeData( \
236  const std::string &attributeName, \
237  const std::vector<size_t> &dimensionality, \
238  const std::vector<x> &data);
239 
241  }
242 }
virtual std::shared_ptr< H5::H5Object > _getAttributeParent() const override
Definition: Attributes.cpp:29
INST_ATTR(INST_READ_ATTR_TYPE)
void deleteAttribute(const std::string &attributeName)
Delete an attribute, by name, that is attached to this object.
Definition: Attributes.cpp:55
#define INST_READ_ATTR_TYPE(x)
Definition: Attributes.cpp:178
constexpr bool isString()
Used to flag string types for special treatment.
Definition: Attributes.cpp:109
std::set< std::string > getAttributeNames() const
List all attributes attached to this object.
Definition: Attributes.cpp:95
DataContainerType getAttributeGroupingType(gsl::not_null< Container *> obj, gsl::not_null< const char *> attname)
virtual void _setAttributeParent(std::shared_ptr< H5::H5Object > obj) override
Definition: Attributes.cpp:24
void writeAttributeData(const std::string &attributeName, const std::vector< size_t > &dimensionas, const std::vector< DataType > &data)
Function to write an attribute to an object, with the provided raw data.
Definition: Attributes.cpp:219
void readAttrVector(gsl::not_null< Container *> obj, gsl::not_null< const char *> attname, std::vector< DataType > &value)
Reads an array (or vector) of objects.
void pushData(const std::string &attributeName, const std::vector< size_t > &dimensionality, std::shared_ptr< ObjectType > obj, const std::vector< DataType > &data, bool forceArray=false)
Definition: Attributes.cpp:193
void readAttr(gsl::not_null< Container *> obj, gsl::not_null< const char *> attname, DataType &value)
Convenient template to read an attribute of a variable.
std::shared_ptr< H5::H5Object > parent
void pullData(const std::string &attributeName, std::vector< size_t > &dims, std::vector< DataType > &tdata, gsl::not_null< const H5::H5Object *> obj)
Template function to pull data from the HDF5 object.
Definition: Attributes.cpp:119
#define INST_WRITE_ATTR_TYPE(x)
Definition: Attributes.cpp:234
static void readAttributeData(gsl::not_null< const H5::H5Object *> parent, const std::string &attributeName, std::vector< size_t > &dimensions, std::vector< DataType > &data)
Function to read the data from an attribute.
Definition: Attributes.cpp:150
void readAttrArray(gsl::not_null< Container *> obj, gsl::not_null< const char *> attname, std::vector< size_t > &dims, std::vector< DataType > &value)
Reads an array (or vector) of objects.
std::type_index getAttributeTypeId(const std::string &attributeName) const
Returns the type of an attribute.
Definition: Attributes.cpp:50
bool doesAttributeExist(const std::string &attributeName) const
Does the object have an attribute with the given name?
Definition: Attributes.cpp:61