1 /**
2 * This file has no copyright assigned and is placed in the Public Domain.
3 * This file is part of the mingw-w64 runtime package.
4 * No warranty is given; refer to the file DISCLAIMER.PD within this package.
5 */
6 #ifndef WIN32_LEAN_AND_MEAN
7 #define WIN32_LEAN_AND_MEAN
8 #endif
9 #include "mb_wc_common.h"
10 #include <wchar.h>
11 #include <stdlib.h>
12 #include <errno.h>
13 #include <limits.h>
14 #include <windows.h>
15
16 __attribute__((noinline))
17 static int __MINGW_ATTRIB_NONNULL(1)
__wcrtomb_cp(char * dst,wchar_t wc,const unsigned int cp,const unsigned int mb_max)18 __wcrtomb_cp (char *dst, wchar_t wc, const unsigned int cp,
19 const unsigned int mb_max)
20 {
21 if (cp == 0)
22 {
23 if (wc > 255)
24 {
25 errno = EILSEQ;
26 return -1;
27 }
28 *dst = (char) wc;
29 return 1;
30 }
31 else
32 {
33 int invalid_char = 0;
34
35 int size = WideCharToMultiByte (cp, 0 /* Is this correct flag? */,
36 &wc, 1, dst, mb_max,
37 NULL, &invalid_char);
38 if (size == 0 || invalid_char)
39 {
40 errno = EILSEQ;
41 return -1;
42 }
43 return size;
44 }
45 }
46
47 size_t
wcrtomb(char * dst,wchar_t wc,mbstate_t * __UNUSED_PARAM (ps))48 wcrtomb (char *dst, wchar_t wc, mbstate_t * __UNUSED_PARAM (ps))
49 {
50 char byte_bucket [MB_LEN_MAX];
51 char* tmp_dst = dst ? dst : &byte_bucket[0];
52 return (size_t)__wcrtomb_cp (tmp_dst, wc, ___lc_codepage_func(),
53 MB_CUR_MAX);
54 }
55
wcsrtombs(char * dst,const wchar_t ** src,size_t len,mbstate_t * __UNUSED_PARAM (ps))56 size_t wcsrtombs (char *dst, const wchar_t **src, size_t len,
57 mbstate_t * __UNUSED_PARAM (ps))
58 {
59 int ret = 0;
60 size_t n = 0;
61 const unsigned int cp = ___lc_codepage_func();
62 const unsigned int mb_max = MB_CUR_MAX;
63 const wchar_t *pwc = *src;
64
65 if (src == NULL || *src == NULL) /* undefined behavior */
66 return 0;
67
68 if (dst != NULL)
69 {
70 while (n < len)
71 {
72 if ((ret = __wcrtomb_cp (dst, *pwc, cp, mb_max)) <= 0)
73 return (size_t) -1;
74 n += ret;
75 dst += ret;
76 if (*(dst - 1) == '\0')
77 {
78 *src = (wchar_t *) NULL;
79 return (n - 1);
80 }
81 pwc++;
82 }
83 *src = pwc;
84 }
85 else
86 {
87 char byte_bucket [MB_LEN_MAX];
88 while (1)
89 {
90 if ((ret = __wcrtomb_cp (&byte_bucket[0], *pwc, cp, mb_max)) <= 0)
91 return (size_t) -1;
92 n += ret;
93 if (byte_bucket [ret - 1] == '\0')
94 return (n - 1);
95 pwc++;
96 }
97 }
98
99 return n;
100 }
101