strstream.cpp revision 309124
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" 14309124Sdim#include "__debug" 15227825Stheraven 16227825Stheraven_LIBCPP_BEGIN_NAMESPACE_STD 17227825Stheraven 18227825Stheravenstrstreambuf::strstreambuf(streamsize __alsize) 19227825Stheraven : __strmode_(__dynamic), 20227825Stheraven __alsize_(__alsize), 21227825Stheraven __palloc_(nullptr), 22227825Stheraven __pfree_(nullptr) 23227825Stheraven{ 24227825Stheraven} 25227825Stheraven 26227825Stheravenstrstreambuf::strstreambuf(void* (*__palloc)(size_t), void (*__pfree)(void*)) 27227825Stheraven : __strmode_(__dynamic), 28227825Stheraven __alsize_(__default_alsize), 29227825Stheraven __palloc_(__palloc), 30227825Stheraven __pfree_(__pfree) 31227825Stheraven{ 32227825Stheraven} 33227825Stheraven 34227825Stheravenvoid 35227825Stheravenstrstreambuf::__init(char* __gnext, streamsize __n, char* __pbeg) 36227825Stheraven{ 37227825Stheraven if (__n == 0) 38232924Stheraven __n = static_cast<streamsize>(strlen(__gnext)); 39227825Stheraven else if (__n < 0) 40227825Stheraven __n = INT_MAX; 41227825Stheraven if (__pbeg == nullptr) 42227825Stheraven setg(__gnext, __gnext, __gnext + __n); 43227825Stheraven else 44227825Stheraven { 45227825Stheraven setg(__gnext, __gnext, __pbeg); 46227825Stheraven setp(__pbeg, __pbeg + __n); 47227825Stheraven } 48227825Stheraven} 49227825Stheraven 50227825Stheravenstrstreambuf::strstreambuf(char* __gnext, streamsize __n, char* __pbeg) 51227825Stheraven : __strmode_(), 52227825Stheraven __alsize_(__default_alsize), 53227825Stheraven __palloc_(nullptr), 54227825Stheraven __pfree_(nullptr) 55227825Stheraven{ 56227825Stheraven __init(__gnext, __n, __pbeg); 57227825Stheraven} 58227825Stheraven 59227825Stheravenstrstreambuf::strstreambuf(const char* __gnext, streamsize __n) 60227825Stheraven : __strmode_(__constant), 61227825Stheraven __alsize_(__default_alsize), 62227825Stheraven __palloc_(nullptr), 63227825Stheraven __pfree_(nullptr) 64227825Stheraven{ 65276792Sdim __init(const_cast<char *>(__gnext), __n, nullptr); 66227825Stheraven} 67227825Stheraven 68227825Stheravenstrstreambuf::strstreambuf(signed char* __gnext, streamsize __n, signed char* __pbeg) 69227825Stheraven : __strmode_(), 70227825Stheraven __alsize_(__default_alsize), 71227825Stheraven __palloc_(nullptr), 72227825Stheraven __pfree_(nullptr) 73227825Stheraven{ 74276792Sdim __init(const_cast<char *>(reinterpret_cast<const char*>(__gnext)), __n, reinterpret_cast<char*>(__pbeg)); 75227825Stheraven} 76227825Stheraven 77227825Stheravenstrstreambuf::strstreambuf(const signed char* __gnext, streamsize __n) 78227825Stheraven : __strmode_(__constant), 79227825Stheraven __alsize_(__default_alsize), 80227825Stheraven __palloc_(nullptr), 81227825Stheraven __pfree_(nullptr) 82227825Stheraven{ 83276792Sdim __init(const_cast<char *>(reinterpret_cast<const char*>(__gnext)), __n, nullptr); 84227825Stheraven} 85227825Stheraven 86227825Stheravenstrstreambuf::strstreambuf(unsigned char* __gnext, streamsize __n, unsigned char* __pbeg) 87227825Stheraven : __strmode_(), 88227825Stheraven __alsize_(__default_alsize), 89227825Stheraven __palloc_(nullptr), 90227825Stheraven __pfree_(nullptr) 91227825Stheraven{ 92276792Sdim __init(const_cast<char *>(reinterpret_cast<const char*>(__gnext)), __n, reinterpret_cast<char*>(__pbeg)); 93227825Stheraven} 94227825Stheraven 95227825Stheravenstrstreambuf::strstreambuf(const unsigned char* __gnext, streamsize __n) 96227825Stheraven : __strmode_(__constant), 97227825Stheraven __alsize_(__default_alsize), 98227825Stheraven __palloc_(nullptr), 99227825Stheraven __pfree_(nullptr) 100227825Stheraven{ 101276792Sdim __init(const_cast<char *>(reinterpret_cast<const char*>(__gnext)), __n, nullptr); 102227825Stheraven} 103227825Stheraven 104227825Stheravenstrstreambuf::~strstreambuf() 105227825Stheraven{ 106227825Stheraven if (eback() && (__strmode_ & __allocated) != 0 && (__strmode_ & __frozen) == 0) 107227825Stheraven { 108227825Stheraven if (__pfree_) 109227825Stheraven __pfree_(eback()); 110227825Stheraven else 111227825Stheraven delete [] eback(); 112227825Stheraven } 113227825Stheraven} 114227825Stheraven 115227825Stheravenvoid 116227825Stheravenstrstreambuf::swap(strstreambuf& __rhs) 117227825Stheraven{ 118227825Stheraven streambuf::swap(__rhs); 119227825Stheraven _VSTD::swap(__strmode_, __rhs.__strmode_); 120227825Stheraven _VSTD::swap(__alsize_, __rhs.__alsize_); 121227825Stheraven _VSTD::swap(__palloc_, __rhs.__palloc_); 122227825Stheraven _VSTD::swap(__pfree_, __rhs.__pfree_); 123227825Stheraven} 124227825Stheraven 125227825Stheravenvoid 126227825Stheravenstrstreambuf::freeze(bool __freezefl) 127227825Stheraven{ 128227825Stheraven if (__strmode_ & __dynamic) 129227825Stheraven { 130227825Stheraven if (__freezefl) 131227825Stheraven __strmode_ |= __frozen; 132227825Stheraven else 133227825Stheraven __strmode_ &= ~__frozen; 134227825Stheraven } 135227825Stheraven} 136227825Stheraven 137227825Stheravenchar* 138227825Stheravenstrstreambuf::str() 139227825Stheraven{ 140227825Stheraven if (__strmode_ & __dynamic) 141227825Stheraven __strmode_ |= __frozen; 142227825Stheraven return eback(); 143227825Stheraven} 144227825Stheraven 145227825Stheravenint 146227825Stheravenstrstreambuf::pcount() const 147227825Stheraven{ 148227825Stheraven return static_cast<int>(pptr() - pbase()); 149227825Stheraven} 150227825Stheraven 151227825Stheravenstrstreambuf::int_type 152227825Stheravenstrstreambuf::overflow(int_type __c) 153227825Stheraven{ 154227825Stheraven if (__c == EOF) 155227825Stheraven return int_type(0); 156227825Stheraven if (pptr() == epptr()) 157227825Stheraven { 158227825Stheraven if ((__strmode_ & __dynamic) == 0 || (__strmode_ & __frozen) != 0) 159227825Stheraven return int_type(EOF); 160261272Sdim size_t old_size = static_cast<size_t> ((epptr() ? epptr() : egptr()) - eback()); 161261272Sdim size_t new_size = max<size_t>(static_cast<size_t>(__alsize_), 2*old_size); 162249989Sdim if (new_size == 0) 163249989Sdim new_size = __default_alsize; 164227825Stheraven char* buf = nullptr; 165227825Stheraven if (__palloc_) 166261272Sdim buf = static_cast<char*>(__palloc_(new_size)); 167227825Stheraven else 168227825Stheraven buf = new char[new_size]; 169227825Stheraven if (buf == nullptr) 170227825Stheraven return int_type(EOF); 171309124Sdim if (old_size != 0) { 172309124Sdim _LIBCPP_ASSERT(eback(), "overflow copying from NULL"); 173309124Sdim memcpy(buf, eback(), static_cast<size_t>(old_size)); 174309124Sdim } 175227825Stheraven ptrdiff_t ninp = gptr() - eback(); 176227825Stheraven ptrdiff_t einp = egptr() - eback(); 177227825Stheraven ptrdiff_t nout = pptr() - pbase(); 178227825Stheraven if (__strmode_ & __allocated) 179227825Stheraven { 180227825Stheraven if (__pfree_) 181227825Stheraven __pfree_(eback()); 182227825Stheraven else 183227825Stheraven delete [] eback(); 184227825Stheraven } 185227825Stheraven setg(buf, buf + ninp, buf + einp); 186309124Sdim setp(buf + einp, buf + new_size); 187232924Stheraven pbump(static_cast<int>(nout)); 188227825Stheraven __strmode_ |= __allocated; 189227825Stheraven } 190227825Stheraven *pptr() = static_cast<char>(__c); 191227825Stheraven pbump(1); 192276792Sdim return int_type(static_cast<unsigned char>(__c)); 193227825Stheraven} 194227825Stheraven 195227825Stheravenstrstreambuf::int_type 196227825Stheravenstrstreambuf::pbackfail(int_type __c) 197227825Stheraven{ 198227825Stheraven if (eback() == gptr()) 199227825Stheraven return EOF; 200227825Stheraven if (__c == EOF) 201227825Stheraven { 202227825Stheraven gbump(-1); 203227825Stheraven return int_type(0); 204227825Stheraven } 205227825Stheraven if (__strmode_ & __constant) 206227825Stheraven { 207227825Stheraven if (gptr()[-1] == static_cast<char>(__c)) 208227825Stheraven { 209227825Stheraven gbump(-1); 210227825Stheraven return __c; 211227825Stheraven } 212227825Stheraven return EOF; 213227825Stheraven } 214227825Stheraven gbump(-1); 215227825Stheraven *gptr() = static_cast<char>(__c); 216227825Stheraven return __c; 217227825Stheraven} 218227825Stheraven 219227825Stheravenstrstreambuf::int_type 220227825Stheravenstrstreambuf::underflow() 221227825Stheraven{ 222227825Stheraven if (gptr() == egptr()) 223227825Stheraven { 224227825Stheraven if (egptr() >= pptr()) 225227825Stheraven return EOF; 226227825Stheraven setg(eback(), gptr(), pptr()); 227227825Stheraven } 228276792Sdim return int_type(static_cast<unsigned char>(*gptr())); 229227825Stheraven} 230227825Stheraven 231227825Stheravenstrstreambuf::pos_type 232227825Stheravenstrstreambuf::seekoff(off_type __off, ios_base::seekdir __way, ios_base::openmode __which) 233227825Stheraven{ 234227825Stheraven off_type __p(-1); 235261272Sdim bool pos_in = (__which & ios::in) != 0; 236261272Sdim bool pos_out = (__which & ios::out) != 0; 237227825Stheraven bool legal = false; 238227825Stheraven switch (__way) 239227825Stheraven { 240227825Stheraven case ios::beg: 241227825Stheraven case ios::end: 242227825Stheraven if (pos_in || pos_out) 243227825Stheraven legal = true; 244227825Stheraven break; 245227825Stheraven case ios::cur: 246227825Stheraven if (pos_in != pos_out) 247227825Stheraven legal = true; 248227825Stheraven break; 249227825Stheraven } 250227825Stheraven if (pos_in && gptr() == nullptr) 251227825Stheraven legal = false; 252227825Stheraven if (pos_out && pptr() == nullptr) 253227825Stheraven legal = false; 254227825Stheraven if (legal) 255227825Stheraven { 256227825Stheraven off_type newoff; 257227825Stheraven char* seekhigh = epptr() ? epptr() : egptr(); 258227825Stheraven switch (__way) 259227825Stheraven { 260227825Stheraven case ios::beg: 261227825Stheraven newoff = 0; 262227825Stheraven break; 263227825Stheraven case ios::cur: 264227825Stheraven newoff = (pos_in ? gptr() : pptr()) - eback(); 265227825Stheraven break; 266227825Stheraven case ios::end: 267227825Stheraven newoff = seekhigh - eback(); 268227825Stheraven break; 269227825Stheraven } 270227825Stheraven newoff += __off; 271227825Stheraven if (0 <= newoff && newoff <= seekhigh - eback()) 272227825Stheraven { 273227825Stheraven char* newpos = eback() + newoff; 274227825Stheraven if (pos_in) 275227825Stheraven setg(eback(), newpos, _VSTD::max(newpos, egptr())); 276227825Stheraven if (pos_out) 277227825Stheraven { 278227825Stheraven // min(pbase, newpos), newpos, epptr() 279227825Stheraven __off = epptr() - newpos; 280227825Stheraven setp(min(pbase(), newpos), epptr()); 281227825Stheraven pbump(static_cast<int>((epptr() - pbase()) - __off)); 282227825Stheraven } 283227825Stheraven __p = newoff; 284227825Stheraven } 285227825Stheraven } 286227825Stheraven return pos_type(__p); 287227825Stheraven} 288227825Stheraven 289227825Stheravenstrstreambuf::pos_type 290227825Stheravenstrstreambuf::seekpos(pos_type __sp, ios_base::openmode __which) 291227825Stheraven{ 292227825Stheraven off_type __p(-1); 293261272Sdim bool pos_in = (__which & ios::in) != 0; 294261272Sdim bool pos_out = (__which & ios::out) != 0; 295227825Stheraven if (pos_in || pos_out) 296227825Stheraven { 297227825Stheraven if (!((pos_in && gptr() == nullptr) || (pos_out && pptr() == nullptr))) 298227825Stheraven { 299227825Stheraven off_type newoff = __sp; 300227825Stheraven char* seekhigh = epptr() ? epptr() : egptr(); 301227825Stheraven if (0 <= newoff && newoff <= seekhigh - eback()) 302227825Stheraven { 303227825Stheraven char* newpos = eback() + newoff; 304227825Stheraven if (pos_in) 305227825Stheraven setg(eback(), newpos, _VSTD::max(newpos, egptr())); 306227825Stheraven if (pos_out) 307227825Stheraven { 308227825Stheraven // min(pbase, newpos), newpos, epptr() 309227825Stheraven off_type temp = epptr() - newpos; 310227825Stheraven setp(min(pbase(), newpos), epptr()); 311227825Stheraven pbump(static_cast<int>((epptr() - pbase()) - temp)); 312227825Stheraven } 313227825Stheraven __p = newoff; 314227825Stheraven } 315227825Stheraven } 316227825Stheraven } 317227825Stheraven return pos_type(__p); 318227825Stheraven} 319227825Stheraven 320227825Stheravenistrstream::~istrstream() 321227825Stheraven{ 322227825Stheraven} 323227825Stheraven 324227825Stheravenostrstream::~ostrstream() 325227825Stheraven{ 326227825Stheraven} 327227825Stheraven 328227825Stheravenstrstream::~strstream() 329227825Stheraven{ 330227825Stheraven} 331227825Stheraven 332227825Stheraven_LIBCPP_END_NAMESPACE_STD 333