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 "johap92_utf.h"
30 
31 
32 /****  _ I C V _ O P E N  ****/
33 
_icv_open()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 void* _icv_open(). */
48 
49 
50 /****  _ I C V _ C L O S E  ****/
51 
_icv_close(int * cd)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 
_icv_iconv(int * cd,char ** inbuf,size_t * inbufleft,char ** outbuf,size_t * outbufleft)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)
89 		{
90 			unsigned short	wcode;
91 			unsigned long	ci, v, cf;
92 			char		result;
93 			extern char	_johap92_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 ((result = _johap92_to_utf8(&ci, &v, &cf,
106 					((unsigned short)*ib << 8) |
107 					((unsigned short)*(ib + 1) & 0xFF)))
108 			    == HANGUL)
109 			{
110 				if ((obtail - ob) < (cf ? 9 : 6))
111 				{
112 					errno = E2BIG;
113 					ret_val = (size_t)-1;
114 					break;
115 				}
116 				*ob++ = (char)((ci >> 16) & 0xFF);
117 				*ob++ = (char)((ci >> 8) & 0xFF);
118 				*ob++ = (char)(ci & 0xFF);
119 				*ob++ = (char)((v >> 16) & 0xFF);
120 				*ob++ = (char)((v >> 8) & 0xFF);
121 				*ob++ = (char)(v & 0xFF);
122 				if (cf)
123 				{
124 					*ob++ = (char)((cf >> 16) & 0xFF);
125 					*ob++ = (char)((cf >> 8) & 0xFF);
126 					*ob++ = (char)(cf & 0xFF);
127 				}
128 			}
129 			else if (result == HANJA_OR_SYMBOL)
130 			{
131 				if ((obtail - ob) < 3)
132 				{
133 					errno = E2BIG;
134 					ret_val = (size_t)-1;
135 					break;
136 				}
137 				*ob++ = (char)((ci >> 16) & 0xFF);
138 				*ob++ = (char)((ci >> 8) & 0xFF);
139 				*ob++ = (char)(ci & 0xFF);
140 			}
141 			else  /* FAILED - this means input char isn't belong to
142 			       *	  input codeset. */
143 			{
144 				errno = EILSEQ;
145 				ret_val = (size_t)-1;
146 				break;
147 			}
148 			ib += 2;
149 
150 		}
151 		else  /* CS0 */
152 		{
153 			if (ob >= obtail)
154 			{
155 				errno = E2BIG;
156 				ret_val = (size_t)-1;
157 				break;
158 			}
159 			*ob++ = *ib++;
160 		}
161 	}
162 
163 	*inbuf = (char*)ib;
164 	*inbufleft = ibtail - ib;
165 	*outbuf = (char*)ob;
166 	*outbufleft = obtail - ob;
167 
168 	return(ret_val);
169 }  /* end of size_t _icv_iconv(int*, char**, size_t*, char**, size_t*). */
170