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