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 <stdlib.h>
36*16d86563SAlexander Pyhalov #include <errno.h>
37*16d86563SAlexander Pyhalov #include <euc.h>
38*16d86563SAlexander Pyhalov #include "japanese.h"
39*16d86563SAlexander Pyhalov #include "jfp_iconv_unicode.h"
40*16d86563SAlexander Pyhalov 
41*16d86563SAlexander Pyhalov #ifdef JAVA_CONV_COMPAT
42*16d86563SAlexander Pyhalov #define	JFP_J2U_ICONV_JAVA
43*16d86563SAlexander Pyhalov #elif	JFP_ICONV_MS932
44*16d86563SAlexander Pyhalov #define	JFP_J2U_ICONV_MS932
45*16d86563SAlexander Pyhalov #else
46*16d86563SAlexander Pyhalov #define	JFP_J2U_ICONV
47*16d86563SAlexander Pyhalov #endif
48*16d86563SAlexander Pyhalov #include "jfp_jis_to_ucs2.h"
49*16d86563SAlexander Pyhalov 
50*16d86563SAlexander Pyhalov void *
_icv_open(void)51*16d86563SAlexander Pyhalov _icv_open(void)
52*16d86563SAlexander Pyhalov {
53*16d86563SAlexander Pyhalov 	return (_icv_open_unicode((size_t)0));
54*16d86563SAlexander Pyhalov }
55*16d86563SAlexander Pyhalov 
56*16d86563SAlexander Pyhalov void
_icv_close(void * cd)57*16d86563SAlexander Pyhalov _icv_close(void *cd)
58*16d86563SAlexander Pyhalov {
59*16d86563SAlexander Pyhalov 	_icv_close_unicode(cd);
60*16d86563SAlexander Pyhalov 	return;
61*16d86563SAlexander Pyhalov }
62*16d86563SAlexander Pyhalov 
63*16d86563SAlexander Pyhalov size_t
_icv_iconv(void * cd,char ** inbuf,size_t * inbytesleft,char ** outbuf,size_t * outbytesleft)64*16d86563SAlexander Pyhalov _icv_iconv(void *cd, char **inbuf, size_t *inbytesleft,
65*16d86563SAlexander Pyhalov 				char **outbuf, size_t *outbytesleft)
66*16d86563SAlexander Pyhalov {
67*16d86563SAlexander Pyhalov 	unsigned int	uni;		/* UTF-32 */
68*16d86563SAlexander Pyhalov 	unsigned int	index;		/* index for table lookup */
69*16d86563SAlexander Pyhalov 	unsigned char	ic1, ic2;	/* 1st and 2nd bytes of a char */
70*16d86563SAlexander Pyhalov 	size_t		rv = (size_t)0;	/* return value of this function */
71*16d86563SAlexander Pyhalov 
72*16d86563SAlexander Pyhalov 	unsigned char	*ip;
73*16d86563SAlexander Pyhalov 	size_t		ileft;
74*16d86563SAlexander Pyhalov 	char		*op;
75*16d86563SAlexander Pyhalov 	size_t		oleft;
76*16d86563SAlexander Pyhalov 
77*16d86563SAlexander Pyhalov 	/*
78*16d86563SAlexander Pyhalov 	 * If inbuf and/or *inbuf are NULL, reset conversion descriptor
79*16d86563SAlexander Pyhalov 	 * and put escape sequence if needed.
80*16d86563SAlexander Pyhalov 	 */
81*16d86563SAlexander Pyhalov 	if ((inbuf == NULL) || (*inbuf == NULL)) {
82*16d86563SAlexander Pyhalov 		_icv_reset_unicode(cd);
83*16d86563SAlexander Pyhalov 		return ((size_t)0);
84*16d86563SAlexander Pyhalov 	}
85*16d86563SAlexander Pyhalov 
86*16d86563SAlexander Pyhalov 	ip = (unsigned char *)*inbuf;
87*16d86563SAlexander Pyhalov 	ileft = *inbytesleft;
88*16d86563SAlexander Pyhalov 	op = *outbuf;
89*16d86563SAlexander Pyhalov 	oleft = *outbytesleft;
90*16d86563SAlexander Pyhalov 
91*16d86563SAlexander Pyhalov 	while (ileft != 0) {
92*16d86563SAlexander Pyhalov 		NGET(ic1, "never fail here"); /* get 1st byte */
93*16d86563SAlexander Pyhalov 
94*16d86563SAlexander Pyhalov 		if (ISASC((int)ic1)) {	/* ASCII; 1 byte */
95*16d86563SAlexander Pyhalov 			uni = _jfp_tbl_jisx0201roman_to_ucs2[ic1];
96*16d86563SAlexander Pyhalov 			PUTU(uni, "ASCII");
97*16d86563SAlexander Pyhalov 		} else if (ISSJKANA(ic1)) { /* JIS X 0201 Kana; 1 byte */
98*16d86563SAlexander Pyhalov 			uni = _jfp_tbl_jisx0201kana_to_ucs2[(ic1 - 0xa1)];
99*16d86563SAlexander Pyhalov 			PUTU(uni, "KANA");
100*16d86563SAlexander Pyhalov 		} else if (ISSJKANJI1(ic1)) { /* JIS X 0208 or UDC; 2 bytes */
101*16d86563SAlexander Pyhalov 			NGET(ic2, "CS1-2 not available");
102*16d86563SAlexander Pyhalov 			if (ISSJKANJI2(ic2)) {
103*16d86563SAlexander Pyhalov 				ic1 = sjtojis1[(ic1 - 0x80)];
104*16d86563SAlexander Pyhalov 				if (ic2 >= 0x9f) {
105*16d86563SAlexander Pyhalov 					ic1++;
106*16d86563SAlexander Pyhalov 				}
107*16d86563SAlexander Pyhalov 				index = ((ic1 - 0x21) * 94)
108*16d86563SAlexander Pyhalov 					+ (sjtojis2[ic2] - 0x21);
109*16d86563SAlexander Pyhalov 				uni = _jfp_tbl_jisx0208_to_ucs2[index];
110*16d86563SAlexander Pyhalov 				PUTU(uni, "KANJI");
111*16d86563SAlexander Pyhalov 			} else { /* 2nd byte check failed */
112*16d86563SAlexander Pyhalov 				RETERROR(EILSEQ, "EILSEQ at CS1-2")
113*16d86563SAlexander Pyhalov 				/* NOTREACHED */
114*16d86563SAlexander Pyhalov 			}
115*16d86563SAlexander Pyhalov 		} else if (ISSJSUPKANJI1(ic1)) { /* VDC, 2 bytes */
116*16d86563SAlexander Pyhalov 			NGET(ic2, "SUP-2 not available");
117*16d86563SAlexander Pyhalov 			if (ISSJKANJI2(ic2)) {
118*16d86563SAlexander Pyhalov 				ic1 = sjtojis1[(ic1 - 0x80)];
119*16d86563SAlexander Pyhalov 				if (ic2 >= 0x9f) {
120*16d86563SAlexander Pyhalov 					ic1++;
121*16d86563SAlexander Pyhalov 				}
122*16d86563SAlexander Pyhalov 				index = ((ic1 - 0x21) * 94)
123*16d86563SAlexander Pyhalov 						+ (sjtojis2[ic2] - 0x21);
124*16d86563SAlexander Pyhalov 				uni = _jfp_tbl_jisx0212_to_ucs2[index];
125*16d86563SAlexander Pyhalov 				PUTU(uni, "SUPKANJI");
126*16d86563SAlexander Pyhalov 			} else { /* 2nd byte check failed */
127*16d86563SAlexander Pyhalov 				RETERROR(EILSEQ, "EILSEQ at CS1-2")
128*16d86563SAlexander Pyhalov 			}
129*16d86563SAlexander Pyhalov 		} else if (ISSJIBM(ic1) || /* Extended IBM char. area */
130*16d86563SAlexander Pyhalov 			ISSJNECIBM(ic1)) { /* NEC/IBM char. area */
131*16d86563SAlexander Pyhalov 			/*
132*16d86563SAlexander Pyhalov 			 * We need a special treatment for each codes.
133*16d86563SAlexander Pyhalov 			 * By adding some offset number for them, we
134*16d86563SAlexander Pyhalov 			 * can process them as the same way of that of
135*16d86563SAlexander Pyhalov 			 * extended IBM chars.
136*16d86563SAlexander Pyhalov 			 */
137*16d86563SAlexander Pyhalov 			NGET(ic2, "IBM-2 not available");
138*16d86563SAlexander Pyhalov 			if (ISSJKANJI2(ic2)) {
139*16d86563SAlexander Pyhalov 				unsigned short dest, upper, lower;
140*16d86563SAlexander Pyhalov 				dest = (ic1 << 8) + ic2;
141*16d86563SAlexander Pyhalov 				if ((0xed40 <= dest) && (dest <= 0xeffc)) {
142*16d86563SAlexander Pyhalov 					REMAP_NEC(dest);
143*16d86563SAlexander Pyhalov 					if (dest == 0xffff) {
144*16d86563SAlexander Pyhalov 						RETERROR(EILSEQ, "invalid NEC")
145*16d86563SAlexander Pyhalov 					}
146*16d86563SAlexander Pyhalov 				}
147*16d86563SAlexander Pyhalov 				/*
148*16d86563SAlexander Pyhalov 				 * XXX: 0xfa54 and 0xfa5b must be mapped
149*16d86563SAlexander Pyhalov 				 *	to JIS0208 area. Therefore we
150*16d86563SAlexander Pyhalov 				 *	have to do special treatment.
151*16d86563SAlexander Pyhalov 				 */
152*16d86563SAlexander Pyhalov 				if ((dest == 0xfa54) || (dest == 0xfa5b)) {
153*16d86563SAlexander Pyhalov 					if (dest == 0xfa54) {
154*16d86563SAlexander Pyhalov 			/* map to JIS X 0208 row 2 cell 44 "NOT SIGN" */
155*16d86563SAlexander Pyhalov 				index = (2 - 1) * 94 + (44 - 1);
156*16d86563SAlexander Pyhalov 					} else {
157*16d86563SAlexander Pyhalov 			/* map to JIS X 0208 row 2 cell 72 "BECAUSE" */
158*16d86563SAlexander Pyhalov 				index = (2 - 1) * 94 + (72 - 1);
159*16d86563SAlexander Pyhalov 					}
160*16d86563SAlexander Pyhalov 					uni = _jfp_tbl_jisx0208_to_ucs2[index];
161*16d86563SAlexander Pyhalov 					PUTU(uni, "IBM");
162*16d86563SAlexander Pyhalov 				} else {
163*16d86563SAlexander Pyhalov 					dest = dest - 0xfa40 -
164*16d86563SAlexander Pyhalov 						(((dest>>8) - 0xfa) * 0x40);
165*16d86563SAlexander Pyhalov 					dest = sjtoibmext[dest];
166*16d86563SAlexander Pyhalov 					if (dest == 0xffff) {
167*16d86563SAlexander Pyhalov 						RETERROR(EILSEQ, "invalid IBM")
168*16d86563SAlexander Pyhalov 					}
169*16d86563SAlexander Pyhalov 					upper = ((dest >> 8) & 0x7f) - 0x21;
170*16d86563SAlexander Pyhalov 					lower = (dest & 0x7f) - 0x21;
171*16d86563SAlexander Pyhalov 					index = (unsigned int)(upper * 94 +
172*16d86563SAlexander Pyhalov 						lower);
173*16d86563SAlexander Pyhalov 					uni = _jfp_tbl_jisx0212_to_ucs2[index];
174*16d86563SAlexander Pyhalov 					PUTU(uni, "IBM");
175*16d86563SAlexander Pyhalov 				}
176*16d86563SAlexander Pyhalov 			} else { /* 2nd byte check failed */
177*16d86563SAlexander Pyhalov 				RETERROR(EILSEQ, "EILSEQ at IBM-2")
178*16d86563SAlexander Pyhalov 			}
179*16d86563SAlexander Pyhalov 		} else if ((0xeb <= ic1) && (ic1 <= 0xec)) {
180*16d86563SAlexander Pyhalov 		/*
181*16d86563SAlexander Pyhalov 		 * Based on the draft convention of OSF-JVC CDEWG,
182*16d86563SAlexander Pyhalov 		 * characters in this area will be mapped to
183*16d86563SAlexander Pyhalov 		 * "CHIKAN-MOJI." (convertible character)
184*16d86563SAlexander Pyhalov 		 * We use U+FFFD in this case.
185*16d86563SAlexander Pyhalov 		 */
186*16d86563SAlexander Pyhalov 			NGET(ic2, "GAP-2 not available");
187*16d86563SAlexander Pyhalov 			if (ISSJKANJI2(ic2)) {
188*16d86563SAlexander Pyhalov 				uni = 0xfffd;
189*16d86563SAlexander Pyhalov 				PUTU(uni, "GAP");
190*16d86563SAlexander Pyhalov 			} else { /* 2nd byte check failed */
191*16d86563SAlexander Pyhalov 				RETERROR(EILSEQ, "EILSEQ at GAP-2")
192*16d86563SAlexander Pyhalov 			}
193*16d86563SAlexander Pyhalov 		} else { /* 1st byte check failed */
194*16d86563SAlexander Pyhalov 			RETERROR(EILSEQ, "EILSEQ at 1st")
195*16d86563SAlexander Pyhalov 		}
196*16d86563SAlexander Pyhalov 
197*16d86563SAlexander Pyhalov 		/*
198*16d86563SAlexander Pyhalov 		 * One character successfully converted so update
199*16d86563SAlexander Pyhalov 		 * values outside of this function's stack.
200*16d86563SAlexander Pyhalov 		 */
201*16d86563SAlexander Pyhalov 		*inbuf = (char *)ip;
202*16d86563SAlexander Pyhalov 		*inbytesleft = ileft;
203*16d86563SAlexander Pyhalov 		*outbuf = op;
204*16d86563SAlexander Pyhalov 		*outbytesleft = oleft;
205*16d86563SAlexander Pyhalov 	}
206*16d86563SAlexander Pyhalov 
207*16d86563SAlexander Pyhalov ret:
208*16d86563SAlexander Pyhalov 	DEBUGPRINTERROR
209*16d86563SAlexander Pyhalov 
210*16d86563SAlexander Pyhalov 	/*
211*16d86563SAlexander Pyhalov 	 * Return value for successful return is not defined by XPG
212*16d86563SAlexander Pyhalov 	 * so return same as *inbytesleft as existing codes do.
213*16d86563SAlexander Pyhalov 	 */
214*16d86563SAlexander Pyhalov 	return ((rv == (size_t)-1) ? rv : *inbytesleft);
215*16d86563SAlexander Pyhalov }
216