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 #include "japanese.h"
31 #include "jfp_iconv_unicode.h"
32
33 #define JFP_J2U_ICONV_X0213
34 #include "jfp_jis_to_ucs2.h"
35
36 void *
_icv_open(void)37 _icv_open(void)
38 {
39 return (_icv_open_unicode((size_t)0));
40 }
41
42 void
_icv_close(void * cd)43 _icv_close(void *cd)
44 {
45 _icv_close_unicode(cd);
46 return;
47 }
48
49 size_t
_icv_iconv(void * cd,char ** inbuf,size_t * inbytesleft,char ** outbuf,size_t * outbytesleft)50 _icv_iconv(void *cd, char **inbuf, size_t *inbytesleft,
51 char **outbuf, size_t *outbytesleft)
52 {
53 unsigned int u32; /* UTF-32 */
54 unsigned short e16; /* 16-bit EUC */
55 unsigned char ic1, ic2, ic3; /* 1st, 2nd, and 3rd bytes of a char */
56 size_t rv = (size_t)0; /* return value of this function */
57
58 unsigned char *ip;
59 size_t ileft;
60 char *op;
61 size_t oleft;
62
63 /*
64 * If inbuf and/or *inbuf are NULL, reset conversion descriptor
65 * and put escape sequence if needed.
66 */
67 if ((inbuf == NULL) || (*inbuf == NULL)) {
68 _icv_reset_unicode(cd);
69 return ((size_t)0);
70 }
71
72 ip = (unsigned char *)*inbuf;
73 ileft = *inbytesleft;
74 op = *outbuf;
75 oleft = *outbytesleft;
76
77 while (ileft != 0) {
78 NGET(ic1, "never fail here"); /* get 1st byte */
79
80 if (ISASC(ic1)) { /* CS0; 1 byte */
81 u32 = (unsigned int)_jfp_tbl_jisx0201roman_to_ucs2[ic1];
82 PUTU(u32, "CS0");
83 } else if (ISCS1(ic1)) { /* JIS X 0213 plane 1; 2 bytes */
84 NGET(ic2, "CS1-2");
85 if (ISCS1(ic2)) { /* 2nd byte check passed */
86 e16 = (ic1 << 8) | ic2;
87 u32 = (unsigned int)_jfp_tbl_jisx0208_to_ucs2[
88 (ic1 - 0xa1) * 94 + (ic2 - 0xa1)];
89 if (IFHISUR(u32)) {
90 u32 = _jfp_lookup_x0213_nonbmp(
91 e16, u32);
92 PUTU(u32, "CS1->NONBMP");
93 } else if (u32 == 0xffff) {
94 /* need to compose */
95 unsigned int u32_2;
96 u32 = _jfp_lookup_x0213_compose(
97 e16, &u32_2);
98 PUTU(u32, "CS1->CP1");
99 PUTU(u32_2, "CS1->CP2");
100 } else {
101 PUTU(u32, "CS1->BMP");
102 }
103 } else { /* 2nd byte check failed */
104 RETERROR(EILSEQ, "CS1-2")
105 }
106 } else if (ic1 == SS2) { /* JIS X 0201 Kana; 2 bytes */
107 NGET(ic2, "CS2-2");
108 if (ISCS2(ic2)) { /* 2nd byte check passed */
109 u32 = (unsigned int)
110 _jfp_tbl_jisx0201kana_to_ucs2[ic2 - 0xa1];
111 PUTU(u32, "CS2->Kana");
112 } else { /* 2nd byte check failed */
113 RETERROR(EILSEQ, "CS2-2")
114 }
115 } else if (ic1 == SS3) { /* JIS X 0213 plane 2; 3 bytes */
116 NGET(ic2, "CS3-2");
117 if (ISCS3(ic2)) { /* 2nd byte check passed */
118 NGET(ic3, "CS3-3");
119 if (ISCS3(ic3)) { /* 3rd byte check passed */
120 e16 = (ic2 << 8) | (ic3 & 0x7f);
121 u32 = (unsigned int)
122 _jfp_tbl_jisx0213p2_to_ucs2[
123 (ic2 - 0xa1) * 94 + (ic3 - 0xa1)];
124 if (IFHISUR(u32)) {
125 u32 = _jfp_lookup_x0213_nonbmp(
126 e16, u32);
127 PUTU(u32, "CS3->NONBMP");
128 } else {
129 PUTU(u32, "CS3->BMP");
130 }
131 } else { /* 3rd byte check failed */
132 RETERROR(EILSEQ, "CS3-3")
133 }
134 } else { /* 2nd byte check failed */
135 RETERROR(EILSEQ, "CS3-2")
136 }
137 } else if (ISC1CTRLEUC(ic1)) { /* C1 control; 1 byte */
138 u32 = ic1;
139 PUTU(u32, "E2BIG C1CTRL");
140 } else { /* 1st byte check failed */
141 RETERROR(EILSEQ, "CS?-1")
142 }
143
144 /*
145 * One character successfully converted so update
146 * values outside of this function's stack.
147 */
148 *inbuf = (char *)ip;
149 *inbytesleft = ileft;
150 *outbuf = op;
151 *outbytesleft = oleft;
152 }
153
154 ret:
155 DEBUGPRINTERROR
156
157 /*
158 * Return value for successful return is not defined by XPG
159 * so return same as *inbytesleft as existing codes do.
160 */
161 return ((rv == (size_t)-1) ? rv : *inbytesleft);
162 }
163