All Classes Namespaces Functions Variables Typedefs Enumerations Pages
interface.h
1 /* Copyright (C) 2009 Markus Friedrich
2  *
3  * This library is free software; you can redistribute it and/or
4  * modify it under the terms of the GNU Lesser General Public
5  * License as published by the Free Software Foundation; either
6  * version 2.1 of the License, or (at your option) any later version.
7  *
8  * This library is distributed in the hope that it will be useful,
9  * but WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11  * Lesser General Public License for more details.
12  *
13  * You should have received a copy of the GNU Lesser General Public
14  * License along with this library; if not, write to the Free Software
15  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
16  *
17  * Contact:
18  * friedrich.at.gc@googlemail.com
19  *
20  */
21 
22 #ifndef _HDF5SERIE_INTERFACE_H_
23 #define _HDF5SERIE_INTERFACE_H_
24 
25 #include <fmatvec/atom.h>
26 #include <hdf5.h>
27 #include <map>
28 #include <set>
29 #include <vector>
30 
31 namespace H5 {
32 
33  #define HDF5SERIE_MAXCTORPARAMETERS 5
34 
35  class ScopedHID {
36  protected:
37  typedef herr_t (*CloseFunc)(hid_t id);
38  hid_t id;
39  CloseFunc closeFunc;
40  public:
41  ScopedHID() : id(-1), closeFunc(NULL) {}
42  ScopedHID(hid_t id_, CloseFunc closeFunc_) : id(id_), closeFunc(closeFunc_) {}
43  ~ScopedHID() {
44  reset();
45  }
46  operator hid_t() {
47  return id;
48  }
49  void reset(hid_t id_=-1, CloseFunc closeFunc_=NULL) {
50  if(id>=0)
51  closeFunc(id);
52  id=id_;
53  closeFunc=closeFunc_;
54  }
55  };
56 
57  class Exception : public std::exception {
58  protected:
59  std::string path;
60  std::string msg;
61  mutable std::string whatMsg;
62  public:
63  explicit Exception(const std::string &path_, const std::string &msg_);
64  ~Exception() throw();
65  const char* what() const throw();
66  };
67 
68  class File;
69  class GroupBase;
70  class Attribute;
71  class Object;
72  template<class Child, class Self> class Container;
73 
74  enum ElementType {
75  simpleDatasetScalar,
76  simpleDatasetVector,
77  simpleDatasetMatrix,
78  vectorSerie,
79  simpleAttributeScalar,
80  simpleAttributeVector,
81  simpleAttributeMatrix
82  };
83 
84  class Element : virtual public fmatvec::Atom {
85  friend class Container<Attribute, Object>;
86  friend class Container<Object, GroupBase>;
87  protected:
88  ScopedHID id;
89  std::string name;
90  Element(const std::string &name_);
91  virtual ~Element();
92  virtual void close();
93  virtual void open();
94  virtual void refresh();
95  virtual void flush();
96  public:
98  hid_t getID() { return id; }
99  std::string getName() { return name; }
100  };
101 
102  // a container of objects of type Child which have itself a parent of type Self
103  template<class Child, class Self>
104  class Container {
105  protected:
106  Container() {
107  }
108  ~Container() {
109  for(typename std::map<std::string, Child*>::iterator it=childs.begin(); it!=childs.end(); ++it)
110  delete it->second;
111  }
112  void close() {
113  for(typename std::map<std::string, Child*>::iterator it=childs.begin(); it!=childs.end(); ++it)
114  it->second->close();
115  }
116  void open() {
117  for(typename std::map<std::string, Child*>::iterator it=childs.begin(); it!=childs.end(); ++it)
118  it->second->open();
119  }
120  void refresh() {
121  for(typename std::map<std::string, Child*>::iterator it=childs.begin(); it!=childs.end(); ++it)
122  it->second->refresh();
123  }
124  void flush() {
125  for(typename std::map<std::string, Child*>::iterator it=childs.begin(); it!=childs.end(); ++it)
126  it->second->flush();
127  }
128  std::map<std::string, Child*> childs;
129 
130  // create a objet of class T which is derived from Child
131  template<class T>
132  class Creator {
133  protected:
134  Self *self;
135  std::string name;
136  std::map<std::string, Child*> &childs;
137  public:
138  Creator(Self *self_, const std::string &name_, std::map<std::string, Child*> &childs_) :
139  self(self_), name(name_), childs(childs_) {}
140 
141  template<typename... Args>
142  T* operator()(Args&&... args) {
143  auto ret=childs.insert(std::pair<std::string, Child*>(name, NULL));
144  if(!ret.second)
145  throw Exception(self->getPath(), "A element of name "+name+" already exists.");
146  try {
147  T* r=new T(static_cast<Self*>(self), name, std::forward<Args>(args)...);
148  ret.first->second=r;
149  return r;
150  }
151  catch(...) {
152  childs.erase(name);
153  throw;
154  }
155  }
156  };
157  template<class T>
158  Creator<T> createChild(const std::string &name_) {
159  if(name_.find_first_of('/')!=std::string::npos)
160  throw Exception(static_cast<Self*>(this)->getPath(), "Internal error: must be a relative name, not absolute or a path");
161  return Creator<T>(static_cast<Self*>(this), name_, childs);
162  }
163 
164  template<class T>
165  T* openChild(const std::string &name_) {
166  if(name_.find_first_of('/')!=std::string::npos)
167  throw Exception(static_cast<Self*>(this)->getPath(), "Internal error: must be a relative name, not absolute or a path");
168  std::pair<typename std::map<std::string, Child*>::iterator, bool> ret=childs.insert(std::pair<std::string, Child*>(name_, NULL));
169  if(!ret.second) {
170  T *o=dynamic_cast<T*>(ret.first->second);
171  if(!o)
172  std::runtime_error("The element "+name_+" if of other type.");
173  return o;
174  }
175  try {
176  T* r=new T(0, static_cast<Self*>(this), name_);
177  ret.first->second=r;
178  return r;
179  }
180  catch(...) {
181  childs.erase(name_);
182  throw;
183  }
184  }
185  };
186 
187  class Object : public Element, public Container<Attribute, Object> {
188  friend class Container<Object, GroupBase>;
189  protected:
190  Object(GroupBase *parent_, const std::string &name_);
191  ~Object();
192  void close();
193  void open();
194  void refresh();
195  void flush();
196  GroupBase *parent;
197  File *file;
198  Object *getFileAsObject(); // helper function used in openChildAttribute
199  Object *getAttrParent(const std::string &path, size_t pos); // helper function used in openChildAttribute
200  public:
201  template<class T>
202  Creator<T> createChildAttribute(const std::string &path) {
203  if(path[0]=='/') // absolute path -> call openChildAttribute from file
204  return getFileAsObject()->createChildAttribute<T>(path.substr(1));
205  // now its a relative path
206  size_t pos;
207  if((pos=path.find_last_of('/'))==std::string::npos) // no / included -> call openChild from Container
208  return createChild<T>(path);
209  // now its a relative path including at least one /
210  return getAttrParent(path, pos)->createChild<T>(path.substr(pos+1));
211  }
212 
213  template<class T>
214  T* openChildAttribute(const std::string &path) {
215  if(path[0]=='/') // absolute path -> call openChildAttribute from file
216  return getFileAsObject()->openChildAttribute<T>(path.substr(1));
217  // now its a relative path
218  size_t pos;
219  if((pos=path.find_last_of('/'))==std::string::npos) // no / included -> call openChild from Container
220  return openChild<T>(path);
221  // now its a relative path including at least one /
222  return getAttrParent(path, pos)->openChild<T>(path.substr(pos+1));
223  }
224  Attribute *openChildAttribute(const std::string &name_, ElementType *objectType=NULL, hid_t *type=NULL);
225  std::set<std::string> getChildAttributeNames();
226  bool hasChildAttribute(const std::string &name_);
227  GroupBase *getParent() { return parent; }
228  File *getFile() { return file; }
229  std::string getPath();
230  };
231 
232  class Attribute : public Element {
233  friend class Container<Attribute, Object>;
234  protected:
235  Attribute(Object *parent_, const std::string &name_);
236  ~Attribute();
237  Object *parent;
238  File *file;
239  void close();
240  void open();
241  void refresh();
242  void flush();
243  public:
244  Object *getParent() { return parent; }
245  File *getFile() { return file; }
246  std::string getPath();
247  };
248 
249  class Dataset : public Object {
250  protected:
251  Dataset(GroupBase *parent_, const std::string &name_);
252  Dataset(int dummy, GroupBase *parent_, const std::string &name_);
253  ~Dataset();
254  void close();
255  void open();
256  void refresh();
257  void flush();
258  public:
259  std::vector<hsize_t> getExtentDims();
260  };
261 
262 }
263 
264 #endif
Definition: interface.h:232
Definition: interface.h:57
Definition: interface.h:132
Definition: interface.h:187
Definition: interface.h:84
Definition: interface.h:35
Definition: group.h:30
Definition: interface.h:72
Definition: interface.h:249
hid_t getID()
Note: use the returned hid_t only temporarily since its value may change, at least when File::reopenA...
Definition: interface.h:98
Definition: file.h:46

Impressum / Disclaimer / Datenschutz Generated by doxygen 1.8.5 Valid HTML