]> git.saurik.com Git - wxWidgets.git/blobdiff - src/common/string.cpp
assert that wxRound() argument is in the supported range
[wxWidgets.git] / src / common / string.cpp
index 25f604519ca24d0ae0aeb8e63cee53635ad854c9..717ce0b52c8cd0e754c9e2af7f4387b85464d74f 100644 (file)
@@ -23,6 +23,7 @@
 
 #ifndef WX_PRECOMP
     #include "wx/string.h"
+    #include "wx/wxcrtvararg.h"
 #endif
 
 #include <ctype.h>
@@ -954,19 +955,24 @@ wxString wxString::FromAscii(const char *ascii)
     if (!ascii)
        return wxEmptyString;
 
-    size_t len = strlen( ascii );
+    size_t len = strlen(ascii);
     wxString res;
 
     if ( len )
     {
-        wxStringBuffer buf(res, len);
-
-        wchar_t *dest = buf;
+        wxImplStringBuffer buf(res, len);
+        wxStringCharType *dest = buf;
 
         for ( ;; )
         {
-           if ( (*dest++ = (wchar_t)(unsigned char)*ascii++) == L'\0' )
-               break;
+            unsigned char c = (unsigned char)*ascii++;
+            wxASSERT_MSG( c < 0x80,
+                          _T("Non-ASCII value passed to FromAscii().") );
+
+            *dest++ = (wchar_t)c;
+
+            if ( c == '\0' )
+                break;
         }
     }
 
@@ -977,35 +983,36 @@ wxString wxString::FromAscii(const char ascii)
 {
     // What do we do with '\0' ?
 
-    wxString res;
-    res += (wchar_t)(unsigned char) ascii;
+    unsigned char c = (unsigned char)ascii;
 
-    return res;
+    wxASSERT_MSG( c < 0x80, _T("Non-ASCII value passed to FromAscii().") );
+
+    // NB: the cast to wchar_t causes interpretation of 'ascii' as Latin1 value
+    return wxString(wxUniChar((wchar_t)c));
 }
 
 const wxCharBuffer wxString::ToAscii() const
 {
     // this will allocate enough space for the terminating NUL too
     wxCharBuffer buffer(length());
-
-
     char *dest = buffer.data();
 
-    const wchar_t *pwc = c_str();
-    for ( ;; )
+    for ( const_iterator i = begin(); i != end(); ++i )
     {
-        *dest++ = (char)(*pwc > SCHAR_MAX ? wxT('_') : *pwc);
+        wxUniChar c(*i);
+        // FIXME-UTF8: unify substituted char ('_') with wxUniChar ('?')
+        *dest++ = c.IsAscii() ? (char)c : '_';
 
         // the output string can't have embedded NULs anyhow, so we can safely
         // stop at first of them even if we do have any
-        if ( !*pwc++ )
+        if ( !c )
             break;
     }
 
     return buffer;
 }
 
-#endif // Unicode
+#endif // wxUSE_UNICODE
 
 // extract string of length nCount starting at nFirst
 wxString wxString::Mid(size_t nFirst, size_t nCount) const
@@ -1442,9 +1449,9 @@ bool wxString::ToDouble(double *val) const
 
 /* static */
 #ifdef wxNEEDS_WXSTRING_PRINTF_MIXIN
-wxString wxStringPrintfMixinBase::DoFormat(const wxChar *format, ...)
+wxString wxStringPrintfMixinBase::DoFormat(const wxString& format, ...)
 #else
-wxString wxString::DoFormat(const wxChar *format, ...)
+wxString wxString::DoFormat(const wxString& format, ...)
 #endif
 {
     va_list argptr;
@@ -1467,9 +1474,9 @@ wxString wxString::FormatV(const wxString& format, va_list argptr)
 }
 
 #ifdef wxNEEDS_WXSTRING_PRINTF_MIXIN
-int wxStringPrintfMixinBase::DoPrintf(const wxChar *format, ...)
+int wxStringPrintfMixinBase::DoPrintf(const wxString& format, ...)
 #else
-int wxString::DoPrintf(const wxChar *format, ...)
+int wxString::DoPrintf(const wxString& format, ...)
 #endif
 {
     va_list argptr;
@@ -1491,14 +1498,27 @@ int wxString::DoPrintf(const wxChar *format, ...)
     return iLen;
 }
 
-int wxString::PrintfV(const wxString& format, va_list argptr)
+#if wxUSE_UNICODE_UTF8
+template<typename BufferType>
+#else
+// we only need one version in non-UTF8 builds and at least two Windows
+// compilers have problems with this function template, so use just one
+// normal function here
+#endif
+static int DoStringPrintfV(wxString& str,
+                           const wxString& format, va_list argptr)
 {
     int size = 1024;
 
     for ( ;; )
     {
-        wxStringBuffer tmp(*this, size + 1);
+#if wxUSE_UNICODE_UTF8
+        BufferType tmp(str, size + 1);
+        typename BufferType::CharType *buf = tmp;
+#else
+        wxStringBuffer tmp(str, size + 1);
         wxChar *buf = tmp;
+#endif
 
         if ( !buf )
         {
@@ -1510,7 +1530,7 @@ int wxString::PrintfV(const wxString& format, va_list argptr)
         // only a copy
         va_list argptrcopy;
         wxVaCopy(argptrcopy, argptr);
-        int len = wxVsnprintf(buf, size, (const wxChar*)/*FIXME-UTF8*/format, argptrcopy);
+        int len = wxVsnprintf(buf, size, format, argptrcopy);
         va_end(argptrcopy);
 
         // some implementations of vsnprintf() don't NUL terminate
@@ -1554,9 +1574,37 @@ int wxString::PrintfV(const wxString& format, va_list argptr)
     }
 
     // we could have overshot
-    Shrink();
+    str.Shrink();
 
-    return length();
+    return str.length();
+}
+
+int wxString::PrintfV(const wxString& format, va_list argptr)
+{
+    va_list argcopy;
+    wxVaCopy(argcopy, argptr);
+
+#if wxUSE_UNICODE_UTF8
+    #if wxUSE_STL_BASED_WXSTRING
+        typedef wxStringTypeBuffer<char> Utf8Buffer;
+    #else
+        typedef wxImplStringBuffer Utf8Buffer;
+    #endif
+#endif
+
+#if wxUSE_UTF8_LOCALE_ONLY
+    return DoStringPrintfV<Utf8Buffer>(*this, format, argcopy);
+#else
+    #if wxUSE_UNICODE_UTF8
+    if ( wxLocaleIsUtf8 )
+        return DoStringPrintfV<Utf8Buffer>(*this, format, argcopy);
+    else
+        // wxChar* version
+        return DoStringPrintfV<wxStringBuffer>(*this, format, argcopy);
+    #else
+        return DoStringPrintfV(*this, format, argcopy);
+    #endif // UTF8/WCHAR
+#endif
 }
 
 // ----------------------------------------------------------------------------