OSDN Git Service

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