etc/services - sync with NetBSD-8
[minix.git] / external / bsd / libc++ / dist / libcxx / src / strstream.cpp
blobea728138db66c9ba8e21ad4f5afb0f216577d20d
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 //===----------------------------------------------------------------------===//
10 #include "strstream"
11 #include "algorithm"
12 #include "climits"
13 #include "cstring"
15 _LIBCPP_BEGIN_NAMESPACE_STD
17 strstreambuf::strstreambuf(streamsize __alsize)
18 : __strmode_(__dynamic),
19 __alsize_(__alsize),
20 __palloc_(nullptr),
21 __pfree_(nullptr)
25 strstreambuf::strstreambuf(void* (*__palloc)(size_t), void (*__pfree)(void*))
26 : __strmode_(__dynamic),
27 __alsize_(__default_alsize),
28 __palloc_(__palloc),
29 __pfree_(__pfree)
33 void
34 strstreambuf::__init(char* __gnext, streamsize __n, char* __pbeg)
36 if (__n == 0)
37 __n = static_cast<streamsize>(strlen(__gnext));
38 else if (__n < 0)
39 __n = INT_MAX;
40 if (__pbeg == nullptr)
41 setg(__gnext, __gnext, __gnext + __n);
42 else
44 setg(__gnext, __gnext, __pbeg);
45 setp(__pbeg, __pbeg + __n);
49 strstreambuf::strstreambuf(char* __gnext, streamsize __n, char* __pbeg)
50 : __strmode_(),
51 __alsize_(__default_alsize),
52 __palloc_(nullptr),
53 __pfree_(nullptr)
55 __init(__gnext, __n, __pbeg);
58 strstreambuf::strstreambuf(const char* __gnext, streamsize __n)
59 : __strmode_(__constant),
60 __alsize_(__default_alsize),
61 __palloc_(nullptr),
62 __pfree_(nullptr)
64 __init(const_cast<char *>(__gnext), __n, nullptr);
67 strstreambuf::strstreambuf(signed char* __gnext, streamsize __n, signed char* __pbeg)
68 : __strmode_(),
69 __alsize_(__default_alsize),
70 __palloc_(nullptr),
71 __pfree_(nullptr)
73 __init(const_cast<char *>(reinterpret_cast<const char*>(__gnext)), __n, reinterpret_cast<char*>(__pbeg));
76 strstreambuf::strstreambuf(const signed char* __gnext, streamsize __n)
77 : __strmode_(__constant),
78 __alsize_(__default_alsize),
79 __palloc_(nullptr),
80 __pfree_(nullptr)
82 __init(const_cast<char *>(reinterpret_cast<const char*>(__gnext)), __n, nullptr);
85 strstreambuf::strstreambuf(unsigned char* __gnext, streamsize __n, unsigned char* __pbeg)
86 : __strmode_(),
87 __alsize_(__default_alsize),
88 __palloc_(nullptr),
89 __pfree_(nullptr)
91 __init(const_cast<char *>(reinterpret_cast<const char*>(__gnext)), __n, reinterpret_cast<char*>(__pbeg));
94 strstreambuf::strstreambuf(const unsigned char* __gnext, streamsize __n)
95 : __strmode_(__constant),
96 __alsize_(__default_alsize),
97 __palloc_(nullptr),
98 __pfree_(nullptr)
100 __init(const_cast<char *>(reinterpret_cast<const char*>(__gnext)), __n, nullptr);
103 strstreambuf::~strstreambuf()
105 if (eback() && (__strmode_ & __allocated) != 0 && (__strmode_ & __frozen) == 0)
107 if (__pfree_)
108 __pfree_(eback());
109 else
110 delete [] eback();
114 void
115 strstreambuf::swap(strstreambuf& __rhs)
117 streambuf::swap(__rhs);
118 _VSTD::swap(__strmode_, __rhs.__strmode_);
119 _VSTD::swap(__alsize_, __rhs.__alsize_);
120 _VSTD::swap(__palloc_, __rhs.__palloc_);
121 _VSTD::swap(__pfree_, __rhs.__pfree_);
124 void
125 strstreambuf::freeze(bool __freezefl)
127 if (__strmode_ & __dynamic)
129 if (__freezefl)
130 __strmode_ |= __frozen;
131 else
132 __strmode_ &= ~__frozen;
136 char*
137 strstreambuf::str()
139 if (__strmode_ & __dynamic)
140 __strmode_ |= __frozen;
141 return eback();
145 strstreambuf::pcount() const
147 return static_cast<int>(pptr() - pbase());
150 strstreambuf::int_type
151 strstreambuf::overflow(int_type __c)
153 if (__c == EOF)
154 return int_type(0);
155 if (pptr() == epptr())
157 if ((__strmode_ & __dynamic) == 0 || (__strmode_ & __frozen) != 0)
158 return int_type(EOF);
159 size_t old_size = static_cast<size_t> ((epptr() ? epptr() : egptr()) - eback());
160 size_t new_size = max<size_t>(static_cast<size_t>(__alsize_), 2*old_size);
161 if (new_size == 0)
162 new_size = __default_alsize;
163 char* buf = nullptr;
164 if (__palloc_)
165 buf = static_cast<char*>(__palloc_(new_size));
166 else
167 buf = new char[new_size];
168 if (buf == nullptr)
169 return int_type(EOF);
170 memcpy(buf, eback(), static_cast<size_t>(old_size));
171 ptrdiff_t ninp = gptr() - eback();
172 ptrdiff_t einp = egptr() - eback();
173 ptrdiff_t nout = pptr() - pbase();
174 ptrdiff_t eout = epptr() - pbase();
175 if (__strmode_ & __allocated)
177 if (__pfree_)
178 __pfree_(eback());
179 else
180 delete [] eback();
182 setg(buf, buf + ninp, buf + einp);
183 setp(buf + einp, buf + einp + eout);
184 pbump(static_cast<int>(nout));
185 __strmode_ |= __allocated;
187 *pptr() = static_cast<char>(__c);
188 pbump(1);
189 return int_type(static_cast<unsigned char>(__c));
192 strstreambuf::int_type
193 strstreambuf::pbackfail(int_type __c)
195 if (eback() == gptr())
196 return EOF;
197 if (__c == EOF)
199 gbump(-1);
200 return int_type(0);
202 if (__strmode_ & __constant)
204 if (gptr()[-1] == static_cast<char>(__c))
206 gbump(-1);
207 return __c;
209 return EOF;
211 gbump(-1);
212 *gptr() = static_cast<char>(__c);
213 return __c;
216 strstreambuf::int_type
217 strstreambuf::underflow()
219 if (gptr() == egptr())
221 if (egptr() >= pptr())
222 return EOF;
223 setg(eback(), gptr(), pptr());
225 return int_type(static_cast<unsigned char>(*gptr()));
228 strstreambuf::pos_type
229 strstreambuf::seekoff(off_type __off, ios_base::seekdir __way, ios_base::openmode __which)
231 off_type __p(-1);
232 bool pos_in = (__which & ios::in) != 0;
233 bool pos_out = (__which & ios::out) != 0;
234 bool legal = false;
235 switch (__way)
237 case ios::beg:
238 case ios::end:
239 if (pos_in || pos_out)
240 legal = true;
241 break;
242 case ios::cur:
243 if (pos_in != pos_out)
244 legal = true;
245 break;
247 if (pos_in && gptr() == nullptr)
248 legal = false;
249 if (pos_out && pptr() == nullptr)
250 legal = false;
251 if (legal)
253 off_type newoff;
254 char* seekhigh = epptr() ? epptr() : egptr();
255 switch (__way)
257 case ios::beg:
258 newoff = 0;
259 break;
260 case ios::cur:
261 newoff = (pos_in ? gptr() : pptr()) - eback();
262 break;
263 case ios::end:
264 newoff = seekhigh - eback();
265 break;
267 newoff += __off;
268 if (0 <= newoff && newoff <= seekhigh - eback())
270 char* newpos = eback() + newoff;
271 if (pos_in)
272 setg(eback(), newpos, _VSTD::max(newpos, egptr()));
273 if (pos_out)
275 // min(pbase, newpos), newpos, epptr()
276 __off = epptr() - newpos;
277 setp(min(pbase(), newpos), epptr());
278 pbump(static_cast<int>((epptr() - pbase()) - __off));
280 __p = newoff;
283 return pos_type(__p);
286 strstreambuf::pos_type
287 strstreambuf::seekpos(pos_type __sp, ios_base::openmode __which)
289 off_type __p(-1);
290 bool pos_in = (__which & ios::in) != 0;
291 bool pos_out = (__which & ios::out) != 0;
292 if (pos_in || pos_out)
294 if (!((pos_in && gptr() == nullptr) || (pos_out && pptr() == nullptr)))
296 off_type newoff = __sp;
297 char* seekhigh = epptr() ? epptr() : egptr();
298 if (0 <= newoff && newoff <= seekhigh - eback())
300 char* newpos = eback() + newoff;
301 if (pos_in)
302 setg(eback(), newpos, _VSTD::max(newpos, egptr()));
303 if (pos_out)
305 // min(pbase, newpos), newpos, epptr()
306 off_type temp = epptr() - newpos;
307 setp(min(pbase(), newpos), epptr());
308 pbump(static_cast<int>((epptr() - pbase()) - temp));
310 __p = newoff;
314 return pos_type(__p);
317 istrstream::~istrstream()
321 ostrstream::~ostrstream()
325 strstream::~strstream()
329 _LIBCPP_END_NAMESPACE_STD