Add C++ runtime libraries for gcc3
[dragonfly.git] / gnu / lib / gcc3 / libstdc++ / strstream-fixed.cc
1 // strstream definitions -*- C++ -*-
2 // $DragonFly: src/gnu/lib/gcc3/libstdc++/Attic/strstream-fixed.cc,v 1.1 2004/01/22 21:45:57 joerg Exp $
3
4 // Copyright (C) 2001, 2002, 2003 Free Software Foundation
5 //
6 // This file is part of the GNU ISO C++ Library.  This library is free
7 // software; you can redistribute it and/or modify it under the
8 // terms of the GNU General Public License as published by the
9 // Free Software Foundation; either version 2, or (at your option)
10 // any later version.
11
12 // This library 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 along
18 // with this library; see the file COPYING.  If not, write to the Free
19 // Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
20 // USA.
21
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.
30
31 /*
32  * Copyright (c) 1998
33  * Silicon Graphics Computer Systems, Inc.
34  *
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.
42  */
43
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.
49
50 #include <backward/strstream>
51 #include <algorithm>
52 #include <new>
53 #include <stdlib.h>
54 #include <string.h>
55 #include <limits.h>
56
57 namespace std
58 {
59   strstreambuf::strstreambuf(streamsize initial_capacity)
60   : _Base(), _M_alloc_fun(0), _M_free_fun(0), _M_dynamic(true), 
61     _M_frozen(false), _M_constant(false)
62   {
63     streamsize n = max(initial_capacity, streamsize(16));
64     
65     char* buf = _M_alloc(n);
66     if (buf) 
67       {
68         setp(buf, buf + n);
69         setg(buf, buf, buf);
70       }
71   }
72
73   strstreambuf::strstreambuf(void* (*alloc_f)(size_t), void (*free_f)(void*))
74   : _Base(), _M_alloc_fun(alloc_f), _M_free_fun(free_f), _M_dynamic(true), 
75     _M_frozen(false), _M_constant(false)
76   {
77     streamsize n = 16;
78
79     char* buf = _M_alloc(n);
80     if (buf) 
81       {
82         setp(buf, buf + n);
83         setg(buf, buf, buf);
84       }
85   }
86
87   strstreambuf::strstreambuf(char* get, streamsize n, char* put)
88   : _Base(), _M_alloc_fun(0), _M_free_fun(0), _M_dynamic(false), 
89     _M_frozen(false), _M_constant(false)
90   { _M_setup(get, put, n); }
91
92   strstreambuf::strstreambuf(signed char* get, streamsize n, signed char* put)
93   : _Base(), _M_alloc_fun(0), _M_free_fun(0), _M_dynamic(false), 
94   _M_frozen(false), _M_constant(false)
95   { _M_setup(reinterpret_cast<char*>(get), reinterpret_cast<char*>(put), n); }
96
97   strstreambuf::strstreambuf(unsigned char* get, streamsize n, 
98                              unsigned char* put)
99   : _Base(), _M_alloc_fun(0), _M_free_fun(0), _M_dynamic(false), 
100     _M_frozen(false), _M_constant(false)
101   { _M_setup(reinterpret_cast<char*>(get), reinterpret_cast<char*>(put), n); }
102
103   strstreambuf::strstreambuf(const char* get, streamsize n)
104   : _Base(), _M_alloc_fun(0), _M_free_fun(0), _M_dynamic(false), 
105     _M_frozen(false), _M_constant(true)
106   { _M_setup(const_cast<char*>(get), 0, n); }
107
108   strstreambuf::strstreambuf(const signed char* get, streamsize n)
109   : _Base(), _M_alloc_fun(0), _M_free_fun(0), _M_dynamic(false), 
110     _M_frozen(false), _M_constant(true)
111   { _M_setup(reinterpret_cast<char*>(const_cast<signed char*>(get)), 0, n); }
112
113   strstreambuf::strstreambuf(const unsigned char* get, streamsize n)
114   : _Base(), _M_alloc_fun(0), _M_free_fun(0), _M_dynamic(false), 
115     _M_frozen(false), _M_constant(true)
116   { _M_setup(reinterpret_cast<char*>(const_cast<unsigned char*>(get)), 0, n); }
117
118   strstreambuf::~strstreambuf()
119   {
120     if (_M_dynamic && !_M_frozen)
121       _M_free(eback());
122   }
123
124   void 
125   strstreambuf::freeze(bool frozenflag)
126   {
127     if (_M_dynamic)
128       _M_frozen = frozenflag;
129   }
130
131   char* 
132   strstreambuf::str()
133   {
134     freeze(true);
135     return eback();
136   }
137
138   int 
139   strstreambuf::pcount() const
140   { return pptr() ? pptr() - pbase() : 0; }
141
142   strstreambuf::int_type 
143   strstreambuf::overflow(int_type c) 
144   {
145     if (c == traits_type::eof())
146       return traits_type::not_eof(c);
147     
148     // Try to expand the buffer.
149     if (pptr() == epptr() && _M_dynamic && !_M_frozen && !_M_constant) 
150       {
151         ptrdiff_t old_size = epptr() - pbase();
152         ptrdiff_t new_size = max(ptrdiff_t(2 * old_size), ptrdiff_t(1));
153         
154         char* buf = _M_alloc(new_size);
155         if (buf) 
156           {
157             memcpy(buf, pbase(), old_size);
158             char* old_buffer = pbase();
159             bool reposition_get = false;
160             ptrdiff_t old_get_offset;
161             if (gptr() != 0) 
162               {
163                 reposition_get = true;
164                 old_get_offset = gptr() - eback();
165               }
166             
167             setp(buf, buf + new_size);
168             pbump(old_size);
169
170             if (reposition_get)
171               setg(buf, buf + old_get_offset, buf + 
172                    max(old_get_offset, old_size));
173
174             _M_free(old_buffer);
175           }
176       }
177     
178     if (pptr() != epptr()) 
179       {
180         *pptr() = c;
181         pbump(1);
182         return c;
183       }
184     else
185       return traits_type::eof();
186   }
187
188   strstreambuf::int_type 
189   strstreambuf::pbackfail(int_type c)
190   {
191     if (gptr() != eback()) 
192       {
193       if (c == _Traits::eof()) 
194         {
195           gbump(-1);
196           return _Traits::not_eof(c);
197         }
198       else if (c == static_cast<int_type>(gptr()[-1])) 
199         {  // KLUDGE
200           gbump(-1);
201           return c;
202         }
203       else if (!_M_constant) 
204         {
205           gbump(-1);
206           *gptr() = c;
207           return c;
208         }
209     }
210     return _Traits::eof();
211   }
212
213   strstreambuf::int_type 
214   strstreambuf::underflow()
215   {
216     if (gptr() == egptr() && pptr() && pptr() > egptr())
217       setg(eback(), gptr(), pptr());
218     
219     if (gptr() != egptr())
220       return (unsigned char) *gptr();
221     else
222       return _Traits::eof();
223   }
224
225   basic_streambuf<char, char_traits<char> >*
226   strstreambuf::setbuf(char*, streamsize)
227   { return this; }
228
229   strstreambuf::pos_type
230   strstreambuf::seekoff(off_type off, ios_base::seekdir dir, 
231                         ios_base::openmode mode)
232   {
233     bool do_get = false;
234     bool do_put = false;
235
236     if ((mode & (ios_base::in | ios_base::out)) 
237         == (ios_base::in | ios_base::out) &&
238         (dir == ios_base::beg || dir == ios_base::end))
239       do_get = do_put = true;
240     else if (mode & ios_base::in)
241       do_get = true;
242     else if (mode & ios_base::out)
243       do_put = true;
244
245     // !gptr() is here because, according to D.7.1 paragraph 4, the seekable
246     // area is undefined if there is no get area.
247     if ((!do_get && !do_put) || (do_put && !pptr()) || !gptr())
248       return pos_type(off_type(-1));
249
250     char* seeklow  = eback();
251     char* seekhigh = epptr() ? epptr() : egptr();
252
253     off_type newoff;
254     switch (dir) 
255       {
256       case ios_base::beg:
257         newoff = 0;
258         break;
259       case ios_base::end:
260         newoff = seekhigh - seeklow;
261         break;
262       case ios_base::cur:
263         newoff = do_put ? pptr() - seeklow : gptr() - seeklow;
264         break;
265       default:
266         return pos_type(off_type(-1));
267       }
268     
269     off += newoff;
270     if (off < 0 || off > seekhigh - seeklow)
271       return pos_type(off_type(-1));
272
273     if (do_put) 
274       {
275         if (seeklow + off < pbase()) 
276           {
277             setp(seeklow, epptr());
278             pbump(off);
279           }
280         else 
281           {
282             setp(pbase(), epptr());
283             pbump(off - (pbase() - seeklow));
284           }
285       }
286     if (do_get) 
287       {
288         if (off <= egptr() - seeklow)
289           setg(seeklow, seeklow + off, egptr());
290         else if (off <= pptr() - seeklow)
291           setg(seeklow, seeklow + off, pptr());
292         else
293           setg(seeklow, seeklow + off, epptr());
294       }
295     return pos_type(newoff);
296   }
297
298   strstreambuf::pos_type
299   strstreambuf::seekpos(pos_type pos, ios_base::openmode mode)
300   { return seekoff(pos - pos_type(off_type(0)), ios_base::beg, mode); }
301
302   char* 
303   strstreambuf::_M_alloc(size_t n)
304   {
305     if (_M_alloc_fun)
306       return static_cast<char*>(_M_alloc_fun(n));
307     else
308       return new char[n];
309   }
310
311   void 
312   strstreambuf::_M_free(char* p)
313   {
314     if (p)
315       if (_M_free_fun)
316         _M_free_fun(p);
317       else
318         delete[] p;
319   }
320
321   void 
322   strstreambuf::_M_setup(char* get, char* put, streamsize n)
323   {
324     if (get) 
325       {
326         size_t N = n > 0 ? size_t(n) : n == 0 ? strlen(get) : size_t(INT_MAX);
327         
328         if (put) 
329           {
330             setg(get, get, put);
331             setp(put, put + N);
332           }
333         else 
334           setg(get, get, get + N);
335       }
336   }
337
338   istrstream::istrstream(char* s)
339   : basic_ios<char>(), basic_istream<char>(0), _M_buf(s, 0)
340   { basic_ios<char>::init(&_M_buf); }
341
342   istrstream::istrstream(const char* s)
343   : basic_ios<char>(), basic_istream<char>(0), _M_buf(s, 0)
344   { basic_ios<char>::init(&_M_buf); }
345
346   istrstream::istrstream(char* s, streamsize n)
347   : basic_ios<char>(), basic_istream<char>(0), _M_buf(s, n)
348   { basic_ios<char>::init(&_M_buf); }
349
350   istrstream::istrstream(const char* s, streamsize n)
351   : basic_ios<char>(), basic_istream<char>(0), _M_buf(s, n)
352   { basic_ios<char>::init(&_M_buf); }
353
354   istrstream::~istrstream() { }
355
356   strstreambuf* 
357   istrstream::rdbuf() const 
358   { return const_cast<strstreambuf*>(&_M_buf); }
359
360   char* 
361   istrstream::str() 
362   { return _M_buf.str(); }
363
364   ostrstream::ostrstream()
365   : basic_ios<char>(), basic_ostream<char>(0), _M_buf()
366   { basic_ios<char>::init(&_M_buf); }
367
368   ostrstream::ostrstream(char* s, int n, ios_base::openmode mode)
369   : basic_ios<char>(), basic_ostream<char>(0), 
370     _M_buf(s, n, mode & ios_base::app ? s + strlen(s) : s)
371   { basic_ios<char>::init(&_M_buf); }
372
373   ostrstream::~ostrstream() {}
374
375   strstreambuf* 
376   ostrstream::rdbuf() const
377   { return const_cast<strstreambuf*>(&_M_buf); }
378
379   void 
380   ostrstream::freeze(bool freezeflag)
381   { _M_buf.freeze(freezeflag); }
382
383   char* 
384   ostrstream::str()
385   { return _M_buf.str(); }
386
387   int 
388   ostrstream::pcount() const
389   { return _M_buf.pcount(); }
390
391   strstream::strstream()
392   : basic_ios<char>(), basic_iostream<char>(0), _M_buf()
393   { basic_ios<char>::init(&_M_buf); }
394
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)
398   { basic_ios<char>::init(&_M_buf); }
399
400   strstream::~strstream() { }
401
402   strstreambuf* 
403   strstream::rdbuf() const
404   { return const_cast<strstreambuf*>(&_M_buf); }
405
406   void 
407   strstream::freeze(bool freezeflag)
408   { _M_buf.freeze(freezeflag); }
409
410   int 
411   strstream::pcount() const
412   { return _M_buf.pcount(); }
413
414   char* 
415   strstream::str()
416   { return _M_buf.str(); }
417 } // namespace std