Fix wxMBConv::cWC2MB() and cMB2WC() returned buffer length
This commit refactors the overloads of cMB2WC() and cWC2MB() methods taking raw pointers and buffers to reuse the same code and fixes the wrong length of the buffer returned by cWC2MB(wchar_t*) overload for conversions using multiple bytes to represent the NUL terminator character (it previously was wrong for UTF-16 and UTF-32 conversions due to wrongly subtracting 1 from the length when creating it instead of correctly subtracting GetMBNulLen()) and the wrong length of the buffer returned from cMB2WC(char*) overload where no adjustment for the trailing NUL was done at all. Also return simple default-constructed buffers from these methods in case of failure instead of using wxScopedCharBuffer::CreateNonOwned() which is less obvious and less efficient (even if the latter probably doesn't matter here because it's only done in case of an error). Finally, add tests checking that using WC2MB() or either of cWC2MB() overloads returns the buffers of the same length and with the same contents.
This commit is contained in:
@@ -394,42 +394,6 @@ size_t wxMBConv::WC2MB(char *outBuff, const wchar_t *inBuff, size_t outLen) cons
|
||||
return rc;
|
||||
}
|
||||
|
||||
wxWCharBuffer wxMBConv::cMB2WC(const char *psz) const
|
||||
{
|
||||
if ( psz )
|
||||
{
|
||||
// calculate the length of the buffer needed first
|
||||
const size_t nLen = ToWChar(NULL, 0, psz);
|
||||
if ( nLen != wxCONV_FAILED )
|
||||
{
|
||||
// now do the actual conversion
|
||||
wxWCharBuffer buf(nLen - 1 /* +1 added implicitly */);
|
||||
|
||||
// +1 for the trailing NULL
|
||||
if ( ToWChar(buf.data(), nLen, psz) != wxCONV_FAILED )
|
||||
return buf;
|
||||
}
|
||||
}
|
||||
|
||||
return wxWCharBuffer();
|
||||
}
|
||||
|
||||
wxCharBuffer wxMBConv::cWC2MB(const wchar_t *pwz) const
|
||||
{
|
||||
if ( pwz )
|
||||
{
|
||||
const size_t nLen = FromWChar(NULL, 0, pwz);
|
||||
if ( nLen != wxCONV_FAILED )
|
||||
{
|
||||
wxCharBuffer buf(nLen - 1);
|
||||
if ( FromWChar(buf.data(), nLen, pwz) != wxCONV_FAILED )
|
||||
return buf;
|
||||
}
|
||||
}
|
||||
|
||||
return wxCharBuffer();
|
||||
}
|
||||
|
||||
wxWCharBuffer
|
||||
wxMBConv::cMB2WC(const char *inBuff, size_t inLen, size_t *outLen) const
|
||||
{
|
||||
@@ -506,10 +470,13 @@ wxMBConv::cWC2MB(const wchar_t *inBuff, size_t inLen, size_t *outLen) const
|
||||
return wxCharBuffer();
|
||||
}
|
||||
|
||||
wxWCharBuffer wxMBConv::cMB2WC(const wxScopedCharBuffer& buf) const
|
||||
wxWCharBuffer wxMBConv::DoConvertMB2WC(const char* buf, size_t srcLen) const
|
||||
{
|
||||
const size_t srcLen = buf.length();
|
||||
if ( srcLen )
|
||||
// Notice that converting NULL pointer should work, i.e. return an empty
|
||||
// buffer instead of crashing, so we need to check both the length and the
|
||||
// pointer because length is wxNO_LEN if it's a raw pointer and doesn't
|
||||
// come from wxScopedCharBuffer.
|
||||
if ( srcLen && buf )
|
||||
{
|
||||
const size_t dstLen = ToWChar(NULL, 0, buf, srcLen);
|
||||
if ( dstLen != wxCONV_FAILED )
|
||||
@@ -517,17 +484,24 @@ wxWCharBuffer wxMBConv::cMB2WC(const wxScopedCharBuffer& buf) const
|
||||
wxWCharBuffer wbuf(dstLen);
|
||||
wbuf.data()[dstLen] = L'\0';
|
||||
if ( ToWChar(wbuf.data(), dstLen, buf, srcLen) != wxCONV_FAILED )
|
||||
{
|
||||
// If the input string was NUL-terminated, we shouldn't include
|
||||
// the length of the trailing NUL into the length of the return
|
||||
// value.
|
||||
if ( srcLen == wxNO_LEN )
|
||||
wbuf.shrink(dstLen - 1);
|
||||
|
||||
return wbuf;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return wxScopedWCharBuffer::CreateNonOwned(L"", 0);
|
||||
return wxWCharBuffer();
|
||||
}
|
||||
|
||||
wxCharBuffer wxMBConv::cWC2MB(const wxScopedWCharBuffer& wbuf) const
|
||||
wxCharBuffer wxMBConv::DoConvertWC2MB(const wchar_t* wbuf, size_t srcLen) const
|
||||
{
|
||||
const size_t srcLen = wbuf.length();
|
||||
if ( srcLen )
|
||||
if ( srcLen && wbuf )
|
||||
{
|
||||
const size_t dstLen = FromWChar(NULL, 0, wbuf, srcLen);
|
||||
if ( dstLen != wxCONV_FAILED )
|
||||
@@ -535,11 +509,18 @@ wxCharBuffer wxMBConv::cWC2MB(const wxScopedWCharBuffer& wbuf) const
|
||||
wxCharBuffer buf(dstLen);
|
||||
buf.data()[dstLen] = '\0';
|
||||
if ( FromWChar(buf.data(), dstLen, wbuf, srcLen) != wxCONV_FAILED )
|
||||
{
|
||||
// As above, in DoConvertMB2WC(), except that the length of the
|
||||
// trailing NUL is variable in this case.
|
||||
if ( srcLen == wxNO_LEN )
|
||||
buf.shrink(dstLen - GetMBNulLen());
|
||||
|
||||
return buf;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return wxScopedCharBuffer::CreateNonOwned("", 0);
|
||||
return wxCharBuffer();
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
Reference in New Issue
Block a user