1 // Copyright (c) 1999-2014 OPEN CASCADE SAS
3 // This file is part of Open CASCADE Technology software library.
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.
11 // Alternatively, this file may be used under the terms of Open CASCADE
12 // commercial license or contractual agreement.
14 // DCE 21.01.99 S3767 Display original messages only
15 // if the level is greater than 2
17 //#include <Transfer_TransferProcess.ixx>
20 // TheStart est suppose Handle(Standard_Transient) ou (Transfer_Finder)
21 // Il doit offrir : "==" , .IsNull() , ->DynamicType()
23 #include <Standard_ErrorHandler.hxx>
24 #include <Standard_Failure.hxx>
26 #include <Message_Messenger.hxx>
27 #include <Message_Msg.hxx>
28 #include <Message.hxx>
30 #include <Transfer_VoidBinder.hxx>
31 #include <Transfer_SimpleBinderOfTransient.hxx>
32 #include <Transfer_MultipleBinder.hxx>
33 #include <Transfer_StatusResult.hxx>
34 #include <Transfer_TransferFailure.hxx>
35 #include <Transfer_TransferDeadLoop.hxx>
37 #include <TCollection_HAsciiString.hxx>
38 #include <TColStd_MapIteratorOfMapOfInteger.hxx>
39 #include <TColStd_Array1OfInteger.hxx>
40 #include <TColStd_HArray1OfInteger.hxx>
43 //#define TRANSLOG // debug
45 static Handle(Standard_Transient) nultrans; // pour retour const&(Null) ...
46 static Handle(Transfer_Binder) nulbinder;
49 //=======================================================================
50 //function : Transfer_TransferProcess
52 //=======================================================================
54 Transfer_TransferProcess::Transfer_TransferProcess (const Standard_Integer nb)
57 theerrh = Standard_True;
58 therootm = Standard_False;
59 thelevel = 0; therootl = 0;
60 themessenger = Message::DefaultMessenger();
62 // theroots = new TColStd_HSequenceOfInteger ();
67 //=======================================================================
68 //function : Transfer_TransferProcess
70 //=======================================================================
72 Transfer_TransferProcess::Transfer_TransferProcess(const Handle(Message_Messenger)& messenger,
73 const Standard_Integer nb)
76 theerrh = Standard_True;
77 therootm = Standard_False;
78 thelevel = 0; therootl = 0;
79 SetMessenger (messenger);
81 // theroots = new TColStd_HSequenceOfInteger ();
85 void Transfer_TransferProcess::Clear ()
87 thelevel = 0; therootl = 0;
90 theindex = 0; thelastobj.Nullify(); thelastbnd.Nullify();
93 void Transfer_TransferProcess::Clean ()
95 Standard_Integer i, nb = NbMapped();
96 Standard_Integer j,unb = 0;
97 for (i = 1; i <= nb; i ++) {
98 if (themap(i).IsNull()) unb ++;
100 if (unb == 0) return;
102 // Refaire la map -> decalages
103 TColStd_Array1OfInteger unbs (1,nb); unbs.Init(0);
104 Transfer_TransferMap newmap (nb*2);
105 for (i = 1; i <= nb; i ++) {
106 TheStart ent = Mapped(i);
107 Handle(Transfer_Binder) bnd = MapItem(i);
108 if (bnd.IsNull()) continue;
109 j = newmap.Add (ent,bnd);
112 themap.Assign (newmap);
114 // Update La liste des racines
115 TColStd_IndexedMapOfInteger aNewRoots;
116 for( i=1; i<= theroots.Extent(); i++ ) {
117 j = theroots.FindKey(i);
118 Standard_Integer k = unbs.Value(j);
119 if ( k ) aNewRoots.Add ( k );
122 theroots = aNewRoots;
124 // Le reste : nettoyage
125 thelastobj.Nullify();
126 thelastbnd.Nullify();
131 //=======================================================================
134 //=======================================================================
136 void Transfer_TransferProcess::Resize (const Standard_Integer nb)
138 if (nb > themap.NbBuckets()) themap.ReSize(nb);
142 //=======================================================================
143 //function : SetActor
145 //=======================================================================
147 void Transfer_TransferProcess::SetActor(const Handle(Transfer_Actor)& actor)
149 if (theactor == actor) return;
150 if (theactor.IsNull()) theactor = actor;
151 else if (actor.IsNull()) theactor = actor; // declenche RAZ
152 else if (theactor->IsLast()) { actor->SetNext(theactor); theactor = actor; }
153 else theactor->SetNext(actor);
157 //=======================================================================
160 //=======================================================================
162 Handle(Transfer_Actor) Transfer_TransferProcess::Actor () const
168 // ########################################################################
171 // ## ## ## Actions Generales sur Binders ## ## ##
172 // ## ## ## Consultations ## ## ##
177 //=======================================================================
180 //=======================================================================
182 Handle(Transfer_Binder) Transfer_TransferProcess::Find (const TheStart& start) const
183 // const Standard_Integer categ) const
185 if (thelastobj == start) {
186 //if (theindex > 0) return thelastbnd->Search(categ); //skl
187 if (theindex > 0) return thelastbnd; //skl
189 Standard_Integer index = themap.FindIndex (start);
191 const Handle(Transfer_Binder)& binder = themap.FindFromIndex(index);
192 //if (binder.IsNull()) //skl
194 //return binder->Search(categ); //skl
199 // ## ## IsBound ## ##
201 //=======================================================================
204 //=======================================================================
206 Standard_Boolean Transfer_TransferProcess::IsBound(const TheStart& start) const
207 // const Standard_Integer categ) const
209 Handle(Transfer_Binder) binder = Find(start); //,categ); skl
210 if (binder.IsNull()) return Standard_False;
211 return binder->HasResult();
214 // ## ## IsAlreadyUsed ## ##
216 //=======================================================================
217 //function : IsAlreadyUsed
219 //=======================================================================
221 Standard_Boolean Transfer_TransferProcess::IsAlreadyUsed(const TheStart& start) const
222 // const Standard_Integer categ) const
224 Handle(Transfer_Binder) binder = Find(start); //,categ); skl
225 if (binder.IsNull()) {
226 StartTrace (binder,start,thelevel,4);
227 throw Transfer_TransferFailure("TransferProcess : IsAlreadyUsed, transfer not done cannot be used...");
229 return (binder->Status() == Transfer_StatusUsed);
233 // ## ## FindAndMask (private) ## ##
235 //=======================================================================
236 //function : FindAndMask
238 //=======================================================================
240 Handle(Transfer_Binder) Transfer_TransferProcess::FindAndMask(const TheStart& start)
241 // const Standard_Integer categ)
243 if (thelastobj == start) {
244 if (theindex > 0) return thelastbnd; //skl ->Search(categ);
247 theindex = themap.FindIndex (start);
248 if (theindex > 0) thelastbnd = themap.FindFromIndex(theindex);
249 else thelastbnd.Nullify();
250 //if (thelastbnd.IsNull()) skl
252 //return thelastbnd->Search(categ); //skl
256 // ## ## ## Modifications ## ## ##
259 //=======================================================================
262 //=======================================================================
264 void Transfer_TransferProcess::Bind (const TheStart& start,
265 const Handle(Transfer_Binder)& binder)
266 // const Standard_Integer categ)
268 if (binder.IsNull()) return;
269 Handle(Transfer_Binder) former = FindAndMask(start);//,categ);skl
270 if (!former.IsNull()) {
271 // On admet VoidBinder : alors on reprend son Check
272 if (former->DynamicType() == STANDARD_TYPE(Transfer_VoidBinder)) {
273 binder->Merge(former);
274 //binder->SetCategory(categ); //skl
275 themap(theindex) = binder; // Substitution
277 else if (former->Status() == Transfer_StatusUsed) {
278 StartTrace (former,start,thelevel,4);
279 throw Transfer_TransferFailure("TransferProcess : Bind, already Bound");
282 if (thetrace > 2) StartTrace (former,start,thelevel,5);
283 binder->CCheck()->GetMessages (former->Check());
286 //binder->SetCategory(categ); //skl
287 if (theindex == 0 || thelastbnd.IsNull()) {
288 if (theindex == 0) theindex = themap.Add(start,binder); // Nouveau
289 else themap(theindex) = binder; // idem en fait
293 //binder->AddResult(thelastbnd);
295 themap(theindex) = binder;
297 /*skl else if (thelastbnd->Category() == categ) { // Substitue cette categorie
298 binder->Next(Standard_False)->SetNext(thelastbnd->Next(Standard_True),Standard_True);
300 themap(theindex) = binder;
302 thelastbnd->AddNext (binder,categ,Standard_True);
307 //=======================================================================
310 //=======================================================================
312 void Transfer_TransferProcess::Rebind (const TheStart& start,
313 const Handle(Transfer_Binder)& binder)
314 // const Standard_Integer categ)
316 Bind(start,binder); //,categ);skl
317 // entre les deux, les differences allaient s amenuisant
318 // au debut, on criait si pas encore Bound (idiot)
319 // ne restait plus comme difference que le test StatusUsed sur Rebind,
320 // tandis que Bind refusait des lors qu il y avait un resultat
321 // -> a present, Bind s aligne sur Rebind
325 //=======================================================================
328 //=======================================================================
330 Standard_Boolean Transfer_TransferProcess::Unbind(const TheStart& start)
331 // const Standard_Integer categ)
333 Handle(Transfer_Binder) former = FindAndMask(start);//,categ);skl
334 if (theindex == 0) return Standard_False;
335 if (former.IsNull()) return Standard_False;
336 if (former->DynamicType() == STANDARD_TYPE(Transfer_VoidBinder)) return Standard_True;
337 //const Interface_Check& ach = thelastbnd->Check();
338 //Handle(Transfer_Binder) newbinder = thelastbnd->RemoveNext(categ);skl
339 //if (newbinder != thelastbnd)skl
340 themap(theindex) = thelastbnd;// = newbinder;skl
341 if(theroots.Contains(theindex)) {
342 TColStd_IndexedMapOfInteger aNewRoots;
343 for(Standard_Integer i = 1; i <= theroots.Extent(); i++)
344 if(theindex!= theroots.FindKey(i))
345 aNewRoots.Add(theroots.FindKey(i));
348 theroots = aNewRoots;
351 thelastobj.Nullify();
352 thelastbnd.Nullify();
354 return Standard_True;
358 //=======================================================================
359 //function : FindElseBind
361 //=======================================================================
363 Handle(Transfer_Binder) Transfer_TransferProcess::FindElseBind(const TheStart& start)
364 // const Standard_Integer categ)
366 Handle(Transfer_Binder) binder = FindAndMask (start);//,categ);skl
367 if (!binder.IsNull()) return binder;
368 binder = new Transfer_VoidBinder;
369 Bind(start,binder);//,categ);skl
374 // ## ## ## Messages associes ## ## ##
376 //=======================================================================
377 //function : SetMessenger
379 //=======================================================================
381 void Transfer_TransferProcess::SetMessenger (const Handle(Message_Messenger)& messenger)
383 if ( messenger.IsNull() )
384 themessenger = Message::DefaultMessenger();
386 themessenger = messenger;
389 //=======================================================================
390 //function : Messenger
392 //=======================================================================
394 Handle(Message_Messenger) Transfer_TransferProcess::Messenger () const
399 //=======================================================================
400 //function : SetTraceLevel
402 //=======================================================================
404 void Transfer_TransferProcess::SetTraceLevel (const Standard_Integer tracelev)
409 //=======================================================================
410 //function : TraceLevel
412 //=======================================================================
414 Standard_Integer Transfer_TransferProcess::TraceLevel () const
419 //=======================================================================
420 //function : SendFail
422 //=======================================================================
424 void Transfer_TransferProcess::SendFail(const TheStart& start,
425 const Message_Msg& amsg)
431 //=======================================================================
432 //function : SendWarning
434 //=======================================================================
436 void Transfer_TransferProcess::SendWarning(const TheStart& start,
437 const Message_Msg& amsg)
439 AddWarning(start,amsg);
443 //=======================================================================
446 //=======================================================================
448 void Transfer_TransferProcess::SendMsg(const TheStart& start,
449 const Message_Msg& amsg)
451 Handle(Transfer_Binder) binder = FindAndMask(start);
452 if (binder.IsNull()) {
453 binder = new Transfer_VoidBinder;
456 // Alimente la trace : Regle causant (user messages)
458 StartTrace (binder,start,thelevel,6);
459 themessenger << amsg.Value();
460 if (amsg.IsEdited()&&thetrace>2)
461 themessenger << " [from: " << amsg.Original() << "]";
462 themessenger << Message_EndLine;
467 //=======================================================================
470 //=======================================================================
472 void Transfer_TransferProcess::AddFail(const TheStart& start,
473 const Standard_CString mess,
474 const Standard_CString orig)
476 Handle(Transfer_Binder) binder = FindAndMask(start);
477 if (binder.IsNull()) {
478 binder = new Transfer_VoidBinder;
481 binder->AddFail (mess,orig);
483 StartTrace (binder,start,thelevel,1);
484 themessenger << " --> Fail : " << mess;
485 if (orig[0] != '\0'&&thetrace>2) themessenger << " [from: " << orig << "]";
486 themessenger << Message_EndLine;
491 //=======================================================================
492 //function : AddError
494 //=======================================================================
496 void Transfer_TransferProcess::AddError(const TheStart& start,
497 const Standard_CString mess,
498 const Standard_CString orig)
500 AddFail (start,mess,orig);
504 //=======================================================================
507 //=======================================================================
509 void Transfer_TransferProcess::AddFail(const TheStart& start,
510 const Message_Msg& amsg)
512 if (amsg.IsEdited()) AddFail (start,TCollection_AsciiString(amsg.Value()).ToCString(),
513 TCollection_AsciiString(amsg.Original()).ToCString());
514 else AddFail (start,TCollection_AsciiString(amsg.Value()).ToCString());
518 //=======================================================================
519 //function : AddWarning
521 //=======================================================================
523 void Transfer_TransferProcess::AddWarning(const TheStart& start,
524 const Standard_CString mess,
525 const Standard_CString orig)
527 Handle(Transfer_Binder) binder = FindAndMask(start);
528 if (binder.IsNull()) {
529 binder = new Transfer_VoidBinder;
532 binder->AddWarning(mess,orig);
534 StartTrace (binder,start,thelevel,2);
535 themessenger << " --> Warning : " << mess;
536 if (orig[0] != '\0'&&thetrace>2) themessenger << " [from: " << orig << "]";
537 themessenger << Message_EndLine;
542 //=======================================================================
543 //function : AddWarning
545 //=======================================================================
547 void Transfer_TransferProcess::AddWarning(const TheStart& start,
548 const Message_Msg& amsg)
550 if (amsg.IsEdited()) AddWarning (start,TCollection_AsciiString(amsg.Value()).ToCString(),
551 TCollection_AsciiString(amsg.Original()).ToCString());
552 else AddWarning (start,TCollection_AsciiString(amsg.Value()).ToCString());
556 //=======================================================================
559 //=======================================================================
561 void Transfer_TransferProcess::Mend(const TheStart& start,
562 const Standard_CString pref)
564 Handle(Transfer_Binder) binder = FindAndMask(start);
565 if (binder.IsNull()) return; // rien a faire ...
566 Handle(Interface_Check) ach = binder->CCheck();
571 //=======================================================================
574 //=======================================================================
576 Handle(Interface_Check) Transfer_TransferProcess::Check(const TheStart& start) const
578 const Handle(Transfer_Binder)& binder = Find(start);
579 if (binder.IsNull()) {
580 Handle(Interface_Check) check;
583 return binder->Check();
587 void Transfer_TransferProcess::AddCaseName(const TheStart& start,
588 const Standard_CString casename)
590 AddCaseValue (start, new TCollection_HAsciiString (casename));
594 void Transfer_TransferProcess::AddCaseValue(const TheStart& start,
595 const Handle(Standard_Transient)& caseval)
597 Handle(Transfer_Binder) binder = FindAndMask(start);
598 if (binder.IsNull()) {
599 binder = new Transfer_VoidBinder;
602 binder->AddCaseValue (caseval);
606 Handle(TColStd_HSequenceOfTransient) Transfer_TransferProcess::CaseList
607 (const TheStart& start) const
609 Handle(TColStd_HSequenceOfTransient) list;
610 const Handle(Transfer_Binder)& binder = Find(start);
611 if (binder.IsNull()) return list;
612 return binder->CaseList();
615 Standard_Integer Transfer_TransferProcess::NextItemWithAttribute
616 (const Standard_CString name, const Standard_Integer num0) const
618 Standard_Integer num, nb = NbMapped();
619 for (num = num0+1; num <= nb; num ++) {
620 Handle(Transfer_Binder) bnd = MapItem (num);
621 if (bnd.IsNull()) continue;
622 if (!bnd->Attribute(name).IsNull()) return num;
628 Interface_ParamType Transfer_TransferProcess::AttributeType
629 (const Standard_CString name) const
631 Interface_ParamType aty, res = Interface_ParamVoid;
632 Standard_Integer num, nb = NbMapped();
633 for (num = 1; num <= nb; num ++) {
634 Handle(Transfer_Binder) bnd = MapItem (num);
635 if (bnd.IsNull()) continue;
636 aty = bnd->AttributeType(name);
637 if (aty == Interface_ParamVoid) continue;
638 if (res == Interface_ParamVoid) res = aty;
639 else if (res != aty) return Interface_ParamMisc;
644 Handle(Dico_DictionaryOfInteger) Transfer_TransferProcess::Attributes
645 (const Standard_CString rootname) const
647 Handle(Dico_DictionaryOfInteger) list = new Dico_DictionaryOfInteger;
648 Standard_Integer num, nb = NbMapped();
649 for (num = 1; num <= nb; num ++) {
650 Handle(Transfer_Binder) bnd = MapItem (num);
651 if (bnd.IsNull()) continue;
652 Handle(Dico_DictionaryOfTransient) atr = bnd->AttrList();
653 if (atr.IsNull()) continue;
654 Dico_IteratorOfDictionaryOfTransient iatr(atr,rootname);
655 for (; iatr.More(); iatr.Next()) {
656 TCollection_AsciiString name = iatr.Name();
657 Standard_Boolean deja;
658 Standard_Integer& nbval = list->NewItem (name.ToCString(),deja);
659 if (!deja) nbval = 0;
669 // ## ## ## Actions sur Types Privilegies ## ## ##
670 // ## ## ## (Transient) ## ## ##
672 // Bind associe un objet a un objet resultat; or la Map associe un Objet a un
673 // Binder (qui designe son resultat)
674 // *Transient travaillent avec un SimpleBinderOfTransient
675 // si deja la, on considere son resultat
676 // sinon, on cree un Binder du bon type
679 //=======================================================================
680 //function : BindTransient
682 //=======================================================================
684 void Transfer_TransferProcess::BindTransient(const TheStart& start,
685 const Handle(Standard_Transient)& res)
686 // const Standard_Integer categ)
688 if (res.IsNull()) return;
689 Handle(Transfer_Binder) former = Find(start);//,categ);skl
690 Handle(Transfer_SimpleBinderOfTransient) binder =
691 Handle(Transfer_SimpleBinderOfTransient)::DownCast(former);
692 // Binding sur place ?
693 if (!binder.IsNull()) {
694 if (binder->Status() == Transfer_StatusVoid) { binder->SetResult(res); return; }
697 binder = new Transfer_SimpleBinderOfTransient;
698 binder->SetResult (res);
699 if (former.IsNull()) Bind(start,binder);//,categ);skl
700 else Rebind(start,binder);//,categ);skl
704 //=======================================================================
705 //function : FindTransient
707 //=======================================================================
709 const Handle(Standard_Transient)& Transfer_TransferProcess::FindTransient
710 (const TheStart& start) const
712 Handle(Transfer_SimpleBinderOfTransient) binder =
713 Handle(Transfer_SimpleBinderOfTransient)::DownCast(Find(start));
714 if (binder.IsNull()) return nultrans;
715 if (!binder->HasResult()) return nultrans;
716 return binder->Result();
720 // Binding Multiple : D abord le declarer par BindMultiple (si pas deja fait)
721 // Puis ajouter les termes par AddMultiple
723 //=======================================================================
724 //function : BindMultiple
726 //=======================================================================
728 void Transfer_TransferProcess::BindMultiple(const TheStart& start)
729 // const Standard_Integer categ)
731 Handle(Transfer_Binder) binder = FindAndMask (start);//,categ);skl
732 if (!binder.IsNull()) {
733 if (!binder->IsKind(STANDARD_TYPE(Transfer_MultipleBinder))) {
734 StartTrace (thelastbnd,start,thelevel,4);
735 throw Transfer_TransferFailure("TransferProcess : BindMultiple");
738 else Bind(start,new Transfer_MultipleBinder);//,categ);skl
742 //=======================================================================
743 //function : AddMultiple
745 //=======================================================================
747 void Transfer_TransferProcess::AddMultiple(const TheStart& start,
748 const Handle(Standard_Transient)& res)
749 // const Standard_Integer categ)
751 Handle(Transfer_Binder) binder = FindAndMask(start);//,categ);skl
752 Handle(Transfer_MultipleBinder) multr =
753 Handle(Transfer_MultipleBinder)::DownCast(binder);
754 if (multr.IsNull()) {
755 StartTrace (binder,start,thelevel,4);
756 if (binder.IsNull()) throw Transfer_TransferFailure("TransferProcess : AddMultiple, nothing bound");
757 else throw Transfer_TransferFailure("TransferProcess : AddMultiple, Binder not a MultipleBinder");
759 multr->AddResult(res);
763 //=======================================================================
764 //function : FindTypedTransient
766 //=======================================================================
768 Standard_Boolean Transfer_TransferProcess::FindTypedTransient
769 (const TheStart& start, const Handle(Standard_Type)& atype,
770 Handle(Standard_Transient)& val) const
772 return GetTypedTransient (Find(start),atype,val);
776 //=======================================================================
777 //function : GetTypedTransient
779 //=======================================================================
781 Standard_Boolean Transfer_TransferProcess::GetTypedTransient
782 (const Handle(Transfer_Binder)& binder, const Handle(Standard_Type)& atype,
783 Handle(Standard_Transient)& val) const
785 return Transfer_SimpleBinderOfTransient::GetTypedResult(binder,atype,val);
789 // ## ## ## ## ## Acces Atomique ## ## ## ## ##
790 // (ne gere pas le scope mais donne acces aux categories)
792 //=======================================================================
793 //function : NbMapped
795 //=======================================================================
797 Standard_Integer Transfer_TransferProcess::NbMapped () const
799 return themap.Extent();
803 //=======================================================================
806 //=======================================================================
808 const TheStart& Transfer_TransferProcess::Mapped(const Standard_Integer num) const
810 return themap.FindKey(num);
814 //=======================================================================
815 //function : MapIndex
817 //=======================================================================
819 Standard_Integer Transfer_TransferProcess::MapIndex(const TheStart& start) const
821 return themap.FindIndex(start);
825 //=======================================================================
828 //=======================================================================
830 Handle(Transfer_Binder) Transfer_TransferProcess::MapItem(const Standard_Integer num) const
831 // const Standard_Integer categ) const
833 Handle(Transfer_Binder) binder = themap.FindFromIndex(num);
834 //sklif (binder.IsNull())
836 //sklreturn binder->Search (categ);
840 // ########################################################################
841 // .... ROOT MANAGEMENT ....
843 //=======================================================================
846 //=======================================================================
848 void Transfer_TransferProcess::SetRoot (const TheStart& start)
850 Standard_Integer index = MapIndex(start);
852 //StartTrace (thelastbnd,start,thelevel,4);
853 //throw Transfer_TransferFailure("TransferProcess : SetRoot");
858 if (thetrace > 2) StartTrace (MapItem(index),start,thelevel,3);
862 //=======================================================================
863 //function : SetRootManagement
865 //=======================================================================
867 void Transfer_TransferProcess::SetRootManagement(const Standard_Boolean stat)
873 //=======================================================================
876 //=======================================================================
878 Standard_Integer Transfer_TransferProcess::NbRoots () const
880 return theroots.Extent();
884 //=======================================================================
887 //=======================================================================
889 const TheStart& Transfer_TransferProcess::Root(const Standard_Integer num) const
891 Standard_Integer ind = 0;
892 if (num > 0 && num <= theroots.Extent()) ind = theroots.FindKey(num);
893 return themap.FindKey (ind);
897 //=======================================================================
898 //function : RootItem
900 //=======================================================================
902 Handle(Transfer_Binder) Transfer_TransferProcess::RootItem(const Standard_Integer num) const
903 // const Standard_Integer categ) const
905 Standard_Integer ind = 0;
906 if (num > 0 && num <= theroots.Extent()) ind = theroots.FindKey(num);
907 return themap.FindFromIndex(ind);//->Search(categ);skl
911 //=======================================================================
912 //function : RootIndex
914 //=======================================================================
916 Standard_Integer Transfer_TransferProcess::RootIndex(const TheStart& start) const
918 Standard_Integer index = MapIndex(start);
919 if (index == 0) return 0;
920 return theroots.FindIndex(index);
924 //=======================================================================
925 //function : NestingLevel
927 //=======================================================================
929 Standard_Integer Transfer_TransferProcess::NestingLevel () const
935 //=======================================================================
936 //function : ResetNestingLevel
938 //=======================================================================
940 void Transfer_TransferProcess::ResetNestingLevel ()
946 // ########################################################################
947 // .... SCOPE MANAGEMENT ....
950 //======================================================================
951 //Purpose : gka TRJ9 for writing SDR for solid
952 // Check if binder has already been bound to the result binder.
953 //======================================================================
955 // static Standard_Boolean Contains(const Handle(Transfer_Binder)& resbinder,
956 // const Handle(Transfer_Binder)& addbinder)
958 // Handle(Transfer_Binder) tmpbind = resbinder;
959 // for ( ; ! tmpbind.IsNull(); tmpbind = tmpbind->NextResult() )
960 // if ( tmpbind == addbinder ) return Standard_True;
961 // return Standard_False;
964 // ########################################################################
965 // .... AUTOMATISMES DE TRANSFERT ....
967 // ## ## ## ## ## Fonctions de Base ## ## ## ## ##
970 //=======================================================================
971 //function : Recognize
973 //=======================================================================
975 Standard_Boolean Transfer_TransferProcess::Recognize(const TheStart& start) const
977 Handle(Transfer_Actor) actor = theactor;
978 // On balaie les Next jusqu a avoir un Resultat
979 while (!actor.IsNull()) {
980 if (actor->Recognize (start)) return Standard_True;
981 actor = actor->Next();
983 return Standard_False;
987 //=======================================================================
988 //function : Transferring
990 //=======================================================================
992 Handle(Transfer_Binder) Transfer_TransferProcess::Transferring(const TheStart& start)
994 // Map deja alimentee ?
995 Handle(Transfer_Binder) former = FindAndMask(start);
997 // .... Transfert deja effectue avec Resultat ? ....
999 // On considere que cette nouvelle demande de Transfert correspond donc a une
1000 // utilisation en plus : noter "AlreadyUsed", donc resultat non modifiable
1001 if (!former.IsNull()) {
1002 if (former->HasResult()) {
1003 former->SetAlreadyUsed();
1008 // .... Etat Initial : peut-etre deja fait ... ou infaisable !
1010 //if (!former.IsNull()) {
1011 Transfer_StatusExec statex = former->StatusExec();
1013 case Transfer_StatusInitial : // Transfert prepare a faire
1015 case Transfer_StatusDone : // Transfert deja fait
1017 themessenger << " .. and Transfer done" << Message_EndLine;
1019 // if (former->HasResult()) former->SetAlreadyUsed();
1021 case Transfer_StatusRun : // ca y est, on boucle
1022 former->SetStatusExec(Transfer_StatusLoop);
1024 case Transfer_StatusError : // pas propre, ca ...
1026 themessenger << " *** Transfer in Error Status :" << Message_EndLine;
1027 StartTrace (former, start, thelevel,0);
1028 // (*themessenger->Out()) << flush;
1030 else StartTrace (former, start,thelevel,4);
1031 throw Transfer_TransferFailure("TransferProcess : Transfer in Error Status");
1032 case Transfer_StatusLoop : // la boucle est bouclee ...
1034 themessenger << " *** Transfer Head of Dead Loop :" << Message_EndLine;
1035 StartTrace (former, start, thelevel,0);
1036 // (*themessenger->Out()) << flush;
1038 else StartTrace (former, start,thelevel,4);
1039 throw Transfer_TransferDeadLoop("TransferProcess : Transfer at Head of a Dead Loop");
1042 std::cout << "Transfer,level "<<thelevel<<Message_Flush;
1046 // .... OK, on peut lancer l Execution
1047 //if (!former.IsNull())
1048 former->SetStatusExec(Transfer_StatusRun);
1051 std::cout << " GO .." << std::endl;
1054 Handle(Transfer_Binder) binder;
1055 Standard_Boolean newbind = Standard_False;
1057 // Transfert sous protection pour les exceptions (pour notification en fait)
1058 Standard_Integer oldlev = thelevel;
1061 binder = TransferProduct(start);
1064 // ... Exceptions a Rattraper : elles ne se ressemblent pas toutes ... !
1065 catch (Transfer_TransferDeadLoop const&) {
1066 if (binder.IsNull()) {
1067 themessenger << " *** Dead Loop with no Result" << Message_EndLine;
1068 if (thetrace) StartTrace (binder, start, thelevel-1,0);
1069 binder = new Transfer_VoidBinder;
1070 Bind (start,binder); newbind = Standard_True;
1071 } else if (binder->StatusExec() == Transfer_StatusLoop) {
1073 themessenger << " *** Dead Loop : Finding head of Loop :" << Message_EndLine;
1074 StartTrace (binder, start, thelevel-1,0);
1076 else StartTrace (binder, start,thelevel-1,4);
1077 throw Transfer_TransferFailure("TransferProcess : Head of Dead Loop");
1078 // Autrement dit, on change d exception (on est sorti de la boucle)
1081 themessenger << " *** Dead Loop : Actor in Loop :" << Message_EndLine;
1082 StartTrace (binder, start, thelevel-1,0);
1085 binder->AddFail("Transfer in dead Loop");
1088 catch (Standard_Failure const& anException) {
1089 if (binder.IsNull()) {
1090 themessenger << " *** Exception Raised with no Result" << Message_EndLine;
1091 binder = new Transfer_VoidBinder;
1092 Bind (start,binder); newbind = Standard_True;
1094 binder->AddFail("Transfer stopped by exception raising");
1096 themessenger << " *** Raised : " << anException.GetMessageString() << Message_EndLine;
1097 StartTrace (binder, start, thelevel-1,4);
1103 // Transfert non protege (ainsi, dbx a la main en cas de plantage par Raise)
1104 else binder = TransferProduct(start);
1106 // .... Conclusion : Noter dans la Map ....
1108 if (!newbind && !binder.IsNull()) {
1109 if (former.IsNull()) {
1110 // Peut-etre <theactor> a fait lui meme Bind ... verifier sinon le faire
1111 if (!IsBound(start)) Bind(start,binder); // resultat = categorie 0
1112 else { // gka TRJ9 for writing SDR for solid
1113 // Handle(Transfer_Binder) tmpbind = Find(start);
1114 // if(!Contains(binder,tmpbind))
1115 // binder->AddResult(tmpbind);
1116 Rebind(start,binder); // test_pattern.sat
1119 else Rebind(start,binder);
1120 // (du coup, <thelastbnd> vaut <binder>)
1122 std::cout << " ... OK" << std::endl;
1126 //= by ABV: 5 Oct 97: nothing generated, but former can be in run state - drop it
1127 //= ASK: may be set it to StatusInitial ?
1128 if ( ! former.IsNull() ) former->SetStatusExec ( Transfer_StatusDone ); //+
1129 return nulbinder; // Binder Null ... que faire d autre ?
1132 // .... Gerer les Racines (si prevu) ....
1134 if (therootl >= thelevel) {
1136 if (therootm && binder->Status() != Transfer_StatusVoid) {
1143 // ## ## TransferProduct : Action proprement dite ## ##
1145 Handle(Transfer_Binder) Transfer_TransferProcess::TransferProduct
1146 (const TheStart& start)
1148 thelevel ++; // si decremente et == 0, transfert racine
1149 Handle(Transfer_Binder) binder;
1150 Handle(Transfer_Actor) actor = theactor;
1152 // On balaie les Next jusqu a avoir un Resultat
1153 while (!actor.IsNull()) {
1154 if (actor->Recognize (start)) binder = actor->Transferring(start,this);
1155 else binder.Nullify();
1156 if (!binder.IsNull()) break;
1157 actor = actor->Next();
1159 if (binder.IsNull()) {
1161 // themessenger << "Transfer has produced no Result" <<endl;
1162 // StartTrace (binder, start, thelevel-1,0); sout << flush;
1164 if (thelevel > 0) thelevel --;
1167 // Gestion du niveau racine (.. a regarder de pres ..)
1168 if (therootl == 0 && binder->StatusExec() == Transfer_StatusDone)
1169 therootl = thelevel - 1;
1171 if (thelevel > 0) thelevel --;
1176 //=======================================================================
1177 //function : Transfer
1179 //=======================================================================
1181 Standard_Boolean Transfer_TransferProcess::Transfer(const TheStart& start)
1183 Handle(Transfer_Binder) binder = Transferring(start);
1184 return (!binder.IsNull());
1188 // #########################################################################
1189 // .... Error Handling + Trace ....
1191 // trace : 1 pour Fail et Exception , 2 pour Root et Warning
1194 //=======================================================================
1195 //function : SetErrorHandle
1197 //=======================================================================
1199 void Transfer_TransferProcess::SetErrorHandle(const Standard_Boolean err)
1202 } // traite par Transferring
1205 //=======================================================================
1206 //function : ErrorHandle
1208 //=======================================================================
1210 Standard_Boolean Transfer_TransferProcess::ErrorHandle() const
1215 //=======================================================================
1216 //function : StartTrace
1218 //=======================================================================
1220 void Transfer_TransferProcess::StartTrace(const Handle(Transfer_Binder)& binder,
1221 const TheStart& start,
1222 const Standard_Integer level,
1223 const Standard_Integer mode) const
1225 // ### Fail (Roots:50) -- Start start->DynamicType()
1226 // ### Fail (Roots:50) -- Start id:#label.. Type:start->DynamicType()
1227 if (thetrace > 3) { // Internal to be switch when searching bug (trace >= 4)
1228 if (mode == 1) themessenger << " ### Fail";
1229 if (mode == 2) themessenger << " ### Warning";
1230 if (mode == 3) themessenger << " ### New Root n0 " << theroots.Extent();
1231 if (mode == 4) themessenger << " ### Exception";
1232 if (mode == 5) themessenger << " ### Substitution";
1233 if (mode == 6) themessenger << " ### Information";
1235 themessenger << " (nested)"; // " at nesting Level:"<<level;
1236 if (mode >= 0 && mode != 3)
1237 themessenger << " at " << theroots.Extent() << " Roots";
1239 if (!start.IsNull()) PrintTrace (start,themessenger);
1242 if (!binder.IsNull()) { // old: if IsNull sout <<endl<< " --- Not Bound";
1243 Handle(Transfer_Binder) bnd = binder;
1244 Standard_Boolean hasres = Standard_False;
1245 while (!bnd.IsNull()) {
1246 if (bnd->Status() != Transfer_StatusVoid) {
1247 // --- Result Type: binder->ResultType() --- Binder : binder->DynamicType();
1249 themessenger << "\n --- Result Type : ";
1251 themessenger << " , ";
1252 themessenger << bnd->ResultTypeName();
1253 // CKY 9-JAN-1999: waiting for XSTEP Kernel message (not IGES_2075)
1254 /* Message_Msg Msg2075("IGES_2075");
1255 Msg2075.AddString(bnd->ResultTypeName());
1256 Msg2075.TraceEver(); */
1257 hasres = Standard_True;
1259 bnd = bnd->NextResult();
1261 if (!hasres && mode > 2) {
1262 themessenger << "\n --- No Result recorded";
1263 // CKY 9-JAN-1999 : waiting for XSTEP Kernel message
1264 // (not IGES_2075, no reference to specifically TopoDS_Shape)
1265 /* Message_Msg Msg2075("IGES_2075");
1266 Msg2075.AddString("No TopoDS_Shape");
1267 Msg2075.TraceEver(); */
1269 //old if (isused) sout << " -- (Already Used in another Transfer)";
1271 themessenger << Message_EndLine;
1275 //=======================================================================
1276 //function : PrintTrace
1278 //=======================================================================
1280 void Transfer_TransferProcess::PrintTrace(const TheStart& start,
1281 const Handle(Message_Messenger)& S) const
1283 if (!start.IsNull()) S <<" Type:" << start->DynamicType()->Name();
1287 //=======================================================================
1288 //function : IsLooping
1290 //=======================================================================
1292 Standard_Boolean Transfer_TransferProcess::IsLooping
1293 (const Standard_Integer alevel) const
1294 { return alevel > NbMapped(); }
1298 // #########################################################################
1299 // .... RESULTATS ....
1302 // ## ## RootResult : Les Racines ## ##
1305 //=======================================================================
1306 //function : RootResult
1308 //=======================================================================
1310 Transfer_Iterator Transfer_TransferProcess::RootResult(const Standard_Boolean withstart) const
1312 Transfer_Iterator iter(withstart);
1313 Standard_Integer max = theroots.Extent();
1314 for (Standard_Integer j = 1; j <= max; j ++) {
1315 Standard_Integer i = theroots.FindKey(j);
1316 Handle(Transfer_Binder) binder = MapItem(i);
1317 if (binder.IsNull()) continue;
1318 if (withstart) iter.Add (binder,Mapped(i));
1319 else iter.Add (binder);
1325 // ## ## CompleteResult : Tous les Resultats ## ##
1327 //=======================================================================
1328 //function : CompleteResult
1330 //=======================================================================
1332 Transfer_Iterator Transfer_TransferProcess::CompleteResult
1333 (const Standard_Boolean withstart) const
1335 Transfer_Iterator iter(withstart);
1336 Standard_Integer max = NbMapped();
1337 for (Standard_Integer i = 1; i <= max; i ++) {
1338 Handle(Transfer_Binder) binder = MapItem(i);
1339 if (binder.IsNull()) continue;
1340 if (withstart) iter.Add (binder,Mapped(i));
1341 else iter.Add (binder);
1347 // ## ## AbnormalResult : Transferts a probleme ## ##
1348 //=======================================================================
1349 //function : AbnormalResult
1351 //=======================================================================
1353 Transfer_Iterator Transfer_TransferProcess::AbnormalResult() const
1355 Transfer_Iterator iter(Standard_True);
1356 Standard_Integer max = NbMapped();
1357 for (Standard_Integer i = 1; i <= max; i ++) {
1358 Handle(Transfer_Binder) binder = MapItem(i);
1359 if (binder.IsNull()) continue;
1360 Transfer_StatusExec statex = binder->StatusExec();
1361 if (statex != Transfer_StatusInitial && statex != Transfer_StatusDone)
1362 iter.Add (binder,Mapped(i)); // on note les cas "pas normaux"
1368 // ## ## ## CheckList : les messages ## ## ##
1369 //=======================================================================
1370 //function : CheckList
1372 //=======================================================================
1374 Interface_CheckIterator Transfer_TransferProcess::CheckList
1375 (const Standard_Boolean erronly) const
1377 Interface_CheckIterator list;
1378 Standard_Integer num, max = NbMapped();
1379 for (Standard_Integer i = 1; i <= max; i ++) {
1380 Handle(Transfer_Binder) binder = MapItem(i);
1381 if (binder.IsNull()) continue;
1382 Transfer_StatusExec statex = binder->StatusExec();
1383 Handle(Interface_Check) check = binder->Check();
1384 if (statex != Transfer_StatusInitial && statex != Transfer_StatusDone &&
1385 !check->HasFailed())
1386 check->AddFail("Transfer in Abnormal Status (!= Initial or Done)");
1387 if (!check->HasFailed() && (erronly || check->NbWarnings() == 0)) continue;
1388 const TheStart& ent = Mapped(i);
1389 num = CheckNum(ent);
1390 if (num == 0) num = i;
1391 check->SetEntity(ent);
1392 list.Add(check,num);
1398 // #########################################################################
1399 // .... RESULTATS PAR ENTITE ....
1401 //=======================================================================
1402 //function : ResultOne
1404 //=======================================================================
1406 Transfer_Iterator Transfer_TransferProcess::ResultOne(const TheStart& start,
1407 const Standard_Integer level,
1408 const Standard_Boolean withstart) const
1410 Transfer_Iterator iter(withstart);
1411 Standard_Integer max = NbMapped();
1412 Standard_Integer ind = MapIndex (start);
1413 if (ind == 0) return iter;
1414 Standard_Integer i1 = (level == 0 ? ind : 1);
1415 Standard_Integer i2 = (level == 0 ? ind : max);
1416 Handle(TColStd_HArray1OfInteger) map = new TColStd_HArray1OfInteger (i1,i2,0);
1417 //MarkScoped (ind,level,map);
1419 for (Standard_Integer i = i1; i <= i2; i ++) {
1420 ind = map->Value(i);
1421 if (ind == 0) continue;
1422 Handle(Transfer_Binder) binder = MapItem(i);
1423 if (binder.IsNull()) continue;
1424 if (withstart) iter.Add (binder,Mapped(ind));
1425 else iter.Add (binder);
1431 //=======================================================================
1432 //function : CheckListOne
1434 //=======================================================================
1436 Interface_CheckIterator Transfer_TransferProcess::CheckListOne
1437 (const TheStart& start,const Standard_Integer level,
1438 const Standard_Boolean erronly) const
1440 Interface_CheckIterator list;
1441 Standard_Integer max = NbMapped();
1442 Standard_Integer num, ind = MapIndex (start);
1443 if (ind == 0) return list;
1444 Standard_Integer i1 = (level == 0 ? ind : 1);
1445 Standard_Integer i2 = (level == 0 ? ind : max);
1446 Handle(TColStd_HArray1OfInteger) map = new TColStd_HArray1OfInteger (i1,i2,0);
1447 //MarkScoped (ind,level,map);
1449 for (Standard_Integer i = i1; i <= i2; i ++) {
1450 ind = map->Value(i);
1451 if (ind == 0) continue;
1452 Handle(Transfer_Binder) binder = MapItem(ind);
1453 if (binder.IsNull()) continue;
1454 Transfer_StatusExec statex = binder->StatusExec();
1455 Handle(Interface_Check) check = binder->Check();
1456 if (statex != Transfer_StatusInitial && statex != Transfer_StatusDone &&
1457 !check->HasFailed())
1458 check->AddFail("Transfer in Abnormal Status (!= Initial or Done)");
1459 if (!check->HasFailed() && (erronly || check->NbWarnings() == 0)) continue;
1460 const TheStart& ent = Mapped(ind);
1461 num = CheckNum(ent); if (num == 0) num = ind;
1462 check->SetEntity(ent);
1463 list.Add(check,num);
1469 //=======================================================================
1470 //function : IsCheckListEmpty
1472 //=======================================================================
1474 Standard_Boolean Transfer_TransferProcess::IsCheckListEmpty
1475 (const TheStart& start, const Standard_Integer level,
1476 const Standard_Boolean erronly) const
1478 Standard_Integer max = NbMapped();
1479 Standard_Integer ind = MapIndex (start);
1480 if (ind == 0) return Standard_False;
1481 Standard_Integer i1 = (level == 0 ? ind : 1);
1482 Standard_Integer i2 = (level == 0 ? ind : max);
1483 Handle(TColStd_HArray1OfInteger) map = new TColStd_HArray1OfInteger (i1,i2,0);
1484 // MarkScoped (ind,level,map);
1486 for (Standard_Integer i = i1; i <= i2; i ++) {
1487 ind = map->Value(i);
1488 if (ind == 0) continue;
1489 Handle(Transfer_Binder) binder = MapItem(ind);
1490 if (binder.IsNull()) continue;
1492 Transfer_StatusExec statex = binder->StatusExec();
1493 Handle(Interface_Check) check = binder->Check();
1494 if (statex != Transfer_StatusInitial && statex != Transfer_StatusDone)
1495 return Standard_False;
1496 if (check->HasFailed() || (!erronly && check->NbWarnings() > 0)) return Standard_False;
1498 return Standard_True;
1502 //=======================================================================
1503 //function : RemoveResult
1505 //=======================================================================
1507 void Transfer_TransferProcess::RemoveResult(const TheStart& start,
1508 const Standard_Integer level,
1509 const Standard_Boolean /*compute*/)
1511 //if (compute) ComputeScopes();
1512 Standard_Integer max = NbMapped();
1513 Standard_Integer ind = MapIndex (start);
1514 if (ind == 0) return;
1515 Standard_Integer i1 = (level == 0 ? ind : 1);
1516 Standard_Integer i2 = (level == 0 ? ind : max);
1517 Handle(TColStd_HArray1OfInteger) map = new TColStd_HArray1OfInteger (i1,i2,0);
1518 // MarkScoped (ind,level,map);
1520 Standard_Integer i; // svv Jan11 2000 : porting on DEC
1521 for (i = i1; i <= i2; i ++) {
1522 ind = map->Value(i);
1523 if (ind == 0) continue;
1524 Handle(Transfer_Binder) binder = MapItem(ind);
1525 if (binder.IsNull()) continue;
1526 // Standard_Boolean cayest = binder->SetNbUserScopes (-1);
1527 // if (cayest) themap(ind) = nulbinder; // RAZ !
1530 //pdn commented for (i = NbRoots(); i > 0; i --)
1531 // if (theroots.Value(i) == ind) theroots.Remove(i);
1535 Standard_Integer Transfer_TransferProcess::CheckNum(const TheStart& ) const
1541 //=======================================================================
1542 //function : SetProgress
1543 //purpose : Sets Progress indicator
1544 //=======================================================================
1546 void Transfer_TransferProcess::SetProgress(const Handle(Message_ProgressIndicator)& theProgress)
1548 myProgress = theProgress;
1551 //=======================================================================
1552 //function : GetProgress
1553 //purpose : Returns Progress indicator
1554 //=======================================================================
1556 Handle(Message_ProgressIndicator) Transfer_TransferProcess::GetProgress() const