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