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