]> git.saurik.com Git - wxWidgets.git/blame - src/common/stdstream.cpp
Workaround for #15404: wxRichTextCtrl: caret does not disappear when focus is lost...
[wxWidgets.git] / src / common / stdstream.cpp
CommitLineData
72a7c559 1/////////////////////////////////////////////////////////////////////////////
80fdcdb9 2// Name: src/common/stdstream.cpp
72a7c559
VZ
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
72a7c559
VZ
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
e5805c0f 22#if wxUSE_STREAMS && wxUSE_STD_IOSTREAM
72a7c559
VZ
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
38namespace
39{
40
5c4f18cc 41bool
72a7c559
VZ
42IosSeekDirToWxSeekMode(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
69wxStdInputStreamBuffer::wxStdInputStreamBuffer(wxInputStream& stream) :
70 m_stream(stream), m_lastChar(EOF)
71{
72}
73
74std::streambuf *
75wxStdInputStreamBuffer::setbuf(char *WXUNUSED(s),
76 std::streamsize WXUNUSED(n))
77{
78 return NULL;
79}
80
81std::streampos
82wxStdInputStreamBuffer::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
101std::streampos
102wxStdInputStreamBuffer::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
116std::streamsize
117wxStdInputStreamBuffer::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
125std::streamsize
126wxStdInputStreamBuffer::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
138int
139wxStdInputStreamBuffer::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
154int
155wxStdInputStreamBuffer::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
170int
171wxStdInputStreamBuffer::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
72a7c559
VZ
185// ==========================================================================
186// wxStdOutputStreamBuffer
187// ==========================================================================
188
189wxStdOutputStreamBuffer::wxStdOutputStreamBuffer(wxOutputStream& stream) :
190 m_stream(stream)
191{
192}
193
194std::streambuf *
195wxStdOutputStreamBuffer::setbuf(char *WXUNUSED(s),
196 std::streamsize WXUNUSED(n))
197{
198 return NULL;
199}
200
201std::streampos
202wxStdOutputStreamBuffer::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
221std::streampos
222wxStdOutputStreamBuffer::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
236std::streamsize
237wxStdOutputStreamBuffer::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
244int
245wxStdOutputStreamBuffer::overflow(int c)
246{
247 m_stream.PutC(c);
248 return m_stream.IsOk() ? c : EOF;
249}
250
251// ==========================================================================
9dfe9a1a 252// wxStdInputStream and wxStdOutputStream
72a7c559
VZ
253// ==========================================================================
254
9dfe9a1a
VZ
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
264wxStdInputStream::wxStdInputStream(wxInputStream& stream)
265 : std::basic_istream<char, std::char_traits<char> >(&m_streamBuffer),
266 m_streamBuffer(stream)
267{
268}
269
270wxStdOutputStream::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
278wxStdInputStream::wxStdInputStream(wxInputStream& stream) :
279 std::istream(NULL), m_streamBuffer(stream)
280{
281 std::ios::init(&m_streamBuffer);
282}
283
72a7c559
VZ
284wxStdOutputStream::wxStdOutputStream(wxOutputStream& stream) :
285 std::ostream(NULL), m_streamBuffer(stream)
286{
287 std::ios::init(&m_streamBuffer);
288}
289
9dfe9a1a
VZ
290#endif // VC6/!VC6
291
e5805c0f 292#endif // wxUSE_STREAMS && wxUSE_STD_IOSTREAM