source: trunk/gcc/libstdc++-v3/src/strstream.cc

Last change on this file was 1392, checked in by bird, 21 years ago

This commit was generated by cvs2svn to compensate for changes in r1391,
which included commits to RCS files with non-trunk default branches.

  • Property cvs2svn:cvs-rev set to 1.1.1.2
  • Property svn:eol-style set to native
  • Property svn:executable set to *
File size: 10.9 KB
Line 
1// strstream definitions -*- C++ -*-
2
3// Copyright (C) 2001, 2002, 2003 Free Software Foundation
4//
5// This file is part of the GNU ISO C++ Library. This library is free
6// software; you can redistribute it and/or modify it under the
7// terms of the GNU General Public License as published by the
8// Free Software Foundation; either version 2, or (at your option)
9// any later version.
10
11// This library is distributed in the hope that it will be useful,
12// but WITHOUT ANY WARRANTY; without even the implied warranty of
13// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14// GNU General Public License for more details.
15
16// You should have received a copy of the GNU General Public License along
17// with this library; see the file COPYING. If not, write to the Free
18// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
19// USA.
20
21// As a special exception, you may use this file as part of a free software
22// library without restriction. Specifically, if other files instantiate
23// templates or use macros or inline functions from this file, or you compile
24// this file and link it with other files to produce an executable, this
25// file does not by itself cause the resulting executable to be covered by
26// the GNU General Public License. This exception does not however
27// invalidate any other reasons why the executable file might be covered by
28// the GNU General Public License.
29
30/*
31 * Copyright (c) 1998
32 * Silicon Graphics Computer Systems, Inc.
33 *
34 * Permission to use, copy, modify, distribute and sell this software
35 * and its documentation for any purpose is hereby granted without fee,
36 * provided that the above copyright notice appear in all copies and
37 * that both that copyright notice and this permission notice appear
38 * in supporting documentation. Silicon Graphics makes no
39 * representations about the suitability of this software for any
40 * purpose. It is provided "as is" without express or implied warranty.
41 */
42
43// Implementation of the classes in header <strstream>.
44// WARNING: The classes defined in <strstream> are DEPRECATED. This
45// header is defined in section D.7.1 of the C++ standard, and it
46// MAY BE REMOVED in a future standard revision. You should use the
47// header <sstream> instead.
48
49#include <strstream>
50#include <algorithm>
51#include <new>
52#include <stdlib.h>
53#include <string.h>
54#include <limits.h>
55
56namespace std
57{
58 strstreambuf::strstreambuf(streamsize initial_capacity)
59 : _Base(), _M_alloc_fun(0), _M_free_fun(0), _M_dynamic(true),
60 _M_frozen(false), _M_constant(false)
61 {
62 streamsize n = max(initial_capacity, streamsize(16));
63
64 char* buf = _M_alloc(n);
65 if (buf)
66 {
67 setp(buf, buf + n);
68 setg(buf, buf, buf);
69 }
70 }
71
72 strstreambuf::strstreambuf(void* (*alloc_f)(size_t), void (*free_f)(void*))
73 : _Base(), _M_alloc_fun(alloc_f), _M_free_fun(free_f), _M_dynamic(true),
74 _M_frozen(false), _M_constant(false)
75 {
76 streamsize n = 16;
77
78 char* buf = _M_alloc(n);
79 if (buf)
80 {
81 setp(buf, buf + n);
82 setg(buf, buf, buf);
83 }
84 }
85
86 strstreambuf::strstreambuf(char* get, streamsize n, char* put)
87 : _Base(), _M_alloc_fun(0), _M_free_fun(0), _M_dynamic(false),
88 _M_frozen(false), _M_constant(false)
89 { _M_setup(get, put, n); }
90
91 strstreambuf::strstreambuf(signed char* get, streamsize n, signed char* put)
92 : _Base(), _M_alloc_fun(0), _M_free_fun(0), _M_dynamic(false),
93 _M_frozen(false), _M_constant(false)
94 { _M_setup(reinterpret_cast<char*>(get), reinterpret_cast<char*>(put), n); }
95
96 strstreambuf::strstreambuf(unsigned char* get, streamsize n,
97 unsigned char* put)
98 : _Base(), _M_alloc_fun(0), _M_free_fun(0), _M_dynamic(false),
99 _M_frozen(false), _M_constant(false)
100 { _M_setup(reinterpret_cast<char*>(get), reinterpret_cast<char*>(put), n); }
101
102 strstreambuf::strstreambuf(const char* get, streamsize n)
103 : _Base(), _M_alloc_fun(0), _M_free_fun(0), _M_dynamic(false),
104 _M_frozen(false), _M_constant(true)
105 { _M_setup(const_cast<char*>(get), 0, n); }
106
107 strstreambuf::strstreambuf(const signed char* get, streamsize n)
108 : _Base(), _M_alloc_fun(0), _M_free_fun(0), _M_dynamic(false),
109 _M_frozen(false), _M_constant(true)
110 { _M_setup(reinterpret_cast<char*>(const_cast<signed char*>(get)), 0, n); }
111
112 strstreambuf::strstreambuf(const unsigned char* get, streamsize n)
113 : _Base(), _M_alloc_fun(0), _M_free_fun(0), _M_dynamic(false),
114 _M_frozen(false), _M_constant(true)
115 { _M_setup(reinterpret_cast<char*>(const_cast<unsigned char*>(get)), 0, n); }
116
117 strstreambuf::~strstreambuf()
118 {
119 if (_M_dynamic && !_M_frozen)
120 _M_free(eback());
121 }
122
123 void
124 strstreambuf::freeze(bool frozenflag)
125 {
126 if (_M_dynamic)
127 _M_frozen = frozenflag;
128 }
129
130 char*
131 strstreambuf::str()
132 {
133 freeze(true);
134 return eback();
135 }
136
137 int
138 strstreambuf::pcount() const
139 { return pptr() ? pptr() - pbase() : 0; }
140
141 strstreambuf::int_type
142 strstreambuf::overflow(int_type c)
143 {
144 if (c == traits_type::eof())
145 return traits_type::not_eof(c);
146
147 // Try to expand the buffer.
148 if (pptr() == epptr() && _M_dynamic && !_M_frozen && !_M_constant)
149 {
150 ptrdiff_t old_size = epptr() - pbase();
151 ptrdiff_t new_size = max(ptrdiff_t(2 * old_size), ptrdiff_t(1));
152
153 char* buf = _M_alloc(new_size);
154 if (buf)
155 {
156 memcpy(buf, pbase(), old_size);
157 char* old_buffer = pbase();
158 bool reposition_get = false;
159 ptrdiff_t old_get_offset;
160 if (gptr() != 0)
161 {
162 reposition_get = true;
163 old_get_offset = gptr() - eback();
164 }
165
166 setp(buf, buf + new_size);
167 pbump(old_size);
168
169 if (reposition_get)
170 setg(buf, buf + old_get_offset, buf +
171 max(old_get_offset, old_size));
172
173 _M_free(old_buffer);
174 }
175 }
176
177 if (pptr() != epptr())
178 {
179 *pptr() = c;
180 pbump(1);
181 return c;
182 }
183 else
184 return traits_type::eof();
185 }
186
187 strstreambuf::int_type
188 strstreambuf::pbackfail(int_type c)
189 {
190 if (gptr() != eback())
191 {
192 if (c == _Traits::eof())
193 {
194 gbump(-1);
195 return _Traits::not_eof(c);
196 }
197 else if (c == static_cast<int_type>(gptr()[-1]))
198 { // KLUDGE
199 gbump(-1);
200 return c;
201 }
202 else if (!_M_constant)
203 {
204 gbump(-1);
205 *gptr() = c;
206 return c;
207 }
208 }
209 return _Traits::eof();
210 }
211
212 strstreambuf::int_type
213 strstreambuf::underflow()
214 {
215 if (gptr() == egptr() && pptr() && pptr() > egptr())
216 setg(eback(), gptr(), pptr());
217
218 if (gptr() != egptr())
219 return (unsigned char) *gptr();
220 else
221 return _Traits::eof();
222 }
223
224 basic_streambuf<char, char_traits<char> >*
225 strstreambuf::setbuf(char*, streamsize)
226 { return this; }
227
228 strstreambuf::pos_type
229 strstreambuf::seekoff(off_type off, ios_base::seekdir dir,
230 ios_base::openmode mode)
231 {
232 bool do_get = false;
233 bool do_put = false;
234
235 if ((mode & (ios_base::in | ios_base::out))
236 == (ios_base::in | ios_base::out) &&
237 (dir == ios_base::beg || dir == ios_base::end))
238 do_get = do_put = true;
239 else if (mode & ios_base::in)
240 do_get = true;
241 else if (mode & ios_base::out)
242 do_put = true;
243
244 // !gptr() is here because, according to D.7.1 paragraph 4, the seekable
245 // area is undefined if there is no get area.
246 if ((!do_get && !do_put) || (do_put && !pptr()) || !gptr())
247 return pos_type(off_type(-1));
248
249 char* seeklow = eback();
250 char* seekhigh = epptr() ? epptr() : egptr();
251
252 off_type newoff;
253 switch (dir)
254 {
255 case ios_base::beg:
256 newoff = 0;
257 break;
258 case ios_base::end:
259 newoff = seekhigh - seeklow;
260 break;
261 case ios_base::cur:
262 newoff = do_put ? pptr() - seeklow : gptr() - seeklow;
263 break;
264 default:
265 return pos_type(off_type(-1));
266 }
267
268 off += newoff;
269 if (off < 0 || off > seekhigh - seeklow)
270 return pos_type(off_type(-1));
271
272 if (do_put)
273 {
274 if (seeklow + off < pbase())
275 {
276 setp(seeklow, epptr());
277 pbump(off);
278 }
279 else
280 {
281 setp(pbase(), epptr());
282 pbump(off - (pbase() - seeklow));
283 }
284 }
285 if (do_get)
286 {
287 if (off <= egptr() - seeklow)
288 setg(seeklow, seeklow + off, egptr());
289 else if (off <= pptr() - seeklow)
290 setg(seeklow, seeklow + off, pptr());
291 else
292 setg(seeklow, seeklow + off, epptr());
293 }
294 return pos_type(newoff);
295 }
296
297 strstreambuf::pos_type
298 strstreambuf::seekpos(pos_type pos, ios_base::openmode mode)
299 { return seekoff(pos - pos_type(off_type(0)), ios_base::beg, mode); }
300
301 char*
302 strstreambuf::_M_alloc(size_t n)
303 {
304 if (_M_alloc_fun)
305 return static_cast<char*>(_M_alloc_fun(n));
306 else
307 return new char[n];
308 }
309
310 void
311 strstreambuf::_M_free(char* p)
312 {
313 if (p)
314 if (_M_free_fun)
315 _M_free_fun(p);
316 else
317 delete[] p;
318 }
319
320 void
321 strstreambuf::_M_setup(char* get, char* put, streamsize n)
322 {
323 if (get)
324 {
325 size_t N = n > 0 ? size_t(n) : n == 0 ? strlen(get) : size_t(INT_MAX);
326
327 if (put)
328 {
329 setg(get, get, put);
330 setp(put, put + N);
331 }
332 else
333 setg(get, get, get + N);
334 }
335 }
336
337 istrstream::istrstream(char* s)
338 : basic_ios<char>(), basic_istream<char>(0), _M_buf(s, 0)
339 { basic_ios<char>::init(&_M_buf); }
340
341 istrstream::istrstream(const char* s)
342 : basic_ios<char>(), basic_istream<char>(0), _M_buf(s, 0)
343 { basic_ios<char>::init(&_M_buf); }
344
345 istrstream::istrstream(char* s, streamsize n)
346 : basic_ios<char>(), basic_istream<char>(0), _M_buf(s, n)
347 { basic_ios<char>::init(&_M_buf); }
348
349 istrstream::istrstream(const char* s, streamsize n)
350 : basic_ios<char>(), basic_istream<char>(0), _M_buf(s, n)
351 { basic_ios<char>::init(&_M_buf); }
352
353 istrstream::~istrstream() { }
354
355 strstreambuf*
356 istrstream::rdbuf() const
357 { return const_cast<strstreambuf*>(&_M_buf); }
358
359 char*
360 istrstream::str()
361 { return _M_buf.str(); }
362
363 ostrstream::ostrstream()
364 : basic_ios<char>(), basic_ostream<char>(0), _M_buf()
365 { basic_ios<char>::init(&_M_buf); }
366
367 ostrstream::ostrstream(char* s, int n, ios_base::openmode mode)
368 : basic_ios<char>(), basic_ostream<char>(0),
369 _M_buf(s, n, mode & ios_base::app ? s + strlen(s) : s)
370 { basic_ios<char>::init(&_M_buf); }
371
372 ostrstream::~ostrstream() {}
373
374 strstreambuf*
375 ostrstream::rdbuf() const
376 { return const_cast<strstreambuf*>(&_M_buf); }
377
378 void
379 ostrstream::freeze(bool freezeflag)
380 { _M_buf.freeze(freezeflag); }
381
382 char*
383 ostrstream::str()
384 { return _M_buf.str(); }
385
386 int
387 ostrstream::pcount() const
388 { return _M_buf.pcount(); }
389
390 strstream::strstream()
391 : basic_ios<char>(), basic_iostream<char>(0), _M_buf()
392 { basic_ios<char>::init(&_M_buf); }
393
394 strstream::strstream(char* s, int n, ios_base::openmode mode)
395 : basic_ios<char>(), basic_iostream<char>(0),
396 _M_buf(s, n, mode & ios_base::app ? s + strlen(s) : s)
397 { basic_ios<char>::init(&_M_buf); }
398
399 strstream::~strstream() { }
400
401 strstreambuf*
402 strstream::rdbuf() const
403 { return const_cast<strstreambuf*>(&_M_buf); }
404
405 void
406 strstream::freeze(bool freezeflag)
407 { _M_buf.freeze(freezeflag); }
408
409 int
410 strstream::pcount() const
411 { return _M_buf.pcount(); }
412
413 char*
414 strstream::str()
415 { return _M_buf.str(); }
416} // namespace std
Note: See TracBrowser for help on using the repository browser.