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