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) 1994 by Sun Microsystems, Inc. 23 */ 24 25 26 #include <stdlib.h> 27 #include <errno.h> 28 #include "ktable.h" 29 #include "nbyte_utf.h" 30 31 32 /**** _ I C V _ O P E N ****/ 33 34 void* _icv_open() 35 { 36 _conv_desc* cd = (_conv_desc*)malloc(sizeof(_conv_desc)); 37 38 if (cd == (_conv_desc*)NULL) 39 { 40 errno = ENOMEM; 41 return((void*)-1); 42 } 43 44 cd->cur_stat = 1; 45 cd->hbuf[1] = cd->hbuf[2] = cd->hbuf[3] = cd->hbuf[4] = '\0'; 46 cd->cur_act = 0; 47 48 return((void*)cd); 49 } /* end of int _icv_open(). */ 50 51 52 /**** _ I C V _ C L O S E ****/ 53 54 void _icv_close(_conv_desc* cd) 55 { 56 if (!cd) 57 errno = EBADF; 58 else 59 free((void*)cd); 60 } /* end of void _icv_close(_conv_desc*). */ 61 62 63 /**** _ I C V _ I C O N V ****/ 64 65 size_t _icv_iconv(_conv_desc* cd, char** inbuf, size_t* inbufleft, 66 char** outbuf, size_t* outbufleft) 67 { 68 size_t ret_val = 0; 69 unsigned char* ib; 70 unsigned char* ob; 71 unsigned char* ibtail; 72 unsigned char* obtail; 73 74 if (!cd) 75 { 76 errno = EBADF; 77 return((size_t)-1); 78 } 79 80 if (!inbuf || !(*inbuf)) 81 { 82 cd->cur_stat = 1; 83 cd->hbuf[1] = cd->hbuf[2] = cd->hbuf[3] = cd->hbuf[4] = '\0'; 84 cd->cur_act = 0; 85 return((size_t)0); 86 } 87 88 ib = (unsigned char*)*inbuf; 89 ob = (unsigned char*)*outbuf; 90 ibtail = ib + *inbufleft; 91 obtail = ob + *outbufleft; 92 93 while (ib < ibtail) 94 { 95 int cur_input, action, state; 96 unsigned long ci, v, cf; 97 char result; 98 int input_conv(char); 99 unsigned short make_johap_code(int, char*); 100 extern char _johap_to_utf8(unsigned long*, unsigned long*, 101 unsigned long*, unsigned short); 102 103 cur_input = input_conv(*ib); 104 action = next_act[cd->cur_stat][cur_input]; 105 state = next_stat[cd->cur_stat][cur_input]; 106 if (action == 4) 107 { 108 if (ob >= obtail) 109 { 110 errno = E2BIG; 111 ret_val = (size_t)-1; 112 break; 113 } 114 *ob++ = *ib; 115 } 116 else if (action >= 5 && action <= 8) 117 cd->hbuf[action - 4] = *ib; 118 else if (action == 9) 119 { 120 ADD_CONVERTED_CODE(0, 0); 121 cd->hbuf[1] = *ib; 122 } 123 else if (action == 10) 124 { 125 ADD_CONVERTED_CODE(0, 0); 126 cd->hbuf[2] = *ib; 127 ADD_CONVERTED_CODE(0, 0); 128 } 129 else if (action == 11 || action == 12) 130 { 131 ADD_CONVERTED_CODE(0, 0); 132 } 133 else if (action == 13) 134 { 135 ADD_CONVERTED_CODE(0, 1); 136 *ob++ = *ib; 137 } 138 else if (action == 14) 139 { 140 register char c1 = cd->hbuf[2], c2 = *ib; 141 142 if (c1 == 'l' && c2 == 'b') /* _|_ && |- */ 143 cd->hbuf[2] = 'm'; 144 else if (c1 == 'l' && c2 == 'c') /* _|_ && H */ 145 cd->hbuf[2] = 'n'; 146 else if (c1 == 'l' && c2 == '|') /* _|_ && | */ 147 cd->hbuf[2] = 'o'; 148 else if (c1 == 's' && c2 == 'f') /* T && -| */ 149 cd->hbuf[2] = 't'; 150 else if (c1 == 's' && c2 == 'g') /* T && -|| */ 151 cd->hbuf[2] = 'u'; 152 else if (c1 == 's' && c2 == '|') /* T && | */ 153 cd->hbuf[2] = 'v'; 154 else if (c1 == 'z' && c2 == '|') /* __ && | */ 155 cd->hbuf[2] = '{'; 156 else 157 cd->hbuf[2] = *ib; /* Just in case. */ 158 } 159 else if (action == 15) 160 { 161 cd->hbuf[2] = *ib; 162 ADD_CONVERTED_CODE(0, 0); 163 } 164 else if (action == 16) 165 { 166 ADD_CONVERTED_CODE(0, 0); 167 } 168 else if (action == 17) 169 { 170 ADD_CONVERTED_CODE(1, 0); 171 cd->hbuf[2] = *ib; 172 } 173 cd->cur_act = action; 174 cd->cur_stat = state; 175 ib++; 176 } 177 178 *inbuf = (char*)ib; 179 *inbufleft = ibtail - ib; 180 *outbuf = (char*)ob; 181 *outbufleft = obtail - ob; 182 183 return(ret_val); 184 } /* end of size_t _icv_iconv(_conv_desc*, char**, size_t*, char**, size_t*).*/ 185 186 187 /**** I N P U T _ C O N V ****/ 188 189 int input_conv(char c) 190 { 191 switch (c) 192 { 193 case 'H': /* dd */ 194 case 'S': /* bb */ 195 case 'Y': /* jj */ 196 return(1); 197 198 case 'A': /* g */ 199 return(2); 200 201 case 'D': /* n */ 202 return(3); 203 204 case 'I': /* r */ 205 return(4); 206 207 case 'R': /* b */ 208 return(5); 209 210 case 'B': /* gg */ 211 case 'G': /* d */ 212 case 'V': /* ss */ 213 case 'W': /* o */ 214 case 'Z': /* ch */ 215 case '[': /* k */ 216 return(6); 217 218 case 'U': /* s */ 219 return(7); 220 221 case 'X': /* j */ 222 return(8); 223 224 case '^': /* h */ 225 return(9); 226 227 case 'Q': /* m */ 228 case ']': /* p */ 229 case '\\': /* t */ 230 return(10); 231 232 case 'k': /* =|| */ 233 case 'd': /* |= */ 234 case 'e': /* |=| */ 235 case 'j': /* =| */ 236 case 'r': /* _||_ */ 237 case 'w': /* TT */ 238 return(11); 239 240 case 'b': /* |- */ 241 case 'c': /* H */ 242 return(12); 243 244 case 'f': /* -| */ 245 case 'g': /* -|| */ 246 return(13); 247 248 case '|': /* | */ 249 return(14); 250 251 case 'l': /* _|_ */ 252 return(15); 253 254 case 's': /* T */ 255 return(16); 256 257 case 'z': /* __ */ 258 return(17); 259 260 case '\016': 261 return(18); 262 263 case '\017': 264 case '\024': 265 return(19); 266 267 default: 268 return(20); 269 } 270 } /* end of int input_conv(char). */ 271 272 273 /**** M A K E _ J O H A P _ C O D E ****/ 274 275 unsigned short make_johap_code(int n, char* temp) 276 { 277 register unsigned short code = 0; 278 char save ='\0'; 279 280 if (n == 1) 281 { 282 if (temp[4] == '\0') 283 { 284 save = temp[3]; 285 temp[3] = '\0'; 286 } 287 else 288 { 289 save = temp[4]; 290 temp[4] = '\0'; 291 } 292 } 293 294 code = (temp[1] >= 'A' && temp[1] <= '^') ? 295 (unsigned short)X32_19[temp[1] - '@'] 296 : (unsigned short)9; 297 code = (code << 5) | (unsigned short)((temp[2] >= 'b' && 298 temp[2] <= '|') ? X32_21[temp[2] - '`'] 299 : 1); 300 code = (code << 5) | (unsigned short)((temp[3] >= 'A' && 301 temp[3] <= '^') ? X32_28[temp[3] - '@'] 302 : 1); 303 304 if (temp[4] >= 'A') 305 { 306 if (temp[3] == 'A' && temp[4] == 'U') /* gs */ 307 code += 2; 308 else if (temp[3] == 'D' && temp[4] == 'X') /* nj */ 309 code++; 310 else if (temp[3] == 'D' && temp[4] == '^') /* nh */ 311 code += 2; 312 else if (temp[3] == 'I' && temp[4] == 'A') /* rg */ 313 code++; 314 else if (temp[3] == 'I' && temp[4] == 'Q') /* rm */ 315 code += 2; 316 else if (temp[3] == 'I' && temp[4] == 'R') /* rb */ 317 code += 3; 318 else if (temp[3] == 'I' && temp[4] == 'U') /* rs */ 319 code += 4; 320 else if (temp[3] == 'I' && temp[4] == '\\') /* rt */ 321 code += 5; 322 else if (temp[3] == 'I' && temp[4] == ']') /* rp */ 323 code += 6; 324 else if (temp[3] == 'I' && temp[4] == '^') /* rh */ 325 code += 7; 326 else if (temp[3] == 'R' && temp[4] == 'U') /* bs */ 327 code++; 328 else if (temp[3] == 'U' && temp[4] == 'U') /* ss */ 329 code++; 330 } 331 332 temp[1] = (n == 1) ? save : '\0'; 333 temp[2] = temp[3] = temp[4] = '\0'; 334 return(code | 0x8000); 335 } /* end of unsigned short make_johap_code(int, char*). */ 336