BALL
1.4.1
|
00001 // -*- Mode: C++; tab-width: 2; -*- 00002 // vi: set ts=2: 00003 // 00004 00005 #ifndef BALL_COMMON_LOGSTREAM_H 00006 #define BALL_COMMON_LOGSTREAM_H 00007 00008 #ifndef BALL_CONFIG_CONFIG_H 00009 # include <BALL/CONFIG/config.h> 00010 #endif 00011 00012 #ifndef BALL_COMMON_GLOBAL_H 00013 # include <BALL/COMMON/global.h> 00014 #endif 00015 00016 #ifndef BALL_COMMON_DEBUG_H 00017 # include <BALL/COMMON/debug.h> 00018 #endif 00019 00020 #ifdef BALL_HAS_SYS_TIME_H 00021 # include <sys/time.h> 00022 #endif 00023 00024 #ifdef BALL_HAS_TIME_H 00025 # include <time.h> 00026 #endif 00027 00028 #ifdef BALL_HAS_SSTREAM 00029 # include <sstream> 00030 #else 00031 # include <strstream> 00032 #endif 00033 00034 #include <iostream> 00035 #include <list> 00036 #include <vector> 00037 #include <string> 00038 00039 00040 using std::list; 00041 using std::vector; 00042 using std::string; 00043 00044 namespace BALL 00045 { 00046 00071 00072 // forward declarations 00073 class LogStream; 00074 class LogStreamNotifier; 00075 00095 class BALL_EXPORT LogStreamBuf 00096 : public std::streambuf 00097 { 00098 00099 friend class LogStream; 00100 00101 public: 00102 00106 static const int MAX_LEVEL; 00107 static const int MIN_LEVEL; 00108 static const Time MAX_TIME; 00110 00114 00118 LogStreamBuf(); 00119 00123 virtual ~LogStreamBuf(); 00124 00126 00127 00131 00136 virtual void dump(std::ostream& s); 00137 00139 00143 00154 virtual int sync(); 00155 00156 int sync(bool force_flush); 00157 00162 virtual int overflow(int c = -1); 00164 00165 BALL_EXPORT struct StreamStruct 00166 { 00167 std::ostream* stream; 00168 string prefix; 00169 int min_level; 00170 int max_level; 00171 LogStreamNotifier* target; 00172 bool disabled; 00173 00174 StreamStruct() 00175 : stream(0), 00176 min_level(MIN_LEVEL), 00177 max_level(MAX_LEVEL), 00178 target(0) 00179 { 00180 } 00181 00182 // Delete the notification target. 00183 ~StreamStruct() 00184 { 00185 } 00186 }; 00187 00188 00189 protected: 00190 00191 struct LoglineStruct 00192 { 00193 int level; 00194 string text; 00195 Time time; 00196 00197 LoglineStruct() 00198 : level(0), 00199 text(""), 00200 time(0) 00201 {} 00202 }; 00203 00204 typedef struct LoglineStruct Logline; 00205 00206 00207 // interpret the prefix format string and return the expanded prefix 00208 string expandPrefix_(const string& prefix, int level, Time time) const; 00209 00210 char* pbuf_; 00211 00212 vector<Logline> loglines_; 00213 00214 int level_; 00215 00216 int tmp_level_; 00217 00218 list<StreamStruct> stream_list_; 00219 00220 string incomplete_line_; 00221 }; 00222 00223 00225 class BALL_EXPORT LogStreamNotifier 00226 { 00227 public: 00228 00230 LogStreamNotifier(); 00231 00233 virtual ~LogStreamNotifier(); 00234 00236 virtual void logNotify(); 00237 00239 void registerAt(LogStream& log_stream, 00240 int min_level = LogStreamBuf::MIN_LEVEL, 00241 int max_level = LogStreamBuf::MAX_LEVEL); 00243 void unregister(); 00244 00245 protected: 00246 00247 std::stringstream stream_; 00248 00249 LogStream* registered_at_; 00250 }; 00251 00252 00253 00259 class BALL_EXPORT LogStream 00260 : public std::ostream 00261 { 00262 public: 00263 00264 00268 00276 enum LogStreamLevel 00277 { 00281 ERROR_LEVEL = 2000 , 00282 00285 WARNING_LEVEL = 1000, 00288 INFORMATION_LEVEL = 0 00289 }; 00290 00292 00296 00307 LogStream(LogStreamBuf* buf = 0, bool delete_buf = true, bool associate_stdio = false); 00308 00312 virtual ~LogStream(); 00313 00315 00319 00323 LogStreamBuf* rdbuf(); 00324 00327 LogStreamBuf* operator -> (); 00329 00333 00340 void setLevel(int level); 00341 00349 int getLevel(); 00350 00364 LogStream& level(int level); 00365 00370 LogStream& info(int n = 0); 00371 00376 LogStream& error(int n = 0); 00377 00382 LogStream& warn(int n = 0); 00383 00385 00389 00404 void insert 00405 (std::ostream& s, int min_level = LogStreamBuf::MIN_LEVEL, 00406 int max_level = LogStreamBuf::MAX_LEVEL); 00407 00415 void remove(std::ostream& s); 00416 00419 void insertNotification(std::ostream& s, 00420 LogStreamNotifier& target, 00421 int min_level = LogStreamBuf::MIN_LEVEL, 00422 int max_level = LogStreamBuf::MAX_LEVEL); 00423 00431 void setMinLevel(const std::ostream& s, int min_level); 00432 00440 void setMaxLevel(const std::ostream& s, int max_level); 00441 00460 void setPrefix(const std::ostream& s, const string& prefix); 00461 00463 void disableOutput() ; 00464 00466 void enableOutput() ; 00467 00469 bool outputEnabled() const 00470 ; 00471 00474 std::ostream& flush(); 00475 00477 00480 00485 void clear(); 00486 00496 Size getNumberOfLines 00497 (int min_level = LogStreamBuf::MIN_LEVEL, 00498 int max_level = LogStreamBuf::MAX_LEVEL) const; 00499 00506 string getLineText(const Index& index) const; 00507 00512 Time getLineTime(const Index& index) const; 00513 00519 int getLineLevel(const Index& index) const; 00520 00529 list<int> filterLines 00530 (int min_level = LogStreamBuf::MIN_LEVEL, int max_level = LogStreamBuf::MAX_LEVEL, 00531 Time earliest = 0, Time latest = LogStreamBuf::MAX_TIME, 00532 const string& s = "") const; 00534 00535 private: 00536 00537 typedef std::list<LogStreamBuf::StreamStruct>::iterator StreamIterator; 00538 00539 StreamIterator findStream_(const std::ostream& stream); 00540 bool hasStream_(std::ostream& stream); 00541 bool bound_() const; 00542 00543 // flag needed by the destructor to decide whether the streambuf 00544 // has to be deleted. If the default ctor is used to create 00545 // the LogStreamBuf, delete_buffer_ is set to true and the ctor 00546 // also deletes the buffer. 00547 bool delete_buffer_; 00548 bool disable_output_; 00549 }; 00550 00551 00556 BALL_EXPORT extern LogStream Log; 00557 00559 00560 # ifndef BALL_NO_INLINE_FUNCTIONS 00561 # include <BALL/COMMON/logStream.iC> 00562 # endif 00563 00564 } // namespace BALL 00565 00566 #endif // BALL_COMMON_LOGSTREAM_H