1//===------------------------ strstream.cpp -------------------------------===// 2// 3// The LLVM Compiler Infrastructure 4// 5// This file is dual licensed under the MIT and the University of Illinois Open 6// Source Licenses. See LICENSE.TXT for details. 7// 8//===----------------------------------------------------------------------===// 9 10#include "strstream" 11#include "algorithm" 12#include "climits" 13#include "cstring" 14 15_LIBCPP_BEGIN_NAMESPACE_STD 16 17strstreambuf::strstreambuf(streamsize __alsize) 18 : __strmode_(__dynamic), 19 __alsize_(__alsize), 20 __palloc_(nullptr), 21 __pfree_(nullptr) 22{ 23} 24 25strstreambuf::strstreambuf(void* (*__palloc)(size_t), void (*__pfree)(void*)) 26 : __strmode_(__dynamic), 27 __alsize_(__default_alsize), 28 __palloc_(__palloc), 29 __pfree_(__pfree) 30{ 31} 32 33void 34strstreambuf::__init(char* __gnext, streamsize __n, char* __pbeg) 35{ 36 if (__n == 0) 37 __n = static_cast<streamsize>(strlen(__gnext)); 38 else if (__n < 0) 39 __n = INT_MAX; 40 if (__pbeg == nullptr) 41 setg(__gnext, __gnext, __gnext + __n); 42 else 43 { 44 setg(__gnext, __gnext, __pbeg); 45 setp(__pbeg, __pbeg + __n); 46 } 47} 48 49strstreambuf::strstreambuf(char* __gnext, streamsize __n, char* __pbeg) 50 : __strmode_(), 51 __alsize_(__default_alsize), 52 __palloc_(nullptr), 53 __pfree_(nullptr) 54{ 55 __init(__gnext, __n, __pbeg); 56} 57 58strstreambuf::strstreambuf(const char* __gnext, streamsize __n) 59 : __strmode_(__constant), 60 __alsize_(__default_alsize), 61 __palloc_(nullptr), 62 __pfree_(nullptr) 63{ 64 __init(const_cast<char *>(__gnext), __n, nullptr); 65} 66 67strstreambuf::strstreambuf(signed char* __gnext, streamsize __n, signed char* __pbeg) 68 : __strmode_(), 69 __alsize_(__default_alsize), 70 __palloc_(nullptr), 71 __pfree_(nullptr) 72{ 73 __init(const_cast<char *>(reinterpret_cast<const char*>(__gnext)), __n, reinterpret_cast<char*>(__pbeg)); 74} 75 76strstreambuf::strstreambuf(const signed char* __gnext, streamsize __n) 77 : __strmode_(__constant), 78 __alsize_(__default_alsize), 79 __palloc_(nullptr), 80 __pfree_(nullptr) 81{ 82 __init(const_cast<char *>(reinterpret_cast<const char*>(__gnext)), __n, nullptr); 83} 84 85strstreambuf::strstreambuf(unsigned char* __gnext, streamsize __n, unsigned char* __pbeg) 86 : __strmode_(), 87 __alsize_(__default_alsize), 88 __palloc_(nullptr), 89 __pfree_(nullptr) 90{ 91 __init(const_cast<char *>(reinterpret_cast<const char*>(__gnext)), __n, reinterpret_cast<char*>(__pbeg)); 92} 93 94strstreambuf::strstreambuf(const unsigned char* __gnext, streamsize __n) 95 : __strmode_(__constant), 96 __alsize_(__default_alsize), 97 __palloc_(nullptr), 98 __pfree_(nullptr) 99{ 100 __init(const_cast<char *>(reinterpret_cast<const char*>(__gnext)), __n, nullptr); 101} 102 103strstreambuf::~strstreambuf() 104{ 105 if (eback() && (__strmode_ & __allocated) != 0 && (__strmode_ & __frozen) == 0) 106 { 107 if (__pfree_) 108 __pfree_(eback()); 109 else 110 delete [] eback(); 111 } 112} 113 114void 115strstreambuf::swap(strstreambuf& __rhs) 116{ 117 streambuf::swap(__rhs); 118 _VSTD::swap(__strmode_, __rhs.__strmode_); 119 _VSTD::swap(__alsize_, __rhs.__alsize_); 120 _VSTD::swap(__palloc_, __rhs.__palloc_); 121 _VSTD::swap(__pfree_, __rhs.__pfree_); 122} 123 124void 125strstreambuf::freeze(bool __freezefl) 126{ 127 if (__strmode_ & __dynamic) 128 { 129 if (__freezefl) 130 __strmode_ |= __frozen; 131 else 132 __strmode_ &= ~__frozen; 133 } 134} 135 136char* 137strstreambuf::str() 138{ 139 if (__strmode_ & __dynamic) 140 __strmode_ |= __frozen; 141 return eback(); 142} 143 144int 145strstreambuf::pcount() const 146{ 147 return static_cast<int>(pptr() - pbase()); 148} 149 150strstreambuf::int_type 151strstreambuf::overflow(int_type __c) 152{ 153 if (__c == EOF) 154 return int_type(0); 155 if (pptr() == epptr()) 156 { 157 if ((__strmode_ & __dynamic) == 0 || (__strmode_ & __frozen) != 0) 158 return int_type(EOF); 159 size_t old_size = static_cast<size_t> ((epptr() ? epptr() : egptr()) - eback()); 160 size_t new_size = max<size_t>(static_cast<size_t>(__alsize_), 2*old_size); 161 if (new_size == 0) 162 new_size = __default_alsize; 163 char* buf = nullptr; 164 if (__palloc_) 165 buf = static_cast<char*>(__palloc_(new_size)); 166 else 167 buf = new char[new_size]; 168 if (buf == nullptr) 169 return int_type(EOF); 170 memcpy(buf, eback(), static_cast<size_t>(old_size)); 171 ptrdiff_t ninp = gptr() - eback(); 172 ptrdiff_t einp = egptr() - eback(); 173 ptrdiff_t nout = pptr() - pbase(); 174 ptrdiff_t eout = epptr() - pbase(); 175 if (__strmode_ & __allocated) 176 { 177 if (__pfree_) 178 __pfree_(eback()); 179 else 180 delete [] eback(); 181 } 182 setg(buf, buf + ninp, buf + einp); 183 setp(buf + einp, buf + einp + eout); 184 pbump(static_cast<int>(nout)); 185 __strmode_ |= __allocated; 186 } 187 *pptr() = static_cast<char>(__c); 188 pbump(1); 189 return int_type(static_cast<unsigned char>(__c)); 190} 191 192strstreambuf::int_type 193strstreambuf::pbackfail(int_type __c) 194{ 195 if (eback() == gptr()) 196 return EOF; 197 if (__c == EOF) 198 { 199 gbump(-1); 200 return int_type(0); 201 } 202 if (__strmode_ & __constant) 203 { 204 if (gptr()[-1] == static_cast<char>(__c)) 205 { 206 gbump(-1); 207 return __c; 208 } 209 return EOF; 210 } 211 gbump(-1); 212 *gptr() = static_cast<char>(__c); 213 return __c; 214} 215 216strstreambuf::int_type 217strstreambuf::underflow() 218{ 219 if (gptr() == egptr()) 220 { 221 if (egptr() >= pptr()) 222 return EOF; 223 setg(eback(), gptr(), pptr()); 224 } 225 return int_type(static_cast<unsigned char>(*gptr())); 226} 227 228strstreambuf::pos_type 229strstreambuf::seekoff(off_type __off, ios_base::seekdir __way, ios_base::openmode __which) 230{ 231 off_type __p(-1); 232 bool pos_in = (__which & ios::in) != 0; 233 bool pos_out = (__which & ios::out) != 0; 234 bool legal = false; 235 switch (__way) 236 { 237 case ios::beg: 238 case ios::end: 239 if (pos_in || pos_out) 240 legal = true; 241 break; 242 case ios::cur: 243 if (pos_in != pos_out) 244 legal = true; 245 break; 246 } 247 if (pos_in && gptr() == nullptr) 248 legal = false; 249 if (pos_out && pptr() == nullptr) 250 legal = false; 251 if (legal) 252 { 253 off_type newoff; 254 char* seekhigh = epptr() ? epptr() : egptr(); 255 switch (__way) 256 { 257 case ios::beg: 258 newoff = 0; 259 break; 260 case ios::cur: 261 newoff = (pos_in ? gptr() : pptr()) - eback(); 262 break; 263 case ios::end: 264 newoff = seekhigh - eback(); 265 break; 266 } 267 newoff += __off; 268 if (0 <= newoff && newoff <= seekhigh - eback()) 269 { 270 char* newpos = eback() + newoff; 271 if (pos_in) 272 setg(eback(), newpos, _VSTD::max(newpos, egptr())); 273 if (pos_out) 274 { 275 // min(pbase, newpos), newpos, epptr() 276 __off = epptr() - newpos; 277 setp(min(pbase(), newpos), epptr()); 278 pbump(static_cast<int>((epptr() - pbase()) - __off)); 279 } 280 __p = newoff; 281 } 282 } 283 return pos_type(__p); 284} 285 286strstreambuf::pos_type 287strstreambuf::seekpos(pos_type __sp, ios_base::openmode __which) 288{ 289 off_type __p(-1); 290 bool pos_in = (__which & ios::in) != 0; 291 bool pos_out = (__which & ios::out) != 0; 292 if (pos_in || pos_out) 293 { 294 if (!((pos_in && gptr() == nullptr) || (pos_out && pptr() == nullptr))) 295 { 296 off_type newoff = __sp; 297 char* seekhigh = epptr() ? epptr() : egptr(); 298 if (0 <= newoff && newoff <= seekhigh - eback()) 299 { 300 char* newpos = eback() + newoff; 301 if (pos_in) 302 setg(eback(), newpos, _VSTD::max(newpos, egptr())); 303 if (pos_out) 304 { 305 // min(pbase, newpos), newpos, epptr() 306 off_type temp = epptr() - newpos; 307 setp(min(pbase(), newpos), epptr()); 308 pbump(static_cast<int>((epptr() - pbase()) - temp)); 309 } 310 __p = newoff; 311 } 312 } 313 } 314 return pos_type(__p); 315} 316 317istrstream::~istrstream() 318{ 319} 320 321ostrstream::~ostrstream() 322{ 323} 324 325strstream::~strstream() 326{ 327} 328 329_LIBCPP_END_NAMESPACE_STD 330