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
26 #include <stdlib.h>
27 #include <errno.h>
28 #include "ktable.h"
29 #include "nbyte_utf.h"
30
31
32 /**** _ I C V _ O P E N ****/
33
_icv_open()34 void* _icv_open()
35 {
36 _conv_desc* cd = (_conv_desc*)malloc(sizeof(_conv_desc));
37
38 if (cd == (_conv_desc*)NULL)
39 {
40 errno = ENOMEM;
41 return((void*)-1);
42 }
43
44 cd->cur_stat = 1;
45 cd->hbuf[1] = cd->hbuf[2] = cd->hbuf[3] = cd->hbuf[4] = '\0';
46 cd->cur_act = 0;
47
48 return((void*)cd);
49 } /* end of int _icv_open(). */
50
51
52 /**** _ I C V _ C L O S E ****/
53
_icv_close(_conv_desc * cd)54 void _icv_close(_conv_desc* cd)
55 {
56 if (!cd)
57 errno = EBADF;
58 else
59 free((void*)cd);
60 } /* end of void _icv_close(_conv_desc*). */
61
62
63 /**** _ I C V _ I C O N V ****/
64
_icv_iconv(_conv_desc * cd,char ** inbuf,size_t * inbufleft,char ** outbuf,size_t * outbufleft)65 size_t _icv_iconv(_conv_desc* cd, char** inbuf, size_t* inbufleft,
66 char** outbuf, size_t* outbufleft)
67 {
68 size_t ret_val = 0;
69 unsigned char* ib;
70 unsigned char* ob;
71 unsigned char* ibtail;
72 unsigned char* obtail;
73
74 if (!cd)
75 {
76 errno = EBADF;
77 return((size_t)-1);
78 }
79
80 if (!inbuf || !(*inbuf))
81 {
82 cd->cur_stat = 1;
83 cd->hbuf[1] = cd->hbuf[2] = cd->hbuf[3] = cd->hbuf[4] = '\0';
84 cd->cur_act = 0;
85 return((size_t)0);
86 }
87
88 ib = (unsigned char*)*inbuf;
89 ob = (unsigned char*)*outbuf;
90 ibtail = ib + *inbufleft;
91 obtail = ob + *outbufleft;
92
93 while (ib < ibtail)
94 {
95 int cur_input, action, state;
96 unsigned long ci, v, cf;
97 char result;
98 int input_conv(char);
99 unsigned short make_johap_code(int, char*);
100 extern char _johap_to_utf8(unsigned long*, unsigned long*,
101 unsigned long*, unsigned short);
102
103 cur_input = input_conv(*ib);
104 action = next_act[cd->cur_stat][cur_input];
105 state = next_stat[cd->cur_stat][cur_input];
106 if (action == 4)
107 {
108 if (ob >= obtail)
109 {
110 errno = E2BIG;
111 ret_val = (size_t)-1;
112 break;
113 }
114 *ob++ = *ib;
115 }
116 else if (action >= 5 && action <= 8)
117 cd->hbuf[action - 4] = *ib;
118 else if (action == 9)
119 {
120 ADD_CONVERTED_CODE(0, 0);
121 cd->hbuf[1] = *ib;
122 }
123 else if (action == 10)
124 {
125 ADD_CONVERTED_CODE(0, 0);
126 cd->hbuf[2] = *ib;
127 ADD_CONVERTED_CODE(0, 0);
128 }
129 else if (action == 11 || action == 12)
130 {
131 ADD_CONVERTED_CODE(0, 0);
132 }
133 else if (action == 13)
134 {
135 ADD_CONVERTED_CODE(0, 1);
136 *ob++ = *ib;
137 }
138 else if (action == 14)
139 {
140 register char c1 = cd->hbuf[2], c2 = *ib;
141
142 if (c1 == 'l' && c2 == 'b') /* _|_ && |- */
143 cd->hbuf[2] = 'm';
144 else if (c1 == 'l' && c2 == 'c') /* _|_ && H */
145 cd->hbuf[2] = 'n';
146 else if (c1 == 'l' && c2 == '|') /* _|_ && | */
147 cd->hbuf[2] = 'o';
148 else if (c1 == 's' && c2 == 'f') /* T && -| */
149 cd->hbuf[2] = 't';
150 else if (c1 == 's' && c2 == 'g') /* T && -|| */
151 cd->hbuf[2] = 'u';
152 else if (c1 == 's' && c2 == '|') /* T && | */
153 cd->hbuf[2] = 'v';
154 else if (c1 == 'z' && c2 == '|') /* __ && | */
155 cd->hbuf[2] = '{';
156 else
157 cd->hbuf[2] = *ib; /* Just in case. */
158 }
159 else if (action == 15)
160 {
161 cd->hbuf[2] = *ib;
162 ADD_CONVERTED_CODE(0, 0);
163 }
164 else if (action == 16)
165 {
166 ADD_CONVERTED_CODE(0, 0);
167 }
168 else if (action == 17)
169 {
170 ADD_CONVERTED_CODE(1, 0);
171 cd->hbuf[2] = *ib;
172 }
173 cd->cur_act = action;
174 cd->cur_stat = state;
175 ib++;
176 }
177
178 *inbuf = (char*)ib;
179 *inbufleft = ibtail - ib;
180 *outbuf = (char*)ob;
181 *outbufleft = obtail - ob;
182
183 return(ret_val);
184 } /* end of size_t _icv_iconv(_conv_desc*, char**, size_t*, char**, size_t*).*/
185
186
187 /**** I N P U T _ C O N V ****/
188
input_conv(char c)189 int input_conv(char c)
190 {
191 switch (c)
192 {
193 case 'H': /* dd */
194 case 'S': /* bb */
195 case 'Y': /* jj */
196 return(1);
197
198 case 'A': /* g */
199 return(2);
200
201 case 'D': /* n */
202 return(3);
203
204 case 'I': /* r */
205 return(4);
206
207 case 'R': /* b */
208 return(5);
209
210 case 'B': /* gg */
211 case 'G': /* d */
212 case 'V': /* ss */
213 case 'W': /* o */
214 case 'Z': /* ch */
215 case '[': /* k */
216 return(6);
217
218 case 'U': /* s */
219 return(7);
220
221 case 'X': /* j */
222 return(8);
223
224 case '^': /* h */
225 return(9);
226
227 case 'Q': /* m */
228 case ']': /* p */
229 case '\\': /* t */
230 return(10);
231
232 case 'k': /* =|| */
233 case 'd': /* |= */
234 case 'e': /* |=| */
235 case 'j': /* =| */
236 case 'r': /* _||_ */
237 case 'w': /* TT */
238 return(11);
239
240 case 'b': /* |- */
241 case 'c': /* H */
242 return(12);
243
244 case 'f': /* -| */
245 case 'g': /* -|| */
246 return(13);
247
248 case '|': /* | */
249 return(14);
250
251 case 'l': /* _|_ */
252 return(15);
253
254 case 's': /* T */
255 return(16);
256
257 case 'z': /* __ */
258 return(17);
259
260 case '\016':
261 return(18);
262
263 case '\017':
264 case '\024':
265 return(19);
266
267 default:
268 return(20);
269 }
270 } /* end of int input_conv(char). */
271
272
273 /**** M A K E _ J O H A P _ C O D E ****/
274
make_johap_code(int n,char * temp)275 unsigned short make_johap_code(int n, char* temp)
276 {
277 register unsigned short code = 0;
278 char save ='\0';
279
280 if (n == 1)
281 {
282 if (temp[4] == '\0')
283 {
284 save = temp[3];
285 temp[3] = '\0';
286 }
287 else
288 {
289 save = temp[4];
290 temp[4] = '\0';
291 }
292 }
293
294 code = (temp[1] >= 'A' && temp[1] <= '^') ?
295 (unsigned short)X32_19[temp[1] - '@']
296 : (unsigned short)9;
297 code = (code << 5) | (unsigned short)((temp[2] >= 'b' &&
298 temp[2] <= '|') ? X32_21[temp[2] - '`']
299 : 1);
300 code = (code << 5) | (unsigned short)((temp[3] >= 'A' &&
301 temp[3] <= '^') ? X32_28[temp[3] - '@']
302 : 1);
303
304 if (temp[4] >= 'A')
305 {
306 if (temp[3] == 'A' && temp[4] == 'U') /* gs */
307 code += 2;
308 else if (temp[3] == 'D' && temp[4] == 'X') /* nj */
309 code++;
310 else if (temp[3] == 'D' && temp[4] == '^') /* nh */
311 code += 2;
312 else if (temp[3] == 'I' && temp[4] == 'A') /* rg */
313 code++;
314 else if (temp[3] == 'I' && temp[4] == 'Q') /* rm */
315 code += 2;
316 else if (temp[3] == 'I' && temp[4] == 'R') /* rb */
317 code += 3;
318 else if (temp[3] == 'I' && temp[4] == 'U') /* rs */
319 code += 4;
320 else if (temp[3] == 'I' && temp[4] == '\\') /* rt */
321 code += 5;
322 else if (temp[3] == 'I' && temp[4] == ']') /* rp */
323 code += 6;
324 else if (temp[3] == 'I' && temp[4] == '^') /* rh */
325 code += 7;
326 else if (temp[3] == 'R' && temp[4] == 'U') /* bs */
327 code++;
328 else if (temp[3] == 'U' && temp[4] == 'U') /* ss */
329 code++;
330 }
331
332 temp[1] = (n == 1) ? save : '\0';
333 temp[2] = temp[3] = temp[4] = '\0';
334 return(code | 0x8000);
335 } /* end of unsigned short make_johap_code(int, char*). */
336