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