]> git.ipfire.org Git - thirdparty/gcc.git/blame - libstdc++-v3/src/strstream.cc
c-tree.texi, [...]: Replace . at end of sentences preceded by a capital letter with @..
[thirdparty/gcc.git] / libstdc++-v3 / src / strstream.cc
CommitLineData
b2dad0e3
BK
1/*
2 * Copyright (c) 1998
3 * Silicon Graphics Computer Systems, Inc.
4 *
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.
12 */
13
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.
19
a40ba78e 20#include <strstream.h>
5feb272b 21#include <algorithm>
b2dad0e3
BK
22#include <new>
23#include <stdlib.h>
24#include <string.h>
25#include <limits.h>
26
d53d7f6e
PE
27namespace std
28{
b2dad0e3
BK
29
30// strstreambuf constructor, destructor.
31
32strstreambuf::strstreambuf(streamsize initial_capacity)
33 : _Base(),
34 _M_alloc_fun(0), _M_free_fun(0),
35 _M_dynamic(true), _M_frozen(false), _M_constant(false)
36{
37 streamsize n = max(initial_capacity, streamsize(16));
38
39 char* buf = _M_alloc(n);
40 if (buf) {
41 setp(buf, buf + n);
42 setg(buf, buf, buf);
43 }
44}
45
46strstreambuf::strstreambuf(void* (*alloc_f)(size_t), void (*free_f)(void*))
47 : _Base(),
48 _M_alloc_fun(alloc_f), _M_free_fun(free_f),
49 _M_dynamic(true), _M_frozen(false), _M_constant(false)
50{
51 streamsize n = 16;
52
53 char* buf = _M_alloc(n);
54 if (buf) {
55 setp(buf, buf + n);
56 setg(buf, buf, buf);
57 }
58}
59
60strstreambuf::strstreambuf(char* get, streamsize n, char* put)
61 : _Base(),
62 _M_alloc_fun(0), _M_free_fun(0),
63 _M_dynamic(false), _M_frozen(false), _M_constant(false)
64{
65 _M_setup(get, put, n);
66}
67
68strstreambuf::strstreambuf(signed char* get, streamsize n, signed char* put)
69 : _Base(),
70 _M_alloc_fun(0), _M_free_fun(0),
71 _M_dynamic(false), _M_frozen(false), _M_constant(false)
72{
73 _M_setup(reinterpret_cast<char*>(get), reinterpret_cast<char*>(put), n);
74}
75
76strstreambuf::strstreambuf(unsigned char* get, streamsize n,
77 unsigned char* put)
78 : _Base(),
79 _M_alloc_fun(0), _M_free_fun(0),
80 _M_dynamic(false), _M_frozen(false), _M_constant(false)
81{
82 _M_setup(reinterpret_cast<char*>(get), reinterpret_cast<char*>(put), n);
83}
84
85strstreambuf::strstreambuf(const char* get, streamsize n)
86 : _Base(),
87 _M_alloc_fun(0), _M_free_fun(0),
88 _M_dynamic(false), _M_frozen(false), _M_constant(true)
89{
90 _M_setup(const_cast<char*>(get), 0, n);
91}
92
93strstreambuf::strstreambuf(const signed char* get, streamsize n)
94 : _Base(),
95 _M_alloc_fun(0), _M_free_fun(0),
96 _M_dynamic(false), _M_frozen(false), _M_constant(true)
97{
98 _M_setup(reinterpret_cast<char*>(const_cast<signed char*>(get)), 0, n);
99}
100
101strstreambuf::strstreambuf(const unsigned char* get, streamsize n)
102 : _Base(),
103 _M_alloc_fun(0), _M_free_fun(0),
104 _M_dynamic(false), _M_frozen(false), _M_constant(true)
105{
106 _M_setup(reinterpret_cast<char*>(const_cast<unsigned char*>(get)), 0, n);
107}
108
109strstreambuf::~strstreambuf()
110{
111 if (_M_dynamic && !_M_frozen)
112 _M_free(eback());
113}
114
115void strstreambuf::freeze(bool frozenflag)
116{
117 if (_M_dynamic)
118 _M_frozen = frozenflag;
119}
120
121char* strstreambuf::str()
122{
123 freeze(true);
124 return eback();
125}
126
127int strstreambuf::pcount() const
128{
129 return pptr() ? pptr() - pbase() : 0;
130}
131
132strstreambuf::int_type strstreambuf::overflow(int_type c) {
133 if (c == traits_type::eof())
134 return traits_type::not_eof(c);
135
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));
140
141 char* buf = _M_alloc(new_size);
142 if (buf) {
143 memcpy(buf, pbase(), old_size);
144
145 char* old_buffer = pbase();
146 bool reposition_get = false;
147 ptrdiff_t old_get_offset;
148 if (gptr() != 0) {
149 reposition_get = true;
150 old_get_offset = gptr() - eback();
151 }
152
153 setp(buf, buf + new_size);
154 pbump(old_size);
155
156 if (reposition_get)
157 setg(buf, buf + old_get_offset, buf + max(old_get_offset, old_size));
158
159 _M_free(old_buffer);
160 }
161 }
162
163 if (pptr() != epptr()) {
164 *pptr() = c;
165 pbump(1);
166 return c;
167 }
168 else
169 return traits_type::eof();
170}
171
172strstreambuf::int_type strstreambuf::pbackfail(int_type c)
173{
174 if (gptr() != eback()) {
175 if (c == _Traits::eof()) {
176 gbump(-1);
177 return _Traits::not_eof(c);
178 }
758c46c9 179 else if (c == static_cast<int_type>(gptr()[-1])) { // KLUDGE
b2dad0e3
BK
180 gbump(-1);
181 return c;
182 }
183 else if (!_M_constant) {
184 gbump(-1);
185 *gptr() = c;
186 return c;
187 }
188 }
189
190 return _Traits::eof();
191}
192
193strstreambuf::int_type strstreambuf::underflow()
194{
195 if (gptr() == egptr() && pptr() && pptr() > egptr())
196 setg(eback(), gptr(), pptr());
197
198 if (gptr() != egptr())
199 return (unsigned char) *gptr();
200 else
201 return _Traits::eof();
202}
203
204basic_streambuf<char, char_traits<char> >*
205strstreambuf::setbuf(char*, streamsize)
206{
207 return this;
208}
209
210strstreambuf::pos_type
211strstreambuf::seekoff(off_type off,
212 ios_base::seekdir dir, ios_base::openmode mode)
213{
214 bool do_get = false;
215 bool do_put = false;
216
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)
222 do_get = true;
223 else if (mode & ios_base::out)
224 do_put = true;
225
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));
230
231 char* seeklow = eback();
232 char* seekhigh = epptr() ? epptr() : egptr();
233
234 off_type newoff;
235 switch(dir) {
236 case ios_base::beg:
237 newoff = 0;
238 break;
239 case ios_base::end:
240 newoff = seekhigh - seeklow;
241 break;
242 case ios_base::cur:
243 newoff = do_put ? pptr() - seeklow : gptr() - seeklow;
244 break;
245 default:
246 return pos_type(off_type(-1));
247 }
248
249 off += newoff;
250 if (off < 0 || off > seekhigh - seeklow)
251 return pos_type(off_type(-1));
252
253 if (do_put) {
254 if (seeklow + off < pbase()) {
255 setp(seeklow, epptr());
256 pbump(off);
257 }
258 else {
259 setp(pbase(), epptr());
260 pbump(off - (pbase() - seeklow));
261 }
262 }
263 if (do_get) {
264 if (off <= egptr() - seeklow)
265 setg(seeklow, seeklow + off, egptr());
266 else if (off <= pptr() - seeklow)
267 setg(seeklow, seeklow + off, pptr());
268 else
269 setg(seeklow, seeklow + off, epptr());
270 }
271
272 return pos_type(newoff);
273}
274
275strstreambuf::pos_type
276strstreambuf::seekpos(pos_type pos, ios_base::openmode mode)
277{
278 return seekoff(pos - pos_type(off_type(0)), ios_base::beg, mode);
279}
280
281char* strstreambuf::_M_alloc(size_t n)
282{
283 if (_M_alloc_fun)
284 return static_cast<char*>(_M_alloc_fun(n));
285 else
286 return new char[n];
287}
288
289void strstreambuf::_M_free(char* p)
290{
291 if (p)
292 if (_M_free_fun)
293 _M_free_fun(p);
294 else
295 delete[] p;
296}
297
298void strstreambuf::_M_setup(char* get, char* put, streamsize n)
299{
300 if (get) {
301 size_t N = n > 0 ? size_t(n) : n == 0 ? strlen(get) : size_t(INT_MAX);
302
303 if (put) {
304 setg(get, get, put);
305 setp(put, put + N);
306 }
307 else {
308 setg(get, get, get + N);
309 }
310 }
311}
312
313//----------------------------------------------------------------------
314// Class istrstream
315
316istrstream::istrstream(char* s)
317 : basic_ios<char>(), basic_istream<char>(0), _M_buf(s, 0)
318{
319 basic_ios<char>::init(&_M_buf);
320}
321
322istrstream::istrstream(const char* s)
323 : basic_ios<char>(), basic_istream<char>(0), _M_buf(s, 0)
324{
325 basic_ios<char>::init(&_M_buf);
326}
327
328istrstream::istrstream(char* s, streamsize n)
329 : basic_ios<char>(), basic_istream<char>(0), _M_buf(s, n)
330{
331 basic_ios<char>::init(&_M_buf);
332}
333
334istrstream::istrstream(const char* s, streamsize n)
335 : basic_ios<char>(), basic_istream<char>(0), _M_buf(s, n)
336{
337 basic_ios<char>::init(&_M_buf);
338}
339
340istrstream::~istrstream() {}
341
342strstreambuf* istrstream::rdbuf() const {
343 return const_cast<strstreambuf*>(&_M_buf);
344}
345
346char* istrstream::str() { return _M_buf.str(); }
347
348//----------------------------------------------------------------------
349// Class ostrstream
350
351ostrstream::ostrstream()
352 : basic_ios<char>(), basic_ostream<char>(0), _M_buf()
353{
354 basic_ios<char>::init(&_M_buf);
355}
356
357ostrstream::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)
360{
361 basic_ios<char>::init(&_M_buf);
362}
363
364ostrstream::~ostrstream() {}
365
366strstreambuf* ostrstream::rdbuf() const
367{
368 return const_cast<strstreambuf*>(&_M_buf);
369}
370
371void ostrstream::freeze(bool freezeflag)
372{
373 _M_buf.freeze(freezeflag);
374}
375
376char* ostrstream::str()
377{
378 return _M_buf.str();
379}
380
381int ostrstream::pcount() const
382{
383 return _M_buf.pcount();
384}
385
386//----------------------------------------------------------------------
387// Class strstream
388
389strstream::strstream()
390 : basic_ios<char>(), basic_iostream<char>(0), _M_buf()
391{
392 basic_ios<char>::init(&_M_buf);
393}
394
395strstream::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)
398{
399 basic_ios<char>::init(&_M_buf);
400}
401
402strstream::~strstream() {}
403
404strstreambuf* strstream::rdbuf() const
405{
406 return const_cast<strstreambuf*>(&_M_buf);
407}
408
409void strstream::freeze(bool freezeflag)
410{
411 _M_buf.freeze(freezeflag);
412}
413
414int strstream::pcount() const
415{
416 return _M_buf.pcount();
417}
418
419char* strstream::str()
420{
421 return _M_buf.str();
422}
423
d53d7f6e 424} // namespace std
b2dad0e3
BK
425
426// Local Variables:
427// mode:C++
428// End: