Gaudi Framework, version v23r4

Home   Generated: Mon Sep 17 2012

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 #include "GaudiKernel/Time.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   // get the current time from the system and format it according to the format
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 // Routine: Constructor.
00042 // Purpose:
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 // Routine: Constructor.
00055 // Purpose:
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 // Routine: Constructor.
00068 // Purpose:
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 // Routine: getMessage
00081 // Purpose: Get the message string.
00082 // ---------------------------------------------------------------------------
00083 //
00084 const std::string& Message::getMessage() const
00085 {
00086   return m_message;
00087 }
00088 
00089 //#############################################################################
00090 // ---------------------------------------------------------------------------
00091 // Routine: setMessage
00092 // Purpose: Set the message string.
00093 // ---------------------------------------------------------------------------
00094 //
00095 void Message::setMessage( const std::string& msg )
00096 {
00097   m_message = msg;
00098 }
00099 
00100 //#############################################################################
00101 // ---------------------------------------------------------------------------
00102 // Routine: getType
00103 // Purpose: Get the message type.
00104 // ---------------------------------------------------------------------------
00105 //
00106 int Message::getType() const
00107 {
00108   return m_type;
00109 }
00110 
00111 //#############################################################################
00112 // ---------------------------------------------------------------------------
00113 // Routine: setType
00114 // Purpose: Set the message type.
00115 // ---------------------------------------------------------------------------
00116 //
00117 void Message::setType( int msg_type )
00118 {
00119   m_type = msg_type;
00120 }
00121 
00122 //#############################################################################
00123 // ---------------------------------------------------------------------------
00124 // Routine: getSource
00125 // Purpose: Get the message source.
00126 // ---------------------------------------------------------------------------
00127 //
00128 const std::string& Message::getSource() const
00129 {
00130   return m_source;
00131 }
00132 
00133 //#############################################################################
00134 // ---------------------------------------------------------------------------
00135 // Routine: setSource
00136 // Purpose: Set the message source.
00137 // ---------------------------------------------------------------------------
00138 //
00139 void Message::setSource( const std::string& src )
00140 {
00141   m_source = src;
00142 }
00143 
00144 //#############################################################################
00145 // ---------------------------------------------------------------------------
00146 // Routine: operator <<
00147 // Purpose:Insert the message into a stream.
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 // Routine: operator <
00160 // Purpose: comparison operator needed for maps
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 // Routine: operator ==
00173 // Purpose: comparison op.
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 // Routine:
00186 // Purpose: Get the format string.
00187 // ---------------------------------------------------------------------------
00188 //
00189 const std::string& Message::getFormat() const
00190 {
00191   return m_format;
00192 }
00193 
00194 //#############################################################################
00195 // ---------------------------------------------------------------------------
00196 // Routine:
00197 // Purpose: Get the default format string.
00198 // ---------------------------------------------------------------------------
00199 //
00200 const std::string Message::getDefaultFormat()
00201 {
00202   return DEFAULT_FORMAT;
00203 }
00204 
00205 
00206 //#############################################################################
00207 // ---------------------------------------------------------------------------
00208 // Routine:
00209 // Purpose: Set the format string -
00210 //          use isFormatted() to check for valid format.
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 // Routine:
00224 // Purpose: Get the time format string.
00225 // ---------------------------------------------------------------------------
00226 //
00227 const std::string& Message::getTimeFormat() const
00228 {
00229   return m_time_format;
00230 }
00231 
00232 //#############################################################################
00233 // ---------------------------------------------------------------------------
00234 // Routine:
00235 // Purpose: Get the default time format string.
00236 // ---------------------------------------------------------------------------
00237 //
00238 const std::string Message::getDefaultTimeFormat()
00239 {
00240   return DEFAULT_TIME_FORMAT ;
00241 }
00242 
00243 
00244 //#############################################################################
00245 // ---------------------------------------------------------------------------
00246 // Routine:
00247 // Purpose: Set the time format string -
00248 //          use isFormatted() to check for valid format.
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 // Routine: makeFormattedMsg
00262 // Purpose: This formats the message according to the format string.
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     // Output format string until format statement found.
00272     while(  i != format.end() && *i != FORMAT_PREFIX )
00273       m_formatted_msg += *i++;
00274 
00275     // Test for end of format string.
00276     if ( i == format.end() ) break;
00277     i++;
00278 
00279     // Find type of formatting.
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     // Reached end of string with improper format.
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 // Routine: decodeFormat
00302 // Purpose: This the work horse that check for a valid format string.
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     // Now test the format.
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 // Routine: invalidFormat.
00377 // Purpose: called when invalid format found.
00378 // ---------------------------------------------------------------------------
00379 //
00380 
00381 void Message::invalidFormat() const
00382 {
00383   makeFormattedMsg( DEFAULT_FORMAT );
00384 }
00385 
00386 //#############################################################################
00387 // ---------------------------------------------------------------------------
00388 // Routine: setWidth
00389 // Purpose: Sets the minimum width of a stream field.
00390 // ---------------------------------------------------------------------------
00391 //
00392 
00393 void Message::setWidth( const std::string& formatArg ) const
00394 {
00395   // Check that the parameters are only digits.
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   // Convert string to int.
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 // Routine: sizeField
00420 // Purpose: Truncates or pads the text to m_width as necessary
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     // Truncate the text if it is too long.
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     // Pad the text.
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 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Defines

Generated at Mon Sep 17 2012 13:49:29 for Gaudi Framework, version v23r4 by Doxygen version 1.7.2 written by Dimitri van Heesch, © 1997-2004