1/* 2 * MacChineseTrad 3 * Copyright (C) TSUBAKIMOTO Hiroya <zorac@4000do.co.jp> 2004 4 * 5 * This program is free software; you can redistribute it and/or modify 6 * it under the terms of the GNU General Public License as published by 7 * the Free Software Foundation; either version 2 of the License, or 8 * (at your option) any later version. 9 * 10 * This program is distributed in the hope that it will be useful, 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 * GNU General Public License for more details. 14 * 15 * You should have received a copy of the GNU General Public License 16 * along with this program; if not, write to the Free Software 17 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 18 * 19 * Reference 20 * http://www.unicode.org/Public/MAPPINGS/VENDORS/APPLE/ 21 */ 22 23#ifdef HAVE_CONFIG_H 24#include "config.h" 25#endif /* HAVE_CONFIG_H */ 26#include <stdlib.h> 27 28#if HAVE_USABLE_ICONV 29 30#include "generic_cjk.h" 31#include "mac_chinese_trad.h" 32 33static size_t mac_chinese_trad_pull(void *,char **, size_t *, char **, size_t *); 34static size_t mac_chinese_trad_push(void *,char **, size_t *, char **, size_t *); 35 36struct charset_functions charset_mac_chinese_trad = { 37 "MAC_CHINESE_TRAD", 38 2, 39 mac_chinese_trad_pull, 40 mac_chinese_trad_push, 41 CHARSET_ICONV | CHARSET_MULTIBYTE | CHARSET_PRECOMPOSED | CHARSET_CLIENT, 42 "BIG-5", 43 NULL, NULL 44}; 45 46static size_t mac_chinese_trad_char_push(u_int8_t* out, const ucs2_t* in, size_t* size) 47{ 48 ucs2_t wc = in[0]; 49 50 if (wc <= 0x7f) { 51 if (wc == 0x5c && *size >= 2 && in[1] == 0xf87f) { 52 *size = 2; 53 out[0] = 0x80; 54 } else { 55 *size = 1; 56 out[0] = (u_int8_t)wc; 57 } 58 return 1; 59 } else if ((wc & 0xf000) == 0xe000) { 60 *size = 1; 61 return 0; 62 } else if (*size >= 2 && (in[1] & ~15) == 0xf870) { 63 ucs2_t comp = cjk_compose(wc, in[1], mac_chinese_trad_compose, 64 sizeof(mac_chinese_trad_compose) / sizeof(u_int32_t)); 65 if (comp) { 66 wc = comp; 67 *size = 2; 68 } else { 69 *size = 1; 70 } 71 } else { 72 *size = 1; 73 } 74 return cjk_char_push(cjk_lookup(wc, mac_chinese_trad_uni2_index, 75 mac_chinese_trad_uni2_charset), out); 76} 77 78static size_t mac_chinese_trad_push(void *cd, char **inbuf, size_t *inbytesleft, 79 char **outbuf, size_t *outbytesleft) 80{ 81 return cjk_generic_push(mac_chinese_trad_char_push, 82 cd, inbuf, inbytesleft, outbuf, outbytesleft); 83} 84 85static size_t mac_chinese_trad_char_pull(ucs2_t* out, const u_int8_t* in, size_t* size) 86{ 87 u_int16_t c = in[0]; 88 89 if (c <= 0x7f) { 90 *size = 1; 91 *out = c; 92 return 1; 93 } else if (c >= 0xa1 && c <= 0xfc) { 94 if (*size >= 2) { 95 u_int8_t c2 = in[1]; 96 97 if ((c2 >= 0x40 && c2 <= 0x7e) || (c2 >= 0xa1 && c2 <= 0xfe)) { 98 *size = 2; 99 c = (c << 8) + c2; 100 } else { 101 errno = EILSEQ; 102 return (size_t)-1; 103 } 104 } else { 105 errno = EINVAL; 106 return (size_t)-1; 107 } 108 } else { 109 *size = 1; 110 } 111 return cjk_char_pull(cjk_lookup(c, mac_chinese_trad_2uni_index, 112 mac_chinese_trad_2uni_charset), 113 out, mac_chinese_trad_compose); 114} 115 116static size_t mac_chinese_trad_pull(void *cd, char **inbuf, size_t *inbytesleft, 117 char **outbuf, size_t *outbytesleft) 118{ 119 return cjk_generic_pull(mac_chinese_trad_char_pull, 120 cd, inbuf, inbytesleft, outbuf, outbytesleft); 121} 122#endif 123