1 //===------------------------ strstream.cpp -------------------------------===//
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 //===----------------------------------------------------------------------===//
15 #include "__undef_macros"
17 _LIBCPP_BEGIN_NAMESPACE_STD
19 strstreambuf::strstreambuf(streamsize __alsize
)
20 : __strmode_(__dynamic
),
27 strstreambuf::strstreambuf(void* (*__palloc
)(size_t), void (*__pfree
)(void*))
28 : __strmode_(__dynamic
),
29 __alsize_(__default_alsize
),
36 strstreambuf::__init(char* __gnext
, streamsize __n
, char* __pbeg
)
39 __n
= static_cast<streamsize
>(strlen(__gnext
));
42 if (__pbeg
== nullptr)
43 setg(__gnext
, __gnext
, __gnext
+ __n
);
46 setg(__gnext
, __gnext
, __pbeg
);
47 setp(__pbeg
, __pbeg
+ __n
);
51 strstreambuf::strstreambuf(char* __gnext
, streamsize __n
, char* __pbeg
)
53 __alsize_(__default_alsize
),
57 __init(__gnext
, __n
, __pbeg
);
60 strstreambuf::strstreambuf(const char* __gnext
, streamsize __n
)
61 : __strmode_(__constant
),
62 __alsize_(__default_alsize
),
66 __init(const_cast<char *>(__gnext
), __n
, nullptr);
69 strstreambuf::strstreambuf(signed char* __gnext
, streamsize __n
, signed char* __pbeg
)
71 __alsize_(__default_alsize
),
75 __init(const_cast<char *>(reinterpret_cast<const char*>(__gnext
)), __n
, reinterpret_cast<char*>(__pbeg
));
78 strstreambuf::strstreambuf(const signed char* __gnext
, streamsize __n
)
79 : __strmode_(__constant
),
80 __alsize_(__default_alsize
),
84 __init(const_cast<char *>(reinterpret_cast<const char*>(__gnext
)), __n
, nullptr);
87 strstreambuf::strstreambuf(unsigned char* __gnext
, streamsize __n
, unsigned char* __pbeg
)
89 __alsize_(__default_alsize
),
93 __init(const_cast<char *>(reinterpret_cast<const char*>(__gnext
)), __n
, reinterpret_cast<char*>(__pbeg
));
96 strstreambuf::strstreambuf(const unsigned char* __gnext
, streamsize __n
)
97 : __strmode_(__constant
),
98 __alsize_(__default_alsize
),
102 __init(const_cast<char *>(reinterpret_cast<const char*>(__gnext
)), __n
, nullptr);
105 strstreambuf::~strstreambuf()
107 if (eback() && (__strmode_
& __allocated
) != 0 && (__strmode_
& __frozen
) == 0)
117 strstreambuf::swap(strstreambuf
& __rhs
)
119 streambuf::swap(__rhs
);
120 _VSTD::swap(__strmode_
, __rhs
.__strmode_
);
121 _VSTD::swap(__alsize_
, __rhs
.__alsize_
);
122 _VSTD::swap(__palloc_
, __rhs
.__palloc_
);
123 _VSTD::swap(__pfree_
, __rhs
.__pfree_
);
127 strstreambuf::freeze(bool __freezefl
)
129 if (__strmode_
& __dynamic
)
132 __strmode_
|= __frozen
;
134 __strmode_
&= ~__frozen
;
141 if (__strmode_
& __dynamic
)
142 __strmode_
|= __frozen
;
147 strstreambuf::pcount() const
149 return static_cast<int>(pptr() - pbase());
152 strstreambuf::int_type
153 strstreambuf::overflow(int_type __c
)
157 if (pptr() == epptr())
159 if ((__strmode_
& __dynamic
) == 0 || (__strmode_
& __frozen
) != 0)
160 return int_type(EOF
);
161 size_t old_size
= static_cast<size_t> ((epptr() ? epptr() : egptr()) - eback());
162 size_t new_size
= max
<size_t>(static_cast<size_t>(__alsize_
), 2*old_size
);
164 new_size
= __default_alsize
;
167 buf
= static_cast<char*>(__palloc_(new_size
));
169 buf
= new char[new_size
];
171 return int_type(EOF
);
173 _LIBCPP_ASSERT(eback(), "overflow copying from NULL");
174 memcpy(buf
, eback(), static_cast<size_t>(old_size
));
176 ptrdiff_t ninp
= gptr() - eback();
177 ptrdiff_t einp
= egptr() - eback();
178 ptrdiff_t nout
= pptr() - pbase();
179 if (__strmode_
& __allocated
)
186 setg(buf
, buf
+ ninp
, buf
+ einp
);
187 setp(buf
+ einp
, buf
+ new_size
);
189 __strmode_
|= __allocated
;
191 *pptr() = static_cast<char>(__c
);
193 return int_type(static_cast<unsigned char>(__c
));
196 strstreambuf::int_type
197 strstreambuf::pbackfail(int_type __c
)
199 if (eback() == gptr())
206 if (__strmode_
& __constant
)
208 if (gptr()[-1] == static_cast<char>(__c
))
216 *gptr() = static_cast<char>(__c
);
220 strstreambuf::int_type
221 strstreambuf::underflow()
223 if (gptr() == egptr())
225 if (egptr() >= pptr())
227 setg(eback(), gptr(), pptr());
229 return int_type(static_cast<unsigned char>(*gptr()));
232 strstreambuf::pos_type
233 strstreambuf::seekoff(off_type __off
, ios_base::seekdir __way
, ios_base::openmode __which
)
236 bool pos_in
= (__which
& ios::in
) != 0;
237 bool pos_out
= (__which
& ios::out
) != 0;
243 if (pos_in
|| pos_out
)
247 if (pos_in
!= pos_out
)
251 if (pos_in
&& gptr() == nullptr)
253 if (pos_out
&& pptr() == nullptr)
258 char* seekhigh
= epptr() ? epptr() : egptr();
265 newoff
= (pos_in
? gptr() : pptr()) - eback();
268 newoff
= seekhigh
- eback();
271 _LIBCPP_UNREACHABLE();
274 if (0 <= newoff
&& newoff
<= seekhigh
- eback())
276 char* newpos
= eback() + newoff
;
278 setg(eback(), newpos
, _VSTD::max(newpos
, egptr()));
281 // min(pbase, newpos), newpos, epptr()
282 __off
= epptr() - newpos
;
283 setp(min(pbase(), newpos
), epptr());
284 __pbump((epptr() - pbase()) - __off
);
289 return pos_type(__p
);
292 strstreambuf::pos_type
293 strstreambuf::seekpos(pos_type __sp
, ios_base::openmode __which
)
296 bool pos_in
= (__which
& ios::in
) != 0;
297 bool pos_out
= (__which
& ios::out
) != 0;
298 if (pos_in
|| pos_out
)
300 if (!((pos_in
&& gptr() == nullptr) || (pos_out
&& pptr() == nullptr)))
302 off_type newoff
= __sp
;
303 char* seekhigh
= epptr() ? epptr() : egptr();
304 if (0 <= newoff
&& newoff
<= seekhigh
- eback())
306 char* newpos
= eback() + newoff
;
308 setg(eback(), newpos
, _VSTD::max(newpos
, egptr()));
311 // min(pbase, newpos), newpos, epptr()
312 off_type temp
= epptr() - newpos
;
313 setp(min(pbase(), newpos
), epptr());
314 __pbump((epptr() - pbase()) - temp
);
320 return pos_type(__p
);
323 istrstream::~istrstream()
327 ostrstream::~ostrstream()
331 strstream::~strstream()
335 _LIBCPP_END_NAMESPACE_STD