source: Sophya/trunk/SophyaLib/BaseTools/ppersist.h@ 2384

Last change on this file since 2384 was 1202, checked in by ansari, 25 years ago

bug swap md5

File size: 14.4 KB
Line 
1// This may look like C code, but it is really -*- C++ -*-
2
3#ifndef PPERSIST_H_SEEN
4#define PPERSIST_H_SEEN
5
6// Flat file persistance, similar to Java serialization
7//
8// E. Aubourg CEA DAPNIA/SPP 1999
9// R. Ansari LAL IN2P3/CNRS 03/2000
10
11
12#include "machdefs.h"
13#include "pexceptions.h"
14#include "gnumd5.h"
15
16
17#include <time.h>
18
19#include <string>
20#include <map>
21#include <vector>
22#include <typeinfo>
23
24
25// Classe de base pour les objets qui peuvent devenir PPersist
26
27namespace SOPHYA {
28
29 class AnyDataObj;
30
31 class PIOPersist;
32 class PInPersist;
33 class POutPersist;
34 class PPersist;
35
36//! Persistent (delegate or mixin) base class
37 class PPersist {
38 public:
39 virtual ~PPersist() {}
40// J'ajoute cette fonction pour assurer la compatibilite
41// avec l'ancien PPersist d'Eros (Reza 23/04/99)
42 virtual int_4 ClassId() const { return(0); }
43
44 void Write(string const& fn) const;
45 void Read(string const& fn);
46
47 virtual void Write(POutPersist&) const;
48 void Read(PInPersist& s); // Reads the type tag and the object
49 void Write(POutPersist&, string const& tag) const;
50 void ReadAtTag(PInPersist& s, string const& tag);
51
52 virtual AnyDataObj* DataObj()=0; // Retourne l'objet reel
53 virtual void SetDataObj(AnyDataObj &)=0;
54
55 virtual uint_8 getMemOId() const ; // Renvoie l'identificateur de l'objet - par defaut=0
56 // Ces deux methodes doivent etre redefinies si getMemOId() renvoie non nul (>0)
57 virtual void ShareDataReference(PPersist &);
58 virtual PPersist* CloneSharedReference();
59 // doit etre surcharge pour renvoyer un mem-oid correct
60 protected:
61 virtual void ReadSelf(PInPersist&)=0;
62 virtual void WriteSelf(POutPersist&) const=0;
63
64 friend class PInPersist;
65 friend class POutPersist;
66 };
67
68
69
70//! Ancestor for PInPersist and POutPersist PPF streams.
71// Handles (statically) the registration of classes.
72
73 class PIOPersist {
74 public:
75 enum {PPS_NATIVE = -1, PPS_LITTLE_ENDIAN = 0, PPS_BIG_ENDIAN = 1};
76 typedef PPersist* (*ClassCreatorFunc)();
77
78 static void RegisterPPHandlerClass(uint_8 classId, string ppclass_name, ClassCreatorFunc f);
79 static void RegisterDataObjClass(uint_8 classId, string class_name);
80
81 static ClassCreatorFunc FindCreatorFunc(uint_8 classId);
82
83 static string getPPClassName(uint_8 classId);
84 static uint_8 getPPClassId(string const & typ_name);
85 static uint_8 getPPClassId(PPersist const & ppo);
86 static string getDataObjClassName(uint_8 classId);
87 static uint_8 getDataObjClassId(string const & typ_name);
88 static uint_8 getDataObjClassId(AnyDataObj const & o);
89
90 static uint_8 Hash(string const& typname);
91 static MD5_CONTEXT ctx;
92
93 static void Initialize(); // Pour initialiser classList
94
95 string FileName() { return filename; } // Retourne le nom de fichier
96
97 private:
98
99 typedef map<uint_8, ClassCreatorFunc, less<uint_8> > ClassList;
100 // Pas de createur appele pour objets statiques sur Linux - $CHECK$ Reza 26/04/99
101 static ClassList * ppclassList; // PPersist class list
102 static map<string, uint_8> * ppclassNameList; // PPersist classId = f(PPersistClassName)
103 static map<string, uint_8> * dobjclassNameList; // PPersist classId = f(DataObjClassName)
104
105 protected:
106
107 enum {PPS_NULL = 0, // this is a null object
108 PPS_STRING = 1, // string, length (4b) + data
109 PPS_OBJECT = 2, // classId, data...
110 PPS_REFERENCE = 3, // objectId
111 PPS_TAG = 4, // tag entries
112 PPS_EOF = 5, // Just before tag infomation, offset to PPS_TAG
113 PPS_ENDOBJECT = 6, // marks the end of a given object information
114 PPS_TAG_MARK = 7, // To have a name tag, position marker in a file
115 PPS_SIMPLE = 16, // 16 + number of bytes, up to 8 bytes
116 PPS_SIMPLE_ARRAY4 = 32, // 32 + number of bytes, up to 8 bytes, then 4 bytes of length
117 PPS_SIMPLE_ARRAY8 = 48 // 48 + number of bytes, up to 8 bytes, then 8 bytes of length
118 };
119 // The following values are used with PPS_SIMPLE and PPS_SIMPLE_ARRAY (Using OR)
120 enum {PPS_DATATYPE_CHAR = 0, // 0 : DataType=character
121 PPS_DATATYPE_FLOAT = 64, // 64 : DataType=float
122 PPS_DATATYPE_INTEGER = 128, // 128 :DataType=integer
123 PPS_DATATYPE_UNSIGNED = 192 // 192 :DataType=Unsigned integer
124 };
125
126 map<string, int_8> tags;
127 string filename;
128 };
129
130
131 // TBD : use hash tables instead of maps. Check hashtbl status in STL.
132
133//! Input stream for PPersit objects.
134 class PInPersist : public PIOPersist {
135 public:
136 PInPersist(string const& flnm, bool scan=true);
137 ~PInPersist();
138
139 bool GotoTag(string const& name);
140 int NbTags();
141 bool GotoTagNum(int itag); // 0..NbTags-1
142 string GetTagName(int itag); // 0..NbTags-1
143 string GetTagClassName(int itag); // 0..NbTags-1
144 vector<string> const & GetTagNames();
145
146 void GetByte (char& c);
147 void GetBytes(void* ptr, size_t bytes);
148 void GetR4 (r_4&);
149 void GetR4s (r_4*, size_t);
150 void GetR8 (r_8&);
151 void GetR8s (r_8*, size_t);
152 void GetI2 (int_2&);
153 void GetI2s (int_2*, size_t);
154 void GetU2 (uint_2&);
155 void GetU2s (uint_2*, size_t);
156 void GetI4 (int_4&);
157 void GetI4s (int_4*, size_t);
158 void GetU4 (uint_4&);
159 void GetU4s (uint_4*, size_t);
160 void GetI8 (int_8&);
161 void GetI8s (int_8*, size_t);
162 void GetU8 (uint_8&);
163 void GetU8s (uint_8*, size_t);
164 void GetLine (char* ptr, size_t len);
165 void GetStr (string&);
166
167 void Get(char& c) {GetByte(c);}
168 void Get(r_4& x) {GetR4(x);}
169 void Get(r_8& x) {GetR8(x);}
170 void Get(uint_2& x) {GetU2(x);}
171 void Get(int_2& x) {GetI2(x);}
172 void Get(uint_4& x) {GetU4(x);}
173 void Get(int_4& x) {GetI4(x);}
174 void Get(uint_8& x) {GetU8(x);}
175 void Get(int_8& x) {GetI8(x);}
176 void Get(r_4* x, size_t n) {GetR4s(x,n);}
177 void Get(r_8* x, size_t n) {GetR8s(x,n);}
178 void Get(uint_2* x, size_t n) {GetU2s(x,n);}
179 void Get(int_2* x, size_t n) {GetI2s(x,n);}
180 void Get(uint_4* x, size_t n) {GetU4s(x,n);}
181 void Get(int_4* x, size_t n) {GetI4s(x,n);}
182 void Get(uint_8* x, size_t n) {GetU8s(x,n);}
183 void Get(int_8* x, size_t n) {GetI8s(x,n);}
184 void Get(string& x) {GetStr(x);}
185
186 // Object Reading
187 PPersist* ReadObject();
188 void GetObject(AnyDataObj & o);
189 void GetObject(AnyDataObj & o, string tagname);
190 PPersist* GetPPObject(AnyDataObj * po=NULL);
191
192 int Version() {return version;}
193 time_t CreationDate() { return creationdate; }
194 string CreationDateStr();
195
196 void AnalyseTags(int lev=0); // List (all or some) tags ...
197
198 // Reza 03/2000
199 // Methodes qui pourraient etre protected, mais doivent etre utilisables par PPersist
200 void ReadReference(PPersist & ppo); // Fill the ppo object from the reference tag
201 PPersist * ReadReference(); // Creates object from the reference tag
202 void KeepOId(uint_8 oid, PPersist & ppo); // Keeps the ppo in the objList
203
204 protected:
205 void CheckTag (short datasz, short datatype);
206 void CheckArrayTag(short datasz, size_t sz, short datatype);
207 void GetTypeTag (unsigned char& c);
208 void GetRawByte (char& c);
209 void GetRawUByte (unsigned char& c);
210 void GetRawBytes(void* ptr, size_t bytes);
211 void GetRawI2 (int_2&);
212 void GetRawI4 (int_4&);
213 void GetRawI8 (int_8&);
214 void GetRawU8 (uint_8&);
215
216 void Scan();
217
218 istream* s;
219
220 bool bigEndian;
221 int version;
222
223 time_t creationdate;
224
225 // already read objects
226 typedef map<uint_8, PPersist * > ObjList;
227 ObjList objList;
228 // Si on a fait une lecture non sequentielle -> seqread = false
229 bool seqread;
230 friend class PPersist;
231 };
232
233//! Output stream for PPersit objects.
234 class POutPersist : public PIOPersist {
235 public:
236 POutPersist(string const& flnm, int endianness = PPS_NATIVE);
237 ~POutPersist();
238
239 void WriteTag(string const& name);
240
241 void PutByte (char c);
242 void PutBytes(void const* ptr, size_t bytes);
243 void PutR4 (r_4);
244 void PutR4s (r_4 const*, size_t);
245 void PutR8 (r_8);
246 void PutR8s (r_8 const*, size_t);
247 void PutI2 (int_2);
248 void PutI2s (int_2 const*, size_t);
249 void PutU2 (uint_2);
250 void PutU2s (uint_2 const*, size_t);
251 void PutI4 (int_4);
252 void PutI4s (int_4 const*, size_t);
253 void PutU4 (uint_4);
254 void PutU4s (uint_4 const*, size_t);
255 void PutI8 (int_8);
256 void PutI8s (int_8 const*, size_t);
257 void PutU8 (uint_8);
258 void PutU8s (uint_8 const*, size_t);
259 void PutLine (char const* ptr, size_t len=0); // deprecated ?
260 void PutStr (string const&);
261 void PutPPObject (PPersist const*); // Like doing Write(stream) on PPersist object
262
263 void PutObject(AnyDataObj & o); // Creates the corresponding PPersist Object and call Write()
264 void PutObject(AnyDataObj & o, string tagname);
265
266 void Put(char c) {PutByte(c);}
267 void Put(r_4 x) {PutR4(x);}
268 void Put(r_8 x) {PutR8(x);}
269 void Put(uint_2 x) {PutU2(x);}
270 void Put(int_2 x) {PutI2(x);}
271 void Put(uint_4 x) {PutU4(x);}
272 void Put(int_4 x) {PutI4(x);}
273 void Put(uint_8 x) {PutU8(x);}
274 void Put(int_8 x) {PutI8(x);}
275 void Put(r_4 const* x, size_t n) {PutR4s(x,n);}
276 void Put(r_8 const* x, size_t n) {PutR8s(x,n);}
277 void Put(uint_2 const* x, size_t n) {PutU2s(x,n);}
278 void Put(int_2 const* x, size_t n) {PutI2s(x,n);}
279 void Put(uint_4 const* x, size_t n) {PutU4s(x,n);}
280 void Put(int_4 const* x, size_t n) {PutI4s(x,n);}
281 void Put(uint_8 const* x, size_t n) {PutU8s(x,n);}
282 void Put(int_8 const* x, size_t n) {PutI8s(x,n);}
283 void Put(string const& s) {PutStr(s);}
284 void Put(PPersist const* x) {PutPPObject(x);}
285
286
287 protected:
288 ostream* s;
289 bool bigEndian;
290
291 void PutArrayTag(short datasz, size_t sz, short datatype);
292 void PutRawByte (char);
293 void PutRawUByte (unsigned char);
294 void PutRawI2 (int_2);
295 void PutRawI4 (int_4);
296 void PutRawI8 (int_8);
297 void PutRawU8 (uint_8);
298 void PutRawBytes(void const* ptr, size_t bytes);
299 bool serializeNullAndRepeat(PPersist const* x);
300 uint_8 findObjectId(PPersist const* x, int_8 & pos);
301 uint_8 assignObjectId(PPersist const* x);
302
303 // objreftag contains the assigned POutStream Object Id and the stream position
304 // of the original written object
305 typedef struct { uint_8 ppsoid; int_8 ppspos; } objreftag;
306 // already serialized objects are kept in a map as a function of the Objects memory Id
307 typedef map<uint_8, objreftag, less<uint_8> > ObjList;
308 ObjList objList;
309 uint_8 pps_OId; // PPS Object Id
310 };
311
312
313#define RAWPERSISTIO(_Type_,_xtyp_) \
314 inline POutPersist& operator << (POutPersist& c, _Type_ const& data) \
315 { \
316 c.Put##_xtyp_(data); \
317 return c; \
318 } \
319 \
320 inline PInPersist& operator >> (PInPersist& c, _Type_& data) \
321 { \
322 c.Get##_xtyp_(data); \
323 return c; \
324 }
325
326 RAWPERSISTIO(int_4,I4);
327 RAWPERSISTIO(uint_4,U4);
328 RAWPERSISTIO(int_2,I2);
329 RAWPERSISTIO(uint_2,U2);
330 RAWPERSISTIO(char,Byte);
331 RAWPERSISTIO(r_4,R4);
332 RAWPERSISTIO(r_8,R8);
333
334#if 0
335#define STRUCTPERSISTIO(_Type_, _field_, _size_) \
336 inline POutPersist& operator << (POutPersist& c, _Type_ const& data) \
337 { \
338 c.PutBytes(&data._field_, _size_); \
339 return c; \
340 } \
341 \
342 inline PInPersist& operator >> (PInPersist& c, _Type_& data) \
343 { \
344 c.GetBytes(&data._field_, _size_); \
345 return c; \
346 }
347
348#endif
349
350
351// --- Cela risque d'etre dangereux --- On le laisse au niveau des DataObj
352// Reza 24/3/2000
353// inline POutPersist& operator << (POutPersist& c, PPersist const& obj)
354// {
355// obj.Write(c);
356// return c;
357// }
358
359// inline PInPersist& operator >> (PInPersist& c, PPersist& obj)
360// {
361// obj.Read(c);
362// return c;
363// }
364
365 // Utility class to
366 // - compute the class ID from a MD5 hash of the class name
367 // - register classes with PIOPersist, through PPRegister macro
368
369//! template class for handling the PPersist registration mechanism.
370 template <class T>
371 class PPersistRegistrar {
372 public:
373 static PPersist* Create() {return new T();}
374 static void Register(string id) { PIOPersist::RegisterPPHandlerClass(Hash(id), typeid(T).name(), Create); }
375 static uint_8 Hash(string id) {
376 return PIOPersist::Hash(id);
377 }
378 };
379
380#define PPRegister(className) PPersistRegistrar<className>::Register(#className);
381#define DObjRegister(ppclassName, className) PIOPersist::RegisterDataObjClass(PIOPersist::Hash(#ppclassName), typeid(className).name());
382
383} // namespace
384
385#endif
Note: See TracBrowser for help on using the repository browser.