xref: /illumos-gate/usr/src/lib/iconv_modules/ko/common/euc_to_UTF2.c (revision 1e56f352c1c208679012bca47d552e127f5b1072)
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