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 "iso2022_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->designator = NDY; 45 cd->state = ASCII; 46 47 return((void*)cd); 48 } /* end of int _icv_open(). */ 49 50 51 /**** _ I C V _ C L O S E ****/ 52 53 void _icv_close(_conv_desc* cd) 54 { 55 if (!cd) 56 errno = EBADF; 57 else 58 free((void*)cd); 59 } /* end of void _icv_close(_conv_desc*). */ 60 61 62 /**** _ I C V _ I C O N V ****/ 63 64 size_t _icv_iconv(_conv_desc* cd, char** inbuf, size_t* inbufleft, 65 char** outbuf, size_t* outbufleft) 66 { 67 size_t ret_val = 0; 68 unsigned char* ib; 69 unsigned char* ob; 70 unsigned char* ibtail; 71 unsigned char* obtail; 72 73 if (!cd) 74 { 75 errno = EBADF; 76 return((size_t)-1); 77 } 78 79 if (!inbuf || !(*inbuf)) 80 { 81 cd->designator = NDY; 82 cd->state = ASCII; 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 (cd->designator == KSC5601) 94 { 95 unsigned short wcode; 96 unsigned long ci, v, cf; 97 char result; 98 extern char _wansung_to_utf8(unsigned long*, 99 unsigned long*, 100 unsigned long*, 101 unsigned short); 102 103 if (*ib == SI) 104 { 105 cd->state = ASCII; 106 ib++; 107 continue; 108 } 109 else if (*ib == SO) 110 { 111 cd->state = WANSUNG; 112 ib++; 113 continue; 114 } 115 else if ((*ib == ' ' && cd->state == WANSUNG) || 116 cd->state == ASCII) 117 { 118 if (ob >= obtail) 119 { 120 errno = E2BIG; 121 ret_val = (size_t)-1; 122 break; 123 } 124 *ob++ = *ib++; 125 continue; 126 } 127 128 /* Pure KS C 5601 Wansung code */ 129 if ((ibtail - ib) < 2) 130 { 131 errno = EINVAL; 132 ret_val = (size_t)-1; 133 break; 134 } 135 136 if (*ib < 0x21 || *ib > 0x7D || *(ib + 1) < 0x21 || 137 *(ib + 1) == 0x7F) 138 { 139 errno = EILSEQ; 140 ret_val = (size_t)-1; 141 break; 142 } 143 144 if ((result = _wansung_to_utf8(&ci, &v, &cf, 145 (((unsigned short)*ib << 8) | 146 ((unsigned short)*(ib + 1) & 0xFF) | 147 0x8080))) 148 == HANGUL) 149 { 150 if ((obtail - ob) < (cf ? 9 : 6)) 151 { 152 errno = E2BIG; 153 ret_val = (size_t)-1; 154 break; 155 } 156 *ob++ = (char)((ci >> 16) & 0xFF); 157 *ob++ = (char)((ci >> 8) & 0xFF); 158 *ob++ = (char)(ci & 0xFF); 159 *ob++ = (char)((v >> 16) & 0xFF); 160 *ob++ = (char)((v >> 8) & 0xFF); 161 *ob++ = (char)(v & 0xFF); 162 if (cf) 163 { 164 *ob++ = (char)((cf >> 16) & 0xFF); 165 *ob++ = (char)((cf >> 8) & 0xFF); 166 *ob++ = (char)(cf & 0xFF); 167 } 168 } 169 else if (result == HANJA_OR_SYMBOL) 170 { 171 if ((obtail - ob) < 3) 172 { 173 errno = E2BIG; 174 ret_val = (size_t)-1; 175 break; 176 } 177 *ob++ = (char)((ci >> 16) & 0xFF); 178 *ob++ = (char)((ci >> 8) & 0xFF); 179 *ob++ = (char)(ci & 0xFF); 180 } 181 else /* FAILED - this means input char isn't belong to 182 * input codeset. */ 183 { 184 errno = EILSEQ; 185 ret_val = (size_t)-1; 186 break; 187 } 188 ib += 2; 189 190 } 191 else 192 { 193 if (*ib == ESC) 194 { 195 if ((ibtail - ib) < 4) 196 { 197 errno = EINVAL; 198 ret_val = (size_t)-1; 199 break; 200 } 201 202 if (*(ib + 1) == '$' && *(ib + 2) == ')' && 203 *(ib + 3) == 'C') 204 { 205 cd->designator = KSC5601; 206 ib += 4; 207 continue; 208 } 209 } 210 211 if (ob >= obtail) 212 { 213 errno = E2BIG; 214 ret_val = (size_t)-1; 215 break; 216 } 217 *ob++ = *ib++; 218 } 219 } 220 221 *inbuf = (char*)ib; 222 *inbufleft = ibtail - ib; 223 *outbuf = (char*)ob; 224 *outbufleft = obtail - ob; 225 226 return(ret_val); 227 } /* end of size_t _icv_iconv(_conv_desc*, char**, size_t*, char**, size_t*).*/ 228