2001-08-03 Daniel Berlin <dan@cgsoftware.com>
[official-gcc.git] / libstdc++-v3 / src / strstream.cc
blob2160c440be2757c8d176d8858824877834364588
1 // strstream definitions -*- C++ -*-
3 // Copyright (C) 2001 Free Software Foundation
4 //
5 // This file is part of GNU CC.
6 //
7 // GNU CC is free software; you can redistribute it and/or modify
8 // it under the terms of the GNU General Public License as published by
9 // the Free Software Foundation; either version 2, or (at your option)
10 // any later version.
11 //
12 // GNU CC is distributed in the hope that it will be useful,
13 // but WITHOUT ANY WARRANTY; without even the implied warranty of
14 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 // GNU General Public License for more details.
16 //
17 // You should have received a copy of the GNU General Public License
18 // along with GNU CC; see the file COPYING. If not, write to
19 // the Free Software Foundation, 59 Temple Place - Suite 330,
20 // Boston, MA 02111-1307, USA.
22 // As a special exception, you may use this file as part of a free software
23 // library without restriction. Specifically, if other files instantiate
24 // templates or use macros or inline functions from this file, or you compile
25 // this file and link it with other files to produce an executable, this
26 // file does not by itself cause the resulting executable to be covered by
27 // the GNU General Public License. This exception does not however
28 // invalidate any other reasons why the executable file might be covered by
29 // the GNU General Public License.
32 * Copyright (c) 1998
33 * Silicon Graphics Computer Systems, Inc.
35 * Permission to use, copy, modify, distribute and sell this software
36 * and its documentation for any purpose is hereby granted without fee,
37 * provided that the above copyright notice appear in all copies and
38 * that both that copyright notice and this permission notice appear
39 * in supporting documentation. Silicon Graphics makes no
40 * representations about the suitability of this software for any
41 * purpose. It is provided "as is" without express or implied warranty.
44 // Implementation of the classes in header <strstream>.
45 // WARNING: The classes defined in <strstream> are DEPRECATED. This
46 // header is defined in section D.7.1 of the C++ standard, and it
47 // MAY BE REMOVED in a future standard revision. You should use the
48 // header <sstream> instead.
50 #include <strstream.h>
51 #include <algorithm>
52 #include <new>
53 #include <stdlib.h>
54 #include <string.h>
55 #include <limits.h>
57 namespace std
60 // strstreambuf constructor, destructor.
62 strstreambuf::strstreambuf(streamsize initial_capacity)
63 : _Base(),
64 _M_alloc_fun(0), _M_free_fun(0),
65 _M_dynamic(true), _M_frozen(false), _M_constant(false)
67 streamsize n = max(initial_capacity, streamsize(16));
69 char* buf = _M_alloc(n);
70 if (buf) {
71 setp(buf, buf + n);
72 setg(buf, buf, buf);
76 strstreambuf::strstreambuf(void* (*alloc_f)(size_t), void (*free_f)(void*))
77 : _Base(),
78 _M_alloc_fun(alloc_f), _M_free_fun(free_f),
79 _M_dynamic(true), _M_frozen(false), _M_constant(false)
81 streamsize n = 16;
83 char* buf = _M_alloc(n);
84 if (buf) {
85 setp(buf, buf + n);
86 setg(buf, buf, buf);
90 strstreambuf::strstreambuf(char* get, streamsize n, char* put)
91 : _Base(),
92 _M_alloc_fun(0), _M_free_fun(0),
93 _M_dynamic(false), _M_frozen(false), _M_constant(false)
95 _M_setup(get, put, n);
98 strstreambuf::strstreambuf(signed char* get, streamsize n, signed char* put)
99 : _Base(),
100 _M_alloc_fun(0), _M_free_fun(0),
101 _M_dynamic(false), _M_frozen(false), _M_constant(false)
103 _M_setup(reinterpret_cast<char*>(get), reinterpret_cast<char*>(put), n);
106 strstreambuf::strstreambuf(unsigned char* get, streamsize n,
107 unsigned char* put)
108 : _Base(),
109 _M_alloc_fun(0), _M_free_fun(0),
110 _M_dynamic(false), _M_frozen(false), _M_constant(false)
112 _M_setup(reinterpret_cast<char*>(get), reinterpret_cast<char*>(put), n);
115 strstreambuf::strstreambuf(const char* get, streamsize n)
116 : _Base(),
117 _M_alloc_fun(0), _M_free_fun(0),
118 _M_dynamic(false), _M_frozen(false), _M_constant(true)
120 _M_setup(const_cast<char*>(get), 0, n);
123 strstreambuf::strstreambuf(const signed char* get, streamsize n)
124 : _Base(),
125 _M_alloc_fun(0), _M_free_fun(0),
126 _M_dynamic(false), _M_frozen(false), _M_constant(true)
128 _M_setup(reinterpret_cast<char*>(const_cast<signed char*>(get)), 0, n);
131 strstreambuf::strstreambuf(const unsigned char* get, streamsize n)
132 : _Base(),
133 _M_alloc_fun(0), _M_free_fun(0),
134 _M_dynamic(false), _M_frozen(false), _M_constant(true)
136 _M_setup(reinterpret_cast<char*>(const_cast<unsigned char*>(get)), 0, n);
139 strstreambuf::~strstreambuf()
141 if (_M_dynamic && !_M_frozen)
142 _M_free(eback());
145 void strstreambuf::freeze(bool frozenflag)
147 if (_M_dynamic)
148 _M_frozen = frozenflag;
151 char* strstreambuf::str()
153 freeze(true);
154 return eback();
157 int strstreambuf::pcount() const
159 return pptr() ? pptr() - pbase() : 0;
162 strstreambuf::int_type strstreambuf::overflow(int_type c) {
163 if (c == traits_type::eof())
164 return traits_type::not_eof(c);
166 // Try to expand the buffer.
167 if (pptr() == epptr() && _M_dynamic && !_M_frozen && !_M_constant) {
168 ptrdiff_t old_size = epptr() - pbase();
169 ptrdiff_t new_size = max(2 * old_size, ptrdiff_t(1));
171 char* buf = _M_alloc(new_size);
172 if (buf) {
173 memcpy(buf, pbase(), old_size);
175 char* old_buffer = pbase();
176 bool reposition_get = false;
177 ptrdiff_t old_get_offset;
178 if (gptr() != 0) {
179 reposition_get = true;
180 old_get_offset = gptr() - eback();
183 setp(buf, buf + new_size);
184 pbump(old_size);
186 if (reposition_get)
187 setg(buf, buf + old_get_offset, buf + max(old_get_offset, old_size));
189 _M_free(old_buffer);
193 if (pptr() != epptr()) {
194 *pptr() = c;
195 pbump(1);
196 return c;
198 else
199 return traits_type::eof();
202 strstreambuf::int_type strstreambuf::pbackfail(int_type c)
204 if (gptr() != eback()) {
205 if (c == _Traits::eof()) {
206 gbump(-1);
207 return _Traits::not_eof(c);
209 else if (c == static_cast<int_type>(gptr()[-1])) { // KLUDGE
210 gbump(-1);
211 return c;
213 else if (!_M_constant) {
214 gbump(-1);
215 *gptr() = c;
216 return c;
220 return _Traits::eof();
223 strstreambuf::int_type strstreambuf::underflow()
225 if (gptr() == egptr() && pptr() && pptr() > egptr())
226 setg(eback(), gptr(), pptr());
228 if (gptr() != egptr())
229 return (unsigned char) *gptr();
230 else
231 return _Traits::eof();
234 basic_streambuf<char, char_traits<char> >*
235 strstreambuf::setbuf(char*, streamsize)
237 return this;
240 strstreambuf::pos_type
241 strstreambuf::seekoff(off_type off,
242 ios_base::seekdir dir, ios_base::openmode mode)
244 bool do_get = false;
245 bool do_put = false;
247 if ((mode & (ios_base::in | ios_base::out)) ==
248 (ios_base::in | ios_base::out) &&
249 (dir == ios_base::beg || dir == ios_base::end))
250 do_get = do_put = true;
251 else if (mode & ios_base::in)
252 do_get = true;
253 else if (mode & ios_base::out)
254 do_put = true;
256 // !gptr() is here because, according to D.7.1 paragraph 4, the seekable
257 // area is undefined if there is no get area.
258 if ((!do_get && !do_put) || (do_put && !pptr()) || !gptr())
259 return pos_type(off_type(-1));
261 char* seeklow = eback();
262 char* seekhigh = epptr() ? epptr() : egptr();
264 off_type newoff;
265 switch(dir) {
266 case ios_base::beg:
267 newoff = 0;
268 break;
269 case ios_base::end:
270 newoff = seekhigh - seeklow;
271 break;
272 case ios_base::cur:
273 newoff = do_put ? pptr() - seeklow : gptr() - seeklow;
274 break;
275 default:
276 return pos_type(off_type(-1));
279 off += newoff;
280 if (off < 0 || off > seekhigh - seeklow)
281 return pos_type(off_type(-1));
283 if (do_put) {
284 if (seeklow + off < pbase()) {
285 setp(seeklow, epptr());
286 pbump(off);
288 else {
289 setp(pbase(), epptr());
290 pbump(off - (pbase() - seeklow));
293 if (do_get) {
294 if (off <= egptr() - seeklow)
295 setg(seeklow, seeklow + off, egptr());
296 else if (off <= pptr() - seeklow)
297 setg(seeklow, seeklow + off, pptr());
298 else
299 setg(seeklow, seeklow + off, epptr());
302 return pos_type(newoff);
305 strstreambuf::pos_type
306 strstreambuf::seekpos(pos_type pos, ios_base::openmode mode)
308 return seekoff(pos - pos_type(off_type(0)), ios_base::beg, mode);
311 char* strstreambuf::_M_alloc(size_t n)
313 if (_M_alloc_fun)
314 return static_cast<char*>(_M_alloc_fun(n));
315 else
316 return new char[n];
319 void strstreambuf::_M_free(char* p)
321 if (p)
322 if (_M_free_fun)
323 _M_free_fun(p);
324 else
325 delete[] p;
328 void strstreambuf::_M_setup(char* get, char* put, streamsize n)
330 if (get) {
331 size_t N = n > 0 ? size_t(n) : n == 0 ? strlen(get) : size_t(INT_MAX);
333 if (put) {
334 setg(get, get, put);
335 setp(put, put + N);
337 else {
338 setg(get, get, get + N);
343 //----------------------------------------------------------------------
344 // Class istrstream
346 istrstream::istrstream(char* s)
347 : basic_ios<char>(), basic_istream<char>(0), _M_buf(s, 0)
349 basic_ios<char>::init(&_M_buf);
352 istrstream::istrstream(const char* s)
353 : basic_ios<char>(), basic_istream<char>(0), _M_buf(s, 0)
355 basic_ios<char>::init(&_M_buf);
358 istrstream::istrstream(char* s, streamsize n)
359 : basic_ios<char>(), basic_istream<char>(0), _M_buf(s, n)
361 basic_ios<char>::init(&_M_buf);
364 istrstream::istrstream(const char* s, streamsize n)
365 : basic_ios<char>(), basic_istream<char>(0), _M_buf(s, n)
367 basic_ios<char>::init(&_M_buf);
370 istrstream::~istrstream() {}
372 strstreambuf* istrstream::rdbuf() const {
373 return const_cast<strstreambuf*>(&_M_buf);
376 char* istrstream::str() { return _M_buf.str(); }
378 //----------------------------------------------------------------------
379 // Class ostrstream
381 ostrstream::ostrstream()
382 : basic_ios<char>(), basic_ostream<char>(0), _M_buf()
384 basic_ios<char>::init(&_M_buf);
387 ostrstream::ostrstream(char* s, int n, ios_base::openmode mode)
388 : basic_ios<char>(), basic_ostream<char>(0),
389 _M_buf(s, n, mode & ios_base::app ? s + strlen(s) : s)
391 basic_ios<char>::init(&_M_buf);
394 ostrstream::~ostrstream() {}
396 strstreambuf* ostrstream::rdbuf() const
398 return const_cast<strstreambuf*>(&_M_buf);
401 void ostrstream::freeze(bool freezeflag)
403 _M_buf.freeze(freezeflag);
406 char* ostrstream::str()
408 return _M_buf.str();
411 int ostrstream::pcount() const
413 return _M_buf.pcount();
416 //----------------------------------------------------------------------
417 // Class strstream
419 strstream::strstream()
420 : basic_ios<char>(), basic_iostream<char>(0), _M_buf()
422 basic_ios<char>::init(&_M_buf);
425 strstream::strstream(char* s, int n, ios_base::openmode mode)
426 : basic_ios<char>(), basic_iostream<char>(0),
427 _M_buf(s, n, mode & ios_base::app ? s + strlen(s) : s)
429 basic_ios<char>::init(&_M_buf);
432 strstream::~strstream() {}
434 strstreambuf* strstream::rdbuf() const
436 return const_cast<strstreambuf*>(&_M_buf);
439 void strstream::freeze(bool freezeflag)
441 _M_buf.freeze(freezeflag);
444 int strstream::pcount() const
446 return _M_buf.pcount();
449 char* strstream::str()
451 return _M_buf.str();
454 } // namespace std
456 // Local Variables:
457 // mode:C++
458 // End: