diff --git a/include/wx/string.h b/include/wx/string.h index 3f4fe1a6bf..1de67ef9c5 100644 --- a/include/wx/string.h +++ b/include/wx/string.h @@ -2787,12 +2787,6 @@ public: : m_str(str), m_buf(lenWanted), m_len(0), m_lenSet(false) { } - ~wxStringTypeBufferLengthBase() - { - wxASSERT(m_lenSet); - m_str.assign(m_buf.data(), m_len); - } - operator CharType*() { return m_buf.data(); } void SetLength(size_t length) { m_len = length; m_lenSet = true; } @@ -2870,6 +2864,33 @@ typedef wxStringInternalBuffer wxStringBuffer; typedef wxStringInternalBufferLength wxStringBufferLength; #endif // !wxUSE_STL_BASED_WXSTRING && !wxUSE_UNICODE_UTF8 +#if wxUSE_UNICODE_UTF8 && !wxUSE_STL_BASED_WXSTRING +typedef wxStringInternalBuffer wxUTF8StringBuffer; +typedef wxStringInternalBufferLength wxUTF8StringBufferLength; +#elif wxUSE_UNICODE // !wxUSE_UNICODE_UTF8 || wxUSE_STL_BASED_WXSTRING +class WXDLLIMPEXP_BASE wxUTF8StringBuffer : public wxStringTypeBufferBase +{ +public: + wxUTF8StringBuffer(wxString& str, size_t lenWanted = 1024) + : wxStringTypeBufferBase(str, lenWanted) {} + ~wxUTF8StringBuffer(); + + DECLARE_NO_COPY_CLASS(wxUTF8StringBuffer) +}; + +class WXDLLIMPEXP_BASE wxUTF8StringBufferLength + : public wxStringTypeBufferLengthBase +{ +public: + wxUTF8StringBufferLength(wxString& str, size_t lenWanted = 1024) + : wxStringTypeBufferLengthBase(str, lenWanted) {} + ~wxUTF8StringBufferLength(); + + DECLARE_NO_COPY_CLASS(wxUTF8StringBufferLength) +}; +#endif // wxUSE_UNICODE_UTF8 && !wxUSE_STL_BASED_WXSTRING or not + + // --------------------------------------------------------------------------- // wxString comparison functions: operator versions are always case sensitive // --------------------------------------------------------------------------- diff --git a/src/common/string.cpp b/src/common/string.cpp index d154b3c937..852ea132ec 100644 --- a/src/common/string.cpp +++ b/src/common/string.cpp @@ -1832,3 +1832,32 @@ wxString wxString::Upper() const // convert to lower case, return the copy of the string wxString wxString::Lower() const { wxString s(*this); return s.MakeLower(); } + +// ---------------------------------------------------------------------------- +// wxUTF8StringBuffer +// ---------------------------------------------------------------------------- + +#if wxUSE_UNICODE && (!wxUSE_UNICODE_UTF8 || wxUSE_STL_BASED_WXSTRING) +wxUTF8StringBuffer::~wxUTF8StringBuffer() +{ + wxMBConvStrictUTF8 conv; + size_t wlen = conv.ToWChar(NULL, 0, m_buf); + wxCHECK_RET( wlen != wxCONV_FAILED, "invalid UTF-8 data in string buffer?" ); + + wxStringInternalBuffer wbuf(m_str, wlen); + conv.ToWChar(wbuf, wlen, m_buf); +} + +wxUTF8StringBufferLength::~wxUTF8StringBufferLength() +{ + wxCHECK_RET(m_lenSet, "length not set"); + + wxMBConvStrictUTF8 conv; + size_t wlen = conv.ToWChar(NULL, 0, m_buf, m_len); + wxCHECK_RET( wlen != wxCONV_FAILED, "invalid UTF-8 data in string buffer?" ); + + wxStringInternalBufferLength wbuf(m_str, wlen); + conv.ToWChar(wbuf, wlen, m_buf, m_len); + wbuf.SetLength(wlen); +} +#endif // wxUSE_UNICODE && (!wxUSE_UNICODE_UTF8 || wxUSE_STL_BASED_WXSTRING) diff --git a/tests/strings/strings.cpp b/tests/strings/strings.cpp index 473f81714f..03afb67675 100644 --- a/tests/strings/strings.cpp +++ b/tests/strings/strings.cpp @@ -53,6 +53,7 @@ private: #endif // wxLongLong_t CPPUNIT_TEST( ToDouble ); CPPUNIT_TEST( WriteBuf ); + CPPUNIT_TEST( UTF8Buf ); CPPUNIT_TEST( CStrDataTernaryOperator ); CPPUNIT_TEST( CStrDataOperators ); CPPUNIT_TEST( CStrDataImplicitConversion ); @@ -80,6 +81,7 @@ private: #endif // wxLongLong_t void ToDouble(); void WriteBuf(); + void UTF8Buf(); void CStrDataTernaryOperator(); void DoCStrDataTernaryOperator(bool cond); void CStrDataOperators(); @@ -676,6 +678,26 @@ void StringTestCase::WriteBuf() CPPUNIT_ASSERT_EQUAL( 0, wxStrcmp(_T("barr"), s) ); } +void StringTestCase::UTF8Buf() +{ +#if wxUSE_UNICODE + // "czech" in Czech ("cestina"): + static const char *textUTF8 = "\304\215e\305\241tina"; + static const wchar_t textUTF16[] = {0x10D, 0x65, 0x161, 0x74, 0x69, 0x6E, 0x61, 0}; + + wxString s; + wxStrcpy(wxUTF8StringBuffer(s, 9), textUTF8); + CPPUNIT_ASSERT(s == textUTF16); + + { + wxUTF8StringBufferLength buf(s, 20); + wxStrcpy(buf, textUTF8); + buf.SetLength(5); + } + CPPUNIT_ASSERT(s == wxString(textUTF16, 0, 3)); +#endif // wxUSE_UNICODE +} + void StringTestCase::CStrDataTernaryOperator()