1 //===----------------------------------------------------------------------===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
10 #include <__utility/unreachable.h>
18 #include <__undef_macros>
20 _LIBCPP_BEGIN_NAMESPACE_STD
22 strstreambuf::strstreambuf(streamsize __alsize
)
23 : __strmode_(__dynamic
),
30 strstreambuf::strstreambuf(void* (*__palloc
)(size_t), void (*__pfree
)(void*))
31 : __strmode_(__dynamic
),
32 __alsize_(__default_alsize
),
39 strstreambuf::__init(char* __gnext
, streamsize __n
, char* __pbeg
)
42 __n
= static_cast<streamsize
>(strlen(__gnext
));
45 if (__pbeg
== nullptr)
46 setg(__gnext
, __gnext
, __gnext
+ __n
);
49 setg(__gnext
, __gnext
, __pbeg
);
50 setp(__pbeg
, __pbeg
+ __n
);
54 strstreambuf::strstreambuf(char* __gnext
, streamsize __n
, char* __pbeg
)
56 __alsize_(__default_alsize
),
60 __init(__gnext
, __n
, __pbeg
);
63 strstreambuf::strstreambuf(const char* __gnext
, streamsize __n
)
64 : __strmode_(__constant
),
65 __alsize_(__default_alsize
),
69 __init(const_cast<char *>(__gnext
), __n
, nullptr);
72 strstreambuf::strstreambuf(signed char* __gnext
, streamsize __n
, signed char* __pbeg
)
74 __alsize_(__default_alsize
),
78 __init(const_cast<char *>(reinterpret_cast<const char*>(__gnext
)), __n
, reinterpret_cast<char*>(__pbeg
));
81 strstreambuf::strstreambuf(const signed char* __gnext
, streamsize __n
)
82 : __strmode_(__constant
),
83 __alsize_(__default_alsize
),
87 __init(const_cast<char *>(reinterpret_cast<const char*>(__gnext
)), __n
, nullptr);
90 strstreambuf::strstreambuf(unsigned char* __gnext
, streamsize __n
, unsigned char* __pbeg
)
92 __alsize_(__default_alsize
),
96 __init(const_cast<char *>(reinterpret_cast<const char*>(__gnext
)), __n
, reinterpret_cast<char*>(__pbeg
));
99 strstreambuf::strstreambuf(const unsigned char* __gnext
, streamsize __n
)
100 : __strmode_(__constant
),
101 __alsize_(__default_alsize
),
105 __init(const_cast<char *>(reinterpret_cast<const char*>(__gnext
)), __n
, nullptr);
108 strstreambuf::~strstreambuf()
110 if (eback() && (__strmode_
& __allocated
) != 0 && (__strmode_
& __frozen
) == 0)
120 strstreambuf::swap(strstreambuf
& __rhs
)
122 streambuf::swap(__rhs
);
123 _VSTD::swap(__strmode_
, __rhs
.__strmode_
);
124 _VSTD::swap(__alsize_
, __rhs
.__alsize_
);
125 _VSTD::swap(__palloc_
, __rhs
.__palloc_
);
126 _VSTD::swap(__pfree_
, __rhs
.__pfree_
);
130 strstreambuf::freeze(bool __freezefl
)
132 if (__strmode_
& __dynamic
)
135 __strmode_
|= __frozen
;
137 __strmode_
&= ~__frozen
;
144 if (__strmode_
& __dynamic
)
145 __strmode_
|= __frozen
;
150 strstreambuf::pcount() const
152 return static_cast<int>(pptr() - pbase());
155 strstreambuf::int_type
156 strstreambuf::overflow(int_type __c
)
160 if (pptr() == epptr())
162 if ((__strmode_
& __dynamic
) == 0 || (__strmode_
& __frozen
) != 0)
163 return int_type(EOF
);
164 size_t old_size
= static_cast<size_t> ((epptr() ? epptr() : egptr()) - eback());
165 size_t new_size
= max
<size_t>(static_cast<size_t>(__alsize_
), 2*old_size
);
167 new_size
= __default_alsize
;
170 buf
= static_cast<char*>(__palloc_(new_size
));
172 buf
= new char[new_size
];
174 return int_type(EOF
);
176 _LIBCPP_ASSERT(eback(), "overflow copying from NULL");
177 memcpy(buf
, eback(), static_cast<size_t>(old_size
));
179 ptrdiff_t ninp
= gptr() - eback();
180 ptrdiff_t einp
= egptr() - eback();
181 ptrdiff_t nout
= pptr() - pbase();
182 if (__strmode_
& __allocated
)
189 setg(buf
, buf
+ ninp
, buf
+ einp
);
190 setp(buf
+ einp
, buf
+ new_size
);
192 __strmode_
|= __allocated
;
194 *pptr() = static_cast<char>(__c
);
196 return int_type(static_cast<unsigned char>(__c
));
199 strstreambuf::int_type
200 strstreambuf::pbackfail(int_type __c
)
202 if (eback() == gptr())
209 if (__strmode_
& __constant
)
211 if (gptr()[-1] == static_cast<char>(__c
))
219 *gptr() = static_cast<char>(__c
);
223 strstreambuf::int_type
224 strstreambuf::underflow()
226 if (gptr() == egptr())
228 if (egptr() >= pptr())
230 setg(eback(), gptr(), pptr());
232 return int_type(static_cast<unsigned char>(*gptr()));
235 strstreambuf::pos_type
236 strstreambuf::seekoff(off_type __off
, ios_base::seekdir __way
, ios_base::openmode __which
)
239 bool pos_in
= (__which
& ios::in
) != 0;
240 bool pos_out
= (__which
& ios::out
) != 0;
246 if (pos_in
|| pos_out
)
250 if (pos_in
!= pos_out
)
254 if (pos_in
&& gptr() == nullptr)
256 if (pos_out
&& pptr() == nullptr)
261 char* seekhigh
= epptr() ? epptr() : egptr();
268 newoff
= (pos_in
? gptr() : pptr()) - eback();
271 newoff
= seekhigh
- eback();
274 __libcpp_unreachable();
277 if (0 <= newoff
&& newoff
<= seekhigh
- eback())
279 char* newpos
= eback() + newoff
;
281 setg(eback(), newpos
, _VSTD::max(newpos
, egptr()));
284 // min(pbase, newpos), newpos, epptr()
285 __off
= epptr() - newpos
;
286 setp(min(pbase(), newpos
), epptr());
287 __pbump((epptr() - pbase()) - __off
);
292 return pos_type(__p
);
295 strstreambuf::pos_type
296 strstreambuf::seekpos(pos_type __sp
, ios_base::openmode __which
)
299 bool pos_in
= (__which
& ios::in
) != 0;
300 bool pos_out
= (__which
& ios::out
) != 0;
301 if (pos_in
|| pos_out
)
303 if (!((pos_in
&& gptr() == nullptr) || (pos_out
&& pptr() == nullptr)))
305 off_type newoff
= __sp
;
306 char* seekhigh
= epptr() ? epptr() : egptr();
307 if (0 <= newoff
&& newoff
<= seekhigh
- eback())
309 char* newpos
= eback() + newoff
;
311 setg(eback(), newpos
, _VSTD::max(newpos
, egptr()));
314 // min(pbase, newpos), newpos, epptr()
315 off_type temp
= epptr() - newpos
;
316 setp(min(pbase(), newpos
), epptr());
317 __pbump((epptr() - pbase()) - temp
);
323 return pos_type(__p
);
326 istrstream::~istrstream()
330 ostrstream::~ostrstream()
334 strstream::~strstream()
338 _LIBCPP_END_NAMESPACE_STD