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
6 // This file is part of Open CASCADE Technology software library.
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.
14 // Alternatively, this file may be used under the terms of Open CASCADE
15 // commercial license or contractual agreement.
17 #include <Units_UnitsDictionary.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>
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>
40 #include "../UnitsAPI/UnitsAPI_Units_dat.pxx"
44 IMPLEMENT_STANDARD_RTTIEXT(Units_UnitsDictionary,MMgt_TShared)
46 //=======================================================================
47 //function : Units_UnitsDictionary
49 //=======================================================================
50 Units_UnitsDictionary::Units_UnitsDictionary()
53 //=======================================================================
56 //=======================================================================
61 //! Auxiliary method removing trailing spaces.
62 static bool strrightadjust (char *str)
64 for (size_t len = strlen(str); len > 0 && IsSpace (str[len-1]); len--)
68 return str[0] != '\0';
71 //! Auxiliary method for iterating string line-by-line.
72 static const char* readLine (TCollection_AsciiString& theLine,
73 const char* theString)
76 if (theString == NULL)
81 for (const char* aCharIter = theString;; ++aCharIter)
83 if (*aCharIter == '\0')
88 if (*aCharIter == '\n')
90 const Standard_Integer aLineLen = Standard_Integer(aCharIter - theString);
93 theLine = TCollection_AsciiString (theString, aLineLen);
102 void Units_UnitsDictionary::Creates()
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;
113 thequantitiessequence = new Units_QuantitiesSequence();
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))
120 // trim trailing spaces
127 // lines starting with dot separate sections of the file
128 if (aLine.Value (1) == '.')
130 // if some units are collected in previous section, store them
133 for(i=0; i<=numberofunits; i++)
135 for(i=0; i<=numberofunits; i++) {
139 while(unitscomputed != numberofunits+1) {
140 for(j=1; j<=numberofunits; j++) {
143 if(matrix[j][i] && matrix[i][0]) {
144 matrix[j][0] = matrix[i][0]*matrix[j][i];
146 if(unitscomputed == numberofunits+1)
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];
154 if(unitscomputed == numberofunits+1)
159 if(unitscomputed == numberofunits+1)
163 for(i=1;i<=theunitssequence->Length();i++) {
164 unit = theunitssequence->Value(i);
165 unit->Value(matrix[i][0]);
169 // skip help string and read header
170 aLineIter = readLine (aLine, aLineIter);
171 aLineIter = readLine (aLine, aLineIter);
173 // header consists of dimension name (40 symbols) and factors
174 // for basic SI dimensions (mass, length, time, ...)
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));
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);
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);
203 Handle(Units_Dimensions) dimensions =
204 new Units_Dimensions (M, L, T, I, t, N, J, P, S);
207 theunitssequence = new Units_UnitsSequence();
208 quantity = new Units_Quantity(name,dimensions,theunitssequence);
209 thequantitiessequence->Append(quantity);
211 // clean matrix of units
212 for(i=0; i<50; i++) {
217 // skip next line (dotted)
218 aLineIter = readLine (aLine, aLineIter);
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));
233 sscanf (aLine.ToCString(), "%51c%27c%27c%27c", unite, symbol, convert, unit2);
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
242 if(convert[0] == '[') {
244 i = (Standard_Integer) strlen(convert);
246 ismove = Standard_True;
250 shiftedunit = new Units_ShiftedUnit(unite);
251 shiftedunit->Quantity(quantity);
252 theunitssequence->Append(shiftedunit);
256 ismove = Standard_False;
260 unit = new Units_Unit(unite);
261 unit->Quantity(quantity);
262 theunitssequence->Append(unit);
267 Units::LexiconUnits(Standard_False)->AddToken(symbol,"U",0.);
268 Standard_Integer last = theunitssequence->Length();
269 theunitssequence->Value(last)->Symbol(symbol);
272 if(convert[charnumber] == '(') {
273 i = (Standard_Integer) strlen(convert);
275 Units_MathSentence mathsentence(&convert[charnumber+1]);
277 move = (mathsentence.Evaluate())->Value();
279 coeff = (mathsentence.Evaluate())->Value();
281 else if(convert[0]) {
283 OSD::CStringToReal(&convert[charnumber], move);
286 OSD::CStringToReal(convert, coeff);
294 Standard_Integer last = theunitssequence->Length();
295 unit = theunitssequence->Value(last);
296 shiftedunit = Handle(Units_ShiftedUnit)::DownCast (unit);
297 shiftedunit->Move(move);
303 for(j=1;j<=theunitssequence->Length();j++)
304 if(theunitssequence->Value(j) == unit2)break;
306 if(j < numberofunits) {
307 matrix[numberofunits][j] = coeff;
310 Units_UnitSentence unitsentence(unit2,thequantitiessequence);
311 matrix[numberofunits][0] = coeff*(unitsentence.Evaluate())->Value();
315 if(numberofunits == 1) {
316 matrix[1][0] = coeff;
317 unit = theunitssequence->Value(numberofunits);
326 //=======================================================================
327 //function : ActiveUnit
329 //=======================================================================
331 TCollection_AsciiString Units_UnitsDictionary::ActiveUnit(const Standard_CString aquantity) const
333 Standard_Integer index1;
334 Handle(Units_Unit) unit;
335 Handle(Units_UnitsSequence) unitssequence;
336 Handle(Units_Quantity) quantity;
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();
346 cout<<" Pas d'unite active pour "<<aquantity<<endl;
353 cout<<" La grandeur physique "<<aquantity<<" n'existe pas."<<endl;