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