UCommon
persist.h
Go to the documentation of this file.
1 // Copyright (C) 2006-2010 David Sugar, Tycho Softworks.
2 //
3 // This file is part of GNU uCommon C++.
4 //
5 // GNU uCommon C++ is free software: you can redistribute it and/or modify
6 // it under the terms of the GNU Lesser General Public License as published
7 // by the Free Software Foundation, either version 3 of the License, or
8 // (at your option) any later version.
9 //
10 // GNU uCommon C++ is distributed in the hope that it will be useful,
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 // GNU Lesser General Public License for more details.
14 //
15 // You should have received a copy of the GNU Lesser General Public License
16 // along with GNU uCommon C++. If not, see <http://www.gnu.org/licenses/>.
17 
23 #if defined(OLD_STDCPP) || defined(NEW_STDCPP)
24 #if !defined(_MSC_VER) || _MSC_VER >= 1400
25 #ifndef _UCOMMON_PERSIST_H_
26 #define _UCOMMON_PERSIST_H_
27 
28 #ifndef _UCOMMON_PLATFORM_H_
29 #include <ucommon/platform.h>
30 #endif
31 
32 #include <iostream>
33 #include <string>
34 #include <vector>
35 #include <deque>
36 #include <map>
37 
38 NAMESPACE_UCOMMON
39 #define NS_PREFIX ucc::
40 
41 // This typedef allows us to declare NewPersistObjectFunction now
42 typedef class PersistObject* (*NewPersistObjectFunction) (void);
43 
44 class __EXPORT PersistException
45 {
46 public:
47  PersistException(const std::string& reason);
48  const std::string& getString() const;
49 
50  virtual ~PersistException() throw();
51 
52 protected:
53  std::string _what;
54 };
55 
64 class __EXPORT TypeManager
65 {
66 public:
72  {
73  public:
74  registration(const char* name, NewPersistObjectFunction func);
75  virtual ~registration();
76  private:
77  std::string myName;
78  };
79 
83  static void add(const char* name, NewPersistObjectFunction construction);
84 
88  static void remove(const char* name);
89 
95  static PersistObject* createInstanceOf(const char* name);
96 
97  typedef std::map<std::string,NewPersistObjectFunction> StringFunctionMap;
98 };
99 
100 /*
101  * The following defines are used to declare and define the relevant code
102  * to allow a class to use the Persistence::Engine code.
103  */
104 
105 #define DECLARE_PERSISTENCE(ClassType) \
106  public: \
107  friend NS_PREFIX PersistEngine& operator>>( NS_PREFIX PersistEngine& ar, ClassType *&ob); \
108  friend NS_PREFIX PersistEngine& operator<<( NS_PREFIX PersistEngine& ar, ClassType const &ob); \
109  friend NS_PREFIX PersistObject *createNew##ClassType(); \
110  virtual const char* getPersistenceID() const; \
111  static NS_PREFIX TypeManager::Registration registrationFor##ClassType;
112 
113 #define IMPLEMENT_PERSISTENCE(ClassType, FullyQualifiedName) \
114  NS_PREFIX PersistObject *createNew##ClassType() { return new ClassType; } \
115  const char* ClassType::getPersistenceID() const {return FullyQualifiedName;} \
116  NS_PREFIX PersistEngine& operator>>(NS_PREFIX PersistEngine& ar, ClassType &ob) \
117  { ar >> (NS_PREFIX PersistObject &) ob; return ar; } \
118  NS_PREFIX PersistEngine& operator>>(NS_PREFIX PersistEngine& ar, ClassType *&ob) \
119  { ar >> (NS_PREFIX PersistObject *&) ob; return ar; } \
120  NS_PREFIX PersistEngine& operator<<(NS_PREFIX PersistEngine& ar, ClassType const &ob) \
121  { ar << (NS_PREFIX PersistObject const *)&ob; return ar; } \
122  NS_PREFIX TypeManager::Registration \
123  ClassType::registrationFor##ClassType(FullyQualifiedName, \
124  createNew##ClassType);
125 
126 class PersistEngine;
127 
147 class __EXPORT PersistObject
148 {
149 public:
155  PersistObject();
156 
160  virtual ~PersistObject();
161 
165  virtual const char* getPersistenceID() const;
166 
172  virtual bool write(PersistEngine& archive) const;
173 
179  virtual bool read(PersistEngine& archive);
180 };
181 
190 class __EXPORT PersistEngine
191 {
192 public:
196  enum EngineMode {
197  modeRead,
198  modeWrite
199  };
200 
206  PersistEngine(std::iostream& stream, EngineMode mode) throw(PersistException);
207 
208  virtual ~PersistEngine();
209 
210  // Write operations
211 
215  inline void write(const PersistObject &object) throw(PersistException)
216  {write(&object); };
217 
221  void write(const PersistObject *object) throw(PersistException);
222 
223  // writes supported primitive types
224  // shortcut, to make the following more readable
225 #define CCXX_ENGINEWRITE_REF(valref) writeBinary((const uint8_t*)&valref,sizeof(valref))
226  inline void write(int8_t i) throw(PersistException) { CCXX_ENGINEWRITE_REF(i); }
227  inline void write(uint8_t i) throw(PersistException) { CCXX_ENGINEWRITE_REF(i); }
228  inline void write(int16_t i) throw(PersistException) { CCXX_ENGINEWRITE_REF(i); }
229  inline void write(uint16_t i) throw(PersistException) { CCXX_ENGINEWRITE_REF(i); }
230  inline void write(int32_t i) throw(PersistException) { CCXX_ENGINEWRITE_REF(i); }
231  inline void write(uint32_t i) throw(PersistException) { CCXX_ENGINEWRITE_REF(i); }
232  inline void write(float i) throw(PersistException) { CCXX_ENGINEWRITE_REF(i); }
233  inline void write(double i) throw(PersistException) { CCXX_ENGINEWRITE_REF(i); }
234  inline void write(bool i) throw(PersistException) { CCXX_ENGINEWRITE_REF(i); }
235 #undef CCXX_ENGINEWRITE_REF
236 
237  void write(const std::string& str) throw(PersistException);
238 
239  // Every write operation boils down to one or more of these
240  void writeBinary(const uint8_t* data, const uint32_t size) throw(PersistException);
241 
242  // Read Operations
243 
247  void read(PersistObject &object) throw(PersistException);
248 
252  void read(PersistObject *&object) throw(PersistException);
253 
254  // reads supported primitive types
255  // shortcut, to make the following more readable
256 #define CCXX_ENGINEREAD_REF(valref) readBinary((uint8_t*)&valref,sizeof(valref))
257  inline void read(int8_t& i) throw(PersistException) { CCXX_ENGINEREAD_REF(i); }
258  inline void read(uint8_t& i) throw(PersistException) { CCXX_ENGINEREAD_REF(i); }
259  inline void read(int16_t& i) throw(PersistException) { CCXX_ENGINEREAD_REF(i); }
260  inline void read(uint16_t& i) throw(PersistException) { CCXX_ENGINEREAD_REF(i); }
261  inline void read(int32_t& i) throw(PersistException) { CCXX_ENGINEREAD_REF(i); }
262  inline void read(uint32_t& i) throw(PersistException) { CCXX_ENGINEREAD_REF(i); }
263  inline void read(float& i) throw(PersistException) { CCXX_ENGINEREAD_REF(i); }
264  inline void read(double& i) throw(PersistException) { CCXX_ENGINEREAD_REF(i); }
265  inline void read(bool &i) throw(PersistException) { CCXX_ENGINEREAD_REF(i); }
266 #undef CCXX_ENGINEREAD_REF
267 
268  void read(std::string& str) throw(PersistException);
269 
270  // Every read operation boiled down to one or more of these
271  void readBinary(uint8_t* data, uint32_t size) throw(PersistException);
272 
273 private:
278  void readObject(PersistObject* object) throw(PersistException);
279 
283  const std::string readClass() throw(PersistException);
284 
285 
289  std::iostream& myUnderlyingStream;
290 
294  EngineMode myOperationalMode;
295 
299  typedef std::vector<PersistObject*> ArchiveVector;
300  typedef std::map<PersistObject const*, int32_t> ArchiveMap;
301  typedef std::vector<std::string> ClassVector;
302  typedef std::map<std::string, int32_t> ClassMap;
303 
304  ArchiveVector myArchiveVector;
305  ArchiveMap myArchiveMap;
306  ClassVector myClassVector;
307  ClassMap myClassMap;
308 };
309 
310 #define CCXX_RE(ar,ob) ar.read(ob); return ar
311 #define CCXX_WE(ar,ob) ar.write(ob); return ar
312 
313 // Standard >> and << stream operators for PersistObject
315 inline PersistEngine& operator >>( PersistEngine& ar, PersistObject &ob) throw(PersistException) {CCXX_RE(ar,ob);}
317 inline PersistEngine& operator >>( PersistEngine& ar, PersistObject *&ob) throw(PersistException) {CCXX_RE(ar,ob);}
319 inline PersistEngine& operator <<( PersistEngine& ar, PersistObject const &ob) throw(PersistException) {CCXX_WE(ar,ob);}
321 inline PersistEngine& operator <<( PersistEngine& ar, PersistObject const *ob) throw(PersistException) {CCXX_WE(ar,ob);}
322 
324 inline PersistEngine& operator >>( PersistEngine& ar, int8_t& ob) throw(PersistException) {CCXX_RE(ar,ob);}
326 inline PersistEngine& operator <<( PersistEngine& ar, int8_t ob) throw(PersistException) {CCXX_WE(ar,ob);}
327 
329 inline PersistEngine& operator >>( PersistEngine& ar, uint8_t& ob) throw(PersistException) {CCXX_RE(ar,ob);}
331 inline PersistEngine& operator <<( PersistEngine& ar, uint8_t ob) throw(PersistException) {CCXX_WE(ar,ob);}
332 
334 inline PersistEngine& operator >>( PersistEngine& ar, int16_t& ob) throw(PersistException) {CCXX_RE(ar,ob);}
336 inline PersistEngine& operator <<( PersistEngine& ar, int16_t ob) throw(PersistException) {CCXX_WE(ar,ob);}
337 
339 inline PersistEngine& operator >>( PersistEngine& ar, uint16_t& ob) throw(PersistException) {CCXX_RE(ar,ob);}
341 inline PersistEngine& operator <<( PersistEngine& ar, uint16_t ob) throw(PersistException) {CCXX_WE(ar,ob);}
342 
344 inline PersistEngine& operator >>( PersistEngine& ar, int32_t& ob) throw(PersistException) {CCXX_RE(ar,ob);}
346 inline PersistEngine& operator <<( PersistEngine& ar, int32_t ob) throw(PersistException) {CCXX_WE(ar,ob);}
347 
349 inline PersistEngine& operator >>( PersistEngine& ar, uint32_t& ob) throw(PersistException) {CCXX_RE(ar,ob);}
351 inline PersistEngine& operator <<( PersistEngine& ar, uint32_t ob) throw(PersistException) {CCXX_WE(ar,ob);}
352 
354 inline PersistEngine& operator >>( PersistEngine& ar, float& ob) throw(PersistException) {CCXX_RE(ar,ob);}
356 inline PersistEngine& operator <<( PersistEngine& ar, float ob) throw(PersistException) {CCXX_WE(ar,ob);}
357 
359 inline PersistEngine& operator >>( PersistEngine& ar, double& ob) throw(PersistException) {CCXX_RE(ar,ob);}
361 inline PersistEngine& operator <<( PersistEngine& ar, double ob) throw(PersistException) {CCXX_WE(ar,ob);}
362 
364 inline PersistEngine& operator >>( PersistEngine& ar, std::string& ob) throw(PersistException) {CCXX_RE(ar,ob);}
366 inline PersistEngine& operator <<( PersistEngine& ar, std::string ob) throw(PersistException) {CCXX_WE(ar,ob);}
367 
369 inline PersistEngine& operator >>( PersistEngine& ar, bool& ob) throw(PersistException) {CCXX_RE(ar,ob);}
371 inline PersistEngine& operator <<( PersistEngine& ar, bool ob) throw(PersistException) {CCXX_WE(ar,ob);}
372 
373 #undef CCXX_RE
374 #undef CCXX_WE
375 
385 template<class T>
386 PersistEngine& operator <<( PersistEngine& ar, typename std::vector<T> const& ob) throw(PersistException)
387 {
388  ar << (uint32_t)ob.size();
389  for(unsigned int i=0; i < ob.size(); ++i)
390  ar << ob[i];
391  return ar;
392 }
393 
399 template<class T>
400 PersistEngine& operator >>( PersistEngine& ar, typename std::vector<T>& ob) throw(PersistException)
401 {
402  ob.clear();
403  uint32_t siz;
404  ar >> siz;
405  ob.resize(siz);
406  for(uint32_t i=0; i < siz; ++i)
407  ar >> ob[i];
408  return ar;
409 }
410 
416 template<class T>
417 PersistEngine& operator <<( PersistEngine& ar, typename std::deque<T> const& ob) throw(PersistException)
418 {
419  ar << (uint32_t)ob.size();
420  for(typename std::deque<T>::const_iterator it=ob.begin(); it != ob.end(); ++it)
421  ar << *it;
422  return ar;
423 }
424 
430 template<class T>
431 PersistEngine& operator >>( PersistEngine& ar, typename std::deque<T>& ob) throw(PersistException)
432 {
433  ob.clear();
434  uint32_t siz;
435  ar >> siz;
436  //ob.resize(siz);
437  for(uint32_t i=0; i < siz; ++i) {
438  T node;
439  ar >> node;
440  ob.push_back(node);
441  //ar >> ob[i];
442  }
443  return ar;
444 }
445 
451 template<class Key, class Value>
452 PersistEngine& operator <<( PersistEngine& ar, typename std::map<Key,Value> const & ob) throw(PersistException)
453 {
454  ar << (uint32_t)ob.size();
455  for(typename std::map<Key,Value>::const_iterator it = ob.begin();it != ob.end();++it)
456  ar << it->first << it->second;
457  return ar;
458 }
459 
465 template<class Key, class Value>
466 PersistEngine& operator >>( PersistEngine& ar, typename std::map<Key,Value>& ob) throw(PersistException)
467 {
468  ob.clear();
469  uint32_t siz;
470  ar >> siz;
471  for(uint32_t i=0; i < siz; ++i) {
472  Key a;
473  ar >> a;
474  ar >> ob[a];
475  }
476  return ar;
477 }
478 
483 template<class x, class y>
484 PersistEngine& operator <<( PersistEngine& ar, std::pair<x,y> &ob) throw(PersistException)
485 {
486  ar << ob.first << ob.second;
487  return ar;
488 }
489 
494 template<class x, class y>
495 PersistEngine& operator >>(PersistEngine& ar, std::pair<x, y> &ob) throw(PersistException)
496 {
497  ar >> ob.first >> ob.second;
498  return ar;
499 }
500 
501 END_NAMESPACE
502 
503 #endif
504 #endif
505 #endif