Changeset 241 in Sophya for trunk/SophyaLib/BaseTools/ppersist.cc


Ignore:
Timestamp:
Apr 21, 1999, 3:12:11 PM (26 years ago)
Author:
ansari
Message:

ppersist + pexc

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"
    23#include <stdio.h>
    34#include "peidainit.h"
    45#include "ppersist.h"
    5 #include "dates.h"
    6 
    7 #ifndef RFIO
    86#include <fstream.h>
    9 #endif
     7#include <typeinfo>
    108
    119
     
    1513#endif
    1614
    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
     15using namespace PlanckDPC;
     16
     17#define MAXTAGLEN 255
     18
     19//++
     20// Class        PIOPersist
    2521// Lib          Outils++
    2622// include      ppersist.h
    2723//
    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
    3530// 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
     36MD5_CTX PIOPersist::ctx;
     37PIOPersist::ClassList PIOPersist::classList;
     38
     39
     40//++
     41void
     42PIOPersist::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())) {
    6052      cerr << "RegisterClass : Error, " << hex << classId << dec
    6153           << " already registered." << endl;
    62       THROW(dupIdErr);
     54      throw(DuplicateIdExc("PIOPersist::RegisterClass"));
    6355    }
    6456 
    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
     61PIOPersist::ClassCreatorFunc
     62PIOPersist::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
    14569
    14670//++
     
    16892
    16993//++
    170 // Links        Voir
     94// Links        See
    17195// PInPersist
    17296// 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//--
    18399 
    184100//++
     
    213129//--
    214130{
    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);
    219132}
    220133
     
    226139//      Relit l'objet dans le fichier ppersist. Il faut connaître a priori
    227140//      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//++
     164void
     165PPersist::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//++
     175void
     176PPersist::ReadAtTag(PInPersist& s, string const& tag)
    281177//
    282178//      Lit l'objet à la position du tag numéro "tagid".
    283179//--
    284180{
    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
    309186
    310187//++
     
    320197
    321198
    322 //++
    323 // Class        PShPersist
    324 // Lib          Outils++
    325 // include      ppersist.h
    326 //
    327 //      Classe de base pour des objets persistants partagés.
    328 //      Un tel objet ne sera écrit qu'une seule fois dans un fichier
    329 //      donné. Les tentatives suivantes d'écriture n'écrivent qu'une
    330 //      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        Parents
    338 // PPersist
    339 //--
    340 
    341 //++
    342 void
    343 PShPersist::Write(POutPersist& s) const
    344 //
    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 type
    352    
    353    s << ClassId();
    354 
    355    // On doit ensuite ecrire notre identificateur et le flag d'ecriture
    356    
    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'ecrit
    366    
    367    if (write)
    368      WriteSelf(s);
    369 }
    370 
    371 PShPersist::~PShPersist()  // Une securite peut-etre facultative
    372 {
    373   DBASSERT(objList);
    374   if (mObjectID) {
    375     DBASSERT(!objList->size() && (objList->find(mObjectID) != objList->end()));
    376     objList->erase(mObjectID);
    377   }
    378 }
    379 
    380 void
    381 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 facultative
    387 
    388   PShPersist::objList->erase(PShPersist::objList->begin(), PShPersist::objList->end());
    389 }
    390 
    391 #define PIOP_Delim  '\n'   // Delimiteur de ligne
    392 //  Les noms ne peuvent depasser 255 caracteres 
    393 #define MAXTAGNAMELEN  255   
    394199
    395200//++
     
    407212//--
    408213{
    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
     247PInPersist::~PInPersist()
     248{
     249  delete s;
     250}
     251
     252
     253void
     254PInPersist::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();
    416262#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();
    423264#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
    558301
    559302bool
    560 PInPersist::GotoTag(int_4 num)
    561 {
    562   if ( (num < 0) || (num >= mNTags) )  return(false);
    563   s->seekg(mTags[num].popos);
     303PInPersist::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);
    564310  return(true);
    565 }
    566 
    567 bool
    568 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 int
    583 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 void
    592 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_4
    608 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 string
    616 PInPersist::TagName(int_4 num)
    617 {
    618   if ( (num < 0) || (num >= mNTags) )  return("");
    619   return((string)mTags[num].nom);
    620311}
    621312
     
    645336//--
    646337
    647 void
    648 PInPersist::GetByte(char& c)
    649 {
    650   GetBytes(&c, 1);
    651 }
    652 
    653 void
    654 PInPersist::GetBytes(void* ptr, size_t bytes)
    655 {
    656   s->read((char*)ptr, bytes);
    657 }
    658338
    659339static inline void bswap8(void* p)
     
    686366}
    687367
     368
     369void
     370PInPersist::GetRawByte(char& c)
     371{
     372  GetRawBytes(&c, 1);
     373}
     374
     375void
     376PInPersist::GetRawBytes(void* ptr, size_t bytes)
     377{
     378  s->read((char*)ptr, bytes);
     379}
     380
     381void
     382PInPersist::GetRawI2   (int_2& result)
     383{
     384  GetRawBytes(&result, sizeof(int_2));
     385  if (bigEndian != IS_BIG_ENDIAN)
     386    bswap2(&result);
     387}
     388
     389void
     390PInPersist::GetRawI4   (int_4& result)
     391{
     392  GetRawBytes(&result, sizeof(int_4));
     393  if (bigEndian != IS_BIG_ENDIAN)
     394    bswap4(&result);
     395}
     396
     397void
     398PInPersist::GetRawI8   (int_8& result)
     399{
     400  GetRawBytes(&result, sizeof(int_8));
     401  if (bigEndian != IS_BIG_ENDIAN)
     402    bswap8(&result);
     403}
     404
     405void
     406PInPersist::GetRawU8   (uint_8& result)
     407{
     408  GetRawBytes(&result, sizeof(uint_8));
     409  if (bigEndian != IS_BIG_ENDIAN)
     410    bswap8(&result);
     411}
     412
     413void
     414PInPersist::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
     422void
     423PInPersist::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
     448void
     449PInPersist::GetByte(char& c)
     450{
     451  CheckTag(1);
     452  GetRawBytes(&c, 1);
     453}
     454
     455void
     456PInPersist::GetBytes(void* ptr, size_t bytes)
     457{
     458  CheckArrayTag(1, bytes);
     459  GetRawBytes(ptr, bytes);
     460}
    688461void
    689462PInPersist::GetR4   (r_4& result)
    690463{
    691   GetBytes(&result, sizeof(r_4));
     464  CheckTag(4);
     465  GetRawBytes(&result, sizeof(r_4));
    692466  if (bigEndian != IS_BIG_ENDIAN)
    693467    bswap4(&result);
     
    698472PInPersist::GetR4s  (r_4* tab, size_t n)
    699473{
    700   GetBytes(tab, n*sizeof(r_4));
     474  CheckArrayTag(4,n);
     475  GetRawBytes(tab, n*sizeof(r_4));
    701476  if (bigEndian == IS_BIG_ENDIAN) return;
    702477
     
    710485PInPersist::GetR8   (r_8& result)
    711486{
    712   GetBytes(&result, sizeof(r_8));
     487  CheckTag(8);
     488  GetRawBytes(&result, sizeof(r_8));
    713489  if (bigEndian != IS_BIG_ENDIAN)
    714490    bswap8(&result);
     
    718494PInPersist::GetR8s  (r_8* tab, size_t n)
    719495{
    720   GetBytes(tab, n*sizeof(r_8));
     496  CheckArrayTag(8,n);
     497  GetRawBytes(tab, n*sizeof(r_8));
    721498  if (bigEndian == IS_BIG_ENDIAN) return;
    722499
     
    730507PInPersist::GetI2   (int_2& result)
    731508{
    732   GetBytes(&result, sizeof(int_2));
     509  CheckTag(2);
     510  GetRawBytes(&result, sizeof(int_2));
    733511  if (bigEndian != IS_BIG_ENDIAN)
    734512    bswap2(&result);
     
    738516PInPersist::GetI2s  (int_2* tab, size_t n)
    739517{
    740   GetBytes(tab, n*sizeof(int_2));
     518  CheckArrayTag(2,n);
     519  GetRawBytes(tab, n*sizeof(int_2));
    741520  if (bigEndian == IS_BIG_ENDIAN) return;
    742521
     
    750529PInPersist::GetU2   (uint_2& result)
    751530{
    752   GetBytes(&result, sizeof(uint_2));
     531  CheckTag(2);
     532  GetRawBytes(&result, sizeof(uint_2));
    753533  if (bigEndian != IS_BIG_ENDIAN)
    754534    bswap2(&result);
     
    758538PInPersist::GetU2s  (uint_2* tab, size_t n)
    759539{
    760   GetBytes(tab, n*sizeof(uint_2));
     540  CheckArrayTag(2,n);
     541  GetRawBytes(tab, n*sizeof(uint_2));
    761542  if (bigEndian == IS_BIG_ENDIAN) return;
    762543
     
    770551PInPersist::GetI4   (int_4& result)
    771552{
    772   GetBytes(&result, sizeof(int_4));
     553  CheckTag(4);
     554  GetRawBytes(&result, sizeof(int_4));
    773555  if (bigEndian != IS_BIG_ENDIAN)
    774556    bswap4(&result);
     
    778560PInPersist::GetI4s  (int_4* tab, size_t n)
    779561{
    780   GetBytes(tab, n*sizeof(int_4));
     562  CheckArrayTag(4,n);
     563  GetRawBytes(tab, n*sizeof(int_4));
    781564  if (bigEndian == IS_BIG_ENDIAN) return;
    782565
     
    790573PInPersist::GetU4   (uint_4& result)
    791574{
    792   GetBytes(&result, sizeof(uint_4));
     575  CheckTag(4);
     576  GetRawBytes(&result, sizeof(uint_4));
    793577  if (bigEndian != IS_BIG_ENDIAN)
    794578    bswap4(&result);
     
    798582PInPersist::GetU4s  (uint_4* tab, size_t n)
    799583{
    800   GetBytes(tab, n*sizeof(uint_4));
     584  CheckArrayTag(4,n);
     585  GetRawBytes(tab, n*sizeof(uint_4));
    801586  if (bigEndian == IS_BIG_ENDIAN) return;
    802587
     
    811596PInPersist::GetI8   (int_8& result)
    812597{
    813   GetBytes(&result, sizeof(int_8));
     598  CheckTag(8);
     599  GetRawBytes(&result, sizeof(int_8));
    814600  if (bigEndian != IS_BIG_ENDIAN)
    815601    bswap8(&result);
     
    819605PInPersist::GetI8s  (int_8* tab, size_t n)
    820606{
    821   GetBytes(tab, n*sizeof(int_8));
     607  CheckArrayTag(8,n);
     608  GetRawBytes(tab, n*sizeof(int_8));
    822609  if (bigEndian == IS_BIG_ENDIAN) return;
    823610
     
    831618PInPersist::GetU8   (uint_8& result)
    832619{
    833   GetBytes(&result, sizeof(uint_8));
     620  CheckTag(8);
     621  GetRawBytes(&result, sizeof(uint_8));
    834622  if (bigEndian != IS_BIG_ENDIAN)
    835623    bswap8(&result);
     
    839627PInPersist::GetU8s  (uint_8* tab, size_t n)
    840628{
    841   GetBytes(tab, n*sizeof(uint_8));
     629  CheckArrayTag(8,n);
     630  GetRawBytes(tab, n*sizeof(uint_8));
    842631  if (bigEndian == IS_BIG_ENDIAN) return;
    843632
     
    852641PInPersist::GetLine(char* ptr, size_t len)
    853642{
    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
     650void
     651PInPersist::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
     666PPersist*
     667PInPersist::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
     705int_4
     706PInPersist::assignObjectId(PPersist* x)
     707{
     708  objList.push_back(x);
     709  return objList.size()-1;
     710}
    857711
    858712//++
     
    880734    bigEndian = endianness;
    881735
    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
     754POutPersist::~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();
    884763#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();
    889765#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
     782void
     783POutPersist::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;
    927793
    928794  #ifdef STREAMPOS_IS_CLASS
    929   nexprev = s->tellp().offset();
     795  tagPos = s->tellp().offset();
    930796  #else
    931   nexprev = s->tellp();
     797  tagPos = s->tellp();
    932798  #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;
    959801}
    960802
     
    978820// void POutPersist::PutU8   (uint_8 result)
    979821// void POutPersist::PutU8s  (uint_8 const* tab, size_t n)
     822// void POutPersist::PutStr  (string const&)
    980823//      Ecriture de données portables.. Pour chaque type
    981824//      de données, on peut écrire une valeur, ou un tableau de valeurs.
     
    988831
    989832void
     833POutPersist::PutRawBytes(void const* ptr, size_t bytes)
     834{
     835  s->write((char const*)ptr, bytes);
     836}
     837
     838void
     839POutPersist::PutRawByte(char c)
     840{
     841  PutRawBytes(&c, 1);
     842}
     843
     844void
     845POutPersist::PutRawI2   (int_2 val)
     846{
     847  if (bigEndian != IS_BIG_ENDIAN)
     848    bswap2(&val);
     849
     850  PutRawBytes(&val, sizeof(int_2));
     851}
     852
     853void
     854POutPersist::PutRawI4   (int_4 val)
     855{
     856  if (bigEndian != IS_BIG_ENDIAN)
     857    bswap4(&val);
     858
     859  PutRawBytes(&val, sizeof(int_4));
     860}
     861
     862void
     863POutPersist::PutRawI8   (int_8 val)
     864{
     865  if (bigEndian != IS_BIG_ENDIAN)
     866    bswap8(&val);
     867
     868  PutRawBytes(&val, sizeof(int_8));
     869}
     870
     871void
     872POutPersist::PutRawU8   (uint_8 val)
     873{
     874  if (bigEndian != IS_BIG_ENDIAN)
     875    bswap8(&val);
     876
     877  PutRawBytes(&val, sizeof(uint_8));
     878}
     879
     880void
     881POutPersist::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
     895void
    990896POutPersist::PutByte(char c)
    991897{
    992   PutBytes(&c, 1);
    993 }
     898  PutRawByte(PPS_SIMPLE + 1);
     899  PutRawBytes(&c, 1);
     900}
     901
     902
    994903
    995904void
    996905POutPersist::PutBytes(void const* ptr, size_t bytes)
    997906{
    998   s->write((char const*)ptr, bytes);
     907  PutArrayTag(1, bytes);
     908  PutRawBytes(ptr, bytes);
    999909}
    1000910
     
    1002912POutPersist::PutR4   (r_4 val)
    1003913{
     914  PutRawByte(PPS_SIMPLE + 4);
     915 
    1004916  if (bigEndian != IS_BIG_ENDIAN)
    1005917    bswap4(&val);
    1006918
    1007   PutBytes(&val, sizeof(r_4));
     919  PutRawBytes(&val, sizeof(r_4));
    1008920}
    1009921
     
    1011923POutPersist::PutR4s  (r_4 const* tab, size_t n)
    1012924{
    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  }
    1018936}
    1019937
     
    1021939POutPersist::PutR8   (r_8 val)
    1022940{
     941  PutRawByte(PPS_SIMPLE + 8);
     942
    1023943  if (bigEndian != IS_BIG_ENDIAN)
    1024944    bswap8(&val);
    1025945
    1026   PutBytes(&val, sizeof(r_8));
     946  PutRawBytes(&val, sizeof(r_8));
    1027947}
    1028948
     
    1030950POutPersist::PutR8s  (r_8 const* tab, size_t n)
    1031951{
    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  }
    1037963}
    1038964
     
    1040966POutPersist::PutI2   (int_2 val)
    1041967{
     968  PutRawByte(PPS_SIMPLE + 2);
     969
    1042970  if (bigEndian != IS_BIG_ENDIAN)
    1043971    bswap2(&val);
    1044972
    1045   PutBytes(&val, sizeof(int_2));
     973  PutRawBytes(&val, sizeof(int_2));
    1046974}
    1047975
     
    1049977POutPersist::PutI2s  (int_2 const* tab, size_t n)
    1050978{
    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  }
    1056990}
    1057991
     
    1059993POutPersist::PutU2   (uint_2 val)
    1060994{
     995  PutRawByte(PPS_SIMPLE + 2);
     996
    1061997  if (bigEndian != IS_BIG_ENDIAN)
    1062998    bswap2(&val);
    1063999
    1064   PutBytes(&val, sizeof(uint_2));
     1000  PutRawBytes(&val, sizeof(uint_2));
    10651001}
    10661002
     
    10681004POutPersist::PutU2s  (uint_2 const* tab, size_t n)
    10691005{
    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  }
    10751017}
    10761018
     
    10781020POutPersist::PutI4   (int_4 val)
    10791021{
     1022  PutRawByte(PPS_SIMPLE + 4);
     1023
    10801024  if (bigEndian != IS_BIG_ENDIAN)
    10811025    bswap4(&val);
    10821026
    1083   PutBytes(&val, sizeof(int_4));
     1027  PutRawBytes(&val, sizeof(int_4));
    10841028}
    10851029
     
    10871031POutPersist::PutI4s  (int_4 const* tab, size_t n)
    10881032{
    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  }
    10941044}
    10951045
     
    10971047POutPersist::PutU4   (uint_4 val)
    10981048{
     1049  PutRawByte(PPS_SIMPLE + 4);
     1050
    10991051  if (bigEndian != IS_BIG_ENDIAN)
    11001052    bswap4(&val);
    11011053
    1102   PutBytes(&val, sizeof(uint_4));
     1054  PutRawBytes(&val, sizeof(uint_4));
    11031055}
    11041056
     
    11061058POutPersist::PutU4s  (uint_4 const* tab, size_t n)
    11071059{
    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  }
    11131071}
    11141072
     
    11161074POutPersist::PutI8   (int_8 val)
    11171075{
     1076  PutRawByte(PPS_SIMPLE + 8);
     1077
    11181078  if (bigEndian != IS_BIG_ENDIAN)
    11191079    bswap8(&val);
    11201080
    1121   PutBytes(&val, sizeof(int_8));
     1081  PutRawBytes(&val, sizeof(int_8));
    11221082}
    11231083
     
    11251085POutPersist::PutI8s  (int_8 const* tab, size_t n)
    11261086{
    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  }
    11321098}
    11331099
     
    11351101POutPersist::PutU8   (uint_8 val)
    11361102{
     1103  PutRawByte(PPS_SIMPLE + 8);
     1104
    11371105  if (bigEndian != IS_BIG_ENDIAN)
    11381106    bswap8(&val);
    11391107
    1140   PutBytes(&val, sizeof(uint_8));
     1108  PutRawBytes(&val, sizeof(uint_8));
    11411109}
    11421110
     
    11441112POutPersist::PutU8s  (uint_8 const* tab, size_t n)
    11451113{
    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
     1127void
     1128POutPersist::PutStr(string const& str)
     1129{
     1130  PutRawByte(PPS_STRING);
     1131  PutRawI2(str.length());
     1132  PutRawBytes(str.c_str(), str.length());
    11511133}
    11521134
     
    11541136POutPersist::PutLine(char const* ptr, size_t len)
    11551137{
     1138  PutRawByte(PPS_LINE);
     1139
    11561140  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
     1145void
     1146POutPersist::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
     1156bool
     1157POutPersist::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  }
    11641170 
    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
     1174int_4
     1175POutPersist::assignObjectId(PPersist const* x)
     1176{
     1177  int_4 id = objList.size();
     1178  objList[x] = id;
     1179  return id;
     1180}
     1181
     1182int_4
     1183POutPersist::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.