Changeset 241 in Sophya for trunk/SophyaLib/BaseTools/ppersist.h
- Timestamp:
- Apr 21, 1999, 3:12:11 PM (26 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/SophyaLib/BaseTools/ppersist.h
r219 r241 1 // This may look like C code, but it is really -*- C++ -*- 2 1 3 #ifndef PPERSIST_H_SEEN 2 4 #define PPERSIST_H_SEEN 3 5 4 // Classe mixin pour implementer une persistance pas trop bete. 5 6 #include "defs.h" 7 #include "machine.h" 8 #include "perrors.h" 9 #include "pclassids.h" 6 // Flat file persistance, similar to Java serialization 7 // 8 // E. Aubourg CEA DAPNIA/SPP 1999 9 10 11 #include "machdefs.h" 12 #include "pexceptions.h" 13 #include "md5.h" 10 14 11 15 #include <string> 12 #include <list>13 16 #include <map> 14 #include <functional> 17 #include <vector> 18 #include <typeinfo> 15 19 16 20 #if defined(__KCC__) … … 21 25 #endif 22 26 23 #ifdef RFIO 24 #include "erostream.h" 25 #else 26 #include <iostream.h> 27 #endif 28 29 30 class PPersistMgr; 31 class PPersist; 32 class PShPersist; 33 class PInPersist; 34 class POutPersist; 35 36 typedef less<int_4> Int4Compare; 37 38 class PPersistMgr { 39 public: 40 typedef PPersist* (*ClassCreatorFunc)(); 41 42 static void RegisterClass(int_4 classId, ClassCreatorFunc f, 43 bool shared=false); 44 static PPersist* ReadObject(PInPersist&); 45 46 static ClassCreatorFunc FindCreatorFunc(int_4 classId); 47 static ClassCreatorFunc FindCreatorFunc(int_4 classId, bool& isShared); 48 49 static void Reset(); // Nouveau fichier, on oublie les objets partages. 50 51 #ifndef __DECCXX 52 private: 53 #endif 54 struct ClassListEntry { 55 bool shared; 56 ClassCreatorFunc f; 27 namespace PlanckDPC { 28 29 class PIOPersist; 30 class PInPersist; 31 class POutPersist; 32 class PPersist; 33 34 /* Persistant (delegate or mixin) object */ 35 36 class PPersist { 37 public: 38 virtual ~PPersist() {} 39 40 void Write(string const& fn) const; 41 void Read(string const& fn); 42 43 virtual void Write(POutPersist&) const; 44 void Read(PInPersist& s); // Reads the type tag and the object 45 void Write(POutPersist&, string const& tag) const; 46 void ReadAtTag(PInPersist& s, string const& tag); 47 protected: 48 virtual void ReadSelf(PInPersist&)=0; 49 virtual void WriteSelf(POutPersist&) const=0; 50 51 friend class PInPersist; 52 friend class POutPersist; 57 53 }; 58 #ifdef __DECCXX 59 private: 60 #endif 61 62 typedef map<int_4, ClassListEntry, Int4Compare> ClassList; 63 64 65 static ClassList* classList; 66 friend class PeidaInitiator; 67 }; 68 69 70 71 class PPersist EXC_AWARE { 72 public: 73 enum {PPS_NATIVE = -1, PPS_LITTLE_ENDIAN = 0, PPS_BIG_ENDIAN = 1}; 74 virtual ~PPersist() {} 75 virtual int_4 ClassId() const=0; 76 77 void Write(string const& fn) const; 78 void Read(string const& fn); 79 80 virtual void Write(POutPersist&) const; 81 void Read(PInPersist& s); // Se lit, y compris le tag de type. 82 int_4 Write(POutPersist&, int_4 key) const; 83 int_4 Write(POutPersist&, int_4 key, string& nom) const; 84 void ReadAtTag(PInPersist& s, int_4 tagid); 85 void ReadAtKey(PInPersist& s, int_4 key); 86 protected: 87 virtual void ReadSelf(PInPersist&)=0; // A redefinir... 88 virtual void WriteSelf(POutPersist&) const=0; // A redefinir... 89 90 friend class PPersistMgr; 91 }; 92 93 class PShPersist : public PPersist{ 94 public: 95 PShPersist() :mObjectID(0) {} 96 virtual ~PShPersist(); 97 virtual void Write(POutPersist&) const; 98 static PShPersist* FindObject(int_4 objId); 99 100 private: 101 typedef map<int_4, PShPersist*, Int4Compare> ObjList; 102 103 static ObjList* objList; 104 /*mutable*/ int_4 mObjectID; 105 friend class PPersistMgr; 106 friend class PeidaInitiator; 107 }; 108 109 110 111 class PInPersist { 112 public: 113 PInPersist(string const& flnm, bool scan=true); 114 ~PInPersist(); 115 116 bool GotoTag(int_4 num); 117 bool GotoKey(int_4 key, int rang=0); 118 int NbKey(int_4 key); 119 void ListTags(); 120 inline int_4 NbTags() { return(mNTags); } 121 int_4 TagKey(int_4 num, int_4& cid, int_4& ln); 122 string TagName(int_4 num); 123 124 void GetByte (char& c); 125 void GetBytes(void* ptr, size_t bytes); 126 void GetR4 (r_4&); 127 void GetR4s (r_4*, size_t); 128 void GetR8 (r_8&); 129 void GetR8s (r_8*, size_t); 130 void GetI2 (int_2&); 131 void GetI2s (int_2*, size_t); 132 void GetU2 (uint_2&); 133 void GetU2s (uint_2*, size_t); 134 void GetI4 (int_4&); 135 void GetI4s (int_4*, size_t); 136 void GetU4 (uint_4&); 137 void GetU4s (uint_4*, size_t); 138 void GetI8 (int_8&); 139 void GetI8s (int_8*, size_t); 140 void GetU8 (uint_8&); 141 void GetU8s (uint_8*, size_t); 142 void GetLine (char* ptr, size_t len); 143 144 void Get(char& c) {GetByte(c);} 145 void Get(r_4& x) {GetR4(x);} 146 void Get(r_8& x) {GetR8(x);} 147 void Get(uint_2& x) {GetU2(x);} 148 void Get(int_2& x) {GetI2(x);} 149 void Get(uint_4& x) {GetU4(x);} 150 void Get(int_4& x) {GetI4(x);} 151 void Get(uint_8& x) {GetU8(x);} 152 void Get(int_8& x) {GetI8(x);} 153 void Get(r_4* x, size_t n) {GetR4s(x,n);} 154 void Get(r_8* x, size_t n) {GetR8s(x,n);} 155 void Get(uint_2* x, size_t n) {GetU2s(x,n);} 156 void Get(int_2* x, size_t n) {GetI2s(x,n);} 157 void Get(uint_4* x, size_t n) {GetU4s(x,n);} 158 void Get(int_4* x, size_t n) {GetI4s(x,n);} 159 void Get(uint_8* x, size_t n) {GetU8s(x,n);} 160 void Get(int_8* x, size_t n) {GetI8s(x,n);} 161 162 int Version() {return version;} 163 string CreationDate() { return creationdate; } 164 165 protected: 166 void Scan(); 167 char* GetCStr(uint_2 l); 168 #ifdef RFIO 169 erosifstream *s; 170 #else 171 istream* s; 172 #endif 173 int bigEndian; 174 int version; 175 176 string fName; 177 string creationdate; 178 179 struct PPFTag { 180 int_8 popos; 181 int_4 cid; 182 int_4 key; 183 uint_2 lnom; 184 char* nom; 185 }; 186 PPFTag* mTags; 187 int_4 mNTags; 188 list<char*> mSbuffs; 189 char* mSbuf; 190 int mSbsz; 191 }; 192 193 class POutPersist { 194 public: 195 POutPersist(string const& flnm, int endianness = PPersist::PPS_NATIVE); 196 ~POutPersist(); 197 198 int_4 WriteTag(int_4 key, char const * name=NULL); 199 void PutByte (char c); 200 void PutBytes(void const* ptr, size_t bytes); 201 void PutR4 (r_4); 202 void PutR4s (r_4 const*, size_t); 203 void PutR8 (r_8); 204 void PutR8s (r_8 const*, size_t); 205 void PutI2 (int_2); 206 void PutI2s (int_2 const*, size_t); 207 void PutU2 (uint_2); 208 void PutU2s (uint_2 const*, size_t); 209 void PutI4 (int_4); 210 void PutI4s (int_4 const*, size_t); 211 void PutU4 (uint_4); 212 void PutU4s (uint_4 const*, size_t); 213 void PutI8 (int_8); 214 void PutI8s (int_8 const*, size_t); 215 void PutU8 (uint_8); 216 void PutU8s (uint_8 const*, size_t); 217 void PutLine (char const* ptr, size_t len=0); 218 219 void Put(char c) {PutByte(c);} 220 void Put(r_4 x) {PutR4(x);} 221 void Put(r_8 x) {PutR8(x);} 222 void Put(uint_2 x) {PutU2(x);} 223 void Put(int_2 x) {PutI2(x);} 224 void Put(uint_4 x) {PutU4(x);} 225 void Put(int_4 x) {PutI4(x);} 226 void Put(uint_8 x) {PutU8(x);} 227 void Put(int_8 x) {PutI8(x);} 228 void Put(r_4 const* x, size_t n) {PutR4s(x,n);} 229 void Put(r_8 const* x, size_t n) {PutR8s(x,n);} 230 void Put(uint_2 const* x, size_t n) {PutU2s(x,n);} 231 void Put(int_2 const* x, size_t n) {PutI2s(x,n);} 232 void Put(uint_4 const* x, size_t n) {PutU4s(x,n);} 233 void Put(int_4 const* x, size_t n) {PutI4s(x,n);} 234 void Put(uint_8 const* x, size_t n) {PutU8s(x,n);} 235 void Put(int_8 const* x, size_t n) {PutI8s(x,n);} 236 237 238 protected: 239 #ifdef RFIO 240 erosofstream *s; 241 #else 242 ostream* s; 243 #endif 244 int bigEndian; 245 int_4 numTag; 246 int_8 previous; 247 }; 248 249 /* 250 // Ceci est dangereux car un template a priorite sur un changement de type, meme trivial... 251 252 template <class T> 253 POutPersist& operator << (POutPersist& c, T const& data) 254 { 255 c.PutBytes(&data, sizeof(T)); 256 return c; 257 } 258 259 template <class T> 260 PInPersist& operator >> (PInPersist& c, T& data) 261 { 262 c.GetBytes(&data, sizeof(T)); 263 return c; 264 } 265 */ 266 54 55 56 57 // Ancestor for PInPersist and POutPersist 58 // Handles (statically) the registration of classes. 59 60 class PIOPersist { 61 public: 62 enum {PPS_NATIVE = -1, PPS_LITTLE_ENDIAN = 0, PPS_BIG_ENDIAN = 1}; 63 typedef PPersist* (*ClassCreatorFunc)(); 64 65 static void RegisterClass(uint_8 classId, ClassCreatorFunc f); 66 static ClassCreatorFunc FindCreatorFunc(uint_8 classId); 67 static uint_8 Hash(string const& typname) { 68 MD5Init(&ctx); 69 MD5Update(&ctx, (unsigned char*) typname.c_str(), typname.size()); 70 MD5Final(&ctx); 71 return ( *((uint_8*) ctx.digest) + *((uint_8*) (ctx.digest+8))); 72 } 73 static MD5_CTX ctx; 74 75 private: 76 77 typedef map<uint_8, ClassCreatorFunc, less<uint_8> > ClassList; 78 static ClassList classList; 79 80 protected: 81 enum {PPS_NULL = 0, // this is a null object 82 PPS_STRING = 1, // string, length (2b) + data 83 PPS_OBJECT = 2, // classId, data... 84 PPS_REFERENCE = 3, // objectId 85 PPS_TAG = 4, // tag entries 86 PPS_EOF = 5, // Just before tag infomation, offset to PPS_TAG 87 PPS_LINE = 6, // '\n'-terminated, deprecated ? 88 PPS_SIMPLE = 16, // 16 + number of bytes, up to 8 bytes 89 PPS_SIMPLE_ARRAY = 32, // 32 + number of bytes, up to 8 bytes, then 2 bytes of length 90 PPS_SIMPLE_ARRAY4 = 64, // 64 + number of bytes, up to 8 bytes, then 4 bytes of length 91 PPS_SIMPLE_ARRAY8 = 128 // 64 + number of bytes, up to 8 bytes, then 8 bytes of length 92 }; 93 94 map<string, int_8> tags; 95 }; 96 97 98 // TBD : use hash tables instead of maps. Check hashtbl status in STL. 99 100 class PInPersist : public PIOPersist { 101 public: 102 PInPersist(string const& flnm, bool scan=true); 103 ~PInPersist(); 104 105 bool GotoTag(string const& name); 106 107 void GetByte (char& c); 108 void GetBytes(void* ptr, size_t bytes); 109 void GetR4 (r_4&); 110 void GetR4s (r_4*, size_t); 111 void GetR8 (r_8&); 112 void GetR8s (r_8*, size_t); 113 void GetI2 (int_2&); 114 void GetI2s (int_2*, size_t); 115 void GetU2 (uint_2&); 116 void GetU2s (uint_2*, size_t); 117 void GetI4 (int_4&); 118 void GetI4s (int_4*, size_t); 119 void GetU4 (uint_4&); 120 void GetU4s (uint_4*, size_t); 121 void GetI8 (int_8&); 122 void GetI8s (int_8*, size_t); 123 void GetU8 (uint_8&); 124 void GetU8s (uint_8*, size_t); 125 void GetLine (char* ptr, size_t len); 126 void GetStr (string&); 127 128 void Get(char& c) {GetByte(c);} 129 void Get(r_4& x) {GetR4(x);} 130 void Get(r_8& x) {GetR8(x);} 131 void Get(uint_2& x) {GetU2(x);} 132 void Get(int_2& x) {GetI2(x);} 133 void Get(uint_4& x) {GetU4(x);} 134 void Get(int_4& x) {GetI4(x);} 135 void Get(uint_8& x) {GetU8(x);} 136 void Get(int_8& x) {GetI8(x);} 137 void Get(r_4* x, size_t n) {GetR4s(x,n);} 138 void Get(r_8* x, size_t n) {GetR8s(x,n);} 139 void Get(uint_2* x, size_t n) {GetU2s(x,n);} 140 void Get(int_2* x, size_t n) {GetI2s(x,n);} 141 void Get(uint_4* x, size_t n) {GetU4s(x,n);} 142 void Get(int_4* x, size_t n) {GetI4s(x,n);} 143 void Get(uint_8* x, size_t n) {GetU8s(x,n);} 144 void Get(int_8* x, size_t n) {GetI8s(x,n);} 145 void Get(string& x) {GetStr(x);} 146 147 PPersist* ReadObject(); 148 149 150 int Version() {return version;} 151 time_t CreationDate() { return creationdate; } 152 153 protected: 154 void CheckTag (short datasz); 155 void CheckArrayTag(short datasz, size_t sz); 156 void GetRawByte (char& c); 157 void GetRawBytes(void* ptr, size_t bytes); 158 void GetRawI2 (int_2&); 159 void GetRawI4 (int_4&); 160 void GetRawI8 (int_8&); 161 void GetRawU8 (uint_8&); 162 void GetObject(PPersist*); // Object has been allocated with correct type 163 int_4 assignObjectId(PPersist* x); 164 void Scan(); 165 char* GetCStr(uint_2 l); 166 167 istream* s; 168 169 bool bigEndian; 170 int version; 171 172 time_t creationdate; 173 174 // already read objects, id = order in array 175 typedef vector<PPersist*> ObjList; 176 ObjList objList; 177 178 friend class PPersist; 179 }; 180 181 class POutPersist : public PIOPersist { 182 public: 183 POutPersist(string const& flnm, int endianness = PPS_NATIVE); 184 ~POutPersist(); 185 186 void WriteTag(string const& name); 187 188 void PutByte (char c); 189 void PutBytes(void const* ptr, size_t bytes); 190 void PutR4 (r_4); 191 void PutR4s (r_4 const*, size_t); 192 void PutR8 (r_8); 193 void PutR8s (r_8 const*, size_t); 194 void PutI2 (int_2); 195 void PutI2s (int_2 const*, size_t); 196 void PutU2 (uint_2); 197 void PutU2s (uint_2 const*, size_t); 198 void PutI4 (int_4); 199 void PutI4s (int_4 const*, size_t); 200 void PutU4 (uint_4); 201 void PutU4s (uint_4 const*, size_t); 202 void PutI8 (int_8); 203 void PutI8s (int_8 const*, size_t); 204 void PutU8 (uint_8); 205 void PutU8s (uint_8 const*, size_t); 206 void PutLine (char const* ptr, size_t len=0); // deprecated ? 207 void PutStr (string const&); 208 void PutObject (PPersist const*); // Like doing Write(stream) on object 209 210 void Put(char c) {PutByte(c);} 211 void Put(r_4 x) {PutR4(x);} 212 void Put(r_8 x) {PutR8(x);} 213 void Put(uint_2 x) {PutU2(x);} 214 void Put(int_2 x) {PutI2(x);} 215 void Put(uint_4 x) {PutU4(x);} 216 void Put(int_4 x) {PutI4(x);} 217 void Put(uint_8 x) {PutU8(x);} 218 void Put(int_8 x) {PutI8(x);} 219 void Put(r_4 const* x, size_t n) {PutR4s(x,n);} 220 void Put(r_8 const* x, size_t n) {PutR8s(x,n);} 221 void Put(uint_2 const* x, size_t n) {PutU2s(x,n);} 222 void Put(int_2 const* x, size_t n) {PutI2s(x,n);} 223 void Put(uint_4 const* x, size_t n) {PutU4s(x,n);} 224 void Put(int_4 const* x, size_t n) {PutI4s(x,n);} 225 void Put(uint_8 const* x, size_t n) {PutU8s(x,n);} 226 void Put(int_8 const* x, size_t n) {PutI8s(x,n);} 227 void Put(string const& s) {PutStr(s);} 228 void Put(PPersist const* x) {PutObject(x);} 229 230 231 protected: 232 ostream* s; 233 bool bigEndian; 234 235 void PutArrayTag(short datasz, size_t sz); 236 void PutRawByte (char); 237 void PutRawI2 (int_2); 238 void PutRawI4 (int_4); 239 void PutRawI8 (int_8); 240 void PutRawU8 (uint_8); 241 void PutRawBytes(void const* ptr, size_t bytes); 242 bool serializeNullAndRepeat(PPersist const* x); 243 int_4 findObjectId(PPersist const* x); 244 int_4 assignObjectId(PPersist const* x); 245 246 // already serialized objects 247 typedef map<PPersist const*, int_4, less<PPersist const*> > ObjList; 248 ObjList objList; 249 }; 250 251 267 252 #define RAWPERSISTIO(_Type_,_xtyp_) \ 268 inline POutPersist& operator << (POutPersist& c, _Type_ const& data) \269 { \270 c.Put##_xtyp_(data);\271 return c; \272 } \253 inline POutPersist& operator << (POutPersist& c, _Type_ const& data) \ 254 { \ 255 c.Put##_xtyp_(data); \ 256 return c; \ 257 } \ 273 258 \ 274 inline PInPersist& operator >> (PInPersist& c, _Type_& data) \275 { \276 c.Get##_xtyp_(data);\277 return c; \278 }279 280 RAWPERSISTIO(int_4,I4) 281 RAWPERSISTIO(uint_4,U4) 282 RAWPERSISTIO(int_2,I2) 283 RAWPERSISTIO(uint_2,U2) 284 RAWPERSISTIO(char,Byte) 285 RAWPERSISTIO(r_4,R4) 286 RAWPERSISTIO(r_8,R8) 287 259 inline PInPersist& operator >> (PInPersist& c, _Type_& data) \ 260 { \ 261 c.Get##_xtyp_(data); \ 262 return c; \ 263 } 264 265 RAWPERSISTIO(int_4,I4); 266 RAWPERSISTIO(uint_4,U4); 267 RAWPERSISTIO(int_2,I2); 268 RAWPERSISTIO(uint_2,U2); 269 RAWPERSISTIO(char,Byte); 270 RAWPERSISTIO(r_4,R4); 271 RAWPERSISTIO(r_8,R8); 272 288 273 #if 0 289 274 #define STRUCTPERSISTIO(_Type_, _field_, _size_) \ 290 inline POutPersist& operator << (POutPersist& c, _Type_ const& data) \291 { \292 c.PutBytes(&data._field_, _size_); \293 return c; \294 } \275 inline POutPersist& operator << (POutPersist& c, _Type_ const& data) \ 276 { \ 277 c.PutBytes(&data._field_, _size_); \ 278 return c; \ 279 } \ 295 280 \ 296 inline PInPersist& operator >> (PInPersist& c, _Type_& data) \297 { \298 c.GetBytes(&data._field_, _size_); \299 return c; \300 }281 inline PInPersist& operator >> (PInPersist& c, _Type_& data) \ 282 { \ 283 c.GetBytes(&data._field_, _size_); \ 284 return c; \ 285 } 301 286 302 287 #endif 303 304 inline POutPersist& operator << (POutPersist& c, PPersist const& obj) 305 { 306 obj.Write(c); 307 return c; 308 } 309 310 inline PInPersist& operator >> (PInPersist& c, PPersist& obj) 311 { 312 obj.Read(c); 313 return c; 314 } 315 316 // Fabrication de fonction Create automatique, et enregistrement... 317 template <class T> 318 class PPersistRegistrar { 319 public: 320 static PPersist* Create() {return new T();} 321 static void Register() {PPersistMgr::RegisterClass(T::classId,Create);} 322 }; 323 288 289 inline POutPersist& operator << (POutPersist& c, PPersist const& obj) 290 { 291 obj.Write(c); 292 return c; 293 } 294 295 inline PInPersist& operator >> (PInPersist& c, PPersist& obj) 296 { 297 obj.Read(c); 298 return c; 299 } 300 301 // Utility class to 302 // - compute the class ID from a MD5 hash of the class name 303 // - register classes with PIOPersist, through PPRegister macro 304 305 template <class T> 306 class PPersistRegistrar { 307 public: 308 static PPersist* Create() {return new T();} 309 static void Register() {PIOPersist::RegisterClass(Hash(),Create);} 310 static uint_8 Hash() { 311 return PIOPersist::Hash(typeid(T).name()); 312 } 313 }; 314 324 315 #define PPRegister(className) PPersistRegistrar<className>::Register(); 316 317 } // namespace 325 318 326 319 #endif
Note:
See TracChangeset
for help on using the changeset viewer.