Piotr Caban : msvcrt: Fixed wcstombs(_s_l) implementation.

Alexandre Julliard julliard at winehq.org
Thu May 6 11:13:23 CDT 2010


Module: wine
Branch: master
Commit: 335c9772ece4964c061526d8178348c6d1f61ac3
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=335c9772ece4964c061526d8178348c6d1f61ac3

Author: Piotr Caban <piotr at codeweavers.com>
Date:   Thu May  6 14:27:57 2010 +0200

msvcrt: Fixed wcstombs(_s_l) implementation.

---

 dlls/msvcrt/msvcrt.spec |    4 +-
 dlls/msvcrt/wcs.c       |  109 +++++++++++++++++++++++++++-------------------
 2 files changed, 66 insertions(+), 47 deletions(-)

diff --git a/dlls/msvcrt/msvcrt.spec b/dlls/msvcrt/msvcrt.spec
index 8655f6f..c7d6654 100644
--- a/dlls/msvcrt/msvcrt.spec
+++ b/dlls/msvcrt/msvcrt.spec
@@ -1040,7 +1040,7 @@
 @ cdecl _wcstoi64(wstr ptr long) MSVCRT__wcstoi64
 @ cdecl _wcstoi64_l(wstr ptr long ptr) MSVCRT__wcstoi64_l
 # stub _wcstol_l
-# stub _wcstombs_l
+@ cdecl _wcstombs_l(ptr ptr long ptr) MSVCRT__wcstombs_l
 @ cdecl _wcstombs_s_l(ptr ptr long wstr long ptr) MSVCRT__wcstombs_s_l
 @ cdecl _wcstoui64(wstr ptr long) MSVCRT__wcstoui64
 @ cdecl _wcstoui64_l(wstr ptr long ptr) MSVCRT__wcstoui64_l
@@ -1417,7 +1417,7 @@
 @ cdecl wcstok(wstr wstr) MSVCRT_wcstok
 # stub wcstok_s
 @ cdecl wcstol(wstr ptr long) ntdll.wcstol
-@ cdecl wcstombs(ptr ptr long) ntdll.wcstombs
+@ cdecl wcstombs(ptr ptr long) MSVCRT_wcstombs
 @ cdecl wcstombs_s(ptr ptr long wstr long) MSVCRT_wcstombs_s
 @ cdecl wcstoul(wstr ptr long) ntdll.wcstoul
 @ stub wcsxfrm #(ptr wstr long) MSVCRT_wcsxfrm
diff --git a/dlls/msvcrt/wcs.c b/dlls/msvcrt/wcs.c
index 5334115..96a25e5 100644
--- a/dlls/msvcrt/wcs.c
+++ b/dlls/msvcrt/wcs.c
@@ -227,76 +227,95 @@ double CDECL MSVCRT__wcstod_l(const MSVCRT_wchar_t* str, MSVCRT_wchar_t** end,
 }
 
 /*********************************************************************
- *		_wcstombs_s_l (MSVCRT.@)
+ *		_wcstombs_l (MSVCRT.@)
  */
