fix wxStringOutputStream::Write() in Unicode build when the output overlaps a boundary between UTF-8 characters (bug 1701426)
git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/branches/WX_2_8_BRANCH@45732 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
@@ -94,6 +94,8 @@ Major new features in 2.8 release
|
|||||||
All:
|
All:
|
||||||
|
|
||||||
- Fix bug in wxFileConfig when recreating a group (Steven Van Ingelgem)
|
- Fix bug in wxFileConfig when recreating a group (Steven Van Ingelgem)
|
||||||
|
- Fix wxStringOutputStream::Write() in Unicode build when the argument
|
||||||
|
overlaps UTF-8 characters boundary
|
||||||
- Account for lines without newline at the end in wxExecute()
|
- Account for lines without newline at the end in wxExecute()
|
||||||
- Added wxString::char_str() and wchar_str() methods for forward
|
- Added wxString::char_str() and wchar_str() methods for forward
|
||||||
compatiblity with wxWidgets 3
|
compatiblity with wxWidgets 3
|
||||||
@@ -135,8 +137,6 @@ wxUniv:
|
|||||||
- Fix wxComboBox::SetSelection(wxNOT_FOUND)
|
- Fix wxComboBox::SetSelection(wxNOT_FOUND)
|
||||||
- Fix setting background colour for controls with transparent background
|
- Fix setting background colour for controls with transparent background
|
||||||
|
|
||||||
>>>>>>> 1.1006.2.35
|
|
||||||
|
|
||||||
2.8.3
|
2.8.3
|
||||||
-----
|
-----
|
||||||
|
|
||||||
|
@@ -66,6 +66,10 @@ public:
|
|||||||
m_pos = m_str->length() / sizeof(wxChar);
|
m_pos = m_str->length() / sizeof(wxChar);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if wxABI_VERSION >= 20804 && wxUSE_UNICODE
|
||||||
|
virtual ~wxStringOutputStream();
|
||||||
|
#endif // wx 2.8.4+
|
||||||
|
|
||||||
// get the string containing current output
|
// get the string containing current output
|
||||||
const wxString& GetString() const { return *m_str; }
|
const wxString& GetString() const { return *m_str; }
|
||||||
|
|
||||||
|
@@ -37,8 +37,8 @@
|
|||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
// TODO: Do we want to include the null char in the stream? If so then
|
// TODO: Do we want to include the null char in the stream? If so then
|
||||||
// just add +1 to m_len in the ctor
|
// just add +1 to m_len in the ctor
|
||||||
wxStringInputStream::wxStringInputStream(const wxString& s)
|
wxStringInputStream::wxStringInputStream(const wxString& s)
|
||||||
#if wxUSE_UNICODE
|
#if wxUSE_UNICODE
|
||||||
: m_str(s), m_buf(wxMBConvUTF8().cWX2MB(s).release()), m_len(strlen(m_buf))
|
: m_str(s), m_buf(wxMBConvUTF8().cWX2MB(s).release()), m_len(strlen(m_buf))
|
||||||
#else
|
#else
|
||||||
@@ -63,9 +63,9 @@ wxStringInputStream::~wxStringInputStream()
|
|||||||
// getlength
|
// getlength
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
wxFileOffset wxStringInputStream::GetLength() const
|
wxFileOffset wxStringInputStream::GetLength() const
|
||||||
{
|
{
|
||||||
return m_len;
|
return m_len;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
@@ -149,13 +149,76 @@ wxFileOffset wxStringOutputStream::OnSysTell() const
|
|||||||
// actual IO
|
// actual IO
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
#if wxUSE_UNICODE
|
||||||
|
|
||||||
|
// we can't add a member to wxStringOutputStream in 2.8 branch without breaking
|
||||||
|
// backwards binary compatibility, so we emulate it by using a hash indexed by
|
||||||
|
// wxStringOutputStream pointers
|
||||||
|
|
||||||
|
// can't use wxCharBuffer as it has incorrect copying semantics and doesn't
|
||||||
|
// store the length which we need here
|
||||||
|
WX_DECLARE_VOIDPTR_HASH_MAP(wxMemoryBuffer, wxStringStreamUnconvBuffers);
|
||||||
|
|
||||||
|
static wxStringStreamUnconvBuffers gs_unconverted;
|
||||||
|
|
||||||
|
wxStringOutputStream::~wxStringOutputStream()
|
||||||
|
{
|
||||||
|
// TODO: check that nothing remains (i.e. the unconverted buffer is empty)?
|
||||||
|
gs_unconverted.erase(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // wxUSE_UNICODE
|
||||||
|
|
||||||
size_t wxStringOutputStream::OnSysWrite(const void *buffer, size_t size)
|
size_t wxStringOutputStream::OnSysWrite(const void *buffer, size_t size)
|
||||||
{
|
{
|
||||||
const char *p = wx_static_cast(const char *, buffer);
|
const char *p = wx_static_cast(const char *, buffer);
|
||||||
|
|
||||||
// append the input buffer (may not be null terminated - thus
|
#if wxUSE_UNICODE
|
||||||
// the literal length
|
// the part of the string we have here may be incomplete, i.e. it can stop
|
||||||
m_str->Append(wxString(p, m_conv, size));
|
// in the middle of an UTF-8 character and so converting it would fail; if
|
||||||
|
// this is the case, accumulate the part which we failed to convert until
|
||||||
|
// we get the rest (and also take into account the part which we might have
|
||||||
|
// left unconverted before)
|
||||||
|
const char *src;
|
||||||
|
size_t srcLen;
|
||||||
|
wxMemoryBuffer& unconv = gs_unconverted[this];
|
||||||
|
if ( unconv.GetDataLen() )
|
||||||
|
{
|
||||||
|
// append the new data to the data remaining since the last time
|
||||||
|
unconv.AppendData(p, size);
|
||||||
|
src = unconv;
|
||||||
|
srcLen = unconv.GetDataLen();
|
||||||
|
}
|
||||||
|
else // no unconverted data left, avoid extra copy
|
||||||
|
{
|
||||||
|
src = p;
|
||||||
|
srcLen = size;
|
||||||
|
}
|
||||||
|
|
||||||
|
wxWCharBuffer wbuf(m_conv.cMB2WC(src, srcLen, NULL /* out len */));
|
||||||
|
if ( wbuf )
|
||||||
|
{
|
||||||
|
// conversion succeeded, clear the unconverted buffer
|
||||||
|
unconv = wxMemoryBuffer(0);
|
||||||
|
|
||||||
|
*m_str += wbuf;
|
||||||
|
}
|
||||||
|
else // conversion failed
|
||||||
|
{
|
||||||
|
// remember unconverted data if there had been none before (otherwise
|
||||||
|
// we've already got it in the buffer)
|
||||||
|
if ( src == p )
|
||||||
|
unconv.AppendData(src, srcLen);
|
||||||
|
|
||||||
|
// pretend that we wrote the data anyhow, otherwise the caller would
|
||||||
|
// believe there was an error and this might not be the case, but do
|
||||||
|
// not update m_pos as m_str hasn't changed
|
||||||
|
return size;
|
||||||
|
}
|
||||||
|
#else // !wxUSE_UNICODE
|
||||||
|
// append directly, no conversion necessary
|
||||||
|
m_str->Append(wxString(p, size));
|
||||||
|
#endif // wxUSE_UNICODE/!wxUSE_UNICODE
|
||||||
|
|
||||||
// update position
|
// update position
|
||||||
m_pos += size;
|
m_pos += size;
|
||||||
|
Reference in New Issue
Block a user