Gaudi Framework, version v22r0

Home   Generated: 9 Feb 2011

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

Generated at Wed Feb 9 16:24:55 2011 for Gaudi Framework, version v22r0 by Doxygen version 1.6.2 written by Dimitri van Heesch, © 1997-2004