Main Page   Namespace List   Class Hierarchy   Compound List   File List   Namespace Members   Compound Members   File Members  

Message.cpp

Go to the documentation of this file.
00001 // $Header: /nfs/slac/g/glast/ground/cvs/GaudiKernel/src/Lib/Message.cpp,v 1.1.1.1 2001/04/18 18:14:18 tlindner Exp $
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 // Formatting string characters.
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 //const char* Message::DEFAULT_FORMAT = "% F%67W%L#############################################################################\n-----------------------------------------------------------------------------\nMessage follows...\nSource  : %S\nType    : %T\nMessage : %M\nEnd of message.\n-----------------------------------------------------------------------------\n";
00022 const char* Message::DEFAULT_FORMAT = "% F%18W%S%7W%R%T %0W%M";
00023 
00024 //#############################################################################
00025 // ---------------------------------------------------------------------------
00026 // Routine: Constructor.
00027 // Purpose:
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 // Routine: Constructor.
00039 // Purpose:
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 // Routine: Constructor.
00051 // Purpose:
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 // Routine: getMessage
00063 // Purpose: Get the message string.
00064 // ---------------------------------------------------------------------------
00065 //
00066 const std::string& Message::getMessage() const
00067 { 
00068   return m_message; 
00069 }
00070 
00071 //#############################################################################
00072 // ---------------------------------------------------------------------------
00073 // Routine: setMessage
00074 // Purpose: Set the message string.
00075 // ---------------------------------------------------------------------------
00076 //
00077 void Message::setMessage( const std::string& msg ) 
00078 { 
00079   m_message = msg; 
00080 }
00081 
00082 //#############################################################################
00083 // ---------------------------------------------------------------------------
00084 // Routine: getType
00085 // Purpose: Get the message type.
00086 // ---------------------------------------------------------------------------
00087 //
00088 int Message::getType() const 
00089 { 
00090   return m_type; 
00091 }
00092 
00093 //#############################################################################
00094 // ---------------------------------------------------------------------------
00095 // Routine: setType
00096 // Purpose: Set the message type.
00097 // ---------------------------------------------------------------------------
00098 //
00099 void Message::setType( int msg_type ) 
00100 { 
00101   m_type = msg_type; 
00102 }
00103 
00104 //#############################################################################
00105 // ---------------------------------------------------------------------------
00106 // Routine: getSource
00107 // Purpose: Get the message source.
00108 // ---------------------------------------------------------------------------
00109 //
00110 const std::string& Message::getSource() const 
00111 { 
00112   return m_source; 
00113 }
00114 
00115 //#############################################################################
00116 // ---------------------------------------------------------------------------
00117 // Routine: setSource
00118 // Purpose: Set the message source.
00119 // ---------------------------------------------------------------------------
00120 //
00121 void Message::setSource( const std::string& src ) 
00122 { 
00123   m_source = src; 
00124 }
00125   
00126 //#############################################################################
00127 // ---------------------------------------------------------------------------
00128 // Routine: operator << 
00129 // Purpose:Insert the message into a stream.
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 // Routine: operator <
00142 // Purpose: comparison operator needed for maps
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 // Routine: operator == 
00155 // Purpose: comparison op.
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 // Routine: 
00168 // Purpose: Get the format string.
00169 // ---------------------------------------------------------------------------
00170 //
00171 const std::string& Message::getFormat() const
00172 {
00173   return m_format;
00174 }
00175 
00176 //#############################################################################
00177 // ---------------------------------------------------------------------------
00178 // Routine: 
00179 // Purpose: Set the format string - 
00180 //          use isFormatted() to check for valid format.
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 // Routine: makeFormattedMsg
00194 // Purpose: This formats the message according to the format string.
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     // Output format string until format statement found.
00204     while(  i != format.end() && *i != FORMAT_PREFIX ) 
00205       m_formatted_msg += *i++;
00206 
00207     // Test for end of format string.
00208     if ( i == format.end() ) break;
00209     i++;
00210 
00211     // Find type of formatting.
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     // Reached end of string with improper format.
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 // Routine: decodeFormat
00234 // Purpose: This the work horse that check for a valid format string.
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     // Now test the format.
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 // Routine: invalidFormat.
00295 // Purpose: called when invalid format found.
00296 // ---------------------------------------------------------------------------
00297 //
00298 
00299 void Message::invalidFormat() const
00300 {
00301   makeFormattedMsg( DEFAULT_FORMAT );
00302 }
00303 
00304 //#############################################################################
00305 // ---------------------------------------------------------------------------
00306 // Routine: setWidth
00307 // Purpose: Sets the minimum width of a stream field.
00308 // ---------------------------------------------------------------------------
00309 //
00310 
00311 void Message::setWidth( const std::string& formatArg ) const
00312 {
00313   // Check that the parameters are only digits.
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   // Convert string to int.
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 // Routine: sizeField
00338 // Purpose: Truncates or pads the text to m_width as necessary
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     // Truncate the text if it is too long.
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     // Pad the text.
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 }

Generated at Wed Nov 21 12:22:04 2001 by doxygen1.2.3 written by Dimitri van Heesch, © 1997-2000