Commit 335c9772 authored by Piotr Caban's avatar Piotr Caban Committed by Alexandre Julliard

msvcrt: Fixed wcstombs(_s_l) implementation.

parent 7352ee84
...@@ -1040,7 +1040,7 @@ ...@@ -1040,7 +1040,7 @@
@ cdecl _wcstoi64(wstr ptr long) MSVCRT__wcstoi64 @ cdecl _wcstoi64(wstr ptr long) MSVCRT__wcstoi64
@ cdecl _wcstoi64_l(wstr ptr long ptr) MSVCRT__wcstoi64_l @ cdecl _wcstoi64_l(wstr ptr long ptr) MSVCRT__wcstoi64_l
# stub _wcstol_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 _wcstombs_s_l(ptr ptr long wstr long ptr) MSVCRT__wcstombs_s_l
@ cdecl _wcstoui64(wstr ptr long) MSVCRT__wcstoui64 @ cdecl _wcstoui64(wstr ptr long) MSVCRT__wcstoui64
@ cdecl _wcstoui64_l(wstr ptr long ptr) MSVCRT__wcstoui64_l @ cdecl _wcstoui64_l(wstr ptr long ptr) MSVCRT__wcstoui64_l
...@@ -1417,7 +1417,7 @@ ...@@ -1417,7 +1417,7 @@
@ cdecl wcstok(wstr wstr) MSVCRT_wcstok @ cdecl wcstok(wstr wstr) MSVCRT_wcstok
# stub wcstok_s # stub wcstok_s
@ cdecl wcstol(wstr ptr long) ntdll.wcstol @ 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 wcstombs_s(ptr ptr long wstr long) MSVCRT_wcstombs_s
@ cdecl wcstoul(wstr ptr long) ntdll.wcstoul @ cdecl wcstoul(wstr ptr long) ntdll.wcstoul
@ stub wcsxfrm #(ptr wstr long) MSVCRT_wcsxfrm @ stub wcsxfrm #(ptr wstr long) MSVCRT_wcsxfrm
......
...@@ -227,76 +227,95 @@ double CDECL MSVCRT__wcstod_l(const MSVCRT_wchar_t* str, MSVCRT_wchar_t** end, ...@@ -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 CDECL MSVCRT__wcstombs_l(char *mbstr, const MSVCRT_wchar_t *wcstr,
MSVCRT_size_t size, const MSVCRT_wchar_t *wcstr,
MSVCRT_size_t count, MSVCRT__locale_t locale) MSVCRT_size_t count, MSVCRT__locale_t locale)
{ {
char default_char = '\0', *p; char default_char = '\0';
int hlp, len; MSVCRT_size_t tmp;
BOOL used_default;
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;
}
if(!locale) if(!locale)
locale = get_locale(); locale = get_locale();
if(size<=count) /* FIXME: Use wcslen here */
len = size; tmp = strlenW(wcstr);
else if(count==_TRUNCATE) if(tmp>count && mbstr)
len = size-1; tmp = count;
else
len = count;
p = mbstr; tmp = WideCharToMultiByte(locale->locinfo->lc_codepage, WC_NO_BEST_FIT_CHARS,
*ret = 0; wcstr, tmp, mbstr, count, &default_char, &used_default);
while(1) {
if(!len)
break;
if(*wcstr == '\0') { if(used_default)
*p = '\0'; return -1;
break;
}
hlp = WideCharToMultiByte(locale->locinfo->lc_codepage, if(tmp<count && mbstr)
WC_NO_BEST_FIT_CHARS, wcstr, 1, p, len, &default_char, NULL); mbstr[tmp] = '\0';
if(!hlp || *p=='\0')
break;
p += hlp; return tmp;
len -= hlp; }
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); MSVCRT__invalid_parameter(NULL, NULL, NULL, 0, 0);
*mbstr = '\0'; if(size)
mbstr[0] = '\0';
*MSVCRT__errno() = MSVCRT_ERANGE; *MSVCRT__errno() = MSVCRT_ERANGE;
return MSVCRT_ERANGE; return MSVCRT_ERANGE;
} }
if(*wcstr == '\0') if(ret)
*ret += 1; *ret = conv;
*p = '\0';
return 0; return 0;
} }
/********************************************************************* /*********************************************************************
* wcstombs_s (MSVCRT.@) * 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) MSVCRT_size_t size, const MSVCRT_wchar_t *wcstr, MSVCRT_size_t count)
{ {
return MSVCRT__wcstombs_s_l(ret, mbstr, size, wcstr, count, NULL); return MSVCRT__wcstombs_s_l(ret, mbstr, size, wcstr, count, NULL);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment