Fixed some warnings. removed some unneccessary includes, removed one
[wine] / win32 / code_page.c
1 /*
2  * Win32 kernel functions
3  *
4  * Copyright 1995 Martin von Loewis and Cameron Heide
5  */
6
7 #include <stdlib.h>
8 #include "winerror.h"
9 #include "winnls.h"
10 #include "heap.h"
11 #include "debug.h"
12
13
14 /******************************************************************************
15  * GetACP [KERNEL32.276]  Gets current ANSI code-page identifier.
16  *
17  * RETURNS
18  *    Current ANSI code-page identifier, default if no current defined
19  */
20 UINT WINAPI GetACP(void)
21 {
22     /* This introduces too many messages */
23 /*    FIXME(win32, "(void): stub\n"); */
24     return 1252;    /* Windows 3.1 ISO Latin */
25 }
26
27
28 /***********************************************************************
29  *           GetCPInfo            (KERNEL32.154)
30  */
31 BOOL WINAPI GetCPInfo( UINT codepage, LPCPINFO cpinfo )
32 {
33     cpinfo->DefaultChar[0] = '?';
34     switch (codepage)
35     {
36     case 932 : /* Shift JIS (japan) */
37         cpinfo->MaxCharSize = 2;
38         cpinfo->LeadByte[0]= 0x81; cpinfo->LeadByte[1] = 0x9F;
39         cpinfo->LeadByte[2]= 0xE0; cpinfo->LeadByte[3] = 0xFC;
40         cpinfo->LeadByte[4]= 0x00; cpinfo->LeadByte[5] = 0x00;
41         break;
42     case 936 : /* GB2312 (Chinese) */
43     case 949 : /* KSC5601-1987 (Korean) */
44     case 950 : /* BIG5 (Chinese) */
45         cpinfo->MaxCharSize = 2;
46         cpinfo->LeadByte[0]= 0x81; cpinfo->LeadByte[1] = 0xFE;
47         cpinfo->LeadByte[2]= 0x00; cpinfo->LeadByte[3] = 0x00;
48         break;
49     case 1361 : /* Johab (Korean) */
50         cpinfo->MaxCharSize = 2;
51         cpinfo->LeadByte[0]= 0x84; cpinfo->LeadByte[1] = 0xD3;
52         cpinfo->LeadByte[2]= 0xD8; cpinfo->LeadByte[3] = 0xDE;
53         cpinfo->LeadByte[4]= 0xE0; cpinfo->LeadByte[5] = 0xF9;
54         cpinfo->LeadByte[6]= 0x00; cpinfo->LeadByte[7] = 0x00;
55         break;
56     default :
57         cpinfo->MaxCharSize = 1;
58         cpinfo->LeadByte[0]= 0x00; cpinfo->LeadByte[1] = 0x00;
59         break;
60     }
61     return 1;
62 }
63
64 /***********************************************************************
65  *              GetOEMCP                (KERNEL32.248)
66  */
67 UINT WINAPI GetOEMCP(void)
68 {
69     return 437;    /* MS-DOS United States */
70 }
71
72 /***********************************************************************
73  *           IsValidCodePage   (KERNEL32.360)
74  */
75 BOOL WINAPI IsValidCodePage(UINT CodePage)
76 {
77     switch ( CodePage )
78     {
79     case 1252 :
80     case 437 :
81         return TRUE;
82     default :
83         return FALSE;
84     }
85 }
86
87
88 /***********************************************************************
89  *              MultiByteToWideChar                (KERNEL32.534)
90  *
91  * PARAMS
92  *   page [in]   Codepage character set to convert from
93  *   flags [in]  Character mapping flags
94  *   src [in]     Source string buffer
95  *   srclen [in]  Length of source string buffer
96  *   dst [in]     Destination buffer
97  *   dstlen [in]  Length of destination buffer
98  *
99  * NOTES
100  *   The returned length includes the null terminator character.
101  *
102  * RETURNS
103  *   Success: If dstlen > 0, number of characters written to destination
104  *            buffer.  If dstlen == 0, number of characters needed to do
105  *            conversion.
106  *   Failure: 0. Occurs if not enough space is available.
107  *
108  * ERRORS
109  *   ERROR_INSUFFICIENT_BUFFER
110  *   ERROR_INVALID_FLAGS (not yet implemented)
111  *   ERROR_INVALID_PARAMETER (not yet implemented)
112  *
113  * BUGS
114  *   Does not properly handle codepage conversions.
115  *   Does not properly handle flags.
116  *
117  */
118 INT WINAPI MultiByteToWideChar(UINT page, DWORD flags,
119                                  LPCSTR src, INT srclen,
120                                  LPWSTR dst, INT dstlen)
121 {
122     int ret;
123
124     if (srclen == -1)
125         srclen = lstrlenA(src)+1;
126     if (!dstlen || !dst)
127         return srclen;
128
129     ret = srclen;
130     while (srclen && dstlen) {
131         *dst = (WCHAR)(unsigned char)*src;
132         dst++;    src++;
133         dstlen--; srclen--;
134     }
135     if (!dstlen && srclen) {
136         SetLastError(ERROR_INSUFFICIENT_BUFFER);
137         return 0;
138     }
139     return ret;
140 }
141
142 /***********************************************************************
143  *              WideCharToMultiByte                (KERNEL32.727)
144  *
145  * PARAMS
146  *   page [in]    Codepage character set to convert to
147  *   flags [in]   Character mapping flags
148  *   src [in]     Source string buffer
149  *   srclen [in]  Length of source string buffer
150  *   dst [in]     Destination buffer
151  *   dstlen [in]  Length of destination buffer
152  *   defchar [in] Default character to use for conversion if no exact
153  *                  conversion can be made
154  *   used [out]   Set if default character was used in the conversion
155  *
156  * NOTES
157  *   The returned length includes the null terminator character.
158  *
159  * RETURNS
160  *   Success: If dstlen > 0, number of characters written to destination
161  *            buffer.  If dstlen == 0, number of characters needed to do
162  *            conversion.
163  *   Failure: 0. Occurs if not enough space is available.
164  *
165  * ERRORS
166  *   ERROR_INSUFFICIENT_BUFFER
167  *   ERROR_INVALID_FLAGS (not yet implemented)
168  *
169  * BUGS
170  *   Does not properly handle codepage conversions.
171  *   Does not properly handle flags.
172  *
173  */
174 INT WINAPI WideCharToMultiByte(UINT page, DWORD flags, LPCWSTR src,
175                                  INT srclen,LPSTR dst, INT dstlen,
176                                  LPCSTR defchar, BOOL *used)
177 {
178     int count = 0;
179     int eos = 0;
180     int care_for_eos=0;
181     int dont_copy= (dstlen==0);
182
183     if ((!src) | ((!dst) && (!dont_copy)) )
184     {   SetLastError(ERROR_INVALID_PARAMETER);
185         return 0;
186     }
187     
188     if (page!=GetACP() && page!=CP_OEMCP && page!=CP_ACP)
189         FIXME(win32,"Conversion in CP %d not supported\n",page);
190 #if 0
191     if (flags)
192         FIXME(win32,"flags %lx not supported\n",flags);
193 #endif
194     if(used)
195         *used=0;
196     if (srclen == -1)
197       {
198         srclen = lstrlenW(src)+1;
199          care_for_eos=1;
200       }
201     while(srclen && (dont_copy || dstlen))
202     {
203         if(!dont_copy){
204             if(*src<256)
205                 *dst = *src;
206             else
207             {
208                 /* ??? The WC_DEFAULTCHAR flag only gets used in
209                  * combination with the WC_COMPOSITECHECK flag or at
210                  * least this is what it seems from using the function
211                  * on NT4.0 in combination with reading the documentation.
212                  */
213                 *dst = defchar ? *defchar : '?';
214                 if(used)*used=1;
215             }
216             dstlen--;
217             dst++;
218         }
219         count++;
220         srclen--;
221         if((!*src) && care_for_eos) {
222             eos = 1;
223             break;
224         }
225         src++;
226     }
227     if (dont_copy)
228         return count;
229
230     if (!eos && srclen > 0) {
231         SetLastError(ERROR_INSUFFICIENT_BUFFER);
232         return 0;
233     }
234     return count;
235 }
236
237
238 /***********************************************************************
239  *           IsDBCSLeadByteEx   (KERNEL32.359)
240  */
241 BOOL WINAPI IsDBCSLeadByteEx( UINT codepage, BYTE testchar )
242 {
243     CPINFO cpinfo;
244     int i;
245
246     GetCPInfo(codepage, &cpinfo);
247     for (i = 0 ; i < sizeof(cpinfo.LeadByte)/sizeof(cpinfo.LeadByte[0]); i+=2)
248     {
249         if (cpinfo.LeadByte[i] == 0)
250             return FALSE;
251         if (cpinfo.LeadByte[i] <= testchar && testchar <= cpinfo.LeadByte[i+1])
252             return TRUE;
253     }
254     return FALSE;
255 }
256
257
258 /***********************************************************************
259  *           IsDBCSLeadByte16   (KERNEL.207)
260  */
261 BOOL16 WINAPI IsDBCSLeadByte16( BYTE testchar )
262 {
263     return IsDBCSLeadByteEx(GetACP(), testchar);
264 }
265
266
267 /***********************************************************************
268  *           IsDBCSLeadByte32   (KERNEL32.358)
269  */
270 BOOL WINAPI IsDBCSLeadByte( BYTE testchar )
271 {
272     return IsDBCSLeadByteEx(GetACP(), testchar);
273 }
274
275
276 /***********************************************************************
277  *              EnumSystemCodePages32A                (KERNEL32.92)
278  */
279 BOOL WINAPI EnumSystemCodePagesA(CODEPAGE_ENUMPROCA lpfnCodePageEnum,DWORD flags)
280 {
281         TRACE(win32,"(%p,%08lx)\n",lpfnCodePageEnum,flags);
282         lpfnCodePageEnum("437");
283         return TRUE;
284 }
285
286 /***********************************************************************
287  *              EnumSystemCodePages32W                (KERNEL32.93)
288  */
289 BOOL WINAPI EnumSystemCodePagesW( CODEPAGE_ENUMPROCW lpfnCodePageEnum,
290                                       DWORD flags)
291 {
292     WCHAR       *cp;
293     TRACE(win32,"(%p,%08lx)\n",lpfnCodePageEnum,flags );
294
295     cp = HEAP_strdupAtoW( GetProcessHeap(), 0, "437" );
296     lpfnCodePageEnum(cp);
297     HeapFree( GetProcessHeap(), 0, cp );
298     return TRUE;
299 }