UniSet  2.2.1
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 {
00058     protected:
00059 #ifndef MODERN_STL_STREAMS
00060         typedef char char_type;
00061         typedef int int_type;
00063         virtual int sync()
00064         {
00065             return 0;
00066         }
00067 #endif
00068 
00069         virtual streamsize xsputn(char_type const*, streamsize n)
00070         {
00071             // fakes a purge of the buffer by returning n
00072             return n;
00073         }
00074 #ifdef MODERN_STL_STREAMS
00075 
00076         virtual int_type overflow(int_type c = traits_type::eof())
00077         {
00078             // fakes success by returning c
00079             return c == traits_type::eof() ? ' ' : c;
00080         }
00081 #else
00082 
00083         virtual int_type overflow(int_type c = EOF)
00084         {
00085             // fakes success by returning c
00086             return c == EOF ? ' ' : c;
00087         }
00088 #endif
00089 };
00090 
00094 class teebuf : public streambuf
00095 {
00096     public:
00098         teebuf(streambuf* b1, streambuf* b2)
00099             : streambuf(), sb1(b1), sb2(b2) {}
00100     protected:
00101 #ifdef MODERN_STL_STREAMS
00102 
00103         virtual int sync()
00104         {
00105             sb2->pubsync();
00106             return sb1->pubsync();
00107         }
00109         virtual streamsize xsputn(char_type const* p, streamsize n)
00110         {
00111             sb2->sputn(p, n);
00112             return sb1->sputn(p, n);
00113         }
00115         virtual int_type overflow(int_type c = traits_type::eof())
00116         {
00117             sb2->sputc(c);
00118             return sb1->sputc(c);
00119         }
00120 #else
00121         typedef char char_type;
00122         typedef int int_type;
00124         virtual int sync()
00125         {
00126             sb2->sync();
00127             return sb1->sync();
00128         }
00130         virtual streamsize xsputn(char_type const* p, streamsize n)
00131         {
00132             sb2->xsputn(p, n);
00133             return sb1->xsputn(p, n);
00134         }
00136         virtual int_type overflow(int_type c = EOF)
00137         {
00138             sb2->overflow(c);
00139             return sb1->overflow(c);
00140         }
00141 #endif
00142     private:
00144         streambuf* sb1;
00146         streambuf* sb2;
00147 };
00148 
00152 class threebuf : public streambuf
00153 {
00154     public:
00156         threebuf(streambuf* b1, streambuf* b2, streambuf* b3)
00157             : streambuf(), sb1(b1), sb2(b2), sb3(b3) {}
00158     protected:
00159 #ifdef MODERN_STL_STREAMS
00160 
00161         virtual int sync()
00162         {
00163             sb2->pubsync();
00164             return sb1->pubsync();
00165         }
00167         virtual streamsize xsputn(char_type const* p, streamsize n)
00168         {
00169             sb2->sputn(p, n);
00170             sb3->sputn(p, n);
00171             return sb1->sputn(p, n);
00172         }
00174         virtual int_type overflow(int_type c = traits_type::eof())
00175         {
00176             sb2->sputc(c);
00177             sb3->sputc(c);
00178             return sb1->sputc(c);
00179         }
00180 #else
00181         typedef char char_type;
00182         typedef int int_type;
00184         virtual int sync()
00185         {
00186             sb2->sync();
00187             sb3->sync();
00188             return sb1->sync();
00189         }
00191         virtual streamsize xsputn(char_type const* p, streamsize n)
00192         {
00193             sb2->xsputn(p, n);
00194             sb2->xsputn(p, n);
00195             return sb1->xsputn(p, n);
00196         }
00198         virtual int_type overflow(int_type c = EOF)
00199         {
00200             sb2->overflow(c);
00201             sb3->owerflow(c);
00202             return sb1->overflow(c);
00203         }
00204 #endif
00205     private:
00207         streambuf* sb1;
00209         streambuf* sb2;
00211         streambuf* sb3;
00212 };
00213 
00215 class debugbuf : public streambuf
00216 {
00217     public:
00219         explicit debugbuf(streambuf* b)
00220             : streambuf(), sb(b) {}
00221     protected:
00222 #ifdef MODERN_STL_STREAMS
00223 
00224         virtual int sync()
00225         {
00226             return sb->pubsync();
00227         }
00229         virtual streamsize xsputn(char_type const* p, streamsize n)
00230         {
00231             return sb->sputn(p, n);
00232         }
00234         virtual int_type overflow(int_type c = traits_type::eof())
00235         {
00236             return sb->sputc(c);
00237         }
00238 #else
00239         typedef char char_type;
00240         typedef int int_type;
00242         virtual int sync()
00243         {
00244             return sb->sync();
00245         }
00247         virtual streamsize xsputn(char_type const* p, streamsize n)
00248         {
00249             return sb->xsputn(p, n);
00250         }
00252         virtual int_type overflow(int_type c = EOF)
00253         {
00254             return sb->overflow(c);
00255         }
00256 #endif
00257     private:
00259         streambuf* sb;
00260 };
00261 
00263 class stringsigbuf : public streambuf
00264 {
00265     public:
00266         stringsigbuf(): sb(new stringbuf())
00267         {
00268         }
00269 
00270         ~stringsigbuf()
00271         {
00272             if( sb )
00273             {
00274                 delete sb;
00275                 sb = 0;
00276             }
00277         }
00278 
00280         explicit stringsigbuf( stringbuf* b )
00281             : streambuf(), sb(b) {}
00282 
00283         typedef sigc::signal<void, const std::string&> StrBufOverflow_Signal;
00284         inline StrBufOverflow_Signal signal_overflow()
00285         {
00286             return s_overflow;
00287         }
00288 
00289     protected:
00290 #ifdef MODERN_STL_STREAMS
00291 
00292         virtual int sync()
00293         {
00294             UniSetTypes::uniset_rwmutex_wrlock l(mut);
00295             return sb->pubsync();
00296         }
00297 
00299         virtual streamsize xsputn(char_type const* p, streamsize n)
00300         {
00301             UniSetTypes::uniset_rwmutex_wrlock l(mut);
00302             streamsize r = sb->sputn(p, n);
00303             s_overflow.emit( sb->str() );
00304             sb->str("");
00305             return r;
00306         }
00308         virtual int_type overflow(int_type c = traits_type::eof())
00309         {
00310             int_type r = sb->sputc(c);
00311 
00312             if( r == '\n' )
00313             {
00314                 UniSetTypes::uniset_rwmutex_wrlock l(mut);
00315                 s_overflow.emit( sb->str() );
00316                 sb->str("");
00317             }
00318 
00319             return r;
00320         }
00321 #else
00322         typedef char char_type;
00323         typedef int int_type;
00325         virtual int sync()
00326         {
00327             return sb->sync();
00328         }
00330         virtual streamsize xsputn(char_type const* p, streamsize n)
00331         {
00332             return sb->xsputn(p, n);
00333         }
00334 
00335         virtual int_type overflow(int_type c = EOF)
00336         {
00337             int_type r = sb->overflow(c);
00338 
00339             if( r == '\n' )
00340             {
00341                 UniSetTypes::uniset_rwmutex_wrlock l(mut);
00342                 s_overflow.emit( sb->str() );
00343                 sb->str("");
00344             }
00345 
00346             return r;
00347         }
00348 #endif
00349     private:
00351         StrBufOverflow_Signal s_overflow;
00352         stringbuf* sb;
00353         UniSetTypes::uniset_rwmutex mut;
00354 };
00355 //--------------------------------------------------------------------------
00357 struct DebugStream::debugstream_internal
00358 {
00360     filebuf fbuf;
00361     stringsigbuf sbuf;
00362     nullbuf nbuf;
00363 };
00364 //--------------------------------------------------------------------------
00365 #endif