ReactOS 0.4.16-dev-303-g11d5cb8
win_iconv.c
Go to the documentation of this file.
1/*
2 * iconv implementation using Win32 API to convert.
3 *
4 * This file is placed in the public domain.
5 */
6
7/* for WC_NO_BEST_FIT_CHARS */
8#ifndef WINVER
9# define WINVER 0x0500
10#endif
11
12#define STRICT
13#include <windows.h>
14#include <errno.h>
15#include <string.h>
16#include <stdlib.h>
17
18#ifdef __GNUC__
19#define UNUSED __attribute__((unused))
20#else
21#define UNUSED
22#endif
23
24/* WORKAROUND: */
25#ifndef UNDER_CE
26#define GetProcAddressA GetProcAddress
27#endif
28
29#if 0
30# define MAKE_EXE
31# define MAKE_DLL
32# define USE_LIBICONV_DLL
33#endif
34
35#if !defined(DEFAULT_LIBICONV_DLL)
36# define DEFAULT_LIBICONV_DLL ""
37#endif
38
39#define MB_CHAR_MAX 16
40
41#define UNICODE_MODE_BOM_DONE 1
42#define UNICODE_MODE_SWAPPED 2
43
44#define FLAG_USE_BOM 1
45#define FLAG_TRANSLIT 2 /* //TRANSLIT */
46#define FLAG_IGNORE 4 /* //IGNORE */
47
48typedef unsigned char uchar;
49typedef unsigned short ushort;
50typedef unsigned int uint;
51
52typedef void* iconv_t;
53
54iconv_t iconv_open(const char *tocode, const char *fromcode);
56size_t iconv(iconv_t cd, const char **inbuf, size_t *inbytesleft, char **outbuf, size_t *outbytesleft);
57
58/* libiconv interface for vim */
59#if defined(MAKE_DLL)
60int
61iconvctl (iconv_t cd, int request, void* argument)
62{
63 /* not supported */
64 return 0;
65}
66#endif
67
68typedef struct compat_t compat_t;
69typedef struct csconv_t csconv_t;
70typedef struct rec_iconv_t rec_iconv_t;
71
72typedef iconv_t (*f_iconv_open)(const char *tocode, const char *fromcode);
74typedef size_t (*f_iconv)(iconv_t cd, const char **inbuf, size_t *inbytesleft, char **outbuf, size_t *outbytesleft);
75typedef int* (*f_errno)(void);
76typedef int (*f_mbtowc)(csconv_t *cv, const uchar *buf, int bufsize, ushort *wbuf, int *wbufsize);
77typedef int (*f_wctomb)(csconv_t *cv, ushort *wbuf, int wbufsize, uchar *buf, int bufsize);
78typedef int (*f_mblen)(csconv_t *cv, const uchar *buf, int bufsize);
79typedef int (*f_flush)(csconv_t *cv, uchar *buf, int bufsize);
80
81#define COMPAT_IN 1
82#define COMPAT_OUT 2
83
84/* unicode mapping for compatibility with other conversion table. */
85struct compat_t {
89};
90
91struct csconv_t {
93 int flags;
100};
101
109#if defined(USE_LIBICONV_DLL)
110 HMODULE hlibiconv;
111#endif
112};
113
114static int win_iconv_open(rec_iconv_t *cd, const char *tocode, const char *fromcode);
115static int win_iconv_close(iconv_t cd);
116static size_t win_iconv(iconv_t cd, const char **inbuf, size_t *inbytesleft, char **outbuf, size_t *outbytesleft);
117
118static int load_mlang(void);
119static int make_csconv(const char *name, csconv_t *cv);
120static int name_to_codepage(const char *name);
121static uint utf16_to_ucs4(const ushort *wbuf);
122static void ucs4_to_utf16(uint wc, ushort *wbuf, int *wbufsize);
123static int mbtowc_flags(int codepage);
125static char *strrstr(const char *str, const char *token);
126static char *xstrndup(const char *s, size_t n);
127static int seterror(int err);
128
129#if defined(USE_LIBICONV_DLL)
130static int libiconv_iconv_open(rec_iconv_t *cd, const char *tocode, const char *fromcode);
131static PVOID MyImageDirectoryEntryToData(LPVOID Base, BOOLEAN MappedAsImage, USHORT DirectoryEntry, PULONG Size);
132static FARPROC find_imported_function(HMODULE hModule, const char *funcname);
133
134static HMODULE hwiniconv;
135#endif
136
137static int sbcs_mblen(csconv_t *cv, const uchar *buf, int bufsize);
138static int dbcs_mblen(csconv_t *cv, const uchar *buf, int bufsize);
139static int mbcs_mblen(csconv_t *cv, const uchar *buf, int bufsize);
140static int utf8_mblen(csconv_t *cv, const uchar *buf, int bufsize);
141static int eucjp_mblen(csconv_t *cv, const uchar *buf, int bufsize);
142
143static int kernel_mbtowc(csconv_t *cv, const uchar *buf, int bufsize, ushort *wbuf, int *wbufsize);
144static int kernel_wctomb(csconv_t *cv, ushort *wbuf, int wbufsize, uchar *buf, int bufsize);
145static int mlang_mbtowc(csconv_t *cv, const uchar *buf, int bufsize, ushort *wbuf, int *wbufsize);
146static int mlang_wctomb(csconv_t *cv, ushort *wbuf, int wbufsize, uchar *buf, int bufsize);
147static int utf16_mbtowc(csconv_t *cv, const uchar *buf, int bufsize, ushort *wbuf, int *wbufsize);
148static int utf16_wctomb(csconv_t *cv, ushort *wbuf, int wbufsize, uchar *buf, int bufsize);
149static int utf32_mbtowc(csconv_t *cv, const uchar *buf, int bufsize, ushort *wbuf, int *wbufsize);
150static int utf32_wctomb(csconv_t *cv, ushort *wbuf, int wbufsize, uchar *buf, int bufsize);
151static int iso2022jp_mbtowc(csconv_t *cv, const uchar *buf, int bufsize, ushort *wbuf, int *wbufsize);
152static int iso2022jp_wctomb(csconv_t *cv, ushort *wbuf, int wbufsize, uchar *buf, int bufsize);
153static int iso2022jp_flush(csconv_t *cv, uchar *buf, int bufsize);
154
155static struct {
157 const char *name;
158} codepage_alias[] = {
159 {65001, "CP65001"},
160 {65001, "UTF8"},
161 {65001, "UTF-8"},
162
163 {1200, "CP1200"},
164 {1200, "UTF16LE"},
165 {1200, "UTF-16LE"},
166 {1200, "UCS2LE"},
167 {1200, "UCS-2LE"},
168
169 {1201, "CP1201"},
170 {1201, "UTF16BE"},
171 {1201, "UTF-16BE"},
172 {1201, "UCS2BE"},
173 {1201, "UCS-2BE"},
174 {1201, "unicodeFFFE"},
175
176 {12000, "CP12000"},
177 {12000, "UTF32LE"},
178 {12000, "UTF-32LE"},
179 {12000, "UCS4LE"},
180 {12000, "UCS-4LE"},
181
182 {12001, "CP12001"},
183 {12001, "UTF32BE"},
184 {12001, "UTF-32BE"},
185 {12001, "UCS4BE"},
186 {12001, "UCS-4BE"},
187
188#ifndef GLIB_COMPILATION
189 /*
190 * Default is big endian.
191 * See rfc2781 4.3 Interpreting text labelled as UTF-16.
192 */
193 {1201, "UTF16"},
194 {1201, "UTF-16"},
195 {1201, "UCS2"},
196 {1201, "UCS-2"},
197 {12001, "UTF32"},
198 {12001, "UTF-32"},
199 {12001, "UCS-4"},
200 {12001, "UCS4"},
201#else
202 /* Default is little endian, because the platform is */
203 {1200, "UTF16"},
204 {1200, "UTF-16"},
205 {1200, "UCS2"},
206 {1200, "UCS-2"},
207 {12000, "UTF32"},
208 {12000, "UTF-32"},
209 {12000, "UCS4"},
210 {12000, "UCS-4"},
211#endif
212
213 /* copy from libiconv `iconv -l` */
214 /* !IsValidCodePage(367) */
215 {20127, "ANSI_X3.4-1968"},
216 {20127, "ANSI_X3.4-1986"},
217 {20127, "ASCII"},
218 {20127, "CP367"},
219 {20127, "IBM367"},
220 {20127, "ISO-IR-6"},
221 {20127, "ISO646-US"},
222 {20127, "ISO_646.IRV:1991"},
223 {20127, "US"},
224 {20127, "US-ASCII"},
225 {20127, "CSASCII"},
226
227 /* !IsValidCodePage(819) */
228 {1252, "CP819"},
229 {1252, "IBM819"},
230 {28591, "ISO-8859-1"},
231 {28591, "ISO-IR-100"},
232 {28591, "ISO8859-1"},
233 {28591, "ISO_8859-1"},
234 {28591, "ISO_8859-1:1987"},
235 {28591, "L1"},
236 {28591, "LATIN1"},
237 {28591, "CSISOLATIN1"},
238
239 {1250, "CP1250"},
240 {1250, "MS-EE"},
241 {1250, "WINDOWS-1250"},
242
243 {1251, "CP1251"},
244 {1251, "MS-CYRL"},
245 {1251, "WINDOWS-1251"},
246
247 {1252, "CP1252"},
248 {1252, "MS-ANSI"},
249 {1252, "WINDOWS-1252"},
250
251 {1253, "CP1253"},
252 {1253, "MS-GREEK"},
253 {1253, "WINDOWS-1253"},
254
255 {1254, "CP1254"},
256 {1254, "MS-TURK"},
257 {1254, "WINDOWS-1254"},
258
259 {1255, "CP1255"},
260 {1255, "MS-HEBR"},
261 {1255, "WINDOWS-1255"},
262
263 {1256, "CP1256"},
264 {1256, "MS-ARAB"},
265 {1256, "WINDOWS-1256"},
266
267 {1257, "CP1257"},
268 {1257, "WINBALTRIM"},
269 {1257, "WINDOWS-1257"},
270
271 {1258, "CP1258"},
272 {1258, "WINDOWS-1258"},
273
274 {850, "850"},
275 {850, "CP850"},
276 {850, "IBM850"},
277 {850, "CSPC850MULTILINGUAL"},
278
279 /* !IsValidCodePage(862) */
280 {862, "862"},
281 {862, "CP862"},
282 {862, "IBM862"},
283 {862, "CSPC862LATINHEBREW"},
284
285 {866, "866"},
286 {866, "CP866"},
287 {866, "IBM866"},
288 {866, "CSIBM866"},
289
290 /* !IsValidCodePage(154) */
291 {154, "CP154"},
292 {154, "CYRILLIC-ASIAN"},
293 {154, "PT154"},
294 {154, "PTCP154"},
295 {154, "CSPTCP154"},
296
297 /* !IsValidCodePage(1133) */
298 {1133, "CP1133"},
299 {1133, "IBM-CP1133"},
300
301 {874, "CP874"},
302 {874, "WINDOWS-874"},
303
304 /* !IsValidCodePage(51932) */
305 {51932, "CP51932"},
306 {51932, "MS51932"},
307 {51932, "WINDOWS-51932"},
308 {51932, "EUC-JP"},
309
310 {932, "CP932"},
311 {932, "MS932"},
312 {932, "SHIFFT_JIS"},
313 {932, "SHIFFT_JIS-MS"},
314 {932, "SJIS"},
315 {932, "SJIS-MS"},
316 {932, "SJIS-OPEN"},
317 {932, "SJIS-WIN"},
318 {932, "WINDOWS-31J"},
319 {932, "WINDOWS-932"},
320 {932, "CSWINDOWS31J"},
321
322 {50221, "CP50221"},
323 {50221, "ISO-2022-JP"},
324 {50221, "ISO-2022-JP-MS"},
325 {50221, "ISO2022-JP"},
326 {50221, "ISO2022-JP-MS"},
327 {50221, "MS50221"},
328 {50221, "WINDOWS-50221"},
329
330 {936, "CP936"},
331 {936, "GBK"},
332 {936, "MS936"},
333 {936, "WINDOWS-936"},
334
335 {950, "CP950"},
336 {950, "BIG5"},
337 {950, "BIG5HKSCS"},
338 {950, "BIG5-HKSCS"},
339
340 {949, "CP949"},
341 {949, "UHC"},
342 {949, "EUC-KR"},
343
344 {1361, "CP1361"},
345 {1361, "JOHAB"},
346
347 {437, "437"},
348 {437, "CP437"},
349 {437, "IBM437"},
350 {437, "CSPC8CODEPAGE437"},
351
352 {737, "CP737"},
353
354 {775, "CP775"},
355 {775, "IBM775"},
356 {775, "CSPC775BALTIC"},
357
358 {852, "852"},
359 {852, "CP852"},
360 {852, "IBM852"},
361 {852, "CSPCP852"},
362
363 /* !IsValidCodePage(853) */
364 {853, "CP853"},
365
366 {855, "855"},
367 {855, "CP855"},
368 {855, "IBM855"},
369 {855, "CSIBM855"},
370
371 {857, "857"},
372 {857, "CP857"},
373 {857, "IBM857"},
374 {857, "CSIBM857"},
375
376 /* !IsValidCodePage(858) */
377 {858, "CP858"},
378
379 {860, "860"},
380 {860, "CP860"},
381 {860, "IBM860"},
382 {860, "CSIBM860"},
383
384 {861, "861"},
385 {861, "CP-IS"},
386 {861, "CP861"},
387 {861, "IBM861"},
388 {861, "CSIBM861"},
389
390 {863, "863"},
391 {863, "CP863"},
392 {863, "IBM863"},
393 {863, "CSIBM863"},
394
395 {864, "CP864"},
396 {864, "IBM864"},
397 {864, "CSIBM864"},
398
399 {865, "865"},
400 {865, "CP865"},
401 {865, "IBM865"},
402 {865, "CSIBM865"},
403
404 {869, "869"},
405 {869, "CP-GR"},
406 {869, "CP869"},
407 {869, "IBM869"},
408 {869, "CSIBM869"},
409
410 /* !IsValidCodePage(1152) */
411 {1125, "CP1125"},
412
413 /*
414 * Code Page Identifiers
415 * http://msdn2.microsoft.com/en-us/library/ms776446.aspx
416 */
417 {37, "IBM037"}, /* IBM EBCDIC US-Canada */
418 {437, "IBM437"}, /* OEM United States */
419 {500, "IBM500"}, /* IBM EBCDIC International */
420 {708, "ASMO-708"}, /* Arabic (ASMO 708) */
421 /* 709 Arabic (ASMO-449+, BCON V4) */
422 /* 710 Arabic - Transparent Arabic */
423 {720, "DOS-720"}, /* Arabic (Transparent ASMO); Arabic (DOS) */
424 {737, "ibm737"}, /* OEM Greek (formerly 437G); Greek (DOS) */
425 {775, "ibm775"}, /* OEM Baltic; Baltic (DOS) */
426 {850, "ibm850"}, /* OEM Multilingual Latin 1; Western European (DOS) */
427 {852, "ibm852"}, /* OEM Latin 2; Central European (DOS) */
428 {855, "IBM855"}, /* OEM Cyrillic (primarily Russian) */
429 {857, "ibm857"}, /* OEM Turkish; Turkish (DOS) */
430 {858, "IBM00858"}, /* OEM Multilingual Latin 1 + Euro symbol */
431 {860, "IBM860"}, /* OEM Portuguese; Portuguese (DOS) */
432 {861, "ibm861"}, /* OEM Icelandic; Icelandic (DOS) */
433 {862, "DOS-862"}, /* OEM Hebrew; Hebrew (DOS) */
434 {863, "IBM863"}, /* OEM French Canadian; French Canadian (DOS) */
435 {864, "IBM864"}, /* OEM Arabic; Arabic (864) */
436 {865, "IBM865"}, /* OEM Nordic; Nordic (DOS) */
437 {866, "cp866"}, /* OEM Russian; Cyrillic (DOS) */
438 {869, "ibm869"}, /* OEM Modern Greek; Greek, Modern (DOS) */
439 {870, "IBM870"}, /* IBM EBCDIC Multilingual/ROECE (Latin 2); IBM EBCDIC Multilingual Latin 2 */
440 {874, "windows-874"}, /* ANSI/OEM Thai (same as 28605, ISO 8859-15); Thai (Windows) */
441 {875, "cp875"}, /* IBM EBCDIC Greek Modern */
442 {932, "shift_jis"}, /* ANSI/OEM Japanese; Japanese (Shift-JIS) */
443 {932, "shift-jis"}, /* alternative name for it */
444 {936, "gb2312"}, /* ANSI/OEM Simplified Chinese (PRC, Singapore); Chinese Simplified (GB2312) */
445 {949, "ks_c_5601-1987"}, /* ANSI/OEM Korean (Unified Hangul Code) */
446 {950, "big5"}, /* ANSI/OEM Traditional Chinese (Taiwan; Hong Kong SAR, PRC); Chinese Traditional (Big5) */
447 {950, "big5hkscs"}, /* ANSI/OEM Traditional Chinese (Hong Kong SAR); Chinese Traditional (Big5-HKSCS) */
448 {950, "big5-hkscs"}, /* alternative name for it */
449 {1026, "IBM1026"}, /* IBM EBCDIC Turkish (Latin 5) */
450 {1047, "IBM01047"}, /* IBM EBCDIC Latin 1/Open System */
451 {1140, "IBM01140"}, /* IBM EBCDIC US-Canada (037 + Euro symbol); IBM EBCDIC (US-Canada-Euro) */
452 {1141, "IBM01141"}, /* IBM EBCDIC Germany (20273 + Euro symbol); IBM EBCDIC (Germany-Euro) */
453 {1142, "IBM01142"}, /* IBM EBCDIC Denmark-Norway (20277 + Euro symbol); IBM EBCDIC (Denmark-Norway-Euro) */
454 {1143, "IBM01143"}, /* IBM EBCDIC Finland-Sweden (20278 + Euro symbol); IBM EBCDIC (Finland-Sweden-Euro) */
455 {1144, "IBM01144"}, /* IBM EBCDIC Italy (20280 + Euro symbol); IBM EBCDIC (Italy-Euro) */
456 {1145, "IBM01145"}, /* IBM EBCDIC Latin America-Spain (20284 + Euro symbol); IBM EBCDIC (Spain-Euro) */
457 {1146, "IBM01146"}, /* IBM EBCDIC United Kingdom (20285 + Euro symbol); IBM EBCDIC (UK-Euro) */
458 {1147, "IBM01147"}, /* IBM EBCDIC France (20297 + Euro symbol); IBM EBCDIC (France-Euro) */
459 {1148, "IBM01148"}, /* IBM EBCDIC International (500 + Euro symbol); IBM EBCDIC (International-Euro) */
460 {1149, "IBM01149"}, /* IBM EBCDIC Icelandic (20871 + Euro symbol); IBM EBCDIC (Icelandic-Euro) */
461 {1250, "windows-1250"}, /* ANSI Central European; Central European (Windows) */
462 {1251, "windows-1251"}, /* ANSI Cyrillic; Cyrillic (Windows) */
463 {1252, "windows-1252"}, /* ANSI Latin 1; Western European (Windows) */
464 {1253, "windows-1253"}, /* ANSI Greek; Greek (Windows) */
465 {1254, "windows-1254"}, /* ANSI Turkish; Turkish (Windows) */
466 {1255, "windows-1255"}, /* ANSI Hebrew; Hebrew (Windows) */
467 {1256, "windows-1256"}, /* ANSI Arabic; Arabic (Windows) */
468 {1257, "windows-1257"}, /* ANSI Baltic; Baltic (Windows) */
469 {1258, "windows-1258"}, /* ANSI/OEM Vietnamese; Vietnamese (Windows) */
470 {1361, "Johab"}, /* Korean (Johab) */
471 {10000, "macintosh"}, /* MAC Roman; Western European (Mac) */
472 {10001, "x-mac-japanese"}, /* Japanese (Mac) */
473 {10002, "x-mac-chinesetrad"}, /* MAC Traditional Chinese (Big5); Chinese Traditional (Mac) */
474 {10003, "x-mac-korean"}, /* Korean (Mac) */
475 {10004, "x-mac-arabic"}, /* Arabic (Mac) */
476 {10005, "x-mac-hebrew"}, /* Hebrew (Mac) */
477 {10006, "x-mac-greek"}, /* Greek (Mac) */
478 {10007, "x-mac-cyrillic"}, /* Cyrillic (Mac) */
479 {10008, "x-mac-chinesesimp"}, /* MAC Simplified Chinese (GB 2312); Chinese Simplified (Mac) */
480 {10010, "x-mac-romanian"}, /* Romanian (Mac) */
481 {10017, "x-mac-ukrainian"}, /* Ukrainian (Mac) */
482 {10021, "x-mac-thai"}, /* Thai (Mac) */
483 {10029, "x-mac-ce"}, /* MAC Latin 2; Central European (Mac) */
484 {10079, "x-mac-icelandic"}, /* Icelandic (Mac) */
485 {10081, "x-mac-turkish"}, /* Turkish (Mac) */
486 {10082, "x-mac-croatian"}, /* Croatian (Mac) */
487 {20000, "x-Chinese_CNS"}, /* CNS Taiwan; Chinese Traditional (CNS) */
488 {20001, "x-cp20001"}, /* TCA Taiwan */
489 {20002, "x_Chinese-Eten"}, /* Eten Taiwan; Chinese Traditional (Eten) */
490 {20003, "x-cp20003"}, /* IBM5550 Taiwan */
491 {20004, "x-cp20004"}, /* TeleText Taiwan */
492 {20005, "x-cp20005"}, /* Wang Taiwan */
493 {20105, "x-IA5"}, /* IA5 (IRV International Alphabet No. 5, 7-bit); Western European (IA5) */
494 {20106, "x-IA5-German"}, /* IA5 German (7-bit) */
495 {20107, "x-IA5-Swedish"}, /* IA5 Swedish (7-bit) */
496 {20108, "x-IA5-Norwegian"}, /* IA5 Norwegian (7-bit) */
497 {20127, "us-ascii"}, /* US-ASCII (7-bit) */
498 {20261, "x-cp20261"}, /* T.61 */
499 {20269, "x-cp20269"}, /* ISO 6937 Non-Spacing Accent */
500 {20273, "IBM273"}, /* IBM EBCDIC Germany */
501 {20277, "IBM277"}, /* IBM EBCDIC Denmark-Norway */
502 {20278, "IBM278"}, /* IBM EBCDIC Finland-Sweden */
503 {20280, "IBM280"}, /* IBM EBCDIC Italy */
504 {20284, "IBM284"}, /* IBM EBCDIC Latin America-Spain */
505 {20285, "IBM285"}, /* IBM EBCDIC United Kingdom */
506 {20290, "IBM290"}, /* IBM EBCDIC Japanese Katakana Extended */
507 {20297, "IBM297"}, /* IBM EBCDIC France */
508 {20420, "IBM420"}, /* IBM EBCDIC Arabic */
509 {20423, "IBM423"}, /* IBM EBCDIC Greek */
510 {20424, "IBM424"}, /* IBM EBCDIC Hebrew */
511 {20833, "x-EBCDIC-KoreanExtended"}, /* IBM EBCDIC Korean Extended */
512 {20838, "IBM-Thai"}, /* IBM EBCDIC Thai */
513 {20866, "koi8-r"}, /* Russian (KOI8-R); Cyrillic (KOI8-R) */
514 {20871, "IBM871"}, /* IBM EBCDIC Icelandic */
515 {20880, "IBM880"}, /* IBM EBCDIC Cyrillic Russian */
516 {20905, "IBM905"}, /* IBM EBCDIC Turkish */
517 {20924, "IBM00924"}, /* IBM EBCDIC Latin 1/Open System (1047 + Euro symbol) */
518 {20932, "EUC-JP"}, /* Japanese (JIS 0208-1990 and 0121-1990) */
519 {20936, "x-cp20936"}, /* Simplified Chinese (GB2312); Chinese Simplified (GB2312-80) */
520 {20949, "x-cp20949"}, /* Korean Wansung */
521 {21025, "cp1025"}, /* IBM EBCDIC Cyrillic Serbian-Bulgarian */
522 /* 21027 (deprecated) */
523 {21866, "koi8-u"}, /* Ukrainian (KOI8-U); Cyrillic (KOI8-U) */
524 {28591, "iso-8859-1"}, /* ISO 8859-1 Latin 1; Western European (ISO) */
525 {28591, "iso8859-1"}, /* ISO 8859-1 Latin 1; Western European (ISO) */
526 {28591, "iso_8859-1"},
527 {28591, "iso_8859_1"},
528 {28592, "iso-8859-2"}, /* ISO 8859-2 Central European; Central European (ISO) */
529 {28592, "iso8859-2"}, /* ISO 8859-2 Central European; Central European (ISO) */
530 {28592, "iso_8859-2"},
531 {28592, "iso_8859_2"},
532 {28593, "iso-8859-3"}, /* ISO 8859-3 Latin 3 */
533 {28593, "iso8859-3"}, /* ISO 8859-3 Latin 3 */
534 {28593, "iso_8859-3"},
535 {28593, "iso_8859_3"},
536 {28594, "iso-8859-4"}, /* ISO 8859-4 Baltic */
537 {28594, "iso8859-4"}, /* ISO 8859-4 Baltic */
538 {28594, "iso_8859-4"},
539 {28594, "iso_8859_4"},
540 {28595, "iso-8859-5"}, /* ISO 8859-5 Cyrillic */
541 {28595, "iso8859-5"}, /* ISO 8859-5 Cyrillic */
542 {28595, "iso_8859-5"},
543 {28595, "iso_8859_5"},
544 {28596, "iso-8859-6"}, /* ISO 8859-6 Arabic */
545 {28596, "iso8859-6"}, /* ISO 8859-6 Arabic */
546 {28596, "iso_8859-6"},
547 {28596, "iso_8859_6"},
548 {28597, "iso-8859-7"}, /* ISO 8859-7 Greek */
549 {28597, "iso8859-7"}, /* ISO 8859-7 Greek */
550 {28597, "iso_8859-7"},
551 {28597, "iso_8859_7"},
552 {28598, "iso-8859-8"}, /* ISO 8859-8 Hebrew; Hebrew (ISO-Visual) */
553 {28598, "iso8859-8"}, /* ISO 8859-8 Hebrew; Hebrew (ISO-Visual) */
554 {28598, "iso_8859-8"},
555 {28598, "iso_8859_8"},
556 {28599, "iso-8859-9"}, /* ISO 8859-9 Turkish */
557 {28599, "iso8859-9"}, /* ISO 8859-9 Turkish */
558 {28599, "iso_8859-9"},
559 {28599, "iso_8859_9"},
560 {28603, "iso-8859-13"}, /* ISO 8859-13 Estonian */
561 {28603, "iso8859-13"}, /* ISO 8859-13 Estonian */
562 {28603, "iso_8859-13"},
563 {28603, "iso_8859_13"},
564 {28605, "iso-8859-15"}, /* ISO 8859-15 Latin 9 */
565 {28605, "iso8859-15"}, /* ISO 8859-15 Latin 9 */
566 {28605, "iso_8859-15"},
567 {28605, "iso_8859_15"},
568 {29001, "x-Europa"}, /* Europa 3 */
569 {38598, "iso-8859-8-i"}, /* ISO 8859-8 Hebrew; Hebrew (ISO-Logical) */
570 {38598, "iso8859-8-i"}, /* ISO 8859-8 Hebrew; Hebrew (ISO-Logical) */
571 {38598, "iso_8859-8-i"},
572 {38598, "iso_8859_8-i"},
573 {50220, "iso-2022-jp"}, /* ISO 2022 Japanese with no halfwidth Katakana; Japanese (JIS) */
574 {50221, "csISO2022JP"}, /* ISO 2022 Japanese with halfwidth Katakana; Japanese (JIS-Allow 1 byte Kana) */
575 {50222, "iso-2022-jp"}, /* ISO 2022 Japanese JIS X 0201-1989; Japanese (JIS-Allow 1 byte Kana - SO/SI) */
576 {50225, "iso-2022-kr"}, /* ISO 2022 Korean */
577 {50225, "iso2022-kr"}, /* ISO 2022 Korean */
578 {50227, "x-cp50227"}, /* ISO 2022 Simplified Chinese; Chinese Simplified (ISO 2022) */
579 /* 50229 ISO 2022 Traditional Chinese */
580 /* 50930 EBCDIC Japanese (Katakana) Extended */
581 /* 50931 EBCDIC US-Canada and Japanese */
582 /* 50933 EBCDIC Korean Extended and Korean */
583 /* 50935 EBCDIC Simplified Chinese Extended and Simplified Chinese */
584 /* 50936 EBCDIC Simplified Chinese */
585 /* 50937 EBCDIC US-Canada and Traditional Chinese */
586 /* 50939 EBCDIC Japanese (Latin) Extended and Japanese */
587 {51932, "euc-jp"}, /* EUC Japanese */
588 {51936, "EUC-CN"}, /* EUC Simplified Chinese; Chinese Simplified (EUC) */
589 {51949, "euc-kr"}, /* EUC Korean */
590 /* 51950 EUC Traditional Chinese */
591 {52936, "hz-gb-2312"}, /* HZ-GB2312 Simplified Chinese; Chinese Simplified (HZ) */
592 {54936, "GB18030"}, /* Windows XP and later: GB18030 Simplified Chinese (4 byte); Chinese Simplified (GB18030) */
593 {57002, "x-iscii-de"}, /* ISCII Devanagari */
594 {57003, "x-iscii-be"}, /* ISCII Bengali */
595 {57004, "x-iscii-ta"}, /* ISCII Tamil */
596 {57005, "x-iscii-te"}, /* ISCII Telugu */
597 {57006, "x-iscii-as"}, /* ISCII Assamese */
598 {57007, "x-iscii-or"}, /* ISCII Oriya */
599 {57008, "x-iscii-ka"}, /* ISCII Kannada */
600 {57009, "x-iscii-ma"}, /* ISCII Malayalam */
601 {57010, "x-iscii-gu"}, /* ISCII Gujarati */
602 {57011, "x-iscii-pa"}, /* ISCII Punjabi */
603
604 {0, NULL}
606
607/*
608 * SJIS SHIFTJIS table CP932 table
609 * ---- --------------------------- --------------------------------
610 * 5C U+00A5 YEN SIGN U+005C REVERSE SOLIDUS
611 * 7E U+203E OVERLINE U+007E TILDE
612 * 815C U+2014 EM DASH U+2015 HORIZONTAL BAR
613 * 815F U+005C REVERSE SOLIDUS U+FF3C FULLWIDTH REVERSE SOLIDUS
614 * 8160 U+301C WAVE DASH U+FF5E FULLWIDTH TILDE
615 * 8161 U+2016 DOUBLE VERTICAL LINE U+2225 PARALLEL TO
616 * 817C U+2212 MINUS SIGN U+FF0D FULLWIDTH HYPHEN-MINUS
617 * 8191 U+00A2 CENT SIGN U+FFE0 FULLWIDTH CENT SIGN
618 * 8192 U+00A3 POUND SIGN U+FFE1 FULLWIDTH POUND SIGN
619 * 81CA U+00AC NOT SIGN U+FFE2 FULLWIDTH NOT SIGN
620 *
621 * EUC-JP and ISO-2022-JP should be compatible with CP932.
622 *
623 * Kernel and MLang have different Unicode mapping table. Make sure
624 * which API is used.
625 */
627 {0x00A5, 0x005C, COMPAT_OUT},
628 {0x203E, 0x007E, COMPAT_OUT},
629 {0x2014, 0x2015, COMPAT_OUT},
630 {0x301C, 0xFF5E, COMPAT_OUT},
631 {0x2016, 0x2225, COMPAT_OUT},
632 {0x2212, 0xFF0D, COMPAT_OUT},
633 {0x00A2, 0xFFE0, COMPAT_OUT},
634 {0x00A3, 0xFFE1, COMPAT_OUT},
635 {0x00AC, 0xFFE2, COMPAT_OUT},
636 {0, 0, 0}
637};
638
640 {0x00A5, 0x005C, COMPAT_OUT},
641 {0x203E, 0x007E, COMPAT_OUT},
642 {0x2014, 0x2015, COMPAT_OUT},
643 {0xFF5E, 0x301C, COMPAT_OUT|COMPAT_IN},
644 {0x2225, 0x2016, COMPAT_OUT|COMPAT_IN},
645 {0xFF0D, 0x2212, COMPAT_OUT|COMPAT_IN},
646 {0xFFE0, 0x00A2, COMPAT_OUT|COMPAT_IN},
647 {0xFFE1, 0x00A3, COMPAT_OUT|COMPAT_IN},
648 {0xFFE2, 0x00AC, COMPAT_OUT|COMPAT_IN},
649 {0, 0, 0}
650};
651
653
654/* cp20932_compat for kernel. cp932_compat for mlang. */
656
658 LPDWORD lpdwMode,
659 DWORD dwSrcEncoding,
660 DWORD dwDstEncoding,
661 LPCSTR lpSrcStr,
662 LPINT lpnSrcSize,
663 LPBYTE lpDstStr,
664 LPINT lpnDstSize
665);
667 LPDWORD lpdwMode,
668 DWORD dwSrcEncoding,
669 LPCSTR lpSrcStr,
670 LPINT lpnMultiCharCount,
671 LPWSTR lpDstStr,
672 LPINT lpnWideCharCount
673);
675 LPDWORD lpdwMode,
676 DWORD dwEncoding,
677 LPCWSTR lpSrcStr,
678 LPINT lpnWideCharCount,
679 LPSTR lpDstStr,
680 LPINT lpnMultiCharCount
681);
683 DWORD dwSrcEncoding,
684 DWORD dwDstEncoding
685);
687 LCID Locale,
688 LPSTR pszRfc1766,
689 int nChar
690);
692 LCID Locale,
693 LPWSTR pszRfc1766,
694 int nChar
695);
697 LCID *pLocale,
698 LPSTR pszRfc1766
699);
701 LCID *pLocale,
702 LPWSTR pszRfc1766
703);
710
711static int
713{
714 HMODULE h;
715 if (ConvertINetString != NULL)
716 return TRUE;
717 h = LoadLibrary(TEXT("mlang.dll"));
718 if (!h)
719 return FALSE;
720 ConvertINetString = (CONVERTINETSTRING)GetProcAddressA(h, "ConvertINetString");
724 LcidToRfc1766A = (LCIDTORFC1766A)GetProcAddressA(h, "LcidToRfc1766A");
725 Rfc1766ToLcidA = (RFC1766TOLCIDA)GetProcAddressA(h, "Rfc1766ToLcidA");
726 return TRUE;
727}
728
730iconv_open(const char *tocode, const char *fromcode)
731{
733
734 cd = (rec_iconv_t *)calloc(1, sizeof(rec_iconv_t));
735 if (cd == NULL)
736 return (iconv_t)(-1);
737
738#if defined(USE_LIBICONV_DLL)
739 errno = 0;
740 if (libiconv_iconv_open(cd, tocode, fromcode))
741 return (iconv_t)cd;
742#endif
743
744 /* reset the errno to prevent reporting wrong error code.
745 * 0 for unsorted error. */
746 errno = 0;
747 if (win_iconv_open(cd, tocode, fromcode))
748 return (iconv_t)cd;
749
750 free(cd);
751
752 return (iconv_t)(-1);
753}
754
755int
757{
758 rec_iconv_t *cd = (rec_iconv_t *)_cd;
759 int r = cd->iconv_close(cd->cd);
760 int e = *(cd->_errno());
761#if defined(USE_LIBICONV_DLL)
762 if (cd->hlibiconv != NULL)
763 FreeLibrary(cd->hlibiconv);
764#endif
765 free(cd);
766 errno = e;
767 return r;
768}
769
770size_t
771iconv(iconv_t _cd, const char **inbuf, size_t *inbytesleft, char **outbuf, size_t *outbytesleft)
772{
773 rec_iconv_t *cd = (rec_iconv_t *)_cd;
774 size_t r = cd->iconv(cd->cd, inbuf, inbytesleft, outbuf, outbytesleft);
775 errno = *(cd->_errno());
776 return r;
777}
778
779static int
780win_iconv_open(rec_iconv_t *cd, const char *tocode, const char *fromcode)
781{
782 if (!make_csconv(fromcode, &cd->from) || !make_csconv(tocode, &cd->to))
783 return FALSE;
784 cd->iconv_close = win_iconv_close;
785 cd->iconv = win_iconv;
786 cd->_errno = _errno;
787 cd->cd = (iconv_t)cd;
788 return TRUE;
789}
790
791static int
793{
794 return 0;
795}
796
797static size_t
798win_iconv(iconv_t _cd, const char **inbuf, size_t *inbytesleft, char **outbuf, size_t *outbytesleft)
799{
800 rec_iconv_t *cd = (rec_iconv_t *)_cd;
801 ushort wbuf[MB_CHAR_MAX]; /* enough room for one character */
802 int insize;
803 int outsize;
804 int wsize;
805 DWORD frommode;
806 DWORD tomode;
807 uint wc;
808 compat_t *cp;
809 int i;
810
811 if (inbuf == NULL || *inbuf == NULL)
812 {
813 if (outbuf != NULL && *outbuf != NULL && cd->to.flush != NULL)
814 {
815 tomode = cd->to.mode;
816 outsize = cd->to.flush(&cd->to, (uchar *)*outbuf, *outbytesleft);
817 if (outsize == -1)
818 {
819 if ((cd->to.flags & FLAG_IGNORE) && errno != E2BIG)
820 {
821 outsize = 0;
822 }
823 else
824 {
825 cd->to.mode = tomode;
826 return (size_t)(-1);
827 }
828 }
829 *outbuf += outsize;
830 *outbytesleft -= outsize;
831 }
832 cd->from.mode = 0;
833 cd->to.mode = 0;
834 return 0;
835 }
836
837 while (*inbytesleft != 0)
838 {
839 frommode = cd->from.mode;
840 tomode = cd->to.mode;
841 wsize = MB_CHAR_MAX;
842
843 insize = cd->from.mbtowc(&cd->from, (const uchar *)*inbuf, *inbytesleft, wbuf, &wsize);
844 if (insize == -1)
845 {
846 if (cd->to.flags & FLAG_IGNORE)
847 {
848 cd->from.mode = frommode;
849 insize = 1;
850 wsize = 0;
851 }
852 else
853 {
854 cd->from.mode = frommode;
855 return (size_t)(-1);
856 }
857 }
858
859 if (wsize == 0)
860 {
861 *inbuf += insize;
862 *inbytesleft -= insize;
863 continue;
864 }
865
866 if (cd->from.compat != NULL)
867 {
868 wc = utf16_to_ucs4(wbuf);
869 cp = cd->from.compat;
870 for (i = 0; cp[i].in != 0; ++i)
871 {
872 if ((cp[i].flag & COMPAT_IN) && cp[i].out == wc)
873 {
874 ucs4_to_utf16(cp[i].in, wbuf, &wsize);
875 break;
876 }
877 }
878 }
879
880 if (cd->to.compat != NULL)
881 {
882 wc = utf16_to_ucs4(wbuf);
883 cp = cd->to.compat;
884 for (i = 0; cp[i].in != 0; ++i)
885 {
886 if ((cp[i].flag & COMPAT_OUT) && cp[i].in == wc)
887 {
888 ucs4_to_utf16(cp[i].out, wbuf, &wsize);
889 break;
890 }
891 }
892 }
893
894 outsize = cd->to.wctomb(&cd->to, wbuf, wsize, (uchar *)*outbuf, *outbytesleft);
895 if (outsize == -1)
896 {
897 if ((cd->to.flags & FLAG_IGNORE) && errno != E2BIG)
898 {
899 cd->to.mode = tomode;
900 outsize = 0;
901 }
902 else
903 {
904 cd->from.mode = frommode;
905 cd->to.mode = tomode;
906 return (size_t)(-1);
907 }
908 }
909
910 *inbuf += insize;
911 *outbuf += outsize;
912 *inbytesleft -= insize;
913 *outbytesleft -= outsize;
914 }
915
916 return 0;
917}
918
919static int
920make_csconv(const char *_name, csconv_t *cv)
921{
922 CPINFO cpinfo;
923 int use_compat = TRUE;
924 int flag = 0;
925 char *name;
926 char *p;
927
928 name = xstrndup(_name, strlen(_name));
929 if (name == NULL)
930 return FALSE;
931
932 /* check for option "enc_name//opt1//opt2" */
933 while ((p = strrstr(name, "//")) != NULL)
934 {
935 if (_stricmp(p + 2, "nocompat") == 0)
936 use_compat = FALSE;
937 else if (_stricmp(p + 2, "translit") == 0)
939 else if (_stricmp(p + 2, "ignore") == 0)
940 flag |= FLAG_IGNORE;
941 *p = 0;
942 }
943
944 cv->mode = 0;
945 cv->flags = flag;
946 cv->mblen = NULL;
947 cv->flush = NULL;
948 cv->compat = NULL;
950 if (cv->codepage == 1200 || cv->codepage == 1201)
951 {
952 cv->mbtowc = utf16_mbtowc;
953 cv->wctomb = utf16_wctomb;
954 if (_stricmp(name, "UTF-16") == 0 || _stricmp(name, "UTF16") == 0 ||
955 _stricmp(name, "UCS-2") == 0 || _stricmp(name, "UCS2") == 0)
956 cv->flags |= FLAG_USE_BOM;
957 }
958 else if (cv->codepage == 12000 || cv->codepage == 12001)
959 {
960 cv->mbtowc = utf32_mbtowc;
961 cv->wctomb = utf32_wctomb;
962 if (_stricmp(name, "UTF-32") == 0 || _stricmp(name, "UTF32") == 0 ||
963 _stricmp(name, "UCS-4") == 0 || _stricmp(name, "UCS4") == 0)
964 cv->flags |= FLAG_USE_BOM;
965 }
966 else if (cv->codepage == 65001)
967 {
968 cv->mbtowc = kernel_mbtowc;
969 cv->wctomb = kernel_wctomb;
970 cv->mblen = utf8_mblen;
971 }
972 else if ((cv->codepage == 50220 || cv->codepage == 50221 || cv->codepage == 50222) && load_mlang())
973 {
977 }
978 else if (cv->codepage == 51932 && load_mlang())
979 {
980 cv->mbtowc = mlang_mbtowc;
981 cv->wctomb = mlang_wctomb;
982 cv->mblen = eucjp_mblen;
983 }
984 else if (IsValidCodePage(cv->codepage)
985 && GetCPInfo(cv->codepage, &cpinfo) != 0)
986 {
987 cv->mbtowc = kernel_mbtowc;
988 cv->wctomb = kernel_wctomb;
989 if (cpinfo.MaxCharSize == 1)
990 cv->mblen = sbcs_mblen;
991 else if (cpinfo.MaxCharSize == 2)
992 cv->mblen = dbcs_mblen;
993 else
994 cv->mblen = mbcs_mblen;
995 }
996 else
997 {
998 /* not supported */
999 free(name);
1000 errno = EINVAL;
1001 return FALSE;
1002 }
1003
1004 if (use_compat)
1005 {
1006 switch (cv->codepage)
1007 {
1008 case 932: cv->compat = cp932_compat; break;
1009 case 20932: cv->compat = cp20932_compat; break;
1010 case 51932: cv->compat = cp51932_compat; break;
1011 case 50220: case 50221: case 50222: cv->compat = cp5022x_compat; break;
1012 }
1013 }
1014
1015 free(name);
1016
1017 return TRUE;
1018}
1019
1020static int
1022{
1023 int i;
1024
1025 if (*name == '\0' ||
1026 strcmp(name, "char") == 0)
1027 return GetACP();
1028 else if (strcmp(name, "wchar_t") == 0)
1029 return 1200;
1030 else if (_strnicmp(name, "cp", 2) == 0)
1031 return atoi(name + 2); /* CP123 */
1032 else if ('0' <= name[0] && name[0] <= '9')
1033 return atoi(name); /* 123 */
1034 else if (_strnicmp(name, "xx", 2) == 0)
1035 return atoi(name + 2); /* XX123 for debug */
1036
1037 for (i = 0; codepage_alias[i].name != NULL; ++i)
1038 if (_stricmp(name, codepage_alias[i].name) == 0)
1039 return codepage_alias[i].codepage;
1040 return -1;
1041}
1042
1043/*
1044 * http://www.faqs.org/rfcs/rfc2781.html
1045 */
1046static uint
1048{
1049 uint wc = wbuf[0];
1050 if (0xD800 <= wbuf[0] && wbuf[0] <= 0xDBFF)
1051 wc = ((wbuf[0] & 0x3FF) << 10) + (wbuf[1] & 0x3FF) + 0x10000;
1052 return wc;
1053}
1054
1055static void
1056ucs4_to_utf16(uint wc, ushort *wbuf, int *wbufsize)
1057{
1058 if (wc < 0x10000)
1059 {
1060 wbuf[0] = wc;
1061 *wbufsize = 1;
1062 }
1063 else
1064 {
1065 wc -= 0x10000;
1066 wbuf[0] = 0xD800 | ((wc >> 10) & 0x3FF);
1067 wbuf[1] = 0xDC00 | (wc & 0x3FF);
1068 *wbufsize = 2;
1069 }
1070}
1071
1072/*
1073 * Check if codepage is one of those for which the dwFlags parameter
1074 * to MultiByteToWideChar() must be zero. Return zero or
1075 * MB_ERR_INVALID_CHARS. The docs in Platform SDK for for Windows
1076 * Server 2003 R2 claims that also codepage 65001 is one of these, but
1077 * that doesn't seem to be the case. The MSDN docs for MSVS2008 leave
1078 * out 65001 (UTF-8), and that indeed seems to be the case on XP, it
1079 * works fine to pass MB_ERR_INVALID_CHARS in dwFlags when converting
1080 * from UTF-8.
1081 */
1082static int
1084{
1085 return (codepage == 50220 || codepage == 50221 ||
1086 codepage == 50222 || codepage == 50225 ||
1087 codepage == 50227 || codepage == 50229 ||
1088 codepage == 52936 || codepage == 54936 ||
1089 (codepage >= 57002 && codepage <= 57011) ||
1090 codepage == 65000 || codepage == 42) ? 0 : MB_ERR_INVALID_CHARS;
1091}
1092
1093/*
1094 * Check if codepage is one those for which the lpUsedDefaultChar
1095 * parameter to WideCharToMultiByte() must be NULL. The docs in
1096 * Platform SDK for Windows Server 2003 R2 claims that this is the
1097 * list below, while the MSDN docs for MSVS2008 claim that it is only
1098 * for 65000 (UTF-7) and 65001 (UTF-8). This time the earlier Platform
1099 * SDK seems to be correct, at least for XP.
1100 */
1101static int
1103{
1104 return (codepage == 65000 || codepage == 65001 ||
1105 codepage == 50220 || codepage == 50221 ||
1106 codepage == 50222 || codepage == 50225 ||
1107 codepage == 50227 || codepage == 50229 ||
1108 codepage == 52936 || codepage == 54936 ||
1109 (codepage >= 57002 && codepage <= 57011) ||
1110 codepage == 42);
1111}
1112
1113static char *
1114strrstr(const char *str, const char *token)
1115{
1116 int len = strlen(token);
1117 const char *p = str + strlen(str);
1118
1119 while (str <= --p)
1120 if (p[0] == token[0] && strncmp(p, token, len) == 0)
1121 return (char *)p;
1122 return NULL;
1123}
1124
1125static char *
1126xstrndup(const char *s, size_t n)
1127{
1128 char *p;
1129
1130 p = (char *)malloc(n + 1);
1131 if (p == NULL)
1132 return NULL;
1133 memcpy(p, s, n);
1134 p[n] = '\0';
1135 return p;
1136}
1137
1138static int
1140{
1141 errno = err;
1142 return -1;
1143}
1144
1145#if defined(USE_LIBICONV_DLL)
1146static int
1147libiconv_iconv_open(rec_iconv_t *cd, const char *tocode, const char *fromcode)
1148{
1149 HMODULE hlibiconv = NULL;
1150 char *dllname;
1151 const char *p;
1152 const char *e;
1153 f_iconv_open _iconv_open;
1154
1155 /*
1156 * always try to load dll, so that we can switch dll in runtime.
1157 */
1158
1159 /* XXX: getenv() can't get variable set by SetEnvironmentVariable() */
1160 p = getenv("WINICONV_LIBICONV_DLL");
1161 if (p == NULL)
1163 /* parse comma separated value */
1164 for ( ; *p != 0; p = (*e == ',') ? e + 1 : e)
1165 {
1166 e = strchr(p, ',');
1167 if (p == e)
1168 continue;
1169 else if (e == NULL)
1170 e = p + strlen(p);
1171 dllname = xstrndup(p, e - p);
1172 if (dllname == NULL)
1173 return FALSE;
1174 hlibiconv = LoadLibraryA(dllname);
1175 free(dllname);
1176 if (hlibiconv != NULL)
1177 {
1178 if (hlibiconv == hwiniconv)
1179 {
1180 FreeLibrary(hlibiconv);
1181 hlibiconv = NULL;
1182 continue;
1183 }
1184 break;
1185 }
1186 }
1187
1188 if (hlibiconv == NULL)
1189 goto failed;
1190
1191 _iconv_open = (f_iconv_open)GetProcAddressA(hlibiconv, "libiconv_open");
1192 if (_iconv_open == NULL)
1193 _iconv_open = (f_iconv_open)GetProcAddressA(hlibiconv, "iconv_open");
1194 cd->iconv_close = (f_iconv_close)GetProcAddressA(hlibiconv, "libiconv_close");
1195 if (cd->iconv_close == NULL)
1196 cd->iconv_close = (f_iconv_close)GetProcAddressA(hlibiconv, "iconv_close");
1197 cd->iconv = (f_iconv)GetProcAddressA(hlibiconv, "libiconv");
1198 if (cd->iconv == NULL)
1199 cd->iconv = (f_iconv)GetProcAddressA(hlibiconv, "iconv");
1200 cd->_errno = (f_errno)find_imported_function(hlibiconv, "_errno");
1201 if (_iconv_open == NULL || cd->iconv_close == NULL
1202 || cd->iconv == NULL || cd->_errno == NULL)
1203 goto failed;
1204
1205 cd->cd = _iconv_open(tocode, fromcode);
1206 if (cd->cd == (iconv_t)(-1))
1207 goto failed;
1208
1209 cd->hlibiconv = hlibiconv;
1210 return TRUE;
1211
1212failed:
1213 if (hlibiconv != NULL)
1214 FreeLibrary(hlibiconv);
1215 return FALSE;
1216}
1217
1218/*
1219 * Reference:
1220 * http://forums.belution.com/ja/vc/000/234/78s.shtml
1221 * http://nienie.com/~masapico/api_ImageDirectoryEntryToData.html
1222 *
1223 * The formal way is
1224 * imagehlp.h or dbghelp.h
1225 * imagehlp.lib or dbghelp.lib
1226 * ImageDirectoryEntryToData()
1227 */
1228#define TO_DOS_HEADER(base) ((PIMAGE_DOS_HEADER)(base))
1229#define TO_NT_HEADERS(base) ((PIMAGE_NT_HEADERS)((LPBYTE)(base) + TO_DOS_HEADER(base)->e_lfanew))
1230static PVOID
1231MyImageDirectoryEntryToData(LPVOID Base, BOOLEAN MappedAsImage, USHORT DirectoryEntry, PULONG Size)
1232{
1233 /* TODO: MappedAsImage? */
1235 p = TO_NT_HEADERS(Base)->OptionalHeader.DataDirectory + DirectoryEntry;
1236 if (p->VirtualAddress == 0) {
1237 *Size = 0;
1238 return NULL;
1239 }
1240 *Size = p->Size;
1241 return (PVOID)((LPBYTE)Base + p->VirtualAddress);
1242}
1243
1244static FARPROC
1245find_imported_function(HMODULE hModule, const char *funcname)
1246{
1248 ULONG Size;
1250 PIMAGE_THUNK_DATA Address; /* Import Address Table */
1251 PIMAGE_THUNK_DATA Name; /* Import Name Table */
1252 PIMAGE_IMPORT_BY_NAME ImpName;
1253
1255 Imp = (PIMAGE_IMPORT_DESCRIPTOR)MyImageDirectoryEntryToData(
1256 (LPVOID)Base,
1257 TRUE,
1259 &Size);
1260 if (Imp == NULL)
1261 return NULL;
1262 for ( ; Imp->OriginalFirstThunk != 0; ++Imp)
1263 {
1266 for ( ; Name->u1.Ordinal != 0; ++Name, ++Address)
1267 {
1268 if (!IMAGE_SNAP_BY_ORDINAL(Name->u1.Ordinal))
1269 {
1270 ImpName = (PIMAGE_IMPORT_BY_NAME)
1271 (Base + (DWORD_PTR)Name->u1.AddressOfData);
1272 if (strcmp((char *)ImpName->Name, funcname) == 0)
1273 return (FARPROC)Address->u1.Function;
1274 }
1275 }
1276 }
1277 return NULL;
1278}
1279#endif
1280
1281static int
1283{
1284 return 1;
1285}
1286
1287static int
1289{
1290 int len = IsDBCSLeadByteEx(cv->codepage, buf[0]) ? 2 : 1;
1291 if (bufsize < len)
1292 return seterror(EINVAL);
1293 return len;
1294}
1295
1296static int
1298{
1299 int len = 0;
1300
1301 if (cv->codepage == 54936) {
1302 if (buf[0] <= 0x7F) len = 1;
1303 else if (buf[0] >= 0x81 && buf[0] <= 0xFE &&
1304 bufsize >= 2 &&
1305 ((buf[1] >= 0x40 && buf[1] <= 0x7E) ||
1306 (buf[1] >= 0x80 && buf[1] <= 0xFE))) len = 2;
1307 else if (buf[0] >= 0x81 && buf[0] <= 0xFE &&
1308 bufsize >= 4 &&
1309 buf[1] >= 0x30 && buf[1] <= 0x39) len = 4;
1310 else
1311 return seterror(EINVAL);
1312 return len;
1313 }
1314 else
1315 return seterror(EINVAL);
1316}
1317
1318static int
1320{
1321 int len = 0;
1322
1323 if (buf[0] < 0x80) len = 1;
1324 else if ((buf[0] & 0xE0) == 0xC0) len = 2;
1325 else if ((buf[0] & 0xF0) == 0xE0) len = 3;
1326 else if ((buf[0] & 0xF8) == 0xF0) len = 4;
1327 else if ((buf[0] & 0xFC) == 0xF8) len = 5;
1328 else if ((buf[0] & 0xFE) == 0xFC) len = 6;
1329
1330 if (len == 0)
1331 return seterror(EILSEQ);
1332 else if (bufsize < len)
1333 return seterror(EINVAL);
1334 return len;
1335}
1336
1337static int
1339{
1340 if (buf[0] < 0x80) /* ASCII */
1341 return 1;
1342 else if (buf[0] == 0x8E) /* JIS X 0201 */
1343 {
1344 if (bufsize < 2)
1345 return seterror(EINVAL);
1346 else if (!(0xA1 <= buf[1] && buf[1] <= 0xDF))
1347 return seterror(EILSEQ);
1348 return 2;
1349 }
1350 else if (buf[0] == 0x8F) /* JIS X 0212 */
1351 {
1352 if (bufsize < 3)
1353 return seterror(EINVAL);
1354 else if (!(0xA1 <= buf[1] && buf[1] <= 0xFE)
1355 || !(0xA1 <= buf[2] && buf[2] <= 0xFE))
1356 return seterror(EILSEQ);
1357 return 3;
1358 }
1359 else /* JIS X 0208 */
1360 {
1361 if (bufsize < 2)
1362 return seterror(EINVAL);
1363 else if (!(0xA1 <= buf[0] && buf[0] <= 0xFE)
1364 || !(0xA1 <= buf[1] && buf[1] <= 0xFE))
1365 return seterror(EILSEQ);
1366 return 2;
1367 }
1368}
1369
1370static int
1371kernel_mbtowc(csconv_t *cv, const uchar *buf, int bufsize, ushort *wbuf, int *wbufsize)
1372{
1373 int len;
1374
1375 len = cv->mblen(cv, buf, bufsize);
1376 if (len == -1)
1377 return -1;
1378 *wbufsize = MultiByteToWideChar(cv->codepage, mbtowc_flags (cv->codepage),
1379 (const char *)buf, len, (wchar_t *)wbuf, *wbufsize);
1380 if (*wbufsize == 0)
1381 return seterror(EILSEQ);
1382 return len;
1383}
1384
1385static int
1386kernel_wctomb(csconv_t *cv, ushort *wbuf, int wbufsize, uchar *buf, int bufsize)
1387{
1388 BOOL usedDefaultChar = 0;
1389 BOOL *p = NULL;
1390 int flags = 0;
1391 int len;
1392
1393 if (bufsize == 0)
1394 return seterror(E2BIG);
1396 {
1397 p = &usedDefaultChar;
1398#ifdef WC_NO_BEST_FIT_CHARS
1399 if (!(cv->flags & FLAG_TRANSLIT))
1401#endif
1402 }
1404 (const wchar_t *)wbuf, wbufsize, (char *)buf, bufsize, NULL, p);
1405 if (len == 0)
1406 {
1408 return seterror(E2BIG);
1409 return seterror(EILSEQ);
1410 }
1411 else if (usedDefaultChar && !(cv->flags & FLAG_TRANSLIT))
1412 return seterror(EILSEQ);
1413 else if (cv->mblen(cv, buf, len) != len) /* validate result */
1414 return seterror(EILSEQ);
1415 return len;
1416}
1417
1418/*
1419 * It seems that the mode (cv->mode) is fixnum.
1420 * For example, when converting iso-2022-jp(cp50221) to unicode:
1421 * in ascii sequence: mode=0xC42C0000
1422 * in jisx0208 sequence: mode=0xC42C0001
1423 * "C42C" is same for each convert session.
1424 * It should be: ((codepage-1)<<16)|state
1425 */
1426static int
1427mlang_mbtowc(csconv_t *cv, const uchar *buf, int bufsize, ushort *wbuf, int *wbufsize)
1428{
1429 int len;
1430 int insize;
1431 HRESULT hr;
1432
1433 len = cv->mblen(cv, buf, bufsize);
1434 if (len == -1)
1435 return -1;
1436 insize = len;
1438 (const char *)buf, &insize, (wchar_t *)wbuf, wbufsize);
1439 if (hr != S_OK || insize != len)
1440 return seterror(EILSEQ);
1441 return len;
1442}
1443
1444static int
1445mlang_wctomb(csconv_t *cv, ushort *wbuf, int wbufsize, uchar *buf, int bufsize)
1446{
1447 char tmpbuf[MB_CHAR_MAX]; /* enough room for one character */
1448 int tmpsize = MB_CHAR_MAX;
1449 int insize = wbufsize;
1450 HRESULT hr;
1451
1453 (const wchar_t *)wbuf, &wbufsize, tmpbuf, &tmpsize);
1454 if (hr != S_OK || insize != wbufsize)
1455 return seterror(EILSEQ);
1456 else if (bufsize < tmpsize)
1457 return seterror(E2BIG);
1458 else if (cv->mblen(cv, (uchar *)tmpbuf, tmpsize) != tmpsize)
1459 return seterror(EILSEQ);
1460 memcpy(buf, tmpbuf, tmpsize);
1461 return tmpsize;
1462}
1463
1464static int
1465utf16_mbtowc(csconv_t *cv, const uchar *buf, int bufsize, ushort *wbuf, int *wbufsize)
1466{
1467 int codepage = cv->codepage;
1468
1469 /* swap endian: 1200 <-> 1201 */
1470 if (cv->mode & UNICODE_MODE_SWAPPED)
1471 codepage ^= 1;
1472
1473 if (bufsize < 2)
1474 return seterror(EINVAL);
1475 if (codepage == 1200) /* little endian */
1476 wbuf[0] = (buf[1] << 8) | buf[0];
1477 else if (codepage == 1201) /* big endian */
1478 wbuf[0] = (buf[0] << 8) | buf[1];
1479
1480 if ((cv->flags & FLAG_USE_BOM) && !(cv->mode & UNICODE_MODE_BOM_DONE))
1481 {
1483 if (wbuf[0] == 0xFFFE)
1484 {
1486 *wbufsize = 0;
1487 return 2;
1488 }
1489 else if (wbuf[0] == 0xFEFF)
1490 {
1491 *wbufsize = 0;
1492 return 2;
1493 }
1494 }
1495
1496 if (0xDC00 <= wbuf[0] && wbuf[0] <= 0xDFFF)
1497 return seterror(EILSEQ);
1498 if (0xD800 <= wbuf[0] && wbuf[0] <= 0xDBFF)
1499 {
1500 if (bufsize < 4)
1501 return seterror(EINVAL);
1502 if (codepage == 1200) /* little endian */
1503 wbuf[1] = (buf[3] << 8) | buf[2];
1504 else if (codepage == 1201) /* big endian */
1505 wbuf[1] = (buf[2] << 8) | buf[3];
1506 if (!(0xDC00 <= wbuf[1] && wbuf[1] <= 0xDFFF))
1507 return seterror(EILSEQ);
1508 *wbufsize = 2;
1509 return 4;
1510 }
1511 *wbufsize = 1;
1512 return 2;
1513}
1514
1515static int
1516utf16_wctomb(csconv_t *cv, ushort *wbuf, int wbufsize, uchar *buf, int bufsize)
1517{
1518 if ((cv->flags & FLAG_USE_BOM) && !(cv->mode & UNICODE_MODE_BOM_DONE))
1519 {
1520 int r;
1521
1523 if (bufsize < 2)
1524 return seterror(E2BIG);
1525 if (cv->codepage == 1200) /* little endian */
1526 memcpy(buf, "\xFF\xFE", 2);
1527 else if (cv->codepage == 1201) /* big endian */
1528 memcpy(buf, "\xFE\xFF", 2);
1529
1530 r = utf16_wctomb(cv, wbuf, wbufsize, buf + 2, bufsize - 2);
1531 if (r == -1)
1532 return -1;
1533 return r + 2;
1534 }
1535
1536 if (bufsize < 2)
1537 return seterror(E2BIG);
1538 if (cv->codepage == 1200) /* little endian */
1539 {
1540 buf[0] = (wbuf[0] & 0x00FF);
1541 buf[1] = (wbuf[0] & 0xFF00) >> 8;
1542 }
1543 else if (cv->codepage == 1201) /* big endian */
1544 {
1545 buf[0] = (wbuf[0] & 0xFF00) >> 8;
1546 buf[1] = (wbuf[0] & 0x00FF);
1547 }
1548 if (0xD800 <= wbuf[0] && wbuf[0] <= 0xDBFF)
1549 {
1550 if (bufsize < 4)
1551 return seterror(E2BIG);
1552 if (cv->codepage == 1200) /* little endian */
1553 {
1554 buf[2] = (wbuf[1] & 0x00FF);
1555 buf[3] = (wbuf[1] & 0xFF00) >> 8;
1556 }
1557 else if (cv->codepage == 1201) /* big endian */
1558 {
1559 buf[2] = (wbuf[1] & 0xFF00) >> 8;
1560 buf[3] = (wbuf[1] & 0x00FF);
1561 }
1562 return 4;
1563 }
1564 return 2;
1565}
1566
1567static int
1568utf32_mbtowc(csconv_t *cv, const uchar *buf, int bufsize, ushort *wbuf, int *wbufsize)
1569{
1570 int codepage = cv->codepage;
1571 uint wc;
1572
1573 /* swap endian: 12000 <-> 12001 */
1574 if (cv->mode & UNICODE_MODE_SWAPPED)
1575 codepage ^= 1;
1576
1577 if (bufsize < 4)
1578 return seterror(EINVAL);
1579 if (codepage == 12000) /* little endian */
1580 wc = (buf[3] << 24) | (buf[2] << 16) | (buf[1] << 8) | buf[0];
1581 else if (codepage == 12001) /* big endian */
1582 wc = (buf[0] << 24) | (buf[1] << 16) | (buf[2] << 8) | buf[3];
1583
1584 if ((cv->flags & FLAG_USE_BOM) && !(cv->mode & UNICODE_MODE_BOM_DONE))
1585 {
1587 if (wc == 0xFFFE0000)
1588 {
1590 *wbufsize = 0;
1591 return 4;
1592 }
1593 else if (wc == 0x0000FEFF)
1594 {
1595 *wbufsize = 0;
1596 return 4;
1597 }
1598 }
1599
1600 if ((0xD800 <= wc && wc <= 0xDFFF) || 0x10FFFF < wc)
1601 return seterror(EILSEQ);
1602 ucs4_to_utf16(wc, wbuf, wbufsize);
1603 return 4;
1604}
1605
1606static int
1607utf32_wctomb(csconv_t *cv, ushort *wbuf, int wbufsize, uchar *buf, int bufsize)
1608{
1609 uint wc;
1610
1611 if ((cv->flags & FLAG_USE_BOM) && !(cv->mode & UNICODE_MODE_BOM_DONE))
1612 {
1613 int r;
1614
1616 if (bufsize < 4)
1617 return seterror(E2BIG);
1618 if (cv->codepage == 12000) /* little endian */
1619 memcpy(buf, "\xFF\xFE\x00\x00", 4);
1620 else if (cv->codepage == 12001) /* big endian */
1621 memcpy(buf, "\x00\x00\xFE\xFF", 4);
1622
1623 r = utf32_wctomb(cv, wbuf, wbufsize, buf + 4, bufsize - 4);
1624 if (r == -1)
1625 return -1;
1626 return r + 4;
1627 }
1628
1629 if (bufsize < 4)
1630 return seterror(E2BIG);
1631 wc = utf16_to_ucs4(wbuf);
1632 if (cv->codepage == 12000) /* little endian */
1633 {
1634 buf[0] = wc & 0x000000FF;
1635 buf[1] = (wc & 0x0000FF00) >> 8;
1636 buf[2] = (wc & 0x00FF0000) >> 16;
1637 buf[3] = (wc & 0xFF000000) >> 24;
1638 }
1639 else if (cv->codepage == 12001) /* big endian */
1640 {
1641 buf[0] = (wc & 0xFF000000) >> 24;
1642 buf[1] = (wc & 0x00FF0000) >> 16;
1643 buf[2] = (wc & 0x0000FF00) >> 8;
1644 buf[3] = wc & 0x000000FF;
1645 }
1646 return 4;
1647}
1648
1649/*
1650 * 50220: ISO 2022 Japanese with no halfwidth Katakana; Japanese (JIS)
1651 * 50221: ISO 2022 Japanese with halfwidth Katakana; Japanese (JIS-Allow
1652 * 1 byte Kana)
1653 * 50222: ISO 2022 Japanese JIS X 0201-1989; Japanese (JIS-Allow 1 byte
1654 * Kana - SO/SI)
1655 *
1656 * MultiByteToWideChar() and WideCharToMultiByte() behave differently
1657 * depending on Windows version. On XP, WideCharToMultiByte() doesn't
1658 * terminate result sequence with ascii escape. But Vista does.
1659 * Use MLang instead.
1660 */
1661
1662#define ISO2022_MODE(cs, shift) (((cs) << 8) | (shift))
1663#define ISO2022_MODE_CS(mode) (((mode) >> 8) & 0xFF)
1664#define ISO2022_MODE_SHIFT(mode) ((mode) & 0xFF)
1665
1666#define ISO2022_SI 0
1667#define ISO2022_SO 1
1668
1669/* shift in */
1670static const char iso2022_SI_seq[] = "\x0F";
1671/* shift out */
1672static const char iso2022_SO_seq[] = "\x0E";
1673
1676 const char *esc;
1678 int len;
1679 int cs;
1680};
1681
1682#define ISO2022JP_CS_ASCII 0
1683#define ISO2022JP_CS_JISX0201_ROMAN 1
1684#define ISO2022JP_CS_JISX0201_KANA 2
1685#define ISO2022JP_CS_JISX0208_1978 3
1686#define ISO2022JP_CS_JISX0208_1983 4
1687#define ISO2022JP_CS_JISX0212 5
1688
1690 {"\x1B\x28\x42", 3, 1, ISO2022JP_CS_ASCII},
1691 {"\x1B\x28\x4A", 3, 1, ISO2022JP_CS_JISX0201_ROMAN},
1692 {"\x1B\x28\x49", 3, 1, ISO2022JP_CS_JISX0201_KANA},
1693 {"\x1B\x24\x40", 3, 2, ISO2022JP_CS_JISX0208_1983}, /* unify 1978 with 1983 */
1694 {"\x1B\x24\x42", 3, 2, ISO2022JP_CS_JISX0208_1983},
1695 {"\x1B\x24\x28\x44", 4, 2, ISO2022JP_CS_JISX0212},
1696 {NULL, 0, 0, 0}
1697};
1698
1699static int
1700iso2022jp_mbtowc(csconv_t *cv, const uchar *buf, int bufsize, ushort *wbuf, int *wbufsize)
1701{
1703 char tmp[MB_CHAR_MAX];
1704 int insize;
1705 HRESULT hr;
1706 DWORD dummy = 0;
1707 int len;
1708 int esc_len;
1709 int cs;
1710 int shift;
1711 int i;
1712
1713 if (buf[0] == 0x1B)
1714 {
1715 for (i = 0; iesc[i].esc != NULL; ++i)
1716 {
1717 esc_len = iesc[i].esc_len;
1718 if (bufsize < esc_len)
1719 {
1720 if (strncmp((char *)buf, iesc[i].esc, bufsize) == 0)
1721 return seterror(EINVAL);
1722 }
1723 else
1724 {
1725 if (strncmp((char *)buf, iesc[i].esc, esc_len) == 0)
1726 {
1727 cv->mode = ISO2022_MODE(iesc[i].cs, ISO2022_SI);
1728 *wbufsize = 0;
1729 return esc_len;
1730 }
1731 }
1732 }
1733 /* not supported escape sequence */
1734 return seterror(EILSEQ);
1735 }
1736 else if (buf[0] == iso2022_SO_seq[0])
1737 {
1739 *wbufsize = 0;
1740 return 1;
1741 }
1742 else if (buf[0] == iso2022_SI_seq[0])
1743 {
1745 *wbufsize = 0;
1746 return 1;
1747 }
1748
1749 cs = ISO2022_MODE_CS(cv->mode);
1751
1752 /* reset the mode for informal sequence */
1753 if (buf[0] < 0x20)
1754 {
1756 shift = ISO2022_SI;
1757 }
1758
1759 len = iesc[cs].len;
1760 if (bufsize < len)
1761 return seterror(EINVAL);
1762 for (i = 0; i < len; ++i)
1763 if (!(buf[i] < 0x80))
1764 return seterror(EILSEQ);
1765 esc_len = iesc[cs].esc_len;
1766 memcpy(tmp, iesc[cs].esc, esc_len);
1767 if (shift == ISO2022_SO)
1768 {
1769 memcpy(tmp + esc_len, iso2022_SO_seq, 1);
1770 esc_len += 1;
1771 }
1772 memcpy(tmp + esc_len, buf, len);
1773
1774 if ((cv->codepage == 50220 || cv->codepage == 50221
1775 || cv->codepage == 50222) && shift == ISO2022_SO)
1776 {
1777 /* XXX: shift-out cannot be used for mbtowc (both kernel and
1778 * mlang) */
1779 esc_len = iesc[ISO2022JP_CS_JISX0201_KANA].esc_len;
1780 memcpy(tmp, iesc[ISO2022JP_CS_JISX0201_KANA].esc, esc_len);
1781 memcpy(tmp + esc_len, buf, len);
1782 }
1783
1784 insize = len + esc_len;
1786 (const char *)tmp, &insize, (wchar_t *)wbuf, wbufsize);
1787 if (hr != S_OK || insize != len + esc_len)
1788 return seterror(EILSEQ);
1789
1790 /* Check for conversion error. Assuming defaultChar is 0x3F. */
1791 /* ascii should be converted from ascii */
1792 if (wbuf[0] == buf[0]
1794 return seterror(EILSEQ);
1795
1796 /* reset the mode for informal sequence */
1797 if (cv->mode != ISO2022_MODE(cs, shift))
1798 cv->mode = ISO2022_MODE(cs, shift);
1799
1800 return len;
1801}
1802
1803static int
1804iso2022jp_wctomb(csconv_t *cv, ushort *wbuf, int wbufsize, uchar *buf, int bufsize)
1805{
1807 char tmp[MB_CHAR_MAX];
1808 int tmpsize = MB_CHAR_MAX;
1809 int insize = wbufsize;
1810 HRESULT hr;
1811 DWORD dummy = 0;
1812 int len;
1813 int esc_len;
1814 int cs;
1815 int shift;
1816 int i;
1817
1818 /*
1819 * MultiByte = [escape sequence] + character + [escape sequence]
1820 *
1821 * Whether trailing escape sequence is added depends on which API is
1822 * used (kernel or MLang, and its version).
1823 */
1825 (const wchar_t *)wbuf, &wbufsize, tmp, &tmpsize);
1826 if (hr != S_OK || insize != wbufsize)
1827 return seterror(EILSEQ);
1828 else if (bufsize < tmpsize)
1829 return seterror(E2BIG);
1830
1831 if (tmpsize == 1)
1832 {
1834 esc_len = 0;
1835 }
1836 else
1837 {
1838 for (i = 1; iesc[i].esc != NULL; ++i)
1839 {
1840 esc_len = iesc[i].esc_len;
1841 if (strncmp(tmp, iesc[i].esc, esc_len) == 0)
1842 {
1843 cs = iesc[i].cs;
1844 break;
1845 }
1846 }
1847 if (iesc[i].esc == NULL)
1848 /* not supported escape sequence */
1849 return seterror(EILSEQ);
1850 }
1851
1852 shift = ISO2022_SI;
1853 if (tmp[esc_len] == iso2022_SO_seq[0])
1854 {
1855 shift = ISO2022_SO;
1856 esc_len += 1;
1857 }
1858
1859 len = iesc[cs].len;
1860
1861 /* Check for converting error. Assuming defaultChar is 0x3F. */
1862 /* ascii should be converted from ascii */
1863 if (cs == ISO2022JP_CS_ASCII && !(wbuf[0] < 0x80))
1864 return seterror(EILSEQ);
1865 else if (tmpsize < esc_len + len)
1866 return seterror(EILSEQ);
1867
1868 if (cv->mode == ISO2022_MODE(cs, shift))
1869 {
1870 /* remove escape sequence */
1871 if (esc_len != 0)
1872 memmove(tmp, tmp + esc_len, len);
1873 esc_len = 0;
1874 }
1875 else
1876 {
1877 if (cs == ISO2022JP_CS_ASCII)
1878 {
1879 esc_len = iesc[ISO2022JP_CS_ASCII].esc_len;
1880 memmove(tmp + esc_len, tmp, len);
1881 memcpy(tmp, iesc[ISO2022JP_CS_ASCII].esc, esc_len);
1882 }
1884 {
1885 /* shift-in before changing to other mode */
1886 memmove(tmp + 1, tmp, len + esc_len);
1887 memcpy(tmp, iso2022_SI_seq, 1);
1888 esc_len += 1;
1889 }
1890 }
1891
1892 if (bufsize < len + esc_len)
1893 return seterror(E2BIG);
1894 memcpy(buf, tmp, len + esc_len);
1895 cv->mode = ISO2022_MODE(cs, shift);
1896 return len + esc_len;
1897}
1898
1899static int
1901{
1903 int esc_len;
1904
1906 {
1907 esc_len = 0;
1909 esc_len += 1;
1911 esc_len += iesc[ISO2022JP_CS_ASCII].esc_len;
1912 if (bufsize < esc_len)
1913 return seterror(E2BIG);
1914
1915 esc_len = 0;
1917 {
1919 esc_len += 1;
1920 }
1922 {
1923 memcpy(buf + esc_len, iesc[ISO2022JP_CS_ASCII].esc,
1924 iesc[ISO2022JP_CS_ASCII].esc_len);
1925 esc_len += iesc[ISO2022JP_CS_ASCII].esc_len;
1926 }
1927 return esc_len;
1928 }
1929 return 0;
1930}
1931
1932#if defined(MAKE_DLL) && defined(USE_LIBICONV_DLL)
1934DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpReserved)
1935{
1936 switch( fdwReason )
1937 {
1938 case DLL_PROCESS_ATTACH:
1939 hwiniconv = (HMODULE)hinstDLL;
1940 break;
1941 case DLL_THREAD_ATTACH:
1942 case DLL_THREAD_DETACH:
1943 case DLL_PROCESS_DETACH:
1944 break;
1945 }
1946 return TRUE;
1947}
1948#endif
1949
1950#if defined(MAKE_EXE)
1951#include <stdio.h>
1952#include <fcntl.h>
1953#include <io.h>
1954int
1955main(int argc, char **argv)
1956{
1957 char *fromcode = NULL;
1958 char *tocode = NULL;
1959 int i;
1960 char inbuf[BUFSIZ];
1961 char outbuf[BUFSIZ];
1962 const char *pin;
1963 char *pout;
1964 size_t inbytesleft;
1965 size_t outbytesleft;
1966 size_t rest = 0;
1967 iconv_t cd;
1968 size_t r;
1969 FILE *in = stdin;
1970 FILE *out = stdout;
1971 int ignore = 0;
1972 char *p;
1973
1976
1977 for (i = 1; i < argc; ++i)
1978 {
1979 if (strcmp(argv[i], "-l") == 0)
1980 {
1981 for (i = 0; codepage_alias[i].name != NULL; ++i)
1982 printf("%s\n", codepage_alias[i].name);
1983 return 0;
1984 }
1985
1986 if (strcmp(argv[i], "-f") == 0)
1987 fromcode = argv[++i];
1988 else if (strcmp(argv[i], "-t") == 0)
1989 tocode = argv[++i];
1990 else if (strcmp(argv[i], "-c") == 0)
1991 ignore = 1;
1992 else if (strcmp(argv[i], "--output") == 0)
1993 {
1994 out = fopen(argv[++i], "wb");
1995 if(out == NULL)
1996 {
1997 fprintf(stderr, "cannot open %s\n", argv[i]);
1998 return 1;
1999 }
2000 }
2001 else
2002 {
2003 in = fopen(argv[i], "rb");
2004 if (in == NULL)
2005 {
2006 fprintf(stderr, "cannot open %s\n", argv[i]);
2007 return 1;
2008 }
2009 break;
2010 }
2011 }
2012
2013 if (fromcode == NULL || tocode == NULL)
2014 {
2015 printf("usage: %s [-c] -f from-enc -t to-enc [file]\n", argv[0]);
2016 return 0;
2017 }
2018
2019 if (ignore)
2020 {
2021 p = tocode;
2022 tocode = (char *)malloc(strlen(p) + strlen("//IGNORE") + 1);
2023 if (tocode == NULL)
2024 {
2025 perror("fatal error");
2026 return 1;
2027 }
2028 strcpy(tocode, p);
2029 strcat(tocode, "//IGNORE");
2030 }
2031
2032 cd = iconv_open(tocode, fromcode);
2033 if (cd == (iconv_t)(-1))
2034 {
2035 perror("iconv_open error");
2036 return 1;
2037 }
2038
2039 while ((inbytesleft = fread(inbuf + rest, 1, sizeof(inbuf) - rest, in)) != 0
2040 || rest != 0)
2041 {
2042 inbytesleft += rest;
2043 pin = inbuf;
2044 pout = outbuf;
2045 outbytesleft = sizeof(outbuf);
2046 r = iconv(cd, &pin, &inbytesleft, &pout, &outbytesleft);
2047 fwrite(outbuf, 1, sizeof(outbuf) - outbytesleft, out);
2048 if (r == (size_t)(-1) && errno != E2BIG && (errno != EINVAL || feof(in)))
2049 {
2050 perror("conversion error");
2051 return 1;
2052 }
2053 memmove(inbuf, pin, inbytesleft);
2054 rest = inbytesleft;
2055 }
2056 pout = outbuf;
2057 outbytesleft = sizeof(outbuf);
2058 r = iconv(cd, NULL, NULL, &pout, &outbytesleft);
2059 fwrite(outbuf, 1, sizeof(outbuf) - outbytesleft, out);
2060 if (r == (size_t)(-1))
2061 {
2062 perror("conversion error");
2063 return 1;
2064 }
2065
2066 iconv_close(cd);
2067
2068 return 0;
2069}
2070#endif
2071
unsigned char BOOLEAN
InitDirComponents & cd
static int argc
Definition: ServiceArgs.c:12
unsigned char uchar
Definition: Unfrag.h:59
char * strcat(char *DstString, const char *SrcString)
Definition: utclib.c:568
#define EINVAL
Definition: acclib.h:90
int strcmp(const char *String1, const char *String2)
Definition: utclib.c:469
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
int strncmp(const char *String1, const char *String2, ACPI_SIZE Count)
Definition: utclib.c:534
char * strcpy(char *DstString, const char *SrcString)
Definition: utclib.c:388
char * strchr(const char *String, int ch)
Definition: utclib.c:501
static int inbuf
Definition: adnsresfilter.c:73
struct NameRec_ * Name
Definition: cdprocs.h:460
#define _stricmp
Definition: cat.c:22
#define _setmode(fd, mode)
Definition: cat.c:21
#define ERROR_INSUFFICIENT_BUFFER
Definition: dderror.h:10
#define free
Definition: debug_ros.c:5
#define malloc
Definition: debug_ros.c:4
#define NULL
Definition: types.h:112
UINT32 uint
Definition: types.h:83
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define _O_BINARY
Definition: cabinet.h:51
HMODULE hModule
Definition: animate.c:44
#define DLL_THREAD_DETACH
Definition: compat.h:133
#define DLL_PROCESS_ATTACH
Definition: compat.h:131
#define DLL_PROCESS_DETACH
Definition: compat.h:130
int(* FARPROC)()
Definition: compat.h:36
#define FreeLibrary(x)
Definition: compat.h:748
#define _strnicmp(_String1, _String2, _MaxCount)
Definition: compat.h:23
#define WideCharToMultiByte
Definition: compat.h:111
#define DLL_THREAD_ATTACH
Definition: compat.h:132
#define MultiByteToWideChar
Definition: compat.h:110
HINSTANCE WINAPI DECLSPEC_HOTPATCH LoadLibraryA(LPCSTR lpLibFileName)
Definition: loader.c:111
UINT WINAPI GetACP(void)
Definition: locale.c:2021
BOOL WINAPI IsValidCodePage(UINT codepage)
Definition: locale.c:2079
BOOL WINAPI GetCPInfo(UINT codepage, LPCPINFO cpinfo)
Definition: locale.c:2144
BOOL WINAPI IsDBCSLeadByteEx(UINT codepage, BYTE testchar)
Definition: locale.c:2104
unsigned int(__cdecl typeof(jpeg_read_scanlines))(struct jpeg_decompress_struct *
Definition: typeof.h:31
#define E2BIG
Definition: errno.h:13
int main()
Definition: test.c:6
__kernel_size_t size_t
Definition: linux.h:237
unsigned short ushort
Definition: linux.h:273
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
#define printf
Definition: freeldr.h:97
GLdouble s
Definition: gl.h:2039
GLdouble GLdouble GLdouble r
Definition: gl.h:2055
GLdouble n
Definition: glext.h:7729
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
GLuint in
Definition: glext.h:9616
GLbitfield flags
Definition: glext.h:7161
GLfloat GLfloat p
Definition: glext.h:8902
GLenum GLuint GLsizei bufsize
Definition: glext.h:7473
GLenum GLsizei len
Definition: glext.h:6722
GLfloat GLfloat GLfloat GLfloat h
Definition: glext.h:7723
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean flag
Definition: glfuncs.h:52
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat token
Definition: glfuncs.h:210
#define MB_ERR_INVALID_CHARS
Definition: unicode.h:41
#define WC_NO_BEST_FIT_CHARS
Definition: unicode.h:46
#define cs
Definition: i386-dis.c:442
#define stdout
Definition: stdio.h:99
_CRTIMP void __cdecl perror(_In_opt_z_ const char *_ErrMsg)
_Check_return_ _CRTIMP int __cdecl _fileno(_In_ FILE *_File)
#define stderr
Definition: stdio.h:100
_Check_return_ _CRTIMP int __cdecl feof(_In_ FILE *_File)
_Check_return_opt_ _CRTIMP int __cdecl fprintf(_Inout_ FILE *_File, _In_z_ _Printf_format_string_ const char *_Format,...)
_Check_return_opt_ _CRTIMP size_t __cdecl fread(_Out_writes_bytes_(_ElementSize *_Count) void *_DstBuf, _In_ size_t _ElementSize, _In_ size_t _Count, _Inout_ FILE *_File)
_Check_return_ _CRTIMP FILE *__cdecl fopen(_In_z_ const char *_Filename, _In_z_ const char *_Mode)
#define stdin
Definition: stdio.h:98
_Check_return_opt_ _CRTIMP size_t __cdecl fwrite(_In_reads_bytes_(_Size *_Count) const void *_Str, _In_ size_t _Size, _In_ size_t _Count, _Inout_ FILE *_File)
_Check_return_ int __cdecl atoi(_In_z_ const char *_Str)
_Check_return_ char *__cdecl getenv(_In_z_ const char *_VarName)
#define S_OK
Definition: intsafe.h:52
const unsigned char size_t insize
Definition: jpeglib.h:984
unsigned char size_t * outsize
Definition: jpeglib.h:981
#define TEXT(s)
Definition: k32.h:26
BOOL WINAPI DllMain(IN HINSTANCE hinstDLL, IN DWORD dwReason, IN LPVOID lpvReserved)
Definition: kbsdll.c:95
#define e
Definition: ke_i.h:82
POINT cp
Definition: magnifier.c:59
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
#define memmove(s1, s2, n)
Definition: mkisofs.h:881
#define shift
Definition: input.c:1755
#define argv
Definition: mplay32.c:18
_In_ BOOLEAN MappedAsImage
Definition: rtlfuncs.h:3950
_In_opt_ ULONG Base
Definition: rtlfuncs.h:2451
#define BUFSIZ
Definition: nsplookup.c:25
struct _IMAGE_IMPORT_DESCRIPTOR * PIMAGE_IMPORT_DESCRIPTOR
#define IMAGE_SNAP_BY_ORDINAL(Ordinal)
Definition: ntimage.h:567
PIMAGE_THUNK_DATA32 PIMAGE_THUNK_DATA
Definition: ntimage.h:566
#define IMAGE_DIRECTORY_ENTRY_IMPORT
Definition: pedump.c:260
struct _IMAGE_IMPORT_BY_NAME * PIMAGE_IMPORT_BY_NAME
unsigned short USHORT
Definition: pedump.c:61
static WCHAR Address[46]
Definition: ping.c:68
#define err(...)
static FILE * out
Definition: regtests2xml.c:44
#define calloc
Definition: rosglue.h:14
const WCHAR * str
_CRTIMP int *__cdecl _errno(void)
Definition: errno.c:17
#define errno
Definition: errno.h:18
#define EILSEQ
Definition: errno.h:109
DWORD LCID
Definition: nls.h:13
#define funcname
Definition: shellext.h:96
HRESULT hr
Definition: shlfolder.c:183
UINT MaxCharSize
Definition: winnls.h:583
uint out
Definition: win_iconv.c:87
uint flag
Definition: win_iconv.c:88
uint in
Definition: win_iconv.c:86
DWORD mode
Definition: win_iconv.c:98
int flags
Definition: win_iconv.c:93
f_mblen mblen
Definition: win_iconv.c:96
f_wctomb wctomb
Definition: win_iconv.c:95
compat_t * compat
Definition: win_iconv.c:99
f_mbtowc mbtowc
Definition: win_iconv.c:94
f_flush flush
Definition: win_iconv.c:97
int codepage
Definition: win_iconv.c:92
const char * esc
Definition: win_iconv.c:1676
Definition: name.c:39
Definition: regsvr.c:104
csconv_t from
Definition: win_iconv.c:107
f_iconv_close iconv_close
Definition: win_iconv.c:104
iconv_t cd
Definition: win_iconv.c:103
f_errno _errno
Definition: win_iconv.c:106
csconv_t to
Definition: win_iconv.c:108
f_iconv iconv
Definition: win_iconv.c:105
Definition: tftpd.h:86
#define DWORD_PTR
Definition: treelist.c:76
uint32_t * PULONG
Definition: typedefs.h:59
uint32_t DWORD_PTR
Definition: typedefs.h:65
unsigned char * LPBYTE
Definition: typedefs.h:53
uint32_t * LPDWORD
Definition: typedefs.h:59
HANDLE HMODULE
Definition: typedefs.h:77
uint32_t ULONG
Definition: typedefs.h:59
_Must_inspect_result_ _In_ WDFDEVICE _In_ PWDF_DEVICE_PROPERTY_DATA _In_ DEVPROPTYPE _In_ ULONG Size
Definition: wdfdevice.h:4533
static int mbcs_mblen(csconv_t *cv, const uchar *buf, int bufsize)
Definition: win_iconv.c:1297
int iconv_close(iconv_t cd)
Definition: win_iconv.c:756
static const char iso2022_SI_seq[]
Definition: win_iconv.c:1670
size_t(* f_iconv)(iconv_t cd, const char **inbuf, size_t *inbytesleft, char **outbuf, size_t *outbytesleft)
Definition: win_iconv.c:74
HRESULT(WINAPI * LCIDTORFC1766A)(LCID Locale, LPSTR pszRfc1766, int nChar)
Definition: win_iconv.c:686
static int kernel_mbtowc(csconv_t *cv, const uchar *buf, int bufsize, ushort *wbuf, int *wbufsize)
Definition: win_iconv.c:1371
#define ISO2022_MODE_SHIFT(mode)
Definition: win_iconv.c:1664
static compat_t cp20932_compat[]
Definition: win_iconv.c:639
int codepage
Definition: win_iconv.c:156
static int kernel_wctomb(csconv_t *cv, ushort *wbuf, int wbufsize, uchar *buf, int bufsize)
Definition: win_iconv.c:1386
iconv_t iconv_open(const char *tocode, const char *fromcode)
Definition: win_iconv.c:730
HRESULT(WINAPI * RFC1766TOLCIDA)(LCID *pLocale, LPSTR pszRfc1766)
Definition: win_iconv.c:696
static int sbcs_mblen(csconv_t *cv, const uchar *buf, int bufsize)
static size_t win_iconv(iconv_t cd, const char **inbuf, size_t *inbytesleft, char **outbuf, size_t *outbytesleft)
Definition: win_iconv.c:798
static const char iso2022_SO_seq[]
Definition: win_iconv.c:1672
static int make_csconv(const char *name, csconv_t *cv)
Definition: win_iconv.c:920
static iso2022_esc_t iso2022jp_esc[]
Definition: win_iconv.c:1689
#define ISO2022_MODE(cs, shift)
Definition: win_iconv.c:1662
#define UNICODE_MODE_BOM_DONE
Definition: win_iconv.c:41
static int win_iconv_close(iconv_t cd)
Definition: win_iconv.c:792
#define FLAG_USE_BOM
Definition: win_iconv.c:44
static int seterror(int err)
Definition: win_iconv.c:1139
#define FLAG_IGNORE
Definition: win_iconv.c:46
static RFC1766TOLCIDA Rfc1766ToLcidA
Definition: win_iconv.c:709
HRESULT(WINAPI * CONVERTINETMULTIBYTETOUNICODE)(LPDWORD lpdwMode, DWORD dwSrcEncoding, LPCSTR lpSrcStr, LPINT lpnMultiCharCount, LPWSTR lpDstStr, LPINT lpnWideCharCount)
Definition: win_iconv.c:666
HRESULT(WINAPI * CONVERTINETSTRING)(LPDWORD lpdwMode, DWORD dwSrcEncoding, DWORD dwDstEncoding, LPCSTR lpSrcStr, LPINT lpnSrcSize, LPBYTE lpDstStr, LPINT lpnDstSize)
Definition: win_iconv.c:657
static int win_iconv_open(rec_iconv_t *cd, const char *tocode, const char *fromcode)
Definition: win_iconv.c:780
static struct @4264 codepage_alias[]
int *(* f_errno)(void)
Definition: win_iconv.c:75
static int dbcs_mblen(csconv_t *cv, const uchar *buf, int bufsize)
Definition: win_iconv.c:1288
static LCIDTORFC1766A LcidToRfc1766A
Definition: win_iconv.c:708
int(* f_mblen)(csconv_t *cv, const uchar *buf, int bufsize)
Definition: win_iconv.c:78
static int iso2022jp_wctomb(csconv_t *cv, ushort *wbuf, int wbufsize, uchar *buf, int bufsize)
Definition: win_iconv.c:1804
static int mbtowc_flags(int codepage)
Definition: win_iconv.c:1083
unsigned char uchar
Definition: win_iconv.c:48
#define GetProcAddressA
Definition: win_iconv.c:26
static int iso2022jp_flush(csconv_t *cv, uchar *buf, int bufsize)
Definition: win_iconv.c:1900
static uint utf16_to_ucs4(const ushort *wbuf)
Definition: win_iconv.c:1047
static int must_use_null_useddefaultchar(int codepage)
Definition: win_iconv.c:1102
static int eucjp_mblen(csconv_t *cv, const uchar *buf, int bufsize)
void * iconv_t
Definition: win_iconv.c:52
static int mlang_mbtowc(csconv_t *cv, const uchar *buf, int bufsize, ushort *wbuf, int *wbufsize)
Definition: win_iconv.c:1427
static int mlang_wctomb(csconv_t *cv, ushort *wbuf, int wbufsize, uchar *buf, int bufsize)
Definition: win_iconv.c:1445
int(* f_iconv_close)(iconv_t cd)
Definition: win_iconv.c:73
#define ISO2022_SO
Definition: win_iconv.c:1667
static int iso2022jp_mbtowc(csconv_t *cv, const uchar *buf, int bufsize, ushort *wbuf, int *wbufsize)
Definition: win_iconv.c:1700
static compat_t cp932_compat[]
Definition: win_iconv.c:626
static char * xstrndup(const char *s, size_t n)
Definition: win_iconv.c:1126
static CONVERTINETMULTIBYTETOUNICODE ConvertINetMultiByteToUnicode
Definition: win_iconv.c:705
static int utf16_wctomb(csconv_t *cv, ushort *wbuf, int wbufsize, uchar *buf, int bufsize)
Definition: win_iconv.c:1516
const char * name
Definition: win_iconv.c:157
static int utf8_mblen(csconv_t *cv, const uchar *buf, int bufsize)
#define MB_CHAR_MAX
Definition: win_iconv.c:39
unsigned int uint
Definition: win_iconv.c:50
int(* f_flush)(csconv_t *cv, uchar *buf, int bufsize)
Definition: win_iconv.c:79
static int utf16_mbtowc(csconv_t *cv, const uchar *buf, int bufsize, ushort *wbuf, int *wbufsize)
Definition: win_iconv.c:1465
HRESULT(WINAPI * RFC1766TOLCIDW)(LCID *pLocale, LPWSTR pszRfc1766)
Definition: win_iconv.c:700
#define COMPAT_OUT
Definition: win_iconv.c:82
HRESULT(WINAPI * CONVERTINETUNICODETOMULTIBYTE)(LPDWORD lpdwMode, DWORD dwEncoding, LPCWSTR lpSrcStr, LPINT lpnWideCharCount, LPSTR lpDstStr, LPINT lpnMultiCharCount)
Definition: win_iconv.c:674
#define COMPAT_IN
Definition: win_iconv.c:81
static int load_mlang(void)
Definition: win_iconv.c:712
static ISCONVERTINETSTRINGAVAILABLE IsConvertINetStringAvailable
Definition: win_iconv.c:707
static int name_to_codepage(const char *name)
Definition: win_iconv.c:1021
iconv_t(* f_iconv_open)(const char *tocode, const char *fromcode)
Definition: win_iconv.c:72
static compat_t * cp5022x_compat
Definition: win_iconv.c:655
#define DEFAULT_LIBICONV_DLL
Definition: win_iconv.c:36
unsigned short ushort
Definition: win_iconv.c:49
int(* f_wctomb)(csconv_t *cv, ushort *wbuf, int wbufsize, uchar *buf, int bufsize)
Definition: win_iconv.c:77
#define UNICODE_MODE_SWAPPED
Definition: win_iconv.c:42
#define ISO2022JP_CS_JISX0201_ROMAN
Definition: win_iconv.c:1683
size_t iconv(iconv_t cd, const char **inbuf, size_t *inbytesleft, char **outbuf, size_t *outbytesleft)
Definition: win_iconv.c:771
#define ISO2022JP_CS_JISX0201_KANA
Definition: win_iconv.c:1684
#define ISO2022_MODE_CS(mode)
Definition: win_iconv.c:1663
static char * strrstr(const char *str, const char *token)
Definition: win_iconv.c:1114
static int utf32_mbtowc(csconv_t *cv, const uchar *buf, int bufsize, ushort *wbuf, int *wbufsize)
Definition: win_iconv.c:1568
static CONVERTINETUNICODETOMULTIBYTE ConvertINetUnicodeToMultiByte
Definition: win_iconv.c:706
#define ISO2022JP_CS_JISX0212
Definition: win_iconv.c:1687
#define ISO2022JP_CS_JISX0208_1983
Definition: win_iconv.c:1686
static compat_t * cp51932_compat
Definition: win_iconv.c:652
#define UNUSED
Definition: win_iconv.c:21
#define ISO2022JP_CS_ASCII
Definition: win_iconv.c:1682
#define ISO2022_SI
Definition: win_iconv.c:1666
HRESULT(WINAPI * LCIDTORFC1766W)(LCID Locale, LPWSTR pszRfc1766, int nChar)
Definition: win_iconv.c:691
int(* f_mbtowc)(csconv_t *cv, const uchar *buf, int bufsize, ushort *wbuf, int *wbufsize)
Definition: win_iconv.c:76
HRESULT(WINAPI * ISCONVERTINETSTRINGAVAILABLE)(DWORD dwSrcEncoding, DWORD dwDstEncoding)
Definition: win_iconv.c:682
static void ucs4_to_utf16(uint wc, ushort *wbuf, int *wbufsize)
Definition: win_iconv.c:1056
#define FLAG_TRANSLIT
Definition: win_iconv.c:45
static CONVERTINETSTRING ConvertINetString
Definition: win_iconv.c:704
static int utf32_wctomb(csconv_t *cv, ushort *wbuf, int wbufsize, uchar *buf, int bufsize)
Definition: win_iconv.c:1607
DWORD WINAPI GetLastError(void)
Definition: except.c:1042
#define LoadLibrary
Definition: winbase.h:3887
int * LPINT
Definition: windef.h:178
#define HRESULT
Definition: msvc.h:7
#define WINAPI
Definition: msvc.h:6
const char * LPCSTR
Definition: xmlstorage.h:183
char * LPSTR
Definition: xmlstorage.h:182
WCHAR * LPWSTR
Definition: xmlstorage.h:184
const WCHAR * LPCWSTR
Definition: xmlstorage.h:185