xref: /netbsd-src/external/apache2/llvm/dist/libcxx/src/strstream.cpp (revision 4d6fc14bc9b0c5bf3e30be318c143ee82cadd108)
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