Gaudi Framework, version v21r4

Home   Generated: 7 Sep 2009

Message.cpp

Go to the documentation of this file.
00001 // $Header: /tmp/svngaudi/tmp.jEpFh25751/Gaudi/GaudiKernel/src/Lib/Message.cpp,v 1.9 2008/02/20 19:16:23 hmd Exp $
00002 #include <string>
00003 #include <iostream>
00004 #include <iomanip>
00005 #include <cstdlib>
00006 #include <cctype>
00007 #include "GaudiKernel/IMessageSvc.h"
00008 #include "GaudiKernel/Message.h"
00009 #include "GaudiKernel/Timing.h"
00010 
00011 #include "GaudiKernel/time_r.h"
00012 
00013 using namespace MSG;
00014 
00015 // Formatting string characters.
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 //const char* Message::DEFAULT_FORMAT = "% F%67W%L#############################################################################\n-----------------------------------------------------------------------------\nMessage follows...\nSource  : %S\nType    : %T\nMessage : %M\nEnd of message.\n-----------------------------------------------------------------------------\n";
00027 const char* Message::DEFAULT_FORMAT = "% F%18W%S%7W%R%T %0W%M";
00028 // Time format accepts anything that strftime does plus %f for milliseconds
00029 const char* Message::DEFAULT_TIME_FORMAT = "%Y-%m-%d %H:%M:%S,%f";
00030 
00031 namespace {
00032 
00033   std::string formattedTime ( std::string fmt, bool universal = false );
00034 
00035 }
00036 
00037 //#############################################################################
00038 // ---------------------------------------------------------------------------
00039 // Routine: Constructor.
00040 // Purpose:
00041 // ---------------------------------------------------------------------------
00042 //
00043 Message::Message() :
00044   m_message( "" ), m_source( "UNKNOWN" ), m_format( DEFAULT_FORMAT ),
00045   m_time_format(DEFAULT_TIME_FORMAT), m_type( NIL ),
00046   m_fill( ' ' ), m_width( 0 ), m_left( true )
00047 {
00048 }
00049 
00050 //#############################################################################
00051 // ---------------------------------------------------------------------------
00052 // Routine: Constructor.
00053 // Purpose:
00054 // ---------------------------------------------------------------------------
00055 //
00056 Message::Message ( const char* src, int type, const char* msg ) :
00057   m_message( msg ), m_source( src ), m_format( DEFAULT_FORMAT ),
00058   m_time_format(DEFAULT_TIME_FORMAT), m_type( type ),
00059   m_fill( ' ' ), m_width( 0 ), m_left( true )
00060 {
00061 }
00062 
00063 //#############################################################################
00064 // ---------------------------------------------------------------------------
00065 // Routine: Constructor.
00066 // Purpose:
00067 // ---------------------------------------------------------------------------
00068 //
00069 Message::Message ( const std::string& src, int type, const std::string& msg ) :
00070   m_message( msg ), m_source( src ), m_format( DEFAULT_FORMAT ),
00071   m_time_format(DEFAULT_TIME_FORMAT), m_type( type ),
00072   m_fill( ' ' ), m_width( 0 ), m_left( true )
00073 {
00074 }
00075 
00076 //#############################################################################
00077 // ---------------------------------------------------------------------------
00078 // Routine: getMessage
00079 // Purpose: Get the message string.
00080 // ---------------------------------------------------------------------------
00081 //
00082 const std::string& Message::getMessage() const
00083 {
00084   return m_message;
00085 }
00086 
00087 //#############################################################################
00088 // ---------------------------------------------------------------------------
00089 // Routine: setMessage
00090 // Purpose: Set the message string.
00091 // ---------------------------------------------------------------------------
00092 //
00093 void Message::setMessage( const std::string& msg )
00094 {
00095   m_message = msg;
00096 }
00097 
00098 //#############################################################################
00099 // ---------------------------------------------------------------------------
00100 // Routine: getType
00101 // Purpose: Get the message type.
00102 // ---------------------------------------------------------------------------
00103 //
00104 int Message::getType() const
00105 {
00106   return m_type;
00107 }
00108 
00109 //#############################################################################
00110 // ---------------------------------------------------------------------------
00111 // Routine: setType
00112 // Purpose: Set the message type.
00113 // ---------------------------------------------------------------------------
00114 //
00115 void Message::setType( int msg_type )
00116 {
00117   m_type = msg_type;
00118 }
00119 
00120 //#############################################################################
00121 // ---------------------------------------------------------------------------
00122 // Routine: getSource
00123 // Purpose: Get the message source.
00124 // ---------------------------------------------------------------------------
00125 //
00126 const std::string& Message::getSource() const
00127 {
00128   return m_source;
00129 }
00130 
00131 //#############################################################################
00132 // ---------------------------------------------------------------------------
00133 // Routine: setSource
00134 // Purpose: Set the message source.
00135 // ---------------------------------------------------------------------------
00136 //
00137 void Message::setSource( const std::string& src )
00138 {
00139   m_source = src;
00140 }
00141 
00142 //#############################################################################
00143 // ---------------------------------------------------------------------------
00144 // Routine: operator <<
00145 // Purpose:Insert the message into a stream.
00146 // ---------------------------------------------------------------------------
00147 //
00148 std::ostream& operator << ( std::ostream& stream, const Message& msg )
00149 {
00150   msg.makeFormattedMsg( msg.m_format );
00151   stream << msg.m_formatted_msg;
00152   return stream;
00153 }
00154 
00155 //#############################################################################
00156 // ---------------------------------------------------------------------------
00157 // Routine: operator <
00158 // Purpose: comparison operator needed for maps
00159 // ---------------------------------------------------------------------------
00160 //
00161 bool Message::operator < ( const Message& b )
00162 {
00163   return m_type   < b.m_type ||
00164          m_source < b.m_source ||
00165          m_message < b.m_message;
00166 }
00167 
00168 //#############################################################################
00169 // ---------------------------------------------------------------------------
00170 // Routine: operator ==
00171 // Purpose: comparison op.
00172 // ---------------------------------------------------------------------------
00173 //
00174 bool operator == ( const Message& a, const Message& b )
00175 {
00176   return a.m_source == b.m_source &&
00177     a.m_type == b.m_type &&
00178     a.m_message == b.m_message;
00179 }
00180 
00181 //#############################################################################
00182 // ---------------------------------------------------------------------------
00183 // Routine:
00184 // Purpose: Get the format string.
00185 // ---------------------------------------------------------------------------
00186 //
00187 const std::string& Message::getFormat() const
00188 {
00189   return m_format;
00190 }
00191 
00192 //#############################################################################
00193 // ---------------------------------------------------------------------------
00194 // Routine:
00195 // Purpose: Get the default format string.
00196 // ---------------------------------------------------------------------------
00197 //
00198 const std::string Message::getDefaultFormat()
00199 {
00200   return DEFAULT_FORMAT;
00201 }
00202 
00203 
00204 //#############################################################################
00205 // ---------------------------------------------------------------------------
00206 // Routine:
00207 // Purpose: Set the format string -
00208 //          use isFormatted() to check for valid format.
00209 // ---------------------------------------------------------------------------
00210 //
00211 void Message::setFormat( const std::string& format ) const
00212 {
00213   if ( format.empty() )
00214     m_format = DEFAULT_FORMAT;
00215   else
00216     m_format = format;
00217 }
00218 
00219 //#############################################################################
00220 // ---------------------------------------------------------------------------
00221 // Routine:
00222 // Purpose: Get the time format string.
00223 // ---------------------------------------------------------------------------
00224 //
00225 const std::string& Message::getTimeFormat() const
00226 {
00227   return m_time_format;
00228 }
00229 
00230 //#############################################################################
00231 // ---------------------------------------------------------------------------
00232 // Routine:
00233 // Purpose: Get the default time format string.
00234 // ---------------------------------------------------------------------------
00235 //
00236 const std::string Message::getDefaultTimeFormat()
00237 {
00238   return DEFAULT_TIME_FORMAT ;
00239 }
00240 
00241 
00242 //#############################################################################
00243 // ---------------------------------------------------------------------------
00244 // Routine:
00245 // Purpose: Set the time format string -
00246 //          use isFormatted() to check for valid format.
00247 // ---------------------------------------------------------------------------
00248 //
00249 void Message::setTimeFormat( const std::string& timeFormat ) const
00250 {
00251   if ( timeFormat.empty() )
00252     m_time_format = DEFAULT_TIME_FORMAT;
00253   else
00254     m_time_format = timeFormat;
00255 }
00256 
00257 //#############################################################################
00258 // ---------------------------------------------------------------------------
00259 // Routine: makeFormattedMsg
00260 // Purpose: This formats the message according to the format string.
00261 // ---------------------------------------------------------------------------
00262 //
00263 void Message::makeFormattedMsg( const std::string& format ) const
00264 {
00265   m_formatted_msg = "";
00266   std::string::const_iterator i = format.begin();
00267   while( i != format.end() ) {
00268 
00269     // Output format string until format statement found.
00270     while(  i != format.end() && *i != FORMAT_PREFIX )
00271       m_formatted_msg += *i++;
00272 
00273     // Test for end of format string.
00274     if ( i == format.end() ) break;
00275     i++;
00276 
00277     // Find type of formatting.
00278     std::string this_format = "";
00279     while( i != format.end() && *i != FORMAT_PREFIX &&
00280            *i != MESSAGE && *i != TYPE && *i != SOURCE &&
00281            *i != FILL && *i != WIDTH && *i != TIME && *i != UTIME &&
00282            *i != JUSTIFY_LEFT && *i != JUSTIFY_RIGHT ) {
00283       this_format += *i++;
00284     }
00285 
00286     // Reached end of string with improper format.
00287     if ( i == format.end() ) {
00288       invalidFormat();
00289       break;
00290     }
00291 
00292     this_format += *i++;
00293     decodeFormat( this_format );
00294   }
00295 }
00296 
00297 //#############################################################################
00298 // ---------------------------------------------------------------------------
00299 // Routine: decodeFormat
00300 // Purpose: This the work horse that check for a valid format string.
00301 // ---------------------------------------------------------------------------
00302 //
00303 void Message::decodeFormat( const std::string& format ) const
00304 {
00305   if ( ! format.empty() ) {
00306     const char FORMAT_TYPE = format[ format.length() - 1 ];
00307     const std::string FORMAT_PARAM = format.substr( 0, format.length() - 1 );
00308 
00309     // Now test the format.
00310     std::string level;
00311     switch( FORMAT_TYPE ) {
00312     case FILL:
00313       if ( FORMAT_PARAM.length() == 1 ) {
00314         m_fill = FORMAT_PARAM[0];
00315       }
00316       else
00317         invalidFormat();
00318       break;
00319 
00320     case TIME:
00321       {
00322         const std::string& timeStr = formattedTime ( m_time_format ) ;
00323         sizeField( timeStr );
00324       }
00325       break;
00326 
00327     case UTIME:
00328       {
00329         const std::string& timeStr = formattedTime ( m_time_format, true ) ;
00330         sizeField( timeStr );
00331       }
00332       break;
00333 
00334     case MESSAGE:
00335       sizeField( m_message );
00336       break;
00337 
00338     case SOURCE:
00339       sizeField( m_source );
00340       break;
00341 
00342     case TYPE:
00343       switch ( m_type )    {
00344 #define SET(x)  case x:  level=#x;  break
00345         SET( NIL );
00346         SET( VERBOSE );
00347         SET( DEBUG );
00348         SET( INFO );
00349         SET( WARNING );
00350         SET( ERROR );
00351         SET( FATAL );
00352         case ALWAYS:       level="SUCCESS"; break;
00353         default:
00354               level = "UNKNOWN";
00355               break;
00356 #undef SET
00357       }
00358       sizeField( level );
00359       break;
00360 
00361     case FORMAT_PREFIX: m_formatted_msg += FORMAT_PREFIX; break;
00362     case JUSTIFY_RIGHT: m_left = false; break;
00363     case JUSTIFY_LEFT: m_left = true; break;
00364     case WIDTH: setWidth( FORMAT_PARAM ); break;
00365     default: invalidFormat(); break;
00366     }
00367   }
00368   else
00369     invalidFormat();
00370 }
00371 
00372 //#############################################################################
00373 // ---------------------------------------------------------------------------
00374 // Routine: invalidFormat.
00375 // Purpose: called when invalid format found.
00376 // ---------------------------------------------------------------------------
00377 //
00378 
00379 void Message::invalidFormat() const
00380 {
00381   makeFormattedMsg( DEFAULT_FORMAT );
00382 }
00383 
00384 //#############################################################################
00385 // ---------------------------------------------------------------------------
00386 // Routine: setWidth
00387 // Purpose: Sets the minimum width of a stream field.
00388 // ---------------------------------------------------------------------------
00389 //
00390 
00391 void Message::setWidth( const std::string& formatArg ) const
00392 {
00393   // Check that the parameters are only digits.
00394   bool only_digits = true;
00395   for( std::string::const_iterator i = formatArg.begin();
00396        i != formatArg.end(); i++ ) {
00397 
00398     if ( ! isdigit( *i ) ) {
00399       only_digits = false;
00400       invalidFormat();
00401       break;
00402     }
00403   }
00404 
00405   // Convert string to int.
00406   if ( only_digits ) {
00407 #ifdef __GNUG__
00408     m_width = atoi( formatArg.c_str() );
00409 #else
00410     m_width = atoi( formatArg.data() );
00411 #endif
00412   }
00413 }
00414 
00415 //#############################################################################
00416 // ---------------------------------------------------------------------------
00417 // Routine: sizeField
00418 // Purpose: Truncates or pads the text to m_width as necessary
00419 // ---------------------------------------------------------------------------
00420 //
00421 
00422 void Message::sizeField( const std::string& text ) const
00423 {
00424   std::string newText;
00425   if ( m_width == 0 || m_width == static_cast<int>( text.length() ) ) {
00426     newText = text;
00427   }
00428   else {
00429 
00430     // Truncate the text if it is too long.
00431     if ( m_width < static_cast<int>( text.length() ) ) {
00432       newText = text.substr( 0, m_width );
00433       for ( int i = 0, j = newText.length()-1; i < 3 && j >= 0; i++, j-- )
00434         newText[ j ] = '.';
00435     }
00436 
00437     // Pad the text.
00438     else {
00439       newText = std::string( m_width, m_fill );
00440       if ( m_left )
00441         newText.replace( newText.begin(), newText.begin() + text.length(),
00442                          text.begin(), text.end() );
00443       else
00444         newText.replace( newText.end() - text.length(), newText.end(),
00445                          text.begin(), text.end() );
00446     }
00447   }
00448 
00449   m_formatted_msg += newText;
00450 }
00451 
00452 namespace {
00453 
00454   // get the current time from the system and format it according to the format
00455   std::string formattedTime ( std::string fmt, bool universal )
00456   {
00457     // get current time in milliseconds
00458     longlong t = System::currentTime( System::milliSec );
00459     int msec = static_cast<int>(t % 1000);
00460     time_t sec = static_cast<time_t>(t / 1000);
00461 
00462     // convert to break-down time
00463     struct tm tms ;
00464     if (universal) {
00465       gmtime_r( &sec, &tms );
00466     } else {
00467       localtime_r( &sec, &tms );
00468     }
00469 
00470     // replace %f in the format string with miliseconds
00471     std::string::size_type n = fmt.find("%f") ;
00472     if ( n != std::string::npos ) {
00473       char subs[4] ;
00474       sprintf ( subs, "%03d", msec ) ;
00475       while ( n != std::string::npos ) {
00476         fmt.replace ( n, 2, subs ) ;
00477         n = fmt.find("%f") ;
00478       }
00479     }
00480 
00481     char buf[128] ;
00482     strftime(buf, 128, fmt.c_str(), &tms );
00483     return std::string( buf );
00484   }
00485 
00486 }
00487 

Generated at Mon Sep 7 18:05:43 2009 for Gaudi Framework, version v21r4 by Doxygen version 1.5.6 written by Dimitri van Heesch, © 1997-2004