File indexing completed on 2025-01-18 09:57:41
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011 #ifndef GAUDIKERNEL_MSGSTREAM_H
0012 #define GAUDIKERNEL_MSGSTREAM_H
0013
0014
0015 #include "GaudiKernel/IMessageSvc.h"
0016 #include "GaudiKernel/SerializeSTL.h"
0017
0018 #include <cstdio>
0019 #include <iomanip>
0020 #include <sstream>
0021 #include <string>
0022 #include <vector>
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034 class MsgStream {
0035 private:
0036
0037
0038
0039 typedef std::ios_base::fmtflags FLAG_TYPE;
0040 typedef std::ios_base::iostate STATE_TYPE;
0041
0042 protected:
0043
0044 IMessageSvc* m_service;
0045
0046 std::string m_buffer;
0047
0048 std::string m_source;
0049
0050 std::ostringstream m_stream;
0051
0052 bool m_active = false;
0053
0054 MSG::Level m_level;
0055
0056 MSG::Level m_currLevel;
0057
0058 bool m_useColors;
0059
0060
0061 IInactiveMessageCounter* m_inactCounter = nullptr;
0062
0063 static bool m_countInactive;
0064
0065 public:
0066
0067 GAUDI_API MsgStream( IMessageSvc* svc, int buffer_length = 128 );
0068
0069 GAUDI_API MsgStream( IMessageSvc* svc, std::string source, int buffer_length = 128 );
0070
0071 MsgStream( const MsgStream& msg )
0072 : m_service( msg.m_service )
0073 , m_active( msg.m_active )
0074 , m_level( msg.m_level )
0075 , m_currLevel( msg.m_currLevel )
0076 , m_useColors( msg.m_useColors )
0077 , m_inactCounter( msg.m_inactCounter ) {
0078 try {
0079 m_source = msg.m_source;
0080 } catch ( ... ) {}
0081 }
0082
0083 GAUDI_API virtual ~MsgStream() = default;
0084
0085 MsgStream& report( int lvl ) {
0086 lvl = ( lvl >= MSG::NUM_LEVELS ) ? MSG::ALWAYS : ( lvl < MSG::NIL ) ? MSG::NIL : lvl;
0087 if ( ( m_currLevel = MSG::Level( lvl ) ) >= level() ) {
0088 activate();
0089 } else {
0090 deactivate();
0091 #ifndef NDEBUG
0092 if ( MsgStream::countInactive() && m_inactCounter ) {
0093 m_inactCounter->incrInactiveCount( MSG::Level( lvl ), m_source );
0094 }
0095 #endif
0096 }
0097 return *this;
0098 }
0099
0100 virtual GAUDI_API MsgStream& doOutput();
0101
0102 const std::string& buffer() const { return m_buffer; }
0103
0104 std::ostringstream& stream() { return m_stream; }
0105
0106 void setMsgSvc( IMessageSvc* svc ) { m_service = svc; }
0107
0108 void setLevel( int level ) {
0109 level = ( level >= MSG::NUM_LEVELS ) ? MSG::ALWAYS : ( level < MSG::NIL ) ? MSG::NIL : level;
0110 m_level = MSG::Level( level );
0111 }
0112
0113 MSG::Level level() const { return m_level; }
0114
0115 MSG::Level currentLevel() const { return m_currLevel; }
0116
0117 void activate() { m_active = true; }
0118
0119 void deactivate() { m_active = false; }
0120
0121 bool isActive() const { return m_active; }
0122
0123 MsgStream& flush() {
0124 if ( isActive() ) m_stream.flush();
0125 return *this;
0126 }
0127
0128 MsgStream& write( const char* buff, int len ) {
0129 if ( isActive() ) m_stream.write( buff, len );
0130 return *this;
0131 }
0132
0133 MsgStream& operator<<( MsgStream& ( *_f )(MsgStream&)) {
0134 if ( isActive() ) _f( *this );
0135 return *this;
0136 }
0137
0138 MsgStream& operator<<( std::ostream& ( *_f )(std::ostream&)) {
0139 if ( isActive() ) _f( m_stream );
0140 return *this;
0141 }
0142
0143 MsgStream& operator<<( std::ios& ( *_f )(std::ios&)) {
0144 if ( isActive() ) _f( m_stream );
0145 return *this;
0146 }
0147
0148 MsgStream& operator<<( MSG::Level level ) { return report( level ); }
0149 MsgStream& operator<<( long long arg ) {
0150 try {
0151
0152 if ( isActive() ) { m_stream << arg; }
0153 } catch ( ... ) {}
0154 return *this;
0155 }
0156
0157
0158 MsgStream& operator<<( std::ios_base& ( *_f )(std::ios_base&)) {
0159 if ( isActive() ) _f( m_stream );
0160 return *this;
0161 }
0162
0163
0164 std::streamsize width() const { return isActive() ? m_stream.width() : 0; }
0165 std::streamsize width( std::streamsize v ) { return isActive() ? m_stream.width( v ) : 0; }
0166 std::streamsize precision() const { return isActive() ? m_stream.precision() : 0; }
0167 std::streamsize precision( int v ) { return isActive() ? m_stream.precision( v ) : 0; }
0168
0169 long flags() const { return isActive() ? m_stream.flags() : 0; }
0170 long flags( FLAG_TYPE v ) { return isActive() ? m_stream.flags( v ) : 0; }
0171 long setf( FLAG_TYPE v ) { return isActive() ? m_stream.setf( v ) : 0; }
0172 char fill() const { return isActive() ? m_stream.fill() : (char)-1; }
0173 char fill( char v ) { return isActive() ? m_stream.fill( v ) : (char)-1; }
0174 int rdstate() const { return isActive() ? m_stream.rdstate() : std::ios_base::failbit; }
0175 bool good() const { return isActive() && m_stream.good(); }
0176 bool eof() const { return isActive() && m_stream.eof(); }
0177 bool bad() const { return isActive() && m_stream.bad(); }
0178 int setf( FLAG_TYPE _f, FLAG_TYPE _m ) { return isActive() ? m_stream.setf( _f, _m ) : 0; }
0179 void unsetf( FLAG_TYPE _l ) {
0180 if ( isActive() ) m_stream.unsetf( _l );
0181 }
0182 void clear( STATE_TYPE _i = std::ios_base::failbit ) {
0183 if ( isActive() ) m_stream.clear( _i );
0184 }
0185
0186
0187 GAUDI_API void setColor( MSG::Color col );
0188
0189 GAUDI_API void setColor( MSG::Color fg, MSG::Color bg );
0190
0191
0192 GAUDI_API void resetColor();
0193
0194
0195
0196 static GAUDI_API bool enableCountInactive( bool value = true );
0197
0198
0199 static GAUDI_API bool countInactive();
0200 };
0201
0202
0203 inline MsgStream& endmsg( MsgStream& s ) { return s.doOutput(); }
0204
0205
0206 GAUDI_API std::string format( const char*, ... );
0207
0208 #ifdef _WIN32
0209 template <class _E>
0210 inline MsgStream& operator<<( MsgStream& s, const std::_Fillobj<_E>& obj ) {
0211 # if _MSC_VER > 1300
0212 if ( s.isActive() ) s.stream().fill( obj._Fill );
0213 # else
0214 if ( s.isActive() ) s.stream().fill( obj._Ch );
0215 # endif
0216 return s;
0217 }
0218 template <class _Tm>
0219 inline MsgStream& operator<<( MsgStream& s, const std::_Smanip<_Tm>& manip ) {
0220 # if _MSC_VER > 1300
0221 if ( s.isActive() ) ( *manip._Pfun )( s.stream(), manip._Manarg );
0222 # else
0223 if ( s.isActive() ) ( *manip._Pf )( s.stream(), manip._Manarg );
0224 # endif
0225 return s;
0226 }
0227 #elif defined( __GNUC__ )
0228 # ifndef __APPLE__
0229 inline MsgStream& operator<<( MsgStream& s, const std::_Setiosflags& manip ) {
0230 try {
0231
0232 if ( s.isActive() ) s.stream() << manip;
0233 } catch ( ... ) {}
0234 return s;
0235 }
0236 inline MsgStream& operator<<( MsgStream& s, const std::_Resetiosflags& manip ) {
0237 try {
0238
0239 if ( s.isActive() ) s.stream() << manip;
0240 } catch ( ... ) {}
0241 return s;
0242 }
0243 inline MsgStream& operator<<( MsgStream& s, const std::_Setbase& manip ) {
0244 try {
0245
0246 if ( s.isActive() ) s.stream() << manip;
0247 } catch ( ... ) {}
0248 return s;
0249 }
0250 inline MsgStream& operator<<( MsgStream& s, const std::_Setprecision& manip ) {
0251 try {
0252
0253 if ( s.isActive() ) s.stream() << manip;
0254 } catch ( ... ) {}
0255 return s;
0256 }
0257 inline MsgStream& operator<<( MsgStream& s, const std::_Setw& manip ) {
0258 try {
0259
0260 if ( s.isActive() ) s.stream() << manip;
0261 } catch ( ... ) {}
0262 return s;
0263 }
0264 # endif
0265 #else
0266
0267 template <class _Tm>
0268 inline MsgStream& operator<<( MsgStream& s, const std::smanip<_Tm>& manip ) {
0269 try {
0270
0271 if ( s.isActive() ) s.stream() << manip;
0272 } catch ( ... ) {}
0273 return s;
0274 }
0275 #endif
0276
0277 namespace MSG {
0278 inline MsgStream& dec( MsgStream& log ) {
0279 log << std::dec;
0280 return log;
0281 }
0282 inline MsgStream& hex( MsgStream& log ) {
0283 log << std::hex;
0284 return log;
0285 }
0286 }
0287
0288
0289
0290 inline MsgStream& operator<<( MsgStream& s, const char* arg ) {
0291 try {
0292
0293 if ( s.isActive() ) s.stream() << arg;
0294 } catch ( ... ) {}
0295 return s;
0296 }
0297
0298
0299 template <typename T>
0300 MsgStream& operator<<( MsgStream& lhs, const T& arg ) {
0301 using namespace GaudiUtils;
0302 if ( lhs.isActive() ) try {
0303
0304 lhs.stream() << arg;
0305 } catch ( ... ) {}
0306 return lhs;
0307 }
0308
0309 #if defined( __GNUC__ ) and not defined( __APPLE__ )
0310
0311 template <typename T>
0312 MsgStream& operator<<( MsgStream& lhs, const std::_Setfill<T>& manip ) {
0313 if ( lhs.isActive() ) try {
0314
0315 lhs.stream() << manip;
0316 } catch ( ... ) {}
0317 return lhs;
0318 }
0319 #endif
0320
0321 #endif