]> git.ipfire.org Git - thirdparty/gcc.git/blob - libstdc++-v3/src/c++98/istream-string.cc
Update copyright years.
[thirdparty/gcc.git] / libstdc++-v3 / src / c++98 / istream-string.cc
1 // Input streams operating on strings-*- C++ -*-
2
3 // Copyright (C) 2004-2016 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 #ifndef _GLIBCXX_USE_CXX11_ABI
30 // Instantiations in this file use the new SSO std::string ABI unless included
31 // by another file which defines _GLIBCXX_USE_CXX11_ABI=0.
32 # define _GLIBCXX_USE_CXX11_ABI 1
33 #endif
34 #include <istream>
35 #include <string>
36
37 namespace std _GLIBCXX_VISIBILITY(default)
38 {
39 _GLIBCXX_BEGIN_NAMESPACE_VERSION
40
41 template<>
42 basic_istream<char>&
43 operator>>(basic_istream<char>& __in, basic_string<char>& __str)
44 {
45 typedef basic_istream<char> __istream_type;
46 typedef __istream_type::int_type __int_type;
47 typedef __istream_type::traits_type __traits_type;
48 typedef __istream_type::__streambuf_type __streambuf_type;
49 typedef __istream_type::__ctype_type __ctype_type;
50 typedef basic_string<char> __string_type;
51 typedef __string_type::size_type __size_type;
52
53 __size_type __extracted = 0;
54 ios_base::iostate __err = ios_base::goodbit;
55 __istream_type::sentry __cerb(__in, false);
56 if (__cerb)
57 {
58 __try
59 {
60 __str.erase();
61 const streamsize __w = __in.width();
62 const __size_type __n = __w > 0 ? static_cast<__size_type>(__w)
63 : __str.max_size();
64 const __ctype_type& __ct = use_facet<__ctype_type>(__in.getloc());
65 const __int_type __eof = __traits_type::eof();
66 __streambuf_type* __sb = __in.rdbuf();
67 __int_type __c = __sb->sgetc();
68
69 while (__extracted < __n
70 && !__traits_type::eq_int_type(__c, __eof)
71 && !__ct.is(ctype_base::space,
72 __traits_type::to_char_type(__c)))
73 {
74 streamsize __size = std::min(streamsize(__sb->egptr()
75 - __sb->gptr()),
76 streamsize(__n - __extracted));
77 if (__size > 1)
78 {
79 __size = (__ct.scan_is(ctype_base::space,
80 __sb->gptr() + 1,
81 __sb->gptr() + __size)
82 - __sb->gptr());
83 __str.append(__sb->gptr(), __size);
84 __sb->__safe_gbump(__size);
85 __extracted += __size;
86 __c = __sb->sgetc();
87 }
88 else
89 {
90 __str += __traits_type::to_char_type(__c);
91 ++__extracted;
92 __c = __sb->snextc();
93 }
94 }
95
96 if (__traits_type::eq_int_type(__c, __eof))
97 __err |= ios_base::eofbit;
98 __in.width(0);
99 }
100 __catch(__cxxabiv1::__forced_unwind&)
101 {
102 __in._M_setstate(ios_base::badbit);
103 __throw_exception_again;
104 }
105 __catch(...)
106 {
107 // _GLIBCXX_RESOLVE_LIB_DEFECTS
108 // 91. Description of operator>> and getline() for string<>
109 // might cause endless loop
110 __in._M_setstate(ios_base::badbit);
111 }
112 }
113 if (!__extracted)
114 __err |= ios_base::failbit;
115 if (__err)
116 __in.setstate(__err);
117 return __in;
118 }
119
120 template<>
121 basic_istream<char>&
122 getline(basic_istream<char>& __in, basic_string<char>& __str,
123 char __delim)
124 {
125 typedef basic_istream<char> __istream_type;
126 typedef __istream_type::int_type __int_type;
127 typedef __istream_type::char_type __char_type;
128 typedef __istream_type::traits_type __traits_type;
129 typedef __istream_type::__streambuf_type __streambuf_type;
130 typedef basic_string<char> __string_type;
131 typedef __string_type::size_type __size_type;
132
133 __size_type __extracted = 0;
134 const __size_type __n = __str.max_size();
135 ios_base::iostate __err = ios_base::goodbit;
136 __istream_type::sentry __cerb(__in, true);
137 if (__cerb)
138 {
139 __try
140 {
141 __str.erase();
142 const __int_type __idelim = __traits_type::to_int_type(__delim);
143 const __int_type __eof = __traits_type::eof();
144 __streambuf_type* __sb = __in.rdbuf();
145 __int_type __c = __sb->sgetc();
146
147 while (__extracted < __n
148 && !__traits_type::eq_int_type(__c, __eof)
149 && !__traits_type::eq_int_type(__c, __idelim))
150 {
151 streamsize __size = std::min(streamsize(__sb->egptr()
152 - __sb->gptr()),
153 streamsize(__n - __extracted));
154 if (__size > 1)
155 {
156 const __char_type* __p = __traits_type::find(__sb->gptr(),
157 __size,
158 __delim);
159 if (__p)
160 __size = __p - __sb->gptr();
161 __str.append(__sb->gptr(), __size);
162 __sb->__safe_gbump(__size);
163 __extracted += __size;
164 __c = __sb->sgetc();
165 }
166 else
167 {
168 __str += __traits_type::to_char_type(__c);
169 ++__extracted;
170 __c = __sb->snextc();
171 }
172 }
173
174 if (__traits_type::eq_int_type(__c, __eof))
175 __err |= ios_base::eofbit;
176 else if (__traits_type::eq_int_type(__c, __idelim))
177 {
178 ++__extracted;
179 __sb->sbumpc();
180 }
181 else
182 __err |= ios_base::failbit;
183 }
184 __catch(__cxxabiv1::__forced_unwind&)
185 {
186 __in._M_setstate(ios_base::badbit);
187 __throw_exception_again;
188 }
189 __catch(...)
190 {
191 // _GLIBCXX_RESOLVE_LIB_DEFECTS
192 // 91. Description of operator>> and getline() for string<>
193 // might cause endless loop
194 __in._M_setstate(ios_base::badbit);
195 }
196 }
197 if (!__extracted)
198 __err |= ios_base::failbit;
199 if (__err)
200 __in.setstate(__err);
201 return __in;
202 }
203
204 #ifdef _GLIBCXX_USE_WCHAR_T
205 template<>
206 basic_istream<wchar_t>&
207 getline(basic_istream<wchar_t>& __in, basic_string<wchar_t>& __str,
208 wchar_t __delim)
209 {
210 typedef basic_istream<wchar_t> __istream_type;
211 typedef __istream_type::int_type __int_type;
212 typedef __istream_type::char_type __char_type;
213 typedef __istream_type::traits_type __traits_type;
214 typedef __istream_type::__streambuf_type __streambuf_type;
215 typedef basic_string<wchar_t> __string_type;
216 typedef __string_type::size_type __size_type;
217
218 __size_type __extracted = 0;
219 const __size_type __n = __str.max_size();
220 ios_base::iostate __err = ios_base::goodbit;
221 __istream_type::sentry __cerb(__in, true);
222 if (__cerb)
223 {
224 __try
225 {
226 __str.erase();
227 const __int_type __idelim = __traits_type::to_int_type(__delim);
228 const __int_type __eof = __traits_type::eof();
229 __streambuf_type* __sb = __in.rdbuf();
230 __int_type __c = __sb->sgetc();
231
232 while (__extracted < __n
233 && !__traits_type::eq_int_type(__c, __eof)
234 && !__traits_type::eq_int_type(__c, __idelim))
235 {
236 streamsize __size = std::min(streamsize(__sb->egptr()
237 - __sb->gptr()),
238 streamsize(__n - __extracted));
239 if (__size > 1)
240 {
241 const __char_type* __p = __traits_type::find(__sb->gptr(),
242 __size,
243 __delim);
244 if (__p)
245 __size = __p - __sb->gptr();
246 __str.append(__sb->gptr(), __size);
247 __sb->__safe_gbump(__size);
248 __extracted += __size;
249 __c = __sb->sgetc();
250 }
251 else
252 {
253 __str += __traits_type::to_char_type(__c);
254 ++__extracted;
255 __c = __sb->snextc();
256 }
257 }
258
259 if (__traits_type::eq_int_type(__c, __eof))
260 __err |= ios_base::eofbit;
261 else if (__traits_type::eq_int_type(__c, __idelim))
262 {
263 ++__extracted;
264 __sb->sbumpc();
265 }
266 else
267 __err |= ios_base::failbit;
268 }
269 __catch(__cxxabiv1::__forced_unwind&)
270 {
271 __in._M_setstate(ios_base::badbit);
272 __throw_exception_again;
273 }
274 __catch(...)
275 {
276 // _GLIBCXX_RESOLVE_LIB_DEFECTS
277 // 91. Description of operator>> and getline() for string<>
278 // might cause endless loop
279 __in._M_setstate(ios_base::badbit);
280 }
281 }
282 if (!__extracted)
283 __err |= ios_base::failbit;
284 if (__err)
285 __in.setstate(__err);
286 return __in;
287 }
288 #endif
289
290 _GLIBCXX_END_NAMESPACE_VERSION
291 } // namespace