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