other.c revision a8fdb4bc
1a8fdb4bcSmrg/*
2a8fdb4bcSmrgCopyright (c) 2002 by Tomohiro KUBOTA
3a8fdb4bcSmrg
4a8fdb4bcSmrgPermission is hereby granted, free of charge, to any person obtaining a copy
5a8fdb4bcSmrgof this software and associated documentation files (the "Software"), to deal
6a8fdb4bcSmrgin the Software without restriction, including without limitation the rights
7a8fdb4bcSmrgto use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8a8fdb4bcSmrgcopies of the Software, and to permit persons to whom the Software is
9a8fdb4bcSmrgfurnished to do so, subject to the following conditions:
10a8fdb4bcSmrg
11a8fdb4bcSmrgThe above copyright notice and this permission notice shall be included in
12a8fdb4bcSmrgall copies or substantial portions of the Software.
13a8fdb4bcSmrg
14a8fdb4bcSmrgTHE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15a8fdb4bcSmrgIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16a8fdb4bcSmrgFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
17a8fdb4bcSmrgAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18a8fdb4bcSmrgLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19a8fdb4bcSmrgOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20a8fdb4bcSmrgTHE SOFTWARE.
21a8fdb4bcSmrg*/
22a8fdb4bcSmrg/* $XFree86: xc/programs/luit/other.c,v 1.1 2002/10/17 01:06:09 dawes Exp $ */
23a8fdb4bcSmrg
24a8fdb4bcSmrg#include <stdlib.h>
25a8fdb4bcSmrg#include <stdio.h>
26a8fdb4bcSmrg#include <string.h>
27a8fdb4bcSmrg#include <ctype.h>
28a8fdb4bcSmrg#include <X11/fonts/fontenc.h>
29a8fdb4bcSmrg#include "other.h"
30a8fdb4bcSmrg#include "charset.h"
31a8fdb4bcSmrg
32a8fdb4bcSmrg#ifndef NULL
33a8fdb4bcSmrg#define NULL 0
34a8fdb4bcSmrg#endif
35a8fdb4bcSmrg
36a8fdb4bcSmrg#define EURO_10646 0x20AC
37a8fdb4bcSmrg
38a8fdb4bcSmrgint
39a8fdb4bcSmrginit_gbk(OtherStatePtr s)
40a8fdb4bcSmrg{
41a8fdb4bcSmrg    s->gbk.mapping =
42a8fdb4bcSmrg        FontEncMapFind("gbk-0", FONT_ENCODING_UNICODE, -1, -1, NULL);
43a8fdb4bcSmrg    if(!s->gbk.mapping) return 0;
44a8fdb4bcSmrg
45a8fdb4bcSmrg    s->gbk.reverse = FontMapReverse(s->gbk.mapping);
46a8fdb4bcSmrg    if(!s->gbk.reverse) return 0;
47a8fdb4bcSmrg
48a8fdb4bcSmrg    s->gbk.buf = -1;
49a8fdb4bcSmrg    return 1;
50a8fdb4bcSmrg}
51a8fdb4bcSmrg
52a8fdb4bcSmrgunsigned int
53a8fdb4bcSmrgmapping_gbk(unsigned int n, OtherStatePtr s)
54a8fdb4bcSmrg{
55a8fdb4bcSmrg    unsigned int r;
56a8fdb4bcSmrg    if(n < 128) return n;
57a8fdb4bcSmrg    if(n == 128) return EURO_10646;
58a8fdb4bcSmrg    r = FontEncRecode(n, s->gbk.mapping);
59a8fdb4bcSmrg    return r;
60a8fdb4bcSmrg}
61a8fdb4bcSmrg
62a8fdb4bcSmrgunsigned int
63a8fdb4bcSmrgreverse_gbk(unsigned int n, OtherStatePtr s)
64a8fdb4bcSmrg{
65a8fdb4bcSmrg    if(n < 128) return n;
66a8fdb4bcSmrg    if(n == EURO_10646) return 128;
67a8fdb4bcSmrg    return s->gbk.reverse->reverse(n, s->gbk.reverse->data);
68a8fdb4bcSmrg}
69a8fdb4bcSmrg
70a8fdb4bcSmrgint
71a8fdb4bcSmrgstack_gbk(unsigned char c, OtherStatePtr s)
72a8fdb4bcSmrg{
73a8fdb4bcSmrg    if(s->gbk.buf < 0) {
74a8fdb4bcSmrg        if(c < 129) return c;
75a8fdb4bcSmrg        s->gbk.buf = c;
76a8fdb4bcSmrg	return -1;
77a8fdb4bcSmrg    } else {
78a8fdb4bcSmrg        int b;
79a8fdb4bcSmrg        if(c < 0x40 || c == 0x7F) {
80a8fdb4bcSmrg            s->gbk.buf = -1;
81a8fdb4bcSmrg            return c;
82a8fdb4bcSmrg        }
83a8fdb4bcSmrg        if(s->gbk.buf < 0xFF && c < 0xFF)
84a8fdb4bcSmrg            b = (s->gbk.buf << 8) + c;
85a8fdb4bcSmrg        else
86a8fdb4bcSmrg            b = -1;
87a8fdb4bcSmrg        s->gbk.buf = -1;
88a8fdb4bcSmrg        return b;
89a8fdb4bcSmrg    }
90a8fdb4bcSmrg}
91a8fdb4bcSmrg
92a8fdb4bcSmrgint
93a8fdb4bcSmrginit_utf8(OtherStatePtr s)
94a8fdb4bcSmrg{
95a8fdb4bcSmrg    s->utf8.buf_ptr = 0;
96a8fdb4bcSmrg    return 1;
97a8fdb4bcSmrg}
98a8fdb4bcSmrg
99a8fdb4bcSmrgunsigned int
100a8fdb4bcSmrgmapping_utf8(unsigned int n, OtherStatePtr s)
101a8fdb4bcSmrg{
102a8fdb4bcSmrg    return n;
103a8fdb4bcSmrg}
104a8fdb4bcSmrg
105a8fdb4bcSmrgunsigned int
106a8fdb4bcSmrgreverse_utf8(unsigned int n, OtherStatePtr s)
107a8fdb4bcSmrg{
108a8fdb4bcSmrg    if(n < 0x80)
109a8fdb4bcSmrg        return n;
110a8fdb4bcSmrg    if(n < 0x800)
111a8fdb4bcSmrg        return 0xC080 + ((n&0x7C0)<<2) + (n&0x3F);
112a8fdb4bcSmrg    if(n < 0x10000)
113a8fdb4bcSmrg        return 0xE08080 + ((n&0xF000)<<4) + ((n&0xFC0)<<2) + (n&0x3F);
114a8fdb4bcSmrg    return 0xF0808080 + ((n&0x1C0000)<<6) + ((n&0x3F000)<<4) +
115a8fdb4bcSmrg           ((n&0xFC0)<<2) + (n&0x3F);
116a8fdb4bcSmrg}
117a8fdb4bcSmrg
118a8fdb4bcSmrgint
119a8fdb4bcSmrgstack_utf8(unsigned char c, OtherStatePtr s)
120a8fdb4bcSmrg{
121a8fdb4bcSmrg    int u;
122a8fdb4bcSmrg
123a8fdb4bcSmrg    if(c < 0x80) {
124a8fdb4bcSmrg        s->utf8.buf_ptr = 0;
125a8fdb4bcSmrg        return c;
126a8fdb4bcSmrg    }
127a8fdb4bcSmrg    if(s->utf8.buf_ptr == 0) {
128a8fdb4bcSmrg        if((c & 0x40) == 0) return -1;
129a8fdb4bcSmrg        s->utf8.buf[s->utf8.buf_ptr++] = c;
130a8fdb4bcSmrg        if((c & 0x60) == 0x40) s->utf8.len = 2;
131a8fdb4bcSmrg        else if((c & 0x70) == 0x60) s->utf8.len = 3;
132a8fdb4bcSmrg        else if((c & 0x78) == 0x70) s->utf8.len = 4;
133a8fdb4bcSmrg        else s->utf8.buf_ptr = 0;
134a8fdb4bcSmrg        return -1;
135a8fdb4bcSmrg    }
136a8fdb4bcSmrg    if((c & 0x40) != 0) {
137a8fdb4bcSmrg        s->utf8.buf_ptr = 0;
138a8fdb4bcSmrg        return -1;
139a8fdb4bcSmrg    }
140a8fdb4bcSmrg    s->utf8.buf[s->utf8.buf_ptr++] = c;
141a8fdb4bcSmrg    if(s->utf8.buf_ptr < s->utf8.len) return -1;
142a8fdb4bcSmrg    switch(s->utf8.len) {
143a8fdb4bcSmrg    case 2:
144a8fdb4bcSmrg        u = ((s->utf8.buf[0] & 0x1F) << 6) | (s->utf8.buf[1] & 0x3F);
145a8fdb4bcSmrg        s->utf8.buf_ptr = 0;
146a8fdb4bcSmrg        if(u < 0x80) return -1; else return u;
147a8fdb4bcSmrg    case 3:
148a8fdb4bcSmrg        u = ((s->utf8.buf[0] & 0x0F) << 12)
149a8fdb4bcSmrg            | ((s->utf8.buf[1] & 0x3F) << 6)
150a8fdb4bcSmrg            | (s->utf8.buf[2] & 0x3F);
151a8fdb4bcSmrg        s->utf8.buf_ptr = 0;
152a8fdb4bcSmrg        if(u < 0x800) return -1; else return u;
153a8fdb4bcSmrg    case 4:
154a8fdb4bcSmrg        u = ((s->utf8.buf[0] & 0x03) << 18)
155a8fdb4bcSmrg            | ((s->utf8.buf[1] & 0x3F) << 12)
156a8fdb4bcSmrg            | ((s->utf8.buf[2] & 0x3F) << 6)
157a8fdb4bcSmrg            | ((s->utf8.buf[3] & 0x3F));
158a8fdb4bcSmrg        s->utf8.buf_ptr = 0;
159a8fdb4bcSmrg        if(u < 0x10000) return -1; else return u;
160a8fdb4bcSmrg    }
161a8fdb4bcSmrg    s->utf8.buf_ptr = 0;
162a8fdb4bcSmrg    return -1;
163a8fdb4bcSmrg}
164a8fdb4bcSmrg
165a8fdb4bcSmrg
166a8fdb4bcSmrg#define HALFWIDTH_10646 0xFF61
167a8fdb4bcSmrg#define YEN_SJIS 0x5C
168a8fdb4bcSmrg#define YEN_10646 0x00A5
169a8fdb4bcSmrg#define OVERLINE_SJIS 0x7E
170a8fdb4bcSmrg#define OVERLINE_10646 0x203E
171a8fdb4bcSmrg
172a8fdb4bcSmrgint
173a8fdb4bcSmrginit_sjis(OtherStatePtr s)
174a8fdb4bcSmrg{
175a8fdb4bcSmrg    s->sjis.x0208mapping =
176a8fdb4bcSmrg        FontEncMapFind("jisx0208.1990-0", FONT_ENCODING_UNICODE, -1, -1, NULL);
177a8fdb4bcSmrg    if(!s->sjis.x0208mapping) return 0;
178a8fdb4bcSmrg
179a8fdb4bcSmrg    s->sjis.x0208reverse = FontMapReverse(s->sjis.x0208mapping);
180a8fdb4bcSmrg    if(!s->sjis.x0208reverse) return 0;
181a8fdb4bcSmrg
182a8fdb4bcSmrg    s->sjis.x0201mapping =
183a8fdb4bcSmrg        FontEncMapFind("jisx0201.1976-0", FONT_ENCODING_UNICODE, -1, -1, NULL);
184a8fdb4bcSmrg    if(!s->sjis.x0201mapping) return 0;
185a8fdb4bcSmrg
186a8fdb4bcSmrg    s->sjis.x0201reverse = FontMapReverse(s->sjis.x0201mapping);
187a8fdb4bcSmrg    if(!s->sjis.x0201reverse) return 0;
188a8fdb4bcSmrg
189a8fdb4bcSmrg    s->sjis.buf = -1;
190a8fdb4bcSmrg    return 1;
191a8fdb4bcSmrg}
192a8fdb4bcSmrg
193a8fdb4bcSmrgunsigned int
194a8fdb4bcSmrgmapping_sjis(unsigned int n, OtherStatePtr s)
195a8fdb4bcSmrg{
196a8fdb4bcSmrg    unsigned int j1, j2, s1, s2;
197a8fdb4bcSmrg    if(n == YEN_SJIS) return YEN_10646;
198a8fdb4bcSmrg    if(n == OVERLINE_SJIS) return OVERLINE_10646;
199a8fdb4bcSmrg    if(n < 0x80) return n;
200a8fdb4bcSmrg    if(n >= 0xA0 && n <= 0xDF) return FontEncRecode(n, s->sjis.x0201mapping);
201a8fdb4bcSmrg    s1 = ((n>>8)&0xFF);
202a8fdb4bcSmrg    s2 = (n&0xFF);
203a8fdb4bcSmrg    j1 = (s1 << 1) - (s1 <= 0x9F ? 0xE0 : 0x160) - (s2 < 0x9F ? 1 : 0);
204a8fdb4bcSmrg    j2 = s2 - 0x1F - (s2 >= 0x7F ? 1 : 0) - (s2 >= 0x9F ? 0x5E : 0);
205a8fdb4bcSmrg    return FontEncRecode((j1<<8) + j2, s->sjis.x0208mapping);
206a8fdb4bcSmrg}
207a8fdb4bcSmrg
208a8fdb4bcSmrgunsigned int
209a8fdb4bcSmrgreverse_sjis(unsigned int n, OtherStatePtr s)
210a8fdb4bcSmrg{
211a8fdb4bcSmrg    unsigned int j, j1, j2, s1, s2;
212a8fdb4bcSmrg    if(n == YEN_10646) return YEN_SJIS;
213a8fdb4bcSmrg    if(n == OVERLINE_10646) return OVERLINE_SJIS;
214a8fdb4bcSmrg    if(n < 0x80) return n;
215a8fdb4bcSmrg    if(n >= HALFWIDTH_10646)
216a8fdb4bcSmrg        return s->sjis.x0201reverse->reverse(n, s->sjis.x0201reverse->data);
217a8fdb4bcSmrg    j = s->sjis.x0208reverse->reverse(n, s->sjis.x0208reverse->data);
218a8fdb4bcSmrg    j1 = ((j>>8)&0xFF);
219a8fdb4bcSmrg    j2 = (j&0xFF);
220a8fdb4bcSmrg    s1 = ((j1 - 1) >> 1) + ((j1 <= 0x5E) ? 0x71 : 0xB1);
221a8fdb4bcSmrg    s2 = j2 + ((j1 & 1) ? ((j2 < 0x60) ? 0x1F : 0x20) : 0x7E);
222a8fdb4bcSmrg    return (s1<<8) + s2;
223a8fdb4bcSmrg}
224a8fdb4bcSmrg
225a8fdb4bcSmrgint
226a8fdb4bcSmrgstack_sjis(unsigned char c, OtherStatePtr s)
227a8fdb4bcSmrg{
228a8fdb4bcSmrg    if(s->sjis.buf < 0) {
229a8fdb4bcSmrg        if(c < 128 || (c >= 0xA0 && c <= 0xDF)) return c;
230a8fdb4bcSmrg        s->sjis.buf = c;
231a8fdb4bcSmrg	return -1;
232a8fdb4bcSmrg    } else {
233a8fdb4bcSmrg        int b;
234a8fdb4bcSmrg        if(c < 0x40 || c == 0x7F) {
235a8fdb4bcSmrg            s->sjis.buf = -1;
236a8fdb4bcSmrg            return c;
237a8fdb4bcSmrg        }
238a8fdb4bcSmrg        if(s->sjis.buf < 0xFF && c < 0xFF)
239a8fdb4bcSmrg            b = (s->sjis.buf << 8) + c;
240a8fdb4bcSmrg        else
241a8fdb4bcSmrg            b = -1;
242a8fdb4bcSmrg        s->sjis.buf = -1;
243a8fdb4bcSmrg        return b;
244a8fdb4bcSmrg    }
245a8fdb4bcSmrg}
246a8fdb4bcSmrg
247a8fdb4bcSmrgint
248a8fdb4bcSmrginit_hkscs(OtherStatePtr s)
249a8fdb4bcSmrg{
250a8fdb4bcSmrg    s->hkscs.mapping =
251a8fdb4bcSmrg        FontEncMapFind("big5hkscs-0", FONT_ENCODING_UNICODE, -1, -1, NULL);
252a8fdb4bcSmrg    if(!s->hkscs.mapping) return 0;
253a8fdb4bcSmrg
254a8fdb4bcSmrg    s->hkscs.reverse = FontMapReverse(s->hkscs.mapping);
255a8fdb4bcSmrg    if(!s->hkscs.reverse) return 0;
256a8fdb4bcSmrg
257a8fdb4bcSmrg    s->hkscs.buf = -1;
258a8fdb4bcSmrg    return 1;
259a8fdb4bcSmrg}
260a8fdb4bcSmrg
261a8fdb4bcSmrgunsigned int
262a8fdb4bcSmrgmapping_hkscs(unsigned int n, OtherStatePtr s)
263a8fdb4bcSmrg{
264a8fdb4bcSmrg    unsigned int r;
265a8fdb4bcSmrg    if(n < 128) return n;
266a8fdb4bcSmrg    if(n == 128) return EURO_10646;
267a8fdb4bcSmrg    r = FontEncRecode(n, s->hkscs.mapping);
268a8fdb4bcSmrg    return r;
269a8fdb4bcSmrg}
270a8fdb4bcSmrg
271a8fdb4bcSmrgunsigned int
272a8fdb4bcSmrgreverse_hkscs(unsigned int n, OtherStatePtr s)
273a8fdb4bcSmrg{
274a8fdb4bcSmrg    if(n < 128) return n;
275a8fdb4bcSmrg    if(n == EURO_10646) return 128;
276a8fdb4bcSmrg    return s->hkscs.reverse->reverse(n, s->hkscs.reverse->data);
277a8fdb4bcSmrg}
278a8fdb4bcSmrg
279a8fdb4bcSmrgint
280a8fdb4bcSmrgstack_hkscs(unsigned char c, OtherStatePtr s)
281a8fdb4bcSmrg{
282a8fdb4bcSmrg    if(s->hkscs.buf < 0) {
283a8fdb4bcSmrg        if(c < 129) return c;
284a8fdb4bcSmrg        s->hkscs.buf = c;
285a8fdb4bcSmrg	return -1;
286a8fdb4bcSmrg    } else {
287a8fdb4bcSmrg        int b;
288a8fdb4bcSmrg        if(c < 0x40 || c == 0x7F) {
289a8fdb4bcSmrg            s->hkscs.buf = -1;
290a8fdb4bcSmrg            return c;
291a8fdb4bcSmrg        }
292a8fdb4bcSmrg        if(s->hkscs.buf < 0xFF && c < 0xFF)
293a8fdb4bcSmrg            b = (s->hkscs.buf << 8) + c;
294a8fdb4bcSmrg        else
295a8fdb4bcSmrg            b = -1;
296a8fdb4bcSmrg        s->hkscs.buf = -1;
297a8fdb4bcSmrg        return b;
298a8fdb4bcSmrg    }
299a8fdb4bcSmrg}
300a8fdb4bcSmrg
301a8fdb4bcSmrg
302a8fdb4bcSmrg/*
303a8fdb4bcSmrg *  Because of the 1 ~ 4 multi-bytes nature of GB18030.
304a8fdb4bcSmrg *  CharSet encoding is split to 2 subset (besides latin)
305a8fdb4bcSmrg *  The 2Bytes MB char is defined in gb18030.2000-0
306a8fdb4bcSmrg *  The 4Bytes MB char is defined in gb18030.2000-1
307a8fdb4bcSmrg *  Please note that the mapping in 2000-1 is not a 4Bytes seq => 2Bytes value
308a8fdb4bcSmrg *  mapping.
309a8fdb4bcSmrg *  To use the 2000-1 we need to 'linear' the 4Bytes sequence and 'lookup' the
310a8fdb4bcSmrg *  unicode value after that.
311a8fdb4bcSmrg *
312a8fdb4bcSmrg *  For more info on GB18030 standard pls check:
313a8fdb4bcSmrg *    http://oss.software.ibm.com/icu/docs/papers/gb18030.html
314a8fdb4bcSmrg *
315a8fdb4bcSmrg *  For more info on GB18030 implementation issues in XFree86 pls check:
316a8fdb4bcSmrg *    http://www.ibm.com/developerWorks/cn/linux/i18n/gb18030/xfree86/part1
317a8fdb4bcSmrg */
318a8fdb4bcSmrgint
319a8fdb4bcSmrginit_gb18030(OtherStatePtr s)
320a8fdb4bcSmrg{
321a8fdb4bcSmrg    s->gb18030.cs0_mapping =
322a8fdb4bcSmrg        FontEncMapFind("gb18030.2000-0", FONT_ENCODING_UNICODE, -1, -1, NULL);
323a8fdb4bcSmrg    if(!s->gb18030.cs0_mapping) return 0;
324a8fdb4bcSmrg
325a8fdb4bcSmrg    s->gb18030.cs0_reverse = FontMapReverse(s->gb18030.cs0_mapping);
326a8fdb4bcSmrg    if(!s->gb18030.cs0_reverse) return 0;
327a8fdb4bcSmrg
328a8fdb4bcSmrg    s->gb18030.cs1_mapping =
329a8fdb4bcSmrg        FontEncMapFind("gb18030.2000-1", FONT_ENCODING_UNICODE, -1, -1, NULL);
330a8fdb4bcSmrg    if(!s->gb18030.cs1_mapping) return 0;
331a8fdb4bcSmrg
332a8fdb4bcSmrg    s->gb18030.cs1_reverse = FontMapReverse(s->gb18030.cs1_mapping);
333a8fdb4bcSmrg    if(!s->gb18030.cs1_reverse) return 0;
334a8fdb4bcSmrg
335a8fdb4bcSmrg    s->gb18030.linear  = 0;
336a8fdb4bcSmrg    s->gb18030.buf_ptr = 0;
337a8fdb4bcSmrg    return 1;
338a8fdb4bcSmrg}
339a8fdb4bcSmrg
340a8fdb4bcSmrgunsigned int
341a8fdb4bcSmrgmapping_gb18030(unsigned int n, OtherStatePtr s)
342a8fdb4bcSmrg{
343a8fdb4bcSmrg    if(n <= 0x80)   return n;       /* 0x80 is valid but unassigned codepoint */
344a8fdb4bcSmrg    if(n >= 0xFFFF) return '?';
345a8fdb4bcSmrg
346a8fdb4bcSmrg    return FontEncRecode(n,
347a8fdb4bcSmrg            (s->gb18030.linear)?s->gb18030.cs1_mapping:s->gb18030.cs0_mapping);
348a8fdb4bcSmrg}
349a8fdb4bcSmrg
350a8fdb4bcSmrgunsigned int
351a8fdb4bcSmrgreverse_gb18030(unsigned int n, OtherStatePtr s)
352a8fdb4bcSmrg{
353a8fdb4bcSmrg    /* when lookup in 2000-0 failed. */
354a8fdb4bcSmrg    /* lookup in 2000-1 and then try to unlinear'd */
355a8fdb4bcSmrg    unsigned int r;
356a8fdb4bcSmrg    if(n <= 0x80) return n;
357a8fdb4bcSmrg
358a8fdb4bcSmrg    r = s->gb18030.cs0_reverse->reverse(n, s->gb18030.cs0_reverse->data);
359a8fdb4bcSmrg    if (r != 0)
360a8fdb4bcSmrg        return r;
361a8fdb4bcSmrg
362a8fdb4bcSmrg    r = s->gb18030.cs1_reverse->reverse(n, s->gb18030.cs1_reverse->data);
363a8fdb4bcSmrg    if (r != 0) {
364a8fdb4bcSmrg        unsigned char bytes[4];
365a8fdb4bcSmrg
366a8fdb4bcSmrg        bytes[3] = 0x30 + r % 10;   r /= 10;
367a8fdb4bcSmrg        bytes[2] = 0x81 + r % 126;  r /= 126;
368a8fdb4bcSmrg        bytes[1] = 0x30 + r % 10;   r /= 10;
369a8fdb4bcSmrg        bytes[0] = 0x81 + r;
370a8fdb4bcSmrg
371a8fdb4bcSmrg        r  = (unsigned int)bytes[0] << 24;
372a8fdb4bcSmrg        r |= (unsigned int)bytes[1] << 16;
373a8fdb4bcSmrg        r |= (unsigned int)bytes[2] << 8;
374a8fdb4bcSmrg        r |= (unsigned int)bytes[3];
375a8fdb4bcSmrg    }
376a8fdb4bcSmrg    return r;
377a8fdb4bcSmrg}
378a8fdb4bcSmrg
379a8fdb4bcSmrgint
380a8fdb4bcSmrgstack_gb18030(unsigned char c, OtherStatePtr s)
381a8fdb4bcSmrg{
382a8fdb4bcSmrg    /* if set gb18030.linear => True. the return value is "linear'd" */
383a8fdb4bcSmrg    if(s->gb18030.buf_ptr == 0) {
384a8fdb4bcSmrg        if(c <= 0x80) return c;
385a8fdb4bcSmrg        if (c == 0xFF) return -1;
386a8fdb4bcSmrg        s->gb18030.linear = 0;
387a8fdb4bcSmrg        s->gb18030.buf[s->gb18030.buf_ptr++] = c;
388a8fdb4bcSmrg        return -1;
389a8fdb4bcSmrg    } else if (s->gb18030.buf_ptr == 1) {
390a8fdb4bcSmrg        if (c >= 0x40) {
391a8fdb4bcSmrg            s->gb18030.buf_ptr = 0;
392a8fdb4bcSmrg            if ((c == 0x80) || (c == 0xFF))
393a8fdb4bcSmrg                return -1;
394a8fdb4bcSmrg            else
395a8fdb4bcSmrg                return (s->gb18030.buf[0] << 8) + c;
396a8fdb4bcSmrg        } else if (c >= 30) {   /* 2Byte is (0x30 -> 0x39) */
397a8fdb4bcSmrg            s->gb18030.buf[s->gb18030.buf_ptr++] = c;
398a8fdb4bcSmrg            return -1;
399a8fdb4bcSmrg        } else {
400a8fdb4bcSmrg            s->gb18030.buf_ptr = 0;
401a8fdb4bcSmrg            return c;
402a8fdb4bcSmrg        }
403a8fdb4bcSmrg    } else if (s->gb18030.buf_ptr == 2) {
404a8fdb4bcSmrg        if ((c >= 0x81) && (c <= 0xFE)) {
405a8fdb4bcSmrg            s->gb18030.buf[s->gb18030.buf_ptr++] = c;
406a8fdb4bcSmrg            return -1;
407a8fdb4bcSmrg        } else {
408a8fdb4bcSmrg            s->gb18030.buf_ptr = 0;
409a8fdb4bcSmrg            return c;
410a8fdb4bcSmrg        }
411a8fdb4bcSmrg    } else {
412a8fdb4bcSmrg        int r = 0;
413a8fdb4bcSmrg        s->gb18030.buf_ptr = 0;
414a8fdb4bcSmrg        if ((c >= 0x30) && (c <= 0x39)) {
415a8fdb4bcSmrg            s->gb18030.linear = 1;
416a8fdb4bcSmrg            r = (((s->gb18030.buf[0] - 0x81) * 10
417a8fdb4bcSmrg                        + (s->gb18030.buf[1] - 0x30)) * 126
418a8fdb4bcSmrg                    + (s->gb18030.buf[2] - 0x81)) * 10
419a8fdb4bcSmrg                + (c - 0x30);
420a8fdb4bcSmrg            return r;
421a8fdb4bcSmrg        }
422a8fdb4bcSmrg        return -1;
423a8fdb4bcSmrg    }
424a8fdb4bcSmrg}
425a8fdb4bcSmrg
426