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