]> git.ipfire.org Git - thirdparty/glibc.git/blob - iconvdata/ibm932.c
Update.
[thirdparty/glibc.git] / iconvdata / ibm932.c
1 /* Conversion from and to IBM932.
2 Copyright (C) 2000-2002 Free Software Foundation, Inc.
3 This file is part of the GNU C Library.
4 Contributed by Masahide Washizawa <washi@jp.ibm.com>, 2000.
5
6 The GNU C Library is free software; you can redistribute it and/or
7 modify it under the terms of the GNU Lesser General Public
8 License as published by the Free Software Foundation; either
9 version 2.1 of the 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 Lesser General Public License for more details.
15
16 You should have received a copy of the GNU Lesser General Public
17 License along with the GNU C Library; if not, write to the Free
18 Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
19 02111-1307 USA. */
20
21 #include <dlfcn.h>
22 #include <stdint.h>
23 #include "ibm932.h"
24
25 #ifndef TRUE
26 #define TRUE 1
27 #define FALSE 0
28 #endif
29
30 #define FROM 0
31 #define TO 1
32
33 /* Definitions used in the body of the `gconv' function. */
34 #define CHARSET_NAME "IBM932//"
35 #define FROM_LOOP from_ibm932
36 #define TO_LOOP to_ibm932
37
38 /* Definitions of initialization and destructor function. */
39 #define DEFINE_INIT 1
40 #define DEFINE_FINI 1
41
42 #define MIN_NEEDED_FROM 1
43 #define MAX_NEEDED_FROM 2
44 #define MIN_NEEDED_TO 4
45
46 /* First, define the conversion function from IBM-932 to UCS4. */
47 #define MIN_NEEDED_INPUT MIN_NEEDED_FROM
48 #define MAX_NEEDED_INPUT MAX_NEEDED_FROM
49 #define MIN_NEEDED_OUTPUT MIN_NEEDED_TO
50 #define LOOPFCT FROM_LOOP
51 #define BODY \
52 { \
53 const struct gap *rp1 = __ibm932sb_to_ucs4_idx; \
54 const struct gap *rp2 = __ibm932db_to_ucs4_idx; \
55 uint32_t ch = *inptr; \
56 uint32_t res; \
57 \
58 if (__builtin_expect (ch >= 0xffff, 0)) \
59 { \
60 rp1 = NULL; \
61 rp2 = NULL; \
62 } \
63 else if (__builtin_expect (ch, 0) == 0x80 \
64 || __builtin_expect (ch, 0) == 0xa0 \
65 || __builtin_expect (ch, 0) == 0xfd \
66 || __builtin_expect (ch, 0) == 0xfe \
67 || __builtin_expect (ch, 0) == 0xff) \
68 { \
69 /* This is an illegal character. */ \
70 STANDARD_FROM_LOOP_ERR_HANDLER (1); \
71 } \
72 else \
73 { \
74 while (ch > rp1->end) \
75 ++rp1; \
76 } \
77 \
78 /* Use the IBM932 table for single byte. */ \
79 if (__builtin_expect (rp1 == NULL, 0) \
80 || __builtin_expect (ch < rp1->start, 0) \
81 || (res = __ibm932sb_to_ucs4[ch + rp1->idx], \
82 __builtin_expect (res, '\1') == 0 && ch != 0)) \
83 { \
84 \
85 /* Use the IBM932 table for double byte. */ \
86 if (__builtin_expect (inptr + 1 >= inend, 0)) \
87 { \
88 /* The second character is not available. \
89 Store the intermediate result. */ \
90 result = __GCONV_INCOMPLETE_INPUT; \
91 break; \
92 } \
93 \
94 ch = (ch * 0x100) + inptr[1]; \
95 while (ch > rp2->end) \
96 ++rp2; \
97 \
98 if (__builtin_expect (rp2 == NULL, 0) \
99 || __builtin_expect (ch < rp2->start, 0) \
100 || (res = __ibm932db_to_ucs4[ch + rp2->idx], \
101 __builtin_expect (res, '\1') == 0 && ch !=0)) \
102 { \
103 /* This is an illegal character. */ \
104 STANDARD_FROM_LOOP_ERR_HANDLER (2); \
105 } \
106 else \
107 { \
108 put32 (outptr, res); \
109 outptr += 4; \
110 inptr += 2; \
111 } \
112 } \
113 else \
114 { \
115 if (res == 0x1c) \
116 res = 0x1a; \
117 else if (res == 0x7f) \
118 res = 0x1c; \
119 else if (res == 0xa5) \
120 res = 0x5c; \
121 else if (res == 0x203e) \
122 res = 0x7e; \
123 else if (res == 0x1a) \
124 res = 0x7f; \
125 put32 (outptr, res); \
126 outptr += 4; \
127 inptr++; \
128 } \
129 }
130 #define LOOP_NEED_FLAGS
131 #include <iconv/loop.c>
132
133 /* Next, define the other direction. */
134 #define MIN_NEEDED_INPUT MIN_NEEDED_TO
135 #define MIN_NEEDED_OUTPUT MIN_NEEDED_FROM
136 #define MAX_NEEDED_OUTPUT MAX_NEEDED_FROM
137 #define LOOPFCT TO_LOOP
138 #define BODY \
139 { \
140 const struct gap *rp = __ucs4_to_ibm932sb_idx; \
141 unsigned char sc; \
142 uint32_t ch = get32 (inptr); \
143 uint16_t found = TRUE; \
144 uint32_t i; \
145 uint32_t low; \
146 uint32_t high; \
147 uint16_t pccode; \
148 \
149 if (__builtin_expect (ch >= 0xffff, 0)) \
150 { \
151 UNICODE_TAG_HANDLER (ch, 4); \
152 rp = NULL; \
153 } \
154 else \
155 while (ch > rp->end) \
156 ++rp; \
157 \
158 /* Use the UCS4 table for single byte. */ \
159 if (__builtin_expect (rp == NULL, 0) \
160 || __builtin_expect (ch < rp->start, 0) \
161 || (sc = __ucs4_to_ibm932sb[ch + rp->idx], \
162 __builtin_expect (sc, '\1') == '\0' && ch != L'\0')) \
163 { \
164 \
165 /* Use the UCS4 table for double byte. */ \
166 found = FALSE; \
167 low = 0; \
168 high = (sizeof (__ucs4_to_ibm932db) >> 1) \
169 / sizeof (__ucs4_to_ibm932db[0][FROM]); \
170 pccode = ch; \
171 while (low <= high) \
172 { \
173 i = (low + high) >> 1; \
174 if (pccode < __ucs4_to_ibm932db[i][FROM]) \
175 high = i - 1; \
176 else if (pccode > __ucs4_to_ibm932db[i][FROM]) \
177 low = i + 1; \
178 else \
179 { \
180 pccode = __ucs4_to_ibm932db[i][TO]; \
181 found = TRUE; \
182 break; \
183 } \
184 } \
185 if (found) \
186 { \
187 if (__builtin_expect (outptr + 2 > outend, 0)) \
188 { \
189 result = __GCONV_FULL_OUTPUT; \
190 break; \
191 } \
192 *outptr++ = pccode >> 8 & 0xff; \
193 *outptr++ = pccode & 0xff; \
194 } \
195 else \
196 { \
197 /* This is an illegal character. */ \
198 STANDARD_TO_LOOP_ERR_HANDLER (4); \
199 } \
200 } \
201 else \
202 { \
203 if (__builtin_expect (outptr + 1 > outend, 0)) \
204 { \
205 result = __GCONV_FULL_OUTPUT; \
206 break; \
207 } \
208 if (ch == 0x5c) \
209 *outptr++ = 0x5c; \
210 else if (ch == 0x7e) \
211 *outptr++ = 0x7e; \
212 else \
213 *outptr++ = sc; \
214 } \
215 \
216 /* Now that we wrote the output increment the input pointer. */ \
217 inptr += 4; \
218 }
219 #define LOOP_NEED_FLAGS
220 #include <iconv/loop.c>
221
222 /* Now define the toplevel functions. */
223 #include <iconv/skeleton.c>