{ assign(pwz, nLength); }
wxString(const wxScopedCharBuffer& buf)
- { assign(buf.data()); } // FIXME-UTF8: fix for embedded NUL and buffer length
+ { assign(buf.data(), buf.length()); }
wxString(const wxScopedWCharBuffer& buf)
- { assign(buf.data()); } // FIXME-UTF8: fix for embedded NUL and buffer length
+ { assign(buf.data(), buf.length()); }
// NB: this version uses m_impl.c_str() to force making a copy of the
// string, so that "wxString(str.c_str())" idiom for passing strings
#else
// wxStringImpl is either not std::string or needs conversion
operator wxStdWideString() const
- // FIXME-UTF8: broken for embedded NULs
- { return wxStdWideString(wc_str()); }
+ {
+ wxScopedWCharBuffer buf(wc_str());
+ return wxStdWideString(buf.data(), buf.length());
+ }
#endif
#if (!wxUSE_UNICODE || wxUSE_UTF8_LOCALE_ONLY) && wxUSE_STL_BASED_WXSTRING
#else
// wxStringImpl is either not std::string or needs conversion
operator std::string() const
- // FIXME-UTF8: broken for embedded NULs
- { return std::string(mb_str()); }
+ {
+ wxScopedCharBuffer buf(mb_str());
+ return std::string(buf.data(), buf.length());
+ }
#endif
#endif // wxUSE_STL
// from wxScopedWCharBuffer
wxString& operator=(const wxScopedWCharBuffer& s)
- { return operator=(s.data()); } // FIXME-UTF8: fix for embedded NULs
+ { return assign(s); }
// from wxScopedCharBuffer
wxString& operator=(const wxScopedCharBuffer& s)
- { return operator=(s.data()); } // FIXME-UTF8: fix for embedded NULs
+ { return assign(s); }
// string concatenation
// in place concatenation
// string += buffer (i.e. from wxGetString)
wxString& operator<<(const wxScopedWCharBuffer& s)
- { return operator<<((const wchar_t *)s); }
+ { return append(s); }
wxString& operator<<(const wxScopedCharBuffer& s)
- { return operator<<((const char *)s); }
+ { return append(s); }
// string += C string
wxString& Append(const wxString& s)
wxString& append(const wxCStrData& str)
{ return append(str.AsString()); }
wxString& append(const wxScopedCharBuffer& str)
- { return append(str.data()); }
+ { return append(str.data(), str.length()); }
wxString& append(const wxScopedWCharBuffer& str)
- { return append(str.data()); }
+ { return append(str.data(), str.length()); }
wxString& append(const wxCStrData& str, size_t n)
{ return append(str.AsString(), 0, n); }
wxString& append(const wxScopedCharBuffer& str, size_t n)
wxString& assign(const wxCStrData& str)
{ return assign(str.AsString()); }
wxString& assign(const wxScopedCharBuffer& str)
- { return assign(str.data()); }
+ { return assign(str.data(), str.length()); }
wxString& assign(const wxScopedWCharBuffer& str)
- { return assign(str.data()); }
+ { return assign(str.data(), str.length()); }
wxString& assign(const wxCStrData& str, size_t len)
{ return assign(str.AsString(), len); }
wxString& assign(const wxScopedCharBuffer& str, size_t len)
return *this;
}
wxString& operator+=(const wxScopedCharBuffer& s)
- { return operator+=(s.data()); }
+ { return append(s); }
wxString& operator+=(const wxScopedWCharBuffer& s)
- { return operator+=(s.data()); }
+ { return append(s); }
// string += char
wxString& operator+=(wxUniChar ch)
{
// we must pass the real string length to SubstrBufFromMB ctor
if ( nLength == npos )
nLength = psz ? strlen(psz) : 0;
- return SubstrBufFromMB(wxCharBuffer::CreateNonOwned(psz, nLength),
+ return SubstrBufFromMB(wxScopedCharBuffer::CreateNonOwned(psz, nLength),
nLength);
}
// else: do the roundtrip through wchar_t*
//Convert wxString in Unicode mode to a multi-byte string
const wxScopedCharBuffer wxString::mb_str(const wxMBConv& conv) const
{
- return conv.cWC2MB(wx_str(), length() + 1 /* size, not length */, NULL);
+ // NB: Length passed to cWC2MB() doesn't include terminating NUL, it's
+ // added by it automatically. If we passed length()+1 here, it would
+ // create a buffer with 2 trailing NULs of length one greater than
+ // expected.
+ return conv.cWC2MB(wx_str(), length(), NULL);
}
#elif wxUSE_UNICODE_UTF8
const wxScopedWCharBuffer wxString::wc_str() const
{
+ // NB: Length passed to cMB2WC() doesn't include terminating NUL, it's
+ // added by it automatically. If we passed length()+1 here, it would
+ // create a buffer with 2 trailing NULs of length one greater than
+ // expected.
return wxMBConvStrictUTF8().cMB2WC
(
m_impl.c_str(),
- m_impl.length() + 1, // size, not length
+ m_impl.length(),
NULL
);
}
if ( conv.IsUTF8() )
return wxScopedCharBuffer::CreateNonOwned(m_impl.c_str(), m_impl.length());
- // FIXME-UTF8: use wc_str() here once we have buffers with length
-
- size_t wcLen;
- wxScopedWCharBuffer wcBuf
- (
- wxMBConvStrictUTF8().cMB2WC
- (
- m_impl.c_str(),
- m_impl.length() + 1, // size
- &wcLen
- )
- );
- if ( !wcLen )
+ wxScopedWCharBuffer wcBuf(wc_str());
+ if ( !wcBuf.length() )
return wxCharBuffer("");
- return conv.cWC2MB(wcBuf, wcLen+1, NULL);
+ return conv.cWC2MB(wcBuf.data(), wcBuf.length(), NULL);
}
#else // ANSI
//mode is not enabled and wxUSE_WCHAR_T is enabled
const wxScopedWCharBuffer wxString::wc_str(const wxMBConv& conv) const
{
- return conv.cMB2WC(wx_str(), length() + 1 /* size, not length */, NULL);
+ // NB: Length passed to cMB2WC() doesn't include terminating NUL, it's
+ // added by it automatically. If we passed length()+1 here, it would
+ // create a buffer with 2 trailing NULs of length one greater than
+ // expected.
+ return conv.cMB2WC(wx_str(), length(), NULL);
}
#endif // Unicode/ANSI