const size_t dstLen = ToWChar(NULL, 0, inBuff, inLen);
if ( dstLen != wxCONV_FAILED )
{
- wxWCharBuffer wbuf(dstLen - 1);
+ // notice that we allocate space for dstLen+1 wide characters here
+ // because we want the buffer to always be NUL-terminated, even if the
+ // input isn't (as otherwise the caller has no way to know its length)
+ wxWCharBuffer wbuf(dstLen);
+ wbuf.data()[dstLen - 1] = L'\0';
if ( ToWChar(wbuf.data(), dstLen, inBuff, inLen) != wxCONV_FAILED )
{
if ( outLen )
size_t dstLen = FromWChar(NULL, 0, inBuff, inLen);
if ( dstLen != wxCONV_FAILED )
{
- // special case of empty input: can't allocate 0 size buffer below as
- // wxCharBuffer insists on NUL-terminating it
- wxCharBuffer buf(dstLen ? dstLen - 1 : 1);
+ const size_t nulLen = GetMBNulLen();
+
+ // as above, ensure that the buffer is always NUL-terminated, even if
+ // the input is not
+ wxCharBuffer buf(dstLen + nulLen - 1);
+ memset(buf.data() + dstLen, 0, nulLen);
if ( FromWChar(buf.data(), dstLen, inBuff, inLen) != wxCONV_FAILED )
{
if ( outLen )
{
*outLen = dstLen;
- const size_t nulLen = GetMBNulLen();
if ( dstLen >= nulLen &&
!NotAllNULs(buf.data() + dstLen - nulLen, nulLen) )
{
return wxCONV_FAILED;
}
-size_t wxMBConvUTF8::MB2WC(wchar_t *buf, const char *psz, size_t n) const
+size_t wxMBConvUTF8::ToWChar(wchar_t *buf, size_t n,
+ const char *psz, size_t srcLen) const
{
if ( m_options == MAP_INVALID_UTF8_NOT )
- return wxMBConvStrictUTF8::MB2WC(buf, psz, n);
+ return wxMBConvStrictUTF8::ToWChar(buf, n, psz, srcLen);
size_t len = 0;
- while (*psz && ((!buf) || (len < n)))
+ while ((srcLen == wxNO_LEN ? *psz : srcLen--) && ((!buf) || (len < n)))
{
const char *opsz = psz;
bool invalid = false;
}
}
- if (buf && (len < n))
+ if (srcLen == wxNO_LEN && buf && (len < n))
*buf = 0;
- return len;
+ return len + 1;
}
static inline bool isoctal(wchar_t wch)
return L'0' <= wch && wch <= L'7';
}
-size_t wxMBConvUTF8::WC2MB(char *buf, const wchar_t *psz, size_t n) const
+size_t wxMBConvUTF8::FromWChar(char *buf, size_t n,
+ const wchar_t *psz, size_t srcLen) const
{
if ( m_options == MAP_INVALID_UTF8_NOT )
- return wxMBConvStrictUTF8::WC2MB(buf, psz, n);
+ return wxMBConvStrictUTF8::FromWChar(buf, n, psz, srcLen);
size_t len = 0;
- while (*psz && ((!buf) || (len < n)))
+ while ((srcLen == wxNO_LEN ? *psz : srcLen--) && ((!buf) || (len < n)))
{
wxUint32 cc;
}
}
- if (buf && (len < n))
+ if (srcLen == wxNO_LEN && buf && (len < n))
*buf = 0;
- return len;
+ return len + 1;
}
// ============================================================================
return wxCONV_FAILED;
}
+ if ( !n )
+ n = wcslen(pwz);
wxWCharBuffer wcBuf(n);
- if ( MB2WC(wcBuf.data(), buf, n) == wxCONV_FAILED ||
+ if ( MB2WC(wcBuf.data(), buf, n + 1) == wxCONV_FAILED ||
wcscmp(wcBuf, pwz) != 0 )
{
// we didn't obtain the same thing we started from, hence
WX_DEFINE_GLOBAL_CONV2(wxMBConv, wxMBConvLibc, wxConvLibc, wxEMPTY_PARAMETER_VALUE);
#endif
-WX_DEFINE_GLOBAL_CONV(wxMBConvStrictUTF8, wxConvUTF8, wxEMPTY_PARAMETER_VALUE);
-WX_DEFINE_GLOBAL_CONV(wxMBConvUTF7, wxConvUTF7, wxEMPTY_PARAMETER_VALUE);
+// NB: we can't use wxEMPTY_PARAMETER_VALUE as final argument here because it's
+// passed to WX_DEFINE_GLOBAL_CONV2 after a macro expansion and so still
+// provokes an error message about "not enough macro parameters"; and we
+// can't use "()" here as the name##Obj declaration would be parsed as a
+// function declaration then, so use a semicolon and live with an extra
+// empty statement (and hope that no compilers warns about this)
+WX_DEFINE_GLOBAL_CONV(wxMBConvStrictUTF8, wxConvUTF8, ;);
+WX_DEFINE_GLOBAL_CONV(wxMBConvUTF7, wxConvUTF7, ;);
WX_DEFINE_GLOBAL_CONV(wxCSConv, wxConvLocal, (wxFONTENCODING_SYSTEM));
WX_DEFINE_GLOBAL_CONV(wxCSConv, wxConvISO8859_1, (wxFONTENCODING_ISO8859_1));