Go to the documentation of this file.00001
00002 #include <string>
00003 #include <iostream>
00004 #include <iomanip>
00005 #include <cstdlib>
00006 #include <cstdio>
00007 #include <cctype>
00008 #include "GaudiKernel/IMessageSvc.h"
00009 #include "GaudiKernel/Message.h"
00010 #include "GaudiKernel/Timing.h"
00011 #include "GaudiKernel/Time.h"
00012
00013 using namespace MSG;
00014
00015
00016 const char Message::FORMAT_PREFIX = '%';
00017 const char Message::JUSTIFY_LEFT = 'L';
00018 const char Message::JUSTIFY_RIGHT = 'R';
00019 const char Message::MESSAGE = 'M';
00020 const char Message::TYPE = 'T';
00021 const char Message::TIME = 't';
00022 const char Message::UTIME = 'u';
00023 const char Message::SOURCE = 'S';
00024 const char Message::FILL = 'F';
00025 const char Message::WIDTH = 'W';
00026
00027 const char* Message::DEFAULT_FORMAT = "% F%18W%S%7W%R%T %0W%M";
00028
00029 const char* Message::DEFAULT_TIME_FORMAT = "%Y-%m-%d %H:%M:%S,%f";
00030
00031 namespace {
00032
00033 inline std::string formattedTime (const std::string &fmt, bool universal = false )
00034 {
00035 return Gaudi::Time::current().format(!universal, fmt);
00036 }
00037 }
00038
00039
00040
00041
00042
00043
00044
00045 Message::Message() :
00046 m_message( "" ), m_source( "UNKNOWN" ), m_format( DEFAULT_FORMAT ),
00047 m_time_format(DEFAULT_TIME_FORMAT), m_type( NIL ),
00048 m_fill( ' ' ), m_width( 0 ), m_left( true )
00049 {
00050 }
00051
00052
00053
00054
00055
00056
00057
00058 Message::Message ( const char* src, int type, const char* msg ) :
00059 m_message( msg ), m_source( src ), m_format( DEFAULT_FORMAT ),
00060 m_time_format(DEFAULT_TIME_FORMAT), m_type( type ),
00061 m_fill( ' ' ), m_width( 0 ), m_left( true )
00062 {
00063 }
00064
00065
00066
00067
00068
00069
00070
00071 Message::Message ( const std::string& src, int type, const std::string& msg ) :
00072 m_message( msg ), m_source( src ), m_format( DEFAULT_FORMAT ),
00073 m_time_format(DEFAULT_TIME_FORMAT), m_type( type ),
00074 m_fill( ' ' ), m_width( 0 ), m_left( true )
00075 {
00076 }
00077
00078
00079
00080
00081
00082
00083
00084 const std::string& Message::getMessage() const
00085 {
00086 return m_message;
00087 }
00088
00089
00090
00091
00092
00093
00094
00095 void Message::setMessage( const std::string& msg )
00096 {
00097 m_message = msg;
00098 }
00099
00100
00101
00102
00103
00104
00105
00106 int Message::getType() const
00107 {
00108 return m_type;
00109 }
00110
00111
00112
00113
00114
00115
00116
00117 void Message::setType( int msg_type )
00118 {
00119 m_type = msg_type;
00120 }
00121
00122
00123
00124
00125
00126
00127
00128 const std::string& Message::getSource() const
00129 {
00130 return m_source;
00131 }
00132
00133
00134
00135
00136
00137
00138
00139 void Message::setSource( const std::string& src )
00140 {
00141 m_source = src;
00142 }
00143
00144
00145
00146
00147
00148
00149
00150 std::ostream& operator << ( std::ostream& stream, const Message& msg )
00151 {
00152 msg.makeFormattedMsg( msg.m_format );
00153 stream << msg.m_formatted_msg;
00154 return stream;
00155 }
00156
00157
00158
00159
00160
00161
00162
00163 bool Message::operator < ( const Message& b )
00164 {
00165 return m_type < b.m_type ||
00166 m_source < b.m_source ||
00167 m_message < b.m_message;
00168 }
00169
00170
00171
00172
00173
00174
00175
00176 bool operator == ( const Message& a, const Message& b )
00177 {
00178 return a.m_source == b.m_source &&
00179 a.m_type == b.m_type &&
00180 a.m_message == b.m_message;
00181 }
00182
00183
00184
00185
00186
00187
00188
00189 const std::string& Message::getFormat() const
00190 {
00191 return m_format;
00192 }
00193
00194
00195
00196
00197
00198
00199
00200 const std::string Message::getDefaultFormat()
00201 {
00202 return DEFAULT_FORMAT;
00203 }
00204
00205
00206
00207
00208
00209
00210
00211
00212
00213 void Message::setFormat( const std::string& format ) const
00214 {
00215 if ( format.empty() )
00216 m_format = DEFAULT_FORMAT;
00217 else
00218 m_format = format;
00219 }
00220
00221
00222
00223
00224
00225
00226
00227 const std::string& Message::getTimeFormat() const
00228 {
00229 return m_time_format;
00230 }
00231
00232
00233
00234
00235
00236
00237
00238 const std::string Message::getDefaultTimeFormat()
00239 {
00240 return DEFAULT_TIME_FORMAT ;
00241 }
00242
00243
00244
00245
00246
00247
00248
00249
00250
00251 void Message::setTimeFormat( const std::string& timeFormat ) const
00252 {
00253 if ( timeFormat.empty() )
00254 m_time_format = DEFAULT_TIME_FORMAT;
00255 else
00256 m_time_format = timeFormat;
00257 }
00258
00259
00260
00261
00262
00263
00264
00265 void Message::makeFormattedMsg( const std::string& format ) const
00266 {
00267 m_formatted_msg = "";
00268 std::string::const_iterator i = format.begin();
00269 while( i != format.end() ) {
00270
00271
00272 while( i != format.end() && *i != FORMAT_PREFIX )
00273 m_formatted_msg += *i++;
00274
00275
00276 if ( i == format.end() ) break;
00277 i++;
00278
00279
00280 std::string this_format = "";
00281 while( i != format.end() && *i != FORMAT_PREFIX &&
00282 *i != MESSAGE && *i != TYPE && *i != SOURCE &&
00283 *i != FILL && *i != WIDTH && *i != TIME && *i != UTIME &&
00284 *i != JUSTIFY_LEFT && *i != JUSTIFY_RIGHT ) {
00285 this_format += *i++;
00286 }
00287
00288
00289 if ( i == format.end() ) {
00290 invalidFormat();
00291 break;
00292 }
00293
00294 this_format += *i++;
00295 decodeFormat( this_format );
00296 }
00297 }
00298
00299
00300
00301
00302
00303
00304
00305 void Message::decodeFormat( const std::string& format ) const
00306 {
00307 if ( ! format.empty() ) {
00308 const char FORMAT_TYPE = format[ format.length() - 1 ];
00309 const std::string FORMAT_PARAM = format.substr( 0, format.length() - 1 );
00310
00311
00312 std::string level;
00313 switch( FORMAT_TYPE ) {
00314 case FILL:
00315 if ( FORMAT_PARAM.length() == 1 ) {
00316 m_fill = FORMAT_PARAM[0];
00317 }
00318 else
00319 invalidFormat();
00320 break;
00321
00322 case TIME:
00323 {
00324 const std::string& timeStr = formattedTime ( m_time_format ) ;
00325 sizeField( timeStr );
00326 }
00327 break;
00328
00329 case UTIME:
00330 {
00331 const std::string& timeStr = formattedTime ( m_time_format, true ) ;
00332 sizeField( timeStr );
00333 }
00334 break;
00335
00336 case MESSAGE:
00337 sizeField( m_message );
00338 break;
00339
00340 case SOURCE:
00341 sizeField( m_source );
00342 break;
00343
00344 case TYPE:
00345 switch ( m_type ) {
00346 #define SET(x) case x: level=#x; break
00347 SET( NIL );
00348 SET( VERBOSE );
00349 SET( DEBUG );
00350 SET( INFO );
00351 SET( WARNING );
00352 SET( ERROR );
00353 SET( FATAL );
00354 case ALWAYS: level="SUCCESS"; break;
00355 default:
00356 level = "UNKNOWN";
00357 break;
00358 #undef SET
00359 }
00360 sizeField( level );
00361 break;
00362
00363 case FORMAT_PREFIX: m_formatted_msg += FORMAT_PREFIX; break;
00364 case JUSTIFY_RIGHT: m_left = false; break;
00365 case JUSTIFY_LEFT: m_left = true; break;
00366 case WIDTH: setWidth( FORMAT_PARAM ); break;
00367 default: invalidFormat(); break;
00368 }
00369 }
00370 else
00371 invalidFormat();
00372 }
00373
00374
00375
00376
00377
00378
00379
00380
00381 void Message::invalidFormat() const
00382 {
00383 makeFormattedMsg( DEFAULT_FORMAT );
00384 }
00385
00386
00387
00388
00389
00390
00391
00392
00393 void Message::setWidth( const std::string& formatArg ) const
00394 {
00395
00396 bool only_digits = true;
00397 for( std::string::const_iterator i = formatArg.begin();
00398 i != formatArg.end(); i++ ) {
00399
00400 if ( ! isdigit( *i ) ) {
00401 only_digits = false;
00402 invalidFormat();
00403 break;
00404 }
00405 }
00406
00407
00408 if ( only_digits ) {
00409 #ifdef __GNUG__
00410 m_width = atoi( formatArg.c_str() );
00411 #else
00412 m_width = atoi( formatArg.data() );
00413 #endif
00414 }
00415 }
00416
00417
00418
00419
00420
00421
00422
00423
00424 void Message::sizeField( const std::string& text ) const
00425 {
00426 std::string newText;
00427 if ( m_width == 0 || m_width == static_cast<int>( text.length() ) ) {
00428 newText = text;
00429 }
00430 else {
00431
00432
00433 if ( m_width < static_cast<int>( text.length() ) ) {
00434 newText = text.substr( 0, m_width );
00435 for ( int i = 0, j = newText.length()-1; i < 3 && j >= 0; i++, j-- )
00436 newText[ j ] = '.';
00437 }
00438
00439
00440 else {
00441 newText = std::string( m_width, m_fill );
00442 if ( m_left )
00443 newText.replace( newText.begin(), newText.begin() + text.length(),
00444 text.begin(), text.end() );
00445 else
00446 newText.replace( newText.end() - text.length(), newText.end(),
00447 text.begin(), text.end() );
00448 }
00449 }
00450
00451 m_formatted_msg += newText;
00452 }