// Input streams -*- C++ -*-

// Copyright (C) 2004, 2005 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library.  This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 2, or (at your option)
// any later version.

// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.

// You should have received a copy of the GNU General Public License along
// with this library; see the file COPYING.  If not, write to the Free
// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
// USA.

// As a special exception, you may use this file as part of a free software
// library without restriction.  Specifically, if other files instantiate
// templates or use macros or inline functions from this file, or you compile
// this file and link it with other files to produce an executable, this
// file does not by itself cause the resulting executable to be covered by
// the GNU General Public License.  This exception does not however
// invalidate any other reasons why the executable file might be covered by
// the GNU General Public License.

//
// ISO C++ 14882: 27.6.1  Input streams
//

#include <istream>

namespace std
{
  template<>
    basic_istream<char>&
    basic_istream<char>::
    getline(char_type* __s, streamsize __n, char_type __delim)
    {
      _M_gcount = 0;
      ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
      sentry __cerb(*this, true);
      if (__cerb)
	{
          try
	    {
	      const int_type __idelim = traits_type::to_int_type(__delim);
	      const int_type __eof = traits_type::eof();
	      __streambuf_type* __sb = this->rdbuf();
	      int_type __c = __sb->sgetc();
	      
	      while (_M_gcount + 1 < __n
		     && !traits_type::eq_int_type(__c, __eof)
		     && !traits_type::eq_int_type(__c, __idelim))
		{
		  streamsize __size = std::min(streamsize(__sb->egptr()
							  - __sb->gptr()),
					       streamsize(__n - _M_gcount
							  - 1));
		  if (__size > 1)
		    {
		      const char_type* __p = traits_type::find(__sb->gptr(),
							       __size,
							       __delim);
		      if (__p)
			__size = __p - __sb->gptr();
		      traits_type::copy(__s, __sb->gptr(), __size);
		      __s += __size;
		      __sb->gbump(__size);
		      _M_gcount += __size;
		      __c = __sb->sgetc();
		    }
		  else
		    {
		      *__s++ = traits_type::to_char_type(__c);
		      ++_M_gcount;
		      __c = __sb->snextc();
		    }
		}

	      if (traits_type::eq_int_type(__c, __eof))
		__err |= ios_base::eofbit;
	      else if (traits_type::eq_int_type(__c, __idelim))
		{
		  ++_M_gcount;		  
		  __sb->sbumpc();
		}
	      else
		__err |= ios_base::failbit;
	    }
	  catch(...)
	    { this->_M_setstate(ios_base::badbit); }
	}
      // _GLIBCXX_RESOLVE_LIB_DEFECTS
      // 243. get and getline when sentry reports failure.
      if (__n > 0)
	*__s = char_type();
      if (!_M_gcount)
	__err |= ios_base::failbit;
      if (__err)
	this->setstate(__err);
      return *this;
    }

  template<>
    basic_istream<char>&
    basic_istream<char>::
    ignore(streamsize __n, int_type __delim)
    {
      if (traits_type::eq_int_type(__delim, traits_type::eof()))
	return ignore(__n);

      _M_gcount = 0;
      sentry __cerb(*this, true);
      if (__cerb && __n > 0)
	{
	  ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
	  try
	    {
	      const char_type __cdelim = traits_type::to_char_type(__delim);	      
	      const int_type __eof = traits_type::eof();
	      __streambuf_type* __sb = this->rdbuf();
	      int_type __c = __sb->sgetc();

	      bool __large_ignore = false;
	      while (true)
		{
		  while (_M_gcount < __n
			 && !traits_type::eq_int_type(__c, __eof)
			 && !traits_type::eq_int_type(__c, __delim))
		    {
		      streamsize __size = std::min(streamsize(__sb->egptr()
							      - __sb->gptr()),
						   streamsize(__n - _M_gcount));
		      if (__size > 1)
			{
			  const char_type* __p = traits_type::find(__sb->gptr(),
								   __size,
								   __cdelim);
			  if (__p)
			    __size = __p - __sb->gptr();
			  __sb->gbump(__size);
			  _M_gcount += __size;
			  __c = __sb->sgetc();
			}
		      else
			{
			  ++_M_gcount;
			  __c = __sb->snextc();
			}
		    }
		  if (__n == numeric_limits<streamsize>::max()
		      && !traits_type::eq_int_type(__c, __eof)
		      && !traits_type::eq_int_type(__c, __delim))
		    {
		      _M_gcount = numeric_limits<streamsize>::min();
		      __large_ignore = true;
		    }
		  else
		    break;
		}

	      if (__large_ignore)
		_M_gcount = numeric_limits<streamsize>::max();

	      if (traits_type::eq_int_type(__c, __eof))
		__err |= ios_base::eofbit;
	      else if (traits_type::eq_int_type(__c, __delim))
		{
		  if (_M_gcount < numeric_limits<streamsize>::max())
		    ++_M_gcount;
		  __sb->sbumpc();
		}
	    }
	  catch(...)
	    { this->_M_setstate(ios_base::badbit); }
	  if (__err)
	    this->setstate(__err);
	}
      return *this;
    }

