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 "euc_utf.h" 30 31 32 /**** _ I C V _ O P E N ****/ 33 34 void* _icv_open() 35 { 36 int* cd = (int*)malloc(sizeof(int)); 37 38 if (cd == (int*)NULL) 39 { 40 errno = ENOMEM; 41 return((void*)-1); 42 } 43 44 *cd = MAGIC_NUMBER; 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(int* cd) 53 { 54 if (!cd) 55 errno = EBADF; 56 else 57 free((void*)cd); 58 } /* end of void _icv_close(int*). */ 59 60 61 /**** _ I C V _ I C O N V ****/ 62 63 size_t _icv_iconv(int* 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 || (*cd) != MAGIC_NUMBER) 73 { 74 errno = EBADF; 75 return((size_t)-1); 76 } 77 78 if (!inbuf || !(*inbuf)) 79 return((size_t)0); 80 81 ib = (unsigned char*)*inbuf; 82 ob = (unsigned char*)*outbuf; 83 ibtail = ib + *inbufleft; 84 obtail = ob + *outbufleft; 85 86 while (ib < ibtail) 87 { 88 if (*ib & 0x80) /* Korean EUC doesn't have CS2 or CS3. */ 89 { 90 unsigned short wcode; 91 unsigned long ci, v, cf; 92 char result; 93 extern char _wansung_to_utf8(unsigned long*, 94 unsigned long*, 95 unsigned long*, 96 unsigned short); 97 98 if ((ibtail - ib) < 2) 99 { 100 errno = EINVAL; 101 ret_val = (size_t)-1; 102 break; 103 } 104 105 if (*ib < 0xA1 || *ib > 0xFD || *(ib + 1) < 0xA1 || 106 *(ib + 1) == 0xFF) 107 { 108 errno = EILSEQ; 109 ret_val = (size_t)-1; 110 break; 111 } 112 113 if ((result = _wansung_to_utf8(&ci, &v, &cf, 114 ((unsigned short)*ib << 8) | 115 ((unsigned short)*(ib + 1) & 0xFF))) 116 == HANGUL) 117 { 118 if ((obtail - ob) < (cf ? 9 : 6)) 119 { 120 errno = E2BIG; 121 ret_val = (size_t)-1; 122 break; 123 } 124 *ob++ = (char)((ci >> 16) & 0xFF); 125 *ob++ = (char)((ci >> 8) & 0xFF); 126 *ob++ = (char)(ci & 0xFF); 127 *ob++ = (char)((v >> 16) & 0xFF); 128 *ob++ = (char)((v >> 8) & 0xFF); 129 *ob++ = (char)(v & 0xFF); 130 if (cf) 131 { 132 *ob++ = (char)((cf >> 16) & 0xFF); 133 *ob++ = (char)((cf >> 8) & 0xFF); 134 *ob++ = (char)(cf & 0xFF); 135 } 136 } 137 else if (result == HANJA_OR_SYMBOL) 138 { 139 if ((obtail - ob) < 3) 140 { 141 errno = E2BIG; 142 ret_val = (size_t)-1; 143 break; 144 } 145 *ob++ = (char)((ci >> 16) & 0xFF); 146 *ob++ = (char)((ci >> 8) & 0xFF); 147 *ob++ = (char)(ci & 0xFF); 148 } 149 else /* FAILED - this means input char isn't belong to 150 * input codeset. */ 151 { 152 errno = EILSEQ; 153 ret_val = (size_t)-1; 154 break; 155 } 156 ib += 2; 157 158 } 159 else /* CS0 */ 160 { 161 if (ob >= obtail) 162 { 163 errno = E2BIG; 164 ret_val = (size_t)-1; 165 break; 166 } 167 *ob++ = *ib++; 168 } 169 } 170 171 *inbuf = (char*)ib; 172 *inbufleft = ibtail - ib; 173 *outbuf = (char*)ob; 174 *outbufleft = obtail - ob; 175 176 return(ret_val); 177 } /* end of size_t _icv_iconv(int*, char**, size_t*, char**, size_t*). */ 178