More spring-cleaning.
[dragonfly.git] / contrib / libstdc++ / sstream
1 /* This is part of libio/iostream, providing -*- C++ -*- input/output.
2 Copyright (C) 2000 Free Software Foundation
3
4 This file is part of the GNU IO Library.  This library is free
5 software; you can redistribute it and/or modify it under the
6 terms of the GNU General Public License as published by the
7 Free Software Foundation; either version 2, or (at your option)
8 any later version.
9
10 This library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with this library; see the file COPYING.  If not, write to the Free
17 Software Foundation, 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
18
19 As a special exception, if you link this library with files
20 compiled with a GNU compiler to produce an executable, this does not cause
21 the resulting executable to be covered by the GNU General Public License.
22 This exception does not however invalidate any other reasons why
23 the executable file might be covered by the GNU General Public License. */
24
25 /* Written by Magnus Fromreide (magfr@lysator.liu.se). */
26 /* seekoff and ideas for overflow is largely borrowed from libstdc++-v3 */
27
28 #ifndef __SSTREAM__
29 #define __SSTREAM__
30
31 #include <iostream.h>
32 #include <streambuf.h>
33 #include <string>
34
35 namespace std
36 {
37   class stringbuf : public streambuf
38   {
39   public:
40     typedef char        char_type;
41     typedef int         int_type;
42     typedef streampos   pos_type;
43     typedef streamoff   off_type;
44
45     explicit
46     stringbuf(int which=ios::in|ios::out)
47       : streambuf(), mode(static_cast<ios::open_mode>(which)),
48         stream(NULL), stream_len(0)
49     {
50       stringbuf_init();
51     }
52
53     explicit
54     stringbuf(const string &str, int which=ios::in|ios::out)
55       : streambuf(), mode(static_cast<ios::open_mode>(which)),
56         stream(NULL), stream_len(0)
57     {
58       if (mode & (ios::in|ios::out))
59         {
60           stream_len = str.size();
61           stream = new char_type[stream_len];
62           str.copy(stream, stream_len);
63         }
64       stringbuf_init();
65     }
66
67     virtual
68     ~stringbuf()
69     {
70       delete[] stream;
71     }
72
73     string
74     str() const
75     {
76       if (pbase() != 0)
77         return string(stream, pptr()-pbase());
78       else
79         return string();
80     }
81
82     void
83     str(const string& str)
84     {
85       delete[] stream;
86       stream_len = str.size();
87       stream = new char_type[stream_len];
88       str.copy(stream, stream_len);
89       stringbuf_init();
90     }
91
92   protected:
93     // The buffer is already in gptr, so if it ends then it is out of data.
94     virtual int
95     underflow()
96     {
97       return EOF;
98     }
99
100     virtual int
101     overflow(int c = EOF)
102     {
103       int res;
104       if (mode & ios::out)
105         {
106           if (c != EOF)
107             {
108               streamsize old_stream_len = stream_len;
109               stream_len += 1;
110               char_type* new_stream = new char_type[stream_len];
111               memcpy(new_stream, stream, old_stream_len);
112               delete[] stream;
113               stream = new_stream;
114               stringbuf_sync(gptr()-eback(), pptr()-pbase());
115               sputc(c);
116               res = c;
117             }
118           else
119             res = EOF;
120         }
121       else
122         res = 0;
123       return res;
124     }
125
126     virtual streambuf*
127     setbuf(char_type* s, streamsize n)
128     {
129       if (n != 0)
130         {
131           delete[] stream;
132           stream = new char_type[n];
133           memcpy(stream, s, n);
134           stream_len = n;
135           stringbuf_sync(0, 0);
136         }
137       return this;
138     }
139
140     virtual pos_type
141     seekoff(off_type off, ios::seek_dir way, int which = ios::in | ios::out)
142     {
143       pos_type ret =  pos_type(off_type(-1));
144       bool testin = which & ios::in && mode & ios::in;
145       bool testout = which & ios::out && mode & ios::out;
146       bool testboth = testin && testout && way != ios::cur;
147
148       if (stream_len && ((testin != testout) || testboth))
149         {
150           char_type* beg = stream;
151           char_type* curi = NULL;
152           char_type* curo = NULL;
153           char_type* endi = NULL;
154           char_type* endo = NULL;
155
156           if (testin)
157             {
158               curi = gptr();
159               endi = egptr();
160             }
161           if (testout)
162             {
163               curo = pptr();
164               endo = epptr();
165             }
166
167           off_type newoffi = 0;
168           off_type newoffo = 0;
169           if (way == ios::beg)
170             {
171               newoffi = beg - curi;
172               newoffo = beg - curo;
173             }
174           else if (way == ios::end)
175             {
176               newoffi = endi - curi;
177               newoffo = endo - curo;
178             }
179
180           if (testin && newoffi + off + curi - beg >= 0 &&
181               endi - beg >= newoffi + off + curi - beg)
182             {
183               gbump(newoffi + off);
184               ret = pos_type(newoffi + off + curi);
185             }
186           if (testout && newoffo + off + curo - beg >= 0 &&
187               endo - beg >= newoffo + off + curo - beg)
188             {
189               pbump(newoffo + off);
190               ret = pos_type(newoffo + off + curo);
191             }
192         }
193       return ret;
194     }
195
196     virtual pos_type
197     seekpos(pos_type sp, int which = ios::in | ios::out)
198     {
199       pos_type ret = seekoff(sp, ios::beg, which);
200       return ret;
201     }
202
203   private:
204     void
205     stringbuf_sync(streamsize i, streamsize o)
206     {
207       if (mode & ios::in)
208         setg(stream, stream + i, stream + stream_len);
209       if (mode & ios::out)
210         {
211           setp(stream, stream + stream_len);
212           pbump(o);
213         }
214     }
215     void
216     stringbuf_init()
217     {
218       if (mode & ios::ate)
219         stringbuf_sync(0, stream_len);
220       else
221         stringbuf_sync(0, 0);
222     }
223
224   private:
225     ios::open_mode      mode;
226     char_type*          stream;
227     streamsize          stream_len;
228   };
229 \f
230   class istringstream : public istream {
231   public:
232     typedef char        char_type;
233     typedef int         int_type;
234     typedef streampos   pos_type;
235     typedef streamoff   off_type;
236
237     explicit
238     istringstream(int which=ios::in)
239       : istream(&sb), sb(which | ios::in)
240     { }
241
242     explicit
243     istringstream(const string& str, int which=ios::in)
244       : istream(&sb), sb(str, which | ios::in)
245     { }
246
247     stringbuf*
248     rdbuf() const
249     {
250       return const_cast<stringbuf*>(&sb);
251     }
252
253     string
254     str() const
255     {
256       return rdbuf()->str();
257     }
258     void
259     str(const string& s)
260     {
261       rdbuf()->str(s);
262     }
263   private:
264     stringbuf sb;
265   };
266 \f
267   class ostringstream : public ostream {
268   public:
269     typedef char        char_type;
270     typedef int         int_type;
271     typedef streampos   pos_type;
272     typedef streamoff   off_type;
273
274     explicit
275     ostringstream(int which=ios::out)
276       : ostream(&sb), sb(which | ios::out)
277     { }
278
279     explicit
280     ostringstream(const string& str, int which=ios::out)
281       : ostream(&sb), sb(str, which | ios::out)
282     { }
283
284     stringbuf*
285     rdbuf() const
286     {
287       return const_cast<stringbuf*>(&sb);
288     }
289
290     string
291     str() const
292     {
293       return rdbuf()->str();
294     }
295
296     void str(const string& s)
297     {
298       rdbuf()->str(s);
299     }
300   private:
301     stringbuf sb;
302   };
303 \f
304   class stringstream : public iostream {
305   public:
306     typedef char        char_type;
307     typedef int         int_type;
308     typedef streampos   pos_type;
309     typedef streamoff   off_type;
310
311     explicit
312     stringstream(int which=ios::out|ios::in)
313       : iostream(&sb), sb(which)
314     { }
315
316     explicit
317     stringstream(const string& str, int which=ios::out|ios::in)
318       : iostream(&sb), sb(str, which)
319     { }
320
321     stringbuf*
322     rdbuf() const
323     {
324       return const_cast<stringbuf*>(&sb);
325     }
326
327     string
328     str() const
329     {
330       return rdbuf()->str();
331     }
332
333     void
334     str(const string& s)
335     {
336       rdbuf()->str(s);
337     }
338   private:
339     stringbuf sb;
340   };
341 };
342
343 #endif /* not __STRSTREAM__ */