1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 /* 22 * Copyright (c) 1995 by Sun Microsystems, Inc. 23 * All Rights Reserved. 24 */ 25 26 27 #include <errno.h> 28 #include "ktable.h" 29 #include "hangulcode.h" 30 31 static unsigned short _johap92_to_wansung(unsigned short code); 32 33 /**** _ I C V _ O P E N ****/ 34 35 void* _icv_open() 36 { 37 return((void*)MAGIC_NUMBER); 38 } /* end of void* _icv_open(). */ 39 40 41 /**** _ I C V _ C L O S E ****/ 42 43 void _icv_close(int* cd) 44 { 45 if (!cd || cd != (int*)MAGIC_NUMBER) 46 errno = EBADF; 47 } /* end of void _icv_close(int*). */ 48 49 50 /**** _ I C V _ I C O N V ****/ 51 52 size_t _icv_iconv(int* cd, char** inbuf, size_t* inbufleft, 53 char** outbuf, size_t* outbufleft) 54 { 55 size_t ret_val = 0; 56 unsigned char* ib; 57 unsigned char* ob; 58 unsigned char* ibtail; 59 unsigned char* obtail; 60 61 if (!cd || cd != (int*)MAGIC_NUMBER) 62 { 63 errno = EBADF; 64 return((size_t)-1); 65 } 66 67 if (!inbuf || !(*inbuf)) 68 return((size_t)0); 69 70 ib = (unsigned char*)*inbuf; 71 ob = (unsigned char*)*outbuf; 72 ibtail = ib + *inbufleft; 73 obtail = ob + *outbufleft; 74 75 while (ib < ibtail) 76 { 77 if (!(*ib & 0x80)) 78 { 79 if (ob >= obtail) 80 { 81 errno = E2BIG; 82 ret_val = (size_t)-1; 83 break; 84 } 85 *ob++ = *ib++; 86 } 87 else 88 { 89 unsigned short result; 90 91 if ((ibtail - ib) < 2) 92 { 93 errno = EINVAL; 94 ret_val = (size_t)-1; 95 break; 96 } 97 98 result = _johap92_to_wansung((unsigned short)(*ib)<<8 | 99 (unsigned short)(*(ib + 1))); 100 if (result != FAILED && result != ILLEGAL_SEQ) 101 { 102 if ((obtail - ob) < 2) 103 { 104 errno = E2BIG; 105 ret_val = (size_t)-1; 106 break; 107 } 108 *ob++ = (unsigned char)(result >> 8); 109 *ob++ = (unsigned char)(result & 0xFF); 110 } 111 else 112 { 113 errno = EILSEQ; 114 ret_val = (size_t)-1; 115 break; 116 } 117 ib += 2; 118 } 119 } 120 121 *inbuf = (char*)ib; 122 *inbufleft = ibtail - ib; 123 *outbuf = (char*)ob; 124 *outbufleft = obtail - ob; 125 126 return(ret_val); 127 } /* end of size_t _icv_iconv(int*, char**, size_t*, char**, size_t*). */ 128 129 130 /**** _ J O H A P 9 2 _ T O _ W A N S U N G ****/ 131 132 static unsigned short _johap92_to_wansung(unsigned short code) 133 { 134 short ci, v, cf; 135 short mask; 136 int disp, i; 137 int ch1, ch2; 138 long cfbit; 139 140 ch1 = code >> 8; 141 ch2 = code & 0xff; 142 143 if ((ch1 >= 0x84 && ch1 <= 0xd3) && ((ch2 >= 0x41 && ch2 <= 0x7e) || 144 (ch2 >= 0x81 && ch2 <= 0xfe))) /* Hangul */ 145 { 146 ci = CHOSUNG(code) - 0x02; 147 v = JOONGSUNG(code) - ((unsigned short)(JOONGSUNG(code) - 2) / 148 8 * 2 + 3); 149 cf = JONGSUNG(code) - (unsigned short)JONGSUNG(code) / 18; 150 151 if (v < 0) 152 return(0xA4A0 + Y19_32[CHOSUNG(code) - 1]); 153 if (ci < 0) 154 { 155 if (cf <= 1) 156 return(0xA4BF + v); 157 return(ILLEGAL_SEQ); 158 } 159 160 for (cfbit = cmp_bitmap[ci][v], disp = 0, i = 0; i < cf; i++) 161 { 162 if (cfbit & BIT_MASK) 163 disp++; 164 cfbit >>= 1; 165 } 166 167 if (!(cfbit & BIT_MASK)) 168 return(ILLEGAL_SEQ); 169 170 code = cmp_srchtbl[ci][v] + disp; 171 mask = cmp_srchtbl[ci][v] & 0xff; 172 if ((mask + disp) > 0xfe) 173 code += SKIP; 174 175 return(code); 176 } 177 else if ((ch2 >= 0x31 && ch2 <= 0x7e) || (ch2 >= 0x91 && ch2 <= 0xfe)) 178 { 179 if (ch1 >= 0xe0 && ch1 <= 0xf9) /* Hanja */ 180 { 181 code = (0xca + (ch1 - 0xe0) * 2 + ch2 / 0xa1) << 8; 182 return(code | ((ch2 > 0xa0) ? ch2 183 : ch2 + 0x70 - ((ch2 / 0x91) * 0x12))); 184 } 185 else if (ch1 >= 0xd9 && ch1 <= 0xde) /* Graphic characters */ 186 { 187 code = (0xa1 + (ch1 - 0xd9) * 2 + ch2 / 0xa1) << 8; 188 return(code | ((ch2 > 0xa0) ? ch2 189 : ch2 + 0x70 - ((ch2 / 0x91) * 0x12))); 190 } 191 else if (ch1 == 0xd8) /* User definable characters */ 192 return((ch2 > 0xa0) ? 0xfe00 | ch2 : 0xc900 193 | (ch2 + 0x70 - ((ch2 / 0x91) * 0x12))); 194 } 195 196 return(FAILED); 197 } /* end og static unsigned short _johap92_to_wansung(unsigned short). */ 198