UniSet  2.0.0
DebugExtBuf.h
00001 #ifndef DEBUGEXTBUF_H
00002 #define DEBUGEXTBUF_H
00003 
00004 // Created by Lars Gullik Bj�nnes
00005 // Copyright 1999 Lars Gullik Bj�nnes (larsbj@lyx.org)
00006 // Released into the public domain.
00007 
00008 // Primarily developed for use in the LyX Project http://www.lyx.org/
00009 // but should be adaptable to any project.
00010 
00011 // (c) 2002 adapted for UniSet by Lav, GNU GPL license
00012 
00013 //#define TEST_DEBUGSTREAM
00014 
00015 
00016 #ifdef __GNUG__
00017 #pragma implementation
00018 #endif
00019 
00020 //#include "DebugStream.h"
00021 #include "Debug.h"
00022 #include "Mutex.h"
00023 
00024 //�Since the current C++ lib in egcs does not have a standard implementation
00025 // of basic_streambuf and basic_filebuf we don't have to include this
00026 // header.
00027 //#define MODERN_STL_STREAMS
00028 #ifdef MODERN_STL_STREAMS
00029 #include <fstream>
00030 #endif
00031 #include <iostream>
00032 #include <sstream>
00033 #include <iomanip>
00034 #include <time.h>
00035 #include <iomanip>
00036 
00037 using std::ostream;
00038 using std::streambuf;
00039 using std::streamsize;
00040 using std::filebuf;
00041 using std::stringbuf;
00042 using std::cerr;
00043 using std::ios;
00044 
00045 /*
00046 ostream & operator<<(ostream & o, Debug::type t)
00047 {
00048     return o << int(t);
00049 }
00050 */
00051 
00056 class nullbuf : public streambuf {
00057 protected:
00058 #ifndef MODERN_STL_STREAMS
00059     typedef char char_type;
00060     typedef int int_type;
00062     virtual int sync() { return 0; }
00063 #endif
00064 
00065     virtual streamsize xsputn(char_type const *, streamsize n) {
00066         // fakes a purge of the buffer by returning n
00067         return n;
00068     }
00069 #ifdef MODERN_STL_STREAMS
00070 
00071     virtual int_type overflow(int_type c = traits_type::eof()) {
00072         // fakes success by returning c
00073         return c == traits_type::eof() ? ' ' : c;
00074     }
00075 #else
00076 
00077     virtual int_type overflow(int_type c = EOF) {
00078         // fakes success by returning c
00079         return c == EOF ? ' ' : c;
00080     }
00081 #endif
00082 };
00083 
00087 class teebuf : public streambuf {
00088 public:
00090     teebuf(streambuf * b1, streambuf * b2)
00091         : streambuf(), sb1(b1), sb2(b2) {}
00092 protected:
00093 #ifdef MODERN_STL_STREAMS
00094 
00095     virtual int sync() {
00096         sb2->pubsync();
00097         return sb1->pubsync();
00098     }
00100     virtual streamsize xsputn(char_type const * p, streamsize n) {
00101         sb2->sputn(p, n);
00102         return sb1->sputn(p, n);
00103     }
00105     virtual int_type overflow(int_type c = traits_type::eof()) {
00106         sb2->sputc(c);
00107         return sb1->sputc(c);
00108     }
00109 #else
00110     typedef char char_type;
00111     typedef int int_type;
00113     virtual int sync() {
00114         sb2->sync();
00115         return sb1->sync();
00116     }
00118     virtual streamsize xsputn(char_type const * p, streamsize n) {
00119         sb2->xsputn(p, n);
00120         return sb1->xsputn(p, n);
00121     }
00123     virtual int_type overflow(int_type c = EOF) {
00124         sb2->overflow(c);
00125         return sb1->overflow(c);
00126     }
00127 #endif
00128 private:
00130     streambuf * sb1;
00132     streambuf * sb2;
00133 };
00134 
00138 class threebuf : public streambuf {
00139 public:
00141     threebuf(streambuf * b1, streambuf * b2, streambuf * b3)
00142         : streambuf(), sb1(b1), sb2(b2), sb3(b3) {}
00143 protected:
00144 #ifdef MODERN_STL_STREAMS
00145 
00146     virtual int sync() {
00147         sb2->pubsync();
00148         return sb1->pubsync();
00149     }
00151     virtual streamsize xsputn(char_type const * p, streamsize n) {
00152         sb2->sputn(p, n);
00153         sb3->sputn(p, n);
00154         return sb1->sputn(p, n);
00155     }
00157     virtual int_type overflow(int_type c = traits_type::eof()) {
00158         sb2->sputc(c);
00159         sb3->sputc(c);
00160         return sb1->sputc(c);
00161     }
00162 #else
00163     typedef char char_type;
00164     typedef int int_type;
00166     virtual int sync() {
00167         sb2->sync();
00168         sb3->sync();
00169         return sb1->sync();
00170     }
00172     virtual streamsize xsputn(char_type const * p, streamsize n) {
00173         sb2->xsputn(p, n);
00174         sb2->xsputn(p, n);
00175         return sb1->xsputn(p, n);
00176     }
00178     virtual int_type overflow(int_type c = EOF) {
00179         sb2->overflow(c);
00180         sb3->owerflow(c);
00181         return sb1->overflow(c);
00182     }
00183 #endif
00184 private:
00186     streambuf * sb1;
00188     streambuf * sb2;
00190     streambuf * sb3;
00191 };
00192 
00194 class debugbuf : public streambuf {
00195 public:
00197     debugbuf(streambuf * b)
00198         : streambuf(), sb(b) {}
00199 protected:
00200 #ifdef MODERN_STL_STREAMS
00201 
00202     virtual int sync() {
00203         return sb->pubsync();
00204     }
00206     virtual streamsize xsputn(char_type const * p, streamsize n) {
00207         return sb->sputn(p, n);
00208     }
00210     virtual int_type overflow(int_type c = traits_type::eof()) {
00211         return sb->sputc(c);
00212     }
00213 #else
00214     typedef char char_type;
00215     typedef int int_type;
00217     virtual int sync() {
00218         return sb->sync();
00219     }
00221     virtual streamsize xsputn(char_type const * p, streamsize n) {
00222         return sb->xsputn(p, n);
00223     }
00225     virtual int_type overflow(int_type c = EOF) {
00226         return sb->overflow(c);
00227     }
00228 #endif
00229 private:
00231     streambuf * sb;
00232 };
00233 
00235 class stringsigbuf : public streambuf {
00236 public:
00237     stringsigbuf():sb(new stringbuf())
00238     {
00239     }
00240 
00241     ~stringsigbuf()
00242     {
00243         if( sb )
00244         {
00245             delete sb;
00246             sb = 0;
00247         }
00248     }
00249 
00251     stringsigbuf( stringbuf* b )
00252         : streambuf(), sb(b) {}
00253 
00254     typedef sigc::signal<void,const std::string&> StrBufOverflow_Signal;
00255     inline StrBufOverflow_Signal signal_overflow(){ return s_overflow; }
00256 
00257 protected:
00258 #ifdef MODERN_STL_STREAMS
00259 
00260     virtual int sync() {
00261         UniSetTypes::uniset_rwmutex_wrlock l(mut);
00262         return sb->pubsync();
00263     }
00264 
00266     virtual streamsize xsputn(char_type const * p, streamsize n) {
00267         UniSetTypes::uniset_rwmutex_wrlock l(mut);
00268         streamsize r = sb->sputn(p, n);
00269         s_overflow.emit( sb->str() );
00270         sb->str("");
00271         return r;
00272     }
00274     virtual int_type overflow(int_type c = traits_type::eof()) {
00275         int_type r = sb->sputc(c);
00276         if( r == '\n' )
00277         {
00278             UniSetTypes::uniset_rwmutex_wrlock l(mut);
00279             s_overflow.emit( sb->str() );
00280             sb->str("");
00281         }
00282         return r;
00283     }
00284 #else
00285     typedef char char_type;
00286     typedef int int_type;
00288     virtual int sync() {
00289         return sb->sync();
00290     }
00292     virtual streamsize xsputn(char_type const * p, streamsize n) {
00293         return sb->xsputn(p, n);
00294     }
00295 
00296     virtual int_type overflow(int_type c = EOF) {
00297         int_type r = sb->overflow(c);
00298         if( r == '\n' )
00299         {
00300             UniSetTypes::uniset_rwmutex_wrlock l(mut);
00301             s_overflow.emit( sb->str() );
00302             sb->str("");
00303         }
00304         return r;
00305     }
00306 #endif
00307 private:
00309     StrBufOverflow_Signal s_overflow;
00310     stringbuf* sb;
00311     UniSetTypes::uniset_rwmutex mut;
00312 };
00313 //--------------------------------------------------------------------------
00315 struct DebugStream::debugstream_internal {
00317     filebuf fbuf;
00318     stringsigbuf sbuf;
00319     nullbuf nbuf;
00320 };
00321 //--------------------------------------------------------------------------
00322 #endif