0024023: Revamp the OCCT Handle -- general
[occt.git] / src / IFSelect / IFSelect_SessionFile.cxx
1 // Copyright (c) 1999-2014 OPEN CASCADE SAS
2 //
3 // This file is part of Open CASCADE Technology software library.
4 //
5 // This library is free software; you can redistribute it and/or modify it under
6 // the terms of the GNU Lesser General Public License version 2.1 as published
7 // by the Free Software Foundation, with special exception defined in the file
8 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
9 // distribution for complete text of the license and disclaimer of any warranty.
10 //
11 // Alternatively, this file may be used under the terms of Open CASCADE
12 // commercial license or contractual agreement.
13
14 #include <IFSelect_SessionFile.ixx>
15 #include <IFSelect_SessionDumper.hxx>
16 #include <IFSelect_BasicDumper.hxx>
17 #include <IFSelect_IntParam.hxx>
18 #include <IFSelect_Selection.hxx>
19 #include <IFSelect_SelectExtract.hxx>
20 #include <IFSelect_SelectDeduct.hxx>
21 #include <IFSelect_SelectControl.hxx>
22 #include <IFSelect_SelectCombine.hxx>
23 #include <IFSelect_SelectAnyType.hxx>
24 #include <IFSelect_SelectAnyList.hxx>
25 #include <IFSelect_ShareOut.hxx>
26 #include <IFSelect_Dispatch.hxx>
27 #include <IFSelect_Modifier.hxx>
28 #include <IFSelect_Transformer.hxx>
29 #include <TCollection_HAsciiString.hxx>
30 #include <TColStd_HSequenceOfInteger.hxx>
31
32 #include <Message_Messenger.hxx>
33 #include <Message.hxx>
34 #include <Interface_Macros.hxx>
35 #include <stdio.h>
36
37 #include <OSD_OpenFile.hxx>
38 #include <IFSelect_GeneralModifier.hxx>
39
40
41 static int deja = 0;
42
43
44     IFSelect_SessionFile::IFSelect_SessionFile
45   (const Handle(IFSelect_WorkSession)& WS)
46 {
47   ClearLines();
48   themode = Standard_False;
49   if (!deja) {    // au moins celui-la :
50     Handle(IFSelect_BasicDumper) basedumper = new IFSelect_BasicDumper;
51     deja = 1;
52   }
53   thedone = Standard_False;
54   thelastgen = 0;
55   thesess = WS;
56 }
57
58     IFSelect_SessionFile::IFSelect_SessionFile
59   (const Handle(IFSelect_WorkSession)& WS, const Standard_CString filename)
60 {
61   ClearLines();
62   themode = Standard_True;
63   if (!deja) {    // au moins celui-la :
64     Handle(IFSelect_BasicDumper) basedumper = new IFSelect_BasicDumper;
65     deja = 1;
66   }
67   thedone = Standard_False;
68   theownflag = Standard_False;
69   thelastgen = 0;
70   thesess = WS;
71   thedone = (Write (filename) == 0);
72 //  Close fait par Write (selon les cas)
73 }
74
75
76     void  IFSelect_SessionFile::ClearLines ()
77       {  thelist.Clear();  thenl = 0;  }
78
79     Standard_Integer  IFSelect_SessionFile::NbLines () const
80       {  return thelist.Length();  }
81
82
83     const TCollection_AsciiString&  IFSelect_SessionFile::Line
84   (const Standard_Integer num) const
85       {  return thelist.Value(num);  }
86
87
88     void  IFSelect_SessionFile::AddLine (const Standard_CString line)
89       {  thelist.Append (TCollection_AsciiString(line) );  }
90
91     void  IFSelect_SessionFile::RemoveLastLine ()
92       {  if (thelist.Length() > 1) thelist.Remove(thelist.Length());  }
93
94
95     Standard_Boolean  IFSelect_SessionFile::WriteFile
96   (const Standard_CString filename)
97 {
98   FILE* lefic = OSD_OpenFile(filename,"w");
99   Standard_Integer nbl = thelist.Length();
100   for (Standard_Integer i = 1; i <= nbl; i ++)
101     fprintf (lefic,"%s\n",thelist.Value(i).ToCString());
102   fclose ( lefic );
103   ClearLines();
104   return Standard_True;
105 }
106
107     Standard_Boolean  IFSelect_SessionFile::ReadFile
108   (const Standard_CString filename)
109 {
110   char ligne[201];
111   FILE* lefic = OSD_OpenFile(filename,"r");
112   if (!lefic) return Standard_False;
113   ClearLines();
114 //  read mode : lire les lignes
115 //  On charge le fichier dans "thelist"
116   Standard_Boolean header = Standard_False;
117   for(;;) {
118     ligne[0] = '\0';
119     fgets(ligne,200,lefic);
120     if (feof(lefic)) break;
121     if (ligne[0] == '\0') continue;
122 //  D abord ligne initiale ?
123     if (!header)
124       {  if (!RecognizeFile(ligne)) break;  header = Standard_True;  }
125     ligne[200] = '\0';  // fin forcee ...
126     TCollection_AsciiString onemore(ligne);
127     thelist.Append(onemore);
128   }
129   fclose ( lefic );
130   return header;
131 }
132
133     Standard_Boolean  IFSelect_SessionFile::RecognizeFile
134   (const Standard_CString headerline)
135 {
136   Handle(Message_Messenger) sout = Message::DefaultMessenger();
137
138   SplitLine (headerline);
139   if (theline.Length() != 4) { sout<<"File Form Incorrect"<<endl; return Standard_False; }
140   Handle(Standard_Type) sesstype = thesess->DynamicType();
141   if (!theline.Value(1).IsEqual("!XSTEP")  ||
142       !theline.Value(2).IsEqual("SESSION") ||
143       !theline.Value(4).IsEqual(sesstype->Name()) )
144     { sout<<"Lineno."<<thenl<<" : File Header Description Incorrect"<<endl; return Standard_False; }
145 //   Value(3) definit la VERSION du format de fichier
146   return Standard_True;
147 }
148
149
150     Standard_Integer  IFSelect_SessionFile::Write
151   (const Standard_CString filename)
152 {
153   thenewnum = 0;
154   Standard_Integer stat = WriteSession();
155   if (stat != 0) return stat;
156   stat = WriteEnd();
157   if (stat != 0) return stat;
158   return (WriteFile(filename) ? 0 : -1);
159 }
160
161     Standard_Integer  IFSelect_SessionFile::Read
162   (const Standard_CString filename)
163 {
164   if (!ReadFile(filename)) return -1;
165   thenewnum = 0;
166   Standard_Integer stat = ReadSession();
167   if (stat != 0) return stat;
168   stat = ReadEnd();
169   return stat;
170 }
171
172
173 //  ##################################################################
174 //  ########        WriteSession : Ecriture du contenu        ########
175
176     Standard_Integer  IFSelect_SessionFile::WriteSession ()
177 {
178   char laligne[200];
179   thedone = Standard_True;
180 //  ...  Preparation Specifique
181   thenames.Nullify();
182   Standard_Integer nbidents = thesess->MaxIdent();
183   thenums = new TColStd_HArray1OfInteger (0,nbidents); thenums->Init(0);
184   Standard_Integer i; // svv Jan11 2000 : porting on DEC
185   for ( i = 1; i <= nbidents; i ++) {
186     Handle(Standard_Transient) item = thesess->Item(i);
187     if (!item.IsNull()) thenums->SetValue(i,-1);
188   }
189
190 //  ...  ECRITURE
191   sprintf (laligne,"!XSTEP SESSION V1 %s",thesess->DynamicType()->Name());
192   WriteLine(laligne,'\n');
193   sprintf (laligne,"!GENERALS");
194   WriteLine(laligne,'\n');
195   sprintf (laligne,"ErrorHandle %d", (thesess->ErrorHandle() ? 1 : 0));
196   WriteLine(laligne,'\n');
197   Handle(TColStd_HSequenceOfInteger) idents;
198   Standard_Integer nb;
199   Handle(TCollection_HAsciiString) name;
200
201   idents = thesess->ItemIdents(STANDARD_TYPE(IFSelect_IntParam));
202   nb = idents->Length();
203   if (nb > 0) WriteLine ("!INTEGERS",'\n');
204   Standard_Integer j; // svv Jan11 2000 : porting on DEC
205   for (j = 1; j <= nb; j ++) {
206     i = idents->Value(j);
207     Handle(IFSelect_IntParam) P = thesess->IntParam(i);
208     name = thesess->Name(P);
209     if (name.IsNull()) {
210       thenewnum ++;  idents->SetValue(i,thenewnum);
211       sprintf(laligne," #%d %d",thenewnum,P->Value());
212     }
213     else  sprintf(laligne," %s %d",name->ToCString(),P->Value());
214     WriteLine(laligne,'\n');
215   }
216
217   idents = thesess->ItemIdents(STANDARD_TYPE(TCollection_HAsciiString));
218   nb = idents->Length();
219   if (nb > 0) WriteLine ("!TEXTS",'\n');
220   for (j = 1; j <= nb; j ++) {
221     i = idents->Value(j);
222     Handle(TCollection_HAsciiString) P = thesess->TextParam(i);
223     name = thesess->Name(P);
224     if (name.IsNull()) {
225       thenewnum ++;  thenums->SetValue(i,thenewnum);
226       sprintf(laligne," #%d %s",thenewnum,P->ToCString());
227     }
228     else  sprintf(laligne," %s %s",name->ToCString(),P->ToCString());
229     WriteLine(laligne,'\n');
230   }
231
232   idents = thesess->ItemIdents(STANDARD_TYPE(IFSelect_Selection));
233   nb = idents->Length();
234   if (nb > 0) WriteLine ("!SELECTIONS",'\n');
235   for (j = 1; j <= nb; j ++) {
236     i = idents->Value(j);
237     Handle(IFSelect_Selection) P = thesess->Selection(i);
238     NewItem (i,P);
239 //  ..  Ecritures particulieres
240 //  ->  Traiter les principaux sous-types : Extract,AnyList,AnyType
241     DeclareAndCast(IFSelect_SelectExtract,sxt,P);
242     if (!sxt.IsNull()) {
243       sprintf(laligne," %c", (sxt->IsDirect() ? 'D' : 'R'));
244       WriteLine(laligne);
245     }
246     DeclareAndCast(IFSelect_SelectAnyList,sli,P);
247     if (!sli.IsNull()) {
248       SetOwn(Standard_False);
249       WriteLine(" LIST");
250       SendItem(sli->Lower());
251       SendItem(sli->Upper());
252       SetOwn(Standard_True);
253     }
254 //  ..  Ecritures specifiques selon dumpers
255     WriteOwn(P);
256     WriteLine("",'\n');
257   }
258
259   SetOwn(Standard_False);
260   if (nb > 0) WriteLine ("!SOURCES",'\n');
261   for (j = 1; j <= nb; j ++) {
262     i = idents->Value(j);
263     Handle(IFSelect_Selection) P = thesess->Selection(i);
264     Standard_Integer nbs = thesess->NbSources(P);
265     if (nbs == 0) continue;
266     name = thesess->Name(P);
267     if (name.IsNull())  sprintf(laligne," #%d %d",thenums->Value(i),nbs);
268     else                sprintf(laligne," %s %d",name->ToCString(),nbs);
269     WriteLine(laligne);
270     for (Standard_Integer k = 1; k <= nbs; k ++)
271       SendItem (thesess->Source(P,k));
272     WriteLine("",'\n');
273   }
274
275   idents = thesess->ItemIdents(STANDARD_TYPE(IFSelect_GeneralModifier));
276   nb = idents->Length();
277   if (nb > 0) WriteLine ("!MODIFIERS",'\n');
278   for (j = 1; j <= nb; j ++) {
279 //  Description de base des Modifiers, donc sans Selection ni Dispatch-Rank
280     i = idents->Value(j);
281     Handle(IFSelect_GeneralModifier) P = thesess->GeneralModifier(i);
282     NewItem (i,P);
283     SetOwn(Standard_True);
284 //  ..  Ecritures specifiques selon dumpers
285     WriteOwn(P);
286     WriteLine("",'\n');
287   }
288
289   idents = thesess->ItemIdents(STANDARD_TYPE(IFSelect_Transformer));
290   nb = idents->Length();
291   if (nb > 0) WriteLine ("!TRANSFORMERS",'\n');
292   for (j = 1; j <= nb; j ++) {
293 //  Description des Transformers
294     i = idents->Value(j);
295     Handle(IFSelect_Transformer) P = thesess->Transformer(i);
296     NewItem (i,P);
297     SetOwn(Standard_True);
298 //  ..  Ecritures specifiques selon dumpers
299     WriteOwn(P);
300     WriteLine("",'\n');
301   }
302
303   SetOwn(Standard_False);
304   idents = thesess->ItemIdents(STANDARD_TYPE(IFSelect_Dispatch));
305   nb = idents->Length();
306   if (nb > 0) WriteLine ("!DISPATCHES",'\n');
307   for (j = 1; j <= nb; j ++) {
308     i = idents->Value(j);
309     Handle(IFSelect_Dispatch) P = thesess->Dispatch(i);
310     NewItem (i,P);
311 //  ..  Final Selection
312     SetOwn(Standard_False);
313     SendItem(P->FinalSelection());
314     SetOwn(Standard_True);
315 //  ..  Ecritures specifiques selon dumpers
316     WriteOwn(P);
317     WriteLine("",'\n');
318   }
319
320   WriteLine ("!FILENAMING");
321   SetOwn(Standard_False);
322   Handle(TCollection_HAsciiString) namingpart = thesess->FilePrefix();
323   if (namingpart->IsEmpty()) namingpart.Nullify();
324   if (namingpart.IsNull()) SendVoid();
325   else SendText(namingpart->ToCString());
326   namingpart = thesess->DefaultFileRoot();
327   if (namingpart->IsEmpty()) namingpart.Nullify();
328   if (namingpart.IsNull()) SendVoid();
329   else SendText(namingpart->ToCString());
330   namingpart = thesess->FileExtension();
331   if (namingpart->IsEmpty()) namingpart.Nullify();
332   if (namingpart.IsNull()) SendVoid();
333   else SendText(namingpart->ToCString());
334   WriteLine("",'\n');
335
336   for (j = 1; j <= nb; j ++) {
337     i = idents->Value(j);
338     Handle(IFSelect_Dispatch) P = thesess->Dispatch(i);
339     if (!P->HasRootName()) continue;
340     namingpart = P->RootName();
341     SetOwn(Standard_False);
342     SendItem(P);
343     sprintf(laligne," %s",namingpart->ToCString());
344     WriteLine(laligne,' ');
345     WriteLine("",'\n');
346   }
347
348 //   Pour les Modifiers, ATTENTION car il faut respecter l ORDRE effectif
349 //   Or il y a deux listes : Model Modifiers; File Modifiers
350 //   Les Modifiers eux-memes ont deja ete ecrits
351 //   Ici, on ecrit simplement leur utilisation dans l envoi final
352   for (Standard_Integer formod = 1; formod >= 0; formod --) {
353     idents = thesess->FinalModifierIdents((formod > 0));  // donnes dans l ordre d application
354     nb = idents->Length();
355     if (nb == 0) continue;
356     if (formod > 0) WriteLine ("!MODELMODIFIERS",'\n');
357     else            WriteLine ("!FILEMODIFIERS",'\n');
358     for (j = 1; j <= nb; j ++) {
359       i = idents->Value(j);
360       Handle(IFSelect_GeneralModifier) P = thesess->GeneralModifier(i);
361       SetOwn(Standard_False);
362       SendItem(P);
363       //  ..  Parametres Generaux (les specifiques ont deja ete envoyes)
364       SendItem(P->Selection());
365       SendItem(P->Dispatch());
366       WriteLine("",'\n');
367     }
368   }
369
370 //  ...  Conclusion
371   theline.Clear();
372   return 0;
373 }
374
375     Standard_Integer  IFSelect_SessionFile::WriteEnd ()
376 {
377   WriteLine("!XSTEP END",'\n');   // sinon, cf sous-types de SessionFile ...
378   return 0;
379 }
380
381
382     void  IFSelect_SessionFile::WriteLine
383   (const Standard_CString line, const Standard_Character follow)
384 {
385   if (line[0] != '\0') thebuff.AssignCat (line);
386   if (follow == '\0') return;
387   if (follow != '\n') thebuff.AssignCat(follow);
388   else {
389     thelist.Append(thebuff);
390     thebuff.Clear();
391     thenl ++;
392   }
393 }
394
395     Standard_Boolean  IFSelect_SessionFile::WriteOwn
396   (const Handle(Standard_Transient)& item)
397 {
398   if (item.IsNull()) return Standard_False;
399   SetOwn(Standard_True);
400   Handle(IFSelect_SessionDumper) dumper = IFSelect_SessionDumper::First();
401   while (!dumper.IsNull()) {
402     if (dumper->WriteOwn(*this,item)) break;
403     dumper = dumper->Next();
404   }
405   SetOwn(Standard_False);
406   return (!dumper.IsNull());    // IsNull -> echec
407 }
408
409
410
411 //  ##################################################################
412 //  ########        ReadSession  :  Lecture du contenu        ########
413
414     Standard_Integer  IFSelect_SessionFile::ReadSession ()
415 {
416   Handle(Message_Messenger) sout = Message::DefaultMessenger();
417
418   thedone = Standard_True;
419 //  ...  Preparation Specifique
420   thenums.Nullify();
421   thenames = new Dico_DictionaryOfInteger;
422 //  ..  Donnees generales, controle
423   if (!ReadLine()) return 1;
424   if (theline.Length() != 4) { sout<<"File Form Incorrect"<<endl; return 1; }
425   Handle(Standard_Type) sesstype = thesess->DynamicType();
426   if (!theline.Value(1).IsEqual("!XSTEP")  ||
427       !theline.Value(2).IsEqual("SESSION") ||
428       !theline.Value(4).IsEqual(sesstype->Name()) )
429     { sout<<"Lineno."<<thenl<<" : File Header Description Incorrect"<<endl; return 1; }
430 //   Value(3) definit la VERSION du format de fichier
431   if (!ReadLine()) return 1;
432
433 //  ..  Parametres Generaux
434   Standard_Integer rubr =
435     (theline.Length() == 1 && theline.Value(1).IsEqual("!GENERALS"));
436   while (rubr) {
437     if (!ReadLine()) return 1;
438     if (theline.Length() == 0) continue;
439     const TCollection_AsciiString& ungen = theline.Value(1);
440     if (ungen.Value(1) == '!') break;  // fin des generaux
441     if (ungen.IsEqual("ErrorHandle")) {
442       if (theline.Length() != 2)
443         { sout<<"Lineno."<<thenl<<" : ErrorHandle Description Incorrect"<<endl; continue; }
444       if      (theline.Value(2).IsEqual("0"))
445         thesess->SetErrorHandle(Standard_False);
446       else if (theline.Value(2).IsEqual("1"))
447         thesess->SetErrorHandle(Standard_True);
448       else { sout<<"Lineno."<<thenl<<" : ErrorHandle Incorrect : "<<theline.Value(2)<<endl; continue; }
449       continue;
450     }
451     else sout<<"Lineno."<<thenl<<" : Unknown General Parameter : "<<ungen<<" , ignored"<<endl;
452   }
453
454 //  ..  IntParams
455 //   deja fait  if (!ReadLine()) return 1;
456   rubr = (theline.Length() == 1 && theline.Value(1).IsEqual("!INTEGERS"));
457   while (rubr) {
458     if (!ReadLine()) return 1;
459     if (theline.Value(1).Value(1) == '!') break;    // liste suivante
460     if (theline.Length() != 2)
461       { sout<<"Lineno."<<thenl<<" : An Integer Parameter is badly defined"<<endl; continue; }
462     Handle(IFSelect_IntParam) par = new IFSelect_IntParam;
463     par->SetValue ( atoi(theline.Value(2).ToCString()) );
464     AddItem (par);
465   }
466
467 //  .. TextParams (ligne de garde deja lue)
468   rubr = (theline.Length() == 1 && theline.Value(1).IsEqual("!TEXTS"));
469   while (rubr) {
470     if (!ReadLine()) return 1;
471     if (theline.Value(1).Value(1) == '!') break;    // liste suivante
472     if (theline.Length() != 2)
473       { sout<<"Lineno."<<thenl<<" : A Text Parameter is badly defined"<<endl; continue; }
474 //    Attention, un texte peut contenir des blancs ...  repartir de line(thenl)
475     TCollection_AsciiString oneline = thelist.Value(thenl);
476     Standard_Integer iw = 0, inc = 0;
477     for (Standard_Integer ic = 1; ic <= oneline.Length(); ic ++) {
478       char unc = oneline.Value(1);
479       inc = ic;
480       if (unc == ' ') iw = 1;
481       else if (iw > 0) break;
482     }
483     oneline.Remove (1,inc);
484     AddItem ( new TCollection_HAsciiString (oneline.ToCString()) );
485   }
486
487 //  .. Selections (ligne de garde deja lue)
488   rubr = (theline.Length() == 1 && theline.Value(1).IsEqual("!SELECTIONS"));
489   while (rubr) {
490     if (!ReadLine()) return 1;
491     if (theline.Value(1).Value(1) == '!') break;    // liste suivante
492     if (theline.Length() < 2)
493       { sout<<"Lineno."<<thenl<<" : A Selection is badly defined"<<endl; continue; }
494 //  ..  Analyse de certains cas generaux
495     Handle(IFSelect_IntParam) low,up;
496     Standard_Integer firstown = 3;
497     Standard_Integer direct   = 0;
498     Standard_Integer numlist  = 0;
499     if (theline.Length() > 2) {
500       if      (theline.Value(3).IsEqual("D")) direct = 1;
501       else if (theline.Value(3).IsEqual("R")) direct = -1;
502       if (direct != 0) firstown ++;
503       if (firstown+2 <= theline.Length()) {
504         if (theline.Value(firstown).IsEqual("LIST"))  {
505           numlist = firstown;  firstown += 3;
506           low = GetCasted(IFSelect_IntParam,ItemValue(numlist+1));
507           up  = GetCasted(IFSelect_IntParam,ItemValue(numlist+2));
508         }
509       }
510       SetLastGeneral (firstown-1);
511     }
512     Handle(Standard_Transient) item;   // a fournir ...
513     ReadOwn(item);
514     if (item.IsNull()) continue;
515     DeclareAndCast(IFSelect_SelectExtract,sxt,item);
516     if (!sxt.IsNull()) {
517       if (direct == 0) sout<<"Lineno."<<thenl<<" : A SelectExtract is badly defined"<<endl;
518       else  sxt->SetDirect( (direct > 0) );
519     }
520     DeclareAndCast(IFSelect_SelectAnyList,sli,item);
521     if (!sli.IsNull()) {
522       if (numlist == 0) sout<<"Lineno."<<thenl<<" : A SelectAnyList is badly defined"<<endl;
523       else sli->SetRange(low,up);
524     }
525     AddItem(item);
526   }
527
528 //  .. Sources
529   rubr = (theline.Length() == 1 && theline.Value(1).IsEqual("!SOURCES"));
530   while (rubr) {
531     if (!ReadLine()) return 1;
532     if (theline.Value(1).Value(1) == '!') break;    // liste suivante
533     if (theline.Length() < 3)
534       { sout<<"Lineno."<<thenl<<" : A Selection Source List is badly defined"<<endl; continue; }
535     DeclareAndCast(IFSelect_Selection,sel,ItemValue(1));
536     if (sel.IsNull())
537       { sout<<"Lineno."<<thenl<<" : A Source List is not for a Selection"<<endl; continue; }
538     Standard_Integer nbs = atoi(theline.Value(2).ToCString());
539 //  .. Differents cas reconnus
540     DeclareAndCast(IFSelect_SelectExtract,sxt,sel);
541     if (!sxt.IsNull()) {
542       if (nbs > 1)
543         sout<<"Lineno."<<thenl<<" : SelectExtract, more than one source, followings ignored"<<endl;
544       DeclareAndCast(IFSelect_Selection,source,ItemValue(3));
545       sxt->SetInput(source);
546     }
547     DeclareAndCast(IFSelect_SelectDeduct,sdt,sel);
548     if (!sdt.IsNull()) {
549       if (nbs > 1)
550         sout<<"Lineno."<<thenl<<" : SelectDeduct, more than one source, followings ignored"<<endl;
551       sdt->SetInput(GetCasted(IFSelect_Selection,ItemValue(3)));
552     }
553     DeclareAndCast(IFSelect_SelectControl,sct,sel);
554     if (!sct.IsNull()) {
555       if (nbs != 2)
556         sout<<"Lineno."<<thenl<<" : SelectControl, not two sources, followings ignored"<<endl;
557       sct->SetMainInput   (GetCasted(IFSelect_Selection,ItemValue(3)));
558       sct->SetSecondInput (GetCasted(IFSelect_Selection,ItemValue(4)));
559     }
560     DeclareAndCast(IFSelect_SelectCombine,sco,sel);
561     if (!sco.IsNull()) {
562       for (Standard_Integer j = 1; j <= nbs; j ++)
563         sco->Add(GetCasted(IFSelect_Selection,ItemValue(j+2)));
564     }
565   }
566
567 //  ... Modifiers en tout genre
568   rubr = (theline.Length() == 1 && theline.Value(1).IsEqual("!MODIFIERS"));
569   while (rubr) {
570     if (!ReadLine()) return 1;
571     if (theline.Value(1).Value(1) == '!') break;    // liste suivante
572     if (theline.Length() < 2)
573       { sout<<"Lineno."<<thenl<<" : A Modifier is badly defined"<<endl; continue; }
574     Handle(Standard_Transient) item;   // a fournir ...
575     ReadOwn(item);
576     if (item.IsNull()) continue;
577     DeclareAndCast(IFSelect_GeneralModifier,modif,item);
578     if (modif.IsNull())
579       { sout<<"Lineno."<<thenl<<" : A Modifier has not been Recognized"<<endl; continue; }
580     AddItem(modif,Standard_False);  // active plus tard
581   }
582
583 //  ... Transformers
584   rubr = (theline.Length() == 1 && theline.Value(1).IsEqual("!TRANSFORMERS"));
585   while (rubr) {
586     if (!ReadLine()) return 1;
587     if (theline.Value(1).Value(1) == '!') break;    // liste suivante
588     if (theline.Length() < 2)
589       { sout<<"Lineno."<<thenl<<" : A Transformer is badly defined"<<endl; continue; }
590     Handle(Standard_Transient) item;   // a fournir ...
591     ReadOwn(item);
592     if (item.IsNull()) continue;
593     DeclareAndCast(IFSelect_Transformer,trf,item);
594     if (trf.IsNull())
595       { sout<<"Lineno."<<thenl<<" : A Transformer has not been Recognized"<<endl; continue; }
596     AddItem(trf,Standard_False);  // active plus tard
597   }
598
599 //  ... Dispatches (ligne de garde deja lue)
600   rubr = (theline.Length() == 1 && theline.Value(1).IsEqual("!DISPATCHES"));
601   while (rubr) {
602     if (!ReadLine()) return 1;
603     if (theline.Value(1).Value(1) == '!') break;    // liste suivante
604     if (theline.Length() < 3)
605       { sout<<"Lineno."<<thenl<<" : A Dispatch is badly defined"<<endl; continue; }
606     DeclareAndCast(IFSelect_Selection,input,ItemValue(3));
607     SetLastGeneral(3);
608     Handle(Standard_Transient) item;   // a fournir ...
609     ReadOwn(item);
610     if (item.IsNull()) continue;
611     DeclareAndCast(IFSelect_Dispatch,disp,item);
612     if (disp.IsNull())
613       { sout<<"Lineno."<<thenl<<" : A Dispatch has not been Recognized"<<endl; continue; }
614     AddItem(disp);
615     thesess->SetItemSelection(disp,input);
616   }
617
618 //  ... FileNaming (ligne de garde deja lue)
619 //  ..  Modifiers deja lus et charges
620   rubr = (theline.Length() == 4 && theline.Value(1).IsEqual("!FILENAMING"));
621   if (rubr) {
622     if (!IsVoid(2)) thesess->SetFilePrefix      (TextValue(2).ToCString());
623     if (!IsVoid(3)) thesess->SetDefaultFileRoot (TextValue(3).ToCString());
624     if (!IsVoid(4)) thesess->SetFileExtension   (TextValue(4).ToCString());
625   }
626   while (rubr) {
627     if (!ReadLine()) return 1;
628     if (theline.Value(1).Value(1) == '!') break;    // liste suivante
629     if (theline.Length() != 2)
630       { sout<<"Lineno."<<thenl<<" : A File Root is badly defined"<<endl; continue; }
631     DeclareAndCast(IFSelect_Dispatch,disp,ItemValue(1));
632     thesess->SetFileRoot (disp,theline.Value(2).ToCString());
633   }
634
635 //  ... Modifiers (ligne de garde deja lue)
636 //  ... Attention, deux listes (MODELMODIFIERS et FILEMODIFIERS)
637   for (Standard_Integer formod = 1; formod >= 0; formod --) {
638     rubr = (theline.Length() == 1 &&
639             ( (formod == 1 && theline.Value(1).IsEqual("!MODELMODIFIERS")) ||
640               (formod == 0 && theline.Value(1).IsEqual("!FILEMODIFIERS"))  ) );
641 //    if ( formod == 1 && ( theline.Length() != 1 ||
642 //                       !theline.Value(1).IsEqual("!MODELMODIFIERS")) )
643 //      { sout<<"Lineno."<<thenl<<" : Model Modifier List Incorrect"<<endl;  return 1; }
644 //    if ( formod == 0 && ( theline.Length() != 1 ||
645 //                       !theline.Value(1).IsEqual("!FILEMODIFIERS")) )
646 //      { sout<<"Lineno."<<thenl<<" : File Modifier List Incorrect"<<endl;  return 1; }
647     while (rubr) {
648       if (!ReadLine()) return 1;
649       if (theline.Value(1).Value(1) == '!') break;    // liste suivante
650       if (theline.Length() < 3)
651         { sout<<"Lineno."<<thenl<<" : A General Modifier is badly defined"<<endl; continue; }
652       DeclareAndCast(IFSelect_GeneralModifier,modif,ItemValue(1));
653       DeclareAndCast(IFSelect_Selection,input,ItemValue(2));
654       DeclareAndCast(IFSelect_Dispatch,disp,ItemValue(3));
655       if (modif.IsNull())
656         { sout<<"Lineno."<<thenl<<" : A General Modifier has not been Recognized"<<endl; continue; }
657       thesess->SetItemSelection   (modif,input);
658       if (!disp.IsNull()) thesess->SetAppliedModifier (modif,disp);
659       else                thesess->SetAppliedModifier (modif,thesess->ShareOut());
660     }
661   }
662
663 //  ...  Conclusion : voir ReadEnd (separe)
664   return 0;
665 }
666
667     Standard_Integer  IFSelect_SessionFile::ReadEnd ()
668 {
669   Handle(Message_Messenger) sout = Message::DefaultMessenger();
670   if ( theline.Length() != 2 ||
671       !theline.Value(1).IsEqual("!XSTEP") ||
672       !theline.Value(2).IsEqual("END"))
673     { sout<<"End of File Incorrect, lineno"<<thenl<<endl;  return 1; }
674   return 0;
675 }
676
677
678     Standard_Boolean  IFSelect_SessionFile::ReadLine ()
679 {
680   if (thenl >= thelist.Length()) return Standard_False;
681   thenl ++;
682   Standard_CString ligne = thelist.Value(thenl).ToCString();
683 //   Lignes vides ?
684   if (ligne[0] == '\0') return ReadLine();
685   SplitLine (ligne);
686   return Standard_True;
687 }
688
689
690     void  IFSelect_SessionFile::SplitLine (const Standard_CString line)
691 {
692   char mot[80];
693   theline.Clear();
694   Standard_Integer nbc  = 0;
695   Standard_Boolean word = (line[0] > ' ');
696   for (Standard_Integer i = 0; line[i] != '\0'; i ++) {
697     if (line[i] > ' ') {
698       if (!word) {  nbc = 0; word = Standard_True;  }
699       mot[nbc] = line[i];  nbc ++;
700     } else {
701       if (word) {
702         word = Standard_False;
703         mot[nbc] = '\0';
704         theline.Append (TCollection_AsciiString(mot));
705       }
706       if (line[i] == '\0' || line[i] == '\n') break;
707     }
708   }
709   thelastgen = 0;
710 }
711
712     Standard_Boolean  IFSelect_SessionFile::ReadOwn
713   (Handle(Standard_Transient)& item)
714 {
715   Handle(Message_Messenger) sout = Message::DefaultMessenger();
716
717   if (theline.Length() < 2) return Standard_False;
718   const TCollection_AsciiString& type = theline.Value(2);
719   if (thelastgen < 2) thelastgen = 2;        // mini : ident+type d abord
720 //  thelastgen = theline.Length();
721 //  for (Standard_Integer i = theline.Length(); i > 0; i --) {
722 //    if (theline.Value(i).Value(1) == ':') thelastgen = i - 1;
723 //  }
724   Handle(IFSelect_SessionDumper) dumper = IFSelect_SessionDumper::First();
725   while (!dumper.IsNull()) {
726     if (dumper->ReadOwn(*this,type,item)) break;
727     dumper = dumper->Next();
728   }
729   if (dumper.IsNull()) sout<<" -- Lineno."<<thenl<<" : an Item could not be read"<<endl;
730   return (!dumper.IsNull());    // IsNull -> echec
731 }
732
733
734     void  IFSelect_SessionFile::AddItem
735   (const Handle(Standard_Transient)& item, const Standard_Boolean active)
736 {
737   Handle(Message_Messenger) sout = Message::DefaultMessenger();
738
739   const TCollection_AsciiString& name = theline.Value(1);
740   Standard_Integer id = 0;
741   if (!item.IsNull()) {
742     if (name.Value(1) == '#') id = thesess->AddItem(item,active);
743     else if (!thesess->NamedItem(name.ToCString()).IsNull()) id =
744       thesess->AddItem(item,active);
745     else id = thesess->AddNamedItem(name.ToCString(),item,active);
746   }
747   else sout<<"Lineno."<<thenl<<" -- Name : "<<name
748     <<" : Item could not be defined" << endl;
749   thenames->SetItem(name.ToCString(),id);
750 }
751
752     Standard_Boolean  IFSelect_SessionFile::IsDone () const
753       {  return thedone;  }
754
755     Handle(IFSelect_WorkSession)  IFSelect_SessionFile::WorkSession () const
756       {  return thesess;  }
757
758 //  ########                Actions Unitaires d ECRITURE               ########
759
760     void  IFSelect_SessionFile::NewItem
761   (const Standard_Integer ident, const Handle(Standard_Transient)& par)
762 {
763   char laligne[100];
764   if (!thesess->HasName(par)) {
765     thenewnum ++;  thenums->SetValue(ident,thenewnum);
766     sprintf(laligne," #%d %s",thenewnum,par->DynamicType()->Name());
767   }
768   else  sprintf(laligne," %s %s",thesess->Name(par)->ToCString(),
769                 par->DynamicType()->Name());
770   WriteLine(laligne);
771 }
772
773     void  IFSelect_SessionFile::SetOwn (const Standard_Boolean mode)
774       {  theownflag = mode;  }
775
776     void  IFSelect_SessionFile::SendVoid ()
777 {
778 ////  if (theownflag) WriteLine(" :$");
779   WriteLine(" $");
780 }
781
782     void  IFSelect_SessionFile::SendItem (const Handle(Standard_Transient)& par)
783 {
784   Handle(Message_Messenger) sout = Message::DefaultMessenger();
785
786   char laligne[100];
787   Standard_Integer filenum = 0;
788   Standard_Integer id = thesess->ItemIdent(par);
789   if (id != 0) filenum = thenums->Value(id);
790   if (filenum == 0) {
791     if (!par.IsNull()) sout << "Lineno " << thenl << " --  Unknown Item : "
792        << " Type:" << par->DynamicType()->Name() << endl;  //sout<<Handle par
793     SendVoid();
794     thedone = Standard_False;
795     return;
796   }
797 ////  if (theownflag) WriteLine(" :");
798 ////  else            WriteLine(" ");
799   if (filenum < 0) sprintf(laligne," :%s",thesess->Name(par)->ToCString());
800   else sprintf(laligne," #%d",filenum);
801   WriteLine(laligne);
802 }
803
804     void  IFSelect_SessionFile::SendText (const Standard_CString text)
805 {
806   char laligne[100];
807 ////  if (theownflag) sprintf(laligne," :%s",text);
808   sprintf(laligne," %s",text);
809   WriteLine(laligne);
810 }
811
812
813 //  ########                Actions Unitaires de LECTURE               ########
814
815     void  IFSelect_SessionFile::SetLastGeneral (const Standard_Integer lastgen)
816       {  thelastgen = lastgen;  }
817
818     Standard_Integer  IFSelect_SessionFile::NbParams () const
819       {  return theline.Length() - thelastgen;  }
820
821
822     Standard_Boolean  IFSelect_SessionFile::IsVoid
823   (const Standard_Integer num) const
824 {
825   Standard_Integer nm = num + thelastgen;
826   if (nm <= 0 || nm > theline.Length()) return Standard_True;
827   const TCollection_AsciiString& term = theline.Value(nm);
828   return (term.IsEqual ("$") || term.IsEqual (":$") );
829 }
830
831     Standard_Boolean  IFSelect_SessionFile::IsText
832   (const Standard_Integer num) const
833 {
834   Standard_Integer nm = num + thelastgen;
835   if (nm <= 0 || nm > theline.Length()) return Standard_False;
836   const TCollection_AsciiString& term = theline.Value(nm);
837   if (term.Value(1) == ':') return Standard_False;
838   if (term.Value(1) == '#') return Standard_False;
839   if (term.IsEqual("$"))    return Standard_False;
840   return Standard_True;
841 }
842
843     const TCollection_AsciiString&  IFSelect_SessionFile::ParamValue
844   (const Standard_Integer num) const
845       {  return theline.Value(num+thelastgen);  }
846
847
848     TCollection_AsciiString  IFSelect_SessionFile::TextValue
849   (const Standard_Integer num) const
850 {
851   Standard_Integer nm = num + thelastgen;
852   TCollection_AsciiString res;
853   if (nm <= 0 || nm > theline.Length()) return res;
854   res = theline.Value(nm);
855   if (res.Value( res.Length() ) == '"') res.Remove(res.Length());
856   if (res.Value(1) == ':') res.Remove(1);
857   if (res.Value(1) == '"') res.Remove(1);
858   return res;
859 }
860
861     Handle(Standard_Transient)  IFSelect_SessionFile::ItemValue
862   (const Standard_Integer num) const
863 {
864   Handle(Message_Messenger) sout = Message::DefaultMessenger();
865
866   Handle(Standard_Transient) res;
867   Standard_Integer nm = num + thelastgen;
868   if (nm <= 0 || nm > theline.Length()) return res;
869   Standard_Integer id;
870   TCollection_AsciiString name = theline.Value(nm);
871   if (name.Value(1) == ':') name.Remove(1);
872   if (name.IsEqual("$")) return res;    // item non-defini justement
873   if (!thenames->GetItem(name.ToCString(),id)) {
874     sout << " -- Item Unknown in File : " << name
875       << " lineno " << thenl << " param." << nm << endl;
876     id = 0;
877   }
878   return thesess->Item(id);
879 }
880
881
882     void  IFSelect_SessionFile::Destroy ()
883 {   }  // agit si File non ferme, sinon ne fait rien