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 : 0 : CODEC_INIT(big5hkscs)
20 : : {
21 : : static int initialized = 0;
22 : :
23 [ # # # # ]: 0 : if (!initialized && IMPORT_MAP(tw, big5, &big5_encmap, &big5_decmap))
24 : 0 : return -1;
25 : 0 : initialized = 1;
26 : 0 : 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 : 0 : ENCODER(big5hkscs)
40 : : {
41 [ # # ]: 0 : while (*inpos < inlen) {
42 : 0 : Py_UCS4 c = INCHAR1;
43 : : DBCHAR code;
44 : : Py_ssize_t insize;
45 : :
46 [ # # ]: 0 : if (c < 0x80) {
47 [ # # ]: 0 : REQUIRE_OUTBUF(1);
48 : 0 : **outbuf = (unsigned char)c;
49 : 0 : NEXT(1, 1);
50 : 0 : continue;
51 : : }
52 : :
53 : 0 : insize = 1;
54 [ # # ]: 0 : REQUIRE_OUTBUF(2);
55 : :
56 [ # # ]: 0 : if (c < 0x10000) {
57 [ # # # # : 0 : if (TRYMAP_ENC(big5hkscs_bmp, code, c)) {
# # # # ]
58 [ # # ]: 0 : if (code == MULTIC) {
59 : : Py_UCS4 c2;
60 [ # # ]: 0 : if (inlen - *inpos >= 2)
61 : 0 : c2 = INCHAR2;
62 : : else
63 : 0 : c2 = 0;
64 : :
65 [ # # ]: 0 : if (inlen - *inpos >= 2 &&
66 [ # # ]: 0 : ((c & 0xffdf) == 0x00ca) &&
67 [ # # ]: 0 : ((c2 & 0xfff7) == 0x0304)) {
68 : 0 : code = big5hkscs_pairenc_table[
69 : 0 : ((c >> 4) |
70 : 0 : (c2 >> 3)) & 3];
71 : 0 : insize = 2;
72 : : }
73 [ # # ]: 0 : else if (inlen - *inpos < 2 &&
74 [ # # ]: 0 : !(flags & MBENC_FLUSH))
75 : 0 : return MBERR_TOOFEW;
76 : : else {
77 [ # # ]: 0 : if (c == 0xca)
78 : 0 : code = 0x8866;
79 : : else /* c == 0xea */
80 : 0 : code = 0x88a7;
81 : : }
82 : : }
83 : : }
84 [ # # # # : 0 : else if (TRYMAP_ENC(big5, code, c))
# # # # ]
85 : : ;
86 : : else
87 : 0 : return 1;
88 : : }
89 [ # # ]: 0 : else if (c < 0x20000)
90 : 0 : return insize;
91 [ # # ]: 0 : else if (c < 0x30000) {
92 [ # # # # : 0 : if (TRYMAP_ENC(big5hkscs_nonbmp, code, c & 0xffff))
# # # # ]
93 : : ;
94 : : else
95 : 0 : return insize;
96 : : }
97 : : else
98 : 0 : return insize;
99 : :
100 : 0 : OUTBYTE1(code >> 8);
101 : 0 : OUTBYTE2(code & 0xFF);
102 : 0 : NEXT(insize, 2);
103 : : }
104 : :
105 : 0 : return 0;
106 : : }
107 : :
108 : : #define BH2S(c1, c2) (((c1) - 0x87) * (0xfe - 0x40 + 1) + ((c2) - 0x40))
109 : :
110 : 0 : DECODER(big5hkscs)
111 : : {
112 [ # # ]: 0 : while (inleft > 0) {
113 : 0 : unsigned char c = INBYTE1;
114 : : Py_UCS4 decoded;
115 : :
116 [ # # ]: 0 : if (c < 0x80) {
117 [ # # ]: 0 : OUTCHAR(c);
118 : 0 : NEXT_IN(1);
119 : 0 : continue;
120 : : }
121 : :
122 [ # # ]: 0 : REQUIRE_INBUF(2);
123 : :
124 [ # # # # : 0 : if (0xc6 > c || c > 0xc8 || (c < 0xc7 && INBYTE2 < 0xa1)) {
# # # # ]
125 [ # # # # : 0 : if (TRYMAP_DEC(big5, decoded, c, INBYTE2)) {
# # # # ]
126 [ # # ]: 0 : OUTCHAR(decoded);
127 : 0 : NEXT_IN(2);
128 : 0 : continue;
129 : : }
130 : : }
131 : :
132 [ # # # # : 0 : if (TRYMAP_DEC(big5hkscs, decoded, c, INBYTE2))
# # # # ]
133 : : {
134 : 0 : 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 [ # # # # ]: 0 : if (BH2S(0x87, 0x40) <= s && s <= BH2S(0xa0, 0xfe)) {
141 : 0 : hintbase = big5hkscs_phint_0;
142 : 0 : s -= BH2S(0x87, 0x40);
143 : : }
144 [ # # # # ]: 0 : else if (BH2S(0xc6,0xa1) <= s && s <= BH2S(0xc8,0xfe)){
145 : 0 : hintbase = big5hkscs_phint_12130;
146 : 0 : s -= BH2S(0xc6, 0xa1);
147 : : }
148 [ # # # # ]: 0 : else if (BH2S(0xf9,0xd6) <= s && s <= BH2S(0xfe,0xfe)){
149 : 0 : hintbase = big5hkscs_phint_21924;
150 : 0 : s -= BH2S(0xf9, 0xd6);
151 : : }
152 : : else
153 : 0 : return MBERR_INTERNAL;
154 : :
155 [ # # ]: 0 : if (hintbase[s >> 3] & (1 << (s & 7))) {
156 [ # # ]: 0 : OUTCHAR(decoded | 0x20000);
157 : 0 : NEXT_IN(2);
158 : : }
159 : : else {
160 [ # # ]: 0 : OUTCHAR(decoded);
161 : 0 : NEXT_IN(2);
162 : : }
163 : 0 : continue;
164 : : }
165 : :
166 [ # # # # : 0 : switch ((c << 8) | INBYTE2) {
# ]
167 [ # # # # : 0 : case 0x8862: OUTCHAR2(0x00ca, 0x0304); break;
# # ]
168 [ # # # # : 0 : case 0x8864: OUTCHAR2(0x00ca, 0x030c); break;
# # ]
169 [ # # # # : 0 : case 0x88a3: OUTCHAR2(0x00ea, 0x0304); break;
# # ]
170 [ # # # # : 0 : case 0x88a5: OUTCHAR2(0x00ea, 0x030c); break;
# # ]
171 : 0 : default: return 1;
172 : : }
173 : :
174 : 0 : NEXT_IN(2); /* all decoded code points are pairs, above. */
175 : : }
176 : :
177 : 0 : 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 : 1 : I_AM_A_MODULE_FOR(hk)
|