1 // Created on: 2001-04-27
2 // Created by: OCC Team
3 // Copyright (c) 2001-2012 OPEN CASCADE SAS
5 // The content of this file is subject to the Open CASCADE Technology Public
6 // License Version 6.5 (the "License"). You may not use the content of this file
7 // except in compliance with the License. Please obtain a copy of the License
8 // at http://www.opencascade.org and read it completely before using this file.
10 // The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
11 // main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
13 // The Original Code and all software distributed under the License is
14 // distributed on an "AS IS" basis, without warranty of any kind, and the
15 // Initial Developer hereby disclaims all such warranties, including without
16 // limitation, any warranties of merchantability, fitness for a particular
17 // purpose or non-infringement. Please see the License for the specific terms
18 // and conditions governing the rights and limitations under the License.
21 #include <Message_Msg.hxx>
22 #include <Message_MsgFile.hxx>
23 #include <TCollection_AsciiString.hxx>
34 //=======================================================================
35 //function : Message_Msg()
36 //purpose : Constructor
37 //=======================================================================
39 Message_Msg::Message_Msg ()
43 //=======================================================================
44 //function : Message_Msg()
45 //purpose : Constructor
46 //=======================================================================
48 Message_Msg::Message_Msg (const Message_Msg& theMsg)
50 myMessageBody = theMsg.myMessageBody;
51 myOriginal = theMsg.myOriginal;
52 for ( Standard_Integer i = 1, n = theMsg.mySeqOfFormats.Length(); i <=n; i++ )
53 mySeqOfFormats.Append ( theMsg.mySeqOfFormats.Value(i) );
56 //=======================================================================
57 //function : Message_Msg()
58 //purpose : Constructor
59 //=======================================================================
61 Message_Msg::Message_Msg (const Standard_CString theMsgCode)
63 TCollection_AsciiString aKey((char*)theMsgCode);
64 Set ( Message_MsgFile::Msg(aKey) );
67 //=======================================================================
68 //function : Message_Msg()
69 //purpose : Constructor
70 //=======================================================================
72 Message_Msg::Message_Msg (const TCollection_ExtendedString& theMsgCode)
74 Set ( Message_MsgFile::Msg(theMsgCode) );
77 //=======================================================================
80 //=======================================================================
82 void Message_Msg::Set (const Standard_CString theMsg)
84 TCollection_AsciiString aMsg((char*)theMsg);
88 //=======================================================================
91 //=======================================================================
93 void Message_Msg::Set (const TCollection_ExtendedString& theMsg)
95 myMessageBody = theMsg;
97 const Standard_ExtString anExtString = myMessageBody.ToExtString();
98 Standard_Integer anMsgLength = myMessageBody.Length();
99 for (Standard_Integer i = 0; i < anMsgLength; i++)
101 // Search for '%' character starting a format specification
102 if (ToCharacter (anExtString[i]) == '%')
104 Standard_Integer aStart = i++;
105 Standard_Character aChar = ToCharacter (anExtString[i]);
106 // Check for format '%%'
109 myMessageBody.Remove (i+1);
110 if (i >= --anMsgLength) break;
111 aChar = ToCharacter (anExtString[i]);
113 // Skip flags, field width and precision
114 while (i < anMsgLength)
116 if (aChar == '-' || aChar == '+' || aChar == ' ' ||
117 aChar == '#' || (aChar >= '0' && aChar <= '9') || aChar == '.')
120 aChar = ToCharacter (anExtString[i]);
122 if (i >= anMsgLength) break;
124 FormatType aFormatType;
125 if (aChar == 'h' || aChar == 'l') aChar = ToCharacter (anExtString[++i]);
126 switch (aChar) // detect the type of format spec
134 aFormatType = Msg_IntegerType;
141 aFormatType = Msg_RealType;
144 aFormatType = Msg_StringType;
147 aFormatType = Msg_IndefiniteType;
150 mySeqOfFormats.Append (Standard_Integer(aFormatType)); // type
151 mySeqOfFormats.Append (aStart); // beginning pos
152 mySeqOfFormats.Append (i + 1 - aStart); // length
155 myOriginal = myMessageBody;
158 //=======================================================================
159 //function : Arg (Standard_CString)
161 //=======================================================================
163 Message_Msg& Message_Msg::Arg (const Standard_CString theString)
165 // get location and format
166 TCollection_AsciiString aFormat;
167 Standard_Integer aFirst = getFormat ( Msg_StringType, aFormat );
171 // print string according to format
172 char * sStringBuffer = new char [Max (strlen(theString)+1, 1024)];
173 sprintf (sStringBuffer, aFormat.ToCString(), theString);
174 TCollection_ExtendedString aStr ( sStringBuffer );
175 delete [] sStringBuffer;
178 // replace the format placeholder by the actual string
179 replaceText ( aFirst, aFormat.Length(), aStr );
184 //=======================================================================
185 //function : Arg (TCollection_ExtendedString)
187 //remark : This type of string is inserted without conversion (i.e. like %s)
188 //=======================================================================
190 Message_Msg& Message_Msg::Arg (const TCollection_ExtendedString& theString)
192 // get location and format
193 TCollection_AsciiString aFormat;
194 Standard_Integer aFirst = getFormat ( Msg_StringType, aFormat );
198 // replace the format placeholder by the actual string
199 replaceText ( aFirst, aFormat.Length(), theString );
204 //=======================================================================
205 //function : Arg (Standard_Integer)
207 //=======================================================================
209 Message_Msg& Message_Msg::Arg (const Standard_Integer theValue)
211 // get location and format
212 TCollection_AsciiString aFormat;
213 Standard_Integer aFirst = getFormat ( Msg_IntegerType, aFormat );
217 // print string according to format
218 char sStringBuffer [64];
219 sprintf (sStringBuffer, aFormat.ToCString(), theValue);
220 TCollection_ExtendedString aStr ( sStringBuffer );
222 // replace the format placeholder by the actual string
223 replaceText ( aFirst, aFormat.Length(), aStr );
228 //=======================================================================
229 //function : Arg (Standard_Real)
231 //=======================================================================
233 Message_Msg& Message_Msg::Arg (const Standard_Real theValue)
235 // get location and format
236 TCollection_AsciiString aFormat;
237 Standard_Integer aFirst = getFormat ( Msg_RealType, aFormat );
241 // print string according to format
242 char sStringBuffer [64];
243 sprintf (sStringBuffer, aFormat.ToCString(), theValue);
244 TCollection_ExtendedString aStr ( sStringBuffer );
246 // replace the format placeholder by the actual string
247 replaceText ( aFirst, aFormat.Length(), aStr );
252 //=======================================================================
254 //purpose : used when the message is dispatched in Message_Messenger
255 //=======================================================================
257 const TCollection_ExtendedString& Message_Msg::Get ()
259 // remove all non-initialised format specifications
260 Standard_Integer i, anIncrement = 0;
261 static const TCollection_ExtendedString anUnknown ("UNKNOWN");
262 for (i = 1; i < mySeqOfFormats.Length(); i += 3)
264 TCollection_ExtendedString aRightPart =
265 myMessageBody.Split(mySeqOfFormats(i+1) + anIncrement);
266 aRightPart.Remove(1, mySeqOfFormats(i+2));
267 myMessageBody += anUnknown;
268 myMessageBody += aRightPart;
269 anIncrement += (anUnknown.Length() - mySeqOfFormats(i+2));
271 return myMessageBody;
274 //=======================================================================
275 //function : getFormat
276 //purpose : Find placeholder in the string where to put next value of
277 // specified type, return its starting position in the string
278 // and relevant format string (located at that position).
279 // The information on returned placeholder is deleted immediately,
280 // so it will not be found further
281 // If failed (no placeholder with relevant type found), returns 0
282 //=======================================================================
284 Standard_Integer Message_Msg::getFormat (const Standard_Integer theType,
285 TCollection_AsciiString &theFormat)
287 for (Standard_Integer i = 1; i <= mySeqOfFormats.Length(); i += 3)
288 if (mySeqOfFormats(i) == theType)
291 Standard_Integer aFirst = mySeqOfFormats(i+1);
292 Standard_Integer aLen = mySeqOfFormats(i+2);
293 theFormat = TCollection_AsciiString ( aLen, ' ' );
294 for ( Standard_Integer j=1; j <= aLen; j++ )
295 if ( IsAnAscii ( myMessageBody.Value ( aFirst + j ) ) )
296 theFormat.SetValue ( j, (Standard_Character)myMessageBody.Value ( aFirst + j ) );
297 // delete information on this placeholder
298 mySeqOfFormats.Remove (i, i+2);
299 // return start position
305 //=======================================================================
306 //function : replaceText
307 //purpose : Replace format text in myMessageBody (theNb chars from theFirst)
309 //=======================================================================
311 void Message_Msg::replaceText (const Standard_Integer theFirst,
312 const Standard_Integer theNb,
313 const TCollection_ExtendedString &theStr)
315 myMessageBody.Remove ( theFirst, theNb );
316 myMessageBody.Insert ( theFirst, theStr );
318 // update information on remaining format placeholders
319 Standard_Integer anIncrement = theStr.Length() - theNb;
320 if ( ! anIncrement ) return;
321 for ( Standard_Integer i = 1; i <= mySeqOfFormats.Length(); i += 3 )
322 if ( mySeqOfFormats(i+1) > theFirst )
323 mySeqOfFormats(i+1) += anIncrement;