1 // Input streams -*- C++ -*- 2 3 // Copyright (C) 2004-2014 Free Software Foundation, Inc. 4 // 5 // This file is part of the GNU ISO C++ Library. This library is free 6 // software; you can redistribute it and/or modify it under the 7 // terms of the GNU General Public License as published by the 8 // Free Software Foundation; either version 3, or (at your option) 9 // any later version. 10 11 // This library is distributed in the hope that it will be useful, 12 // but WITHOUT ANY WARRANTY; without even the implied warranty of 13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 // GNU General Public License for more details. 15 16 // Under Section 7 of GPL version 3, you are granted additional 17 // permissions described in the GCC Runtime Library Exception, version 18 // 3.1, as published by the Free Software Foundation. 19 20 // You should have received a copy of the GNU General Public License and 21 // a copy of the GCC Runtime Library Exception along with this program; 22 // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see 23 // <http://www.gnu.org/licenses/>. 24 25 // 26 // ISO C++ 14882: 27.6.1 Input streams 27 // 28 29 #include <istream> 30 31 namespace std _GLIBCXX_VISIBILITY(default) 32 { 33 _GLIBCXX_BEGIN_NAMESPACE_VERSION 34 35 template<> 36 basic_istream<char>& 37 basic_istream<char>:: getline(char_type * __s,streamsize __n,char_type __delim)38 getline(char_type* __s, streamsize __n, char_type __delim) 39 { 40 _M_gcount = 0; 41 ios_base::iostate __err = ios_base::goodbit; 42 sentry __cerb(*this, true); 43 if (__cerb) 44 { 45 __try 46 { 47 const int_type __idelim = traits_type::to_int_type(__delim); 48 const int_type __eof = traits_type::eof(); 49 __streambuf_type* __sb = this->rdbuf(); 50 int_type __c = __sb->sgetc(); 51 52 while (_M_gcount + 1 < __n 53 && !traits_type::eq_int_type(__c, __eof) 54 && !traits_type::eq_int_type(__c, __idelim)) 55 { 56 streamsize __size = std::min(streamsize(__sb->egptr() 57 - __sb->gptr()), 58 streamsize(__n - _M_gcount 59 - 1)); 60 if (__size > 1) 61 { 62 const char_type* __p = traits_type::find(__sb->gptr(), 63 __size, 64 __delim); 65 if (__p) 66 __size = __p - __sb->gptr(); 67 traits_type::copy(__s, __sb->gptr(), __size); 68 __s += __size; 69 __sb->__safe_gbump(__size); 70 _M_gcount += __size; 71 __c = __sb->sgetc(); 72 } 73 else 74 { 75 *__s++ = traits_type::to_char_type(__c); 76 ++_M_gcount; 77 __c = __sb->snextc(); 78 } 79 } 80 81 if (traits_type::eq_int_type(__c, __eof)) 82 __err |= ios_base::eofbit; 83 else if (traits_type::eq_int_type(__c, __idelim)) 84 { 85 ++_M_gcount; 86 __sb->sbumpc(); 87 } 88 else 89 __err |= ios_base::failbit; 90 } 91 __catch(__cxxabiv1::__forced_unwind&) 92 { 93 this->_M_setstate(ios_base::badbit); 94 __throw_exception_again; 95 } 96 __catch(...) 97 { this->_M_setstate(ios_base::badbit); } 98 } 99 // _GLIBCXX_RESOLVE_LIB_DEFECTS 100 // 243. get and getline when sentry reports failure. 101 if (__n > 0) 102 *__s = char_type(); 103 if (!_M_gcount) 104 __err |= ios_base::failbit; 105 if (__err) 106 this->setstate(__err); 107 return *this; 108 } 109 110 template<> 111 basic_istream<char>& 112 basic_istream<char>:: ignore(streamsize __n,int_type __delim)113 ignore(streamsize __n, int_type __delim) 114 { 115 if (traits_type::eq_int_type(__delim, traits_type::eof())) 116 return ignore(__n); 117 118 _M_gcount = 0; 119 sentry __cerb(*this, true); 120 if (__n > 0 && __cerb) 121 { 122 ios_base::iostate __err = ios_base::goodbit; 123 __try 124 { 125 const char_type __cdelim = traits_type::to_char_type(__delim); 126 const int_type __eof = traits_type::eof(); 127 __streambuf_type* __sb = this->rdbuf(); 128 int_type __c = __sb->sgetc(); 129 130 bool __large_ignore = false; 131 while (true) 132 { 133 while (_M_gcount < __n 134 && !traits_type::eq_int_type(__c, __eof) 135 && !traits_type::eq_int_type(__c, __delim)) 136 { 137 streamsize __size = std::min(streamsize(__sb->egptr() 138 - __sb->gptr()), 139 streamsize(__n - _M_gcount)); 140 if (__size > 1) 141 { 142 const char_type* __p = traits_type::find(__sb->gptr(), 143 __size, 144 __cdelim); 145 if (__p) 146 __size = __p - __sb->gptr(); 147 __sb->__safe_gbump(__size); 148 _M_gcount += __size; 149 __c = __sb->sgetc(); 150 } 151 else 152 { 153 ++_M_gcount; 154 __c = __sb->snextc(); 155 } 156 } 157 if (__n == __gnu_cxx::__numeric_traits<streamsize>::__max 158 && !traits_type::eq_int_type(__c, __eof) 159 && !traits_type::eq_int_type(__c, __delim)) 160 { 161 _M_gcount = 162 __gnu_cxx::__numeric_traits<streamsize>::__min; 163 __large_ignore = true; 164 } 165 else 166 break; 167 } 168 169 if (__large_ignore) 170 _M_gcount = __gnu_cxx::__numeric_traits<streamsize>::__max; 171 172 if (traits_type::eq_int_type(__c, __eof)) 173 __err |= ios_base::eofbit; 174 else if (traits_type::eq_int_type(__c, __delim)) 175 { 176 if (_M_gcount 177 < __gnu_cxx::__numeric_traits<streamsize>::__max) 178 ++_M_gcount; 179 __sb->sbumpc(); 180 } 181 } 182 __catch(__cxxabiv1::__forced_unwind&) 183 { 184 this->_M_setstate(ios_base::badbit); 185 __throw_exception_again; 186 } 187 __catch(...) 188 { this->_M_setstate(ios_base::badbit); } 189 if (__err) 190 this->setstate(__err); 191 } 192 return *this; 193 } 194 195 template<> 196 basic_istream<char>& operator >>(basic_istream<char> & __in,char * __s)197 operator>>(basic_istream<char>& __in, char* __s) 198 { 199 typedef basic_istream<char> __istream_type; 200 typedef __istream_type::int_type __int_type; 201 typedef __istream_type::char_type __char_type; 202 typedef __istream_type::traits_type __traits_type; 203 typedef __istream_type::__streambuf_type __streambuf_type; 204 typedef __istream_type::__ctype_type __ctype_type; 205 206 streamsize __extracted = 0; 207 ios_base::iostate __err = ios_base::goodbit; 208 __istream_type::sentry __cerb(__in, false); 209 if (__cerb) 210 { 211 __try 212 { 213 // Figure out how many characters to extract. 214 streamsize __num = __in.width(); 215 if (__num <= 0) 216 __num = __gnu_cxx::__numeric_traits<streamsize>::__max; 217 218 const __ctype_type& __ct = use_facet<__ctype_type>(__in.getloc()); 219 220 const __int_type __eof = __traits_type::eof(); 221 __streambuf_type* __sb = __in.rdbuf(); 222 __int_type __c = __sb->sgetc(); 223 224 while (__extracted < __num - 1 225 && !__traits_type::eq_int_type(__c, __eof) 226 && !__ct.is(ctype_base::space, 227 __traits_type::to_char_type(__c))) 228 { 229 streamsize __size = std::min(streamsize(__sb->egptr() 230 - __sb->gptr()), 231 streamsize(__num - __extracted 232 - 1)); 233 if (__size > 1) 234 { 235 __size = (__ct.scan_is(ctype_base::space, 236 __sb->gptr() + 1, 237 __sb->gptr() + __size) 238 - __sb->gptr()); 239 __traits_type::copy(__s, __sb->gptr(), __size); 240 __s += __size; 241 __sb->__safe_gbump(__size); 242 __extracted += __size; 243 __c = __sb->sgetc(); 244 } 245 else 246 { 247 *__s++ = __traits_type::to_char_type(__c); 248 ++__extracted; 249 __c = __sb->snextc(); 250 } 251 } 252 253 if (__traits_type::eq_int_type(__c, __eof)) 254 __err |= ios_base::eofbit; 255 256 // _GLIBCXX_RESOLVE_LIB_DEFECTS 257 // 68. Extractors for char* should store null at end 258 *__s = __char_type(); 259 __in.width(0); 260 } 261 __catch(__cxxabiv1::__forced_unwind&) 262 { 263 __in._M_setstate(ios_base::badbit); 264 __throw_exception_again; 265 } 266 __catch(...) 267 { __in._M_setstate(ios_base::badbit); } 268 } 269 if (!__extracted) 270 __err |= ios_base::failbit; 271 if (__err) 272 __in.setstate(__err); 273 return __in; 274 } 275 276 template<> 277 basic_istream<char>& operator >>(basic_istream<char> & __in,basic_string<char> & __str)278 operator>>(basic_istream<char>& __in, basic_string<char>& __str) 279 { 280 typedef basic_istream<char> __istream_type; 281 typedef __istream_type::int_type __int_type; 282 typedef __istream_type::traits_type __traits_type; 283 typedef __istream_type::__streambuf_type __streambuf_type; 284 typedef __istream_type::__ctype_type __ctype_type; 285 typedef basic_string<char> __string_type; 286 typedef __string_type::size_type __size_type; 287 288 __size_type __extracted = 0; 289 ios_base::iostate __err = ios_base::goodbit; 290 __istream_type::sentry __cerb(__in, false); 291 if (__cerb) 292 { 293 __try 294 { 295 __str.erase(); 296 const streamsize __w = __in.width(); 297 const __size_type __n = __w > 0 ? static_cast<__size_type>(__w) 298 : __str.max_size(); 299 const __ctype_type& __ct = use_facet<__ctype_type>(__in.getloc()); 300 const __int_type __eof = __traits_type::eof(); 301 __streambuf_type* __sb = __in.rdbuf(); 302 __int_type __c = __sb->sgetc(); 303 304 while (__extracted < __n 305 && !__traits_type::eq_int_type(__c, __eof) 306 && !__ct.is(ctype_base::space, 307 __traits_type::to_char_type(__c))) 308 { 309 streamsize __size = std::min(streamsize(__sb->egptr() 310 - __sb->gptr()), 311 streamsize(__n - __extracted)); 312 if (__size > 1) 313 { 314 __size = (__ct.scan_is(ctype_base::space, 315 __sb->gptr() + 1, 316 __sb->gptr() + __size) 317 - __sb->gptr()); 318 __str.append(__sb->gptr(), __size); 319 __sb->__safe_gbump(__size); 320 __extracted += __size; 321 __c = __sb->sgetc(); 322 } 323 else 324 { 325 __str += __traits_type::to_char_type(__c); 326 ++__extracted; 327 __c = __sb->snextc(); 328 } 329 } 330 331 if (__traits_type::eq_int_type(__c, __eof)) 332 __err |= ios_base::eofbit; 333 __in.width(0); 334 } 335 __catch(__cxxabiv1::__forced_unwind&) 336 { 337 __in._M_setstate(ios_base::badbit); 338 __throw_exception_again; 339 } 340 __catch(...) 341 { 342 // _GLIBCXX_RESOLVE_LIB_DEFECTS 343 // 91. Description of operator>> and getline() for string<> 344 // might cause endless loop 345 __in._M_setstate(ios_base::badbit); 346 } 347 } 348 if (!__extracted) 349 __err |= ios_base::failbit; 350 if (__err) 351 __in.setstate(__err); 352 return __in; 353 } 354 355 template<> 356 basic_istream<char>& getline(basic_istream<char> & __in,basic_string<char> & __str,char __delim)357 getline(basic_istream<char>& __in, basic_string<char>& __str, 358 char __delim) 359 { 360 typedef basic_istream<char> __istream_type; 361 typedef __istream_type::int_type __int_type; 362 typedef __istream_type::char_type __char_type; 363 typedef __istream_type::traits_type __traits_type; 364 typedef __istream_type::__streambuf_type __streambuf_type; 365 typedef basic_string<char> __string_type; 366 typedef __string_type::size_type __size_type; 367 368 __size_type __extracted = 0; 369 const __size_type __n = __str.max_size(); 370 ios_base::iostate __err = ios_base::goodbit; 371 __istream_type::sentry __cerb(__in, true); 372 if (__cerb) 373 { 374 __try 375 { 376 __str.erase(); 377 const __int_type __idelim = __traits_type::to_int_type(__delim); 378 const __int_type __eof = __traits_type::eof(); 379 __streambuf_type* __sb = __in.rdbuf(); 380 __int_type __c = __sb->sgetc(); 381 382 while (__extracted < __n 383 && !__traits_type::eq_int_type(__c, __eof) 384 && !__traits_type::eq_int_type(__c, __idelim)) 385 { 386 streamsize __size = std::min(streamsize(__sb->egptr() 387 - __sb->gptr()), 388 streamsize(__n - __extracted)); 389 if (__size > 1) 390 { 391 const __char_type* __p = __traits_type::find(__sb->gptr(), 392 __size, 393 __delim); 394 if (__p) 395 __size = __p - __sb->gptr(); 396 __str.append(__sb->gptr(), __size); 397 __sb->__safe_gbump(__size); 398 __extracted += __size; 399 __c = __sb->sgetc(); 400 } 401 else 402 { 403 __str += __traits_type::to_char_type(__c); 404 ++__extracted; 405 __c = __sb->snextc(); 406 } 407 } 408 409 if (__traits_type::eq_int_type(__c, __eof)) 410 __err |= ios_base::eofbit; 411 else if (__traits_type::eq_int_type(__c, __idelim)) 412 { 413 ++__extracted; 414 __sb->sbumpc(); 415 } 416 else 417 __err |= ios_base::failbit; 418 } 419 __catch(__cxxabiv1::__forced_unwind&) 420 { 421 __in._M_setstate(ios_base::badbit); 422 __throw_exception_again; 423 } 424 __catch(...) 425 { 426 // _GLIBCXX_RESOLVE_LIB_DEFECTS 427 // 91. Description of operator>> and getline() for string<> 428 // might cause endless loop 429 __in._M_setstate(ios_base::badbit); 430 } 431 } 432 if (!__extracted) 433 __err |= ios_base::failbit; 434 if (__err) 435 __in.setstate(__err); 436 return __in; 437 } 438 439 #ifdef _GLIBCXX_USE_WCHAR_T 440 template<> 441 basic_istream<wchar_t>& 442 basic_istream<wchar_t>:: getline(char_type * __s,streamsize __n,char_type __delim)443 getline(char_type* __s, streamsize __n, char_type __delim) 444 { 445 _M_gcount = 0; 446 ios_base::iostate __err = ios_base::goodbit; 447 sentry __cerb(*this, true); 448 if (__cerb) 449 { 450 __try 451 { 452 const int_type __idelim = traits_type::to_int_type(__delim); 453 const int_type __eof = traits_type::eof(); 454 __streambuf_type* __sb = this->rdbuf(); 455 int_type __c = __sb->sgetc(); 456 457 while (_M_gcount + 1 < __n 458 && !traits_type::eq_int_type(__c, __eof) 459 && !traits_type::eq_int_type(__c, __idelim)) 460 { 461 streamsize __size = std::min(streamsize(__sb->egptr() 462 - __sb->gptr()), 463 streamsize(__n - _M_gcount 464 - 1)); 465 if (__size > 1) 466 { 467 const char_type* __p = traits_type::find(__sb->gptr(), 468 __size, 469 __delim); 470 if (__p) 471 __size = __p - __sb->gptr(); 472 traits_type::copy(__s, __sb->gptr(), __size); 473 __s += __size; 474 __sb->__safe_gbump(__size); 475 _M_gcount += __size; 476 __c = __sb->sgetc(); 477 } 478 else 479 { 480 *__s++ = traits_type::to_char_type(__c); 481 ++_M_gcount; 482 __c = __sb->snextc(); 483 } 484 } 485 486 if (traits_type::eq_int_type(__c, __eof)) 487 __err |= ios_base::eofbit; 488 else if (traits_type::eq_int_type(__c, __idelim)) 489 { 490 ++_M_gcount; 491 __sb->sbumpc(); 492 } 493 else 494 __err |= ios_base::failbit; 495 } 496 __catch(__cxxabiv1::__forced_unwind&) 497 { 498 this->_M_setstate(ios_base::badbit); 499 __throw_exception_again; 500 } 501 __catch(...) 502 { this->_M_setstate(ios_base::badbit); } 503 } 504 // _GLIBCXX_RESOLVE_LIB_DEFECTS 505 // 243. get and getline when sentry reports failure. 506 if (__n > 0) 507 *__s = char_type(); 508 if (!_M_gcount) 509 __err |= ios_base::failbit; 510 if (__err) 511 this->setstate(__err); 512 return *this; 513 } 514 515 template<> 516 basic_istream<wchar_t>& 517 basic_istream<wchar_t>:: ignore(streamsize __n,int_type __delim)518 ignore(streamsize __n, int_type __delim) 519 { 520 if (traits_type::eq_int_type(__delim, traits_type::eof())) 521 return ignore(__n); 522 523 _M_gcount = 0; 524 sentry __cerb(*this, true); 525 if (__n > 0 && __cerb) 526 { 527 ios_base::iostate __err = ios_base::goodbit; 528 __try 529 { 530 const char_type __cdelim = traits_type::to_char_type(__delim); 531 const int_type __eof = traits_type::eof(); 532 __streambuf_type* __sb = this->rdbuf(); 533 int_type __c = __sb->sgetc(); 534 535 bool __large_ignore = false; 536 while (true) 537 { 538 while (_M_gcount < __n 539 && !traits_type::eq_int_type(__c, __eof) 540 && !traits_type::eq_int_type(__c, __delim)) 541 { 542 streamsize __size = std::min(streamsize(__sb->egptr() 543 - __sb->gptr()), 544 streamsize(__n - _M_gcount)); 545 if (__size > 1) 546 { 547 const char_type* __p = traits_type::find(__sb->gptr(), 548 __size, 549 __cdelim); 550 if (__p) 551 __size = __p - __sb->gptr(); 552 __sb->__safe_gbump(__size); 553 _M_gcount += __size; 554 __c = __sb->sgetc(); 555 } 556 else 557 { 558 ++_M_gcount; 559 __c = __sb->snextc(); 560 } 561 } 562 if (__n == __gnu_cxx::__numeric_traits<streamsize>::__max 563 && !traits_type::eq_int_type(__c, __eof) 564 && !traits_type::eq_int_type(__c, __delim)) 565 { 566 _M_gcount = 567 __gnu_cxx::__numeric_traits<streamsize>::__min; 568 __large_ignore = true; 569 } 570 else 571 break; 572 } 573 574 if (__large_ignore) 575 _M_gcount = __gnu_cxx::__numeric_traits<streamsize>::__max; 576 577 if (traits_type::eq_int_type(__c, __eof)) 578 __err |= ios_base::eofbit; 579 else if (traits_type::eq_int_type(__c, __delim)) 580 { 581 if (_M_gcount 582 < __gnu_cxx::__numeric_traits<streamsize>::__max) 583 ++_M_gcount; 584 __sb->sbumpc(); 585 } 586 } 587 __catch(__cxxabiv1::__forced_unwind&) 588 { 589 this->_M_setstate(ios_base::badbit); 590 __throw_exception_again; 591 } 592 __catch(...) 593 { this->_M_setstate(ios_base::badbit); } 594 if (__err) 595 this->setstate(__err); 596 } 597 return *this; 598 } 599 600 template<> 601 basic_istream<wchar_t>& getline(basic_istream<wchar_t> & __in,basic_string<wchar_t> & __str,wchar_t __delim)602 getline(basic_istream<wchar_t>& __in, basic_string<wchar_t>& __str, 603 wchar_t __delim) 604 { 605 typedef basic_istream<wchar_t> __istream_type; 606 typedef __istream_type::int_type __int_type; 607 typedef __istream_type::char_type __char_type; 608 typedef __istream_type::traits_type __traits_type; 609 typedef __istream_type::__streambuf_type __streambuf_type; 610 typedef basic_string<wchar_t> __string_type; 611 typedef __string_type::size_type __size_type; 612 613 __size_type __extracted = 0; 614 const __size_type __n = __str.max_size(); 615 ios_base::iostate __err = ios_base::goodbit; 616 __istream_type::sentry __cerb(__in, true); 617 if (__cerb) 618 { 619 __try 620 { 621 __str.erase(); 622 const __int_type __idelim = __traits_type::to_int_type(__delim); 623 const __int_type __eof = __traits_type::eof(); 624 __streambuf_type* __sb = __in.rdbuf(); 625 __int_type __c = __sb->sgetc(); 626 627 while (__extracted < __n 628 && !__traits_type::eq_int_type(__c, __eof) 629 && !__traits_type::eq_int_type(__c, __idelim)) 630 { 631 streamsize __size = std::min(streamsize(__sb->egptr() 632 - __sb->gptr()), 633 streamsize(__n - __extracted)); 634 if (__size > 1) 635 { 636 const __char_type* __p = __traits_type::find(__sb->gptr(), 637 __size, 638 __delim); 639 if (__p) 640 __size = __p - __sb->gptr(); 641 __str.append(__sb->gptr(), __size); 642 __sb->__safe_gbump(__size); 643 __extracted += __size; 644 __c = __sb->sgetc(); 645 } 646 else 647 { 648 __str += __traits_type::to_char_type(__c); 649 ++__extracted; 650 __c = __sb->snextc(); 651 } 652 } 653 654 if (__traits_type::eq_int_type(__c, __eof)) 655 __err |= ios_base::eofbit; 656 else if (__traits_type::eq_int_type(__c, __idelim)) 657 { 658 ++__extracted; 659 __sb->sbumpc(); 660 } 661 else 662 __err |= ios_base::failbit; 663 } 664 __catch(__cxxabiv1::__forced_unwind&) 665 { 666 __in._M_setstate(ios_base::badbit); 667 __throw_exception_again; 668 } 669 __catch(...) 670 { 671 // _GLIBCXX_RESOLVE_LIB_DEFECTS 672 // 91. Description of operator>> and getline() for string<> 673 // might cause endless loop 674 __in._M_setstate(ios_base::badbit); 675 } 676 } 677 if (!__extracted) 678 __err |= ios_base::failbit; 679 if (__err) 680 __in.setstate(__err); 681 return __in; 682 } 683 #endif 684 685 _GLIBCXX_END_NAMESPACE_VERSION 686 } // namespace 687