// File:       istream.c++
// Version:    1.01
// Author:     (c) Miles Sabin, 1997
// Purpose:    approximation to ANSI C++ istream

// Change log:
//  13/02/97   v. 1.00
//  27/03/97   v. 1.01
//             Brought more into line with Dec '96 WP.
//             Functionality bundled into command objects to allow
//               sharing of common exception handling code.

#include "istream.h"

#include <ctype.h>            // for isspace()
#include "exception.h"
#include "ostream.h"
#include "streambuf.h"
#include "tpltutil.h"

#include "autodstry.c++"


// Implementation of basic_istream_char

basic_istream_char::basic_istream_char(basic_streambuf_char* sb)
  : gcount_(0)
  { basic_ios_char::init(sb); }

basic_istream_char::~basic_istream_char()
  {}


// Implementation of basic_istream_char_sentry

INSTANTIATE_CLASS_1(AutoDestroyer, basic_istream_char_sentry)

basic_istream_char_sentry::basic_istream_char_sentry(basic_istream_char& is, bool noskipws)
  : is_(is),
    ok_(false)
  {
    if(is_.good())
    {
      if(is_.tie() != 0)
        is.tie()->flush();

      basic_streambuf_char* sb = is_.rdbuf();

      if(ios_base::get_sync_with_stdio())
        sb->sync_stream_with_stdio();

      if(!noskipws && ((is.flags()&ios::skipws) != 0))
      {
        int c = sb->sgetc();
        while(c != basic_istream_char::traits::eof() && isspace(c))
          c = sb->snextc();
      }

      ok_ = true;
    }
  }

basic_istream_char_sentry::~basic_istream_char_sentry()
  {
    if(ios_base::get_sync_with_stdio() && !uncaught_exception())
      is_.rdbuf()->sync_stdio_with_stream();
  }

void destroy(basic_istream_char_sentry* p)
{
  p->~basic_istream_char_sentry();
}
