mirror of
https://github.com/reactos/reactos.git
synced 2024-07-10 22:55:05 +00:00
[CRT]
Implement mbstowcs_s. passes all crt apitests. svn path=/trunk/; revision=57345
This commit is contained in:
parent
3ed646a229
commit
5fcb637cb2
|
@ -1272,7 +1272,7 @@
|
|||
# stub mbsrtowcs
|
||||
# stub mbsrtowcs_s
|
||||
@ cdecl mbstowcs(ptr str long)
|
||||
# stub mbstowcs_s
|
||||
@ cdecl mbstowcs_s(ptr ptr long str long)
|
||||
@ cdecl mbtowc(wstr str long)
|
||||
@ cdecl memchr(ptr long long)
|
||||
@ cdecl memcmp(ptr ptr long)
|
||||
|
|
|
@ -256,6 +256,7 @@ list(APPEND CRT_SOURCE
|
|||
string/is_wctype.c
|
||||
string/itoa.c
|
||||
string/itow.c
|
||||
string/mbstowcs_s.c
|
||||
string/scanf.c
|
||||
string/splitp.c
|
||||
string/strcoll.c
|
||||
|
|
117
reactos/lib/sdk/crt/string/mbstowcs_s.c
Normal file
117
reactos/lib/sdk/crt/string/mbstowcs_s.c
Normal file
|
@ -0,0 +1,117 @@
|
|||
/*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS CRT
|
||||
* PURPOSE: Implementation of mbstowcs_s
|
||||
* FILE: lib/sdk/crt/stdlib/mbstowcs_s.c
|
||||
* PROGRAMMER: Timo Kreuzer
|
||||
*/
|
||||
|
||||
#include <precomp.h>
|
||||
#include <specstrings.h>
|
||||
|
||||
#define _mbsnlen strnlen
|
||||
|
||||
_CRTIMP
|
||||
_Check_return_opt_
|
||||
errno_t
|
||||
__cdecl
|
||||
mbstowcs_s(
|
||||
_Out_opt_ size_t *pReturnValue,
|
||||
_Out_writes_to_opt_(sizeInWords, *pReturnValue) wchar_t *pwcstr,
|
||||
_In_ size_t sizeInWords,
|
||||
_In_reads_or_z_(count) const char *pmbstr,
|
||||
_In_ size_t count)
|
||||
{
|
||||
size_t cchMax, cwcWritten;
|
||||
errno_t retval = 0;
|
||||
|
||||
/* Make sure, either we have a target buffer > 0 bytes, or no buffer */
|
||||
if (!MSVCRT_CHECK_PMT( ((sizeInWords != 0) && (pwcstr != 0)) ||
|
||||
((sizeInWords == 0) && (pwcstr == 0)) ))
|
||||
{
|
||||
_set_errno(EINVAL);
|
||||
return EINVAL;
|
||||
}
|
||||
|
||||
/* Check if we have a return value pointer */
|
||||
if (pReturnValue)
|
||||
{
|
||||
/* Default to 0 bytes written */
|
||||
*pReturnValue = 0;
|
||||
}
|
||||
|
||||
if (!MSVCRT_CHECK_PMT((count == 0) || (pmbstr != 0)))
|
||||
{
|
||||
_set_errno(EINVAL);
|
||||
return EINVAL;
|
||||
}
|
||||
|
||||
/* Check if there is anything to do */
|
||||
if ((pwcstr == 0) && (pmbstr == 0))
|
||||
{
|
||||
_set_errno(EINVAL);
|
||||
return EINVAL;
|
||||
}
|
||||
|
||||
/* Check if we have a multibyte string */
|
||||
if (pmbstr)
|
||||
{
|
||||
/* Check if we also have a wchar buffer */
|
||||
if (pwcstr)
|
||||
{
|
||||
/* Calculate the maximum the we can write */
|
||||
cchMax = (count < sizeInWords) ? count + 1 : sizeInWords;
|
||||
|
||||
/* Now do the conversion */
|
||||
cwcWritten = mbstowcs(pwcstr, pmbstr, cchMax);
|
||||
|
||||
/* Check if the buffer was not zero terminated */
|
||||
if (cwcWritten == cchMax)
|
||||
{
|
||||
/* Check if we reached the max size of the dest buffer */
|
||||
if (cwcWritten == sizeInWords)
|
||||
{
|
||||
/* Does the caller allow this? */
|
||||
if (count != _TRUNCATE)
|
||||
{
|
||||
/* Not allowed, truncate to 0 length */
|
||||
pwcstr[0] = L'\0';
|
||||
|
||||
/* Return error */
|
||||
_set_errno(ERANGE);
|
||||
return ERANGE;
|
||||
}
|
||||
|
||||
/* Inform the caller about truncation */
|
||||
retval = STRUNCATE;
|
||||
}
|
||||
|
||||
/* zero teminate the buffer */
|
||||
pwcstr[cwcWritten - 1] = L'\0';
|
||||
}
|
||||
else
|
||||
{
|
||||
/* The buffer is zero terminated, count the terminating char */
|
||||
cwcWritten++;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Get the length of the string, plus 0 terminator */
|
||||
cwcWritten = _mbsnlen(pmbstr, count) + 1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
cwcWritten = count + 1;
|
||||
}
|
||||
|
||||
/* Check if we have a return value pointer */
|
||||
if (pReturnValue)
|
||||
{
|
||||
/* Default to 0 bytes written */
|
||||
*pReturnValue = cwcWritten;
|
||||
}
|
||||
|
||||
return retval;
|
||||
}
|
Loading…
Reference in a new issue