1 // Input streams operating on strings-*- C++ -*-
2 
3 // Copyright (C) 2004-2018 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
292