ReactOS 0.4.15-dev-7842-g558ab78
wcstombs_s.c
Go to the documentation of this file.
1/*
2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS CRT
4 * PURPOSE: Implementation of mbstowcs_s
5 * FILE: lib/sdk/crt/string/wcstombs_s.c
6 * PROGRAMMER: Timo Kreuzer
7 */
8
9#include <precomp.h>
10
17 _Out_opt_ size_t * pcchConverted,
18 _Out_writes_bytes_to_opt_(cjDstSize, *pcchConverted)
19 char * pmbstrDst,
20 _In_ size_t cjDstSize,
21 _In_z_ const wchar_t * pwszSrc,
22 _In_ size_t cjMaxCount)
23{
24 size_t cchMax, cchConverted;
25 errno_t retval = 0;
26
27 /* Make sure, either we have a target buffer > 0 bytes, or no buffer */
28 if (!MSVCRT_CHECK_PMT( ((cjDstSize != 0) && (pmbstrDst != 0)) ||
29 ((cjDstSize == 0) && (pmbstrDst == 0)) ))
30 {
32 return EINVAL;
33 }
34
35 /* Check if we have a return value pointer */
36 if (pcchConverted)
37 {
38 /* Default to 0 bytes written */
39 *pcchConverted = 0;
40 }
41
42 if (!MSVCRT_CHECK_PMT((cjMaxCount == 0) || (pwszSrc != 0)))
43 {
45 return EINVAL;
46 }
47
48 /* Check if there is anything to do */
49 if ((pmbstrDst == 0) && (pwszSrc == 0))
50 {
52 return EINVAL;
53 }
54
55 /* Check if we have a wchar string */
56 if (pwszSrc)
57 {
58 /* Check if we also have a multibyte buffer */
59 if (pmbstrDst)
60 {
61 /* Calculate the maximum that we can write */
62 cchMax = (cjMaxCount < cjDstSize) ? cjMaxCount + 1 : cjDstSize;
63
64 /* Now do the conversion */
65 cchConverted = wcstombs(pmbstrDst, pwszSrc, cchMax);
66
67 /* Check if the buffer was not zero terminated */
68 if (cchConverted == cchMax)
69 {
70 /* Check if we reached the max size of the dest buffer */
71 if (cchConverted == cjDstSize)
72 {
73 /* Does the caller allow this? */
74 if (cjMaxCount != _TRUNCATE)
75 {
76 /* Not allowed, truncate to 0 length */
77 pmbstrDst[0] = L'\0';
78
79 /* Return error */
81 return ERANGE;
82 }
83
84 /* Inform the caller about truncation */
85 retval = STRUNCATE;
86 }
87
88 /* zero teminate the buffer */
89 pmbstrDst[cchConverted - 1] = L'\0';
90 }
91 else
92 {
93 /* The buffer is zero terminated, count the terminating char */
94 cchConverted++;
95 }
96 }
97 else
98 {
99 /* Get the length of the string, plus 0 terminator */
100 cchConverted = wcsnlen(pwszSrc, cjMaxCount) + 1;
101 }
102 }
103 else
104 {
105 cchConverted = cjMaxCount + 1;
106 }
107
108 /* Check if we have a return value pointer */
109 if (pcchConverted)
110 {
111 /* Default to 0 bytes written */
112 *pcchConverted = cchConverted;
113 }
114
115 return retval;
116}
UINT cchMax
#define EINVAL
Definition: acclib.h:90
#define ERANGE
Definition: acclib.h:92
#define __cdecl
Definition: accygwin.h:79
#define _TRUNCATE
Definition: crtdefs.h:262
#define _Check_return_wat_
Definition: crtdefs.h:459
#define _CRTIMP
Definition: crtdefs.h:72
int errno_t
Definition: crtdefs.h:374
size_t __cdecl wcstombs(_Out_writes_opt_z_(_MaxCount) char *_Dest, _In_z_ const wchar_t *_Source, _In_ size_t _MaxCount)
#define MSVCRT_CHECK_PMT(x)
Definition: mbstowcs_s.c:26
_Check_return_wat_ _CRTIMP errno_t __cdecl wcstombs_s(_Out_opt_ size_t *pcchConverted, _Out_writes_bytes_to_opt_(cjDstSize, *pcchConverted) char *pmbsDst, _In_ size_t cjDstSize, _In_z_ const wchar_t *pwszSrc, _In_ size_t cjMaxCount)
#define _Out_opt_
Definition: ms_sal.h:346
#define _Success_(expr)
Definition: ms_sal.h:259
#define _In_z_
Definition: ms_sal.h:313
#define _Out_writes_bytes_to_opt_(size, count)
Definition: ms_sal.h:361
#define _In_
Definition: ms_sal.h:308
#define L(x)
Definition: ntvdm.h:50
#define STRUNCATE
Definition: errno.h:110
errno_t __cdecl _set_errno(_In_ int _Value)