1*38fd1498Szrj // String based streams -*- C++ -*- 2*38fd1498Szrj 3*38fd1498Szrj // Copyright (C) 1997-2018 Free Software Foundation, Inc. 4*38fd1498Szrj // 5*38fd1498Szrj // This file is part of the GNU ISO C++ Library. This library is free 6*38fd1498Szrj // software; you can redistribute it and/or modify it under the 7*38fd1498Szrj // terms of the GNU General Public License as published by the 8*38fd1498Szrj // Free Software Foundation; either version 3, or (at your option) 9*38fd1498Szrj // any later version. 10*38fd1498Szrj 11*38fd1498Szrj // This library is distributed in the hope that it will be useful, 12*38fd1498Szrj // but WITHOUT ANY WARRANTY; without even the implied warranty of 13*38fd1498Szrj // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14*38fd1498Szrj // GNU General Public License for more details. 15*38fd1498Szrj 16*38fd1498Szrj // Under Section 7 of GPL version 3, you are granted additional 17*38fd1498Szrj // permissions described in the GCC Runtime Library Exception, version 18*38fd1498Szrj // 3.1, as published by the Free Software Foundation. 19*38fd1498Szrj 20*38fd1498Szrj // You should have received a copy of the GNU General Public License and 21*38fd1498Szrj // a copy of the GCC Runtime Library Exception along with this program; 22*38fd1498Szrj // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see 23*38fd1498Szrj // <http://www.gnu.org/licenses/>. 24*38fd1498Szrj 25*38fd1498Szrj /** @file bits/sstream.tcc 26*38fd1498Szrj * This is an internal header file, included by other library headers. 27*38fd1498Szrj * Do not attempt to use it directly. @headername{sstream} 28*38fd1498Szrj */ 29*38fd1498Szrj 30*38fd1498Szrj // 31*38fd1498Szrj // ISO C++ 14882: 27.7 String-based streams 32*38fd1498Szrj // 33*38fd1498Szrj 34*38fd1498Szrj #ifndef _SSTREAM_TCC 35*38fd1498Szrj #define _SSTREAM_TCC 1 36*38fd1498Szrj 37*38fd1498Szrj #pragma GCC system_header 38*38fd1498Szrj 39*38fd1498Szrj namespace std _GLIBCXX_VISIBILITY(default) 40*38fd1498Szrj { 41*38fd1498Szrj _GLIBCXX_BEGIN_NAMESPACE_VERSION 42*38fd1498Szrj 43*38fd1498Szrj template <class _CharT, class _Traits, class _Alloc> 44*38fd1498Szrj typename basic_stringbuf<_CharT, _Traits, _Alloc>::int_type 45*38fd1498Szrj basic_stringbuf<_CharT, _Traits, _Alloc>:: pbackfail(int_type __c)46*38fd1498Szrj pbackfail(int_type __c) 47*38fd1498Szrj { 48*38fd1498Szrj int_type __ret = traits_type::eof(); 49*38fd1498Szrj if (this->eback() < this->gptr()) 50*38fd1498Szrj { 51*38fd1498Szrj // Try to put back __c into input sequence in one of three ways. 52*38fd1498Szrj // Order these tests done in is unspecified by the standard. 53*38fd1498Szrj const bool __testeof = traits_type::eq_int_type(__c, __ret); 54*38fd1498Szrj if (!__testeof) 55*38fd1498Szrj { 56*38fd1498Szrj const bool __testeq = traits_type::eq(traits_type:: 57*38fd1498Szrj to_char_type(__c), 58*38fd1498Szrj this->gptr()[-1]); 59*38fd1498Szrj const bool __testout = this->_M_mode & ios_base::out; 60*38fd1498Szrj if (__testeq || __testout) 61*38fd1498Szrj { 62*38fd1498Szrj this->gbump(-1); 63*38fd1498Szrj if (!__testeq) 64*38fd1498Szrj *this->gptr() = traits_type::to_char_type(__c); 65*38fd1498Szrj __ret = __c; 66*38fd1498Szrj } 67*38fd1498Szrj } 68*38fd1498Szrj else 69*38fd1498Szrj { 70*38fd1498Szrj this->gbump(-1); 71*38fd1498Szrj __ret = traits_type::not_eof(__c); 72*38fd1498Szrj } 73*38fd1498Szrj } 74*38fd1498Szrj return __ret; 75*38fd1498Szrj } 76*38fd1498Szrj 77*38fd1498Szrj template <class _CharT, class _Traits, class _Alloc> 78*38fd1498Szrj typename basic_stringbuf<_CharT, _Traits, _Alloc>::int_type 79*38fd1498Szrj basic_stringbuf<_CharT, _Traits, _Alloc>:: overflow(int_type __c)80*38fd1498Szrj overflow(int_type __c) 81*38fd1498Szrj { 82*38fd1498Szrj const bool __testout = this->_M_mode & ios_base::out; 83*38fd1498Szrj if (__builtin_expect(!__testout, false)) 84*38fd1498Szrj return traits_type::eof(); 85*38fd1498Szrj 86*38fd1498Szrj const bool __testeof = traits_type::eq_int_type(__c, traits_type::eof()); 87*38fd1498Szrj if (__builtin_expect(__testeof, false)) 88*38fd1498Szrj return traits_type::not_eof(__c); 89*38fd1498Szrj 90*38fd1498Szrj const __size_type __capacity = _M_string.capacity(); 91*38fd1498Szrj 92*38fd1498Szrj #if _GLIBCXX_USE_CXX11_ABI 93*38fd1498Szrj if ((this->epptr() - this->pbase()) < __capacity) 94*38fd1498Szrj { 95*38fd1498Szrj // There is additional capacity in _M_string that can be used. 96*38fd1498Szrj char_type* __base = const_cast<char_type*>(_M_string.data()); 97*38fd1498Szrj _M_pbump(__base, __base + __capacity, this->pptr() - this->pbase()); 98*38fd1498Szrj if (_M_mode & ios_base::in) 99*38fd1498Szrj { 100*38fd1498Szrj const __size_type __nget = this->gptr() - this->eback(); 101*38fd1498Szrj const __size_type __eget = this->egptr() - this->eback(); 102*38fd1498Szrj this->setg(__base, __base + __nget, __base + __eget + 1); 103*38fd1498Szrj } 104*38fd1498Szrj *this->pptr() = traits_type::to_char_type(__c); 105*38fd1498Szrj this->pbump(1); 106*38fd1498Szrj return __c; 107*38fd1498Szrj } 108*38fd1498Szrj #endif 109*38fd1498Szrj 110*38fd1498Szrj const __size_type __max_size = _M_string.max_size(); 111*38fd1498Szrj const bool __testput = this->pptr() < this->epptr(); 112*38fd1498Szrj if (__builtin_expect(!__testput && __capacity == __max_size, false)) 113*38fd1498Szrj return traits_type::eof(); 114*38fd1498Szrj 115*38fd1498Szrj // Try to append __c into output sequence in one of two ways. 116*38fd1498Szrj // Order these tests done in is unspecified by the standard. 117*38fd1498Szrj const char_type __conv = traits_type::to_char_type(__c); 118*38fd1498Szrj if (!__testput) 119*38fd1498Szrj { 120*38fd1498Szrj // NB: Start ostringstream buffers at 512 chars. This is an 121*38fd1498Szrj // experimental value (pronounced "arbitrary" in some of the 122*38fd1498Szrj // hipper English-speaking countries), and can be changed to 123*38fd1498Szrj // suit particular needs. 124*38fd1498Szrj // 125*38fd1498Szrj // _GLIBCXX_RESOLVE_LIB_DEFECTS 126*38fd1498Szrj // 169. Bad efficiency of overflow() mandated 127*38fd1498Szrj // 432. stringbuf::overflow() makes only one write position 128*38fd1498Szrj // available 129*38fd1498Szrj const __size_type __opt_len = std::max(__size_type(2 * __capacity), 130*38fd1498Szrj __size_type(512)); 131*38fd1498Szrj const __size_type __len = std::min(__opt_len, __max_size); 132*38fd1498Szrj __string_type __tmp(_M_string.get_allocator()); 133*38fd1498Szrj __tmp.reserve(__len); 134*38fd1498Szrj if (this->pbase()) 135*38fd1498Szrj __tmp.assign(this->pbase(), this->epptr() - this->pbase()); 136*38fd1498Szrj __tmp.push_back(__conv); 137*38fd1498Szrj _M_string.swap(__tmp); 138*38fd1498Szrj _M_sync(const_cast<char_type*>(_M_string.data()), 139*38fd1498Szrj this->gptr() - this->eback(), this->pptr() - this->pbase()); 140*38fd1498Szrj } 141*38fd1498Szrj else 142*38fd1498Szrj *this->pptr() = __conv; 143*38fd1498Szrj this->pbump(1); 144*38fd1498Szrj return __c; 145*38fd1498Szrj } 146*38fd1498Szrj 147*38fd1498Szrj template <class _CharT, class _Traits, class _Alloc> 148*38fd1498Szrj typename basic_stringbuf<_CharT, _Traits, _Alloc>::int_type 149*38fd1498Szrj basic_stringbuf<_CharT, _Traits, _Alloc>:: underflow()150*38fd1498Szrj underflow() 151*38fd1498Szrj { 152*38fd1498Szrj int_type __ret = traits_type::eof(); 153*38fd1498Szrj const bool __testin = this->_M_mode & ios_base::in; 154*38fd1498Szrj if (__testin) 155*38fd1498Szrj { 156*38fd1498Szrj // Update egptr() to match the actual string end. 157*38fd1498Szrj _M_update_egptr(); 158*38fd1498Szrj 159*38fd1498Szrj if (this->gptr() < this->egptr()) 160*38fd1498Szrj __ret = traits_type::to_int_type(*this->gptr()); 161*38fd1498Szrj } 162*38fd1498Szrj return __ret; 163*38fd1498Szrj } 164*38fd1498Szrj 165*38fd1498Szrj template <class _CharT, class _Traits, class _Alloc> 166*38fd1498Szrj typename basic_stringbuf<_CharT, _Traits, _Alloc>::pos_type 167*38fd1498Szrj basic_stringbuf<_CharT, _Traits, _Alloc>:: seekoff(off_type __off,ios_base::seekdir __way,ios_base::openmode __mode)168*38fd1498Szrj seekoff(off_type __off, ios_base::seekdir __way, ios_base::openmode __mode) 169*38fd1498Szrj { 170*38fd1498Szrj pos_type __ret = pos_type(off_type(-1)); 171*38fd1498Szrj bool __testin = (ios_base::in & this->_M_mode & __mode) != 0; 172*38fd1498Szrj bool __testout = (ios_base::out & this->_M_mode & __mode) != 0; 173*38fd1498Szrj const bool __testboth = __testin && __testout && __way != ios_base::cur; 174*38fd1498Szrj __testin &= !(__mode & ios_base::out); 175*38fd1498Szrj __testout &= !(__mode & ios_base::in); 176*38fd1498Szrj 177*38fd1498Szrj // _GLIBCXX_RESOLVE_LIB_DEFECTS 178*38fd1498Szrj // 453. basic_stringbuf::seekoff need not always fail for an empty stream. 179*38fd1498Szrj const char_type* __beg = __testin ? this->eback() : this->pbase(); 180*38fd1498Szrj if ((__beg || !__off) && (__testin || __testout || __testboth)) 181*38fd1498Szrj { 182*38fd1498Szrj _M_update_egptr(); 183*38fd1498Szrj 184*38fd1498Szrj off_type __newoffi = __off; 185*38fd1498Szrj off_type __newoffo = __newoffi; 186*38fd1498Szrj if (__way == ios_base::cur) 187*38fd1498Szrj { 188*38fd1498Szrj __newoffi += this->gptr() - __beg; 189*38fd1498Szrj __newoffo += this->pptr() - __beg; 190*38fd1498Szrj } 191*38fd1498Szrj else if (__way == ios_base::end) 192*38fd1498Szrj __newoffo = __newoffi += this->egptr() - __beg; 193*38fd1498Szrj 194*38fd1498Szrj if ((__testin || __testboth) 195*38fd1498Szrj && __newoffi >= 0 196*38fd1498Szrj && this->egptr() - __beg >= __newoffi) 197*38fd1498Szrj { 198*38fd1498Szrj this->setg(this->eback(), this->eback() + __newoffi, 199*38fd1498Szrj this->egptr()); 200*38fd1498Szrj __ret = pos_type(__newoffi); 201*38fd1498Szrj } 202*38fd1498Szrj if ((__testout || __testboth) 203*38fd1498Szrj && __newoffo >= 0 204*38fd1498Szrj && this->egptr() - __beg >= __newoffo) 205*38fd1498Szrj { 206*38fd1498Szrj _M_pbump(this->pbase(), this->epptr(), __newoffo); 207*38fd1498Szrj __ret = pos_type(__newoffo); 208*38fd1498Szrj } 209*38fd1498Szrj } 210*38fd1498Szrj return __ret; 211*38fd1498Szrj } 212*38fd1498Szrj 213*38fd1498Szrj template <class _CharT, class _Traits, class _Alloc> 214*38fd1498Szrj typename basic_stringbuf<_CharT, _Traits, _Alloc>::pos_type 215*38fd1498Szrj basic_stringbuf<_CharT, _Traits, _Alloc>:: seekpos(pos_type __sp,ios_base::openmode __mode)216*38fd1498Szrj seekpos(pos_type __sp, ios_base::openmode __mode) 217*38fd1498Szrj { 218*38fd1498Szrj pos_type __ret = pos_type(off_type(-1)); 219*38fd1498Szrj const bool __testin = (ios_base::in & this->_M_mode & __mode) != 0; 220*38fd1498Szrj const bool __testout = (ios_base::out & this->_M_mode & __mode) != 0; 221*38fd1498Szrj 222*38fd1498Szrj const char_type* __beg = __testin ? this->eback() : this->pbase(); 223*38fd1498Szrj if ((__beg || !off_type(__sp)) && (__testin || __testout)) 224*38fd1498Szrj { 225*38fd1498Szrj _M_update_egptr(); 226*38fd1498Szrj 227*38fd1498Szrj const off_type __pos(__sp); 228*38fd1498Szrj const bool __testpos = (0 <= __pos 229*38fd1498Szrj && __pos <= this->egptr() - __beg); 230*38fd1498Szrj if (__testpos) 231*38fd1498Szrj { 232*38fd1498Szrj if (__testin) 233*38fd1498Szrj this->setg(this->eback(), this->eback() + __pos, 234*38fd1498Szrj this->egptr()); 235*38fd1498Szrj if (__testout) 236*38fd1498Szrj _M_pbump(this->pbase(), this->epptr(), __pos); 237*38fd1498Szrj __ret = __sp; 238*38fd1498Szrj } 239*38fd1498Szrj } 240*38fd1498Szrj return __ret; 241*38fd1498Szrj } 242*38fd1498Szrj 243*38fd1498Szrj template <class _CharT, class _Traits, class _Alloc> 244*38fd1498Szrj void 245*38fd1498Szrj basic_stringbuf<_CharT, _Traits, _Alloc>:: _M_sync(char_type * __base,__size_type __i,__size_type __o)246*38fd1498Szrj _M_sync(char_type* __base, __size_type __i, __size_type __o) 247*38fd1498Szrj { 248*38fd1498Szrj const bool __testin = _M_mode & ios_base::in; 249*38fd1498Szrj const bool __testout = _M_mode & ios_base::out; 250*38fd1498Szrj char_type* __endg = __base + _M_string.size(); 251*38fd1498Szrj char_type* __endp = __base + _M_string.capacity(); 252*38fd1498Szrj 253*38fd1498Szrj if (__base != _M_string.data()) 254*38fd1498Szrj { 255*38fd1498Szrj // setbuf: __i == size of buffer area (_M_string.size() == 0). 256*38fd1498Szrj __endg += __i; 257*38fd1498Szrj __i = 0; 258*38fd1498Szrj __endp = __endg; 259*38fd1498Szrj } 260*38fd1498Szrj 261*38fd1498Szrj if (__testin) 262*38fd1498Szrj this->setg(__base, __base + __i, __endg); 263*38fd1498Szrj if (__testout) 264*38fd1498Szrj { 265*38fd1498Szrj _M_pbump(__base, __endp, __o); 266*38fd1498Szrj // egptr() always tracks the string end. When !__testin, 267*38fd1498Szrj // for the correct functioning of the streambuf inlines 268*38fd1498Szrj // the other get area pointers are identical. 269*38fd1498Szrj if (!__testin) 270*38fd1498Szrj this->setg(__endg, __endg, __endg); 271*38fd1498Szrj } 272*38fd1498Szrj } 273*38fd1498Szrj 274*38fd1498Szrj template <class _CharT, class _Traits, class _Alloc> 275*38fd1498Szrj void 276*38fd1498Szrj basic_stringbuf<_CharT, _Traits, _Alloc>:: _M_pbump(char_type * __pbeg,char_type * __pend,off_type __off)277*38fd1498Szrj _M_pbump(char_type* __pbeg, char_type* __pend, off_type __off) 278*38fd1498Szrj { 279*38fd1498Szrj this->setp(__pbeg, __pend); 280*38fd1498Szrj while (__off > __gnu_cxx::__numeric_traits<int>::__max) 281*38fd1498Szrj { 282*38fd1498Szrj this->pbump(__gnu_cxx::__numeric_traits<int>::__max); 283*38fd1498Szrj __off -= __gnu_cxx::__numeric_traits<int>::__max; 284*38fd1498Szrj } 285*38fd1498Szrj this->pbump(__off); 286*38fd1498Szrj } 287*38fd1498Szrj 288*38fd1498Szrj // Inhibit implicit instantiations for required instantiations, 289*38fd1498Szrj // which are defined via explicit instantiations elsewhere. 290*38fd1498Szrj #if _GLIBCXX_EXTERN_TEMPLATE 291*38fd1498Szrj extern template class basic_stringbuf<char>; 292*38fd1498Szrj extern template class basic_istringstream<char>; 293*38fd1498Szrj extern template class basic_ostringstream<char>; 294*38fd1498Szrj extern template class basic_stringstream<char>; 295*38fd1498Szrj 296*38fd1498Szrj #ifdef _GLIBCXX_USE_WCHAR_T 297*38fd1498Szrj extern template class basic_stringbuf<wchar_t>; 298*38fd1498Szrj extern template class basic_istringstream<wchar_t>; 299*38fd1498Szrj extern template class basic_ostringstream<wchar_t>; 300*38fd1498Szrj extern template class basic_stringstream<wchar_t>; 301*38fd1498Szrj #endif 302*38fd1498Szrj #endif 303*38fd1498Szrj 304*38fd1498Szrj _GLIBCXX_END_NAMESPACE_VERSION 305*38fd1498Szrj } // namespace std 306*38fd1498Szrj 307*38fd1498Szrj #endif 308