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