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