source: Sophya/trunk/SophyaLib/BaseTools/ppersist.cc@ 2457

Last change on this file since 2457 was 2441, checked in by ansari, 22 years ago

1) Premiere serie des modifications et ajout fonctionalites pour les PPersist:

  • Ecriture/lecture complex<> et tableaux de complex
  • Ecriture/lecture int_1, uint_1 et tableaux de
  • Tag de positionnement et table de tag de positionnement

2) Adaptation de Read/Write NDataBlock et suppression du fichier piocmplx.h

Reza 03/10/2003

File size: 47.7 KB
RevLine 
[241]1#include "machdefs.h"
[251]2#include <stdio.h>
3#include <sys/types.h>
4#include <time.h>
[241]5#include "pexceptions.h"
[219]6#include "ppersist.h"
[802]7#include "anydataobj.h"
[2322]8#include <fstream>
9#include <iostream>
[241]10#include <typeinfo>
[219]11
12
13#ifdef __mac__
14#include "unixmac.h"
15#include <SIOUX.h>
16#endif
17
[802]18// strptime n'est pas defini sous Linux - Reza Mars 2000
[1783]19#if defined(OS_LINUX) || defined(OS_MACOSX)
[802]20extern "C" {
[2111]21char *strptime(const char *buf, const char *format, struct tm *tm);
[802]22}
23#endif
24
[241]25#define MAXTAGLEN 255
26
[219]27//++
[241]28// Class PIOPersist
[219]29// Lib Outils++
30// include ppersist.h
31//
[241]32// Root class for persistant files. Handles the registration of
33// persistant classes
[219]34//--
35
36//++
[241]37// Links See
[219]38// PPersist
[241]39// PInPersist
40// POutPersist
[219]41//--
42
43
[742]44MD5_CONTEXT PIOPersist::ctx;
[802]45PIOPersist::ClassList * PIOPersist::ppclassList = NULL; // $CHECK$ Reza 26/04/99
46map<string, uint_8> * PIOPersist::ppclassNameList = NULL;
47map<string, uint_8> * PIOPersist::dobjclassNameList = NULL;
[241]48
[269]49//++
50void
51PIOPersist::Initialize()
52// Initialisation globale (objets statiques) $CHECK$ Reza 26/04/99
53//--
54{
[802]55ppclassList = new PIOPersist::ClassList;
56ppclassNameList = new map<string, uint_8>;
57dobjclassNameList = new map<string, uint_8>;
[1900]58cout << " PIOPersist::Initialize() Starting Sophya Persistence management service " << endl;
[269]59}
[241]60
[219]61//++
62void
[802]63PIOPersist::RegisterPPHandlerClass(uint_8 classId, string ppclass_name, ClassCreatorFunc f)
[219]64//
[802]65// Register a new persistence handler (PPersist) class.
66// The classId is usually a hash of the class name, and
67// ppclass_name is typeid(PPersistClass).name() .
68// This method is called only through the PPersistRegistrar template
[219]69//
70//--
71{
[802]72 if (ppclassList->size() && (ppclassList->find(classId) != ppclassList->end()) ) {
73 cerr << "RegisterClass : Error, " << hex << classId << dec
74 << " already registered." << endl;
[816]75 throw(DuplicateIdExc("PIOPersist::RegisterPPHandlerClass() Already registered (1)"));
[802]76 }
77 if (ppclassNameList->size() && (ppclassNameList->find(ppclass_name) != ppclassNameList->end())) {
78 cerr << "RegisterClass : Error (2) " << ppclass_name
79 << " already registered." << endl;
[816]80 throw(DuplicateIdExc("PIOPersist::RegisterPPHandlerClass() Already registered(2)"));
[219]81 }
82
[802]83 (*ppclassList)[classId] = f;
84 (*ppclassNameList)[ppclass_name] = classId;
[219]85}
86
[802]87//++
88void
89PIOPersist::RegisterDataObjClass(uint_8 classId, string class_name)
90// Register a new DataObj class corresponding to a PPersist classId
91// class_typename should be typeid(DataObject).name()
92//--
93{
[816]94 if (ppclassList->find(classId) == ppclassList->end() ) {
95 cerr << "PIOPersist::RegisterDataObjClass() Error (1) "
96 << hex << classId << dec << " Not Found !" << endl;
97 throw( NotFoundExc("PIOPersist::RegisterDataObjClass() Not found classId ") );
98 }
99 if (dobjclassNameList->size() && (dobjclassNameList->find(class_name) != dobjclassNameList->end())) {
100 cerr << "PIOPersist::RegisterDataObjClass() Error (2)" << class_name
101 << " already registered." << endl;
102 throw(DuplicateIdExc("PIOPersist::RegisterDataObjClass() - Already registered"));
103 }
[219]104
[802]105 (*dobjclassNameList)[class_name] = classId;
106}
107
108// class_typename should be typeid(DataObject).name(), to be
109// used by POutPersist::PutDataObject() methods.
110
[241]111PIOPersist::ClassCreatorFunc
112PIOPersist::FindCreatorFunc(uint_8 classId)
[802]113// Returns the PPersist class creator function for the specified classId
[219]114{
[802]115 ClassList::iterator i = ppclassList->find(classId);
116 if (i == ppclassList->end()) throw(NotFoundExc("PIOPersist::FindCreatorFunc() Not found classId"));
[241]117 return (*i).second;
[219]118}
119
[802]120string
121PIOPersist::getPPClassName(uint_8 classId)
122// Returns the PPersist class name for the specified classId
123{
124 map<string, uint_8>::iterator i;
125 for (i= ppclassNameList->begin(); i != ppclassNameList->end(); i++)
126 if ( (*i).second == classId ) return (*i).first;
[219]127
[802]128 throw(NotFoundExc("PIOPersist::getPPClassName() Not found classId"));
129}
130
131uint_8
132PIOPersist::getPPClassId(string const & typ_name)
133// Returns the classId for the specified PPersist class type name
134{
135 map<string, uint_8>::iterator i = ppclassNameList->find(typ_name);
136 if (i == ppclassNameList->end())
137 throw(NotFoundExc("PIOPersist::getPPClassId() Not found className"));
138 return (*i).second;
139}
140
141uint_8
142PIOPersist::getPPClassId(PPersist const & ppo)
143// Returns the classId for the specified PPersist class
144{
145 string typ_name = typeid(ppo).name() ;
146 return (getPPClassId(typ_name) );
147}
148
149
150string
151PIOPersist::getDataObjClassName(uint_8 classId)
152// Returns the PPersist class name for the specified classId
153{
154 map<string, uint_8>::iterator i;
155 for (i= dobjclassNameList->begin(); i != dobjclassNameList->end(); i++)
156 if ( (*i).second == classId ) return (*i).first;
157
158 throw(NotFoundExc("PIOPersist::getDataObjClassName() Not found classId"));
159}
160
161uint_8
162PIOPersist::getDataObjClassId(string const & typ_name)
163// Returns the classId for the specified PPersist class type name
164{
165 map<string, uint_8>::iterator i = dobjclassNameList->find(typ_name);
166 if (i == dobjclassNameList->end())
167 throw(NotFoundExc("PIOPersist::getDataObjClassId() Not found className"));
168 return (*i).second;
169}
170
171uint_8
172PIOPersist::getDataObjClassId(AnyDataObj const & o)
173// Returns the classId for the specified PPersist class
174{
175 string typ_name = typeid(o).name() ;
176 return (getDataObjClassId(typ_name) );
177}
178
179
[1202]180static inline void bswap8(void* p)
181{
182 uint_8 tmp = *(uint_8*)p;
183 *(uint_8*)p = ((tmp >> (7*8)) & 0x000000FF) |
184 ((tmp >> (5*8)) & 0x0000FF00) |
185 ((tmp >> (3*8)) & 0x00FF0000) |
186 ((tmp >> (1*8)) & 0xFF000000) |
187 ((tmp & 0xFF000000) << (1*8)) |
188 ((tmp & 0x00FF0000) << (3*8)) |
189 ((tmp & 0x0000FF00) << (5*8)) |
190 ((tmp & 0x000000FF) << (7*8));
191}
192
193static inline void bswap4(void* p)
194{
195 uint_4 tmp = *(uint_4*)p;
196 *(uint_4*)p = ((tmp >> 24) & 0x000000FF) |
197 ((tmp >> 8) & 0x0000FF00) |
198 ((tmp & 0x0000FF00) << 8) |
199 ((tmp & 0x000000FF) << 24);
200}
201
202static inline void bswap2(void* p)
203{
204 uint_2 tmp = *(uint_2*)p;
205 *(uint_2*)p = ((tmp >> 8) & 0x00FF) |
206 ((tmp & 0x00FF) << 8);
207}
208
209
210uint_8 PIOPersist::Hash(string const& typname) {
211 md5_init(&ctx);
212 md5_write(&ctx, (unsigned char*) typname.c_str(), typname.size());
213 md5_final(&ctx);
214 uint_8 hash1 = *((uint_8*) ctx.buf);
215 uint_8 hash2 = *((uint_8*) (ctx.buf+8));
216#if IS_BIG_ENDIAN
217 bswap8(&hash1);
218 bswap8(&hash2);
219#endif
220
221 return (hash1+hash2);
222}
223
224
[219]225//++
226// Class PPersist
227// Lib Outils++
228// include ppersist.h
229//
230// Classe de base pour des objets persistants. Pour créer un objet
231// persistant :
232// - Hériter de PPersist.
233// - Définir un numéro d'identification de la classe, unique dans Peida
234// - Implémenter "ClassId()"
235// - Implémenter "WriteSelf" et "ReadSelf", qui doivent écrire toutes les variables
236// membres que l'on souhaite écrire, et les relire dans le même ordre.
237// Pour écrire une référence à un objet : l'objet doit être un PPersist,
238// et il suffit d'appeler "Write" sur cet objet, et "PPersistMgr::ReadObject".
239// Si plusieurs objets font référence au même, pour éviter de l'écrire plusieurs
240// fois, il faut que cet objet soit un PShPersist.
241// - Pour que le fichier soit portable, écrire et lire les variables membres en utilisant
242// les fonctions PutXX/GetXX de PInPersist/POutPersist.
243//
244// Attention: les méthodes à redéfinir sont WriteSelf et ReadSelf, mais il ne faut jamais
245// les appeler directement. Seuls Write et Read peuvent être appelées par l'utilisateur.
246//--
247
248//++
[241]249// Links See
[219]250// PInPersist
251// POutPersist
[241]252// PIOPersist
[219]253//--
254
255//++
256void
257PPersist::Write(string const& fn) const
258//
259// Ecrit l'objet dans un nouveau fichier ppersist "fn".
260//--
261{
262 POutPersist of(fn);
263 Write(of);
264}
265
266//++
267void
268PPersist::Read(string const& fn)
269//
270// Relit l'objet dans le fichier ppersist "fn". Il faut connaître a priori
271// le type de l'objet. Pour une relecture avec création automatique du bon
272// objet, utiliser PPersistMgr::ReadObject.
273//--
274{
275 PInPersist inf(fn);
276 Read(inf);
277}
278
279//++
280void
281PPersist::Write(POutPersist& s) const
282//
283// Ecrit l'objet dans le fichier PPersist.
284//--
285{
[802]286 s.PutPPObject(this);
[219]287}
288
289
290//++
291void
292PPersist::Read(PInPersist& s)
293//
294// Relit l'objet dans le fichier ppersist. Il faut connaître a priori
295// le type de l'objet. Pour une relecture avec création automatique du bon
[241]296// objet, utiliser PInPersist::ReadObject.
297// Il faut qu'on soit un objet ecrit
[219]298//--
299{
[241]300 // We should be the exact type
301 // Check tag value
[802]302 unsigned char ppstype,ppstag;
[588]303 s.GetTypeTag(ppstype);
[802]304 if ( (ppstype != PInPersist::PPS_OBJECT) && ( ppstype != PInPersist::PPS_REFERENCE ) ) {
[241]305 }
[802]306 if (ppstype == PInPersist::PPS_OBJECT) {
307 // Check class id
308 uint_8 classId;
309 s.GetRawU8(classId);
310 uint_8 oid,oid2;
311 s.GetRawU8(oid);
312 if (classId != PIOPersist::getPPClassId(*this) )
313 throw FileFormatExc("PPersist::Read (): not the same object type");
314 ReadSelf(s);
315 // Read the ENDOBJECT
316 s.GetRawUByte(ppstag);
317 if (ppstag != PInPersist::PPS_ENDOBJECT)
318 throw FileFormatExc("PPersist::Read() No PPS_ENDOBJECT tag");
319 s.GetRawU8(oid2);
320 if (oid2 != oid)
321 throw FileFormatExc("PPersist::Read() Inconsistent PPS-OId at PPS_ENDOBJECT ");
322 s.KeepOId(oid, *this); // Object should be kept with its PPS_OId (if oid > 0)
[241]323 }
[802]324 else if ( ppstype == PInPersist::PPS_REFERENCE )
325 s.ReadReference(*this);
[219]326
[802]327 else throw FileFormatExc("PPersist::Read() : not an object in flow");
328
[219]329}
330
331//++
[241]332void
333PPersist::Write(POutPersist& s, string const& tag) const
[219]334//
[241]335// Ecrit l'objet dans le fichier PPersist avec un tag
[219]336//--
337{
[2441]338 s.WriteNameTag(tag);
[802]339 s.PutPPObject(this);
[219]340}
341
342//++
343void
[241]344PPersist::ReadAtTag(PInPersist& s, string const& tag)
[219]345//
346// Lit l'objet à la position du tag numéro "tagid".
347//--
348{
[241]349 if (!s.GotoTag(tag))
350 throw NotFoundExc("PPersist::ReadAtTag tag not found");
351 Read(s);
[219]352}
353
[802]354// Renvoie l'identificateur de l'objet - par defaut=0
[219]355
[802]356uint_8
357PPersist::getMemOId() const
358{
359 return(0);
360}
361
362// Ces deux methodes doivent etre redefinies si getMemOId() renvoie non nul (>0)
363// ShareDataReference() et CloneSharedReference()
364void
365PPersist::ShareDataReference(PPersist & pcs)
366{
367 throw NotAvailableOperation("PPersist::ShareDataReference() - Unsupported operation !");
368}
369
370PPersist *
371PPersist::CloneSharedReference()
372{
373 throw NotAvailableOperation("PPersist::CloneSharedReference() - Unsupported operation !");
374}
375
[219]376//++
377// virtual void PPersist::ReadSelf(PInPersist&)=0
378// Méthode virtuelle pure à redéfinir. Elle est appelée par Read
379// et PPersistMgr::ReadObject. Il faut relire les variables membres,
380// dans l'ordre où elles ont été écrites par WriteSelf.
381// virtual void PPersist::WriteSelf(POutPersist&) const=0
382// Méthode virtuelle pure à redéfinir. Elle est appelée par Write.
383// Il faut écrire les variables membres,
384// dans l'ordre où elles seront relues par ReadSelf.
385//--
386
387
388
389//++
390// Class PInPersist
391// Lib Outils++
392// include ppersist.h
393//
394// Fichier d'objets persistants, en lecture.
395//--
396
397//++
398PInPersist::PInPersist(string const& flnm, bool scan)
399//
400// Constructeur. Ouvre le fichier.
401//--
402{
[241]403 s = new ifstream(flnm.c_str(),ios::in | IOS_BIN);
404
405 // Read and check header
406
[219]407 char rbuf[36];
[241]408 GetRawBytes(rbuf, 32);
[576]409 if (strncmp(rbuf,"SOS-SOPHYA-PPersistFile", 23) != 0) {
[241]410 throw FileFormatExc("PInPersist::PInPersist bad header");
[219]411 }
[802]412 rbuf[32] = '\0';
413 version = atoi(rbuf+25);
414 if (version < 2) {
415 cerr << "PInPersist::PInPersist(" << flnm << ") Version(=" << version
416 << ") < 2 not supported !" << endl;
417 throw FileFormatExc("PInPersist::PInPersist() - Unsupported (Old) Version");
418 }
[241]419 // read endianness
420 GetRawBytes(rbuf, 32);
421 if (strncmp(rbuf,"BIG-ENDIAN",10) == 0)
422 bigEndian = true;
423 else if (strncmp(rbuf,"LITTLE-ENDIAN",13) == 0)
424 bigEndian = false;
425 else {
426 throw FileFormatExc("PInPersist::PInPersist bad header - endianness");
427 }
428
429 // read creation date
430 GetRawBytes(rbuf, 32);
431 rbuf[32] = '\0';
432 struct tm tm;
[2441]433 /* #if !(defined(__MWERKS__) || defined(OS_MACOSX)) RZ-DEL */
[742]434 strptime(rbuf,"%d/%m/%Y %H:%M:%S GMT",&tm);
[2441]435 /* #else
[742]436 sscanf(rbuf,"%2d/%2d/%4d %2d:%2d:%2d GMT",&tm.tm_mday,&tm.tm_mon,&tm.tm_year,
437 &tm.tm_hour,&tm.tm_min,&tm.tm_sec);
[2441]438
[742]439 tm.tm_mon --;
440 tm.tm_year -= 1900;
[2441]441 #endif RZ-DEL */
442
[241]443 creationdate = mktime(&tm);
[802]444 filename = flnm; // keep the filename
445 seqread = true; // To flag non sequential reads
[241]446 if (scan) Scan();
[219]447}
448
449
450
451PInPersist::~PInPersist()
452{
[802]453 ObjList::iterator i;
454 for(i=objList.begin(); i!= objList.end(); i++)
455 if ((*i).second) delete (*i).second;
[219]456 delete s;
457}
458
459
[802]460string
461PInPersist::CreationDateStr()
462{
463 time_t cdt = CreationDate();
464 string cdate = ctime(&cdt);
465 return(cdate);
466}
467
[219]468void
469PInPersist::Scan()
470{
[241]471 // On cherche la liste des tags, a la fin du fichier
[219]472
[802]473 unsigned char ppstype;
[241]474 size_t debut;
475#ifdef STREAMPOS_IS_CLASS
[219]476 debut = s->tellg().offset();
[241]477#else
[219]478 debut = s->tellg();
[241]479#endif
[219]480
[241]481 // Find tag entries at end of file
[2430]482 // if (defined(Linux) || defined(Darwin)) && defined(__GNUG__) && (__GNUC__ < 3)
483#if defined(__GNUG__) && (__GNUC__ < 3)
[1101]484 // There seems to be a bug where seekg with ios::end under Linux with g++
[2430]485 // prior to version gcc 3.1
486 // The bug seems to be there also with Darwin/MacOSX
[1063]487 // So, we use seek with ios::beg
488 s->seekg(0, ios::end);
489 int_8 tagpos = s->tellg() - (sizeof(int_8)+1);
490 s->seekg(tagpos, ios::beg);
[1101]491#else
492 s->seekg(-(sizeof(int_8)+1), ios::end);
[1063]493#endif
494
[588]495 GetTypeTag(ppstype);
[241]496 if (ppstype != PPS_EOF)
497 throw FileFormatExc("PInPersist::Scan corrupted file, no eof entry at end of file");
[219]498
[241]499 int_8 pos;
500 GetRawI8(pos);
[2430]501#if defined(Darwin)
502 // Septembre 2003 - Reza : Pb avec MacOSX 10.2
503 // Sur MacOSX (10.2, g++ 3.1), la lecture du dernier byte du flot cause
504 // une erreur, et le flot ne se repositionne plus
505 // On ferme le flot et on le rouvre ...
506 delete s;
507 s = new ifstream(FileName().c_str(), ios::in | IOS_BIN);
508#endif
[241]509 if (pos < 0) { // no tags
510 s->seekg(debut);
511 return;
512 }
[219]513
[241]514 char buffer[MAXTAGLEN+1];
515 s->seekg(pos);
516 while (true) {
[588]517 GetTypeTag(ppstype);
[241]518 if (ppstype == PPS_EOF) break;
519
[2441]520 if (ppstype != PPS_NAMETAG_TABLE)
[241]521 throw FileFormatExc("PInPersist::Scan corrupted file, bad tag entry");
[219]522
[241]523 GetRawI8(pos);
524 int_4 len;
525 GetRawI4(len);
526 if (len > MAXTAGLEN)
527 throw FileFormatExc("PInPersist::Scan corrupted file, tag name too long");
528 GetRawBytes(buffer, len);
529 buffer[len] = '\0';
[219]530
[241]531 tags[buffer] = pos;
[219]532 }
[241]533 s->seekg(debut);
[219]534}
535
536
[256]537int
538PInPersist::NbTags()
539{
540 return tags.size();
541}
542
[219]543bool
[2441]544PInPersist::GotoPositionTag(int_8 pos)
[219]545{
[2441]546 s->seekg(pos);
547 int_8 tpos;
548 GetRawI8(tpos);
549 if (tpos != pos)
550 throw FileFormatExc("PInPersist::GotoPositionTag() - Wrong tag position!");
551 return true;
552}
553
554bool
555PInPersist::GotoNameTag(string const& name)
556{
[241]557 map<string, int_8>::iterator i = tags.find(name);
558 if (i == tags.end())
559 return false;
[2441]560 // throw NotFoundExc("PInPersist::GotoNameTag tag not found");
[241]561 s->seekg((*i).second);
[802]562 seqread = false;
563 // objList.clear(); $CHECK$ EA 171199 Ne pas faire ? Reza 03/2000 ?
[219]564 return(true);
565}
566
[2441]567
[256]568bool
569PInPersist::GotoTagNum(int itag)
570{
[582]571 if (itag<0 || itag >= (int)tags.size()) return false;
[256]572 map<string, int_8>::iterator i = tags.begin();
573 for (int j=0; j<itag; j++) i++;
574 s->seekg((*i).second);
[871]575 seqread = false;
[802]576 // objList.clear(); $CHECK$ EA 171199 Ne pas faire ? Reza 03/2000 ?
[256]577 return(true);
578}
579
[582]580string
581PInPersist::GetTagName(int itag)
582{
583 if (itag<0 || itag >= (int)tags.size()) return "";
584 map<string, int_8>::iterator i = tags.begin();
585 for (int j=0; j<itag; j++) i++;
586 return((*i).first);
587}
[256]588
[802]589string
590PInPersist::GetTagClassName(int itag)
591{
592 // A faire
593// if (itag<0 || itag >= (int)tags.size()) return "";
594// map<string, int_8>::iterator i = tags.begin();
595// for (int j=0; j<itag; j++) i++;
596// uint_8 cid = (*i).second;
597// return(GetClassName(cid));
598 return("");
599}
600
[582]601static vector<string> * ret_tag_names = NULL;
602vector<string> const &
603PInPersist::GetTagNames()
604{
605if (ret_tag_names) delete ret_tag_names;
606ret_tag_names = new vector<string> ;
607map<string, int_8>::iterator i;
608for(i=tags.begin(); i!=tags.end(); i++) ret_tag_names->push_back((*i).first);
609return(*ret_tag_names);
610}
611
[219]612//++
613// void PInPersist::GetByte(char& c)
614// void PInPersist::GetBytes(void* ptr, size_t bytes)
615// void PInPersist::GetR4 (r_4& result)
616// void PInPersist::GetR4s (r_4* tab, size_t n)
617// void PInPersist::GetR8 (r_8& result)
618// void PInPersist::GetR8s (r_8* tab, size_t n)
619// void PInPersist::GetI2 (int_2& result)
620// void PInPersist::GetI2s (int_2* tab, size_t n)
621// void PInPersist::GetU2 (uint_2& result)
622// void PInPersist::GetU2s (uint_2* tab, size_t n)
623// void PInPersist::GetI4 (int_4& result)
624// void PInPersist::GetI4s (int_4* tab, size_t n)
625// void PInPersist::GetU4 (uint_4& result)
626// void PInPersist::GetU4s (uint_4* tab, size_t n)
627// void PInPersist::GetI8 (int_8& result)
628// void PInPersist::GetI8s (int_8* tab, size_t n)
629// void PInPersist::GetU8 (uint_8& result)
630// void PInPersist::GetU8s (uint_8* tab, size_t n)
631// Lecture de données portables depuis le fichier PPersist. Pour chaque type
632// de données, on peut lire une valeur, ou un tableau de valeurs.
633// void PInPersist::GetLine(char* ptr, size_t len)
634// Lecture d'une ligne de texte depuis le fichier PPersist.
635//--
636
637
[588]638void
[802]639PInPersist::GetTypeTag(unsigned char& c)
[588]640{
[2441]641 int_8 tpos;
642 c = PPS_NAMETAG_MARK;
643 while ( (c == PPS_NAMETAG_MARK) || (c == PPS_POSTAG_MARK) ) {
644 GetRawUByte(c);
645 if (c == PPS_POSTAG_MARK) GetRawI8(tpos);
646 }
647 // while (c == PPS_NAMETAG_MARK) { Il ne faut plus faire ca !
[802]648 // objList.clear(); $CHECK$ Reza 03/2000
649 // GetRawByte(c);
650 // }
[588]651}
[241]652
[588]653
[219]654void
[241]655PInPersist::GetRawByte(char& c)
656{
657 GetRawBytes(&c, 1);
658}
659
660void
[802]661PInPersist::GetRawUByte(unsigned char& c)
662{
663 GetRawBytes(&c, 1);
664}
665
666void
[241]667PInPersist::GetRawBytes(void* ptr, size_t bytes)
668{
669 s->read((char*)ptr, bytes);
670}
671
672void
673PInPersist::GetRawI2 (int_2& result)
674{
675 GetRawBytes(&result, sizeof(int_2));
676 if (bigEndian != IS_BIG_ENDIAN)
677 bswap2(&result);
678}
679
680void
681PInPersist::GetRawI4 (int_4& result)
682{
683 GetRawBytes(&result, sizeof(int_4));
684 if (bigEndian != IS_BIG_ENDIAN)
685 bswap4(&result);
686}
687
688void
689PInPersist::GetRawI8 (int_8& result)
690{
691 GetRawBytes(&result, sizeof(int_8));
692 if (bigEndian != IS_BIG_ENDIAN)
693 bswap8(&result);
694}
695
696void
697PInPersist::GetRawU8 (uint_8& result)
698{
699 GetRawBytes(&result, sizeof(uint_8));
700 if (bigEndian != IS_BIG_ENDIAN)
701 bswap8(&result);
702}
703
704void
[802]705PInPersist::CheckTag(short datasz, short datatype)
706// datatype = PPS_DATATYPE_CHAR or PPS_DATATYPE_FLOAT or PPS_DATATYPE_INTEGER or PPS_DATATYPE_UNSIGNED
[241]707{
[802]708 unsigned char ppstype;
[588]709 GetTypeTag(ppstype);
[802]710 if (ppstype != PPS_SIMPLE + datasz + datatype)
[256]711 throw FileFormatExc("PInPersist::CheckTag bad type in ppersist file");
[241]712}
713
714void
[802]715PInPersist::CheckArrayTag(short datasz, size_t sz, short datatype)
716// datatype = PPS_DATATYPE_CHAR or PPS_DATATYPE_FLOAT or PPS_DATATYPE_INTEGER or PPS_DATATYPE_UNSIGNED
[241]717{
[802]718 unsigned char ppstype;
[588]719 GetTypeTag(ppstype);
[241]720 size_t filesz;
[802]721 if (sz <= 0x7fffffff) {
722 if (ppstype != PPS_SIMPLE_ARRAY4 + datasz + datatype)
723 throw FileFormatExc("PInPersist::CheckArrayTag bad type in ppersist file");
[241]724 int_4 ff;
725 GetRawI4(ff); filesz=ff;
726 } else {
[802]727 if (ppstype != PPS_SIMPLE_ARRAY8 + datasz + datatype)
728 throw FileFormatExc("PInPersist::CheckArrayTag bad type in ppersist file");
[241]729 uint_8 ff;
730 GetRawU8(ff); filesz=ff;
731 }
732 if (filesz != sz)
[802]733 throw FileFormatExc("PInPersist::CheckArrayTag bad array size in ppersist file");
[241]734}
735
736void
737PInPersist::GetByte(char& c)
738{
[802]739 CheckTag(1,PPS_DATATYPE_CHAR);
[241]740 GetRawBytes(&c, 1);
741}
742
[802]743
[241]744void
745PInPersist::GetBytes(void* ptr, size_t bytes)
746{
[802]747 CheckArrayTag(1, bytes, PPS_DATATYPE_CHAR);
[241]748 GetRawBytes(ptr, bytes);
749}
750void
[219]751PInPersist::GetR4 (r_4& result)
752{
[802]753 CheckTag(4,PPS_DATATYPE_FLOAT);
[241]754 GetRawBytes(&result, sizeof(r_4));
[219]755 if (bigEndian != IS_BIG_ENDIAN)
756 bswap4(&result);
757}
758
759
760void
761PInPersist::GetR4s (r_4* tab, size_t n)
762{
[802]763 CheckArrayTag(4,n,PPS_DATATYPE_FLOAT);
[241]764 GetRawBytes(tab, n*sizeof(r_4));
[219]765 if (bigEndian == IS_BIG_ENDIAN) return;
766
767 for (unsigned int i=0; i<n; i++)
768 bswap4(tab+i);
769
770 return;
771}
772
773void
774PInPersist::GetR8 (r_8& result)
775{
[802]776 CheckTag(8,PPS_DATATYPE_FLOAT);
[241]777 GetRawBytes(&result, sizeof(r_8));
[219]778 if (bigEndian != IS_BIG_ENDIAN)
779 bswap8(&result);
780}
781
782void
783PInPersist::GetR8s (r_8* tab, size_t n)
784{
[802]785 CheckArrayTag(8,n,PPS_DATATYPE_FLOAT);
[241]786 GetRawBytes(tab, n*sizeof(r_8));
[219]787 if (bigEndian == IS_BIG_ENDIAN) return;
788
789 for (unsigned int i=0; i<n; i++)
790 bswap8(tab+i);
791
792 return;
793}
794
795void
[2441]796PInPersist::GetI1 (int_1& result)
797{
798 CheckTag(1,PPS_DATATYPE_INTEGER);
799 GetRawBytes(&result, sizeof(int_1));
800}
801
802void
803PInPersist::GetI1s (int_1* tab, size_t n)
804{
805 CheckArrayTag(1,n,PPS_DATATYPE_INTEGER);
806 GetRawBytes(tab, n*sizeof(int_1));
807}
808
809void
810PInPersist::GetU1 (uint_1& result)
811{
812 CheckTag(1,PPS_DATATYPE_UNSIGNED);
813 GetRawBytes(&result, sizeof(uint_1));
814}
815
816void
817PInPersist::GetU1s (uint_1* tab, size_t n)
818{
819 CheckArrayTag(1,n,PPS_DATATYPE_UNSIGNED);
820 GetRawBytes(tab, n*sizeof(uint_1));
821}
822
823void
[219]824PInPersist::GetI2 (int_2& result)
825{
[802]826 CheckTag(2,PPS_DATATYPE_INTEGER);
[241]827 GetRawBytes(&result, sizeof(int_2));
[219]828 if (bigEndian != IS_BIG_ENDIAN)
829 bswap2(&result);
830}
831
832void
833PInPersist::GetI2s (int_2* tab, size_t n)
834{
[802]835 CheckArrayTag(2,n,PPS_DATATYPE_INTEGER);
[241]836 GetRawBytes(tab, n*sizeof(int_2));
[219]837 if (bigEndian == IS_BIG_ENDIAN) return;
838
839 for (unsigned int i=0; i<n; i++)
840 bswap2(tab+i);
841
842 return;
843}
844
845void
846PInPersist::GetU2 (uint_2& result)
847{
[802]848 CheckTag(2,PPS_DATATYPE_UNSIGNED);
[241]849 GetRawBytes(&result, sizeof(uint_2));
[219]850 if (bigEndian != IS_BIG_ENDIAN)
851 bswap2(&result);
852}
853
854void
855PInPersist::GetU2s (uint_2* tab, size_t n)
856{
[802]857 CheckArrayTag(2,n,PPS_DATATYPE_UNSIGNED);
[241]858 GetRawBytes(tab, n*sizeof(uint_2));
[219]859 if (bigEndian == IS_BIG_ENDIAN) return;
860
861 for (unsigned int i=0; i<n; i++)
862 bswap2(tab+i);
863
864 return;
865}
866
867void
868PInPersist::GetI4 (int_4& result)
869{
[802]870 CheckTag(4,PPS_DATATYPE_INTEGER);
[241]871 GetRawBytes(&result, sizeof(int_4));
[219]872 if (bigEndian != IS_BIG_ENDIAN)
873 bswap4(&result);
874}
875
876void
877PInPersist::GetI4s (int_4* tab, size_t n)
878{
[802]879 CheckArrayTag(4,n,PPS_DATATYPE_INTEGER);
[241]880 GetRawBytes(tab, n*sizeof(int_4));
[219]881 if (bigEndian == IS_BIG_ENDIAN) return;
882
883 for (unsigned int i=0; i<n; i++)
884 bswap4(tab+i);
885
886 return;
887}
888
889void
890PInPersist::GetU4 (uint_4& result)
891{
[802]892 CheckTag(4,PPS_DATATYPE_UNSIGNED);
[241]893 GetRawBytes(&result, sizeof(uint_4));
[219]894 if (bigEndian != IS_BIG_ENDIAN)
895 bswap4(&result);
896}
897
898void
899PInPersist::GetU4s (uint_4* tab, size_t n)
900{
[802]901 CheckArrayTag(4,n,PPS_DATATYPE_UNSIGNED);
[241]902 GetRawBytes(tab, n*sizeof(uint_4));
[219]903 if (bigEndian == IS_BIG_ENDIAN) return;
904
905 for (unsigned int i=0; i<n; i++)
906 bswap4(tab+i);
907
908 return;
909}
910
911
912void
913PInPersist::GetI8 (int_8& result)
914{
[802]915 CheckTag(8,PPS_DATATYPE_INTEGER);
[241]916 GetRawBytes(&result, sizeof(int_8));
[219]917 if (bigEndian != IS_BIG_ENDIAN)
918 bswap8(&result);
919}
920
921void
922PInPersist::GetI8s (int_8* tab, size_t n)
923{
[802]924 CheckArrayTag(8,n,PPS_DATATYPE_INTEGER);
[241]925 GetRawBytes(tab, n*sizeof(int_8));
[219]926 if (bigEndian == IS_BIG_ENDIAN) return;
927
928 for (unsigned int i=0; i<n; i++)
929 bswap8(tab+i);
930
931 return;
932}
933
934void
935PInPersist::GetU8 (uint_8& result)
936{
[802]937 CheckTag(8,PPS_DATATYPE_UNSIGNED);
[241]938 GetRawBytes(&result, sizeof(uint_8));
[219]939 if (bigEndian != IS_BIG_ENDIAN)
940 bswap8(&result);
941}
942
943void
944PInPersist::GetU8s (uint_8* tab, size_t n)
945{
[802]946 CheckArrayTag(8,n,PPS_DATATYPE_UNSIGNED);
[241]947 GetRawBytes(tab, n*sizeof(uint_8));
[219]948 if (bigEndian == IS_BIG_ENDIAN) return;
949
950 for (unsigned int i=0; i<n; i++)
951 bswap8(tab+i);
952
953 return;
954}
955
956
957void
958PInPersist::GetLine(char* ptr, size_t len)
959{
[802]960 string str;
961 GetStr(str);
962 strncpy(ptr, str.c_str(), len);
963 ptr[len] = '\0';
[219]964}
965
[241]966void
967PInPersist::GetStr(string& str)
968{
[802]969 unsigned char ppstype;
[588]970 GetTypeTag(ppstype);
[241]971 if (ppstype != PPS_STRING)
[802]972 throw FileFormatExc("PInPersist::GetStr bad type in ppersist file");
973 int_4 len;
974 GetRawI4(len);
[582]975 char * buff = new char[len+1];
[241]976 GetRawBytes(buff, len);
977 buff[len] = '\0';
978 str = buff;
979 delete[] buff;
980}
[219]981
[2441]982void
983PInPersist::GetZ4 (complex<r_4>& result)
984{
985 CheckTag(4,PPS_DATATYPE_COMPLEX);
986 r_4 reim[2];
987 GetRawBytes(reim, 2*sizeof(r_4));
988 if (bigEndian != IS_BIG_ENDIAN) {
989 bswap4(reim);
990 bswap4(reim+1);
991 }
992 result = complex<r_4>(reim[0], reim[1]);
993}
[802]994
[2441]995void
996PInPersist::GetZ4s (complex<r_4>* tab, size_t n)
997{
998 CheckArrayTag(4,n,PPS_DATATYPE_COMPLEX);
999 GetRawBytes(tab, n*2*sizeof(r_4));
1000 if (bigEndian == IS_BIG_ENDIAN) return;
1001
1002 r_4 * p = (r_4 *)tab;
1003 for (unsigned int i=0; i<n; i++) {
1004 bswap4(p); p++;
1005 bswap4(p); p++;
1006 }
1007 return;
1008}
1009
1010void
1011PInPersist::GetZ8 (complex<r_8>& result)
1012{
1013 CheckTag(8,PPS_DATATYPE_COMPLEX);
1014 r_8 reim[2];
1015 GetRawBytes(reim, 2*sizeof(r_8));
1016 if (bigEndian != IS_BIG_ENDIAN) {
1017 bswap8(reim);
1018 bswap8(reim+1);
1019 }
1020 result = complex<r_8>(reim[0], reim[1]);
1021}
1022
1023void
1024PInPersist::GetZ8s (complex<r_8>* tab, size_t n)
1025{
1026 CheckArrayTag(8,n,PPS_DATATYPE_COMPLEX);
1027 GetRawBytes(tab, n*2*sizeof(r_8));
1028 if (bigEndian == IS_BIG_ENDIAN) return;
1029
1030 r_8 * p = (r_8 *)tab;
1031 for (unsigned int i=0; i<n; i++) {
1032 bswap8(p); p++;
1033 bswap8(p); p++;
1034 }
1035 return;
1036}
1037
1038
1039void
1040PInPersist::GetPosTagTable(int_8* ptab, size_t sz)
1041{
1042 unsigned char ppstype;
1043 GetTypeTag(ppstype);
1044 if (ppstype != PPS_POSTAG_TABLE)
1045 throw FileFormatExc("PInPersist::GetPosTagTable bad type in ppersist stream");
1046 int_4 tsz;
1047 GetRawI4(tsz);
1048 if (tsz != sz)
1049 throw FileFormatExc("PInPersist::GetPosTagTable Size mismatch ");
1050 for(int kk=0; kk<tsz; kk++)
1051 GetRawI8(ptab[kk]);
1052 return;
1053}
1054
1055void
1056PInPersist::GetPosTagTable(vector<int_8>& ptab)
1057{
1058 unsigned char ppstype;
1059 GetTypeTag(ppstype);
1060 if (ppstype != PPS_POSTAG_TABLE)
1061 throw FileFormatExc("PInPersist::GetPosTagTable bad type in ppersist stream");
1062 ptab.clear();
1063 int_4 tsz;
1064 GetRawI4(tsz);
1065 int_8 tpos;
1066 for(int kk=0; kk<tsz; kk++) {
1067 GetRawI8(tpos);
1068 ptab.push_back(tpos);
1069 }
1070 return;
1071}
1072
[241]1073PPersist*
1074PInPersist::ReadObject()
1075{
[802]1076 return(GetPPObject());
1077}
1078
1079void
1080PInPersist::GetObject(AnyDataObj & o)
1081{
1082 GetPPObject(&o);
1083 return;
1084}
1085
1086void
1087PInPersist::GetObject(AnyDataObj & o, string tagname)
1088{
1089 GotoTag(tagname);
1090 GetPPObject(&o);
1091 return;
1092}
1093
1094PPersist*
1095PInPersist::GetPPObject(AnyDataObj * po)
1096{
[241]1097 // Get tag
[802]1098 unsigned char ppstype;
[588]1099 GetTypeTag(ppstype);
[241]1100 if (ppstype != PPS_OBJECT && ppstype != PPS_REFERENCE && ppstype != PPS_NULL) {
[256]1101 throw FileFormatExc("PInPersist::ReadObject : not an object in flow");
[241]1102 }
1103
1104 if (ppstype == PPS_NULL) {
1105 return NULL;
1106 } else if (ppstype == PPS_OBJECT) {
1107 // Get class id
1108 uint_8 classId;
1109 GetRawU8(classId);
[802]1110 uint_8 oid,oid2;
1111 GetRawU8(oid);
[241]1112
1113 // Get factory method
1114 ClassCreatorFunc f = FindCreatorFunc(classId);
1115 if (!f) {
1116 throw NotFoundExc("PInPersist::ReadObject class not registered");
1117 }
1118
1119 // Create object
1120 PPersist* object = f();
[802]1121 // If a DataObject was specified , we assign it to the PPersistObject
1122 if (po != NULL) object->SetDataObj(*po);
1123
[241]1124 object->ReadSelf(*this);
[802]1125 unsigned char ppstag;
1126 // Read the ENDOBJECT
1127 GetRawUByte(ppstag);
1128 if (ppstag != PPS_ENDOBJECT)
1129 throw FileFormatExc("PInPersist::ReadObject No PPS_ENDOBJECT tag");
1130 GetRawU8(oid2);
1131 if (oid2 != oid)
1132 throw FileFormatExc("PInPersist::ReadObject Inconsistent PPS-OId at PPS_ENDOBJECT ");
1133
1134 KeepOId(oid, *object);
[241]1135 return object;
[802]1136 }
1137 else if (ppstype == PPS_REFERENCE)
1138 return ReadReference();
1139
1140 else throw FileFormatExc("PInPersist::ReadObject invalide Tag Type !");
1141}
1142
1143
1144void
1145PInPersist::AnalyseTags(int lev)
1146{
1147 unsigned char ppstag=0;
[2441]1148 unsigned char ppst1,ppst2,ppst3,ppst30;
[802]1149 uint_8 cpos,fsize;
1150 uint_8 ui8,cid,oid;
1151 int_4 i4;
1152 int_8 i8;
1153 char * buff;
1154 string str;
1155
1156 cout << "\n ---------------------------------------------------------- " << endl;
1157 cout << " PInPersist::AnalyseTags(Level= " << lev << ")" << endl;
1158
1159
1160#ifdef STREAMPOS_IS_CLASS
1161 cpos = s->tellg().offset();
1162#else
1163 cpos = s->tellg();
1164#endif
1165 s->seekg(0,ios::end);
1166#ifdef STREAMPOS_IS_CLASS
1167 fsize = s->tellg().offset();
1168#else
1169 fsize = s->tellg();
1170#endif
1171 s->seekg(cpos,ios::beg);
1172
1173 cout << " Version= " << Version() << " FileSize= " << fsize
1174 << " Creation Date= " << CreationDateStr() << endl;
1175
1176 uint_8 totntags = 0;
1177 bool eofok = false;
1178
1179 while ( (ppstag != PPS_EOF) && (cpos < fsize) ) {
1180#ifdef STREAMPOS_IS_CLASS
1181 cpos = s->tellg().offset();
1182#else
1183 cpos = s->tellg();
1184#endif
1185 GetRawUByte(ppstag);
1186 totntags++;
1187
1188 ppst1 = ppstag&0x0f; // bits 0123
1189 ppst2 = ppstag&0x30; // bits 45
1190 ppst3 = ppstag&0xc0; // bits 67
[2441]1191 ppst30 = ppstag&0xc1; // bits 0 67
[802]1192 if ((ppst2 == 0) && (ppst3 == 0) ) {
1193 switch (ppst1) {
1194
1195 case PPS_NULL :
1196 if (lev > 1) cout << "<PPS_NULL> tag at position " << hex << cpos << dec << endl;
1197 break;
1198
1199 case PPS_STRING :
1200 GetRawI4(i4);
1201 if (lev > 1) cout << "<PPS_STRING> tag at position " << hex << cpos << dec
1202 << " Length=" << i4 << endl;
1203 s->seekg(i4,ios::cur);
1204 break;
1205
1206 case PPS_OBJECT :
1207 GetRawU8(cid);
1208 GetRawU8(oid);
1209 cout << "<PPS_OBJECT> tag at position " << hex << cpos << " ClassId= " << cid
1210 << " ObjectId= " << oid << dec << endl;
1211 break;
1212
1213 case PPS_REFERENCE :
1214 GetRawU8(oid);
1215 GetRawI8(i8);
1216 cout << "<PPS_REFERENCE> tag at position " << hex << cpos << " ObjectId= "
1217 << oid << " OrigPos=" << i8 << dec << endl;
1218 break;
1219
[2441]1220 case PPS_NAMETAG_MARK :
1221 cout << "<PPS_NAMETAG_MARK> tag at position " << hex << cpos << dec << endl;
[802]1222 break;
[2441]1223
1224 case PPS_POSTAG_MARK :
1225 GetRawI8(i8);
1226 cout << "<PPS_POSTAG_MARK> tag at position " << hex << cpos
1227 << " TPos=" << i8 << dec << endl;
1228 break;
[802]1229
1230 case PPS_ENDOBJECT :
1231 GetRawU8(oid);
1232 cout << "<PPS_ENDOBJECT> tag at position " << hex << cpos << " ObjectId= "
1233 << oid << dec << endl;
1234 break;
1235
[2441]1236 case PPS_POSTAG_TABLE :
1237 GetRawI4(i4);
1238 for(int kkt=0; kkt<i4; kkt++) GetRawI8(i8);
1239 cout << "<PPS_POSTAG_TABLE> tag at position " << hex << cpos << dec << endl;
1240 break;
1241
1242 case PPS_NAMETAG_TABLE :
[802]1243 GetRawI8(i8);
1244 GetRawI4(i4);
1245 buff = new char[i4+1];
1246 GetRawBytes(buff, i4);
1247 buff[i4] = '\0'; str = buff;
1248 delete[] buff;
1249 cout << "<PPS_TAG> tag at position " << hex << cpos << dec
1250 << " Name= " << str << endl;
1251 break;
1252
1253 case PPS_EOF :
1254 GetRawI8(i8);
1255 cout << "<PPS_EOF> tag at position " << hex << cpos
1256 << " TagPos=" << i8 << dec << endl;
1257 eofok = true;
1258 break;
1259
1260 default :
1261 cerr << " ERROR : Unexpected tag value " << hex << ppstag
1262 << " At position" << cpos << dec << endl;
1263 throw FileFormatExc("PInPersist::AnalyseTags() - Unexpected tag value !");
1264 }
[241]1265 }
[802]1266 else {
1267 string dtype = "???? x";
[2441]1268 if (ppst30 == PPS_DATATYPE_COMPLEX) dtype = "COMPLEX x";
1269 else if (ppst3 == PPS_DATATYPE_CHAR) dtype = "CHAR x";
[802]1270 else if (ppst3 == PPS_DATATYPE_FLOAT) dtype = "FLOAT x";
1271 else if (ppst3 == PPS_DATATYPE_INTEGER) dtype = "INTEGER x";
1272 else if (ppst3 == PPS_DATATYPE_UNSIGNED) dtype = "UNSIGNED x";
1273 int_4 dsize = ppst1;
[2441]1274 int_4 dsizeskip = dsize;
1275 if (ppst30 == PPS_DATATYPE_COMPLEX) {
1276 dsize--;
1277 dsizeskip = 2*dsize;
1278 }
[802]1279 char sb[16];
1280 sprintf(sb, "%d", dsize);
1281 dtype += sb;
1282
1283 switch (ppst2) {
1284
1285 case PPS_SIMPLE :
1286 if (lev > 2) cout << "<PPS_SIMPLE> tag at position " << hex << cpos << dec
1287 << " DataType=" << dtype << endl;
[2441]1288 s->seekg(dsizeskip, ios::cur);
[802]1289 break;
1290
1291 case PPS_SIMPLE_ARRAY4 :
1292 GetRawI4(i4);
1293 if (lev > 0) cout << "<PPS_SIMPLE_ARRAY4> tag at position " << hex << cpos << dec
1294 << " DataType=" << dtype << " NElts= " << i4 << endl;
[2441]1295 s->seekg((uint_8)dsizeskip*(uint_8)i4, ios::cur);
[802]1296 break;
1297
1298 case PPS_SIMPLE_ARRAY8 :
1299 GetRawU8(ui8);
1300 if (lev > 0) cout << "<PPS_SIMPLE_ARRAY8> tag at position " << hex << cpos << dec
1301 << " DataType=" << dtype << " NElts= " << ui8 << endl;
[2441]1302 s->seekg((uint_8)dsizeskip*ui8, ios::cur);
[802]1303 break;
1304 }
1305 }
[241]1306 }
[802]1307 if (!eofok)
1308 throw FileFormatExc("PInPersist::AnalyseTags() - Not found <PPS_EOF> tag ");
1309
1310 cout << " PInPersist::AnalyseTags() - End - Total Number of Tags= " << totntags << endl;
1311 cout << " ---------------------------------------------------------- \n" << endl;
1312 return;
[241]1313}
1314
[802]1315void
1316PInPersist::ReadReference(PPersist & ppo)
[241]1317{
[802]1318 PPersist * pr = ReadReference();
1319 ppo.ShareDataReference(*pr);
[241]1320}
1321
[802]1322
1323PPersist *
1324PInPersist::ReadReference()
1325{
1326 uint_8 oid;
1327 int_8 pos;
1328 GetRawU8(oid);
1329 GetRawI8(pos);
1330 // cerr << " DBG - PInPersist::ReadReference-A " << oid << " Pos= " << pos << endl;
1331 map<uint_8, PPersist *>::iterator i = objList.find(oid);
1332 if (i != objList.end()) return (*i).second;
1333 else { // We may have skeeped it !
1334 // Let's try to read it
1335 int_8 cpos;
1336#ifdef STREAMPOS_IS_CLASS
1337 cpos = s->tellg().offset();
1338#else
1339 cpos = s->tellg();
1340#endif
1341 s->seekg(pos);
1342 PPersist* ppo = ReadObject();
1343 s->seekg(cpos);
1344 delete ppo;
1345 // cerr << " DBG - PInPersist::ReadReference-B ... " << endl;
1346
1347 map<uint_8, PPersist *>::iterator i2 = objList.find(oid);
1348 if (i2 == objList.end())
1349 throw FileFormatExc("PInPersist::ReadReference() Not found PPS_OId ");
1350 return (*i2).second;
1351 }
1352}
1353
1354
1355void
1356PInPersist::KeepOId(uint_8 oid, PPersist & ppo)
1357{
1358 if ((oid&0x1) == 0) return; // This is not an object which can be referenced
1359 // cerr << " DBG - PInPersist::KeepOId() " << oid << endl;
1360 if ((objList.size() > 0) && (objList.find(oid) != objList.end()) ) {
1361 // Ceci ne devrait arriver que si on lit dans le desordre (avec GotoTag)
1362 // et pas avec une lecture sequentielle ... Reza 03/2000
1363 // cerr << "PInPersist::KeepOId()/Warning - already present PPS_ObjectId ! " << oid << endl;
1364 if (seqread) throw FileFormatExc("PInPersist::KeepOId() already present PPS_ObjectId ");
1365 PPersist *pp = (*objList.find(oid)).second;
1366 ppo.ShareDataReference(*pp);
1367 }
1368 else {
1369 PPersist * npp = ppo.CloneSharedReference();
1370 if (npp == NULL) throw PError("PInPersist::KeepOId() NULL returned by PPersist.Clone() ! ");
1371 objList[oid] = npp;
1372 }
1373 return;
1374}
1375
[219]1376//++
1377// Class POutPersist
1378// Lib Outils++
1379// include ppersist.h
1380//
1381// Fichier d'objets persistants, en écriture.
1382//--
1383
1384
1385//++
1386// POutPersist(string const& flnm, int endianness = PPersist::PPS_NATIVE)
1387//
1388// Crée un nouveau fichier ppersist. Par défaut, il est petit=boutien
1389// sur machines petit-boutiennes, et gros-boutien sur machines
1390// gros-boutiennes. On peut explicitement spécifier PPersist::PPS_LITTLE_ENDIAN
1391// ou PPersist::PPS_BIG_ENDIAN.
1392//--
1393POutPersist::POutPersist(string const& flnm, int endianness)
1394{
1395 if (endianness == -1)
1396 bigEndian = IS_BIG_ENDIAN;
1397 else
1398 bigEndian = endianness;
1399
[802]1400 // PPS (POutPersist stream) Object Id initialisation
1401 pps_OId = 0;
[241]1402 // Output stream creation
1403 s = new ofstream(flnm.c_str(),ios::out | IOS_BIN);
[2441]1404 version = 3;
[241]1405 // Header
[2441]1406 PutRawBytes("SOS-SOPHYA-PPersistFile V3 ",32);
[241]1407 PutRawBytes(bigEndian
1408 ? "BIG-ENDIAN "
1409 : "LITTLE-ENDIAN ",32);
1410
1411// ---- GMT creation date of the file
1412 time_t tm = time(NULL);
1413 char datestring[33];
[742]1414 int l=strftime(datestring,32,"%d/%m/%Y %H:%M:%S GMT",gmtime(&tm));
[241]1415 for(int i=l; i<32; i++) datestring[i] = ' ';
1416 datestring[32] = '\0';
1417 PutRawBytes(datestring, 32);
[802]1418 filename = flnm;
[219]1419}
1420
1421POutPersist::~POutPersist()
1422{
[241]1423 if (tags.size() == 0) {
[802]1424 PutRawUByte(PPS_EOF);
[241]1425 PutRawI8(-1);
1426 } else {
1427 int_8 tagPos;
1428#ifdef STREAMPOS_IS_CLASS
1429 tagPos = s->tellp().offset();
1430#else
1431 tagPos = s->tellp();
1432#endif
1433 for (map<string,int_8>::iterator i = tags.begin(); i != tags.end(); i++) {
1434 string name = (*i).first;
1435 int_8 pos = (*i).second;
[2441]1436 PutRawUByte(PPS_NAMETAG_TABLE); // This is a tag
[241]1437 PutRawI8(pos); // position of previous tag
1438 PutRawI4(name.length()); // length of the name
1439 PutRawBytes(name.c_str(), name.length()); // name, without final "0".
1440 }
[802]1441 PutRawUByte(PPS_EOF);
[241]1442 PutRawI8(tagPos);
1443 }
1444
1445 delete s; // Close the stream
[219]1446}
1447
[2441]1448int_8
1449POutPersist::WritePositionTag()
1450{
1451 int_8 tagpos;
1452#ifdef STREAMPOS_IS_CLASS
1453 tagpos = s->tellp().offset();
1454#else
1455 tagpos = s->tellp();
1456#endif
1457 PutRawByte(PPS_POSTAG_MARK);
1458 PutI8(tagpos);
1459 return(tagpos);
1460}
[219]1461
[241]1462void
[2441]1463POutPersist::WriteNameTag(string const& name)
[219]1464{
[241]1465 if (name.length() > MAXTAGLEN)
[2441]1466 throw ParmError("POutPersist::WriteNameTag tag name too long");
[219]1467
[241]1468 if (tags.find(name) != tags.end())
[2441]1469 throw DuplicateIdExc("POutPersist::WriteNameTag duplicate tag name");
[241]1470
1471 // Get current file position
1472 int_8 tagPos;
1473
[219]1474 #ifdef STREAMPOS_IS_CLASS
[241]1475 tagPos = s->tellp().offset();
[219]1476 #else
[241]1477 tagPos = s->tellp();
[219]1478 #endif
[241]1479
1480 tags[name] = tagPos;
[2441]1481 PutRawUByte(PPS_NAMETAG_MARK); // This is a tag
[802]1482 // objList.clear(); // $CHECK$ EA 171199 - Ne pas faire ? Reza 03/2000
[219]1483}
1484
1485//++
1486// void POutPersist::PutByte(char& c)
1487// void POutPersist::PutBytes(void const* ptr, size_t bytes)
1488// void POutPersist::PutR4 (r_4 result)
1489// void POutPersist::PutR4s (r_4 const* tab, size_t n)
1490// void POutPersist::PutR8 (r_8 result)
1491// void POutPersist::PutR8s (r_8 const* tab, size_t n)
1492// void POutPersist::PutI2 (int_2 result)
1493// void POutPersist::PutI2s (int_2 const* tab, size_t n)
1494// void POutPersist::PutU2 (uint_2 result)
1495// void POutPersist::PutU2s (uint_2 const* tab, size_t n)
1496// void POutPersist::PutI4 (int_4 result)
1497// void POutPersist::PutI4s (int_4 const* tab, size_t n)
1498// void POutPersist::PutU4 (uint_4 result)
1499// void POutPersist::PutU4s (uint_4 const* tab, size_t n)
1500// void POutPersist::PutI8 (int_8 result)
1501// void POutPersist::PutI8s (int_8 const* tab, size_t n)
1502// void POutPersist::PutU8 (uint_8 result)
1503// void POutPersist::PutU8s (uint_8 const* tab, size_t n)
[241]1504// void POutPersist::PutStr (string const&)
[219]1505// Ecriture de données portables.. Pour chaque type
1506// de données, on peut écrire une valeur, ou un tableau de valeurs.
1507// void POutPersist::PutLine(char const* ptr, size_t len)
1508// Ecriture d'une ligne de texte dans le fichier PPersist.
1509//--
1510
1511
1512
1513
1514void
[241]1515POutPersist::PutRawBytes(void const* ptr, size_t bytes)
1516{
1517 s->write((char const*)ptr, bytes);
1518}
1519
1520void
1521POutPersist::PutRawByte(char c)
1522{
1523 PutRawBytes(&c, 1);
1524}
1525
1526void
[802]1527POutPersist::PutRawUByte(unsigned char c)
1528{
1529 PutRawBytes(&c, 1);
1530}
1531
1532void
[241]1533POutPersist::PutRawI2 (int_2 val)
1534{
1535 if (bigEndian != IS_BIG_ENDIAN)
1536 bswap2(&val);
1537
1538 PutRawBytes(&val, sizeof(int_2));
1539}
1540
1541void
1542POutPersist::PutRawI4 (int_4 val)
1543{
1544 if (bigEndian != IS_BIG_ENDIAN)
1545 bswap4(&val);
1546
1547 PutRawBytes(&val, sizeof(int_4));
1548}
1549
1550void
1551POutPersist::PutRawI8 (int_8 val)
1552{
1553 if (bigEndian != IS_BIG_ENDIAN)
1554 bswap8(&val);
1555
1556 PutRawBytes(&val, sizeof(int_8));
1557}
1558
1559void
1560POutPersist::PutRawU8 (uint_8 val)
1561{
1562 if (bigEndian != IS_BIG_ENDIAN)
1563 bswap8(&val);
1564
1565 PutRawBytes(&val, sizeof(uint_8));
1566}
1567
1568void
[802]1569POutPersist::PutArrayTag(short datasz, size_t sz, short datatype)
1570// datatype = PPS_DATATYPE_CHAR or PPS_DATATYPE_FLOAT or PPS_DATATYPE_INTEGER or PPS_DATATYPE_UNSIGNED
[241]1571{
[802]1572 if (sz <= 0x7fffffff) {
1573 PutRawUByte(PPS_SIMPLE_ARRAY4 + datasz + datatype);
[241]1574 PutRawI4(sz);
1575 } else {
[802]1576 PutRawUByte(PPS_SIMPLE_ARRAY8 + datasz + datatype);
[241]1577 PutRawU8(sz);
1578 }
1579}
1580
1581void
[219]1582POutPersist::PutByte(char c)
1583{
[802]1584 PutRawByte(PPS_SIMPLE + 1 + PPS_DATATYPE_CHAR);
[241]1585 PutRawBytes(&c, 1);
[219]1586}
1587
[241]1588
1589
[219]1590void
1591POutPersist::PutBytes(void const* ptr, size_t bytes)
1592{
[802]1593 PutArrayTag(1, bytes, PPS_DATATYPE_CHAR);
[241]1594 PutRawBytes(ptr, bytes);
[219]1595}
1596
1597void
1598POutPersist::PutR4 (r_4 val)
1599{
[802]1600 PutRawUByte(PPS_SIMPLE + 4 + PPS_DATATYPE_FLOAT);
[241]1601
[219]1602 if (bigEndian != IS_BIG_ENDIAN)
1603 bswap4(&val);
1604
[241]1605 PutRawBytes(&val, sizeof(r_4));
[219]1606}
1607
1608void
1609POutPersist::PutR4s (r_4 const* tab, size_t n)
1610{
[802]1611 PutArrayTag(4, n, PPS_DATATYPE_FLOAT);
[241]1612
1613 if (bigEndian == IS_BIG_ENDIAN) {
1614 PutRawBytes(tab, n*sizeof(r_4));
1615 } else {
1616 for (unsigned int i=0; i<n; i++) {
1617 r_4 val = tab[i];
1618 bswap4(&val);
1619 PutRawBytes(&val, sizeof(r_4));
1620 }
1621 }
[219]1622}
1623
1624void
1625POutPersist::PutR8 (r_8 val)
1626{
[802]1627 PutRawUByte(PPS_SIMPLE + 8 + PPS_DATATYPE_FLOAT);
[241]1628
[219]1629 if (bigEndian != IS_BIG_ENDIAN)
1630 bswap8(&val);
1631
[241]1632 PutRawBytes(&val, sizeof(r_8));
[219]1633}
1634
1635void
1636POutPersist::PutR8s (r_8 const* tab, size_t n)
1637{
[802]1638 PutArrayTag(8, n, PPS_DATATYPE_FLOAT);
[241]1639
1640 if (bigEndian == IS_BIG_ENDIAN) {
1641 PutRawBytes(tab, n*sizeof(r_8));
1642 } else {
1643 for (unsigned int i=0; i<n; i++) {
1644 r_8 val = tab[i];
1645 bswap8(&val);
1646 PutRawBytes(&val, sizeof(r_8));
1647 }
1648 }
[219]1649}
1650
1651void
[2441]1652POutPersist::PutI1 (int_1 val)
1653{
1654 PutRawUByte(PPS_SIMPLE + 1 + PPS_DATATYPE_INTEGER);
1655 PutRawBytes(&val, sizeof(int_1));
1656}
1657
1658void
1659POutPersist::PutI1s (int_1 const* tab, size_t n)
1660{
1661 PutArrayTag(1, n, PPS_DATATYPE_INTEGER);
1662 PutRawBytes(tab, n*sizeof(int_1));
1663}
1664
1665void
1666POutPersist::PutU1 (uint_1 val)
1667{
1668 PutRawUByte(PPS_SIMPLE + 1 + PPS_DATATYPE_UNSIGNED);
1669 PutRawBytes(&val, sizeof(uint_1));
1670}
1671
1672void
1673POutPersist::PutU1s (uint_1 const* tab, size_t n)
1674{
1675 PutArrayTag(1, n, PPS_DATATYPE_UNSIGNED);
1676 PutRawBytes(tab, n*sizeof(uint_1));
1677}
1678
1679void
[219]1680POutPersist::PutI2 (int_2 val)
1681{
[802]1682 PutRawUByte(PPS_SIMPLE + 2 + PPS_DATATYPE_INTEGER);
[241]1683
[219]1684 if (bigEndian != IS_BIG_ENDIAN)
1685 bswap2(&val);
1686
[241]1687 PutRawBytes(&val, sizeof(int_2));
[219]1688}
1689
1690void
1691POutPersist::PutI2s (int_2 const* tab, size_t n)
1692{
[802]1693 PutArrayTag(2, n, PPS_DATATYPE_INTEGER);
[241]1694
1695 if (bigEndian == IS_BIG_ENDIAN) {
1696 PutRawBytes(tab, n*sizeof(int_2));
1697 } else {
1698 for (unsigned int i=0; i<n; i++) {
1699 int_2 val = tab[i];
1700 bswap2(&val);
1701 PutRawBytes(&val, sizeof(int_2));
1702 }
1703 }
[219]1704}
1705
1706void
1707POutPersist::PutU2 (uint_2 val)
1708{
[802]1709 PutRawUByte(PPS_SIMPLE + 2 + PPS_DATATYPE_UNSIGNED);
[241]1710
[219]1711 if (bigEndian != IS_BIG_ENDIAN)
1712 bswap2(&val);
1713
[241]1714 PutRawBytes(&val, sizeof(uint_2));
[219]1715}
1716
1717void
1718POutPersist::PutU2s (uint_2 const* tab, size_t n)
1719{
[802]1720 PutArrayTag(2, n, PPS_DATATYPE_UNSIGNED);
[241]1721
1722 if (bigEndian == IS_BIG_ENDIAN) {
1723 PutRawBytes(tab, n*sizeof(uint_2));
1724 } else {
1725 for (unsigned int i=0; i<n; i++) {
1726 uint_2 val = tab[i];
1727 bswap2(&val);
1728 PutRawBytes(&val, sizeof(uint_2));
1729 }
1730 }
[219]1731}
1732
1733void
1734POutPersist::PutI4 (int_4 val)
1735{
[802]1736 PutRawUByte(PPS_SIMPLE + 4 + PPS_DATATYPE_INTEGER);
[241]1737
[219]1738 if (bigEndian != IS_BIG_ENDIAN)
1739 bswap4(&val);
1740
[241]1741 PutRawBytes(&val, sizeof(int_4));
[219]1742}
1743
1744void
1745POutPersist::PutI4s (int_4 const* tab, size_t n)
1746{
[802]1747 PutArrayTag(4, n, PPS_DATATYPE_INTEGER);
[241]1748
1749 if (bigEndian == IS_BIG_ENDIAN) {
1750 PutRawBytes(tab, n*sizeof(int_4));
1751 } else {
1752 for (unsigned int i=0; i<n; i++) {
1753 int_4 val = tab[i];
1754 bswap4(&val);
1755 PutRawBytes(&val, sizeof(int_4));
1756 }
1757 }
[219]1758}
1759
1760void
1761POutPersist::PutU4 (uint_4 val)
1762{
[802]1763 PutRawUByte(PPS_SIMPLE + 4 + PPS_DATATYPE_UNSIGNED);
[241]1764
[219]1765 if (bigEndian != IS_BIG_ENDIAN)
1766 bswap4(&val);
1767
[241]1768 PutRawBytes(&val, sizeof(uint_4));
[219]1769}
1770
1771void
1772POutPersist::PutU4s (uint_4 const* tab, size_t n)
1773{
[802]1774 PutArrayTag(4, n, PPS_DATATYPE_UNSIGNED);
[241]1775
1776 if (bigEndian == IS_BIG_ENDIAN) {
1777 PutRawBytes(tab, n*sizeof(uint_4));
1778 } else {
1779 for (unsigned int i=0; i<n; i++) {
1780 uint_4 val = tab[i];
1781 bswap4(&val);
1782 PutRawBytes(&val, sizeof(uint_4));
1783 }
1784 }
[219]1785}
1786
1787void
1788POutPersist::PutI8 (int_8 val)
1789{
[802]1790 PutRawUByte(PPS_SIMPLE + 8 + PPS_DATATYPE_INTEGER);
[241]1791
[219]1792 if (bigEndian != IS_BIG_ENDIAN)
1793 bswap8(&val);
1794
[241]1795 PutRawBytes(&val, sizeof(int_8));
[219]1796}
1797
1798void
1799POutPersist::PutI8s (int_8 const* tab, size_t n)
1800{
[802]1801 PutArrayTag(8, n, PPS_DATATYPE_INTEGER);
[241]1802
1803 if (bigEndian == IS_BIG_ENDIAN) {
1804 PutRawBytes(tab, n*sizeof(int_8));
1805 } else {
1806 for (unsigned int i=0; i<n; i++) {
1807 int_8 val = tab[i];
1808 bswap8(&val);
1809 PutRawBytes(&val, sizeof(int_8));
1810 }
1811 }
[219]1812}
1813
1814void
1815POutPersist::PutU8 (uint_8 val)
1816{
[802]1817 PutRawUByte(PPS_SIMPLE + 8 + PPS_DATATYPE_UNSIGNED);
[241]1818
[219]1819 if (bigEndian != IS_BIG_ENDIAN)
1820 bswap8(&val);
1821
[241]1822 PutRawBytes(&val, sizeof(uint_8));
[219]1823}
1824
1825void
1826POutPersist::PutU8s (uint_8 const* tab, size_t n)
1827{
[802]1828 PutArrayTag(8, n, PPS_DATATYPE_UNSIGNED);
[241]1829
1830 if (bigEndian == IS_BIG_ENDIAN) {
1831 PutRawBytes(tab, n*sizeof(uint_8));
1832 } else {
1833 for (unsigned int i=0; i<n; i++) {
1834 uint_8 val = tab[i];
1835 bswap8(&val);
1836 PutRawBytes(&val, sizeof(uint_8));
1837 }
1838 }
[219]1839}
1840
1841void
[241]1842POutPersist::PutStr(string const& str)
1843{
[802]1844 PutRawUByte(PPS_STRING);
1845 PutRawI4(str.length());
[241]1846 PutRawBytes(str.c_str(), str.length());
1847}
1848
1849void
[219]1850POutPersist::PutLine(char const* ptr, size_t len)
1851{
[802]1852 string str = ptr;
1853 PutStr(str);
1854}
[241]1855
[802]1856
1857void
[2441]1858POutPersist::PutZ4 (complex<r_4> val)
1859{
1860 PutRawUByte(PPS_SIMPLE + 4 + PPS_DATATYPE_COMPLEX);
1861 r_4 reim[2];
1862 reim[0] = val.real();
1863 reim[1] = val.imag();
1864 if (bigEndian != IS_BIG_ENDIAN) {
1865 bswap4(reim);
1866 bswap4(reim+1);
1867 }
1868 PutRawBytes(reim, 2*sizeof(r_4));
1869}
1870
1871void
1872POutPersist::PutZ4s (complex<r_4> const* tab, size_t n)
1873{
1874 PutArrayTag(4, n, PPS_DATATYPE_COMPLEX);
1875
1876 if (bigEndian == IS_BIG_ENDIAN) {
1877 PutRawBytes(tab, n*2*sizeof(r_4));
1878 } else {
1879 for (unsigned int i=0; i<n; i++) {
1880 r_4 reim[2];
1881 reim[0] = tab[i].real();
1882 reim[1] = tab[i].imag();
1883 bswap4(reim);
1884 bswap4(reim+1);
1885 PutRawBytes(reim, 2*sizeof(r_4));
1886 }
1887 }
1888}
1889
1890void
1891POutPersist::PutZ8 (complex<r_8> val)
1892{
1893 PutRawUByte(PPS_SIMPLE + 8 + PPS_DATATYPE_COMPLEX);
1894 r_8 reim[2];
1895 reim[0] = val.real();
1896 reim[1] = val.imag();
1897 if (bigEndian != IS_BIG_ENDIAN) {
1898 bswap8(reim);
1899 bswap8(reim+1);
1900 }
1901 PutRawBytes(reim, 2*sizeof(r_8));
1902}
1903
1904void
1905POutPersist::PutZ8s (complex<r_8> const* tab, size_t n)
1906{
1907 PutArrayTag(8, n, PPS_DATATYPE_COMPLEX);
1908
1909 if (bigEndian == IS_BIG_ENDIAN) {
1910 PutRawBytes(tab, n*2*sizeof(r_8));
1911 } else {
1912 for (unsigned int i=0; i<n; i++) {
1913 r_8 reim[2];
1914 reim[0] = tab[i].real();
1915 reim[1] = tab[i].imag();
1916 bswap8(reim);
1917 bswap8(reim+1);
1918 PutRawBytes(reim, 2*sizeof(r_8));
1919 }
1920 }
1921}
1922
1923void
1924POutPersist::PutPosTagTable(int_8 const * ptab, size_t sz)
1925{
1926 PutRawUByte(PPS_POSTAG_TABLE);
1927 int_4 tsz = sz;
1928 PutRawI4(tsz);
1929 for(int kk=0; kk<tsz; kk++)
1930 PutRawI8(ptab[kk]);
1931 return;
1932}
1933
1934void
1935POutPersist::PutPosTagTable(vector<int_8> const& ptab)
1936{
1937 PutRawUByte(PPS_POSTAG_TABLE);
1938 int_4 tsz = ptab.size();
1939 PutRawI4(tsz);
1940 for(int kk=0; kk<tsz; kk++)
1941 PutRawI8(ptab[kk]);
1942 return;
1943}
1944
1945void
[802]1946POutPersist::PutObject(AnyDataObj & o)
1947{
1948 ClassCreatorFunc f = FindCreatorFunc(getDataObjClassId(o));
1949 if (!f)
1950 throw NotFoundExc("PInPersist::PutObject() class not registered");
1951 PPersist* ppo = f();
1952 ppo->SetDataObj(o);
1953 PutPPObject(ppo);
[219]1954}
1955
[241]1956void
[802]1957POutPersist::PutObject(AnyDataObj & o, string tagname)
[241]1958{
[2441]1959 WriteNameTag(tagname);
[802]1960 PutObject(o);
1961}
[219]1962
[802]1963
1964void
1965POutPersist::PutPPObject(PPersist const* obj)
1966{
1967 if (serializeNullAndRepeat(obj)) return; // NULL object or already written in stream
1968
1969 // We have to write the object
1970 uint_8 oid = assignObjectId(obj); // We assing a PPS Object Id
1971 PutRawUByte(PPS_OBJECT); // We write the Object Tag
1972 PutRawU8(getPPClassId(*obj)); // Writing the PPersist ClassId
1973 PutRawU8(oid); // Write the PPS Object Id
[241]1974 obj->WriteSelf(*this);
[802]1975 PutRawUByte(PPS_ENDOBJECT); // We write the End-Of-Object Tag
1976 PutRawU8(oid); // and again its PPS Object Id
[241]1977}
[219]1978
[241]1979bool
1980POutPersist::serializeNullAndRepeat(PPersist const* x)
[219]1981{
[241]1982 if (x == NULL) {
[802]1983 PutRawUByte(PPS_NULL);
[241]1984 return true;
1985 }
[219]1986
[802]1987 int_8 pos;
1988 uint_8 id = findObjectId(x, pos);
1989 if (id > 0) {
1990 PutRawUByte(PPS_REFERENCE);
1991 PutRawU8(id); // Writing the corresponding object Id
1992 PutRawI8(pos); // The original object position
[241]1993 return true;
1994 }
[219]1995
[802]1996 return false; // Object have to be written in stream ...
[219]1997}
1998
[802]1999uint_8
[241]2000POutPersist::assignObjectId(PPersist const* x)
[219]2001{
[802]2002 pps_OId += 16; // We keep the three first bytes for future usage
2003 // Bit 1 non zero -> Object can be referenced
2004 uint_8 id = pps_OId;
2005 uint_8 mid = x->getMemOId();
2006 if (mid > 0) {
2007 int_8 pos;
2008 if (findObjectId(x,pos) > 0)
2009 throw PError("POutPersist::assignObjectId() Error - Already serialized object ! ");
[821]2010 id += 1; // Bit 1 non zero -> Object can be referenced
[802]2011 objreftag rt;
2012 rt.ppsoid = id;
2013#ifdef STREAMPOS_IS_CLASS
2014 rt.ppspos = s->tellp().offset();
2015#else
2016 rt.ppspos = s->tellp();
2017#endif
2018 objList[mid] = rt;
2019 }
[241]2020 return id;
[219]2021}
2022
[802]2023uint_8
2024POutPersist::findObjectId(PPersist const* x, int_8 & pos)
[219]2025{
[802]2026 pos = -1;
2027 uint_8 mid = x->getMemOId();
2028 if (mid == 0) return(0);
2029 ObjList::iterator i = objList.find(mid);
2030 if (i == objList.end()) return 0;
2031 pos = (*i).second.ppspos;
2032 return (*i).second.ppsoid;
[219]2033}
2034
[241]2035
Note: See TracBrowser for help on using the repository browser.