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

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

#include "piscmds.h"

#include <ctype.h>
#include "istream.h"
#include "streambuf.h"
#include "string.h"


// Implementation of ExtractStringCommand

ExtractBasicStringCommand::ExtractBasicStringCommand(basic_istream_char& is, basic_string_char& s, streamsize n, int delim, bool getline)
  : s_(s),
    n_(n),
    delim_(delim),
    getline_(getline)
  { execute_template(is); }

ExtractBasicStringCommand::~ExtractBasicStringCommand()
  {}

ios::iostate ExtractBasicStringCommand::execute(basic_istream_char& is)
  {
    ios::iostate state = ios::goodbit;

    s_.erase();

    basic_streambuf_char* sb = is.rdbuf();

    int c = sb->sgetc();
    while(c != basic_istream_char::traits::eof() && (getline_ ? c != delim_ : !isspace(c)) && n_ > 0)
    {
      s_.append(1, c);
      --n_;
      c = sb->snextc();
    }

    if(c == basic_istream_char::traits::eof())
      state |= ios::eofbit;
    else if(getline_ && c == delim_)
      sb->sbumpc();

    return state;
  }


// Implementation of basic_string_char free fns

basic_istream_char& operator>>(basic_istream_char& is, basic_string_char& str)
{
  int n = is.width();
  ExtractBasicStringCommand cmd(is, str, (n > 0 ? n : str.max_size()), basic_istream_char::traits::eof(), false);
  is.width(0);
  return is;
}

basic_istream_char& getline(basic_istream_char& is, basic_string_char& str, char delim)
{
  ExtractBasicStringCommand cmd(is, str, str.max_size(), delim, true);
  if(str.empty())
    is.setstate(ios::failbit);
  return is;
}
