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// DCE 21.01.99 S3767 Display original messages only
15//	 if the level is greater than 2
16
17//#include <Transfer_TransferProcess.ixx>
18//  Class generique
19
20//  TheStart est suppose Handle(Standard_Transient) ou (Transfer_Finder)
21//  Il doit offrir : "==" , .IsNull() , ->DynamicType()
22
23#include <Standard_ErrorHandler.hxx>
24#include <Standard_Failure.hxx>
25
26#include <Message_Messenger.hxx>
27#include <Message_Msg.hxx>
28#include <Message.hxx>
29#include <Message_ProgressScope.hxx>
30
31#include <Transfer_VoidBinder.hxx>
32#include <Transfer_SimpleBinderOfTransient.hxx>
33#include <Transfer_MultipleBinder.hxx>
34#include <Transfer_StatusResult.hxx>
35#include <Transfer_TransferFailure.hxx>
36#include <Transfer_TransferDeadLoop.hxx>
37
38#include <TCollection_HAsciiString.hxx>
39#include <TColStd_MapIteratorOfMapOfInteger.hxx>
40#include <TColStd_Array1OfInteger.hxx>
41#include <TColStd_HArray1OfInteger.hxx>
42
43
44//#define TRANSLOG   // debug
45
46static Handle(Standard_Transient)  nultrans;   // pour retour const&(Null) ...
47static Handle(Transfer_Binder)     nulbinder;
48
49
50//=======================================================================
51//function : Transfer_TransferProcess
52//purpose  :
53//=======================================================================
54
55Transfer_TransferProcess::Transfer_TransferProcess (const Standard_Integer nb)
56      : themap (nb)
57{
58  theerrh  = Standard_True;
59  therootm = Standard_False;
60  thelevel = 0;     therootl  = 0;
61  themessenger = Message::DefaultMessenger();
62  thetrace = 0;
63//  theroots = new TColStd_HSequenceOfInteger ();
64  theindex = 0;
65}
66
67
68//=======================================================================
69//function : Transfer_TransferProcess
70//purpose  :
71//=======================================================================
72
73Transfer_TransferProcess::Transfer_TransferProcess(const Handle(Message_Messenger)& messenger,
74						   const Standard_Integer nb)
75     : themap (nb)
76{
77  theerrh  = Standard_True;
78  therootm = Standard_False;
79  thelevel = 0;     therootl  = 0;
80  SetMessenger (messenger);
81  thetrace = 1;
82//  theroots = new TColStd_HSequenceOfInteger ();
83  theindex = 0;
84}
85
86    void Transfer_TransferProcess::Clear ()
87{
88  thelevel = 0;     therootl  = 0;
89  theroots.Clear();
90  themap.Clear();
91  theindex = 0;  thelastobj.Nullify();  thelastbnd.Nullify();
92}
93
94    void Transfer_TransferProcess::Clean ()
95{
96  Standard_Integer i, nb = NbMapped();
97  Standard_Integer j,unb = 0;
98  for (i = 1; i <= nb; i ++) {
99    if (themap(i).IsNull()) unb ++;
100  }
101  if (unb == 0) return;
102
103//   Refaire la map -> decalages
104  TColStd_Array1OfInteger unbs (1,nb);  unbs.Init(0);
105  Transfer_TransferMap newmap (nb*2);
106  for (i = 1; i <= nb; i ++) {
107    TheStart ent = Mapped(i);
108    Handle(Transfer_Binder) bnd = MapItem(i);
109    if (bnd.IsNull()) continue;
110    j = newmap.Add (ent,bnd);
111    unbs.SetValue (i,j);
112  }
113  themap.Assign (newmap);
114
115  // Update   La liste des racines
116  TColStd_IndexedMapOfInteger aNewRoots;
117  for( i=1; i<= theroots.Extent(); i++ ) {
118    j = theroots.FindKey(i);
119    Standard_Integer k = unbs.Value(j);
120    if ( k ) aNewRoots.Add ( k );
121  }
122  theroots.Clear();
123  theroots = aNewRoots;
124
125//    Le reste : nettoyage
126  thelastobj.Nullify();
127  thelastbnd.Nullify();
128  theindex = 0;
129}
130
131
132//=======================================================================
133//function : Resize
134//purpose  :
135//=======================================================================
136
137void Transfer_TransferProcess::Resize (const Standard_Integer nb)
138{
139  if (nb > themap.NbBuckets()) themap.ReSize(nb);
140}
141
142
143//=======================================================================
144//function : SetActor
145//purpose  :
146//=======================================================================
147
148void  Transfer_TransferProcess::SetActor(const Handle(Transfer_Actor)& actor)
149{
150  if (theactor == actor)         return;
151  if (theactor.IsNull())         theactor = actor;
152  else if (actor.IsNull())       theactor = actor;  // declenche RAZ
153  else if (theactor->IsLast()) { actor->SetNext(theactor);  theactor = actor; }
154  else                           theactor->SetNext(actor);
155}
156
157
158//=======================================================================
159//function : Actor
160//purpose  :
161//=======================================================================
162
163Handle(Transfer_Actor)  Transfer_TransferProcess::Actor () const
164{
165  return theactor;
166}
167
168
169//  ########################################################################
170//  ....                             MAPPING                            ....
171
172//  ##    ##    ##       Actions Generales sur Binders       ##    ##    ##
173//  ##    ##    ##               Consultations               ##    ##    ##
174
175
176//        ##    ##    Find    ##    ##
177
178//=======================================================================
179//function : Find
180//purpose  :
181//=======================================================================
182
183Handle(Transfer_Binder) Transfer_TransferProcess::Find (const TheStart& start) const
184//							 const Standard_Integer categ) const
185{
186  if (thelastobj == start) {
187    //if (theindex > 0) return thelastbnd->Search(categ); //skl
188    if (theindex > 0) return thelastbnd; //skl
189  }
190  Standard_Integer index = themap.FindIndex (start);
191  if (index > 0) {
192    const Handle(Transfer_Binder)& binder = themap.FindFromIndex(index);
193    //if (binder.IsNull()) //skl
194    return binder;
195    //return binder->Search(categ); //skl
196  }
197  return nulbinder;
198}
199
200//        ##    ##    IsBound    ##    ##
201
202//=======================================================================
203//function : IsBound
204//purpose  :
205//=======================================================================
206
207Standard_Boolean  Transfer_TransferProcess::IsBound(const TheStart& start) const
208//						    const Standard_Integer categ) const
209{
210  Handle(Transfer_Binder) binder = Find(start); //,categ); skl
211  if (binder.IsNull()) return Standard_False;
212  return binder->HasResult();
213}
214
215//        ##    ##    IsAlreadyUsed    ##    ##
216
217//=======================================================================
218//function : IsAlreadyUsed
219//purpose  :
220//=======================================================================
221
222Standard_Boolean Transfer_TransferProcess::IsAlreadyUsed(const TheStart& start) const
223//							 const Standard_Integer categ) const
224{
225  Handle(Transfer_Binder) binder = Find(start); //,categ); skl
226  if (binder.IsNull()) {
227    StartTrace (binder,start,thelevel,4);
228    throw Transfer_TransferFailure("TransferProcess : IsAlreadyUsed, transfer not done cannot be used...");
229  }
230  return (binder->Status() == Transfer_StatusUsed);
231}
232
233
234//        ##    ##    FindAndMask (private)    ##    ##
235
236//=======================================================================
237//function : FindAndMask
238//purpose  :
239//=======================================================================
240
241Handle(Transfer_Binder) Transfer_TransferProcess::FindAndMask(const TheStart& start)
242//							      const Standard_Integer categ)
243{
244  if (thelastobj == start) {
245    if (theindex > 0) return thelastbnd; //skl ->Search(categ);
246  }
247  thelastobj = start;
248  theindex   = themap.FindIndex (start);
249  if (theindex > 0) thelastbnd = themap.FindFromIndex(theindex);
250  else thelastbnd.Nullify();
251  //if (thelastbnd.IsNull()) skl
252  return thelastbnd;
253  //return thelastbnd->Search(categ); //skl
254}
255
256
257//  ##    ##    ##               Modifications               ##    ##    ##
258
259
260//=======================================================================
261//function : Bind
262//purpose  :
263//=======================================================================
264
265void Transfer_TransferProcess::Bind (const TheStart& start,
266				     const Handle(Transfer_Binder)& binder)
267//				      const Standard_Integer categ)
268{
269  if (binder.IsNull()) return;
270  Handle(Transfer_Binder) former = FindAndMask(start);//,categ);skl
271  if (!former.IsNull()) {
272//  On admet VoidBinder : alors on reprend son Check
273    if (former->DynamicType() == STANDARD_TYPE(Transfer_VoidBinder)) {
274      binder->Merge(former);
275      //binder->SetCategory(categ); //skl
276      themap(theindex) = binder;                          // Substitution
277    }
278    else if (former->Status() == Transfer_StatusUsed) {
279      StartTrace (former,start,thelevel,4);
280      throw Transfer_TransferFailure("TransferProcess : Bind, already Bound");
281    }
282    else {
283      if (thetrace > 2) StartTrace (former,start,thelevel,5);
284      binder->CCheck()->GetMessages (former->Check());
285    }
286  }
287  //binder->SetCategory(categ); //skl
288  if (theindex == 0 || thelastbnd.IsNull()) {
289    if (theindex == 0) theindex = themap.Add(start,binder);  // Nouveau
290    else themap(theindex) = binder;                          // idem en fait
291    thelastbnd = binder;
292  }
293  else { //skl
294    //binder->AddResult(thelastbnd);
295    thelastbnd  = binder;
296    themap(theindex) = binder;
297  }
298/*skl else if (thelastbnd->Category() == categ) {   // Substitue cette categorie
299    binder->Next(Standard_False)->SetNext(thelastbnd->Next(Standard_True),Standard_True);
300    thelastbnd  = binder;
301    themap(theindex) = binder;
302  } else {
303    thelastbnd->AddNext (binder,categ,Standard_True);
304  } */
305}
306
307
308//=======================================================================
309//function : Rebind
310//purpose  :
311//=======================================================================
312
313void  Transfer_TransferProcess::Rebind (const TheStart& start,
314					const Handle(Transfer_Binder)& binder)
315//					const Standard_Integer categ)
316{
317  Bind(start,binder); //,categ);skl
318  // entre les deux, les differences allaient s amenuisant
319  //  au debut, on criait si pas encore Bound (idiot)
320  //  ne restait plus comme difference que le test StatusUsed sur Rebind,
321  //    tandis que Bind refusait des lors qu il y avait un resultat
322  //  -> a present, Bind s aligne sur Rebind
323}
324
325
326//=======================================================================
327//function : Unbind
328//purpose  :
329//=======================================================================
330
331Standard_Boolean Transfer_TransferProcess::Unbind(const TheStart& start)
332//						   const Standard_Integer categ)
333{
334  Handle(Transfer_Binder) former = FindAndMask(start);//,categ);skl
335  if (theindex == 0) return Standard_False;
336  if (former.IsNull()) return Standard_False;
337  if (former->DynamicType() == STANDARD_TYPE(Transfer_VoidBinder)) return Standard_True;
338  //const Interface_Check& ach = thelastbnd->Check();
339  //Handle(Transfer_Binder) newbinder = thelastbnd->RemoveNext(categ);skl
340  //if (newbinder != thelastbnd)skl
341    themap(theindex) = thelastbnd;// = newbinder;skl
342  if(theroots.Contains(theindex)) {
343    TColStd_IndexedMapOfInteger aNewRoots;
344    for(Standard_Integer i = 1; i <= theroots.Extent(); i++)
345      if(theindex!= theroots.FindKey(i))
346	aNewRoots.Add(theroots.FindKey(i));
347
348    theroots.Clear();
349    theroots = aNewRoots;
350  }
351
352  thelastobj.Nullify();
353  thelastbnd.Nullify();
354  theindex = 0;
355  return Standard_True;
356}
357
358
359//=======================================================================
360//function : FindElseBind
361//purpose  :
362//=======================================================================
363
364Handle(Transfer_Binder) Transfer_TransferProcess::FindElseBind(const TheStart& start)
365//							       const Standard_Integer categ)
366{
367  Handle(Transfer_Binder) binder = FindAndMask (start);//,categ);skl
368  if (!binder.IsNull()) return binder;
369  binder = new Transfer_VoidBinder;
370  Bind(start,binder);//,categ);skl
371  return binder;
372}
373
374
375//  ##    ##    ##              Messages associes              ##    ##    ##
376
377//=======================================================================
378//function : SetMessenger
379//purpose  :
380//=======================================================================
381
382void Transfer_TransferProcess::SetMessenger (const Handle(Message_Messenger)& messenger)
383{
384  if ( messenger.IsNull() )
385    themessenger = Message::DefaultMessenger();
386  else
387    themessenger = messenger;
388}
389
390//=======================================================================
391//function : Messenger
392//purpose  :
393//=======================================================================
394
395Handle(Message_Messenger) Transfer_TransferProcess::Messenger () const
396{
397  return themessenger;
398}
399
400//=======================================================================
401//function : SetTraceLevel
402//purpose  :
403//=======================================================================
404
405void Transfer_TransferProcess::SetTraceLevel (const Standard_Integer tracelev)
406{
407  thetrace = tracelev;
408}
409
410//=======================================================================
411//function : TraceLevel
412//purpose  :
413//=======================================================================
414
415Standard_Integer Transfer_TransferProcess::TraceLevel () const
416{
417  return thetrace;
418}
419
420//=======================================================================
421//function : SendFail
422//purpose  :
423//=======================================================================
424
425void  Transfer_TransferProcess::SendFail(const TheStart& start,
426					 const Message_Msg& amsg)
427{
428  AddFail(start,amsg);
429}
430
431
432//=======================================================================
433//function : SendWarning
434//purpose  :
435//=======================================================================
436
437void  Transfer_TransferProcess::SendWarning(const TheStart& start,
438					    const Message_Msg& amsg)
439{
440  AddWarning(start,amsg);
441}
442
443
444//=======================================================================
445//function : SendMsg
446//purpose  :
447//=======================================================================
448
449void  Transfer_TransferProcess::SendMsg(const TheStart& start,
450					const Message_Msg& amsg)
451{
452  Handle(Transfer_Binder) binder = FindAndMask(start);
453  if (binder.IsNull()) {
454    binder = new Transfer_VoidBinder;
455    Bind (start,binder);
456  }
457  // Alimente la trace : Regle causant (user messages)
458  if (thetrace > 0) {
459    StartTrace (binder,start,thelevel,6);
460    Message_Messenger::StreamBuffer aSender = themessenger->SendInfo();
461    aSender << amsg.Value();
462    if (amsg.IsEdited()&&thetrace>2)
463      aSender << " [from: " << amsg.Original() << "]";
464    aSender << std::endl;
465  }
466}
467
468
469//=======================================================================
470//function : AddFail
471//purpose  :
472//=======================================================================
473
474void Transfer_TransferProcess::AddFail(const TheStart& start,
475				       const Standard_CString mess,
476				       const Standard_CString orig)
477{
478  Handle(Transfer_Binder) binder = FindAndMask(start);
479  if (binder.IsNull()) {
480    binder = new Transfer_VoidBinder;
481    Bind (start,binder);
482  }
483  binder->AddFail (mess,orig);
484  if (thetrace > 0) {
485    StartTrace (binder,start,thelevel,1);
486    Message_Messenger::StreamBuffer aSender = themessenger->SendFail();
487    aSender << "    --> Fail : " << mess;
488    if (orig[0] != '\0'&&thetrace>2) aSender << " [from: " << orig << "]";
489    aSender << std::endl;
490  }
491}
492
493
494//=======================================================================
495//function : AddError
496//purpose  :
497//=======================================================================
498
499void Transfer_TransferProcess::AddError(const TheStart& start,
500					const Standard_CString mess,
501					const Standard_CString orig)
502{
503  AddFail (start,mess,orig);
504}
505
506
507//=======================================================================
508//function : AddFail
509//purpose  :
510//=======================================================================
511
512void Transfer_TransferProcess::AddFail(const TheStart& start,
513				       const Message_Msg& amsg)
514{
515  if (amsg.IsEdited()) AddFail (start,TCollection_AsciiString(amsg.Value()).ToCString(),
516				TCollection_AsciiString(amsg.Original()).ToCString());
517  else AddFail (start,TCollection_AsciiString(amsg.Value()).ToCString());
518}
519
520
521//=======================================================================
522//function : AddWarning
523//purpose  :
524//=======================================================================
525
526void Transfer_TransferProcess::AddWarning(const TheStart& start,
527					  const Standard_CString mess,
528					  const Standard_CString orig)
529{
530  Handle(Transfer_Binder) binder = FindAndMask(start);
531  if (binder.IsNull()) {
532    binder = new Transfer_VoidBinder;
533    Bind (start,binder);
534  }
535  binder->AddWarning(mess,orig);
536  if (thetrace > 1) {
537    StartTrace (binder,start,thelevel,2);
538    Message_Messenger::StreamBuffer aSender = themessenger->SendWarning();
539    aSender << "    --> Warning : " << mess;
540    if (orig[0] != '\0'&&thetrace>2) aSender << " [from: " << orig << "]";
541    aSender << std::endl;
542  }
543}
544
545
546//=======================================================================
547//function : AddWarning
548//purpose  :
549//=======================================================================
550
551void Transfer_TransferProcess::AddWarning(const TheStart& start,
552					  const Message_Msg& amsg)
553{
554  if (amsg.IsEdited()) AddWarning (start,TCollection_AsciiString(amsg.Value()).ToCString(),
555				   TCollection_AsciiString(amsg.Original()).ToCString());
556  else AddWarning (start,TCollection_AsciiString(amsg.Value()).ToCString());
557}
558
559
560//=======================================================================
561//function : Mend
562//purpose  :
563//=======================================================================
564
565void  Transfer_TransferProcess::Mend(const TheStart& start,
566				     const Standard_CString pref)
567{
568  Handle(Transfer_Binder) binder = FindAndMask(start);
569  if (binder.IsNull()) return;  // rien a faire ...
570  Handle(Interface_Check) ach =  binder->CCheck();
571  ach->Mend (pref);
572}
573
574
575//=======================================================================
576//function : Check
577//purpose  :
578//=======================================================================
579
580Handle(Interface_Check) Transfer_TransferProcess::Check(const TheStart& start) const
581{
582  const Handle(Transfer_Binder)& binder = Find(start);
583  if (binder.IsNull()) {
584    Handle(Interface_Check) check;
585    return check;
586  }
587  return binder->Check();
588}
589
590/*skl
591void Transfer_TransferProcess::AddCaseName(const TheStart& start,
592					   const Standard_CString casename)
593{
594  AddCaseValue (start, new TCollection_HAsciiString (casename));
595}
596
597
598void Transfer_TransferProcess::AddCaseValue(const TheStart& start,
599					    const Handle(Standard_Transient)& caseval)
600{
601  Handle(Transfer_Binder) binder = FindAndMask(start);
602  if (binder.IsNull()) {
603    binder = new Transfer_VoidBinder;
604    Bind (start,binder);
605  }
606  binder->AddCaseValue (caseval);
607}
608
609
610Handle(TColStd_HSequenceOfTransient) Transfer_TransferProcess::CaseList
611       (const TheStart& start) const
612{
613  Handle(TColStd_HSequenceOfTransient) list;
614  const Handle(Transfer_Binder)& binder = Find(start);
615  if (binder.IsNull()) return list;
616  return binder->CaseList();
617}
618
619Standard_Integer Transfer_TransferProcess::NextItemWithAttribute
620  (const Standard_CString name, const Standard_Integer num0) const
621{
622  Standard_Integer num, nb = NbMapped();
623  for (num = num0+1; num <= nb; num ++) {
624    Handle(Transfer_Binder) bnd = MapItem (num);
625    if (bnd.IsNull()) continue;
626    if (!bnd->Attribute(name).IsNull()) return num;
627  }
628  return 0;
629}
630
631
632Interface_ParamType Transfer_TransferProcess::AttributeType
633  (const Standard_CString name) const
634{
635  Interface_ParamType aty, res = Interface_ParamVoid;
636  Standard_Integer num, nb = NbMapped();
637  for (num = 1; num <= nb; num ++) {
638    Handle(Transfer_Binder) bnd = MapItem (num);
639    if (bnd.IsNull()) continue;
640    aty = bnd->AttributeType(name);
641    if (aty == Interface_ParamVoid) continue;
642    if (res == Interface_ParamVoid) res = aty;
643    else if (res != aty) return Interface_ParamMisc;
644  }
645  return res;
646}
647
648Handle(Dico_DictionaryOfInteger) Transfer_TransferProcess::Attributes
649  (const Standard_CString rootname) const
650{
651  Handle(Dico_DictionaryOfInteger) list = new Dico_DictionaryOfInteger;
652  Standard_Integer num, nb = NbMapped();
653  for (num = 1; num <= nb; num ++) {
654    Handle(Transfer_Binder) bnd = MapItem (num);
655    if (bnd.IsNull()) continue;
656    Handle(Dico_DictionaryOfTransient) atr = bnd->AttrList();
657    if (atr.IsNull()) continue;
658    Dico_IteratorOfDictionaryOfTransient iatr(atr,rootname);
659    for (; iatr.More(); iatr.Next()) {
660      TCollection_AsciiString name = iatr.Name();
661      Standard_Boolean deja;
662      Standard_Integer& nbval = list->NewItem (name.ToCString(),deja);
663      if (!deja) nbval = 0;
664      nbval ++;
665    }
666
667  }
668  return list;
669}
670skl*/
671
672
673//  ##    ##    ##        Actions sur Types Privilegies        ##    ##    ##
674//  ##    ##    ##          (Transient)                        ##    ##    ##
675
676// Bind associe un objet a un objet resultat; or la Map associe un Objet a un
677// Binder (qui designe son resultat)
678//  *Transient  travaillent avec un SimpleBinderOfTransient
679// si  deja la, on considere son resultat
680// sinon, on cree un Binder du bon type
681
682
683//=======================================================================
684//function : BindTransient
685//purpose  :
686//=======================================================================
687
688void Transfer_TransferProcess::BindTransient(const TheStart& start,
689					     const Handle(Standard_Transient)& res)
690//					     const Standard_Integer categ)
691{
692  if (res.IsNull()) return;
693  Handle(Transfer_Binder) former = Find(start);//,categ);skl
694  Handle(Transfer_SimpleBinderOfTransient) binder =
695    Handle(Transfer_SimpleBinderOfTransient)::DownCast(former);
696//      Binding sur place ?
697  if (!binder.IsNull()) {
698    if (binder->Status() == Transfer_StatusVoid) { binder->SetResult(res); return; }
699  }
700//      Sinon, refaire
701  binder = new Transfer_SimpleBinderOfTransient;
702  binder->SetResult (res);
703  if (former.IsNull()) Bind(start,binder);//,categ);skl
704  else Rebind(start,binder);//,categ);skl
705}
706
707
708//=======================================================================
709//function : FindTransient
710//purpose  :
711//=======================================================================
712
713const Handle(Standard_Transient)& Transfer_TransferProcess::FindTransient
714       (const TheStart& start) const
715{
716  Handle(Transfer_SimpleBinderOfTransient) binder =
717    Handle(Transfer_SimpleBinderOfTransient)::DownCast(Find(start));
718  if (binder.IsNull()) return nultrans;
719  if (!binder->HasResult()) return nultrans;
720  return binder->Result();
721}
722
723
724//  Binding Multiple : D abord le declarer par BindMultiple (si pas deja fait)
725//  Puis ajouter les termes par AddMultiple
726
727//=======================================================================
728//function : BindMultiple
729//purpose  :
730//=======================================================================
731
732void Transfer_TransferProcess::BindMultiple(const TheStart& start)
733//					    const Standard_Integer categ)
734{
735  Handle(Transfer_Binder) binder = FindAndMask (start);//,categ);skl
736  if (!binder.IsNull()) {
737    if (!binder->IsKind(STANDARD_TYPE(Transfer_MultipleBinder))) {
738      StartTrace (thelastbnd,start,thelevel,4);
739      throw Transfer_TransferFailure("TransferProcess : BindMultiple");
740    }
741  }
742  else Bind(start,new Transfer_MultipleBinder);//,categ);skl
743}
744
745
746//=======================================================================
747//function : AddMultiple
748//purpose  :
749//=======================================================================
750
751void Transfer_TransferProcess::AddMultiple(const TheStart& start,
752					   const Handle(Standard_Transient)& res)
753//					   const Standard_Integer categ)
754{
755  Handle(Transfer_Binder) binder = FindAndMask(start);//,categ);skl
756  Handle(Transfer_MultipleBinder) multr =
757    Handle(Transfer_MultipleBinder)::DownCast(binder);
758  if (multr.IsNull()) {
759    StartTrace (binder,start,thelevel,4);
760    if (binder.IsNull()) throw Transfer_TransferFailure("TransferProcess : AddMultiple, nothing bound");
761    else                 throw Transfer_TransferFailure("TransferProcess : AddMultiple, Binder not a MultipleBinder");
762  }
763  multr->AddResult(res);
764}
765
766
767//=======================================================================
768//function : FindTypedTransient
769//purpose  :
770//=======================================================================
771
772Standard_Boolean Transfer_TransferProcess::FindTypedTransient
773  (const TheStart& start, const Handle(Standard_Type)& atype,
774   Handle(Standard_Transient)& val) const
775{
776  return GetTypedTransient (Find(start),atype,val);
777}
778
779
780//=======================================================================
781//function : GetTypedTransient
782//purpose  :
783//=======================================================================
784
785Standard_Boolean  Transfer_TransferProcess::GetTypedTransient
786  (const Handle(Transfer_Binder)& binder, const Handle(Standard_Type)& atype,
787   Handle(Standard_Transient)& val) const
788{
789  return Transfer_SimpleBinderOfTransient::GetTypedResult(binder,atype,val);
790}
791
792
793//  ##    ##    ##    ##    ##    Acces Atomique    ##    ##    ##    ##    ##
794//    (ne gere pas le scope mais donne acces aux categories)
795
796//=======================================================================
797//function : NbMapped
798//purpose  :
799//=======================================================================
800
801Standard_Integer  Transfer_TransferProcess::NbMapped () const
802{
803  return themap.Extent();
804}
805
806
807//=======================================================================
808//function : Mapped
809//purpose  :
810//=======================================================================
811
812const TheStart& Transfer_TransferProcess::Mapped(const Standard_Integer num) const
813{
814  return themap.FindKey(num);
815}
816
817
818//=======================================================================
819//function : MapIndex
820//purpose  :
821//=======================================================================
822
823Standard_Integer Transfer_TransferProcess::MapIndex(const TheStart& start) const
824{
825  return themap.FindIndex(start);
826}
827
828
829//=======================================================================
830//function : MapItem
831//purpose  :
832//=======================================================================
833
834Handle(Transfer_Binder) Transfer_TransferProcess::MapItem(const Standard_Integer num) const
835//							  const Standard_Integer categ) const
836{
837  Handle(Transfer_Binder) binder = themap.FindFromIndex(num);
838  //sklif (binder.IsNull())
839  return binder;
840  //sklreturn binder->Search (categ);
841}
842
843
844//  ########################################################################
845//  ....                         ROOT MANAGEMENT                        ....
846
847//=======================================================================
848//function : SetRoot
849//purpose  :
850//=======================================================================
851
852void Transfer_TransferProcess::SetRoot (const TheStart& start)
853{
854  Standard_Integer index = MapIndex(start);
855  if (index == 0) {
856    //StartTrace (thelastbnd,start,thelevel,4);
857    //throw Transfer_TransferFailure("TransferProcess : SetRoot");
858    return;
859  }
860
861  theroots.Add(index);
862  if (thetrace > 2) StartTrace (MapItem(index),start,thelevel,3);
863}
864
865
866//=======================================================================
867//function : SetRootManagement
868//purpose  :
869//=======================================================================
870
871void  Transfer_TransferProcess::SetRootManagement(const Standard_Boolean stat)
872{
873  therootm = stat;
874}
875
876
877//=======================================================================
878//function : NbRoots
879//purpose  :
880//=======================================================================
881
882Standard_Integer  Transfer_TransferProcess::NbRoots () const
883{
884  return theroots.Extent();
885}
886
887
888//=======================================================================
889//function : Root
890//purpose  :
891//=======================================================================
892
893const TheStart&  Transfer_TransferProcess::Root(const Standard_Integer num) const
894{
895  Standard_Integer ind = 0;
896  if (num > 0 && num <= theroots.Extent()) ind = theroots.FindKey(num);
897  return themap.FindKey (ind);
898}
899
900
901//=======================================================================
902//function : RootItem
903//purpose  :
904//=======================================================================
905
906Handle(Transfer_Binder) Transfer_TransferProcess::RootItem(const Standard_Integer num) const
907//							   const Standard_Integer categ) const
908{
909  Standard_Integer ind = 0;
910  if (num > 0 && num <= theroots.Extent()) ind = theroots.FindKey(num);
911  return themap.FindFromIndex(ind);//->Search(categ);skl
912}
913
914
915//=======================================================================
916//function : RootIndex
917//purpose  :
918//=======================================================================
919
920Standard_Integer  Transfer_TransferProcess::RootIndex(const TheStart& start) const
921{
922  Standard_Integer index = MapIndex(start);
923  if (index == 0) return 0;
924  return theroots.FindIndex(index);
925}
926
927
928//=======================================================================
929//function : NestingLevel
930//purpose  :
931//=======================================================================
932
933Standard_Integer  Transfer_TransferProcess::NestingLevel () const
934{
935  return thelevel;
936}
937
938
939//=======================================================================
940//function : ResetNestingLevel
941//purpose  :
942//=======================================================================
943
944void Transfer_TransferProcess::ResetNestingLevel ()
945{
946  thelevel = 0;
947}
948
949
950//  ########################################################################
951//  ....                        SCOPE MANAGEMENT                        ....
952
953
954//======================================================================
955//Purpose : gka TRJ9 for writing SDR for solid
956//          Check if binder has already been bound to the result binder.
957//======================================================================
958
959// static Standard_Boolean Contains(const Handle(Transfer_Binder)& resbinder,
960// 				 const Handle(Transfer_Binder)& addbinder)
961// {
962//   Handle(Transfer_Binder) tmpbind = resbinder;
963//   for ( ; ! tmpbind.IsNull(); tmpbind = tmpbind->NextResult() )
964//     if ( tmpbind == addbinder ) return Standard_True;
965//   return Standard_False;
966// }
967
968//  ########################################################################
969//  ....                    AUTOMATISMES DE TRANSFERT                   ....
970
971//  ##    ##    ##    ##    ##  Fonctions de Base  ##    ##    ##    ##    ##
972
973
974//=======================================================================
975//function : Recognize
976//purpose  :
977//=======================================================================
978
979Standard_Boolean  Transfer_TransferProcess::Recognize(const TheStart& start) const
980{
981  Handle(Transfer_Actor) actor = theactor;
982  //   On balaie les Next jusqu a avoir un Resultat
983  while (!actor.IsNull()) {
984    if (actor->Recognize (start)) return Standard_True;
985    actor = actor->Next();
986  }
987  return Standard_False;
988}
989
990
991//=======================================================================
992//function : Transferring
993//purpose  :
994//=======================================================================
995
996Handle(Transfer_Binder) Transfer_TransferProcess::Transferring(const TheStart& start,
997                                                               const Message_ProgressRange& theProgress)
998{
999  //   Map deja alimentee ?
1000  Handle(Transfer_Binder) former = FindAndMask(start);
1001
1002  //  ....    Transfert deja effectue avec Resultat ?    ....
1003
1004  //  On considere que cette nouvelle demande de Transfert correspond donc a une
1005  //  utilisation en plus : noter "AlreadyUsed", donc resultat non modifiable
1006  if (!former.IsNull()) {
1007    if (former->HasResult()) {
1008      former->SetAlreadyUsed();
1009      return former;
1010    }
1011  //}
1012
1013    //  ....    Etat Initial : peut-etre deja fait ... ou infaisable !
1014
1015    Message_Messenger::StreamBuffer aSender = themessenger->SendInfo();
1016  //if (!former.IsNull()) {
1017    Transfer_StatusExec statex = former->StatusExec();
1018    switch (statex) {
1019      case Transfer_StatusInitial :               // Transfert prepare a faire
1020	break;
1021      case Transfer_StatusDone :                  // Transfert deja fait
1022//#ifdef TRANSLOG
1023	aSender << " .. and Transfer done" << std::endl;
1024//#endif
1025//	if (former->HasResult()) former->SetAlreadyUsed();
1026	return former;
1027      case Transfer_StatusRun :                   // ca y est, on boucle
1028	former->SetStatusExec(Transfer_StatusLoop);
1029	return former;
1030      case Transfer_StatusError :                 // pas propre, ca ...
1031	if (thetrace) {
1032	  aSender << "                  *** Transfer in Error Status  :" << std::endl;
1033	  StartTrace (former, start, thelevel,0);
1034//	  (*themessenger->Out()) << flush;
1035	}
1036	else StartTrace (former, start,thelevel,4);
1037	throw Transfer_TransferFailure("TransferProcess : Transfer in Error Status");
1038      case Transfer_StatusLoop :                  // la boucle est bouclee ...
1039	if (thetrace) {
1040	  aSender << "                  *** Transfer  Head of Dead Loop  :" << std::endl;
1041	  StartTrace (former, start, thelevel,0);
1042//	  (*themessenger->Out()) << flush;
1043	}
1044	else StartTrace (former, start,thelevel,4);
1045	throw Transfer_TransferDeadLoop("TransferProcess : Transfer at Head of a Dead Loop");
1046    }
1047#ifdef TRANSLOG
1048    std::cout << "Transfer,level "<<thelevel<<Message_Flush;
1049#endif
1050  //}
1051
1052  //  ....    OK, on peut lancer l Execution
1053  //if (!former.IsNull())
1054    former->SetStatusExec(Transfer_StatusRun);
1055  }
1056#ifdef TRANSLOG
1057  std::cout << " GO .." << std::endl;
1058#endif
1059
1060  Handle(Transfer_Binder) binder;
1061  Standard_Boolean newbind = Standard_False;
1062  if (theerrh) {
1063    Message_Messenger::StreamBuffer aSender = themessenger->SendInfo();
1064
1065    //   Transfert sous protection pour les exceptions (pour notification en fait)
1066    Standard_Integer oldlev = thelevel;
1067    try {
1068      OCC_CATCH_SIGNALS
1069      binder = TransferProduct(start, theProgress);
1070    }
1071
1072    //    ...  Exceptions a Rattraper : elles ne se ressemblent pas toutes ... !
1073    catch (Transfer_TransferDeadLoop const&) {
1074      if (binder.IsNull()) {
1075	aSender << "                  *** Dead Loop with no Result" << std::endl;
1076	if (thetrace) StartTrace (binder, start, thelevel-1,0);
1077	binder = new Transfer_VoidBinder;
1078	Bind (start,binder);  newbind = Standard_True;
1079      } else if (binder->StatusExec() == Transfer_StatusLoop) {
1080	if (thetrace) {
1081	  aSender << "                  *** Dead Loop : Finding head of Loop :" << std::endl;
1082	  StartTrace (binder, start, thelevel-1,0);
1083	}
1084	else StartTrace (binder, start,thelevel-1,4);
1085	throw Transfer_TransferFailure("TransferProcess : Head of Dead Loop");
1086// Autrement dit, on change d exception (on est sorti de la boucle)
1087      } else {
1088	if (thetrace) {
1089	  aSender << "                  *** Dead Loop : Actor in Loop :" << std::endl;
1090	  StartTrace (binder, start, thelevel-1,0);
1091	}
1092      }
1093      binder->AddFail("Transfer in dead Loop");
1094      thelevel = oldlev;
1095    }
1096    catch (Standard_Failure const& anException) {
1097      if (binder.IsNull()) {
1098	aSender << "                  *** Exception Raised with no Result" << std::endl;
1099	binder = new Transfer_VoidBinder;
1100	Bind (start,binder);  newbind = Standard_True;
1101      }
1102      binder->AddFail("Transfer stopped by exception raising");
1103      if (thetrace) {
1104	aSender << "    *** Raised : " << anException.GetMessageString() << std::endl;
1105	StartTrace (binder, start, thelevel-1,4);
1106      }
1107      thelevel = oldlev;
1108    }
1109  }
1110
1111//   Transfert non protege (ainsi, dbx a la main en cas de plantage par Raise)
1112  else  binder = TransferProduct(start, theProgress);
1113
1114  if (theProgress.UserBreak())
1115    return Handle(Transfer_Binder)();
1116
1117//  ....                Conclusion : Noter dans la Map                ....
1118
1119  if (!newbind && !binder.IsNull()) {
1120    if (former.IsNull()) {
1121//    Peut-etre <theactor> a fait lui meme Bind ... verifier sinon le faire
1122      if (!IsBound(start)) Bind(start,binder);     // resultat = categorie 0
1123      else {                                       // gka TRJ9 for writing SDR for solid
1124// 	Handle(Transfer_Binder) tmpbind = Find(start);
1125// 	if(!Contains(binder,tmpbind))
1126// 	   binder->AddResult(tmpbind);
1127 	Rebind(start,binder); // test_pattern.sat
1128      }
1129    }
1130    else Rebind(start,binder);
1131//  (du coup, <thelastbnd> vaut <binder>)
1132#ifdef TRANSLOG
1133    std::cout << " ... OK" << std::endl;
1134#endif
1135  }
1136  else {
1137    //= by ABV: 5 Oct 97: nothing generated, but former can be in run state - drop it
1138    //= ASK: may be set it to StatusInitial ?
1139    if ( ! former.IsNull() ) former->SetStatusExec ( Transfer_StatusDone ); //+
1140    return nulbinder;    // Binder Null ... que faire d autre ?
1141  }
1142
1143//  ....                Gerer les Racines (si prevu)                ....
1144
1145  if (therootl >= thelevel) {
1146    therootl = 0;
1147    if (therootm && binder->Status() != Transfer_StatusVoid) {
1148      SetRoot (start);
1149    }
1150  }
1151  return thelastbnd;
1152}
1153
1154//  ##    ##        TransferProduct : Action proprement dite        ##    ##
1155
1156    Handle(Transfer_Binder) Transfer_TransferProcess::TransferProduct
1157  (const TheStart& start,
1158   const Message_ProgressRange& theProgress)
1159{
1160  thelevel ++;             // si decremente et == 0, transfert racine
1161  Handle(Transfer_Binder) binder;
1162  Handle(Transfer_Actor) actor = theactor;
1163
1164//   On balaie les Next jusqu a avoir un Resultat
1165  Message_ProgressScope aScope (theProgress, NULL, 1, true);
1166  while (!actor.IsNull()) {
1167    if (actor->Recognize (start)) binder = actor->Transferring(start,this, aScope.Next());
1168    else binder.Nullify();
1169    if (!binder.IsNull()) break;
1170    actor = actor->Next();
1171  }
1172  if (aScope.UserBreak())
1173    return Handle(Transfer_Binder)();
1174
1175  if (binder.IsNull()) {
1176//    if (thetrace) {
1177//      aSender << "Transfer has produced no Result" <<endl;
1178//      StartTrace (binder, start, thelevel-1,0); sout << flush;
1179//    }
1180    if (thelevel > 0) thelevel --;
1181    return binder;
1182  }
1183//      Gestion du niveau racine (.. a regarder de pres ..)
1184  if (therootl == 0 && binder->StatusExec() == Transfer_StatusDone)
1185    therootl = thelevel - 1;
1186
1187  if (thelevel > 0) thelevel --;
1188  return binder;
1189}
1190
1191
1192//=======================================================================
1193//function : Transfer
1194//purpose  :
1195//=======================================================================
1196
1197Standard_Boolean  Transfer_TransferProcess::Transfer(const TheStart& start,
1198                                                     const Message_ProgressRange& theProgress)
1199{
1200  Handle(Transfer_Binder) binder = Transferring(start, theProgress);
1201  return (!binder.IsNull());
1202}
1203
1204
1205//  #########################################################################
1206//  ....                      Error Handling + Trace                     ....
1207
1208//  trace : 1 pour Fail et Exception , 2 pour Root et Warning
1209
1210
1211//=======================================================================
1212//function : SetErrorHandle
1213//purpose  :
1214//=======================================================================
1215
1216void Transfer_TransferProcess::SetErrorHandle(const Standard_Boolean err)
1217{
1218  theerrh = err;
1219}    // traite par Transferring
1220
1221
1222//=======================================================================
1223//function : ErrorHandle
1224//purpose  :
1225//=======================================================================
1226
1227Standard_Boolean  Transfer_TransferProcess::ErrorHandle() const
1228{
1229  return theerrh;
1230}
1231
1232//=======================================================================
1233//function : StartTrace
1234//purpose  :
1235//=======================================================================
1236
1237void Transfer_TransferProcess::StartTrace(const Handle(Transfer_Binder)& binder,
1238					  const TheStart& start,
1239					  const Standard_Integer level,
1240					  const Standard_Integer mode) const
1241{
1242  Message_Messenger::StreamBuffer aSender = themessenger->SendInfo();
1243  // ###  Fail (Roots:50)  --  Start start->DynamicType()
1244  // ###  Fail (Roots:50)  --  Start id:#label.. Type:start->DynamicType()
1245  if (thetrace > 3) {  // Internal to be switch when searching bug (trace >= 4)
1246    if (mode == 1) aSender << "  ###  Fail";
1247    if (mode == 2) aSender << "  ###  Warning";
1248    if (mode == 3) aSender << "  ###  New Root n0 " << theroots.Extent();
1249    if (mode == 4) aSender << "  ###  Exception";
1250    if (mode == 5) aSender << "  ###  Substitution";
1251    if (mode == 6) aSender << "  ###  Information";
1252    if (level > 1)
1253      aSender << " (nested)";  // " at nesting Level:"<<level;
1254    if (mode >= 0 && mode != 3)
1255      aSender << " at " << theroots.Extent() << " Roots";
1256  }
1257  if (!start.IsNull()) PrintTrace (start,aSender);
1258////  sout << endl;
1259
1260  if (!binder.IsNull()) {   // old: if IsNull sout <<endl<< "  ---  Not Bound";
1261    Handle(Transfer_Binder) bnd = binder;
1262    Standard_Boolean hasres = Standard_False;
1263    while (!bnd.IsNull()) {
1264      if (bnd->Status() != Transfer_StatusVoid) {
1265// ---  Result Type: binder->ResultType()  ---  Binder : binder->DynamicType();
1266	if (!hasres)
1267	  aSender << "\n  ---  Result Type : ";
1268	else
1269	  aSender << " , ";
1270	aSender << bnd->ResultTypeName();
1271//  CKY 9-JAN-1999:  waiting for XSTEP Kernel message (not IGES_2075)
1272/*        Message_Msg Msg2075("IGES_2075");
1273          Msg2075.AddString(bnd->ResultTypeName());
1274          Msg2075.TraceEver();  */
1275	hasres = Standard_True;
1276      }
1277      bnd = bnd->NextResult();
1278    }
1279    if (!hasres && mode > 2) {
1280      aSender << "\n  ---  No Result recorded";
1281//  CKY 9-JAN-1999 : waiting for XSTEP Kernel message
1282//     (not IGES_2075, no reference to specifically TopoDS_Shape)
1283/*       Message_Msg Msg2075("IGES_2075");
1284         Msg2075.AddString("No TopoDS_Shape");
1285         Msg2075.TraceEver();  */
1286    }
1287//old    if (isused) sout << "  --    (Already Used in another Transfer)";
1288  }
1289  aSender << std::endl;
1290}
1291
1292
1293//=======================================================================
1294//function : PrintTrace
1295//purpose  :
1296//=======================================================================
1297
1298void  Transfer_TransferProcess::PrintTrace(const TheStart& start, Standard_OStream& S) const
1299{
1300  if (!start.IsNull())   S <<" Type:" << start->DynamicType()->Name();
1301}
1302
1303
1304//=======================================================================
1305//function : IsLooping
1306//purpose  :
1307//=======================================================================
1308
1309Standard_Boolean  Transfer_TransferProcess::IsLooping
1310  (const Standard_Integer alevel) const
1311      {  return alevel > NbMapped();  }
1312
1313
1314
1315//  #########################################################################
1316//  ....                            RESULTATS                            ....
1317
1318
1319//  ##    ##        RootResult : Les Racines        ##    ##
1320
1321
1322//=======================================================================
1323//function : RootResult
1324//purpose  :
1325//=======================================================================
1326
1327Transfer_Iterator Transfer_TransferProcess::RootResult(const Standard_Boolean withstart) const
1328{
1329  Transfer_Iterator iter(withstart);
1330  Standard_Integer max = theroots.Extent();
1331  for (Standard_Integer j = 1; j <= max; j ++) {
1332    Standard_Integer i = theroots.FindKey(j);
1333    Handle(Transfer_Binder) binder = MapItem(i);
1334    if (binder.IsNull()) continue;
1335    if (withstart) iter.Add (binder,Mapped(i));
1336    else iter.Add (binder);
1337  }
1338  return iter;
1339}
1340
1341
1342//  ##    ##        CompleteResult : Tous les Resultats        ##    ##
1343
1344//=======================================================================
1345//function : CompleteResult
1346//purpose  :
1347//=======================================================================
1348
1349Transfer_Iterator Transfer_TransferProcess::CompleteResult
1350  (const Standard_Boolean withstart) const
1351{
1352  Transfer_Iterator iter(withstart);
1353  Standard_Integer max = NbMapped();
1354  for (Standard_Integer i = 1; i <= max; i ++) {
1355    Handle(Transfer_Binder) binder = MapItem(i);
1356    if (binder.IsNull()) continue;
1357    if (withstart) iter.Add (binder,Mapped(i));
1358    else iter.Add (binder);
1359  }
1360  return iter;
1361}
1362
1363
1364//  ##    ##        AbnormalResult : Transferts a probleme        ##    ##
1365//=======================================================================
1366//function : AbnormalResult
1367//purpose  :
1368//=======================================================================
1369
1370Transfer_Iterator Transfer_TransferProcess::AbnormalResult() const
1371{
1372  Transfer_Iterator iter(Standard_True);
1373  Standard_Integer max = NbMapped();
1374  for (Standard_Integer i = 1; i <= max; i ++) {
1375    Handle(Transfer_Binder) binder = MapItem(i);
1376    if (binder.IsNull()) continue;
1377    Transfer_StatusExec statex = binder->StatusExec();
1378    if (statex != Transfer_StatusInitial && statex != Transfer_StatusDone)
1379      iter.Add (binder,Mapped(i));  // on note les cas "pas normaux"
1380  }
1381  return iter;
1382}
1383
1384
1385//  ##    ##    ##         CheckList : les messages         ##    ##    ##
1386//=======================================================================
1387//function : CheckList
1388//purpose  :
1389//=======================================================================
1390
1391Interface_CheckIterator  Transfer_TransferProcess::CheckList
1392  (const Standard_Boolean erronly) const
1393{
1394  Interface_CheckIterator list;
1395  Standard_Integer num, max = NbMapped();
1396  for (Standard_Integer i = 1; i <= max; i ++) {
1397    Handle(Transfer_Binder) binder = MapItem(i);
1398    if (binder.IsNull()) continue;
1399    Transfer_StatusExec statex = binder->StatusExec();
1400    Handle(Interface_Check) check = binder->Check();
1401    if (statex != Transfer_StatusInitial && statex != Transfer_StatusDone &&
1402	!check->HasFailed())
1403      check->AddFail("Transfer in Abnormal Status (!= Initial or Done)");
1404    if (!check->HasFailed() && (erronly || check->NbWarnings() == 0)) continue;
1405    const TheStart& ent = Mapped(i);
1406    num = CheckNum(ent);
1407    if (num == 0) num = i;
1408    check->SetEntity(ent);
1409    list.Add(check,num);
1410  }
1411  return list;
1412}
1413
1414
1415//  #########################################################################
1416//  ....                       RESULTATS PAR ENTITE                      ....
1417
1418//=======================================================================
1419//function : ResultOne
1420//purpose  :
1421//=======================================================================
1422
1423Transfer_Iterator Transfer_TransferProcess::ResultOne(const TheStart& start,
1424						      const Standard_Integer level,
1425						      const Standard_Boolean withstart) const
1426{
1427  Transfer_Iterator iter(withstart);
1428  Standard_Integer max = NbMapped();
1429  Standard_Integer ind = MapIndex (start);
1430  if (ind == 0) return iter;
1431  Standard_Integer i1 = (level == 0 ? ind : 1);
1432  Standard_Integer i2 = (level == 0 ? ind : max);
1433  Handle(TColStd_HArray1OfInteger) map = new TColStd_HArray1OfInteger (i1,i2,0);
1434  //MarkScoped (ind,level,map);
1435
1436  for (Standard_Integer i = i1; i <= i2; i ++) {
1437    ind = map->Value(i);
1438    if (ind == 0) continue;
1439    Handle(Transfer_Binder) binder = MapItem(i);
1440    if (binder.IsNull()) continue;
1441    if (withstart) iter.Add (binder,Mapped(ind));
1442    else iter.Add (binder);
1443  }
1444  return iter;
1445}
1446
1447
1448//=======================================================================
1449//function : CheckListOne
1450//purpose  :
1451//=======================================================================
1452
1453Interface_CheckIterator  Transfer_TransferProcess::CheckListOne
1454  (const TheStart& start,const Standard_Integer level,
1455   const Standard_Boolean erronly) const
1456{
1457  Interface_CheckIterator list;
1458  Standard_Integer max = NbMapped();
1459  Standard_Integer num, ind = MapIndex (start);
1460  if (ind == 0) return list;
1461  Standard_Integer i1 = (level == 0 ? ind : 1);
1462  Standard_Integer i2 = (level == 0 ? ind : max);
1463  Handle(TColStd_HArray1OfInteger) map = new TColStd_HArray1OfInteger (i1,i2,0);
1464  //MarkScoped (ind,level,map);
1465
1466  for (Standard_Integer i = i1; i <= i2; i ++) {
1467    ind = map->Value(i);
1468    if (ind == 0) continue;
1469    Handle(Transfer_Binder) binder = MapItem(ind);
1470    if (binder.IsNull()) continue;
1471    Transfer_StatusExec statex = binder->StatusExec();
1472    Handle(Interface_Check) check = binder->Check();
1473    if (statex != Transfer_StatusInitial && statex != Transfer_StatusDone &&
1474	!check->HasFailed())
1475      check->AddFail("Transfer in Abnormal Status (!= Initial or Done)");
1476    if (!check->HasFailed() && (erronly || check->NbWarnings() == 0)) continue;
1477    const TheStart& ent = Mapped(ind);
1478    num = CheckNum(ent);  if (num == 0) num = ind;
1479    check->SetEntity(ent);
1480    list.Add(check,num);
1481  }
1482  return list;
1483}
1484
1485
1486//=======================================================================
1487//function : IsCheckListEmpty
1488//purpose  :
1489//=======================================================================
1490
1491Standard_Boolean  Transfer_TransferProcess::IsCheckListEmpty
1492  (const TheStart& start, const Standard_Integer level,
1493   const Standard_Boolean erronly) const
1494{
1495  Standard_Integer max = NbMapped();
1496  Standard_Integer ind = MapIndex (start);
1497  if (ind == 0) return Standard_False;
1498  Standard_Integer i1 = (level == 0 ? ind : 1);
1499  Standard_Integer i2 = (level == 0 ? ind : max);
1500  Handle(TColStd_HArray1OfInteger) map = new TColStd_HArray1OfInteger (i1,i2,0);
1501//  MarkScoped (ind,level,map);
1502
1503  for (Standard_Integer i = i1; i <= i2; i ++) {
1504    ind = map->Value(i);
1505    if (ind == 0) continue;
1506    Handle(Transfer_Binder) binder = MapItem(ind);
1507    if (binder.IsNull()) continue;
1508
1509    Transfer_StatusExec statex = binder->StatusExec();
1510    Handle(Interface_Check) check = binder->Check();
1511    if (statex != Transfer_StatusInitial && statex != Transfer_StatusDone)
1512      return Standard_False;
1513    if (check->HasFailed() || (!erronly && check->NbWarnings() > 0)) return Standard_False;
1514  }
1515  return Standard_True;
1516}
1517
1518
1519//=======================================================================
1520//function : RemoveResult
1521//purpose  :
1522//=======================================================================
1523
1524void  Transfer_TransferProcess::RemoveResult(const TheStart& start,
1525					     const Standard_Integer level,
1526					     const Standard_Boolean /*compute*/)
1527{
1528  //if (compute) ComputeScopes();
1529  Standard_Integer max = NbMapped();
1530  Standard_Integer ind = MapIndex (start);
1531  if (ind == 0) return;
1532  Standard_Integer i1 = (level == 0 ? ind : 1);
1533  Standard_Integer i2 = (level == 0 ? ind : max);
1534  Handle(TColStd_HArray1OfInteger) map = new TColStd_HArray1OfInteger (i1,i2,0);
1535//  MarkScoped (ind,level,map);
1536
1537  Standard_Integer i; // svv Jan11 2000 : porting on DEC
1538  for (i = i1; i <= i2; i ++) {
1539    ind = map->Value(i);
1540    if (ind == 0) continue;
1541    Handle(Transfer_Binder) binder = MapItem(ind);
1542    if (binder.IsNull()) continue;
1543//    Standard_Boolean cayest = binder->SetNbUserScopes (-1);
1544//    if (cayest) themap(ind) = nulbinder;    // RAZ !
1545  }
1546
1547//pdn commented  for (i = NbRoots(); i > 0; i --)
1548//    if (theroots.Value(i) == ind) theroots.Remove(i);
1549}
1550
1551
1552Standard_Integer  Transfer_TransferProcess::CheckNum(const TheStart& ) const
1553{
1554  return 0;
1555}
1556
1557