OSDN Git Service

Modify "@copy 2012" to read "Copyright 2012, 2013".
[mingw/mingw-org-wsl.git] / src / libcrt / wchar / wcrtomb.c
1 /**
2  * @file wcrtomb.c
3  * Copyright 2012, 2013 MinGW.org project
4  *
5  * Permission is hereby granted, free of charge, to any person obtaining a
6  * copy of this software and associated documentation files (the "Software"),
7  * to deal in the Software without restriction, including without limitation
8  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
9  * and/or sell copies of the Software, and to permit persons to whom the
10  * Software is furnished to do so, subject to the following conditions:
11  * 
12  * The above copyright notice and this permission notice (including the next
13  * paragraph) shall be included in all copies or substantial portions of the
14  * Software.
15  * 
16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
22  * DEALINGS IN THE SOFTWARE.
23  */
24 #include "mb_wc_common.h"
25 #include <wchar.h>
26 #include <stdlib.h>
27 #include <errno.h>
28 #include <limits.h>
29 #define WIN32_LEAN_AND_MEAN
30 #include <windows.h>
31
32
33 static int __MINGW_ATTRIB_NONNULL(1)
34  __wcrtomb_cp (char *dst, wchar_t wc, const unsigned int cp,
35                const unsigned int mb_max)
36 {       
37   if (cp == 0)
38     {
39       if (wc > 255)
40         {
41           errno = EILSEQ;
42           return -1;
43         }
44       *dst = (char) wc;
45       return 1;
46     }
47   else
48     {
49       int invalid_char = 0;
50    
51       int size = WideCharToMultiByte (cp, 0 /* Is this correct flag? */,
52                                       &wc, 1, dst, mb_max,
53                                       NULL, &invalid_char);
54       if (size == 0 || invalid_char)  
55         {
56           errno = EILSEQ;
57           return -1;
58         }
59       return size;
60     }
61 }
62
63 size_t
64 wcrtomb (char *dst, wchar_t wc, mbstate_t * __UNUSED_PARAM (ps))
65 {
66   char byte_bucket [MB_LEN_MAX];
67   char* tmp_dst = dst ? dst : byte_bucket;      
68   return (size_t)__wcrtomb_cp (tmp_dst, wc, get_codepage (),
69                                MB_CUR_MAX);
70 }
71
72 size_t wcsrtombs (char *dst, const wchar_t **src, size_t len,
73                   mbstate_t * __UNUSED_PARAM (ps))
74 {
75   int ret = 0;
76   size_t n = 0;
77   const unsigned int cp = get_codepage();
78   const unsigned int mb_max = MB_CUR_MAX;
79   const wchar_t *pwc = *src;
80   
81   if (src == NULL || *src == NULL) /* undefined behavior */
82      return 0;
83
84   if (dst != NULL)
85     {
86        while (n < len)
87         {
88           if ((ret = __wcrtomb_cp (dst, *pwc, cp, mb_max)) <= 0)
89              return (size_t) -1;
90           n += ret;
91           dst += ret;
92           if (*(dst - 1) == '\0')
93             {
94               *src = (wchar_t*) NULL;;
95               return (n  - 1);
96             }
97           pwc++;
98         }
99       *src = pwc;
100     }
101   else
102     {
103       char byte_bucket [MB_LEN_MAX];
104       while (n < len)
105         {
106           if ((ret = __wcrtomb_cp (byte_bucket, *pwc, cp, mb_max))
107                  <= 0)
108             return (size_t) -1;    
109           n += ret;
110           if (byte_bucket [ret - 1] == '\0')
111             return (n - 1);
112           pwc++;
113         }
114     }
115  
116   return n;
117 }