1169691Skan// Input streams -*- C++ -*-
2169691Skan
3169691Skan// Copyright (C) 2004, 2005 Free Software Foundation, Inc.
4169691Skan//
5169691Skan// This file is part of the GNU ISO C++ Library.  This library is free
6169691Skan// software; you can redistribute it and/or modify it under the
7169691Skan// terms of the GNU General Public License as published by the
8169691Skan// Free Software Foundation; either version 2, or (at your option)
9169691Skan// any later version.
10169691Skan
11169691Skan// This library is distributed in the hope that it will be useful,
12169691Skan// but WITHOUT ANY WARRANTY; without even the implied warranty of
13169691Skan// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14169691Skan// GNU General Public License for more details.
15169691Skan
16169691Skan// You should have received a copy of the GNU General Public License along
17169691Skan// with this library; see the file COPYING.  If not, write to the Free
18169691Skan// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
19169691Skan// USA.
20169691Skan
21169691Skan// As a special exception, you may use this file as part of a free software
22169691Skan// library without restriction.  Specifically, if other files instantiate
23169691Skan// templates or use macros or inline functions from this file, or you compile
24169691Skan// this file and link it with other files to produce an executable, this
25169691Skan// file does not by itself cause the resulting executable to be covered by
26169691Skan// the GNU General Public License.  This exception does not however
27169691Skan// invalidate any other reasons why the executable file might be covered by
28169691Skan// the GNU General Public License.
29169691Skan
30169691Skan//
31169691Skan// ISO C++ 14882: 27.6.1  Input streams
32169691Skan//
33169691Skan
34169691Skan#include <istream>
35169691Skan
36169691Skan_GLIBCXX_BEGIN_NAMESPACE(std)
37169691Skan
38169691Skan  template<>
39169691Skan    basic_istream<char>&
40169691Skan    basic_istream<char>::
41169691Skan    getline(char_type* __s, streamsize __n, char_type __delim)
42169691Skan    {
43169691Skan      _M_gcount = 0;
44169691Skan      ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
45169691Skan      sentry __cerb(*this, true);
46169691Skan      if (__cerb)
47169691Skan	{
48169691Skan          try
49169691Skan	    {
50169691Skan	      const int_type __idelim = traits_type::to_int_type(__delim);
51169691Skan	      const int_type __eof = traits_type::eof();
52169691Skan	      __streambuf_type* __sb = this->rdbuf();
53169691Skan	      int_type __c = __sb->sgetc();
54169691Skan
55169691Skan	      while (_M_gcount + 1 < __n
56169691Skan		     && !traits_type::eq_int_type(__c, __eof)
57169691Skan		     && !traits_type::eq_int_type(__c, __idelim))
58169691Skan		{
59169691Skan		  streamsize __size = std::min(streamsize(__sb->egptr()
60169691Skan							  - __sb->gptr()),
61169691Skan					       streamsize(__n - _M_gcount
62169691Skan							  - 1));
63169691Skan		  if (__size > 1)
64169691Skan		    {
65169691Skan		      const char_type* __p = traits_type::find(__sb->gptr(),
66169691Skan							       __size,
67169691Skan							       __delim);
68169691Skan		      if (__p)
69169691Skan			__size = __p - __sb->gptr();
70169691Skan		      traits_type::copy(__s, __sb->gptr(), __size);
71169691Skan		      __s += __size;
72169691Skan		      __sb->gbump(__size);
73169691Skan		      _M_gcount += __size;
74169691Skan		      __c = __sb->sgetc();
75169691Skan		    }
76169691Skan		  else
77169691Skan		    {
78169691Skan		      *__s++ = traits_type::to_char_type(__c);
79169691Skan		      ++_M_gcount;
80169691Skan		      __c = __sb->snextc();
81169691Skan		    }
82169691Skan		}
83169691Skan
84169691Skan	      if (traits_type::eq_int_type(__c, __eof))
85169691Skan		__err |= ios_base::eofbit;
86169691Skan	      else if (traits_type::eq_int_type(__c, __idelim))
87169691Skan		{
88169691Skan		  ++_M_gcount;
89169691Skan		  __sb->sbumpc();
90169691Skan		}
91169691Skan	      else
92169691Skan		__err |= ios_base::failbit;
93169691Skan	    }
94169691Skan	  catch(...)
95169691Skan	    { this->_M_setstate(ios_base::badbit); }
96169691Skan	}
97169691Skan      // _GLIBCXX_RESOLVE_LIB_DEFECTS
98169691Skan      // 243. get and getline when sentry reports failure.
99169691Skan      if (__n > 0)
100169691Skan	*__s = char_type();
101169691Skan      if (!_M_gcount)
102169691Skan	__err |= ios_base::failbit;
103169691Skan      if (__err)
104169691Skan	this->setstate(__err);
105169691Skan      return *this;
106169691Skan    }
107169691Skan
108169691Skan  template<>
109169691Skan    basic_istream<char>&
110169691Skan    basic_istream<char>::
111169691Skan    ignore(streamsize __n, int_type __delim)
112169691Skan    {
113169691Skan      if (traits_type::eq_int_type(__delim, traits_type::eof()))
114169691Skan	return ignore(__n);
115169691Skan
116169691Skan      _M_gcount = 0;
117169691Skan      sentry __cerb(*this, true);
118169691Skan      if (__cerb && __n > 0)
119169691Skan	{
120169691Skan	  ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
121169691Skan	  try
122169691Skan	    {
123169691Skan	      const char_type __cdelim = traits_type::to_char_type(__delim);
124169691Skan	      const int_type __eof = traits_type::eof();
125169691Skan	      __streambuf_type* __sb = this->rdbuf();
126169691Skan	      int_type __c = __sb->sgetc();
127169691Skan
128169691Skan	      bool __large_ignore = false;
129169691Skan	      while (true)
130169691Skan		{
131169691Skan		  while (_M_gcount < __n
132169691Skan			 && !traits_type::eq_int_type(__c, __eof)
133169691Skan			 && !traits_type::eq_int_type(__c, __delim))
134169691Skan		    {
135169691Skan		      streamsize __size = std::min(streamsize(__sb->egptr()
136169691Skan							      - __sb->gptr()),
137169691Skan						   streamsize(__n - _M_gcount));
138169691Skan		      if (__size > 1)
139169691Skan			{
140169691Skan			  const char_type* __p = traits_type::find(__sb->gptr(),
141169691Skan								   __size,
142169691Skan								   __cdelim);
143169691Skan			  if (__p)
144169691Skan			    __size = __p - __sb->gptr();
145169691Skan			  __sb->gbump(__size);
146169691Skan			  _M_gcount += __size;
147169691Skan			  __c = __sb->sgetc();
148169691Skan			}
149169691Skan		      else
150169691Skan			{
151169691Skan			  ++_M_gcount;
152169691Skan			  __c = __sb->snextc();
153169691Skan			}
154169691Skan		    }
155169691Skan		  if (__n == numeric_limits<streamsize>::max()
156169691Skan		      && !traits_type::eq_int_type(__c, __eof)
157169691Skan		      && !traits_type::eq_int_type(__c, __delim))
158169691Skan		    {
159169691Skan		      _M_gcount = numeric_limits<streamsize>::min();
160169691Skan		      __large_ignore = true;
161169691Skan		    }
162169691Skan		  else
163169691Skan		    break;
164169691Skan		}
165169691Skan
166169691Skan	      if (__large_ignore)
167169691Skan		_M_gcount = numeric_limits<streamsize>::max();
168169691Skan
169169691Skan	      if (traits_type::eq_int_type(__c, __eof))
170169691Skan		__err |= ios_base::eofbit;
171169691Skan	      else if (traits_type::eq_int_type(__c, __delim))
172169691Skan		{
173169691Skan		  if (_M_gcount < numeric_limits<streamsize>::max())
174169691Skan		    ++_M_gcount;
175169691Skan		  __sb->sbumpc();
176169691Skan		}
177169691Skan	    }
178169691Skan	  catch(...)
179169691Skan	    { this->_M_setstate(ios_base::badbit); }
180169691Skan	  if (__err)
181169691Skan	    this->setstate(__err);
182169691Skan	}
183169691Skan      return *this;
184169691Skan    }
185169691Skan
186169691Skan  template<>
187169691Skan    basic_istream<char>&
188169691Skan    operator>>(basic_istream<char>& __in, char* __s)
189169691Skan    {
190169691Skan      typedef basic_istream<char>       	__istream_type;
191169691Skan      typedef __istream_type::int_type		__int_type;
192169691Skan      typedef __istream_type::char_type		__char_type;
193169691Skan      typedef __istream_type::traits_type	__traits_type;
194169691Skan      typedef __istream_type::__streambuf_type  __streambuf_type;
195169691Skan      typedef __istream_type::__ctype_type	__ctype_type;
196169691Skan
197169691Skan      streamsize __extracted = 0;
198169691Skan      ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
199169691Skan      __istream_type::sentry __cerb(__in, false);
200169691Skan      if (__cerb)
201169691Skan	{
202169691Skan	  try
203169691Skan	    {
204169691Skan	      // Figure out how many characters to extract.
205169691Skan	      streamsize __num = __in.width();
206169691Skan	      if (__num <= 0)
207169691Skan		__num = numeric_limits<streamsize>::max();
208169691Skan
209169691Skan	      const __ctype_type& __ct = use_facet<__ctype_type>(__in.getloc());
210169691Skan
211169691Skan	      const __int_type __eof = __traits_type::eof();
212169691Skan	      __streambuf_type* __sb = __in.rdbuf();
213169691Skan	      __int_type __c = __sb->sgetc();
214169691Skan
215169691Skan	      while (__extracted < __num - 1
216169691Skan		     && !__traits_type::eq_int_type(__c, __eof)
217169691Skan		     && !__ct.is(ctype_base::space,
218169691Skan				 __traits_type::to_char_type(__c)))
219169691Skan		{
220169691Skan		  streamsize __size = std::min(streamsize(__sb->egptr()
221169691Skan							  - __sb->gptr()),
222169691Skan					       streamsize(__num - __extracted
223169691Skan							  - 1));
224169691Skan		  if (__size > 1)
225169691Skan		    {
226169691Skan		      __size = (__ct.scan_is(ctype_base::space,
227169691Skan					     __sb->gptr() + 1,
228169691Skan					     __sb->gptr() + __size)
229169691Skan				- __sb->gptr());
230169691Skan		      __traits_type::copy(__s, __sb->gptr(), __size);
231169691Skan		      __s += __size;
232169691Skan		      __sb->gbump(__size);
233169691Skan		      __extracted += __size;
234169691Skan		      __c = __sb->sgetc();
235169691Skan		    }
236169691Skan		  else
237169691Skan		    {
238169691Skan		      *__s++ = __traits_type::to_char_type(__c);
239169691Skan		      ++__extracted;
240169691Skan		      __c = __sb->snextc();
241169691Skan		    }
242169691Skan		}
243169691Skan
244169691Skan	      if (__traits_type::eq_int_type(__c, __eof))
245169691Skan		__err |= ios_base::eofbit;
246169691Skan
247169691Skan	      // _GLIBCXX_RESOLVE_LIB_DEFECTS
248169691Skan	      // 68.  Extractors for char* should store null at end
249169691Skan	      *__s = __char_type();
250169691Skan	      __in.width(0);
251169691Skan	    }
252169691Skan	  catch(...)
253169691Skan	    { __in._M_setstate(ios_base::badbit); }
254169691Skan	}
255169691Skan      if (!__extracted)
256169691Skan	__err |= ios_base::failbit;
257169691Skan      if (__err)
258169691Skan	__in.setstate(__err);
259169691Skan      return __in;
260169691Skan    }
261169691Skan
262169691Skan  template<>
263169691Skan    basic_istream<char>&
264169691Skan    operator>>(basic_istream<char>& __in, basic_string<char>& __str)
265169691Skan    {
266169691Skan      typedef basic_istream<char>       	__istream_type;
267169691Skan      typedef __istream_type::int_type		__int_type;
268169691Skan      typedef __istream_type::char_type		__char_type;
269169691Skan      typedef __istream_type::traits_type	__traits_type;
270169691Skan      typedef __istream_type::__streambuf_type  __streambuf_type;
271169691Skan      typedef __istream_type::__ctype_type	__ctype_type;
272169691Skan      typedef basic_string<char>        	__string_type;
273169691Skan      typedef __string_type::size_type		__size_type;
274169691Skan
275169691Skan      __size_type __extracted = 0;
276169691Skan      ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
277169691Skan      __istream_type::sentry __cerb(__in, false);
278169691Skan      if (__cerb)
279169691Skan	{
280169691Skan	  try
281169691Skan	    {
282169691Skan	      __str.erase();
283169691Skan	      const streamsize __w = __in.width();
284169691Skan	      const __size_type __n = __w > 0 ? static_cast<__size_type>(__w)
285169691Skan		                              : __str.max_size();
286169691Skan	      const __ctype_type& __ct = use_facet<__ctype_type>(__in.getloc());
287169691Skan	      const __int_type __eof = __traits_type::eof();
288169691Skan	      __streambuf_type* __sb = __in.rdbuf();
289169691Skan	      __int_type __c = __sb->sgetc();
290169691Skan
291169691Skan	      while (__extracted < __n
292169691Skan		     && !__traits_type::eq_int_type(__c, __eof)
293169691Skan		     && !__ct.is(ctype_base::space,
294169691Skan				 __traits_type::to_char_type(__c)))
295169691Skan		{
296169691Skan		  streamsize __size = std::min(streamsize(__sb->egptr()
297169691Skan							  - __sb->gptr()),
298169691Skan					       streamsize(__n - __extracted));
299169691Skan		  if (__size > 1)
300169691Skan		    {
301169691Skan		      __size = (__ct.scan_is(ctype_base::space,
302169691Skan					     __sb->gptr() + 1,
303169691Skan					     __sb->gptr() + __size)
304169691Skan				- __sb->gptr());
305169691Skan		      __str.append(__sb->gptr(), __size);
306169691Skan		      __sb->gbump(__size);
307169691Skan		      __extracted += __size;
308169691Skan		      __c = __sb->sgetc();
309169691Skan		    }
310169691Skan		  else
311169691Skan		    {
312169691Skan		      __str += __traits_type::to_char_type(__c);
313169691Skan		      ++__extracted;
314169691Skan		      __c = __sb->snextc();
315169691Skan		    }
316169691Skan		}
317169691Skan
318169691Skan	      if (__traits_type::eq_int_type(__c, __eof))
319169691Skan		__err |= ios_base::eofbit;
320169691Skan	      __in.width(0);
321169691Skan	    }
322169691Skan	  catch(...)
323169691Skan	    {
324169691Skan	      // _GLIBCXX_RESOLVE_LIB_DEFECTS
325169691Skan	      // 91. Description of operator>> and getline() for string<>
326169691Skan	      // might cause endless loop
327169691Skan	      __in._M_setstate(ios_base::badbit);
328169691Skan	    }
329169691Skan	}
330169691Skan      if (!__extracted)
331169691Skan	__err |= ios_base::failbit;
332169691Skan      if (__err)
333169691Skan	__in.setstate(__err);
334169691Skan      return __in;
335169691Skan    }
336169691Skan
337169691Skan  template<>
338169691Skan    basic_istream<char>&
339169691Skan    getline(basic_istream<char>& __in, basic_string<char>& __str,
340169691Skan	    char __delim)
341169691Skan    {
342169691Skan      typedef basic_istream<char>       	__istream_type;
343169691Skan      typedef __istream_type::int_type		__int_type;
344169691Skan      typedef __istream_type::char_type		__char_type;
345169691Skan      typedef __istream_type::traits_type	__traits_type;
346169691Skan      typedef __istream_type::__streambuf_type  __streambuf_type;
347169691Skan      typedef __istream_type::__ctype_type	__ctype_type;
348169691Skan      typedef basic_string<char>        	__string_type;
349169691Skan      typedef __string_type::size_type		__size_type;
350169691Skan
351169691Skan      __size_type __extracted = 0;
352169691Skan      const __size_type __n = __str.max_size();
353169691Skan      ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
354169691Skan      __istream_type::sentry __cerb(__in, true);
355169691Skan      if (__cerb)
356169691Skan	{
357169691Skan	  try
358169691Skan	    {
359169691Skan	      __str.erase();
360169691Skan	      const __int_type __idelim = __traits_type::to_int_type(__delim);
361169691Skan	      const __int_type __eof = __traits_type::eof();
362169691Skan	      __streambuf_type* __sb = __in.rdbuf();
363169691Skan	      __int_type __c = __sb->sgetc();
364169691Skan
365169691Skan	      while (__extracted < __n
366169691Skan		     && !__traits_type::eq_int_type(__c, __eof)
367169691Skan		     && !__traits_type::eq_int_type(__c, __idelim))
368169691Skan		{
369169691Skan		  streamsize __size = std::min(streamsize(__sb->egptr()
370169691Skan							  - __sb->gptr()),
371169691Skan					       streamsize(__n - __extracted));
372169691Skan		  if (__size > 1)
373169691Skan		    {
374169691Skan		      const __char_type* __p = __traits_type::find(__sb->gptr(),
375169691Skan								   __size,
376169691Skan								   __delim);
377169691Skan		      if (__p)
378169691Skan			__size = __p - __sb->gptr();
379169691Skan		      __str.append(__sb->gptr(), __size);
380169691Skan		      __sb->gbump(__size);
381169691Skan		      __extracted += __size;
382169691Skan		      __c = __sb->sgetc();
383169691Skan		    }
384169691Skan		  else
385169691Skan		    {
386169691Skan		      __str += __traits_type::to_char_type(__c);
387169691Skan		      ++__extracted;
388169691Skan		      __c = __sb->snextc();
389169691Skan		    }
390169691Skan		}
391169691Skan
392169691Skan	      if (__traits_type::eq_int_type(__c, __eof))
393169691Skan		__err |= ios_base::eofbit;
394169691Skan	      else if (__traits_type::eq_int_type(__c, __idelim))
395169691Skan		{
396169691Skan		  ++__extracted;
397169691Skan		  __sb->sbumpc();
398169691Skan		}
399169691Skan	      else
400169691Skan		__err |= ios_base::failbit;
401169691Skan	    }
402169691Skan	  catch(...)
403169691Skan	    {
404169691Skan	      // _GLIBCXX_RESOLVE_LIB_DEFECTS
405169691Skan	      // 91. Description of operator>> and getline() for string<>
406169691Skan	      // might cause endless loop
407169691Skan	      __in._M_setstate(ios_base::badbit);
408169691Skan	    }
409169691Skan	}
410169691Skan      if (!__extracted)
411169691Skan	__err |= ios_base::failbit;
412169691Skan      if (__err)
413169691Skan	__in.setstate(__err);
414169691Skan      return __in;
415169691Skan    }
416169691Skan
417169691Skan#ifdef _GLIBCXX_USE_WCHAR_T
418169691Skan  template<>
419169691Skan    basic_istream<wchar_t>&
420169691Skan    basic_istream<wchar_t>::
421169691Skan    getline(char_type* __s, streamsize __n, char_type __delim)
422169691Skan    {
423169691Skan      _M_gcount = 0;
424169691Skan      ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
425169691Skan      sentry __cerb(*this, true);
426169691Skan      if (__cerb)
427169691Skan	{
428169691Skan          try
429169691Skan	    {
430169691Skan	      const int_type __idelim = traits_type::to_int_type(__delim);
431169691Skan	      const int_type __eof = traits_type::eof();
432169691Skan	      __streambuf_type* __sb = this->rdbuf();
433169691Skan	      int_type __c = __sb->sgetc();
434169691Skan
435169691Skan	      while (_M_gcount + 1 < __n
436169691Skan		     && !traits_type::eq_int_type(__c, __eof)
437169691Skan		     && !traits_type::eq_int_type(__c, __idelim))
438169691Skan		{
439169691Skan		  streamsize __size = std::min(streamsize(__sb->egptr()
440169691Skan							  - __sb->gptr()),
441169691Skan					       streamsize(__n - _M_gcount
442169691Skan							  - 1));
443169691Skan		  if (__size > 1)
444169691Skan		    {
445169691Skan		      const char_type* __p = traits_type::find(__sb->gptr(),
446169691Skan							       __size,
447169691Skan							       __delim);
448169691Skan		      if (__p)
449169691Skan			__size = __p - __sb->gptr();
450169691Skan		      traits_type::copy(__s, __sb->gptr(), __size);
451169691Skan		      __s += __size;
452169691Skan		      __sb->gbump(__size);
453169691Skan		      _M_gcount += __size;
454169691Skan		      __c = __sb->sgetc();
455169691Skan		    }
456169691Skan		  else
457169691Skan		    {
458169691Skan		      *__s++ = traits_type::to_char_type(__c);
459169691Skan		      ++_M_gcount;
460169691Skan		      __c = __sb->snextc();
461169691Skan		    }
462169691Skan		}
463169691Skan
464169691Skan	      if (traits_type::eq_int_type(__c, __eof))
465169691Skan		__err |= ios_base::eofbit;
466169691Skan	      else if (traits_type::eq_int_type(__c, __idelim))
467169691Skan		{
468169691Skan		  ++_M_gcount;
469169691Skan		  __sb->sbumpc();
470169691Skan		}
471169691Skan	      else
472169691Skan		__err |= ios_base::failbit;
473169691Skan	    }
474169691Skan	  catch(...)
475169691Skan	    { this->_M_setstate(ios_base::badbit); }
476169691Skan	}
477169691Skan      // _GLIBCXX_RESOLVE_LIB_DEFECTS
478169691Skan      // 243. get and getline when sentry reports failure.
479169691Skan      if (__n > 0)
480169691Skan	*__s = char_type();
481169691Skan      if (!_M_gcount)
482169691Skan	__err |= ios_base::failbit;
483169691Skan      if (__err)
484169691Skan	this->setstate(__err);
485169691Skan      return *this;
486169691Skan    }
487169691Skan
488169691Skan  template<>
489169691Skan    basic_istream<wchar_t>&
490169691Skan    basic_istream<wchar_t>::
491169691Skan    ignore(streamsize __n, int_type __delim)
492169691Skan    {
493169691Skan      if (traits_type::eq_int_type(__delim, traits_type::eof()))
494169691Skan	return ignore(__n);
495169691Skan
496169691Skan      _M_gcount = 0;
497169691Skan      sentry __cerb(*this, true);
498169691Skan      if (__cerb && __n > 0)
499169691Skan	{
500169691Skan	  ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
501169691Skan	  try
502169691Skan	    {
503169691Skan	      const char_type __cdelim = traits_type::to_char_type(__delim);
504169691Skan	      const int_type __eof = traits_type::eof();
505169691Skan	      __streambuf_type* __sb = this->rdbuf();
506169691Skan	      int_type __c = __sb->sgetc();
507169691Skan
508169691Skan	      bool __large_ignore = false;
509169691Skan	      while (true)
510169691Skan		{
511169691Skan		  while (_M_gcount < __n
512169691Skan			 && !traits_type::eq_int_type(__c, __eof)
513169691Skan			 && !traits_type::eq_int_type(__c, __delim))
514169691Skan		    {
515169691Skan		      streamsize __size = std::min(streamsize(__sb->egptr()
516169691Skan							      - __sb->gptr()),
517169691Skan						   streamsize(__n - _M_gcount));
518169691Skan		      if (__size > 1)
519169691Skan			{
520169691Skan			  const char_type* __p = traits_type::find(__sb->gptr(),
521169691Skan								   __size,
522169691Skan								   __cdelim);
523169691Skan			  if (__p)
524169691Skan			    __size = __p - __sb->gptr();
525169691Skan			  __sb->gbump(__size);
526169691Skan			  _M_gcount += __size;
527169691Skan			  __c = __sb->sgetc();
528169691Skan			}
529169691Skan		      else
530169691Skan			{
531169691Skan			  ++_M_gcount;
532169691Skan			  __c = __sb->snextc();
533169691Skan			}
534169691Skan		    }
535169691Skan		  if (__n == numeric_limits<streamsize>::max()
536169691Skan		      && !traits_type::eq_int_type(__c, __eof)
537169691Skan		      && !traits_type::eq_int_type(__c, __delim))
538169691Skan		    {
539169691Skan		      _M_gcount = numeric_limits<streamsize>::min();
540169691Skan		      __large_ignore = true;
541169691Skan		    }
542169691Skan		  else
543169691Skan		    break;
544169691Skan		}
545169691Skan
546169691Skan	      if (__large_ignore)
547169691Skan		_M_gcount = numeric_limits<streamsize>::max();
548169691Skan
549169691Skan	      if (traits_type::eq_int_type(__c, __eof))
550169691Skan		__err |= ios_base::eofbit;
551169691Skan	      else if (traits_type::eq_int_type(__c, __delim))
552169691Skan		{
553169691Skan		  if (_M_gcount < numeric_limits<streamsize>::max())
554169691Skan		    ++_M_gcount;
555169691Skan		  __sb->sbumpc();
556169691Skan		}
557169691Skan	    }
558169691Skan	  catch(...)
559169691Skan	    { this->_M_setstate(ios_base::badbit); }
560169691Skan	  if (__err)
561169691Skan	    this->setstate(__err);
562169691Skan	}
563169691Skan      return *this;
564169691Skan    }
565169691Skan
566169691Skan  template<>
567169691Skan    basic_istream<wchar_t>&
568169691Skan    getline(basic_istream<wchar_t>& __in, basic_string<wchar_t>& __str,
569169691Skan	    wchar_t __delim)
570169691Skan    {
571169691Skan      typedef basic_istream<wchar_t>       	__istream_type;
572169691Skan      typedef __istream_type::int_type		__int_type;
573169691Skan      typedef __istream_type::char_type		__char_type;
574169691Skan      typedef __istream_type::traits_type	__traits_type;
575169691Skan      typedef __istream_type::__streambuf_type  __streambuf_type;
576169691Skan      typedef __istream_type::__ctype_type	__ctype_type;
577169691Skan      typedef basic_string<wchar_t>        	__string_type;
578169691Skan      typedef __string_type::size_type		__size_type;
579169691Skan
580169691Skan      __size_type __extracted = 0;
581169691Skan      const __size_type __n = __str.max_size();
582169691Skan      ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
583169691Skan      __istream_type::sentry __cerb(__in, true);
584169691Skan      if (__cerb)
585169691Skan	{
586169691Skan	  try
587169691Skan	    {
588169691Skan	      __str.erase();
589169691Skan	      const __int_type __idelim = __traits_type::to_int_type(__delim);
590169691Skan	      const __int_type __eof = __traits_type::eof();
591169691Skan	      __streambuf_type* __sb = __in.rdbuf();
592169691Skan	      __int_type __c = __sb->sgetc();
593169691Skan
594169691Skan	      while (__extracted < __n
595169691Skan		     && !__traits_type::eq_int_type(__c, __eof)
596169691Skan		     && !__traits_type::eq_int_type(__c, __idelim))
597169691Skan		{
598169691Skan		  streamsize __size = std::min(streamsize(__sb->egptr()
599169691Skan							  - __sb->gptr()),
600169691Skan					       streamsize(__n - __extracted));
601169691Skan		  if (__size > 1)
602169691Skan		    {
603169691Skan		      const __char_type* __p = __traits_type::find(__sb->gptr(),
604169691Skan								   __size,
605169691Skan								   __delim);
606169691Skan		      if (__p)
607169691Skan			__size = __p - __sb->gptr();
608169691Skan		      __str.append(__sb->gptr(), __size);
609169691Skan		      __sb->gbump(__size);
610169691Skan		      __extracted += __size;
611169691Skan		      __c = __sb->sgetc();
612169691Skan		    }
613169691Skan		  else
614169691Skan		    {
615169691Skan		      __str += __traits_type::to_char_type(__c);
616169691Skan		      ++__extracted;
617169691Skan		      __c = __sb->snextc();
618169691Skan		    }
619169691Skan		}
620169691Skan
621169691Skan	      if (__traits_type::eq_int_type(__c, __eof))
622169691Skan		__err |= ios_base::eofbit;
623169691Skan	      else if (__traits_type::eq_int_type(__c, __idelim))
624169691Skan		{
625169691Skan		  ++__extracted;
626169691Skan		  __sb->sbumpc();
627169691Skan		}
628169691Skan	      else
629169691Skan		__err |= ios_base::failbit;
630169691Skan	    }
631169691Skan	  catch(...)
632169691Skan	    {
633169691Skan	      // _GLIBCXX_RESOLVE_LIB_DEFECTS
634169691Skan	      // 91. Description of operator>> and getline() for string<>
635169691Skan	      // might cause endless loop
636169691Skan	      __in._M_setstate(ios_base::badbit);
637169691Skan	    }
638169691Skan	}
639169691Skan      if (!__extracted)
640169691Skan	__err |= ios_base::failbit;
641169691Skan      if (__err)
642169691Skan	__in.setstate(__err);
643169691Skan      return __in;
644169691Skan    }
645169691Skan#endif
646169691Skan
647169691Skan_GLIBCXX_END_NAMESPACE
648