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