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 //===----------------------------------------------------------------------===//
16 _LIBCPP_BEGIN_NAMESPACE_STD
18 strstreambuf::strstreambuf(streamsize __alsize)
19 : __strmode_(__dynamic),
26 strstreambuf::strstreambuf(void* (*__palloc)(size_t), void (*__pfree)(void*))
27 : __strmode_(__dynamic),
28 __alsize_(__default_alsize),
35 strstreambuf::__init(char* __gnext, streamsize __n, char* __pbeg)
38 __n = static_cast<streamsize>(strlen(__gnext));
41 if (__pbeg == nullptr)
42 setg(__gnext, __gnext, __gnext + __n);
45 setg(__gnext, __gnext, __pbeg);
46 setp(__pbeg, __pbeg + __n);
50 strstreambuf::strstreambuf(char* __gnext, streamsize __n, char* __pbeg)
52 __alsize_(__default_alsize),
56 __init(__gnext, __n, __pbeg);
59 strstreambuf::strstreambuf(const char* __gnext, streamsize __n)
60 : __strmode_(__constant),
61 __alsize_(__default_alsize),
65 __init(const_cast<char *>(__gnext), __n, nullptr);
68 strstreambuf::strstreambuf(signed char* __gnext, streamsize __n, signed char* __pbeg)
70 __alsize_(__default_alsize),
74 __init(const_cast<char *>(reinterpret_cast<const char*>(__gnext)), __n, reinterpret_cast<char*>(__pbeg));
77 strstreambuf::strstreambuf(const signed char* __gnext, streamsize __n)
78 : __strmode_(__constant),
79 __alsize_(__default_alsize),
83 __init(const_cast<char *>(reinterpret_cast<const char*>(__gnext)), __n, nullptr);
86 strstreambuf::strstreambuf(unsigned char* __gnext, streamsize __n, unsigned char* __pbeg)
88 __alsize_(__default_alsize),
92 __init(const_cast<char *>(reinterpret_cast<const char*>(__gnext)), __n, reinterpret_cast<char*>(__pbeg));
95 strstreambuf::strstreambuf(const unsigned char* __gnext, streamsize __n)
96 : __strmode_(__constant),
97 __alsize_(__default_alsize),
101 __init(const_cast<char *>(reinterpret_cast<const char*>(__gnext)), __n, nullptr);
104 strstreambuf::~strstreambuf()
106 if (eback() && (__strmode_ & __allocated) != 0 && (__strmode_ & __frozen) == 0)
116 strstreambuf::swap(strstreambuf& __rhs)
118 streambuf::swap(__rhs);
119 _VSTD::swap(__strmode_, __rhs.__strmode_);
120 _VSTD::swap(__alsize_, __rhs.__alsize_);
121 _VSTD::swap(__palloc_, __rhs.__palloc_);
122 _VSTD::swap(__pfree_, __rhs.__pfree_);
126 strstreambuf::freeze(bool __freezefl)
128 if (__strmode_ & __dynamic)
131 __strmode_ |= __frozen;
133 __strmode_ &= ~__frozen;
140 if (__strmode_ & __dynamic)
141 __strmode_ |= __frozen;
146 strstreambuf::pcount() const
148 return static_cast<int>(pptr() - pbase());
151 strstreambuf::int_type
152 strstreambuf::overflow(int_type __c)
156 if (pptr() == epptr())
158 if ((__strmode_ & __dynamic) == 0 || (__strmode_ & __frozen) != 0)
159 return int_type(EOF);
160 size_t old_size = static_cast<size_t> ((epptr() ? epptr() : egptr()) - eback());
161 size_t new_size = max<size_t>(static_cast<size_t>(__alsize_), 2*old_size);
163 new_size = __default_alsize;
166 buf = static_cast<char*>(__palloc_(new_size));
168 buf = new char[new_size];
170 return int_type(EOF);
172 _LIBCPP_ASSERT(eback(), "overflow copying from NULL");
173 memcpy(buf, eback(), static_cast<size_t>(old_size));
175 ptrdiff_t ninp = gptr() - eback();
176 ptrdiff_t einp = egptr() - eback();
177 ptrdiff_t nout = pptr() - pbase();
178 if (__strmode_ & __allocated)
185 setg(buf, buf + ninp, buf + einp);
186 setp(buf + einp, buf + new_size);
187 pbump(static_cast<int>(nout));
188 __strmode_ |= __allocated;
190 *pptr() = static_cast<char>(__c);
192 return int_type(static_cast<unsigned char>(__c));
195 strstreambuf::int_type
196 strstreambuf::pbackfail(int_type __c)
198 if (eback() == gptr())
205 if (__strmode_ & __constant)
207 if (gptr()[-1] == static_cast<char>(__c))
215 *gptr() = static_cast<char>(__c);
219 strstreambuf::int_type
220 strstreambuf::underflow()
222 if (gptr() == egptr())
224 if (egptr() >= pptr())
226 setg(eback(), gptr(), pptr());
228 return int_type(static_cast<unsigned char>(*gptr()));
231 strstreambuf::pos_type
232 strstreambuf::seekoff(off_type __off, ios_base::seekdir __way, ios_base::openmode __which)
235 bool pos_in = (__which & ios::in) != 0;
236 bool pos_out = (__which & ios::out) != 0;
242 if (pos_in || pos_out)
246 if (pos_in != pos_out)
250 if (pos_in && gptr() == nullptr)
252 if (pos_out && pptr() == nullptr)
257 char* seekhigh = epptr() ? epptr() : egptr();
264 newoff = (pos_in ? gptr() : pptr()) - eback();
267 newoff = seekhigh - eback();
271 if (0 <= newoff && newoff <= seekhigh - eback())
273 char* newpos = eback() + newoff;
275 setg(eback(), newpos, _VSTD::max(newpos, egptr()));
278 // min(pbase, newpos), newpos, epptr()
279 __off = epptr() - newpos;
280 setp(min(pbase(), newpos), epptr());
281 pbump(static_cast<int>((epptr() - pbase()) - __off));
286 return pos_type(__p);
289 strstreambuf::pos_type
290 strstreambuf::seekpos(pos_type __sp, ios_base::openmode __which)
293 bool pos_in = (__which & ios::in) != 0;
294 bool pos_out = (__which & ios::out) != 0;
295 if (pos_in || pos_out)
297 if (!((pos_in && gptr() == nullptr) || (pos_out && pptr() == nullptr)))
299 off_type newoff = __sp;
300 char* seekhigh = epptr() ? epptr() : egptr();
301 if (0 <= newoff && newoff <= seekhigh - eback())
303 char* newpos = eback() + newoff;
305 setg(eback(), newpos, _VSTD::max(newpos, egptr()));
308 // min(pbase, newpos), newpos, epptr()
309 off_type temp = epptr() - newpos;
310 setp(min(pbase(), newpos), epptr());
311 pbump(static_cast<int>((epptr() - pbase()) - temp));
317 return pos_type(__p);
320 istrstream::~istrstream()
324 ostrstream::~ostrstream()
328 strstream::~strstream()
332 _LIBCPP_END_NAMESPACE_STD