1*aef5731fSOliver Tappe /*
2*aef5731fSOliver Tappe * Copyright (C) 1999-2001 Free Software Foundation, Inc.
3*aef5731fSOliver Tappe * This file is part of the GNU LIBICONV Library.
4*aef5731fSOliver Tappe *
5*aef5731fSOliver Tappe * The GNU LIBICONV Library is free software; you can redistribute it
6*aef5731fSOliver Tappe * and/or modify it under the terms of the GNU Library General Public
7*aef5731fSOliver Tappe * License as published by the Free Software Foundation; either version 2
8*aef5731fSOliver Tappe * of the License, or (at your option) any later version.
9*aef5731fSOliver Tappe *
10*aef5731fSOliver Tappe * The GNU LIBICONV Library is distributed in the hope that it will be
11*aef5731fSOliver Tappe * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
12*aef5731fSOliver Tappe * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13*aef5731fSOliver Tappe * Library General Public License for more details.
14*aef5731fSOliver Tappe *
15*aef5731fSOliver Tappe * You should have received a copy of the GNU Library General Public
16*aef5731fSOliver Tappe * License along with the GNU LIBICONV Library; see the file COPYING.LIB.
17*aef5731fSOliver Tappe * If not, write to the Free Software Foundation, Inc., 51 Franklin Street,
18*aef5731fSOliver Tappe * Fifth Floor, Boston, MA 02110-1301, USA.
19*aef5731fSOliver Tappe */
20*aef5731fSOliver Tappe
21*aef5731fSOliver Tappe /*
22*aef5731fSOliver Tappe * ISO-2022-CN-EXT
23*aef5731fSOliver Tappe */
24*aef5731fSOliver Tappe
25*aef5731fSOliver Tappe /* Specification: RFC 1922 */
26*aef5731fSOliver Tappe
27*aef5731fSOliver Tappe #define ESC 0x1b
28*aef5731fSOliver Tappe #define SO 0x0e
29*aef5731fSOliver Tappe #define SI 0x0f
30*aef5731fSOliver Tappe
31*aef5731fSOliver Tappe /*
32*aef5731fSOliver Tappe * The state is composed of one of the following values
33*aef5731fSOliver Tappe */
34*aef5731fSOliver Tappe #define STATE_ASCII 0
35*aef5731fSOliver Tappe #define STATE_TWOBYTE 1
36*aef5731fSOliver Tappe /*
37*aef5731fSOliver Tappe * and one of the following values, << 8
38*aef5731fSOliver Tappe */
39*aef5731fSOliver Tappe #define STATE2_NONE 0
40*aef5731fSOliver Tappe #define STATE2_DESIGNATED_GB2312 1
41*aef5731fSOliver Tappe #define STATE2_DESIGNATED_CNS11643_1 2
42*aef5731fSOliver Tappe #define STATE2_DESIGNATED_ISO_IR_165 3
43*aef5731fSOliver Tappe /*
44*aef5731fSOliver Tappe * and one of the following values, << 16
45*aef5731fSOliver Tappe */
46*aef5731fSOliver Tappe #define STATE3_NONE 0
47*aef5731fSOliver Tappe #define STATE3_DESIGNATED_CNS11643_2 1
48*aef5731fSOliver Tappe /*
49*aef5731fSOliver Tappe * and one of the following values, << 24
50*aef5731fSOliver Tappe */
51*aef5731fSOliver Tappe #define STATE4_NONE 0
52*aef5731fSOliver Tappe #define STATE4_DESIGNATED_CNS11643_3 1
53*aef5731fSOliver Tappe #define STATE4_DESIGNATED_CNS11643_4 2
54*aef5731fSOliver Tappe #define STATE4_DESIGNATED_CNS11643_5 3
55*aef5731fSOliver Tappe #define STATE4_DESIGNATED_CNS11643_6 4
56*aef5731fSOliver Tappe #define STATE4_DESIGNATED_CNS11643_7 5
57*aef5731fSOliver Tappe
58*aef5731fSOliver Tappe #define SPLIT_STATE \
59*aef5731fSOliver Tappe unsigned int state1 = state & 0xff, state2 = (state >> 8) & 0xff, state3 = (state >> 16) & 0xff, state4 = state >> 24
60*aef5731fSOliver Tappe #define COMBINE_STATE \
61*aef5731fSOliver Tappe state = (state4 << 24) | (state3 << 16) | (state2 << 8) | state1
62*aef5731fSOliver Tappe
63*aef5731fSOliver Tappe static int
iso2022_cn_ext_mbtowc(conv_t conv,ucs4_t * pwc,const unsigned char * s,int n)64*aef5731fSOliver Tappe iso2022_cn_ext_mbtowc (conv_t conv, ucs4_t *pwc, const unsigned char *s, int n)
65*aef5731fSOliver Tappe {
66*aef5731fSOliver Tappe state_t state = conv->istate;
67*aef5731fSOliver Tappe SPLIT_STATE;
68*aef5731fSOliver Tappe int count = 0;
69*aef5731fSOliver Tappe unsigned char c;
70*aef5731fSOliver Tappe for (;;) {
71*aef5731fSOliver Tappe c = *s;
72*aef5731fSOliver Tappe if (c == ESC) {
73*aef5731fSOliver Tappe if (n < count+4)
74*aef5731fSOliver Tappe goto none;
75*aef5731fSOliver Tappe if (s[1] == '$') {
76*aef5731fSOliver Tappe if (s[2] == ')') {
77*aef5731fSOliver Tappe if (s[3] == 'A') {
78*aef5731fSOliver Tappe state2 = STATE2_DESIGNATED_GB2312;
79*aef5731fSOliver Tappe s += 4; count += 4;
80*aef5731fSOliver Tappe if (n < count+1)
81*aef5731fSOliver Tappe goto none;
82*aef5731fSOliver Tappe continue;
83*aef5731fSOliver Tappe }
84*aef5731fSOliver Tappe if (s[3] == 'G') {
85*aef5731fSOliver Tappe state2 = STATE2_DESIGNATED_CNS11643_1;
86*aef5731fSOliver Tappe s += 4; count += 4;
87*aef5731fSOliver Tappe if (n < count+1)
88*aef5731fSOliver Tappe goto none;
89*aef5731fSOliver Tappe continue;
90*aef5731fSOliver Tappe }
91*aef5731fSOliver Tappe if (s[3] == 'E') {
92*aef5731fSOliver Tappe state2 = STATE2_DESIGNATED_ISO_IR_165;
93*aef5731fSOliver Tappe s += 4; count += 4;
94*aef5731fSOliver Tappe if (n < count+1)
95*aef5731fSOliver Tappe goto none;
96*aef5731fSOliver Tappe continue;
97*aef5731fSOliver Tappe }
98*aef5731fSOliver Tappe }
99*aef5731fSOliver Tappe if (s[2] == '*') {
100*aef5731fSOliver Tappe if (s[3] == 'H') {
101*aef5731fSOliver Tappe state3 = STATE3_DESIGNATED_CNS11643_2;
102*aef5731fSOliver Tappe s += 4; count += 4;
103*aef5731fSOliver Tappe if (n < count+1)
104*aef5731fSOliver Tappe goto none;
105*aef5731fSOliver Tappe continue;
106*aef5731fSOliver Tappe }
107*aef5731fSOliver Tappe }
108*aef5731fSOliver Tappe if (s[2] == '+') {
109*aef5731fSOliver Tappe if (s[3] == 'I') {
110*aef5731fSOliver Tappe state4 = STATE4_DESIGNATED_CNS11643_3;
111*aef5731fSOliver Tappe s += 4; count += 4;
112*aef5731fSOliver Tappe if (n < count+1)
113*aef5731fSOliver Tappe goto none;
114*aef5731fSOliver Tappe continue;
115*aef5731fSOliver Tappe }
116*aef5731fSOliver Tappe if (s[3] == 'J') {
117*aef5731fSOliver Tappe state4 = STATE4_DESIGNATED_CNS11643_4;
118*aef5731fSOliver Tappe s += 4; count += 4;
119*aef5731fSOliver Tappe if (n < count+1)
120*aef5731fSOliver Tappe goto none;
121*aef5731fSOliver Tappe continue;
122*aef5731fSOliver Tappe }
123*aef5731fSOliver Tappe if (s[3] == 'K') {
124*aef5731fSOliver Tappe state4 = STATE4_DESIGNATED_CNS11643_5;
125*aef5731fSOliver Tappe s += 4; count += 4;
126*aef5731fSOliver Tappe if (n < count+1)
127*aef5731fSOliver Tappe goto none;
128*aef5731fSOliver Tappe continue;
129*aef5731fSOliver Tappe }
130*aef5731fSOliver Tappe if (s[3] == 'L') {
131*aef5731fSOliver Tappe state4 = STATE4_DESIGNATED_CNS11643_6;
132*aef5731fSOliver Tappe s += 4; count += 4;
133*aef5731fSOliver Tappe if (n < count+1)
134*aef5731fSOliver Tappe goto none;
135*aef5731fSOliver Tappe continue;
136*aef5731fSOliver Tappe }
137*aef5731fSOliver Tappe if (s[3] == 'M') {
138*aef5731fSOliver Tappe state4 = STATE4_DESIGNATED_CNS11643_7;
139*aef5731fSOliver Tappe s += 4; count += 4;
140*aef5731fSOliver Tappe if (n < count+1)
141*aef5731fSOliver Tappe goto none;
142*aef5731fSOliver Tappe continue;
143*aef5731fSOliver Tappe }
144*aef5731fSOliver Tappe }
145*aef5731fSOliver Tappe }
146*aef5731fSOliver Tappe if (s[1] == 'N') {
147*aef5731fSOliver Tappe switch (state3) {
148*aef5731fSOliver Tappe case STATE3_NONE:
149*aef5731fSOliver Tappe return RET_ILSEQ;
150*aef5731fSOliver Tappe case STATE3_DESIGNATED_CNS11643_2:
151*aef5731fSOliver Tappe if (s[2] < 0x80 && s[3] < 0x80) {
152*aef5731fSOliver Tappe int ret = cns11643_2_mbtowc(conv,pwc,s+2,2);
153*aef5731fSOliver Tappe if (ret == RET_ILSEQ)
154*aef5731fSOliver Tappe return RET_ILSEQ;
155*aef5731fSOliver Tappe if (ret != 2) abort();
156*aef5731fSOliver Tappe COMBINE_STATE;
157*aef5731fSOliver Tappe conv->istate = state;
158*aef5731fSOliver Tappe return count+4;
159*aef5731fSOliver Tappe } else
160*aef5731fSOliver Tappe return RET_ILSEQ;
161*aef5731fSOliver Tappe default: abort();
162*aef5731fSOliver Tappe }
163*aef5731fSOliver Tappe }
164*aef5731fSOliver Tappe if (s[1] == 'O') {
165*aef5731fSOliver Tappe switch (state4) {
166*aef5731fSOliver Tappe case STATE4_NONE:
167*aef5731fSOliver Tappe return RET_ILSEQ;
168*aef5731fSOliver Tappe case STATE4_DESIGNATED_CNS11643_3:
169*aef5731fSOliver Tappe if (s[2] < 0x80 && s[3] < 0x80) {
170*aef5731fSOliver Tappe int ret = cns11643_3_mbtowc(conv,pwc,s+2,2);
171*aef5731fSOliver Tappe if (ret == RET_ILSEQ)
172*aef5731fSOliver Tappe return RET_ILSEQ;
173*aef5731fSOliver Tappe if (ret != 2) abort();
174*aef5731fSOliver Tappe COMBINE_STATE;
175*aef5731fSOliver Tappe conv->istate = state;
176*aef5731fSOliver Tappe return count+4;
177*aef5731fSOliver Tappe } else
178*aef5731fSOliver Tappe return RET_ILSEQ;
179*aef5731fSOliver Tappe case STATE4_DESIGNATED_CNS11643_4:
180*aef5731fSOliver Tappe if (s[2] < 0x80 && s[3] < 0x80) {
181*aef5731fSOliver Tappe int ret = cns11643_4_mbtowc(conv,pwc,s+2,2);
182*aef5731fSOliver Tappe if (ret == RET_ILSEQ)
183*aef5731fSOliver Tappe return RET_ILSEQ;
184*aef5731fSOliver Tappe if (ret != 2) abort();
185*aef5731fSOliver Tappe COMBINE_STATE;
186*aef5731fSOliver Tappe conv->istate = state;
187*aef5731fSOliver Tappe return count+4;
188*aef5731fSOliver Tappe } else
189*aef5731fSOliver Tappe return RET_ILSEQ;
190*aef5731fSOliver Tappe case STATE4_DESIGNATED_CNS11643_5:
191*aef5731fSOliver Tappe if (s[2] < 0x80 && s[3] < 0x80) {
192*aef5731fSOliver Tappe int ret = cns11643_5_mbtowc(conv,pwc,s+2,2);
193*aef5731fSOliver Tappe if (ret == RET_ILSEQ)
194*aef5731fSOliver Tappe return RET_ILSEQ;
195*aef5731fSOliver Tappe if (ret != 2) abort();
196*aef5731fSOliver Tappe COMBINE_STATE;
197*aef5731fSOliver Tappe conv->istate = state;
198*aef5731fSOliver Tappe return count+4;
199*aef5731fSOliver Tappe } else
200*aef5731fSOliver Tappe return RET_ILSEQ;
201*aef5731fSOliver Tappe case STATE4_DESIGNATED_CNS11643_6:
202*aef5731fSOliver Tappe if (s[2] < 0x80 && s[3] < 0x80) {
203*aef5731fSOliver Tappe int ret = cns11643_6_mbtowc(conv,pwc,s+2,2);
204*aef5731fSOliver Tappe if (ret == RET_ILSEQ)
205*aef5731fSOliver Tappe return RET_ILSEQ;
206*aef5731fSOliver Tappe if (ret != 2) abort();
207*aef5731fSOliver Tappe COMBINE_STATE;
208*aef5731fSOliver Tappe conv->istate = state;
209*aef5731fSOliver Tappe return count+4;
210*aef5731fSOliver Tappe } else
211*aef5731fSOliver Tappe return RET_ILSEQ;
212*aef5731fSOliver Tappe case STATE4_DESIGNATED_CNS11643_7:
213*aef5731fSOliver Tappe if (s[2] < 0x80 && s[3] < 0x80) {
214*aef5731fSOliver Tappe int ret = cns11643_7_mbtowc(conv,pwc,s+2,2);
215*aef5731fSOliver Tappe if (ret == RET_ILSEQ)
216*aef5731fSOliver Tappe return RET_ILSEQ;
217*aef5731fSOliver Tappe if (ret != 2) abort();
218*aef5731fSOliver Tappe COMBINE_STATE;
219*aef5731fSOliver Tappe conv->istate = state;
220*aef5731fSOliver Tappe return count+4;
221*aef5731fSOliver Tappe } else
222*aef5731fSOliver Tappe return RET_ILSEQ;
223*aef5731fSOliver Tappe default: abort();
224*aef5731fSOliver Tappe }
225*aef5731fSOliver Tappe }
226*aef5731fSOliver Tappe return RET_ILSEQ;
227*aef5731fSOliver Tappe }
228*aef5731fSOliver Tappe if (c == SO) {
229*aef5731fSOliver Tappe if (state2 != STATE2_DESIGNATED_GB2312 && state2 != STATE2_DESIGNATED_CNS11643_1 && state2 != STATE2_DESIGNATED_ISO_IR_165)
230*aef5731fSOliver Tappe return RET_ILSEQ;
231*aef5731fSOliver Tappe state1 = STATE_TWOBYTE;
232*aef5731fSOliver Tappe s++; count++;
233*aef5731fSOliver Tappe if (n < count+1)
234*aef5731fSOliver Tappe goto none;
235*aef5731fSOliver Tappe continue;
236*aef5731fSOliver Tappe }
237*aef5731fSOliver Tappe if (c == SI) {
238*aef5731fSOliver Tappe state1 = STATE_ASCII;
239*aef5731fSOliver Tappe s++; count++;
240*aef5731fSOliver Tappe if (n < count+1)
241*aef5731fSOliver Tappe goto none;
242*aef5731fSOliver Tappe continue;
243*aef5731fSOliver Tappe }
244*aef5731fSOliver Tappe break;
245*aef5731fSOliver Tappe }
246*aef5731fSOliver Tappe switch (state1) {
247*aef5731fSOliver Tappe case STATE_ASCII:
248*aef5731fSOliver Tappe if (c < 0x80) {
249*aef5731fSOliver Tappe int ret = ascii_mbtowc(conv,pwc,s,1);
250*aef5731fSOliver Tappe if (ret == RET_ILSEQ)
251*aef5731fSOliver Tappe return RET_ILSEQ;
252*aef5731fSOliver Tappe if (ret != 1) abort();
253*aef5731fSOliver Tappe if (*pwc == 0x000a || *pwc == 0x000d) {
254*aef5731fSOliver Tappe state2 = STATE2_NONE; state3 = STATE3_NONE; state4 = STATE3_NONE;
255*aef5731fSOliver Tappe }
256*aef5731fSOliver Tappe COMBINE_STATE;
257*aef5731fSOliver Tappe conv->istate = state;
258*aef5731fSOliver Tappe return count+1;
259*aef5731fSOliver Tappe } else
260*aef5731fSOliver Tappe return RET_ILSEQ;
261*aef5731fSOliver Tappe case STATE_TWOBYTE:
262*aef5731fSOliver Tappe if (n < count+2)
263*aef5731fSOliver Tappe goto none;
264*aef5731fSOliver Tappe if (s[0] < 0x80 && s[1] < 0x80) {
265*aef5731fSOliver Tappe int ret;
266*aef5731fSOliver Tappe switch (state2) {
267*aef5731fSOliver Tappe case STATE2_NONE:
268*aef5731fSOliver Tappe return RET_ILSEQ;
269*aef5731fSOliver Tappe case STATE2_DESIGNATED_GB2312:
270*aef5731fSOliver Tappe ret = gb2312_mbtowc(conv,pwc,s,2); break;
271*aef5731fSOliver Tappe case STATE2_DESIGNATED_CNS11643_1:
272*aef5731fSOliver Tappe ret = cns11643_1_mbtowc(conv,pwc,s,2); break;
273*aef5731fSOliver Tappe case STATE2_DESIGNATED_ISO_IR_165:
274*aef5731fSOliver Tappe ret = isoir165_mbtowc(conv,pwc,s,2); break;
275*aef5731fSOliver Tappe default: abort();
276*aef5731fSOliver Tappe }
277*aef5731fSOliver Tappe if (ret == RET_ILSEQ)
278*aef5731fSOliver Tappe return RET_ILSEQ;
279*aef5731fSOliver Tappe if (ret != 2) abort();
280*aef5731fSOliver Tappe COMBINE_STATE;
281*aef5731fSOliver Tappe conv->istate = state;
282*aef5731fSOliver Tappe return count+2;
283*aef5731fSOliver Tappe } else
284*aef5731fSOliver Tappe return RET_ILSEQ;
285*aef5731fSOliver Tappe default: abort();
286*aef5731fSOliver Tappe }
287*aef5731fSOliver Tappe
288*aef5731fSOliver Tappe none:
289*aef5731fSOliver Tappe COMBINE_STATE;
290*aef5731fSOliver Tappe conv->istate = state;
291*aef5731fSOliver Tappe return RET_TOOFEW(count);
292*aef5731fSOliver Tappe }
293*aef5731fSOliver Tappe
294*aef5731fSOliver Tappe static int
iso2022_cn_ext_wctomb(conv_t conv,unsigned char * r,ucs4_t wc,int n)295*aef5731fSOliver Tappe iso2022_cn_ext_wctomb (conv_t conv, unsigned char *r, ucs4_t wc, int n)
296*aef5731fSOliver Tappe {
297*aef5731fSOliver Tappe state_t state = conv->ostate;
298*aef5731fSOliver Tappe SPLIT_STATE;
299*aef5731fSOliver Tappe unsigned char buf[3];
300*aef5731fSOliver Tappe int ret;
301*aef5731fSOliver Tappe
302*aef5731fSOliver Tappe /* There is no need to handle Unicode 3.1 tag characters and to look for
303*aef5731fSOliver Tappe "zh-CN" or "zh-TW" tags, because GB2312 and CNS11643 are disjoint. */
304*aef5731fSOliver Tappe
305*aef5731fSOliver Tappe /* Try ASCII. */
306*aef5731fSOliver Tappe ret = ascii_wctomb(conv,buf,wc,1);
307*aef5731fSOliver Tappe if (ret != RET_ILUNI) {
308*aef5731fSOliver Tappe if (ret != 1) abort();
309*aef5731fSOliver Tappe if (buf[0] < 0x80) {
310*aef5731fSOliver Tappe int count = (state1 == STATE_ASCII ? 1 : 2);
311*aef5731fSOliver Tappe if (n < count)
312*aef5731fSOliver Tappe return RET_TOOSMALL;
313*aef5731fSOliver Tappe if (state1 != STATE_ASCII) {
314*aef5731fSOliver Tappe r[0] = SI;
315*aef5731fSOliver Tappe r += 1;
316*aef5731fSOliver Tappe state1 = STATE_ASCII;
317*aef5731fSOliver Tappe }
318*aef5731fSOliver Tappe r[0] = buf[0];
319*aef5731fSOliver Tappe if (wc == 0x000a || wc == 0x000d) {
320*aef5731fSOliver Tappe state2 = STATE2_NONE; state3 = STATE3_NONE; state4 = STATE3_NONE;
321*aef5731fSOliver Tappe }
322*aef5731fSOliver Tappe COMBINE_STATE;
323*aef5731fSOliver Tappe conv->ostate = state;
324*aef5731fSOliver Tappe return count;
325*aef5731fSOliver Tappe }
326*aef5731fSOliver Tappe }
327*aef5731fSOliver Tappe
328*aef5731fSOliver Tappe /* Try GB 2312-1980. */
329*aef5731fSOliver Tappe ret = gb2312_wctomb(conv,buf,wc,2);
330*aef5731fSOliver Tappe if (ret != RET_ILUNI) {
331*aef5731fSOliver Tappe if (ret != 2) abort();
332*aef5731fSOliver Tappe if (buf[0] < 0x80 && buf[1] < 0x80) {
333*aef5731fSOliver Tappe int count = (state2 == STATE2_DESIGNATED_GB2312 ? 0 : 4) + (state1 == STATE_TWOBYTE ? 0 : 1) + 2;
334*aef5731fSOliver Tappe if (n < count)
335*aef5731fSOliver Tappe return RET_TOOSMALL;
336*aef5731fSOliver Tappe if (state2 != STATE2_DESIGNATED_GB2312) {
337*aef5731fSOliver Tappe r[0] = ESC;
338*aef5731fSOliver Tappe r[1] = '$';
339*aef5731fSOliver Tappe r[2] = ')';
340*aef5731fSOliver Tappe r[3] = 'A';
341*aef5731fSOliver Tappe r += 4;
342*aef5731fSOliver Tappe state2 = STATE2_DESIGNATED_GB2312;
343*aef5731fSOliver Tappe }
344*aef5731fSOliver Tappe if (state1 != STATE_TWOBYTE) {
345*aef5731fSOliver Tappe r[0] = SO;
346*aef5731fSOliver Tappe r += 1;
347*aef5731fSOliver Tappe state1 = STATE_TWOBYTE;
348*aef5731fSOliver Tappe }
349*aef5731fSOliver Tappe r[0] = buf[0];
350*aef5731fSOliver Tappe r[1] = buf[1];
351*aef5731fSOliver Tappe COMBINE_STATE;
352*aef5731fSOliver Tappe conv->ostate = state;
353*aef5731fSOliver Tappe return count;
354*aef5731fSOliver Tappe }
355*aef5731fSOliver Tappe }
356*aef5731fSOliver Tappe
357*aef5731fSOliver Tappe ret = cns11643_wctomb(conv,buf,wc,3);
358*aef5731fSOliver Tappe if (ret != RET_ILUNI) {
359*aef5731fSOliver Tappe if (ret != 3) abort();
360*aef5731fSOliver Tappe
361*aef5731fSOliver Tappe /* Try CNS 11643-1992 Plane 1. */
362*aef5731fSOliver Tappe if (buf[0] == 1 && buf[1] < 0x80 && buf[2] < 0x80) {
363*aef5731fSOliver Tappe int count = (state2 == STATE2_DESIGNATED_CNS11643_1 ? 0 : 4) + (state1 == STATE_TWOBYTE ? 0 : 1) + 2;
364*aef5731fSOliver Tappe if (n < count)
365*aef5731fSOliver Tappe return RET_TOOSMALL;
366*aef5731fSOliver Tappe if (state2 != STATE2_DESIGNATED_CNS11643_1) {
367*aef5731fSOliver Tappe r[0] = ESC;
368*aef5731fSOliver Tappe r[1] = '$';
369*aef5731fSOliver Tappe r[2] = ')';
370*aef5731fSOliver Tappe r[3] = 'G';
371*aef5731fSOliver Tappe r += 4;
372*aef5731fSOliver Tappe state2 = STATE2_DESIGNATED_CNS11643_1;
373*aef5731fSOliver Tappe }
374*aef5731fSOliver Tappe if (state1 != STATE_TWOBYTE) {
375*aef5731fSOliver Tappe r[0] = SO;
376*aef5731fSOliver Tappe r += 1;
377*aef5731fSOliver Tappe state1 = STATE_TWOBYTE;
378*aef5731fSOliver Tappe }
379*aef5731fSOliver Tappe r[0] = buf[1];
380*aef5731fSOliver Tappe r[1] = buf[2];
381*aef5731fSOliver Tappe COMBINE_STATE;
382*aef5731fSOliver Tappe conv->ostate = state;
383*aef5731fSOliver Tappe return count;
384*aef5731fSOliver Tappe }
385*aef5731fSOliver Tappe
386*aef5731fSOliver Tappe /* Try CNS 11643-1992 Plane 2. */
387*aef5731fSOliver Tappe if (buf[0] == 2 && buf[1] < 0x80 && buf[2] < 0x80) {
388*aef5731fSOliver Tappe int count = (state3 == STATE3_DESIGNATED_CNS11643_2 ? 0 : 4) + 4;
389*aef5731fSOliver Tappe if (n < count)
390*aef5731fSOliver Tappe return RET_TOOSMALL;
391*aef5731fSOliver Tappe if (state3 != STATE3_DESIGNATED_CNS11643_2) {
392*aef5731fSOliver Tappe r[0] = ESC;
393*aef5731fSOliver Tappe r[1] = '$';
394*aef5731fSOliver Tappe r[2] = '*';
395*aef5731fSOliver Tappe r[3] = 'H';
396*aef5731fSOliver Tappe r += 4;
397*aef5731fSOliver Tappe state3 = STATE3_DESIGNATED_CNS11643_2;
398*aef5731fSOliver Tappe }
399*aef5731fSOliver Tappe r[0] = ESC;
400*aef5731fSOliver Tappe r[1] = 'N';
401*aef5731fSOliver Tappe r[2] = buf[1];
402*aef5731fSOliver Tappe r[3] = buf[2];
403*aef5731fSOliver Tappe COMBINE_STATE;
404*aef5731fSOliver Tappe conv->ostate = state;
405*aef5731fSOliver Tappe return count;
406*aef5731fSOliver Tappe }
407*aef5731fSOliver Tappe
408*aef5731fSOliver Tappe /* Try CNS 11643-1992 Plane 3. */
409*aef5731fSOliver Tappe if (buf[0] == 3 && buf[1] < 0x80 && buf[2] < 0x80) {
410*aef5731fSOliver Tappe int count = (state4 == STATE4_DESIGNATED_CNS11643_3 ? 0 : 4) + 4;
411*aef5731fSOliver Tappe if (n < count)
412*aef5731fSOliver Tappe return RET_TOOSMALL;
413*aef5731fSOliver Tappe if (state4 != STATE4_DESIGNATED_CNS11643_3) {
414*aef5731fSOliver Tappe r[0] = ESC;
415*aef5731fSOliver Tappe r[1] = '$';
416*aef5731fSOliver Tappe r[2] = '+';
417*aef5731fSOliver Tappe r[3] = 'I';
418*aef5731fSOliver Tappe r += 4;
419*aef5731fSOliver Tappe state4 = STATE4_DESIGNATED_CNS11643_3;
420*aef5731fSOliver Tappe }
421*aef5731fSOliver Tappe r[0] = ESC;
422*aef5731fSOliver Tappe r[1] = 'O';
423*aef5731fSOliver Tappe r[2] = buf[1];
424*aef5731fSOliver Tappe r[3] = buf[2];
425*aef5731fSOliver Tappe COMBINE_STATE;
426*aef5731fSOliver Tappe conv->ostate = state;
427*aef5731fSOliver Tappe return count;
428*aef5731fSOliver Tappe }
429*aef5731fSOliver Tappe
430*aef5731fSOliver Tappe /* Try CNS 11643-1992 Plane 4. */
431*aef5731fSOliver Tappe if (buf[0] == 4 && buf[1] < 0x80 && buf[2] < 0x80) {
432*aef5731fSOliver Tappe int count = (state4 == STATE4_DESIGNATED_CNS11643_4 ? 0 : 4) + 4;
433*aef5731fSOliver Tappe if (n < count)
434*aef5731fSOliver Tappe return RET_TOOSMALL;
435*aef5731fSOliver Tappe if (state4 != STATE4_DESIGNATED_CNS11643_4) {
436*aef5731fSOliver Tappe r[0] = ESC;
437*aef5731fSOliver Tappe r[1] = '$';
438*aef5731fSOliver Tappe r[2] = '+';
439*aef5731fSOliver Tappe r[3] = 'J';
440*aef5731fSOliver Tappe r += 4;
441*aef5731fSOliver Tappe state4 = STATE4_DESIGNATED_CNS11643_4;
442*aef5731fSOliver Tappe }
443*aef5731fSOliver Tappe r[0] = ESC;
444*aef5731fSOliver Tappe r[1] = 'O';
445*aef5731fSOliver Tappe r[2] = buf[1];
446*aef5731fSOliver Tappe r[3] = buf[2];
447*aef5731fSOliver Tappe COMBINE_STATE;
448*aef5731fSOliver Tappe conv->ostate = state;
449*aef5731fSOliver Tappe return count;
450*aef5731fSOliver Tappe }
451*aef5731fSOliver Tappe
452*aef5731fSOliver Tappe /* Try CNS 11643-1992 Plane 5. */
453*aef5731fSOliver Tappe if (buf[0] == 5 && buf[1] < 0x80 && buf[2] < 0x80) {
454*aef5731fSOliver Tappe int count = (state4 == STATE4_DESIGNATED_CNS11643_5 ? 0 : 4) + 4;
455*aef5731fSOliver Tappe if (n < count)
456*aef5731fSOliver Tappe return RET_TOOSMALL;
457*aef5731fSOliver Tappe if (state4 != STATE4_DESIGNATED_CNS11643_5) {
458*aef5731fSOliver Tappe r[0] = ESC;
459*aef5731fSOliver Tappe r[1] = '$';
460*aef5731fSOliver Tappe r[2] = '+';
461*aef5731fSOliver Tappe r[3] = 'K';
462*aef5731fSOliver Tappe r += 4;
463*aef5731fSOliver Tappe state4 = STATE4_DESIGNATED_CNS11643_5;
464*aef5731fSOliver Tappe }
465*aef5731fSOliver Tappe r[0] = ESC;
466*aef5731fSOliver Tappe r[1] = 'O';
467*aef5731fSOliver Tappe r[2] = buf[1];
468*aef5731fSOliver Tappe r[3] = buf[2];
469*aef5731fSOliver Tappe COMBINE_STATE;
470*aef5731fSOliver Tappe conv->ostate = state;
471*aef5731fSOliver Tappe return count;
472*aef5731fSOliver Tappe }
473*aef5731fSOliver Tappe
474*aef5731fSOliver Tappe /* Try CNS 11643-1992 Plane 6. */
475*aef5731fSOliver Tappe if (buf[0] == 6 && buf[1] < 0x80 && buf[2] < 0x80) {
476*aef5731fSOliver Tappe int count = (state4 == STATE4_DESIGNATED_CNS11643_6 ? 0 : 4) + 4;
477*aef5731fSOliver Tappe if (n < count)
478*aef5731fSOliver Tappe return RET_TOOSMALL;
479*aef5731fSOliver Tappe if (state4 != STATE4_DESIGNATED_CNS11643_6) {
480*aef5731fSOliver Tappe r[0] = ESC;
481*aef5731fSOliver Tappe r[1] = '$';
482*aef5731fSOliver Tappe r[2] = '+';
483*aef5731fSOliver Tappe r[3] = 'L';
484*aef5731fSOliver Tappe r += 4;
485*aef5731fSOliver Tappe state4 = STATE4_DESIGNATED_CNS11643_6;
486*aef5731fSOliver Tappe }
487*aef5731fSOliver Tappe r[0] = ESC;
488*aef5731fSOliver Tappe r[1] = 'O';
489*aef5731fSOliver Tappe r[2] = buf[1];
490*aef5731fSOliver Tappe r[3] = buf[2];
491*aef5731fSOliver Tappe COMBINE_STATE;
492*aef5731fSOliver Tappe conv->ostate = state;
493*aef5731fSOliver Tappe return count;
494*aef5731fSOliver Tappe }
495*aef5731fSOliver Tappe
496*aef5731fSOliver Tappe /* Try CNS 11643-1992 Plane 7. */
497*aef5731fSOliver Tappe if (buf[0] == 7 && buf[1] < 0x80 && buf[2] < 0x80) {
498*aef5731fSOliver Tappe int count = (state4 == STATE4_DESIGNATED_CNS11643_7 ? 0 : 4) + 4;
499*aef5731fSOliver Tappe if (n < count)
500*aef5731fSOliver Tappe return RET_TOOSMALL;
501*aef5731fSOliver Tappe if (state4 != STATE4_DESIGNATED_CNS11643_7) {
502*aef5731fSOliver Tappe r[0] = ESC;
503*aef5731fSOliver Tappe r[1] = '$';
504*aef5731fSOliver Tappe r[2] = '+';
505*aef5731fSOliver Tappe r[3] = 'M';
506*aef5731fSOliver Tappe r += 4;
507*aef5731fSOliver Tappe state4 = STATE4_DESIGNATED_CNS11643_7;
508*aef5731fSOliver Tappe }
509*aef5731fSOliver Tappe r[0] = ESC;
510*aef5731fSOliver Tappe r[1] = 'O';
511*aef5731fSOliver Tappe r[2] = buf[1];
512*aef5731fSOliver Tappe r[3] = buf[2];
513*aef5731fSOliver Tappe COMBINE_STATE;
514*aef5731fSOliver Tappe conv->ostate = state;
515*aef5731fSOliver Tappe return count;
516*aef5731fSOliver Tappe }
517*aef5731fSOliver Tappe
518*aef5731fSOliver Tappe }
519*aef5731fSOliver Tappe
520*aef5731fSOliver Tappe /* Try ISO-IR-165. */
521*aef5731fSOliver Tappe ret = isoir165_wctomb(conv,buf,wc,2);
522*aef5731fSOliver Tappe if (ret != RET_ILUNI) {
523*aef5731fSOliver Tappe if (ret != 2) abort();
524*aef5731fSOliver Tappe if (buf[0] < 0x80 && buf[1] < 0x80) {
525*aef5731fSOliver Tappe int count = (state2 == STATE2_DESIGNATED_ISO_IR_165 ? 0 : 4) + (state1 == STATE_TWOBYTE ? 0 : 1) + 2;
526*aef5731fSOliver Tappe if (n < count)
527*aef5731fSOliver Tappe return RET_TOOSMALL;
528*aef5731fSOliver Tappe if (state2 != STATE2_DESIGNATED_ISO_IR_165) {
529*aef5731fSOliver Tappe r[0] = ESC;
530*aef5731fSOliver Tappe r[1] = '$';
531*aef5731fSOliver Tappe r[2] = ')';
532*aef5731fSOliver Tappe r[3] = 'E';
533*aef5731fSOliver Tappe r += 4;
534*aef5731fSOliver Tappe state2 = STATE2_DESIGNATED_ISO_IR_165;
535*aef5731fSOliver Tappe }
536*aef5731fSOliver Tappe if (state1 != STATE_TWOBYTE) {
537*aef5731fSOliver Tappe r[0] = SO;
538*aef5731fSOliver Tappe r += 1;
539*aef5731fSOliver Tappe state1 = STATE_TWOBYTE;
540*aef5731fSOliver Tappe }
541*aef5731fSOliver Tappe r[0] = buf[0];
542*aef5731fSOliver Tappe r[1] = buf[1];
543*aef5731fSOliver Tappe COMBINE_STATE;
544*aef5731fSOliver Tappe conv->ostate = state;
545*aef5731fSOliver Tappe return count;
546*aef5731fSOliver Tappe }
547*aef5731fSOliver Tappe }
548*aef5731fSOliver Tappe
549*aef5731fSOliver Tappe return RET_ILUNI;
550*aef5731fSOliver Tappe }
551*aef5731fSOliver Tappe
552*aef5731fSOliver Tappe static int
iso2022_cn_ext_reset(conv_t conv,unsigned char * r,int n)553*aef5731fSOliver Tappe iso2022_cn_ext_reset (conv_t conv, unsigned char *r, int n)
554*aef5731fSOliver Tappe {
555*aef5731fSOliver Tappe state_t state = conv->ostate;
556*aef5731fSOliver Tappe SPLIT_STATE;
557*aef5731fSOliver Tappe (void)state2;
558*aef5731fSOliver Tappe (void)state3;
559*aef5731fSOliver Tappe (void)state4;
560*aef5731fSOliver Tappe if (state1 != STATE_ASCII) {
561*aef5731fSOliver Tappe if (n < 1)
562*aef5731fSOliver Tappe return RET_TOOSMALL;
563*aef5731fSOliver Tappe r[0] = SI;
564*aef5731fSOliver Tappe /* conv->ostate = 0; will be done by the caller */
565*aef5731fSOliver Tappe return 1;
566*aef5731fSOliver Tappe } else
567*aef5731fSOliver Tappe return 0;
568*aef5731fSOliver Tappe }
569*aef5731fSOliver Tappe
570*aef5731fSOliver Tappe #undef COMBINE_STATE
571*aef5731fSOliver Tappe #undef SPLIT_STATE
572*aef5731fSOliver Tappe #undef STATE4_DESIGNATED_CNS11643_7
573*aef5731fSOliver Tappe #undef STATE4_DESIGNATED_CNS11643_6
574*aef5731fSOliver Tappe #undef STATE4_DESIGNATED_CNS11643_5
575*aef5731fSOliver Tappe #undef STATE4_DESIGNATED_CNS11643_4
576*aef5731fSOliver Tappe #undef STATE4_DESIGNATED_CNS11643_3
577*aef5731fSOliver Tappe #undef STATE4_NONE
578*aef5731fSOliver Tappe #undef STATE3_DESIGNATED_CNS11643_2
579*aef5731fSOliver Tappe #undef STATE3_NONE
580*aef5731fSOliver Tappe #undef STATE2_DESIGNATED_ISO_IR_165
581*aef5731fSOliver Tappe #undef STATE2_DESIGNATED_CNS11643_1
582*aef5731fSOliver Tappe #undef STATE2_DESIGNATED_GB2312
583*aef5731fSOliver Tappe #undef STATE2_NONE
584*aef5731fSOliver Tappe #undef STATE_TWOBYTE
585*aef5731fSOliver Tappe #undef STATE_ASCII
586