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