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 AND PERMISSION NOTICE
23  *
24  * Copyright (c) 1991-2005 Unicode, Inc. All rights reserved. Distributed
25  * under the Terms of Use in http://www.unicode.org/copyright.html.
26  *
27  * This file has been modified by Sun Microsystems, Inc.
28  */
29 /*
30  * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
31  * Use is subject to license terms.
32  */
33 
34 
35 #include <stdio.h>
36 #include <stdlib.h>
37 #include <errno.h>
38 #include <euc.h>
39 
40 #include "japanese.h"
41 #include "jfp_iconv_unicode.h"
42 
43 #ifdef JAVA_CONV_COMPAT
44 #define	JFP_U2E_ICONV_JAVA
45 #elif	JFP_ICONV_MS932
46 #define	JFP_U2E_ICONV_MS932
47 #else
48 #define	JFP_U2E_ICONV
49 #endif
50 #include "jfp_ucs2_to_euc16.h"
51 
52 #define	DEF_SINGLE	'?'
53 
54 static unsigned short lookuptbl(unsigned short);
55 
56 void *
_icv_open(void)57 _icv_open(void)
58 {
59 	return (_icv_open_unicode((size_t)0));
60 }
61 
62 void
_icv_close(void * cd)63 _icv_close(void *cd)
64 {
65 	_icv_close_unicode(cd);
66 	return;
67 }
68 
69 size_t
_icv_iconv(void * cd,char ** inbuf,size_t * inbytesleft,char ** outbuf,size_t * outbytesleft)70 _icv_iconv(void *cd, char **inbuf, size_t *inbytesleft,
71 				char **outbuf, size_t *outbytesleft)
72 {
73 	unsigned char	ic;
74 	size_t		rv = (size_t)0;
75 	unsigned int	ucs4;
76 	unsigned short	euc16;
77 	unsigned short	dest;
78 
79 	unsigned char	*ip;
80         size_t		ileft;
81 	char		*op;
82         size_t		oleft;
83 
84 	/*
85 	 * If inbuf and/or *inbuf are NULL, reset conversion descriptor
86 	 * and put escape sequence if needed.
87 	 */
88 	if ((inbuf == NULL) || (*inbuf == NULL)) {
89 		_icv_reset_unicode(cd);
90 		return ((size_t)0);
91 	}
92 
93 	ip = (unsigned char *)*inbuf;
94 	ileft = *inbytesleft;
95 	op = *outbuf;
96 	oleft = *outbytesleft;
97 
98 	while (ileft != 0) {
99 		GETU(&ucs4);
100 
101 		if (ucs4 > 0xffff) {
102 			/* non-BMP */
103 			NPUT((unsigned char)DEF_SINGLE, "non-BMP(replaced)");
104 		} else {
105 			euc16 = _jfp_ucs2_to_euc16((unsigned short)ucs4);
106 
107 			switch (euc16 & 0x8080) {
108 			case 0x0000:	/* CS0 */
109 				if (ISC1CTRL((unsigned char)euc16)) {
110 					NPUT((unsigned char)'?',
111 						"CS0-C1CTRL(replaced)")
112 				} else {
113 					ic = (unsigned char)euc16;
114 					NPUT(ic, "CS0-1");
115 				}
116 				break;
117 			case 0x8080:	/* CS1 */
118 				ic = (unsigned short)((euc16 >> 8) & 0x7f);
119 				NPUT(jis208tosj1[ic], "CS1-1");
120 				/*
121 				 * for even number row (Ku), add 0x80 to
122 				 * look latter half of jistosj2[] array
123 				 */
124 				ic = (unsigned char)((euc16 & 0x7f)
125 					+ (((ic % 2) == 0) ? 0x80 : 0x00));
126 				NPUT(jistosj2[ic], "CS1-2");
127 				break;
128 			case 0x0080:	/* CS2 */
129 				ic = (unsigned char)euc16;
130 				NPUT(ic, "CS2-1");
131 				break;
132 			case 0x8000:	/* CS3 */
133 				ic = (unsigned short)((euc16 >> 8) & 0x7f);
134 				if (euc16 == 0xa271) {
135 					/* NUMERO SIGN */
136 					NPUT(0x87, "CS3-NUMERO-1");
137 					NPUT(0x82, "CS3-NUMERO-2");
138 				} else if (ic < 0x75) { /* check if IBM VDC */
139 					dest = lookuptbl(euc16 & 0x7f7f);
140 					if (dest == 0xffff) {
141 						NPUT((unsigned char)'?',
142 							"CS3-NoSJIS(replaced)")
143 					} else {
144 #ifdef	JAVA_CONV_COMPAT
145 						NPUT((unsigned char)'?',
146 							"CS3-IBM(replaced)")
147 #else	/* !JAVA_CONV_COMPAT */
148 						/* avoid putting NUL ('\0') */
149 						if (dest > 0xff) {
150 							NPUT((dest >> 8) & 0xff,
151 								"CS3-IBM-1");
152 							NPUT(dest & 0xff,
153 								"CS3-IBM-2");
154 						} else {
155 							NPUT(dest & 0xff,
156 								"CS3-IBM-1");
157 						}
158 #endif	/* JAVA_CONV_COMPAT */
159 					}
160 				} else {
161 					NPUT(jis212tosj1[ic], "CS3-1");
162 					/*
163 					 * for even number row (Ku), add 0x80 to
164 					 * look latter half of jistosj2[] array
165 					 */
166 					ic = (unsigned short)((euc16 & 0x7f)
167 						+ (((ic % 2) == 0) ?
168 						0x80 : 0x00));
169 					NPUT(jistosj2[ic], "CS3-2");
170 				}
171 				break;
172 			}
173 		}
174 
175 next:
176 		/*
177 		 * One character successfully converted so update
178 		 * values outside of this function's stack.
179 		 */
180 		*inbuf = (char *)ip;
181 		*inbytesleft = ileft;
182 		*outbuf = op;
183 		*outbytesleft = oleft;
184 	}
185 
186 ret:
187 
188 #if	defined(DEBUG)
189 	if (rv == (size_t)-1) {
190 		fprintf(stderr, "DEBUG: errno=%d: %s\n", errno, debugmsg);
191 	}
192 #endif	/* DEBUG */
193 
194 	/*
195 	 * Return value for successful return is not defined by XPG
196 	 * so return same as *inbytesleft as existing codes do.
197 	 */
198 	return ((rv == (size_t)-1) ? rv : *inbytesleft);
199 }
200 
201 /*
202  * lookuptbl()
203  * Return the index number if its index-ed number
204  * is the same as dest value.
205  */
206 static unsigned short
lookuptbl(unsigned short dest)207 lookuptbl(unsigned short dest)
208 {
209 	unsigned short tmp;
210 	int i;
211 	int sz = (sizeof (sjtoibmext) / sizeof (sjtoibmext[0]));
212 
213 	for (i = 0; i < sz; i++) {
214 		tmp = (sjtoibmext[i] & 0x7f7f);
215 		if (tmp == dest)
216 			return ((i + 0xfa40 + ((i / 0xc0) * 0x40)));
217 	}
218 	return (0x3f);
219 }
220