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

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

#include "piscmds.h"

#include "exception.h"
#include "istream.h"
#include "streambuf.h"


// Implementation of ExtractStreamBufCommand

ExtractStreamBufCommand::ExtractStreamBufCommand(basic_istream_char& is, basic_streambuf_char* osb, int delim, bool noskipws)
  : osb_(osb),
    delim_(delim),
    gcount_(0)
  { execute_template(is, noskipws); }

ExtractStreamBufCommand::~ExtractStreamBufCommand()
  {}

ios::iostate ExtractStreamBufCommand::execute(basic_istream_char& is)
  {
    if(osb_ == 0)
      return ios::failbit;

    ios::iostate state = ios::goodbit;

    basic_streambuf_char* isb = is.rdbuf();
    int c = isb->sgetc();

    while(c != basic_istream_char::traits::eof() && c != delim_)
    {
      bool out_fail = true;

      try
      {
        out_fail = (osb_->sputc(c) == basic_streambuf_char::traits::eof());
      }
      BEGIN_HANDLERS
      catch_DOTS
      {
        // Dec '96 WP says catch and ignore
      }
      END_HANDLERS

      if(out_fail)
        break;

      c = isb->snextc();
      ++gcount_;
    }

    if(c == basic_istream_char::traits::eof())
      state |= ios::eofbit;

    if(gcount_ == 0)
      state |= ios::failbit;

    return state;
  }


// Implementation of basic_istream_char

basic_istream_char& basic_istream_char::operator>>(basic_streambuf_char* sb)
  {
    ExtractStreamBufCommand cmd(*this, sb, traits::eof());
    return *this;
  }

basic_istream_char& basic_istream_char::get(basic_streambuf_char* sb, char delim)
  {
    gcount_ = 0;

    ExtractStreamBufCommand cmd(*this, sb, delim, true);
    gcount_ = cmd.gcount();

    return *this;
  }

