// File:       poscmd03.c++
// Version:    1.00
// Author:     (c) Miles Sabin, 1997
// Purpose:    insert streambuf command

// Change log:
//  28/03/97   v. 1.00

#include "poscmds.h"

#include <stdio.h>       // for sprintf()
#include "exception.h"
#include "istream.h"
#include "ostream.h"
#include "streambuf.h"


// Implementation of InsertStreamBufCommand

InsertStreamBufCommand::InsertStreamBufCommand(basic_ostream_char& os, basic_streambuf_char* isb)
  : isb_(isb)
  { execute_template(os); }

InsertStreamBufCommand::~InsertStreamBufCommand()
  {}

ios::iostate InsertStreamBufCommand::execute(basic_ostream_char& os)
  {
    if(isb_ == 0)
      return ios::badbit;

    basic_streambuf_char* osb = os.rdbuf();

    char c;

    try
    {
      c = isb_->sgetc();
    }
    BEGIN_HANDLERS
    catch_DOTS
    {
      os.setstate_no_throw(ios::failbit);
      if((os.exceptions()&ios::failbit) != 0)
      {
        set_rethrow();  // ensure the right exception is propagated
        rethrow;
      }
      return ios::failbit;
    }
    END_HANDLERS

    if(c == basic_istream_char::traits::eof() || osb->sputc(c) == basic_ostream_char::traits::eof())
      return ios::failbit;

    do
    {
      try
      {
        c = isb_->snextc();
      }
      BEGIN_HANDLERS
      catch_DOTS
      {
        os.setstate_no_throw(ios::failbit);
        if((os.exceptions()&ios::failbit) != 0)
        {
          set_rethrow();  // ensure the right exception is propagated
          rethrow;
        }
        return ios::failbit;
      }
      END_HANDLERS

      if(c == basic_istream_char::traits::eof())
        break;
    }
    while(osb->sputc(c) != basic_ostream_char::traits::eof());

    return ios::goodbit;
  }


// Implementation of basic_ostream_char

basic_ostream_char& basic_ostream_char::operator<<(basic_streambuf_char* sb)
  {
    InsertStreamBufCommand cmd(*this, sb);
    return *this;
  }

