From ed2dfd2b9395634440a13f3a9b789cc6cd5076f7 Mon Sep 17 00:00:00 2001 From: Timo Kreuzer Date: Thu, 27 Sep 2012 21:56:13 +0000 Subject: [PATCH] [CRT] Implement wcstombs_s svn path=/trunk/; revision=57405 --- reactos/dll/win32/msvcrt/msvcrt.spec | 10 +-- reactos/lib/sdk/crt/crt.cmake | 3 + reactos/lib/sdk/crt/string/mbstowcs_s.c | 16 ++-- reactos/lib/sdk/crt/string/wcstombs_s.c | 115 ++++++++++++++++++++++++ 4 files changed, 130 insertions(+), 14 deletions(-) create mode 100644 reactos/lib/sdk/crt/string/wcstombs_s.c diff --git a/reactos/dll/win32/msvcrt/msvcrt.spec b/reactos/dll/win32/msvcrt/msvcrt.spec index 8ac2e5643e9..2e238c7c81a 100644 --- a/reactos/dll/win32/msvcrt/msvcrt.spec +++ b/reactos/dll/win32/msvcrt/msvcrt.spec @@ -435,7 +435,7 @@ # stub _get_fmode # @ cdecl _get_heap_handle() @ cdecl _get_osfhandle(long) -@ cdecl _get_osplatform(ptr) +@ cdecl _get_osplatform(ptr) # stub _get_osver @ cdecl _get_output_format() @ cdecl _get_pgmptr(ptr) @@ -477,9 +477,9 @@ @ cdecl _heapwalk(ptr) @ cdecl _hypot(double double) @ cdecl _i64toa(long long ptr long) -@ cdecl _i64toa_s(long long ptr long long) +@ cdecl _i64toa_s(long long ptr long long) @ cdecl _i64tow(long long ptr long) -@ cdecl _i64tow_s(long long ptr long long) +@ cdecl _i64tow_s(long long ptr long long) @ cdecl _initterm(ptr ptr) @ cdecl _initterm_e(ptr ptr) @ cdecl -arch=i386 _inp(long) MSVCRT__inp @@ -1396,7 +1396,7 @@ @ cdecl wcsncmp(wstr wstr long) @ cdecl wcsncpy(ptr wstr long) @ cdecl wcsncpy_s(ptr long wstr long) -# stub wcsnlen +@ cdecl wcsnlen(wstr long) @ cdecl wcspbrk(wstr wstr) @ cdecl wcsrchr(wstr long) # stub wcsrtombs @@ -1408,7 +1408,7 @@ @ cdecl wcstok_s(ptr wstr ptr) @ cdecl wcstol(wstr ptr long) @ cdecl wcstombs(ptr ptr long) -# @ cdecl wcstombs_s(ptr ptr long wstr long) +@ cdecl wcstombs_s(ptr ptr long wstr long) @ cdecl wcstoul(wstr ptr long) @ cdecl wcsxfrm(ptr wstr long) # stub wctob diff --git a/reactos/lib/sdk/crt/crt.cmake b/reactos/lib/sdk/crt/crt.cmake index a46055827bf..c60a7cbe2fd 100644 --- a/reactos/lib/sdk/crt/crt.cmake +++ b/reactos/lib/sdk/crt/crt.cmake @@ -247,6 +247,8 @@ list(APPEND CRT_SOURCE stdlib/wsenv.c stdlib/wmakpath.c stdlib/wmakpath_s.c + string/_mbsnlen.c + string/_mbstrnlen.c string/atof.c string/atoi.c string/atoi64.c @@ -283,6 +285,7 @@ list(APPEND CRT_SOURCE string/strxfrm.c string/wcs.c string/wcstol.c + string/wcstombs_s.c string/wcstoul.c string/wctype.c string/wsplitp.c diff --git a/reactos/lib/sdk/crt/string/mbstowcs_s.c b/reactos/lib/sdk/crt/string/mbstowcs_s.c index 6442cd1aae6..bb53c748821 100644 --- a/reactos/lib/sdk/crt/string/mbstowcs_s.c +++ b/reactos/lib/sdk/crt/string/mbstowcs_s.c @@ -7,17 +7,15 @@ */ #include -#include - -#define _mbsnlen strnlen +#include _CRTIMP _Check_return_opt_ errno_t __cdecl mbstowcs_s( - _Out_opt_ size_t *pReturnValue, - _Out_writes_to_opt_(sizeInWords, *pReturnValue) wchar_t *pwcstr, + _Out_opt_ size_t *pcchConverted, + _Out_writes_to_opt_(sizeInWords, *pcchConverted) wchar_t *pwcstr, _In_ size_t sizeInWords, _In_reads_or_z_(count) const char *pmbstr, _In_ size_t count) @@ -34,10 +32,10 @@ mbstowcs_s( } /* Check if we have a return value pointer */ - if (pReturnValue) + if (pcchConverted) { /* Default to 0 bytes written */ - *pReturnValue = 0; + *pcchConverted = 0; } if (!MSVCRT_CHECK_PMT((count == 0) || (pmbstr != 0))) @@ -107,10 +105,10 @@ mbstowcs_s( } /* Check if we have a return value pointer */ - if (pReturnValue) + if (pcchConverted) { /* Default to 0 bytes written */ - *pReturnValue = cwcWritten; + *pcchConverted = cwcWritten; } return retval; diff --git a/reactos/lib/sdk/crt/string/wcstombs_s.c b/reactos/lib/sdk/crt/string/wcstombs_s.c new file mode 100644 index 00000000000..910c370763b --- /dev/null +++ b/reactos/lib/sdk/crt/string/wcstombs_s.c @@ -0,0 +1,115 @@ +/* + * 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 + +_Check_return_wat_ +_CRTIMP +errno_t +__cdecl +wcstombs_s( + _Out_opt_ size_t * pcchConverted, + _Out_writes_bytes_to_opt_(cjDstSize, *pcchConverted) + char * pmbstrDst, + _In_ size_t cjDstSize, + _In_z_ const wchar_t * pwszSrc, + _In_ size_t cjMaxCount) +{ + size_t cchMax, cchConverted; + errno_t retval = 0; + + /* Make sure, either we have a target buffer > 0 bytes, or no buffer */ + if (!MSVCRT_CHECK_PMT( ((cjDstSize != 0) && (pmbstrDst != 0)) || + ((cjDstSize == 0) && (pmbstrDst == 0)) )) + { + _set_errno(EINVAL); + return EINVAL; + } + + /* Check if we have a return value pointer */ + if (pcchConverted) + { + /* Default to 0 bytes written */ + *pcchConverted = 0; + } + + if (!MSVCRT_CHECK_PMT((cjMaxCount == 0) || (pwszSrc != 0))) + { + _set_errno(EINVAL); + return EINVAL; + } + + /* Check if there is anything to do */ + if ((pmbstrDst == 0) && (pwszSrc == 0)) + { + _set_errno(EINVAL); + return EINVAL; + } + + /* Check if we have a wchar string */ + if (pwszSrc) + { + /* Check if we also have a multibyte buffer */ + if (pmbstrDst) + { + /* Calculate the maximum that we can write */ + cchMax = (cjMaxCount < cjDstSize) ? cjMaxCount + 1 : cjDstSize; + + /* Now do the conversion */ + cchConverted = wcstombs(pmbstrDst, pwszSrc, cchMax); + + /* Check if the buffer was not zero terminated */ + if (cchConverted == cchMax) + { + /* Check if we reached the max size of the dest buffer */ + if (cchConverted == cjDstSize) + { + /* Does the caller allow this? */ + if (cjMaxCount != _TRUNCATE) + { + /* Not allowed, truncate to 0 length */ + pmbstrDst[0] = L'\0'; + + /* Return error */ + _set_errno(ERANGE); + return ERANGE; + } + + /* Inform the caller about truncation */ + retval = STRUNCATE; + } + + /* zero teminate the buffer */ + pmbstrDst[cchConverted - 1] = L'\0'; + } + else + { + /* The buffer is zero terminated, count the terminating char */ + cchConverted++; + } + } + else + { + /* Get the length of the string, plus 0 terminator */ + cchConverted = wcsnlen(pwszSrc, cjMaxCount) + 1; + } + } + else + { + cchConverted = cjMaxCount + 1; + } + + /* Check if we have a return value pointer */ + if (pcchConverted) + { + /* Default to 0 bytes written */ + *pcchConverted = cchConverted; + } + + return retval; +}