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 2007 Sun Microsystems, Inc. All rights reserved.
23*16d86563SAlexander Pyhalov * Use is subject to license terms.
24*16d86563SAlexander Pyhalov */
25*16d86563SAlexander Pyhalov
26*16d86563SAlexander Pyhalov
27*16d86563SAlexander Pyhalov #include <stdlib.h>
28*16d86563SAlexander Pyhalov #include <errno.h>
29*16d86563SAlexander Pyhalov #include <euc.h>
30*16d86563SAlexander Pyhalov
31*16d86563SAlexander Pyhalov #include "japanese.h"
32*16d86563SAlexander Pyhalov #include "jfp_iconv_unicode.h"
33*16d86563SAlexander Pyhalov
34*16d86563SAlexander Pyhalov #define JFP_U2E_ICONV_X0213
35*16d86563SAlexander Pyhalov #include "jfp_ucs2_to_euc16.h"
36*16d86563SAlexander Pyhalov
37*16d86563SAlexander Pyhalov #define DEF_SINGLE '?'
38*16d86563SAlexander Pyhalov
39*16d86563SAlexander Pyhalov #define INVL 0xff
40*16d86563SAlexander Pyhalov
41*16d86563SAlexander Pyhalov static const unsigned char rowtosj1_x0213_p1[] = {
42*16d86563SAlexander Pyhalov /* 1 2 3 4 5 6 7 */
43*16d86563SAlexander Pyhalov INVL, 0x81, 0x81, 0x82, 0x82, 0x83, 0x83, 0x84,
44*16d86563SAlexander Pyhalov /* 8 9 10 11 12 13 14 15 */
45*16d86563SAlexander Pyhalov 0x84, 0x85, 0x85, 0x86, 0x86, 0x87, 0x87, 0x88,
46*16d86563SAlexander Pyhalov /* 16 17 18 19 20 21 22 23 */
47*16d86563SAlexander Pyhalov 0x88, 0x89, 0x89, 0x8a, 0x8a, 0x8b, 0x8b, 0x8c,
48*16d86563SAlexander Pyhalov /* 24 25 26 27 28 29 30 31 */
49*16d86563SAlexander Pyhalov 0x8c, 0x8d, 0x8d, 0x8e, 0x8e, 0x8f, 0x8f, 0x90,
50*16d86563SAlexander Pyhalov /* 32 33 34 35 36 37 38 39 */
51*16d86563SAlexander Pyhalov 0x90, 0x91, 0x91, 0x92, 0x92, 0x93, 0x93, 0x94,
52*16d86563SAlexander Pyhalov /* 40 41 42 43 44 45 46 47 */
53*16d86563SAlexander Pyhalov 0x94, 0x95, 0x95, 0x96, 0x96, 0x97, 0x97, 0x98,
54*16d86563SAlexander Pyhalov /* 48 49 50 51 52 53 54 55 */
55*16d86563SAlexander Pyhalov 0x98, 0x99, 0x99, 0x9a, 0x9a, 0x9b, 0x9b, 0x9c,
56*16d86563SAlexander Pyhalov /* 56 57 58 59 60 61 62 63 */
57*16d86563SAlexander Pyhalov 0x9c, 0x9d, 0x9d, 0x9e, 0x9e, 0x9f, 0x9f, 0xe0,
58*16d86563SAlexander Pyhalov /* 64 65 66 67 68 69 70 71 */
59*16d86563SAlexander Pyhalov 0xe0, 0xe1, 0xe1, 0xe2, 0xe2, 0xe3, 0xe3, 0xe4,
60*16d86563SAlexander Pyhalov /* 72 73 74 75 76 77 78 79 */
61*16d86563SAlexander Pyhalov 0xe4, 0xe5, 0xe5, 0xe6, 0xe6, 0xe7, 0xe7, 0xe8,
62*16d86563SAlexander Pyhalov /* 80 81 82 83 84 85 86 87 */
63*16d86563SAlexander Pyhalov 0xe8, 0xe9, 0xe9, 0xea, 0xea, 0xeb, 0xeb, 0xec,
64*16d86563SAlexander Pyhalov /* 88 89 90 91 92 93 94 */
65*16d86563SAlexander Pyhalov 0xec, 0xed, 0xed, 0xee, 0xee, 0xef, 0xef
66*16d86563SAlexander Pyhalov };
67*16d86563SAlexander Pyhalov
68*16d86563SAlexander Pyhalov static const unsigned char rowtosj1_x0213_p2[] = {
69*16d86563SAlexander Pyhalov /* 1 2 3 4 5 6 7 */
70*16d86563SAlexander Pyhalov INVL, 0xf0, INVL, 0xf1, 0xf1, 0xf2, INVL, INVL,
71*16d86563SAlexander Pyhalov /* 8 9 10 11 12 13 14 15 */
72*16d86563SAlexander Pyhalov 0xf0, INVL, INVL, INVL, 0xf2, 0xf3, 0xf3, 0xf4,
73*16d86563SAlexander Pyhalov /* 16 17 18 19 20 21 22 23 */
74*16d86563SAlexander Pyhalov INVL, INVL, INVL, INVL, INVL, INVL, INVL, INVL,
75*16d86563SAlexander Pyhalov /* 24 25 26 27 28 29 30 31 */
76*16d86563SAlexander Pyhalov INVL, INVL, INVL, INVL, INVL, INVL, INVL, INVL,
77*16d86563SAlexander Pyhalov /* 32 33 34 35 36 37 38 39 */
78*16d86563SAlexander Pyhalov INVL, INVL, INVL, INVL, INVL, INVL, INVL, INVL,
79*16d86563SAlexander Pyhalov /* 40 41 42 43 44 45 46 47 */
80*16d86563SAlexander Pyhalov INVL, INVL, INVL, INVL, INVL, INVL, INVL, INVL,
81*16d86563SAlexander Pyhalov /* 48 49 50 51 52 53 54 55 */
82*16d86563SAlexander Pyhalov INVL, INVL, INVL, INVL, INVL, INVL, INVL, INVL,
83*16d86563SAlexander Pyhalov /* 56 57 58 59 60 61 62 63 */
84*16d86563SAlexander Pyhalov INVL, INVL, INVL, INVL, INVL, INVL, INVL, INVL,
85*16d86563SAlexander Pyhalov /* 64 65 66 67 68 69 70 71 */
86*16d86563SAlexander Pyhalov INVL, INVL, INVL, INVL, INVL, INVL, INVL, INVL,
87*16d86563SAlexander Pyhalov /* 72 73 74 75 76 77 78 79 */
88*16d86563SAlexander Pyhalov INVL, INVL, INVL, INVL, INVL, INVL, 0xf4, 0xf5,
89*16d86563SAlexander Pyhalov /* 80 81 82 83 84 85 86 87 */
90*16d86563SAlexander Pyhalov 0xf5, 0xf6, 0xf6, 0xf7, 0xf7, 0xf8, 0xf8, 0xf9,
91*16d86563SAlexander Pyhalov /* 88 89 90 91 92 93 94 */
92*16d86563SAlexander Pyhalov 0xf9, 0xfa, 0xfa, 0xfb, 0xfb, 0xfc, 0xfc
93*16d86563SAlexander Pyhalov };
94*16d86563SAlexander Pyhalov
e16tosj_x0213(unsigned short e16,unsigned char * pc2)95*16d86563SAlexander Pyhalov static unsigned char e16tosj_x0213(
96*16d86563SAlexander Pyhalov unsigned short e16,
97*16d86563SAlexander Pyhalov unsigned char *pc2)
98*16d86563SAlexander Pyhalov {
99*16d86563SAlexander Pyhalov unsigned char c1;
100*16d86563SAlexander Pyhalov unsigned char r, c;
101*16d86563SAlexander Pyhalov
102*16d86563SAlexander Pyhalov /* range check (if valid for plane 1 or 2) for e16
103*16d86563SAlexander Pyhalov has been done by the caller side */
104*16d86563SAlexander Pyhalov
105*16d86563SAlexander Pyhalov r = (e16 >> 8) - 0xa0;
106*16d86563SAlexander Pyhalov
107*16d86563SAlexander Pyhalov if ((e16 & 0x8080) == 0x8080) { /* Plane 1 */
108*16d86563SAlexander Pyhalov c1 = rowtosj1_x0213_p1[r];
109*16d86563SAlexander Pyhalov } else { /* Plane 2 */
110*16d86563SAlexander Pyhalov c1 = rowtosj1_x0213_p2[r];
111*16d86563SAlexander Pyhalov }
112*16d86563SAlexander Pyhalov
113*16d86563SAlexander Pyhalov c = (e16 & 0x7f) - 0x20;
114*16d86563SAlexander Pyhalov
115*16d86563SAlexander Pyhalov if ((r % 2) == 1) { /* odd row */
116*16d86563SAlexander Pyhalov *pc2 = (c - 1) + 0x40;
117*16d86563SAlexander Pyhalov if (*pc2 >= 0x7f) {
118*16d86563SAlexander Pyhalov (*pc2)++;
119*16d86563SAlexander Pyhalov }
120*16d86563SAlexander Pyhalov } else { /* even row */
121*16d86563SAlexander Pyhalov *pc2 = (c - 1) + 0x9f;
122*16d86563SAlexander Pyhalov }
123*16d86563SAlexander Pyhalov
124*16d86563SAlexander Pyhalov return (c1);
125*16d86563SAlexander Pyhalov }
126*16d86563SAlexander Pyhalov
127*16d86563SAlexander Pyhalov void *
_icv_open(void)128*16d86563SAlexander Pyhalov _icv_open(void)
129*16d86563SAlexander Pyhalov {
130*16d86563SAlexander Pyhalov return (_icv_open_unicode((size_t)0));
131*16d86563SAlexander Pyhalov }
132*16d86563SAlexander Pyhalov
133*16d86563SAlexander Pyhalov void
_icv_close(void * cd)134*16d86563SAlexander Pyhalov _icv_close(void *cd)
135*16d86563SAlexander Pyhalov {
136*16d86563SAlexander Pyhalov _icv_close_unicode(cd);
137*16d86563SAlexander Pyhalov return;
138*16d86563SAlexander Pyhalov }
139*16d86563SAlexander Pyhalov
140*16d86563SAlexander Pyhalov size_t
_icv_iconv(void * cd,char ** inbuf,size_t * inbytesleft,char ** outbuf,size_t * outbytesleft)141*16d86563SAlexander Pyhalov _icv_iconv(void *cd, char **inbuf, size_t *inbytesleft,
142*16d86563SAlexander Pyhalov char **outbuf, size_t *outbytesleft)
143*16d86563SAlexander Pyhalov {
144*16d86563SAlexander Pyhalov unsigned int u32; /* UTF-32 */
145*16d86563SAlexander Pyhalov unsigned short e16; /* 16-bit EUC */
146*16d86563SAlexander Pyhalov unsigned char ic1, ic2;
147*16d86563SAlexander Pyhalov size_t rv = (size_t)0;
148*16d86563SAlexander Pyhalov
149*16d86563SAlexander Pyhalov unsigned char *ip;
150*16d86563SAlexander Pyhalov size_t ileft;
151*16d86563SAlexander Pyhalov char *op;
152*16d86563SAlexander Pyhalov size_t oleft;
153*16d86563SAlexander Pyhalov
154*16d86563SAlexander Pyhalov /*
155*16d86563SAlexander Pyhalov * If inbuf and/or *inbuf are NULL, reset conversion descriptor
156*16d86563SAlexander Pyhalov * and put escape sequence if needed.
157*16d86563SAlexander Pyhalov */
158*16d86563SAlexander Pyhalov if ((inbuf == NULL) || (*inbuf == NULL)) {
159*16d86563SAlexander Pyhalov _icv_reset_unicode(cd);
160*16d86563SAlexander Pyhalov return ((size_t)0);
161*16d86563SAlexander Pyhalov }
162*16d86563SAlexander Pyhalov
163*16d86563SAlexander Pyhalov ip = (unsigned char *)*inbuf;
164*16d86563SAlexander Pyhalov ileft = *inbytesleft;
165*16d86563SAlexander Pyhalov op = *outbuf;
166*16d86563SAlexander Pyhalov oleft = *outbytesleft;
167*16d86563SAlexander Pyhalov
168*16d86563SAlexander Pyhalov while (ileft != 0) {
169*16d86563SAlexander Pyhalov GETU(&u32)
170*16d86563SAlexander Pyhalov
171*16d86563SAlexander Pyhalov e16 = _jfp_u32_to_euc16(u32);
172*16d86563SAlexander Pyhalov
173*16d86563SAlexander Pyhalov switch (e16 & 0x8080) {
174*16d86563SAlexander Pyhalov case 0x0000: /* ASCII */
175*16d86563SAlexander Pyhalov ic1 = (unsigned char)e16;
176*16d86563SAlexander Pyhalov NPUT(ic1, "ASCII");
177*16d86563SAlexander Pyhalov break;
178*16d86563SAlexander Pyhalov case 0x8080: /* PLANE1 */
179*16d86563SAlexander Pyhalov ic1 = e16tosj_x0213(e16, &ic2);
180*16d86563SAlexander Pyhalov NPUT(ic1, "PLANE1-1");
181*16d86563SAlexander Pyhalov NPUT(ic2, "PLANE1-2");
182*16d86563SAlexander Pyhalov break;
183*16d86563SAlexander Pyhalov case 0x0080: /* KANA */
184*16d86563SAlexander Pyhalov ic1 = (unsigned char)e16;
185*16d86563SAlexander Pyhalov NPUT(ic1, "KANA");
186*16d86563SAlexander Pyhalov break;
187*16d86563SAlexander Pyhalov case 0x8000: /* CS3 */
188*16d86563SAlexander Pyhalov ic1 = e16tosj_x0213(e16, &ic2);
189*16d86563SAlexander Pyhalov NPUT(ic1, "PLANE2-1");
190*16d86563SAlexander Pyhalov NPUT(ic2, "PLANE2-2");
191*16d86563SAlexander Pyhalov break;
192*16d86563SAlexander Pyhalov }
193*16d86563SAlexander Pyhalov
194*16d86563SAlexander Pyhalov next:
195*16d86563SAlexander Pyhalov /*
196*16d86563SAlexander Pyhalov * One character successfully converted so update
197*16d86563SAlexander Pyhalov * values outside of this function's stack.
198*16d86563SAlexander Pyhalov */
199*16d86563SAlexander Pyhalov *inbuf = (char *)ip;
200*16d86563SAlexander Pyhalov *inbytesleft = ileft;
201*16d86563SAlexander Pyhalov *outbuf = op;
202*16d86563SAlexander Pyhalov *outbytesleft = oleft;
203*16d86563SAlexander Pyhalov }
204*16d86563SAlexander Pyhalov
205*16d86563SAlexander Pyhalov ret:
206*16d86563SAlexander Pyhalov
207*16d86563SAlexander Pyhalov DEBUGPRINTERROR
208*16d86563SAlexander Pyhalov
209*16d86563SAlexander Pyhalov /*
210*16d86563SAlexander Pyhalov * Return value for successful return is not defined by XPG
211*16d86563SAlexander Pyhalov * so return same as *inbytesleft as existing codes do.
212*16d86563SAlexander Pyhalov */
213*16d86563SAlexander Pyhalov return ((rv == (size_t)-1) ? rv : *inbytesleft);
214*16d86563SAlexander Pyhalov }
215