Branch data Line data Source code
1 : : /*
2 : : * _codecs_hk.c: Codecs collection for encodings from Hong Kong
3 : : *
4 : : * Written by Hye-Shik Chang <perky@FreeBSD.org>
5 : : */
6 : :
7 : : #define USING_IMPORTED_MAPS
8 : :
9 : : #include "cjkcodecs.h"
10 : : #include "mappings_hk.h"
11 : :
12 : : /*
13 : : * BIG5HKSCS codec
14 : : */
15 : :
16 : : static const encode_map *big5_encmap = NULL;
17 : : static const decode_map *big5_decmap = NULL;
18 : :
19 : 6 : CODEC_INIT(big5hkscs)
20 : : {
21 : : static int initialized = 0;
22 : :
23 [ + - - + ]: 6 : if (!initialized && IMPORT_MAP(tw, big5, &big5_encmap, &big5_decmap))
24 : 0 : return -1;
25 : 6 : initialized = 1;
26 : 6 : return 0;
27 : : }
28 : :
29 : : /*
30 : : * There are four possible pair unicode -> big5hkscs maps as in HKSCS 2004:
31 : : * U+00CA U+0304 -> 8862 (U+00CA alone is mapped to 8866)
32 : : * U+00CA U+030C -> 8864
33 : : * U+00EA U+0304 -> 88a3 (U+00EA alone is mapped to 88a7)
34 : : * U+00EA U+030C -> 88a5
35 : : * These are handled by not mapping tables but a hand-written code.
36 : : */
37 : : static const DBCHAR big5hkscs_pairenc_table[4] = {0x8862, 0x8864, 0x88a3, 0x88a5};
38 : :
39 : 5485 : ENCODER(big5hkscs)
40 : : {
41 [ + + ]: 13974 : while (*inpos < inlen) {
42 : 8665 : Py_UCS4 c = INCHAR1;
43 : : DBCHAR code;
44 : : Py_ssize_t insize;
45 : :
46 [ + + ]: 8665 : if (c < 0x80) {
47 [ + + ]: 2023 : REQUIRE_OUTBUF(1);
48 : 2022 : **outbuf = (unsigned char)c;
49 : 2022 : NEXT(1, 1);
50 : 2022 : continue;
51 : : }
52 : :
53 : 6642 : insize = 1;
54 [ - + ]: 6642 : REQUIRE_OUTBUF(2);
55 : :
56 [ + + ]: 6642 : if (c < 0x10000) {
57 [ + + + + : 4796 : if (TRYMAP_ENC(big5hkscs_bmp, code, c)) {
+ - + + ]
58 [ + + ]: 4669 : if (code == MULTIC) {
59 : : Py_UCS4 c2;
60 [ + + ]: 815 : if (inlen - *inpos >= 2)
61 : 765 : c2 = INCHAR2;
62 : : else
63 : 50 : c2 = 0;
64 : :
65 [ + + ]: 815 : if (inlen - *inpos >= 2 &&
66 [ + - ]: 765 : ((c & 0xffdf) == 0x00ca) &&
67 [ + + ]: 765 : ((c2 & 0xfff7) == 0x0304)) {
68 : 306 : code = big5hkscs_pairenc_table[
69 : 306 : ((c >> 4) |
70 : 306 : (c2 >> 3)) & 3];
71 : 306 : insize = 2;
72 : : }
73 [ + + ]: 509 : else if (inlen - *inpos < 2 &&
74 [ + + ]: 50 : !(flags & MBENC_FLUSH))
75 : 48 : return MBERR_TOOFEW;
76 : : else {
77 [ + + ]: 461 : if (c == 0xca)
78 : 154 : code = 0x8866;
79 : : else /* c == 0xea */
80 : 307 : code = 0x88a7;
81 : : }
82 : : }
83 : : }
84 [ + + + - : 127 : else if (TRYMAP_ENC(big5, code, c))
+ - - + ]
85 : : ;
86 : : else
87 : 127 : return 1;
88 : : }
89 [ - + ]: 1846 : else if (c < 0x20000)
90 : 0 : return insize;
91 [ + - ]: 1846 : else if (c < 0x30000) {
92 [ + - + - : 1846 : if (TRYMAP_ENC(big5hkscs_nonbmp, code, c & 0xffff))
+ - + - ]
93 : : ;
94 : : else
95 : 0 : return insize;
96 : : }
97 : : else
98 : 0 : return insize;
99 : :
100 : 6467 : OUTBYTE1(code >> 8);
101 : 6467 : OUTBYTE2(code & 0xFF);
102 : 6467 : NEXT(insize, 2);
103 : : }
104 : :
105 : 5309 : return 0;
106 : : }
107 : :
108 : : #define BH2S(c1, c2) (((c1) - 0x87) * (0xfe - 0x40 + 1) + ((c2) - 0x40))
109 : :
110 : 5545 : DECODER(big5hkscs)
111 : : {
112 [ + + ]: 18985 : while (inleft > 0) {
113 : 13633 : unsigned char c = INBYTE1;
114 : : Py_UCS4 decoded;
115 : :
116 [ + + ]: 13633 : if (c < 0x80) {
117 [ - + ]: 6836 : OUTCHAR(c);
118 : 6836 : NEXT_IN(1);
119 : 6836 : continue;
120 : : }
121 : :
122 [ + + ]: 6797 : REQUIRE_INBUF(2);
123 : :
124 [ + + + + : 6677 : if (0xc6 > c || c > 0xc8 || (c < 0xc7 && INBYTE2 < 0xa1)) {
+ + - + ]
125 [ + + + - : 6314 : if (TRYMAP_DEC(big5, decoded, c, INBYTE2)) {
+ + + - ]
126 [ - + ]: 87 : OUTCHAR(decoded);
127 : 87 : NEXT_IN(2);
128 : 87 : continue;
129 : : }
130 : : }
131 : :
132 [ + + + - : 6590 : if (TRYMAP_DEC(big5hkscs, decoded, c, INBYTE2))
+ + + + ]
133 : 6203 : {
134 : 6203 : int s = BH2S(c, INBYTE2);
135 : : const unsigned char *hintbase;
136 : :
137 : : assert(0x87 <= c && c <= 0xfe);
138 : : assert(0x40 <= INBYTE2 && INBYTE2 <= 0xfe);
139 : :
140 [ + - + + ]: 6203 : if (BH2S(0x87, 0x40) <= s && s <= BH2S(0xa0, 0xfe)) {
141 : 5032 : hintbase = big5hkscs_phint_0;
142 : 5032 : s -= BH2S(0x87, 0x40);
143 : : }
144 [ + - + + ]: 1171 : else if (BH2S(0xc6,0xa1) <= s && s <= BH2S(0xc8,0xfe)){
145 : 361 : hintbase = big5hkscs_phint_12130;
146 : 361 : s -= BH2S(0xc6, 0xa1);
147 : : }
148 [ + - + - ]: 810 : else if (BH2S(0xf9,0xd6) <= s && s <= BH2S(0xfe,0xfe)){
149 : 810 : hintbase = big5hkscs_phint_21924;
150 : 810 : s -= BH2S(0xf9, 0xd6);
151 : : }
152 : : else
153 : 0 : return MBERR_INTERNAL;
154 : :
155 [ + + ]: 6203 : if (hintbase[s >> 3] & (1 << (s & 7))) {
156 [ - + ]: 1850 : OUTCHAR(decoded | 0x20000);
157 : 1850 : NEXT_IN(2);
158 : : }
159 : : else {
160 [ - + ]: 4353 : OUTCHAR(decoded);
161 : 4353 : NEXT_IN(2);
162 : : }
163 : 6203 : continue;
164 : : }
165 : :
166 [ + - + - : 387 : switch ((c << 8) | INBYTE2) {
+ ]
167 [ + + - + : 157 : case 0x8862: OUTCHAR2(0x00ca, 0x0304); break;
- + ]
168 [ # # # # : 0 : case 0x8864: OUTCHAR2(0x00ca, 0x030c); break;
# # ]
169 [ + + - + : 157 : case 0x88a3: OUTCHAR2(0x00ea, 0x0304); break;
- + ]
170 [ # # # # : 0 : case 0x88a5: OUTCHAR2(0x00ea, 0x030c); break;
# # ]
171 : 73 : default: return 1;
172 : : }
173 : :
174 : 314 : NEXT_IN(2); /* all decoded code points are pairs, above. */
175 : : }
176 : :
177 : 5352 : return 0;
178 : : }
179 : :
180 : :
181 : : BEGIN_MAPPINGS_LIST
182 : : MAPPING_DECONLY(big5hkscs)
183 : : MAPPING_ENCONLY(big5hkscs_bmp)
184 : : MAPPING_ENCONLY(big5hkscs_nonbmp)
185 : : END_MAPPINGS_LIST
186 : :
187 : : BEGIN_CODECS_LIST
188 : : CODEC_STATELESS_WINIT(big5hkscs)
189 : : END_CODECS_LIST
190 : :
191 : 7 : I_AM_A_MODULE_FOR(hk)
|