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