GetClassInfo should return global classes even if the hInstance
[wine] / memory / codepage.c
1 /*
2  * Code page functions
3  *
4  * Copyright 2000 Alexandre Julliard
5  */
6
7 #include <assert.h>
8 #include <stdio.h>
9
10 #include "winbase.h"
11 #include "winerror.h"
12 #include "winnls.h"
13 #include "wine/unicode.h"
14 #include "debugtools.h"
15
16 DEFAULT_DEBUG_CHANNEL(string);
17
18 /* current code pages */
19 static unsigned int ansi_cp = 1252;  /* Windows 3.1 ISO Latin */
20 static unsigned int oem_cp = 437;    /* MS-DOS United States */
21 static unsigned int mac_cp = 10000;  /* Mac Roman */
22
23 static const union cptable *ansi_cptable;
24 static const union cptable *oem_cptable;
25 static const union cptable *mac_cptable;
26
27
28 /* find the table for a given codepage, handling CP_ACP etc. pseudo-codepages */
29 static const union cptable *get_codepage_table( unsigned int codepage )
30 {
31     const union cptable *ret = NULL;
32
33     if (!ansi_cptable)  /* initialize them */
34     {
35         /* FIXME: should load from the registry */
36         ansi_cptable = cp_get_table( ansi_cp );
37         oem_cptable = cp_get_table( oem_cp );
38         mac_cptable = cp_get_table( mac_cp );
39         assert( ansi_cptable );
40         assert( oem_cptable );
41         assert( mac_cptable );
42     }
43
44     switch(codepage)
45     {
46     case CP_ACP:        return ansi_cptable;
47     case CP_OEMCP:      return oem_cptable;
48     case CP_MACCP:      return mac_cptable;
49     case CP_THREAD_ACP: return ansi_cptable; /* FIXME */
50     case CP_UTF7:
51     case CP_UTF8:
52         break;
53     default:
54         if (codepage == ansi_cp) return ansi_cptable;
55         if (codepage == oem_cp) return oem_cptable;
56         if (codepage == mac_cp) return mac_cptable;
57         ret = cp_get_table( codepage );
58         break;
59     }
60     return ret;
61 }
62
63 /******************************************************************************
64  *              GetACP   (KERNEL32)
65  *
66  * RETURNS
67  *    Current ANSI code-page identifier, default if no current defined
68  */
69 UINT WINAPI GetACP(void)
70 {
71     return ansi_cp;
72 }
73
74
75 /***********************************************************************
76  *              GetOEMCP   (KERNEL32)
77  */
78 UINT WINAPI GetOEMCP(void)
79 {
80     return oem_cp;
81 }
82
83
84 /***********************************************************************
85  *           IsValidCodePage   (KERNEL32)
86  */
87 BOOL WINAPI IsValidCodePage( UINT codepage )
88 {
89     return cp_get_table( codepage ) != NULL;
90 }
91
92
93 /***********************************************************************
94  *           IsDBCSLeadByteEx   (KERNEL32)
95  */
96 BOOL WINAPI IsDBCSLeadByteEx( UINT codepage, BYTE testchar )
97 {
98     const union cptable *table = get_codepage_table( codepage );
99     return table && is_dbcs_leadbyte( table, testchar );
100 }
101
102
103 /***********************************************************************
104  *           IsDBCSLeadByte   (KERNEL32)
105  */
106 BOOL WINAPI IsDBCSLeadByte( BYTE testchar )
107 {
108     return is_dbcs_leadbyte( ansi_cptable, testchar );
109 }
110
111
112 /***********************************************************************
113  *           GetCPInfo   (KERNEL32)
114  */
115 BOOL WINAPI GetCPInfo( UINT codepage, LPCPINFO cpinfo )
116 {
117     const union cptable *table = get_codepage_table( codepage );
118
119     if (!table) 
120     {
121         SetLastError( ERROR_INVALID_PARAMETER );
122         return FALSE;
123     }
124     if (table->info.def_char & 0xff00)
125     {
126         cpinfo->DefaultChar[0] = table->info.def_char & 0xff00;
127         cpinfo->DefaultChar[1] = table->info.def_char & 0x00ff;
128     }
129     else
130     {
131         cpinfo->DefaultChar[0] = table->info.def_char & 0xff;
132         cpinfo->DefaultChar[1] = 0;
133     }
134     if ((cpinfo->MaxCharSize = table->info.char_size) == 2)
135         memcpy( cpinfo->LeadByte, table->dbcs.lead_bytes, sizeof(cpinfo->LeadByte) );
136     else
137         cpinfo->LeadByte[0] = cpinfo->LeadByte[1] = 0;
138
139     return TRUE;
140 }
141
142
143 /***********************************************************************
144  *              EnumSystemCodePagesA   (KERNEL32)
145  */
146 BOOL WINAPI EnumSystemCodePagesA( CODEPAGE_ENUMPROCA lpfnCodePageEnum, DWORD flags )
147 {
148     const union cptable *table;
149     char buffer[10];
150     int index = 0;
151
152     for (;;)
153     {
154         if (!(table = cp_enum_table( index++ ))) break;
155         sprintf( buffer, "%d", table->info.codepage );
156         if (!lpfnCodePageEnum( buffer )) break;
157     }
158     return TRUE;
159 }
160
161
162 /***********************************************************************
163  *              EnumSystemCodePagesW   (KERNEL32)
164  */
165 BOOL WINAPI EnumSystemCodePagesW( CODEPAGE_ENUMPROCW lpfnCodePageEnum, DWORD flags )
166 {
167     const union cptable *table;
168     WCHAR buffer[10], *p;
169     int page, index = 0;
170
171     for (;;)
172     {
173         if (!(table = cp_enum_table( index++ ))) break;
174         p = buffer + sizeof(buffer)/sizeof(WCHAR);
175         *--p = 0;
176         page = table->info.codepage;
177         do
178         {
179             *--p = '0' + (page % 10);
180             page /= 10;
181         } while( page );
182         if (!lpfnCodePageEnum( p )) break;
183     }
184     return TRUE;
185 }
186
187
188 /***********************************************************************
189  *              MultiByteToWideChar   (KERNEL32)
190  *
191  * PARAMS
192  *   page [in]    Codepage character set to convert from
193  *   flags [in]   Character mapping flags
194  *   src [in]     Source string buffer
195  *   srclen [in]  Length of source string buffer
196  *   dst [in]     Destination buffer
197  *   dstlen [in]  Length of destination buffer
198  *
199  * NOTES
200  *   The returned length includes the null terminator character.
201  *
202  * RETURNS
203  *   Success: If dstlen > 0, number of characters written to destination
204  *            buffer.  If dstlen == 0, number of characters needed to do
205  *            conversion.
206  *   Failure: 0. Occurs if not enough space is available.
207  *
208  * ERRORS
209  *   ERROR_INSUFFICIENT_BUFFER
210  *   ERROR_INVALID_PARAMETER
211  *   ERROR_NO_UNICODE_TRANSLATION
212  *
213  */
214 INT WINAPI MultiByteToWideChar( UINT page, DWORD flags, LPCSTR src, INT srclen,
215                                 LPWSTR dst, INT dstlen )
216 {
217     const union cptable *table;
218     int ret;
219
220     if (srclen == -1) srclen = strlen(src) + 1;
221
222     if (page >= CP_UTF7)
223     {
224         FIXME("UTF not supported\n");
225         SetLastError( ERROR_CALL_NOT_IMPLEMENTED );
226         return 0;
227     }
228
229     if (!(table = get_codepage_table( page )))
230     {
231         SetLastError( ERROR_INVALID_PARAMETER );
232         return 0;
233     }
234
235     if (flags & MB_COMPOSITE) FIXME("MB_COMPOSITE not supported\n");
236     if (flags & MB_USEGLYPHCHARS) FIXME("MB_USEGLYPHCHARS not supported\n");
237
238     ret = cp_mbstowcs( table, flags, src, srclen, dst, dstlen );
239
240     if (ret < 0)
241     {
242         switch(ret)
243         {
244         case -1: SetLastError( ERROR_INSUFFICIENT_BUFFER ); break;
245         case -2: SetLastError( ERROR_NO_UNICODE_TRANSLATION ); break;
246         }
247         ret = 0;
248     }
249     return ret;
250 }
251
252
253 /***********************************************************************
254  *              WideCharToMultiByte   (KERNEL32)
255  *
256  * PARAMS
257  *   page [in]    Codepage character set to convert to
258  *   flags [in]   Character mapping flags
259  *   src [in]     Source string buffer
260  *   srclen [in]  Length of source string buffer
261  *   dst [in]     Destination buffer
262  *   dstlen [in]  Length of destination buffer
263  *   defchar [in] Default character to use for conversion if no exact
264  *                  conversion can be made
265  *   used [out]   Set if default character was used in the conversion
266  *
267  * NOTES
268  *   The returned length includes the null terminator character.
269  *
270  * RETURNS
271  *   Success: If dstlen > 0, number of characters written to destination
272  *            buffer.  If dstlen == 0, number of characters needed to do
273  *            conversion.
274  *   Failure: 0. Occurs if not enough space is available.
275  *
276  * ERRORS
277  *   ERROR_INSUFFICIENT_BUFFER
278  *   ERROR_INVALID_PARAMETER
279  */
280 INT WINAPI WideCharToMultiByte( UINT page, DWORD flags, LPCWSTR src, INT srclen,
281                                 LPSTR dst, INT dstlen, LPCSTR defchar, BOOL *used )
282 {
283     const union cptable *table;
284     int ret, used_tmp;
285
286     if (srclen == -1) srclen = strlenW(src) + 1;
287
288     if (page >= CP_UTF7)
289     {
290         FIXME("UTF not supported\n");
291         SetLastError( ERROR_CALL_NOT_IMPLEMENTED );
292         return 0;
293     }
294
295     if (!(table = get_codepage_table( page )))
296     {
297         SetLastError( ERROR_INVALID_PARAMETER );
298         return 0;
299     }
300
301 /*    if (flags & WC_COMPOSITECHECK) FIXME( "WC_COMPOSITECHECK (%lx) not supported\n", flags );*/
302
303     ret = cp_wcstombs( table, flags, src, srclen, dst, dstlen, defchar, used ? &used_tmp : NULL );
304     if (used) *used = used_tmp;
305
306     if (ret == -1)
307     {
308         SetLastError( ERROR_INSUFFICIENT_BUFFER );
309         ret = 0;
310     }
311     return ret;
312 }