Merge to XFA: Use stdint.h types throughout PDFium.
[pdfium.git] / xfa / src / fgas / src / crt / fx_codepage.cpp
1 // Copyright 2014 PDFium Authors. All rights reserved.\r
2 // Use of this source code is governed by a BSD-style license that can be\r
3 // found in the LICENSE file.\r
4 \r
5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com\r
6 \r
7 #include "../fgas_base.h"\r
8 #include "fx_codepage.h"\r
9 static const FX_CHARSET_MAP g_FXCharset2CodePageTable[] = {\r
10     { 0,        1252  },\r
11     { 1,        0         },\r
12     { 2,        42        },\r
13     { 77,       10000 },\r
14     { 78,       10001 },\r
15     { 79,       10003 },\r
16     { 80,       10008 },\r
17     { 81,       10002 },\r
18     { 83,       10005 },\r
19     { 84,       10004 },\r
20     { 85,       10006 },\r
21     { 86,       10081 },\r
22     { 87,       10021 },\r
23     { 88,       10029 },\r
24     { 89,       10007 },\r
25     { 128,      932     },\r
26     { 129,      949     },\r
27     { 130,      1361 },\r
28     { 134,      936     },\r
29     { 136,      950     },\r
30     { 161,      1253 },\r
31     { 162,      1254 },\r
32     { 163,      1258 },\r
33     { 177,      1255 },\r
34     { 178,      1256 },\r
35     { 186,      1257 },\r
36     { 204,      1251 },\r
37     { 222,      874     },\r
38     { 238,      1250 },\r
39     { 254,      437     },\r
40     { 255,      850     },\r
41 };\r
42 FX_WORD FX_GetCodePageFromCharset(uint8_t charset)\r
43 {\r
44     int32_t iEnd = sizeof(g_FXCharset2CodePageTable) / sizeof(FX_CHARSET_MAP) - 1;\r
45     FXSYS_assert(iEnd >= 0);\r
46     int32_t iStart = 0, iMid;\r
47     do {\r
48         iMid = (iStart + iEnd) / 2;\r
49         const FX_CHARSET_MAP & cp = g_FXCharset2CodePageTable[iMid];\r
50         if (charset == cp.charset) {\r
51             return cp.codepage;\r
52         } else if (charset < cp.charset) {\r
53             iEnd = iMid - 1;\r
54         } else {\r
55             iStart = iMid + 1;\r
56         }\r
57     } while (iStart <= iEnd);\r
58     return 0xFFFF;\r
59 }\r
60 static const FX_CHARSET_MAP g_FXCodepage2CharsetTable[] = {\r
61     { 1,        0         },\r
62     { 2,        42        },\r
63     { 254,      437     },\r
64     { 255,      850     },\r
65     { 222,      874     },\r
66     { 128,      932     },\r
67     { 134,      936     },\r
68     { 129,      949     },\r
69     { 136,      950     },\r
70     { 238,      1250 },\r
71     { 204,      1251 },\r
72     { 0,        1252  },\r
73     { 161,      1253 },\r
74     { 162,      1254 },\r
75     { 177,      1255 },\r
76     { 178,      1256 },\r
77     { 186,      1257 },\r
78     { 163,      1258 },\r
79     { 130,      1361 },\r
80     { 77,       10000 },\r
81     { 78,       10001 },\r
82     { 79,       10003 },\r
83     { 80,       10008 },\r
84     { 81,       10002 },\r
85     { 83,       10005 },\r
86     { 84,       10004 },\r
87     { 85,       10006 },\r
88     { 86,       10081 },\r
89     { 87,       10021 },\r
90     { 88,       10029 },\r
91     { 89,       10007 },\r
92 };\r
93 FX_WORD FX_GetCharsetFromCodePage(FX_WORD codepage)\r
94 {\r
95     int32_t iEnd = sizeof(g_FXCodepage2CharsetTable) / sizeof(FX_CHARSET_MAP) - 1;\r
96     FXSYS_assert(iEnd >= 0);\r
97     int32_t iStart = 0, iMid;\r
98     do {\r
99         iMid = (iStart + iEnd) / 2;\r
100         const FX_CHARSET_MAP & cp = g_FXCodepage2CharsetTable[iMid];\r
101         if (codepage == cp.codepage) {\r
102             return cp.charset;\r
103         } else if (codepage < cp.codepage) {\r
104             iEnd = iMid - 1;\r
105         } else {\r
106             iStart = iMid + 1;\r
107         }\r
108     } while (iStart <= iEnd);\r
109     return 0xFFFF;\r
110 }\r
111 const FX_LANG2CPMAP g_FXLang2CodepageTable[] = {\r
112     {FX_LANG_Arabic_SaudiArabia       , FX_CODEPAGE_MSWin_Arabic         },\r
113     {FX_LANG_Bulgarian_Bulgaria       , FX_CODEPAGE_MSWin_Cyrillic       },\r
114     {FX_LANG_Catalan_Catalan          , FX_CODEPAGE_MSWin_WesternEuropean},\r
115     {FX_LANG_Chinese_Taiwan           , FX_CODEPAGE_ChineseTraditional   },\r
116     {FX_LANG_CzechRepublic            , FX_CODEPAGE_MSWin_EasternEuropean},\r
117     {FX_LANG_Danish_Denmark           , FX_CODEPAGE_MSWin_WesternEuropean},\r
118     {FX_LANG_German_Germany           , FX_CODEPAGE_MSWin_WesternEuropean},\r
119     {FX_LANG_Greek_Greece             , FX_CODEPAGE_MSWin_Greek          },\r
120     {FX_LANG_English_UnitedStates     , FX_CODEPAGE_MSWin_WesternEuropean},\r
121     {FX_LANG_Spanish_TraditionalSort  , FX_CODEPAGE_MSWin_WesternEuropean},\r
122     {FX_LANG_Finnish_Finland          , FX_CODEPAGE_MSWin_WesternEuropean},\r
123     {FX_LANG_French_France            , FX_CODEPAGE_MSWin_WesternEuropean},\r
124     {FX_LANG_Hebrew_Israel            , FX_CODEPAGE_MSWin_Hebrew         },\r
125     {FX_LANG_Hungarian_Hungary        , FX_CODEPAGE_MSWin_EasternEuropean},\r
126     {FX_LANG_Icelandic_Iceland        , FX_CODEPAGE_MSWin_WesternEuropean},\r
127     {FX_LANG_Italian_Italy            , FX_CODEPAGE_MSWin_WesternEuropean},\r
128     {FX_LANG_Japanese_Japan           , FX_CODEPAGE_ShiftJIS             },\r
129     {FX_LANG_Korean_Korea             , FX_CODEPAGE_Korean               },\r
130     {FX_LANG_Dutch_Netherlands        , FX_CODEPAGE_MSWin_WesternEuropean},\r
131     {FX_LANG_Norwegian_Bokmal         , FX_CODEPAGE_MSWin_WesternEuropean},\r
132     {FX_LANG_Polish_Poland            , FX_CODEPAGE_MSWin_EasternEuropean},\r
133     {FX_LANG_Portuguese_Brazil        , FX_CODEPAGE_MSWin_WesternEuropean},\r
134     {FX_LANG_Romanian_Romania         , FX_CODEPAGE_MSWin_EasternEuropean},\r
135     {FX_LANG_Russian_Russia           , FX_CODEPAGE_MSWin_Cyrillic       },\r
136     {FX_LANG_Croatian_Croatia         , FX_CODEPAGE_MSWin_EasternEuropean},\r
137     {FX_LANG_Slovak_Slovakia          , FX_CODEPAGE_MSWin_EasternEuropean},\r
138     {FX_LANG_Albanian_Albania         , FX_CODEPAGE_MSWin_EasternEuropean},\r
139     {FX_LANG_Swedish_Sweden           , FX_CODEPAGE_MSWin_WesternEuropean},\r
140     {FX_LANG_Thai_Thailand            , FX_CODEPAGE_MSDOS_Thai           },\r
141     {FX_LANG_Turkish_Turkey           , FX_CODEPAGE_MSWin_Turkish        },\r
142     {FX_LANG_Urdu_Pakistan            , FX_CODEPAGE_MSWin_Arabic         },\r
143     {FX_LANG_Indonesian_Indonesia     , FX_CODEPAGE_MSWin_WesternEuropean},\r
144     {FX_LANG_Ukrainian_Ukraine        , FX_CODEPAGE_MSWin_Cyrillic       },\r
145     {FX_LANG_Belarusian_Belarus       , FX_CODEPAGE_MSWin_Cyrillic       },\r
146     {FX_LANG_Slovenian_Slovenia       , FX_CODEPAGE_MSWin_EasternEuropean},\r
147     {FX_LANG_Estonian_Estonia         , FX_CODEPAGE_MSWin_Baltic         },\r
148     {FX_LANG_Latvian_Latvia           , FX_CODEPAGE_MSWin_Baltic         },\r
149     {FX_LANG_Lithuanian_Lithuania     , FX_CODEPAGE_MSWin_Baltic         },\r
150     {FX_LANG_Persian                  , FX_CODEPAGE_MSWin_Arabic         },\r
151     {FX_LANG_Vietnamese_Vietnam       , FX_CODEPAGE_MSWin_Vietnamese     },\r
152     {FX_LANG_Armenian_Armenia         , FX_CODEPAGE_DefANSI              },\r
153     {FX_LANG_Azerbaijan_Latin         , FX_CODEPAGE_MSWin_Turkish        },\r
154     {FX_LANG_Basque_Basque            , FX_CODEPAGE_MSWin_WesternEuropean},\r
155     {FX_LANG_Macedonian               , FX_CODEPAGE_MSWin_Cyrillic       },\r
156     {FX_LANG_Afrikaans_SouthAfrica    , FX_CODEPAGE_MSWin_WesternEuropean},\r
157     {FX_LANG_Georgian_Georgia         , FX_CODEPAGE_DefANSI              },\r
158     {FX_LANG_Faroese_FaroeIslands     , FX_CODEPAGE_MSWin_WesternEuropean},\r
159     {FX_LANG_Hindi_India              , FX_CODEPAGE_DefANSI              },\r
160     {FX_LANG_Malay_Malaysia           , FX_CODEPAGE_MSWin_WesternEuropean},\r
161     {FX_LANG_Kazakh_Kazakhstan        , FX_CODEPAGE_MSWin_Cyrillic       },\r
162     {FX_LANG_Kyrgyz_Kyrgyzstan        , FX_CODEPAGE_MSWin_Cyrillic       },\r
163     {FX_LANG_Kiswahili_Kenya          , FX_CODEPAGE_MSWin_WesternEuropean},\r
164     {FX_LANG_Uzbek_LatinUzbekistan    , FX_CODEPAGE_MSWin_Turkish        },\r
165     {FX_LANG_Tatar_Russia             , FX_CODEPAGE_MSWin_Cyrillic       },\r
166     {FX_LANG_Punjabi_India            , FX_CODEPAGE_DefANSI              },\r
167     {FX_LANG_Gujarati_India           , FX_CODEPAGE_DefANSI              },\r
168     {FX_LANG_Tamil_India              , FX_CODEPAGE_DefANSI              },\r
169     {FX_LANG_Telugu_India             , FX_CODEPAGE_DefANSI              },\r
170     {FX_LANG_Kannada_India            , FX_CODEPAGE_DefANSI              },\r
171     {FX_LANG_Marathi_India            , FX_CODEPAGE_DefANSI              },\r
172     {FX_LANG_SanskritIndia            , FX_CODEPAGE_DefANSI              },\r
173     {FX_LANG_Mongolian_CyrillicMongolia,        FX_CODEPAGE_MSWin_Cyrillic       },\r
174     {FX_LANG_Galician_Galician        , FX_CODEPAGE_MSWin_WesternEuropean},\r
175     {FX_LANG_Konkani_India            , FX_CODEPAGE_DefANSI              },\r
176     {FX_LANG_Syriac_Syria             , FX_CODEPAGE_DefANSI              },\r
177     {FX_LANG_Divehi_Maldives          , FX_CODEPAGE_DefANSI              },\r
178     {FX_LANG_Arabic_Iraq              , FX_CODEPAGE_MSWin_Arabic         },\r
179     {FX_LANG_Chinese_PRC              , FX_CODEPAGE_ChineseSimplified    },\r
180     {FX_LANG_German_Switzerland       , FX_CODEPAGE_MSWin_WesternEuropean},\r
181     {FX_LANG_English_UnitedKingdom    , FX_CODEPAGE_MSWin_WesternEuropean},\r
182     {FX_LANG_Spanish_Mexico           , FX_CODEPAGE_MSWin_WesternEuropean},\r
183     {FX_LANG_French_Belgium           , FX_CODEPAGE_MSWin_WesternEuropean},\r
184     {FX_LANG_Italian_Switzerland      , FX_CODEPAGE_MSWin_WesternEuropean},\r
185     {FX_LANG_Dutch_Belgium            , FX_CODEPAGE_MSWin_WesternEuropean},\r
186     {FX_LANG_Norwegian_Nynorsk        , FX_CODEPAGE_MSWin_WesternEuropean},\r
187     {FX_LANG_Portuguese_Portugal      , FX_CODEPAGE_MSWin_WesternEuropean},\r
188     {FX_LANG_SerbianLatin_Serbia      , FX_CODEPAGE_MSWin_EasternEuropean},\r
189     {FX_LANG_Swedish_Finland          , FX_CODEPAGE_MSWin_WesternEuropean},\r
190     {FX_LANG_Azerbaijan_Cyrillic      , FX_CODEPAGE_MSWin_Cyrillic       },\r
191     {FX_LANG_Malay_BruneiDarussalam   , FX_CODEPAGE_MSWin_WesternEuropean},\r
192     {FX_LANG_Uzbek_CyrillicUzbekistan , FX_CODEPAGE_MSWin_Cyrillic       },\r
193     {FX_LANG_Arabic_Egypt             , FX_CODEPAGE_MSWin_Arabic         },\r
194     {FX_LANG_Chinese_HongKong         , FX_CODEPAGE_ChineseTraditional   },\r
195     {FX_LANG_German_Austria           , FX_CODEPAGE_MSWin_WesternEuropean},\r
196     {FX_LANG_English_Australia        , FX_CODEPAGE_MSWin_WesternEuropean},\r
197     {FX_LANG_Spanish_InternationalSort, FX_CODEPAGE_MSWin_WesternEuropean},\r
198     {FX_LANG_French_Canada            , FX_CODEPAGE_MSWin_WesternEuropean},\r
199     {FX_LANG_SerbianCyrillic_Serbia   , FX_CODEPAGE_MSWin_Cyrillic       },\r
200     {FX_LANG_Arabic_Libya             , FX_CODEPAGE_MSWin_Arabic         },\r
201     {FX_LANG_Chinese_Singapore        , FX_CODEPAGE_ChineseSimplified    },\r
202     {FX_LANG_German_Luxembourg        , FX_CODEPAGE_MSWin_WesternEuropean},\r
203     {FX_LANG_English_Canada           , FX_CODEPAGE_MSWin_WesternEuropean},\r
204     {FX_LANG_Spanish_Guatemala        , FX_CODEPAGE_MSWin_WesternEuropean},\r
205     {FX_LANG_French_Switzerland       , FX_CODEPAGE_MSWin_WesternEuropean},\r
206     {FX_LANG_Arabic_Algeria           , FX_CODEPAGE_MSWin_Arabic         },\r
207     {FX_LANG_Chinese_Macao            , FX_CODEPAGE_ChineseTraditional   },\r
208     {FX_LANG_German_Liechtenstein     , FX_CODEPAGE_MSWin_WesternEuropean},\r
209     {FX_LANG_English_NewZealand       , FX_CODEPAGE_MSWin_WesternEuropean},\r
210     {FX_LANG_Spanish_CostaRica        , FX_CODEPAGE_MSWin_WesternEuropean},\r
211     {FX_LANG_French_Luxembourg        , FX_CODEPAGE_MSWin_WesternEuropean},\r
212     {FX_LANG_Arabic_Morocco           , FX_CODEPAGE_MSWin_Arabic         },\r
213     {FX_LANG_English_Ireland          , FX_CODEPAGE_MSWin_WesternEuropean},\r
214     {FX_LANG_Spanish_Panama           , FX_CODEPAGE_MSWin_WesternEuropean},\r
215     {FX_LANG_French_Monaco            , FX_CODEPAGE_MSWin_WesternEuropean},\r
216     {FX_LANG_Arabic_Tunisia           , FX_CODEPAGE_MSWin_Arabic         },\r
217     {FX_LANG_English_SouthAfrica      , FX_CODEPAGE_MSWin_WesternEuropean},\r
218     {FX_LANG_Spanish_DominicanRepublic, FX_CODEPAGE_MSWin_WesternEuropean},\r
219     {FX_LANG_Arabic_Oman              , FX_CODEPAGE_MSWin_Arabic         },\r
220     {FX_LANG_English_Jamaica          , FX_CODEPAGE_MSWin_WesternEuropean},\r
221     {FX_LANG_Spanish_Venezuela        , FX_CODEPAGE_MSWin_WesternEuropean},\r
222     {FX_LANG_Arabic_Yemen             , FX_CODEPAGE_MSWin_Arabic         },\r
223     {FX_LANG_English_Caribbean        , FX_CODEPAGE_MSWin_WesternEuropean},\r
224     {FX_LANG_Spanish_Colombia         , FX_CODEPAGE_MSWin_WesternEuropean},\r
225     {FX_LANG_Arabic_Syria             , FX_CODEPAGE_MSWin_Arabic         },\r
226     {FX_LANG_English_Belize           , FX_CODEPAGE_MSWin_WesternEuropean},\r
227     {FX_LANG_Spanish_Peru             , FX_CODEPAGE_MSWin_WesternEuropean},\r
228     {FX_LANG_Arabic_Jordan            , FX_CODEPAGE_MSWin_Arabic         },\r
229     {FX_LANG_English_TrinidadTobago   , FX_CODEPAGE_MSWin_WesternEuropean},\r
230     {FX_LANG_Spanish_Argentina        , FX_CODEPAGE_MSWin_WesternEuropean},\r
231     {FX_LANG_Arabic_Lebanon           , FX_CODEPAGE_MSWin_Arabic         },\r
232     {FX_LANG_English_Zimbabwe         , FX_CODEPAGE_MSWin_WesternEuropean},\r
233     {FX_LANG_Spanish_Ecuador          , FX_CODEPAGE_MSWin_WesternEuropean},\r
234     {FX_LANG_Arabic_Kuwait            , FX_CODEPAGE_MSWin_Arabic         },\r
235     {FX_LANG_English_Philippines      , FX_CODEPAGE_MSWin_WesternEuropean},\r
236     {FX_LANG_Spanish_Chile            , FX_CODEPAGE_MSWin_WesternEuropean},\r
237     {FX_LANG_Arabic_UAE               , FX_CODEPAGE_MSWin_Arabic         },\r
238     {FX_LANG_Spanish_Uruguay          , FX_CODEPAGE_MSWin_WesternEuropean},\r
239     {FX_LANG_Arabic_Bahrain           , FX_CODEPAGE_MSWin_Arabic         },\r
240     {FX_LANG_Spanish_Paraguay         , FX_CODEPAGE_MSWin_WesternEuropean},\r
241     {FX_LANG_Arabic_Qatar             , FX_CODEPAGE_MSWin_Arabic         },\r
242     {FX_LANG_Spanish_Bolivia          , FX_CODEPAGE_MSWin_WesternEuropean},\r
243     {FX_LANG_Spanish_ElSalvador       , FX_CODEPAGE_MSWin_WesternEuropean},\r
244     {FX_LANG_Spanish_Honduras         , FX_CODEPAGE_MSWin_WesternEuropean},\r
245     {FX_LANG_Spanish_Nicaragua        , FX_CODEPAGE_MSWin_WesternEuropean},\r
246     {FX_LANG_Spanish_PuertoRico       , FX_CODEPAGE_MSWin_WesternEuropean},\r
247 };\r
248 FX_WORD FX_GetDefCodePageByLanguage(FX_WORD wLanguage)\r
249 {\r
250     int32_t iEnd = sizeof(g_FXLang2CodepageTable) / sizeof(FX_LANG2CPMAP) - 1;\r
251     FXSYS_assert(iEnd >= 0);\r
252     int32_t iStart = 0, iMid;\r
253     do {\r
254         iMid = (iStart + iEnd) / 2;\r
255         const FX_LANG2CPMAP &cp = g_FXLang2CodepageTable[iMid];\r
256         if (wLanguage == cp.wLanguage) {\r
257             return cp.wCodepage;\r
258         } else if (wLanguage < cp.wLanguage) {\r
259             iEnd = iMid - 1;\r
260         } else {\r
261             iStart = iMid + 1;\r
262         }\r
263     } while (iStart <= iEnd);\r
264     return 0xFFFF;\r
265 }\r
266 static const FX_STR2CPHASH g_FXCPHashTable[] = {\r
267     { 0xd45,    0x6faf },               { 0xd46,        0x6fb0 },               { 0xd47,        0x6fb1 },               { 0xd48,        0x6fb2 },\r
268     { 0xd49,    0x4e6 },                { 0xd4d,        0x6fbd },               { 0xe9e,        0x4e4 },                { 0xc998,       0x1b5 },\r
269     { 0x18ef0,  0x3a8 },                { 0x19f85,      0x5182 },               { 0x2e2335,     0x3b6 },                { 0x325153,     0x5182 },\r
270     { 0x145bded,        0x2716 },       { 0x3c9a5f2,    0xc6f3 },       { 0x4c45f2d,    0x3a4 },        { 0x4c45f4e,    0xc431 },\r
271     { 0x58caf51,        0x4e4 },        { 0x5a5cd7d,    0x3a8 },        { 0x5a6c6a7,    0x4e4 },        { 0x5a6ca0b,    0x1b5 },\r
272     { 0x5a6cd68,        0x307 },        { 0x5a6d8d3,    0x4e4 },        { 0x5a6d948,    0x354 },        { 0x5a6d96b,    0x362 },\r
273     { 0x5a6d984,        0x366 },        { 0x5a90e35,    0x1b5 },        { 0x5e0cf00,    0x6fb5 },       { 0x609c324,    0x551 },\r
274     { 0x617d97f,        0x5182 },       { 0x6a6fd91,    0xfde8 },       { 0x6a6fd92,    0xfde9 },       { 0x6b102de,    0xcadc },\r
275     { 0x6b10f48,        0x4e89 },       { 0x1020805f,   0x4e4 },        { 0x10f0524c,   0x6fb5 },       { 0x11d558fe,   0x6fb0 },\r
276     { 0x13898d19,       0xc42d },       { 0x13898d3a,   0xc431 },       { 0x138a319e,   0x6fb1 },       { 0x14679c09,   0x96c6 },\r
277     { 0x153f0a3d,       0x6fb2 },       { 0x1576eeb3,   0x4e20 },       { 0x169a0ce6,   0xc6f9 },       { 0x16f3e2dc,   0x6fb3 },\r
278     { 0x18a8bb7a,       0x6fb4 },       { 0x1a5d9419,   0x6fb5 },       { 0x1a847b48,   0x3a8 },        { 0x1b762419,   0xcec8 },\r
279     { 0x1b9d7847,       0x475 },        { 0x1c126cb9,   0x6fb6 },       { 0x1ccdbc7d,   0x4f42 },       { 0x1d330f5f,   0x2714 },\r
280     { 0x1dc74559,       0x4e6 },        { 0x1edd80da,   0x4e4 },        { 0x23e4b03d,   0xfde8 },       { 0x24f28a16,   0x4f3d },\r
281     { 0x286e7a32,       0x2715 },       { 0x2c7c18ed,   0x3a8 },        { 0x2e2103b7,   0x2713 },       { 0x304bf479,   0x6fb4 },\r
282     { 0x304bf47d,       0x6fb5 },       { 0x309bb869,   0xfde8 },       { 0x309bb86a,   0xfde9 },       { 0x33664357,   0x3b6 },\r
283     { 0x352d6b49,       0x3a4 },        { 0x36f5661c,   0x1b5 },        { 0x392e8f48,   0xcadc },       { 0x3dc7c64c,   0x47c },\r
284     { 0x3ed2e8e1,       0x4e4 },        { 0x3f0c2fea,   0xcaed },       { 0x3f0fef8f,   0xc6f2 },       { 0x3f5e130f,   0x5182 },\r
285     { 0x47174d1f,       0x3a8 },        { 0x49686b7b,   0x6fb4 },       { 0x4b80b0d9,   0x3a4 },        { 0x4dcda97a,   0x4e4 },\r
286     { 0x4dcda9b6,       0x4e4 },        { 0x4e881e6a,   0x5221 },       { 0x4ffdf5a1,   0x36a },        { 0x4ffdf5a5,   0x6fbd },\r
287     { 0x5241ce16,       0x4e8b },       { 0x546bab9d,   0x4e4 },        { 0x54a3d64e,   0x6fb6 },       { 0x562179bd,   0x5161 },\r
288     { 0x57c1df15,       0xc6f7 },       { 0x61ff6e62,   0x4f36 },       { 0x6359c7d8,   0x4f35 },       { 0x63f3c335,   0x3a8 },\r
289     { 0x645a0f78,       0x477 },        { 0x691ac2fd,   0x275f },       { 0x6dc2eab0,   0x2d0 },        { 0x6dc2eeef,   0x35e },\r
290     { 0x6dc2ef10,       0x36a },        { 0x7103138a,   0x47d },        { 0x710dfbd0,   0xc6f5 },       { 0x7319f6cb,   0x36a },\r
291     { 0x745096ad,       0x3a8 },        { 0x74866229,   0x4e8c },       { 0x77185fa5,   0x3a8 },        { 0x7953f002,   0x6faf },\r
292     { 0x7953f003,       0x6fb0 },       { 0x7953f004,   0x6fb1 },       { 0x7953f005,   0x6fb2 },       { 0x7953f006,   0x6fb7 },\r
293     { 0x7953f00a,       0x6fbd },       { 0x7c577571,   0x2761 },       { 0x7e8c8ff1,   0x479 },        { 0x8031f47f,   0x3b5 },\r
294     { 0x8031f481,       0x3b5 },        { 0x80c4a710,   0x5187 },       { 0x857c7e14,   0xfde8 },       { 0x857c7e15,   0xfde9 },\r
295     { 0x86b59c90,       0x4e4 },        { 0x86b59c91,   0x6fb0 },       { 0x86b59c92,   0x6fb1 },       { 0x86b59c93,   0x6fb2 },\r
296     { 0x86b59c94,       0x6fb3 },       { 0x86b59c95,   0x6fb4 },       { 0x86b59c96,   0x6fb5 },       { 0x86b59c97,   0x4e7 },\r
297     { 0x86b59c98,       0x4e6 },        { 0x8b4b24ec,   0x5190 },       { 0x8face362,   0x4e4 },        { 0x8ff9ec2a,   0xfde9 },\r
298     { 0x919d3989,       0xcadc },       { 0x9967e5ad,   0x4e22 },       { 0x99f8b933,   0x6fbd },       { 0x9bd2a380,   0x4fc7 },\r
299     { 0x9befad23,       0x4f38 },       { 0x9c7ac649,   0x4f3c },       { 0xa02468db,   0xdeae },       { 0xa02468ec,   0xdeab },\r
300     { 0xa024692a,       0xdeaa },       { 0xa0246997,   0xdeb2 },       { 0xa02469ff,   0xdeb0 },       { 0xa0246a3d,   0xdeb1 },\r
301     { 0xa0246a8c,       0xdeaf },       { 0xa0246a9a,   0xdeb3 },       { 0xa0246b16,   0xdeac },       { 0xa0246b1a,   0xdead },\r
302     { 0xa071addc,       0x4b1 },        { 0xa38b62dc,   0x474 },        { 0xa4c09fed,   0x3a8 },        { 0xa51e86e5,   0x4e7 },\r
303     { 0xa67ab13e,       0x3a4 },        { 0xa7414244,   0x51a9 },       { 0xa9ddbead,   0xc6fb },       { 0xab24ffab,   0x4e8a },\r
304     { 0xabef8ac4,       0x2710 },       { 0xabfa20ac,   0x6fb4 },       { 0xad36895e,   0x4e2 },        { 0xad36895f,   0x4e3 },\r
305     { 0xaf310e90,       0x402 },        { 0xaf31166f,   0x4e8 },        { 0xaf7277a5,   0x3b6 },        { 0xafc0d8b3,   0x96c6 },\r
306     { 0xb0fd5dba,       0xcae0 },       { 0xb0fd5e95,   0xcadc },       { 0xb1052893,   0x7149 },       { 0xb1e98745,   0x36a },\r
307     { 0xb277e91c,       0x5166 },       { 0xb2f7eac5,   0xcae0 },       { 0xb2f7eba0,   0xcadc },       { 0xb2f7ebc1,   0x3b5 },\r
308     { 0xb53fa77d,       0x3a8 },        { 0xb6391138,   0x6fb5 },       { 0xb7358b7f,   0x6fb6 },       { 0xb8c42b40,   0x4e4 },\r
309     { 0xb8c42ea4,       0x1b5 },        { 0xb8c439e7,   0x2e1 },        { 0xb8c43a61,   0x307 },        { 0xb8c43d6c,   0x4e4 },\r
310     { 0xb8c43ddf,       0x352 },        { 0xb8c43de1,   0x354 },        { 0xb8c43de6,   0x359 },        { 0xb8c43dff,   0x35d },\r
311     { 0xb8c43e04,       0x362 },        { 0xb8c43e07,   0x365 },        { 0xbcd29a7f,   0x3a8 },        { 0xbce34e78,   0x5182 },\r
312     { 0xbce34e7b,       0x556a },       { 0xbce81504,   0x3b5 },        { 0xbd8a4c95,   0x272d },       { 0xbdd89dad,   0x4e4 },\r
313     { 0xbdd89dae,       0x6fb0 },       { 0xbdd89daf,   0x6fb1 },       { 0xbdd89db0,   0x6fb2 },       { 0xbdd89db1,   0x4e6 },\r
314     { 0xbdd89db5,       0x6fbd },       { 0xc1756e9f,   0x36b },        { 0xc7482444,   0x47a },        { 0xc9281c18,   0x4e4 },\r
315     { 0xc9ef95df,       0x47b },        { 0xccc9db0d,   0x4e4 },        { 0xccc9db0e,   0x6fb0 },       { 0xcd73425f,   0x3b6 },\r
316     { 0xce38b40b,       0x4b0 },        { 0xce99e549,   0x25 },         { 0xcf598740,   0x4e7 },        { 0xcf6d6f78,   0x4e4 },\r
317     { 0xcf758df6,       0x3a4 },        { 0xd1266e51,   0x6fb5 },       { 0xd2910213,   0x2718 },       { 0xd29196bb,   0x2712 },\r
318     { 0xd3eb2fc2,       0x476 },        { 0xd442dc2c,   0x4fc4 },       { 0xd9da4da4,   0x2711 },       { 0xdbad2f42,   0x4e4 },\r
319     { 0xdbad2f43,       0x6fb0 },       { 0xdbad2f44,   0x6fb1 },       { 0xdbad2f45,   0x6fb2 },       { 0xdbad2f46,   0x6fb3 },\r
320     { 0xdbad2f47,       0x6fb4 },       { 0xdbad2f48,   0x6fb5 },       { 0xdbad2f49,   0x6fb6 },       { 0xdbad2f4a,   0x4e6 },\r
321     { 0xdc438033,       0x4f31 },       { 0xdccb439b,   0x477 },        { 0xdccdc626,   0x3b5 },        { 0xdd80a595,   0x4e4 },\r
322     { 0xdd80a596,       0x6fb0 },       { 0xdd80a59e,   0x6fb1 },       { 0xdd80a5b4,   0x6fb2 },       { 0xdd80a5d9,   0x6fb5 },\r
323     { 0xdd80a5da,       0x6fb4 },       { 0xdd80a5fa,   0x6fb6 },       { 0xdd80a615,   0x6fb3 },       { 0xdd80a619,   0x4e6 },\r
324     { 0xdd80a61a,       0x3b5 },        { 0xdd80c0f8,   0x4e9f },       { 0xdf7e46ff,   0x4fc8 },       { 0xdf8680fd,   0x556a },\r
325     { 0xdfb0bd6e,       0xc42d },       { 0xdff05486,   0x2c4 },        { 0xe3323399,   0x3a4 },        { 0xe60412dd,   0x3b5 },\r
326     { 0xeee47add,       0x4b0 },        { 0xf021a186,   0x4e2 },        { 0xf021a187,   0x4e3 },        { 0xf021a188,   0x4e4 },\r
327     { 0xf021a189,       0x4e5 },        { 0xf021a18a,   0x4e6 },        { 0xf021a18b,   0x4e7 },        { 0xf021a18c,   0x4e8 },\r
328     { 0xf021a18d,       0x4e9 },        { 0xf021a18e,   0x4ea },        { 0xf0700456,   0x6fb3 },       { 0xf274f175,   0x3b5 },\r
329     { 0xf2a9730b,       0x3a8 },        { 0xf3d463c2,   0x3a4 },        { 0xf52a70a3,   0xc42e },       { 0xf5693147,   0x6fb3 },\r
330     { 0xf637e157,       0x478 },        { 0xfc213f3a,   0x2717 },       { 0xff654d14,   0x3b5 },\r
331 };\r
332 FX_WORD FX_GetCodePageFromStringA(FX_LPCSTR pStr, int32_t iLength)\r
333 {\r
334     FXSYS_assert(pStr != NULL);\r
335     if (iLength < 0) {\r
336         iLength = FXSYS_strlen(pStr);\r
337     }\r
338     if (iLength == 0) {\r
339         return 0xFFFF;\r
340     }\r
341     uint32_t uHash = FX_HashCode_String_GetA(pStr, iLength, TRUE);\r
342     int32_t iStart = 0, iMid;\r
343     int32_t iEnd = sizeof(g_FXCPHashTable) / sizeof(FX_STR2CPHASH) - 1;\r
344     FXSYS_assert(iEnd >= 0);\r
345     do {\r
346         iMid = (iStart + iEnd) / 2;\r
347         const FX_STR2CPHASH & cp = g_FXCPHashTable[iMid];\r
348         if (uHash == cp.uHash) {\r
349             return (FX_WORD)cp.uCodePage;\r
350         } else if (uHash < cp.uHash) {\r
351             iEnd = iMid - 1;\r
352         } else {\r
353             iStart = iMid + 1;\r
354         }\r
355     } while (iStart <= iEnd);\r
356     return 0xFFFF;\r
357 }\r
358 FX_WORD FX_GetCodePageFormStringW(FX_LPCWSTR pStr, int32_t iLength)\r
359 {\r
360     if (iLength < 0) {\r
361         iLength = FXSYS_wcslen(pStr);\r
362     }\r
363     if (iLength == 0) {\r
364         return 0xFFFF;\r
365     }\r
366     CFX_ByteString csStr;\r
367     FX_LPSTR pBuf = csStr.GetBuffer(iLength + 1);\r
368     for (int32_t i = 0; i < iLength; ++i) {\r
369         *pBuf ++ = (FX_CHAR) * pStr ++;\r
370     }\r
371     csStr.ReleaseBuffer(iLength);\r
372     return FX_GetCodePageFromStringA(csStr, iLength);\r
373 }\r