UCommon
persist.h
1// Copyright (C) 2006-2014 David Sugar, Tycho Softworks.
2// Copyright (C) 2015 Cherokees of Idaho.
3//
4// This file is part of GNU uCommon C++.
5//
6// GNU uCommon C++ is free software: you can redistribute it and/or modify
7// it under the terms of the GNU Lesser General Public License as published
8// by the Free Software Foundation, either version 3 of the License, or
9// (at your option) any later version.
10//
11// GNU uCommon C++ is distributed in the hope that it will be useful,
12// but WITHOUT ANY WARRANTY; without even the implied warranty of
13// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14// GNU Lesser General Public License for more details.
15//
16// You should have received a copy of the GNU Lesser General Public License
17// along with GNU uCommon C++. If not, see <http://www.gnu.org/licenses/>.
18
24#ifndef UCOMMON_SYSRUNTIME
25#ifndef COMMONCPP_PERSIST_H_
26#define COMMONCPP_PERSIST_H_
27
28#ifndef COMMONCPP_CONFIG_H_
29#include <commoncpp/config.h>
30#endif
31
32#include <iostream>
33#include <string>
34#include <vector>
35#include <deque>
36#include <map>
37
38namespace ost {
39
40// This typedef allows us to declare NewPersistObjectFunction now
41typedef class PersistObject* (*NewPersistObjectFunction) (void);
42
43class __EXPORT PersistException
44{
45public:
46 PersistException(const std::string& reason);
47 const std::string& getString() const;
48
49 virtual ~PersistException() throw();
50
51protected:
52 std::string _what;
53};
54
63class __EXPORT TypeManager
64{
65private:
66 __DELETE_DEFAULTS(TypeManager);
67
68public:
74 {
75 public:
76 registration(const char* name, NewPersistObjectFunction func);
77 virtual ~registration();
78 private:
79 __DELETE_COPY(registration);
80
81 std::string myName;
82 };
83
87 static void add(const char* name, NewPersistObjectFunction construction);
88
92 static void remove(const char* name);
93
99 static PersistObject* createInstanceOf(const char* name);
100
101 typedef std::map<std::string,NewPersistObjectFunction> StringFunctionMap;
102};
103
104/*
105 * The following defines are used to declare and define the relevant code
106 * to allow a class to use the Persistence::Engine code.
107 */
108
109#define DECLARE_PERSISTENCE(ClassType) \
110 public: \
111 friend ucommon::PersistEngine& operator>>( ucommon::PersistEngine& ar, ClassType *&ob); \
112 friend ucommon::PersistEngine& operator<<( ucommon::PersistEngine& ar, ClassType const &ob); \
113 friend ucommon::PersistObject *createNew##ClassType(); \
114 virtual const char* getPersistenceID() const; \
115 static ucommon::TypeManager::Registration registrationFor##ClassType;
116
117#define IMPLEMENT_PERSISTENCE(ClassType, FullyQualifiedName) \
118 ucommon::PersistObject *createNew##ClassType() { return new ClassType; } \
119 const char* ClassType::getPersistenceID() const {return FullyQualifiedName;} \
120 ucommon::PersistEngine& operator>>(ucommon::PersistEngine& ar, ClassType &ob) \
121 { ar >> (ucommon::PersistObject &) ob; return ar; } \
122 ucommon::PersistEngine& operator>>(ucommon::PersistEngine& ar, ClassType *&ob) \
123 { ar >> (ucommon::PersistObject *&) ob; return ar; } \
124 ucommon::PersistEngine& operator<<(ucommon::PersistEngine& ar, ClassType const &ob) \
125 { ar << (ucommon::PersistObject const *)&ob; return ar; } \
126 ucommon::TypeManager::Registration \
127 ClassType::registrationFor##ClassType(FullyQualifiedName, \
128 createNew##ClassType);
129
130class PersistEngine;
131
151class __EXPORT PersistObject
152{
153public:
160
164 virtual ~PersistObject();
165
169 virtual const char* getPersistenceID() const;
170
176 virtual bool write(PersistEngine& archive) const;
177
183 virtual bool read(PersistEngine& archive);
184};
185
194class __EXPORT PersistEngine
195{
196private:
197 __DELETE_COPY(PersistEngine);
198
199public:
204 modeRead,
205 modeWrite
206 };
207
213 PersistEngine(std::iostream& stream, EngineMode mode) throw(PersistException);
214
215 virtual ~PersistEngine();
216
217 // Write operations
218
222 inline void write(const PersistObject &object) throw(PersistException)
223 {write(&object);}
224
228 void write(const PersistObject *object) throw(PersistException);
229
230 // writes supported primitive types
231 // shortcut, to make the following more readable
232#define CCXX_ENGINEWRITE_REF(valref) writeBinary((const uint8_t*)&valref,sizeof(valref))
233 inline void write(int8_t i) throw(PersistException) { CCXX_ENGINEWRITE_REF(i); }
234 inline void write(uint8_t i) throw(PersistException) { CCXX_ENGINEWRITE_REF(i); }
235 inline void write(int16_t i) throw(PersistException) { CCXX_ENGINEWRITE_REF(i); }
236 inline void write(uint16_t i) throw(PersistException) { CCXX_ENGINEWRITE_REF(i); }
237 inline void write(int32_t i) throw(PersistException) { CCXX_ENGINEWRITE_REF(i); }
238 inline void write(uint32_t i) throw(PersistException) { CCXX_ENGINEWRITE_REF(i); }
239 inline void write(float i) throw(PersistException) { CCXX_ENGINEWRITE_REF(i); }
240 inline void write(double i) throw(PersistException) { CCXX_ENGINEWRITE_REF(i); }
241 inline void write(bool i) throw(PersistException) { CCXX_ENGINEWRITE_REF(i); }
242#undef CCXX_ENGINEWRITE_REF
243
244 void write(const std::string& str) throw(PersistException);
245
246 // Every write operation boils down to one or more of these
247 void writeBinary(const uint8_t* data, const uint32_t size) throw(PersistException);
248
249 // Read Operations
250
254 void read(PersistObject &object) throw(PersistException);
255
259 void read(PersistObject *&object) throw(PersistException);
260
261 // reads supported primitive types
262 // shortcut, to make the following more readable
263#define CCXX_ENGINEREAD_REF(valref) readBinary((uint8_t*)&valref,sizeof(valref))
264 inline void read(int8_t& i) throw(PersistException) { CCXX_ENGINEREAD_REF(i); }
265 inline void read(uint8_t& i) throw(PersistException) { CCXX_ENGINEREAD_REF(i); }
266 inline void read(int16_t& i) throw(PersistException) { CCXX_ENGINEREAD_REF(i); }
267 inline void read(uint16_t& i) throw(PersistException) { CCXX_ENGINEREAD_REF(i); }
268 inline void read(int32_t& i) throw(PersistException) { CCXX_ENGINEREAD_REF(i); }
269 inline void read(uint32_t& i) throw(PersistException) { CCXX_ENGINEREAD_REF(i); }
270 inline void read(float& i) throw(PersistException) { CCXX_ENGINEREAD_REF(i); }
271 inline void read(double& i) throw(PersistException) { CCXX_ENGINEREAD_REF(i); }
272 inline void read(bool &i) throw(PersistException) { CCXX_ENGINEREAD_REF(i); }
273#undef CCXX_ENGINEREAD_REF
274
275 void read(std::string& str) throw(PersistException);
276
277 // Every read operation boiled down to one or more of these
278 void readBinary(uint8_t* data, uint32_t size) throw(PersistException);
279
280private:
285 void readObject(PersistObject* object) throw(PersistException);
286
290 const std::string readClass() throw(PersistException);
291
292
296 std::iostream& myUnderlyingStream;
297
301 EngineMode myOperationalMode;
302
306 typedef std::vector<PersistObject*> ArchiveVector;
307 typedef std::map<PersistObject const*, int32_t> ArchiveMap;
308 typedef std::vector<std::string> ClassVector;
309 typedef std::map<std::string, int32_t> ClassMap;
310
311 ArchiveVector myArchiveVector;
312 ArchiveMap myArchiveMap;
313 ClassVector myClassVector;
314 ClassMap myClassMap;
315};
316
317#define CCXX_RE(ar,ob) ar.read(ob); return ar
318#define CCXX_WE(ar,ob) ar.write(ob); return ar
319
320// Standard >> and << stream operators for PersistObject
322inline PersistEngine& operator >>( PersistEngine& ar, PersistObject &ob) throw(PersistException) {CCXX_RE(ar,ob);}
324inline PersistEngine& operator >>( PersistEngine& ar, PersistObject *&ob) throw(PersistException) {CCXX_RE(ar,ob);}
326inline PersistEngine& operator <<( PersistEngine& ar, PersistObject const &ob) throw(PersistException) {CCXX_WE(ar,ob);}
328inline PersistEngine& operator <<( PersistEngine& ar, PersistObject const *ob) throw(PersistException) {CCXX_WE(ar,ob);}
329
331inline PersistEngine& operator >>( PersistEngine& ar, int8_t& ob) throw(PersistException) {CCXX_RE(ar,ob);}
333inline PersistEngine& operator <<( PersistEngine& ar, int8_t ob) throw(PersistException) {CCXX_WE(ar,ob);}
334
336inline PersistEngine& operator >>( PersistEngine& ar, uint8_t& ob) throw(PersistException) {CCXX_RE(ar,ob);}
338inline PersistEngine& operator <<( PersistEngine& ar, uint8_t ob) throw(PersistException) {CCXX_WE(ar,ob);}
339
341inline PersistEngine& operator >>( PersistEngine& ar, int16_t& ob) throw(PersistException) {CCXX_RE(ar,ob);}
343inline PersistEngine& operator <<( PersistEngine& ar, int16_t ob) throw(PersistException) {CCXX_WE(ar,ob);}
344
346inline PersistEngine& operator >>( PersistEngine& ar, uint16_t& ob) throw(PersistException) {CCXX_RE(ar,ob);}
348inline PersistEngine& operator <<( PersistEngine& ar, uint16_t ob) throw(PersistException) {CCXX_WE(ar,ob);}
349
351inline PersistEngine& operator >>( PersistEngine& ar, int32_t& ob) throw(PersistException) {CCXX_RE(ar,ob);}
353inline PersistEngine& operator <<( PersistEngine& ar, int32_t ob) throw(PersistException) {CCXX_WE(ar,ob);}
354
356inline PersistEngine& operator >>( PersistEngine& ar, uint32_t& ob) throw(PersistException) {CCXX_RE(ar,ob);}
358inline PersistEngine& operator <<( PersistEngine& ar, uint32_t ob) throw(PersistException) {CCXX_WE(ar,ob);}
359
361inline PersistEngine& operator >>( PersistEngine& ar, float& ob) throw(PersistException) {CCXX_RE(ar,ob);}
363inline PersistEngine& operator <<( PersistEngine& ar, float ob) throw(PersistException) {CCXX_WE(ar,ob);}
364
366inline PersistEngine& operator >>( PersistEngine& ar, double& ob) throw(PersistException) {CCXX_RE(ar,ob);}
368inline PersistEngine& operator <<( PersistEngine& ar, double ob) throw(PersistException) {CCXX_WE(ar,ob);}
369
371inline PersistEngine& operator >>( PersistEngine& ar, std::string& ob) throw(PersistException) {CCXX_RE(ar,ob);}
373inline PersistEngine& operator <<( PersistEngine& ar, std::string ob) throw(PersistException) {CCXX_WE(ar,ob);}
374
376inline PersistEngine& operator >>( PersistEngine& ar, bool& ob) throw(PersistException) {CCXX_RE(ar,ob);}
378inline PersistEngine& operator <<( PersistEngine& ar, bool ob) throw(PersistException) {CCXX_WE(ar,ob);}
379
380#undef CCXX_RE
381#undef CCXX_WE
382
392template<class T>
393PersistEngine& operator <<( PersistEngine& ar, typename std::vector<T> const& ob) throw(PersistException)
394{
395 ar << (uint32_t)ob.size();
396 for(unsigned int i=0; i < ob.size(); ++i)
397 ar << ob[i];
398 return ar;
399}
400
406template<class T>
407PersistEngine& operator >>( PersistEngine& ar, typename std::vector<T>& ob) throw(PersistException)
408{
409 ob.clear();
410 uint32_t siz;
411 ar >> siz;
412 ob.resize(siz);
413 for(uint32_t i=0; i < siz; ++i)
414 ar >> ob[i];
415 return ar;
416}
417
423template<class T>
424PersistEngine& operator <<( PersistEngine& ar, typename std::deque<T> const& ob) throw(PersistException)
425{
426 ar << (uint32_t)ob.size();
427 for(typename std::deque<T>::const_iterator it=ob.begin(); it != ob.end(); ++it)
428 ar << *it;
429 return ar;
430}
431
437template<class T>
438PersistEngine& operator >>( PersistEngine& ar, typename std::deque<T>& ob) throw(PersistException)
439{
440 ob.clear();
441 uint32_t siz;
442 ar >> siz;
443 //ob.resize(siz);
444 for(uint32_t i=0; i < siz; ++i) {
445 T node;
446 ar >> node;
447 ob.push_back(node);
448 //ar >> ob[i];
449 }
450 return ar;
451}
452
458template<class Key, class Value>
459PersistEngine& operator <<( PersistEngine& ar, typename std::map<Key,Value> const & ob) throw(PersistException)
460{
461 ar << (uint32_t)ob.size();
462 for(typename std::map<Key,Value>::const_iterator it = ob.begin();it != ob.end();++it)
463 ar << it->first << it->second;
464 return ar;
465}
466
472template<class Key, class Value>
473PersistEngine& operator >>( PersistEngine& ar, typename std::map<Key,Value>& ob) throw(PersistException)
474{
475 ob.clear();
476 uint32_t siz;
477 ar >> siz;
478 for(uint32_t i=0; i < siz; ++i) {
479 Key a;
480 ar >> a;
481 ar >> ob[a];
482 }
483 return ar;
484}
485
490template<class x, class y>
491PersistEngine& operator <<( PersistEngine& ar, std::pair<x,y> &ob) throw(PersistException)
492{
493 ar << ob.first << ob.second;
494 return ar;
495}
496
501template<class x, class y>
502PersistEngine& operator >>(PersistEngine& ar, std::pair<x, y> &ob) throw(PersistException)
503{
504 ar >> ob.first >> ob.second;
505 return ar;
506}
507
508} // namespace ucommon
509
510#endif
511#endif
Type manager for persistence engine.
Definition persist.h:64
static void add(const char *name, NewPersistObjectFunction construction)
This adds a new construction function to the type manager.
static PersistObject * createInstanceOf(const char *name)
This function creates a new object of the required type and returns a pointer to it.
static void remove(const char *name)
And this one removes a type from the managers lists.
This manages a registration to the typemanager - attempting to remove problems with the optimizers.
Definition persist.h:74
PersistObject.
Definition persist.h:152
PersistObject()
This constructor is used in serialization processes.
virtual bool write(PersistEngine &archive) const
This method is used to write to the Persistence::Engine It is not equivalent to the << operator as it...
virtual ~PersistObject()
Default destructor.
virtual bool read(PersistEngine &archive)
This method is used to read from a Persistence::Engine It is not equivalent to the >> operator as it ...
virtual const char * getPersistenceID() const
This returns the ID of the persistent object (Its type)
Stream serialization of persistent classes.
Definition persist.h:195
EngineMode
These are the modes the Persistence::Engine can work in.
Definition persist.h:203
void read(PersistObject *&object)
reads a PersistObject into a pointer allocating memory for the object if necessary.
void write(const PersistObject &object)
writes a PersistObject from a reference.
Definition persist.h:222
PersistEngine(std::iostream &stream, EngineMode mode)
Constructs a Persistence::Engine with the specified stream in the given mode.
void write(const PersistObject *object)
writes a PersistObject from a pointer.
void read(PersistObject &object)
reads a PersistObject into a reference overwriting the object.