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>& operator >>(basic_istream<char> & __in,basic_string<char> & __str)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>& getline(basic_istream<char> & __in,basic_string<char> & __str,char __delim)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>& getline(basic_istream<wchar_t> & __in,basic_string<wchar_t> & __str,wchar_t __delim)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