xref: /titanic_53/usr/src/lib/iconv_modules/zh/common/HZ-GB-2312%zh_CN.euc.c (revision 91e1e26ac6a73ce959289cf7d3d96c4baedbe0b8)
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 (c) 1994 by Sun Microsystems, Inc.
23  */
24 
25 #include <stdio.h>
26 #include <stdlib.h>
27 #include <errno.h>
28 
29 #define SI      0x0f
30 #define SO      0x0e
31 #define ESC     0x1b
32 #define	MSB	0x80
33 
34 #define NON_ID_CHAR '_'
35 
36 enum	_GSTATE { G0, G1, G2, G3, G4, G5};
37 
38 
39 typedef struct _icv_state {
40 	char	_lastc;
41 	short	_gstate;
42 } _iconv_st;
43 
44 int
45 hz2gb(char in_byte1, char in_byte2, char *buf, int buflen);
46 
47 /*
48  * Open; called from iconv_open()
49  */
50 void *
_icv_open()51 _icv_open()
52 {
53 	_iconv_st *st;
54 
55 	if ((st = (_iconv_st *)malloc(sizeof(_iconv_st))) == NULL) {
56 		errno = ENOMEM;
57 		return ((void *) -1);
58 	}
59 
60 	st->_gstate = G0;
61 	return ((void *)st);
62 }
63 
64 
65 /*
66  * Close; called from iconv_close()
67  */
68 void
_icv_close(_iconv_st * st)69 _icv_close(_iconv_st *st)
70 {
71 	if (st == NULL)
72 		errno = EBADF;
73 	else
74 		free(st);
75 }
76 
77 
78 /*
79  * Actual conversion; called from iconv()
80  */
81 /*=======================================================================
82  *
83  *         ~          {     Chinese
84  * +-> G0 -----> G1 ----> G2 ----> G3
85  * |   | ascii   | ascii  |~}      |
86  * +----------------------+--------+
87  *=======================================================================*/
88 size_t
_icv_iconv(_iconv_st * st,char ** inbuf,size_t * inbytesleft,char ** outbuf,size_t * outbytesleft)89 _icv_iconv(_iconv_st *st, char **inbuf, size_t*inbytesleft,
90 			char **outbuf, size_t*outbytesleft)
91 {
92 	int	n;
93 
94 	if (st == NULL) {
95 		errno = EBADF;
96 		return -1;
97 	}
98 	if (inbuf == NULL || *inbuf == NULL) { /* Reset request. */
99 		st->_gstate = G0;
100 		return 0;
101 	}
102 
103 	errno = 0;
104 
105 	while (*inbytesleft > 0 && *outbytesleft > 0) {
106 	    switch (st->_gstate) {
107 	    case G0:
108 		if ( **inbuf == '~' ) {
109 		    st->_gstate = G1;
110 		} else if (!((**inbuf) & MSB)) {	/* ASCII */
111 		    **outbuf = **inbuf;
112 		    (*outbuf)++, (*outbytesleft)--;
113 		} else {
114 		    errno = EILSEQ;
115 		    return (size_t)-1;
116 		}
117 		break;
118 	    case G1:
119 		if ( **inbuf == '{' ) {
120 		    st->_gstate = G2;
121 		} else if (**inbuf == '~') {
122 		    **outbuf = '~';
123 		    (*outbuf)++, (*outbytesleft)--;
124 		    st->_gstate = G0;
125 		} else {
126 		    errno = EILSEQ;
127 		    return -1;
128 		}
129 		break;
130 	    case G2:
131 		if ( **inbuf == '~' ) {
132 		    st->_gstate = G4;
133 		} else {
134 		    st->_lastc = **inbuf;
135 		    st->_gstate = G3;
136 		}
137 		break;
138 	    case G3:
139 		n = hz2gb(st->_lastc, **inbuf, *outbuf, *outbytesleft);
140 		if (n > 0) {
141 		    (*outbuf) += n, (*outbytesleft) -= n;
142 		} else {
143 		    errno = E2BIG;
144 		    return -1;
145 		}
146 		st->_gstate = G2;
147 		break;
148 	    case G4:
149 		if ( **inbuf == '}' ) {
150 		    st->_gstate = G0;
151 		} else {
152 		    errno = EILSEQ;
153 		    return -1;
154 		}
155 
156 		break;
157 	    }
158 
159 	    (*inbuf)++, (*inbytesleft)--;
160 	    if (errno)
161 		return -1;
162 	}
163 
164 	if ( st->_gstate != G0 && *inbytesleft == 0 ) {
165 	    errno = EINVAL;
166 	    return (size_t)-1;
167 	}
168 
169 	if (*inbytesleft > 0 && *outbytesleft == 0) {
170 		errno = E2BIG;
171 		return -1;
172 	}
173 	return (*inbytesleft);
174 }
175 
176 
177 int
hz2gb(in_byte1,in_byte2,buf,buflen)178 hz2gb(in_byte1, in_byte2, buf, buflen)
179 char	in_byte1, in_byte2;
180 char	*buf;
181 int	buflen;
182 {
183 
184 	if ( buflen < 2 )
185 	    return 0;
186 	*buf = in_byte1 | MSB;
187 	*(buf+1) = in_byte2 | MSB;
188 	return 2;
189 }
190