strstream.cpp revision 261272
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) 37232924Stheraven __n = static_cast<streamsize>(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); 159261272Sdim size_t old_size = static_cast<size_t> ((epptr() ? epptr() : egptr()) - eback()); 160261272Sdim size_t new_size = max<size_t>(static_cast<size_t>(__alsize_), 2*old_size); 161249989Sdim if (new_size == 0) 162249989Sdim new_size = __default_alsize; 163227825Stheraven char* buf = nullptr; 164227825Stheraven if (__palloc_) 165261272Sdim buf = static_cast<char*>(__palloc_(new_size)); 166227825Stheraven else 167227825Stheraven buf = new char[new_size]; 168227825Stheraven if (buf == nullptr) 169227825Stheraven return int_type(EOF); 170232924Stheraven memcpy(buf, eback(), static_cast<size_t>(old_size)); 171227825Stheraven ptrdiff_t ninp = gptr() - eback(); 172227825Stheraven ptrdiff_t einp = egptr() - eback(); 173227825Stheraven ptrdiff_t nout = pptr() - pbase(); 174227825Stheraven ptrdiff_t eout = epptr() - pbase(); 175227825Stheraven if (__strmode_ & __allocated) 176227825Stheraven { 177227825Stheraven if (__pfree_) 178227825Stheraven __pfree_(eback()); 179227825Stheraven else 180227825Stheraven delete [] eback(); 181227825Stheraven } 182227825Stheraven setg(buf, buf + ninp, buf + einp); 183227825Stheraven setp(buf + einp, buf + einp + eout); 184232924Stheraven pbump(static_cast<int>(nout)); 185227825Stheraven __strmode_ |= __allocated; 186227825Stheraven } 187227825Stheraven *pptr() = static_cast<char>(__c); 188227825Stheraven pbump(1); 189227825Stheraven return int_type((unsigned char)__c); 190227825Stheraven} 191227825Stheraven 192227825Stheravenstrstreambuf::int_type 193227825Stheravenstrstreambuf::pbackfail(int_type __c) 194227825Stheraven{ 195227825Stheraven if (eback() == gptr()) 196227825Stheraven return EOF; 197227825Stheraven if (__c == EOF) 198227825Stheraven { 199227825Stheraven gbump(-1); 200227825Stheraven return int_type(0); 201227825Stheraven } 202227825Stheraven if (__strmode_ & __constant) 203227825Stheraven { 204227825Stheraven if (gptr()[-1] == static_cast<char>(__c)) 205227825Stheraven { 206227825Stheraven gbump(-1); 207227825Stheraven return __c; 208227825Stheraven } 209227825Stheraven return EOF; 210227825Stheraven } 211227825Stheraven gbump(-1); 212227825Stheraven *gptr() = static_cast<char>(__c); 213227825Stheraven return __c; 214227825Stheraven} 215227825Stheraven 216227825Stheravenstrstreambuf::int_type 217227825Stheravenstrstreambuf::underflow() 218227825Stheraven{ 219227825Stheraven if (gptr() == egptr()) 220227825Stheraven { 221227825Stheraven if (egptr() >= pptr()) 222227825Stheraven return EOF; 223227825Stheraven setg(eback(), gptr(), pptr()); 224227825Stheraven } 225227825Stheraven return int_type((unsigned char)*gptr()); 226227825Stheraven} 227227825Stheraven 228227825Stheravenstrstreambuf::pos_type 229227825Stheravenstrstreambuf::seekoff(off_type __off, ios_base::seekdir __way, ios_base::openmode __which) 230227825Stheraven{ 231227825Stheraven off_type __p(-1); 232261272Sdim bool pos_in = (__which & ios::in) != 0; 233261272Sdim bool pos_out = (__which & ios::out) != 0; 234227825Stheraven bool legal = false; 235227825Stheraven switch (__way) 236227825Stheraven { 237227825Stheraven case ios::beg: 238227825Stheraven case ios::end: 239227825Stheraven if (pos_in || pos_out) 240227825Stheraven legal = true; 241227825Stheraven break; 242227825Stheraven case ios::cur: 243227825Stheraven if (pos_in != pos_out) 244227825Stheraven legal = true; 245227825Stheraven break; 246227825Stheraven } 247227825Stheraven if (pos_in && gptr() == nullptr) 248227825Stheraven legal = false; 249227825Stheraven if (pos_out && pptr() == nullptr) 250227825Stheraven legal = false; 251227825Stheraven if (legal) 252227825Stheraven { 253227825Stheraven off_type newoff; 254227825Stheraven char* seekhigh = epptr() ? epptr() : egptr(); 255227825Stheraven switch (__way) 256227825Stheraven { 257227825Stheraven case ios::beg: 258227825Stheraven newoff = 0; 259227825Stheraven break; 260227825Stheraven case ios::cur: 261227825Stheraven newoff = (pos_in ? gptr() : pptr()) - eback(); 262227825Stheraven break; 263227825Stheraven case ios::end: 264227825Stheraven newoff = seekhigh - eback(); 265227825Stheraven break; 266227825Stheraven } 267227825Stheraven newoff += __off; 268227825Stheraven if (0 <= newoff && newoff <= seekhigh - eback()) 269227825Stheraven { 270227825Stheraven char* newpos = eback() + newoff; 271227825Stheraven if (pos_in) 272227825Stheraven setg(eback(), newpos, _VSTD::max(newpos, egptr())); 273227825Stheraven if (pos_out) 274227825Stheraven { 275227825Stheraven // min(pbase, newpos), newpos, epptr() 276227825Stheraven __off = epptr() - newpos; 277227825Stheraven setp(min(pbase(), newpos), epptr()); 278227825Stheraven pbump(static_cast<int>((epptr() - pbase()) - __off)); 279227825Stheraven } 280227825Stheraven __p = newoff; 281227825Stheraven } 282227825Stheraven } 283227825Stheraven return pos_type(__p); 284227825Stheraven} 285227825Stheraven 286227825Stheravenstrstreambuf::pos_type 287227825Stheravenstrstreambuf::seekpos(pos_type __sp, ios_base::openmode __which) 288227825Stheraven{ 289227825Stheraven off_type __p(-1); 290261272Sdim bool pos_in = (__which & ios::in) != 0; 291261272Sdim bool pos_out = (__which & ios::out) != 0; 292227825Stheraven if (pos_in || pos_out) 293227825Stheraven { 294227825Stheraven if (!((pos_in && gptr() == nullptr) || (pos_out && pptr() == nullptr))) 295227825Stheraven { 296227825Stheraven off_type newoff = __sp; 297227825Stheraven char* seekhigh = epptr() ? epptr() : egptr(); 298227825Stheraven if (0 <= newoff && newoff <= seekhigh - eback()) 299227825Stheraven { 300227825Stheraven char* newpos = eback() + newoff; 301227825Stheraven if (pos_in) 302227825Stheraven setg(eback(), newpos, _VSTD::max(newpos, egptr())); 303227825Stheraven if (pos_out) 304227825Stheraven { 305227825Stheraven // min(pbase, newpos), newpos, epptr() 306227825Stheraven off_type temp = epptr() - newpos; 307227825Stheraven setp(min(pbase(), newpos), epptr()); 308227825Stheraven pbump(static_cast<int>((epptr() - pbase()) - temp)); 309227825Stheraven } 310227825Stheraven __p = newoff; 311227825Stheraven } 312227825Stheraven } 313227825Stheraven } 314227825Stheraven return pos_type(__p); 315227825Stheraven} 316227825Stheraven 317227825Stheravenistrstream::~istrstream() 318227825Stheraven{ 319227825Stheraven} 320227825Stheraven 321227825Stheravenostrstream::~ostrstream() 322227825Stheraven{ 323227825Stheraven} 324227825Stheraven 325227825Stheravenstrstream::~strstream() 326227825Stheraven{ 327227825Stheraven} 328227825Stheraven 329227825Stheraven_LIBCPP_END_NAMESPACE_STD 330