Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1567 lines
41 KiB

  1. //+---------------------------------------------------------------------------
  2. //
  3. //
  4. // CThaiTrieIter - class CThaiTrieIter use for traversing trie.
  5. //
  6. // History:
  7. // created 7/99 aarayas
  8. //
  9. // �1999 Microsoft Corporation
  10. //----------------------------------------------------------------------------
  11. #include "CThaiTrieIter.hpp"
  12. #define WORDSIZE 64
  13. static unsigned int iStackSize = 0;
  14. //+---------------------------------------------------------------------------
  15. //
  16. // Function: IsThaiBeginClusterCharacter
  17. //
  18. // Synopsis:
  19. //
  20. // Arguments:
  21. //
  22. // Modifies:
  23. //
  24. // History: created 8/99 aarayas
  25. //
  26. // Notes:
  27. //
  28. //----------------------------------------------------------------------------
  29. BOOL IsThaiBeginClusterCharacter(WCHAR wc)
  30. {
  31. return ( ( wc >= THAI_Vowel_Sara_E ) && (wc <= THAI_Vowel_Sara_AI_MaiMaLai) );
  32. }
  33. //+---------------------------------------------------------------------------
  34. //
  35. // Function: IsThaiUpperAndLowerClusterCharacter
  36. //
  37. // Synopsis:
  38. //
  39. // Arguments:
  40. //
  41. // Modifies:
  42. //
  43. // History: created 7/99 aarayas
  44. //
  45. // Notes:
  46. //
  47. //----------------------------------------------------------------------------
  48. BOOL IsThaiUpperAndLowerClusterCharacter(WCHAR wc)
  49. {
  50. return ( ( (wc == THAI_Vowel_Sign_Mai_HanAkat) ) ||
  51. ( (wc >= THAI_Vowel_Sign_Sara_Am) && (wc <= THAI_Vowel_Sign_Phinthu) ) ||
  52. ( (wc >= THAI_Tone_MaiTaiKhu) && (wc <= THAI_Nikhahit) ) );
  53. }
  54. //+---------------------------------------------------------------------------
  55. //
  56. // Function: IsThaiEndingClusterCharacter
  57. //
  58. // Synopsis:
  59. //
  60. // Arguments:
  61. //
  62. // Modifies:
  63. //
  64. // History: created 8/99 aarayas
  65. //
  66. // Notes:
  67. //
  68. //----------------------------------------------------------------------------
  69. BOOL IsThaiEndingClusterCharacter(WCHAR wc)
  70. {
  71. return (
  72. // (wc == THAI_Sign_PaiYanNoi) || // take this line out to fix O11.PaiYanNoi issue.
  73. (wc == THAI_Vowel_Sara_A) ||
  74. (wc == THAI_Vowel_Sara_AA) ||
  75. (wc == THAI_Vowel_LakKhangYao) ||
  76. (wc == THAI_Vowel_MaiYaMok) );
  77. }
  78. //+---------------------------------------------------------------------------
  79. //
  80. // Function: IsThaiMostlyBeginCharacter
  81. //
  82. // Synopsis:
  83. //
  84. // Arguments:
  85. //
  86. // Modifies:
  87. //
  88. // History: created 8/99 aarayas
  89. //
  90. // Notes:
  91. //
  92. //----------------------------------------------------------------------------
  93. bool IsThaiMostlyBeginCharacter(WCHAR wc)
  94. {
  95. return ( (wc >= THAI_Vowel_Sara_E && wc <= THAI_Vowel_Sara_AI_MaiMaLai) || // Character always in front of a word.
  96. (wc == THAI_Cho_Ching) || // Character always in front of a word.
  97. (wc == THAI_Pho_Phung) || // Character always in front of a word.
  98. (wc == THAI_Fo_Fa) || // Character always in front of a word.
  99. (wc == THAI_Ho_Nok_Huk) || // Character always in front of a word.
  100. (wc == THAI_Ho_Hip) || // Character most like in front of a word.
  101. (wc == THAI_Pho_Samphao) || // Character most like in front of a word.
  102. (wc == THAI_Kho_Rakhang) || // Character most like in front of a word.
  103. (wc == THAI_Fo_Fan) || // Character most like in front of a word.
  104. (wc == THAI_So_So) || // Character most like in front of a word.
  105. (wc == THAI_Tho_NangmonTho) ); // Character most like in front of a word.
  106. }
  107. //+---------------------------------------------------------------------------
  108. //
  109. // Function: IsContain
  110. //
  111. // Synopsis:
  112. //
  113. // Arguments:
  114. //
  115. // Modifies:
  116. //
  117. // History: created 7/00 aarayas
  118. //
  119. // Notes:
  120. //
  121. //----------------------------------------------------------------------------
  122. bool IsContain(const WCHAR* pwcWord, unsigned int iWordLen, WCHAR wc)
  123. {
  124. const WCHAR* pwc = pwcWord;
  125. const WCHAR* pwcEnd = pwcWord + iWordLen;
  126. while (pwc < pwcEnd)
  127. {
  128. if (*pwc == wc)
  129. return true;
  130. pwc++;
  131. }
  132. return false;
  133. }
  134. //+---------------------------------------------------------------------------
  135. //
  136. // Function: IsThaiMostlyLastCharacter
  137. //
  138. // Synopsis:
  139. //
  140. // Arguments:
  141. //
  142. // Modifies:
  143. //
  144. // History: created 8/99 aarayas
  145. //
  146. // Notes:
  147. //
  148. //----------------------------------------------------------------------------
  149. bool IsThaiMostlyLastCharacter(WCHAR wc)
  150. {
  151. return ( (wc == THAI_Vowel_Sign_Sara_Am) || // Always the end of word.
  152. (wc == THAI_Sign_PaiYanNoi) || // Always the end of word.
  153. (wc == THAI_Vowel_MaiYaMok) || // Always the end of word.
  154. (wc == THAI_Vowel_LakKhangYao) || // Most likely the end of word.
  155. (wc == THAI_Thanthakhat) ); // Most likely the end of word.
  156. }
  157. //+---------------------------------------------------------------------------
  158. //
  159. // Function: IsThaiToneMark
  160. //
  161. // Synopsis:
  162. //
  163. // Arguments:
  164. //
  165. // Modifies:
  166. //
  167. // History: created 8/99 aarayas
  168. //
  169. // Notes:
  170. //
  171. //----------------------------------------------------------------------------
  172. bool IsThaiToneMark(WCHAR wc)
  173. {
  174. return ( (wc >= 0x0e48) && (wc <= 0x0e4b) ||
  175. (wc == 0x0e31));
  176. }
  177. //+---------------------------------------------------------------------------
  178. //
  179. // Function: IsThaiEndingSign
  180. //
  181. // Synopsis:
  182. //
  183. // Arguments:
  184. //
  185. // Modifies:
  186. //
  187. // History: created 8/02 aarayas
  188. //
  189. // Notes:
  190. //
  191. //----------------------------------------------------------------------------
  192. bool IsThaiEndingSign(WCHAR wc)
  193. {
  194. return ((bool) (wc == THAI_Vowel_MaiYaMok || wc == THAI_Sign_PaiYanNoi));
  195. }
  196. //+---------------------------------------------------------------------------
  197. //
  198. // Function: GetCluster
  199. //
  200. // Synopsis: The function return the next number of character which represent
  201. // a cluster of Thai text.
  202. //
  203. // ie. Kor Kai, Kor Kai -> 1
  204. // Kor Kai, Sara Um -> 2
  205. //
  206. // * Note this function will not return no more than 3 character,
  207. // for cluster as this would represent invalid sequence of character.
  208. //
  209. // Arguments:
  210. //
  211. // Modifies:
  212. //
  213. // History: created 7/99 aarayas
  214. //
  215. // Notes:
  216. //
  217. //----------------------------------------------------------------------------
  218. /*
  219. unsigned int GetCluster(WCHAR* pszIndex)
  220. {
  221. int iRetValue = 0;
  222. // Take all begin cluster character.
  223. while (IsThaiBeginClusterCharacter(*pszIndex))
  224. {
  225. pszIndex++;
  226. iRetValue++;
  227. }
  228. if (IsThaiConsonant(*pszIndex))
  229. {
  230. pszIndex++;
  231. iRetValue++;
  232. while (IsThaiUpperAndLowerClusterCharacter(*pszIndex))
  233. {
  234. pszIndex++;
  235. iRetValue++;
  236. }
  237. while (IsThaiEndingClusterCharacter(*pszIndex))
  238. {
  239. pszIndex++;
  240. iRetValue++;
  241. }
  242. }
  243. if (iRetValue == 0)
  244. // The character is probably a punctuation.
  245. iRetValue++;
  246. return iRetValue;
  247. }
  248. */
  249. //+---------------------------------------------------------------------------
  250. //
  251. // Function: IsThaiConsonant
  252. //
  253. // Synopsis:
  254. //
  255. // Arguments:
  256. //
  257. // Modifies:
  258. //
  259. // History: created 7/99 aarayas
  260. //
  261. // Notes:
  262. //
  263. //----------------------------------------------------------------------------
  264. BOOL IsThaiConsonant(WCHAR wc)
  265. {
  266. return ( (wc >= THAI_Ko_Kai) && (wc <= THAI_Ho_Nok_Huk) );
  267. }
  268. //+---------------------------------------------------------------------------
  269. //
  270. // Define the different part of speech for Thai.
  271. //
  272. //----------------------------------------------------------------------------
  273. WCHAR wzPOSLookup[POSTYPE][46] =
  274. { L"NONE", // 0 . No tags.
  275. L"NPRP", // 1 . Proper noun
  276. L"NCNM", // 2 . Cardinal number
  277. L"NONM", // 3 . Ordinal number
  278. L"NLBL", // 4 . Label noun
  279. L"NCMN", // 5 . Common noun
  280. L"NTTL", // 6 . Title noun
  281. L"PPRS", // 7 . Personal pronoun
  282. L"PDMN", // 8 . Demonstrative pronoun
  283. L"PNTR", // 9 . Interrogative pronoun
  284. L"PREL", // 10. Relative pronoun
  285. L"VACT", // 11. Active verb
  286. L"VSTA", // 12. Stative verb
  287. L"VATT", // 13. Attributive verb
  288. L"XVBM", // 14. Pre-verb auxiliary, before negator
  289. L"XVAM", // 15. Pre-verb auxiliary, after negator
  290. L"XVMM", // 16. Pre-verb, before or after negator
  291. L"XVBB", // 17. Pre-verb auxiliary, in imperative mood
  292. L"XVAE", // 18. Post-verb auxiliary
  293. L"DDAN", // 19. Definite determiner, after noun without classifier in between
  294. L"DDAC", // 20. Definite determiner, allowing classifier in between
  295. L"DDBQ", // 21. Definite determiner, between noun and classifier or preceding quantitative expression
  296. L"DDAQ", // 22. Definite determiner, following quantitative expression
  297. L"DIAC", // 23. Indefinite determiner, following noun; allowing classifier in between
  298. L"DIBQ", // 24. Indefinite determiner, between noun and classifier or preceding quantitative expression
  299. L"DIAQ", // 25. Indefinite determiner, following quantitative expression
  300. L"DCNM", // 26. Determiner, cardinal number expression
  301. L"DONM", // 27. Determiner, ordinal number expression
  302. L"ADVN", // 28. Adverb with normal form
  303. L"ADVI", // 29. Adverb with iterative form
  304. L"ADVP", // 30. Adverb with prefixed form
  305. L"ADVS", // 31. Sentential adverb
  306. L"CNIT", // 32. Unit classifier
  307. L"CLTV", // 33. Collective classifier
  308. L"CMTR", // 34. Measurement classifier
  309. L"CFQC", // 35. Frequency classifier
  310. L"CVBL", // 36. Verbal classifier
  311. L"JCRG", // 37. Coordinating conjunction
  312. L"JCMP", // 38. Comparative conjunction
  313. L"JSBR", // 39. Subordinating conjunction
  314. L"RPRE", // 40. Preposition
  315. L"INT", // 41. Interjection
  316. L"FIXN", // 42. Nominal prefix
  317. L"FIXV", // 43. Adverbial prefix
  318. L"EAFF", // 44. Ending for affirmative sentencev
  319. L"EITT", // 45. Ending for interrogative sentence
  320. L"NEG", // 46. Negator
  321. L"PUNC", // 47. Punctuation
  322. L"ADVI ADVN",
  323. // 48.
  324. L"ADVI ADVN NCMN",
  325. // 49.
  326. L"ADVI ADVN VSTA",
  327. // 50.
  328. L"ADVI VATT",
  329. // 51.
  330. L"ADVN ADVP",
  331. // 52.
  332. L"ADVN ADVP ADVS",
  333. // 53.
  334. L"ADVN ADVP DIAQ DIBQ JCMP JSBR RPRE",
  335. // 54.
  336. L"ADVN ADVP NCMN VATT",
  337. // 55.
  338. L"ADVN ADVP VSTA",
  339. // 56.
  340. L"ADVN ADVS DDAC DDAN DIAC VATT XVAE",
  341. // 57.
  342. L"ADVN ADVS DDAN NCMN VATT VSTA",
  343. // 58.
  344. L"ADVN ADVS NCMN",
  345. // 59.
  346. L"ADVN ADVS NCMN VATT",
  347. // 60.
  348. L"ADVN ADVS VACT",
  349. // 61.
  350. L"ADVN ADVS VATT",
  351. // 62.
  352. L"ADVN CFQC NCMN RPRE VSTA",
  353. // 63.
  354. L"ADVN CLTV CNIT NCMN RPRE",
  355. // 64.
  356. L"ADVN DCNM",
  357. // 65.
  358. L"ADVN DDAC DDAN",
  359. // 66.
  360. L"ADVN DDAC DDAN NCMN PDMN",
  361. // 67.
  362. L"ADVN DDAC DDAN PDMN",
  363. // 68.
  364. L"ADVN DDAN DDBQ",
  365. // 69.
  366. L"ADVN DDAN DIAC PDMN VSTA",
  367. // 70.
  368. L"ADVN DDAN FIXN PDMN",
  369. // 71.
  370. L"ADVN DDAN NCMN",
  371. // 72.
  372. L"ADVN DDAQ",
  373. // 73.
  374. L"ADVN DDBQ",
  375. // 74.
  376. L"ADVN DDBQ RPRE VATT",
  377. // 75.
  378. L"ADVN DDBQ VATT VSTA XVAE",
  379. // 76.
  380. L"ADVN DIAC",
  381. // 77.
  382. L"ADVN DIAC PDMN",
  383. // 78.
  384. L"ADVN DIBQ",
  385. // 79.
  386. L"ADVN DIBQ NCMN",
  387. // 80.
  388. L"ADVN DIBQ VACT VSTA",
  389. // 81.
  390. L"ADVN DIBQ VATT",
  391. // 82.
  392. L"ADVN DONM JCMP",
  393. // 83.
  394. L"ADVN DONM JSBR NCMN RPRE VATT XVAE",
  395. // 84.
  396. L"ADVN EITT PNTR",
  397. // 85.
  398. L"ADVN FIXN",
  399. // 86.
  400. L"ADVN JCMP",
  401. // 87.
  402. L"ADVN JCRG",
  403. // 88.
  404. L"ADVN JCRG JSBR",
  405. // 89.
  406. L"ADVN JCRG JSBR XVBM XVMM",
  407. // 90.
  408. L"ADVN JCRG RPRE VACT VSTA XVAE",
  409. // 91.
  410. L"ADVN JSBR",
  411. // 92.
  412. L"ADVN JSBR NCMN",
  413. // 93.
  414. L"ADVN JSBR RPRE VATT",
  415. // 94.
  416. L"ADVN JSBR RPRE XVAE",
  417. // 95.
  418. L"ADVN JSBR VSTA",
  419. // 96.
  420. L"ADVN JSBR XVAE XVBM",
  421. // 97.
  422. L"ADVN NCMN",
  423. // 98.
  424. L"ADVN NCMN RPRE VACT VATT VSTA",
  425. // 99.
  426. L"ADVN NCMN RPRE VACT XVAE",
  427. // 100.
  428. L"ADVN NCMN RPRE VATT",
  429. // 101.
  430. L"ADVN NCMN VACT VATT VSTA",
  431. // 102.
  432. L"ADVN NCMN VACT VSTA",
  433. // 103.
  434. L"ADVN NCMN VATT",
  435. // 104.
  436. L"ADVN NCMN VATT VSTA",
  437. // 105.
  438. L"ADVN NEG",
  439. // 106.
  440. L"ADVN NPRP VATT",
  441. // 107.
  442. L"ADVN PDMN VACT",
  443. // 108.
  444. L"ADVN PNTR",
  445. // 109.
  446. L"ADVN RPRE",
  447. // 110.
  448. L"ADVN RPRE VACT VATT XVAE",
  449. // 111.
  450. L"ADVN RPRE VACT XVAM XVBM",
  451. // 112.
  452. L"ADVN RPRE VATT VSTA",
  453. // 113.
  454. L"ADVN RPRE VSTA",
  455. // 114.
  456. L"ADVN VACT",
  457. // 115.
  458. L"ADVN VACT VATT",
  459. // 116.
  460. L"ADVN VACT VATT VSTA",
  461. // 117.
  462. L"ADVN VACT VATT VSTA XVAM XVBM",
  463. // 118.
  464. L"ADVN VACT VSTA",
  465. // 119.
  466. L"ADVN VACT VSTA XVAE",
  467. // 120.
  468. L"ADVN VACT XVAE",
  469. // 121.
  470. L"ADVN VATT",
  471. // 122.
  472. L"ADVN VATT VSTA",
  473. // 123.
  474. L"ADVN VATT VSTA XVAM XVBM XVMM",
  475. // 124.
  476. L"ADVN VATT XVBM",
  477. // 125.
  478. L"ADVN VSTA",
  479. // 126.
  480. L"ADVN VSTA XVAE",
  481. // 127.
  482. L"ADVN VSTA XVBM",
  483. // 128.
  484. L"ADVN XVAE",
  485. // 129.
  486. L"ADVN XVAM",
  487. // 130.
  488. L"ADVN XVBM XVMM",
  489. // 131.
  490. L"ADVP JSBR RPRE VATT",
  491. // 132.
  492. L"ADVP VATT",
  493. // 133.
  494. L"ADVS DDAC JCRG",
  495. // 134.
  496. L"ADVS DDAC JSBR",
  497. // 135.
  498. L"ADVS DDAN VSTA",
  499. // 136.
  500. L"ADVS DIAC",
  501. // 137.
  502. L"ADVS DONM",
  503. // 138.
  504. L"ADVS JCRG JSBR",
  505. // 139.
  506. L"ADVS JCRG JSBR RPRE",
  507. // 140.
  508. L"ADVS JSBR",
  509. // 141.
  510. L"ADVS JSBR RPRE",
  511. // 142.
  512. L"ADVS NCMN",
  513. // 143.
  514. L"ADVS VATT",
  515. // 144.
  516. L"CFQC CLTV CNIT DCNM JCRG JSBR NCMN RPRE XVBM",
  517. // 145.
  518. L"CFQC CNIT PREL",
  519. // 146.
  520. L"CFQC NCMN",
  521. // 147.
  522. L"CLTV CNIT NCMN",
  523. // 148.
  524. L"CLTV CNIT NCMN RPRE",
  525. // 149.
  526. L"CLTV CNIT NCMN VSTA",
  527. // 150.
  528. L"CLTV NCMN",
  529. // 151.
  530. L"CLTV NCMN VACT VATT",
  531. // 152.
  532. L"CLTV NCMN VATT",
  533. // 153.
  534. L"CMTR CNIT NCMN",
  535. // 154.
  536. L"CMTR NCMN",
  537. // 155.
  538. L"CMTR NCMN VATT VSTA",
  539. // 156.
  540. L"CNIT DDAC NCMN VATT",
  541. // 157.
  542. L"CNIT DONM NCMN RPRE VATT",
  543. // 158.
  544. L"CNIT FIXN FIXV JSBR NCMN",
  545. // 159.
  546. L"CNIT JCRG JSBR NCMN PREL RPRE VATT",
  547. // 160.
  548. L"CNIT JSBR RPRE",
  549. // 161.
  550. L"CNIT NCMN",
  551. // 162.
  552. L"CNIT NCMN RPRE",
  553. // 163.
  554. L"CNIT NCMN RPRE VATT",
  555. // 164.
  556. L"CNIT NCMN VACT",
  557. // 165.
  558. L"CNIT NCMN VSTA",
  559. // 166.
  560. L"CNIT NCNM",
  561. // 167.
  562. L"CNIT PPRS",
  563. // 168.
  564. L"DCNM DDAC DIAC DONM VATT VSTA",
  565. // 169.
  566. L"DCNM DDAN DIAC",
  567. // 170.
  568. L"DCNM DIAC NCMN NCNM",
  569. // 171.
  570. L"DCNM DIBQ NCMN",
  571. // 172.
  572. L"DCNM DONM",
  573. // 173.
  574. L"DCNM NCMN",
  575. // 174.
  576. L"DCNM NCNM",
  577. // 175.
  578. L"DCNM NCNM VACT",
  579. // 176.
  580. L"DCNM VATT",
  581. // 177.
  582. L"DDAC DDAN",
  583. // 178.
  584. L"DDAC DDAN DIAC NCMN",
  585. // 179.
  586. L"DDAC DDAN DIAC VATT",
  587. // 180.
  588. L"DDAC DDAN EAFF PDMN",
  589. // 181.
  590. L"DDAC DDAN PDMN",
  591. // 182.
  592. L"DDAC DIAC VSTA",
  593. // 183.
  594. L"DDAC NCMN",
  595. // 184.
  596. L"DDAN DDBQ",
  597. // 185.
  598. L"DDAN DIAC PNTR",
  599. // 186.
  600. L"DDAN NCMN",
  601. // 187.
  602. L"DDAN NCMN RPRE VATT",
  603. // 188.
  604. L"DDAN PDMN",
  605. // 189.
  606. L"DDAN RPRE",
  607. // 190.
  608. L"DDAN VATT",
  609. // 191.
  610. L"DDAQ VATT",
  611. // 192.
  612. L"DDBQ DIBQ",
  613. // 193.
  614. L"DDBQ JCRG JSBR",
  615. // 194.
  616. L"DDBQ JCRG NCMN",
  617. // 195.
  618. L"DIAC PDMN",
  619. // 196.
  620. L"DIBQ JSBR RPRE VSTA",
  621. // 197.
  622. L"DIBQ NCMN",
  623. // 198.
  624. L"DIBQ VATT",
  625. // 199.
  626. L"DIBQ VATT VSTA",
  627. // 200.
  628. L"DIBQ XVBM",
  629. // 201.
  630. L"DONM NCMN RPRE",
  631. // 202.
  632. L"DONM VACT VATT VSTA",
  633. // 203.
  634. L"DONM VATT",
  635. // 204.
  636. L"EAFF XVAE XVAM XVBM",
  637. // 205.
  638. L"EITT JCRG",
  639. // 206.
  640. L"FIXN FIXV NCMN",
  641. // 207.
  642. L"FIXN FIXV RPRE VSTA",
  643. // 208.
  644. L"FIXN JSBR NCMN PREL RPRE VSTA XVBM",
  645. // 209.
  646. L"FIXN NCMN",
  647. // 210.
  648. L"FIXN VACT",
  649. // 211.
  650. L"FIXN VACT VSTA",
  651. // 212.
  652. L"FIXV JSBR RPRE",
  653. // 213.
  654. L"JCMP JSBR",
  655. // 214.
  656. L"JCMP RPRE VSTA",
  657. // 215.
  658. L"JCMP VATT VSTA",
  659. // 216.
  660. L"JCMP VSTA",
  661. // 217.
  662. L"JCRG JSBR",
  663. // 218.
  664. L"JCRG JSBR NCMN RPRE",
  665. // 219.
  666. L"JCRG JSBR RPRE",
  667. // 220.
  668. L"JCRG RPRE",
  669. // 221.
  670. L"JCRG RPRE VATT VSTA",
  671. // 222.
  672. L"JCRG VSTA",
  673. // 223.
  674. L"JSBR NCMN",
  675. // 224.
  676. L"JSBR NCMN XVAE",
  677. // 225.
  678. L"JSBR NCMN XVAM XVBM XVMM",
  679. // 226.
  680. L"JSBR PREL",
  681. // 227.
  682. L"JSBR PREL RPRE",
  683. // 228.
  684. L"JSBR PREL XVBM",
  685. // 229.
  686. L"JSBR RPRE",
  687. // 230.
  688. L"JSBR RPRE VACT",
  689. // 231.
  690. L"JSBR RPRE VACT VSTA",
  691. // 232.
  692. L"JSBR RPRE VACT XVAE XVAM",
  693. // 233.
  694. L"JSBR RPRE VATT",
  695. // 234.
  696. L"JSBR RPRE VSTA",
  697. // 235.
  698. L"JSBR RPRE XVAM",
  699. // 236.
  700. L"JSBR VACT",
  701. // 237.
  702. L"JSBR VACT VSTA",
  703. // 238.
  704. L"JSBR VATT XVBM XVMM",
  705. // 239.
  706. L"JSBR VSTA",
  707. // 240.
  708. L"JSBR XVBM",
  709. // 241.
  710. L"NCMN NCNM",
  711. // 242.
  712. L"NCMN NCNM NPRP",
  713. // 243.
  714. L"NCMN NLBL NPRP",
  715. // 244.
  716. L"NCMN NPRP",
  717. // 245.
  718. L"NCMN NPRP RPRE",
  719. // 246.
  720. L"NCMN NTTL",
  721. // 247.
  722. L"NCMN PDMN PPRS",
  723. // 248.
  724. L"NCMN PDMN VATT",
  725. // 249.
  726. L"NCMN PNTR",
  727. // 250.
  728. L"NCMN PPRS PREL VACT",
  729. // 251.
  730. L"NCMN RPRE",
  731. // 252.
  732. L"NCMN RPRE VACT VATT",
  733. // 253.
  734. L"NCMN RPRE VATT",
  735. // 254.
  736. L"NCMN VACT",
  737. // 255.
  738. L"NCMN VACT VATT",
  739. // 256.
  740. L"NCMN VACT VATT VSTA XVAE",
  741. // 257.
  742. L"NCMN VACT VSTA",
  743. // 258.
  744. L"NCMN VACT VSTA XVAM",
  745. // 259.
  746. L"NCMN VACT VSTA XVBB",
  747. // 260.
  748. L"NCMN VATT",
  749. // 261.
  750. L"NCMN VATT VSTA",
  751. // 262.
  752. L"NCMN VATT XVAM",
  753. // 263.
  754. L"NCMN VSTA",
  755. // 264.
  756. L"NCMN XVBM",
  757. // 265.
  758. L"NPRP RPRE",
  759. // 266.
  760. L"NPRP VATT",
  761. // 267.
  762. L"NTTL PPRS",
  763. // 268.
  764. L"PDMN PPRS",
  765. // 269.
  766. L"PDMN VATT",
  767. // 270.
  768. L"PDMN VATT VSTA",
  769. // 271.
  770. L"PPRS PREL",
  771. // 272.
  772. L"PPRS VATT",
  773. // 273.
  774. L"RPRE VACT",
  775. // 274.
  776. L"RPRE VACT VATT",
  777. // 275.
  778. L"RPRE VACT VSTA",
  779. // 276.
  780. L"RPRE VACT VSTA XVAE",
  781. // 277.
  782. L"RPRE VACT XVAE",
  783. // 278.
  784. L"RPRE VATT",
  785. // 279.
  786. L"RPRE VATT VSTA",
  787. // 280.
  788. L"RPRE VSTA",
  789. // 281.
  790. L"VACT VATT",
  791. // 282.
  792. L"VACT VATT VSTA",
  793. // 283.
  794. L"VACT VATT XVAE XVAM XVBM",
  795. // 284.
  796. L"VACT VSTA",
  797. // 285.
  798. L"VACT VSTA XVAE",
  799. // 286.
  800. L"VACT VSTA XVAE XVAM",
  801. // 287.
  802. L"VACT VSTA XVAE XVAM XVMM",
  803. // 288.
  804. L"VACT VSTA XVAM",
  805. // 289.
  806. L"VACT VSTA XVAM XVMM",
  807. // 290.
  808. L"VACT XVAE",
  809. // 291.
  810. L"VACT XVAM",
  811. // 292.
  812. L"VACT XVAM XVMM",
  813. // 293.
  814. L"VACT XVMM",
  815. // 294.
  816. L"VATT VSTA",
  817. // 295.
  818. L"VSTA XVAE",
  819. // 296.
  820. L"VSTA XVAM",
  821. // 297.
  822. L"VSTA XVAM XVMM",
  823. // 298.
  824. L"VSTA XVBM",
  825. // 299.
  826. L"XVAM XVBM",
  827. // 300.
  828. L"XVAM XVBM XVMM",
  829. // 301.
  830. L"XVAM XVMM",
  831. // 302.
  832. L"UNKN",
  833. // 303. Unknown
  834. L"ABBR"
  835. // 304. Abbrivation
  836. };
  837. //+---------------------------------------------------------------------------
  838. //
  839. // Function: POSCompress
  840. //
  841. // Synopsis: Part Of Speech Compress - translating string to unique id.
  842. //
  843. // Arguments:
  844. //
  845. // Modifies:
  846. //
  847. // History: created 7/99 aarayas
  848. //
  849. // Notes:
  850. //
  851. //----------------------------------------------------------------------------
  852. DWORD POSCompress(const WCHAR* szTag)
  853. {
  854. int i;
  855. for (i = 0; i < POSTYPE; i++)
  856. {
  857. if (wcscmp(szTag, &wzPOSLookup[i][0]) == 0)
  858. {
  859. return (DWORD)i;
  860. }
  861. }
  862. return POSTYPE;
  863. }
  864. //+---------------------------------------------------------------------------
  865. //
  866. // Function: POSDecompress
  867. //
  868. // Synopsis: Part Of Speech Decompress - Decompress tag get
  869. //
  870. // Arguments:
  871. //
  872. // Modifies:
  873. //
  874. // History: created 7/99 aarayas
  875. //
  876. // Notes:
  877. //
  878. //----------------------------------------------------------------------------
  879. inline WCHAR* POSDecompress(DWORD dwTag)
  880. {
  881. return (&wzPOSLookup[dwTag][0]);
  882. }
  883. //+---------------------------------------------------------------------------
  884. //
  885. // Class: CThaiTrieIter
  886. //
  887. // Synoposis: Constructor:
  888. //
  889. // Arguments:
  890. //
  891. // Modifies:
  892. //
  893. // History: created 8/99 aarayas
  894. //
  895. // Notes:
  896. //
  897. //----------------------------------------------------------------------------
  898. CThaiTrieIter::CThaiTrieIter() : resultWord(NULL), soundexWord(NULL), tempWord(NULL),
  899. pTrieScanArray(NULL), m_fThaiNumber(false)
  900. {
  901. resultWord = new WCHAR[WORDSIZE];
  902. tempWord = new WCHAR[WORDSIZE];
  903. pTrieScanArray = new TRIESCAN[53];
  904. }
  905. //+---------------------------------------------------------------------------
  906. //
  907. // Class: CThaiTrieIter
  908. //
  909. // Synoposis: Destructor
  910. //
  911. // Arguments:
  912. //
  913. // Modifies:
  914. //
  915. // History: created 8/99 aarayas
  916. //
  917. // Notes:
  918. //
  919. //----------------------------------------------------------------------------
  920. CThaiTrieIter::~CThaiTrieIter()
  921. {
  922. if (resultWord)
  923. delete resultWord;
  924. if (tempWord)
  925. delete tempWord;
  926. if (pTrieScanArray)
  927. delete pTrieScanArray;
  928. }
  929. //+---------------------------------------------------------------------------
  930. //
  931. // Class: CThaiTrieIter
  932. //
  933. // Synopsis: Initialize variables.
  934. //
  935. // Arguments:
  936. //
  937. // Modifies:
  938. //
  939. // History: created 8/99 aarayas
  940. //
  941. // Notes:
  942. //
  943. //----------------------------------------------------------------------------
  944. void CThaiTrieIter::Init(CTrie* ctrie)
  945. {
  946. // Declare varialbes.
  947. WCHAR wc;
  948. // Initialize parent.
  949. CTrieIter::Init(ctrie);
  950. // Initialize Hash table.
  951. for (wc = THAI_Ko_Kai; wc <= THAI_Ho_Nok_Huk; wc++)
  952. GetScanFirstChar(wc,&pTrieScanArray[wc - THAI_Ko_Kai]);
  953. for (wc = THAI_Vowel_Sara_E; wc <= THAI_Vowel_Sara_AI_MaiMaLai; wc++)
  954. GetScanFirstChar(wc,&pTrieScanArray[wc - THAI_Ko_Kai - 17]);
  955. }
  956. //+---------------------------------------------------------------------------
  957. //
  958. // Class: CThaiTrieIter
  959. //
  960. // Synopsis: Initialize variables.
  961. //
  962. // Arguments:
  963. //
  964. // Modifies:
  965. //
  966. // History: created 8/99 aarayas
  967. //
  968. // Notes:
  969. //
  970. //----------------------------------------------------------------------------
  971. bool CThaiTrieIter::GetScanFirstChar(WCHAR wc, TRIESCAN* pTrieScan)
  972. {
  973. // Reset the trie scan.
  974. memset(&trieScan1, 0, sizeof(TRIESCAN));
  975. if (!TrieGetNextState(pTrieCtrl, &trieScan1))
  976. return false;
  977. while (wc != trieScan1.wch)
  978. {
  979. // Keep moving the the right of the trie.
  980. if (!TrieGetNextNode(pTrieCtrl, &trieScan1))
  981. {
  982. memset(pTrieScan, 0, sizeof(TRIESCAN));
  983. return false;
  984. }
  985. }
  986. memcpy(pTrieScan, &trieScan1, sizeof(TRIESCAN));
  987. return true;
  988. }
  989. //+---------------------------------------------------------------------------
  990. //
  991. // Class: CThaiTrieIter
  992. //
  993. // Synopsis: The function move trieScan to the relevant node matching with
  994. // with the cluster of Thai character.
  995. //
  996. // Arguments: szCluster - contain the thai character cluster.
  997. // iNumCluster - contain the size of character.
  998. //
  999. // Modifies:
  1000. //
  1001. // History: created 7/99 aarayas
  1002. //
  1003. // Notes:
  1004. //
  1005. //----------------------------------------------------------------------------
  1006. BOOL CThaiTrieIter::MoveCluster(const WCHAR* szCluster, unsigned int iNumCluster)
  1007. {
  1008. // Declare and initailze local variables.
  1009. unsigned int i = 0;
  1010. // Assert(iNumCluster <= 6, "Invalid cluster");
  1011. CopyScan();
  1012. if (!TrieGetNextState(pTrieCtrl, &trieScan1))
  1013. return FALSE;
  1014. while (TRUE)
  1015. {
  1016. if (szCluster[i] == trieScan1.wch)
  1017. {
  1018. i++;
  1019. if (i == iNumCluster)
  1020. {
  1021. memcpy(&trieScan, &trieScan1, sizeof(TRIESCAN));
  1022. GetNode();
  1023. return TRUE;
  1024. }
  1025. // Move down the Trie Branch.
  1026. else if (!TrieGetNextState(pTrieCtrl, &trieScan1)) break;
  1027. }
  1028. // Move the Trie right one node.
  1029. else if (!TrieGetNextNode(pTrieCtrl, &trieScan1)) break;
  1030. }
  1031. return FALSE;
  1032. }
  1033. //+---------------------------------------------------------------------------
  1034. //
  1035. // Class: CThaiTrieIter
  1036. //
  1037. // Synopsis: The function move trieScan to the relevant node matching with
  1038. // with the cluster of Thai character.
  1039. //
  1040. // Arguments: szCluster - contain the thai character cluster.
  1041. // iNumCluster - contain the size of character.
  1042. //
  1043. // Modifies:
  1044. //
  1045. // History: created 7/99 aarayas
  1046. //
  1047. // Notes:
  1048. //
  1049. //----------------------------------------------------------------------------
  1050. bool CThaiTrieIter::MoveCluster(WCHAR* szCluster, unsigned int iNumCluster, bool fBeginNewWord)
  1051. {
  1052. // Declare and initailze local variables.
  1053. unsigned int i = 0;
  1054. Assert(iNumCluster <= 6, "Invalid cluster");
  1055. // No need to move.
  1056. if (iNumCluster == 0)
  1057. return false;
  1058. // Use a look indexes for where the first character is at.
  1059. if (fBeginNewWord)
  1060. {
  1061. m_fThaiNumber = false;
  1062. // Quick look up for proper characters.
  1063. if (szCluster[i] >= THAI_Ko_Kai && szCluster[i] <= THAI_Ho_Nok_Huk)
  1064. memcpy(&trieScan,&pTrieScanArray[(szCluster[i] - THAI_Ko_Kai)], sizeof(TRIESCAN));
  1065. else if (szCluster[i] >= THAI_Vowel_Sara_E && szCluster[i] <= THAI_Vowel_Sara_AI_MaiMaLai)
  1066. memcpy(&trieScan,&pTrieScanArray[(szCluster[i] - THAI_Ko_Kai - 17)], sizeof(TRIESCAN));
  1067. else
  1068. {
  1069. Reset();
  1070. m_fThaiNumber = IsThaiNumeric(szCluster[i]);
  1071. }
  1072. if (trieScan.wch == szCluster[i])
  1073. i++;
  1074. if (i == iNumCluster)
  1075. {
  1076. GetNode();
  1077. return true;
  1078. }
  1079. }
  1080. CopyScan();
  1081. if (!TrieGetNextState(pTrieCtrl, &trieScan1))
  1082. return false;
  1083. if (m_fThaiNumber)
  1084. {
  1085. fWordEnd = true;
  1086. if (IsThaiNumeric(szCluster[i]) || szCluster[i] == L',' || szCluster[i] == L'.')
  1087. return true;
  1088. else
  1089. return false;
  1090. }
  1091. while (true)
  1092. {
  1093. if (szCluster[i] == trieScan1.wch)
  1094. {
  1095. i++;
  1096. if ((i == iNumCluster) ||
  1097. ( (szCluster[i] == THAI_Vowel_MaiYaMok || szCluster[i] == THAI_Sign_PaiYanNoi)/* && (i+1 == iNumCluster )*/) )
  1098. {
  1099. memcpy(&trieScan, &trieScan1, sizeof(TRIESCAN));
  1100. GetNode();
  1101. return true;
  1102. }
  1103. // Move down the Trie Branch.
  1104. else if (!TrieGetNextState(pTrieCtrl, &trieScan1)) break;
  1105. }
  1106. // Let Nikhahit equal Sara Am.
  1107. // TODO: case Nikhahit Mai To and Sara AA should equal to Mai To Sara Am. TO risk for this version.
  1108. // This bug was found because Thairath newspaper doesn't write this properly on their web page.
  1109. else if (szCluster[i] == THAI_Nikhahit && szCluster[i+1] == THAI_Vowel_Sara_AA &&
  1110. trieScan1.wch == THAI_Vowel_Sign_Sara_Am)
  1111. {
  1112. if (szCluster[i+1] == THAI_Vowel_Sara_AA)
  1113. i++;
  1114. i++;
  1115. if ((i == iNumCluster) ||
  1116. ( (szCluster[i] == THAI_Vowel_MaiYaMok || szCluster[i] == THAI_Sign_PaiYanNoi)/* && (i+1 == iNumCluster )*/) )
  1117. {
  1118. memcpy(&trieScan, &trieScan1, sizeof(TRIESCAN));
  1119. GetNode();
  1120. return true;
  1121. }
  1122. // Move down the Trie Branch.
  1123. else if (!TrieGetNextState(pTrieCtrl, &trieScan1)) break;
  1124. }
  1125. // Move the Trie right one node.
  1126. else if (!TrieGetNextNode(pTrieCtrl, &trieScan1)) break;
  1127. }
  1128. if (fBeginNewWord)
  1129. Reset();
  1130. return false;
  1131. }
  1132. //+---------------------------------------------------------------------------
  1133. //
  1134. // Class: CThaiTrieIter
  1135. //
  1136. // Synopsis:
  1137. //
  1138. // Arguments:
  1139. //
  1140. // Modifies:
  1141. //
  1142. // History: created 7/99 aarayas
  1143. //
  1144. // Notes:
  1145. //
  1146. //----------------------------------------------------------------------------
  1147. SOUNDEXSTATE CThaiTrieIter::MoveSoundexByCluster(WCHAR* szCluster, unsigned int iNumCluster, unsigned int iNumNextCluster)
  1148. {
  1149. // Declare and initailze local variables.
  1150. unsigned int i = 0 , x = 0;
  1151. bool fStoreScan = false;
  1152. TRIESCAN trieScanPush;
  1153. Assert(iNumCluster <= 6, "Invalid cluster");
  1154. Assert(iNumNextCluster <= 6, "Invalid cluster");
  1155. CopyScan();
  1156. if (!TrieGetNextState(pTrieCtrl, &trieScan1))
  1157. return UNABLE_TO_MOVE;
  1158. if (IsThaiEndingSign(*szCluster))
  1159. return STOP_MOVE;
  1160. // Match as much as possible
  1161. while (true)
  1162. {
  1163. if (szCluster[i] == trieScan1.wch)
  1164. {
  1165. i++;
  1166. if (i == iNumCluster)
  1167. {
  1168. memcpy(&trieScan, &trieScan1, sizeof(TRIESCAN));
  1169. GetNode();
  1170. return NOSUBSTITUTE;
  1171. }
  1172. // Move down the Trie Branch.
  1173. else if (!TrieGetNextState(pTrieCtrl, &trieScan1)) break;
  1174. // Save our current scan position.
  1175. memcpy(&trieScanPush, &trieScan1, sizeof(TRIESCAN));
  1176. fStoreScan = true;
  1177. }
  1178. // Move the Trie right one node.
  1179. else if (!TrieGetNextNode(pTrieCtrl, &trieScan1)) break;
  1180. }
  1181. // Try doing some tonemark substitution.
  1182. if (fStoreScan && IsThaiToneMark(szCluster[i]) )
  1183. {
  1184. // Restore trieScan1 to last matched.
  1185. memcpy(&trieScan1, &trieScanPush, sizeof(TRIESCAN));
  1186. while (true)
  1187. {
  1188. if (IsThaiToneMark(trieScan1.wch))
  1189. {
  1190. if ( (i + 1) == iNumCluster)
  1191. {
  1192. if (CheckNextCluster(szCluster+iNumCluster,iNumNextCluster))
  1193. {
  1194. memcpy(&trieScan, &trieScan1, sizeof(TRIESCAN));
  1195. GetNode();
  1196. return SUBSTITUTE_DIACRITIC;
  1197. }
  1198. }
  1199. }
  1200. // Move the Trie right one node.
  1201. // Goes through all the none Tonemark.
  1202. if (!TrieGetNextNode(pTrieCtrl, &trieScan1)) break;
  1203. }
  1204. }
  1205. // Try doing droping the current tonemark.
  1206. // Example is case can be best found "Click" is spelt in Thai from the
  1207. // different group at Microsoft.
  1208. if (fStoreScan && !IsThaiToneMark(szCluster[i]) )
  1209. {
  1210. // Restore trieScan1 to last matched.
  1211. memcpy(&trieScan1, &trieScanPush, sizeof(TRIESCAN));
  1212. while (true)
  1213. {
  1214. if (IsThaiToneMark(trieScan1.wch))
  1215. {
  1216. if ( (i + 1) == iNumCluster)
  1217. {
  1218. if (CheckNextCluster(szCluster+iNumCluster,iNumNextCluster))
  1219. {
  1220. memcpy(&trieScan, &trieScan1, sizeof(TRIESCAN));
  1221. GetNode();
  1222. return SUBSTITUTE_DIACRITIC;
  1223. }
  1224. }
  1225. }
  1226. // Move the Trie right one node.
  1227. // Drop all the Tonemark.
  1228. if (!TrieGetNextNode(pTrieCtrl, &trieScan1)) break;
  1229. }
  1230. }
  1231. return UNABLE_TO_MOVE;
  1232. }
  1233. //+---------------------------------------------------------------------------
  1234. //
  1235. // Class: CThaiTrieIter
  1236. //
  1237. // Synopsis: set trieScan1 = trieScan.
  1238. //
  1239. // Arguments:
  1240. //
  1241. // Modifies:
  1242. //
  1243. // History: created 7/99 aarayas
  1244. //
  1245. // Notes:
  1246. //
  1247. //----------------------------------------------------------------------------
  1248. inline void CThaiTrieIter::CopyScan()
  1249. {
  1250. // Let trieScan1 = trieScan
  1251. memcpy(&trieScan1,&trieScan, sizeof(TRIESCAN));
  1252. }
  1253. //+---------------------------------------------------------------------------
  1254. //
  1255. // Class: CThaiTrieIter
  1256. //
  1257. // Synoposis: the function traverse through the whole dictionary
  1258. // to find the best possible match words.
  1259. //
  1260. // Arguments:
  1261. //
  1262. // Modifies:
  1263. //
  1264. // History: created 8/99 aarayas
  1265. //
  1266. // Notes:
  1267. //
  1268. //----------------------------------------------------------------------------
  1269. int CThaiTrieIter::Soundex(WCHAR* word)
  1270. {
  1271. // Reset Trie.
  1272. Reset();
  1273. // Move Down.
  1274. Down();
  1275. // Clean soundexWord.
  1276. memset(resultWord, 0, sizeof(WCHAR) * WORDSIZE);
  1277. memset(tempWord, 0, sizeof(WCHAR) * WORDSIZE);
  1278. soundexWord = word;
  1279. iResultScore = GetScore(L"\x0e04\x0e25\x0e34\x0e01\x0e01\x0e01",soundexWord);
  1280. iResultScore = 2000;
  1281. #if defined (_DEBUG)
  1282. iStackSize = 0;
  1283. #endif
  1284. Traverse(0,1000);
  1285. return iResultScore;
  1286. }
  1287. //+---------------------------------------------------------------------------
  1288. //
  1289. // Class: CThaiTrieIter
  1290. //
  1291. // Synoposis:
  1292. //
  1293. // Arguments:
  1294. //
  1295. // Modifies:
  1296. //
  1297. // History: created 8/99 aarayas
  1298. //
  1299. // Notes:
  1300. //
  1301. //----------------------------------------------------------------------------
  1302. unsigned int CThaiTrieIter::GetScore(WCHAR* idealWord, WCHAR* inputWord)
  1303. {
  1304. unsigned int iScore = 1000;
  1305. unsigned int idealWordLen = wcslen(idealWord);
  1306. unsigned int iInputWordLen = wcslen(inputWord);
  1307. unsigned int iIndexBegin = 0;
  1308. unsigned int i;
  1309. unsigned int x = 0;
  1310. unsigned int iMaxCompare;
  1311. bool fShouldExit;
  1312. for (i=0; i < iInputWordLen; i++)
  1313. {
  1314. iMaxCompare = ( (iIndexBegin + 2) < idealWordLen ) ? (iIndexBegin + 2) : idealWordLen;
  1315. if (i <= idealWordLen)
  1316. {
  1317. x = iIndexBegin;
  1318. fShouldExit = false;
  1319. while (true)
  1320. {
  1321. if ((x >= iMaxCompare) || (fShouldExit) )
  1322. break;
  1323. if (idealWord[x] == inputWord[i])
  1324. {
  1325. x++;
  1326. iIndexBegin = x;
  1327. break;
  1328. }
  1329. if (IsThaiUpperAndLowerClusterCharacter(inputWord[i]))
  1330. iScore += 5;
  1331. else
  1332. iScore += 10;
  1333. x++;
  1334. fShouldExit = true;
  1335. }
  1336. }
  1337. else
  1338. {
  1339. if (IsThaiUpperAndLowerClusterCharacter(inputWord[i]))
  1340. iScore += 20;
  1341. else
  1342. iScore += 30;
  1343. }
  1344. }
  1345. while (x <= idealWordLen)
  1346. {
  1347. if (IsThaiUpperAndLowerClusterCharacter(idealWord[x]))
  1348. iScore += 5;
  1349. else
  1350. iScore += 10;
  1351. x++;
  1352. }
  1353. return iScore;
  1354. }
  1355. //+---------------------------------------------------------------------------
  1356. //
  1357. // Class: CThaiTrieIter
  1358. //
  1359. // Synoposis:
  1360. //
  1361. // Arguments:
  1362. //
  1363. // Modifies:
  1364. //
  1365. // History: created 8/99 aarayas
  1366. //
  1367. // Notes:
  1368. //
  1369. //----------------------------------------------------------------------------
  1370. bool CThaiTrieIter::Traverse(unsigned int iCharPos, unsigned int score)
  1371. {
  1372. TRIESCAN trieScanLevel;
  1373. #if defined(_DEBUG)
  1374. iStackSize++;
  1375. #endif
  1376. // push current trieScan into local stack trieScanLevel.
  1377. memcpy(&trieScanLevel,&trieScan, sizeof(TRIESCAN));
  1378. // Get Node information
  1379. GetNode();
  1380. // Store the current character to result word.
  1381. tempWord[iCharPos] = wc;
  1382. tempWord[iCharPos + 1] = 0;
  1383. // Determine the distance between two string.
  1384. score = GetScore(tempWord, soundexWord);
  1385. // See if we have reached the end of a word.
  1386. if (fWordEnd)
  1387. {
  1388. tempWord[iCharPos + 1] = 0;
  1389. // Is Soundex score lower than we have.
  1390. if (score < iResultScore)
  1391. {
  1392. // wcscpy(resultWord,tempWord);
  1393. Wzncpy(resultWord,tempWord,WORDSIZE);
  1394. iResultScore = score;
  1395. }
  1396. }
  1397. // See if we can prune the result of the words.
  1398. if (score > (iResultScore + APPROXIMATEWEIGHT))
  1399. {
  1400. #if defined(_DEBUG)
  1401. iStackSize--;
  1402. #endif
  1403. return true;
  1404. }
  1405. // Move down Trie branch.
  1406. if (Down())
  1407. {
  1408. Traverse(iCharPos + 1, score);
  1409. if (Right())
  1410. Traverse(iCharPos + 1, score);
  1411. // restore trieScan
  1412. memcpy(&trieScan,&trieScanLevel, sizeof(TRIESCAN));
  1413. if (Right())
  1414. Traverse(iCharPos, score);
  1415. }
  1416. #if defined(_DEBUG)
  1417. iStackSize--;
  1418. #endif
  1419. return true;
  1420. }
  1421. //+---------------------------------------------------------------------------
  1422. //
  1423. // Class: CThaiTrieIter
  1424. //
  1425. // Synoposis: This function will trieScan1 to the next cluster if
  1426. // the move is possible.
  1427. //
  1428. // Arguments:
  1429. //
  1430. // Modifies:
  1431. //
  1432. // History: created 8/99 aarayas
  1433. //
  1434. // Notes:
  1435. //
  1436. //----------------------------------------------------------------------------
  1437. bool CThaiTrieIter::CheckNextCluster(const WCHAR* szCluster, unsigned int iNumCluster)
  1438. {
  1439. // Declare and initailze local variables.
  1440. unsigned int i = 0;
  1441. TRIESCAN trieScan2;
  1442. Assert(iNumCluster <= 6, "Invalid cluster");
  1443. // If there are no cluster to check consider cluster found.
  1444. if (0 == iNumCluster)
  1445. return true;
  1446. memcpy(&trieScan2, &trieScan1, sizeof(TRIESCAN));
  1447. // Move down the Trie Branch.
  1448. if (!TrieGetNextState(pTrieCtrl, &trieScan2))
  1449. return false;
  1450. while (true)
  1451. {
  1452. if (szCluster[i] == trieScan2.wch)
  1453. {
  1454. i++;
  1455. if (i == iNumCluster)
  1456. {
  1457. return true;
  1458. }
  1459. // Move down the Trie Branch.
  1460. else if (!TrieGetNextState(pTrieCtrl, &trieScan2)) break;
  1461. }
  1462. // Move the Trie right one node.
  1463. else if (!TrieGetNextNode(pTrieCtrl, &trieScan2)) break;
  1464. }
  1465. return false;
  1466. }