1 //===------------------------ strstream.cpp -------------------------------===//
3 // The LLVM Compiler Infrastructure
5 // This file is dual licensed under the MIT and the University of Illinois Open
6 // Source Licenses. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
15 _LIBCPP_BEGIN_NAMESPACE_STD
17 strstreambuf::strstreambuf(streamsize __alsize
)
18 : __strmode_(__dynamic
),
25 strstreambuf::strstreambuf(void* (*__palloc
)(size_t), void (*__pfree
)(void*))
26 : __strmode_(__dynamic
),
27 __alsize_(__default_alsize
),
34 strstreambuf::__init(char* __gnext
, streamsize __n
, char* __pbeg
)
37 __n
= static_cast<streamsize
>(strlen(__gnext
));
40 if (__pbeg
== nullptr)
41 setg(__gnext
, __gnext
, __gnext
+ __n
);
44 setg(__gnext
, __gnext
, __pbeg
);
45 setp(__pbeg
, __pbeg
+ __n
);
49 strstreambuf::strstreambuf(char* __gnext
, streamsize __n
, char* __pbeg
)
51 __alsize_(__default_alsize
),
55 __init(__gnext
, __n
, __pbeg
);
58 strstreambuf::strstreambuf(const char* __gnext
, streamsize __n
)
59 : __strmode_(__constant
),
60 __alsize_(__default_alsize
),
64 __init(const_cast<char *>(__gnext
), __n
, nullptr);
67 strstreambuf::strstreambuf(signed char* __gnext
, streamsize __n
, signed char* __pbeg
)
69 __alsize_(__default_alsize
),
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
),
82 __init(const_cast<char *>(reinterpret_cast<const char*>(__gnext
)), __n
, nullptr);
85 strstreambuf::strstreambuf(unsigned char* __gnext
, streamsize __n
, unsigned char* __pbeg
)
87 __alsize_(__default_alsize
),
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
),
100 __init(const_cast<char *>(reinterpret_cast<const char*>(__gnext
)), __n
, nullptr);
103 strstreambuf::~strstreambuf()
105 if (eback() && (__strmode_
& __allocated
) != 0 && (__strmode_
& __frozen
) == 0)
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_
);
125 strstreambuf::freeze(bool __freezefl
)
127 if (__strmode_
& __dynamic
)
130 __strmode_
|= __frozen
;
132 __strmode_
&= ~__frozen
;
139 if (__strmode_
& __dynamic
)
140 __strmode_
|= __frozen
;
145 strstreambuf::pcount() const
147 return static_cast<int>(pptr() - pbase());
150 strstreambuf::int_type
151 strstreambuf::overflow(int_type __c
)
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
);
162 new_size
= __default_alsize
;
165 buf
= static_cast<char*>(__palloc_(new_size
));
167 buf
= new char[new_size
];
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
)
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
);
189 return int_type(static_cast<unsigned char>(__c
));
192 strstreambuf::int_type
193 strstreambuf::pbackfail(int_type __c
)
195 if (eback() == gptr())
202 if (__strmode_
& __constant
)
204 if (gptr()[-1] == static_cast<char>(__c
))
212 *gptr() = static_cast<char>(__c
);
216 strstreambuf::int_type
217 strstreambuf::underflow()
219 if (gptr() == egptr())
221 if (egptr() >= pptr())
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
)
232 bool pos_in
= (__which
& ios::in
) != 0;
233 bool pos_out
= (__which
& ios::out
) != 0;
239 if (pos_in
|| pos_out
)
243 if (pos_in
!= pos_out
)
247 if (pos_in
&& gptr() == nullptr)
249 if (pos_out
&& pptr() == nullptr)
254 char* seekhigh
= epptr() ? epptr() : egptr();
261 newoff
= (pos_in
? gptr() : pptr()) - eback();
264 newoff
= seekhigh
- eback();
268 if (0 <= newoff
&& newoff
<= seekhigh
- eback())
270 char* newpos
= eback() + newoff
;
272 setg(eback(), newpos
, _VSTD::max(newpos
, egptr()));
275 // min(pbase, newpos), newpos, epptr()
276 __off
= epptr() - newpos
;
277 setp(min(pbase(), newpos
), epptr());
278 pbump(static_cast<int>((epptr() - pbase()) - __off
));
283 return pos_type(__p
);
286 strstreambuf::pos_type
287 strstreambuf::seekpos(pos_type __sp
, ios_base::openmode __which
)
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
;
302 setg(eback(), newpos
, _VSTD::max(newpos
, egptr()));
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
));
314 return pos_type(__p
);
317 istrstream::~istrstream()
321 ostrstream::~ostrstream()
325 strstream::~strstream()
329 _LIBCPP_END_NAMESPACE_STD