0031939: Coding - correction of spelling errors in comments [part 3]
[occt.git] / src / Units / Units_UnitsDictionary.cxx
1 // Created on: 1992-06-24
2 // Created by: Gilles DEBARBOUILLE
3 // Copyright (c) 1992-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 #include <Units_UnitsDictionary.hxx>
18
19 #include <OSD.hxx>
20 #include <OSD_OpenFile.hxx>
21 #include <Standard_Stream.hxx>
22 #include <Standard_Type.hxx>
23 #include <TCollection_AsciiString.hxx>
24 #include <TCollection_HAsciiString.hxx>
25 #include <TColStd_HSequenceOfHAsciiString.hxx>
26 #include <Units.hxx>
27 #include <Units_Dimensions.hxx>
28 #include <Units_MathSentence.hxx>
29 #include <Units_Operators.hxx>
30 #include <Units_QuantitiesSequence.hxx>
31 #include <Units_Quantity.hxx>
32 #include <Units_ShiftedUnit.hxx>
33 #include <Units_Token.hxx>
34 #include <Units_TokensSequence.hxx>
35 #include <Units_Unit.hxx>
36 #include <Units_UnitSentence.hxx>
37 #include <Units_UnitsLexicon.hxx>
38 #include <Units_UnitsSequence.hxx>
39
40 #include "../UnitsAPI/UnitsAPI_Units_dat.pxx"
41
42 #include <stdio.h>
43
44 IMPLEMENT_STANDARD_RTTIEXT(Units_UnitsDictionary,Standard_Transient)
45
46 //=======================================================================
47 //function : Units_UnitsDictionary
48 //purpose  : 
49 //=======================================================================
50 Units_UnitsDictionary::Units_UnitsDictionary()
51 { }
52
53 //=======================================================================
54 //function : Creates
55 //purpose  : 
56 //=======================================================================
57
58 namespace
59 {
60
61   //! Auxiliary method removing trailing spaces.
62   static bool strrightadjust (char *str)
63   {
64     for (size_t len = strlen(str); len > 0 && IsSpace (str[len-1]); len--)
65     {
66       str[len-1] = '\0';
67     }
68     return str[0] != '\0';
69   }
70
71   //! Auxiliary method for iterating string line-by-line.
72   static const char* readLine (TCollection_AsciiString& theLine,
73                                const char* theString)
74   {
75     theLine.Clear();
76     if (theString == NULL)
77     {
78       return NULL;
79     }
80
81     for (const char* aCharIter = theString;; ++aCharIter)
82     {
83       if (*aCharIter == '\0')
84       {
85         return NULL;
86       }
87
88       if (*aCharIter == '\n')
89       {
90         const Standard_Integer aLineLen = Standard_Integer(aCharIter - theString);
91         if (aLineLen != 0)
92         {
93           theLine = TCollection_AsciiString (theString, aLineLen);
94         }
95         return aCharIter + 1;
96       }
97     }
98   }
99
100 }
101
102 void Units_UnitsDictionary::Creates()
103 {
104   Standard_Boolean ismove;
105   Standard_Integer i, j, k, charnumber, unitscomputed;
106   Standard_Real matrix[50][50], coeff=0, move=0;
107   Handle(Units_Token) token;
108   Handle(Units_UnitsSequence) theunitssequence;
109   Handle(Units_Unit) unit;
110   Handle(Units_ShiftedUnit) shiftedunit;
111   Handle(Units_Quantity) quantity;
112
113   thequantitiessequence = new Units_QuantitiesSequence();
114
115   // read file line by line
116   Standard_Integer numberofunits = 0;
117   TCollection_AsciiString aLine;
118   for (const char* aLineIter = readLine (aLine, UnitsAPI_Units_dat); aLineIter != NULL; aLineIter = readLine (aLine, aLineIter))
119   {
120     // trim trailing spaces
121     aLine.RightAdjust();
122     if (aLine.IsEmpty())
123     {
124       continue;
125     }
126
127     // lines starting with dot separate sections of the file
128     if (aLine.Value (1) == '.')
129     {
130       // if some units are collected in previous section, store them
131       if(numberofunits) {
132         unitscomputed = 0;
133         for(i=0; i<=numberofunits; i++)
134           matrix[i][i] = 1.;
135         for(i=0; i<=numberofunits; i++) {
136           if(matrix[i][0])
137             unitscomputed++;
138         }
139         while(unitscomputed != numberofunits+1) {
140           for(j=1; j<=numberofunits; j++) {
141             if(!matrix[j][0]) {
142               for(i=1; i<j; i++) {
143                 if(matrix[j][i] && matrix[i][0]) {
144                   matrix[j][0] = matrix[i][0]*matrix[j][i];
145                   unitscomputed++;
146                   if(unitscomputed == numberofunits+1)
147                     break;
148                 }
149               }
150               for(k=j+1; k<=numberofunits; k++) {
151                 if(matrix[k][j] && matrix[k][0]) {
152                   matrix[j][0] = matrix[k][0]/matrix[k][j];
153                   unitscomputed++;
154                   if(unitscomputed == numberofunits+1)
155                     break;
156                 }
157               }
158             }
159             if(unitscomputed == numberofunits+1)
160               break;
161           }
162         }
163         for(i=1;i<=theunitssequence->Length();i++) {
164           unit = theunitssequence->Value(i);
165           unit->Value(matrix[i][0]);
166         }
167       }
168           
169       // skip help string and read header
170       aLineIter = readLine (aLine, aLineIter);
171       aLineIter = readLine (aLine, aLineIter);
172
173       // header consists of dimension name (40 symbols) and factors
174       // for basic SI dimensions (mass, length, time, ...)
175       char name[41];
176       char MM[11], LL[11], TT[11], II[11], tt[11], NN[11], JJ[11], PP[11], SS[11];
177       memset(name,0x00,sizeof(name));
178       memset(MM,0x00,sizeof(MM));
179       memset(LL,0x00,sizeof(LL));
180       memset(TT,0x00,sizeof(TT));
181       memset(II,0x00,sizeof(II));
182       memset(tt,0x00,sizeof(tt));
183       memset(NN,0x00,sizeof(NN));
184       memset(JJ,0x00,sizeof(JJ));
185       memset(PP,0x00,sizeof(PP));
186       memset(SS,0x00,sizeof(SS));
187
188       sscanf (aLine.ToCString(), "%40c%10c%10c%10c%10c%10c%10c%10c%10c%10c",
189                     name, MM, LL, TT, II, tt, NN, JJ, PP, SS);
190       strrightadjust (name);
191
192       Standard_Real M=0., L=0., T=0., I=0., t=0., N=0., J=0., P=0., S=0.;
193       OSD::CStringToReal(MM, M);
194       OSD::CStringToReal(LL, L);
195       OSD::CStringToReal(TT, T);
196       OSD::CStringToReal(II, I);
197       OSD::CStringToReal(tt, t);
198       OSD::CStringToReal(NN, N);
199       OSD::CStringToReal(JJ, J);
200       OSD::CStringToReal(PP, P);
201       OSD::CStringToReal(SS, S);
202
203       Handle(Units_Dimensions) dimensions = 
204         new Units_Dimensions (M, L, T, I, t, N, J, P, S);
205
206       numberofunits = 0;
207       theunitssequence = new Units_UnitsSequence();
208       quantity = new Units_Quantity(name,dimensions,theunitssequence);
209       thequantitiessequence->Append(quantity);
210
211       // clean matrix of units
212       for(i=0; i<50; i++) {
213         for(j=0; j<50; j++)
214           matrix[i][j] = 0.;
215       }
216
217       // skip next line (dotted)
218       aLineIter = readLine (aLine, aLineIter);
219     }
220     else
221     {
222       // normal line defining a unit should contain:
223       // - unit name (51 symbol)
224       // - unit notation (27 symbols)
225       // - factor (27 symbols)
226       // - base unit (27 symbols)
227       char unite[52], symbol[28], convert[28], unit2[28];
228       memset(unite,  0x00,sizeof(unite));
229       memset(symbol, 0x00,sizeof(symbol));
230       memset(convert,0x00,sizeof(convert));
231       memset(unit2,  0x00,sizeof(unit2));
232
233       sscanf (aLine.ToCString(), "%51c%27c%27c%27c", unite, symbol, convert, unit2);
234
235       strrightadjust (unite);
236       strrightadjust (symbol);
237       strrightadjust (convert);
238       strrightadjust (unit2);
239       if (! unite[0] && ! symbol[0] && ! convert[0] && ! unit2[0])
240         continue; // empty line
241           
242       if(convert[0] == '[') {
243         coeff = 1.;
244         i = (Standard_Integer) strlen(convert);
245         convert[i-1] = 0;
246         ismove = Standard_True;
247         charnumber = 1;
248         if(unite[0]) {
249           numberofunits++;
250           shiftedunit = new Units_ShiftedUnit(unite);
251           shiftedunit->Quantity(quantity);
252           theunitssequence->Append(shiftedunit);
253         }
254       }
255       else {
256         ismove = Standard_False;
257         charnumber = 0;
258         if(unite[0]) {
259           numberofunits++;
260           unit = new Units_Unit(unite);
261           unit->Quantity(quantity);
262           theunitssequence->Append(unit);
263         }
264       }
265       
266       if(symbol[0]) {
267         Units::LexiconUnits(Standard_False)->AddToken(symbol,"U",0.);
268         Standard_Integer last = theunitssequence->Length();
269         theunitssequence->Value(last)->Symbol(symbol);
270       }
271           
272       if(convert[charnumber] == '(') {
273         i = (Standard_Integer) strlen(convert);
274         convert[i-1] = 0;
275         Units_MathSentence mathsentence(&convert[charnumber+1]);
276         if(ismove)
277           move  = (mathsentence.Evaluate())->Value();
278         else
279           coeff = (mathsentence.Evaluate())->Value();
280       }
281       else if(convert[0]) {
282         if(ismove) {
283           OSD::CStringToReal(&convert[charnumber], move);
284         }
285         else
286           OSD::CStringToReal(convert, coeff);
287       }
288       else {
289         coeff = 1.;
290       }
291
292       if(ismove) {
293         if(move) {
294           Standard_Integer last = theunitssequence->Length();
295           unit = theunitssequence->Value(last);
296           shiftedunit = Handle(Units_ShiftedUnit)::DownCast (unit);
297           shiftedunit->Move(move);
298         }
299       }
300
301       if(unit2[0]) {
302         j = 0;
303         for(j=1;j<=theunitssequence->Length();j++)
304           if(theunitssequence->Value(j) == unit2)break;
305
306         if(j < numberofunits) {
307           matrix[numberofunits][j] = coeff;
308         }
309         else {
310           Units_UnitSentence unitsentence(unit2,thequantitiessequence);
311           matrix[numberofunits][0] = coeff*(unitsentence.Evaluate())->Value();
312         }
313       }
314       else {
315         if(numberofunits == 1) {
316           matrix[1][0] = coeff;
317           unit = theunitssequence->Value(numberofunits);
318           unit->Value(coeff);
319         }
320       }
321     }
322   }
323 }
324
325
326 //=======================================================================
327 //function : ActiveUnit
328 //purpose  : 
329 //=======================================================================
330
331 TCollection_AsciiString Units_UnitsDictionary::ActiveUnit(const Standard_CString aquantity) const
332 {
333   Standard_Integer index1;
334   Handle(Units_Unit) unit;
335   Handle(Units_UnitsSequence) unitssequence;
336   Handle(Units_Quantity) quantity;
337
338   for(index1=1;index1<=thequantitiessequence->Length();index1++) {
339     quantity = thequantitiessequence->Value(index1);
340     if(quantity == aquantity) {
341       unitssequence = quantity->Sequence();
342       if(unitssequence->Length())
343         return unitssequence->Value(1)->SymbolsSequence()->Value(1)->String();
344       else {
345 #ifdef OCCT_DEBUG
346         std::cout<<" Pas d'unite active pour "<<aquantity<<std::endl;
347 #endif
348         return "";
349       }
350     }
351   }
352
353   std::cout<<" La grandeur physique "<<aquantity<<" n'existe pas."<<std::endl;
354   return "";
355 }