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