1/* 2 * MacJapanese 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_japanese.h" 32 33static size_t mac_japanese_pull(void *,char **, size_t *, char **, size_t *); 34static size_t mac_japanese_push(void *,char **, size_t *, char **, size_t *); 35 36struct charset_functions charset_mac_japanese = { 37 "MAC_JAPANESE", 38 1, 39 mac_japanese_pull, 40 mac_japanese_push, 41 CHARSET_ICONV | CHARSET_MULTIBYTE | CHARSET_PRECOMPOSED | CHARSET_CLIENT, 42 "SHIFT_JIS", 43 NULL, NULL 44}; 45 46static size_t mac_japanese_char_push(uint8_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] = (uint8_t)(wc == 0x5c ? 0x80 : wc); 53 return 1; 54 } else if ((wc & 0xf000) == 0xe000) { /* user defined */ 55 *size = 1; 56 if (wc > 0xe98b) return 0; 57 wc -= 0xe000; 58 out[0] = (uint8_t)(wc / 188 + 0xf0); 59 out[1] = (uint8_t)(wc % 188 + 0x40); 60 if (out[1] >= 0x7f) ++out[1]; 61 return 2; 62 } else if ((wc & ~7) == 0xf860) { 63 wc = cjk_compose_seq(in, size, mac_japanese_compose, 64 sizeof(mac_japanese_compose) / sizeof(uint32_t)); 65 if (!wc) return (size_t)-1; 66 } else if (*size >= 2 && ((in[1] & ~15) == 0xf870 || in[1] == 0x20dd)) { 67 ucs2_t comp = cjk_compose(wc, in[1], mac_japanese_compose, 68 sizeof(mac_japanese_compose) / sizeof(uint32_t)); 69 if (comp) { 70 wc = comp; 71 *size = 2; 72 } else { 73 *size = 1; 74 } 75 } else { 76 *size = 1; 77 } 78 return cjk_char_push(cjk_lookup(wc, mac_japanese_uni2_index, 79 mac_japanese_uni2_charset), out); 80} 81 82static size_t mac_japanese_push(void *cd, char **inbuf, size_t *inbytesleft, 83 char **outbuf, size_t *outbytesleft) 84{ 85 return cjk_generic_push(mac_japanese_char_push, 86 cd, inbuf, inbytesleft, outbuf, outbytesleft); 87} 88 89static size_t mac_japanese_char_pull(ucs2_t* out, const uint8_t* in, size_t* size) 90{ 91 uint16_t c = in[0]; 92 93 if (c <= 0x7f) { 94 *size = 1; 95 *out = (c == 0x5c ? 0xa5 : c); 96 return 1; 97 } else if ((c >= 0x81 && c <= 0x9f) || (c >= 0xe0 && c <= 0xfc)) { 98 if (*size >= 2) { 99 uint8_t c2 = in[1]; 100 101 if ((c2 >= 0x40 && c2 <= 0x7e) || (c2 >= 0x80 && c2 <= 0xfc)) { 102 *size = 2; 103 if (c >= 0xf0) { /* user defined */ 104 *out = 0xe000 + (c - 0xf0) * 188 + c2 - (c2 < 0x80 ? 0x40 : 0x41); 105 return 1; 106 } 107 c = (c << 8) + c2; 108 } else { 109 errno = EILSEQ; 110 return (size_t)-1; 111 } 112 } else { 113 errno = EINVAL; 114 return (size_t)-1; 115 } 116 } else { 117 *size = 1; 118 } 119 return cjk_char_pull(cjk_lookup(c, mac_japanese_2uni_index, 120 mac_japanese_2uni_charset), 121 out, mac_japanese_compose); 122} 123 124static size_t mac_japanese_pull(void *cd, char **inbuf, size_t *inbytesleft, 125 char **outbuf, size_t *outbytesleft) 126{ 127 return cjk_generic_pull(mac_japanese_char_pull, 128 cd, inbuf, inbytesleft, outbuf, outbytesleft); 129} 130#endif 131