  template<>
    basic_istream<char>&
    getline(basic_istream<char>& __in, basic_string<char>& __str,
	    char __delim)
    {
      typedef basic_istream<char>       	__istream_type;
      typedef __istream_type::int_type		__int_type;
      typedef __istream_type::char_type		__char_type;
      typedef __istream_type::traits_type	__traits_type;
      typedef __istream_type::__streambuf_type  __streambuf_type;
      typedef __istream_type::__ctype_type	__ctype_type;
      typedef basic_string<char>        	__string_type;
      typedef __string_type::size_type		__size_type;

      __size_type __extracted = 0;
      const __size_type __n = __str.max_size();
      ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
      __istream_type::sentry __cerb(__in, true);
      if (__cerb)
	{
	  try
	    {
	      __str.erase();
	      const __int_type __idelim = __traits_type::to_int_type(__delim);
	      const __int_type __eof = __traits_type::eof();
	      __streambuf_type* __sb = __in.rdbuf();
	      __int_type __c = __sb->sgetc();

	      while (__extracted < __n
		     && !__traits_type::eq_int_type(__c, __eof)
		     && !__traits_type::eq_int_type(__c, __idelim))
		{
		  streamsize __size = std::min(streamsize(__sb->egptr()
							  - __sb->gptr()),
					       streamsize(__n - __extracted));
		  if (__size > 1)
		    {
		      const __char_type* __p = __traits_type::find(__sb->gptr(),
								   __size,
								   __delim);
		      if (__p)
			__size = __p - __sb->gptr();
		      __str.append(__sb->gptr(), __size);
		      __sb->gbump(__size);
		      __extracted += __size;
		      __c = __sb->sgetc();
		    }
		  else
		    {
		      __str += __traits_type::to_char_type(__c);
		      ++__extracted;
		      __c = __sb->snextc();
		    }		  
		}

	      if (__traits_type::eq_int_type(__c, __eof))
		__err |= ios_base::eofbit;
	      else if (__traits_type::eq_int_type(__c, __idelim))
		{
		  ++__extracted;
		  __sb->sbumpc();
		}
	      else
		__err |= ios_base::failbit;
	    }
	  catch(...)
	    {
	      // _GLIBCXX_RESOLVE_LIB_DEFECTS
	      // 91. Description of operator>> and getline() for string<>
	      // might cause endless loop
	      __in._M_setstate(ios_base::badbit);
	    }
	}
      if (!__extracted)
	__err |= ios_base::failbit;
      if (__err)
	__in.setstate(__err);
      return __in;
    }

#ifdef _GLIBCXX_USE_WCHAR_T
  template<>
    basic_istream<wchar_t>&
    basic_istream<wchar_t>::
    getline(char_type* __s, streamsize __n, char_type __delim)
    {
      _M_gcount = 0;
      ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
      sentry __cerb(*this, true);
      if (__cerb)
	{
          try
	    {
	      const int_type __idelim = traits_type::to_int_type(__delim);
	      const int_type __eof = traits_type::eof();
	      __streambuf_type* __sb = this->rdbuf();
	      int_type __c = __sb->sgetc();
	      
	      while (_M_gcount + 1 < __n
		     && !traits_type::eq_int_type(__c, __eof)
		     && !traits_type::eq_int_type(__c, __idelim))
		{
		  streamsize __size = std::min(streamsize(__sb->egptr()
							  - __sb->gptr()),
					       streamsize(__n - _M_gcount
							  - 1));
		  if (__size > 1)
		    {
		      const char_type* __p = traits_type::find(__sb->gptr(),
							       __size,
							       __delim);
		      if (__p)
			__size = __p - __sb->gptr();
		      traits_type::copy(__s, __sb->gptr(), __size);
		      __s += __size;
		      __sb->gbump(__size);
		      _M_gcount += __size;
		      __c = __sb->sgetc();
		    }
		  else
		    {
		      *__s++ = traits_type::to_char_type(__c);
		      ++_M_gcount;
		      __c = __sb->snextc();
		    }
		}

	      if (traits_type::eq_int_type(__c, __eof))
		__err |= ios_base::eofbit;
	      else if (traits_type::eq_int_type(__c, __idelim))
		{
		  ++_M_gcount;		  
		  __sb->sbumpc();
		}
	      else
		__err |= ios_base::failbit;
	    }
	  catch(...)
	    { this->_M_setstate(ios_base::badbit); }
	}
      // _GLIBCXX_RESOLVE_LIB_DEFECTS
      // 243. get and getline when sentry reports failure.
      if (__n > 0)
	*__s = char_type();
      if (!_M_gcount)
	__err |= ios_base::failbit;
      if (__err)
	this->setstate(__err);
      return *this;
    }

