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