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 1994-2003 Sun Microsystems, Inc. All rights reserved.
23*16d86563SAlexander Pyhalov * Use is subject to license terms.
24*16d86563SAlexander Pyhalov */
25*16d86563SAlexander Pyhalov
26*16d86563SAlexander Pyhalov #include <stdio.h>
27*16d86563SAlexander Pyhalov #include <stdlib.h>
28*16d86563SAlexander Pyhalov #include <errno.h>
29*16d86563SAlexander Pyhalov #include <euc.h>
30*16d86563SAlexander Pyhalov #define JFP_ICONV_STATELESS
31*16d86563SAlexander Pyhalov #include "japanese.h"
32*16d86563SAlexander Pyhalov
33*16d86563SAlexander Pyhalov
34*16d86563SAlexander Pyhalov void *
_icv_open(void)35*16d86563SAlexander Pyhalov _icv_open(void)
36*16d86563SAlexander Pyhalov {
37*16d86563SAlexander Pyhalov return (_icv_open_stateless());
38*16d86563SAlexander Pyhalov }
39*16d86563SAlexander Pyhalov
40*16d86563SAlexander Pyhalov void
_icv_close(void * cd)41*16d86563SAlexander Pyhalov _icv_close(void *cd)
42*16d86563SAlexander Pyhalov {
43*16d86563SAlexander Pyhalov _icv_close_stateless(cd);
44*16d86563SAlexander Pyhalov return;
45*16d86563SAlexander Pyhalov }
46*16d86563SAlexander Pyhalov
47*16d86563SAlexander Pyhalov size_t
_icv_iconv(void * cd,char ** inbuf,size_t * inbytesleft,char ** outbuf,size_t * outbytesleft)48*16d86563SAlexander Pyhalov _icv_iconv(void *cd, char **inbuf, size_t *inbytesleft,
49*16d86563SAlexander Pyhalov char **outbuf, size_t *outbytesleft)
50*16d86563SAlexander Pyhalov {
51*16d86563SAlexander Pyhalov int stat;
52*16d86563SAlexander Pyhalov unsigned char *ip, ic, *op;
53*16d86563SAlexander Pyhalov size_t ileft, oleft;
54*16d86563SAlexander Pyhalov size_t retval;
55*16d86563SAlexander Pyhalov
56*16d86563SAlexander Pyhalov /*
57*16d86563SAlexander Pyhalov * If inbuf and/or *inbuf are NULL, reset conversion descriptor
58*16d86563SAlexander Pyhalov * and put escape sequence if needed.
59*16d86563SAlexander Pyhalov */
60*16d86563SAlexander Pyhalov if ((inbuf == NULL) || (*inbuf == NULL)) {
61*16d86563SAlexander Pyhalov /* nothing to do here for this module */
62*16d86563SAlexander Pyhalov return ((size_t)0);
63*16d86563SAlexander Pyhalov }
64*16d86563SAlexander Pyhalov
65*16d86563SAlexander Pyhalov stat = ST_INIT;
66*16d86563SAlexander Pyhalov
67*16d86563SAlexander Pyhalov ip = (unsigned char *)*inbuf;
68*16d86563SAlexander Pyhalov op = (unsigned char *)*outbuf;
69*16d86563SAlexander Pyhalov ileft = *inbytesleft;
70*16d86563SAlexander Pyhalov oleft = *outbytesleft;
71*16d86563SAlexander Pyhalov
72*16d86563SAlexander Pyhalov /*
73*16d86563SAlexander Pyhalov * Main loop; basically 1 loop per 1 input byte
74*16d86563SAlexander Pyhalov */
75*16d86563SAlexander Pyhalov
76*16d86563SAlexander Pyhalov while ((int)ileft > 0) {
77*16d86563SAlexander Pyhalov GET(ic);
78*16d86563SAlexander Pyhalov if ((stat == ST_INCS1) || (stat == ST_INCS3)) {
79*16d86563SAlexander Pyhalov ic = sjtojis2[ic];
80*16d86563SAlexander Pyhalov PUT(ic | CMSB);
81*16d86563SAlexander Pyhalov stat = ST_INIT;
82*16d86563SAlexander Pyhalov continue;
83*16d86563SAlexander Pyhalov } else if (ISASC((int)ic)) { /* ASCII */
84*16d86563SAlexander Pyhalov CHECK2BIG(EUCW0,1);
85*16d86563SAlexander Pyhalov PUT(ic);
86*16d86563SAlexander Pyhalov continue;
87*16d86563SAlexander Pyhalov } else if (ISSJKANA(ic)) { /* kana start */
88*16d86563SAlexander Pyhalov CHECK2BIG((SS2W + EUCW2),1);
89*16d86563SAlexander Pyhalov PUT(SS2);
90*16d86563SAlexander Pyhalov PUT(ic);
91*16d86563SAlexander Pyhalov continue;
92*16d86563SAlexander Pyhalov } else if (ISSJKANJI1(ic)) { /* CS_1 kanji starts */
93*16d86563SAlexander Pyhalov if ((int)ileft > 0) {
94*16d86563SAlexander Pyhalov if (ISSJKANJI2(*ip)) {
95*16d86563SAlexander Pyhalov CHECK2BIG(EUCW1,1);
96*16d86563SAlexander Pyhalov stat = ST_INCS1;
97*16d86563SAlexander Pyhalov ic = sjtojis1[(ic - 0x80)];
98*16d86563SAlexander Pyhalov if (*ip >= 0x9f) {
99*16d86563SAlexander Pyhalov ic++;
100*16d86563SAlexander Pyhalov }
101*16d86563SAlexander Pyhalov PUT(ic | CMSB);
102*16d86563SAlexander Pyhalov continue;
103*16d86563SAlexander Pyhalov } else { /* 2nd byte is illegal */
104*16d86563SAlexander Pyhalov UNGET();
105*16d86563SAlexander Pyhalov errno = EILSEQ;
106*16d86563SAlexander Pyhalov retval = (size_t)ERR_RETURN;
107*16d86563SAlexander Pyhalov goto ret;
108*16d86563SAlexander Pyhalov }
109*16d86563SAlexander Pyhalov } else { /* input fragment of Kanji */
110*16d86563SAlexander Pyhalov UNGET();
111*16d86563SAlexander Pyhalov errno = EINVAL;
112*16d86563SAlexander Pyhalov retval = (size_t)ERR_RETURN;
113*16d86563SAlexander Pyhalov goto ret;
114*16d86563SAlexander Pyhalov }
115*16d86563SAlexander Pyhalov } else if (ISSJSUPKANJI1(ic)) { /* CS_3 kanji starts */
116*16d86563SAlexander Pyhalov if ((int)ileft > 0) {
117*16d86563SAlexander Pyhalov if (ISSJKANJI2(*ip)) {
118*16d86563SAlexander Pyhalov CHECK2BIG((SS3W + EUCW3),1);
119*16d86563SAlexander Pyhalov stat = ST_INCS3;
120*16d86563SAlexander Pyhalov ic = sjtojis1[(ic - 0x80)];
121*16d86563SAlexander Pyhalov if (*ip >= 0x9f) {
122*16d86563SAlexander Pyhalov ic++;
123*16d86563SAlexander Pyhalov }
124*16d86563SAlexander Pyhalov PUT(SS3);
125*16d86563SAlexander Pyhalov PUT(ic | CMSB);
126*16d86563SAlexander Pyhalov continue;
127*16d86563SAlexander Pyhalov } else { /* 2nd byte is illegal */
128*16d86563SAlexander Pyhalov UNGET();
129*16d86563SAlexander Pyhalov errno = EILSEQ;
130*16d86563SAlexander Pyhalov retval = (size_t)ERR_RETURN;
131*16d86563SAlexander Pyhalov goto ret;
132*16d86563SAlexander Pyhalov }
133*16d86563SAlexander Pyhalov } else { /* input fragment of Kanji */
134*16d86563SAlexander Pyhalov UNGET();
135*16d86563SAlexander Pyhalov errno = EINVAL;
136*16d86563SAlexander Pyhalov retval = (size_t)ERR_RETURN;
137*16d86563SAlexander Pyhalov goto ret;
138*16d86563SAlexander Pyhalov }
139*16d86563SAlexander Pyhalov } else if (ISSJIBM(ic) || /* Extended IBM char. area */
140*16d86563SAlexander Pyhalov ISSJNECIBM(ic)) { /* NEC/IBM char. area */
141*16d86563SAlexander Pyhalov /*
142*16d86563SAlexander Pyhalov * We need a special treatment for each codes.
143*16d86563SAlexander Pyhalov * By adding some offset number for them, we
144*16d86563SAlexander Pyhalov * can process them as the same way of that of
145*16d86563SAlexander Pyhalov * extended IBM chars.
146*16d86563SAlexander Pyhalov */
147*16d86563SAlexander Pyhalov if ((int)ileft > 0) {
148*16d86563SAlexander Pyhalov if (ISSJKANJI2(*ip)) {
149*16d86563SAlexander Pyhalov unsigned short dest;
150*16d86563SAlexander Pyhalov dest = (ic << 8);
151*16d86563SAlexander Pyhalov GET(ic);
152*16d86563SAlexander Pyhalov dest += ic;
153*16d86563SAlexander Pyhalov if ((0xed40 <= dest) &&
154*16d86563SAlexander Pyhalov (dest <= 0xeffc)) {
155*16d86563SAlexander Pyhalov REMAP_NEC(dest);
156*16d86563SAlexander Pyhalov if (dest == 0xffff) {
157*16d86563SAlexander Pyhalov goto ill_ibm;
158*16d86563SAlexander Pyhalov }
159*16d86563SAlexander Pyhalov }
160*16d86563SAlexander Pyhalov if ((dest == 0xfa54) ||
161*16d86563SAlexander Pyhalov (dest == 0xfa5b)) {
162*16d86563SAlexander Pyhalov CHECK2BIG(EUCW1,2);
163*16d86563SAlexander Pyhalov if (dest == 0xfa54) {
164*16d86563SAlexander Pyhalov PUT(0xa2);
165*16d86563SAlexander Pyhalov PUT(0xcc);
166*16d86563SAlexander Pyhalov } else {
167*16d86563SAlexander Pyhalov PUT(0xa2);
168*16d86563SAlexander Pyhalov PUT(0xe8);
169*16d86563SAlexander Pyhalov }
170*16d86563SAlexander Pyhalov continue;
171*16d86563SAlexander Pyhalov }
172*16d86563SAlexander Pyhalov CHECK2BIG((SS3W + EUCW3),2);
173*16d86563SAlexander Pyhalov dest = dest - 0xfa40 -
174*16d86563SAlexander Pyhalov (((dest>>8) - 0xfa) * 0x40);
175*16d86563SAlexander Pyhalov dest = sjtoibmext[dest];
176*16d86563SAlexander Pyhalov if (dest == 0xffff) {
177*16d86563SAlexander Pyhalov /*
178*16d86563SAlexander Pyhalov * Illegal code points
179*16d86563SAlexander Pyhalov * in IBM-EXT area.
180*16d86563SAlexander Pyhalov */
181*16d86563SAlexander Pyhalov ill_ibm:
182*16d86563SAlexander Pyhalov UNGET();
183*16d86563SAlexander Pyhalov UNGET();
184*16d86563SAlexander Pyhalov errno = EILSEQ;
185*16d86563SAlexander Pyhalov retval = (size_t)ERR_RETURN;
186*16d86563SAlexander Pyhalov goto ret;
187*16d86563SAlexander Pyhalov }
188*16d86563SAlexander Pyhalov PUT(SS3);
189*16d86563SAlexander Pyhalov PUT((dest>>8) & 0xff);
190*16d86563SAlexander Pyhalov PUT(dest & 0xff);
191*16d86563SAlexander Pyhalov continue;
192*16d86563SAlexander Pyhalov } else { /* 2nd byte is illegal */
193*16d86563SAlexander Pyhalov UNGET();
194*16d86563SAlexander Pyhalov errno = EILSEQ;
195*16d86563SAlexander Pyhalov retval = (size_t)ERR_RETURN;
196*16d86563SAlexander Pyhalov goto ret;
197*16d86563SAlexander Pyhalov }
198*16d86563SAlexander Pyhalov } else { /* input fragment of Kanji */
199*16d86563SAlexander Pyhalov UNGET();
200*16d86563SAlexander Pyhalov errno = EINVAL;
201*16d86563SAlexander Pyhalov retval = (size_t)ERR_RETURN;
202*16d86563SAlexander Pyhalov goto ret;
203*16d86563SAlexander Pyhalov }
204*16d86563SAlexander Pyhalov } else if ((0xeb <= ic) && (ic <= 0xec)) {
205*16d86563SAlexander Pyhalov /*
206*16d86563SAlexander Pyhalov * Based on the draft convention of OSF-JVC CDEWG,
207*16d86563SAlexander Pyhalov * characters in this area will be mapped to
208*16d86563SAlexander Pyhalov * "CHIKAN-MOJI." (convertible character)
209*16d86563SAlexander Pyhalov * So far, we'll use (0x222e) for it.
210*16d86563SAlexander Pyhalov */
211*16d86563SAlexander Pyhalov if ((int)ileft > 0) {
212*16d86563SAlexander Pyhalov if (ISSJKANJI2(*ip)) {
213*16d86563SAlexander Pyhalov CHECK2BIG(EUCW1,1);
214*16d86563SAlexander Pyhalov GET(ic); /* Dummy */
215*16d86563SAlexander Pyhalov PUT((EGETA>>8) & 0xff);
216*16d86563SAlexander Pyhalov PUT(EGETA & 0xff);
217*16d86563SAlexander Pyhalov continue;
218*16d86563SAlexander Pyhalov } else { /* 2nd byte is illegal */
219*16d86563SAlexander Pyhalov UNGET();
220*16d86563SAlexander Pyhalov errno = EILSEQ;
221*16d86563SAlexander Pyhalov retval = (size_t)ERR_RETURN;
222*16d86563SAlexander Pyhalov goto ret;
223*16d86563SAlexander Pyhalov }
224*16d86563SAlexander Pyhalov } else { /* input fragment of Kanji */
225*16d86563SAlexander Pyhalov UNGET();
226*16d86563SAlexander Pyhalov errno = EINVAL;
227*16d86563SAlexander Pyhalov retval = (size_t)ERR_RETURN;
228*16d86563SAlexander Pyhalov goto ret;
229*16d86563SAlexander Pyhalov }
230*16d86563SAlexander Pyhalov } else { /* 1st byte is illegal */
231*16d86563SAlexander Pyhalov UNGET();
232*16d86563SAlexander Pyhalov errno = EILSEQ;
233*16d86563SAlexander Pyhalov retval = (size_t)ERR_RETURN;
234*16d86563SAlexander Pyhalov goto ret;
235*16d86563SAlexander Pyhalov }
236*16d86563SAlexander Pyhalov }
237*16d86563SAlexander Pyhalov retval = ileft;
238*16d86563SAlexander Pyhalov ret:
239*16d86563SAlexander Pyhalov *inbuf = (char *)ip;
240*16d86563SAlexander Pyhalov *inbytesleft = ileft;
241*16d86563SAlexander Pyhalov *outbuf = (char *)op;
242*16d86563SAlexander Pyhalov *outbytesleft = oleft;
243*16d86563SAlexander Pyhalov
244*16d86563SAlexander Pyhalov return (retval);
245*16d86563SAlexander Pyhalov }
246