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 #include "__undef_macros"
18 _LIBCPP_BEGIN_NAMESPACE_STD
20 strstreambuf::strstreambuf(streamsize __alsize)
21 : __strmode_(__dynamic),
28 strstreambuf::strstreambuf(void* (*__palloc)(size_t), void (*__pfree)(void*))
29 : __strmode_(__dynamic),
30 __alsize_(__default_alsize),
37 strstreambuf::__init(char* __gnext, streamsize __n, char* __pbeg)
40 __n = static_cast<streamsize>(strlen(__gnext));
43 if (__pbeg == nullptr)
44 setg(__gnext, __gnext, __gnext + __n);
47 setg(__gnext, __gnext, __pbeg);
48 setp(__pbeg, __pbeg + __n);
52 strstreambuf::strstreambuf(char* __gnext, streamsize __n, char* __pbeg)
54 __alsize_(__default_alsize),
58 __init(__gnext, __n, __pbeg);
61 strstreambuf::strstreambuf(const char* __gnext, streamsize __n)
62 : __strmode_(__constant),
63 __alsize_(__default_alsize),
67 __init(const_cast<char *>(__gnext), __n, nullptr);
70 strstreambuf::strstreambuf(signed char* __gnext, streamsize __n, signed char* __pbeg)
72 __alsize_(__default_alsize),
76 __init(const_cast<char *>(reinterpret_cast<const char*>(__gnext)), __n, reinterpret_cast<char*>(__pbeg));
79 strstreambuf::strstreambuf(const signed char* __gnext, streamsize __n)
80 : __strmode_(__constant),
81 __alsize_(__default_alsize),
85 __init(const_cast<char *>(reinterpret_cast<const char*>(__gnext)), __n, nullptr);
88 strstreambuf::strstreambuf(unsigned char* __gnext, streamsize __n, unsigned char* __pbeg)
90 __alsize_(__default_alsize),
94 __init(const_cast<char *>(reinterpret_cast<const char*>(__gnext)), __n, reinterpret_cast<char*>(__pbeg));
97 strstreambuf::strstreambuf(const unsigned char* __gnext, streamsize __n)
98 : __strmode_(__constant),
99 __alsize_(__default_alsize),
103 __init(const_cast<char *>(reinterpret_cast<const char*>(__gnext)), __n, nullptr);
106 strstreambuf::~strstreambuf()
108 if (eback() && (__strmode_ & __allocated) != 0 && (__strmode_ & __frozen) == 0)
118 strstreambuf::swap(strstreambuf& __rhs)
120 streambuf::swap(__rhs);
121 _VSTD::swap(__strmode_, __rhs.__strmode_);
122 _VSTD::swap(__alsize_, __rhs.__alsize_);
123 _VSTD::swap(__palloc_, __rhs.__palloc_);
124 _VSTD::swap(__pfree_, __rhs.__pfree_);
128 strstreambuf::freeze(bool __freezefl)
130 if (__strmode_ & __dynamic)
133 __strmode_ |= __frozen;
135 __strmode_ &= ~__frozen;
142 if (__strmode_ & __dynamic)
143 __strmode_ |= __frozen;
148 strstreambuf::pcount() const
150 return static_cast<int>(pptr() - pbase());
153 strstreambuf::int_type
154 strstreambuf::overflow(int_type __c)
158 if (pptr() == epptr())
160 if ((__strmode_ & __dynamic) == 0 || (__strmode_ & __frozen) != 0)
161 return int_type(EOF);
162 size_t old_size = static_cast<size_t> ((epptr() ? epptr() : egptr()) - eback());
163 size_t new_size = max<size_t>(static_cast<size_t>(__alsize_), 2*old_size);
165 new_size = __default_alsize;
168 buf = static_cast<char*>(__palloc_(new_size));
170 buf = new char[new_size];
172 return int_type(EOF);
174 _LIBCPP_ASSERT(eback(), "overflow copying from NULL");
175 memcpy(buf, eback(), static_cast<size_t>(old_size));
177 ptrdiff_t ninp = gptr() - eback();
178 ptrdiff_t einp = egptr() - eback();
179 ptrdiff_t nout = pptr() - pbase();
180 if (__strmode_ & __allocated)
187 setg(buf, buf + ninp, buf + einp);
188 setp(buf + einp, buf + new_size);
189 pbump(static_cast<int>(nout));
190 __strmode_ |= __allocated;
192 *pptr() = static_cast<char>(__c);
194 return int_type(static_cast<unsigned char>(__c));
197 strstreambuf::int_type
198 strstreambuf::pbackfail(int_type __c)
200 if (eback() == gptr())
207 if (__strmode_ & __constant)
209 if (gptr()[-1] == static_cast<char>(__c))
217 *gptr() = static_cast<char>(__c);
221 strstreambuf::int_type
222 strstreambuf::underflow()
224 if (gptr() == egptr())
226 if (egptr() >= pptr())
228 setg(eback(), gptr(), pptr());
230 return int_type(static_cast<unsigned char>(*gptr()));
233 strstreambuf::pos_type
234 strstreambuf::seekoff(off_type __off, ios_base::seekdir __way, ios_base::openmode __which)
237 bool pos_in = (__which & ios::in) != 0;
238 bool pos_out = (__which & ios::out) != 0;
244 if (pos_in || pos_out)
248 if (pos_in != pos_out)
252 if (pos_in && gptr() == nullptr)
254 if (pos_out && pptr() == nullptr)
259 char* seekhigh = epptr() ? epptr() : egptr();
266 newoff = (pos_in ? gptr() : pptr()) - eback();
269 newoff = seekhigh - eback();
272 _LIBCPP_UNREACHABLE();
275 if (0 <= newoff && newoff <= seekhigh - eback())
277 char* newpos = eback() + newoff;
279 setg(eback(), newpos, _VSTD::max(newpos, egptr()));
282 // min(pbase, newpos), newpos, epptr()
283 __off = epptr() - newpos;
284 setp(min(pbase(), newpos), epptr());
285 pbump(static_cast<int>((epptr() - pbase()) - __off));
290 return pos_type(__p);
293 strstreambuf::pos_type
294 strstreambuf::seekpos(pos_type __sp, ios_base::openmode __which)
297 bool pos_in = (__which & ios::in) != 0;
298 bool pos_out = (__which & ios::out) != 0;
299 if (pos_in || pos_out)
301 if (!((pos_in && gptr() == nullptr) || (pos_out && pptr() == nullptr)))
303 off_type newoff = __sp;
304 char* seekhigh = epptr() ? epptr() : egptr();
305 if (0 <= newoff && newoff <= seekhigh - eback())
307 char* newpos = eback() + newoff;
309 setg(eback(), newpos, _VSTD::max(newpos, egptr()));
312 // min(pbase, newpos), newpos, epptr()
313 off_type temp = epptr() - newpos;
314 setp(min(pbase(), newpos), epptr());
315 pbump(static_cast<int>((epptr() - pbase()) - temp));
321 return pos_type(__p);
324 istrstream::~istrstream()
328 ostrstream::~ostrstream()
332 strstream::~strstream()
336 _LIBCPP_END_NAMESPACE_STD