viet.c (6859B)
1 2 #include "wc.h" 3 #include "viet.h" 4 #include "wtf.h" 5 #include "search.h" 6 #ifdef USE_UNICODE 7 #include "ucs.h" 8 #endif 9 #include "map/tcvn57123_tcvn5712.map" 10 11 wc_uint8 wc_c0_tcvn57122_map[ 0x20 ] = { 12 0, 1, 1, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 14 }; 15 wc_uint8 wc_c0_viscii112_map[ 0x20 ] = { 16 0, 0, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 18 }; 19 wc_uint8 wc_c0_vps2_map[ 0x20 ] = { 20 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 1, 1, 0, 0, 22 }; 23 static wc_uint8 tcvn5712_precompose_map[ 0x100 ] = { 24 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 25 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 26 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 27 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 28 /* A E I O */ 29 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 30 /* U Y */ 31 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 32 /* a e i o */ 33 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 34 /* u y */ 35 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 36 37 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 38 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 39 /* A( A^ E^ O^ O+ U+ a( a^ e^ o^ o+ u+ */ 40 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 41 /* ` ? ~ ' . */ 42 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 43 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 44 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 45 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 46 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 47 }; 48 static wc_uint8 cp1258_precompose_map[ 0x100 ] = { 49 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 51 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 52 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 53 /* A E I O */ 54 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 55 /* U Y */ 56 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 57 /* a e i o */ 58 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 59 /* u y */ 60 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 61 62 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 64 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 65 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 66 /* A^ A( E^ ` */ 67 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 0, 2, 0, 0, 0, 68 /* ? O^ O+ U+ ~ */ 69 0, 0, 2, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 2, 0, 70 /* a^ a( e^ ' */ 71 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 0, 2, 0, 0, 0, 72 /* . o^ o+ u+ */ 73 0, 0, 2, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 74 }; 75 76 wc_uint32 77 wc_tcvn5712_precompose(wc_uchar c1, wc_uchar c2) 78 { 79 if (tcvn5712_precompose_map[c1] == 1 && tcvn5712_precompose_map[c2] == 2) 80 return ((wc_uint32)c1 << 8) | c2; 81 else 82 return 0; 83 } 84 85 wc_wchar_t 86 wc_tcvn57123_to_tcvn5712(wc_wchar_t cc) 87 { 88 wc_map *map; 89 90 map = wc_map_search((wc_uint16)(cc.code & 0x7f7f), 91 tcvn57123_tcvn5712_map, N_tcvn57123_tcvn5712_map); 92 if (map) { 93 cc.ccs = (map->code2 < 0x20) ? WC_CCS_TCVN_5712_2 : WC_CCS_TCVN_5712_1; 94 cc.code = map->code2 | 0x80; 95 } else { 96 cc.ccs = WC_CCS_UNKNOWN; 97 } 98 return cc; 99 } 100 101 wc_uint32 102 wc_cp1258_precompose(wc_uchar c1, wc_uchar c2) 103 { 104 if (cp1258_precompose_map[c1] == 1 && cp1258_precompose_map[c2] == 2) 105 return ((wc_uint32)c1 << 8) | c2; 106 else 107 return 0; 108 } 109 110 Str 111 wc_conv_from_viet(Str is, wc_ces ces) 112 { 113 Str os; 114 wc_uchar *sp = (wc_uchar *)is->ptr; 115 wc_uchar *ep = sp + is->length; 116 wc_uchar *p; 117 wc_ccs ccs1 = WcCesInfo[WC_CCS_INDEX(ces)].gset[1].ccs; 118 wc_ccs ccs2 = WcCesInfo[WC_CCS_INDEX(ces)].gset[2].ccs; 119 wc_uint8 *map = NULL; 120 121 switch (ces) { 122 case WC_CES_TCVN_5712: 123 map = wc_c0_tcvn57122_map; 124 break; 125 case WC_CES_VISCII_11: 126 map = wc_c0_viscii112_map; 127 break; 128 case WC_CES_VPS: 129 map = wc_c0_vps2_map; 130 break; 131 } 132 133 wc_create_detect_map(ces, WC_FALSE); 134 for (p = sp; p < ep && ! WC_DETECT_MAP[*p]; p++) 135 ; 136 if (p == ep) 137 return is; 138 os = Strnew_size(is->length); 139 if (p > sp) 140 Strcat_charp_n(os, is->ptr, (int)(p - sp)); 141 142 for (; p < ep; p++) { 143 if (*p & 0x80) 144 wtf_push(os, ccs1, (wc_uint32)*p); 145 else if (*p < 0x20 && map[*p]) 146 wtf_push(os, ccs2, (wc_uint32)*p); 147 else 148 Strcat_char(os, (char)*p); 149 } 150 return os; 151 } 152 153 void 154 wc_push_to_viet(Str os, wc_wchar_t cc, wc_status *st) 155 { 156 wc_ccs ccs1 = st->ces_info->gset[1].ccs; 157 wc_ccs ccs2 = 0, ccs3 = 0; 158 wc_uint8 *map = NULL; 159 160 switch (st->ces_info->id) { 161 case WC_CES_CP1258: 162 ccs3 = st->ces_info->gset[2].ccs; 163 break; 164 case WC_CES_TCVN_5712: 165 map = wc_c0_tcvn57122_map; 166 ccs2 = st->ces_info->gset[2].ccs; 167 ccs3 = st->ces_info->gset[3].ccs; 168 break; 169 case WC_CES_VISCII_11: 170 map = wc_c0_viscii112_map; 171 ccs2 = st->ces_info->gset[2].ccs; 172 break; 173 case WC_CES_VPS: 174 map = wc_c0_vps2_map; 175 ccs2 = st->ces_info->gset[2].ccs; 176 break; 177 } 178 179 while (1) { 180 if (cc.ccs == ccs1) { 181 Strcat_char(os, (char)(cc.code | 0x80)); 182 return; 183 } else if (cc.ccs == ccs2) { 184 Strcat_char(os, (char)(cc.code & 0x7f)); 185 return; 186 } else if (cc.ccs == ccs3) { 187 Strcat_char(os, (char)((cc.code >> 8) & 0xff)); 188 Strcat_char(os, (char)(cc.code & 0xff)); 189 return; 190 } 191 switch (cc.ccs) { 192 case WC_CCS_US_ASCII: 193 if (cc.code < 0x20 && map && map[cc.code]) 194 Strcat_char(os, ' '); 195 else 196 Strcat_char(os, (char)cc.code); 197 return; 198 case WC_CCS_UNKNOWN_W: 199 if (!WcOption.no_replace) 200 Strcat_charp(os, WC_REPLACE_W); 201 return; 202 case WC_CCS_UNKNOWN: 203 if (!WcOption.no_replace) 204 Strcat_charp(os, WC_REPLACE); 205 return; 206 default: 207 #ifdef USE_UNICODE 208 if (WcOption.ucs_conv) 209 cc = wc_any_to_any_ces(cc, st); 210 else 211 #endif 212 cc.ccs = WC_CCS_IS_WIDE(cc.ccs) ? WC_CCS_UNKNOWN_W : WC_CCS_UNKNOWN; 213 continue; 214 } 215 } 216 } 217 218 Str 219 wc_char_conv_from_viet(wc_uchar c, wc_status *st) 220 { 221 Str os = Strnew_size(1); 222 wc_uint8 *map = NULL; 223 224 switch (st->ces_info->id) { 225 case WC_CES_TCVN_5712: 226 map = wc_c0_tcvn57122_map; 227 break; 228 case WC_CES_VISCII_11: 229 map = wc_c0_viscii112_map; 230 break; 231 case WC_CES_VPS: 232 map = wc_c0_vps2_map; 233 break; 234 } 235 236 if (c & 0x80) 237 wtf_push(os, st->ces_info->gset[1].ccs, (wc_uint32)c); 238 else if (c < 0x20 && map[c]) 239 wtf_push(os, st->ces_info->gset[2].ccs, (wc_uint32)c); 240 else 241 Strcat_char(os, (char)c); 242 return os; 243 }