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 AND PERMISSION NOTICE
23 *
24 * Copyright (c) 1991-2005 Unicode, Inc. All rights reserved. Distributed
25 * under the Terms of Use in http://www.unicode.org/copyright.html.
26 *
27 * This file has been modified by Sun Microsystems, Inc.
28 */
29 /*
30 * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
31 * Use is subject to license terms.
32 */
33
34
35 #include <stdio.h>
36 #include <stdlib.h>
37 #include <errno.h>
38 #include <euc.h>
39
40 #include "japanese.h"
41 #include "jfp_iconv_unicode.h"
42
43 #ifdef JAVA_CONV_COMPAT
44 #define JFP_U2E_ICONV_JAVA
45 #elif JFP_ICONV_MS932
46 #define JFP_U2E_ICONV_MS932
47 #else
48 #define JFP_U2E_ICONV
49 #endif
50 #include "jfp_ucs2_to_euc16.h"
51
52 #define DEF_SINGLE '?'
53
54 static unsigned short lookuptbl(unsigned short);
55
56 void *
_icv_open(void)57 _icv_open(void)
58 {
59 return (_icv_open_unicode((size_t)0));
60 }
61
62 void
_icv_close(void * cd)63 _icv_close(void *cd)
64 {
65 _icv_close_unicode(cd);
66 return;
67 }
68
69 size_t
_icv_iconv(void * cd,char ** inbuf,size_t * inbytesleft,char ** outbuf,size_t * outbytesleft)70 _icv_iconv(void *cd, char **inbuf, size_t *inbytesleft,
71 char **outbuf, size_t *outbytesleft)
72 {
73 unsigned char ic;
74 size_t rv = (size_t)0;
75 unsigned int ucs4;
76 unsigned short euc16;
77 unsigned short dest;
78
79 unsigned char *ip;
80 size_t ileft;
81 char *op;
82 size_t oleft;
83
84 /*
85 * If inbuf and/or *inbuf are NULL, reset conversion descriptor
86 * and put escape sequence if needed.
87 */
88 if ((inbuf == NULL) || (*inbuf == NULL)) {
89 _icv_reset_unicode(cd);
90 return ((size_t)0);
91 }
92
93 ip = (unsigned char *)*inbuf;
94 ileft = *inbytesleft;
95 op = *outbuf;
96 oleft = *outbytesleft;
97
98 while (ileft != 0) {
99 GETU(&ucs4);
100
101 if (ucs4 > 0xffff) {
102 /* non-BMP */
103 NPUT((unsigned char)DEF_SINGLE, "non-BMP(replaced)");
104 } else {
105 euc16 = _jfp_ucs2_to_euc16((unsigned short)ucs4);
106
107 switch (euc16 & 0x8080) {
108 case 0x0000: /* CS0 */
109 if (ISC1CTRL((unsigned char)euc16)) {
110 NPUT((unsigned char)'?',
111 "CS0-C1CTRL(replaced)")
112 } else {
113 ic = (unsigned char)euc16;
114 NPUT(ic, "CS0-1");
115 }
116 break;
117 case 0x8080: /* CS1 */
118 ic = (unsigned short)((euc16 >> 8) & 0x7f);
119 NPUT(jis208tosj1[ic], "CS1-1");
120 /*
121 * for even number row (Ku), add 0x80 to
122 * look latter half of jistosj2[] array
123 */
124 ic = (unsigned char)((euc16 & 0x7f)
125 + (((ic % 2) == 0) ? 0x80 : 0x00));
126 NPUT(jistosj2[ic], "CS1-2");
127 break;
128 case 0x0080: /* CS2 */
129 ic = (unsigned char)euc16;
130 NPUT(ic, "CS2-1");
131 break;
132 case 0x8000: /* CS3 */
133 ic = (unsigned short)((euc16 >> 8) & 0x7f);
134 if (euc16 == 0xa271) {
135 /* NUMERO SIGN */
136 NPUT(0x87, "CS3-NUMERO-1");
137 NPUT(0x82, "CS3-NUMERO-2");
138 } else if (ic < 0x75) { /* check if IBM VDC */
139 dest = lookuptbl(euc16 & 0x7f7f);
140 if (dest == 0xffff) {
141 NPUT((unsigned char)'?',
142 "CS3-NoSJIS(replaced)")
143 } else {
144 #ifdef JAVA_CONV_COMPAT
145 NPUT((unsigned char)'?',
146 "CS3-IBM(replaced)")
147 #else /* !JAVA_CONV_COMPAT */
148 /* avoid putting NUL ('\0') */
149 if (dest > 0xff) {
150 NPUT((dest >> 8) & 0xff,
151 "CS3-IBM-1");
152 NPUT(dest & 0xff,
153 "CS3-IBM-2");
154 } else {
155 NPUT(dest & 0xff,
156 "CS3-IBM-1");
157 }
158 #endif /* JAVA_CONV_COMPAT */
159 }
160 } else {
161 NPUT(jis212tosj1[ic], "CS3-1");
162 /*
163 * for even number row (Ku), add 0x80 to
164 * look latter half of jistosj2[] array
165 */
166 ic = (unsigned short)((euc16 & 0x7f)
167 + (((ic % 2) == 0) ?
168 0x80 : 0x00));
169 NPUT(jistosj2[ic], "CS3-2");
170 }
171 break;
172 }
173 }
174
175 next:
176 /*
177 * One character successfully converted so update
178 * values outside of this function's stack.
179 */
180 *inbuf = (char *)ip;
181 *inbytesleft = ileft;
182 *outbuf = op;
183 *outbytesleft = oleft;
184 }
185
186 ret:
187
188 #if defined(DEBUG)
189 if (rv == (size_t)-1) {
190 fprintf(stderr, "DEBUG: errno=%d: %s\n", errno, debugmsg);
191 }
192 #endif /* DEBUG */
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
201 /*
202 * lookuptbl()
203 * Return the index number if its index-ed number
204 * is the same as dest value.
205 */
206 static unsigned short
lookuptbl(unsigned short dest)207 lookuptbl(unsigned short dest)
208 {
209 unsigned short tmp;
210 int i;
211 int sz = (sizeof (sjtoibmext) / sizeof (sjtoibmext[0]));
212
213 for (i = 0; i < sz; i++) {
214 tmp = (sjtoibmext[i] & 0x7f7f);
215 if (tmp == dest)
216 return ((i + 0xfa40 + ((i / 0xc0) * 0x40)));
217 }
218 return (0x3f);
219 }
220