1/* 2 * MacChineseSimp 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_simp.h" 32 33static size_t mac_chinese_simp_pull(void *,char **, size_t *, char **, size_t *); 34static size_t mac_chinese_simp_push(void *,char **, size_t *, char **, size_t *); 35 36struct charset_functions charset_mac_chinese_simp = { 37 "MAC_CHINESE_SIMP", 38 25, 39 mac_chinese_simp_pull, 40 mac_chinese_simp_push, 41 CHARSET_ICONV | CHARSET_MULTIBYTE | CHARSET_PRECOMPOSED | CHARSET_CLIENT, 42 "EUC-CN", 43 NULL, NULL 44}; 45 46static size_t mac_chinese_simp_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 *size = 1; 52 out[0] = (u_int8_t)wc; 53 return 1; 54 } else if ((wc & 0xf000) == 0xe000) { 55 *size = 1; 56 return 0; 57 } else if (*size >= 2 && (in[1] & ~15) == 0xf870) { 58 ucs2_t comp = cjk_compose(wc, in[1], mac_chinese_simp_compose, 59 sizeof(mac_chinese_simp_compose) / sizeof(u_int32_t)); 60 if (comp) { 61 wc = comp; 62 *size = 2; 63 } else { 64 *size = 1; 65 } 66 } else { 67 *size = 1; 68 } 69 return cjk_char_push(cjk_lookup(wc, mac_chinese_simp_uni2_index, 70 mac_chinese_simp_uni2_charset), out); 71} 72 73static size_t mac_chinese_simp_push(void *cd, char **inbuf, size_t *inbytesleft, 74 char **outbuf, size_t *outbytesleft) 75{ 76 return cjk_generic_push(mac_chinese_simp_char_push, 77 cd, inbuf, inbytesleft, outbuf, outbytesleft); 78} 79 80static size_t mac_chinese_simp_char_pull(ucs2_t* out, const u_int8_t* in, size_t* size) 81{ 82 u_int16_t c = in[0]; 83 84 if (c <= 0x7f) { 85 *size = 1; 86 *out = c; 87 return 1; 88 } else if (c >= 0xa1 && c <= 0xfc) { 89 if (*size >= 2) { 90 u_int8_t c2 = in[1]; 91 92 if (c2 >= 0xa1 && c2 <= 0xfe) { 93 *size = 2; 94 c = (c << 8) + c2; 95 } else { 96 errno = EILSEQ; 97 return (size_t)-1; 98 } 99 } else { 100 errno = EINVAL; 101 return (size_t)-1; 102 } 103 } else { 104 *size = 1; 105 } 106 return cjk_char_pull(cjk_lookup(c, mac_chinese_simp_2uni_index, 107 mac_chinese_simp_2uni_charset), 108 out, mac_chinese_simp_compose); 109} 110 111static size_t mac_chinese_simp_pull(void *cd, char **inbuf, size_t *inbytesleft, 112 char **outbuf, size_t *outbytesleft) 113{ 114 return cjk_generic_pull(mac_chinese_simp_char_pull, 115 cd, inbuf, inbytesleft, outbuf, outbytesleft); 116} 117#endif 118