1 //===------------------------ strstream.cpp -------------------------------===//
3 // The LLVM Compiler Infrastructure
5 // This file is dual licensed under the MIT and the University of Illinois Open
6 // Source Licenses. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
15 _LIBCPP_BEGIN_NAMESPACE_STD
17 strstreambuf::strstreambuf(streamsize __alsize)
18 : __strmode_(__dynamic),
25 strstreambuf::strstreambuf(void* (*__palloc)(size_t), void (*__pfree)(void*))
26 : __strmode_(__dynamic),
27 __alsize_(__default_alsize),
34 strstreambuf::__init(char* __gnext, streamsize __n, char* __pbeg)
37 __n = static_cast<streamsize>(strlen(__gnext));
40 if (__pbeg == nullptr)
41 setg(__gnext, __gnext, __gnext + __n);
44 setg(__gnext, __gnext, __pbeg);
45 setp(__pbeg, __pbeg + __n);
49 strstreambuf::strstreambuf(char* __gnext, streamsize __n, char* __pbeg)
51 __alsize_(__default_alsize),
55 __init(__gnext, __n, __pbeg);
58 strstreambuf::strstreambuf(const char* __gnext, streamsize __n)
59 : __strmode_(__constant),
60 __alsize_(__default_alsize),
64 __init((char*)__gnext, __n, nullptr);
67 strstreambuf::strstreambuf(signed char* __gnext, streamsize __n, signed char* __pbeg)
69 __alsize_(__default_alsize),
73 __init((char*)__gnext, __n, (char*)__pbeg);
76 strstreambuf::strstreambuf(const signed char* __gnext, streamsize __n)
77 : __strmode_(__constant),
78 __alsize_(__default_alsize),
82 __init((char*)__gnext, __n, nullptr);
85 strstreambuf::strstreambuf(unsigned char* __gnext, streamsize __n, unsigned char* __pbeg)
87 __alsize_(__default_alsize),
91 __init((char*)__gnext, __n, (char*)__pbeg);
94 strstreambuf::strstreambuf(const unsigned char* __gnext, streamsize __n)
95 : __strmode_(__constant),
96 __alsize_(__default_alsize),
100 __init((char*)__gnext, __n, nullptr);
103 strstreambuf::~strstreambuf()
105 if (eback() && (__strmode_ & __allocated) != 0 && (__strmode_ & __frozen) == 0)
115 strstreambuf::swap(strstreambuf& __rhs)
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_);
125 strstreambuf::freeze(bool __freezefl)
127 if (__strmode_ & __dynamic)
130 __strmode_ |= __frozen;
132 __strmode_ &= ~__frozen;
139 if (__strmode_ & __dynamic)
140 __strmode_ |= __frozen;
145 strstreambuf::pcount() const
147 return static_cast<int>(pptr() - pbase());
150 strstreambuf::int_type
151 strstreambuf::overflow(int_type __c)
155 if (pptr() == epptr())
157 if ((__strmode_ & __dynamic) == 0 || (__strmode_ & __frozen) != 0)
158 return int_type(EOF);
159 streamsize old_size = (epptr() ? epptr() : egptr()) - eback();
160 streamsize new_size = max<streamsize>(__alsize_, 2*old_size);
163 buf = static_cast<char*>(__palloc_(static_cast<size_t>(new_size)));
165 buf = new char[new_size];
167 return int_type(EOF);
168 memcpy(buf, eback(), static_cast<size_t>(old_size));
169 ptrdiff_t ninp = gptr() - eback();
170 ptrdiff_t einp = egptr() - eback();
171 ptrdiff_t nout = pptr() - pbase();
172 ptrdiff_t eout = epptr() - pbase();
173 if (__strmode_ & __allocated)
180 setg(buf, buf + ninp, buf + einp);
181 setp(buf + einp, buf + einp + eout);
182 pbump(static_cast<int>(nout));
183 __strmode_ |= __allocated;
185 *pptr() = static_cast<char>(__c);
187 return int_type((unsigned char)__c);
190 strstreambuf::int_type
191 strstreambuf::pbackfail(int_type __c)
193 if (eback() == gptr())
200 if (__strmode_ & __constant)
202 if (gptr()[-1] == static_cast<char>(__c))
210 *gptr() = static_cast<char>(__c);
214 strstreambuf::int_type
215 strstreambuf::underflow()
217 if (gptr() == egptr())
219 if (egptr() >= pptr())
221 setg(eback(), gptr(), pptr());
223 return int_type((unsigned char)*gptr());
226 strstreambuf::pos_type
227 strstreambuf::seekoff(off_type __off, ios_base::seekdir __way, ios_base::openmode __which)
230 bool pos_in = __which & ios::in;
231 bool pos_out = __which & ios::out;
237 if (pos_in || pos_out)
241 if (pos_in != pos_out)
245 if (pos_in && gptr() == nullptr)
247 if (pos_out && pptr() == nullptr)
252 char* seekhigh = epptr() ? epptr() : egptr();
259 newoff = (pos_in ? gptr() : pptr()) - eback();
262 newoff = seekhigh - eback();
266 if (0 <= newoff && newoff <= seekhigh - eback())
268 char* newpos = eback() + newoff;
270 setg(eback(), newpos, _VSTD::max(newpos, egptr()));
273 // min(pbase, newpos), newpos, epptr()
274 __off = epptr() - newpos;
275 setp(min(pbase(), newpos), epptr());
276 pbump(static_cast<int>((epptr() - pbase()) - __off));
281 return pos_type(__p);
284 strstreambuf::pos_type
285 strstreambuf::seekpos(pos_type __sp, ios_base::openmode __which)
288 bool pos_in = __which & ios::in;
289 bool pos_out = __which & ios::out;
290 if (pos_in || pos_out)
292 if (!((pos_in && gptr() == nullptr) || (pos_out && pptr() == nullptr)))
294 off_type newoff = __sp;
295 char* seekhigh = epptr() ? epptr() : egptr();
296 if (0 <= newoff && newoff <= seekhigh - eback())
298 char* newpos = eback() + newoff;
300 setg(eback(), newpos, _VSTD::max(newpos, egptr()));
303 // min(pbase, newpos), newpos, epptr()
304 off_type temp = epptr() - newpos;
305 setp(min(pbase(), newpos), epptr());
306 pbump(static_cast<int>((epptr() - pbase()) - temp));
312 return pos_type(__p);
315 istrstream::~istrstream()
319 ostrstream::~ostrstream()
323 strstream::~strstream()
327 _LIBCPP_END_NAMESPACE_STD