• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 <windows.h>
14 
15 static int __MINGW_ATTRIB_NONNULL(1) __MINGW_ATTRIB_NONNULL(4)
__mbrtowc_cp(wchar_t * __restrict__ pwc,const char * __restrict__ s,size_t n,mbstate_t * __restrict__ ps,const unsigned int cp,const unsigned int mb_max)16 __mbrtowc_cp (wchar_t * __restrict__ pwc, const char * __restrict__ s,
17 	      size_t n, mbstate_t* __restrict__ ps,
18 	      const unsigned int cp, const unsigned int mb_max)
19 {
20   union {
21     mbstate_t val;
22     char mbcs[4];
23   } shift_state;
24 
25   /* Do the prelim checks */
26   if (s == NULL)
27     return 0;
28 
29   if (n == 0)
30     /* The standard doesn't mention this case explicitly. Tell
31        caller that the conversion from a non-null s is incomplete. */
32     return -2;
33 
34   /* Save the current shift state, in case we need it in DBCS case.  */
35   shift_state.val = *ps;
36   *ps = 0;
37 
38   if (!*s)
39     {
40       *pwc = 0;
41       return 0;
42     }
43 
44   if (mb_max > 1)
45     {
46       if (shift_state.mbcs[0] != 0)
47 	{
48 	  /* Complete the mb char with the trailing byte.  */
49 	  shift_state.mbcs[1] = *s;  /* the second byte */
50 	  if (MultiByteToWideChar(cp, MB_ERR_INVALID_CHARS,
51 				  shift_state.mbcs, 2, pwc, 1)
52 		 == 0)
53 	    {
54 	      /* An invalid trailing byte */
55 	      errno = EILSEQ;
56 	      return -1;
57 	    }
58 	  return 2;
59 	}
60       else if (IsDBCSLeadByteEx (cp, *s))
61 	{
62 	  /* If told to translate one byte, just save the leadbyte
63 	     in *ps.  */
64 	  if (n < 2)
65 	    {
66 	      ((char*) ps)[0] = *s;
67 	      return -2;
68 	    }
69 	  /* Else translate the first two bytes  */
70 	  else if (MultiByteToWideChar (cp, MB_ERR_INVALID_CHARS,
71 					s, 2, pwc, 1)
72 		    == 0)
73 	    {
74 	      errno = EILSEQ;
75 	      return -1;
76 	    }
77 	  return 2;
78 	}
79     }
80 
81   /* Fall through to single byte char  */
82   if (cp == 0)
83       *pwc = (wchar_t)(unsigned char)*s;
84 
85   else if (MultiByteToWideChar (cp, MB_ERR_INVALID_CHARS, s, 1, pwc, 1)
86 	    == 0)
87     {
88       errno = EILSEQ;
89       return  -1;
90     }
91 
92   return 1;
93 }
94 
95 size_t
mbrtowc(wchar_t * __restrict__ pwc,const char * __restrict__ s,size_t n,mbstate_t * __restrict__ ps)96 mbrtowc (wchar_t * __restrict__ pwc, const char * __restrict__ s,
97 	 size_t n, mbstate_t* __restrict__ ps)
98 {
99   static mbstate_t internal_mbstate = 0;
100   wchar_t  byte_bucket = 0;
101   wchar_t* dst = pwc ? pwc : &byte_bucket;
102 
103   return (size_t) __mbrtowc_cp (dst, s, n, ps ? ps : &internal_mbstate,
104 				___lc_codepage_func(), MB_CUR_MAX);
105 }
106 
107 
108 size_t
mbsrtowcs(wchar_t * __restrict__ dst,const char ** __restrict__ src,size_t len,mbstate_t * __restrict__ ps)109 mbsrtowcs (wchar_t* __restrict__ dst,  const char ** __restrict__ src,
110 	   size_t len, mbstate_t* __restrict__ ps)
111 {
112   int ret =0 ;
113   size_t n = 0;
114   static mbstate_t internal_mbstate = 0;
115   mbstate_t* internal_ps = ps ? ps : &internal_mbstate;
116   const unsigned int cp = ___lc_codepage_func();
117   const unsigned int mb_max = MB_CUR_MAX;
118 
119   if (src == NULL || *src == NULL)	/* undefined behavior */
120     return 0;
121 
122   if (dst != NULL)
123     {
124       while (n < len
125 	     && (ret = __mbrtowc_cp(dst, *src, len - n,
126 				    internal_ps, cp, mb_max))
127 		  > 0)
128 	{
129 	  ++dst;
130 	  *src += ret;
131 	  n += ret;
132 	}
133 
134       if (n < len && ret == 0)
135 	*src = (char *)NULL;
136     }
137   else
138     {
139       wchar_t byte_bucket = 0;
140       while ((ret = __mbrtowc_cp (&byte_bucket, *src + n, mb_max,
141 				     internal_ps, cp, mb_max))
142 		  > 0)
143 	n += ret;
144     }
145   return n;
146 }
147 
148 size_t
mbrlen(const char * __restrict__ s,size_t n,mbstate_t * __restrict__ ps)149 mbrlen (const char * __restrict__ s, size_t n,
150 	mbstate_t * __restrict__ ps)
151 {
152   static mbstate_t s_mbstate = 0;
153   wchar_t byte_bucket = 0;
154   return __mbrtowc_cp (&byte_bucket, s, n, (ps) ? ps : &s_mbstate,
155 		       ___lc_codepage_func(), MB_CUR_MAX);
156 }
157