/[pcsx2_0.9.7]/trunk/3rdparty/wxWidgets/src/common/sstream.cpp
ViewVC logotype

Contents of /trunk/3rdparty/wxWidgets/src/common/sstream.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 31 - (show annotations) (download)
Tue Sep 7 03:24:11 2010 UTC (10 years, 3 months ago) by william
File size: 7075 byte(s)
committing r3113 initial commit again...
1 ///////////////////////////////////////////////////////////////////////////////
2 // Name: common/sstream.cpp
3 // Purpose: string-based streams implementation
4 // Author: Vadim Zeitlin
5 // Modified by: Ryan Norton (UTF8 UNICODE)
6 // Created: 2004-09-19
7 // RCS-ID: $Id: sstream.cpp 45772 2007-05-03 02:19:16Z VZ $
8 // Copyright: (c) 2004 Vadim Zeitlin <vadim@wxwindows.org>
9 // Licence: wxWindows licence
10 ///////////////////////////////////////////////////////////////////////////////
11
12 // ============================================================================
13 // declarations
14 // ============================================================================
15
16 // ----------------------------------------------------------------------------
17 // headers
18 // ----------------------------------------------------------------------------
19
20 // For compilers that support precompilation, includes "wx.h".
21 #include "wx/wxprec.h"
22
23 #ifdef __BORLANDC__
24 #pragma hdrstop
25 #endif
26
27 #if wxUSE_STREAMS
28
29 #include "wx/sstream.h"
30
31 #if wxUSE_UNICODE
32 #include "wx/hashmap.h"
33 #endif
34
35 // ============================================================================
36 // wxStringInputStream implementation
37 // ============================================================================
38
39 // ----------------------------------------------------------------------------
40 // construction/destruction
41 // ----------------------------------------------------------------------------
42
43 // TODO: Do we want to include the null char in the stream? If so then
44 // just add +1 to m_len in the ctor
45 wxStringInputStream::wxStringInputStream(const wxString& s)
46 #if wxUSE_UNICODE
47 : m_str(s), m_buf(wxMBConvUTF8().cWX2MB(s).release()), m_len(strlen(m_buf))
48 #else
49 : m_str(s), m_buf((char*)s.c_str()), m_len(s.length())
50 #endif
51 {
52 #if wxUSE_UNICODE
53 wxASSERT_MSG(m_buf != NULL, _T("Could not convert string to UTF8!"));
54 #endif
55 m_pos = 0;
56 }
57
58 wxStringInputStream::~wxStringInputStream()
59 {
60 #if wxUSE_UNICODE
61 // Note: wx[W]CharBuffer uses malloc()/free()
62 // PCSX2 : wx[W]CharBuffer now uses the wxString local heap! --air
63 //free(m_buf);
64 _freeHeap_wxString(m_buf);
65 #endif
66 }
67
68 // ----------------------------------------------------------------------------
69 // getlength
70 // ----------------------------------------------------------------------------
71
72 wxFileOffset wxStringInputStream::GetLength() const
73 {
74 return m_len;
75 }
76
77 // ----------------------------------------------------------------------------
78 // seek/tell
79 // ----------------------------------------------------------------------------
80
81 wxFileOffset wxStringInputStream::OnSysSeek(wxFileOffset ofs, wxSeekMode mode)
82 {
83 switch ( mode )
84 {
85 case wxFromStart:
86 // nothing to do, ofs already ok
87 break;
88
89 case wxFromEnd:
90 ofs += m_len;
91 break;
92
93 case wxFromCurrent:
94 ofs += m_pos;
95 break;
96
97 default:
98 wxFAIL_MSG( _T("invalid seek mode") );
99 return wxInvalidOffset;
100 }
101
102 if ( ofs < 0 || ofs > wx_static_cast(wxFileOffset, m_len) )
103 return wxInvalidOffset;
104
105 // FIXME: this can't be right
106 m_pos = wx_truncate_cast(size_t, ofs);
107
108 return ofs;
109 }
110
111 wxFileOffset wxStringInputStream::OnSysTell() const
112 {
113 return wx_static_cast(wxFileOffset, m_pos);
114 }
115
116 // ----------------------------------------------------------------------------
117 // actual IO
118 // ----------------------------------------------------------------------------
119
120 size_t wxStringInputStream::OnSysRead(void *buffer, size_t size)
121 {
122 const size_t sizeMax = m_len - m_pos;
123
124 if ( size >= sizeMax )
125 {
126 if ( sizeMax == 0 )
127 {
128 m_lasterror = wxSTREAM_EOF;
129 return 0;
130 }
131
132 size = sizeMax;
133 }
134
135 memcpy(buffer, m_buf + m_pos, size);
136 m_pos += size;
137
138 return size;
139 }
140
141 // ============================================================================
142 // wxStringOutputStream implementation
143 // ============================================================================
144
145 // ----------------------------------------------------------------------------
146 // seek/tell
147 // ----------------------------------------------------------------------------
148
149 wxFileOffset wxStringOutputStream::OnSysTell() const
150 {
151 return wx_static_cast(wxFileOffset, m_pos);
152 }
153
154 // ----------------------------------------------------------------------------
155 // actual IO
156 // ----------------------------------------------------------------------------
157
158 #if wxUSE_UNICODE
159
160 // we can't add a member to wxStringOutputStream in 2.8 branch without breaking
161 // backwards binary compatibility, so we emulate it by using a hash indexed by
162 // wxStringOutputStream pointers
163
164 // can't use wxCharBuffer as it has incorrect copying semantics and doesn't
165 // store the length which we need here
166 WX_DECLARE_VOIDPTR_HASH_MAP(wxMemoryBuffer, wxStringStreamUnconvBuffers);
167
168 static wxStringStreamUnconvBuffers gs_unconverted;
169
170 wxStringOutputStream::~wxStringOutputStream()
171 {
172 // TODO: check that nothing remains (i.e. the unconverted buffer is empty)?
173 gs_unconverted.erase(this);
174 }
175
176 #endif // wxUSE_UNICODE
177
178 size_t wxStringOutputStream::OnSysWrite(const void *buffer, size_t size)
179 {
180 const char *p = wx_static_cast(const char *, buffer);
181
182 #if wxUSE_UNICODE
183 // the part of the string we have here may be incomplete, i.e. it can stop
184 // in the middle of an UTF-8 character and so converting it would fail; if
185 // this is the case, accumulate the part which we failed to convert until
186 // we get the rest (and also take into account the part which we might have
187 // left unconverted before)
188 const char *src;
189 size_t srcLen;
190 wxMemoryBuffer& unconv = gs_unconverted[this];
191 if ( unconv.GetDataLen() )
192 {
193 // append the new data to the data remaining since the last time
194 unconv.AppendData(p, size);
195 src = unconv;
196 srcLen = unconv.GetDataLen();
197 }
198 else // no unconverted data left, avoid extra copy
199 {
200 src = p;
201 srcLen = size;
202 }
203
204 wxWCharBuffer wbuf(m_conv.cMB2WC(src, srcLen, NULL /* out len */));
205 if ( wbuf )
206 {
207 // conversion succeeded, clear the unconverted buffer
208 unconv = wxMemoryBuffer(0);
209
210 *m_str += wbuf;
211 }
212 else // conversion failed
213 {
214 // remember unconverted data if there had been none before (otherwise
215 // we've already got it in the buffer)
216 if ( src == p )
217 unconv.AppendData(src, srcLen);
218
219 // pretend that we wrote the data anyhow, otherwise the caller would
220 // believe there was an error and this might not be the case, but do
221 // not update m_pos as m_str hasn't changed
222 return size;
223 }
224 #else // !wxUSE_UNICODE
225 // append directly, no conversion necessary
226 m_str->Append(wxString(p, size));
227 #endif // wxUSE_UNICODE/!wxUSE_UNICODE
228
229 // update position
230 m_pos += size;
231
232 // return number of bytes actually written
233 return size;
234 }
235
236 #endif // wxUSE_STREAMS
237

  ViewVC Help
Powered by ViewVC 1.1.22