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