OSDN Git Service

More rationalization of CRT_INLINE function implementations.
[mingw/mingw-org-wsl.git] / mingwrt / mingwex / wcrtomb.c
1 #include "mb_wc_common.h"
2 #include <wchar.h>
3 #include <stdlib.h>
4 #include <errno.h>
5 #include <limits.h>
6 #define WIN32_LEAN_AND_MEAN
7 #include <windows.h>
8
9
10 static int __MINGW_ATTRIB_NONNULL(1)
11  __wcrtomb_cp (char *dst, wchar_t wc, const unsigned int cp,
12                const unsigned int mb_max)
13 {
14   if (cp == 0)
15     {
16       if (wc > 255)
17         {
18           errno = EILSEQ;
19           return -1;
20         }
21       *dst = (char) wc;
22       return 1;
23     }
24   else
25     {
26       int invalid_char = 0;
27
28       int size = WideCharToMultiByte (cp, 0 /* Is this correct flag? */,
29                                       &wc, 1, dst, mb_max,
30                                       NULL, &invalid_char);
31       if (size == 0 || invalid_char)
32         {
33           errno = EILSEQ;
34           return -1;
35         }
36       return size;
37     }
38 }
39
40 size_t
41 wcrtomb (char *dst, wchar_t wc, mbstate_t * __UNUSED_PARAM (ps))
42 {
43   char byte_bucket [MB_LEN_MAX];
44   char* tmp_dst = dst ? dst : byte_bucket;
45   return (size_t)__wcrtomb_cp (tmp_dst, wc, get_codepage (),
46                                MB_CUR_MAX);
47 }
48
49 size_t wcsrtombs (char *dst, const wchar_t **src, size_t len,
50                   mbstate_t * __UNUSED_PARAM (ps))
51 {
52   int ret = 0;
53   size_t n = 0;
54   const unsigned int cp = get_codepage();
55   const unsigned int mb_max = MB_CUR_MAX;
56   const wchar_t *pwc = *src;
57
58   if (src == NULL || *src == NULL) /* undefined behavior */
59      return 0;
60
61   if (dst != NULL)
62     {
63        while (n < len)
64         {
65           if ((ret = __wcrtomb_cp (dst, *pwc, cp, mb_max)) <= 0)
66              return (size_t) -1;
67           n += ret;
68           dst += ret;
69           if (*(dst - 1) == '\0')
70             {
71               *src = (wchar_t*) NULL;;
72               return (n  - 1);
73             }
74           pwc++;
75         }
76       *src = pwc;
77     }
78   else
79     {
80       char byte_bucket [MB_LEN_MAX];
81       while (n < len)
82         {
83           if ((ret = __wcrtomb_cp (byte_bucket, *pwc, cp, mb_max))
84                  <= 0)
85             return (size_t) -1;
86           n += ret;
87           if (byte_bucket [ret - 1] == '\0')
88             return (n - 1);
89           pwc++;
90         }
91     }
92
93   return n;
94 }