Main Page | Modules | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

MsgStream.h

Go to the documentation of this file.
00001 
00002 // $Id: MsgStream.h,v 1.25 2006/10/28 05:07:14 gmieg Exp $
00003 //
00004 // MsgStream
00005 //
00006 // Allows messages to be filtered, formatted and send to one or many
00007 // output streams 
00008 //
00009 // messier@huhepl.harvard.edu
00011 #ifndef MSGSTREAM_H
00012 #define MSGSTREAM_H
00013 #ifndef IOSFWD
00014 #include <iosfwd>
00015 #define IOSFWD
00016 #endif
00017 #ifndef IOSTREAM
00018 #include <iostream> // Needed for __omanip and __manip and others
00019 #define IOSTREAM
00020 #endif
00021 #ifndef IOMANIP
00022 #include <iomanip> // Needed for smanip
00023 #define IOMANIP
00024 #endif
00025 #ifndef VECTOR
00026 #include <vector>
00027 #define VECTOR
00028 #endif
00029 #ifndef MAP
00030 #include <map>
00031 #endif
00032 #ifndef STRING
00033 #define STRING
00034 #include <string> // Needed for string << operator
00035 #endif
00036 #ifndef STDEXCEPT
00037 #define STDEXCEPT
00038 #include <stdexcept>
00039 #endif
00040 #ifndef MSG_H
00041 #include "MessageService/Msg.h"
00042 #endif
00043 #ifndef MSGOSTREAM_H
00044 #include "MessageService/MsgOStream.h"
00045 #endif
00046 #ifndef MSGSTATISTIC_H
00047 #include "MessageService/MsgStatistic.h"
00048 #endif
00049 
00050 class MsgBoundFormat;
00051 class MsgOStream;
00052 
00053 using namespace std;
00054 
00055 class MSGException : public std::runtime_error
00056 {
00057  public:
00058   MSGException() : std::runtime_error("MSGException") {}
00059 };
00060 
00061 //......................................................................
00062 
00063 class MsgStream
00064 {
00065   friend ostream& operator<<(ostream& os, const MsgStream& s);
00066 public:
00067   MsgStream();
00068   MsgStream(const char* name);
00069 
00070   bool            IsActive(Msg::LogLevel_t lvl) const { return lvl>=fLogLevel; }
00071   Msg::LogLevel_t GetLogLevel() const { return fLogLevel; };
00072   void            PrintStatistics(ostream& os);
00073 
00074   void AttachOStream(Msg::LogLevel_t lvl, const char *name);
00075   void DetachOStream(Msg::LogLevel_t lvl, const char *name);
00076   void Close();
00077   void Flush();
00078   void AddFormat(Msg::LogLevel_t lvl, int fmt);
00079   void RemoveFormat(Msg::LogLevel_t lvl, int fmt) { fFormat[lvl]&=(~fmt); }
00080   void SetLogLevel(Msg::LogLevel_t lvl);
00081   void SetFormat(Msg::LogLevel_t lvl, int fmt)    { fFormat[lvl] = fmt;   }
00082 
00083   MsgStream& operator()(Msg::LogLevel_t priority, const char* file, 
00084                         const char* cvsid, int line);
00085   void LogPrint(Msg::LogLevel_t priority, const char* file);
00086 
00087   //====================================================================
00088   // The set of << operators - basically these just loop over the
00089   // output streams attached to the message stream an use the <<
00090   // operator defined for that stream
00091   //
00092   // << operator for most normal classes
00093   template<class TP> MsgStream& operator<<(const TP& t) {
00094     if (fCurrentLogLevel >= fLogLevel) {
00095       vector<MsgOStream*>::iterator vend(fMsgOStream[fCurrentLogLevel].end());
00096       for (vector<MsgOStream*>::iterator 
00097              iter(fMsgOStream[fCurrentLogLevel].begin());
00098            iter != vend;
00099            ++iter) {
00100         (*iter)->Os() << t;
00101       }
00102     }
00103     return (*this);
00104   }
00105 
00106   // << operator for omanips...
00107   typedef std::ostream& (*__MSGomanip)(std::ostream&);
00108   MsgStream& operator<<(__MSGomanip func) {
00109     if (fCurrentLogLevel >= fLogLevel) {
00110       vector<MsgOStream*>::iterator vend(fMsgOStream[fCurrentLogLevel].end());
00111       for (vector<MsgOStream*>::iterator 
00112              iter(fMsgOStream[fCurrentLogLevel].begin());
00113            iter != vend;
00114            ++iter) {
00115         (*iter)->Os() << func;
00116       }
00117     }
00118     return (*this);
00119   }
00120 
00121   //====================================================================
00122   // Handle differences between gcc V3 and eariler versions here
00123   //====================================================================
00124 #if ( __GNUC__ >= 3)
00125   // << operator for ios_base...
00126   typedef ios_base& (*__MSGios_base)(ios_base&);
00127   MsgStream& operator<<(__MSGios_base iosb) {
00128     if (fCurrentLogLevel >= fLogLevel) {
00129       vector<MsgOStream*>::iterator vend(fMsgOStream[fCurrentLogLevel].end());
00130       for (vector<MsgOStream*>::iterator
00131              iter = fMsgOStream[fCurrentLogLevel].begin();
00132            iter != vend;
00133            ++iter) {
00134         (*iter)->Os() << iosb;
00135       }
00136     }
00137     return (*this);
00138   }
00139 #else // (__GNUC__ < 3)
00140   // << operator for manips...
00141   typedef ios& (*__MSGmanip)(ios&);
00142   MsgStream& operator<<(__MSGmanip func) {
00143     if (fCurrentLogLevel >= fLogLevel) {
00144       vector<MsgOStream*>::iterator vend(fMsgOStream[fCurrentLogLevel].end());
00145       for (vector<MsgOStream*>::iterator
00146              iter(fMsgOStream[fCurrentLogLevel].begin());
00147            iter != vend;
00148            ++iter) {
00149         (*iter)->Os() << func;
00150       }
00151     }
00152     return (*this);
00153   }
00154 #endif // __GNUC__
00155 
00156 private:
00157   void Init();
00158   void StatPrint(ostream& os, const char* label, int n) const;
00159   void SetCurrentDateString();
00160   void SetCVSVersion(const char* CVSId);
00161 
00162   enum { kMaxNameSize = 8 };
00163   char                fName[kMaxNameSize+1];        // Name of this MsgStream
00164   Msg::LogLevel_t     fLogLevel;                    // Threshold for print
00165   int                 fFormat[Msg::kNLogLevel];     // Formatting flags
00166   vector<MsgOStream*> fMsgOStream[Msg::kNLogLevel]; // Output streams
00167   map<string,MsgStatistic> fFileStat;          // Print stats by file name
00168   
00169   Msg::LogLevel_t fCurrentLogLevel; // The log level of messages being printed
00170   char fCurrentDate[32];            // Time stamp for current message
00171   char fCVSVersion[128];            // CVS version for current message
00172 };
00173 
00174 
00175 
00176 
00177 #endif // MSGSTREAM_H
00178 

Generated on Mon Jun 16 14:57:44 2008 for loon by  doxygen 1.3.9.1