From 0b44a0315b47dd8eced9f3b7f31580cf14bbfc01 Mon Sep 17 00:00:00 2001 From: Rich Felker Date: Sat, 12 Feb 2011 00:22:29 -0500 Subject: initial check-in, version 0.5.0 --- src/locale/iconv.c | 568 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 568 insertions(+) create mode 100644 src/locale/iconv.c (limited to 'src/locale/iconv.c') diff --git a/src/locale/iconv.c b/src/locale/iconv.c new file mode 100644 index 00000000..4e46c7e4 --- /dev/null +++ b/src/locale/iconv.c @@ -0,0 +1,568 @@ +#include +#include +#include +#include +#include +#include +#include + +#define UTF_32BE 000 +#define UTF_16LE 001 +#define UTF_16BE 002 +#define UTF_32LE 003 +#define UCS2BE 004 +#define UCS2LE 005 +#define WCHAR_T 007 + +#define US_ASCII 021 +#define UTF_8 022 +#define LATIN_9 024 +#define TIS_620 025 +#define JIS_0201 026 + +#define EUC 031 +#define EUC_TW 032 +#define SHIFT_JIS 033 +#define BIG5 034 +#define GBK 035 + +/* FIXME: these are not implemented yet + * EUC: A1-FE A1-FE + * GBK: 81-FE 40-7E,80-FE + * Big5: A1-FE 40-7E,A1-FE + */ + +/* Definitions of charmaps. Each charmap consists of: + * 1. Empty-string-terminated list of null-terminated aliases. + * 2. Special type code or bits per character. + * 3. Number of elided entries (128 for specials). + * 4. Character table (size determined by fields 2 and 3). */ + +static const unsigned char charmaps[] = +"utf8\0\0\022\x80" +"wchart\0\0\007\x80" + +"ucs2\0ucs2be\0\0\004\x80" +"ucs2le\0\0\005\x80" + +"utf16\0utf16be\0\0\002\x80" +"utf16le\0\0\001\x80" + +"ucs4\0ucs4be\0utf32\0utf32be\0\0\000\x80" +"ucs4le\0utf32le\0\0\003\x80" + +"ascii\0iso646\0usascii\0\0\021\x80" +"latin1\0iso88591\0\0\x09\x80" +"latin9\0iso885915\0\0\024\x80" +"tis620\0iso885911\0\0\025\x80" +"jis0201\0\0\026\x80" + +"iso88592\0\0\x0a\x21" +"\x04\x61\x1b\x14\x29\x3d\x69\x75\x0a\x2a" +"\x60\x79\x45\x56\x5e\xad\xf4\xb5\x17\x2c" +"\x05\x6d\x2b\x14\x2d\x3e\x6d\x75\x2c\x2e" +"\x61\x7d\x55\x96\x5e\xdd\xfa\xc5\x17\x55" +"\xc1\x08\x23\x10\x31\x39\x19\x74\x0c\x43" +"\xc9\x60\xb4\x8c\x46\xcd\x38\xe3\x10\x44" +"\x43\x1d\x35\x0d\x35\x50\x59\x73\x0d\x56" +"\x6e\x69\x03\x17\x37\xdd\x88\xf5\x4d\x55" +"\xe1\x88\x33\x10\x39\x3a\x1d\x74\x4e\x43" +"\xe9\x64\xb4\xce\x46\xed\xb8\xf3\x50\x44" +"\x44\x21\x35\x0f\x3d\x51\xd9\x73\x4f\x56" +"\x6f\xe9\x13\x17\x3f\xfd\x8c\x95\x2d" + +"iso88593\0\0\x0a\x21" +"\x26\x61\x3b\x0a\x29\x00\x90\x74\x0a\x2a" +"\x30\x79\xe5\x11\x4d\xad\x00\xb0\x17\x2c" +"\x27\xc9\x32\x0b\x2d\xb5\x94\x74\x0b\x2e" +"\x31\x7d\xf5\x51\x4d\xbd\x00\xc0\x17\x30" +"\xc1\x08\x03\x00\x31\x0a\x21\x74\x0c\x32" +"\xc9\x28\xb3\x0c\x33\xcd\x38\xf3\x0c\x00" +"\xd1\x48\x33\x0d\x35\x20\x59\x73\x0d\x47" +"\xd9\x68\xb3\x0d\x37\x6c\x71\xf5\x0d\x38" +"\xe1\x88\x03\x00\x39\x0b\x25\x74\x0e\x3a" +"\xe9\xa8\xb3\x0e\x3b\xed\xb8\xf3\x0e\x00" +"\xf1\xc8\x33\x0f\x3d\x21\xd9\x73\x4f\x47" +"\xf9\xe8\xb3\x0f\x3f\x6d\x75\x95\x2d" + +"iso88594\0\0\x0a\x21" +"\x04\xe1\x64\x15\x29\x28\xed\x74\x0a\x2a" +"\x60\x49\x24\x92\x59\xad\xf4\xf5\x0a\x2c" +"\x05\x6d\x7b\x15\x2d\x29\xf1\x74\x2c\x2e" +"\x61\x4d\x34\xd2\x59\x4a\xf9\xb5\x14\x40" +"\xc1\x08\x33\x0c\x31\xc5\x18\xe3\x12\x43" +"\xc9\x60\xb4\x8c\x45\xcd\x38\xa3\x12\x44" +"\x45\x31\x65\x13\x35\xd5\x58\x73\x0d\x36" +"\x72\x69\xb3\x0d\x37\x68\xa9\xf5\x4d\x40" +"\xe1\x88\x33\x0e\x39\xe5\x98\xf3\x52\x43" +"\xe9\x64\xb4\xce\x45\xed\xb8\xb3\x52\x44" +"\x46\x35\x75\x13\x3d\xf5\xd8\x73\x0f\x3e" +"\x73\xe9\xb3\x0f\x3f\x69\xad\x95\x2d" + +"iso88595\0\0\x0e\x21" +"\x01\x84\x00\x31\x40\x10\x10\x05\x84\x01" +"\x71\x40\x20\x10\x09\x84\x02\xb1\x40\x30" +"\x10\xad\x80\x03\xf1\x40\x40\x10\x11\x84" +"\x04\x31\x41\x50\x10\x15\x84\x05\x71\x41" +"\x60\x10\x19\x84\x06\xb1\x41\x70\x10\x1d" +"\x84\x07\xf1\x41\x80\x10\x21\x84\x08\x31" +"\x42\x90\x10\x25\x84\x09\x71\x42\xa0\x10" +"\x29\x84\x0a\xb1\x42\xb0\x10\x2d\x84\x0b" +"\xf1\x42\xc0\x10\x31\x84\x0c\x31\x43\xd0" +"\x10\x35\x84\x0d\x71\x43\xe0\x10\x39\x84" +"\x0e\xb1\x43\xf0\x10\x3d\x84\x0f\xf1\x43" +"\x00\x11\x41\x84\x10\x31\x44\x10\x11\x45" +"\x84\x11\x71\x44\x20\x11\x49\x84\x12\xb1" +"\x44\x30\x11\x4d\x84\x13\xf1\x44\x58\x84" +"\x51\x84\x14\x31\x45\x50\x11\x55\x84\x15" +"\x71\x45\x60\x11\x59\x84\x16\xb1\x45\x70" +"\x11\xa7\x80\x17\xf1\x45\x00" + +"iso88596\0\0\x0b\x21" +"\x00\x00\x00\x00\x48\x01\x00\x00\x00\x00" +"\x00\x00\x00\x00\x00\x18\xdc\x0a\x00\x00" +"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +"\x00\x00\x00\x00\x00\xc0\x86\x01\x00\x00" +"\x00\x7c\x18\x00\x21\x16\xf1\x88\x49\x5c" +"\x62\x13\x9f\x18\xc5\x29\x56\xf1\x8a\x59" +"\xdc\x62\x17\xbf\x18\xc6\x31\x96\xf1\x8c" +"\x69\x5c\x63\x1b\xdf\x18\xc7\x39\xd6\x31" +"\x00\x00\x00\x00\x00\x00\x00\xc8\x41\x16" +"\xf2\x90\x89\x5c\x64\x23\x1f\x19\xc9\x49" +"\x56\xf2\x92\x99\xdc\x64\x27\x3f\x19\xca" +"\x51\x96\x32\x00\x00\x00\x00\x00\x00\x00" +"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +"\x00" + +"iso88597\0\0\x0e\x21" +"\x18\x60\x06\x38\x0a\xb0\x82\xaf\xa0\x29" +"\x70\x0a\xa0\x02\xa9\x80\xde\xb0\x0a\xb0" +"\x02\xad\x00\x00\x50\x01\xc2\x02\xb1\x80" +"\x2c\x30\x0b\x10\x0e\x85\x83\xe1\x70\x0b" +"\x20\x0e\x89\x83\xe2\xb0\x0b\x30\x0e\xbd" +"\x80\xe3\xf0\x38\x40\x0e\x91\x83\xe4\x30" +"\x39\x50\x0e\x95\x83\xe5\x70\x39\x60\x0e" +"\x99\x83\xe6\xb0\x39\x70\x0e\x9d\x83\xe7" +"\xf0\x39\x80\x0e\xa1\x03\x00\x30\x3a\x90" +"\x0e\xa5\x83\xe9\x70\x3a\xa0\x0e\xa9\x83" +"\xea\xb0\x3a\xb0\x0e\xad\x83\xeb\xf0\x3a" +"\xc0\x0e\xb1\x83\xec\x30\x3b\xd0\x0e\xb5" +"\x83\xed\x70\x3b\xe0\x0e\xb9\x83\xee\xb0" +"\x3b\xf0\x0e\xbd\x83\xef\xf0\x3b\x00\x0f" +"\xc1\x83\xf0\x30\x3c\x10\x0f\xc5\x83\xf1" +"\x70\x3c\x20\x0f\xc9\x83\xf2\xb0\x3c\x30" +"\x0f\xcd\x83\xf3\x00\x00\x00" + +"iso88598\0\0\x0e\x21" +"\x00\x80\x28\x30\x0a\x90\x02\xa5\x80\x29" +"\x70\x0a\xa0\x02\xa9\xc0\x35\xb0\x0a\xb0" +"\x02\xad\x80\x2b\xf0\x0a\xc0\x02\xb1\x80" +"\x2c\x30\x0b\xd0\x02\xb5\x80\x2d\x70\x0b" +"\xe0\x02\xb9\xc0\x3d\xb0\x0b\xf0\x02\xbd" +"\x80\x2f\x00\x00\x00\x00\x00\x00\x00\x00" +"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +"\x00\x00\x00\x00\x00\x00\x00\x00\x70\x01" +"\x42\x17\xd1\x85\x74\x31\x5d\x50\x17\xd5" +"\x85\x75\x71\x5d\x60\x17\xd9\x85\x76\xb1" +"\x5d\x70\x17\xdd\x85\x77\xf1\x5d\x80\x17" +"\xe1\x85\x78\x31\x5e\x90\x17\xe5\x85\x79" +"\x71\x5e\xa0\x17\xe9\x85\x7a\x01\x00\x00" +"\x00\x0e\xe0\x03\x08\x00\x00" + +"iso88599\0\0\x09\x50" +"\x1e\xa3\x49\x9b\x46\xad\x9a\xb5\x6b\xd8" +"\xb2\x69\xdb\xc6\x0d\xa6\xd7\x6f\xe0\xc2" +"\x89\x1b\x47\xae\x9c\xb9\x73\xe8\xd2\xa9" +"\x5b\xc7\xae\x9d\xbb\x77\x1f\xe3\xc9\x9b" +"\x47\xaf\x9e\xbd\x7b\xf8\xf2\xe9\xdb\xc7" +"\x2f\xe6\xd7\x7f" + +"iso885910\0\0\x0e\x21" +"\x04\x81\x44\x20\x12\xa8\x04\x28\x81\x4d" +"\x70\x0a\xec\x04\x10\x01\x58\x60\x16\xf4" +"\x05\xad\x80\x5a\xa0\x14\xc0\x02\x05\xc1" +"\x44\x30\x12\xac\x04\x29\xc1\x4d\x70\x0b" +"\xf0\x04\x11\x41\x58\x70\x16\xf8\x05\x15" +"\xe0\x5a\xb0\x14\x00\x04\xc1\x80\x30\x30" +"\x0c\x10\x03\xc5\x80\x31\xe0\x12\x30\x04" +"\xc9\x00\x46\xb0\x0c\x58\x04\xcd\x80\x33" +"\xf0\x0c\x40\x03\x45\x01\x53\x30\x0d\x50" +"\x03\xd5\x80\x35\x80\x16\x60\x03\x72\x81" +"\x36\xb0\x0d\x70\x03\xdd\x80\x37\xf0\x0d" +"\x04\x04\xe1\x80\x38\x30\x0e\x90\x03\xe5" +"\x80\x39\xf0\x12\x34\x04\xe9\x40\x46\xb0" +"\x0e\x5c\x04\xed\x80\x3b\xf0\x0e\xc0\x03" +"\x46\x41\x53\x30\x0f\xd0\x03\xf5\x80\x3d" +"\x90\x16\xe0\x03\x73\x81\x3e\xb0\x0f\xf0" +"\x03\xfd\x80\x3f\x80\x13\x00" + +"iso885913\0\0\x0e\x21" +"\x1d\xa0\x28\x30\x0a\x90\x02\x1e\xa0\x29" +"\x70\x0a\x60\x03\xa9\x80\x55\xb0\x0a\xb0" +"\x02\xad\x80\x2b\x60\x0c\xc0\x02\xb1\x80" +"\x2c\x30\x0b\x70\x80\xb5\x80\x2d\x70\x0b" +"\xe0\x03\xb9\xc0\x55\xb0\x0b\xf0\x02\xbd" +"\x80\x2f\x60\x0e\x10\x04\x2e\x01\x40\x60" +"\x10\x10\x03\xc5\x00\x46\x20\x11\x30\x04" +"\xc9\x40\x5e\x60\x11\x88\x04\x36\x81\x4a" +"\xb0\x13\x80\x05\x43\x41\x51\x30\x0d\x30" +"\x05\xd5\x80\x35\x70\x0d\xc8\x05\x41\x81" +"\x56\xa0\x16\x70\x03\x7b\x41\x5f\xf0\x0d" +"\x14\x04\x2f\x41\x40\x70\x10\x90\x03\xe5" +"\x40\x46\x30\x11\x34\x04\xe9\x80\x5e\x70" +"\x11\x8c\x04\x37\xc1\x4a\xc0\x13\x84\x05" +"\x44\x81\x51\x30\x0f\x34\x05\xf5\x80\x3d" +"\x70\x0f\xcc\x05\x42\xc1\x56\xb0\x16\xf0" +"\x03\x7c\x81\x5f\x90\x01\x02" + +"iso885914\0\0\x0d\x21" +"\x02\x7e\xc0\x8f\x02\x85\xb0\x10\x14\xfc" +"\x29\x00\xf4\xa9\x40\xd0\x2f\x78\x79\xdf" +"\x0a\x5c\x01\x5e\xf0\xf0\x1f\x1e\x24\x84" +"\x04\x20\x1f\xe4\x6d\x81\x95\x0f\xf4\x57" +"\x7e\xd0\x83\xf9\x79\x4f\xe8\x0b\x7d\x98" +"\x07\x06\xc1\x40\x18\x0c\x03\x62\x50\x0c" +"\x8c\xc1\x31\x40\x06\xc9\x40\x19\x2c\x03" +"\x66\xd0\x0c\x9c\xc1\x33\xa0\x0b\xd1\x40" +"\x1a\x4c\x03\x6a\x50\x0d\xac\x81\x9a\xc7" +"\x06\xd9\x40\x1b\x6c\x03\x6e\xd0\x0d\xec" +"\xc2\x37\x00\x07\xe1\x40\x1c\x8c\x03\x72" +"\x50\x0e\xcc\xc1\x39\x40\x07\xe9\x40\x1d" +"\xac\x03\x76\xd0\x0e\xdc\xc1\x3b\xa8\x0b" +"\xf1\x40\x1e\xcc\x03\x7a\x50\x0f\xec\xc1" +"\x9a\xc7\x07\xf9\x40\x1f\xec\x03\x7e\xd0" +"\x0f\xee\xc2\x3f\x00" + +"iso885916\0\0\x0e\x21" +"\x04\x41\x41\x10\x14\xb0\x82\x1e\x20\x58" +"\x70\x0a\x84\x05\xa9\x00\x86\xb0\x0a\xe4" +"\x05\xad\x80\x5e\xb0\x17\xc0\x02\xb1\x00" +"\x43\x20\x14\xf4\x05\x1d\xa0\x2d\x70\x0b" +"\xf8\x05\x0d\x41\x86\xb0\x0b\x48\x05\x53" +"\x01\x5e\xc0\x17\x00\x03\xc1\x80\x30\x20" +"\x10\x10\x03\x06\x81\x31\x70\x0c\x20\x03" +"\xc9\x80\x32\xb0\x0c\x30\x03\xcd\x80\x33" +"\xf0\x0c\x40\x04\x43\x81\x34\x30\x0d\x50" +"\x03\x50\x81\x35\xa0\x15\xc0\x05\xd9\x80" +"\x36\xb0\x0d\x70\x03\x18\x81\x86\xf0\x0d" +"\x80\x03\xe1\x80\x38\x30\x10\x90\x03\x07" +"\x81\x39\x70\x0e\xa0\x03\xe9\x80\x3a\xb0" +"\x0e\xb0\x03\xed\x80\x3b\xf0\x0e\x44\x04" +"\x44\x81\x3c\x30\x0f\xd0\x03\x51\x81\x3d" +"\xb0\x15\xc4\x05\xf9\x80\x3e\xb0\x0f\xf0" +"\x03\x19\xc1\x86\xf0\x0f\x00" + +"windows1252\0\0\x0e\x00" +"\xac\x20\x00\xa0\x01\x4a\x06\x1e\xa0\x09" +"\x08\x02\x86\x80\xc6\x02\x0c\x08\x16\xe4" +"\x80\x52\x01\x00\xd0\x17\x00\x00\x00\x00" +"\x06\x98\x01\x72\x80\x1d\xa0\x08\x38\x01" +"\x52\x80\xdc\x82\x48\x18\x16\xe8\x80\x53" +"\x01\x00\xe0\x17\xe0\x05\xa0\x40\x28\x20" +"\x0a\x8c\x02\xa4\x40\x29\x60\x0a\x9c\x02" +"\xa8\x40\x2a\xa0\x0a\xac\x02\xac\x40\x2b" +"\xe0\x0a\xbc\x02\xb0\x40\x2c\x20\x0b\xcc" +"\x02\xb4\x40\x2d\x60\x0b\xdc\x02\xb8\x40" +"\x2e\xa0\x0b\xec\x02\xbc\x40\x2f\xe0\x0b" +"\xfc\x02\xc0\x40\x30\x20\x0c\x0c\x03\xc4" +"\x40\x31\x60\x0c\x1c\x03\xc8\x40\x32\xa0" +"\x0c\x2c\x03\xcc\x40\x33\xe0\x0c\x3c\x03" +"\xd0\x40\x34\x20\x0d\x4c\x03\xd4\x40\x35" +"\x60\x0d\x5c\x03\xd8\x40\x36\xa0\x0d\x6c" +"\x03\xdc\x40\x37\xe0\x0d\x7c\x03\xe0\x40" +"\x38\x20\x0e\x8c\x03\xe4\x40\x39\x60\x0e" +"\x9c\x03\xe8\x40\x3a\xa0\x0e\xac\x03\xec" +"\x40\x3b\xe0\x0e\xbc\x03\xf0\x40\x3c\x20" +"\x0f\xcc\x03\xf4\x40\x3d\x60\x0f\xdc\x03" +"\xf8\x40\x3e\xa0\x0f\xec\x03\xfc\x40\x3f" +"\xe0\x0f\xfc\x03" +; + + + +static int fuzzycmp(const char *a, const char *b) +{ + for (; *a && *b; a++, b++) { + while (*a && (*a|32U)-'a'>26 && *a-'0'>10U) a++; + if ((*a|32U) != *b) return 1; + } + return *a != *b; +} + +static int find_charmap(const char *name) +{ + const unsigned char *s; + for (s=charmaps; *s; ) { + if (!fuzzycmp(name, s)) { + for (; *s; s+=strlen(s)+1); + return s+1-charmaps; + } + s += strlen(s)+1; + if (!*s) s += ((128-s[2])*s[1]+7)/8 + 3; + } + return -1; +} + +iconv_t iconv_open(const char *to, const char *from) +{ + int f, t; + + if ((t = find_charmap(to)) < 0 || (f = find_charmap(from)) < 0) { + errno = EINVAL; + return (iconv_t)-1; + } + + return (void *)(f<<16 | t); +} + +int iconv_close(iconv_t cd) +{ + return 0; +} + +static unsigned get_16(const unsigned char *s, int e) +{ + e &= 1; + return s[e]<<8 | s[1-e]; +} + +static void put_16(unsigned char *s, unsigned c, int e) +{ + e &= 1; + s[e] = c>>8; + s[1-e] = c; +} + +static unsigned get_32(const unsigned char *s, int e) +{ + return s[e]+0U<<24 | s[e^1]<<16 | s[e^2]<<8 | s[e^3]; +} + +static void put_32(unsigned char *s, unsigned c, int e) +{ + s[e^0] = c>>24; + s[e^1] = c>>16; + s[e^2] = c>>8; + s[e^3] = c; +} + + + +#define GET_MAPPING(m, i, n) ( (1<<(n))-1 & ( \ + (m)[(i)*(n)/8] >> ((n)%8*(i)%8) | \ + (m)[(i)*(n)/8+1] << 8-((n)%8*(i)%8) | \ + (m)[(i)*(n)/8+2] << 16-((n)%8*(i)%8) ) ) + +static unsigned get_mapping(const unsigned char *m, unsigned c, unsigned n) +{ + switch (n) { + default: + case 9: return m[c*9/8]>>c%8 | m[c*9/8+1]<<8-c%8 & (1<>2*c%8 | m[c*10/8+1]<<8-2*c%8 & (1< +size_t iconv(iconv_t cd0, char **in, size_t *inb, char **out, size_t *outb) +{ + size_t x=0; + unsigned long cd = (unsigned long)cd0; + unsigned to = cd & 0xffff; + unsigned from = cd >> 16; + const unsigned char *map = charmaps+from+2; + const unsigned char *tomap = charmaps+to+2; + mbstate_t st = {0}; + wchar_t wc; + unsigned c, d; + size_t k, l; + int err; + unsigned elide = map[-1] + 128; + unsigned toelide = tomap[-1] + 128; + unsigned char type = map[-2]; + unsigned char totype = tomap[-2]; + + if (!in || !*in || !*inb) return 0; + + for (; *inb; *in+=l, *inb-=l) { + c = *(unsigned char *)*in; + l = 1; + if (type < 8 || c >= 0x80) switch (type) { + case UTF_8: + l = mbrtowc_utf8(&wc, *in, *inb, &st); + if (!l) l++; + else if (l == (size_t)-1) goto ilseq; + else if (l == (size_t)-2) goto starved; + c = wc; + break; + case LATIN_9: + if ((unsigned)c - 0xa4 <= 0xbe - 0xa4) { + static const unsigned char map[] = { + 0, 0x60, 0, 0x61, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0x7d, 0, 0, 0, 0x7e, 0, 0, 0, + 0x52, 0x53, 0x78 + }; + if (c == 0xa4) c = 0x20ac; + else if (map[c-0xa5]) c = 0x100 | map[c-0xa5]; + } + break; + case TIS_620: + if (c >= 0xa1) c += 0x0e01-0xa1; + break; + case JIS_0201: + if (c >= 0xa1) + if (c <= 0xdf) c += 0xff61-0xa1; + else goto ilseq; + break; + case 9: case 10: case 11: case 13: case 14: + if (c < elide) break; + c = get_mapping(map, c-elide, type); + if (!c) { + case US_ASCII: + goto ilseq; + } + break; + case WCHAR_T: + l = sizeof(wchar_t); + if (*inb < l) goto starved; + c = *(wchar_t *)*in; + if (0) { + case UTF_32BE: + case UTF_32LE: + l = 4; + if (*inb < 4) goto starved; + c = get_32(*in, type); + } + if (c-0xd800u < 0x800u || c >= 0x110000u) goto ilseq; + break; + case UCS2BE: + case UCS2LE: + case UTF_16BE: + case UTF_16LE: + l = 2; + if (*inb < 2) goto starved; + c = get_16(*in, type); + if ((unsigned)(c-0xdc00) < 0x400) goto ilseq; + if ((unsigned)(c-0xd800) < 0x400) { + if (type-UCS2BE < 2U) goto ilseq; + l = 4; + if (*inb < 4) goto starved; + d = get_16(*in + 2, from); + if ((unsigned)(c-0xdc00) >= 0x400) goto ilseq; + c = ((c-0xd800)<<10) | (d-0xdc00); + } + break; + } + + switch (totype) { + case WCHAR_T: + if (*outb < sizeof(wchar_t)) goto toobig; + *(wchar_t *)*out = c; + *out += sizeof(wchar_t); + *outb -= sizeof(wchar_t); + break; + case UTF_8: + if (*outb < 4) { + char tmp[4]; + k = wctomb_utf8(tmp, c); + if (*outb < k) goto toobig; + memcpy(*out, tmp, k); + } else k = wctomb_utf8(*out, c); + *out += k; + *outb -= k; + break; + case TIS_620: + if (c-0xe01u <= 0xff-0xa1) + c -= 0xe01-0xa1; + else if (c >= 0xa1) + goto ascii; + goto revout; + case JIS_0201: + if (c-0xff61u <= 0xdf-0xa1) + c -= 0xff61-0xa1; + else if (c >= 0xa1) + goto ascii; + goto revout; + case LATIN_9: + if (c == 0x20ac) { + c=0xa4; + } else if (c-0x150u<=0x12 && (1<0x100 || + c-0xa5u<=0xbeu-0xa5 + && (1< 0x7f) x++, c='*'; + case 9: case 10: case 11: case 13: case 14: + if (*outb < 1) goto toobig; + if (c < toelide) { + revout: + *(*out)++ = c; + *outb -= 1; + break; + } + for (d=0; d<256-toelide; d++) { + if (c == get_mapping(tomap, d, totype)) { + c = d + toelide; + goto revout; + } + } + x++; + c = '*'; + goto revout; + case UCS2BE: + case UCS2LE: + case UTF_16BE: + case UTF_16LE: + if (c < 0x10000) { + if (*outb < 2) goto toobig; + put_16(*out, c, totype); + *out += 2; + *outb -= 2; + break; + } + if (type-UCS2BE < 2U) goto ilseq; + if (*outb < 4) goto toobig; + put_16(*out, (c>>10)|0xd800, totype); + put_16(*out + 2, (c&0x3ff)|0xdc00, totype); + *out += 4; + *outb -= 4; + break; + case UTF_32BE: + case UTF_32LE: + if (*outb < 4) goto toobig; + put_32(*out, c, totype); + *out += 4; + *outb -= 4; + break; + } + } + return x; +ilseq: + err = EILSEQ; + x = -1; + goto end; +toobig: + err = E2BIG; + goto end; +starved: + err = EINVAL; +end: + errno = err; + return x; +} -- cgit v1.2.1