ucommon
persist.h
Go to the documentation of this file.
1 // Copyright (C) 2006-2014 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 #ifndef UCOMMON_SYSRUNTIME
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 
40 // This typedef allows us to declare NewPersistObjectFunction now
41 typedef class PersistObject* (*NewPersistObjectFunction) (void);
42 
43 class __EXPORT PersistException
44 {
45 public:
46  PersistException(const std::string& reason);
47  const std::string& getString() const;
48 
49  virtual ~PersistException() throw();
50 
51 protected:
52  std::string _what;
53 };
54 
63 class __EXPORT TypeManager
64 {
65 public:
71  {
72  public:
73  registration(const char* name, NewPersistObjectFunction func);
74  virtual ~registration();
75  private:
76  std::string myName;
77  };
78 
82  static void add(const char* name, NewPersistObjectFunction construction);
83 
87  static void remove(const char* name);
88 
94  static PersistObject* createInstanceOf(const char* name);
95 
96  typedef std::map<std::string,NewPersistObjectFunction> StringFunctionMap;
97 };
98 
99 /*
100  * The following defines are used to declare and define the relevant code
101  * to allow a class to use the Persistence::Engine code.
102  */
103 
104 #define DECLARE_PERSISTENCE(ClassType) \
105  public: \
106  friend ucommon::PersistEngine& operator>>( ucommon::PersistEngine& ar, ClassType *&ob); \
107  friend ucommon::PersistEngine& operator<<( ucommon::PersistEngine& ar, ClassType const &ob); \
108  friend ucommon::PersistObject *createNew##ClassType(); \
109  virtual const char* getPersistenceID() const; \
110  static ucommon::TypeManager::Registration registrationFor##ClassType;
111 
112 #define IMPLEMENT_PERSISTENCE(ClassType, FullyQualifiedName) \
113  ucommon::PersistObject *createNew##ClassType() { return new ClassType; } \
114  const char* ClassType::getPersistenceID() const {return FullyQualifiedName;} \
115  ucommon::PersistEngine& operator>>(ucommon::PersistEngine& ar, ClassType &ob) \
116  { ar >> (ucommon::PersistObject &) ob; return ar; } \
117  ucommon::PersistEngine& operator>>(ucommon::PersistEngine& ar, ClassType *&ob) \
118  { ar >> (ucommon::PersistObject *&) ob; return ar; } \
119  ucommon::PersistEngine& operator<<(ucommon::PersistEngine& ar, ClassType const &ob) \
120  { ar << (ucommon::PersistObject const *)&ob; return ar; } \
121  ucommon::TypeManager::Registration \
122  ClassType::registrationFor##ClassType(FullyQualifiedName, \
123  createNew##ClassType);
124 
125 class PersistEngine;
126 
146 class __EXPORT PersistObject
147 {
148 public:
154  PersistObject();
155 
159  virtual ~PersistObject();
160 
164  virtual const char* getPersistenceID() const;
165 
171  virtual bool write(PersistEngine& archive) const;
172 
178  virtual bool read(PersistEngine& archive);
179 };
180 
189 class __EXPORT PersistEngine
190 {
191 public:
195  enum EngineMode {
196  modeRead,
197  modeWrite
198  };
199 
205  PersistEngine(std::iostream& stream, EngineMode mode) throw(PersistException);
206 
207  virtual ~PersistEngine();
208 
209  // Write operations
210 
214  inline void write(const PersistObject &object) throw(PersistException)
215  {write(&object);}
216 
220  void write(const PersistObject *object) throw(PersistException);
221 
222  // writes supported primitive types
223  // shortcut, to make the following more readable
224 #define CCXX_ENGINEWRITE_REF(valref) writeBinary((const uint8_t*)&valref,sizeof(valref))
225  inline void write(int8_t i) throw(PersistException) { CCXX_ENGINEWRITE_REF(i); }
226  inline void write(uint8_t i) throw(PersistException) { CCXX_ENGINEWRITE_REF(i); }
227  inline void write(int16_t i) throw(PersistException) { CCXX_ENGINEWRITE_REF(i); }
228  inline void write(uint16_t i) throw(PersistException) { CCXX_ENGINEWRITE_REF(i); }
229  inline void write(int32_t i) throw(PersistException) { CCXX_ENGINEWRITE_REF(i); }
230  inline void write(uint32_t i) throw(PersistException) { CCXX_ENGINEWRITE_REF(i); }
231  inline void write(float i) throw(PersistException) { CCXX_ENGINEWRITE_REF(i); }
232  inline void write(double i) throw(PersistException) { CCXX_ENGINEWRITE_REF(i); }
233  inline void write(bool i) throw(PersistException) { CCXX_ENGINEWRITE_REF(i); }
234 #undef CCXX_ENGINEWRITE_REF
235 
236  void write(const std::string& str) throw(PersistException);
237 
238  // Every write operation boils down to one or more of these
239  void writeBinary(const uint8_t* data, const uint32_t size) throw(PersistException);
240 
241  // Read Operations
242 
246  void read(PersistObject &object) throw(PersistException);
247 
251  void read(PersistObject *&object) throw(PersistException);
252 
253  // reads supported primitive types
254  // shortcut, to make the following more readable
255 #define CCXX_ENGINEREAD_REF(valref) readBinary((uint8_t*)&valref,sizeof(valref))
256  inline void read(int8_t& i) throw(PersistException) { CCXX_ENGINEREAD_REF(i); }
257  inline void read(uint8_t& i) throw(PersistException) { CCXX_ENGINEREAD_REF(i); }
258  inline void read(int16_t& i) throw(PersistException) { CCXX_ENGINEREAD_REF(i); }
259  inline void read(uint16_t& i) throw(PersistException) { CCXX_ENGINEREAD_REF(i); }
260  inline void read(int32_t& i) throw(PersistException) { CCXX_ENGINEREAD_REF(i); }
261  inline void read(uint32_t& i) throw(PersistException) { CCXX_ENGINEREAD_REF(i); }
262  inline void read(float& i) throw(PersistException) { CCXX_ENGINEREAD_REF(i); }
263  inline void read(double& i) throw(PersistException) { CCXX_ENGINEREAD_REF(i); }
264  inline void read(bool &i) throw(PersistException) { CCXX_ENGINEREAD_REF(i); }
265 #undef CCXX_ENGINEREAD_REF
266 
267  void read(std::string& str) throw(PersistException);
268 
269  // Every read operation boiled down to one or more of these
270  void readBinary(uint8_t* data, uint32_t size) throw(PersistException);
271 
272 private:
277  void readObject(PersistObject* object) throw(PersistException);
278 
282  const std::string readClass() throw(PersistException);
283 
284 
288  std::iostream& myUnderlyingStream;
289 
293  EngineMode myOperationalMode;
294 
298  typedef std::vector<PersistObject*> ArchiveVector;
299  typedef std::map<PersistObject const*, int32_t> ArchiveMap;
300  typedef std::vector<std::string> ClassVector;
301  typedef std::map<std::string, int32_t> ClassMap;
302 
303  ArchiveVector myArchiveVector;
304  ArchiveMap myArchiveMap;
305  ClassVector myClassVector;
306  ClassMap myClassMap;
307 };
308 
309 #define CCXX_RE(ar,ob) ar.read(ob); return ar
310 #define CCXX_WE(ar,ob) ar.write(ob); return ar
311 
312 // Standard >> and << stream operators for PersistObject
314 inline PersistEngine& operator >>( PersistEngine& ar, PersistObject &ob) throw(PersistException) {CCXX_RE(ar,ob);}
316 inline PersistEngine& operator >>( PersistEngine& ar, PersistObject *&ob) throw(PersistException) {CCXX_RE(ar,ob);}
318 inline PersistEngine& operator <<( PersistEngine& ar, PersistObject const &ob) throw(PersistException) {CCXX_WE(ar,ob);}
320 inline PersistEngine& operator <<( PersistEngine& ar, PersistObject const *ob) throw(PersistException) {CCXX_WE(ar,ob);}
321 
323 inline PersistEngine& operator >>( PersistEngine& ar, int8_t& ob) throw(PersistException) {CCXX_RE(ar,ob);}
325 inline PersistEngine& operator <<( PersistEngine& ar, int8_t ob) throw(PersistException) {CCXX_WE(ar,ob);}
326 
328 inline PersistEngine& operator >>( PersistEngine& ar, uint8_t& ob) throw(PersistException) {CCXX_RE(ar,ob);}
330 inline PersistEngine& operator <<( PersistEngine& ar, uint8_t ob) throw(PersistException) {CCXX_WE(ar,ob);}
331 
333 inline PersistEngine& operator >>( PersistEngine& ar, int16_t& ob) throw(PersistException) {CCXX_RE(ar,ob);}
335 inline PersistEngine& operator <<( PersistEngine& ar, int16_t ob) throw(PersistException) {CCXX_WE(ar,ob);}
336 
338 inline PersistEngine& operator >>( PersistEngine& ar, uint16_t& ob) throw(PersistException) {CCXX_RE(ar,ob);}
340 inline PersistEngine& operator <<( PersistEngine& ar, uint16_t ob) throw(PersistException) {CCXX_WE(ar,ob);}
341 
343 inline PersistEngine& operator >>( PersistEngine& ar, int32_t& ob) throw(PersistException) {CCXX_RE(ar,ob);}
345 inline PersistEngine& operator <<( PersistEngine& ar, int32_t ob) throw(PersistException) {CCXX_WE(ar,ob);}
346 
348 inline PersistEngine& operator >>( PersistEngine& ar, uint32_t& ob) throw(PersistException) {CCXX_RE(ar,ob);}
350 inline PersistEngine& operator <<( PersistEngine& ar, uint32_t ob) throw(PersistException) {CCXX_WE(ar,ob);}
351 
353 inline PersistEngine& operator >>( PersistEngine& ar, float& ob) throw(PersistException) {CCXX_RE(ar,ob);}
355 inline PersistEngine& operator <<( PersistEngine& ar, float ob) throw(PersistException) {CCXX_WE(ar,ob);}
356 
358 inline PersistEngine& operator >>( PersistEngine& ar, double& ob) throw(PersistException) {CCXX_RE(ar,ob);}
360 inline PersistEngine& operator <<( PersistEngine& ar, double ob) throw(PersistException) {CCXX_WE(ar,ob);}
361 
363 inline PersistEngine& operator >>( PersistEngine& ar, std::string& ob) throw(PersistException) {CCXX_RE(ar,ob);}
365 inline PersistEngine& operator <<( PersistEngine& ar, std::string ob) throw(PersistException) {CCXX_WE(ar,ob);}
366 
368 inline PersistEngine& operator >>( PersistEngine& ar, bool& ob) throw(PersistException) {CCXX_RE(ar,ob);}
370 inline PersistEngine& operator <<( PersistEngine& ar, bool ob) throw(PersistException) {CCXX_WE(ar,ob);}
371 
372 #undef CCXX_RE
373 #undef CCXX_WE
374 
384 template<class T>
385 PersistEngine& operator <<( PersistEngine& ar, typename std::vector<T> const& ob) throw(PersistException)
386 {
387  ar << (uint32_t)ob.size();
388  for(unsigned int i=0; i < ob.size(); ++i)
389  ar << ob[i];
390  return ar;
391 }
392 
398 template<class T>
399 PersistEngine& operator >>( PersistEngine& ar, typename std::vector<T>& ob) throw(PersistException)
400 {
401  ob.clear();
402  uint32_t siz;
403  ar >> siz;
404  ob.resize(siz);
405  for(uint32_t i=0; i < siz; ++i)
406  ar >> ob[i];
407  return ar;
408 }
409 
415 template<class T>
416 PersistEngine& operator <<( PersistEngine& ar, typename std::deque<T> const& ob) throw(PersistException)
417 {
418  ar << (uint32_t)ob.size();
419  for(typename std::deque<T>::const_iterator it=ob.begin(); it != ob.end(); ++it)
420  ar << *it;
421  return ar;
422 }
423 
429 template<class T>
430 PersistEngine& operator >>( PersistEngine& ar, typename std::deque<T>& ob) throw(PersistException)
431 {
432  ob.clear();
433  uint32_t siz;
434  ar >> siz;
435  //ob.resize(siz);
436  for(uint32_t i=0; i < siz; ++i) {
437  T node;
438  ar >> node;
439  ob.push_back(node);
440  //ar >> ob[i];
441  }
442  return ar;
443 }
444 
450 template<class Key, class Value>
451 PersistEngine& operator <<( PersistEngine& ar, typename std::map<Key,Value> const & ob) throw(PersistException)
452 {
453  ar << (uint32_t)ob.size();
454  for(typename std::map<Key,Value>::const_iterator it = ob.begin();it != ob.end();++it)
455  ar << it->first << it->second;
456  return ar;
457 }
458 
464 template<class Key, class Value>
465 PersistEngine& operator >>( PersistEngine& ar, typename std::map<Key,Value>& ob) throw(PersistException)
466 {
467  ob.clear();
468  uint32_t siz;
469  ar >> siz;
470  for(uint32_t i=0; i < siz; ++i) {
471  Key a;
472  ar >> a;
473  ar >> ob[a];
474  }
475  return ar;
476 }
477 
482 template<class x, class y>
483 PersistEngine& operator <<( PersistEngine& ar, std::pair<x,y> &ob) throw(PersistException)
484 {
485  ar << ob.first << ob.second;
486  return ar;
487 }
488 
493 template<class x, class y>
494 PersistEngine& operator >>(PersistEngine& ar, std::pair<x, y> &ob) throw(PersistException)
495 {
496  ar >> ob.first >> ob.second;
497  return ar;
498 }
499 
500 } // namespace ucommon
501 
502 #endif
503 #endif
504 #endif
EngineMode
These are the modes the Persistence::Engine can work in.
Definition: persist.h:195
This manages a registration to the typemanager - attempting to remove problems with the optimizers...
Definition: persist.h:70
Stream serialization of persistent classes.
Definition: persist.h:189
Common namespace for all ucommon objects.
Definition: access.h:46
Type manager for persistence engine.
Definition: persist.h:63
void write(const PersistObject &object)
writes a PersistObject from a reference.
Definition: persist.h:214
Various miscellaneous platform specific headers and defines.
PersistObject.
Definition: persist.h:146