dbf_lang.pas 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639
  1. unit dbf_lang;
  2. {$I dbf_common.inc}
  3. interface
  4. uses
  5. {$ifdef WIN32}
  6. Windows;
  7. {$else}
  8. {$ifdef KYLIX}
  9. Libc,
  10. {$endif}
  11. Types, dbf_wtil;
  12. {$endif}
  13. const
  14. //*************************************************************************//
  15. // DB3/DB4/FoxPro Lang ID consts, for readable code
  16. //*************************************************************************//
  17. // ...
  18. FoxLangId_ENU_437 = $01;
  19. FoxLangId_Intl_850 = $02;
  20. FoxLangId_Windows_1252 = $03;
  21. FoxLangId_Mac_10000 = $04;
  22. // ...
  23. DbfLangId_DAN_865 = $08;
  24. DbfLangId_NLD_437 = $09;
  25. DbfLangId_NLD_850 = $0A;
  26. DbfLangId_FIN_437 = $0B;
  27. DbfLangId_FIN_850 = $0C; // is it used? does not exist in BDE
  28. DbfLangId_FRA_437 = $0D;
  29. DbfLangId_FRA_850 = $0E;
  30. DbfLangId_DEU_437 = $0F;
  31. DbfLangId_DEU_850 = $10;
  32. DbfLangId_ITA_437 = $11;
  33. DbfLangId_ITA_850 = $12;
  34. DbfLangId_JPN_932 = $13;
  35. DbfLangId_ESP_850 = $14;
  36. DbfLangId_SVE_437 = $15;
  37. DbfLangId_SVE_850 = $16;
  38. DbfLangId_NOR_865 = $17;
  39. DbfLangId_ESP_437 = $18;
  40. DbfLangId_ENG_437 = $19;
  41. DbfLangId_ENG_850 = $1A;
  42. DbfLangId_ENU_437 = $1B;
  43. DbfLangId_FRC_863 = $1C;
  44. DbfLangId_FRC_850 = $1D;
  45. // ...
  46. DbfLangId_CSY_852 = $1F;
  47. DbfLangId_CSY_867 = $20;
  48. // ...
  49. DbfLangId_HUN_852 = $22;
  50. DbfLangId_PLK_852 = $23;
  51. DbfLangId_PTG_860 = $24;
  52. DbfLangId_PTB_850 = $25;
  53. DbfLangId_RUS_866 = $26;
  54. // ...
  55. DbfLangId_ENU_850 = $37;
  56. // ...
  57. DbfLangId_CHS_936 = $4D;
  58. DbfLangId_KOR_949 = $4E;
  59. DbfLangId_CHT_950 = $4F;
  60. DbfLangId_THA_874 = $50;
  61. // ...
  62. DbfLangId_JPN_DIC_932 = $56;
  63. DbfLangId_Ascii_1252 = $57;
  64. DbfLangId_WEurope_1252 = $58;
  65. DbfLangId_Spanish_1252 = $59;
  66. // ...
  67. FoxLangId_German_437 = $5E;
  68. FoxLangId_Nordic_437 = $5F;
  69. FoxLangId_Nordic_850 = $60;
  70. FoxLangId_German_1252 = $61;
  71. FoxLangId_Nordic_1252 = $62;
  72. // ...
  73. FoxLangId_EEurope_852 = $64;
  74. FoxLangId_Russia_866 = $65;
  75. FoxLangId_Nordic_865 = $66;
  76. FoxLangId_Iceland_861 = $67;
  77. FoxLangId_Czech_895 = $68;
  78. // ...
  79. DbfLangId_POL_620 = $69;
  80. // ...
  81. FoxLangId_Greek_737 = $6A;
  82. FoxLangId_Turkish_857 = $6B;
  83. // ...
  84. FoxLangId_Taiwan_950 = $78;
  85. FoxLangId_Korean_949 = $79;
  86. FoxLangId_Chinese_936 = $7A;
  87. FoxLangId_Japan_932 = $7B;
  88. FoxLangId_Thai_874 = $7C;
  89. FoxLangId_Hebrew_1255 = $7D;
  90. FoxLangId_Arabic_1256 = $7E;
  91. // ...
  92. DbfLangId_Hebrew = $85;
  93. DbfLangId_ELL_437 = $86; // greek, code page 737 (?)
  94. DbfLangId_SLO_852 = $87;
  95. DbfLangId_TRK_857 = $88;
  96. // ...
  97. DbfLangId_BUL_868 = $8E;
  98. // ...
  99. FoxLangId_Russia_10007 = $96;
  100. FoxLangId_EEurope_10029 = $97;
  101. FoxLangId_Greek_10006 = $98;
  102. // ...
  103. FoxLangId_Czech_1250 = $9B;
  104. FoxLangId_Czech_850 = $9C; // DOS
  105. // ...
  106. FoxLangId_EEurope_1250 = $C8;
  107. FoxLangId_Russia_1251 = $C9;
  108. FoxLangId_Turkish_1254 = $CA;
  109. FoxLangId_Greek_1253 = $CB;
  110. // special constants
  111. DbfLocale_NotFound = $010000;
  112. DbfLocale_Bul868 = $020000;
  113. //*************************************************************************//
  114. // DB3/DB4/FoxPro Language ID to CodePage convert table
  115. //*************************************************************************//
  116. LangId_To_CodePage: array[Byte] of Word =
  117. // | 0| 1| 2| 3| 4| 5| 6| 7|
  118. // | 8| 9| A| B| C| D| E| F|
  119. // | | | | | | | | |
  120. {00} ( 0, 437, 850, 1252,10000, 0, 0, 0,
  121. {08} 865, 437, 850, 437, 850, 437, 850, 437,
  122. {10} 850, 437, 850, 932, 850, 437, 850, 865,
  123. {18} 437, 437, 850, 437, 863, 850, 0, 852,
  124. {20} 867, 0, 852, 852, 860, 850, 866, 0,
  125. {28} 0, 0, 0, 0, 0, 0, 0, 0,
  126. {30} 0, 0, 0, 0, 0, 0, 0, 850,
  127. {38} 0, 0, 0, 0, 0, 0, 0, 0,
  128. {40} 0, 0, 0, 0, 0, 0, 0, 0,
  129. {48} 0, 0, 0, 0, 0, 936, 949, 950,
  130. {50} 874, 0, 0, 0, 0, 0, 932, 1252,
  131. {58} 1252, 1252, 0, 0, 0, 0, 437, 437,
  132. {60} 850, 1252, 1252, 0, 852, 866, 865, 861,
  133. {68} 895, 620, 737, 857, 0, 0, 0, 0,
  134. {70} 0, 0, 0, 0, 0, 0, 0, 0,
  135. {78} 950, 949, 936, 932, 874, 1255, 1256, 0,
  136. {80} 0, 0, 0, 0, 0, 862, 437, 852,
  137. {88} 857, 0, 0, 0, 0, 0, 868, 0,
  138. {90} 0, 0, 0, 0, 0, 0,10007,10029,
  139. {98} 10006, 0, 0, 1250, 850, 0, 0, 0,
  140. {A0} 0, 0, 0, 0, 0, 0, 0, 0,
  141. {A8} 0, 0, 0, 0, 0, 0, 0, 0,
  142. {B0} 0, 0, 0, 0, 0, 0, 0, 0,
  143. {B8} 0, 0, 0, 0, 0, 0, 0, 0,
  144. {C0} 0, 0, 0, 0, 0, 0, 0, 0,
  145. {C8} 1250, 1251, 1254, 1253, 0, 0, 0, 0,
  146. {D0} 0, 0, 0, 0, 0, 0, 0, 0,
  147. {D8} 0, 0, 0, 0, 0, 0, 0, 0,
  148. {E0} 0, 0, 0, 0, 0, 0, 0, 0,
  149. {E8} 0, 0, 0, 0, 0, 0, 0, 0,
  150. {F0} 0, 0, 0, 0, 0, 0, 0, 0,
  151. {F8} 0, 0, 0, 0, 0, 0, 0, 0);
  152. {$ifdef FPC_VERSION}
  153. {$ifdef VER1_0}
  154. LANG_ARABIC = $01;
  155. LANG_HEBREW = $0d;
  156. LANG_THAI = $1e;
  157. SUBLANG_KOREAN = $01; { Korean (Extended Wansung) }
  158. SORT_CHINESE_PRC = $2; { PRC Chinese Stroke Count order }
  159. {$endif}
  160. {$endif}
  161. //*************************************************************************//
  162. // DB3/DB4/FoxPro Language ID to Locale convert table
  163. //*************************************************************************//
  164. // table
  165. LangId_To_Locale: array[Byte] of LCID =
  166. (
  167. DbfLocale_NotFound,
  168. {01} LANG_ENGLISH or (SUBLANG_ENGLISH_US shl 10) or (SORT_DEFAULT shl 16),
  169. LANG_ENGLISH or (SUBLANG_ENGLISH_UK shl 10) or (SORT_DEFAULT shl 16), {international ??}
  170. LANG_ENGLISH or (SUBLANG_ENGLISH_UK shl 10) or (SORT_DEFAULT shl 16), {windows ??}
  171. LANG_ENGLISH or (SUBLANG_ENGLISH_UK shl 10) or (SORT_DEFAULT shl 16), {macintosh ??}
  172. 0,0,0,
  173. {08} LANG_DANISH or (SUBLANG_DEFAULT shl 10) or (SORT_DEFAULT shl 16),
  174. LANG_DUTCH or (SUBLANG_DUTCH shl 10) or (SORT_DEFAULT shl 16),
  175. LANG_DUTCH or (SUBLANG_DUTCH shl 10) or (SORT_DEFAULT shl 16),
  176. LANG_FINNISH or (SUBLANG_DEFAULT shl 10) or (SORT_DEFAULT shl 16),
  177. LANG_FINNISH or (SUBLANG_DEFAULT shl 10) or (SORT_DEFAULT shl 16),
  178. LANG_FRENCH or (SUBLANG_FRENCH shl 10) or (SORT_DEFAULT shl 16),
  179. LANG_FRENCH or (SUBLANG_FRENCH shl 10) or (SORT_DEFAULT shl 16),
  180. LANG_GERMAN or (SUBLANG_GERMAN shl 10) or (SORT_DEFAULT shl 16),
  181. LANG_GERMAN or (SUBLANG_GERMAN shl 10) or (SORT_DEFAULT shl 16),
  182. LANG_ITALIAN or (SUBLANG_ITALIAN shl 10) or (SORT_DEFAULT shl 16),
  183. LANG_ITALIAN or (SUBLANG_ITALIAN shl 10) or (SORT_DEFAULT shl 16),
  184. LANG_JAPANESE or (SUBLANG_DEFAULT shl 10) or (SORT_DEFAULT shl 16),
  185. LANG_SPANISH or (SUBLANG_SPANISH shl 10) or (SORT_DEFAULT shl 16),
  186. LANG_SWEDISH or (SUBLANG_DEFAULT shl 10) or (SORT_DEFAULT shl 16),
  187. LANG_SWEDISH or (SUBLANG_DEFAULT shl 10) or (SORT_DEFAULT shl 16),
  188. LANG_NORWEGIAN or (SUBLANG_DEFAULT shl 10) or (SORT_DEFAULT shl 16),
  189. LANG_SPANISH or (SUBLANG_DEFAULT shl 10) or (SORT_DEFAULT shl 16),
  190. LANG_ENGLISH or (SUBLANG_ENGLISH_UK shl 10) or (SORT_DEFAULT shl 16),
  191. LANG_ENGLISH or (SUBLANG_ENGLISH_UK shl 10) or (SORT_DEFAULT shl 16),
  192. LANG_ENGLISH or (SUBLANG_ENGLISH_US shl 10) or (SORT_DEFAULT shl 16),
  193. LANG_FRENCH or (SUBLANG_FRENCH_CANADIAN shl 10) or (SORT_DEFAULT shl 16),
  194. LANG_FRENCH or (SUBLANG_FRENCH_CANADIAN shl 10) or (SORT_DEFAULT shl 16),
  195. {1E} 0,
  196. {1F} LANG_CZECH or (SUBLANG_DEFAULT shl 10) or (SORT_DEFAULT shl 16),
  197. LANG_CZECH or (SUBLANG_DEFAULT shl 10) or (SORT_DEFAULT shl 16),
  198. {21} 0,
  199. {22} LANG_HUNGARIAN or (SUBLANG_DEFAULT shl 10) or (SORT_DEFAULT shl 16),
  200. LANG_POLISH or (SUBLANG_DEFAULT shl 10) or (SORT_DEFAULT shl 16),
  201. LANG_PORTUGUESE or (SUBLANG_PORTUGUESE_BRAZILIAN shl 10) or (SORT_DEFAULT shl 16),
  202. LANG_PORTUGUESE or (SUBLANG_PORTUGUESE_BRAZILIAN shl 10) or (SORT_DEFAULT shl 16),
  203. LANG_RUSSIAN or (SUBLANG_DEFAULT shl 10) or (SORT_DEFAULT shl 16),
  204. {27} 0,0,0,0,0,0,0,0,0,
  205. {30} 0,0,0,0,0,0,0,
  206. {37} LANG_ENGLISH or (SUBLANG_ENGLISH_US shl 10) or (SORT_DEFAULT shl 16),
  207. {38} 0,0,0,0,0,0,0,0,
  208. {40} 0,0,0,0,0,0,0,0,0,0,0,0,0,
  209. {4D} LANG_CHINESE or (SUBLANG_CHINESE_SIMPLIFIED shl 10) or (SORT_DEFAULT shl 16),
  210. LANG_KOREAN or (SUBLANG_KOREAN shl 10) or (SORT_DEFAULT shl 16),
  211. LANG_CHINESE or (SUBLANG_CHINESE_TRADITIONAL shl 10) or (SORT_DEFAULT shl 16),
  212. LANG_THAI or (SUBLANG_DEFAULT shl 10) or (SORT_DEFAULT shl 16),
  213. {51} 0,0,0,0,0,
  214. {56} LANG_JAPANESE or (SUBLANG_DEFAULT shl 10) or (SORT_DEFAULT shl 16), // JPN: Dic932 ??
  215. 0, // Ascii: Binary
  216. LANG_ENGLISH or (SUBLANG_ENGLISH_UK shl 10) or (SORT_DEFAULT shl 16), // Western Europe ??
  217. LANG_SPANISH or (SUBLANG_SPANISH shl 10) or (SORT_DEFAULT shl 16),
  218. {5A} 0,0,0,0,
  219. // FoxPro
  220. {5E} LANG_GERMAN or (SUBLANG_GERMAN shl 10) or (SORT_DEFAULT shl 16),
  221. LANG_NORWEGIAN or (SUBLANG_DEFAULT shl 10) or (SORT_DEFAULT shl 16),
  222. LANG_NORWEGIAN or (SUBLANG_DEFAULT shl 10) or (SORT_DEFAULT shl 16),
  223. LANG_GERMAN or (SUBLANG_DEFAULT shl 10) or (SORT_DEFAULT shl 16),
  224. LANG_NORWEGIAN or (SUBLANG_DEFAULT shl 10) or (SORT_DEFAULT shl 16),
  225. {63} 0,
  226. {64} LANG_CZECH or (SUBLANG_DEFAULT shl 10) or (SORT_DEFAULT shl 16), // Eastern Europe ??
  227. LANG_RUSSIAN or (SUBLANG_DEFAULT shl 10) or (SORT_DEFAULT shl 16),
  228. LANG_NORWEGIAN or (SUBLANG_DEFAULT shl 10) or (SORT_DEFAULT shl 16),
  229. LANG_ICELANDIC or (SUBLANG_DEFAULT shl 10) or (SORT_DEFAULT shl 16),
  230. LANG_CZECH or (SUBLANG_DEFAULT shl 10) or (SORT_DEFAULT shl 16),
  231. LANG_POLISH or (SUBLANG_DEFAULT shl 10) or (SORT_DEFAULT shl 16),
  232. LANG_GREEK or (SUBLANG_DEFAULT shl 10) or (SORT_DEFAULT shl 16),
  233. LANG_TURKISH or (SUBLANG_DEFAULT shl 10) or (SORT_DEFAULT shl 16),
  234. {6C} 0,0,0,0,
  235. {70} 0,0,0,0,0,0,0,0,
  236. {78} LANG_CHINESE or (SUBLANG_CHINESE_HONGKONG shl 10) or (SORT_DEFAULT shl 16),
  237. LANG_KOREAN or (SUBLANG_KOREAN shl 10) or (SORT_DEFAULT shl 16),
  238. LANG_CHINESE or (SUBLANG_CHINESE_SINGAPORE shl 10) or (SORT_CHINESE_PRC shl 16),
  239. LANG_JAPANESE or (SUBLANG_DEFAULT shl 10) or (SORT_DEFAULT shl 16), // JPN: Dic932 ??
  240. LANG_THAI or (SUBLANG_DEFAULT shl 10) or (SORT_DEFAULT shl 16),
  241. LANG_HEBREW or (SUBLANG_DEFAULT shl 10) or (SORT_DEFAULT shl 16),
  242. LANG_ARABIC or (SUBLANG_DEFAULT shl 10) or (SORT_DEFAULT shl 16),
  243. 0,
  244. {80} 0,0,0,0,0,
  245. // dBase
  246. {85} LANG_HEBREW or (SUBLANG_DEFAULT shl 10) or (SORT_DEFAULT shl 16),
  247. LANG_GREEK or (SUBLANG_DEFAULT shl 10) or (SORT_DEFAULT shl 16),
  248. LANG_SLOVAK or (SUBLANG_DEFAULT shl 10) or (SORT_DEFAULT shl 16),
  249. LANG_TURKISH or (SUBLANG_DEFAULT shl 10) or (SORT_DEFAULT shl 16),
  250. {89} 0,0,0,0,0,
  251. {8E} LANG_BULGARIAN or (SUBLANG_DEFAULT shl 10) or (SORT_DEFAULT shl 16),
  252. {8F} 0,0,0,0,0,0,0,
  253. {96} LANG_RUSSIAN or (SUBLANG_DEFAULT shl 10) or (SORT_DEFAULT shl 16),
  254. LANG_CZECH or (SUBLANG_DEFAULT shl 10) or (SORT_DEFAULT shl 16), // Eastern Europe ??
  255. LANG_GREEK or (SUBLANG_DEFAULT shl 10) or (SORT_DEFAULT shl 16),
  256. 0,0,
  257. // FoxPro
  258. {9B} LANG_CZECH or (SUBLANG_DEFAULT shl 10) or (SORT_DEFAULT shl 16),
  259. LANG_CZECH or (SUBLANG_DEFAULT shl 10) or (SORT_DEFAULT shl 16),
  260. {9D} 0,0,0,
  261. {A0} 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  262. {B0} 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  263. {C0} 0,0,0,0,0,0,0,0,
  264. {C8} LANG_CZECH or (SUBLANG_DEFAULT shl 10) or (SORT_DEFAULT shl 16), // Eastern Europe ??
  265. LANG_RUSSIAN or (SUBLANG_DEFAULT shl 10) or (SORT_DEFAULT shl 16),
  266. LANG_TURKISH or (SUBLANG_DEFAULT shl 10) or (SORT_DEFAULT shl 16),
  267. LANG_GREEK or (SUBLANG_DEFAULT shl 10) or (SORT_DEFAULT shl 16),
  268. {CC} 0,0,0,0,
  269. {D0} 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  270. {E0} 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  271. {F0} 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
  272. );
  273. //*************************************************************************//
  274. // DB7 LangID Locale substrings
  275. //*************************************************************************//
  276. // convert table
  277. LangId_To_LocaleStr: array[Byte] of Cardinal =
  278. (
  279. DbfLocale_NotFound,
  280. {01} Ord('U') or (Ord('S') shl 8) or (Ord('0') shl 16),
  281. Ord('U') or (Ord('K') shl 8) or (Ord('0') shl 16),
  282. Ord('U') or (Ord('K') shl 8) or (Ord('0') shl 16),
  283. Ord('U') or (Ord('K') shl 8) or (Ord('0') shl 16),
  284. 0,0,0,
  285. {08} Ord('D') or (Ord('A') shl 8) or (Ord('0') shl 16),
  286. Ord('N') or (Ord('L') shl 8) or (Ord('0') shl 16),
  287. Ord('N') or (Ord('L') shl 8) or (Ord('0') shl 16),
  288. Ord('F') or (Ord('I') shl 8) or (Ord('0') shl 16),
  289. Ord('F') or (Ord('I') shl 8) or (Ord('0') shl 16),
  290. Ord('F') or (Ord('R') shl 8) or (Ord('0') shl 16),
  291. Ord('F') or (Ord('R') shl 8) or (Ord('0') shl 16),
  292. Ord('D') or (Ord('E') shl 8) or (Ord('0') shl 16),
  293. Ord('D') or (Ord('E') shl 8) or (Ord('0') shl 16),
  294. Ord('I') or (Ord('T') shl 8) or (Ord('0') shl 16),
  295. Ord('I') or (Ord('T') shl 8) or (Ord('1') shl 16),
  296. Ord('J') or (Ord('P') shl 8) or (Ord('0') shl 16),
  297. Ord('E') or (Ord('S') shl 8) or (Ord('0') shl 16),
  298. Ord('S') or (Ord('V') shl 8) or (Ord('0') shl 16),
  299. Ord('S') or (Ord('V') shl 8) or (Ord('1') shl 16),
  300. Ord('N') or (Ord('O') shl 8) or (Ord('0') shl 16),
  301. Ord('E') or (Ord('S') shl 8) or (Ord('1') shl 16),
  302. Ord('U') or (Ord('K') shl 8) or (Ord('0') shl 16),
  303. Ord('U') or (Ord('K') shl 8) or (Ord('0') shl 16),
  304. Ord('U') or (Ord('S') shl 8) or (Ord('0') shl 16),
  305. Ord('C') or (Ord('F') shl 8) or (Ord('1') shl 16),
  306. Ord('C') or (Ord('F') shl 8) or (Ord('1') shl 16),
  307. {1E} 0,
  308. {1F} Ord('C') or (Ord('Z') shl 8) or (Ord('0') shl 16),
  309. Ord('C') or (Ord('Z') shl 8) or (Ord('0') shl 16),
  310. {21} 0,
  311. {22} Ord('H') or (Ord('D') shl 8) or (Ord('C') shl 16),
  312. Ord('P') or (Ord('O') shl 8) or (Ord('0') shl 16),
  313. Ord('P') or (Ord('T') shl 8) or (Ord('0') shl 16),
  314. Ord('P') or (Ord('T') shl 8) or (Ord('0') shl 16),
  315. Ord('R') or (Ord('U') shl 8) or (Ord('0') shl 16),
  316. {27} 0,0,0,0,0,0,0,0,0,
  317. {30} 0,0,0,0,0,0,0,
  318. {37} Ord('U') or (Ord('S') shl 8) or (Ord('0') shl 16),
  319. {38} 0,0,0,0,0,0,0,0,
  320. {40} 0,0,0,0,0,0,0,0,0,0,0,0,0,
  321. {4D} Ord('C') or (Ord('N') shl 8) or (Ord('0') shl 16),
  322. Ord('K') or (Ord('O') shl 8) or (Ord('0') shl 16),
  323. Ord('T') or (Ord('W') shl 8) or (Ord('0') shl 16),
  324. Ord('T') or (Ord('H') shl 8) or (Ord('0') shl 16),
  325. {51} 0,0,0,0,0,
  326. {56} Ord('J') or (Ord('P') shl 8) or (Ord('1') shl 16),
  327. Ord('U') or (Ord('S') shl 8) or (Ord('0') shl 16),
  328. Ord('W') or (Ord('E') shl 8) or (Ord('0') shl 16),
  329. Ord('E') or (Ord('S') shl 8) or (Ord('0') shl 16),
  330. {5A} 0,0,0,0,
  331. // FoxPro
  332. {5E} Ord('D') or (Ord('E') shl 8),
  333. Ord('N') or (Ord('O') shl 8),
  334. Ord('N') or (Ord('O') shl 8),
  335. Ord('D') or (Ord('E') shl 8),
  336. Ord('N') or (Ord('O') shl 8),
  337. {63} 0,
  338. {64} Ord('C') or (Ord('Z') shl 8) or (Ord('0') shl 16),
  339. Ord('R') or (Ord('U') shl 8) or (Ord('0') shl 16),
  340. Ord('N') or (Ord('O') shl 8),
  341. Ord('I') or (Ord('C') shl 8) or (Ord('0') shl 16), // made this one up: iceland
  342. Ord('C') or (Ord('Z') shl 8) or (Ord('0') shl 16),
  343. {69} Ord('P') or (Ord('O') shl 8) or (Ord('1') shl 16),
  344. Ord('G') or (Ord('R') shl 8) or (Ord('0') shl 16),
  345. Ord('T') or (Ord('R') shl 8) or (Ord('0') shl 16),
  346. {6C} 0,0,0,0,
  347. {70} 0,0,0,0,0,0,0,0,
  348. {78} Ord('C') or (Ord('H') shl 8) or (Ord('0') shl 16), // made this one up: chinese hongkong
  349. Ord('K') or (Ord('O') shl 8) or (Ord('0') shl 16),
  350. Ord('C') or (Ord('S') shl 8) or (Ord('0') shl 16), // made this one up: chinese singapore
  351. Ord('J') or (Ord('P') shl 8) or (Ord('0') shl 16),
  352. Ord('T') or (Ord('H') shl 8) or (Ord('0') shl 16),
  353. Ord('R') or (Ord('E') shl 8) or (Ord('W') shl 16),
  354. Ord('A') or (Ord('R') shl 8) or (Ord('0') shl 16), // made this one up: arabic (default)
  355. {7F} 0,
  356. {80} 0,0,0,0,0,
  357. // dBase
  358. {85} Ord('R') or (Ord('E') shl 8) or (Ord('W') shl 16),
  359. Ord('G') or (Ord('R') shl 8) or (Ord('0') shl 16),
  360. Ord('S') or (Ord('L') shl 8) or (Ord('0') shl 16),
  361. Ord('T') or (Ord('R') shl 8) or (Ord('0') shl 16),
  362. {89} 0,0,0,0,0,
  363. {8E} DbfLocale_Bul868,
  364. {8F} 0,0,0,0,0,0,0,
  365. {96} Ord('R') or (Ord('U') shl 8) or (Ord('0') shl 16),
  366. Ord('C') or (Ord('Z') shl 8) or (Ord('0') shl 16),
  367. Ord('G') or (Ord('R') shl 8) or (Ord('0') shl 16),
  368. {99} 0,0,
  369. // FoxPro
  370. {9B} 0, //LANG_CZECH or (SUBLANG_DEFAULT shl 10) or (SORT_DEFAULT shl 16),
  371. 0, //LANG_CZECH or (SUBLANG_DEFAULT shl 10) or (SORT_DEFAULT shl 16),
  372. {9D} 0,0,0,
  373. {A0} 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  374. {B0} 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  375. {C0} 0,0,0,0,0,0,0,0,
  376. {C8} Ord('C') or (Ord('Z') shl 8) or (Ord('0') shl 16),
  377. Ord('R') or (Ord('U') shl 8) or (Ord('0') shl 16),
  378. Ord('T') or (Ord('R') shl 8) or (Ord('0') shl 16),
  379. Ord('G') or (Ord('R') shl 8) or (Ord('0') shl 16),
  380. {CC} 0,0,0,0,
  381. {D0} 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  382. {E0} 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  383. {F0} 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
  384. );
  385. {
  386. DbfLocaleId_DAN_865 = Ord('D') or (Ord('A') shl 8) or (Ord('0') shl 16);
  387. DbfLocaleId_NLD_437 = Ord('N') or (Ord('L') shl 8) or (Ord('0') shl 16);
  388. DbfLocaleId_NLD_850 = Ord('N') or (Ord('L') shl 8) or (Ord('0') shl 16);
  389. DbfLocaleId_FIN_437 = Ord('F') or (Ord('I') shl 8) or (Ord('0') shl 16);
  390. DbfLocaleId_FIN_850 = Ord('F') or (Ord('I') shl 8) or (Ord('0') shl 16);
  391. DbfLocaleId_FRA_437 = Ord('F') or (Ord('R') shl 8) or (Ord('0') shl 16);
  392. DbfLocaleId_FRA_850 = Ord('F') or (Ord('R') shl 8) or (Ord('0') shl 16);
  393. DbfLocaleId_DEU_437 = Ord('D') or (Ord('E') shl 8) or (Ord('0') shl 16);
  394. DbfLocaleId_DEU_850 = Ord('D') or (Ord('E') shl 8) or (Ord('0') shl 16);
  395. DbfLocaleId_ITA_437 = Ord('I') or (Ord('T') shl 8) or (Ord('0') shl 16);
  396. DbfLocaleId_ITA_850 = Ord('I') or (Ord('T') shl 8) or (Ord('1') shl 16);
  397. DbfLocaleId_JPN_932 = Ord('J') or (Ord('P') shl 8) or (Ord('0') shl 16);
  398. DbfLocaleId_ESP_850 = Ord('E') or (Ord('S') shl 8) or (Ord('0') shl 16);
  399. DbfLocaleId_SVE_437 = Ord('S') or (Ord('V') shl 8) or (Ord('0') shl 16);
  400. DbfLocaleId_SVE_850 = Ord('S') or (Ord('V') shl 8) or (Ord('1') shl 16);
  401. DbfLocaleId_NOR_865 = Ord('N') or (Ord('O') shl 8) or (Ord('0') shl 16);
  402. DbfLocaleId_ESP_437 = Ord('E') or (Ord('S') shl 8) or (Ord('1') shl 16);
  403. DbfLocaleId_ENG_437 = Ord('U') or (Ord('K') shl 8) or (Ord('0') shl 16);
  404. DbfLocaleId_ENG_850 = Ord('U') or (Ord('K') shl 8) or (Ord('0') shl 16);
  405. DbfLocaleId_ENU_437 = Ord('U') or (Ord('S') shl 8) or (Ord('0') shl 16);
  406. DbfLocaleId_FRC_863 = Ord('C') or (Ord('F') shl 8) or (Ord('1') shl 16);
  407. DbfLocaleId_FRC_850 = Ord('C') or (Ord('F') shl 8) or (Ord('1') shl 16);
  408. // ...
  409. DbfLocaleId_CSY_852 = Ord('C') or (Ord('Z') shl 8) or (Ord('0') shl 16);
  410. DbfLocaleId_CSY_867 = Ord('C') or (Ord('Z') shl 8) or (Ord('0') shl 16);
  411. // ...
  412. DbfLocaleId_HUN_852 = Ord('H') or (Ord('D') shl 8) or (Ord('C') shl 16);
  413. DbfLocaleId_PLK_852 = Ord('P') or (Ord('O') shl 8) or (Ord('0') shl 16);
  414. DbfLocaleId_PTG_860 = Ord('P') or (Ord('T') shl 8) or (Ord('0') shl 16);
  415. DbfLocaleId_PTB_850 = Ord('P') or (Ord('T') shl 8) or (Ord('0') shl 16);
  416. DbfLocaleId_RUS_866 = Ord('R') or (Ord('U') shl 8) or (Ord('0') shl 16);
  417. // ...
  418. DbfLocaleId_ENU_850 = Ord('U') or (Ord('S') shl 8) or (Ord('0') shl 16);
  419. // ...
  420. DbfLocaleId_CHS_936 = Ord('C') or (Ord('N') shl 8) or (Ord('0') shl 16);
  421. DbfLocaleId_KOR_949 = Ord('K') or (Ord('O') shl 8) or (Ord('0') shl 16);
  422. DbfLocaleId_CHT_950 = Ord('T') or (Ord('W') shl 8) or (Ord('0') shl 16);
  423. DbfLocaleId_THA_874 = Ord('T') or (Ord('H') shl 8) or (Ord('0') shl 16);
  424. // ...
  425. DbfLocaleId_JPN_DIC_932 = Ord('J') or (Ord('P') shl 8) or (Ord('1') shl 16);
  426. DbfLocaleId_Ascii_Ansi = Ord('U') or (Ord('S') shl 8) or (Ord('0') shl 16);
  427. DbfLocaleId_WEurope_Ansi = Ord('W') or (Ord('E') shl 8) or (Ord('0') shl 16);
  428. DbfLocaleId_Spanish_Ansi = Ord('E') or (Ord('S') shl 8) or (Ord('0') shl 16);
  429. // ...
  430. DbfLocaleId_Hebrew = Ord('R') or (Ord('E') shl 8) or (Ord('W') shl 16);
  431. DbfLocaleId_ELL_437 = Ord('G') or (Ord('R') shl 8) or (Ord('0') shl 16);
  432. DbfLocaleId_SLO_852 = Ord('S') or (Ord('L') shl 8) or (Ord('0') shl 16);
  433. DbfLocaleId_TRK_857 = Ord('T') or (Ord('R') shl 8) or (Ord('0') shl 16);
  434. // ...
  435. DbfLocaleId_BUL_868 = 'BGDB868';
  436. }
  437. // VdBase 7 Language strings
  438. // 'DBWIN...' -> Charset 1252 (ansi)
  439. // 'DB999...' -> Code page 999, 9 any digit
  440. // 'DBHEBREW' -> Code page 1255 ??
  441. // 'FOX..999' -> Code page 999, 9 any digit
  442. // 'FOX..WIN' -> Charset 1252 (ansi)
  443. //*************************************************************************//
  444. // reverse convert routines
  445. //*************************************************************************//
  446. function ConstructLangName(CodePage: Integer; Locale: LCID; IsFoxPro: Boolean): string;
  447. function ConstructLangId(CodePage: Integer; Locale: LCID; IsFoxPro: Boolean): Byte;
  448. function GetLangId_From_LangName(LocaleStr: string): Byte;
  449. implementation
  450. uses
  451. SysUtils;
  452. type
  453. PCardinal = ^Cardinal;
  454. function ConstructLangName(CodePage: Integer; Locale: LCID; IsFoxPro: Boolean): string;
  455. var
  456. SubType: Cardinal;
  457. begin
  458. // ANSI?
  459. SubType := LangId_To_LocaleStr[ConstructLangId(CodePage, Locale, IsFoxPro)];
  460. // found?
  461. if SubType <> DbfLocale_NotFound then
  462. begin
  463. // foxpro or dbase?
  464. if IsFoxPro then
  465. begin
  466. Result := 'FOX' + PChar(@SubType);
  467. if CodePage = 1252 then
  468. Result := Result + 'WIN'
  469. else
  470. Result := Result + IntToStr(CodePage);
  471. end else begin
  472. if SubType = DbfLocale_Bul868 then
  473. begin
  474. // special case
  475. Result := 'BGDB868';
  476. end else begin
  477. // start with DB
  478. Result := 'DB';
  479. // add codepage
  480. if CodePage = 1252 then
  481. Result := Result + 'WIN'
  482. else
  483. Result := Result + IntToStr(CodePage);
  484. // add subtype
  485. Result := Result + PChar(@SubType);
  486. end;
  487. end;
  488. end;
  489. end;
  490. const
  491. // range of Dbase / FoxPro locale; these are INCLUSIVE
  492. dBase_RegionCount = 4;
  493. dBase_Regions: array[0..dBase_RegionCount*2-1] of Byte =
  494. ($00, $00,
  495. $05, $5D,
  496. $69, $69, // a lonely dbf entry :-)
  497. $80, $90);
  498. function FindLangId(CodePage, Info2: Cardinal; Info2Table: PCardinal; IsFoxPro: Boolean): Byte;
  499. var
  500. I, Region, FoxRes, DbfRes: Integer;
  501. begin
  502. Region := 0;
  503. DbfRes := 0;
  504. FoxRes := 0;
  505. // scan
  506. for I := 0 to $FF do
  507. begin
  508. // check if need to advance to next region
  509. if Region + 2 < dBase_RegionCount then
  510. if I >= dBase_Regions[Region + 2] then
  511. Inc(Region, 2);
  512. // it seems delphi does not properly understand pointers?
  513. // what a mess :-(
  514. if ((LangId_To_CodePage[I] = CodePage) or (CodePage = 0)) and (PCardinal(PChar(Info2Table)+(I*4))^ = Info2) then
  515. if I <= dBase_Regions[Region+1] then
  516. DbfRes := Byte(I)
  517. else
  518. FoxRes := Byte(I);
  519. end;
  520. // if we can find langid in other set, use it
  521. if (DbfRes <> 0) and (not IsFoxPro or (FoxRes = 0)) then
  522. Result := DbfRes
  523. else {(DbfRes = 0) or (IsFoxPro and (FoxRes <> 0)}
  524. if (FoxRes <> 0) {and (IsFoxPro or (DbfRes = 0)} then
  525. Result := FoxRes
  526. else
  527. Result := 0;
  528. end;
  529. {
  530. function FindLangId(CodePage, Info2: Cardinal; Info2Table: PCardinal; IsFoxPro: Boolean): Byte;
  531. var
  532. I, Region, lEnd: Integer;
  533. EndReached: Boolean;
  534. begin
  535. Region := 0;
  536. Result := 0;
  537. repeat
  538. // determine region to scan
  539. if IsFoxPro then
  540. begin
  541. // foxpro, in between dbase regions
  542. I := dBase_Regions[Region+1] + 1;
  543. lEnd := dBase_Regions[Region+2] - 1;
  544. EndReached := Region = dBase_RegionCount*2-4;
  545. end else begin
  546. // dBase, select regions
  547. I := dBase_Regions[Region];
  548. lEnd := dBase_Regions[Region+1];
  549. EndReached := Region = dBase_RegionCount*2-2;
  550. end;
  551. // scan
  552. repeat
  553. // it seems delphi does not properly understand pointers?
  554. // what a mess :-(
  555. if (LangId_To_CodePage[I] = CodePage) and (PCardinal(PChar(Info2Table)+(I*4))^ = Info2) then
  556. Result := Byte(I);
  557. Inc(I);
  558. // lEnd is included in range
  559. until (Result <> 0) or (I > lEnd);
  560. // goto next region
  561. if (Result = 0) then
  562. Inc(Region, 2);
  563. // found or end?
  564. until (Result <> 0) or EndReached;
  565. end;
  566. }
  567. function ConstructLangId(CodePage: Integer; Locale: LCID; IsFoxPro: Boolean): Byte;
  568. begin
  569. // locale: lower 16bits only
  570. Locale := (Locale and $FFFF) or (SORT_DEFAULT shl 16);
  571. Result := FindLangId(CodePage, Locale, @LangId_To_Locale[0], IsFoxPro);
  572. // not found? try any codepage
  573. if Result = 0 then
  574. Result := FindLangId(0, Locale, @LangId_To_Locale[0], IsFoxPro);
  575. end;
  576. function GetLangId_From_LangName(LocaleStr: string): Byte;
  577. var
  578. CodePage, SubType: Integer;
  579. IsFoxPro: Boolean;
  580. CodePageStr: string;
  581. begin
  582. // determine foxpro/dbase
  583. IsFoxPro := CompareMem(PChar('FOX'), PChar(LocaleStr), 3);
  584. // get codepage/locale subtype
  585. if IsFoxPro then
  586. begin
  587. CodePageStr := Copy(LocaleStr, 6, 3);
  588. SubType := Integer(LocaleStr[4]) or (Integer(LocaleStr[5]) shl 8);
  589. end else begin
  590. CodePageStr := Copy(LocaleStr, 3, 3);
  591. SubType := Integer(LocaleStr[6]) or (Integer(LocaleStr[7]) shl 8) or (Integer(LocaleStr[8]) shl 16);
  592. end;
  593. // convert codepage string to codepage id
  594. if CodePageStr = 'WIN' then
  595. CodePage := 1252
  596. else if CodePageStr = 'REW' then // hebrew
  597. CodePage := 1255
  598. else
  599. CodePage := StrToInt(CodePageStr);
  600. // find lang id
  601. Result := FindLangId(CodePage, SubType, @LangId_To_LocaleStr[0], IsFoxPro);
  602. end;
  603. end.