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