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 1994-2003 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
24 */
25
26 #include <stdio.h>
27 #include <stdlib.h>
28 #include <errno.h>
29 #include <euc.h>
30 #define JFP_ICONV_STATELESS
31 #include "japanese.h"
32
33 void *
_icv_open(void)34 _icv_open(void)
35 {
36 return (_icv_open_stateless());
37 }
38
39 void
_icv_close(void * cd)40 _icv_close(void *cd)
41 {
42 _icv_close_stateless(cd);
43 return;
44 }
45
46 size_t
_icv_iconv(void * cd,char ** inbuf,size_t * inbytesleft,char ** outbuf,size_t * outbytesleft)47 _icv_iconv(void *cd, char **inbuf, size_t *inbytesleft,
48 char **outbuf, size_t *outbytesleft)
49 {
50 int stat;
51 unsigned char *ip, ic;
52 char *op;
53 size_t ileft, oleft;
54 size_t retval;
55
56 stat = ST_INIT;
57
58 /*
59 * If inbuf and/or *inbuf are NULL, reset conversion descriptor
60 * and put escape sequence if needed.
61 */
62 if ((inbuf == NULL) || (*inbuf == NULL)) {
63 /* nothing to do here for this module */
64 return ((size_t)0);
65 }
66
67 ip = (unsigned char *)*inbuf;
68 op = *outbuf;
69 ileft = *inbytesleft;
70 oleft = *outbytesleft;
71
72 /*
73 * Main loop; basically 1 loop per 1 input byte
74 */
75
76 while ((int)ileft > 0) {
77 GET(ic);
78 if (stat == ST_INCS1) {
79 PUT(((ic & CMASK) - 0x20));
80 stat = ST_INIT;
81 continue;
82 } else if (stat == ST_INCS3) {
83 PUT(((ic & CMASK) - 0x20));
84 GET(ic);
85 PUT(((ic & CMASK) - 0x20));
86 stat = ST_INIT;
87 continue;
88 }
89 if (ISASC((int)ic)) { /* ASCII */
90 errno = EILSEQ;
91 retval = (size_t)ERR_RETURN;
92 goto ret;
93 } else if (ISCS1(ic)) { /* CS_1 starts */
94 if ((int)ileft > 0) {
95 if (ISCS1(ic) && ISCS1(*ip)) {
96 if (oleft < JISW1) {
97 UNGET();
98 errno = E2BIG;
99 retval = (size_t)ERR_RETURN;
100 goto ret;
101 }
102 stat = ST_INCS1;
103 PUT(((ic & CMASK) - 0x20));
104 continue;
105 } else {
106 errno = EILSEQ;
107 retval = (size_t)ERR_RETURN;
108 goto ret;
109 }
110 } else { /* input fragment of Kanji */
111 UNGET();
112 errno = EINVAL;
113 retval = (size_t)ERR_RETURN;
114 goto ret;
115 }
116 } else if (ic == SS2) { /* Kana starts */
117 errno = EILSEQ;
118 retval = (size_t)ERR_RETURN;
119 goto ret;
120 } else if (ic == SS3) { /* JISX0212 starts */
121 if (ileft >= EUCW3) {
122 if (ISCS3(*ip) && ISCS3(*(ip + 1))) {
123 if (oleft < JISW3) {
124 UNGET();
125 errno = E2BIG;
126 retval = (size_t)ERR_RETURN;
127 goto ret;
128 }
129 stat = ST_INCS3;
130 continue;
131 } else {
132 errno = EILSEQ;
133 retval = (size_t)ERR_RETURN;
134 goto ret;
135 }
136 } else { /* input fragment of JISX0212 */
137 UNGET();
138 errno = EINVAL;
139 retval = (size_t)ERR_RETURN;
140 goto ret;
141 }
142 } else {
143 UNGET();
144 errno = EILSEQ;
145 retval = (size_t)ERR_RETURN;
146 goto ret;
147 }
148 }
149 retval = ileft;
150 ret:
151 *inbuf = (char *)ip;
152 *inbytesleft = ileft;
153 ret2:
154 *outbuf = op;
155 *outbytesleft = oleft;
156
157 return (retval);
158 }
159