3 * Silicon Graphics Computer Systems, Inc.
5 * Permission to use, copy, modify, distribute and sell this software
6 * and its documentation for any purpose is hereby granted without fee,
7 * provided that the above copyright notice appear in all copies and
8 * that both that copyright notice and this permission notice appear
9 * in supporting documentation. Silicon Graphics makes no
10 * representations about the suitability of this software for any
11 * purpose. It is provided "as is" without express or implied warranty.
14 // Implementation of the classes in header <strstream>.
15 // WARNING: The classes defined in <strstream> are DEPRECATED. This
16 // header is defined in section D.7.1 of the C++ standard, and it
17 // MAY BE REMOVED in a future standard revision. You should use the
18 // header <sstream> instead.
20 #include <strstream.h>
30 // strstreambuf constructor, destructor.
32 strstreambuf::strstreambuf(streamsize initial_capacity)
34 _M_alloc_fun(0), _M_free_fun(0),
35 _M_dynamic(true), _M_frozen(false), _M_constant(false)
37 streamsize n = max(initial_capacity, streamsize(16));
39 char* buf = _M_alloc(n);
46 strstreambuf::strstreambuf(void* (*alloc_f)(size_t), void (*free_f)(void*))
48 _M_alloc_fun(alloc_f), _M_free_fun(free_f),
49 _M_dynamic(true), _M_frozen(false), _M_constant(false)
53 char* buf = _M_alloc(n);
60 strstreambuf::strstreambuf(char* get, streamsize n, char* put)
62 _M_alloc_fun(0), _M_free_fun(0),
63 _M_dynamic(false), _M_frozen(false), _M_constant(false)
65 _M_setup(get, put, n);
68 strstreambuf::strstreambuf(signed char* get, streamsize n, signed char* put)
70 _M_alloc_fun(0), _M_free_fun(0),
71 _M_dynamic(false), _M_frozen(false), _M_constant(false)
73 _M_setup(reinterpret_cast<char*>(get), reinterpret_cast<char*>(put), n);
76 strstreambuf::strstreambuf(unsigned char* get, streamsize n,
79 _M_alloc_fun(0), _M_free_fun(0),
80 _M_dynamic(false), _M_frozen(false), _M_constant(false)
82 _M_setup(reinterpret_cast<char*>(get), reinterpret_cast<char*>(put), n);
85 strstreambuf::strstreambuf(const char* get, streamsize n)
87 _M_alloc_fun(0), _M_free_fun(0),
88 _M_dynamic(false), _M_frozen(false), _M_constant(true)
90 _M_setup(const_cast<char*>(get), 0, n);
93 strstreambuf::strstreambuf(const signed char* get, streamsize n)
95 _M_alloc_fun(0), _M_free_fun(0),
96 _M_dynamic(false), _M_frozen(false), _M_constant(true)
98 _M_setup(reinterpret_cast<char*>(const_cast<signed char*>(get)), 0, n);
101 strstreambuf::strstreambuf(const unsigned char* get, streamsize n)
103 _M_alloc_fun(0), _M_free_fun(0),
104 _M_dynamic(false), _M_frozen(false), _M_constant(true)
106 _M_setup(reinterpret_cast<char*>(const_cast<unsigned char*>(get)), 0, n);
109 strstreambuf::~strstreambuf()
111 if (_M_dynamic && !_M_frozen)
115 void strstreambuf::freeze(bool frozenflag)
118 _M_frozen = frozenflag;
121 char* strstreambuf::str()
127 int strstreambuf::pcount() const
129 return pptr() ? pptr() - pbase() : 0;
132 strstreambuf::int_type strstreambuf::overflow(int_type c) {
133 if (c == traits_type::eof())
134 return traits_type::not_eof(c);
136 // Try to expand the buffer.
137 if (pptr() == epptr() && _M_dynamic && !_M_frozen && !_M_constant) {
138 ptrdiff_t old_size = epptr() - pbase();
139 ptrdiff_t new_size = max(2 * old_size, ptrdiff_t(1));
141 char* buf = _M_alloc(new_size);
143 memcpy(buf, pbase(), old_size);
145 char* old_buffer = pbase();
146 bool reposition_get = false;
147 ptrdiff_t old_get_offset;
149 reposition_get = true;
150 old_get_offset = gptr() - eback();
153 setp(buf, buf + new_size);
157 setg(buf, buf + old_get_offset, buf + max(old_get_offset, old_size));
163 if (pptr() != epptr()) {
169 return traits_type::eof();
172 strstreambuf::int_type strstreambuf::pbackfail(int_type c)
174 if (gptr() != eback()) {
175 if (c == _Traits::eof()) {
177 return _Traits::not_eof(c);
179 else if (c == static_cast<int_type>(gptr()[-1])) { // KLUDGE
183 else if (!_M_constant) {
190 return _Traits::eof();
193 strstreambuf::int_type strstreambuf::underflow()
195 if (gptr() == egptr() && pptr() && pptr() > egptr())
196 setg(eback(), gptr(), pptr());
198 if (gptr() != egptr())
199 return (unsigned char) *gptr();
201 return _Traits::eof();
204 basic_streambuf<char, char_traits<char> >*
205 strstreambuf::setbuf(char*, streamsize)
210 strstreambuf::pos_type
211 strstreambuf::seekoff(off_type off,
212 ios_base::seekdir dir, ios_base::openmode mode)
217 if ((mode & (ios_base::in | ios_base::out)) ==
218 (ios_base::in | ios_base::out) &&
219 (dir == ios_base::beg || dir == ios_base::end))
220 do_get = do_put = true;
221 else if (mode & ios_base::in)
223 else if (mode & ios_base::out)
226 // !gptr() is here because, according to D.7.1 paragraph 4, the seekable
227 // area is undefined if there is no get area.
228 if ((!do_get && !do_put) || (do_put && !pptr()) || !gptr())
229 return pos_type(off_type(-1));
231 char* seeklow = eback();
232 char* seekhigh = epptr() ? epptr() : egptr();
240 newoff = seekhigh - seeklow;
243 newoff = do_put ? pptr() - seeklow : gptr() - seeklow;
246 return pos_type(off_type(-1));
250 if (off < 0 || off > seekhigh - seeklow)
251 return pos_type(off_type(-1));
254 if (seeklow + off < pbase()) {
255 setp(seeklow, epptr());
259 setp(pbase(), epptr());
260 pbump(off - (pbase() - seeklow));
264 if (off <= egptr() - seeklow)
265 setg(seeklow, seeklow + off, egptr());
266 else if (off <= pptr() - seeklow)
267 setg(seeklow, seeklow + off, pptr());
269 setg(seeklow, seeklow + off, epptr());
272 return pos_type(newoff);
275 strstreambuf::pos_type
276 strstreambuf::seekpos(pos_type pos, ios_base::openmode mode)
278 return seekoff(pos - pos_type(off_type(0)), ios_base::beg, mode);
281 char* strstreambuf::_M_alloc(size_t n)
284 return static_cast<char*>(_M_alloc_fun(n));
289 void strstreambuf::_M_free(char* p)
298 void strstreambuf::_M_setup(char* get, char* put, streamsize n)
301 size_t N = n > 0 ? size_t(n) : n == 0 ? strlen(get) : size_t(INT_MAX);
308 setg(get, get, get + N);
313 //----------------------------------------------------------------------
316 istrstream::istrstream(char* s)
317 : basic_ios<char>(), basic_istream<char>(0), _M_buf(s, 0)
319 basic_ios<char>::init(&_M_buf);
322 istrstream::istrstream(const char* s)
323 : basic_ios<char>(), basic_istream<char>(0), _M_buf(s, 0)
325 basic_ios<char>::init(&_M_buf);
328 istrstream::istrstream(char* s, streamsize n)
329 : basic_ios<char>(), basic_istream<char>(0), _M_buf(s, n)
331 basic_ios<char>::init(&_M_buf);
334 istrstream::istrstream(const char* s, streamsize n)
335 : basic_ios<char>(), basic_istream<char>(0), _M_buf(s, n)
337 basic_ios<char>::init(&_M_buf);
340 istrstream::~istrstream() {}
342 strstreambuf* istrstream::rdbuf() const {
343 return const_cast<strstreambuf*>(&_M_buf);
346 char* istrstream::str() { return _M_buf.str(); }
348 //----------------------------------------------------------------------
351 ostrstream::ostrstream()
352 : basic_ios<char>(), basic_ostream<char>(0), _M_buf()
354 basic_ios<char>::init(&_M_buf);
357 ostrstream::ostrstream(char* s, int n, ios_base::openmode mode)
358 : basic_ios<char>(), basic_ostream<char>(0),
359 _M_buf(s, n, mode & ios_base::app ? s + strlen(s) : s)
361 basic_ios<char>::init(&_M_buf);
364 ostrstream::~ostrstream() {}
366 strstreambuf* ostrstream::rdbuf() const
368 return const_cast<strstreambuf*>(&_M_buf);
371 void ostrstream::freeze(bool freezeflag)
373 _M_buf.freeze(freezeflag);
376 char* ostrstream::str()
381 int ostrstream::pcount() const
383 return _M_buf.pcount();
386 //----------------------------------------------------------------------
389 strstream::strstream()
390 : basic_ios<char>(), basic_iostream<char>(0), _M_buf()
392 basic_ios<char>::init(&_M_buf);
395 strstream::strstream(char* s, int n, ios_base::openmode mode)
396 : basic_ios<char>(), basic_iostream<char>(0),
397 _M_buf(s, n, mode & ios_base::app ? s + strlen(s) : s)
399 basic_ios<char>::init(&_M_buf);
402 strstream::~strstream() {}
404 strstreambuf* strstream::rdbuf() const
406 return const_cast<strstreambuf*>(&_M_buf);
409 void strstream::freeze(bool freezeflag)
411 _M_buf.freeze(freezeflag);
414 int strstream::pcount() const
416 return _M_buf.pcount();
419 char* strstream::str()