1/* 2 * MacKorean 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_korean.h" 32 33static size_t mac_korean_pull(void *,char **, size_t *, char **, size_t *); 34static size_t mac_korean_push(void *,char **, size_t *, char **, size_t *); 35 36struct charset_functions charset_mac_korean = { 37 "MAC_KOREAN", 38 3, 39 mac_korean_pull, 40 mac_korean_push, 41 CHARSET_ICONV | CHARSET_MULTIBYTE | CHARSET_PRECOMPOSED | CHARSET_CLIENT, 42 "EUC-KR", 43 NULL, NULL 44}; 45 46static size_t mac_korean_char_push(uint8_t* out, const ucs2_t* in, size_t* size) 47{ 48 ucs2_t wc = in[0]; 49 50 if ((wc & ~7) == 0xf860) { 51 wc = cjk_compose_seq(in, size, mac_korean_compose, 52 sizeof(mac_korean_compose) / sizeof(uint32_t)); 53 if (!wc) return (size_t)-1; 54 } else if ((wc & 0xf000) == 0xe000) { 55 *size = 1; 56 return 0; 57 } else if (*size >= 2) { 58 ucs2_t comb = in[1]; 59 size_t n = 1; 60 61 while ((comb & ~15) == 0xf870 || 62 (comb >= 0x0300 && comb <= 0x036f) || 63 (comb >= 0x20d0 && comb <= 0x20ea)) { 64 ucs2_t comp = cjk_compose(wc, comb, mac_korean_compose, 65 sizeof(mac_korean_compose) / sizeof(uint32_t)); 66 if (!comp) break; 67 wc = comp; 68 if (++n == *size) break; 69 comb = in[n]; 70 } 71 *size = n; 72 } else { 73 *size = 1; 74 } 75 if (wc <= 0x7f) { 76 out[0] = (uint8_t)wc; 77 return 1; 78 } 79 return cjk_char_push(cjk_lookup(wc, mac_korean_uni2_index, 80 mac_korean_uni2_charset), out); 81} 82 83static size_t mac_korean_push(void *cd, char **inbuf, size_t *inbytesleft, 84 char **outbuf, size_t *outbytesleft) 85{ 86 return cjk_generic_push(mac_korean_char_push, 87 cd, inbuf, inbytesleft, outbuf, outbytesleft); 88} 89 90static size_t mac_korean_char_pull(ucs2_t* out, const uint8_t* in, size_t* size) 91{ 92 uint16_t c = in[0]; 93 94 if (c <= 0x7f) { 95 *size = 1; 96 *out = c; 97 return 1; 98 } else if (c >= 0xa1 && c <= 0xfe) { 99 if (*size >= 2) { 100 uint8_t c2 = in[1]; 101 if ((c2 >= 0x41 && c2 <= 0x7d) || (c2 >= 0x81 && c2 <= 0xfe)) { 102 *size = 2; 103 c = (c << 8) + c2; 104 } else { 105 errno = EILSEQ; 106 return (size_t)-1; 107 } 108 } else { 109 errno = EINVAL; 110 return (size_t)-1; 111 } 112 } else { 113 *size = 1; 114 } 115 return cjk_char_pull(cjk_lookup(c, mac_korean_2uni_index, 116 mac_korean_2uni_charset), 117 out, mac_korean_compose); 118} 119 120static size_t mac_korean_pull(void *cd, char **inbuf, size_t *inbytesleft, 121 char **outbuf, size_t *outbytesleft) 122{ 123 return cjk_generic_pull(mac_korean_char_pull, 124 cd, inbuf, inbytesleft, outbuf, outbytesleft); 125} 126#endif 127