GNU CommonC++
persist.h
Go to the documentation of this file.
1 // Copyright (C) 1999-2005 Open Source Telecom Corporation.
2 //
3 // This program is free software; you can redistribute it and/or modify
4 // it under the terms of the GNU General Public License as published by
5 // the Free Software Foundation; either version 2 of the License, or
6 // (at your option) any later version.
7 //
8 // This program 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
11 // GNU General Public License for more details.
12 //
13 // You should have received a copy of the GNU General Public License
14 // along with this program; if not, write to the Free Software
15 // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
16 //
17 // As a special exception, you may use this file as part of a free software
18 // library without restriction. Specifically, if other files instantiate
19 // templates or use macros or inline functions from this file, or you compile
20 // this file and link it with other files to produce an executable, this
21 // file does not by itself cause the resulting executable to be covered by
22 // the GNU General Public License. This exception does not however
23 // invalidate any other reasons why the executable file might be covered by
24 // the GNU General Public License.
25 //
26 // This exception applies only to the code released under the name GNU
27 // Common C++. If you copy code from other releases into a copy of GNU
28 // Common C++, as the General Public License permits, the exception does
29 // not apply to the code that you add in this way. To avoid misleading
30 // anyone as to the status of such modified files, you must delete
31 // this exception notice from them.
32 //
33 // If you write modifications of your own for GNU Common C++, it is your choice
34 // whether to permit this exception to apply to your modifications.
35 // If you do not wish that, delete this exception notice.
36 //
37 
43 #ifndef CCXX_PERSIST_H_
44 #define CCXX_PERSIST_H_
45 
46 #ifndef CCXX_CONFIG_H_
47 #include <cc++/config.h>
48 #endif
49 
50 #ifndef CCXX_EXCEPTIONS_H_
51 #include <cc++/exception.h>
52 #endif
53 
54 #ifndef CCXX_MISSING_H_
55 #include <cc++/missing.h>
56 #endif
57 
58 #ifndef CCXX_STRING_H_
59 #include <cc++/string.h>
60 #endif
61 
62 #ifdef HAVE_ZLIB_H
63 #ifndef NO_COMPRESSION
64 #include <zlib.h>
65 #endif
66 #else
67 #define NO_COMPRESSION
68 #endif
69 
70 #include <iostream>
71 #include <string>
72 #include <vector>
73 #include <deque>
74 #include <map>
75 
76 #ifdef CCXX_NAMESPACES
77 namespace ost {
78 #define NS_PREFIX ost::
79 #else
80 #define NS_PREFIX
81 #endif
82 
83 #ifdef CCXX_EXCEPTIONS
84 #ifdef COMMON_STD_EXCEPTION
85 
86 class __EXPORT PersistException : public Exception
87 {
88 public:
89  PersistException(const String &what) : Exception(what) {};
90 };
91 
92 #else
93 
94 class __EXPORT PersistException
95 {
96 public:
97  PersistException(const String& reason);
98  inline const String& getString() const
99  {return Exception::getString();};
100 
101  virtual ~PersistException() {} throw();
102 protected:
103  String _what;
104 };
105 
106 #endif
107 #endif
108 
109 // This typedef allows us to declare NewBaseObjectFunction now
110 typedef class BaseObject* (*NewBaseObjectFunction) (void);
111 
121 {
122 public:
123 
129  {
130  public:
131  Registration(const char* name, NewBaseObjectFunction func);
132  virtual ~Registration();
133  private:
134  String myName;
135  };
136 
140  static void add(const char* name, NewBaseObjectFunction construction);
141 
145  static void remove(const char* name);
146 
152  static BaseObject* createInstanceOf(const char* name);
153 
154  typedef std::map<String,NewBaseObjectFunction> StringFunctionMap;
155 };
156 
157 
158 /*
159  * The following defines are used to declare and define the relevant code
160  * to allow a class to use the Persistence::Engine code.
161  */
162 
163 #define DECLARE_PERSISTENCE(ClassType) \
164  public: \
165  friend NS_PREFIX Engine& operator>>( NS_PREFIX Engine& ar, ClassType *&ob); \
166  friend NS_PREFIX Engine& operator<<( NS_PREFIX Engine& ar, ClassType const &ob); \
167  friend NS_PREFIX BaseObject *createNew##ClassType(); \
168  virtual const char* getPersistenceID() const; \
169  static NS_PREFIX TypeManager::Registration registrationFor##ClassType;
170 
171 #define IMPLEMENT_PERSISTENCE(ClassType, FullyQualifiedName) \
172  NS_PREFIX BaseObject *createNew##ClassType() { return new ClassType; } \
173  const char* ClassType::getPersistenceID() const {return FullyQualifiedName;} \
174  NS_PREFIX Engine& operator>>(NS_PREFIX Engine& ar, ClassType &ob) \
175  { ar >> (NS_PREFIX BaseObject &) ob; return ar; } \
176  NS_PREFIX Engine& operator>>(NS_PREFIX Engine& ar, ClassType *&ob) \
177  { ar >> (NS_PREFIX BaseObject *&) ob; return ar; } \
178  NS_PREFIX Engine& operator<<(NS_PREFIX Engine& ar, ClassType const &ob) \
179  { ar << (NS_PREFIX BaseObject const *)&ob; return ar; } \
180  NS_PREFIX TypeManager::Registration \
181  ClassType::registrationFor##ClassType(FullyQualifiedName, \
182  createNew##ClassType);
183 
184 class Engine;
185 
206 {
207 public:
213  BaseObject();
214 
218  virtual ~BaseObject();
219 
223  virtual const char* getPersistenceID() const;
224 
230  virtual bool write(Engine& archive) const;
231 
237  virtual bool read(Engine& archive);
238 };
239 
240 
252 {
253 public:
257  enum EngineMode {
259  modeWrite
260  };
261 
267  Engine(std::iostream& stream, EngineMode mode) THROWS (PersistException);
268 
273  void sync();
274 
275  virtual ~Engine();
276 
277 
278  // Write operations
279 
283  void write(const BaseObject &object) THROWS (PersistException)
284  { write(&object); };
285 
289  void write(const BaseObject *object) THROWS (PersistException);
290 
291  // writes supported primitive types
292  // shortcut, to make the following more readable
293 #define CCXX_ENGINEWRITE_REF(valref) writeBinary((const uint8*)&valref,sizeof(valref))
294  void write(int8 i) THROWS (PersistException) { CCXX_ENGINEWRITE_REF(i); }
295  void write(uint8 i) THROWS (PersistException) { CCXX_ENGINEWRITE_REF(i); }
296  void write(int16 i) THROWS (PersistException) { CCXX_ENGINEWRITE_REF(i); }
297  void write(uint16 i) THROWS (PersistException) { CCXX_ENGINEWRITE_REF(i); }
298  void write(int32 i) THROWS (PersistException) { CCXX_ENGINEWRITE_REF(i); }
299  void write(uint32 i) THROWS (PersistException) { CCXX_ENGINEWRITE_REF(i); }
300 #ifdef HAVE_64_BITS
301  void write(int64 i) THROWS (PersistException) { CCXX_ENGINEWRITE_REF(i); }
302  void write(uint64 i) THROWS (PersistException) { CCXX_ENGINEWRITE_REF(i); }
303 #endif
304  void write(float i) THROWS (PersistException) { CCXX_ENGINEWRITE_REF(i); }
305  void write(double i) THROWS (PersistException) { CCXX_ENGINEWRITE_REF(i); }
306 #undef CCXX_ENGINEWRITE_REF
307 
308  void write(const String& str) THROWS (PersistException);
309  void write(const std::string& str) THROWS (PersistException);
310 
311  // Every write operation boils down to one or more of these
312  void writeBinary(const uint8* data, const uint32 size) THROWS (PersistException);
313 
314 
315  // Read Operations
316 
320  void read(BaseObject &object) THROWS (PersistException);
321 
325  void read(BaseObject *&object) THROWS (PersistException);
326 
327  // reads supported primitive types
328  // shortcut, to make the following more readable
329 #define CCXX_ENGINEREAD_REF(valref) readBinary((uint8*)&valref,sizeof(valref))
330  void read(int8& i) THROWS (PersistException) { CCXX_ENGINEREAD_REF(i); }
331  void read(uint8& i) THROWS (PersistException) { CCXX_ENGINEREAD_REF(i); }
332  void read(int16& i) THROWS (PersistException) { CCXX_ENGINEREAD_REF(i); }
333  void read(uint16& i) THROWS (PersistException) { CCXX_ENGINEREAD_REF(i); }
334  void read(int32& i) THROWS (PersistException) { CCXX_ENGINEREAD_REF(i); }
335  void read(uint32& i) THROWS (PersistException) { CCXX_ENGINEREAD_REF(i); }
336 #ifdef HAVE_64_BITS
337  void read(int64& i) THROWS (PersistException) { CCXX_ENGINEREAD_REF(i); }
338  void read(uint64& i) THROWS (PersistException) { CCXX_ENGINEREAD_REF(i); }
339 #endif
340  void read(float& i) THROWS (PersistException) { CCXX_ENGINEREAD_REF(i); }
341  void read(double& i) THROWS (PersistException) { CCXX_ENGINEREAD_REF(i); }
342 #undef CCXX_ENGINEREAD_REF
343 
344  void read(String& str) THROWS (PersistException);
345  void read(std::string& str) THROWS (PersistException);
346 
347  // Every read operation boild down to one or more of these
348  void readBinary(uint8* data, uint32 size) THROWS (PersistException);
349 
350 private:
355  void readObject(BaseObject* object) THROWS (PersistException);
356 
360  const String readClass() THROWS (PersistException);
361 
362 
366  std::iostream& myUnderlyingStream;
367 
371  EngineMode myOperationalMode;
372 
376  typedef std::vector<BaseObject*> ArchiveVector;
377  typedef std::map<BaseObject const*, int32> ArchiveMap;
378  typedef std::vector<String> ClassVector;
379  typedef std::map<String, int32> ClassMap;
380 
381  ArchiveVector myArchiveVector;
382  ArchiveMap myArchiveMap;
383  ClassVector myClassVector;
384  ClassMap myClassMap;
385 
386  // Compression support
387 #ifndef NO_COMPRESSION
388  z_stream myZStream;
389  uint8* myCompressedDataBuffer;
390  uint8* myUncompressedDataBuffer;
391  uint8* myLastUncompressedDataRead;
392 #endif
393 };
394 
395 // Standard >> and << stream operators for BaseObject
397 __EXPORT Engine& operator >>( Engine& ar, BaseObject &ob) THROWS (PersistException);
399 __EXPORT Engine& operator >>( Engine& ar, BaseObject *&ob) THROWS (PersistException);
401 __EXPORT Engine& operator <<( Engine& ar, BaseObject const &ob) THROWS (PersistException);
403 __EXPORT Engine& operator <<( Engine& ar, BaseObject const *ob) THROWS (PersistException);
404 
406 __EXPORT Engine& operator >>( Engine& ar, int8& ob) THROWS (PersistException);
408 __EXPORT Engine& operator <<( Engine& ar, int8 ob) THROWS (PersistException);
409 
411 __EXPORT Engine& operator >>( Engine& ar, uint8& ob) THROWS (PersistException);
413 __EXPORT Engine& operator <<( Engine& ar, uint8 ob) THROWS (PersistException);
414 
416 __EXPORT Engine& operator >>( Engine& ar, int16& ob) THROWS (PersistException);
418 __EXPORT Engine& operator <<( Engine& ar, int16 ob) THROWS (PersistException);
419 
421 __EXPORT Engine& operator >>( Engine& ar, uint16& ob) THROWS (PersistException);
423 __EXPORT Engine& operator <<( Engine& ar, uint16 ob) THROWS (PersistException);
424 
426 __EXPORT Engine& operator >>( Engine& ar, int32& ob) THROWS (PersistException);
428 __EXPORT Engine& operator <<( Engine& ar, int32 ob) THROWS (PersistException);
429 
431 __EXPORT Engine& operator >>( Engine& ar, uint32& ob) THROWS (PersistException);
433 __EXPORT Engine& operator <<( Engine& ar, uint32 ob) THROWS (PersistException);
434 
435 #ifdef HAVE_64_BITS
436 
437 __EXPORT Engine& operator >>( Engine& ar, int64& ob) THROWS (PersistException);
439 __EXPORT Engine& operator <<( Engine& ar, int64 ob) THROWS (PersistException);
440 
442 __EXPORT Engine& operator >>( Engine& ar, uint64& ob) THROWS (PersistException);
444 __EXPORT Engine& operator <<( Engine& ar, uint64 ob) THROWS (PersistException);
445 #endif
446 
448 __EXPORT Engine& operator >>( Engine& ar, float& ob) THROWS (PersistException);
450 __EXPORT Engine& operator <<( Engine& ar, float ob) THROWS (PersistException);
451 
453 __EXPORT Engine& operator >>( Engine& ar, double& ob) THROWS (PersistException);
455 __EXPORT Engine& operator <<( Engine& ar, double ob) THROWS (PersistException);
456 
458 __EXPORT Engine& operator >>( Engine& ar, String& ob) THROWS (PersistException);
460 __EXPORT Engine& operator <<( Engine& ar, String ob) THROWS (PersistException);
461 
463 __EXPORT Engine& operator >>( Engine& ar, std::string& ob) THROWS (PersistException);
465 __EXPORT Engine& operator <<( Engine& ar, std::string ob) THROWS (PersistException);
466 
468 __EXPORT Engine& operator >>( Engine& ar, bool& ob) THROWS (PersistException);
470 __EXPORT Engine& operator <<( Engine& ar, bool ob) THROWS (PersistException);
471 
481 template<class T>
482 Engine& operator <<( Engine& ar, typename std::vector<T> const& ob) THROWS (PersistException)
483 {
484  ar << (uint32)ob.size();
485  for(unsigned int i=0; i < ob.size(); ++i)
486  ar << ob[i];
487  return ar;
488 }
489 
495 template<class T>
496 Engine& operator >>( Engine& ar, typename std::vector<T>& ob) THROWS (PersistException)
497 {
498  ob.clear();
499  uint32 siz;
500  ar >> siz;
501  ob.resize(siz);
502  for(uint32 i=0; i < siz; ++i)
503  ar >> ob[i];
504  return ar;
505 }
506 
512 template<class T>
513 Engine& operator <<( Engine& ar, typename std::deque<T> const& ob) THROWS (PersistException)
514 {
515  ar << (uint32)ob.size();
516  for(typename std::deque<T>::const_iterator it=ob.begin(); it != ob.end(); ++it)
517  ar << *it;
518  return ar;
519 }
520 
526 template<class T>
527 Engine& operator >>( Engine& ar, typename std::deque<T>& ob) THROWS (PersistException)
528 {
529  ob.clear();
530  uint32 siz;
531  ar >> siz;
532  //ob.resize(siz);
533  for(uint32 i=0; i < siz; ++i) {
534  T node;
535  ar >> node;
536  ob.push_back(node);
537  //ar >> ob[i];
538  }
539  return ar;
540 }
541 
547 template<class Key, class Value>
548 Engine& operator <<( Engine& ar, typename std::map<Key,Value> const & ob) THROWS (PersistException)
549 {
550  ar << (uint32)ob.size();
551  for(typename std::map<Key,Value>::const_iterator it = ob.begin();it != ob.end();++it)
552  ar << it->first << it->second;
553  return ar;
554 }
555 
561 template<class Key, class Value>
562 Engine& operator >>( Engine& ar, typename std::map<Key,Value>& ob) THROWS (PersistException)
563 {
564  ob.clear();
565  uint32 siz;
566  ar >> siz;
567  for(uint32 i=0; i < siz; ++i) {
568  Key a;
569  ar >> a;
570  ar >> ob[a];
571  }
572  return ar;
573 }
574 
579 template<class x, class y>
580 Engine& operator <<( Engine& ar, std::pair<x,y> &ob) THROWS (PersistException)
581 {
582  ar << ob.first << ob.second;
583  return ar;
584 }
585 
590 template<class x, class y>
591 Engine& operator >>(Engine& ar, std::pair<x, y> &ob) THROWS (PersistException)
592 {
593  ar >> ob.first >> ob.second;
594  return ar;
595 }
596 
597 #ifdef CCXX_NAMESPACES
598 }
599 #endif
600 
601 #endif
602