Applied #15393 (dghart) fixing wxRichTextTable for percentage widths
[wxWidgets.git] / src / common / stdstream.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: src/common/stdstream.cpp
3 // Purpose: Implementation of std::istream and std::ostream derived
4 // wrappers for wxInputStream and wxOutputStream
5 // Author: Jonathan Liu <net147@gmail.com>
6 // Created: 2009-05-02
7 // Copyright: (c) 2009 Jonathan Liu
8 // Licence: wxWindows licence
9 /////////////////////////////////////////////////////////////////////////////
10
11 // ==========================================================================
12 // Declarations
13 // ==========================================================================
14
15 // For compilers that support precompilation, includes "wx.h".
16 #include "wx/wxprec.h"
17
18 #ifdef __BORLANDC__
19 #pragma hdrstop
20 #endif
21
22 #if wxUSE_STREAMS && wxUSE_STD_IOSTREAM
23
24 #ifndef WX_PRECOMP
25 #endif
26
27 #include "wx/stdstream.h"
28
29 #include <ios>
30 #include <istream>
31 #include <ostream>
32 #include <streambuf>
33
34 // ==========================================================================
35 // Helpers
36 // ==========================================================================
37
38 namespace
39 {
40
41 bool
42 IosSeekDirToWxSeekMode(std::ios_base::seekdir way,
43 wxSeekMode& seekMode)
44 {
45 switch ( way )
46 {
47 case std::ios_base::beg:
48 seekMode = wxFromStart;
49 break;
50 case std::ios_base::cur:
51 seekMode = wxFromCurrent;
52 break;
53 case std::ios_base::end:
54 seekMode = wxFromEnd;
55 break;
56 default:
57 return false;
58 }
59
60 return true;
61 }
62
63 } // anonymous namespace
64
65 // ==========================================================================
66 // wxStdInputStreamBuffer
67 // ==========================================================================
68
69 wxStdInputStreamBuffer::wxStdInputStreamBuffer(wxInputStream& stream) :
70 m_stream(stream), m_lastChar(EOF)
71 {
72 }
73
74 std::streambuf *
75 wxStdInputStreamBuffer::setbuf(char *WXUNUSED(s),
76 std::streamsize WXUNUSED(n))
77 {
78 return NULL;
79 }
80
81 std::streampos
82 wxStdInputStreamBuffer::seekoff(std::streamoff off,
83 std::ios_base::seekdir way,
84 std::ios_base::openmode which)
85 {
86 wxSeekMode seekMode;
87
88 if ( !IosSeekDirToWxSeekMode(way, seekMode) )
89 return -1;
90 if ( !(which & std::ios_base::in) )
91 return -1;
92
93 off_t newPos = m_stream.SeekI((off_t) off, seekMode);
94
95 if ( newPos != wxInvalidOffset )
96 return (std::streampos) newPos;
97 else
98 return -1;
99 }
100
101 std::streampos
102 wxStdInputStreamBuffer::seekpos(std::streampos sp,
103 std::ios_base::openmode which)
104 {
105 if ( !(which & std::ios_base::in) )
106 return -1;
107
108 off_t newPos = m_stream.SeekI((off_t) sp);
109
110 if ( newPos != wxInvalidOffset )
111 return (std::streampos) newPos;
112 else
113 return -1;
114 }
115
116 std::streamsize
117 wxStdInputStreamBuffer::showmanyc()
118 {
119 if ( m_stream.CanRead() && (off_t) m_stream.GetSize() > m_stream.TellI() )
120 return m_stream.GetSize() - m_stream.TellI();
121 else
122 return 0;
123 }
124
125 std::streamsize
126 wxStdInputStreamBuffer::xsgetn(char *s, std::streamsize n)
127 {
128 m_stream.Read((void *) s, (size_t) n);
129
130 std::streamsize read = m_stream.LastRead();
131
132 if ( read > 0 )
133 m_lastChar = (unsigned char) s[read - 1];
134
135 return read;
136 }
137
138 int
139 wxStdInputStreamBuffer::underflow()
140 {
141 int ch = m_stream.GetC();
142
143 if ( m_stream.LastRead() == 1 )
144 {
145 m_stream.Ungetch((char) ch);
146 return ch;
147 }
148 else
149 {
150 return EOF;
151 }
152 }
153
154 int
155 wxStdInputStreamBuffer::uflow()
156 {
157 int ch = m_stream.GetC();
158
159 if ( m_stream.LastRead() == 1 )
160 {
161 m_lastChar = ch;
162 return ch;
163 }
164 else
165 {
166 return EOF;
167 }
168 }
169
170 int
171 wxStdInputStreamBuffer::pbackfail(int c)
172 {
173 if ( c == EOF )
174 {
175 if ( m_lastChar == EOF )
176 return EOF;
177
178 c = m_lastChar;
179 m_lastChar = EOF;
180 }
181
182 return m_stream.Ungetch((char) c) ? c : EOF;
183 }
184
185 // ==========================================================================
186 // wxStdOutputStreamBuffer
187 // ==========================================================================
188
189 wxStdOutputStreamBuffer::wxStdOutputStreamBuffer(wxOutputStream& stream) :
190 m_stream(stream)
191 {
192 }
193
194 std::streambuf *
195 wxStdOutputStreamBuffer::setbuf(char *WXUNUSED(s),
196 std::streamsize WXUNUSED(n))
197 {
198 return NULL;
199 }
200
201 std::streampos
202 wxStdOutputStreamBuffer::seekoff(std::streamoff off,
203 std::ios_base::seekdir way,
204 std::ios_base::openmode which)
205 {
206 wxSeekMode seekMode;
207
208 if ( !IosSeekDirToWxSeekMode(way, seekMode) )
209 return -1;
210 if ( !(which & std::ios_base::out) )
211 return -1;
212
213 off_t newPos = m_stream.SeekO((off_t) off, seekMode);
214
215 if ( newPos != wxInvalidOffset )
216 return (std::streampos) newPos;
217 else
218 return -1;
219 }
220
221 std::streampos
222 wxStdOutputStreamBuffer::seekpos(std::streampos sp,
223 std::ios_base::openmode which)
224 {
225 if ( !(which & std::ios_base::out) )
226 return -1;
227
228 off_t newPos = m_stream.SeekO((off_t) sp);
229
230 if ( newPos != wxInvalidOffset )
231 return (std::streampos) newPos;
232 else
233 return -1;
234 }
235
236 std::streamsize
237 wxStdOutputStreamBuffer::xsputn(const char *s,
238 std::streamsize n)
239 {
240 m_stream.Write((const void *) s, (size_t) n);
241 return (std::streamsize) m_stream.LastWrite();
242 }
243
244 int
245 wxStdOutputStreamBuffer::overflow(int c)
246 {
247 m_stream.PutC(c);
248 return m_stream.IsOk() ? c : EOF;
249 }
250
251 // ==========================================================================
252 // wxStdInputStream and wxStdOutputStream
253 // ==========================================================================
254
255 // FIXME-VC6: it is impossible to call basic_ios<char>::init() with this
256 // compiler, it complains about invalid call to non-static member
257 // function so use a suspicious (as it uses a pointer to not yet
258 // constructed streambuf) but working workaround
259 //
260 // It also doesn't like using istream in the ctor initializer list
261 // and we must spell it out as basic_istream<char>.
262 #ifdef __VISUALC6__
263
264 wxStdInputStream::wxStdInputStream(wxInputStream& stream)
265 : std::basic_istream<char, std::char_traits<char> >(&m_streamBuffer),
266 m_streamBuffer(stream)
267 {
268 }
269
270 wxStdOutputStream::wxStdOutputStream(wxOutputStream& stream)
271 : std::basic_ostream<char, std::char_traits<char> >(&m_streamBuffer),
272 m_streamBuffer(stream)
273 {
274 }
275
276 #else // !VC6
277
278 wxStdInputStream::wxStdInputStream(wxInputStream& stream) :
279 std::istream(NULL), m_streamBuffer(stream)
280 {
281 std::ios::init(&m_streamBuffer);
282 }
283
284 wxStdOutputStream::wxStdOutputStream(wxOutputStream& stream) :
285 std::ostream(NULL), m_streamBuffer(stream)
286 {
287 std::ios::init(&m_streamBuffer);
288 }
289
290 #endif // VC6/!VC6
291
292 #endif // wxUSE_STREAMS && wxUSE_STD_IOSTREAM