ReactOS  0.4.15-dev-3177-gd6a0299
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 
11 _Success_(return!=EINVAL)
13 _CRTIMP
14 errno_t
15 __cdecl
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 }
errno_t __cdecl _set_errno(_In_ int _Value)
#define __cdecl
Definition: accygwin.h:79
#define _CRTIMP
Definition: crtdefs.h:72
Definition: arc.h:39
#define STRUNCATE
Definition: errno.h:110
_Success_(return!=EINVAL)
Definition: wcstombs_s.c:11
_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 _In_
Definition: ms_sal.h:308
#define _In_z_
Definition: ms_sal.h:313
int errno_t
Definition: crtdefs.h:374
#define _TRUNCATE
Definition: crtdefs.h:262
UINT cchMax
#define ERANGE
Definition: acclib.h:92
static const WCHAR L[]
Definition: oid.c:1250
#define MSVCRT_CHECK_PMT(x)
Definition: mbstowcs_s.c:26
#define _Out_writes_bytes_to_opt_(size, count)
Definition: ms_sal.h:361
#define _Check_return_wat_
Definition: crtdefs.h:459
#define _Out_opt_
Definition: ms_sal.h:346
size_t __cdecl wcstombs(_Out_writes_opt_z_(_MaxCount) char *_Dest, _In_z_ const wchar_t *_Source, _In_ size_t _MaxCount)