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) 1996 by Sun Microsystems, Inc. 23 */ 24 25 26 #include <stdlib.h> 27 #include <errno.h> 28 #include <widec.h> 29 #include "common_han.h" 30 #include "euc_utf_api.h" 31 32 #define ESC 0x1B 33 #define SO 0x0E 34 #define SI 0x0F 35 36 typedef struct __conv_desc { 37 enum { NOT_DEFINED_YET, KSC5601 } designator; 38 enum { ASCII, HANGUL } state; 39 } _conv_desc; 40 41 /**** _ I C V _ O P E N ****/ 42 43 void* _icv_open() 44 { 45 _conv_desc* cd = (_conv_desc*)malloc(sizeof(_conv_desc)); 46 47 if (cd == (_conv_desc*)NULL) 48 { 49 errno = ENOMEM; 50 return((void*)-1); 51 } 52 53 cd->designator = NOT_DEFINED_YET; 54 cd->state = ASCII; 55 56 return((void*)cd); 57 } /* end of int _icv_open(). */ 58 59 60 /**** _ I C V _ C L O S E ****/ 61 62 void _icv_close(_conv_desc* cd) 63 { 64 if (!cd) 65 errno = EBADF; 66 else 67 free((void*)cd); 68 } /* end of void _icv_close(_conv_desc*). */ 69 70 71 /**** _ I C V _ I C O N V ****/ 72 73 size_t _icv_iconv(_conv_desc* cd, char** inbuf, size_t* inbufleft, 74 char** outbuf, size_t* outbufleft) 75 { 76 size_t ret_val = 0; 77 unsigned char* ib; 78 unsigned char* ob; 79 unsigned char* ibtail; 80 unsigned char* obtail; 81 82 if (!cd) 83 { 84 errno = EBADF; 85 return((size_t)-1); 86 } 87 88 if (!inbuf || !(*inbuf)) 89 { 90 cd->designator = NOT_DEFINED_YET; 91 cd->state = ASCII; 92 return((size_t)0); 93 } 94 95 ib = (unsigned char*)*inbuf; 96 ob = (unsigned char*)*outbuf; 97 ibtail = ib + *inbufleft; 98 obtail = ob + *outbufleft; 99 100 while (ib < ibtail) 101 { 102 if (cd->designator == KSC5601) 103 { 104 hcode_type euc_code, utf_code; 105 106 if (*ib == SI) 107 { 108 cd->state = ASCII; 109 ib++; 110 continue; 111 } 112 else if (*ib == SO) 113 { 114 cd->state = HANGUL; 115 ib++; 116 continue; 117 } 118 else if ((*ib == ' ' && cd->state == HANGUL) || 119 cd->state == ASCII) 120 { 121 if (ob >= obtail) 122 { 123 errno = E2BIG; 124 ret_val = (size_t)-1; 125 break; 126 } 127 *ob++ = *ib++; 128 continue; 129 } 130 131 /* Pure KS C 5601 Wansung code */ 132 if ((ibtail - ib) < 2) 133 { 134 errno = EINVAL; 135 ret_val = (size_t)-1; 136 break; 137 } 138 139 if (*ib < 0x21 || *ib > 0x7E || *(ib + 1) < 0x21 || 140 *(ib + 1) == 0x7F) 141 { 142 errno = EILSEQ; 143 ret_val = (size_t)-1; 144 break; 145 } 146 147 euc_code.code = 0; 148 euc_code.byte.byte3 = *ib; 149 euc_code.byte.byte4 = *(ib + 1); 150 euc_code.wansung.msb1 = 1; 151 euc_code.wansung.msb2 = 1; 152 153 utf_code = _wansung_to_utf8(euc_code); 154 155 if (utf_code.code != 0) 156 { 157 if ((obtail - ob) < 3) 158 { 159 errno = E2BIG; 160 ret_val = (size_t)-1; 161 break; 162 } 163 /* UTF8 code from 2 bytes is always 3 bytes */ 164 *ob++ = (char)utf_code.byte.byte2; 165 *ob++ = (char)utf_code.byte.byte3; 166 *ob++ = (char)utf_code.byte.byte4; 167 } 168 else /* FAILED - this means input char isn't belong to 169 * input codeset. */ 170 { 171 errno = EILSEQ; 172 ret_val = (size_t)-1; 173 break; 174 } 175 ib += 2; 176 177 } 178 else 179 { 180 if (*ib == ESC) 181 { 182 if ((ibtail - ib) < 4) 183 { 184 errno = EINVAL; 185 ret_val = (size_t)-1; 186 break; 187 } 188 189 if (*(ib + 1) == '$' && *(ib + 2) == ')' && 190 *(ib + 3) == 'C') 191 { 192 cd->designator = KSC5601; 193 ib += 4; 194 continue; 195 } 196 } 197 198 if (ob >= obtail) 199 { 200 errno = E2BIG; 201 ret_val = (size_t)-1; 202 break; 203 } 204 *ob++ = *ib++; 205 } 206 } 207 208 *inbuf = (char*)ib; 209 *inbufleft = ibtail - ib; 210 *outbuf = (char*)ob; 211 *outbufleft = obtail - ob; 212 213 return(ret_val); 214 } /* end of size_t _icv_iconv(_conv_desc*, char**, size_t*, char**, size_t*).*/ 215