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