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

Last change on this file since 827 was 821, checked in by ansari, 25 years ago

Correction commentaires - Reza 06/04/2000

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