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 CS0_SEQ2 0x28 /* ( */
40 #define CS0_SEQ3 0x42 /* B */
41
42 #define CS1_SEQ2 0x24 /* $ */
43 #define CS1_SEQ3 0x28 /* ( */
44 #define CS1_SEQ4 0x51 /* Q */
45
46 #define CS3_SEQ2 0x24 /* $ */
47 #define CS3_SEQ3 0x28 /* ( */
48 #define CS3_SEQ4 0x50 /* P */
49
50 struct _icv_state {
51 int _st_cset;
52 };
53
54 void *
_icv_open(void)55 _icv_open(void)
56 {
57 void *cd;
58 struct _icv_state *st;
59
60 cd = _icv_open_unicode(sizeof (struct _icv_state));
61
62 if (cd != NULL) {
63 st = (struct _icv_state *)(_icv_get_ext(cd));
64 st->_st_cset = CS_0;
65 }
66
67 return (cd);
68 }
69
70 void
_icv_close(void * cd)71 _icv_close(void *cd)
72 {
73 _icv_close_unicode(cd);
74 return;
75 }
76
77 size_t
_icv_iconv(void * cd,char ** inbuf,size_t * inbytesleft,char ** outbuf,size_t * outbytesleft)78 _icv_iconv(void *cd, char **inbuf, size_t *inbytesleft,
79 char **outbuf, size_t *outbytesleft)
80 {
81 unsigned int u32; /* UTF-32 */
82 unsigned short e16; /* 16-bit EUC */
83 unsigned char ic;
84 size_t rv = (size_t)0;
85
86 struct _icv_state *st = (struct _icv_state *)(_icv_get_ext(cd));
87 int cset;
88
89 unsigned char *ip;
90 size_t ileft;
91 char *op;
92 size_t oleft;
93
94 /*
95 * If inbuf and/or *inbuf are NULL, reset conversion descriptor
96 * and put escape sequence if needed.
97 */
98 if ((inbuf == NULL) || (*inbuf == NULL)) {
99 if (st->_st_cset != CS_0) {
100 if ((outbuf != NULL) && (*outbuf != NULL)
101 && (outbytesleft != NULL)) {
102 op = (char *)*outbuf;
103 oleft = *outbytesleft;
104 NPUT(ESC, "RESET-SEQ-ESC");
105 NPUT(CS0_SEQ2, "RESET-SEQ2");
106 NPUT(CS0_SEQ3, "RESET-SEQ3");
107 *outbuf = (char *)op;
108 *outbytesleft = oleft;
109 }
110 st->_st_cset = CS_0;
111 _icv_reset_unicode(cd);
112 }
113 return ((size_t)0);
114 }
115
116 cset = st->_st_cset;
117
118 ip = (unsigned char *)*inbuf;
119 ileft = *inbytesleft;
120 op = *outbuf;
121 oleft = *outbytesleft;
122
123 while (ileft != 0) {
124 GETU(&u32)
125
126 e16 = _jfp_u32_to_euc16(u32);
127
128 switch (e16 & 0x8080) {
129 case 0x0000: /* CS0 */
130 if (cset != CS_0) {
131 NPUT(ESC, "CS0-SEQ-ESC");
132 NPUT(CS0_SEQ2, "CS0-SEQ2");
133 NPUT(CS0_SEQ3, "CS0-SEQ3");
134 cset = CS_0;
135 }
136 ic = (unsigned char)e16;
137 NPUT(ic, "CS0");
138 break;
139 case 0x8080: /* CS1 */
140 if (cset != CS_1) {
141 NPUT(ESC, "CS1-SEQ-ESC");
142 NPUT(CS1_SEQ2, "CS1-SEQ2");
143 NPUT(CS1_SEQ3, "CS1-SEQ3");
144 NPUT(CS1_SEQ4, "CS1-SEQ4");
145 cset = CS_1;
146 }
147 ic = (unsigned char)((e16 >> 8) & 0x7f);
148 NPUT(ic, "CS1-1");
149 ic = (unsigned char)(e16 & 0x7f);
150 NPUT(ic, "CS1-2");
151 break;
152 case 0x0080: /* CS2 */
153 if (cset != CS_0) {
154 NPUT(ESC, "CS2-REPL-SEQ-ESC");
155 NPUT(CS0_SEQ2, "CS2-REPL-SEQ2");
156 NPUT(CS0_SEQ3, "CS2-REPL-SEQ3");
157 cset = CS_0;
158 }
159 ic = DEF_SINGLE;
160 NPUT(ic, "CS2-REPL");
161 break;
162 case 0x8000: /* CS3 */
163 if (cset != CS_3) {
164 NPUT(ESC, "CS3-SEQ-ESC");
165 NPUT(CS3_SEQ2, "CS3-SEQ2");
166 NPUT(CS3_SEQ3, "CS3-SEQ3");
167 NPUT(CS3_SEQ4, "CS3-SEQ4");
168 cset = CS_3;
169 }
170 ic = (unsigned char)((e16 >> 8) & 0x7f);
171 NPUT(ic, "CS3-1");
172 ic = (unsigned char)(e16 & 0x7f);
173 NPUT(ic, "CS3-2");
174 break;
175 }
176
177 next:
178 /*
179 * One character successfully converted so update
180 * values outside of this function's stack.
181 */
182 *inbuf = (char *)ip;
183 *inbytesleft = ileft;
184 *outbuf = op;
185 *outbytesleft = oleft;
186
187 st->_st_cset = cset;
188 }
189
190 ret:
191
192 DEBUGPRINTERROR
193
194 /*
195 * Return value for successful return is not defined by XPG
196 * so return same as *inbytesleft as existing codes do.
197 */
198 return ((rv == (size_t)-1) ? rv : *inbytesleft);
199 }
200