0026377: Passing Handle objects as arguments to functions as non-const reference...
[occt.git] / src / IFSelect / IFSelect_ShareOut.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
15 #include <IFSelect_Dispatch.hxx>
16 #include <IFSelect_GeneralModifier.hxx>
17 #include <IFSelect_Modifier.hxx>
18 #include <IFSelect_ShareOut.hxx>
19 #include <Interface_InterfaceError.hxx>
20 #include <Interface_Macros.hxx>
21 #include <Standard_OutOfRange.hxx>
22 #include <Standard_Transient.hxx>
23 #include <Standard_Type.hxx>
24 #include <TCollection_AsciiString.hxx>
25 #include <TCollection_HAsciiString.hxx>
26
27 #include <stdio.h>
28 IMPLEMENT_STANDARD_RTTIEXT(IFSelect_ShareOut,MMgt_TShared)
29
30 IFSelect_ShareOut::IFSelect_ShareOut ()
31 {
32   thedefrt  = new TCollection_HAsciiString ("Default");
33   thenbdefs = thelastrun = 0;
34 }
35
36
37     void  IFSelect_ShareOut::Clear (const Standard_Boolean onlydisp)
38 {
39   thedisps.Clear();
40   ClearResult(!onlydisp);
41   if (onlydisp) return;
42   themodelmodifiers.Clear();
43   thefilemodifiers.Clear();
44 }
45
46     Standard_Boolean  IFSelect_ShareOut::RemoveItem
47   (const Handle(Standard_Transient)& item)
48 {
49   DeclareAndCast(IFSelect_GeneralModifier,modifier,item);
50   if (!modifier.IsNull()) {
51     Standard_Boolean formodel = modifier->IsKind(STANDARD_TYPE(IFSelect_Modifier));
52     Standard_Integer atnum = ModifierRank(modifier);
53     return RemoveModifier (formodel,atnum);
54   }
55   DeclareAndCast(IFSelect_Dispatch,disp,item);
56   if (!disp.IsNull()) {
57     Standard_Integer atnum = DispatchRank(disp);
58     return RemoveDispatch(atnum);
59   }
60   return Standard_False;
61 }
62
63
64     void  IFSelect_ShareOut::ClearResult (const Standard_Boolean alsoname)
65 {
66   thelastrun = 0;
67   if (alsoname) thenbdefs = 0;
68 }
69
70     Standard_Integer  IFSelect_ShareOut::LastRun () const
71       {  return thelastrun;  }
72
73     void  IFSelect_ShareOut::SetLastRun (const Standard_Integer lastrun)
74       {  thelastrun = lastrun;  }
75
76 //  #######################################################################
77 //  ####                DISPATCHES (ENVOI DES FICHIERS)                ####
78
79     Standard_Integer  IFSelect_ShareOut::NbDispatches () const 
80       {  return thedisps.Length();  }
81
82     Standard_Integer  IFSelect_ShareOut::DispatchRank
83   (const Handle(IFSelect_Dispatch)& disp) const 
84 {
85   if (disp.IsNull()) return 0;
86   for (Standard_Integer i = thedisps.Length(); i >= 1; i --)
87     if (disp == thedisps.Value(i)) return i;
88   return 0;
89 }
90
91     const Handle(IFSelect_Dispatch)&  IFSelect_ShareOut::Dispatch
92   (const Standard_Integer num) const 
93 {
94   return thedisps.Value(num);
95 }
96
97     void  IFSelect_ShareOut::AddDispatch
98   (const Handle(IFSelect_Dispatch)& disp)
99 {
100   if (disp.IsNull()) return;
101   thedisps.Append(disp);
102 }
103
104
105     Standard_Boolean  IFSelect_ShareOut::RemoveDispatch
106   (const Standard_Integer rank)
107 {
108   if (rank <= thelastrun || rank > thedisps.Length()) return Standard_False;
109   thedisps.Remove(rank);
110   return Standard_True;
111 }
112
113 //  ##########################################################################
114 //  ####                            MODIFIERS                             ####
115
116     void  IFSelect_ShareOut::AddModifier
117   (const Handle(IFSelect_GeneralModifier)& modifier,
118    const Standard_Integer atnum)
119 {
120   Standard_Boolean formodel = modifier->IsKind(STANDARD_TYPE(IFSelect_Modifier));
121   if (ModifierRank(modifier) == 0)  AddModif (modifier,formodel,atnum);
122   Handle(IFSelect_Dispatch) nuldisp;
123   modifier->SetDispatch(nuldisp);
124 }
125
126     void  IFSelect_ShareOut::AddModifier
127   (const Handle(IFSelect_GeneralModifier)& modifier,
128    const Standard_Integer dispnum, const Standard_Integer atnum)
129 {
130   Standard_Boolean formodel = modifier->IsKind(STANDARD_TYPE(IFSelect_Modifier));
131   if (ModifierRank(modifier) == 0)  AddModif (modifier,formodel,atnum);
132   Handle(IFSelect_Dispatch) disp = Dispatch(dispnum);
133   modifier->SetDispatch(disp);
134 }
135
136
137     void  IFSelect_ShareOut::AddModif
138   (const Handle(IFSelect_GeneralModifier)& modifier,
139    const Standard_Boolean formodel, const Standard_Integer atnum)
140 {
141   if (formodel) {
142     if (atnum > 0 && atnum <= themodelmodifiers.Length())
143       themodelmodifiers.InsertBefore(atnum,modifier);
144     else themodelmodifiers.Append(modifier);
145   } else {
146     if (atnum > 0 && atnum <= thefilemodifiers.Length())
147       thefilemodifiers.InsertBefore(atnum,modifier);
148     else thefilemodifiers.Append(modifier);
149   }
150 }
151
152     Standard_Integer  IFSelect_ShareOut::NbModifiers
153   (const Standard_Boolean formodel) const 
154 {
155   if (formodel) return themodelmodifiers.Length();
156   else          return thefilemodifiers.Length();
157 }
158
159     Handle(IFSelect_GeneralModifier)  IFSelect_ShareOut::GeneralModifier
160   (const Standard_Boolean formodel, const Standard_Integer atnum) const
161 {
162   if (formodel) return themodelmodifiers.Value(atnum);
163   else          return thefilemodifiers.Value(atnum);
164 }
165
166     Handle(IFSelect_Modifier)  IFSelect_ShareOut::ModelModifier
167   (const Standard_Integer num) const 
168 {  return Handle(IFSelect_Modifier)::DownCast(themodelmodifiers.Value(num));  }
169
170     Standard_Integer  IFSelect_ShareOut::ModifierRank
171   (const Handle(IFSelect_GeneralModifier)& modifier) const 
172 {
173   Standard_Integer i;
174   Standard_Boolean formodel = modifier->IsKind(STANDARD_TYPE(IFSelect_Modifier));
175   if (formodel) {
176     for (i = themodelmodifiers.Length(); i >= 1; i --)
177       if (modifier == themodelmodifiers.Value(i)) return i;
178   } else {
179     for (i = thefilemodifiers.Length(); i >= 1; i --)
180       if (modifier == thefilemodifiers.Value(i)) return i;
181   }
182   return 0;
183 }
184
185
186     Standard_Boolean  IFSelect_ShareOut::RemoveModifier
187   (const Standard_Boolean formodel, const Standard_Integer atnum)
188 {
189   if (atnum <= 0) return Standard_False;
190   if (formodel) {
191     if (atnum > themodelmodifiers.Length()) return Standard_False;
192     themodelmodifiers.Remove(atnum);
193   } else {
194     if (atnum > thefilemodifiers.Length()) return Standard_False;
195     thefilemodifiers.Remove(atnum);
196   }
197   return Standard_True;
198 }
199
200
201 //    ChangeModifierRank revient a une permutation circulaire :
202 //    before est mis en after, ceux qui sont entre tournent
203     Standard_Boolean    IFSelect_ShareOut::ChangeModifierRank
204   (const Standard_Boolean formodel,
205    const Standard_Integer before,   const Standard_Integer after)
206 {
207   Standard_Integer nb;
208   if (before <= 0 || after <= 0) return Standard_False;
209   if (before == after) return Standard_True;
210   if (formodel) {
211     nb = themodelmodifiers.Length();
212     if (before > nb || after > nb) return Standard_False;
213     Handle(IFSelect_GeneralModifier) bef = themodelmodifiers.Value(before);
214     themodelmodifiers.Remove(before);
215     if (after == nb) themodelmodifiers.Append(bef);
216     else             themodelmodifiers.InsertBefore(after,bef);
217   } else {
218     nb = thefilemodifiers.Length();
219     if (before > nb || after > nb) return Standard_False;
220     Handle(IFSelect_GeneralModifier) bef = thefilemodifiers.Value(before);
221     thefilemodifiers.Remove(before);
222     if (after == nb) thefilemodifiers.Append(bef);
223     else             thefilemodifiers.InsertBefore(after,bef);
224   }
225   return Standard_True;
226 }
227
228 //  #######################################################################
229 //  ####                    NOMINATION DES FICHIERS                    ####
230 //  Rq : thenbdefs s applique tant que l on ne change pas les termes principaux
231
232     Standard_Boolean  IFSelect_ShareOut::SetRootName
233   (const Standard_Integer num, const Handle(TCollection_HAsciiString)& name)
234 {
235   if (num < 1 || num > thedisps.Length()) return Standard_False;
236   if (RootNumber(name) != 0) return Standard_False;
237   Dispatch(num)->SetRootName (name);
238   return Standard_True;
239 }
240
241     Standard_Boolean  IFSelect_ShareOut::HasRootName
242   (const Standard_Integer num) const
243 {
244   if (num < 1 || num > thedisps.Length()) return Standard_False;
245   return Dispatch(num)->HasRootName();
246 }
247
248     Handle(TCollection_HAsciiString)  IFSelect_ShareOut::RootName
249   (const Standard_Integer num) const
250 {
251   Handle(TCollection_HAsciiString) nulname;
252   if (num < 1 || num > thedisps.Length()) return nulname;
253   return Dispatch(num)->RootName();
254 }
255
256     Standard_Integer  IFSelect_ShareOut::RootNumber
257   (const Handle(TCollection_HAsciiString)& name) const
258 {
259   if (name.IsNull()) return 0;
260   if (!thedefrt.IsNull()) {
261     if (thedefrt->IsSameString(name)) return -1;
262   }
263   for (Standard_Integer i = 1; i <= thedisps.Length(); i ++) {
264     Handle(TCollection_HAsciiString) root = thedisps.Value(i)->RootName();
265     if (root.IsNull()) continue;
266     if (root->IsSameString(name)) return i;
267   }
268   return 0;
269 }
270
271
272     void  IFSelect_ShareOut::SetPrefix
273   (const Handle(TCollection_HAsciiString)& pref)
274       {  thepref = pref;  thenbdefs = 0;  }
275
276     Standard_Boolean  IFSelect_ShareOut::SetDefaultRootName
277   (const Handle(TCollection_HAsciiString)& defrt)
278 {
279   if (RootNumber(defrt) != 0) return Standard_False;
280   if (thedefrt.IsNull() || !thedefrt->IsSameString(defrt)) thenbdefs = 0;
281   thedefrt = defrt;
282   return Standard_True;
283 }
284
285     void  IFSelect_ShareOut::SetExtension
286   (const Handle(TCollection_HAsciiString)& ext)
287       {  theext = ext;  thenbdefs = 0;  }
288
289     Handle(TCollection_HAsciiString)  IFSelect_ShareOut::Prefix () const 
290 {
291   if (thepref.IsNull()) return new TCollection_HAsciiString("");
292   return thepref;
293 }
294
295     Handle(TCollection_HAsciiString)  IFSelect_ShareOut::DefaultRootName () const
296 {
297   if (thedefrt.IsNull()) return new TCollection_HAsciiString("");
298   return thedefrt;
299 }
300
301     Handle(TCollection_HAsciiString)  IFSelect_ShareOut::Extension () const 
302 {
303   if (theext.IsNull()) return new TCollection_HAsciiString("");
304   return theext;
305 }
306
307
308     TCollection_AsciiString  IFSelect_ShareOut::FileName
309   (const Standard_Integer dnum, const Standard_Integer pnum,
310    const Standard_Integer nbpack)
311 {
312   Handle(TCollection_HAsciiString) rot = RootName(dnum);
313   Standard_Integer num  = pnum;
314   Standard_Integer npac = nbpack;
315   Standard_Boolean sufnum = (npac > 1 || num > 1);
316   if (rot.IsNull()) {
317     rot = thedefrt;
318     thenbdefs ++;  num = thenbdefs;
319     npac = 0;
320     sufnum = Standard_True; // numeroter sur noms par defaut, des le 1er sans 0
321   }
322
323   TCollection_AsciiString res;
324   if (!thepref.IsNull()) res.AssignCat (thepref->ToCString());
325   if (!rot.IsNull())     res.AssignCat (rot->ToCString());
326
327 //  Suffixe numerique
328   if (sufnum) {    // sinon, pas de suffixe numerique
329 //  Nom du PacketSuffix : _ suivi du numero <num>
330 //  Si nbpack non nul, alors on a un majorant et on peut preceder de zeros
331 //  Ex.: nbpack = 50 (donc 2 chiffres), num = 3, cela donnera _03
332 //  idnum pas utilise : cette methode peut etre redefinie et utiliser idnum ...
333 //  Si nbpack = 0 ou 1, num = 1 pas de suffixe, sinon suffixe "_num" tel quel
334 //  MODIF du 3-NOV-1995 -> pour eviter toute confusion, num = 1 donne aussi _1
335     Standard_Integer nbch = 0;
336     char format[10],suffixe[30];  format[1] = ' ';
337     if (npac >= num) {
338       Standard_Integer nbpa = 1;
339       while (nbpa <= npac)  {  nbpa *= 10; nbch ++;  }
340     }
341     if (nbch > 1) {
342       sprintf(format,"_ %d.%dd",nbch,nbch);
343       format[1] = '%';
344     } else if (npac >= num || num >= 1) {
345       sprintf(format,"_ d");
346       format[1] = '%';
347     }
348     if (format[1] == '%') {
349       sprintf (suffixe,format,num);
350       res.AssignCat (suffixe);
351     }
352   }
353
354   if (!theext.IsNull())  res.AssignCat (theext->ToCString());
355   return res;
356 }