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