final cleanup of string conversion with null characters (hopefully :))
git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@30320 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
parent
0c6099b79e
commit
f5fb687186
@ -46,17 +46,17 @@ public:
|
|||||||
virtual size_t MB2WC(wchar_t *outputBuf, const char *psz, size_t outputSize) const = 0;
|
virtual size_t MB2WC(wchar_t *outputBuf, const char *psz, size_t outputSize) const = 0;
|
||||||
virtual size_t WC2MB(char *outputBuf, const wchar_t *psz, size_t outputSize) const = 0;
|
virtual size_t WC2MB(char *outputBuf, const wchar_t *psz, size_t outputSize) const = 0;
|
||||||
|
|
||||||
// actual conversion for strings with embedded null characters
|
|
||||||
//
|
|
||||||
// outputSize is the size of the output buffer
|
|
||||||
// pszLen is the length of the input string (including all but last null character)
|
|
||||||
size_t MB2WC(wchar_t *outputBuf, const char *psz, size_t outputSize, size_t pszLen) const;
|
|
||||||
size_t WC2MB(char *outputBuf, const wchar_t *psz, size_t outputSize, size_t pszLen) const;
|
|
||||||
|
|
||||||
// MB <-> WC
|
// MB <-> WC
|
||||||
const wxWCharBuffer cMB2WC(const char *psz) const;
|
const wxWCharBuffer cMB2WC(const char *psz) const;
|
||||||
const wxCharBuffer cWC2MB(const wchar_t *psz) const;
|
const wxCharBuffer cWC2MB(const wchar_t *psz) const;
|
||||||
|
|
||||||
|
// MB <-> WC for strings with embedded null characters
|
||||||
|
//
|
||||||
|
// pszLen length of the input string
|
||||||
|
// pOutSize gets the final size of the converted string
|
||||||
|
const wxWCharBuffer cMB2WC(const char *psz, size_t pszLen, size_t* pOutSize) const;
|
||||||
|
const wxCharBuffer cWC2MB(const wchar_t *psz, size_t pszLen, size_t* pOutSize) const;
|
||||||
|
|
||||||
// convenience functions for converting MB or WC to/from wxWin default
|
// convenience functions for converting MB or WC to/from wxWin default
|
||||||
#if wxUSE_UNICODE
|
#if wxUSE_UNICODE
|
||||||
const wxWCharBuffer cMB2WX(const char *psz) const { return cMB2WC(psz); }
|
const wxWCharBuffer cMB2WX(const char *psz) const { return cMB2WC(psz); }
|
||||||
|
@ -217,14 +217,18 @@ const wxCharBuffer wxMBConv::cWC2MB(const wchar_t *pwz) const
|
|||||||
return buf;
|
return buf;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t wxMBConv::MB2WC(wchar_t* szBuffer, const char* szString,
|
const wxWCharBuffer wxMBConv::cMB2WC(const char *szString, size_t nStringLen, size_t* pOutSize) const
|
||||||
size_t outsize, size_t nStringLen) const
|
|
||||||
{
|
{
|
||||||
|
wxASSERT(pOutSize != NULL);
|
||||||
|
|
||||||
const char* szEnd = szString + nStringLen + 1;
|
const char* szEnd = szString + nStringLen + 1;
|
||||||
const char* szPos = szString;
|
const char* szPos = szString;
|
||||||
const char* szStart = szPos;
|
const char* szStart = szPos;
|
||||||
|
|
||||||
size_t nActualLength = 0;
|
size_t nActualLength = 0;
|
||||||
|
size_t nCurrentSize = nStringLen; //try normal size first (should never resize?)
|
||||||
|
|
||||||
|
wxWCharBuffer theBuffer(nCurrentSize);
|
||||||
|
|
||||||
//Convert the string until the length() is reached, continuing the
|
//Convert the string until the length() is reached, continuing the
|
||||||
//loop every time a null character is reached
|
//loop every time a null character is reached
|
||||||
@ -237,18 +241,31 @@ size_t wxMBConv::MB2WC(wchar_t* szBuffer, const char* szString,
|
|||||||
|
|
||||||
//Invalid conversion?
|
//Invalid conversion?
|
||||||
if( nLen == (size_t)-1 )
|
if( nLen == (size_t)-1 )
|
||||||
return nLen;
|
{
|
||||||
|
*pOutSize = 0;
|
||||||
|
theBuffer.data()[0u] = wxT('\0');
|
||||||
|
return theBuffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
//Increase the actual length (+1 for current null character)
|
//Increase the actual length (+1 for current null character)
|
||||||
nActualLength += nLen + 1;
|
nActualLength += nLen + 1;
|
||||||
|
|
||||||
//Only copy data in if buffer size is big enough
|
//if buffer too big, realloc the buffer
|
||||||
if (szBuffer != NULL &&
|
if (nActualLength > (nCurrentSize+1))
|
||||||
nActualLength <= outsize)
|
|
||||||
{
|
{
|
||||||
//Convert the current (sub)string
|
wxWCharBuffer theNewBuffer(nCurrentSize << 1);
|
||||||
if ( MB2WC(&szBuffer[szPos - szStart], szPos, nLen + 1) == (size_t)-1 )
|
memcpy(theNewBuffer.data(), theBuffer.data(), nCurrentSize * sizeof(wchar_t));
|
||||||
return (size_t)-1;
|
theBuffer = theNewBuffer;
|
||||||
|
nCurrentSize <<= 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Convert the current (sub)string
|
||||||
|
if ( MB2WC(&theBuffer.data()[szPos - szStart], szPos, nLen + 1) == (size_t)-1 )
|
||||||
|
{
|
||||||
|
*pOutSize = 0;
|
||||||
|
theBuffer.data()[0u] = wxT('\0');
|
||||||
|
return theBuffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
//Increment to next (sub)string
|
//Increment to next (sub)string
|
||||||
@ -258,17 +275,23 @@ size_t wxMBConv::MB2WC(wchar_t* szBuffer, const char* szString,
|
|||||||
szPos += strlen(szPos) + 1;
|
szPos += strlen(szPos) + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
return nActualLength - 1; //success - return actual length
|
//success - return actual length and the buffer
|
||||||
|
*pOutSize = nActualLength;
|
||||||
|
return theBuffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t wxMBConv::WC2MB(char* szBuffer, const wchar_t* szString,
|
const wxCharBuffer wxMBConv::cWC2MB(const wchar_t *szString, size_t nStringLen, size_t* pOutSize) const
|
||||||
size_t outsize, size_t nStringLen) const
|
|
||||||
{
|
{
|
||||||
|
wxASSERT(pOutSize != NULL);
|
||||||
|
|
||||||
const wchar_t* szEnd = szString + nStringLen + 1;
|
const wchar_t* szEnd = szString + nStringLen + 1;
|
||||||
const wchar_t* szPos = szString;
|
const wchar_t* szPos = szString;
|
||||||
const wchar_t* szStart = szPos;
|
const wchar_t* szStart = szPos;
|
||||||
|
|
||||||
size_t nActualLength = 0;
|
size_t nActualLength = 0;
|
||||||
|
size_t nCurrentSize = nStringLen << 2; //try * 4 first
|
||||||
|
|
||||||
|
wxCharBuffer theBuffer(nCurrentSize);
|
||||||
|
|
||||||
//Convert the string until the length() is reached, continuing the
|
//Convert the string until the length() is reached, continuing the
|
||||||
//loop every time a null character is reached
|
//loop every time a null character is reached
|
||||||
@ -281,18 +304,30 @@ size_t wxMBConv::WC2MB(char* szBuffer, const wchar_t* szString,
|
|||||||
|
|
||||||
//Invalid conversion?
|
//Invalid conversion?
|
||||||
if( nLen == (size_t)-1 )
|
if( nLen == (size_t)-1 )
|
||||||
return nLen;
|
{
|
||||||
|
*pOutSize = 0;
|
||||||
|
theBuffer.data()[0u] = wxT('\0');
|
||||||
|
return theBuffer;
|
||||||
|
}
|
||||||
|
|
||||||
//Increase the actual length (+1 for current null character)
|
//Increase the actual length (+1 for current null character)
|
||||||
nActualLength += nLen + 1;
|
nActualLength += nLen + 1;
|
||||||
|
|
||||||
//Only copy data in if buffer size is big enough
|
//if buffer too big, realloc the buffer
|
||||||
if (szBuffer != NULL &&
|
if (nActualLength > (nCurrentSize+1))
|
||||||
nActualLength <= outsize)
|
|
||||||
{
|
{
|
||||||
//Convert the current (sub)string
|
wxCharBuffer theNewBuffer(nCurrentSize << 1);
|
||||||
if(WC2MB(&szBuffer[szPos - szStart], szPos, nLen + 1) == (size_t)-1 )
|
memcpy(theNewBuffer.data(), theBuffer.data(), nCurrentSize);
|
||||||
return (size_t)-1;
|
theBuffer = theNewBuffer;
|
||||||
|
nCurrentSize <<= 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Convert the current (sub)string
|
||||||
|
if(WC2MB(&theBuffer.data()[szPos - szStart], szPos, nLen + 1) == (size_t)-1 )
|
||||||
|
{
|
||||||
|
*pOutSize = 0;
|
||||||
|
theBuffer.data()[0u] = wxT('\0');
|
||||||
|
return theBuffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
//Increment to next (sub)string
|
//Increment to next (sub)string
|
||||||
@ -302,7 +337,9 @@ size_t wxMBConv::WC2MB(char* szBuffer, const wchar_t* szString,
|
|||||||
szPos += wxWcslen(szPos) + 1;
|
szPos += wxWcslen(szPos) + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
return nActualLength - 1; //success - return actual length
|
//success - return actual length and the buffer
|
||||||
|
*pOutSize = nActualLength;
|
||||||
|
return theBuffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
|
@ -1028,45 +1028,21 @@ wxString::wxString(const char *psz, wxMBConv& conv, size_t nLength)
|
|||||||
// anything to do?
|
// anything to do?
|
||||||
if ( (nLen != 0) && (nLen != (size_t)-1) )
|
if ( (nLen != 0) && (nLen != (size_t)-1) )
|
||||||
{
|
{
|
||||||
//Get length of converted string
|
//Convert string
|
||||||
size_t dwConvLen = conv.MB2WC(NULL, psz, 0, nLen);
|
size_t nRealSize;
|
||||||
|
wxWCharBuffer theBuffer = conv.cMB2WC(psz, nLen, &nRealSize);
|
||||||
|
|
||||||
//if valid, do the conversion
|
//Copy
|
||||||
if (dwConvLen != (size_t) -1)
|
if (nRealSize)
|
||||||
{
|
assign( theBuffer.data() , nRealSize - 1 );
|
||||||
//Get internal buffer
|
|
||||||
wxStringBufferLength internalBuffer(*this, dwConvLen + 1);
|
|
||||||
|
|
||||||
//Do the actual conversion & Set the length of the buffer
|
|
||||||
internalBuffer.SetLength(
|
|
||||||
conv.MB2WC(internalBuffer, psz, dwConvLen + 1, nLen)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//Convert wxString in Unicode mode to a multi-byte string
|
//Convert wxString in Unicode mode to a multi-byte string
|
||||||
const wxCharBuffer wxString::mb_str(wxMBConv& conv) const
|
const wxCharBuffer wxString::mb_str(wxMBConv& conv) const
|
||||||
{
|
{
|
||||||
//Get length of converted string
|
size_t dwOutSize;
|
||||||
size_t dwConvLen = conv.WC2MB(NULL, (*this).c_str(), 0, length());
|
return conv.cWC2MB(c_str(), length(), &dwOutSize);
|
||||||
|
|
||||||
//if valid, do the conversion
|
|
||||||
if (dwConvLen != (size_t) -1)
|
|
||||||
{
|
|
||||||
//Create good buffer
|
|
||||||
wxCharBuffer buffer(dwConvLen + 1);
|
|
||||||
|
|
||||||
//Do the actual conversion
|
|
||||||
conv.WC2MB(buffer.data(), (*this).c_str(), dwConvLen + 1, length());
|
|
||||||
|
|
||||||
return buffer;
|
|
||||||
}
|
|
||||||
|
|
||||||
//create bogus buffer
|
|
||||||
wxCharBuffer buffer(1);
|
|
||||||
buffer.data()[0u] = 0;
|
|
||||||
return buffer;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#else // ANSI
|
#else // ANSI
|
||||||
@ -1108,20 +1084,13 @@ wxString::wxString(const wchar_t *pwz, wxMBConv& conv, size_t nLength)
|
|||||||
// anything to do?
|
// anything to do?
|
||||||
if ( (nLen != 0) && (nLen != (size_t)-1) )
|
if ( (nLen != 0) && (nLen != (size_t)-1) )
|
||||||
{
|
{
|
||||||
//Get length of converted string
|
//Convert string
|
||||||
size_t dwConvLen = conv.WC2MB(NULL, pwz, 0, nLen);
|
size_t nRealSize;
|
||||||
|
wxCharBuffer theBuffer = conv.cWC2MB(pwz, nLen, &nRealSize);
|
||||||
|
|
||||||
//if valid, do the conversion
|
//Copy
|
||||||
if (dwConvLen != (size_t) -1)
|
if (nRealSize)
|
||||||
{
|
assign( theBuffer.data() , nRealSize - 1 );
|
||||||
//Get internal buffer
|
|
||||||
wxStringBufferLength internalBuffer(*this, dwConvLen + 1);
|
|
||||||
|
|
||||||
//Do the actual conversion & Set the length of the buffer
|
|
||||||
internalBuffer.SetLength(
|
|
||||||
conv.WC2MB(internalBuffer, pwz, dwConvLen + 1, nLen)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1129,25 +1098,8 @@ wxString::wxString(const wchar_t *pwz, wxMBConv& conv, size_t nLength)
|
|||||||
//mode is not enabled and wxUSE_WCHAR_T is enabled
|
//mode is not enabled and wxUSE_WCHAR_T is enabled
|
||||||
const wxWCharBuffer wxString::wc_str(wxMBConv& conv) const
|
const wxWCharBuffer wxString::wc_str(wxMBConv& conv) const
|
||||||
{
|
{
|
||||||
//Get length of converted string
|
size_t dwOutSize;
|
||||||
size_t dwConvLen = conv.MB2WC(NULL, (*this).c_str(), 0, length());
|
return conv.cMB2WC(c_str(), length(), &dwOutSize);
|
||||||
|
|
||||||
//if valid, do the conversion
|
|
||||||
if (dwConvLen != (size_t) -1)
|
|
||||||
{
|
|
||||||
//Create good buffer
|
|
||||||
wxWCharBuffer buffer(dwConvLen + 1);
|
|
||||||
|
|
||||||
//Do the actual conversion
|
|
||||||
conv.MB2WC(buffer.data(), (*this).c_str(), dwConvLen + 1, length());
|
|
||||||
|
|
||||||
return buffer;
|
|
||||||
}
|
|
||||||
|
|
||||||
//create bogus buffer
|
|
||||||
wxWCharBuffer buffer(1);
|
|
||||||
buffer.data()[0u] = 0;
|
|
||||||
return buffer;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // wxUSE_WCHAR_T
|
#endif // wxUSE_WCHAR_T
|
||||||
|
Loading…
Reference in New Issue
Block a user