Fix wxStringOutputStream position when using external string
Initialize m_pos correctly when using an existing, and hence possibly not empty, string (and not the internal one which is always empty initially). The old code was totally wrong as it divided the string length by the size of wxChar instead of multiplying by it, but doing this could have been wrong too with UTF-16 and surrogates, so use the conversion object to compute the real length of the string representation in the corresponding encoding. Add a simple unit test checking that this works as intended. Closes #17985.
This commit is contained in:
@@ -135,7 +135,14 @@ wxStringOutputStream::wxStringOutputStream(wxString *pString, wxMBConv& conv)
|
|||||||
#endif // wxUSE_UNICODE
|
#endif // wxUSE_UNICODE
|
||||||
{
|
{
|
||||||
m_str = pString ? pString : &m_strInternal;
|
m_str = pString ? pString : &m_strInternal;
|
||||||
m_pos = m_str->length() / sizeof(wxChar);
|
|
||||||
|
#if wxUSE_UNICODE_WCHAR
|
||||||
|
m_pos = m_conv.FromWChar(NULL, 0, m_str->wc_str(), m_str->length());
|
||||||
|
#elif wxUSE_UNICODE_UTF8
|
||||||
|
m_pos = m_str->utf8_length();
|
||||||
|
#else // !wxUSE_UNICODE
|
||||||
|
m_pos = m_str->length();
|
||||||
|
#endif // wxUSE_UNICODE/!wxUSE_UNICODE
|
||||||
}
|
}
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
|
@@ -119,3 +119,32 @@ void strStream::Output_Check()
|
|||||||
|
|
||||||
// Register the stream sub suite, by using some stream helper macro.
|
// Register the stream sub suite, by using some stream helper macro.
|
||||||
STREAM_TEST_SUBSUITE_NAMED_REGISTRATION(strStream)
|
STREAM_TEST_SUBSUITE_NAMED_REGISTRATION(strStream)
|
||||||
|
|
||||||
|
TEST_CASE("wxStringOutputStream::Tell", "[stream]")
|
||||||
|
{
|
||||||
|
wxStringOutputStream ss;
|
||||||
|
CHECK( ss.TellO() == 0 );
|
||||||
|
|
||||||
|
const char* const s = "Hello world";
|
||||||
|
const wxFileOffset len = strlen(s);
|
||||||
|
|
||||||
|
ss.Write(s, len);
|
||||||
|
CHECK( ss.TellO() == len );
|
||||||
|
|
||||||
|
wxString str(s);
|
||||||
|
CHECK( wxStringOutputStream(&str).TellO() == len );
|
||||||
|
|
||||||
|
|
||||||
|
wxMBConvUTF16 convUTF16;
|
||||||
|
wxStringOutputStream ss16(NULL, convUTF16);
|
||||||
|
CHECK( ss16.TellO() == 0 );
|
||||||
|
|
||||||
|
const wxCharBuffer s16 = convUTF16.cWC2MB(wxWCharBuffer(str.wc_str()));
|
||||||
|
ss16.Write(s16, s16.length());
|
||||||
|
CHECK( ss16.TellO() == 2*len );
|
||||||
|
CHECK( wxStringOutputStream(&str, convUTF16).TellO() == 2*len );
|
||||||
|
|
||||||
|
// The U+2070D character is represented by a surrogate pair in UTF-16.
|
||||||
|
wxString u2070D = wxString::FromUTF8("\xF0\xA0\x9C\x8D");
|
||||||
|
CHECK( wxStringOutputStream(&u2070D, convUTF16).TellO() == 4 );
|
||||||
|
}
|
||||||
|
Reference in New Issue
Block a user