OLD | NEW |
1 // Copyright 2014 PDFium Authors. All rights reserved. | 1 // Copyright 2014 PDFium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com | 5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com |
6 | 6 |
7 #include "core/fxcrt/include/fx_ext.h" | 7 #include "core/fxcrt/include/fx_ext.h" |
8 #include "xfa/fgas/crt/fgas_codepage.h" | 8 #include "xfa/fgas/crt/fgas_codepage.h" |
9 #include "xfa/fgas/crt/fgas_language.h" | 9 #include "xfa/fgas/crt/fgas_language.h" |
10 | 10 |
11 static const FX_CHARSET_MAP g_FXCharset2CodePageTable[] = { | 11 namespace { |
| 12 |
| 13 struct FX_STR2CPHASH { |
| 14 uint32_t uHash; |
| 15 uint16_t uCodePage; |
| 16 }; |
| 17 |
| 18 struct FX_CHARSET_MAP { |
| 19 uint16_t charset; |
| 20 uint16_t codepage; |
| 21 }; |
| 22 |
| 23 struct FX_LANG2CPMAP { |
| 24 uint16_t wLanguage; |
| 25 uint16_t wCodepage; |
| 26 }; |
| 27 |
| 28 const FX_CHARSET_MAP g_FXCharset2CodePageTable[] = { |
12 {0, 1252}, {1, 0}, {2, 42}, {77, 10000}, {78, 10001}, | 29 {0, 1252}, {1, 0}, {2, 42}, {77, 10000}, {78, 10001}, |
13 {79, 10003}, {80, 10008}, {81, 10002}, {83, 10005}, {84, 10004}, | 30 {79, 10003}, {80, 10008}, {81, 10002}, {83, 10005}, {84, 10004}, |
14 {85, 10006}, {86, 10081}, {87, 10021}, {88, 10029}, {89, 10007}, | 31 {85, 10006}, {86, 10081}, {87, 10021}, {88, 10029}, {89, 10007}, |
15 {128, 932}, {129, 949}, {130, 1361}, {134, 936}, {136, 950}, | 32 {128, 932}, {129, 949}, {130, 1361}, {134, 936}, {136, 950}, |
16 {161, 1253}, {162, 1254}, {163, 1258}, {177, 1255}, {178, 1256}, | 33 {161, 1253}, {162, 1254}, {163, 1258}, {177, 1255}, {178, 1256}, |
17 {186, 1257}, {204, 1251}, {222, 874}, {238, 1250}, {254, 437}, | 34 {186, 1257}, {204, 1251}, {222, 874}, {238, 1250}, {254, 437}, |
18 {255, 850}, | 35 {255, 850}, |
19 }; | 36 }; |
20 uint16_t FX_GetCodePageFromCharset(uint8_t charset) { | 37 |
21 int32_t iEnd = sizeof(g_FXCharset2CodePageTable) / sizeof(FX_CHARSET_MAP) - 1; | 38 const FX_CHARSET_MAP g_FXCodepage2CharsetTable[] = { |
22 ASSERT(iEnd >= 0); | |
23 int32_t iStart = 0, iMid; | |
24 do { | |
25 iMid = (iStart + iEnd) / 2; | |
26 const FX_CHARSET_MAP& cp = g_FXCharset2CodePageTable[iMid]; | |
27 if (charset == cp.charset) { | |
28 return cp.codepage; | |
29 } else if (charset < cp.charset) { | |
30 iEnd = iMid - 1; | |
31 } else { | |
32 iStart = iMid + 1; | |
33 } | |
34 } while (iStart <= iEnd); | |
35 return 0xFFFF; | |
36 } | |
37 static const FX_CHARSET_MAP g_FXCodepage2CharsetTable[] = { | |
38 {1, 0}, {2, 42}, {254, 437}, {255, 850}, {222, 874}, | 39 {1, 0}, {2, 42}, {254, 437}, {255, 850}, {222, 874}, |
39 {128, 932}, {134, 936}, {129, 949}, {136, 950}, {238, 1250}, | 40 {128, 932}, {134, 936}, {129, 949}, {136, 950}, {238, 1250}, |
40 {204, 1251}, {0, 1252}, {161, 1253}, {162, 1254}, {177, 1255}, | 41 {204, 1251}, {0, 1252}, {161, 1253}, {162, 1254}, {177, 1255}, |
41 {178, 1256}, {186, 1257}, {163, 1258}, {130, 1361}, {77, 10000}, | 42 {178, 1256}, {186, 1257}, {163, 1258}, {130, 1361}, {77, 10000}, |
42 {78, 10001}, {79, 10003}, {80, 10008}, {81, 10002}, {83, 10005}, | 43 {78, 10001}, {79, 10003}, {80, 10008}, {81, 10002}, {83, 10005}, |
43 {84, 10004}, {85, 10006}, {86, 10081}, {87, 10021}, {88, 10029}, | 44 {84, 10004}, {85, 10006}, {86, 10081}, {87, 10021}, {88, 10029}, |
44 {89, 10007}, | 45 {89, 10007}, |
45 }; | 46 }; |
46 uint16_t FX_GetCharsetFromCodePage(uint16_t codepage) { | 47 |
47 int32_t iEnd = sizeof(g_FXCodepage2CharsetTable) / sizeof(FX_CHARSET_MAP) - 1; | |
48 ASSERT(iEnd >= 0); | |
49 int32_t iStart = 0, iMid; | |
50 do { | |
51 iMid = (iStart + iEnd) / 2; | |
52 const FX_CHARSET_MAP& cp = g_FXCodepage2CharsetTable[iMid]; | |
53 if (codepage == cp.codepage) { | |
54 return cp.charset; | |
55 } else if (codepage < cp.codepage) { | |
56 iEnd = iMid - 1; | |
57 } else { | |
58 iStart = iMid + 1; | |
59 } | |
60 } while (iStart <= iEnd); | |
61 return 0xFFFF; | |
62 } | |
63 const FX_LANG2CPMAP g_FXLang2CodepageTable[] = { | 48 const FX_LANG2CPMAP g_FXLang2CodepageTable[] = { |
64 {FX_LANG_Arabic_SaudiArabia, FX_CODEPAGE_MSWin_Arabic}, | 49 {FX_LANG_Arabic_SaudiArabia, FX_CODEPAGE_MSWin_Arabic}, |
65 {FX_LANG_Bulgarian_Bulgaria, FX_CODEPAGE_MSWin_Cyrillic}, | 50 {FX_LANG_Bulgarian_Bulgaria, FX_CODEPAGE_MSWin_Cyrillic}, |
66 {FX_LANG_Catalan_Catalan, FX_CODEPAGE_MSWin_WesternEuropean}, | 51 {FX_LANG_Catalan_Catalan, FX_CODEPAGE_MSWin_WesternEuropean}, |
67 {FX_LANG_Chinese_Taiwan, FX_CODEPAGE_ChineseTraditional}, | 52 {FX_LANG_Chinese_Taiwan, FX_CODEPAGE_ChineseTraditional}, |
68 {FX_LANG_CzechRepublic, FX_CODEPAGE_MSWin_EasternEuropean}, | 53 {FX_LANG_CzechRepublic, FX_CODEPAGE_MSWin_EasternEuropean}, |
69 {FX_LANG_Danish_Denmark, FX_CODEPAGE_MSWin_WesternEuropean}, | 54 {FX_LANG_Danish_Denmark, FX_CODEPAGE_MSWin_WesternEuropean}, |
70 {FX_LANG_German_Germany, FX_CODEPAGE_MSWin_WesternEuropean}, | 55 {FX_LANG_German_Germany, FX_CODEPAGE_MSWin_WesternEuropean}, |
71 {FX_LANG_Greek_Greece, FX_CODEPAGE_MSWin_Greek}, | 56 {FX_LANG_Greek_Greece, FX_CODEPAGE_MSWin_Greek}, |
72 {FX_LANG_English_UnitedStates, FX_CODEPAGE_MSWin_WesternEuropean}, | 57 {FX_LANG_English_UnitedStates, FX_CODEPAGE_MSWin_WesternEuropean}, |
(...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
190 {FX_LANG_Spanish_Uruguay, FX_CODEPAGE_MSWin_WesternEuropean}, | 175 {FX_LANG_Spanish_Uruguay, FX_CODEPAGE_MSWin_WesternEuropean}, |
191 {FX_LANG_Arabic_Bahrain, FX_CODEPAGE_MSWin_Arabic}, | 176 {FX_LANG_Arabic_Bahrain, FX_CODEPAGE_MSWin_Arabic}, |
192 {FX_LANG_Spanish_Paraguay, FX_CODEPAGE_MSWin_WesternEuropean}, | 177 {FX_LANG_Spanish_Paraguay, FX_CODEPAGE_MSWin_WesternEuropean}, |
193 {FX_LANG_Arabic_Qatar, FX_CODEPAGE_MSWin_Arabic}, | 178 {FX_LANG_Arabic_Qatar, FX_CODEPAGE_MSWin_Arabic}, |
194 {FX_LANG_Spanish_Bolivia, FX_CODEPAGE_MSWin_WesternEuropean}, | 179 {FX_LANG_Spanish_Bolivia, FX_CODEPAGE_MSWin_WesternEuropean}, |
195 {FX_LANG_Spanish_ElSalvador, FX_CODEPAGE_MSWin_WesternEuropean}, | 180 {FX_LANG_Spanish_ElSalvador, FX_CODEPAGE_MSWin_WesternEuropean}, |
196 {FX_LANG_Spanish_Honduras, FX_CODEPAGE_MSWin_WesternEuropean}, | 181 {FX_LANG_Spanish_Honduras, FX_CODEPAGE_MSWin_WesternEuropean}, |
197 {FX_LANG_Spanish_Nicaragua, FX_CODEPAGE_MSWin_WesternEuropean}, | 182 {FX_LANG_Spanish_Nicaragua, FX_CODEPAGE_MSWin_WesternEuropean}, |
198 {FX_LANG_Spanish_PuertoRico, FX_CODEPAGE_MSWin_WesternEuropean}, | 183 {FX_LANG_Spanish_PuertoRico, FX_CODEPAGE_MSWin_WesternEuropean}, |
199 }; | 184 }; |
200 uint16_t FX_GetDefCodePageByLanguage(uint16_t wLanguage) { | 185 |
201 int32_t iEnd = sizeof(g_FXLang2CodepageTable) / sizeof(FX_LANG2CPMAP) - 1; | 186 const FX_STR2CPHASH g_FXCPHashTable[] = { |
202 ASSERT(iEnd >= 0); | |
203 int32_t iStart = 0, iMid; | |
204 do { | |
205 iMid = (iStart + iEnd) / 2; | |
206 const FX_LANG2CPMAP& cp = g_FXLang2CodepageTable[iMid]; | |
207 if (wLanguage == cp.wLanguage) { | |
208 return cp.wCodepage; | |
209 } else if (wLanguage < cp.wLanguage) { | |
210 iEnd = iMid - 1; | |
211 } else { | |
212 iStart = iMid + 1; | |
213 } | |
214 } while (iStart <= iEnd); | |
215 return 0xFFFF; | |
216 } | |
217 static const FX_STR2CPHASH g_FXCPHashTable[] = { | |
218 {0xd45, 0x6faf}, {0xd46, 0x6fb0}, {0xd47, 0x6fb1}, | 187 {0xd45, 0x6faf}, {0xd46, 0x6fb0}, {0xd47, 0x6fb1}, |
219 {0xd48, 0x6fb2}, {0xd49, 0x4e6}, {0xd4d, 0x6fbd}, | 188 {0xd48, 0x6fb2}, {0xd49, 0x4e6}, {0xd4d, 0x6fbd}, |
220 {0xe9e, 0x4e4}, {0xc998, 0x1b5}, {0x18ef0, 0x3a8}, | 189 {0xe9e, 0x4e4}, {0xc998, 0x1b5}, {0x18ef0, 0x3a8}, |
221 {0x19f85, 0x5182}, {0x2e2335, 0x3b6}, {0x325153, 0x5182}, | 190 {0x19f85, 0x5182}, {0x2e2335, 0x3b6}, {0x325153, 0x5182}, |
222 {0x145bded, 0x2716}, {0x3c9a5f2, 0xc6f3}, {0x4c45f2d, 0x3a4}, | 191 {0x145bded, 0x2716}, {0x3c9a5f2, 0xc6f3}, {0x4c45f2d, 0x3a4}, |
223 {0x4c45f4e, 0xc431}, {0x58caf51, 0x4e4}, {0x5a5cd7d, 0x3a8}, | 192 {0x4c45f4e, 0xc431}, {0x58caf51, 0x4e4}, {0x5a5cd7d, 0x3a8}, |
224 {0x5a6c6a7, 0x4e4}, {0x5a6ca0b, 0x1b5}, {0x5a6cd68, 0x307}, | 193 {0x5a6c6a7, 0x4e4}, {0x5a6ca0b, 0x1b5}, {0x5a6cd68, 0x307}, |
225 {0x5a6d8d3, 0x4e4}, {0x5a6d948, 0x354}, {0x5a6d96b, 0x362}, | 194 {0x5a6d8d3, 0x4e4}, {0x5a6d948, 0x354}, {0x5a6d96b, 0x362}, |
226 {0x5a6d984, 0x366}, {0x5a90e35, 0x1b5}, {0x5e0cf00, 0x6fb5}, | 195 {0x5a6d984, 0x366}, {0x5a90e35, 0x1b5}, {0x5e0cf00, 0x6fb5}, |
227 {0x609c324, 0x551}, {0x617d97f, 0x5182}, {0x6a6fd91, 0xfde8}, | 196 {0x609c324, 0x551}, {0x617d97f, 0x5182}, {0x6a6fd91, 0xfde8}, |
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
294 {0xdd80a61a, 0x3b5}, {0xdd80c0f8, 0x4e9f}, {0xdf7e46ff, 0x4fc8}, | 263 {0xdd80a61a, 0x3b5}, {0xdd80c0f8, 0x4e9f}, {0xdf7e46ff, 0x4fc8}, |
295 {0xdf8680fd, 0x556a}, {0xdfb0bd6e, 0xc42d}, {0xdff05486, 0x2c4}, | 264 {0xdf8680fd, 0x556a}, {0xdfb0bd6e, 0xc42d}, {0xdff05486, 0x2c4}, |
296 {0xe3323399, 0x3a4}, {0xe60412dd, 0x3b5}, {0xeee47add, 0x4b0}, | 265 {0xe3323399, 0x3a4}, {0xe60412dd, 0x3b5}, {0xeee47add, 0x4b0}, |
297 {0xf021a186, 0x4e2}, {0xf021a187, 0x4e3}, {0xf021a188, 0x4e4}, | 266 {0xf021a186, 0x4e2}, {0xf021a187, 0x4e3}, {0xf021a188, 0x4e4}, |
298 {0xf021a189, 0x4e5}, {0xf021a18a, 0x4e6}, {0xf021a18b, 0x4e7}, | 267 {0xf021a189, 0x4e5}, {0xf021a18a, 0x4e6}, {0xf021a18b, 0x4e7}, |
299 {0xf021a18c, 0x4e8}, {0xf021a18d, 0x4e9}, {0xf021a18e, 0x4ea}, | 268 {0xf021a18c, 0x4e8}, {0xf021a18d, 0x4e9}, {0xf021a18e, 0x4ea}, |
300 {0xf0700456, 0x6fb3}, {0xf274f175, 0x3b5}, {0xf2a9730b, 0x3a8}, | 269 {0xf0700456, 0x6fb3}, {0xf274f175, 0x3b5}, {0xf2a9730b, 0x3a8}, |
301 {0xf3d463c2, 0x3a4}, {0xf52a70a3, 0xc42e}, {0xf5693147, 0x6fb3}, | 270 {0xf3d463c2, 0x3a4}, {0xf52a70a3, 0xc42e}, {0xf5693147, 0x6fb3}, |
302 {0xf637e157, 0x478}, {0xfc213f3a, 0x2717}, {0xff654d14, 0x3b5}, | 271 {0xf637e157, 0x478}, {0xfc213f3a, 0x2717}, {0xff654d14, 0x3b5}, |
303 }; | 272 }; |
304 uint16_t FX_GetCodePageFromStringA(const FX_CHAR* pStr, int32_t iLength) { | 273 |
| 274 uint16_t GetCodePageFromStringA(const FX_CHAR* pStr, int32_t iLength) { |
305 ASSERT(pStr != NULL); | 275 ASSERT(pStr != NULL); |
306 if (iLength < 0) { | 276 if (iLength < 0) { |
307 iLength = FXSYS_strlen(pStr); | 277 iLength = FXSYS_strlen(pStr); |
308 } | 278 } |
309 if (iLength == 0) { | 279 if (iLength == 0) { |
310 return 0xFFFF; | 280 return 0xFFFF; |
311 } | 281 } |
312 uint32_t uHash = FX_HashCode_GetA(CFX_ByteStringC(pStr, iLength), true); | 282 uint32_t uHash = FX_HashCode_GetA(CFX_ByteStringC(pStr, iLength), true); |
313 int32_t iStart = 0; | 283 int32_t iStart = 0; |
314 int32_t iEnd = sizeof(g_FXCPHashTable) / sizeof(FX_STR2CPHASH) - 1; | 284 int32_t iEnd = sizeof(g_FXCPHashTable) / sizeof(FX_STR2CPHASH) - 1; |
315 ASSERT(iEnd >= 0); | 285 ASSERT(iEnd >= 0); |
316 do { | 286 do { |
317 int32_t iMid = (iStart + iEnd) / 2; | 287 int32_t iMid = (iStart + iEnd) / 2; |
318 const FX_STR2CPHASH& cp = g_FXCPHashTable[iMid]; | 288 const FX_STR2CPHASH& cp = g_FXCPHashTable[iMid]; |
319 if (uHash == cp.uHash) { | 289 if (uHash == cp.uHash) { |
320 return (uint16_t)cp.uCodePage; | 290 return (uint16_t)cp.uCodePage; |
321 } else if (uHash < cp.uHash) { | 291 } else if (uHash < cp.uHash) { |
322 iEnd = iMid - 1; | 292 iEnd = iMid - 1; |
323 } else { | 293 } else { |
324 iStart = iMid + 1; | 294 iStart = iMid + 1; |
325 } | 295 } |
326 } while (iStart <= iEnd); | 296 } while (iStart <= iEnd); |
327 return 0xFFFF; | 297 return 0xFFFF; |
328 } | 298 } |
329 uint16_t FX_GetCodePageFormStringW(const FX_WCHAR* pStr, int32_t iLength) { | 299 |
| 300 } // namespace |
| 301 |
| 302 uint16_t FX_GetCodePageFromCharset(uint8_t charset) { |
| 303 int32_t iEnd = sizeof(g_FXCharset2CodePageTable) / sizeof(FX_CHARSET_MAP) - 1; |
| 304 ASSERT(iEnd >= 0); |
| 305 int32_t iStart = 0, iMid; |
| 306 do { |
| 307 iMid = (iStart + iEnd) / 2; |
| 308 const FX_CHARSET_MAP& cp = g_FXCharset2CodePageTable[iMid]; |
| 309 if (charset == cp.charset) { |
| 310 return cp.codepage; |
| 311 } else if (charset < cp.charset) { |
| 312 iEnd = iMid - 1; |
| 313 } else { |
| 314 iStart = iMid + 1; |
| 315 } |
| 316 } while (iStart <= iEnd); |
| 317 return 0xFFFF; |
| 318 } |
| 319 |
| 320 uint16_t FX_GetCharsetFromCodePage(uint16_t codepage) { |
| 321 int32_t iEnd = sizeof(g_FXCodepage2CharsetTable) / sizeof(FX_CHARSET_MAP) - 1; |
| 322 ASSERT(iEnd >= 0); |
| 323 int32_t iStart = 0, iMid; |
| 324 do { |
| 325 iMid = (iStart + iEnd) / 2; |
| 326 const FX_CHARSET_MAP& cp = g_FXCodepage2CharsetTable[iMid]; |
| 327 if (codepage == cp.codepage) { |
| 328 return cp.charset; |
| 329 } else if (codepage < cp.codepage) { |
| 330 iEnd = iMid - 1; |
| 331 } else { |
| 332 iStart = iMid + 1; |
| 333 } |
| 334 } while (iStart <= iEnd); |
| 335 return 0xFFFF; |
| 336 } |
| 337 |
| 338 uint16_t FX_GetDefCodePageByLanguage(uint16_t wLanguage) { |
| 339 int32_t iEnd = sizeof(g_FXLang2CodepageTable) / sizeof(FX_LANG2CPMAP) - 1; |
| 340 ASSERT(iEnd >= 0); |
| 341 int32_t iStart = 0, iMid; |
| 342 do { |
| 343 iMid = (iStart + iEnd) / 2; |
| 344 const FX_LANG2CPMAP& cp = g_FXLang2CodepageTable[iMid]; |
| 345 if (wLanguage == cp.wLanguage) { |
| 346 return cp.wCodepage; |
| 347 } else if (wLanguage < cp.wLanguage) { |
| 348 iEnd = iMid - 1; |
| 349 } else { |
| 350 iStart = iMid + 1; |
| 351 } |
| 352 } while (iStart <= iEnd); |
| 353 return 0xFFFF; |
| 354 } |
| 355 |
| 356 uint16_t FX_GetCodePageFromStringW(const FX_WCHAR* pStr, int32_t iLength) { |
330 if (iLength < 0) { | 357 if (iLength < 0) { |
331 iLength = FXSYS_wcslen(pStr); | 358 iLength = FXSYS_wcslen(pStr); |
332 } | 359 } |
333 if (iLength == 0) { | 360 if (iLength == 0) { |
334 return 0xFFFF; | 361 return 0xFFFF; |
335 } | 362 } |
336 CFX_ByteString csStr; | 363 CFX_ByteString csStr; |
337 FX_CHAR* pBuf = csStr.GetBuffer(iLength + 1); | 364 FX_CHAR* pBuf = csStr.GetBuffer(iLength + 1); |
338 for (int32_t i = 0; i < iLength; ++i) { | 365 for (int32_t i = 0; i < iLength; ++i) { |
339 *pBuf++ = (FX_CHAR)*pStr++; | 366 *pBuf++ = (FX_CHAR)*pStr++; |
340 } | 367 } |
341 csStr.ReleaseBuffer(iLength); | 368 csStr.ReleaseBuffer(iLength); |
342 return FX_GetCodePageFromStringA(csStr.c_str(), iLength); | 369 return GetCodePageFromStringA(csStr.c_str(), iLength); |
343 } | 370 } |
| 371 |
| 372 void FX_SwapByteOrder(FX_WCHAR* pStr, int32_t iLength) { |
| 373 ASSERT(pStr != NULL); |
| 374 if (iLength < 0) { |
| 375 iLength = FXSYS_wcslen(pStr); |
| 376 } |
| 377 uint16_t wch; |
| 378 if (sizeof(FX_WCHAR) > 2) { |
| 379 while (iLength-- > 0) { |
| 380 wch = (uint16_t)*pStr; |
| 381 wch = (wch >> 8) | (wch << 8); |
| 382 wch &= 0x00FF; |
| 383 *pStr++ = wch; |
| 384 } |
| 385 } else { |
| 386 while (iLength-- > 0) { |
| 387 wch = (uint16_t)*pStr; |
| 388 wch = (wch >> 8) | (wch << 8); |
| 389 *pStr++ = wch; |
| 390 } |
| 391 } |
| 392 } |
| 393 |
| 394 void FX_UTF16ToWChar(void* pBuffer, int32_t iLength) { |
| 395 ASSERT(pBuffer != NULL && iLength > 0); |
| 396 if (sizeof(FX_WCHAR) == 2) { |
| 397 return; |
| 398 } |
| 399 uint16_t* pSrc = (uint16_t*)pBuffer; |
| 400 FX_WCHAR* pDst = (FX_WCHAR*)pBuffer; |
| 401 while (--iLength >= 0) { |
| 402 pDst[iLength] = (FX_WCHAR)pSrc[iLength]; |
| 403 } |
| 404 } |
| 405 |
| 406 void FX_WCharToUTF16(void* pBuffer, int32_t iLength) { |
| 407 ASSERT(pBuffer != NULL && iLength > 0); |
| 408 if (sizeof(FX_WCHAR) == 2) { |
| 409 return; |
| 410 } |
| 411 const FX_WCHAR* pSrc = (const FX_WCHAR*)pBuffer; |
| 412 uint16_t* pDst = (uint16_t*)pBuffer; |
| 413 while (--iLength >= 0) { |
| 414 *pDst++ = (uint16_t)*pSrc++; |
| 415 } |
| 416 } |
| 417 |
| 418 int32_t FX_DecodeString(uint16_t wCodePage, |
| 419 const FX_CHAR* pSrc, |
| 420 int32_t* pSrcLen, |
| 421 FX_WCHAR* pDst, |
| 422 int32_t* pDstLen, |
| 423 FX_BOOL bErrBreak) { |
| 424 if (wCodePage == FX_CODEPAGE_UTF8) { |
| 425 return FX_UTF8Decode(pSrc, pSrcLen, pDst, pDstLen); |
| 426 } |
| 427 return -1; |
| 428 } |
| 429 int32_t FX_UTF8Decode(const FX_CHAR* pSrc, |
| 430 int32_t* pSrcLen, |
| 431 FX_WCHAR* pDst, |
| 432 int32_t* pDstLen) { |
| 433 if (pSrcLen == NULL || pDstLen == NULL) { |
| 434 return -1; |
| 435 } |
| 436 int32_t iSrcLen = *pSrcLen; |
| 437 if (iSrcLen < 1) { |
| 438 *pSrcLen = *pDstLen = 0; |
| 439 return 1; |
| 440 } |
| 441 int32_t iDstLen = *pDstLen; |
| 442 FX_BOOL bValidDst = (pDst != NULL && iDstLen > 0); |
| 443 uint32_t dwCode = 0; |
| 444 int32_t iPending = 0; |
| 445 int32_t iSrcNum = 0, iDstNum = 0; |
| 446 int32_t k = 0; |
| 447 int32_t iIndex = 0; |
| 448 k = 1; |
| 449 while (iIndex < iSrcLen) { |
| 450 uint8_t byte = (uint8_t) * (pSrc + iIndex); |
| 451 if (byte < 0x80) { |
| 452 iPending = 0; |
| 453 k = 1; |
| 454 iDstNum++; |
| 455 iSrcNum += k; |
| 456 if (bValidDst) { |
| 457 *pDst++ = byte; |
| 458 if (iDstNum >= iDstLen) { |
| 459 break; |
| 460 } |
| 461 } |
| 462 } else if (byte < 0xc0) { |
| 463 if (iPending < 1) { |
| 464 break; |
| 465 } |
| 466 iPending--; |
| 467 dwCode |= (byte & 0x3f) << (iPending * 6); |
| 468 if (iPending == 0) { |
| 469 iDstNum++; |
| 470 iSrcNum += k; |
| 471 if (bValidDst) { |
| 472 *pDst++ = dwCode; |
| 473 if (iDstNum >= iDstLen) { |
| 474 break; |
| 475 } |
| 476 } |
| 477 } |
| 478 } else if (byte < 0xe0) { |
| 479 iPending = 1; |
| 480 k = 2; |
| 481 dwCode = (byte & 0x1f) << 6; |
| 482 } else if (byte < 0xf0) { |
| 483 iPending = 2; |
| 484 k = 3; |
| 485 dwCode = (byte & 0x0f) << 12; |
| 486 } else if (byte < 0xf8) { |
| 487 iPending = 3; |
| 488 k = 4; |
| 489 dwCode = (byte & 0x07) << 18; |
| 490 } else if (byte < 0xfc) { |
| 491 iPending = 4; |
| 492 k = 5; |
| 493 dwCode = (byte & 0x03) << 24; |
| 494 } else if (byte < 0xfe) { |
| 495 iPending = 5; |
| 496 k = 6; |
| 497 dwCode = (byte & 0x01) << 30; |
| 498 } else { |
| 499 break; |
| 500 } |
| 501 iIndex++; |
| 502 } |
| 503 *pSrcLen = iSrcNum; |
| 504 *pDstLen = iDstNum; |
| 505 return 1; |
| 506 } |
OLD | NEW |