0025748: Parallel version of progress indicator
[occt.git] / src / Message / Message_Msg.cxx
CommitLineData
b311480e 1// Created on: 2001-04-27
2// Created by: OCC Team
973c2be1 3// Copyright (c) 2001-2014 OPEN CASCADE SAS
b311480e 4//
973c2be1 5// This file is part of Open CASCADE Technology software library.
b311480e 6//
d5f74e42 7// This library is free software; you can redistribute it and/or modify it under
8// the terms of the GNU Lesser General Public License version 2.1 as published
973c2be1 9// by the Free Software Foundation, with special exception defined in the file
10// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
11// distribution for complete text of the license and disclaimer of any warranty.
b311480e 12//
973c2be1 13// Alternatively, this file may be used under the terms of Open CASCADE
14// commercial license or contractual agreement.
7fd59977 15
16#include <Message_Msg.hxx>
17#include <Message_MsgFile.hxx>
18#include <TCollection_AsciiString.hxx>
19#include <stdio.h>
b311480e 20
7fd59977 21typedef enum
22{
23 Msg_IntegerType,
24 Msg_RealType,
25 Msg_StringType,
26 Msg_IndefiniteType
27} FormatType;
28
29//=======================================================================
30//function : Message_Msg()
31//purpose : Constructor
32//=======================================================================
33
34Message_Msg::Message_Msg ()
35{}
36
37
38//=======================================================================
39//function : Message_Msg()
40//purpose : Constructor
41//=======================================================================
42
43Message_Msg::Message_Msg (const Message_Msg& theMsg)
44{
45 myMessageBody = theMsg.myMessageBody;
46 myOriginal = theMsg.myOriginal;
47 for ( Standard_Integer i = 1, n = theMsg.mySeqOfFormats.Length(); i <=n; i++ )
48 mySeqOfFormats.Append ( theMsg.mySeqOfFormats.Value(i) );
49}
50
51//=======================================================================
52//function : Message_Msg()
53//purpose : Constructor
54//=======================================================================
55
56Message_Msg::Message_Msg (const Standard_CString theMsgCode)
57{
58 TCollection_AsciiString aKey((char*)theMsgCode);
59 Set ( Message_MsgFile::Msg(aKey) );
60}
61
62//=======================================================================
63//function : Message_Msg()
64//purpose : Constructor
65//=======================================================================
66
67Message_Msg::Message_Msg (const TCollection_ExtendedString& theMsgCode)
68{
69 Set ( Message_MsgFile::Msg(theMsgCode) );
70}
71
72//=======================================================================
73//function : Set
74//purpose :
75//=======================================================================
76
77void Message_Msg::Set (const Standard_CString theMsg)
78{
79 TCollection_AsciiString aMsg((char*)theMsg);
80 Set ( aMsg );
81}
82
83//=======================================================================
84//function : Set
85//purpose :
86//=======================================================================
87
88void Message_Msg::Set (const TCollection_ExtendedString& theMsg)
89{
90 myMessageBody = theMsg;
91
92 const Standard_ExtString anExtString = myMessageBody.ToExtString();
93 Standard_Integer anMsgLength = myMessageBody.Length();
94 for (Standard_Integer i = 0; i < anMsgLength; i++)
95 {
96 // Search for '%' character starting a format specification
97 if (ToCharacter (anExtString[i]) == '%')
98 {
99 Standard_Integer aStart = i++;
100 Standard_Character aChar = ToCharacter (anExtString[i]);
101 // Check for format '%%'
102 if (aChar == '%')
103 {
104 myMessageBody.Remove (i+1);
105 if (i >= --anMsgLength) break;
106 aChar = ToCharacter (anExtString[i]);
107 }
108 // Skip flags, field width and precision
109 while (i < anMsgLength)
110 {
111 if (aChar == '-' || aChar == '+' || aChar == ' ' ||
112 aChar == '#' || (aChar >= '0' && aChar <= '9') || aChar == '.')
113 i++;
114 else break;
115 aChar = ToCharacter (anExtString[i]);
116 }
117 if (i >= anMsgLength) break;
118
119 FormatType aFormatType;
120 if (aChar == 'h' || aChar == 'l') aChar = ToCharacter (anExtString[++i]);
121 switch (aChar) // detect the type of format spec
122 {
123 case 'd':
124 case 'i':
125 case 'o':
126 case 'u':
127 case 'x':
128 case 'X':
129 aFormatType = Msg_IntegerType;
130 break;
131 case 'f':
132 case 'e':
133 case 'E':
134 case 'g':
135 case 'G':
136 aFormatType = Msg_RealType;
137 break;
138 case 's':
139 aFormatType = Msg_StringType;
140 break;
141 default:
142 aFormatType = Msg_IndefiniteType;
143 continue;
144 }
145 mySeqOfFormats.Append (Standard_Integer(aFormatType)); // type
146 mySeqOfFormats.Append (aStart); // beginning pos
147 mySeqOfFormats.Append (i + 1 - aStart); // length
148 }
149 }
150 myOriginal = myMessageBody;
151}
152
153//=======================================================================
154//function : Arg (Standard_CString)
155//purpose :
156//=======================================================================
157
158Message_Msg& Message_Msg::Arg (const Standard_CString theString)
159{
160 // get location and format
161 TCollection_AsciiString aFormat;
162 Standard_Integer aFirst = getFormat ( Msg_StringType, aFormat );
163 if ( !aFirst )
164 return *this;
165
166 // print string according to format
60be1f9b 167 char * sStringBuffer = new char [Max ((Standard_Integer)strlen(theString)+1, 1024)];
91322f44 168 Sprintf (sStringBuffer, aFormat.ToCString(), theString);
d9ff84e8 169 TCollection_ExtendedString aStr ( sStringBuffer, Standard_True );
06ddeafb 170 delete [] sStringBuffer;
7fd59977 171 sStringBuffer = 0;
172
173 // replace the format placeholder by the actual string
174 replaceText ( aFirst, aFormat.Length(), aStr );
175
176 return *this;
177}
178
179//=======================================================================
180//function : Arg (TCollection_ExtendedString)
181//purpose :
182//remark : This type of string is inserted without conversion (i.e. like %s)
183//=======================================================================
184
185Message_Msg& Message_Msg::Arg (const TCollection_ExtendedString& theString)
186{
187 // get location and format
188 TCollection_AsciiString aFormat;
189 Standard_Integer aFirst = getFormat ( Msg_StringType, aFormat );
190 if ( !aFirst )
191 return *this;
192
193 // replace the format placeholder by the actual string
194 replaceText ( aFirst, aFormat.Length(), theString );
195
196 return *this;
197}
198
199//=======================================================================
200//function : Arg (Standard_Integer)
201//purpose :
202//=======================================================================
203
204Message_Msg& Message_Msg::Arg (const Standard_Integer theValue)
205{
206 // get location and format
207 TCollection_AsciiString aFormat;
208 Standard_Integer aFirst = getFormat ( Msg_IntegerType, aFormat );
209 if ( !aFirst )
210 return *this;
211
212 // print string according to format
213 char sStringBuffer [64];
91322f44 214 Sprintf (sStringBuffer, aFormat.ToCString(), theValue);
7fd59977 215 TCollection_ExtendedString aStr ( sStringBuffer );
216
217 // replace the format placeholder by the actual string
218 replaceText ( aFirst, aFormat.Length(), aStr );
219
220 return *this;
221}
222
223//=======================================================================
224//function : Arg (Standard_Real)
225//purpose :
226//=======================================================================
227
228Message_Msg& Message_Msg::Arg (const Standard_Real theValue)
229{
230 // get location and format
231 TCollection_AsciiString aFormat;
232 Standard_Integer aFirst = getFormat ( Msg_RealType, aFormat );
233 if ( !aFirst )
234 return *this;
235
236 // print string according to format
237 char sStringBuffer [64];
91322f44 238 Sprintf (sStringBuffer, aFormat.ToCString(), theValue);
7fd59977 239 TCollection_ExtendedString aStr ( sStringBuffer );
240
241 // replace the format placeholder by the actual string
242 replaceText ( aFirst, aFormat.Length(), aStr );
243
244 return *this;
245}
246
247//=======================================================================
248//function : Get
249//purpose : used when the message is dispatched in Message_Messenger
250//=======================================================================
251
252const TCollection_ExtendedString& Message_Msg::Get ()
253{
254 // remove all non-initialised format specifications
255 Standard_Integer i, anIncrement = 0;
256 static const TCollection_ExtendedString anUnknown ("UNKNOWN");
257 for (i = 1; i < mySeqOfFormats.Length(); i += 3)
258 {
259 TCollection_ExtendedString aRightPart =
260 myMessageBody.Split(mySeqOfFormats(i+1) + anIncrement);
261 aRightPart.Remove(1, mySeqOfFormats(i+2));
262 myMessageBody += anUnknown;
263 myMessageBody += aRightPart;
264 anIncrement += (anUnknown.Length() - mySeqOfFormats(i+2));
265 }
266 return myMessageBody;
267}
268
269//=======================================================================
270//function : getFormat
271//purpose : Find placeholder in the string where to put next value of
272// specified type, return its starting position in the string
273// and relevant format string (located at that position).
274// The information on returned placeholder is deleted immediately,
275// so it will not be found further
276// If failed (no placeholder with relevant type found), returns 0
277//=======================================================================
278
279Standard_Integer Message_Msg::getFormat (const Standard_Integer theType,
280 TCollection_AsciiString &theFormat)
281{
282 for (Standard_Integer i = 1; i <= mySeqOfFormats.Length(); i += 3)
283 if (mySeqOfFormats(i) == theType)
284 {
285 // Extract format
286 Standard_Integer aFirst = mySeqOfFormats(i+1);
287 Standard_Integer aLen = mySeqOfFormats(i+2);
288 theFormat = TCollection_AsciiString ( aLen, ' ' );
289 for ( Standard_Integer j=1; j <= aLen; j++ )
290 if ( IsAnAscii ( myMessageBody.Value ( aFirst + j ) ) )
291 theFormat.SetValue ( j, (Standard_Character)myMessageBody.Value ( aFirst + j ) );
292 // delete information on this placeholder
293 mySeqOfFormats.Remove (i, i+2);
294 // return start position
295 return aFirst + 1;
296 }
297 return 0;
298}
299
300//=======================================================================
301//function : replaceText
302//purpose : Replace format text in myMessageBody (theNb chars from theFirst)
303// by string theStr
304//=======================================================================
305
306void Message_Msg::replaceText (const Standard_Integer theFirst,
307 const Standard_Integer theNb,
308 const TCollection_ExtendedString &theStr)
309{
310 myMessageBody.Remove ( theFirst, theNb );
311 myMessageBody.Insert ( theFirst, theStr );
312
313 // update information on remaining format placeholders
314 Standard_Integer anIncrement = theStr.Length() - theNb;
315 if ( ! anIncrement ) return;
316 for ( Standard_Integer i = 1; i <= mySeqOfFormats.Length(); i += 3 )
317 if ( mySeqOfFormats(i+1) > theFirst )
318 mySeqOfFormats(i+1) += anIncrement;
319}