Branch data Line data Source code
1 : : /*
2 : : * _codecs_jp.c: Codecs collection for Japanese encodings
3 : : *
4 : : * Written by Hye-Shik Chang <perky@FreeBSD.org>
5 : : */
6 : :
7 : : #define USING_BINARY_PAIR_SEARCH
8 : : #define EMPBASE 0x20000
9 : :
10 : : #include "cjkcodecs.h"
11 : : #include "mappings_jp.h"
12 : : #include "mappings_jisx0213_pair.h"
13 : : #include "alg_jisx0201.h"
14 : : #include "emu_jisx0213_2000.h"
15 : :
16 : : /*
17 : : * CP932 codec
18 : : */
19 : :
20 : 13406 : ENCODER(cp932)
21 : : {
22 [ + + ]: 87692 : while (*inpos < inlen) {
23 : 74414 : Py_UCS4 c = INCHAR1;
24 : : DBCHAR code;
25 : : unsigned char c1, c2;
26 : :
27 [ + + ]: 74414 : if (c <= 0x80) {
28 [ + + ]: 15773 : WRITEBYTE1((unsigned char)c);
29 : 15772 : NEXT(1, 1);
30 : 15772 : continue;
31 : : }
32 [ + + + + ]: 58641 : else if (c >= 0xff61 && c <= 0xff9f) {
33 [ - + ]: 63 : WRITEBYTE1(c - 0xfec0);
34 : 63 : NEXT(1, 1);
35 : 63 : continue;
36 : : }
37 [ + + + + ]: 58578 : else if (c >= 0xf8f0 && c <= 0xf8f3) {
38 : : /* Windows compatibility */
39 [ - + ]: 4 : REQUIRE_OUTBUF(1);
40 [ + + ]: 4 : if (c == 0xf8f0)
41 : 1 : OUTBYTE1(0xa0);
42 : : else
43 : 3 : OUTBYTE1(c - 0xf8f1 + 0xfd);
44 : 4 : NEXT(1, 1);
45 : 4 : continue;
46 : : }
47 : :
48 [ - + ]: 58574 : if (c > 0xFFFF)
49 : 0 : return 1;
50 [ - + ]: 58574 : REQUIRE_OUTBUF(2);
51 : :
52 [ + + + + : 58574 : if (TRYMAP_ENC(cp932ext, code, c)) {
+ + + + ]
53 : 454 : OUTBYTE1(code >> 8);
54 : 454 : OUTBYTE2(code & 0xff);
55 : : }
56 [ + + + - : 58120 : else if (TRYMAP_ENC(jisxcommon, code, c)) {
+ + + + ]
57 [ - + ]: 57993 : if (code & 0x8000) /* MSB set: JIS X 0212 */
58 : 0 : return 1;
59 : :
60 : : /* JIS X 0208 */
61 : 57993 : c1 = code >> 8;
62 : 57993 : c2 = code & 0xff;
63 [ + + ]: 57993 : c2 = (((c1 - 0x21) & 1) ? 0x5e : 0) + (c2 - 0x21);
64 : 57993 : c1 = (c1 - 0x21) >> 1;
65 [ + + ]: 57993 : OUTBYTE1(c1 < 0x1f ? c1 + 0x81 : c1 + 0xc1);
66 [ + + ]: 57993 : OUTBYTE2(c2 < 0x3f ? c2 + 0x40 : c2 + 0x41);
67 : : }
68 [ - + - - ]: 127 : else if (c >= 0xe000 && c < 0xe758) {
69 : : /* User-defined area */
70 : 0 : c1 = (Py_UCS4)(c - 0xe000) / 188;
71 : 0 : c2 = (Py_UCS4)(c - 0xe000) % 188;
72 : 0 : OUTBYTE1(c1 + 0xf0);
73 [ # # ]: 0 : OUTBYTE2(c2 < 0x3f ? c2 + 0x40 : c2 + 0x41);
74 : : }
75 : : else
76 : 127 : return 1;
77 : :
78 : 58447 : NEXT(1, 2);
79 : : }
80 : :
81 : 13278 : return 0;
82 : : }
83 : :
84 : 20248 : DECODER(cp932)
85 : : {
86 [ + + ]: 101286 : while (inleft > 0) {
87 : 86054 : unsigned char c = INBYTE1, c2;
88 : : Py_UCS4 decoded;
89 : :
90 [ + + ]: 86054 : if (c <= 0x80) {
91 [ - + ]: 20994 : OUTCHAR(c);
92 : 20994 : NEXT_IN(1);
93 : 20994 : continue;
94 : : }
95 [ + + + + ]: 65060 : else if (c >= 0xa0 && c <= 0xdf) {
96 [ + + ]: 190 : if (c == 0xa0)
97 [ - + ]: 1 : OUTCHAR(0xf8f0); /* half-width katakana */
98 : : else
99 [ - + ]: 189 : OUTCHAR(0xfec0 + c);
100 : 190 : NEXT_IN(1);
101 : 190 : continue;
102 : : }
103 [ + + ]: 64870 : else if (c >= 0xfd/* && c <= 0xff*/) {
104 : : /* Windows compatibility */
105 [ - + ]: 9 : OUTCHAR(0xf8f1 - 0xfd + c);
106 : 9 : NEXT_IN(1);
107 : 9 : continue;
108 : : }
109 : :
110 [ + + ]: 64861 : REQUIRE_INBUF(2);
111 : 59866 : c2 = INBYTE2;
112 : :
113 [ + + + + : 59866 : if (TRYMAP_DEC(cp932ext, decoded, c, c2))
+ + + - ]
114 [ - + ]: 2116 : OUTCHAR(decoded);
115 [ + - + + : 57750 : else if ((c >= 0x81 && c <= 0x9f) || (c >= 0xe0 && c <= 0xea)){
+ - + + ]
116 [ + + + + : 57729 : if (c2 < 0x40 || (c2 > 0x7e && c2 < 0x80) || c2 > 0xfc)
+ - - + ]
117 : 4 : return 1;
118 : :
119 [ + + ]: 57725 : c = (c < 0xe0 ? c - 0x81 : c - 0xc1);
120 [ + + ]: 57725 : c2 = (c2 < 0x80 ? c2 - 0x40 : c2 - 0x41);
121 : 57725 : c = (2 * c + (c2 < 0x5e ? 0 : 1) + 0x21);
122 [ + + ]: 57725 : c2 = (c2 < 0x5e ? c2 : c2 - 0x5e) + 0x21;
123 : :
124 [ + + + - : 57725 : if (TRYMAP_DEC(jisx0208, decoded, c, c2))
+ + + - ]
125 [ - + ]: 57718 : OUTCHAR(decoded);
126 : : else
127 : 7 : return 1;
128 : : }
129 [ + + + + ]: 21 : else if (c >= 0xf0 && c <= 0xf9) {
130 [ + + + + ]: 12 : if ((c2 >= 0x40 && c2 <= 0x7e) ||
131 [ + + + - ]: 11 : (c2 >= 0x80 && c2 <= 0xfc))
132 [ + + - + ]: 11 : OUTCHAR(0xe000 + 188 * (c - 0xf0) +
133 : : (c2 < 0x80 ? c2 - 0x40 : c2 - 0x41));
134 : : else
135 : 1 : return 1;
136 : : }
137 : : else
138 : 9 : return 1;
139 : :
140 : 59845 : NEXT_IN(2);
141 : : }
142 : :
143 : 15232 : return 0;
144 : : }
145 : :
146 : :
147 : : /*
148 : : * EUC-JIS-2004 codec
149 : : */
150 : :
151 : 23755 : ENCODER(euc_jis_2004)
152 : : {
153 [ + + ]: 173834 : while (*inpos < inlen) {
154 : 150665 : Py_UCS4 c = INCHAR1;
155 : : DBCHAR code;
156 : : Py_ssize_t insize;
157 : :
158 [ + + ]: 150665 : if (c < 0x80) {
159 [ + + ]: 32922 : WRITEBYTE1(c);
160 : 32920 : NEXT(1, 1);
161 : 32920 : continue;
162 : : }
163 : :
164 : 117743 : insize = 1;
165 : :
166 [ + + ]: 117743 : if (c <= 0xFFFF) {
167 [ + + + - : 116523 : EMULATE_JISX0213_2000_ENCODE_BMP(code, c)
+ - + - +
- + - + -
+ - + - +
- - + + +
- + ]
168 [ + + + + : 116523 : else if (TRYMAP_ENC(jisx0213_bmp, code, c)) {
+ + + + ]
169 [ + + ]: 10503 : if (code == MULTIC) {
170 [ + + ]: 5264 : if (inlen - *inpos < 2) {
171 [ + + ]: 355 : if (flags & MBENC_FLUSH) {
172 : 24 : code = find_pairencmap(
173 : 24 : (ucs2_t)c, 0,
174 : : jisx0213_pair_encmap,
175 : : JISX0213_ENCPAIRS);
176 [ - + ]: 24 : if (code == DBCINV)
177 : 0 : return 1;
178 : : }
179 : : else
180 : 331 : return MBERR_TOOFEW;
181 : : }
182 : : else {
183 : 4909 : Py_UCS4 c2 = INCHAR2;
184 : 4909 : code = find_pairencmap(
185 : 4909 : (ucs2_t)c, c2,
186 : : jisx0213_pair_encmap,
187 : : JISX0213_ENCPAIRS);
188 [ + + ]: 4909 : if (code == DBCINV) {
189 : 4287 : code = find_pairencmap(
190 : 4287 : (ucs2_t)c, 0,
191 : : jisx0213_pair_encmap,
192 : : JISX0213_ENCPAIRS);
193 [ - + ]: 4287 : if (code == DBCINV)
194 : 0 : return 1;
195 : : } else
196 : 622 : insize = 2;
197 : : }
198 : : }
199 : : }
200 [ + + + - : 106020 : else if (TRYMAP_ENC(jisxcommon, code, c))
+ + + + ]
201 : : ;
202 [ + + + - ]: 317 : else if (c >= 0xff61 && c <= 0xff9f) {
203 : : /* JIS X 0201 half-width katakana */
204 [ - + ]: 63 : WRITEBYTE2(0x8e, c - 0xfec0);
205 : 63 : NEXT(1, 2);
206 : 63 : continue;
207 : : }
208 [ - + ]: 254 : else if (c == 0xff3c)
209 : : /* F/W REVERSE SOLIDUS (see NOTES) */
210 : 0 : code = 0x2140;
211 [ + + ]: 254 : else if (c == 0xff5e)
212 : : /* F/W TILDE (see NOTES) */
213 : 1 : code = 0x2232;
214 : : else
215 : 253 : return 1;
216 : : }
217 [ + - ]: 1220 : else if (c >> 16 == EMPBASE >> 16) {
218 [ + + - + ]: 1220 : EMULATE_JISX0213_2000_ENCODE_EMP(code, c)
219 [ + - + - : 1220 : else if (TRYMAP_ENC(jisx0213_emp, code, c & 0xffff))
+ - + - ]
220 : : ;
221 : : else
222 : 0 : return insize;
223 : : }
224 : : else
225 : 0 : return insize;
226 : :
227 [ + + ]: 117096 : if (code & 0x8000) {
228 : : /* Codeset 2 */
229 [ - + ]: 3659 : WRITEBYTE3(0x8f, code >> 8, (code & 0xFF) | 0x80);
230 : 3659 : NEXT(insize, 3);
231 : : } else {
232 : : /* Codeset 1 */
233 [ - + ]: 113437 : WRITEBYTE2((code >> 8) | 0x80, (code & 0xFF) | 0x80);
234 : 113437 : NEXT(insize, 2);
235 : : }
236 : : }
237 : :
238 : 23169 : return 0;
239 : : }
240 : :
241 : 38117 : DECODER(euc_jis_2004)
242 : : {
243 [ + + ]: 201554 : while (inleft > 0) {
244 : 174021 : unsigned char c = INBYTE1;
245 : : Py_UCS4 code, decoded;
246 : :
247 [ + + ]: 174021 : if (c < 0x80) {
248 [ - + ]: 43332 : OUTCHAR(c);
249 : 43332 : NEXT_IN(1);
250 : 43332 : continue;
251 : : }
252 : :
253 [ + + ]: 130689 : if (c == 0x8e) {
254 : : /* JIS X 0201 half-width katakana */
255 : : unsigned char c2;
256 : :
257 [ - + ]: 69 : REQUIRE_INBUF(2);
258 : 69 : c2 = INBYTE2;
259 [ + + + - ]: 69 : if (c2 >= 0xa1 && c2 <= 0xdf) {
260 [ - + ]: 63 : OUTCHAR(0xfec0 + c2);
261 : 63 : NEXT_IN(2);
262 : : }
263 : : else
264 : 6 : return 1;
265 : : }
266 [ + + ]: 130620 : else if (c == 0x8f) {
267 : : unsigned char c2, c3;
268 : :
269 [ + + ]: 3989 : REQUIRE_INBUF(3);
270 : 3697 : c2 = INBYTE2 ^ 0x80;
271 : 3697 : c3 = INBYTE3 ^ 0x80;
272 : :
273 : : /* JIS X 0213 Plane 2 or JIS X 0212 (see NOTES) */
274 [ + + + + : 3697 : EMULATE_JISX0213_2000_DECODE_PLANE2(writer, c2, c3)
- + - - ]
275 [ + + + + : 3697 : else if (TRYMAP_DEC(jisx0213_2_bmp, decoded, c2, c3))
+ + + + ]
276 [ - + ]: 2786 : OUTCHAR(decoded);
277 [ + + + - : 911 : else if (TRYMAP_DEC(jisx0213_2_emp, code, c2, c3)) {
+ - + - ]
278 [ - + ]: 905 : OUTCHAR(EMPBASE | code);
279 : 905 : NEXT_IN(3);
280 : 905 : continue;
281 : : }
282 [ - + - - : 6 : else if (TRYMAP_DEC(jisx0212, decoded, c2, c3))
- - - - ]
283 [ # # ]: 0 : OUTCHAR(decoded);
284 : : else
285 : 6 : return 1;
286 : 2786 : NEXT_IN(3);
287 : : }
288 : : else {
289 : : unsigned char c2;
290 : :
291 [ + + ]: 126631 : REQUIRE_INBUF(2);
292 : 116497 : c ^= 0x80;
293 : 116497 : c2 = INBYTE2 ^ 0x80;
294 : :
295 : : /* JIS X 0213 Plane 1 */
296 [ + + + + : 116497 : EMULATE_JISX0213_2000_DECODE_PLANE1(writer, c, c2)
+ - + + +
- + + + -
+ + + - +
+ + - + +
+ - + + +
- + + + -
+ + + - +
+ - + ]
297 [ + + + + ]: 116497 : else if (c == 0x21 && c2 == 0x40)
298 [ - + ]: 4 : OUTCHAR(0xff3c);
299 [ + + + + ]: 116493 : else if (c == 0x22 && c2 == 0x32)
300 [ - + ]: 1 : OUTCHAR(0xff5e);
301 [ + + + + : 116492 : else if (TRYMAP_DEC(jisx0208, decoded, c, c2))
+ + + + ]
302 [ - + ]: 112850 : OUTCHAR(decoded);
303 [ + + + - : 3642 : else if (TRYMAP_DEC(jisx0213_1_bmp, decoded, c, c2))
+ + + + ]
304 [ - + ]: 2527 : OUTCHAR(decoded);
305 [ + + + - : 1115 : else if (TRYMAP_DEC(jisx0213_1_emp, code, c, c2)) {
+ + + - ]
306 [ - + ]: 339 : OUTCHAR(EMPBASE | code);
307 : 339 : NEXT_IN(2);
308 : 339 : continue;
309 : : }
310 [ + + + - : 776 : else if (TRYMAP_DEC(jisx0213_pair, code, c, c2)) {
+ - + - ]
311 [ + + - + : 630 : OUTCHAR2(code >> 16, code & 0xffff);
- + ]
312 : 630 : NEXT_IN(2);
313 : 630 : continue;
314 : : }
315 : : else
316 : 146 : return 1;
317 : 115382 : NEXT_IN(2);
318 : : }
319 : : }
320 : :
321 : 27533 : return 0;
322 : : }
323 : :
324 : :
325 : : /*
326 : : * EUC-JP codec
327 : : */
328 : :
329 : 19023 : ENCODER(euc_jp)
330 : : {
331 [ + + ]: 98938 : while (*inpos < inlen) {
332 : 80043 : Py_UCS4 c = INCHAR1;
333 : : DBCHAR code;
334 : :
335 [ + + ]: 80043 : if (c < 0x80) {
336 [ + + ]: 15778 : WRITEBYTE1((unsigned char)c);
337 : 15777 : NEXT(1, 1);
338 : 15777 : continue;
339 : : }
340 : :
341 [ - + ]: 64265 : if (c > 0xFFFF)
342 : 0 : return 1;
343 : :
344 [ + + + - : 64265 : if (TRYMAP_ENC(jisxcommon, code, c))
+ + + + ]
345 : : ;
346 [ + + + - ]: 192 : else if (c >= 0xff61 && c <= 0xff9f) {
347 : : /* JIS X 0201 half-width katakana */
348 [ - + ]: 63 : WRITEBYTE2(0x8e, c - 0xfec0);
349 : 63 : NEXT(1, 2);
350 : 63 : continue;
351 : : }
352 : : #ifndef STRICT_BUILD
353 [ - + ]: 129 : else if (c == 0xff3c) /* FULL-WIDTH REVERSE SOLIDUS */
354 : 0 : code = 0x2140;
355 [ + + ]: 129 : else if (c == 0xa5) { /* YEN SIGN */
356 [ - + ]: 1 : WRITEBYTE1(0x5c);
357 : 1 : NEXT(1, 1);
358 : 1 : continue;
359 [ + + ]: 128 : } else if (c == 0x203e) { /* OVERLINE */
360 [ - + ]: 1 : WRITEBYTE1(0x7e);
361 : 1 : NEXT(1, 1);
362 : 1 : continue;
363 : : }
364 : : #endif
365 : : else
366 : 127 : return 1;
367 : :
368 [ + + ]: 64073 : if (code & 0x8000) {
369 : : /* JIS X 0212 */
370 [ - + ]: 6066 : WRITEBYTE3(0x8f, code >> 8, (code & 0xFF) | 0x80);
371 : 6066 : NEXT(1, 3);
372 : : } else {
373 : : /* JIS X 0208 */
374 [ - + ]: 58007 : WRITEBYTE2((code >> 8) | 0x80, (code & 0xFF) | 0x80);
375 : 58007 : NEXT(1, 2);
376 : : }
377 : : }
378 : :
379 : 18895 : return 0;
380 : : }
381 : :
382 : 25975 : DECODER(euc_jp)
383 : : {
384 [ + + ]: 112586 : while (inleft > 0) {
385 : 91727 : unsigned char c = INBYTE1;
386 : : Py_UCS4 decoded;
387 : :
388 [ + + ]: 91727 : if (c < 0x80) {
389 [ - + ]: 20996 : OUTCHAR(c);
390 : 20996 : NEXT_IN(1);
391 : 20996 : continue;
392 : : }
393 : :
394 [ + + ]: 70731 : if (c == 0x8e) {
395 : : /* JIS X 0201 half-width katakana */
396 : : unsigned char c2;
397 : :
398 [ - + ]: 66 : REQUIRE_INBUF(2);
399 : 66 : c2 = INBYTE2;
400 [ + + + - ]: 66 : if (c2 >= 0xa1 && c2 <= 0xdf) {
401 [ - + ]: 63 : OUTCHAR(0xfec0 + c2);
402 : 63 : NEXT_IN(2);
403 : : }
404 : : else
405 : 3 : return 1;
406 : : }
407 [ + + ]: 70665 : else if (c == 0x8f) {
408 : : unsigned char c2, c3;
409 : :
410 [ - + ]: 6069 : REQUIRE_INBUF(3);
411 : 6069 : c2 = INBYTE2;
412 : 6069 : c3 = INBYTE3;
413 : : /* JIS X 0212 */
414 [ + + + - : 6069 : if (TRYMAP_DEC(jisx0212, decoded, c2 ^ 0x80, c3 ^ 0x80)) {
+ - + - ]
415 [ - + ]: 6066 : OUTCHAR(decoded);
416 : 6066 : NEXT_IN(3);
417 : : }
418 : : else
419 : 3 : return 1;
420 : : }
421 : : else {
422 : : unsigned char c2;
423 : :
424 [ + + ]: 64596 : REQUIRE_INBUF(2);
425 : 59595 : c2 = INBYTE2;
426 : : /* JIS X 0208 */
427 : : #ifndef STRICT_BUILD
428 [ + + + + ]: 59595 : if (c == 0xa1 && c2 == 0xc0)
429 : : /* FULL-WIDTH REVERSE SOLIDUS */
430 [ - + ]: 2 : OUTCHAR(0xff3c);
431 : : else
432 : : #endif
433 [ + + + + : 59593 : if (TRYMAP_DEC(jisx0208, decoded, c ^ 0x80, c2 ^ 0x80))
+ + + - ]
434 [ - + ]: 59484 : OUTCHAR(decoded);
435 : : else
436 : 109 : return 1;
437 : 59486 : NEXT_IN(2);
438 : : }
439 : : }
440 : :
441 : 20859 : return 0;
442 : : }
443 : :
444 : :
445 : : /*
446 : : * SHIFT_JIS codec
447 : : */
448 : :
449 : 12882 : ENCODER(shift_jis)
450 : : {
451 [ + + ]: 86635 : while (*inpos < inlen) {
452 : 73882 : Py_UCS4 c = INCHAR1;
453 : : DBCHAR code;
454 : : unsigned char c1, c2;
455 : :
456 : : #ifdef STRICT_BUILD
457 : : JISX0201_R_ENCODE(c, code)
458 : : #else
459 [ + + ]: 73882 : if (c < 0x80)
460 : 15739 : code = c;
461 [ + + ]: 58143 : else if (c == 0x00a5)
462 : 1 : code = 0x5c; /* YEN SIGN */
463 [ + + ]: 58142 : else if (c == 0x203e)
464 : 1 : code = 0x7e; /* OVERLINE */
465 : : #endif
466 [ + + - + ]: 58141 : else JISX0201_K_ENCODE(c, code)
467 [ - + ]: 58141 : else if (c > 0xFFFF)
468 : 0 : return 1;
469 : : else
470 : 58141 : code = NOCHAR;
471 : :
472 [ + + + - : 73882 : if (code < 0x80 || (code >= 0xa1 && code <= 0xdf)) {
- + ]
473 [ + + ]: 15741 : REQUIRE_OUTBUF(1);
474 : :
475 : 15740 : OUTBYTE1((unsigned char)code);
476 : 15740 : NEXT(1, 1);
477 : 15740 : continue;
478 : : }
479 : :
480 [ - + ]: 58141 : REQUIRE_OUTBUF(2);
481 : :
482 [ + - ]: 58141 : if (code == NOCHAR) {
483 [ + + + - : 58141 : if (TRYMAP_ENC(jisxcommon, code, c))
+ + + + ]
484 : : ;
485 : : #ifndef STRICT_BUILD
486 [ - + ]: 127 : else if (c == 0xff3c)
487 : 0 : code = 0x2140; /* FULL-WIDTH REVERSE SOLIDUS */
488 : : #endif
489 : : else
490 : 127 : return 1;
491 : :
492 [ + + ]: 58014 : if (code & 0x8000) /* MSB set: JIS X 0212 */
493 : 1 : return 1;
494 : : }
495 : :
496 : 58013 : c1 = code >> 8;
497 : 58013 : c2 = code & 0xff;
498 [ + + ]: 58013 : c2 = (((c1 - 0x21) & 1) ? 0x5e : 0) + (c2 - 0x21);
499 : 58013 : c1 = (c1 - 0x21) >> 1;
500 [ + + ]: 58013 : OUTBYTE1(c1 < 0x1f ? c1 + 0x81 : c1 + 0xc1);
501 [ + + ]: 58013 : OUTBYTE2(c2 < 0x3f ? c2 + 0x40 : c2 + 0x41);
502 : 58013 : NEXT(1, 2);
503 : : }
504 : :
505 : 12753 : return 0;
506 : : }
507 : :
508 : 19752 : DECODER(shift_jis)
509 : : {
510 [ + + ]: 100172 : while (inleft > 0) {
511 : 85480 : unsigned char c = INBYTE1;
512 : : Py_UCS4 decoded;
513 : :
514 : : #ifdef STRICT_BUILD
515 : : JISX0201_R_DECODE(c, writer)
516 : : #else
517 [ + + ]: 85480 : if (c < 0x80)
518 [ - + ]: 20918 : OUTCHAR(c);
519 : : #endif
520 [ + + + + : 64562 : else JISX0201_K_DECODE(c, writer)
- + ]
521 [ + + + + : 64436 : else if ((c >= 0x81 && c <= 0x9f) || (c >= 0xe0 && c <= 0xea)){
+ + + + ]
522 : : unsigned char c1, c2;
523 : :
524 [ + + ]: 64382 : REQUIRE_INBUF(2);
525 : 59388 : c2 = INBYTE2;
526 [ + + + + : 59388 : if (c2 < 0x40 || (c2 > 0x7e && c2 < 0x80) || c2 > 0xfc)
+ - - + ]
527 : 1 : return 1;
528 : :
529 [ + + ]: 59387 : c1 = (c < 0xe0 ? c - 0x81 : c - 0xc1);
530 [ + + ]: 59387 : c2 = (c2 < 0x80 ? c2 - 0x40 : c2 - 0x41);
531 : 59387 : c1 = (2 * c1 + (c2 < 0x5e ? 0 : 1) + 0x21);
532 [ + + ]: 59387 : c2 = (c2 < 0x5e ? c2 : c2 - 0x5e) + 0x21;
533 : :
534 : : #ifndef STRICT_BUILD
535 [ + + + + ]: 59387 : if (c1 == 0x21 && c2 == 0x40) {
536 : : /* FULL-WIDTH REVERSE SOLIDUS */
537 [ - + ]: 1 : OUTCHAR(0xff3c);
538 : 1 : NEXT_IN(2);
539 : 1 : continue;
540 : : }
541 : : #endif
542 [ + + + - : 59386 : if (TRYMAP_DEC(jisx0208, decoded, c1, c2)) {
+ + + - ]
543 [ - + ]: 59375 : OUTCHAR(decoded);
544 : 59375 : NEXT_IN(2);
545 : 59375 : continue;
546 : : }
547 : : else
548 : 11 : return 1;
549 : : }
550 : : else
551 : 54 : return 1;
552 : :
553 : 21044 : NEXT_IN(1); /* JIS X 0201 */
554 : : }
555 : :
556 : 14692 : return 0;
557 : : }
558 : :
559 : :
560 : : /*
561 : : * SHIFT_JIS-2004 codec
562 : : */
563 : :
564 : 23370 : ENCODER(shift_jis_2004)
565 : : {
566 [ + + ]: 170770 : while (*inpos < inlen) {
567 : 147935 : Py_UCS4 c = INCHAR1;
568 : 147935 : DBCHAR code = NOCHAR;
569 : : int c1, c2;
570 : : Py_ssize_t insize;
571 : :
572 [ + + + - : 147935 : JISX0201_ENCODE(c, code)
+ - + + +
+ + + -
+ ]
573 : :
574 [ + + + - : 147935 : if (code < 0x80 || (code >= 0xa1 && code <= 0xdf)) {
- + ]
575 [ + + ]: 32165 : WRITEBYTE1((unsigned char)code);
576 : 32163 : NEXT(1, 1);
577 : 32163 : continue;
578 : : }
579 : :
580 [ - + ]: 115770 : REQUIRE_OUTBUF(2);
581 : 115770 : insize = 1;
582 : :
583 [ + - ]: 115770 : if (code == NOCHAR) {
584 [ + + ]: 115770 : if (c <= 0xffff) {
585 [ + + + - : 115009 : EMULATE_JISX0213_2000_ENCODE_BMP(code, c)
+ - + - +
- + - + -
+ - + - +
- - + + +
+ + ]
586 [ + + + + : 115008 : else if (TRYMAP_ENC(jisx0213_bmp, code, c)) {
+ + + + ]
587 [ + + ]: 9208 : if (code == MULTIC) {
588 [ + + ]: 4588 : if (inlen - *inpos < 2) {
589 [ + + ]: 304 : if (flags & MBENC_FLUSH) {
590 : 21 : code = find_pairencmap
591 : 21 : ((ucs2_t)c, 0,
592 : : jisx0213_pair_encmap,
593 : : JISX0213_ENCPAIRS);
594 [ - + ]: 21 : if (code == DBCINV)
595 : 0 : return 1;
596 : : }
597 : : else
598 : 283 : return MBERR_TOOFEW;
599 : : }
600 : : else {
601 : 4284 : Py_UCS4 ch2 = INCHAR2;
602 : 4284 : code = find_pairencmap(
603 : 4284 : (ucs2_t)c, ch2,
604 : : jisx0213_pair_encmap,
605 : : JISX0213_ENCPAIRS);
606 [ + + ]: 4284 : if (code == DBCINV) {
607 : 3978 : code = find_pairencmap(
608 : 3978 : (ucs2_t)c, 0,
609 : : jisx0213_pair_encmap,
610 : : JISX0213_ENCPAIRS);
611 [ - + ]: 3978 : if (code == DBCINV)
612 : 0 : return 1;
613 : : }
614 : : else
615 : 306 : insize = 2;
616 : : }
617 : : }
618 : : }
619 [ + + + - : 105800 : else if (TRYMAP_ENC(jisxcommon, code, c)) {
+ + + + ]
620 : : /* abandon JIS X 0212 codes */
621 [ - + ]: 105550 : if (code & 0x8000)
622 : 0 : return 1;
623 : : }
624 : : else
625 : 250 : return 1;
626 : : }
627 [ + - ]: 761 : else if (c >> 16 == EMPBASE >> 16) {
628 [ + - - + ]: 761 : EMULATE_JISX0213_2000_ENCODE_EMP(code, c)
629 [ + - + - : 761 : else if (TRYMAP_ENC(jisx0213_emp, code, c&0xffff))
+ - + - ]
630 : : ;
631 : : else
632 : 0 : return insize;
633 : : }
634 : : else
635 : 0 : return insize;
636 : : }
637 : :
638 : 115237 : c1 = code >> 8;
639 : 115237 : c2 = (code & 0xff) - 0x21;
640 : :
641 [ + + ]: 115237 : if (c1 & 0x80) {
642 : : /* Plane 2 */
643 [ + + ]: 3048 : if (c1 >= 0xee)
644 : 2202 : c1 -= 0x87;
645 [ + + + + ]: 846 : else if (c1 >= 0xac || c1 == 0xa8)
646 : 470 : c1 -= 0x49;
647 : : else
648 : 376 : c1 -= 0x43;
649 : : }
650 : : else {
651 : : /* Plane 1 */
652 : 112189 : c1 -= 0x21;
653 : : }
654 : :
655 [ + + ]: 115237 : if (c1 & 1)
656 : 71537 : c2 += 0x5e;
657 : 115237 : c1 >>= 1;
658 [ + + ]: 115237 : OUTBYTE1(c1 + (c1 < 0x1f ? 0x81 : 0xc1));
659 [ + + ]: 115237 : OUTBYTE2(c2 + (c2 < 0x3f ? 0x40 : 0x41));
660 : :
661 : 115237 : NEXT(insize, 2);
662 : : }
663 : :
664 : 22835 : return 0;
665 : : }
666 : :
667 : 37259 : DECODER(shift_jis_2004)
668 : : {
669 [ + + ]: 198147 : while (inleft > 0) {
670 : 171061 : unsigned char c = INBYTE1;
671 : :
672 [ + + - + : 171061 : JISX0201_DECODE(c, writer)
+ + - + +
+ - + + +
- + + + -
+ + + + +
- + ]
673 [ + + + + : 128261 : else if ((c >= 0x81 && c <= 0x9f) || (c >= 0xe0 && c <= 0xfc)){
+ + + + ]
674 : : unsigned char c1, c2;
675 : : Py_UCS4 code, decoded;
676 : :
677 [ + + ]: 128230 : REQUIRE_INBUF(2);
678 : 118094 : c2 = INBYTE2;
679 [ + + + + : 118094 : if (c2 < 0x40 || (c2 > 0x7e && c2 < 0x80) || c2 > 0xfc)
+ - + + ]
680 : 5 : return 1;
681 : :
682 [ + + ]: 118089 : c1 = (c < 0xe0 ? c - 0x81 : c - 0xc1);
683 [ + + ]: 118089 : c2 = (c2 < 0x80 ? c2 - 0x40 : c2 - 0x41);
684 : 118089 : c1 = (2 * c1 + (c2 < 0x5e ? 0 : 1));
685 [ + + ]: 118089 : c2 = (c2 < 0x5e ? c2 : c2 - 0x5e) + 0x21;
686 : :
687 [ + + ]: 118089 : if (c1 < 0x5e) { /* Plane 1 */
688 : 114999 : c1 += 0x21;
689 [ + + + + : 114999 : EMULATE_JISX0213_2000_DECODE_PLANE1(writer,
+ - + + +
- + + + -
+ + + - +
+ + - + +
+ - + + +
- + + + -
+ + + - +
+ - + ]
690 : : c1, c2)
691 [ + + + + : 114999 : else if (TRYMAP_DEC(jisx0208, decoded, c1, c2))
+ + + + ]
692 [ - + ]: 112313 : OUTCHAR(decoded);
693 [ + - + - : 2686 : else if (TRYMAP_DEC(jisx0213_1_bmp, decoded, c1, c2))
+ + + + ]
694 [ - + ]: 2190 : OUTCHAR(decoded);
695 [ + + + - : 496 : else if (TRYMAP_DEC(jisx0213_1_emp, code, c1, c2))
+ - + - ]
696 [ - + ]: 182 : OUTCHAR(EMPBASE | code);
697 [ + - + - : 314 : else if (TRYMAP_DEC(jisx0213_pair, code, c1, c2))
+ - + - ]
698 [ + + - + : 314 : OUTCHAR2(code >> 16, code & 0xffff);
- + ]
699 : : else
700 : 0 : return 1;
701 : 114999 : NEXT_IN(2);
702 : : }
703 : : else { /* Plane 2 */
704 [ + + ]: 3090 : if (c1 >= 0x67)
705 : 2236 : c1 += 0x07;
706 [ + + + + ]: 854 : else if (c1 >= 0x63 || c1 == 0x5f)
707 : 478 : c1 -= 0x37;
708 : : else
709 : 376 : c1 -= 0x3d;
710 : :
711 [ + + + + : 3090 : EMULATE_JISX0213_2000_DECODE_PLANE2(writer,
+ + - + ]
712 : : c1, c2)
713 [ + - + + : 3089 : else if (TRYMAP_DEC(jisx0213_2_bmp, decoded, c1, c2))
+ + + + ]
714 [ - + ]: 2497 : OUTCHAR(decoded);
715 [ + - + - : 592 : else if (TRYMAP_DEC(jisx0213_2_emp, code, c1, c2)) {
+ + + - ]
716 [ - + ]: 591 : OUTCHAR(EMPBASE | code);
717 : 591 : NEXT_IN(2);
718 : 591 : continue;
719 : : }
720 : : else
721 : 1 : return 1;
722 : 2498 : NEXT_IN(2);
723 : : }
724 : 117497 : continue;
725 : : }
726 : : else
727 : 31 : return 1;
728 : :
729 : 42800 : NEXT_IN(1); /* JIS X 0201 */
730 : : }
731 : :
732 : 27086 : return 0;
733 : : }
734 : :
735 : :
736 : : BEGIN_MAPPINGS_LIST
737 : : MAPPING_DECONLY(jisx0208)
738 : : MAPPING_DECONLY(jisx0212)
739 : : MAPPING_ENCONLY(jisxcommon)
740 : : MAPPING_DECONLY(jisx0213_1_bmp)
741 : : MAPPING_DECONLY(jisx0213_2_bmp)
742 : : MAPPING_ENCONLY(jisx0213_bmp)
743 : : MAPPING_DECONLY(jisx0213_1_emp)
744 : : MAPPING_DECONLY(jisx0213_2_emp)
745 : : MAPPING_ENCONLY(jisx0213_emp)
746 : : MAPPING_ENCDEC(jisx0213_pair)
747 : : MAPPING_ENCDEC(cp932ext)
748 : : END_MAPPINGS_LIST
749 : :
750 : : BEGIN_CODECS_LIST
751 : : CODEC_STATELESS(shift_jis)
752 : : CODEC_STATELESS(cp932)
753 : : CODEC_STATELESS(euc_jp)
754 : : CODEC_STATELESS(shift_jis_2004)
755 : : CODEC_STATELESS(euc_jis_2004)
756 : : { "euc_jisx0213", (void *)2000, NULL, _STATELESS_METHODS(euc_jis_2004) },
757 : : { "shift_jisx0213", (void *)2000, NULL, _STATELESS_METHODS(shift_jis_2004) },
758 : : END_CODECS_LIST
759 : :
760 : 13 : I_AM_A_MODULE_FOR(jp)
|