strstream.cpp revision 227825
1227825Stheraven//===------------------------ strstream.cpp -------------------------------===// 2227825Stheraven// 3227825Stheraven// The LLVM Compiler Infrastructure 4227825Stheraven// 5227825Stheraven// This file is dual licensed under the MIT and the University of Illinois Open 6227825Stheraven// Source Licenses. See LICENSE.TXT for details. 7227825Stheraven// 8227825Stheraven//===----------------------------------------------------------------------===// 9227825Stheraven 10227825Stheraven#include "strstream" 11227825Stheraven#include "algorithm" 12227825Stheraven#include "climits" 13227825Stheraven#include "cstring" 14227825Stheraven 15227825Stheraven_LIBCPP_BEGIN_NAMESPACE_STD 16227825Stheraven 17227825Stheravenstrstreambuf::strstreambuf(streamsize __alsize) 18227825Stheraven : __strmode_(__dynamic), 19227825Stheraven __alsize_(__alsize), 20227825Stheraven __palloc_(nullptr), 21227825Stheraven __pfree_(nullptr) 22227825Stheraven{ 23227825Stheraven} 24227825Stheraven 25227825Stheravenstrstreambuf::strstreambuf(void* (*__palloc)(size_t), void (*__pfree)(void*)) 26227825Stheraven : __strmode_(__dynamic), 27227825Stheraven __alsize_(__default_alsize), 28227825Stheraven __palloc_(__palloc), 29227825Stheraven __pfree_(__pfree) 30227825Stheraven{ 31227825Stheraven} 32227825Stheraven 33227825Stheravenvoid 34227825Stheravenstrstreambuf::__init(char* __gnext, streamsize __n, char* __pbeg) 35227825Stheraven{ 36227825Stheraven if (__n == 0) 37227825Stheraven __n = strlen(__gnext); 38227825Stheraven else if (__n < 0) 39227825Stheraven __n = INT_MAX; 40227825Stheraven if (__pbeg == nullptr) 41227825Stheraven setg(__gnext, __gnext, __gnext + __n); 42227825Stheraven else 43227825Stheraven { 44227825Stheraven setg(__gnext, __gnext, __pbeg); 45227825Stheraven setp(__pbeg, __pbeg + __n); 46227825Stheraven } 47227825Stheraven} 48227825Stheraven 49227825Stheravenstrstreambuf::strstreambuf(char* __gnext, streamsize __n, char* __pbeg) 50227825Stheraven : __strmode_(), 51227825Stheraven __alsize_(__default_alsize), 52227825Stheraven __palloc_(nullptr), 53227825Stheraven __pfree_(nullptr) 54227825Stheraven{ 55227825Stheraven __init(__gnext, __n, __pbeg); 56227825Stheraven} 57227825Stheraven 58227825Stheravenstrstreambuf::strstreambuf(const char* __gnext, streamsize __n) 59227825Stheraven : __strmode_(__constant), 60227825Stheraven __alsize_(__default_alsize), 61227825Stheraven __palloc_(nullptr), 62227825Stheraven __pfree_(nullptr) 63227825Stheraven{ 64227825Stheraven __init((char*)__gnext, __n, nullptr); 65227825Stheraven} 66227825Stheraven 67227825Stheravenstrstreambuf::strstreambuf(signed char* __gnext, streamsize __n, signed char* __pbeg) 68227825Stheraven : __strmode_(), 69227825Stheraven __alsize_(__default_alsize), 70227825Stheraven __palloc_(nullptr), 71227825Stheraven __pfree_(nullptr) 72227825Stheraven{ 73227825Stheraven __init((char*)__gnext, __n, (char*)__pbeg); 74227825Stheraven} 75227825Stheraven 76227825Stheravenstrstreambuf::strstreambuf(const signed char* __gnext, streamsize __n) 77227825Stheraven : __strmode_(__constant), 78227825Stheraven __alsize_(__default_alsize), 79227825Stheraven __palloc_(nullptr), 80227825Stheraven __pfree_(nullptr) 81227825Stheraven{ 82227825Stheraven __init((char*)__gnext, __n, nullptr); 83227825Stheraven} 84227825Stheraven 85227825Stheravenstrstreambuf::strstreambuf(unsigned char* __gnext, streamsize __n, unsigned char* __pbeg) 86227825Stheraven : __strmode_(), 87227825Stheraven __alsize_(__default_alsize), 88227825Stheraven __palloc_(nullptr), 89227825Stheraven __pfree_(nullptr) 90227825Stheraven{ 91227825Stheraven __init((char*)__gnext, __n, (char*)__pbeg); 92227825Stheraven} 93227825Stheraven 94227825Stheravenstrstreambuf::strstreambuf(const unsigned char* __gnext, streamsize __n) 95227825Stheraven : __strmode_(__constant), 96227825Stheraven __alsize_(__default_alsize), 97227825Stheraven __palloc_(nullptr), 98227825Stheraven __pfree_(nullptr) 99227825Stheraven{ 100227825Stheraven __init((char*)__gnext, __n, nullptr); 101227825Stheraven} 102227825Stheraven 103227825Stheravenstrstreambuf::~strstreambuf() 104227825Stheraven{ 105227825Stheraven if (eback() && (__strmode_ & __allocated) != 0 && (__strmode_ & __frozen) == 0) 106227825Stheraven { 107227825Stheraven if (__pfree_) 108227825Stheraven __pfree_(eback()); 109227825Stheraven else 110227825Stheraven delete [] eback(); 111227825Stheraven } 112227825Stheraven} 113227825Stheraven 114227825Stheravenvoid 115227825Stheravenstrstreambuf::swap(strstreambuf& __rhs) 116227825Stheraven{ 117227825Stheraven streambuf::swap(__rhs); 118227825Stheraven _VSTD::swap(__strmode_, __rhs.__strmode_); 119227825Stheraven _VSTD::swap(__alsize_, __rhs.__alsize_); 120227825Stheraven _VSTD::swap(__palloc_, __rhs.__palloc_); 121227825Stheraven _VSTD::swap(__pfree_, __rhs.__pfree_); 122227825Stheraven} 123227825Stheraven 124227825Stheravenvoid 125227825Stheravenstrstreambuf::freeze(bool __freezefl) 126227825Stheraven{ 127227825Stheraven if (__strmode_ & __dynamic) 128227825Stheraven { 129227825Stheraven if (__freezefl) 130227825Stheraven __strmode_ |= __frozen; 131227825Stheraven else 132227825Stheraven __strmode_ &= ~__frozen; 133227825Stheraven } 134227825Stheraven} 135227825Stheraven 136227825Stheravenchar* 137227825Stheravenstrstreambuf::str() 138227825Stheraven{ 139227825Stheraven if (__strmode_ & __dynamic) 140227825Stheraven __strmode_ |= __frozen; 141227825Stheraven return eback(); 142227825Stheraven} 143227825Stheraven 144227825Stheravenint 145227825Stheravenstrstreambuf::pcount() const 146227825Stheraven{ 147227825Stheraven return static_cast<int>(pptr() - pbase()); 148227825Stheraven} 149227825Stheraven 150227825Stheravenstrstreambuf::int_type 151227825Stheravenstrstreambuf::overflow(int_type __c) 152227825Stheraven{ 153227825Stheraven if (__c == EOF) 154227825Stheraven return int_type(0); 155227825Stheraven if (pptr() == epptr()) 156227825Stheraven { 157227825Stheraven if ((__strmode_ & __dynamic) == 0 || (__strmode_ & __frozen) != 0) 158227825Stheraven return int_type(EOF); 159227825Stheraven streamsize old_size = (epptr() ? epptr() : egptr()) - eback(); 160227825Stheraven streamsize new_size = max<streamsize>(__alsize_, 2*old_size); 161227825Stheraven char* buf = nullptr; 162227825Stheraven if (__palloc_) 163227825Stheraven buf = static_cast<char*>(__palloc_(new_size)); 164227825Stheraven else 165227825Stheraven buf = new char[new_size]; 166227825Stheraven if (buf == nullptr) 167227825Stheraven return int_type(EOF); 168227825Stheraven memcpy(buf, eback(), old_size); 169227825Stheraven ptrdiff_t ninp = gptr() - eback(); 170227825Stheraven ptrdiff_t einp = egptr() - eback(); 171227825Stheraven ptrdiff_t nout = pptr() - pbase(); 172227825Stheraven ptrdiff_t eout = epptr() - pbase(); 173227825Stheraven if (__strmode_ & __allocated) 174227825Stheraven { 175227825Stheraven if (__pfree_) 176227825Stheraven __pfree_(eback()); 177227825Stheraven else 178227825Stheraven delete [] eback(); 179227825Stheraven } 180227825Stheraven setg(buf, buf + ninp, buf + einp); 181227825Stheraven setp(buf + einp, buf + einp + eout); 182227825Stheraven pbump(nout); 183227825Stheraven __strmode_ |= __allocated; 184227825Stheraven } 185227825Stheraven *pptr() = static_cast<char>(__c); 186227825Stheraven pbump(1); 187227825Stheraven return int_type((unsigned char)__c); 188227825Stheraven} 189227825Stheraven 190227825Stheravenstrstreambuf::int_type 191227825Stheravenstrstreambuf::pbackfail(int_type __c) 192227825Stheraven{ 193227825Stheraven if (eback() == gptr()) 194227825Stheraven return EOF; 195227825Stheraven if (__c == EOF) 196227825Stheraven { 197227825Stheraven gbump(-1); 198227825Stheraven return int_type(0); 199227825Stheraven } 200227825Stheraven if (__strmode_ & __constant) 201227825Stheraven { 202227825Stheraven if (gptr()[-1] == static_cast<char>(__c)) 203227825Stheraven { 204227825Stheraven gbump(-1); 205227825Stheraven return __c; 206227825Stheraven } 207227825Stheraven return EOF; 208227825Stheraven } 209227825Stheraven gbump(-1); 210227825Stheraven *gptr() = static_cast<char>(__c); 211227825Stheraven return __c; 212227825Stheraven} 213227825Stheraven 214227825Stheravenstrstreambuf::int_type 215227825Stheravenstrstreambuf::underflow() 216227825Stheraven{ 217227825Stheraven if (gptr() == egptr()) 218227825Stheraven { 219227825Stheraven if (egptr() >= pptr()) 220227825Stheraven return EOF; 221227825Stheraven setg(eback(), gptr(), pptr()); 222227825Stheraven } 223227825Stheraven return int_type((unsigned char)*gptr()); 224227825Stheraven} 225227825Stheraven 226227825Stheravenstrstreambuf::pos_type 227227825Stheravenstrstreambuf::seekoff(off_type __off, ios_base::seekdir __way, ios_base::openmode __which) 228227825Stheraven{ 229227825Stheraven off_type __p(-1); 230227825Stheraven bool pos_in = __which & ios::in; 231227825Stheraven bool pos_out = __which & ios::out; 232227825Stheraven bool legal = false; 233227825Stheraven switch (__way) 234227825Stheraven { 235227825Stheraven case ios::beg: 236227825Stheraven case ios::end: 237227825Stheraven if (pos_in || pos_out) 238227825Stheraven legal = true; 239227825Stheraven break; 240227825Stheraven case ios::cur: 241227825Stheraven if (pos_in != pos_out) 242227825Stheraven legal = true; 243227825Stheraven break; 244227825Stheraven } 245227825Stheraven if (pos_in && gptr() == nullptr) 246227825Stheraven legal = false; 247227825Stheraven if (pos_out && pptr() == nullptr) 248227825Stheraven legal = false; 249227825Stheraven if (legal) 250227825Stheraven { 251227825Stheraven off_type newoff; 252227825Stheraven char* seekhigh = epptr() ? epptr() : egptr(); 253227825Stheraven switch (__way) 254227825Stheraven { 255227825Stheraven case ios::beg: 256227825Stheraven newoff = 0; 257227825Stheraven break; 258227825Stheraven case ios::cur: 259227825Stheraven newoff = (pos_in ? gptr() : pptr()) - eback(); 260227825Stheraven break; 261227825Stheraven case ios::end: 262227825Stheraven newoff = seekhigh - eback(); 263227825Stheraven break; 264227825Stheraven } 265227825Stheraven newoff += __off; 266227825Stheraven if (0 <= newoff && newoff <= seekhigh - eback()) 267227825Stheraven { 268227825Stheraven char* newpos = eback() + newoff; 269227825Stheraven if (pos_in) 270227825Stheraven setg(eback(), newpos, _VSTD::max(newpos, egptr())); 271227825Stheraven if (pos_out) 272227825Stheraven { 273227825Stheraven // min(pbase, newpos), newpos, epptr() 274227825Stheraven __off = epptr() - newpos; 275227825Stheraven setp(min(pbase(), newpos), epptr()); 276227825Stheraven pbump(static_cast<int>((epptr() - pbase()) - __off)); 277227825Stheraven } 278227825Stheraven __p = newoff; 279227825Stheraven } 280227825Stheraven } 281227825Stheraven return pos_type(__p); 282227825Stheraven} 283227825Stheraven 284227825Stheravenstrstreambuf::pos_type 285227825Stheravenstrstreambuf::seekpos(pos_type __sp, ios_base::openmode __which) 286227825Stheraven{ 287227825Stheraven off_type __p(-1); 288227825Stheraven bool pos_in = __which & ios::in; 289227825Stheraven bool pos_out = __which & ios::out; 290227825Stheraven if (pos_in || pos_out) 291227825Stheraven { 292227825Stheraven if (!((pos_in && gptr() == nullptr) || (pos_out && pptr() == nullptr))) 293227825Stheraven { 294227825Stheraven off_type newoff = __sp; 295227825Stheraven char* seekhigh = epptr() ? epptr() : egptr(); 296227825Stheraven if (0 <= newoff && newoff <= seekhigh - eback()) 297227825Stheraven { 298227825Stheraven char* newpos = eback() + newoff; 299227825Stheraven if (pos_in) 300227825Stheraven setg(eback(), newpos, _VSTD::max(newpos, egptr())); 301227825Stheraven if (pos_out) 302227825Stheraven { 303227825Stheraven // min(pbase, newpos), newpos, epptr() 304227825Stheraven off_type temp = epptr() - newpos; 305227825Stheraven setp(min(pbase(), newpos), epptr()); 306227825Stheraven pbump(static_cast<int>((epptr() - pbase()) - temp)); 307227825Stheraven } 308227825Stheraven __p = newoff; 309227825Stheraven } 310227825Stheraven } 311227825Stheraven } 312227825Stheraven return pos_type(__p); 313227825Stheraven} 314227825Stheraven 315227825Stheravenistrstream::~istrstream() 316227825Stheraven{ 317227825Stheraven} 318227825Stheraven 319227825Stheravenostrstream::~ostrstream() 320227825Stheraven{ 321227825Stheraven} 322227825Stheraven 323227825Stheravenstrstream::~strstream() 324227825Stheraven{ 325227825Stheraven} 326227825Stheraven 327227825Stheraven_LIBCPP_END_NAMESPACE_STD 328