1 // Input streams -*- C++ -*-
3 // Copyright (C) 2004-2024 Free Software Foundation, Inc.
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)
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.
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.
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/>.
26 // ISO C++ 14882: 27.6.1 Input streams
31 namespace std
_GLIBCXX_VISIBILITY(default)
33 _GLIBCXX_BEGIN_NAMESPACE_VERSION
38 getline(char_type
* __s
, streamsize __n
, char_type __delim
)
41 ios_base::iostate __err
= ios_base::goodbit
;
42 sentry
__cerb(*this, true);
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();
52 while (_M_gcount
+ 1 < __n
53 && !traits_type::eq_int_type(__c
, __eof
)
54 && !traits_type::eq_int_type(__c
, __idelim
))
56 streamsize __size
= std::min(streamsize(__sb
->egptr()
58 streamsize(__n
- _M_gcount
62 const char_type
* __p
= traits_type::find(__sb
->gptr(),
66 __size
= __p
- __sb
->gptr();
67 traits_type::copy(__s
, __sb
->gptr(), __size
);
69 __sb
->__safe_gbump(__size
);
75 *__s
++ = traits_type::to_char_type(__c
);
81 if (traits_type::eq_int_type(__c
, __eof
))
82 __err
|= ios_base::eofbit
;
83 else if (traits_type::eq_int_type(__c
, __idelim
))
89 __err
|= ios_base::failbit
;
91 __catch(__cxxabiv1::__forced_unwind
&)
93 this->_M_setstate(ios_base::badbit
);
94 __throw_exception_again
;
97 { this->_M_setstate(ios_base::badbit
); }
99 // _GLIBCXX_RESOLVE_LIB_DEFECTS
100 // 243. get and getline when sentry reports failure.
104 __err
|= ios_base::failbit
;
106 this->setstate(__err
);
112 basic_istream
<char>::
113 ignore(streamsize __n
, int_type __delim
)
116 // If conversion to int_type changes the value then __delim does not
117 // correspond to a value of type char_type, and so will never match
118 // a character extracted from the input sequence. Just use ignore(n).
119 const int_type chk_delim
= traits_type::to_int_type(__delim
);
120 const bool matchable
= traits_type::eq_int_type(chk_delim
, __delim
);
121 if (__builtin_expect(!matchable
, 0))
123 // Now we know that __delim is a valid char_type value, so it's safe
124 // for the code below to use traits_type::find to search for it.
128 sentry
__cerb(*this, true);
129 if (__n
> 0 && __cerb
)
131 ios_base::iostate __err
= ios_base::goodbit
;
134 const char_type __cdelim
= traits_type::to_char_type(__delim
);
135 const int_type __eof
= traits_type::eof();
136 __streambuf_type
* __sb
= this->rdbuf();
137 int_type __c
= __sb
->sgetc();
139 bool __large_ignore
= false;
142 while (_M_gcount
< __n
143 && !traits_type::eq_int_type(__c
, __eof
)
144 && !traits_type::eq_int_type(__c
, __delim
))
146 streamsize __size
= std::min(streamsize(__sb
->egptr()
148 streamsize(__n
- _M_gcount
));
151 const char_type
* __p
= traits_type::find(__sb
->gptr(),
155 __size
= __p
- __sb
->gptr();
156 __sb
->__safe_gbump(__size
);
163 __c
= __sb
->snextc();
166 if (__n
== __gnu_cxx::__numeric_traits
<streamsize
>::__max
167 && !traits_type::eq_int_type(__c
, __eof
)
168 && !traits_type::eq_int_type(__c
, __delim
))
171 __gnu_cxx::__numeric_traits
<streamsize
>::__min
;
172 __large_ignore
= true;
178 if (__n
== __gnu_cxx::__numeric_traits
<streamsize
>::__max
)
181 _M_gcount
= __gnu_cxx::__numeric_traits
<streamsize
>::__max
;
183 if (traits_type::eq_int_type(__c
, __eof
))
184 __err
|= ios_base::eofbit
;
187 if (_M_gcount
!= __n
)
192 else if (_M_gcount
< __n
) // implies __c == __delim or EOF
194 if (traits_type::eq_int_type(__c
, __eof
))
195 __err
|= ios_base::eofbit
;
203 __catch(__cxxabiv1::__forced_unwind
&)
205 this->_M_setstate(ios_base::badbit
);
206 __throw_exception_again
;
209 { this->_M_setstate(ios_base::badbit
); }
211 this->setstate(__err
);
217 __istream_extract(istream
& __in
, char* __s
, streamsize __num
)
219 typedef basic_istream
<char> __istream_type
;
220 typedef __istream_type::int_type __int_type
;
221 typedef __istream_type::char_type __char_type
;
222 typedef __istream_type::traits_type __traits_type
;
223 typedef __istream_type::__streambuf_type __streambuf_type
;
224 typedef __istream_type::__ctype_type __ctype_type
;
226 streamsize __extracted
= 0;
227 ios_base::iostate __err
= ios_base::goodbit
;
228 __istream_type::sentry
__cerb(__in
, false);
233 // Figure out how many characters to extract.
234 streamsize __width
= __in
.width();
235 if (0 < __width
&& __width
< __num
)
238 const __ctype_type
& __ct
= use_facet
<__ctype_type
>(__in
.getloc());
240 const __int_type __eof
= __traits_type::eof();
241 __streambuf_type
* __sb
= __in
.rdbuf();
242 __int_type __c
= __sb
->sgetc();
244 while (__extracted
< __num
- 1
245 && !__traits_type::eq_int_type(__c
, __eof
)
246 && !__ct
.is(ctype_base::space
,
247 __traits_type::to_char_type(__c
)))
249 streamsize __size
= std::min(streamsize(__sb
->egptr()
251 streamsize(__num
- __extracted
255 __size
= (__ct
.scan_is(ctype_base::space
,
257 __sb
->gptr() + __size
)
259 __traits_type::copy(__s
, __sb
->gptr(), __size
);
261 __sb
->__safe_gbump(__size
);
262 __extracted
+= __size
;
267 *__s
++ = __traits_type::to_char_type(__c
);
269 __c
= __sb
->snextc();
273 if (__extracted
< __num
- 1
274 && __traits_type::eq_int_type(__c
, __eof
))
275 __err
|= ios_base::eofbit
;
277 // _GLIBCXX_RESOLVE_LIB_DEFECTS
278 // 68. Extractors for char* should store null at end
279 *__s
= __char_type();
282 __catch(__cxxabiv1::__forced_unwind
&)
284 __in
._M_setstate(ios_base::badbit
);
285 __throw_exception_again
;
288 { __in
._M_setstate(ios_base::badbit
); }
291 __err
|= ios_base::failbit
;
293 __in
.setstate(__err
);
296 #ifdef _GLIBCXX_USE_WCHAR_T
298 basic_istream
<wchar_t>&
299 basic_istream
<wchar_t>::
300 getline(char_type
* __s
, streamsize __n
, char_type __delim
)
303 ios_base::iostate __err
= ios_base::goodbit
;
304 sentry
__cerb(*this, true);
309 const int_type __idelim
= traits_type::to_int_type(__delim
);
310 const int_type __eof
= traits_type::eof();
311 __streambuf_type
* __sb
= this->rdbuf();
312 int_type __c
= __sb
->sgetc();
314 while (_M_gcount
+ 1 < __n
315 && !traits_type::eq_int_type(__c
, __eof
)
316 && !traits_type::eq_int_type(__c
, __idelim
))
318 streamsize __size
= std::min(streamsize(__sb
->egptr()
320 streamsize(__n
- _M_gcount
324 const char_type
* __p
= traits_type::find(__sb
->gptr(),
328 __size
= __p
- __sb
->gptr();
329 traits_type::copy(__s
, __sb
->gptr(), __size
);
331 __sb
->__safe_gbump(__size
);
337 *__s
++ = traits_type::to_char_type(__c
);
339 __c
= __sb
->snextc();
343 if (traits_type::eq_int_type(__c
, __eof
))
344 __err
|= ios_base::eofbit
;
345 else if (traits_type::eq_int_type(__c
, __idelim
))
351 __err
|= ios_base::failbit
;
353 __catch(__cxxabiv1::__forced_unwind
&)
355 this->_M_setstate(ios_base::badbit
);
356 __throw_exception_again
;
359 { this->_M_setstate(ios_base::badbit
); }
361 // _GLIBCXX_RESOLVE_LIB_DEFECTS
362 // 243. get and getline when sentry reports failure.
366 __err
|= ios_base::failbit
;
368 this->setstate(__err
);
373 basic_istream
<wchar_t>&
374 basic_istream
<wchar_t>::
375 ignore(streamsize __n
, int_type __delim
)
377 if (traits_type::eq_int_type(__delim
, traits_type::eof()))
381 sentry
__cerb(*this, true);
382 if (__n
> 0 && __cerb
)
384 ios_base::iostate __err
= ios_base::goodbit
;
387 const char_type __cdelim
= traits_type::to_char_type(__delim
);
388 const int_type __eof
= traits_type::eof();
389 __streambuf_type
* __sb
= this->rdbuf();
390 int_type __c
= __sb
->sgetc();
392 bool __large_ignore
= false;
395 while (_M_gcount
< __n
396 && !traits_type::eq_int_type(__c
, __eof
)
397 && !traits_type::eq_int_type(__c
, __delim
))
399 streamsize __size
= std::min(streamsize(__sb
->egptr()
401 streamsize(__n
- _M_gcount
));
404 const char_type
* __p
= traits_type::find(__sb
->gptr(),
408 __size
= __p
- __sb
->gptr();
409 __sb
->__safe_gbump(__size
);
416 __c
= __sb
->snextc();
419 if (__n
== __gnu_cxx::__numeric_traits
<streamsize
>::__max
420 && !traits_type::eq_int_type(__c
, __eof
)
421 && !traits_type::eq_int_type(__c
, __delim
))
424 __gnu_cxx::__numeric_traits
<streamsize
>::__min
;
425 __large_ignore
= true;
431 if (__n
== __gnu_cxx::__numeric_traits
<streamsize
>::__max
)
434 _M_gcount
= __gnu_cxx::__numeric_traits
<streamsize
>::__max
;
436 if (traits_type::eq_int_type(__c
, __eof
))
437 __err
|= ios_base::eofbit
;
440 if (_M_gcount
!= __n
)
445 else if (_M_gcount
< __n
) // implies __c == __delim or EOF
447 if (traits_type::eq_int_type(__c
, __eof
))
448 __err
|= ios_base::eofbit
;
456 __catch(__cxxabiv1::__forced_unwind
&)
458 this->_M_setstate(ios_base::badbit
);
459 __throw_exception_again
;
462 { this->_M_setstate(ios_base::badbit
); }
464 this->setstate(__err
);
471 _GLIBCXX_END_NAMESPACE_VERSION