  template<>
    basic_istream<wchar_t>&
    basic_istream<wchar_t>::
    ignore(streamsize __n, int_type __delim)
    {
      if (traits_type::eq_int_type(__delim, traits_type::eof()))
	return ignore(__n);

      _M_gcount = 0;
      sentry __cerb(*this, true);
      if (__cerb && __n > 0)
	{
	  ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
	  try
	    {
	      const char_type __cdelim = traits_type::to_char_type(__delim);	      
	      const int_type __eof = traits_type::eof();
	      __streambuf_type* __sb = this->rdbuf();
	      int_type __c = __sb->sgetc();

	      bool __large_ignore = false;
	      while (true)
		{
		  while (_M_gcount < __n
			 && !traits_type::eq_int_type(__c, __eof)
			 && !traits_type::eq_int_type(__c, __delim))
		    {
		      streamsize __size = std::min(streamsize(__sb->egptr()
							      - __sb->gptr()),
						   streamsize(__n - _M_gcount));
		      if (__size > 1)
			{
			  const char_type* __p = traits_type::find(__sb->gptr(),
								   __size,
								   __cdelim);
			  if (__p)
			    __size = __p - __sb->gptr();
			  __sb->gbump(__size);
			  _M_gcount += __size;
			  __c = __sb->sgetc();
			}
		      else
			{
			  ++_M_gcount;
			  __c = __sb->snextc();
			}
		    }
		  if (__n == numeric_limits<streamsize>::max()
		      && !traits_type::eq_int_type(__c, __eof)
		      && !traits_type::eq_int_type(__c, __delim))
		    {
		      _M_gcount = numeric_limits<streamsize>::min();
		      __large_ignore = true;
		    }
		  else
		    break;
		}

	      if (__large_ignore)
		_M_gcount = numeric_limits<streamsize>::max();

	      if (traits_type::eq_int_type(__c, __eof))
		__err |= ios_base::eofbit;
	      else if (traits_type::eq_int_type(__c, __delim))
		{
		  if (_M_gcount < numeric_limits<streamsize>::max())
		    ++_M_gcount;
		  __sb->sbumpc();
		}
	    }
	  catch(...)
	    { this->_M_setstate(ios_base::badbit); }
	  if (__err)
	    this->setstate(__err);
	}
      return *this;
    }

  template<>
    basic_istream<wchar_t>&
    getline(basic_istream<wchar_t>& __in, basic_string<wchar_t>& __str,
	    wchar_t __delim)
    {
      typedef basic_istream<wchar_t>       	__istream_type;
      typedef __istream_type::int_type		__int_type;
      typedef __istream_type::char_type		__char_type;
      typedef __istream_type::traits_type	__traits_type;
      typedef __istream_type::__streambuf_type  __streambuf_type;
      typedef __istream_type::__ctype_type	__ctype_type;
      typedef basic_string<wchar_t>        	__string_type;
      typedef __string_type::size_type		__size_type;

      __size_type __extracted = 0;
      const __size_type __n = __str.max_size();
      ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
      __istream_type::sentry __cerb(__in, true);
      if (__cerb)
	{
	  try
	    {
	      __str.erase();
	      const __int_type __idelim = __traits_type::to_int_type(__delim);
	      const __int_type __eof = __traits_type::eof();
	      __streambuf_type* __sb = __in.rdbuf();
	      __int_type __c = __sb->sgetc();

	      while (__extracted < __n
		     && !__traits_type::eq_int_type(__c, __eof)
		     && !__traits_type::eq_int_type(__c, __idelim))
		{
		  streamsize __size = std::min(streamsize(__sb->egptr()
							  - __sb->gptr()),
					       streamsize(__n - __extracted));
		  if (__size > 1)
		    {
		      const __char_type* __p = __traits_type::find(__sb->gptr(),
								   __size,
								   __delim);
		      if (__p)
			__size = __p - __sb->gptr();
		      __str.append(__sb->gptr(), __size);
		      __sb->gbump(__size);
		      __extracted += __size;
		      __c = __sb->sgetc();
		    }
		  else
		    {
		      __str += __traits_type::to_char_type(__c);
		      ++__extracted;
		      __c = __sb->snextc();
		    }		  
		}

	      if (__traits_type::eq_int_type(__c, __eof))
		__err |= ios_base::eofbit;
	      else if (__traits_type::eq_int_type(__c, __idelim))
		{
		  ++__extracted;
		  __sb->sbumpc();
		}
	      else
		__err |= ios_base::failbit;
	    }
	  catch(...)
	    {
	      // _GLIBCXX_RESOLVE_LIB_DEFECTS
	      // 91. Description of operator>> and getline() for string<>
	      // might cause endless loop
	      __in._M_setstate(ios_base::badbit);
	    }
	}
      if (!__extracted)
	__err |= ios_base::failbit;
      if (__err)
	__in.setstate(__err);
      return __in;
    }
#endif
} // namespace std
