Changeset 241 in Sophya for trunk/SophyaLib/BaseTools/ppersist.cc
- Timestamp:
- Apr 21, 1999, 3:12:11 PM (26 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/SophyaLib/BaseTools/ppersist.cc
r219 r241 1 #include "defs.h" 1 #include "machdefs.h" 2 #include "pexceptions.h" 2 3 #include <stdio.h> 3 4 #include "peidainit.h" 4 5 #include "ppersist.h" 5 #include "dates.h"6 7 #ifndef RFIO8 6 #include <fstream.h> 9 # endif7 #include <typeinfo> 10 8 11 9 … … 15 13 #endif 16 14 17 #if SWAP==1 18 #define IS_BIG_ENDIAN 0 19 #else 20 #define IS_BIG_ENDIAN 1 21 #endif 22 23 //++ 24 // Class PPersistMgr 15 using namespace PlanckDPC; 16 17 #define MAXTAGLEN 255 18 19 //++ 20 // Class PIOPersist 25 21 // Lib Outils++ 26 22 // include ppersist.h 27 23 // 28 // Classe gestionnaire d'objets persistants. Les méthodes statiques 29 // de cette classe permettent d'enregistrer des classes persistantes, 30 // et de relire automatiquement des objets. 31 //-- 32 33 //++ 34 // Links Voir 24 // Root class for persistant files. Handles the registration of 25 // persistant classes 26 //-- 27 28 //++ 29 // Links See 35 30 // PPersist 36 // PShPersist 37 //-- 38 39 PPersistMgr::ClassList* PPersistMgr::classList = NULL; 40 PShPersist::ObjList* PShPersist::objList = NULL; 41 42 //++ 43 void 44 PPersistMgr::RegisterClass(int_4 classId, ClassCreatorFunc f, bool shared) 45 // 46 // Enregistre une nouvelle classe auprès du gestionnaire. classId doit 47 // identifier de façon unique la classe. f doit créer un nouvel objet 48 // de cette classe (qui doit hériter de PPersist), non initialisé, et qui 49 // sera relu à partir du fichier d'objets persistants. 50 // 51 // Si shared est true, la classe doit hériter de PShPersist, et la persistance 52 // gère le fait que plusieurs objets Xi puissent faire référence à un même objet A. 53 // A, qui hérite donc de PShPersist, ne sera écrit qu'une seule fois dans le fichier 54 // lorsque les Xi sont écrits, et la référence à A sera mise à jour lors de la lecture 55 // des Xi... 56 //-- 57 { 58 DBASSERT(classList); 59 if (classList->size() && (classList->find(classId) != classList->end())) { 31 // PInPersist 32 // POutPersist 33 //-- 34 35 36 MD5_CTX PIOPersist::ctx; 37 PIOPersist::ClassList PIOPersist::classList; 38 39 40 //++ 41 void 42 PIOPersist::RegisterClass(uint_8 classId, ClassCreatorFunc f) 43 // 44 // Register a new persistant class. 45 // The classId is usually a hash of the class name, and this 46 // method is called only through the PPersistRegistrar template 47 // class, with the PPRegister(className) macro. 48 // 49 //-- 50 { 51 if (classList.size() && (classList.find(classId) != classList.end())) { 60 52 cerr << "RegisterClass : Error, " << hex << classId << dec 61 53 << " already registered." << endl; 62 THROW(dupIdErr);54 throw(DuplicateIdExc("PIOPersist::RegisterClass")); 63 55 } 64 56 65 ClassListEntry entry = {shared, f}; 66 (*classList)[classId] = entry; 67 } 68 69 70 PPersistMgr::ClassCreatorFunc 71 PPersistMgr::FindCreatorFunc(int_4 classId) 72 { 73 DBASSERT(classList); 74 return (*classList)[classId].f; 75 } 76 77 PPersistMgr::ClassCreatorFunc 78 PPersistMgr::FindCreatorFunc(int_4 classId, bool& isShared) 79 { 80 DBASSERT(classList); 81 ClassListEntry entry = (*classList)[classId]; 82 isShared = entry.shared; 83 return entry.f; 84 } 85 86 //++ 87 PPersist* 88 PPersistMgr::ReadObject(PInPersist& s) 89 // 90 // Lit un objet dans le stream s, en créant automatiquement un 91 // objet du bon type. 92 //-- 93 { 94 DBASSERT(classList); 95 DBASSERT(PShPersist::objList); 96 // On commence par lire le type de l'objet 97 int_4 classId; 98 s >> classId; 99 100 // On recupere le createur, et on regarde si l'objet est partage 101 bool shared; 102 if (!classList->size() || (classList->find(classId) == classList->end())) { 103 cerr << "PPersistMgr::ReadObject Error : Class " << classId << " not registered" << endl; 104 THROW(notFoundErr); 105 } 106 PPersistMgr::ClassCreatorFunc f = FindCreatorFunc(classId, shared); 107 108 if (!f) THROW(notFoundErr); 109 110 PPersist* object; 111 if (shared) { 112 // Si l'objet est partage, ce qui suit est son identificateur, sur 4 octets 113 // et un octet ensuite qui dit si l'objet est present. 114 115 int_4 objectId; 116 char objectSaved; 117 118 s >> objectId >> objectSaved; 119 120 #if 0 121 // On regarde si l'objet est deja en memoire 122 object = PShPersist::FindObject(objectId); 123 124 // On verifie qu'on est dans une situation coherente... 125 if ((!objectSaved) == (!object)) THROW(inconsistentErr); 126 #else 127 if (!objectSaved) { 128 object = PShPersist::FindObject(objectId); 129 if (!object) THROW(inconsistentErr); 130 } 131 #endif 132 if (objectSaved) { 133 object = f(); 134 object->ReadSelf(s); 135 ((PShPersist*)object)->mObjectID = objectId; 136 (*PShPersist::objList)[objectId] = (PShPersist*)object; 137 } 138 } else { 139 object = f(); 140 object->ReadSelf(s); 141 } 142 143 return object; 144 } 57 classList[classId] = f; 58 } 59 60 61 PIOPersist::ClassCreatorFunc 62 PIOPersist::FindCreatorFunc(uint_8 classId) 63 { 64 ClassList::iterator i = classList.find(classId); 65 if (i == classList.end()) throw(NotFoundExc("PIOPersist::FindCreatorFunc")); 66 return (*i).second; 67 } 68 145 69 146 70 //++ … … 168 92 169 93 //++ 170 // Links Voir94 // Links See 171 95 // PInPersist 172 96 // POutPersist 173 // PPersistMgr 174 // PShPersist 175 //-- 176 177 PShPersist* 178 PShPersist::FindObject(int_4 objId) 179 { 180 DBASSERT(objList); 181 return (*objList)[objId]; 182 } 97 // PIOPersist 98 //-- 183 99 184 100 //++ … … 213 129 //-- 214 130 { 215 // On doit tout d'abord ecrire notre type 216 s << ClassId(); 217 // Puis on s'ecrit, tout betement... 218 WriteSelf(s); 131 s.PutObject(this); 219 132 } 220 133 … … 226 139 // Relit l'objet dans le fichier ppersist. Il faut connaître a priori 227 140 // le type de l'objet. Pour une relecture avec création automatique du bon 228 // objet, utiliser PPersistMgr::ReadObject. 229 //-- 230 { 231 // A n'utiliser que si on connait a priori 232 // le vrai type de l'objet. 233 234 // On doit tout d'abord lire notre type 235 int_4 classId; 236 s >> classId; 237 if (classId != ClassId()) { 238 cerr << "PPersist::Read() Object type (=" << ClassId() << ") mismatch (type in file=" 239 << classId << ")" << endl; 240 THROW(typeMismatchErr); } 241 // Puis on se lit, tout betement... 242 243 ReadSelf(s); 244 } 245 246 //++ 247 int_4 248 PPersist::Write(POutPersist& s, int_4 key) const 249 // 250 // Ecrit l'objet dans le fichier PPersist avec un tag ayant "key" comme 251 // valeur du champ clé du tag. 252 //-- 253 { 254 int_4 rc; 255 // On ecrit le tag de positionnement et on recupere le numero de tag 256 rc = s.WriteTag(key, NULL); 257 // avant d'ecrire l'objet lui-meme 258 Write(s); 259 return(rc); 260 } 261 262 //++ 263 int_4 264 PPersist::Write(POutPersist& s, int_4 key, string& nom) const 265 // 266 // Ecrit l'objet dans le fichier PPersist avec un tag ayant "key", nom comme 267 // valeurs des champs clé et nom du tag. 268 //-- 269 { 270 int_4 rc; 271 // On ecrit le tag de positionnement et on recupere le numero de tag 272 rc = s.WriteTag(key, nom.c_str()); 273 // avant d'ecrire l'objet lui-meme 274 Write(s); 275 return(rc); 276 } 277 278 //++ 279 void 280 PPersist::ReadAtTag(PInPersist& s, int_4 tagid) 141 // objet, utiliser PInPersist::ReadObject. 142 // Il faut qu'on soit un objet ecrit 143 //-- 144 { 145 // We should be the exact type 146 // Check tag value 147 char ppstype; 148 s.GetRawByte(ppstype); 149 if (ppstype != PInPersist::PPS_OBJECT) { 150 throw TypeMismatchExc("PPersist::Read : not an object in flow"); 151 } 152 153 // Check class id 154 uint_8 classId; 155 s.GetRawU8(classId); 156 if (classId != PIOPersist::Hash(typeid(*this).name())) { 157 throw TypeMismatchExc("PPersist::Read : not the same object type"); 158 } 159 160 ReadSelf(s); 161 } 162 163 //++ 164 void 165 PPersist::Write(POutPersist& s, string const& tag) const 166 // 167 // Ecrit l'objet dans le fichier PPersist avec un tag 168 //-- 169 { 170 s.WriteTag(tag); 171 s.PutObject(this); 172 } 173 174 //++ 175 void 176 PPersist::ReadAtTag(PInPersist& s, string const& tag) 281 177 // 282 178 // Lit l'objet à la position du tag numéro "tagid". 283 179 //-- 284 180 { 285 if (s.GotoTag(tagid)) Read(s); 286 else { 287 cerr << "PInPersist::GotoTag() Error ! \n" << 288 "From PPersist::ReadAtTag(PInPersist, tag= " << tagid << ") " << endl; 289 THROW(fileErr); 290 } 291 return; 292 } 293 294 //++ 295 void 296 PPersist::ReadAtKey(PInPersist& s, int_4 key) 297 // 298 // Lit l'objet à la position du tag contenant la clé "key". 299 //-- 300 { 301 if (s.GotoKey(key)) Read(s); 302 else { 303 cerr << "PInPersist::GotoKey() Error ! \n" << 304 "From PPersist::ReadAtKey(PInPersist, key= " << key << ") " << endl; 305 THROW(fileErr); 306 } 307 return; 308 } 181 if (!s.GotoTag(tag)) 182 throw NotFoundExc("PPersist::ReadAtTag tag not found"); 183 Read(s); 184 } 185 309 186 310 187 //++ … … 320 197 321 198 322 //++323 // Class PShPersist324 // Lib Outils++325 // include ppersist.h326 //327 // Classe de base pour des objets persistants partagés.328 // Un tel objet ne sera écrit qu'une seule fois dans un fichier329 // donné. Les tentatives suivantes d'écriture n'écrivent qu'une330 // référence à la première écriture.331 //332 // Lors de la lecture, l'objet est créé lors de la première lecture,333 // puis l'adresse de cet objet est retournée lors des lectures suivantes.334 //--335 336 //++337 // Links Parents338 // PPersist339 //--340 341 //++342 void343 PShPersist::Write(POutPersist& s) const344 //345 // Ecrit l'objet dans le fichier s.346 //347 // En fait, l'objet est physiquement écrit une seule fois.348 //--349 {350 DBASSERT(objList);351 // On doit tout d'abord ecrire notre type352 353 s << ClassId();354 355 // On doit ensuite ecrire notre identificateur et le flag d'ecriture356 357 char write = (mObjectID == 0) ? 255 : 0;358 if (mObjectID == 0) {359 (int_4&)mObjectID = (*objList).size() ? (*((*objList).rbegin())).first+1 : 1;360 (*objList)[mObjectID] = (PShPersist*)this;361 }362 363 s << mObjectID << write ;364 365 // Puis, si necessaire, on s'ecrit366 367 if (write)368 WriteSelf(s);369 }370 371 PShPersist::~PShPersist() // Une securite peut-etre facultative372 {373 DBASSERT(objList);374 if (mObjectID) {375 DBASSERT(!objList->size() && (objList->find(mObjectID) != objList->end()));376 objList->erase(mObjectID);377 }378 }379 380 void381 PPersistMgr::Reset()382 {383 DBASSERT(PShPersist::objList);384 for (PShPersist::ObjList::iterator i = PShPersist::objList->begin();385 i != PShPersist::objList->end(); i++)386 (*i).second->mObjectID = 0; // Une securite peut-etre facultative387 388 PShPersist::objList->erase(PShPersist::objList->begin(), PShPersist::objList->end());389 }390 391 #define PIOP_Delim '\n' // Delimiteur de ligne392 // Les noms ne peuvent depasser 255 caracteres393 #define MAXTAGNAMELEN 255394 199 395 200 //++ … … 407 212 //-- 408 213 { 409 mSbsz = 0; // Pour conserver les noms des tags ( V4 et au dela ) 410 mSbuf = NULL; 411 mTags = NULL; 412 mNTags = 0; // " " " " 413 fName = flnm; 414 #ifdef RFIO 415 s = new erosifstream(flnm.c_str(),"rb"); 214 s = new ifstream(flnm.c_str(),ios::in | IOS_BIN); 215 216 // Read and check header 217 218 char rbuf[36]; 219 GetRawBytes(rbuf, 32); 220 if (strncmp(rbuf,"PlanckDPC-PPersistFile", 22) != 0) { 221 throw FileFormatExc("PInPersist::PInPersist bad header"); 222 } 223 version = atoi(rbuf+24); 224 225 // read endianness 226 GetRawBytes(rbuf, 32); 227 if (strncmp(rbuf,"BIG-ENDIAN",10) == 0) 228 bigEndian = true; 229 else if (strncmp(rbuf,"LITTLE-ENDIAN",13) == 0) 230 bigEndian = false; 231 else { 232 throw FileFormatExc("PInPersist::PInPersist bad header - endianness"); 233 } 234 235 // read creation date 236 GetRawBytes(rbuf, 32); 237 rbuf[32] = '\0'; 238 struct tm tm; 239 strptime(rbuf,"%d/%m/%Y %T GMT",&tm); 240 creationdate = mktime(&tm); 241 242 if (scan) Scan(); 243 } 244 245 246 247 PInPersist::~PInPersist() 248 { 249 delete s; 250 } 251 252 253 void 254 PInPersist::Scan() 255 { 256 // On cherche la liste des tags, a la fin du fichier 257 258 char ppstype; 259 size_t debut; 260 #ifdef STREAMPOS_IS_CLASS 261 debut = s->tellg().offset(); 416 262 #else 417 // $CHECK$ EA ios::binary (ou ios::bin) doit exister PARTOUT. 418 // Voir note dans defs.h pres de HAS_IOS_BIN 419 #if defined(__MWERKS__) 420 s = new ifstream(flnm.c_str(),ios::in | ios::binary); // ios::binary pas connnu partout - $CHECK$ Reza 13/02/98 421 #else 422 s = new ifstream(flnm.c_str(),ios::in ); 263 debut = s->tellg(); 423 264 #endif 424 #endif 425 PPersistMgr::Reset(); 426 char rbuf[36]; 427 GetBytes(rbuf, 32); 428 if (strncmp(rbuf,"PEIDA-PPersistFile", 18) != 0) { 429 cerr << "PInPersist::PInPersist Error : File " << flnm << " (empty file or bad header)" 430 << endl; 431 THROW(fileErr); } 432 version = atoi(rbuf+20); 433 bigEndian = IS_BIG_ENDIAN; // Les V2 sont relus en mode natif 434 if (version >= 3) { 435 GetBytes(rbuf, 32); 436 if (strncmp(rbuf,"BIG-ENDIAN",10) == 0) 437 bigEndian = true; 438 else if (strncmp(rbuf,"LITTLE-ENDIAN",13) == 0) 439 bigEndian = false; 440 else { 441 cerr << "PInPersist::PInPersist Error : File" << flnm; 442 cerr << " (V>=3 et ni BIG-ENDIAN, ni LITTLE-ENDIAN" << endl; 443 THROW(fileErr); 444 } 445 } 446 if (version >= 5) { // On lit la date de creation (V5 et au-dela) 447 GetBytes(rbuf, 32); 448 rbuf[32] = '\0'; 449 for(int k=0; k<32; k++) 450 if (rbuf[k] == ' ') { rbuf[k] = '\0'; break; } 451 creationdate = rbuf; 452 } // Fin de lecture de date 453 else creationdate = "??/??/??" ; 454 // Le fichier peut contenir des tag (V4 et au dela) 455 if ( (version >= 4) && scan ) Scan(); 456 } 457 458 459 460 PInPersist::~PInPersist() 461 { 462 list<char*>::iterator it; 463 for(it = mSbuffs.begin(); it != mSbuffs.end(); it++) delete[] (*it); 464 if (mTags) delete[] mTags; 465 delete s; 466 PPersistMgr::Reset(); 467 } 468 469 // A cause de aCC qui ne veut pas char* b = "" 470 static char ChaineVide[2] = {'\0', '\0'}; 471 472 void 473 PInPersist::Scan() 474 { 475 // On parcourt le fichier depuis la fin pour identifier tous les tags 476 int_8 debut, prev, premier; 477 int_4 ntag, ntc, ll; 478 uint_2 ln; 479 char pad[4]; 480 481 #if defined(STREAMPOS_IS_CLASS) && !defined(RFIO) 482 debut = s->tellg().offset(); 483 #else 484 debut = s->tellg(); 485 #endif 486 487 premier = 0; 488 s->seekg(-(sizeof(int_8)+sizeof(int_4)), ios::end); 489 GetI8(prev); 490 GetI4(ntag); 491 if ( (ntag <= 0) || (prev < 0) ) 492 { s->seekg(debut,ios::beg); return; } 493 494 mNTags = ntag; 495 mTags = new PPFTag[ntag]; 496 497 PPFTag* tag; 498 while( (prev > 0) && (ntag > 0) ) { 499 s->seekg(prev); 500 if (ntag == 1) premier = prev; 501 GetI8(prev); 502 GetI4(ntc); 503 ntag--; 504 if (ntc != ntag) { 505 cerr << "PInPersist::Scan() / Error: NTag,TC= " << ntag << "," << ntc << endl; 506 THROW(fileErr); 507 } 508 tag = mTags+ntag; 509 GetI4(tag->key); 510 GetU2(ln); 511 if (ln > 0) { 512 tag->lnom = ln; 513 tag->nom = GetCStr(ln); 514 GetBytes(tag->nom, ln+1); 515 ll = 3-((ln+2)%4); 516 GetBytes(pad, ll); 517 } 518 else { 519 GetU2(ln); 520 tag->lnom = 0; 521 tag->nom = ChaineVide; 522 } 523 // On recupere la position pour l'objet qui suit 524 #ifdef STREAMPOS_IS_CLASS 525 tag->popos = s->tellg().offset(); 526 #else 527 tag->popos = s->tellg(); 528 #endif 529 530 GetI4(tag->cid); 531 } 532 533 if ( (ntag != 0) || (prev >= 0) ) { // En principe , ca ne doit pas arriver 534 cerr << "PInPersist::Scan() / Error: (End: ntag=" << ntag << 535 " prev=" << (int_4)prev << endl; 536 THROW(fileErr); 537 } 538 // on se repositionne au debut du 1er objet du fichier 539 if (premier == debut) GotoTag(0); 540 else s->seekg(debut); 541 return; 542 } 543 544 char* 545 PInPersist::GetCStr(uint_2 sz) 546 { 547 char* rs; 548 sz += 1; // Pour le 0 de la fin 549 if (sz > mSbsz) 550 { mSbsz = (sz > (MAXTAGNAMELEN+1)) ? sz : (MAXTAGNAMELEN+1); 551 mSbuf = new char[mSbsz]; mSbuffs.push_back(mSbuf); } 552 553 rs = mSbuf; 554 mSbuf += sz; 555 mSbsz -= sz; 556 return(rs); 557 } 265 266 // Find tag entries at end of file 267 s->seekg(-(sizeof(int_8)+1), ios::end); 268 GetRawByte(ppstype); 269 if (ppstype != PPS_EOF) 270 throw FileFormatExc("PInPersist::Scan corrupted file, no eof entry at end of file"); 271 272 int_8 pos; 273 GetRawI8(pos); 274 if (pos < 0) { // no tags 275 s->seekg(debut); 276 return; 277 } 278 279 char buffer[MAXTAGLEN+1]; 280 s->seekg(pos); 281 while (true) { 282 GetRawByte(ppstype); 283 if (ppstype == PPS_EOF) break; 284 285 if (ppstype != PPS_TAG) 286 throw FileFormatExc("PInPersist::Scan corrupted file, bad tag entry"); 287 288 GetRawI8(pos); 289 int_4 len; 290 GetRawI4(len); 291 if (len > MAXTAGLEN) 292 throw FileFormatExc("PInPersist::Scan corrupted file, tag name too long"); 293 GetRawBytes(buffer, len); 294 buffer[len] = '\0'; 295 296 tags[buffer] = pos; 297 } 298 s->seekg(debut); 299 } 300 558 301 559 302 bool 560 PInPersist::GotoTag(int_4 num) 561 { 562 if ( (num < 0) || (num >= mNTags) ) return(false); 563 s->seekg(mTags[num].popos); 303 PInPersist::GotoTag(string const& name) 304 { 305 map<string, int_8>::iterator i = tags.find(name); 306 if (i == tags.end()) 307 return false; 308 // throw NotFoundExc("PInPersist::GotoTag tag not found"); 309 s->seekg((*i).second); 564 310 return(true); 565 }566 567 bool568 PInPersist::GotoKey(int_4 key, int rang)569 {570 if (rang < 0) return(false);571 int n = 0, i;572 int fnd = -1;573 for(i=0; i<mNTags; i++)574 if (mTags[i].key == key) {575 if (n == rang) { fnd = i; break; }576 n++; }577 578 if (fnd >= 0) return(GotoTag(fnd));579 else return(false);580 }581 582 int583 PInPersist::NbKey(int_4 key)584 {585 int n = 0, i;586 for(i=0; i<mNTags; i++)587 if (mTags[i].key == key) n++;588 return(n);589 }590 591 void592 PInPersist::ListTags()593 {594 cout << "PInPersist/ File " << fName << "\n";595 cout << "Nb Tags in file : " << mNTags << "\n";596 string str;597 int i;598 for(i=0; i<mNTags; i++) {599 str = mTags[i].nom;600 cout << i << "- CId= " << mTags[i].cid << " Key= "601 << mTags[i].key << " ( " << str << " )\n" ;602 }603 cout << endl;604 return;605 }606 607 int_4608 PInPersist::TagKey(int_4 num, int_4& cid, int_4& ln)609 {610 if ( (num < 0) || (num >= mNTags) ) return(0);611 cid = mTags[num].cid; ln = mTags[num].lnom;612 return(mTags[num].key);613 }614 615 string616 PInPersist::TagName(int_4 num)617 {618 if ( (num < 0) || (num >= mNTags) ) return("");619 return((string)mTags[num].nom);620 311 } 621 312 … … 645 336 //-- 646 337 647 void648 PInPersist::GetByte(char& c)649 {650 GetBytes(&c, 1);651 }652 653 void654 PInPersist::GetBytes(void* ptr, size_t bytes)655 {656 s->read((char*)ptr, bytes);657 }658 338 659 339 static inline void bswap8(void* p) … … 686 366 } 687 367 368 369 void 370 PInPersist::GetRawByte(char& c) 371 { 372 GetRawBytes(&c, 1); 373 } 374 375 void 376 PInPersist::GetRawBytes(void* ptr, size_t bytes) 377 { 378 s->read((char*)ptr, bytes); 379 } 380 381 void 382 PInPersist::GetRawI2 (int_2& result) 383 { 384 GetRawBytes(&result, sizeof(int_2)); 385 if (bigEndian != IS_BIG_ENDIAN) 386 bswap2(&result); 387 } 388 389 void 390 PInPersist::GetRawI4 (int_4& result) 391 { 392 GetRawBytes(&result, sizeof(int_4)); 393 if (bigEndian != IS_BIG_ENDIAN) 394 bswap4(&result); 395 } 396 397 void 398 PInPersist::GetRawI8 (int_8& result) 399 { 400 GetRawBytes(&result, sizeof(int_8)); 401 if (bigEndian != IS_BIG_ENDIAN) 402 bswap8(&result); 403 } 404 405 void 406 PInPersist::GetRawU8 (uint_8& result) 407 { 408 GetRawBytes(&result, sizeof(uint_8)); 409 if (bigEndian != IS_BIG_ENDIAN) 410 bswap8(&result); 411 } 412 413 void 414 PInPersist::CheckTag(short datasz) 415 { 416 char ppstype; 417 GetRawByte(ppstype); 418 if (ppstype != PPS_SIMPLE + datasz) 419 throw TypeMismatchExc("PInPersist::CheckTag bad type in ppersist file"); 420 } 421 422 void 423 PInPersist::CheckArrayTag(short datasz, size_t sz) 424 { 425 char ppstype; 426 GetRawByte(ppstype); 427 size_t filesz; 428 if (sz <= 0x7fff) { 429 if (ppstype != PPS_SIMPLE_ARRAY + datasz) 430 throw TypeMismatchExc("PInPersist::CheckTag bad type in ppersist file"); 431 int_2 ff; 432 GetRawI2(ff); filesz=ff; 433 } else if (sz <= 0x7fffffff) { 434 if (ppstype != PPS_SIMPLE_ARRAY4 + datasz) 435 throw TypeMismatchExc("PInPersist::CheckTag bad type in ppersist file"); 436 int_4 ff; 437 GetRawI4(ff); filesz=ff; 438 } else { 439 if (ppstype != PPS_SIMPLE_ARRAY8 + datasz) 440 throw TypeMismatchExc("PInPersist::CheckTag bad type in ppersist file"); 441 uint_8 ff; 442 GetRawU8(ff); filesz=ff; 443 } 444 if (filesz != sz) 445 throw TypeMismatchExc("PInPersist::CheckTag bad array size in ppersist file"); 446 } 447 448 void 449 PInPersist::GetByte(char& c) 450 { 451 CheckTag(1); 452 GetRawBytes(&c, 1); 453 } 454 455 void 456 PInPersist::GetBytes(void* ptr, size_t bytes) 457 { 458 CheckArrayTag(1, bytes); 459 GetRawBytes(ptr, bytes); 460 } 688 461 void 689 462 PInPersist::GetR4 (r_4& result) 690 463 { 691 GetBytes(&result, sizeof(r_4)); 464 CheckTag(4); 465 GetRawBytes(&result, sizeof(r_4)); 692 466 if (bigEndian != IS_BIG_ENDIAN) 693 467 bswap4(&result); … … 698 472 PInPersist::GetR4s (r_4* tab, size_t n) 699 473 { 700 GetBytes(tab, n*sizeof(r_4)); 474 CheckArrayTag(4,n); 475 GetRawBytes(tab, n*sizeof(r_4)); 701 476 if (bigEndian == IS_BIG_ENDIAN) return; 702 477 … … 710 485 PInPersist::GetR8 (r_8& result) 711 486 { 712 GetBytes(&result, sizeof(r_8)); 487 CheckTag(8); 488 GetRawBytes(&result, sizeof(r_8)); 713 489 if (bigEndian != IS_BIG_ENDIAN) 714 490 bswap8(&result); … … 718 494 PInPersist::GetR8s (r_8* tab, size_t n) 719 495 { 720 GetBytes(tab, n*sizeof(r_8)); 496 CheckArrayTag(8,n); 497 GetRawBytes(tab, n*sizeof(r_8)); 721 498 if (bigEndian == IS_BIG_ENDIAN) return; 722 499 … … 730 507 PInPersist::GetI2 (int_2& result) 731 508 { 732 GetBytes(&result, sizeof(int_2)); 509 CheckTag(2); 510 GetRawBytes(&result, sizeof(int_2)); 733 511 if (bigEndian != IS_BIG_ENDIAN) 734 512 bswap2(&result); … … 738 516 PInPersist::GetI2s (int_2* tab, size_t n) 739 517 { 740 GetBytes(tab, n*sizeof(int_2)); 518 CheckArrayTag(2,n); 519 GetRawBytes(tab, n*sizeof(int_2)); 741 520 if (bigEndian == IS_BIG_ENDIAN) return; 742 521 … … 750 529 PInPersist::GetU2 (uint_2& result) 751 530 { 752 GetBytes(&result, sizeof(uint_2)); 531 CheckTag(2); 532 GetRawBytes(&result, sizeof(uint_2)); 753 533 if (bigEndian != IS_BIG_ENDIAN) 754 534 bswap2(&result); … … 758 538 PInPersist::GetU2s (uint_2* tab, size_t n) 759 539 { 760 GetBytes(tab, n*sizeof(uint_2)); 540 CheckArrayTag(2,n); 541 GetRawBytes(tab, n*sizeof(uint_2)); 761 542 if (bigEndian == IS_BIG_ENDIAN) return; 762 543 … … 770 551 PInPersist::GetI4 (int_4& result) 771 552 { 772 GetBytes(&result, sizeof(int_4)); 553 CheckTag(4); 554 GetRawBytes(&result, sizeof(int_4)); 773 555 if (bigEndian != IS_BIG_ENDIAN) 774 556 bswap4(&result); … … 778 560 PInPersist::GetI4s (int_4* tab, size_t n) 779 561 { 780 GetBytes(tab, n*sizeof(int_4)); 562 CheckArrayTag(4,n); 563 GetRawBytes(tab, n*sizeof(int_4)); 781 564 if (bigEndian == IS_BIG_ENDIAN) return; 782 565 … … 790 573 PInPersist::GetU4 (uint_4& result) 791 574 { 792 GetBytes(&result, sizeof(uint_4)); 575 CheckTag(4); 576 GetRawBytes(&result, sizeof(uint_4)); 793 577 if (bigEndian != IS_BIG_ENDIAN) 794 578 bswap4(&result); … … 798 582 PInPersist::GetU4s (uint_4* tab, size_t n) 799 583 { 800 GetBytes(tab, n*sizeof(uint_4)); 584 CheckArrayTag(4,n); 585 GetRawBytes(tab, n*sizeof(uint_4)); 801 586 if (bigEndian == IS_BIG_ENDIAN) return; 802 587 … … 811 596 PInPersist::GetI8 (int_8& result) 812 597 { 813 GetBytes(&result, sizeof(int_8)); 598 CheckTag(8); 599 GetRawBytes(&result, sizeof(int_8)); 814 600 if (bigEndian != IS_BIG_ENDIAN) 815 601 bswap8(&result); … … 819 605 PInPersist::GetI8s (int_8* tab, size_t n) 820 606 { 821 GetBytes(tab, n*sizeof(int_8)); 607 CheckArrayTag(8,n); 608 GetRawBytes(tab, n*sizeof(int_8)); 822 609 if (bigEndian == IS_BIG_ENDIAN) return; 823 610 … … 831 618 PInPersist::GetU8 (uint_8& result) 832 619 { 833 GetBytes(&result, sizeof(uint_8)); 620 CheckTag(8); 621 GetRawBytes(&result, sizeof(uint_8)); 834 622 if (bigEndian != IS_BIG_ENDIAN) 835 623 bswap8(&result); … … 839 627 PInPersist::GetU8s (uint_8* tab, size_t n) 840 628 { 841 GetBytes(tab, n*sizeof(uint_8)); 629 CheckArrayTag(8,n); 630 GetRawBytes(tab, n*sizeof(uint_8)); 842 631 if (bigEndian == IS_BIG_ENDIAN) return; 843 632 … … 852 641 PInPersist::GetLine(char* ptr, size_t len) 853 642 { 854 s->getline(ptr, len, PIOP_Delim); 855 } 856 643 char ppstype; 644 GetRawByte(ppstype); 645 if (ppstype != PPS_LINE) 646 throw TypeMismatchExc("PInPersist::GetLine bad type in ppersist file"); 647 s->getline(ptr, len, '\n'); 648 } 649 650 void 651 PInPersist::GetStr(string& str) 652 { 653 char ppstype; 654 GetRawByte(ppstype); 655 if (ppstype != PPS_STRING) 656 throw TypeMismatchExc("PInPersist::GetLine bad type in ppersist file"); 657 int_2 len; 658 GetRawI2(len); 659 char * buff = new char(len+1); 660 GetRawBytes(buff, len); 661 buff[len] = '\0'; 662 str = buff; 663 delete[] buff; 664 } 665 666 PPersist* 667 PInPersist::ReadObject() 668 { 669 // Get tag 670 char ppstype; 671 GetRawByte(ppstype); 672 if (ppstype != PPS_OBJECT && ppstype != PPS_REFERENCE && ppstype != PPS_NULL) { 673 throw TypeMismatchExc("PInPersist::ReadObject : not an object in flow"); 674 } 675 676 if (ppstype == PPS_NULL) { 677 return NULL; 678 } else if (ppstype == PPS_OBJECT) { 679 // Get class id 680 uint_8 classId; 681 GetRawU8(classId); 682 683 // Get factory method 684 ClassCreatorFunc f = FindCreatorFunc(classId); 685 if (!f) { 686 throw NotFoundExc("PInPersist::ReadObject class not registered"); 687 } 688 689 // Create object 690 PPersist* object = f(); 691 object->ReadSelf(*this); 692 assignObjectId(object); 693 return object; 694 } else { 695 // Get object id 696 int_4 id; 697 GetRawI4(id); 698 if (id <0 || id>=objList.size()) { 699 throw FileFormatExc("PInPersist::ReadObject invalid object id for reference"); 700 } 701 return objList[id]; 702 } 703 } 704 705 int_4 706 PInPersist::assignObjectId(PPersist* x) 707 { 708 objList.push_back(x); 709 return objList.size()-1; 710 } 857 711 858 712 //++ … … 880 734 bigEndian = endianness; 881 735 882 #ifdef RFIO 883 s = new erosofstream(flnm.c_str(),"wb"); 736 // Output stream creation 737 s = new ofstream(flnm.c_str(),ios::out | IOS_BIN); 738 739 // Header 740 PutRawBytes("PlanckDPC-PPersistFile V1 ",32); 741 PutRawBytes(bigEndian 742 ? "BIG-ENDIAN " 743 : "LITTLE-ENDIAN ",32); 744 745 // ---- GMT creation date of the file 746 time_t tm = time(NULL); 747 char datestring[33]; 748 int l=strftime(datestring,32,"%d/%m/%Y %T GMT",gmtime(&tm)); 749 for(int i=l; i<32; i++) datestring[i] = ' '; 750 datestring[32] = '\0'; 751 PutRawBytes(datestring, 32); 752 } 753 754 POutPersist::~POutPersist() 755 { 756 if (tags.size() == 0) { 757 PutRawByte(PPS_EOF); 758 PutRawI8(-1); 759 } else { 760 int_8 tagPos; 761 #ifdef STREAMPOS_IS_CLASS 762 tagPos = s->tellp().offset(); 884 763 #else 885 #if defined(__MWERKS__) 886 s = new ofstream(flnm.c_str(),ios::out | ios::binary); // ios::binary pas connnu partout - $CHECK$ Reza 13/02/98 887 #else 888 s = new ofstream(flnm.c_str(),ios::out ); 764 tagPos = s->tellp(); 889 765 #endif 890 #endif 891 PPersistMgr::Reset(); 892 PutBytes("PEIDA-PPersistFile V5 ",32); 893 PutBytes(bigEndian 894 ? "BIG-ENDIAN " 895 : "LITTLE-ENDIAN ",32); 896 // ---- On ecrit la date de creation a partir de V5 897 Date today; 898 string stod = today.DateStr(Date::kLocalTime) + "#" + today.TimeStr(Date::kLocalTime); 899 char buff[36]; 900 int l = stod.length(); 901 if (l < 33) strcpy(buff, stod.c_str()); 902 else strncpy(buff, stod.c_str(), 33); 903 for(int i=l+1; i<32; i++) buff[i] = ' '; 904 buff[32] = '\0'; 905 PutBytes(buff, 32); 906 // Fin d'ecriture de date -------- 907 previous = -1; // Pas de Tag precedant 908 numTag = 0; 909 } 910 911 POutPersist::~POutPersist() 912 { 913 PutI8(previous); 914 PutI4(numTag); 915 delete s; 916 PPersistMgr::Reset(); 917 } 918 919 920 int_4 921 POutPersist::WriteTag(int_4 key, char const * nom) 922 { 923 int_8 nexprev; 924 uint_2 l; 925 int ll; 926 char pad[4] = {'\0', '\0', '\0', '\0'}; 766 for (map<string,int_8>::iterator i = tags.begin(); i != tags.end(); i++) { 767 string name = (*i).first; 768 int_8 pos = (*i).second; 769 PutRawByte(PPS_TAG); // This is a tag 770 PutRawI8(pos); // position of previous tag 771 PutRawI4(name.length()); // length of the name 772 PutRawBytes(name.c_str(), name.length()); // name, without final "0". 773 } 774 PutRawByte(PPS_EOF); 775 PutRawI8(tagPos); 776 } 777 778 delete s; // Close the stream 779 } 780 781 782 void 783 POutPersist::WriteTag(string const& name) 784 { 785 if (name.length() > MAXTAGLEN) 786 throw ParmError("POutPersist::WriteTag tag name too long"); 787 788 if (tags.find(name) != tags.end()) 789 throw DuplicateIdExc("POutPersist::WriteTag duplicate tag name"); 790 791 // Get current file position 792 int_8 tagPos; 927 793 928 794 #ifdef STREAMPOS_IS_CLASS 929 nexprev= s->tellp().offset();795 tagPos = s->tellp().offset(); 930 796 #else 931 nexprev= s->tellp();797 tagPos = s->tellp(); 932 798 #endif 933 // On ecrit dans l'ordre 934 // - La position du tag precedant (-1 s'il n'y en a pas) 935 // - Le numero de tag ( qui s incremete automatiquement ) 936 // - La cle utilisateur (key) 937 // - La longueur du nom 938 // - le nom lui-meme (Avec un pad afin de faire nom+longueur=multiple de 4) 939 PutI8(previous); 940 PutI4(numTag); 941 PutI4(key); 942 if (nom==NULL) { 943 PutU2(0); PutU2(0); 944 } 945 else { 946 ll = strlen(nom); 947 if (ll <= 0) { 948 PutU2(0); PutU2(0); 949 } 950 l = (ll <= MAXTAGNAMELEN) ? ll : MAXTAGNAMELEN ; 951 PutU2(l); 952 PutBytes(nom,l+1); 953 ll = 3-((ll+2)%4); 954 PutBytes(pad, ll); 955 } 956 previous = nexprev; 957 numTag++; 958 return((numTag-1)); 799 800 tags[name] = tagPos; 959 801 } 960 802 … … 978 820 // void POutPersist::PutU8 (uint_8 result) 979 821 // void POutPersist::PutU8s (uint_8 const* tab, size_t n) 822 // void POutPersist::PutStr (string const&) 980 823 // Ecriture de données portables.. Pour chaque type 981 824 // de données, on peut écrire une valeur, ou un tableau de valeurs. … … 988 831 989 832 void 833 POutPersist::PutRawBytes(void const* ptr, size_t bytes) 834 { 835 s->write((char const*)ptr, bytes); 836 } 837 838 void 839 POutPersist::PutRawByte(char c) 840 { 841 PutRawBytes(&c, 1); 842 } 843 844 void 845 POutPersist::PutRawI2 (int_2 val) 846 { 847 if (bigEndian != IS_BIG_ENDIAN) 848 bswap2(&val); 849 850 PutRawBytes(&val, sizeof(int_2)); 851 } 852 853 void 854 POutPersist::PutRawI4 (int_4 val) 855 { 856 if (bigEndian != IS_BIG_ENDIAN) 857 bswap4(&val); 858 859 PutRawBytes(&val, sizeof(int_4)); 860 } 861 862 void 863 POutPersist::PutRawI8 (int_8 val) 864 { 865 if (bigEndian != IS_BIG_ENDIAN) 866 bswap8(&val); 867 868 PutRawBytes(&val, sizeof(int_8)); 869 } 870 871 void 872 POutPersist::PutRawU8 (uint_8 val) 873 { 874 if (bigEndian != IS_BIG_ENDIAN) 875 bswap8(&val); 876 877 PutRawBytes(&val, sizeof(uint_8)); 878 } 879 880 void 881 POutPersist::PutArrayTag(short datasz, size_t sz) 882 { 883 if (sz <= 0x7fff) { 884 PutRawByte(PPS_SIMPLE_ARRAY + datasz); 885 PutRawI2(sz); 886 } else if (sz <= 0x7fffffff) { 887 PutRawByte(PPS_SIMPLE_ARRAY4 + datasz); 888 PutRawI4(sz); 889 } else { 890 PutRawByte(PPS_SIMPLE_ARRAY8 + datasz); 891 PutRawU8(sz); 892 } 893 } 894 895 void 990 896 POutPersist::PutByte(char c) 991 897 { 992 PutBytes(&c, 1); 993 } 898 PutRawByte(PPS_SIMPLE + 1); 899 PutRawBytes(&c, 1); 900 } 901 902 994 903 995 904 void 996 905 POutPersist::PutBytes(void const* ptr, size_t bytes) 997 906 { 998 s->write((char const*)ptr, bytes); 907 PutArrayTag(1, bytes); 908 PutRawBytes(ptr, bytes); 999 909 } 1000 910 … … 1002 912 POutPersist::PutR4 (r_4 val) 1003 913 { 914 PutRawByte(PPS_SIMPLE + 4); 915 1004 916 if (bigEndian != IS_BIG_ENDIAN) 1005 917 bswap4(&val); 1006 918 1007 Put Bytes(&val, sizeof(r_4));919 PutRawBytes(&val, sizeof(r_4)); 1008 920 } 1009 921 … … 1011 923 POutPersist::PutR4s (r_4 const* tab, size_t n) 1012 924 { 1013 if (bigEndian == IS_BIG_ENDIAN) 1014 PutBytes(tab, n*sizeof(r_4)); 1015 else 1016 for (unsigned int i=0; i<n; i++) 1017 PutR4(tab[i]); 925 PutArrayTag(4, n); 926 927 if (bigEndian == IS_BIG_ENDIAN) { 928 PutRawBytes(tab, n*sizeof(r_4)); 929 } else { 930 for (unsigned int i=0; i<n; i++) { 931 r_4 val = tab[i]; 932 bswap4(&val); 933 PutRawBytes(&val, sizeof(r_4)); 934 } 935 } 1018 936 } 1019 937 … … 1021 939 POutPersist::PutR8 (r_8 val) 1022 940 { 941 PutRawByte(PPS_SIMPLE + 8); 942 1023 943 if (bigEndian != IS_BIG_ENDIAN) 1024 944 bswap8(&val); 1025 945 1026 Put Bytes(&val, sizeof(r_8));946 PutRawBytes(&val, sizeof(r_8)); 1027 947 } 1028 948 … … 1030 950 POutPersist::PutR8s (r_8 const* tab, size_t n) 1031 951 { 1032 if (bigEndian == IS_BIG_ENDIAN) 1033 PutBytes(tab, n*sizeof(r_8)); 1034 else 1035 for (unsigned int i=0; i<n; i++) 1036 PutR8(tab[i]); 952 PutArrayTag(8, n); 953 954 if (bigEndian == IS_BIG_ENDIAN) { 955 PutRawBytes(tab, n*sizeof(r_8)); 956 } else { 957 for (unsigned int i=0; i<n; i++) { 958 r_8 val = tab[i]; 959 bswap8(&val); 960 PutRawBytes(&val, sizeof(r_8)); 961 } 962 } 1037 963 } 1038 964 … … 1040 966 POutPersist::PutI2 (int_2 val) 1041 967 { 968 PutRawByte(PPS_SIMPLE + 2); 969 1042 970 if (bigEndian != IS_BIG_ENDIAN) 1043 971 bswap2(&val); 1044 972 1045 Put Bytes(&val, sizeof(int_2));973 PutRawBytes(&val, sizeof(int_2)); 1046 974 } 1047 975 … … 1049 977 POutPersist::PutI2s (int_2 const* tab, size_t n) 1050 978 { 1051 if (bigEndian == IS_BIG_ENDIAN) 1052 PutBytes(tab, n*sizeof(int_2)); 1053 else 1054 for (unsigned int i=0; i<n; i++) 1055 PutI2(tab[i]); 979 PutArrayTag(2, n); 980 981 if (bigEndian == IS_BIG_ENDIAN) { 982 PutRawBytes(tab, n*sizeof(int_2)); 983 } else { 984 for (unsigned int i=0; i<n; i++) { 985 int_2 val = tab[i]; 986 bswap2(&val); 987 PutRawBytes(&val, sizeof(int_2)); 988 } 989 } 1056 990 } 1057 991 … … 1059 993 POutPersist::PutU2 (uint_2 val) 1060 994 { 995 PutRawByte(PPS_SIMPLE + 2); 996 1061 997 if (bigEndian != IS_BIG_ENDIAN) 1062 998 bswap2(&val); 1063 999 1064 Put Bytes(&val, sizeof(uint_2));1000 PutRawBytes(&val, sizeof(uint_2)); 1065 1001 } 1066 1002 … … 1068 1004 POutPersist::PutU2s (uint_2 const* tab, size_t n) 1069 1005 { 1070 if (bigEndian == IS_BIG_ENDIAN) 1071 PutBytes(tab, n*sizeof(uint_2)); 1072 else 1073 for (unsigned int i=0; i<n; i++) 1074 PutU2(tab[i]); 1006 PutArrayTag(2, n); 1007 1008 if (bigEndian == IS_BIG_ENDIAN) { 1009 PutRawBytes(tab, n*sizeof(uint_2)); 1010 } else { 1011 for (unsigned int i=0; i<n; i++) { 1012 uint_2 val = tab[i]; 1013 bswap2(&val); 1014 PutRawBytes(&val, sizeof(uint_2)); 1015 } 1016 } 1075 1017 } 1076 1018 … … 1078 1020 POutPersist::PutI4 (int_4 val) 1079 1021 { 1022 PutRawByte(PPS_SIMPLE + 4); 1023 1080 1024 if (bigEndian != IS_BIG_ENDIAN) 1081 1025 bswap4(&val); 1082 1026 1083 Put Bytes(&val, sizeof(int_4));1027 PutRawBytes(&val, sizeof(int_4)); 1084 1028 } 1085 1029 … … 1087 1031 POutPersist::PutI4s (int_4 const* tab, size_t n) 1088 1032 { 1089 if (bigEndian == IS_BIG_ENDIAN) 1090 PutBytes(tab, n*sizeof(int_4)); 1091 else 1092 for (unsigned int i=0; i<n; i++) 1093 PutI4(tab[i]); 1033 PutArrayTag(4, n); 1034 1035 if (bigEndian == IS_BIG_ENDIAN) { 1036 PutRawBytes(tab, n*sizeof(int_4)); 1037 } else { 1038 for (unsigned int i=0; i<n; i++) { 1039 int_4 val = tab[i]; 1040 bswap4(&val); 1041 PutRawBytes(&val, sizeof(int_4)); 1042 } 1043 } 1094 1044 } 1095 1045 … … 1097 1047 POutPersist::PutU4 (uint_4 val) 1098 1048 { 1049 PutRawByte(PPS_SIMPLE + 4); 1050 1099 1051 if (bigEndian != IS_BIG_ENDIAN) 1100 1052 bswap4(&val); 1101 1053 1102 Put Bytes(&val, sizeof(uint_4));1054 PutRawBytes(&val, sizeof(uint_4)); 1103 1055 } 1104 1056 … … 1106 1058 POutPersist::PutU4s (uint_4 const* tab, size_t n) 1107 1059 { 1108 if (bigEndian == IS_BIG_ENDIAN) 1109 PutBytes(tab, n*sizeof(uint_4)); 1110 else 1111 for (unsigned int i=0; i<n; i++) 1112 PutU4(tab[i]); 1060 PutArrayTag(4, n); 1061 1062 if (bigEndian == IS_BIG_ENDIAN) { 1063 PutRawBytes(tab, n*sizeof(uint_4)); 1064 } else { 1065 for (unsigned int i=0; i<n; i++) { 1066 uint_4 val = tab[i]; 1067 bswap4(&val); 1068 PutRawBytes(&val, sizeof(uint_4)); 1069 } 1070 } 1113 1071 } 1114 1072 … … 1116 1074 POutPersist::PutI8 (int_8 val) 1117 1075 { 1076 PutRawByte(PPS_SIMPLE + 8); 1077 1118 1078 if (bigEndian != IS_BIG_ENDIAN) 1119 1079 bswap8(&val); 1120 1080 1121 Put Bytes(&val, sizeof(int_8));1081 PutRawBytes(&val, sizeof(int_8)); 1122 1082 } 1123 1083 … … 1125 1085 POutPersist::PutI8s (int_8 const* tab, size_t n) 1126 1086 { 1127 if (bigEndian == IS_BIG_ENDIAN) 1128 PutBytes(tab, n*sizeof(int_8)); 1129 else 1130 for (unsigned int i=0; i<n; i++) 1131 PutI8(tab[i]); 1087 PutArrayTag(8, n); 1088 1089 if (bigEndian == IS_BIG_ENDIAN) { 1090 PutRawBytes(tab, n*sizeof(int_8)); 1091 } else { 1092 for (unsigned int i=0; i<n; i++) { 1093 int_8 val = tab[i]; 1094 bswap8(&val); 1095 PutRawBytes(&val, sizeof(int_8)); 1096 } 1097 } 1132 1098 } 1133 1099 … … 1135 1101 POutPersist::PutU8 (uint_8 val) 1136 1102 { 1103 PutRawByte(PPS_SIMPLE + 8); 1104 1137 1105 if (bigEndian != IS_BIG_ENDIAN) 1138 1106 bswap8(&val); 1139 1107 1140 Put Bytes(&val, sizeof(uint_8));1108 PutRawBytes(&val, sizeof(uint_8)); 1141 1109 } 1142 1110 … … 1144 1112 POutPersist::PutU8s (uint_8 const* tab, size_t n) 1145 1113 { 1146 if (bigEndian == IS_BIG_ENDIAN) 1147 PutBytes(tab, n*sizeof(uint_8)); 1148 else 1149 for (unsigned int i=0; i<n; i++) 1150 PutU8(tab[i]); 1114 PutArrayTag(8, n); 1115 1116 if (bigEndian == IS_BIG_ENDIAN) { 1117 PutRawBytes(tab, n*sizeof(uint_8)); 1118 } else { 1119 for (unsigned int i=0; i<n; i++) { 1120 uint_8 val = tab[i]; 1121 bswap8(&val); 1122 PutRawBytes(&val, sizeof(uint_8)); 1123 } 1124 } 1125 } 1126 1127 void 1128 POutPersist::PutStr(string const& str) 1129 { 1130 PutRawByte(PPS_STRING); 1131 PutRawI2(str.length()); 1132 PutRawBytes(str.c_str(), str.length()); 1151 1133 } 1152 1134 … … 1154 1136 POutPersist::PutLine(char const* ptr, size_t len) 1155 1137 { 1138 PutRawByte(PPS_LINE); 1139 1156 1140 if (len == 0) len = strlen(ptr); 1157 s->write(ptr, len); 1158 #ifdef RFIO 1159 char cd = PIOP_Delim; 1160 s->write(&cd, 1); 1161 #else 1162 s->put(PIOP_Delim); 1163 #endif 1141 PutRawBytes(ptr, len); 1142 PutRawByte('\n'); 1143 } 1144 1145 void 1146 POutPersist::PutObject(PPersist const* obj) 1147 { 1148 if (serializeNullAndRepeat(obj)) return; 1149 1150 PutRawByte(PPS_OBJECT); 1151 PutRawU8(PIOPersist::Hash(typeid(*obj).name())); 1152 assignObjectId(obj); 1153 obj->WriteSelf(*this); 1154 } 1155 1156 bool 1157 POutPersist::serializeNullAndRepeat(PPersist const* x) 1158 { 1159 if (x == NULL) { 1160 PutRawByte(PPS_NULL); 1161 return true; 1162 } 1163 1164 int_4 id = findObjectId(x); 1165 if (id >= 0) { 1166 PutRawByte(PPS_REFERENCE); 1167 PutRawI4(id); 1168 return true; 1169 } 1164 1170 1165 } 1166 1167 1168 // --- Classe d'initialisation de PEIDA++, (PPersistMgr en particulier) 1169 int PeidaInitiator::FgInit = 0; 1170 1171 PeidaInitiator::PeidaInitiator() 1172 { 1173 FgInit++; 1174 if (FgInit > 1) return; 1175 1176 InitFailNewHandler(); 1177 1178 #ifdef xx__mac__ 1179 //InitToolBox(); 1180 //SIOUXSettings.initializeTB = FALSE; 1181 SIOUXSettings.autocloseonquit = FALSE; 1182 SIOUXSettings.asktosaveonclose = FALSE; 1183 SIOUXSettings.showstatusline = TRUE; 1184 #endif 1185 1186 PPersistMgr::classList = new PPersistMgr::ClassList; 1187 PShPersist::objList = new PShPersist::ObjList; 1188 1189 1190 #if (!defined(__GNUG__) && !defined(__MWERKS__) && !defined(HPUX)) 1191 // pas de bufferisation pour printf cmv 18/3/97 selon E.A. 1192 // setvbuf(stdout,NULL,_IOLBF,0); setvbuf(stderr,NULL,_IOLBF,0); 1193 setlinebuf(stdout); 1194 setlinebuf(stderr); 1195 #endif 1196 1197 // si var env PEIDA_NOPRTVER definie pas de print 1198 if(!getenv("PEIDA_NOPRTVER")) PrintPeidaVersion(); 1199 } 1200 1201 PeidaInitiator::~PeidaInitiator() 1202 { 1203 FgInit--; 1204 if (FgInit == 0) 1205 { 1206 delete PPersistMgr::classList; PPersistMgr::classList = NULL; 1207 delete PShPersist::objList; PShPersist::objList = NULL; 1208 } 1209 } 1210 1211 double PeidaInitiator::Version(bool fgprt) 1212 { 1213 if (fgprt) PrintPeidaVersion(); 1214 return(PeidaVersion()); 1215 } 1216 1217 // On met un objet initiator en statique, pour les loaders qui savent 1218 // appeler le constructeur des objets statiques Reza 08/98 1219 static PeidaInitiator ppeidainit; 1220 1171 return false; 1172 } 1173 1174 int_4 1175 POutPersist::assignObjectId(PPersist const* x) 1176 { 1177 int_4 id = objList.size(); 1178 objList[x] = id; 1179 return id; 1180 } 1181 1182 int_4 1183 POutPersist::findObjectId(PPersist const* x) 1184 { 1185 ObjList::iterator i = objList.find(x); 1186 if (i == objList.end()) return -1; 1187 return (*i).second; 1188 } 1189 1190
Note:
See TracChangeset
for help on using the changeset viewer.