]> git.saurik.com Git - wxWidgets.git/blame - src/common/sstream.cpp
leave i386 compiler to default
[wxWidgets.git] / src / common / sstream.cpp
CommitLineData
121fa06a 1///////////////////////////////////////////////////////////////////////////////
80fdcdb9 2// Name: src/common/sstream.cpp
121fa06a
VZ
3// Purpose: string-based streams implementation
4// Author: Vadim Zeitlin
c5d99d7b 5// Modified by: Ryan Norton (UTF8 UNICODE)
121fa06a 6// Created: 2004-09-19
121fa06a
VZ
7// Copyright: (c) 2004 Vadim Zeitlin <vadim@wxwindows.org>
8// Licence: wxWindows licence
9///////////////////////////////////////////////////////////////////////////////
10
11// ============================================================================
12// declarations
13// ============================================================================
14
15// ----------------------------------------------------------------------------
16// headers
17// ----------------------------------------------------------------------------
18
19// For compilers that support precompilation, includes "wx.h".
20#include "wx/wxprec.h"
21
22#ifdef __BORLANDC__
23 #pragma hdrstop
24#endif
25
26#if wxUSE_STREAMS
27
28#include "wx/sstream.h"
29
30// ============================================================================
31// wxStringInputStream implementation
32// ============================================================================
33
c5d99d7b
RN
34// ----------------------------------------------------------------------------
35// construction/destruction
36// ----------------------------------------------------------------------------
37
cb28cc9e 38// TODO: Do we want to include the null char in the stream? If so then
03647350 39// just add +1 to m_len in the ctor
86501081 40wxStringInputStream::wxStringInputStream(const wxString& s)
c5d99d7b 41#if wxUSE_UNICODE
86501081
VS
42 // FIXME-UTF8: use wxCharBufferWithLength if we have it
43 : m_str(s), m_buf(s.utf8_str()), m_len(strlen(m_buf))
c5d99d7b 44#else
86501081 45 : m_str(s), m_buf(s.mb_str()), m_len(s.length())
c5d99d7b
RN
46#endif
47{
48#if wxUSE_UNICODE
9a83f860 49 wxASSERT_MSG(m_buf.data() != NULL, wxT("Could not convert string to UTF8!"));
c5d99d7b
RN
50#endif
51 m_pos = 0;
52}
53
c5d99d7b
RN
54// ----------------------------------------------------------------------------
55// getlength
56// ----------------------------------------------------------------------------
57
03647350
VZ
58wxFileOffset wxStringInputStream::GetLength() const
59{
60 return m_len;
c5d99d7b
RN
61}
62
121fa06a
VZ
63// ----------------------------------------------------------------------------
64// seek/tell
65// ----------------------------------------------------------------------------
66
4004775e 67wxFileOffset wxStringInputStream::OnSysSeek(wxFileOffset ofs, wxSeekMode mode)
121fa06a
VZ
68{
69 switch ( mode )
70 {
71 case wxFromStart:
72 // nothing to do, ofs already ok
73 break;
74
75 case wxFromEnd:
c5d99d7b 76 ofs += m_len;
121fa06a
VZ
77 break;
78
79 case wxFromCurrent:
80 ofs += m_pos;
81 break;
82
83 default:
9a83f860 84 wxFAIL_MSG( wxT("invalid seek mode") );
121fa06a
VZ
85 return wxInvalidOffset;
86 }
87
5c33522f 88 if ( ofs < 0 || ofs > static_cast<wxFileOffset>(m_len) )
5a4c7f71
VZ
89 return wxInvalidOffset;
90
c781c316
VZ
91 // FIXME: this can't be right
92 m_pos = wx_truncate_cast(size_t, ofs);
121fa06a
VZ
93
94 return ofs;
95}
96
4004775e 97wxFileOffset wxStringInputStream::OnSysTell() const
121fa06a 98{
5c33522f 99 return static_cast<wxFileOffset>(m_pos);
121fa06a
VZ
100}
101
102// ----------------------------------------------------------------------------
103// actual IO
104// ----------------------------------------------------------------------------
105
106size_t wxStringInputStream::OnSysRead(void *buffer, size_t size)
107{
c5d99d7b 108 const size_t sizeMax = m_len - m_pos;
121fa06a
VZ
109
110 if ( size >= sizeMax )
111 {
112 if ( sizeMax == 0 )
113 {
114 m_lasterror = wxSTREAM_EOF;
115 return 0;
116 }
117
118 size = sizeMax;
119 }
120
86501081 121 memcpy(buffer, m_buf.data() + m_pos, size);
121fa06a
VZ
122 m_pos += size;
123
124 return size;
125}
126
127// ============================================================================
128// wxStringOutputStream implementation
129// ============================================================================
130
a5ea75bc
VZ
131// ----------------------------------------------------------------------------
132// seek/tell
133// ----------------------------------------------------------------------------
134
4004775e 135wxFileOffset wxStringOutputStream::OnSysTell() const
a5ea75bc 136{
5c33522f 137 return static_cast<wxFileOffset>(m_pos);
a5ea75bc
VZ
138}
139
121fa06a
VZ
140// ----------------------------------------------------------------------------
141// actual IO
142// ----------------------------------------------------------------------------
143
144size_t wxStringOutputStream::OnSysWrite(const void *buffer, size_t size)
145{
5c33522f 146 const char *p = static_cast<const char *>(buffer);
121fa06a 147
ff8a5f3d 148#if wxUSE_UNICODE
2c17722e
VZ
149 // the part of the string we have here may be incomplete, i.e. it can stop
150 // in the middle of an UTF-8 character and so converting it would fail; if
151 // this is the case, accumulate the part which we failed to convert until
152 // we get the rest (and also take into account the part which we might have
153 // left unconverted before)
154 const char *src;
155 size_t srcLen;
156 if ( m_unconv.GetDataLen() )
157 {
158 // append the new data to the data remaining since the last time
159 m_unconv.AppendData(p, size);
160 src = m_unconv;
161 srcLen = m_unconv.GetDataLen();
162 }
163 else // no unconverted data left, avoid extra copy
164 {
165 src = p;
166 srcLen = size;
167 }
168
a7b9ab62
VZ
169 size_t wlen;
170 wxWCharBuffer wbuf(m_conv.cMB2WC(src, srcLen, &wlen));
2c17722e
VZ
171 if ( wbuf )
172 {
173 // conversion succeeded, clear the unconverted buffer
174 m_unconv = wxMemoryBuffer(0);
175
a7b9ab62 176 m_str->append(wbuf, wlen);
2c17722e
VZ
177 }
178 else // conversion failed
179 {
180 // remember unconverted data if there had been none before (otherwise
181 // we've already got it in the buffer)
182 if ( src == p )
183 m_unconv.AppendData(src, srcLen);
184
185 // pretend that we wrote the data anyhow, otherwise the caller would
186 // believe there was an error and this might not be the case, but do
187 // not update m_pos as m_str hasn't changed
188 return size;
189 }
ff8a5f3d
VZ
190#else // !wxUSE_UNICODE
191 // no recoding necessary
2c17722e 192 m_str->append(p, size);
ff8a5f3d 193#endif // wxUSE_UNICODE/!wxUSE_UNICODE
121fa06a 194
cb28cc9e 195 // update position
c5d99d7b 196 m_pos += size;
a5ea75bc 197
cb28cc9e 198 // return number of bytes actually written
c5d99d7b 199 return size;
121fa06a
VZ
200}
201
202#endif // wxUSE_STREAMS
203