mirror of
https://github.com/reactos/reactos.git
synced 2024-10-01 23:14:53 +00:00
[SDK][STDLIB][STRING] Wine-sync wcsrtombs_l and _mbstowcs_l
This is a partial sync of the CRT library with wcsrtombs_l and _mbstowcs_l functions from WINE. The _wctomb_s_l implementation of WINE which is used by _wctomb_s, _wctomb_l and wctomb brings failed results of the wctomb unit testcase and at the same time it crashes the whole testcase after. Therefore I will not address the wctomb function for the moment being.
This commit is contained in:
parent
4d8a5e921e
commit
d8eeb31b8a
|
@ -1,7 +1,7 @@
|
|||
#include <precomp.h>
|
||||
|
||||
/*********************************************************************
|
||||
* _mbstowcs_l
|
||||
* _mbstowcs_l (MSVCRT.@)
|
||||
*/
|
||||
size_t CDECL _mbstowcs_l(wchar_t *wcstr, const char *mbstr,
|
||||
size_t count, _locale_t locale)
|
||||
|
@ -9,11 +9,27 @@ size_t CDECL _mbstowcs_l(wchar_t *wcstr, const char *mbstr,
|
|||
MSVCRT_pthreadlocinfo locinfo;
|
||||
size_t i, size;
|
||||
|
||||
if(!mbstr) {
|
||||
_set_errno(EINVAL);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if(!locale)
|
||||
locinfo = get_locinfo();
|
||||
else
|
||||
locinfo = ((MSVCRT__locale_t)locale)->locinfo;
|
||||
|
||||
if(!locinfo->lc_codepage) {
|
||||
if(!wcstr)
|
||||
return strlen(mbstr);
|
||||
|
||||
for(i=0; i<count; i++) {
|
||||
wcstr[i] = (unsigned char)mbstr[i];
|
||||
if(!wcstr[i]) break;
|
||||
}
|
||||
return i;
|
||||
}
|
||||
|
||||
/* Ignore count parameter */
|
||||
if(!wcstr)
|
||||
return MultiByteToWideChar(locinfo->lc_codepage, 0, mbstr, -1, NULL, 0)-1;
|
||||
|
@ -25,10 +41,17 @@ size_t CDECL _mbstowcs_l(wchar_t *wcstr, const char *mbstr,
|
|||
size += (_isleadbyte_l((unsigned char)mbstr[size], locale) ? 2 : 1);
|
||||
}
|
||||
|
||||
size = MultiByteToWideChar(locinfo->lc_codepage, 0,
|
||||
mbstr, size, wcstr, count);
|
||||
if(size) {
|
||||
size = MultiByteToWideChar(locinfo->lc_codepage, 0,
|
||||
mbstr, size, wcstr, count);
|
||||
if(!size) {
|
||||
if(count) wcstr[0] = '\0';
|
||||
_set_errno(EILSEQ);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
if(size<count && wcstr)
|
||||
if(size<count)
|
||||
wcstr[size] = '\0';
|
||||
|
||||
return size;
|
||||
|
|
|
@ -257,7 +257,8 @@ INT CDECL wctomb( char *dst, wchar_t ch )
|
|||
/*********************************************************************
|
||||
* wcsrtombs_l (INTERNAL)
|
||||
*/
|
||||
static size_t CDECL wcsrtombs_l(char *mbstr, const wchar_t **wcstr, size_t count, _locale_t locale)
|
||||
static size_t CDECL wcsrtombs_l(char *mbstr, const wchar_t **wcstr,
|
||||
size_t count, _locale_t locale)
|
||||
{
|
||||
MSVCRT_pthreadlocinfo locinfo;
|
||||
size_t tmp = 0;
|
||||
|
@ -268,12 +269,32 @@ static size_t CDECL wcsrtombs_l(char *mbstr, const wchar_t **wcstr, size_t count
|
|||
else
|
||||
locinfo = ((MSVCRT__locale_t)locale)->locinfo;
|
||||
|
||||
if(!locinfo->lc_codepage) {
|
||||
size_t i;
|
||||
|
||||
if(!mbstr)
|
||||
return strlenW(*wcstr);
|
||||
|
||||
for(i=0; i<count; i++) {
|
||||
if((*wcstr)[i] > 255) {
|
||||
_set_errno(EILSEQ);
|
||||
return -1;
|
||||
}
|
||||
|
||||
mbstr[i] = (*wcstr)[i];
|
||||
if(!(*wcstr)[i]) break;
|
||||
}
|
||||
return i;
|
||||
}
|
||||
|
||||
if(!mbstr) {
|
||||
tmp = WideCharToMultiByte(locinfo->lc_codepage, WC_NO_BEST_FIT_CHARS,
|
||||
*wcstr, -1, NULL, 0, NULL, &used_default)-1;
|
||||
if(used_default)
|
||||
*wcstr, -1, NULL, 0, NULL, &used_default);
|
||||
if(!tmp || used_default) {
|
||||
_set_errno(EILSEQ);
|
||||
return -1;
|
||||
return tmp;
|
||||
}
|
||||
return tmp-1;
|
||||
}
|
||||
|
||||
while(**wcstr) {
|
||||
|
@ -282,8 +303,10 @@ static size_t CDECL wcsrtombs_l(char *mbstr, const wchar_t **wcstr, size_t count
|
|||
|
||||
size = WideCharToMultiByte(locinfo->lc_codepage, WC_NO_BEST_FIT_CHARS,
|
||||
*wcstr, 1, buf, 3, NULL, &used_default);
|
||||
if(used_default)
|
||||
if(!size || used_default) {
|
||||
_set_errno(EILSEQ);
|
||||
return -1;
|
||||
}
|
||||
if(tmp+size > count)
|
||||
return tmp;
|
||||
|
||||
|
|
Loading…
Reference in a new issue