Be sure to initialize the size before use.
[official-gcc.git] / libstdc++ / sstream
blob714be717e5071b8a7de2f36036ad1e1ceefbbc0b
1 /* This is part of libio/iostream, providing -*- C++ -*- input/output.\r
2 Copyright (C) 2000 Free Software Foundation\r
3 \r
4 This file is part of the GNU IO Library.  This library is free\r
5 software; you can redistribute it and/or modify it under the\r
6 terms of the GNU General Public License as published by the\r
7 Free Software Foundation; either version 2, or (at your option)\r
8 any later version.\r
9 \r
10 This library is distributed in the hope that it will be useful,\r
11 but WITHOUT ANY WARRANTY; without even the implied warranty of\r
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
13 GNU General Public License for more details.\r
15 You should have received a copy of the GNU General Public License\r
16 along with this library; see the file COPYING.  If not, write to the Free\r
17 Software Foundation, 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.\r
19 As a special exception, if you link this library with files\r
20 compiled with a GNU compiler to produce an executable, this does not cause\r
21 the resulting executable to be covered by the GNU General Public License.\r
22 This exception does not however invalidate any other reasons why\r
23 the executable file might be covered by the GNU General Public License. */\r
25 /* Written by Magnus Fromreide (magfr@lysator.liu.se). */\r
27 #ifndef __SSTREAM__\r
28 #define __SSTREAM__\r
30 #include <string>\r
31 #include <iostream.h>\r
32 #include <streambuf.h>\r
34 namespace std\r
35 {\r
36   class stringbuf : public streambuf\r
37   {\r
38   public:\r
39     typedef char        char_type;\r
40     typedef int         int_type;\r
41     typedef streampos   pos_type;\r
42     typedef streamoff   off_type;\r
44     explicit stringbuf(int which=ios::in|ios::out) :\r
45       streambuf(which), buf(), mode(static_cast<ios::open_mode>(which)),\r
46       rpos(0), bufsize(1)\r
47     { }\r
48         \r
49     explicit stringbuf(const std::string &s, int which=ios::in|ios::out) :\r
50       streambuf(which), buf(s), mode(static_cast<ios::open_mode>(which)),\r
51       bufsize(1)\r
52     {\r
53       if(mode & ios::in)\r
54         {\r
55           setg(&defbuf, &defbuf + bufsize, &defbuf + bufsize);\r
56         }\r
57       if(mode & ios::out)\r
58         {\r
59           setp(&defbuf, &defbuf + bufsize);\r
60         }\r
61       rpos = (mode & ios::ate ? s.size() : 0);\r
62     }\r
63         \r
64     std::string str() const\r
65     {\r
66       const_cast<stringbuf*>(this)->sync();  // Sigh, really ugly hack\r
67       return buf;\r
68     };\r
70     void str(const std::string& s)\r
71     {\r
72       buf = s;\r
73       if(mode & ios::in)\r
74         {\r
75           gbump(egptr() - gptr());\r
76         }\r
77       if(mode & ios::out)\r
78         {\r
79           pbump(pbase() - pptr());\r
80         }\r
81       rpos = (mode & ios::ate ? s.size() : 0);\r
82     }\r
84   protected:\r
85     inline virtual int sync();\r
86     inline virtual int overflow(int = EOF);\r
87     inline virtual int underflow();\r
88   private:\r
89     std::string                 buf;\r
90     ios::open_mode              mode;\r
91     std::string::size_type      rpos;\r
92     streamsize                  bufsize;\r
93     char                        defbuf;\r
94   };\r
96   class stringstreambase : virtual public ios {\r
97   protected:\r
98     stringbuf __my_sb;\r
99   public:\r
100     std::string str() const\r
101     {\r
102       return dynamic_cast<stringbuf*>(_strbuf)->str();\r
103     }\r
104     void str(const std::string& s)\r
105     {\r
106       clear();\r
107       dynamic_cast<stringbuf*>(_strbuf)->str(s);\r
108     }\r
109         \r
110     stringbuf* rdbuf()\r
111     {\r
112       return &__my_sb;\r
113     }\r
114   protected:\r
115     stringstreambase(int which) :\r
116       __my_sb(which)\r
117     {\r
118       init (&__my_sb);\r
119     }\r
120         \r
121     stringstreambase(const std::string& s, int which) :\r
122       __my_sb(s, which)\r
123     {\r
124       init (&__my_sb);\r
125     }\r
126   };\r
127     \r
128   class istringstream : public stringstreambase, public istream {\r
129   public:\r
130     istringstream(int which=ios::in) :\r
131       stringstreambase(which)\r
132     { }\r
133         \r
134     istringstream(const std::string& s, int which=ios::in) :\r
135       stringstreambase(s, which)\r
136     { }\r
137   };\r
138     \r
139   class ostringstream : public stringstreambase, public ostream {\r
140   public:\r
141     ostringstream(int which=ios::out) :\r
142       stringstreambase(which)\r
143     { }\r
144         \r
145     ostringstream(const std::string& s, int which=ios::out) :\r
146       stringstreambase(s, which)\r
147     { }\r
148   };\r
149     \r
150   class stringstream : public stringstreambase, public iostream {\r
151   public:\r
152     stringstream(int which=ios::in|ios::out) :\r
153       stringstreambase(which)\r
154     { }\r
155     \r
156     stringstream(const std::string &s, int which=ios::in|ios::out) :\r
157       stringstreambase(s, which)\r
158     { }\r
159   };\r
162 inline int std::stringbuf::sync()\r
164   if((mode & ios::out) == 0)\r
165     return EOF;\r
167   streamsize n = pptr() - pbase();\r
168   if(n)\r
169     {\r
170       buf.replace(rpos, std::string::npos, pbase(), n);\r
171       if(buf.size() - rpos != n)\r
172         return EOF;\r
173       rpos += n;\r
174       pbump(-n);\r
175       gbump(egptr() - gptr());\r
176     }\r
177   return 0;\r
180 inline int std::stringbuf::overflow(int ch)\r
182   if((mode & ios::out) == 0)\r
183     return EOF;\r
185   streamsize n = pptr() - pbase();\r
187   if(n && sync())\r
188     return EOF;\r
190   if(ch != EOF)\r
191     {\r
192       std::string::size_type oldSize = buf.size();\r
193       \r
194       buf.replace(rpos, std::string::npos, ch);\r
195       if(buf.size() - oldSize != 1)\r
196         return EOF;\r
197       ++rpos;\r
198     }\r
199   return 0;\r
202 inline int std::stringbuf::underflow()\r
204   sync();\r
205   if((mode & ios::in) == 0)\r
206     {\r
207       return EOF;\r
208     }\r
209   if(rpos >= buf.size())\r
210     {\r
211       return EOF;\r
212     }\r
213   \r
214   std::string::size_type n = egptr() - eback();\r
215   std::string::size_type s;\r
217   s = buf.copy(eback(), n, rpos);\r
218   pbump(pbase() - pptr());\r
219   gbump(eback() - gptr());\r
220   int res = (0377 & buf[rpos]);\r
221   rpos += s;\r
222   return res;\r
225 #endif /* not __STRSTREAM__ */\r