strstream.cpp revision 327952
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" 14314564Sdim#include "cstdlib" 15309124Sdim#include "__debug" 16321369Sdim#include "__undef_macros" 17227825Stheraven 18227825Stheraven_LIBCPP_BEGIN_NAMESPACE_STD 19227825Stheraven 20227825Stheravenstrstreambuf::strstreambuf(streamsize __alsize) 21227825Stheraven : __strmode_(__dynamic), 22227825Stheraven __alsize_(__alsize), 23227825Stheraven __palloc_(nullptr), 24227825Stheraven __pfree_(nullptr) 25227825Stheraven{ 26227825Stheraven} 27227825Stheraven 28227825Stheravenstrstreambuf::strstreambuf(void* (*__palloc)(size_t), void (*__pfree)(void*)) 29227825Stheraven : __strmode_(__dynamic), 30227825Stheraven __alsize_(__default_alsize), 31227825Stheraven __palloc_(__palloc), 32227825Stheraven __pfree_(__pfree) 33227825Stheraven{ 34227825Stheraven} 35227825Stheraven 36227825Stheravenvoid 37227825Stheravenstrstreambuf::__init(char* __gnext, streamsize __n, char* __pbeg) 38227825Stheraven{ 39227825Stheraven if (__n == 0) 40232924Stheraven __n = static_cast<streamsize>(strlen(__gnext)); 41227825Stheraven else if (__n < 0) 42227825Stheraven __n = INT_MAX; 43227825Stheraven if (__pbeg == nullptr) 44227825Stheraven setg(__gnext, __gnext, __gnext + __n); 45227825Stheraven else 46227825Stheraven { 47227825Stheraven setg(__gnext, __gnext, __pbeg); 48227825Stheraven setp(__pbeg, __pbeg + __n); 49227825Stheraven } 50227825Stheraven} 51227825Stheraven 52227825Stheravenstrstreambuf::strstreambuf(char* __gnext, streamsize __n, char* __pbeg) 53227825Stheraven : __strmode_(), 54227825Stheraven __alsize_(__default_alsize), 55227825Stheraven __palloc_(nullptr), 56227825Stheraven __pfree_(nullptr) 57227825Stheraven{ 58227825Stheraven __init(__gnext, __n, __pbeg); 59227825Stheraven} 60227825Stheraven 61227825Stheravenstrstreambuf::strstreambuf(const char* __gnext, streamsize __n) 62227825Stheraven : __strmode_(__constant), 63227825Stheraven __alsize_(__default_alsize), 64227825Stheraven __palloc_(nullptr), 65227825Stheraven __pfree_(nullptr) 66227825Stheraven{ 67276792Sdim __init(const_cast<char *>(__gnext), __n, nullptr); 68227825Stheraven} 69227825Stheraven 70227825Stheravenstrstreambuf::strstreambuf(signed char* __gnext, streamsize __n, signed char* __pbeg) 71227825Stheraven : __strmode_(), 72227825Stheraven __alsize_(__default_alsize), 73227825Stheraven __palloc_(nullptr), 74227825Stheraven __pfree_(nullptr) 75227825Stheraven{ 76276792Sdim __init(const_cast<char *>(reinterpret_cast<const char*>(__gnext)), __n, reinterpret_cast<char*>(__pbeg)); 77227825Stheraven} 78227825Stheraven 79227825Stheravenstrstreambuf::strstreambuf(const signed char* __gnext, streamsize __n) 80227825Stheraven : __strmode_(__constant), 81227825Stheraven __alsize_(__default_alsize), 82227825Stheraven __palloc_(nullptr), 83227825Stheraven __pfree_(nullptr) 84227825Stheraven{ 85276792Sdim __init(const_cast<char *>(reinterpret_cast<const char*>(__gnext)), __n, nullptr); 86227825Stheraven} 87227825Stheraven 88227825Stheravenstrstreambuf::strstreambuf(unsigned char* __gnext, streamsize __n, unsigned char* __pbeg) 89227825Stheraven : __strmode_(), 90227825Stheraven __alsize_(__default_alsize), 91227825Stheraven __palloc_(nullptr), 92227825Stheraven __pfree_(nullptr) 93227825Stheraven{ 94276792Sdim __init(const_cast<char *>(reinterpret_cast<const char*>(__gnext)), __n, reinterpret_cast<char*>(__pbeg)); 95227825Stheraven} 96227825Stheraven 97227825Stheravenstrstreambuf::strstreambuf(const unsigned char* __gnext, streamsize __n) 98227825Stheraven : __strmode_(__constant), 99227825Stheraven __alsize_(__default_alsize), 100227825Stheraven __palloc_(nullptr), 101227825Stheraven __pfree_(nullptr) 102227825Stheraven{ 103276792Sdim __init(const_cast<char *>(reinterpret_cast<const char*>(__gnext)), __n, nullptr); 104227825Stheraven} 105227825Stheraven 106227825Stheravenstrstreambuf::~strstreambuf() 107227825Stheraven{ 108227825Stheraven if (eback() && (__strmode_ & __allocated) != 0 && (__strmode_ & __frozen) == 0) 109227825Stheraven { 110227825Stheraven if (__pfree_) 111227825Stheraven __pfree_(eback()); 112227825Stheraven else 113227825Stheraven delete [] eback(); 114227825Stheraven } 115227825Stheraven} 116227825Stheraven 117227825Stheravenvoid 118227825Stheravenstrstreambuf::swap(strstreambuf& __rhs) 119227825Stheraven{ 120227825Stheraven streambuf::swap(__rhs); 121227825Stheraven _VSTD::swap(__strmode_, __rhs.__strmode_); 122227825Stheraven _VSTD::swap(__alsize_, __rhs.__alsize_); 123227825Stheraven _VSTD::swap(__palloc_, __rhs.__palloc_); 124227825Stheraven _VSTD::swap(__pfree_, __rhs.__pfree_); 125227825Stheraven} 126227825Stheraven 127227825Stheravenvoid 128227825Stheravenstrstreambuf::freeze(bool __freezefl) 129227825Stheraven{ 130227825Stheraven if (__strmode_ & __dynamic) 131227825Stheraven { 132227825Stheraven if (__freezefl) 133227825Stheraven __strmode_ |= __frozen; 134227825Stheraven else 135227825Stheraven __strmode_ &= ~__frozen; 136227825Stheraven } 137227825Stheraven} 138227825Stheraven 139227825Stheravenchar* 140227825Stheravenstrstreambuf::str() 141227825Stheraven{ 142227825Stheraven if (__strmode_ & __dynamic) 143227825Stheraven __strmode_ |= __frozen; 144227825Stheraven return eback(); 145227825Stheraven} 146227825Stheraven 147227825Stheravenint 148227825Stheravenstrstreambuf::pcount() const 149227825Stheraven{ 150227825Stheraven return static_cast<int>(pptr() - pbase()); 151227825Stheraven} 152227825Stheraven 153227825Stheravenstrstreambuf::int_type 154227825Stheravenstrstreambuf::overflow(int_type __c) 155227825Stheraven{ 156227825Stheraven if (__c == EOF) 157227825Stheraven return int_type(0); 158227825Stheraven if (pptr() == epptr()) 159227825Stheraven { 160227825Stheraven if ((__strmode_ & __dynamic) == 0 || (__strmode_ & __frozen) != 0) 161227825Stheraven return int_type(EOF); 162261272Sdim size_t old_size = static_cast<size_t> ((epptr() ? epptr() : egptr()) - eback()); 163261272Sdim size_t new_size = max<size_t>(static_cast<size_t>(__alsize_), 2*old_size); 164249989Sdim if (new_size == 0) 165249989Sdim new_size = __default_alsize; 166227825Stheraven char* buf = nullptr; 167227825Stheraven if (__palloc_) 168261272Sdim buf = static_cast<char*>(__palloc_(new_size)); 169227825Stheraven else 170227825Stheraven buf = new char[new_size]; 171227825Stheraven if (buf == nullptr) 172227825Stheraven return int_type(EOF); 173309124Sdim if (old_size != 0) { 174309124Sdim _LIBCPP_ASSERT(eback(), "overflow copying from NULL"); 175309124Sdim memcpy(buf, eback(), static_cast<size_t>(old_size)); 176309124Sdim } 177227825Stheraven ptrdiff_t ninp = gptr() - eback(); 178227825Stheraven ptrdiff_t einp = egptr() - eback(); 179227825Stheraven ptrdiff_t nout = pptr() - pbase(); 180227825Stheraven if (__strmode_ & __allocated) 181227825Stheraven { 182227825Stheraven if (__pfree_) 183227825Stheraven __pfree_(eback()); 184227825Stheraven else 185227825Stheraven delete [] eback(); 186227825Stheraven } 187227825Stheraven setg(buf, buf + ninp, buf + einp); 188309124Sdim setp(buf + einp, buf + new_size); 189327952Sdim __pbump(nout); 190227825Stheraven __strmode_ |= __allocated; 191227825Stheraven } 192227825Stheraven *pptr() = static_cast<char>(__c); 193227825Stheraven pbump(1); 194276792Sdim return int_type(static_cast<unsigned char>(__c)); 195227825Stheraven} 196227825Stheraven 197227825Stheravenstrstreambuf::int_type 198227825Stheravenstrstreambuf::pbackfail(int_type __c) 199227825Stheraven{ 200227825Stheraven if (eback() == gptr()) 201227825Stheraven return EOF; 202227825Stheraven if (__c == EOF) 203227825Stheraven { 204227825Stheraven gbump(-1); 205227825Stheraven return int_type(0); 206227825Stheraven } 207227825Stheraven if (__strmode_ & __constant) 208227825Stheraven { 209227825Stheraven if (gptr()[-1] == static_cast<char>(__c)) 210227825Stheraven { 211227825Stheraven gbump(-1); 212227825Stheraven return __c; 213227825Stheraven } 214227825Stheraven return EOF; 215227825Stheraven } 216227825Stheraven gbump(-1); 217227825Stheraven *gptr() = static_cast<char>(__c); 218227825Stheraven return __c; 219227825Stheraven} 220227825Stheraven 221227825Stheravenstrstreambuf::int_type 222227825Stheravenstrstreambuf::underflow() 223227825Stheraven{ 224227825Stheraven if (gptr() == egptr()) 225227825Stheraven { 226227825Stheraven if (egptr() >= pptr()) 227227825Stheraven return EOF; 228227825Stheraven setg(eback(), gptr(), pptr()); 229227825Stheraven } 230276792Sdim return int_type(static_cast<unsigned char>(*gptr())); 231227825Stheraven} 232227825Stheraven 233227825Stheravenstrstreambuf::pos_type 234227825Stheravenstrstreambuf::seekoff(off_type __off, ios_base::seekdir __way, ios_base::openmode __which) 235227825Stheraven{ 236227825Stheraven off_type __p(-1); 237261272Sdim bool pos_in = (__which & ios::in) != 0; 238261272Sdim bool pos_out = (__which & ios::out) != 0; 239227825Stheraven bool legal = false; 240227825Stheraven switch (__way) 241227825Stheraven { 242227825Stheraven case ios::beg: 243227825Stheraven case ios::end: 244227825Stheraven if (pos_in || pos_out) 245227825Stheraven legal = true; 246227825Stheraven break; 247227825Stheraven case ios::cur: 248227825Stheraven if (pos_in != pos_out) 249227825Stheraven legal = true; 250227825Stheraven break; 251227825Stheraven } 252227825Stheraven if (pos_in && gptr() == nullptr) 253227825Stheraven legal = false; 254227825Stheraven if (pos_out && pptr() == nullptr) 255227825Stheraven legal = false; 256227825Stheraven if (legal) 257227825Stheraven { 258227825Stheraven off_type newoff; 259227825Stheraven char* seekhigh = epptr() ? epptr() : egptr(); 260227825Stheraven switch (__way) 261227825Stheraven { 262227825Stheraven case ios::beg: 263227825Stheraven newoff = 0; 264227825Stheraven break; 265227825Stheraven case ios::cur: 266227825Stheraven newoff = (pos_in ? gptr() : pptr()) - eback(); 267227825Stheraven break; 268227825Stheraven case ios::end: 269227825Stheraven newoff = seekhigh - eback(); 270227825Stheraven break; 271314564Sdim default: 272314564Sdim _LIBCPP_UNREACHABLE(); 273227825Stheraven } 274227825Stheraven newoff += __off; 275227825Stheraven if (0 <= newoff && newoff <= seekhigh - eback()) 276227825Stheraven { 277227825Stheraven char* newpos = eback() + newoff; 278227825Stheraven if (pos_in) 279227825Stheraven setg(eback(), newpos, _VSTD::max(newpos, egptr())); 280227825Stheraven if (pos_out) 281227825Stheraven { 282227825Stheraven // min(pbase, newpos), newpos, epptr() 283227825Stheraven __off = epptr() - newpos; 284227825Stheraven setp(min(pbase(), newpos), epptr()); 285327952Sdim __pbump((epptr() - pbase()) - __off); 286227825Stheraven } 287227825Stheraven __p = newoff; 288227825Stheraven } 289227825Stheraven } 290227825Stheraven return pos_type(__p); 291227825Stheraven} 292227825Stheraven 293227825Stheravenstrstreambuf::pos_type 294227825Stheravenstrstreambuf::seekpos(pos_type __sp, ios_base::openmode __which) 295227825Stheraven{ 296227825Stheraven off_type __p(-1); 297261272Sdim bool pos_in = (__which & ios::in) != 0; 298261272Sdim bool pos_out = (__which & ios::out) != 0; 299227825Stheraven if (pos_in || pos_out) 300227825Stheraven { 301227825Stheraven if (!((pos_in && gptr() == nullptr) || (pos_out && pptr() == nullptr))) 302227825Stheraven { 303227825Stheraven off_type newoff = __sp; 304227825Stheraven char* seekhigh = epptr() ? epptr() : egptr(); 305227825Stheraven if (0 <= newoff && newoff <= seekhigh - eback()) 306227825Stheraven { 307227825Stheraven char* newpos = eback() + newoff; 308227825Stheraven if (pos_in) 309227825Stheraven setg(eback(), newpos, _VSTD::max(newpos, egptr())); 310227825Stheraven if (pos_out) 311227825Stheraven { 312227825Stheraven // min(pbase, newpos), newpos, epptr() 313227825Stheraven off_type temp = epptr() - newpos; 314227825Stheraven setp(min(pbase(), newpos), epptr()); 315327952Sdim __pbump((epptr() - pbase()) - temp); 316227825Stheraven } 317227825Stheraven __p = newoff; 318227825Stheraven } 319227825Stheraven } 320227825Stheraven } 321227825Stheraven return pos_type(__p); 322227825Stheraven} 323227825Stheraven 324227825Stheravenistrstream::~istrstream() 325227825Stheraven{ 326227825Stheraven} 327227825Stheraven 328227825Stheravenostrstream::~ostrstream() 329227825Stheraven{ 330227825Stheraven} 331227825Stheraven 332227825Stheravenstrstream::~strstream() 333227825Stheraven{ 334227825Stheraven} 335227825Stheraven 336227825Stheraven_LIBCPP_END_NAMESPACE_STD 337