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 "utf_euc.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 RESET_CONV_DESC(); 45 46 return((void*)cd); 47 } /* end of int _icv_open(). */ 48 49 50 /**** _ I C V _ C L O S E ****/ 51 52 void _icv_close(_conv_desc* cd) 53 { 54 if (!cd) 55 errno = EBADF; 56 else 57 free((void*)cd); 58 } /* end of void _icv_close(_conv_desc*). */ 59 60 61 /**** _ I C V _ I C O N V ****/ 62 63 size_t _icv_iconv(_conv_desc* cd, char** inbuf, size_t* inbufleft, 64 char** outbuf, size_t* outbufleft) 65 { 66 extern unsigned short _johap_to_wansung(unsigned short, unsigned short, 67 unsigned short); 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 RESET_CONV_DESC(); 83 return((size_t)0); 84 } 85 86 ib = (unsigned char*)*inbuf; 87 ob = (unsigned char*)*outbuf; 88 ibtail = ib + *inbufleft; 89 obtail = ob + *outbufleft; 90 91 while (ib < ibtail) 92 { 93 if (!(*ib & 0x80)) /* 7 bits */ 94 { 95 PROCESS_PRIOR_CVC(); 96 97 if (ob >= obtail) 98 { 99 errno = E2BIG; 100 ret_val = (size_t)-1; 101 break; 102 } 103 *ob++ = *ib++; 104 } 105 else if ((*ib & 0xF0) == 0xE0) /* 16 bits */ 106 { 107 unsigned long utf; 108 109 if ((ibtail - ib) < 3) 110 { 111 errno = EINVAL; 112 ret_val = (size_t)-1; 113 break; 114 } 115 116 utf = ((unsigned long)(*ib) << 16) | 117 ((unsigned long)(*(ib + 1)) << 8) | 118 (unsigned long)(*(ib + 2)); 119 if (utf == 0xE1859F || 120 (utf >= 0xE18480 && utf <= 0xE18492)) /* Ci */ 121 { 122 PROCESS_PRIOR_CVC(); 123 124 cd->ci = (utf == 0xE1859F) ? CVC_FILL 125 : utf - 0xE18480; 126 cd->prev_state = CI; 127 } 128 else if (utf == 0xE185A0 || 129 (utf >= 0xE185A1 && utf <= 0xE185B5)) /* V */ 130 { 131 if (cd->prev_state != E && cd->prev_state != CI) 132 PROCESS_PRIOR_CVC(); 133 134 cd->v = (utf == 0xE185A0) ? CVC_FILL 135 : utf - 0xE185A1; 136 cd->prev_state = V; 137 } 138 else if ((utf >= 0xE186A8 && utf <= 0xE186BF) || 139 (utf >= 0xE18780 && utf <= 0xE18782)) /* Cf */ 140 { 141 if (cd->prev_state != E && cd->prev_state != V) 142 PROCESS_PRIOR_CVC(); 143 144 cd->cf = utf - ((utf >= 0xE18780) ? 0xE18766 145 : 0xE186A6); 146 cd->prev_state = CF; 147 148 PROCESS_PRIOR_CVC(); 149 } 150 else if (utf >= 0xE082A1 && utf <= 0xEFBFA6) 151 { 152 register int h, i, j, l; 153 154 PROCESS_PRIOR_CVC(); 155 156 if ((obtail - ob) < 2) 157 { 158 errno = E2BIG; 159 ret_val = (size_t)-1; 160 break; 161 } 162 163 for (l = 0, h = MAX_U2E_NUM; l < h; ) 164 { 165 i = (l + h) / 2; 166 if (utf82euc_tbl[i].utf8 == utf) 167 break; 168 else if (utf82euc_tbl[l].utf8 == utf) 169 { 170 i = l; 171 break; 172 } 173 else if (utf82euc_tbl[h].utf8 == utf) 174 { 175 i = h; 176 break; 177 } 178 else if (utf82euc_tbl[i].utf8 < utf) 179 l = i + 1; 180 else 181 h = i - 1; 182 } 183 184 if (utf82euc_tbl[i].utf8 != utf) 185 { 186 /* Let's assume the code is 187 * non-identical. */ 188 *ob++ = NON_IDENTICAL; 189 *ob++ = NON_IDENTICAL; 190 ret_val += 2; 191 } 192 else 193 { 194 *ob++ = (char)((utf82euc_tbl[i].code 195 >> 8) & 0xFF); 196 *ob++ = (char)(utf82euc_tbl[i].code & 197 0xFF); 198 } 199 } 200 else 201 { 202 PROCESS_PRIOR_CVC(); 203 204 /* Let's assume the code is non-identical. */ 205 if ((obtail - ob) < 2) 206 { 207 errno = E2BIG; 208 ret_val = (size_t)-1; 209 break; 210 } 211 *ob++ = NON_IDENTICAL; 212 *ob++ = NON_IDENTICAL; 213 ret_val += 2; 214 } 215 ib += 3; 216 } 217 else /* 11, 21, 26 & 31 bits codes won't be able to convert. */ 218 { 219 short int offset; 220 221 PROCESS_PRIOR_CVC(); 222 223 if ((*ib & 0xE0) == 0xC0) /* 11 */ 224 offset = 2; 225 else if ((*ib & 0xF0) == 0xE0) /* 16 */ 226 offset = 3; 227 else if ((*ib & 0xF8) == 0xF0) /* 21 */ 228 offset = 4; 229 else if ((*ib & 0xFC) == 0xF8) /* 26 */ 230 offset = 5; 231 else if ((*ib & 0xFE) == 0xFC) /* 31 */ 232 offset = 6; 233 else /* Illegal sequence. */ 234 offset = 1; 235 236 if ((ibtail - ib) < offset) 237 { 238 errno = EINVAL; 239 ret_val = (size_t)-1; 240 break; 241 } 242 ib += offset; 243 244 /* Let's assume the code is non-identical. */ 245 offset = (offset > 2) ? 2 : 1; 246 if ((obtail - ob) < offset) 247 { 248 errno = E2BIG; 249 ret_val = (size_t)-1; 250 break; 251 } 252 *ob++ = NON_IDENTICAL; 253 if (offset > 1) 254 *ob++ = NON_IDENTICAL; 255 ret_val += offset; 256 } 257 } 258 259 *inbuf = (char*)ib; 260 *inbufleft = ibtail - ib; 261 *outbuf = (char*)ob; 262 *outbufleft = obtail - ob; 263 264 return(ret_val); 265 } /* end of size_t _icv_iconv(_conv_desc*, char**, size_t*, char**, size_t*).*/ 266