1*38fd1498Szrj // strstream definitions -*- C++ -*- 2*38fd1498Szrj 3*38fd1498Szrj // Copyright (C) 2001-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 /* 26*38fd1498Szrj * Copyright (c) 1998 27*38fd1498Szrj * Silicon Graphics Computer Systems, Inc. 28*38fd1498Szrj * 29*38fd1498Szrj * Permission to use, copy, modify, distribute and sell this software 30*38fd1498Szrj * and its documentation for any purpose is hereby granted without fee, 31*38fd1498Szrj * provided that the above copyright notice appear in all copies and 32*38fd1498Szrj * that both that copyright notice and this permission notice appear 33*38fd1498Szrj * in supporting documentation. Silicon Graphics makes no 34*38fd1498Szrj * representations about the suitability of this software for any 35*38fd1498Szrj * purpose. It is provided "as is" without express or implied warranty. 36*38fd1498Szrj */ 37*38fd1498Szrj 38*38fd1498Szrj // Implementation of the classes in header <strstream>. 39*38fd1498Szrj // WARNING: The classes defined in <strstream> are DEPRECATED. This 40*38fd1498Szrj // header is defined in section D.7.1 of the C++ standard, and it 41*38fd1498Szrj // MAY BE REMOVED in a future standard revision. You should use the 42*38fd1498Szrj // header <sstream> instead. 43*38fd1498Szrj 44*38fd1498Szrj #include <strstream> 45*38fd1498Szrj #include <algorithm> 46*38fd1498Szrj #include <new> 47*38fd1498Szrj #include <stdlib.h> 48*38fd1498Szrj #include <string.h> 49*38fd1498Szrj #include <limits.h> 50*38fd1498Szrj 51*38fd1498Szrj namespace std _GLIBCXX_VISIBILITY(default) 52*38fd1498Szrj { 53*38fd1498Szrj _GLIBCXX_BEGIN_NAMESPACE_VERSION 54*38fd1498Szrj strstreambuf(streamsize initial_capacity)55*38fd1498Szrj strstreambuf::strstreambuf(streamsize initial_capacity) 56*38fd1498Szrj : _Base(), _M_alloc_fun(0), _M_free_fun(0), _M_dynamic(true), 57*38fd1498Szrj _M_frozen(false), _M_constant(false) 58*38fd1498Szrj { 59*38fd1498Szrj streamsize n = std::max(initial_capacity, streamsize(16)); 60*38fd1498Szrj 61*38fd1498Szrj char* buf = _M_alloc(n); 62*38fd1498Szrj if (buf) 63*38fd1498Szrj { 64*38fd1498Szrj setp(buf, buf + n); 65*38fd1498Szrj setg(buf, buf, buf); 66*38fd1498Szrj } 67*38fd1498Szrj } 68*38fd1498Szrj strstreambuf(void * (* alloc_f)(size_t),void (* free_f)(void *))69*38fd1498Szrj strstreambuf::strstreambuf(void* (*alloc_f)(size_t), void (*free_f)(void*)) 70*38fd1498Szrj : _Base(), _M_alloc_fun(alloc_f), _M_free_fun(free_f), _M_dynamic(true), 71*38fd1498Szrj _M_frozen(false), _M_constant(false) 72*38fd1498Szrj { 73*38fd1498Szrj streamsize n = 16; 74*38fd1498Szrj 75*38fd1498Szrj char* buf = _M_alloc(n); 76*38fd1498Szrj if (buf) 77*38fd1498Szrj { 78*38fd1498Szrj setp(buf, buf + n); 79*38fd1498Szrj setg(buf, buf, buf); 80*38fd1498Szrj } 81*38fd1498Szrj } 82*38fd1498Szrj strstreambuf(char * get,streamsize n,char * put)83*38fd1498Szrj strstreambuf::strstreambuf(char* get, streamsize n, char* put) throw () 84*38fd1498Szrj : _Base(), _M_alloc_fun(0), _M_free_fun(0), _M_dynamic(false), 85*38fd1498Szrj _M_frozen(false), _M_constant(false) 86*38fd1498Szrj { _M_setup(get, put, n); } 87*38fd1498Szrj strstreambuf(signed char * get,streamsize n,signed char * put)88*38fd1498Szrj strstreambuf::strstreambuf(signed char* get, streamsize n, signed char* put) throw () 89*38fd1498Szrj : _Base(), _M_alloc_fun(0), _M_free_fun(0), _M_dynamic(false), 90*38fd1498Szrj _M_frozen(false), _M_constant(false) 91*38fd1498Szrj { _M_setup(reinterpret_cast<char*>(get), reinterpret_cast<char*>(put), n); } 92*38fd1498Szrj strstreambuf(unsigned char * get,streamsize n,unsigned char * put)93*38fd1498Szrj strstreambuf::strstreambuf(unsigned char* get, streamsize n, 94*38fd1498Szrj unsigned char* put) throw () 95*38fd1498Szrj : _Base(), _M_alloc_fun(0), _M_free_fun(0), _M_dynamic(false), 96*38fd1498Szrj _M_frozen(false), _M_constant(false) 97*38fd1498Szrj { _M_setup(reinterpret_cast<char*>(get), reinterpret_cast<char*>(put), n); } 98*38fd1498Szrj strstreambuf(const char * get,streamsize n)99*38fd1498Szrj strstreambuf::strstreambuf(const char* get, streamsize n) throw () 100*38fd1498Szrj : _Base(), _M_alloc_fun(0), _M_free_fun(0), _M_dynamic(false), 101*38fd1498Szrj _M_frozen(false), _M_constant(true) 102*38fd1498Szrj { _M_setup(const_cast<char*>(get), 0, n); } 103*38fd1498Szrj strstreambuf(const signed char * get,streamsize n)104*38fd1498Szrj strstreambuf::strstreambuf(const signed char* get, streamsize n) throw () 105*38fd1498Szrj : _Base(), _M_alloc_fun(0), _M_free_fun(0), _M_dynamic(false), 106*38fd1498Szrj _M_frozen(false), _M_constant(true) 107*38fd1498Szrj { _M_setup(reinterpret_cast<char*>(const_cast<signed char*>(get)), 0, n); } 108*38fd1498Szrj strstreambuf(const unsigned char * get,streamsize n)109*38fd1498Szrj strstreambuf::strstreambuf(const unsigned char* get, streamsize n) throw () 110*38fd1498Szrj : _Base(), _M_alloc_fun(0), _M_free_fun(0), _M_dynamic(false), 111*38fd1498Szrj _M_frozen(false), _M_constant(true) 112*38fd1498Szrj { _M_setup(reinterpret_cast<char*>(const_cast<unsigned char*>(get)), 0, n); } 113*38fd1498Szrj ~strstreambuf()114*38fd1498Szrj strstreambuf::~strstreambuf() 115*38fd1498Szrj { 116*38fd1498Szrj if (_M_dynamic && !_M_frozen) 117*38fd1498Szrj _M_free(eback()); 118*38fd1498Szrj } 119*38fd1498Szrj 120*38fd1498Szrj void freeze(bool frozenflag)121*38fd1498Szrj strstreambuf::freeze(bool frozenflag) throw () 122*38fd1498Szrj { 123*38fd1498Szrj if (_M_dynamic) 124*38fd1498Szrj _M_frozen = frozenflag; 125*38fd1498Szrj } 126*38fd1498Szrj 127*38fd1498Szrj char* str()128*38fd1498Szrj strstreambuf::str() throw () 129*38fd1498Szrj { 130*38fd1498Szrj freeze(true); 131*38fd1498Szrj return eback(); 132*38fd1498Szrj } 133*38fd1498Szrj 134*38fd1498Szrj int pcount() const135*38fd1498Szrj strstreambuf::pcount() const throw () 136*38fd1498Szrj { return pptr() ? pptr() - pbase() : 0; } 137*38fd1498Szrj 138*38fd1498Szrj strstreambuf::int_type overflow(int_type c)139*38fd1498Szrj strstreambuf::overflow(int_type c) 140*38fd1498Szrj { 141*38fd1498Szrj if (c == traits_type::eof()) 142*38fd1498Szrj return traits_type::not_eof(c); 143*38fd1498Szrj 144*38fd1498Szrj // Try to expand the buffer. 145*38fd1498Szrj if (pptr() == epptr() && _M_dynamic && !_M_frozen && !_M_constant) 146*38fd1498Szrj { 147*38fd1498Szrj ptrdiff_t old_size = epptr() - pbase(); 148*38fd1498Szrj ptrdiff_t new_size = std::max(ptrdiff_t(2 * old_size), ptrdiff_t(1)); 149*38fd1498Szrj 150*38fd1498Szrj char* buf = _M_alloc(new_size); 151*38fd1498Szrj if (buf) 152*38fd1498Szrj { 153*38fd1498Szrj memcpy(buf, pbase(), old_size); 154*38fd1498Szrj char* old_buffer = pbase(); 155*38fd1498Szrj bool reposition_get = false; 156*38fd1498Szrj ptrdiff_t old_get_offset; 157*38fd1498Szrj if (gptr() != 0) 158*38fd1498Szrj { 159*38fd1498Szrj reposition_get = true; 160*38fd1498Szrj old_get_offset = gptr() - eback(); 161*38fd1498Szrj } 162*38fd1498Szrj 163*38fd1498Szrj setp(buf, buf + new_size); 164*38fd1498Szrj __safe_pbump(old_size); 165*38fd1498Szrj 166*38fd1498Szrj if (reposition_get) 167*38fd1498Szrj setg(buf, buf + old_get_offset, buf + 168*38fd1498Szrj std::max(old_get_offset, old_size)); 169*38fd1498Szrj 170*38fd1498Szrj _M_free(old_buffer); 171*38fd1498Szrj } 172*38fd1498Szrj } 173*38fd1498Szrj 174*38fd1498Szrj if (pptr() != epptr()) 175*38fd1498Szrj { 176*38fd1498Szrj *pptr() = c; 177*38fd1498Szrj pbump(1); 178*38fd1498Szrj return c; 179*38fd1498Szrj } 180*38fd1498Szrj else 181*38fd1498Szrj return traits_type::eof(); 182*38fd1498Szrj } 183*38fd1498Szrj 184*38fd1498Szrj strstreambuf::int_type pbackfail(int_type c)185*38fd1498Szrj strstreambuf::pbackfail(int_type c) 186*38fd1498Szrj { 187*38fd1498Szrj if (gptr() != eback()) 188*38fd1498Szrj { 189*38fd1498Szrj if (c == _Traits::eof()) 190*38fd1498Szrj { 191*38fd1498Szrj gbump(-1); 192*38fd1498Szrj return _Traits::not_eof(c); 193*38fd1498Szrj } 194*38fd1498Szrj else if (c == _Traits::to_int_type(gptr()[-1])) 195*38fd1498Szrj { // KLUDGE 196*38fd1498Szrj gbump(-1); 197*38fd1498Szrj return c; 198*38fd1498Szrj } 199*38fd1498Szrj else if (!_M_constant) 200*38fd1498Szrj { 201*38fd1498Szrj gbump(-1); 202*38fd1498Szrj *gptr() = c; 203*38fd1498Szrj return c; 204*38fd1498Szrj } 205*38fd1498Szrj } 206*38fd1498Szrj return _Traits::eof(); 207*38fd1498Szrj } 208*38fd1498Szrj 209*38fd1498Szrj strstreambuf::int_type underflow()210*38fd1498Szrj strstreambuf::underflow() 211*38fd1498Szrj { 212*38fd1498Szrj if (gptr() == egptr() && pptr() && pptr() > egptr()) 213*38fd1498Szrj setg(eback(), gptr(), pptr()); 214*38fd1498Szrj 215*38fd1498Szrj if (gptr() != egptr()) 216*38fd1498Szrj return (unsigned char) *gptr(); 217*38fd1498Szrj else 218*38fd1498Szrj return _Traits::eof(); 219*38fd1498Szrj } 220*38fd1498Szrj 221*38fd1498Szrj basic_streambuf<char, char_traits<char> >* setbuf(char *,streamsize)222*38fd1498Szrj strstreambuf::setbuf(char*, streamsize) 223*38fd1498Szrj { return this; } 224*38fd1498Szrj 225*38fd1498Szrj strstreambuf::pos_type seekoff(off_type off,ios_base::seekdir dir,ios_base::openmode mode)226*38fd1498Szrj strstreambuf::seekoff(off_type off, ios_base::seekdir dir, 227*38fd1498Szrj ios_base::openmode mode) 228*38fd1498Szrj { 229*38fd1498Szrj bool do_get = false; 230*38fd1498Szrj bool do_put = false; 231*38fd1498Szrj 232*38fd1498Szrj if ((mode & (ios_base::in | ios_base::out)) 233*38fd1498Szrj == (ios_base::in | ios_base::out) && 234*38fd1498Szrj (dir == ios_base::beg || dir == ios_base::end)) 235*38fd1498Szrj do_get = do_put = true; 236*38fd1498Szrj else if (mode & ios_base::in) 237*38fd1498Szrj do_get = true; 238*38fd1498Szrj else if (mode & ios_base::out) 239*38fd1498Szrj do_put = true; 240*38fd1498Szrj 241*38fd1498Szrj // !gptr() is here because, according to D.7.1 paragraph 4, the seekable 242*38fd1498Szrj // area is undefined if there is no get area. 243*38fd1498Szrj if ((!do_get && !do_put) || (do_put && !pptr()) || !gptr()) 244*38fd1498Szrj return pos_type(off_type(-1)); 245*38fd1498Szrj 246*38fd1498Szrj char* seeklow = eback(); 247*38fd1498Szrj char* seekhigh = epptr() ? epptr() : egptr(); 248*38fd1498Szrj 249*38fd1498Szrj off_type newoff; 250*38fd1498Szrj switch (dir) 251*38fd1498Szrj { 252*38fd1498Szrj case ios_base::beg: 253*38fd1498Szrj newoff = 0; 254*38fd1498Szrj break; 255*38fd1498Szrj case ios_base::end: 256*38fd1498Szrj newoff = seekhigh - seeklow; 257*38fd1498Szrj break; 258*38fd1498Szrj case ios_base::cur: 259*38fd1498Szrj newoff = do_put ? pptr() - seeklow : gptr() - seeklow; 260*38fd1498Szrj break; 261*38fd1498Szrj default: 262*38fd1498Szrj return pos_type(off_type(-1)); 263*38fd1498Szrj } 264*38fd1498Szrj 265*38fd1498Szrj off += newoff; 266*38fd1498Szrj if (off < 0 || off > seekhigh - seeklow) 267*38fd1498Szrj return pos_type(off_type(-1)); 268*38fd1498Szrj 269*38fd1498Szrj if (do_put) 270*38fd1498Szrj { 271*38fd1498Szrj if (seeklow + off < pbase()) 272*38fd1498Szrj { 273*38fd1498Szrj setp(seeklow, epptr()); 274*38fd1498Szrj __safe_pbump(off); 275*38fd1498Szrj } 276*38fd1498Szrj else 277*38fd1498Szrj { 278*38fd1498Szrj setp(pbase(), epptr()); 279*38fd1498Szrj __safe_pbump(off - (pbase() - seeklow)); 280*38fd1498Szrj } 281*38fd1498Szrj } 282*38fd1498Szrj if (do_get) 283*38fd1498Szrj { 284*38fd1498Szrj if (off <= egptr() - seeklow) 285*38fd1498Szrj setg(seeklow, seeklow + off, egptr()); 286*38fd1498Szrj else if (off <= pptr() - seeklow) 287*38fd1498Szrj setg(seeklow, seeklow + off, pptr()); 288*38fd1498Szrj else 289*38fd1498Szrj setg(seeklow, seeklow + off, epptr()); 290*38fd1498Szrj } 291*38fd1498Szrj return pos_type(newoff); 292*38fd1498Szrj } 293*38fd1498Szrj 294*38fd1498Szrj strstreambuf::pos_type seekpos(pos_type pos,ios_base::openmode mode)295*38fd1498Szrj strstreambuf::seekpos(pos_type pos, ios_base::openmode mode) 296*38fd1498Szrj { return seekoff(pos - pos_type(off_type(0)), ios_base::beg, mode); } 297*38fd1498Szrj 298*38fd1498Szrj char* _M_alloc(size_t n)299*38fd1498Szrj strstreambuf::_M_alloc(size_t n) 300*38fd1498Szrj { 301*38fd1498Szrj if (_M_alloc_fun) 302*38fd1498Szrj return static_cast<char*>(_M_alloc_fun(n)); 303*38fd1498Szrj else 304*38fd1498Szrj return new char[n]; 305*38fd1498Szrj } 306*38fd1498Szrj 307*38fd1498Szrj void _M_free(char * p)308*38fd1498Szrj strstreambuf::_M_free(char* p) 309*38fd1498Szrj { 310*38fd1498Szrj if (p) 311*38fd1498Szrj { 312*38fd1498Szrj if (_M_free_fun) 313*38fd1498Szrj _M_free_fun(p); 314*38fd1498Szrj else 315*38fd1498Szrj delete[] p; 316*38fd1498Szrj } 317*38fd1498Szrj } 318*38fd1498Szrj 319*38fd1498Szrj void _M_setup(char * get,char * put,streamsize n)320*38fd1498Szrj strstreambuf::_M_setup(char* get, char* put, streamsize n) throw () 321*38fd1498Szrj { 322*38fd1498Szrj if (get) 323*38fd1498Szrj { 324*38fd1498Szrj size_t N = n > 0 ? size_t(n) : n == 0 ? strlen(get) : size_t(INT_MAX); 325*38fd1498Szrj 326*38fd1498Szrj if (put) 327*38fd1498Szrj { 328*38fd1498Szrj setg(get, get, put); 329*38fd1498Szrj setp(put, put + N); 330*38fd1498Szrj } 331*38fd1498Szrj else 332*38fd1498Szrj setg(get, get, get + N); 333*38fd1498Szrj } 334*38fd1498Szrj } 335*38fd1498Szrj istrstream(char * s)336*38fd1498Szrj istrstream::istrstream(char* s) 337*38fd1498Szrj : basic_ios<char>(), basic_istream<char>(0), _M_buf(s, 0) 338*38fd1498Szrj { basic_ios<char>::init(&_M_buf); } 339*38fd1498Szrj istrstream(const char * s)340*38fd1498Szrj istrstream::istrstream(const char* s) 341*38fd1498Szrj : basic_ios<char>(), basic_istream<char>(0), _M_buf(s, 0) 342*38fd1498Szrj { basic_ios<char>::init(&_M_buf); } 343*38fd1498Szrj istrstream(char * s,streamsize n)344*38fd1498Szrj istrstream::istrstream(char* s, streamsize n) 345*38fd1498Szrj : basic_ios<char>(), basic_istream<char>(0), _M_buf(s, n) 346*38fd1498Szrj { basic_ios<char>::init(&_M_buf); } 347*38fd1498Szrj istrstream(const char * s,streamsize n)348*38fd1498Szrj istrstream::istrstream(const char* s, streamsize n) 349*38fd1498Szrj : basic_ios<char>(), basic_istream<char>(0), _M_buf(s, n) 350*38fd1498Szrj { basic_ios<char>::init(&_M_buf); } 351*38fd1498Szrj ~istrstream()352*38fd1498Szrj istrstream::~istrstream() { } 353*38fd1498Szrj 354*38fd1498Szrj strstreambuf* rdbuf() const355*38fd1498Szrj istrstream::rdbuf() const throw () 356*38fd1498Szrj { return const_cast<strstreambuf*>(&_M_buf); } 357*38fd1498Szrj 358*38fd1498Szrj char* str()359*38fd1498Szrj istrstream::str() throw () 360*38fd1498Szrj { return _M_buf.str(); } 361*38fd1498Szrj ostrstream()362*38fd1498Szrj ostrstream::ostrstream() 363*38fd1498Szrj : basic_ios<char>(), basic_ostream<char>(0), _M_buf() 364*38fd1498Szrj { basic_ios<char>::init(&_M_buf); } 365*38fd1498Szrj ostrstream(char * s,int n,ios_base::openmode mode)366*38fd1498Szrj ostrstream::ostrstream(char* s, int n, ios_base::openmode mode) 367*38fd1498Szrj : basic_ios<char>(), basic_ostream<char>(0), 368*38fd1498Szrj _M_buf(s, n, mode & ios_base::app ? s + strlen(s) : s) 369*38fd1498Szrj { basic_ios<char>::init(&_M_buf); } 370*38fd1498Szrj ~ostrstream()371*38fd1498Szrj ostrstream::~ostrstream() {} 372*38fd1498Szrj 373*38fd1498Szrj strstreambuf* rdbuf() const374*38fd1498Szrj ostrstream::rdbuf() const throw () 375*38fd1498Szrj { return const_cast<strstreambuf*>(&_M_buf); } 376*38fd1498Szrj 377*38fd1498Szrj void freeze(bool freezeflag)378*38fd1498Szrj ostrstream::freeze(bool freezeflag) throw () 379*38fd1498Szrj { _M_buf.freeze(freezeflag); } 380*38fd1498Szrj 381*38fd1498Szrj char* str()382*38fd1498Szrj ostrstream::str() throw () 383*38fd1498Szrj { return _M_buf.str(); } 384*38fd1498Szrj 385*38fd1498Szrj int pcount() const386*38fd1498Szrj ostrstream::pcount() const throw () 387*38fd1498Szrj { return _M_buf.pcount(); } 388*38fd1498Szrj strstream()389*38fd1498Szrj strstream::strstream() 390*38fd1498Szrj : basic_ios<char>(), basic_iostream<char>(0), _M_buf() 391*38fd1498Szrj { basic_ios<char>::init(&_M_buf); } 392*38fd1498Szrj strstream(char * s,int n,ios_base::openmode mode)393*38fd1498Szrj strstream::strstream(char* s, int n, ios_base::openmode mode) 394*38fd1498Szrj : basic_ios<char>(), basic_iostream<char>(0), 395*38fd1498Szrj _M_buf(s, n, mode & ios_base::app ? s + strlen(s) : s) 396*38fd1498Szrj { basic_ios<char>::init(&_M_buf); } 397*38fd1498Szrj ~strstream()398*38fd1498Szrj strstream::~strstream() { } 399*38fd1498Szrj 400*38fd1498Szrj strstreambuf* rdbuf() const401*38fd1498Szrj strstream::rdbuf() const throw () 402*38fd1498Szrj { return const_cast<strstreambuf*>(&_M_buf); } 403*38fd1498Szrj 404*38fd1498Szrj void freeze(bool freezeflag)405*38fd1498Szrj strstream::freeze(bool freezeflag) throw () 406*38fd1498Szrj { _M_buf.freeze(freezeflag); } 407*38fd1498Szrj 408*38fd1498Szrj int pcount() const409*38fd1498Szrj strstream::pcount() const throw () 410*38fd1498Szrj { return _M_buf.pcount(); } 411*38fd1498Szrj 412*38fd1498Szrj char* str()413*38fd1498Szrj strstream::str() throw () 414*38fd1498Szrj { return _M_buf.str(); } 415*38fd1498Szrj 416*38fd1498Szrj _GLIBCXX_END_NAMESPACE_VERSION 417*38fd1498Szrj } // namespace 418