-int CDECL MSVCRT__wcstombs_s_l(MSVCRT_size_t *ret, char *mbstr,
-        MSVCRT_size_t size, const MSVCRT_wchar_t *wcstr,
+MSVCRT_size_t CDECL MSVCRT__wcstombs_l(char *mbstr, const MSVCRT_wchar_t *wcstr,
         MSVCRT_size_t count, MSVCRT__locale_t locale)
 {
-    char default_char = '\0', *p;
-    int hlp, len;
-
-    if(!size)
-        return 0;
-
-    if(!mbstr || !wcstr) {
-        MSVCRT__invalid_parameter(NULL, NULL, NULL, 0, 0);
-        if(mbstr)
-            *mbstr = '\0';
-        *MSVCRT__errno() = MSVCRT_EINVAL;
-        return MSVCRT_EINVAL;
-    }
+    char default_char = '\0';
+    MSVCRT_size_t tmp;
+    BOOL used_default;
 
     if(!locale)
         locale = get_locale();
 
-    if(size<=count)
-        len = size;
-    else if(count==_TRUNCATE)
-        len = size-1;
-    else
-        len = count;
+    /* FIXME: Use wcslen here */
+    tmp = strlenW(wcstr);
+    if(tmp>count && mbstr)
+        tmp = count;
 
-    p = mbstr;
-    *ret = 0;
-    while(1) {
-        if(!len)
-            break;
+    tmp = WideCharToMultiByte(locale->locinfo->lc_codepage, WC_NO_BEST_FIT_CHARS,
+            wcstr, tmp, mbstr, count, &default_char, &used_default);
 
-        if(*wcstr == '\0') {
-            *p = '\0';
-            break;
-        }
+    if(used_default)
+        return -1;
 
-        hlp = WideCharToMultiByte(locale->locinfo->lc_codepage,
-                WC_NO_BEST_FIT_CHARS, wcstr, 1, p, len, &default_char, NULL);
-        if(!hlp || *p=='\0')
-            break;
+    if(tmp<count && mbstr)
+        mbstr[tmp] = '\0';
 
-        p += hlp;
-        len -= hlp;
+    return tmp;
+}
 
-        wcstr++;
-        *ret += 1;
+/*********************************************************************
+ *		wcstombs (MSVCRT.@)
+ */
+MSVCRT_size_t CDECL MSVCRT_wcstombs(char *mbstr, const MSVCRT_wchar_t *wcstr,
+        MSVCRT_size_t count)
+{
+    return MSVCRT__wcstombs_l(mbstr, wcstr, count, NULL);
+}
+
+/*********************************************************************
+ *		_wcstombs_s_l (MSVCRT.@)
+ */
+MSVCRT_size_t CDECL MSVCRT__wcstombs_s_l(MSVCRT_size_t *ret, char *mbstr,
+        MSVCRT_size_t size, const MSVCRT_wchar_t *wcstr,
+        MSVCRT_size_t count, MSVCRT__locale_t locale)
+{
+    MSVCRT_size_t conv;
+
+    if(!mbstr && !size) {
+        conv = MSVCRT__wcstombs_l(NULL, wcstr, 0, locale);
+        if(ret)
+            *ret = conv;
+        return 0;
+    }
+
+    if(!wcstr || !mbstr) {
+        MSVCRT__invalid_parameter(NULL, NULL, NULL, 0, 0);
+        if(mbstr && size)
+            mbstr[0] = '\0';
+        *MSVCRT__errno() = MSVCRT_EINVAL;
+        return MSVCRT_EINVAL;
     }
 
-    if(!len && size<=count) {
+    if(count==_TRUNCATE || size<count)
+        conv = size;
+    else
+        conv = count;
+
+    conv = MSVCRT__wcstombs_l(mbstr, wcstr, conv, locale);
+    if(conv<size)
+        mbstr[conv++] = '\0';
+    else if(conv==size && (count==_TRUNCATE || mbstr[conv-1]=='\0'))
+        mbstr[conv-1] = '\0';
+    else {
         MSVCRT__invalid_parameter(NULL, NULL, NULL, 0, 0);
-        *mbstr = '\0';
+        if(size)
+            mbstr[0] = '\0';
         *MSVCRT__errno() = MSVCRT_ERANGE;
         return MSVCRT_ERANGE;
     }
 
-    if(*wcstr == '\0')
-        *ret += 1;
-    *p = '\0';
+    if(ret)
+        *ret = conv;
     return 0;
 }
 
 /*********************************************************************
  *		wcstombs_s (MSVCRT.@)
  */
-int CDECL MSVCRT_wcstombs_s(MSVCRT_size_t *ret, char *mbstr,
+MSVCRT_size_t CDECL MSVCRT_wcstombs_s(MSVCRT_size_t *ret, char *mbstr,
         MSVCRT_size_t size, const MSVCRT_wchar_t *wcstr, MSVCRT_size_t count)
 {
     return MSVCRT__wcstombs_s_l(ret, mbstr, size, wcstr, count, NULL);




More information about the wine-cvs mailing list