0025622: CAST analysis: Avoid invocation of virtual Methods of the declared Class...
[occt.git] / src / Interface / Interface_CopyTool.cxx
1 // Copyright (c) 1999-2014 OPEN CASCADE SAS
2 //
3 // This file is part of Open CASCADE Technology software library.
4 //
5 // This library is free software; you can redistribute it and/or modify it under
6 // the terms of the GNU Lesser General Public License version 2.1 as published
7 // by the Free Software Foundation, with special exception defined in the file
8 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
9 // distribution for complete text of the license and disclaimer of any warranty.
10 //
11 // Alternatively, this file may be used under the terms of Open CASCADE
12 // commercial license or contractual agreement.
13
14 #include <Interface_CopyTool.ixx>
15 #include <Interface_GeneralModule.hxx>
16 #include <Interface_ReportEntity.hxx>
17 #include <Interface_InterfaceError.hxx>
18 #include <TCollection_HAsciiString.hxx>
19
20
21 // Se souvenir qu une version plus riche de CopyTool existe : c est
22 // TransferDispatch (package Transfer). Cette classe offre beaucoup plus de
23 // possibilite (parametrage des actions, gestion du Mapping ...)
24 // Mais le principe (transfert en 2 passes) reste le meme, a savoir :
25 // Passe 1 normale : les entites a transferer sont designees, elles entrainent
26 // leurs sous-references vraies
27 // Passe 2 : une fois tous les transferts faits, les relations "Imply" sont
28 // mises, pour les entites designees ET QUI ONT ETE AUSSI TRANSFEREES, la
29 // relation est reconduite (pas de nouveau Share)
30
31
32 //  #####################################################################
33 //  ....                        CONSTRUCTEURS                        ....
34
35 Interface_CopyTool::Interface_CopyTool
36   (const Handle(Interface_InterfaceModel)& amodel,
37    const Interface_GeneralLib& lib)
38     : thelib (lib) , thelst (amodel->NbEntities())
39 {
40   thelst.Init(Standard_False);
41   themod = amodel;
42   themap = new Interface_CopyMap (amodel);
43   therep = new Interface_CopyMap (amodel);
44   thelev = 0;  theimp = Standard_False;
45 }
46
47     Interface_CopyTool::Interface_CopyTool
48   (const Handle(Interface_InterfaceModel)& amodel,
49    const Handle(Interface_Protocol)& protocol)
50     : thelib (protocol) , thelst (amodel->NbEntities())
51 {
52   thelst.Init(Standard_False);
53   themod = amodel;
54   themap = new Interface_CopyMap (amodel);
55   therep = new Interface_CopyMap (amodel);
56   thelev = 0;  theimp = Standard_False;
57 }
58
59
60     Interface_CopyTool::Interface_CopyTool
61   (const Handle(Interface_InterfaceModel)& amodel)
62     : thelib (Interface_Protocol::Active()) , thelst (amodel->NbEntities())
63 {
64   if (Interface_Protocol::Active().IsNull()) Interface_InterfaceError::Raise
65     ("Interface CopyTool : Create with Active Protocol undefined");
66
67   thelst.Init(Standard_False);
68   themod = amodel;
69   themap = new Interface_CopyMap (amodel);
70   therep = new Interface_CopyMap (amodel);
71   thelev = 0;  theimp = Standard_False;
72 }
73
74     Handle(Interface_InterfaceModel)  Interface_CopyTool::Model () const
75       {  return themod;  }
76
77     void Interface_CopyTool::SetControl
78   (const Handle(Interface_CopyControl)& othermap)
79       {  themap = othermap;  }
80
81     Handle(Interface_CopyControl)  Interface_CopyTool::Control () const
82       {  return themap;  }
83
84
85 //  #####################################################################
86 //  ....                    Actions Individuelles                    ....
87
88     void Interface_CopyTool::Clear ()
89 {
90   themap->Clear();
91   therep->Clear();
92   thelev = 0;  theimp = Standard_False;
93   therts.Clear();
94   ClearLastFlags();
95 }
96
97     Standard_Boolean Interface_CopyTool::NewVoid
98   (const Handle(Standard_Transient)& entfrom,
99    Handle(Standard_Transient)& entto)
100 {
101   if (entfrom == theent) {
102     if (themdu.IsNull()) return Standard_False;
103     return themdu->NewVoid(theCN,entto);
104   }
105   theent = entfrom;
106   Standard_Boolean res = thelib.Select (entfrom,themdu,theCN);
107   if (res)   res   = themdu->NewVoid (theCN,entto);
108   if (!res)  res   = themdu->NewCopiedCase (theCN,entfrom,entto,*this);
109 //  if (!res) entto = entfrom->ShallowCopy();   sorry, nothing more possible
110   return res;
111 }
112
113
114     Standard_Boolean Interface_CopyTool::Copy
115   (const Handle(Standard_Transient)& entfrom,
116    Handle(Standard_Transient)& entto,
117    const Standard_Boolean mapped, const Standard_Boolean errstat)
118 {
119   Standard_Boolean res = Standard_True;
120   if (entfrom == theent) {
121     if (themdu.IsNull()) res = Standard_False;
122   } else {
123     theent = entfrom;
124     res = thelib.Select(entfrom,themdu,theCN);
125   }
126   if (!res) {
127 //  Built-in :
128     if (entfrom.IsNull()) return res;
129     if (entfrom->DynamicType() == STANDARD_TYPE(TCollection_HAsciiString)) {
130       entto = new TCollection_HAsciiString
131         ( Handle(TCollection_HAsciiString)::DownCast(entfrom)->ToCString() );
132       res = Standard_True;
133     }
134     return res;
135   }
136 //  On cree l Entite vide (NewVoid), la Copie reste a faire
137   res = NewVoid(entfrom,entto);
138   if (mapped) themap->Bind (entfrom,entto);    // Mapper avant de continuer ...
139
140 //  A present, on effectue la Copie (selon cas; si ShallowCopy ne suffit pas :
141 //  c est <themdu> qui decide)
142
143 //    Une Entite en Erreur n est pas copiee (pas de sens et c est risque ...)
144 //    Cependant, elle est "Copiee a Vide (NewVoid)" donc referencable
145   if (!errstat)    themdu->CopyCase(theCN,entfrom,entto,*this);
146   return res;
147 }
148
149     void  Interface_CopyTool::Implied
150   (const Handle(Standard_Transient)& entfrom,
151    const Handle(Standard_Transient)& entto)
152 {
153   Handle(Interface_GeneralModule) module;
154   Standard_Integer CN;
155   if (thelib.Select(entfrom,module,CN))
156     module->RenewImpliedCase(CN,entfrom,entto,*this);
157 }
158
159
160 //  ....                Alimentation de la Map                ....
161
162     Handle(Standard_Transient) Interface_CopyTool::Transferred
163   (const Handle(Standard_Transient)& ent)
164 {
165   Handle(Standard_Transient) res;
166   if (ent.IsNull()) return res;    // Copie d un Null : tres simple ...
167   Standard_Integer nument = themod->Number(ent);
168
169 //  <nument> == 0 -> Peut etre une sous-partie non partagee ...
170 //  On accepte mais on se protege contre un bouclage
171   if (nument == 0 && thelev > 100) Interface_InterfaceError::Raise
172     ("CopyTool : Transferred, Entity is not contained in Starting Model");
173   if (!themap->Search(ent,res)) {       // deja transfere ? sinon, le faire
174
175 //  On opere la Copie (enfin, on tente)
176 //  En cas d echec, rien n est enregistre
177     if (!Copy(ent,res, (nument != 0), themod->IsRedefinedContent(nument) ))
178       return res;
179
180     thelev ++;
181     if (nument != 0) thelst.SetTrue (nument);
182     Handle(Interface_ReportEntity) rep;
183     if (nument != 0) rep = themod->ReportEntity (nument);
184     if (!rep.IsNull()) {
185 //  ATTENTION ATTENTION, si ReportEntity : Copier aussi Content et refaire une
186 //  ReportEntity avec les termes initiaux
187       if (rep->IsUnknown()) therep->Bind
188         (ent, new Interface_ReportEntity(res));
189       else {
190         Handle(Standard_Transient) contfrom, contto;
191         contfrom = rep->Content();
192         Handle(Interface_ReportEntity) repto =
193           new Interface_ReportEntity (rep->Check(),res);
194         if (!contfrom.IsNull()) {
195           if (contfrom == ent) contto = res;
196           else  Copy (contfrom,contto, themod->Contains(contfrom), Standard_False);
197           repto->SetContent (contto);
198         }
199         therep->Bind (ent,repto);
200       }
201     }
202 //    Gerer le niveau d imbrication (0 = racine du transfert)
203     thelev --;
204   }
205   if (thelev == 0 && nument > 0) therts.Append(nument);
206   return res;
207 }
208
209     void Interface_CopyTool::Bind
210   (const Handle(Standard_Transient)& ent,
211    const Handle(Standard_Transient)& res)
212 {
213   Standard_Integer num = themod->Number(ent);
214   themap->Bind (ent,res);
215   thelst.SetTrue (num);
216 }
217
218     Standard_Boolean Interface_CopyTool::Search
219   (const Handle(Standard_Transient)& ent,
220    Handle(Standard_Transient)& res) const
221       {  return themap->Search (ent,res);  }
222
223 //  ##    ##    ##    ##    ##    ##    ##    ##    ##    ##    ##    ##    ##
224 //                              LastFlag
225
226     void Interface_CopyTool::ClearLastFlags ()
227       {  thelst.Init(Standard_False);  }
228
229     Standard_Integer  Interface_CopyTool::LastCopiedAfter
230   (const Standard_Integer numfrom,
231    Handle(Standard_Transient)& ent, Handle(Standard_Transient)& res) const
232 {
233   Standard_Integer nb = thelst.Length();
234   for (Standard_Integer num = numfrom + 1; num <= nb; num ++) {
235     if (thelst.Value(num)) {
236       ent = themod->Value(num);
237       if (themap->Search(ent,res)) return num;
238     }
239   }
240   return 0;
241 }
242
243
244 //  #########################################################################
245 //  ....                        Actions Generales                        ....
246
247     void Interface_CopyTool::TransferEntity
248   (const Handle(Standard_Transient)& ent)
249       {  Handle(Standard_Transient) res = Transferred(ent);  }
250
251     void Interface_CopyTool::RenewImpliedRefs ()
252 {
253   if (theimp) return;    // deja fait
254   theimp = Standard_True;
255
256 //  Transfert Passe 2 : recuperation des relations non "Share" (mais "Imply")
257 //  c-a-d portant sur des entites qui ont pu ou non etre transferees
258 //  (Et que la 1re passe n a pas copie mais laisse en Null)
259 //  N.B. : on devrait interdire de commander des nouveaux transferts ...
260
261   Standard_Integer nb = themod->NbEntities();
262   for (Standard_Integer i = 1; i <= nb; i ++) {
263     Handle(Standard_Transient) ent = themod->Value(i);
264     Handle(Standard_Transient) res;
265     if (!themap->Search(ent,res)) continue;        // entite pas transferee
266 //    Reconduction des references "Imply".  Attention, ne pas copier si non chargee
267     Handle(Interface_ReportEntity) rep;
268     if (!therep->Search(ent,rep))   Implied (ent,res);
269     else if (!rep->HasNewContent()) Implied (ent,res);
270   }
271 }
272
273
274     void Interface_CopyTool::FillModel
275   (const Handle(Interface_InterfaceModel)& bmodel)
276 {
277 //  Travaux preparatoires concernant les modeles
278 //  On commence : cela implique le Header
279   bmodel->Clear();
280   bmodel->GetFromAnother(themod);
281
282 //  Transfert Passe 1 : On prend les Entites prealablement copiees
283   Interface_EntityIterator list = CompleteResult(Standard_True);
284   bmodel->GetFromTransfer(list);
285
286 //  Transfert Passe 2 : recuperation des relations non "Share" (mais "Imply")
287   RenewImpliedRefs();
288 }
289
290
291     Interface_EntityIterator Interface_CopyTool::CompleteResult
292   (const Standard_Boolean withreports) const
293 {
294   Interface_EntityIterator iter;
295   Standard_Integer nb = themod->NbEntities();
296   for (Standard_Integer i = 1; i <= nb; i ++) {
297     Handle(Standard_Transient) ent = themod->Value(i);
298     Handle(Standard_Transient) res;
299     if (!themap->Search(ent,res)) continue;
300     if (withreports) {
301       Handle(Interface_ReportEntity) rep;
302       if (therep->Search(ent,rep)) res = rep;
303     }
304     iter.GetOneItem(res);
305   }
306   return iter;
307 }
308
309     Interface_EntityIterator Interface_CopyTool::RootResult
310   (const Standard_Boolean withreports) const
311 {
312   Interface_EntityIterator iter;
313   Standard_Integer nb = therts.Length();
314   for (Standard_Integer i = 1; i <= nb; i ++) {
315     Standard_Integer j = therts.Value(i);
316     Handle(Standard_Transient) ent = themod->Value(j);
317     Handle(Standard_Transient) res;
318     if (!themap->Search(ent,res)) continue;
319     if (withreports) {
320       Handle(Interface_ReportEntity) rep;
321       if (therep->Search(ent,rep)) res = rep;
322     }
323     iter.GetOneItem(res);
324   }
325   return iter;
326 }
327
328 //=======================================================================
329 //function : ~Interface_CopyTool
330 //purpose  : Destructor
331 //=======================================================================
332
333 Interface_CopyTool::~Interface_CopyTool()
334 {
335 }