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 | // |
973c2be1 |
7 | // This library is free software; you can redistribute it and / or modify it |
8 | // under the terms of the GNU Lesser General Public version 2.1 as published |
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 |
21 | typedef 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 | |
34 | Message_Msg::Message_Msg () |
35 | {} |
36 | |
37 | |
38 | //======================================================================= |
39 | //function : Message_Msg() |
40 | //purpose : Constructor |
41 | //======================================================================= |
42 | |
43 | Message_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 | |
56 | Message_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 | |
67 | Message_Msg::Message_Msg (const TCollection_ExtendedString& theMsgCode) |
68 | { |
69 | Set ( Message_MsgFile::Msg(theMsgCode) ); |
70 | } |
71 | |
72 | //======================================================================= |
73 | //function : Set |
74 | //purpose : |
75 | //======================================================================= |
76 | |
77 | void 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 | |
88 | void 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 | |
158 | Message_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); |
7fd59977 |
169 | TCollection_ExtendedString aStr ( sStringBuffer ); |
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 | |
185 | Message_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 | |
204 | Message_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 | |
228 | Message_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 | |
252 | const 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 | |
279 | Standard_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 | |
306 | void 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 | } |