// =====================================================================
//  $Id: TStringStreamBuffer.cc,v 1.2 2004/06/28 07:17:37 goiwai Exp $
//  $Name: CLDAQ-1-14-03 $
//  $Log: TStringStreamBuffer.cc,v $
//  Revision 1.2  2004/06/28 07:17:37  goiwai
//  TclogのデフォルトのログレベルをINFOレベルにしました。
//
//  Revision 1.1  2004/06/24 15:17:51  goiwai
//  std::cout等をやめて、TOutputStreamのオブジェクトTcoutを使うことにした。理由は、出力前に皮をかぶせてやりたかったから。
//  SystemActionのCatch〜で設定できる。
//
//
// =====================================================================
#include "TStringStreamBuffer.hh"
#include "TSystemAction.hh"
#include "TSystemLogging.hh"

TStringStreamBuffer::TStringStreamBuffer( Tint len )
  : std::streambuf(),
    theSystemAction( 0 ), 
    theString( 0 ), 
    theLength( len ),
    theIndex( 0 ),
    theLogLevel( TSystemLogging::INFO )
{
  theString = new Tchar[ theLength + 1 ];
}

TStringStreamBuffer::TStringStreamBuffer( const TStringStreamBuffer& right )
  : std::streambuf(),
    theSystemAction( right.theSystemAction ),
    theString( right.theString ),
    theLength( right.theLength ),
    theIndex( right.theIndex ),
    theLogLevel( right.theLogLevel )
{;}

TStringStreamBuffer::~TStringStreamBuffer()
{
  delete [] theString;
}

TStringStreamBuffer& TStringStreamBuffer::operator=( const TStringStreamBuffer& right )
{
  if ( &right == this ) {
    return *this;
  }

  theSystemAction = right.theSystemAction;
  theString = right.theString;
  theLength = right.theLength;
  theIndex = right.theIndex;
  theLogLevel = right.theLogLevel;

  return *this;
}

Tint TStringStreamBuffer::overflow( Tint c )
{
  Tint retval = 0;
  if ( theIndex >= theLength ) {
    retval = sync();
  }
  theString[ theIndex ] = c;
  theIndex ++;

  if ( c == '\n' ) {
    retval = sync();
    // Fix to overcome a bug on GNU gcc-3.0.X compilers. The return value
    // for cout, cerr overflow() function has to be c instead of 0 when
    // buffer is flushed for carriage-return.
#if (__GNUC__==3) && (__GNUC_MINOR__==0)
    if ( this == &coutbuf || this == &cerrbuf || this == &clogbuf ) {
      retval = c;
    }
#endif
  }
  return retval;
}

Tint TStringStreamBuffer::sync()
{
  theString[ theIndex ] = '\0';
  theIndex = 0;
  ReceiveString();
  return 0;
}

Tvoid TStringStreamBuffer::ReceiveString()
{
  Tstring message( theString );

  if ( this == &coutbuf && theSystemAction != 0 ) {
    theSystemAction -> CatchStandardOut( message );
  } else if ( this == &cerrbuf && theSystemAction != 0 ) {
    theSystemAction -> CatchStandardError( message );
  } else if ( this == &clogbuf && theSystemAction != 0 ) {
    theSystemAction -> CatchLog( message, theLogLevel );
  } else if ( this == &coutbuf && theSystemAction == 0 ) {
    std::cout << message << std::flush;
  } else if ( this == &cerrbuf && theSystemAction == 0 ) {
    std::cerr << message << std::flush;
  } else if ( this == &clogbuf && theSystemAction == 0 ) {
    std::clog << message << std::flush;
  }

  return;
}

TStringStreamBuffer coutbuf;
TStringStreamBuffer cerrbuf;
TStringStreamBuffer clogbuf;

#ifdef __CLDAQ_ROOT_DLL
    ClassImp(TStringStreamBuffer)
#endif
