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

Last change on this file since 2763 was 2698, checked in by ansari, 20 years ago

1/ Simplification de la classe gestionnairee PPersist ObjFile<T> (objfio.h)
2/ Ajout DECL_TEMP_SPEC ds ppftpointerio.h
3/ Nom specifique pour methode SegDBInterface::GetSegment() const devenu
SegDBInterface::GetCstSegment() const pour eviter l'appel a la methode non const
et adapatation classes derivees (segdatablock.h et swsegdb.h)
4/ Ajout SkipToNextObjet() ds PInPersist::ReadObject() (ppersist.cc) et protection contre pointeur NULL -> new DVList pour la lecture PPersist de DVList

Reza - 27 Avril 2005

File size: 19.0 KB
RevLine 
[2615]1#include "sopnamsp.h"
[241]2#include "machdefs.h"
[251]3#include <stdio.h>
4#include <sys/types.h>
5#include <time.h>
[241]6#include "pexceptions.h"
[219]7#include "ppersist.h"
[802]8#include "anydataobj.h"
[2322]9#include <iostream>
[2657]10#include <iomanip>
[241]11#include <typeinfo>
[219]12
[2475]13// ------------------------- Historique ---------------------------
14// Le code de ppersist a ete separe en deux en Decembre 2003
15// a partir de la version CVS (1.26 - ppersist.cc) et
16// (1.19 - ppersist.h) .
17// la partie sur l'ecriture des donnees de base et leurs tableaux
18// a ete mis dans les fichiers ppfbinstream.h .cc
19// (Classes PPFBinaryInputStream et PPFBinaryOutputStream
20// -----------------------------------------------------------------
[219]21
22
[241]23#define MAXTAGLEN 255
24
[219]25//++
[241]26// Class PIOPersist
[219]27// Lib Outils++
28// include ppersist.h
29//
[241]30// Root class for persistant files. Handles the registration of
31// persistant classes
[219]32//--
33
34//++
[241]35// Links See
[219]36// PPersist
[241]37// PInPersist
38// POutPersist
[219]39//--
40
41
[742]42MD5_CONTEXT PIOPersist::ctx;
[802]43PIOPersist::ClassList * PIOPersist::ppclassList = NULL; // $CHECK$ Reza 26/04/99
44map<string, uint_8> * PIOPersist::ppclassNameList = NULL;
45map<string, uint_8> * PIOPersist::dobjclassNameList = NULL;
[241]46
[269]47//++
48void
49PIOPersist::Initialize()
50// Initialisation globale (objets statiques) $CHECK$ Reza 26/04/99
51//--
52{
[802]53ppclassList = new PIOPersist::ClassList;
54ppclassNameList = new map<string, uint_8>;
55dobjclassNameList = new map<string, uint_8>;
[1900]56cout << " PIOPersist::Initialize() Starting Sophya Persistence management service " << endl;
[269]57}
[241]58
[219]59//++
60void
[802]61PIOPersist::RegisterPPHandlerClass(uint_8 classId, string ppclass_name, ClassCreatorFunc f)
[219]62//
[802]63// Register a new persistence handler (PPersist) class.
[2475]64// The classId is usually a hash of the class< name, and
[802]65// ppclass_name is typeid(PPersistClass).name() .
66// This method is called only through the PPersistRegistrar template
[219]67//
68//--
69{
[802]70 if (ppclassList->size() && (ppclassList->find(classId) != ppclassList->end()) ) {
71 cerr << "RegisterClass : Error, " << hex << classId << dec
72 << " already registered." << endl;
[816]73 throw(DuplicateIdExc("PIOPersist::RegisterPPHandlerClass() Already registered (1)"));
[802]74 }
75 if (ppclassNameList->size() && (ppclassNameList->find(ppclass_name) != ppclassNameList->end())) {
76 cerr << "RegisterClass : Error (2) " << ppclass_name
77 << " already registered." << endl;
[816]78 throw(DuplicateIdExc("PIOPersist::RegisterPPHandlerClass() Already registered(2)"));
[219]79 }
80
[802]81 (*ppclassList)[classId] = f;
82 (*ppclassNameList)[ppclass_name] = classId;
[219]83}
84
[802]85//++
86void
87PIOPersist::RegisterDataObjClass(uint_8 classId, string class_name)
88// Register a new DataObj class corresponding to a PPersist classId
89// class_typename should be typeid(DataObject).name()
90//--
91{
[816]92 if (ppclassList->find(classId) == ppclassList->end() ) {
93 cerr << "PIOPersist::RegisterDataObjClass() Error (1) "
94 << hex << classId << dec << " Not Found !" << endl;
95 throw( NotFoundExc("PIOPersist::RegisterDataObjClass() Not found classId ") );
96 }
97 if (dobjclassNameList->size() && (dobjclassNameList->find(class_name) != dobjclassNameList->end())) {
98 cerr << "PIOPersist::RegisterDataObjClass() Error (2)" << class_name
99 << " already registered." << endl;
100 throw(DuplicateIdExc("PIOPersist::RegisterDataObjClass() - Already registered"));
101 }
[219]102
[802]103 (*dobjclassNameList)[class_name] = classId;
104}
105
106// class_typename should be typeid(DataObject).name(), to be
107// used by POutPersist::PutDataObject() methods.
108
[2657]109//! Lists the registered PPersist handler classes and the corresponding class id.
110void
111PIOPersist::ListPPHandlers()
112{
113 cout << " PIOPersist::ListPPHandlers() - List of registered PPersist handler classes " << endl;
114 map<string, uint_8>::iterator it;
115 int k = 0;
116 for (it = (*ppclassNameList).begin(); it != (*ppclassNameList).end(); it++) {
117 cout << ++k << ": " << (*it).first << "\n" << " ClassId: Hex= "
118 << hex << (*it).second << " (Dec= " << dec << (*it).second << ")" << endl;
119 }
120}
121
122//! Lists the registered DataObj classes with the corresponding PPHandler name
123void
124PIOPersist::ListDataObjClasses()
125{
126 cout << " PIOPersist::ListDataObjClasses() : Registered DataObj class list " << endl;
127 map<string, uint_8>::iterator it;
128 int k = 0;
129 for (it = (*dobjclassNameList).begin(); it != (*dobjclassNameList).end(); it++) {
130 cout << ++k << "- " << (*it).first << " -> " << getPPClassName((*it).second) << endl;
131 }
132}
133
[241]134PIOPersist::ClassCreatorFunc
135PIOPersist::FindCreatorFunc(uint_8 classId)
[802]136// Returns the PPersist class creator function for the specified classId
[219]137{
[802]138 ClassList::iterator i = ppclassList->find(classId);
139 if (i == ppclassList->end()) throw(NotFoundExc("PIOPersist::FindCreatorFunc() Not found classId"));
[241]140 return (*i).second;
[219]141}
142
[802]143string
144PIOPersist::getPPClassName(uint_8 classId)
145// Returns the PPersist class name for the specified classId
146{
147 map<string, uint_8>::iterator i;
148 for (i= ppclassNameList->begin(); i != ppclassNameList->end(); i++)
149 if ( (*i).second == classId ) return (*i).first;
[219]150
[802]151 throw(NotFoundExc("PIOPersist::getPPClassName() Not found classId"));
152}
153
154uint_8
155PIOPersist::getPPClassId(string const & typ_name)
156// Returns the classId for the specified PPersist class type name
157{
158 map<string, uint_8>::iterator i = ppclassNameList->find(typ_name);
159 if (i == ppclassNameList->end())
160 throw(NotFoundExc("PIOPersist::getPPClassId() Not found className"));
161 return (*i).second;
162}
163
164uint_8
165PIOPersist::getPPClassId(PPersist const & ppo)
166// Returns the classId for the specified PPersist class
167{
168 string typ_name = typeid(ppo).name() ;
169 return (getPPClassId(typ_name) );
170}
171
172
173string
174PIOPersist::getDataObjClassName(uint_8 classId)
175// Returns the PPersist class name for the specified classId
176{
177 map<string, uint_8>::iterator i;
178 for (i= dobjclassNameList->begin(); i != dobjclassNameList->end(); i++)
179 if ( (*i).second == classId ) return (*i).first;
180
181 throw(NotFoundExc("PIOPersist::getDataObjClassName() Not found classId"));
182}
183
184uint_8
185PIOPersist::getDataObjClassId(string const & typ_name)
186// Returns the classId for the specified PPersist class type name
187{
188 map<string, uint_8>::iterator i = dobjclassNameList->find(typ_name);
189 if (i == dobjclassNameList->end())
190 throw(NotFoundExc("PIOPersist::getDataObjClassId() Not found className"));
191 return (*i).second;
192}
193
194uint_8
195PIOPersist::getDataObjClassId(AnyDataObj const & o)
196// Returns the classId for the specified PPersist class
197{
198 string typ_name = typeid(o).name() ;
199 return (getDataObjClassId(typ_name) );
200}
201
[2476]202static inline void bswap8_hash(void* p)
203{
204 uint_8 tmp = *(uint_8*)p;
205 *(uint_8*)p = ((tmp >> (7*8)) & 0x000000FF) |
206 ((tmp >> (5*8)) & 0x0000FF00) |
207 ((tmp >> (3*8)) & 0x00FF0000) |
208 ((tmp >> (1*8)) & 0xFF000000) |
209 ((tmp & 0xFF000000) << (1*8)) |
210 ((tmp & 0x00FF0000) << (3*8)) |
211 ((tmp & 0x0000FF00) << (5*8)) |
212 ((tmp & 0x000000FF) << (7*8));
213}
[802]214
[1202]215
216
217uint_8 PIOPersist::Hash(string const& typname) {
218 md5_init(&ctx);
219 md5_write(&ctx, (unsigned char*) typname.c_str(), typname.size());
220 md5_final(&ctx);
221 uint_8 hash1 = *((uint_8*) ctx.buf);
222 uint_8 hash2 = *((uint_8*) (ctx.buf+8));
223#if IS_BIG_ENDIAN
[2476]224 bswap8_hash(&hash1);
225 bswap8_hash(&hash2);
[1202]226#endif
227
228 return (hash1+hash2);
229}
230
231
[219]232//++
233// Class PPersist
234// Lib Outils++
235// include ppersist.h
236//
237// Classe de base pour des objets persistants. Pour créer un objet
238// persistant :
239// - Hériter de PPersist.
240// - Définir un numéro d'identification de la classe, unique dans Peida
241// - Implémenter "ClassId()"
242// - Implémenter "WriteSelf" et "ReadSelf", qui doivent écrire toutes les variables
243// membres que l'on souhaite écrire, et les relire dans le même ordre.
244// Pour écrire une référence à un objet : l'objet doit être un PPersist,
245// et il suffit d'appeler "Write" sur cet objet, et "PPersistMgr::ReadObject".
246// Si plusieurs objets font référence au même, pour éviter de l'écrire plusieurs
247// fois, il faut que cet objet soit un PShPersist.
248// - Pour que le fichier soit portable, écrire et lire les variables membres en utilisant
249// les fonctions PutXX/GetXX de PInPersist/POutPersist.
250//
251// Attention: les méthodes à redéfinir sont WriteSelf et ReadSelf, mais il ne faut jamais
252// les appeler directement. Seuls Write et Read peuvent être appelées par l'utilisateur.
253//--
254
255//++
[241]256// Links See
[219]257// PInPersist
258// POutPersist
[241]259// PIOPersist
[219]260//--
261
262//++
263void
264PPersist::Write(string const& fn) const
265//
266// Ecrit l'objet dans un nouveau fichier ppersist "fn".
267//--
268{
269 POutPersist of(fn);
270 Write(of);
271}
272
273//++
274void
275PPersist::Read(string const& fn)
276//
277// Relit l'objet dans le fichier ppersist "fn". Il faut connaître a priori
278// le type de l'objet. Pour une relecture avec création automatique du bon
279// objet, utiliser PPersistMgr::ReadObject.
280//--
281{
282 PInPersist inf(fn);
[2698]283 inf.SkipToNextObject();
[219]284 Read(inf);
285}
286
287//++
288void
289PPersist::Write(POutPersist& s) const
290//
291// Ecrit l'objet dans le fichier PPersist.
292//--
293{
[802]294 s.PutPPObject(this);
[219]295}
296
297
298//++
299void
300PPersist::Read(PInPersist& s)
301//
302// Relit l'objet dans le fichier ppersist. Il faut connaître a priori
303// le type de l'objet. Pour une relecture avec création automatique du bon
[241]304// objet, utiliser PInPersist::ReadObject.
305// Il faut qu'on soit un objet ecrit
[219]306//--
307{
[241]308 // We should be the exact type
309 // Check tag value
[802]310 unsigned char ppstype,ppstag;
[588]311 s.GetTypeTag(ppstype);
[802]312 if ( (ppstype != PInPersist::PPS_OBJECT) && ( ppstype != PInPersist::PPS_REFERENCE ) ) {
[241]313 }
[802]314 if (ppstype == PInPersist::PPS_OBJECT) {
315 // Check class id
316 uint_8 classId;
317 s.GetRawU8(classId);
318 uint_8 oid,oid2;
319 s.GetRawU8(oid);
320 if (classId != PIOPersist::getPPClassId(*this) )
321 throw FileFormatExc("PPersist::Read (): not the same object type");
322 ReadSelf(s);
323 // Read the ENDOBJECT
324 s.GetRawUByte(ppstag);
325 if (ppstag != PInPersist::PPS_ENDOBJECT)
326 throw FileFormatExc("PPersist::Read() No PPS_ENDOBJECT tag");
327 s.GetRawU8(oid2);
328 if (oid2 != oid)
329 throw FileFormatExc("PPersist::Read() Inconsistent PPS-OId at PPS_ENDOBJECT ");
330 s.KeepOId(oid, *this); // Object should be kept with its PPS_OId (if oid > 0)
[241]331 }
[802]332 else if ( ppstype == PInPersist::PPS_REFERENCE )
333 s.ReadReference(*this);
[219]334
[802]335 else throw FileFormatExc("PPersist::Read() : not an object in flow");
336
[219]337}
338
339//++
[241]340void
341PPersist::Write(POutPersist& s, string const& tag) const
[219]342//
[241]343// Ecrit l'objet dans le fichier PPersist avec un tag
[219]344//--
345{
[2441]346 s.WriteNameTag(tag);
[802]347 s.PutPPObject(this);
[219]348}
349
350//++
351void
[241]352PPersist::ReadAtTag(PInPersist& s, string const& tag)
[219]353//
354// Lit l'objet à la position du tag numéro "tagid".
355//--
356{
[2459]357 if (!s.GotoNameTag(tag))
[241]358 throw NotFoundExc("PPersist::ReadAtTag tag not found");
359 Read(s);
[219]360}
361
[802]362// Renvoie l'identificateur de l'objet - par defaut=0
[219]363
[802]364uint_8
365PPersist::getMemOId() const
366{
367 return(0);
368}
369
370// Ces deux methodes doivent etre redefinies si getMemOId() renvoie non nul (>0)
371// ShareDataReference() et CloneSharedReference()
372void
373PPersist::ShareDataReference(PPersist & pcs)
374{
375 throw NotAvailableOperation("PPersist::ShareDataReference() - Unsupported operation !");
376}
377
378PPersist *
379PPersist::CloneSharedReference()
380{
381 throw NotAvailableOperation("PPersist::CloneSharedReference() - Unsupported operation !");
382}
383
[219]384//++
385// virtual void PPersist::ReadSelf(PInPersist&)=0
386// Méthode virtuelle pure à redéfinir. Elle est appelée par Read
387// et PPersistMgr::ReadObject. Il faut relire les variables membres,
388// dans l'ordre où elles ont été écrites par WriteSelf.
389// virtual void PPersist::WriteSelf(POutPersist&) const=0
390// Méthode virtuelle pure à redéfinir. Elle est appelée par Write.
391// Il faut écrire les variables membres,
392// dans l'ordre où elles seront relues par ReadSelf.
393//--
394
395
396
397//++
398// Class PInPersist
399// Lib Outils++
400// include ppersist.h
401//
402// Fichier d'objets persistants, en lecture.
403//--
404
[2482]405PInPersist::PInPersist(RawInOutStream * is, bool ad, bool scan)
406 : PPFBinaryInputStream(is, ad, scan)
407{
408}
409
[219]410PInPersist::PInPersist(string const& flnm, bool scan)
[2475]411 : PPFBinaryInputStream(flnm, scan)
[219]412{
413}
414
415
416
417PInPersist::~PInPersist()
418{
[802]419 ObjList::iterator i;
420 for(i=objList.begin(); i!= objList.end(); i++)
421 if ((*i).second) delete (*i).second;
[219]422}
423
424
[802]425
[582]426string
[802]427PInPersist::GetTagClassName(int itag)
428{
429 // A faire
430// if (itag<0 || itag >= (int)tags.size()) return "";
431// map<string, int_8>::iterator i = tags.begin();
432// for (int j=0; j<itag; j++) i++;
433// uint_8 cid = (*i).second;
434// return(GetClassName(cid));
435 return("");
436}
437
[241]438PPersist*
439PInPersist::ReadObject()
440{
[2698]441 SkipToNextObject();
[802]442 return(GetPPObject());
443}
444
445void
446PInPersist::GetObject(AnyDataObj & o)
447{
448 GetPPObject(&o);
449 return;
450}
451
452void
453PInPersist::GetObject(AnyDataObj & o, string tagname)
454{
[2459]455 GotoNameTag(tagname);
[802]456 GetPPObject(&o);
457 return;
458}
459
460PPersist*
461PInPersist::GetPPObject(AnyDataObj * po)
462{
[241]463 // Get tag
[802]464 unsigned char ppstype;
[588]465 GetTypeTag(ppstype);
[241]466 if (ppstype != PPS_OBJECT && ppstype != PPS_REFERENCE && ppstype != PPS_NULL) {
[256]467 throw FileFormatExc("PInPersist::ReadObject : not an object in flow");
[241]468 }
469
470 if (ppstype == PPS_NULL) {
471 return NULL;
472 } else if (ppstype == PPS_OBJECT) {
473 // Get class id
474 uint_8 classId;
475 GetRawU8(classId);
[802]476 uint_8 oid,oid2;
477 GetRawU8(oid);
[241]478
479 // Get factory method
480 ClassCreatorFunc f = FindCreatorFunc(classId);
481 if (!f) {
482 throw NotFoundExc("PInPersist::ReadObject class not registered");
483 }
484
485 // Create object
486 PPersist* object = f();
[802]487 // If a DataObject was specified , we assign it to the PPersistObject
488 if (po != NULL) object->SetDataObj(*po);
489
[241]490 object->ReadSelf(*this);
[802]491 unsigned char ppstag;
492 // Read the ENDOBJECT
493 GetRawUByte(ppstag);
494 if (ppstag != PPS_ENDOBJECT)
495 throw FileFormatExc("PInPersist::ReadObject No PPS_ENDOBJECT tag");
496 GetRawU8(oid2);
497 if (oid2 != oid)
498 throw FileFormatExc("PInPersist::ReadObject Inconsistent PPS-OId at PPS_ENDOBJECT ");
499
500 KeepOId(oid, *object);
[241]501 return object;
[802]502 }
503 else if (ppstype == PPS_REFERENCE)
504 return ReadReference();
505
506 else throw FileFormatExc("PInPersist::ReadObject invalide Tag Type !");
507}
508
509
510
511void
512PInPersist::ReadReference(PPersist & ppo)
[241]513{
[802]514 PPersist * pr = ReadReference();
515 ppo.ShareDataReference(*pr);
[241]516}
517
[802]518
519PPersist *
520PInPersist::ReadReference()
521{
522 uint_8 oid;
523 int_8 pos;
524 GetRawU8(oid);
525 GetRawI8(pos);
526 // cerr << " DBG - PInPersist::ReadReference-A " << oid << " Pos= " << pos << endl;
527 map<uint_8, PPersist *>::iterator i = objList.find(oid);
528 if (i != objList.end()) return (*i).second;
529 else { // We may have skeeped it !
530 // Let's try to read it
531 int_8 cpos;
532 cpos = s->tellg();
533 s->seekg(pos);
534 PPersist* ppo = ReadObject();
535 s->seekg(cpos);
536 delete ppo;
537 // cerr << " DBG - PInPersist::ReadReference-B ... " << endl;
538
539 map<uint_8, PPersist *>::iterator i2 = objList.find(oid);
540 if (i2 == objList.end())
541 throw FileFormatExc("PInPersist::ReadReference() Not found PPS_OId ");
542 return (*i2).second;
543 }
544}
545
546
547void
548PInPersist::KeepOId(uint_8 oid, PPersist & ppo)
549{
550 if ((oid&0x1) == 0) return; // This is not an object which can be referenced
551 // cerr << " DBG - PInPersist::KeepOId() " << oid << endl;
552 if ((objList.size() > 0) && (objList.find(oid) != objList.end()) ) {
[2459]553 // Ceci ne devrait arriver que si on lit dans le desordre (avec GotoNameTag)
[802]554 // et pas avec une lecture sequentielle ... Reza 03/2000
555 // cerr << "PInPersist::KeepOId()/Warning - already present PPS_ObjectId ! " << oid << endl;
556 if (seqread) throw FileFormatExc("PInPersist::KeepOId() already present PPS_ObjectId ");
557 PPersist *pp = (*objList.find(oid)).second;
558 ppo.ShareDataReference(*pp);
559 }
560 else {
561 PPersist * npp = ppo.CloneSharedReference();
562 if (npp == NULL) throw PError("PInPersist::KeepOId() NULL returned by PPersist.Clone() ! ");
563 objList[oid] = npp;
564 }
565 return;
566}
567
[219]568//++
569// Class POutPersist
570// Lib Outils++
571// include ppersist.h
572//
573// Fichier d'objets persistants, en écriture.
574//--
575
576
577//++
578// POutPersist(string const& flnm, int endianness = PPersist::PPS_NATIVE)
579//
580// Crée un nouveau fichier ppersist. Par défaut, il est petit=boutien
581// sur machines petit-boutiennes, et gros-boutien sur machines
582// gros-boutiennes. On peut explicitement spécifier PPersist::PPS_LITTLE_ENDIAN
583// ou PPersist::PPS_BIG_ENDIAN.
584//--
[2477]585POutPersist::POutPersist(RawInOutStream* os, bool ad, int endianness)
586 : PPFBinaryOutputStream(os, ad, endianness)
587{
588 pps_OId = 0;
589 wobj_level = 0;
590}
591
[219]592POutPersist::POutPersist(string const& flnm, int endianness)
[2475]593 : PPFBinaryOutputStream(flnm, endianness)
[219]594{
[802]595 // PPS (POutPersist stream) Object Id initialisation
596 pps_OId = 0;
[2477]597 wobj_level = 0;
[219]598}
599
600POutPersist::~POutPersist()
601{
602}
603
604
[241]605void
[802]606POutPersist::PutObject(AnyDataObj & o)
607{
608 ClassCreatorFunc f = FindCreatorFunc(getDataObjClassId(o));
609 if (!f)
610 throw NotFoundExc("PInPersist::PutObject() class not registered");
611 PPersist* ppo = f();
612 ppo->SetDataObj(o);
613 PutPPObject(ppo);
[219]614}
615
[241]616void
[802]617POutPersist::PutObject(AnyDataObj & o, string tagname)
[241]618{
[2441]619 WriteNameTag(tagname);
[802]620 PutObject(o);
621}
[219]622
[802]623
624void
625POutPersist::PutPPObject(PPersist const* obj)
626{
627 if (serializeNullAndRepeat(obj)) return; // NULL object or already written in stream
628
629 // We have to write the object
630 uint_8 oid = assignObjectId(obj); // We assing a PPS Object Id
631 PutRawUByte(PPS_OBJECT); // We write the Object Tag
[2477]632 wobj_level++; // Niveau d'imbrication d'ecriture d'objets
[802]633 PutRawU8(getPPClassId(*obj)); // Writing the PPersist ClassId
634 PutRawU8(oid); // Write the PPS Object Id
[241]635 obj->WriteSelf(*this);
[2477]636 // Comptage d'objets ecrits
637 _nbobjs++;
[2482]638 if (wobj_level > _maxnestlevel) _maxnestlevel = wobj_level;
[2477]639 if (wobj_level == 1) _nbtlobjs++;
640 wobj_level--;
[802]641 PutRawUByte(PPS_ENDOBJECT); // We write the End-Of-Object Tag
642 PutRawU8(oid); // and again its PPS Object Id
[241]643}
[219]644
[241]645bool
646POutPersist::serializeNullAndRepeat(PPersist const* x)
[219]647{
[241]648 if (x == NULL) {
[802]649 PutRawUByte(PPS_NULL);
[241]650 return true;
651 }
[219]652
[802]653 int_8 pos;
654 uint_8 id = findObjectId(x, pos);
655 if (id > 0) {
656 PutRawUByte(PPS_REFERENCE);
657 PutRawU8(id); // Writing the corresponding object Id
658 PutRawI8(pos); // The original object position
[2482]659 _nbrefs++; // Compteur de nombre de reference ecrits
[241]660 return true;
661 }
[219]662
[802]663 return false; // Object have to be written in stream ...
[219]664}
665
[802]666uint_8
[241]667POutPersist::assignObjectId(PPersist const* x)
[219]668{
[802]669 pps_OId += 16; // We keep the three first bytes for future usage
670 // Bit 1 non zero -> Object can be referenced
671 uint_8 id = pps_OId;
672 uint_8 mid = x->getMemOId();
673 if (mid > 0) {
674 int_8 pos;
675 if (findObjectId(x,pos) > 0)
676 throw PError("POutPersist::assignObjectId() Error - Already serialized object ! ");
[821]677 id += 1; // Bit 1 non zero -> Object can be referenced
[802]678 objreftag rt;
679 rt.ppsoid = id;
[2476]680 // cout << " DBG-rt.ppspos = s->tellp(); " << endl;
[802]681 rt.ppspos = s->tellp();
[2476]682 // cout << " DBG-rt.ppspos = s->tellp(); = " << rt.ppspos << endl;
[802]683 objList[mid] = rt;
684 }
[241]685 return id;
[219]686}
687
[802]688uint_8
689POutPersist::findObjectId(PPersist const* x, int_8 & pos)
[219]690{
[802]691 pos = -1;
692 uint_8 mid = x->getMemOId();
693 if (mid == 0) return(0);
694 ObjList::iterator i = objList.find(mid);
695 if (i == objList.end()) return 0;
696 pos = (*i).second.ppspos;
697 return (*i).second.ppsoid;
[219]698}
699
[241]700
Note: See TracBrowser for help on using the repository browser.