a508c848ef183d342789779a67267c77674bc819
[platform/upstream/glibc.git] / iconvdata / euc-tw.c
1 /* Mapping tables for EUC-TW handling.
2    Copyright (C) 1998, 1999, 2000 Free Software Foundation, Inc.
3    This file is part of the GNU C Library.
4    Contributed by Ulrich Drepper <drepper@cygnus.com>, 1998.
5
6    The GNU C Library is free software; you can redistribute it and/or
7    modify it under the terms of the GNU Library General Public License as
8    published by the Free Software Foundation; either version 2 of the
9    License, or (at your option) any later version.
10
11    The GNU C Library is distributed in the hope that it will be useful,
12    but WITHOUT ANY WARRANTY; without even the implied warranty of
13    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14    Library General Public License for more details.
15
16    You should have received a copy of the GNU Library General Public
17    License along with the GNU C Library; see the file COPYING.LIB.  If not,
18    write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19    Boston, MA 02111-1307, USA.  */
20
21 #include <stdint.h>
22 #include <cns11643l1.h>
23 #include <cns11643.h>
24
25 /* Definitions used in the body of the `gconv' function.  */
26 #define CHARSET_NAME            "EUC-TW//"
27 #define FROM_LOOP               from_euc_tw
28 #define TO_LOOP                 to_euc_tw
29 #define DEFINE_INIT             1
30 #define DEFINE_FINI             1
31 #define MIN_NEEDED_FROM         1
32 #define MAX_NEEDED_FROM         4
33 #define MIN_NEEDED_TO           4
34
35
36 /* First define the conversion function from EUC-TW to UCS4.  */
37 #define MIN_NEEDED_INPUT        MIN_NEEDED_FROM
38 #define MAX_NEEDED_INPUT        MAX_NEEDED_FROM
39 #define MIN_NEEDED_OUTPUT       MIN_NEEDED_TO
40 #define LOOPFCT                 FROM_LOOP
41 #define BODY \
42   {                                                                           \
43     uint32_t ch = *inptr;                                                     \
44                                                                               \
45     if (ch <= 0x7f)                                                           \
46       /* Plain ASCII.  */                                                     \
47       ++inptr;                                                                \
48     else if ((ch <= 0xa0 || ch > 0xfe) && ch != 0x8e)                         \
49       {                                                                       \
50         /* This is illegal.  */                                               \
51         result = __GCONV_ILLEGAL_INPUT;                                       \
52         break;                                                                \
53       }                                                                       \
54     else                                                                      \
55       {                                                                       \
56         /* Two or more byte character.  First test whether the next           \
57            character is also available.  */                                   \
58         uint32_t ch2;                                                         \
59                                                                               \
60         if (NEED_LENGTH_TEST && inptr + (ch == 0x8e ? 3 : 1) >= inend)        \
61           {                                                                   \
62             /* The second character is not available.  Store the              \
63                intermediate result.  */                                       \
64             result = __GCONV_INCOMPLETE_INPUT;                                \
65             break;                                                            \
66           }                                                                   \
67                                                                               \
68         ch2 = *inptr;                                                         \
69                                                                               \
70         /* All second bytes of a multibyte character must be >= 0xa1. */      \
71         if (ch2 < 0xa1 || ch2 == 0xff)                                        \
72           {                                                                   \
73             /* This is an illegal character.  */                              \
74             result = __GCONV_ILLEGAL_INPUT;                                   \
75             break;                                                            \
76           }                                                                   \
77                                                                               \
78         if (ch == 0x8e)                                                       \
79           {                                                                   \
80             /* This is code set 2: CNS 11643, planes 1 to 16.  */             \
81             const char *endp = inptr + 1;                                     \
82                                                                               \
83             ch = cns11643_to_ucs4 (&endp,                                     \
84                                    NEED_LENGTH_TEST ? inend - inptr - 1 : 3,  \
85                                    0x80);                                     \
86             /* Please note that we need not test for the missing input        \
87                characters here anymore.  */                                   \
88             if (ch == __UNKNOWN_10646_CHAR)                                   \
89               {                                                               \
90                 /* Illegal input.  */                                         \
91                 result = __GCONV_ILLEGAL_INPUT;                               \
92                 break;                                                        \
93               }                                                               \
94                                                                               \
95             inptr += 4;                                                       \
96           }                                                                   \
97         else                                                                  \
98           {                                                                   \
99             /* This is code set 1: CNS 11643, plane 1.  */                    \
100             const unsigned char *endp = inptr;                                \
101                                                                               \
102             ch = cns11643l1_to_ucs4 (&endp,                                   \
103                                      NEED_LENGTH_TEST ? inend - inptr : 2,    \
104                                      0x80);                                   \
105             /* Please note that we need not test for the missing input        \
106                characters here anymore.  */                                   \
107             if (ch == __UNKNOWN_10646_CHAR)                                   \
108               {                                                               \
109                 /* Illegal input.  */                                         \
110                 result = __GCONV_ILLEGAL_INPUT;                               \
111                 break;                                                        \
112               }                                                               \
113                                                                               \
114             inptr += 2;                                                       \
115           }                                                                   \
116       }                                                                       \
117                                                                               \
118     put32 (outptr, ch);                                                       \
119     outptr += 4;                                                              \
120   }
121 #include <iconv/loop.c>
122
123
124 /* Next, define the other direction.  */
125 #define MIN_NEEDED_INPUT        MIN_NEEDED_TO
126 #define MIN_NEEDED_OUTPUT       MIN_NEEDED_FROM
127 #define MAX_NEEDED_OUTPUT       MAX_NEEDED_FROM
128 #define LOOPFCT                 TO_LOOP
129 #define BODY \
130   {                                                                           \
131     uint32_t ch = get32 (inptr);                                              \
132                                                                               \
133     if (ch <= 0x7f)                                                           \
134       /* It's plain ASCII.  */                                                \
135       *outptr++ = ch;                                                         \
136     else                                                                      \
137       {                                                                       \
138         /* Try the JIS character sets.  */                                    \
139         size_t found;                                                         \
140                                                                               \
141         found = ucs4_to_cns11643l1 (ch, outptr,                               \
142                                     NEED_LENGTH_TEST ? outend - outptr : 2);  \
143         if (NEED_LENGTH_TEST && found == 0)                                   \
144           {                                                                   \
145             /* We ran out of space.  */                                       \
146             result = __GCONV_INCOMPLETE_INPUT;                                \
147             break;                                                            \
148           }                                                                   \
149         if (found != __UNKNOWN_10646_CHAR)                                    \
150           {                                                                   \
151             /* It's a CNS 11643, plane 1 character, adjust it for EUC-TW.  */ \
152             *outptr++ += 0x80;                                                \
153             *outptr++ += 0x80;                                                \
154           }                                                                   \
155         else                                                                  \
156           {                                                                   \
157             /* No CNS 11643, plane 1 character.  */                           \
158                                                                               \
159             found = ucs4_to_cns11643 (ch, outptr + 1,                         \
160                                       (NEED_LENGTH_TEST                       \
161                                        ? outend - outptr - 1 : 3));           \
162             if (NEED_LENGTH_TEST && found == 0)                               \
163               {                                                               \
164                 /* We ran out of space.  */                                   \
165                 result = __GCONV_INCOMPLETE_INPUT;                            \
166                 break;                                                        \
167               }                                                               \
168             if (found == __UNKNOWN_10646_CHAR)                                \
169               {                                                               \
170                 /* No legal input.  */                                        \
171                 result = __GCONV_ILLEGAL_INPUT;                               \
172                 break;                                                        \
173               }                                                               \
174                                                                               \
175             /* It's a CNS 11643 character, adjust it for EUC-TW.  */          \
176             *outptr++ = '\x8e';                                               \
177             *outptr++ += 0xa0;                                                \
178             *outptr++ += 0x80;                                                \
179             *outptr++ += 0x80;                                                \
180           }                                                                   \
181       }                                                                       \
182                                                                               \
183     inptr += 4;                                                               \
184   }
185 #include <iconv/loop.c>
186
187
188 /* Now define the toplevel functions.  */
189 #include <iconv/skeleton.c>