0030895: Coding Rules - specify std namespace explicitly for std::cout and streams
[occt.git] / src / Units / Units_UnitsSystem.cxx
1 // Created on: 1993-10-22
2 // Created by: Gilles DEBARBOUILLE
3 // Copyright (c) 1993-1999 Matra Datavision
4 // Copyright (c) 1999-2014 OPEN CASCADE SAS
5 //
6 // This file is part of Open CASCADE Technology software library.
7 //
8 // This library is free software; you can redistribute it and/or modify it under
9 // the terms of the GNU Lesser General Public License version 2.1 as published
10 // by the Free Software Foundation, with special exception defined in the file
11 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
12 // distribution for complete text of the license and disclaimer of any warranty.
13 //
14 // Alternatively, this file may be used under the terms of Open CASCADE
15 // commercial license or contractual agreement.
16
17 //              Convertir correctement les unites translatees
18
19 #include <Resource_Manager.hxx>
20 #include <Standard_Type.hxx>
21 #include <TCollection_AsciiString.hxx>
22 #include <TColStd_HSequenceOfHAsciiString.hxx>
23 #include <Units.hxx>
24 #include <Units_Explorer.hxx>
25 #include <Units_NoSuchType.hxx>
26 #include <Units_NoSuchUnit.hxx>
27 #include <Units_Operators.hxx>
28 #include <Units_QuantitiesSequence.hxx>
29 #include <Units_Quantity.hxx>
30 #include <Units_ShiftedToken.hxx>
31 #include <Units_ShiftedUnit.hxx>
32 #include <Units_Token.hxx>
33 #include <Units_Unit.hxx>
34 #include <Units_UnitsDictionary.hxx>
35 #include <Units_UnitSentence.hxx>
36 #include <Units_UnitsSequence.hxx>
37 #include <Units_UnitsSystem.hxx>
38
39 IMPLEMENT_STANDARD_RTTIEXT(Units_UnitsSystem,Standard_Transient)
40
41 //=======================================================================
42 //function : Units_UnitsSystem
43 //purpose  : 
44 //=======================================================================
45 Units_UnitsSystem::Units_UnitsSystem()
46 {
47   thequantitiessequence = new Units_QuantitiesSequence();
48   theactiveunitssequence = new TColStd_HSequenceOfInteger;
49 }
50
51
52 //=======================================================================
53 //function : Units_UnitsSystem
54 //purpose  : 
55 //=======================================================================
56
57 Units_UnitsSystem::Units_UnitsSystem(const Standard_CString aName,
58                                      const Standard_Boolean Verbose)
59 {
60   Handle(Resource_Manager) themanager = new Resource_Manager(aName,Verbose);
61
62   thequantitiessequence = new Units_QuantitiesSequence();
63   theactiveunitssequence = new TColStd_HSequenceOfInteger;
64 }
65
66
67 //=======================================================================
68 //function : QuantitiesSequence
69 //purpose  : 
70 //=======================================================================
71
72 Handle(Units_QuantitiesSequence) Units_UnitsSystem::QuantitiesSequence() const
73 {
74   return thequantitiessequence;
75 }
76
77
78 //=======================================================================
79 //function : ActiveUnitsSequence
80 //purpose  : 
81 //=======================================================================
82
83 Handle(TColStd_HSequenceOfInteger) Units_UnitsSystem::ActiveUnitsSequence() const
84 {
85   return theactiveunitssequence;
86 }
87
88
89 //=======================================================================
90 //function : Specify
91 //purpose  : 
92 //=======================================================================
93
94 void Units_UnitsSystem::Specify(const Standard_CString aquantity,const Standard_CString aunit)
95 {
96   Standard_Integer index;
97   Handle(Units_Unit) unit;
98   Handle(Units_UnitsSequence) unitssequence;
99   Handle(Units_Quantity) quantity;
100   Handle(Units_Quantity) thequantity;
101   Handle(Units_QuantitiesSequence) quantitiessequence;
102   TCollection_AsciiString quantityname;
103
104   Units_UnitSentence unitsentence(aunit);
105   if(!unitsentence.IsDone()) {
106     std::cout<<"Units_UnitsSystem::Specify : incorrect unit"<<std::endl;
107     return;
108   }
109   Handle(Units_Token) token = unitsentence.Evaluate();
110
111   if( token->IsKind(STANDARD_TYPE(Units_ShiftedToken)) ) {
112     Handle(Units_ShiftedToken) stoken =
113         Handle(Units_ShiftedToken)::DownCast(token) ;
114     Handle(Units_ShiftedUnit) sunit;
115     unit = sunit = new Units_ShiftedUnit(aunit,aunit);
116     sunit->Value(stoken->Value());
117     sunit->Move(stoken->Move());
118   } else {
119     unit = new Units_Unit(aunit,aunit);
120     unit->Value(token->Value());
121   }
122
123   for(index=1;index<=thequantitiessequence->Length();index++) {
124     quantity = thequantitiessequence->Value(index);
125     if(quantity == aquantity) {   
126       unit->Quantity(quantity);
127       quantity->Sequence()->Append(unit);
128       return;
129     }
130   }
131
132   quantity = Units::Quantity(aquantity);
133   
134 //  Units_NoSuchType_Raise_if(quantity.IsNull(),aquantity);
135   if( quantity.IsNull() ) {
136     std::cout<<"Warning: in Units_UnitsSystem : Units_NoSuchType '" << aquantity << "'" << std::endl;
137     return;
138   }
139   
140   unitssequence = new Units_UnitsSequence();
141   quantityname = quantity->Name();
142   thequantity = new Units_Quantity(quantityname.ToCString(),quantity->Dimensions(),unitssequence);
143   unit->Quantity(thequantity);
144   thequantitiessequence->Append(thequantity);
145   theactiveunitssequence->Append(0);
146   thequantity->Sequence()->Append(unit);
147 }
148
149
150 //=======================================================================
151 //function : Remove
152 //purpose  : 
153 //=======================================================================
154
155 void Units_UnitsSystem::Remove(const Standard_CString aquantity,
156                                const Standard_CString aunit)
157 {
158   Standard_Integer index1,index2;
159   Handle(Units_Unit) unit;
160   Handle(Units_UnitsSequence) unitssequence;
161   Handle(Units_Quantity) quantity;
162
163   for(index1=1;index1<=thequantitiessequence->Length();index1++) {
164
165     quantity = thequantitiessequence->Value(index1);
166     if(quantity == aquantity) {
167
168       unitssequence = quantity->Sequence();
169       for(index2=1;index2<=unitssequence->Length();index2++) {
170
171         unit = unitssequence->Value(index2);
172         if(unit == aunit) {
173           unitssequence->Remove(index2);
174             
175           if(unitssequence->Length() == 0) {
176             thequantitiessequence->Remove(index1);
177             theactiveunitssequence->Remove(index1);
178           }
179           else {
180             if(theactiveunitssequence->Value(index1) == index2)
181               theactiveunitssequence->SetValue(index1,0);
182             else if(theactiveunitssequence->Value(index1) > index2)
183               theactiveunitssequence->SetValue(index1,theactiveunitssequence->Value(index1)-1);
184             return;
185           }
186         }
187       }
188       
189       throw Units_NoSuchUnit(aunit);
190       
191     }
192   }
193   
194   throw Units_NoSuchType(aquantity);
195 }
196
197
198 //=======================================================================
199 //function : Activate
200 //purpose  : 
201 //=======================================================================
202
203 void Units_UnitsSystem::Activate(const Standard_CString aquantity,
204                                  const Standard_CString aunit)
205 {
206   Standard_Integer index1,index2;
207   Handle(Units_Unit) unit;
208   Handle(Units_UnitsSequence) unitssequence;
209   Handle(Units_Quantity) quantity;
210
211   for(index1=1;index1<=thequantitiessequence->Length();index1++) {
212     quantity = thequantitiessequence->Value(index1);
213     if(quantity == aquantity)   {
214       unitssequence = quantity->Sequence();
215       for(index2=1;index2<=thequantitiessequence->Length();index2++) {
216         unit = unitssequence->Value(index2);
217         if(unit == aunit) {
218           theactiveunitssequence->SetValue(index1,index2);
219           return;
220         }
221       }
222       throw Units_NoSuchUnit(aunit);
223     }
224   }
225
226   throw Units_NoSuchType(aquantity);
227 }
228
229
230 //=======================================================================
231 //function : Activates
232 //purpose  : 
233 //=======================================================================
234
235 void Units_UnitsSystem::Activates()
236 {
237   Standard_Integer index;
238   Handle(Units_UnitsSequence) unitssequence;
239   Handle(Units_Quantity) quantity;
240
241   for(index=1;index<=thequantitiessequence->Length();index++) {
242     quantity = thequantitiessequence->Value(index);
243     unitssequence = quantity->Sequence();
244     if( unitssequence->Length() > 0 ) {
245       theactiveunitssequence->SetValue(index,1);
246     }
247   }
248 }
249
250
251 //=======================================================================
252 //function : ActiveUnit
253 //purpose  : 
254 //=======================================================================
255
256 TCollection_AsciiString Units_UnitsSystem::ActiveUnit(const Standard_CString aquantity) const
257 {
258   Standard_Integer index1,index2;
259   Handle(Units_Unit) unit;
260   Handle(Units_UnitsSequence) unitssequence;
261   Handle(Units_Quantity) quantity;
262
263   for(index1=1;index1<=thequantitiessequence->Length();index1++) {
264     quantity = thequantitiessequence->Value(index1);
265     if(quantity == aquantity) {
266       unitssequence = quantity->Sequence();
267       index2 = theactiveunitssequence->Value(index1);
268       if(index2)
269         return unitssequence->Value(index2)->SymbolsSequence()->Value(1)->String();
270       else {
271 #ifdef OCCT_DEBUG
272         std::cout<<" Pas d'unite active pour "<<aquantity<<std::endl;
273 #endif
274         return TCollection_AsciiString() ;
275       }
276     }
277   }
278
279   throw Units_NoSuchType(aquantity);
280 }
281
282
283 //=======================================================================
284 //function : ConvertValueToUserSystem
285 //purpose  : 
286 //=======================================================================
287
288 Standard_Real Units_UnitsSystem::ConvertValueToUserSystem
289   (const Standard_CString aquantity,
290    const Standard_Real avalue,
291    const Standard_CString aunit) const
292 {
293   Units_UnitSentence unitsentence(aunit);
294   if(!unitsentence.IsDone()) {
295     std::cout<<"Units_UnitsSystem::ConvertValueToUserSystem : incorrect unit => return 0"<<std::endl;
296     return 0.;
297   }
298   return ConvertSIValueToUserSystem(aquantity,avalue*(unitsentence.Evaluate())->Value());
299 }
300
301
302 //=======================================================================
303 //function : ConvertSIValueToUserSystem
304 //purpose  : 
305 //=======================================================================
306
307 Standard_Real Units_UnitsSystem::ConvertSIValueToUserSystem
308   (const Standard_CString aquantity,const Standard_Real avalue) const
309 {
310   Standard_Integer index,activeunit;
311   Handle(Units_UnitsSequence) unitssequence;
312   Handle(Units_Quantity) quantity;
313   Handle(Units_QuantitiesSequence) quantitiessequence;
314   Handle(Units_Unit) unit;
315   Handle(Units_ShiftedUnit) sunit;
316   Standard_Real uvalue,umove;
317
318   for(index=1;index<=thequantitiessequence->Length();index++) {
319     quantity = thequantitiessequence->Value(index);
320     if(quantity == aquantity) {
321       activeunit = theactiveunitssequence->Value(index);
322       if(activeunit) {
323         unitssequence = quantity->Sequence();
324         unit = unitssequence->Value(activeunit);
325         if( unit->IsKind(STANDARD_TYPE(Units_ShiftedUnit)) ) {
326           sunit = Handle(Units_ShiftedUnit)::DownCast(unit) ;
327           uvalue = sunit->Value();
328           umove = sunit->Move();
329           return avalue/uvalue - umove;
330         }
331         else
332         {
333           uvalue = unit->Value();
334           return avalue/uvalue;
335         }
336       }
337       else {
338         return avalue;
339       }
340     }
341   }
342
343   quantity = Units::Quantity(aquantity);
344   
345   Units_NoSuchType_Raise_if(quantity.IsNull(),aquantity);
346
347   return avalue;
348 }
349
350
351 //=======================================================================
352 //function : ConvertUserSystemValueToSI
353 //purpose  : 
354 //=======================================================================
355
356 Standard_Real Units_UnitsSystem::ConvertUserSystemValueToSI
357   (const Standard_CString aquantity,const Standard_Real avalue) const
358 {
359   Standard_Integer index,activeunit;
360   Handle(Units_UnitsSequence) unitssequence;
361   Handle(Units_Quantity) quantity;
362   Handle(Units_QuantitiesSequence) quantitiessequence;
363   Handle(Units_Unit) unit;
364   Handle(Units_ShiftedUnit) sunit;
365   Standard_Real uvalue,umove;
366
367   for(index=1;index<=thequantitiessequence->Length();index++) {
368     quantity = thequantitiessequence->Value(index);
369     if(quantity == aquantity) {
370       activeunit = theactiveunitssequence->Value(index);
371       if(activeunit) {
372         unitssequence = quantity->Sequence();
373         unit = unitssequence->Value(activeunit);
374         if( unit->IsKind(STANDARD_TYPE(Units_ShiftedUnit)) ) {
375           sunit = Handle(Units_ShiftedUnit)::DownCast(unit) ;
376           uvalue = sunit->Value();
377           umove = sunit->Move();
378           return avalue*(uvalue + umove);
379         } else
380         {
381           uvalue = unit->Value();
382           return avalue*uvalue;
383         }
384       }
385       else {
386         return avalue;
387       }
388     }
389   }
390
391   quantity = Units::Quantity(aquantity);
392   
393   Units_NoSuchType_Raise_if(quantity.IsNull(),aquantity);
394
395   return avalue;
396 }
397
398
399 //=======================================================================
400 //function : Dump
401 //purpose  : 
402 //=======================================================================
403
404 void Units_UnitsSystem::Dump() const
405 {
406   Handle(Standard_Transient) transient = This();
407   Handle(Units_UnitsSystem) unitssystem = Handle(Units_UnitsSystem)::DownCast (transient);
408   Units_Explorer explorer(unitssystem);
409   std::cout<<" UNITSSYSTEM : "<<std::endl;
410   for(; explorer.MoreQuantity(); explorer.NextQuantity()) {
411     std::cout<<explorer.Quantity()<<std::endl;
412     for(; explorer.MoreUnit(); explorer.NextUnit())
413       std::cout<<"  "<<explorer.Unit()<<std::endl;
414   }
415 }
416
417
418 //=======================================================================
419 //function : IsEmpty
420 //purpose  : 
421 //=======================================================================
422
423 Standard_Boolean Units_UnitsSystem::IsEmpty() const
424 {
425   return (thequantitiessequence->Length() > 0) ? Standard_False : Standard_True;
426 }