strstream.cpp revision 232950
159191Skris//===------------------------ strstream.cpp -------------------------------===// 259191Skris// 359191Skris// The LLVM Compiler Infrastructure 459191Skris// 559191Skris// This file is dual licensed under the MIT and the University of Illinois Open 659191Skris// Source Licenses. See LICENSE.TXT for details. 759191Skris// 859191Skris//===----------------------------------------------------------------------===// 959191Skris 1059191Skris#include "strstream" 1159191Skris#include "algorithm" 1259191Skris#include "climits" 1359191Skris#include "cstring" 1459191Skris 1559191Skris_LIBCPP_BEGIN_NAMESPACE_STD 1659191Skris 1759191Skrisstrstreambuf::strstreambuf(streamsize __alsize) 1859191Skris : __strmode_(__dynamic), 1959191Skris __alsize_(__alsize), 2059191Skris __palloc_(nullptr), 2159191Skris __pfree_(nullptr) 2259191Skris{ 2359191Skris} 24111147Snectar 2559191Skrisstrstreambuf::strstreambuf(void* (*__palloc)(size_t), void (*__pfree)(void*)) 2659191Skris : __strmode_(__dynamic), 2759191Skris __alsize_(__default_alsize), 2859191Skris __palloc_(__palloc), 2959191Skris __pfree_(__pfree) 3059191Skris{ 3159191Skris} 3259191Skris 3359191Skrisvoid 3459191Skrisstrstreambuf::__init(char* __gnext, streamsize __n, char* __pbeg) 3559191Skris{ 3659191Skris if (__n == 0) 3759191Skris __n = static_cast<streamsize>(strlen(__gnext)); 3859191Skris else if (__n < 0) 3959191Skris __n = INT_MAX; 4059191Skris if (__pbeg == nullptr) 4159191Skris setg(__gnext, __gnext, __gnext + __n); 4259191Skris else 4359191Skris { 4459191Skris setg(__gnext, __gnext, __pbeg); 4559191Skris setp(__pbeg, __pbeg + __n); 4659191Skris } 4759191Skris} 4859191Skris 4959191Skrisstrstreambuf::strstreambuf(char* __gnext, streamsize __n, char* __pbeg) 5059191Skris : __strmode_(), 5159191Skris __alsize_(__default_alsize), 5259191Skris __palloc_(nullptr), 5359191Skris __pfree_(nullptr) 5459191Skris{ 5559191Skris __init(__gnext, __n, __pbeg); 5659191Skris} 5759191Skris 5859191Skrisstrstreambuf::strstreambuf(const char* __gnext, streamsize __n) 5959191Skris : __strmode_(__constant), 6059191Skris __alsize_(__default_alsize), 6159191Skris __palloc_(nullptr), 6259191Skris __pfree_(nullptr) 6359191Skris{ 6459191Skris __init((char*)__gnext, __n, nullptr); 6559191Skris} 6659191Skris 6759191Skrisstrstreambuf::strstreambuf(signed char* __gnext, streamsize __n, signed char* __pbeg) 6859191Skris : __strmode_(), 6959191Skris __alsize_(__default_alsize), 7059191Skris __palloc_(nullptr), 7159191Skris __pfree_(nullptr) 7259191Skris{ 7359191Skris __init((char*)__gnext, __n, (char*)__pbeg); 7459191Skris} 7559191Skris 7659191Skrisstrstreambuf::strstreambuf(const signed char* __gnext, streamsize __n) 7759191Skris : __strmode_(__constant), 7859191Skris __alsize_(__default_alsize), 7959191Skris __palloc_(nullptr), 8059191Skris __pfree_(nullptr) 8159191Skris{ 8259191Skris __init((char*)__gnext, __n, nullptr); 8359191Skris} 8459191Skris 8559191Skrisstrstreambuf::strstreambuf(unsigned char* __gnext, streamsize __n, unsigned char* __pbeg) 8659191Skris : __strmode_(), 8759191Skris __alsize_(__default_alsize), 8859191Skris __palloc_(nullptr), 8959191Skris __pfree_(nullptr) 9059191Skris{ 9159191Skris __init((char*)__gnext, __n, (char*)__pbeg); 9259191Skris} 9359191Skris 9459191Skrisstrstreambuf::strstreambuf(const unsigned char* __gnext, streamsize __n) 9559191Skris : __strmode_(__constant), 9659191Skris __alsize_(__default_alsize), 9759191Skris __palloc_(nullptr), 9859191Skris __pfree_(nullptr) 9959191Skris{ 10059191Skris __init((char*)__gnext, __n, nullptr); 10159191Skris} 10259191Skris 10359191Skrisstrstreambuf::~strstreambuf() 10459191Skris{ 10559191Skris if (eback() && (__strmode_ & __allocated) != 0 && (__strmode_ & __frozen) == 0) 10659191Skris { 10759191Skris if (__pfree_) 10859191Skris __pfree_(eback()); 10959191Skris else 11059191Skris delete [] eback(); 11159191Skris } 11259191Skris} 11359191Skris 11459191Skrisvoid 11559191Skrisstrstreambuf::swap(strstreambuf& __rhs) 11659191Skris{ 11759191Skris streambuf::swap(__rhs); 11859191Skris _VSTD::swap(__strmode_, __rhs.__strmode_); 11959191Skris _VSTD::swap(__alsize_, __rhs.__alsize_); 12059191Skris _VSTD::swap(__palloc_, __rhs.__palloc_); 12159191Skris _VSTD::swap(__pfree_, __rhs.__pfree_); 12259191Skris} 12359191Skris 12459191Skrisvoid 12559191Skrisstrstreambuf::freeze(bool __freezefl) 126111147Snectar{ 127111147Snectar if (__strmode_ & __dynamic) 128238405Sjkim { 129111147Snectar if (__freezefl) 130111147Snectar __strmode_ |= __frozen; 131111147Snectar else 132111147Snectar __strmode_ &= ~__frozen; 13359191Skris } 13459191Skris} 13559191Skris 13659191Skrischar* 13759191Skrisstrstreambuf::str() 13859191Skris{ 13959191Skris if (__strmode_ & __dynamic) 14059191Skris __strmode_ |= __frozen; 14159191Skris return eback(); 14259191Skris} 14359191Skris 14459191Skrisint 14559191Skrisstrstreambuf::pcount() const 14659191Skris{ 14759191Skris return static_cast<int>(pptr() - pbase()); 14859191Skris} 14959191Skris 15059191Skrisstrstreambuf::int_type 15159191Skrisstrstreambuf::overflow(int_type __c) 15259191Skris{ 15359191Skris if (__c == EOF) 15459191Skris return int_type(0); 15559191Skris if (pptr() == epptr()) 15659191Skris { 15759191Skris if ((__strmode_ & __dynamic) == 0 || (__strmode_ & __frozen) != 0) 15859191Skris return int_type(EOF); 15959191Skris streamsize old_size = (epptr() ? epptr() : egptr()) - eback(); 16059191Skris streamsize new_size = max<streamsize>(__alsize_, 2*old_size); 16159191Skris char* buf = nullptr; 16259191Skris if (__palloc_) 16359191Skris buf = static_cast<char*>(__palloc_(static_cast<size_t>(new_size))); 16459191Skris else 16559191Skris buf = new char[new_size]; 16659191Skris if (buf == nullptr) 16759191Skris return int_type(EOF); 16859191Skris memcpy(buf, eback(), static_cast<size_t>(old_size)); 16959191Skris ptrdiff_t ninp = gptr() - eback(); 17059191Skris ptrdiff_t einp = egptr() - eback(); 17159191Skris ptrdiff_t nout = pptr() - pbase(); 17259191Skris ptrdiff_t eout = epptr() - pbase(); 17359191Skris if (__strmode_ & __allocated) 17459191Skris { 17559191Skris if (__pfree_) 17659191Skris __pfree_(eback()); 17759191Skris else 17859191Skris delete [] eback(); 17959191Skris } 18059191Skris setg(buf, buf + ninp, buf + einp); 18159191Skris setp(buf + einp, buf + einp + eout); 18259191Skris pbump(static_cast<int>(nout)); 18359191Skris __strmode_ |= __allocated; 18459191Skris } 18559191Skris *pptr() = static_cast<char>(__c); 18659191Skris pbump(1); 18759191Skris return int_type((unsigned char)__c); 18859191Skris} 18959191Skris 19059191Skrisstrstreambuf::int_type 19159191Skrisstrstreambuf::pbackfail(int_type __c) 19259191Skris{ 19359191Skris if (eback() == gptr()) 19459191Skris return EOF; 19559191Skris if (__c == EOF) 19659191Skris { 19759191Skris gbump(-1); 19859191Skris return int_type(0); 19959191Skris } 20059191Skris if (__strmode_ & __constant) 20159191Skris { 20259191Skris if (gptr()[-1] == static_cast<char>(__c)) 20359191Skris { 20459191Skris gbump(-1); 20559191Skris return __c; 20659191Skris } 20759191Skris return EOF; 20859191Skris } 20959191Skris gbump(-1); 21059191Skris *gptr() = static_cast<char>(__c); 21159191Skris return __c; 21259191Skris} 21359191Skris 21459191Skrisstrstreambuf::int_type 21559191Skrisstrstreambuf::underflow() 21659191Skris{ 21759191Skris if (gptr() == egptr()) 21859191Skris { 21959191Skris if (egptr() >= pptr()) 22059191Skris return EOF; 22159191Skris setg(eback(), gptr(), pptr()); 22259191Skris } 22359191Skris return int_type((unsigned char)*gptr()); 22459191Skris} 22559191Skris 22659191Skrisstrstreambuf::pos_type 22759191Skrisstrstreambuf::seekoff(off_type __off, ios_base::seekdir __way, ios_base::openmode __which) 22859191Skris{ 22959191Skris off_type __p(-1); 23059191Skris bool pos_in = __which & ios::in; 23159191Skris bool pos_out = __which & ios::out; 23259191Skris bool legal = false; 23359191Skris switch (__way) 23459191Skris { 23559191Skris case ios::beg: 23659191Skris case ios::end: 23759191Skris if (pos_in || pos_out) 23859191Skris legal = true; 23959191Skris break; 24059191Skris case ios::cur: 24159191Skris if (pos_in != pos_out) 24259191Skris legal = true; 24359191Skris break; 244 } 245 if (pos_in && gptr() == nullptr) 246 legal = false; 247 if (pos_out && pptr() == nullptr) 248 legal = false; 249 if (legal) 250 { 251 off_type newoff; 252 char* seekhigh = epptr() ? epptr() : egptr(); 253 switch (__way) 254 { 255 case ios::beg: 256 newoff = 0; 257 break; 258 case ios::cur: 259 newoff = (pos_in ? gptr() : pptr()) - eback(); 260 break; 261 case ios::end: 262 newoff = seekhigh - eback(); 263 break; 264 } 265 newoff += __off; 266 if (0 <= newoff && newoff <= seekhigh - eback()) 267 { 268 char* newpos = eback() + newoff; 269 if (pos_in) 270 setg(eback(), newpos, _VSTD::max(newpos, egptr())); 271 if (pos_out) 272 { 273 // min(pbase, newpos), newpos, epptr() 274 __off = epptr() - newpos; 275 setp(min(pbase(), newpos), epptr()); 276 pbump(static_cast<int>((epptr() - pbase()) - __off)); 277 } 278 __p = newoff; 279 } 280 } 281 return pos_type(__p); 282} 283 284strstreambuf::pos_type 285strstreambuf::seekpos(pos_type __sp, ios_base::openmode __which) 286{ 287 off_type __p(-1); 288 bool pos_in = __which & ios::in; 289 bool pos_out = __which & ios::out; 290 if (pos_in || pos_out) 291 { 292 if (!((pos_in && gptr() == nullptr) || (pos_out && pptr() == nullptr))) 293 { 294 off_type newoff = __sp; 295 char* seekhigh = epptr() ? epptr() : egptr(); 296 if (0 <= newoff && newoff <= seekhigh - eback()) 297 { 298 char* newpos = eback() + newoff; 299 if (pos_in) 300 setg(eback(), newpos, _VSTD::max(newpos, egptr())); 301 if (pos_out) 302 { 303 // min(pbase, newpos), newpos, epptr() 304 off_type temp = epptr() - newpos; 305 setp(min(pbase(), newpos), epptr()); 306 pbump(static_cast<int>((epptr() - pbase()) - temp)); 307 } 308 __p = newoff; 309 } 310 } 311 } 312 return pos_type(__p); 313} 314 315istrstream::~istrstream() 316{ 317} 318 319ostrstream::~ostrstream() 320{ 321} 322 323strstream::~strstream() 324{ 325} 326 327_LIBCPP_END_NAMESPACE_STD 328