0023335: Array overrun is possible. The value of 'i' index could reach 200 in Interfa...
[occt.git] / src / Interface / Interface_MSG.cxx
CommitLineData
b311480e 1// Copyright (c) 1999-2012 OPEN CASCADE SAS
2//
3// The content of this file is subject to the Open CASCADE Technology Public
4// License Version 6.5 (the "License"). You may not use the content of this file
5// except in compliance with the License. Please obtain a copy of the License
6// at http://www.opencascade.org and read it completely before using this file.
7//
8// The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
9// main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
10//
11// The Original Code and all software distributed under the License is
12// distributed on an "AS IS" basis, without warranty of any kind, and the
13// Initial Developer hereby disclaims all such warranties, including without
14// limitation, any warranties of merchantability, fitness for a particular
15// purpose or non-infringement. Please see the License for the specific terms
16// and conditions governing the rights and limitations under the License.
17
7fd59977 18
19#include <Standard_Stream.hxx>
20
21
22#include <Interface_MSG.ixx>
23#include <TCollection_HAsciiString.hxx>
24#include <Dico_DictionaryOfTransient.hxx>
25#include <Dico_DictionaryOfInteger.hxx>
26#include <Dico_IteratorOfDictionaryOfInteger.hxx>
27#include <Dico_IteratorOfDictionaryOfTransient.hxx>
28#include <TColStd_HSequenceOfHAsciiString.hxx>
29#include <OSD_Process.hxx>
30#include <Quantity_Date.hxx>
31
32#include <Standard_DomainError.hxx>
33#include <stdio.h>
34
35
36static Handle(Dico_DictionaryOfTransient) thedic;
37static Handle(Dico_DictionaryOfInteger) thelist;
38static Handle(TColStd_HSequenceOfHAsciiString) thedup;
39static Standard_Boolean theprint = Standard_True;
40static Standard_Boolean therec = Standard_False;
41static Standard_Boolean therun = Standard_False;
42static Standard_Boolean theraise = Standard_False;
43
44static char blank[] =
45" ";
60be1f9b 46static Standard_Integer maxblank = (Standard_Integer) strlen(blank);
7fd59977 47
48
49Interface_MSG::Interface_MSG (const Standard_CString key)
50 : thekey (key) , theval (NULL)
51{
52
53}
54
55
56Interface_MSG::Interface_MSG
57 (const Standard_CString key, const Standard_Integer i1)
58 : thekey (key) , theval (NULL)
59{
60 char mess[300];
61 sprintf (mess, Interface_MSG::Translated(thekey), i1);
60be1f9b 62 theval = new char[strlen (mess) + 1];
7fd59977 63 strcpy (theval,mess);
64}
65
66
67Interface_MSG::Interface_MSG
68 (const Standard_CString key, const Standard_Integer i1, const Standard_Integer i2)
69 : thekey (key) , theval (NULL)
70{
71 char mess[300];
72 sprintf (mess, Interface_MSG::Translated(thekey), i1,i2);
60be1f9b 73 theval = new char[strlen (mess) + 1];
7fd59977 74 strcpy (theval,mess);
75}
76
77
78Interface_MSG::Interface_MSG
79 (const Standard_CString key, const Standard_Real r1, const Standard_Integer intervals)
80 : thekey (key) , theval (NULL)
81{
82 char mess[300];
83 sprintf (mess, Interface_MSG::Translated(thekey),
84 (intervals < 0 ? r1 : Interface_MSG::Intervalled(r1,intervals)) );
60be1f9b 85 theval = new char[strlen (mess) + 1];
7fd59977 86 strcpy (theval,mess);
87}
88
89
90Interface_MSG::Interface_MSG
91 (const Standard_CString key, const Standard_CString str)
92 : thekey (key) , theval (NULL)
93{
94 char mess[300];
95 sprintf (mess, Interface_MSG::Translated(thekey), str);
60be1f9b 96 theval = new char[strlen (mess) + 1];
7fd59977 97 strcpy (theval,mess);
98}
99
100
101Interface_MSG::Interface_MSG
102 (const Standard_CString key,
103 const Standard_Integer val, const Standard_CString str)
104 : thekey (key) , theval (NULL)
105{
106 char mess[300];
107 sprintf (mess, Interface_MSG::Translated(thekey), val, str);
60be1f9b 108 theval = new char[strlen (mess) + 1];
7fd59977 109 strcpy (theval,mess);
110}
111
112
113Standard_CString Interface_MSG::Value () const
114{ return (theval ? theval : Interface_MSG::Translated(thekey));
115 }
116
117
118void Interface_MSG::Destroy ()
119{
120 if (theval) {
121 delete [] theval;
122 theval = NULL;
123 }
124}
125
126
127Interface_MSG::operator Standard_CString () const
128{
129 return Value();
130}
131
132
133// ########### Lecture Ecriture Fichier ##########
134
135Standard_Integer Interface_MSG::Read (Standard_IStream& S)
136{
137 Standard_Integer i,nb = 0;
138 char buf[200], key[200];
139 buf[0] = '\0';
140 while (S.getline (buf,200)) {
141 if (buf[0] == '@' && buf[1] == '@') continue;
142 if (buf[0] == '\0') continue;
143 if (buf[0] == '@') {
144 nb ++;
db3d2a99 145 for (i = 1; i <= 199; i ++) {
7fd59977 146 key[i-1] = buf[i];
147 if (buf[i] == '\0') break;
148 }
149 }
150 else Record (key,buf);
151 buf[0] = '\0';
152 }
153 return nb;
154}
155
156 Standard_Integer Interface_MSG::Read (const Standard_CString file)
157{
158 ifstream S(file);
159 if (!S) return -1;
160 return Read (S);
161}
162
163 Standard_Integer Interface_MSG::Write
164 (Standard_OStream& S, const Standard_CString rootkey)
165{
166 Standard_Integer nb = 0;
167 if (thedic.IsNull()) return nb;
168 if (rootkey[0] != '\0') S<<"@@ ROOT:"<<rootkey<<endl;
169 Dico_IteratorOfDictionaryOfTransient iter (thedic,rootkey);
170 for (iter.Start(); iter.More(); iter.Next()) {
171 S<<"@"<<iter.Name()<<"\n";
172 Handle(TCollection_HAsciiString) str =
173 Handle(TCollection_HAsciiString)::DownCast(iter.Value());
174 if (str.IsNull()) continue;
175 nb ++;
176 S<<str->ToCString()<<"\n";
177 }
178 S<<flush;
179 return nb;
180}
181
182
183// ########### EXPLOITATION ##########
184
185Standard_Boolean Interface_MSG::IsKey (const Standard_CString key)
186{
187 return (key[0] == '^');
188}
189
190
191Standard_CString Interface_MSG::Translated (const Standard_CString key)
192{
193 if (!therun) return key;
194 if (!thedic.IsNull()) {
195 Handle(TCollection_HAsciiString) str;
196 if (thedic->GetItem(key,str)) return str->ToCString();
197 }
198 if (theprint) cout<<" ** Interface_MSG:Translate ?? "<<key<<" **"<<endl;
199 if (therec) {
200 Standard_Boolean deja;
201 if (thelist.IsNull()) thelist = new Dico_DictionaryOfInteger;
202 Standard_Integer& nb = thelist->NewItem (key,deja);
203 if (!deja) nb = 0; nb ++;
204 }
205 if (theraise) Standard_DomainError::Raise ("Interface_MSG : Translate");
206 return key;
207}
208
209
210void Interface_MSG::Record
211 (const Standard_CString key, const Standard_CString item)
212{
213 if (thedic.IsNull()) thedic = new Dico_DictionaryOfTransient;
214 Standard_Boolean deja;
215 Handle(TCollection_HAsciiString) dup;
216 Handle(Standard_Transient)& res = thedic->NewItem (key,deja);
217 Handle(TCollection_HAsciiString) str = new TCollection_HAsciiString (item);
218 res = str;
219 if (!deja) return;
220 if (theprint) cout<<" ** Interface_MSG:Record ?? "<<key<<" ** "<<item<<" **"<<endl;
221 if (therec) {
222 if (thedup.IsNull()) thedup = new TColStd_HSequenceOfHAsciiString();
223 dup = new TCollection_HAsciiString(key);
224 thedup->Append(dup);
225 dup = new TCollection_HAsciiString(item);
226 thedup->Append(dup);
227 }
228 if (theraise) Standard_DomainError::Raise ("Interface_MSG : Record");
229}
230
231
232void Interface_MSG::SetTrace
233 (const Standard_Boolean toprint, const Standard_Boolean torecord)
234{
235 theprint = toprint;
236 therec = torecord;
237}
238
239
240void Interface_MSG::SetMode (const Standard_Boolean running,
241 const Standard_Boolean raising)
242{
243 therun = running; theraise = raising;
244}
245
246
247void Interface_MSG::PrintTrace (Standard_OStream& S)
248{
249 Handle(TCollection_HAsciiString) dup;
250 Standard_Integer i, nb = 0;
251 if (!thedup.IsNull()) nb = thedup->Length()/2;
252 for (i = 1; i <= nb; i ++) {
253 dup = thedup->Value(2*i-1);
254 S<<"** DUP:"<<dup->ToCString();
255 dup = thedup->Value(2*i);
256 S<<" ** "<<dup->ToCString()<<endl;
257 }
258
259 if (thelist.IsNull()) return;
260 Dico_IteratorOfDictionaryOfInteger iter (thelist);
261 for (iter.Start(); iter.More(); iter.Next()) {
262 S<<"** MSG(NB="<<iter.Value()<<"): "<<iter.Name()<<endl;
263 }
264}
265
266
267// ########### ARRONDIS DE FLOTTANTS ############
268
269Standard_Real Interface_MSG::Intervalled
270 (const Standard_Real val,
271 const Standard_Integer order, const Standard_Boolean upper)
272{
273 Standard_Real vl = (val > 0. ? val : -val);
274 Standard_Real bl = 1., bu = 1.;
275 if (vl >= 1.) {
276 bu = 10.;
277 for (Standard_Integer i = 0; i < 200; i ++) {
278 if (vl < bu) break;
279 bl = bu; bu *= 10.;
280 }
281 } else {
282 bl = 0.1;
283 for (Standard_Integer i = 0; i < 200; i ++) {
284 if (vl >= bl) break;
285 bu = bl; bl /= 10.;
286 }
287 if (vl == 0.) return 0.;
288 }
289
290 Standard_Real rst = vl/bl;
291 if (order <= 1) rst = (upper ? 10. : 1.);
292 else if (order == 2) {
293 if (rst <= 3.) rst = (upper ? 3. : 1.);
294 else rst = (upper ? 10. : 3.);
295 } else if (order == 3) {
296 if (rst <= 2.) rst = (upper ? 2. : 1.);
297 else if (rst <= 5.) rst = (upper ? 5. : 2.);
298 else rst = (upper ? 10. : 5.);
299 } else if (order == 4) {
300 if (rst <= 2.) rst = (upper ? 2. : 1.);
301 else if (rst <= 3.) rst = (upper ? 3. : 2.);
302 else if (rst <= 6.) rst = (upper ? 6. : 3.);
303 else rst = (upper ? 10. : 6.);
304 }
305 else if (order <= 6) {
306 if (rst <= 1.5) rst = (upper ? 1.5 : 1. );
307 else if (rst <= 2. ) rst = (upper ? 2. : 1.5);
308 else if (rst <= 3. ) rst = (upper ? 3. : 2. );
309 else if (rst <= 5. ) rst = (upper ? 5. : 3. );
310 else if (rst <= 7. ) rst = (upper ? 7. : 5. );
311 else rst = (upper ? 10. : 7. );
312 }
313 else { // n a de sens que jusqu a 10 ...
314 if (rst <= 1.2) rst = (upper ? 1.2 : 1. );
315 else if (rst <= 1.5) rst = (upper ? 1.5 : 1.2);
316 else if (rst <= 2. ) rst = (upper ? 2. : 1.5);
317 else if (rst <= 2.5) rst = (upper ? 2.5 : 2. );
318 else if (rst <= 3. ) rst = (upper ? 3. : 2.5);
319 else if (rst <= 4. ) rst = (upper ? 4. : 3. );
320 else if (rst <= 5. ) rst = (upper ? 5. : 4. );
321 else if (rst <= 6. ) rst = (upper ? 6. : 5. );
322 else if (rst <= 8. ) rst = (upper ? 8. : 6. );
323 else rst = (upper ? 10. : 8. );
324 }
325 return ((val < 0.) ? -(bl*rst) : (bl*rst) );
326}
327
328
329// ########### DATES ############
330
331void Interface_MSG::TDate (const Standard_CString text,
332 const Standard_Integer yy,
333 const Standard_Integer mm,
334 const Standard_Integer dd,
335 const Standard_Integer hh,
336 const Standard_Integer mn,
337 const Standard_Integer ss,
338 const Standard_CString format)
339{
340// valeurs nulles : en tete (avec au moins une non nulle, la derniere)
341// -> completees avec les valeurs actuelle (system date)
342// tout nul on laisse
343
344 //svv #2 Standard_Integer y1 , m1 , d1 , h1 , n1 , s1;
345 Standard_Integer y2 = yy, m2 = mm, d2 = dd, h2 = hh, n2 = mn, s2 = ss;
346 if (yy == 0 && ss != 0) {
347// completion
348 OSD_Process pourdate;
349 Quantity_Date ladate = pourdate.SystemDate ();
350 if ( yy == 0) {
351 y2 = ladate.Year();
352 if ( mm == 0) {
353 m2 = ladate.Month();
354 if (dd == 0) {
355 d2 = ladate.Day();
356 if (hh == 0) {
357 h2 = ladate.Hour();
358 if (mn == 0) {
359 n2 = ladate.Minute();
360 s2 = ladate.Second();
361 }
362 }
363 }
364 }
365 }
366 }
367 char *pText=(char *)text;
368 if (!format || format[0] == '\0')
369 sprintf(pText,"%4.4d-%2.2d-%2.2d:%2.2d-%2.2d-%2.2d",y2,m2,d2,h2,n2,s2);
370 else if ((format[0] == 'c' || format[0] == 'C') && format[1] == ':')
371 sprintf (pText,&format[2],y2,m2,d2,h2,n2,s2);
372}
373
374
375Standard_Boolean Interface_MSG::NDate (const Standard_CString text,
376 Standard_Integer& yy,
377 Standard_Integer& mm,
378 Standard_Integer& dd,
379 Standard_Integer& hh,
380 Standard_Integer& mn,
381 Standard_Integer& ss)
382{
383 Standard_Integer i ,num = 1;
384 for (i = 0; text[i] != '\0'; i ++) {
385 char val = text[i];
386 if (val >= 48 && val <= 57) {
387 if ( (num & 1) == 0) num ++;
388 if (num == 1) yy = yy*10 + (val-48);
389 if (num == 3) mm = mm*10 + (val-48);
390 if (num == 5) dd = dd*10 + (val-48);
391 if (num == 7) hh = hh*10 + (val-48);
392 if (num == 9) mn = mn*10 + (val-48);
393 if (num == 11) ss = ss*10 + (val-48);
394 }
395 else if ( (num & 1) != 0) num ++;
396 }
397 return (num > 0);
398}
399
400
401Standard_Integer Interface_MSG::CDate (const Standard_CString text1,
402 const Standard_CString text2)
403{
404 Standard_Integer i1=0,i2=0,i3=0,i4=0,i5=0,i6=0,j1=0,j2=0,j3=0,j4=0,j5=0,j6=0;
405 if (!NDate (text1,i1,i2,i3,i4,i5,i6)) return 0;
406 if (!NDate (text2,j1,j2,j3,j4,j5,j6)) return 0;
407 if (i1 < j1) return -1;
408 if (i1 > j1) return 1;
409 if (i2 < j2) return -1;
410 if (i2 > j2) return 1;
411 if (i3 < j3) return -1;
412 if (i3 > j3) return 1;
413 if (i4 < j4) return -1;
414 if (i4 > j4) return 1;
415 if (i5 < j5) return -1;
416 if (i5 > j5) return 1;
417 if (i6 < j6) return -1;
418 if (i6 > j6) return 1;
419 return 0;
420}
421
422
423Standard_CString Interface_MSG::Blanks (const Standard_Integer val,
424 const Standard_Integer max)
425{
426 Standard_Integer count;
427 if (val < 0) return Interface_MSG::Blanks (-val,max-1);
428 if (val < 10) count = 9;
429 else if (val < 100) count = 8;
430 else if (val < 1000) count = 7;
431 else if (val < 10000) count = 6;
432 else if (val < 100000) count = 5;
433 else if (val < 1000000) count = 4;
434 else if (val < 10000000) count = 3;
435 else if (val < 100000000) count = 2;
436 else if (val < 1000000000) count = 1;
437 else count = 0;
438 count = count + max - 10;
439 if (count < 0) count = 0;
440 return &blank [maxblank - count];
441}
442
443
444Standard_CString Interface_MSG::Blanks (const Standard_CString val,
445 const Standard_Integer max)
446{
60be1f9b 447 Standard_Integer lng = (Standard_Integer) strlen(val);
7fd59977 448 if (lng > maxblank || lng > max) return "";
449 return &blank [maxblank - max + lng];
450}
451
452
453Standard_CString Interface_MSG::Blanks
454 (const Standard_Integer count)
455{
456 if (count <= 0) return "";
457 if (count >= maxblank) return blank;
458 return &blank [maxblank-count];
459}
460
461
462void Interface_MSG::Print (Standard_OStream& S, const Standard_CString val,
463 const Standard_Integer max,
464 const Standard_Integer just)
465{
466 if (max > maxblank) { Print(S,val,maxblank,just); return; }
60be1f9b 467 Standard_Integer lng = (Standard_Integer) strlen (val);
7fd59977 468 if (lng > max) { S << val; return; }
469 Standard_Integer m1 = (max-lng) /2;
470 Standard_Integer m2 = max-lng - m1;
471 if (just < 0) S<<val<<&blank[maxblank-m1-m2];
472 else if (just == 0) S<<&blank[maxblank-m1]<<val<<&blank[maxblank-m2];
473 else S<<&blank[maxblank-m1-m2]<<val;
474}