]> git.saurik.com Git - wxWidgets.git/blobdiff - src/common/strconv.cpp
non-pch build fix for wxUSE_DISPLAY==0
[wxWidgets.git] / src / common / strconv.cpp
index 91186b40c69db828d9b9d909546ed28bb6653b15..3e354f466b668ab41e01c581f0bea6af1df5ac2a 100644 (file)
@@ -391,7 +391,11 @@ wxMBConv::cMB2WC(const char *inBuff, size_t inLen, size_t *outLen) const
     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 )
@@ -417,16 +421,18 @@ wxMBConv::cWC2MB(const wchar_t *inBuff, size_t inLen, size_t *outLen) const
     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) )
                 {
@@ -983,14 +989,15 @@ wxMBConvStrictUTF8::FromWChar(char *dst, size_t dstLen,
     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;
@@ -1124,10 +1131,10 @@ size_t wxMBConvUTF8::MB2WC(wchar_t *buf, const char *psz, size_t n) const
         }
     }
 
-    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)
@@ -1135,14 +1142,15 @@ 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;
 
@@ -1210,10 +1218,10 @@ size_t wxMBConvUTF8::WC2MB(char *buf, const wchar_t *psz, size_t n) const
         }
     }
 
-    if (buf && (len < n))
+    if (srcLen == wxNO_LEN && buf && (len < n))
         *buf = 0;
 
-    return len;
+    return len + 1;
 }
 
 // ============================================================================
@@ -2449,8 +2457,10 @@ public:
                     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
@@ -3188,8 +3198,14 @@ wxCharBuffer wxSafeConvertWX2MB(const wchar_t *ws)
     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));