removed old libs
[TestXSLT.git] / libiconv / lib / gb18030.h
1 /*
2  * Copyright (C) 1999-2001 Free Software Foundation, Inc.
3  * This file is part of the GNU LIBICONV Library.
4  *
5  * The GNU LIBICONV Library is free software; you can redistribute it
6  * and/or modify it under the terms of the GNU Library General Public
7  * License as published by the Free Software Foundation; either version 2
8  * of the License, or (at your option) any later version.
9  *
10  * The GNU LIBICONV Library is distributed in the hope that it will be
11  * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * Library General Public License for more details.
14  *
15  * You should have received a copy of the GNU Library General Public
16  * License along with the GNU LIBICONV Library; see the file COPYING.LIB.
17  * If not, write to the Free Software Foundation, Inc., 59 Temple Place -
18  * Suite 330, Boston, MA 02111-1307, USA.
19  */
20
21 /*
22  * GB18030
23  */
24
25 /*
26  * GB18030, as implemented in glibc-2.2, is an extension of GBK (= CP936).
27  * It adds the following ranges:
28  * 1. Two-byte range
29  *    0xA2E3, 0xA8BF, 0xA98A..0xA995, 0xFE50..0xFE9F
30  * 2. Four-byte range
31  *    0x{81..84}{30..39}{81..FE}{30..39}
32  *    Most of Unicode plane 1 in Unicode order.
33  *    Start: 0x81308130 = 0x0080
34  *    End:   0x8431A439 = 0xFFFF
35  * 3. Four-byte range
36  *    0x{90..E3}{30..39}{81..FE}{30..39}
37  *    Unicode plane 2..16 in Unicode order.
38  *    Start: 0x90308130 = 0x010000
39  *    End:   0xE3329A35 = 0x10FFFF
40  */
41
42 #include "gb18030ext.h"
43 #include "gb18030uni.h"
44
45 static int
46 gb18030_mbtowc (conv_t conv, ucs4_t *pwc, const unsigned char *s, int n)
47 {
48   int ret;
49
50   /* Code set 0 (ASCII) */
51   if (*s < 0x80)
52     return ascii_mbtowc(conv,pwc,s,n);
53
54   /* Code set 1 (GBK extended) */
55   ret = gbk_mbtowc(conv,pwc,s,n);
56   if (ret != RET_ILSEQ)
57     return ret;
58
59   ret = gb18030ext_mbtowc(conv,pwc,s,n);
60   if (ret != RET_ILSEQ)
61     return ret;
62
63   /* Code set 2 (remainder of Unicode U+0000..U+FFFF) */
64   ret = gb18030uni_mbtowc(conv,pwc,s,n);
65   if (ret != RET_ILSEQ)
66     return ret;
67
68   /* Code set 3 (Unicode U+10000..U+10FFFF) */
69   {
70     unsigned char c1 = s[0];
71     if (c1 >= 0x90 && c1 <= 0xe3) {
72       if (n >= 2) {
73         unsigned char c2 = s[1];
74         if (c2 >= 0x30 && c2 <= 0x39) {
75           if (n >= 3) {
76             unsigned char c3 = s[2];
77             if (c3 >= 0x81 && c3 <= 0xfe) {
78               if (n >= 4) {
79                 unsigned char c4 = s[3];
80                 if (c4 >= 0x30 && c4 <= 0x39) {
81                   unsigned int i = (((c1 - 0x90) * 10 + (c2 - 0x30)) * 126 + (c3 - 0x81)) * 10 + (c4 - 0x30);
82                   if (i >= 0 && i < 0x100000) {
83                     *pwc = (ucs4_t) (0x10000 + i);
84                     return 4;
85                   }
86                 }
87                 return RET_ILSEQ;
88               }
89               return RET_TOOFEW(0);
90             }
91             return RET_ILSEQ;
92           }
93           return RET_TOOFEW(0);
94         }
95         return RET_ILSEQ;
96       }
97       return RET_TOOFEW(0);
98     }
99     return RET_ILSEQ;
100   }
101 }
102
103 static int
104 gb18030_wctomb (conv_t conv, unsigned char *r, ucs4_t wc, int n)
105 {
106   int ret;
107
108   /* Code set 0 (ASCII) */
109   ret = ascii_wctomb(conv,r,wc,n);
110   if (ret != RET_ILUNI)
111     return ret;
112
113   /* Code set 1 (GBK extended) */
114   ret = gbk_wctomb(conv,r,wc,n);
115   if (ret != RET_ILUNI)
116     return ret;
117
118   ret = gb18030ext_wctomb(conv,r,wc,n);
119   if (ret != RET_ILUNI)
120     return ret;
121
122   /* Code set 2 (remainder of Unicode U+0000..U+FFFF) */
123   ret = gb18030uni_wctomb(conv,r,wc,n);
124   if (ret != RET_ILUNI)
125     return ret;
126
127   /* Code set 3 (Unicode U+10000..U+10FFFF) */
128   if (n >= 4) {
129     if (wc >= 0x10000 && wc < 0x110000) {
130       unsigned int i = wc - 0x10000;
131       r[3] = (i % 10) + 0x30; i = i / 10;
132       r[2] = (i % 126) + 0x81; i = i / 126;
133       r[1] = (i % 10) + 0x30; i = i / 10;
134       r[0] = i + 0x90;
135       return 4;
136     }
137     return RET_ILUNI;
138   }
139   return RET_TOOSMALL;
140 }