windows-nt/Source/XPSP1/NT/windows/feime/cht/search.c
2020-09-26 16:20:57 +08:00

1229 lines
33 KiB
C

/*++
Copyright (c) 1990-1999 Microsoft Corporation, All Rights Reserved
Module Name:
SEARCH.c
++*/
#include <windows.h>
#include <immdev.h>
#include "imeattr.h"
#include "imedefs.h"
#if !defined(ROMANIME)
#if defined(WINAR30)
/**********************************************************************/
/* SearchQuickKey() */
/* Description: */
/* Search for the quick key table */
/* file format can be changed in different version for */
/* performance consideration, ISVs should not assume its format */
/* Array has the CopyRight of this table file */
/**********************************************************************/
void PASCAL SearchQuickKey(
LPCANDIDATELIST lpCandList,
LPPRIVCONTEXT lpImcP)
{
UINT uStart, uEnd;
HANDLE hHighWordTbl;
LPWORD lpHighWordTbl;
if (lpImcP->bSeq[1]) {
uStart = (lpImcP->bSeq[0] - 1) * 300 + (lpImcP->bSeq[1] - 1) * 10 +
300;
} else {
uStart = (lpImcP->bSeq[0] - 1) * 10;
}
hHighWordTbl = OpenFileMapping(FILE_MAP_READ, FALSE,
lpImeL->szTblFile[1]);
if (!hHighWordTbl) {
return;
}
lpHighWordTbl = MapViewOfFile(hHighWordTbl, FILE_MAP_READ,
0, 0, 0);
if (!lpHighWordTbl) {
goto SrchQuickKeyOvr;
}
uEnd = uStart + 10;
for (; uStart < uEnd; uStart++) {
UINT uCode;
uCode = (WORD)*(lpHighWordTbl + uStart);
AddCodeIntoCand(lpCandList, uCode);
}
UnmapViewOfFile(lpHighWordTbl);
SrchQuickKeyOvr:
CloseHandle(hHighWordTbl);
}
#endif
#if defined(DAYI) || defined(UNIIME)
/**********************************************************************/
/* SearchPhraseTbl() */
/* Description: */
/* file format can be changed in different version for */
/* performance consideration, ISVs should not assume its format */
/**********************************************************************/
void PASCAL SearchPhraseTbl( // searching the phrase table files
#if defined(UNIIME)
LPIMEL lpImeL,
#endif
UINT uTblIndex,
LPCANDIDATELIST lpCandList,
DWORD dwPattern)
{
HANDLE hTbl;
LPBYTE lpTbl;
int iLo, iHi, iMid;
BOOL bFound;
LPBYTE lpPattern;
hTbl = OpenFileMapping(FILE_MAP_READ, FALSE,
lpImeL->szTblFile[uTblIndex]);
if (!hTbl) {
return;
}
lpTbl = (LPBYTE)MapViewOfFile(hTbl, FILE_MAP_READ, 0, 0, 0);
if (!lpTbl) {
CloseHandle(hTbl);
return;
}
iLo = 0;
#ifdef UNICODE
iHi = lpImeL->uTblSize[uTblIndex] / (lpImeL->nSeqBytes + sizeof(DWORD));
#else
iHi = lpImeL->uTblSize[uTblIndex] / (lpImeL->nSeqBytes + sizeof(WORD));
#endif
iMid = (iHi + iLo) /2;
// binary search
for (; iLo <= iHi; ) {
LPUNADWORD lpCurr;
#ifdef UNICODE
lpCurr = (LPDWORD)(lpTbl + (lpImeL->nSeqBytes + sizeof(DWORD)) *
iMid);
#else
lpCurr = (LPDWORD)(lpTbl + (lpImeL->nSeqBytes + sizeof(WORD)) *
iMid);
#endif
if (dwPattern > (*lpCurr & lpImeL->dwPatternMask)) {
iLo = iMid + 1;
} else if (dwPattern < (*lpCurr & lpImeL->dwPatternMask)) {
iHi = iMid - 1;
} else {
bFound = TRUE;
break;
}
iMid = (iHi + iLo) /2;
}
if (bFound) {
HANDLE hPhrase;
LPBYTE lpPhrase;
LPWORD lpStart, lpEnd;
// find the lower bound
#ifdef UNICODE
lpPattern = lpTbl + (lpImeL->nSeqBytes + sizeof(DWORD)) * iMid;
#else
lpPattern = lpTbl + (lpImeL->nSeqBytes + sizeof(WORD)) * iMid;
#endif
#ifdef UNICODE
for (; (LPBYTE)lpPattern >= lpTbl; (LPBYTE)lpPattern -=
lpImeL->nSeqBytes + sizeof(DWORD)) {
#else
for (; (LPBYTE)lpPattern >= lpTbl; (LPBYTE)lpPattern -=
lpImeL->nSeqBytes + sizeof(WORD)) {
#endif
if (dwPattern > (*(LPUNADWORD)lpPattern & lpImeL->dwPatternMask)) {
// previous one is the lower bound
#ifdef UNICODE
(LPBYTE)lpPattern += lpImeL->nSeqBytes + sizeof(DWORD);
#else
(LPBYTE)lpPattern += lpImeL->nSeqBytes + sizeof(WORD);
#endif
break;
}
}
if ((LPBYTE)lpPattern <= lpTbl) {
goto SrchPhrUnmapPattern;
}
hPhrase = OpenFileMapping(FILE_MAP_READ, FALSE,
lpImeL->szTblFile[uTblIndex + 1]);
if (!hPhrase) {
goto SrchPhrUnmapPattern;
}
lpPhrase = (LPBYTE)MapViewOfFile(hPhrase, FILE_MAP_READ, 0, 0, 0);
if (!lpPhrase) {
goto SrchPhrClosePhr;
}
// offset of the string
#ifdef UNICODE
lpEnd = (LPWORD)lpPhrase + *(LPUNADWORD)(lpPattern +
lpImeL->nSeqBytes);
#else
lpEnd = (LPWORD)lpPhrase + *(LPUNAWORD)(lpPattern + lpImeL->nSeqBytes);
#endif
#ifdef UNICODE
for (; dwPattern == (*(LPUNADWORD)lpPattern & lpImeL->dwPatternMask);
(LPBYTE)lpPattern += lpImeL->nSeqBytes + sizeof(DWORD)) {
#else
for (; dwPattern == (*(LPUNADWORD)lpPattern & lpImeL->dwPatternMask);
(LPBYTE)lpPattern += lpImeL->nSeqBytes + sizeof(WORD)) {
#endif
WORD wCode;
DWORD dwStrLen;
lpStart = lpEnd;
// offset of next string
#ifdef UNICODE
lpEnd = (LPWORD)lpPhrase + *(LPUNADWORD)(lpPattern +
lpImeL->nSeqBytes * 2 + sizeof(DWORD));
#else
lpEnd = (LPWORD)lpPhrase + *(LPUNAWORD)(lpPattern +
lpImeL->nSeqBytes * 2 + sizeof(WORD));
#endif
for (dwStrLen = 0; lpStart < lpEnd; lpStart++,
dwStrLen += sizeof(WORD)) {
wCode = *lpStart;
#ifndef UNICODE
wCode = HIBYTE(wCode) | (LOBYTE(wCode) << 8);
#endif
// add this char into candidate list
*(LPWSTR)((LPBYTE)lpCandList + lpCandList->dwOffset[
lpCandList->dwCount] + dwStrLen) = wCode;
}
// null terminator
*(LPTSTR)((LPBYTE)lpCandList + lpCandList->dwOffset[
lpCandList->dwCount] + dwStrLen) = '\0';
dwStrLen += sizeof(TCHAR);
// add one string into candidate list
lpCandList->dwCount++;
if (lpCandList->dwCount >= MAXCAND) {
// Grow memory here and do something,
// if you still want to process it.
break;
}
// string length plus size of the null terminator
lpCandList->dwOffset[lpCandList->dwCount] =
lpCandList->dwOffset[lpCandList->dwCount - 1] +
dwStrLen + sizeof(TCHAR);
}
UnmapViewOfFile(lpPhrase);
SrchPhrClosePhr:
CloseHandle(hPhrase);
}
SrchPhrUnmapPattern:
UnmapViewOfFile(lpTbl);
CloseHandle(hTbl);
return;
}
#endif
#if defined(WINAR30)
/**********************************************************************/
/* SearchPhraseTbl() */
/* Description: */
/* file format can be changed in different version for */
/* performance consideration, ISVs should not assume its format */
/**********************************************************************/
void PASCAL SearchPhraseTbl( // searching the phrase table files
UINT uTblIndex,
LPCANDIDATELIST lpCandList,
DWORD dwPattern)
{
HANDLE hTbl;
LPBYTE lpTbl;
int iLo, iHi, iMid;
BOOL bFound;
LPBYTE lpPattern,lpPattern_end;
hTbl = OpenFileMapping(FILE_MAP_READ, FALSE,
lpImeL->szTblFile[uTblIndex]);
if (!hTbl) {
return;
}
lpTbl = (LPBYTE)MapViewOfFile(hTbl, FILE_MAP_READ, 0, 0, 0);
if (!lpTbl) {
CloseHandle(hTbl);
return;
}
iLo = 1;
// iHi = lpImeL->uTblSize[uTblIndex] / (lpImeL->nSeqBytes *2);
iHi = (*(LPDWORD)(lpTbl) & lpImeL->dwPatternMask);
iMid = (iHi + iLo) /2;
// binary search
for (; iLo <= iHi; ) {
LPUNADWORD lpCurr;
lpCurr = (LPDWORD)(lpTbl + (lpImeL->nSeqBytes * 2 ) *
iMid);
if (dwPattern > (*lpCurr & lpImeL->dwPatternMask)) {
iLo = iMid + 1;
} else if (dwPattern < (*lpCurr & lpImeL->dwPatternMask)) {
iHi = iMid - 1;
} else {
bFound = TRUE;
break;
}
iMid = (iHi + iLo) /2;
}
if (bFound) {
HANDLE hPhrase;
LPBYTE lpPhrase;
LPWORD lpStart, lpEnd;
// find the lower bound
lpPattern = lpTbl + (lpImeL->nSeqBytes * 2) * iMid;
for (; (LPBYTE)lpPattern >= lpTbl; (LPBYTE)lpPattern -=
lpImeL->nSeqBytes * 2 ) {
if (dwPattern > (*(LPUNADWORD)lpPattern & lpImeL->dwPatternMask)) {
// previous one is the lower bound
(LPBYTE)lpPattern += lpImeL->nSeqBytes * 2;
break;
}
}
if ((LPBYTE)lpPattern <= lpTbl) {
goto SrchPhrUnmapPattern;
}
hPhrase = OpenFileMapping(FILE_MAP_READ, FALSE,
lpImeL->szTblFile[uTblIndex + 1]);
if (!hPhrase) {
goto SrchPhrUnmapPattern;
}
lpPhrase = (LPBYTE)MapViewOfFile(hPhrase, FILE_MAP_READ, 0, 0, 0);
if (!lpPhrase) {
goto SrchPhrClosePhr;
}
// offset of the string
lpEnd = (LPWORD)lpPhrase + (*(LPUNADWORD)(lpPattern + lpImeL->nSeqBytes) & lpImeL->dwPatternMask);
for (; dwPattern == (*(LPUNADWORD)lpPattern & lpImeL->dwPatternMask);
(LPBYTE)lpPattern += lpImeL->nSeqBytes * 2 ) {
WORD wCode;
DWORD dwStrLen;
lpStart = lpEnd;
// offset of next string
lpEnd = (LPWORD)lpPhrase + (*(LPUNADWORD)(lpPattern +
lpImeL->nSeqBytes * 3) & lpImeL->dwPatternMask);
for (dwStrLen = 0; lpStart < lpEnd; lpStart++,
dwStrLen += sizeof(WORD)) {
wCode = *lpStart;
// add this char into candidate list
*(LPWSTR)((LPBYTE)lpCandList + lpCandList->dwOffset[
lpCandList->dwCount] + dwStrLen) = wCode;
}
// null terminator
*(LPTSTR)((LPBYTE)lpCandList + lpCandList->dwOffset[
lpCandList->dwCount] + dwStrLen) = '\0';
dwStrLen += sizeof(TCHAR);
// add one string into candidate list
lpCandList->dwCount++;
if (lpCandList->dwCount >= MAXCAND) {
// Grow memory here and do something,
// if you still want to process it.
break;
}
// string length plus size of the null terminator
lpCandList->dwOffset[lpCandList->dwCount] =
lpCandList->dwOffset[lpCandList->dwCount - 1] +
dwStrLen + sizeof(TCHAR);
}
iHi = (*(LPDWORD)(lpTbl) & lpImeL->dwPatternMask);
lpPattern = lpTbl + (lpImeL->nSeqBytes * 2) * iHi;
iHi = (*(LPDWORD)(lpTbl+4) & lpImeL->dwPatternMask);
lpPattern_end = lpTbl + (lpImeL->nSeqBytes * 2) * iHi;
for (; (LPBYTE)lpPattern < lpPattern_end; (LPBYTE)lpPattern +=
lpImeL->nSeqBytes * 2 ) {
WORD wCode;
DWORD dwStrLen;
if (dwPattern == (*(LPUNADWORD)lpPattern & lpImeL->dwPatternMask)) {
lpStart = (LPWORD)lpPhrase + (*(LPUNADWORD)(lpPattern + lpImeL->nSeqBytes) & lpImeL->dwPatternMask);
lpEnd = (LPWORD)lpPhrase + (*(LPUNADWORD)(lpPattern + (lpImeL->nSeqBytes *3)) & lpImeL->dwPatternMask);
for (dwStrLen = 0; lpStart < lpEnd; lpStart++,
dwStrLen += sizeof(WORD)) {
wCode = *lpStart;
// add this char into candidate list
*(LPWSTR)((LPBYTE)lpCandList + lpCandList->dwOffset[
lpCandList->dwCount] + dwStrLen) = wCode;
}
// null terminator
*(LPTSTR)((LPBYTE)lpCandList + lpCandList->dwOffset[
lpCandList->dwCount] + dwStrLen) = '\0';
dwStrLen += sizeof(TCHAR);
// add one string into candidate list
lpCandList->dwCount++;
if (lpCandList->dwCount >= MAXCAND) {
// Grow memory here and do something,
// if you still want to process it.
break;
}
// string length plus size of the null terminator
lpCandList->dwOffset[lpCandList->dwCount] =
lpCandList->dwOffset[lpCandList->dwCount - 1] +
dwStrLen + sizeof(TCHAR);
}
}
UnmapViewOfFile(lpPhrase);
SrchPhrClosePhr:
CloseHandle(hPhrase);
}
SrchPhrUnmapPattern:
UnmapViewOfFile(lpTbl);
CloseHandle(hTbl);
return;
}
#endif
#if defined(CHAJEI) || defined(QUICK) || defined(WINAR30)
/**********************************************************************/
/* MatchPattern() */
/**********************************************************************/
DWORD PASCAL MatchPattern(
DWORD dwSearchPattern,
LPPRIVCONTEXT lpImcP)
{
int i;
if (lpImcP->iGhostCard == lpImeL->nMaxKey) {
#if defined(WINAR30)
} else if (lpImcP->iGhostCard == 0) {
// no order search
BYTE bSeq[8];
int j;
*(LPDWORD)bSeq = *(LPDWORD)lpImcP->bSeq;
*(LPDWORD)&bSeq[4] = *(LPDWORD)&lpImcP->bSeq[4];
// 0 out the ghost card *XYZ -> 0XYZ
bSeq[0] = 0;
for (j = 0; j < lpImeL->nMaxKey; j++,
dwSearchPattern >>= lpImeL->nSeqBits) {
DWORD dwSeqCode;
dwSeqCode = dwSearchPattern & lpImeL->dwSeqMask;
if (!dwSeqCode) {
continue;
}
for (i = 1; i < lpImcP->iInputEnd; i++) {
if (dwSeqCode == bSeq[i]) {
// find one - turn off this one not search again
bSeq[i] = 0;
break;
}
}
}
if (*(LPDWORD)bSeq) {
// not matched, next one
dwSearchPattern = 0;
} else if (*(LPDWORD)&bSeq[4]) {
// not matched, next one
dwSearchPattern = 0;
} else {
dwSearchPattern = lpImcP->dwPattern;
}
#endif
} else {
DWORD dwPatternTmp;
DWORD dwPrefixMask, dwPostfixMask;
int iGhostCard;
#if defined(QUICK)
if (lpImcP->iInputEnd == 1) {
// for quick the single input X can not get any mask
return (dwSearchPattern);
}
#endif
dwPatternTmp = dwSearchPattern;
// prepare prefix mask - for example XX mask of XX*Y
dwPrefixMask = lpImeL->dwPatternMask;
for (i = lpImeL->nMaxKey - 1; i >= lpImcP->iGhostCard; i--) {
dwPrefixMask <<= lpImeL->nSeqBits;
}
dwSearchPattern &= dwPrefixMask;
// prepare postfix mask - for example YY mask of X*YY
#if defined(QUICK)
// we do not have X*Y for quick IME, we use a virtual * here
iGhostCard = lpImcP->iGhostCard - 1;
#else
iGhostCard = lpImcP->iGhostCard;
#endif
// + 1 because this first mask do not need to shift
// so the shift time will be one time less
for (i = iGhostCard + 1 + 1; i < lpImeL->nMaxKey; i++,
dwPatternTmp >>= lpImeL->nSeqBits) {
if (dwPatternTmp & lpImeL->dwSeqMask) {
break;
}
}
dwPostfixMask = 0;
for (i = iGhostCard + 1; i < lpImcP->iInputEnd; i++) {
dwPostfixMask <<= lpImeL->nSeqBits;
dwPostfixMask |= lpImeL->dwSeqMask;
}
dwPatternTmp &= dwPostfixMask;
for (; i < lpImeL->nMaxKey; i++) {
dwPatternTmp <<= lpImeL->nSeqBits;
}
dwSearchPattern |= dwPatternTmp;
}
return (dwSearchPattern);
}
#endif
#if defined(WINAR30)
/**********************************************************************/
/* WildCardSearchPattern() */
/**********************************************************************/
void PASCAL WildCardSearchPattern(
LPBYTE lpCurr,
LPBYTE lpEnd,
LPPRIVCONTEXT lpImcP,
LPCANDIDATELIST lpCandList)
{
DWORD dwRecLen;
dwRecLen = lpImeL->nSeqBytes + sizeof(WORD);
for (; lpCurr < lpEnd; lpCurr += dwRecLen) {
DWORD dwSearchPattern;
#if defined(WINAR30)
DWORD dwWildCardPattern;
#endif
UINT uCode;
// skip the first word (bank ID) of internal code
dwSearchPattern = *(LPUNADWORD)lpCurr & lpImeL->dwPatternMask;
#if defined(WINAR30)
dwWildCardPattern = dwSearchPattern;
#endif
if (lpImcP->iGhostCard != lpImeL->nMaxKey) {
dwSearchPattern = MatchPattern(dwSearchPattern, lpImcP);
}
#if defined(WINAR30)
dwSearchPattern &= lpImcP->dwWildCardMask;
#endif
if (lpImcP->dwPattern != dwSearchPattern) {
continue;
}
#if defined(WINAR30)
if (!lpImcP->dwLastWildCard) {
} else if (dwWildCardPattern & lpImcP->dwLastWildCard) {
// a ? wild card or a * ghost card must have a stroke there
} else {
// a ? wild card or a * ghost card do not have a stroke there
// - can not match
continue;
}
#endif
uCode = *(LPWSTR)(lpCurr + lpImeL->nSeqBytes);
AddCodeIntoCand(lpCandList, uCode);
if (lpCandList->dwCount >= MAXCAND) {
// Grow memory here and do something,
// if you still want to process it.
break;
}
}
return;
}
#endif
#if !defined(WINIME) && !defined(UNICDIME)
/**********************************************************************/
/* SearchPattern() */
/**********************************************************************/
#if defined(CHAJEI) || defined(QUICK)
int PASCAL SearchPattern(
LPBYTE lpTbl,
LPPRIVCONTEXT lpImcP)
{
int iLo, iMid, iHi;
#if defined(CHAJEI)
DWORD dwCompReadStrLen;
#endif
if (lpImcP->bSeq[0] > lpImeL->nSeqCode) {
return (0);
}
iMid = lpImcP->bSeq[0] * (lpImeL->nSeqCode + 1); // A1 char
#if defined(QUICK)
if (lpImcP->bSeq[1] > lpImeL->nSeqCode) {
return (0);
}
iMid += lpImcP->bSeq[1];
#endif
#if defined(CHAJEI)
if (!lpImcP->bSeq[0]) {
dwCompReadStrLen = 0;
} else if (!lpImcP->bSeq[1]) {
dwCompReadStrLen = sizeof(WORD);
} else if (!lpImcP->bSeq[2]) {
dwCompReadStrLen = 2 * sizeof(WORD);
} else if (!lpImcP->bSeq[3]) {
dwCompReadStrLen = 3 * sizeof(WORD);
} else if (!lpImcP->bSeq[4]) {
dwCompReadStrLen = 4 * sizeof(WORD);
} else {
dwCompReadStrLen = 5 * sizeof(WORD);
}
if (dwCompReadStrLen > sizeof(WORD)) {
if (lpImcP->bSeq[dwCompReadStrLen / 2 - 1] > lpImeL->nSeqCode) {
return (0);
}
iMid += lpImcP->bSeq[dwCompReadStrLen / 2 - 1];
}
#endif
iLo = *((LPWORD)lpTbl + iMid); // start WORD of A234.TBL & ACODE.TBL
iHi = *((LPWORD)lpTbl + iMid + 1); // end WORD of A234.TBL & ACODE.TBL
if (iLo < iHi) {
return (iMid);
} else {
return (0);
}
}
#else
int PASCAL SearchPattern(
#if defined(UNIIME)
LPIMEL lpImeL,
#endif
LPBYTE lpTbl,
UINT uTblIndex,
LPPRIVCONTEXT lpImcP)
{
int iLo, iMid, iHi;
BOOL fFound;
DWORD dwRecLen;
fFound = FALSE;
#if defined(PHON)
dwRecLen = lpImeL->nSeqBytes;
#else
dwRecLen = lpImeL->nSeqBytes + sizeof(WORD);
#endif
iLo = 0;
iHi = lpImeL->uTblSize[uTblIndex] / dwRecLen;
iMid = (iLo + iHi) / 2;
#if defined(WINAR30) //1996/3/3
for (; iHi >= iLo; ) {
LPUNADWORD lpCurr;
lpCurr = (LPDWORD)(lpTbl + dwRecLen * iHi);
if (lpImcP->dwPattern == (*lpCurr & lpImeL->dwPatternMask)) {
fFound = TRUE;
iMid = iHi;
break;
}
iHi = iHi - 1;
#else
for (; iLo <= iHi; ) {
LPUNADWORD lpCurr;
lpCurr = (LPDWORD)(lpTbl + dwRecLen * iMid);
if (lpImcP->dwPattern > (*lpCurr & lpImeL->dwPatternMask)) {
iLo = iMid + 1;
} else if (lpImcP->dwPattern < (*lpCurr & lpImeL->dwPatternMask)) {
iHi = iMid - 1;
} else {
fFound = TRUE;
break;
}
iMid = (iLo + iHi) / 2;
#endif
}
if (fFound) {
return (iMid);
} else {
return (0);
}
}
#endif
/**********************************************************************/
/* FindPattern() */
/**********************************************************************/
void PASCAL FindPattern(
#if defined(UNIIME)
LPIMEL lpImeL,
#endif
LPBYTE lpTbl,
int iMid,
LPCANDIDATELIST lpCandList,
LPPRIVCONTEXT lpImcP)
{
#ifndef WINAR30
int iLo, iHi;
#endif
DWORD dwRecLen;
#if defined(CHAJEI)
HANDLE hTblA234;
LPBYTE lpTblA234, lpA234;
DWORD dwPatternA234;
#endif
#if defined(PHON) || defined(CHAJEI) || defined(QUICK)
HANDLE hTblCode;
LPBYTE lpTblCode;
#endif
LPBYTE lpStart, lpEnd;
#if defined(PHON)
dwRecLen = lpImeL->nSeqBytes;
#elif !defined(CHAJEI) && !defined(QUICK)
dwRecLen = lpImeL->nSeqBytes + sizeof(WORD);
#else
#endif
// find the lower bound
#if defined(PHON)
{
HANDLE hTable;
LPWORD lpTable;
hTable = OpenFileMapping(FILE_MAP_READ, FALSE, lpImeL->szTblFile[1]);
if (!hTable) {
return;
}
lpTable = MapViewOfFile(hTable, FILE_MAP_READ, 0, 0, 0);
if (!lpTable) {
goto FndPatCloseTbl1;
}
iLo = *(lpTable + iMid);
iHi = *(lpTable + iMid + 1);
UnmapViewOfFile(lpTable);
FndPatCloseTbl1:
CloseHandle(hTable);
if (!lpTable) {
return;
}
}
#elif defined(CHAJEI) || defined(QUICK)
iLo = *((LPWORD)lpTbl + iMid);
iHi = *((LPWORD)lpTbl + iMid + 1);
if (iLo >= iHi) {
return;
}
#else
#if defined(WINAR30) //1996/3/4
lpStart = lpTbl;
lpEnd = lpTbl + dwRecLen * (iMid+1);
#else
// find the lower bound
iLo = iMid - 1;
lpStart = lpTbl + dwRecLen * iLo;
for (; lpStart >= lpTbl; lpStart -= dwRecLen) {
register DWORD dwSearchPattern;
dwSearchPattern = *(LPUNADWORD)lpStart & lpImeL->dwPatternMask;
if (lpImcP->dwPattern > dwSearchPattern) {
// previous one is the lower bound
lpStart += dwRecLen;
break;
}
}
if (lpStart <= lpTbl) {
return;
}
// offset of code
lpStart += lpImeL->nSeqBytes;
// find the higher bound
iHi = iMid + 1;
lpEnd = lpTbl + dwRecLen * iHi;
for (; ; lpEnd += dwRecLen) {
register DWORD dwSearchPattern;
dwSearchPattern = *(LPUNADWORD)lpEnd & lpImeL->dwPatternMask;
if (lpImcP->dwPattern < dwSearchPattern) {
// the one is the higher bound, not including
break;
}
}
// offset of code
lpEnd += lpImeL->nSeqBytes;
#endif
#endif
#if defined(CHAJEI)
// A234.TBL
hTblA234 = OpenFileMapping(FILE_MAP_READ, FALSE, lpImeL->szTblFile[1]);
if (!hTblA234) {
return;
}
lpTblA234 = MapViewOfFile(hTblA234, FILE_MAP_READ, 0, 0, 0);
if (!lpTblA234) {
goto FndPatCloseTblA234;
}
lpA234 = lpTblA234 + sizeof(WORD) * iLo;
dwPatternA234 = 0;
if (lpImcP->bSeq[2]) {
dwPatternA234 |= lpImcP->bSeq[1] << (lpImeL->nSeqBits * 2);
}
if (lpImcP->bSeq[3]) {
dwPatternA234 |= lpImcP->bSeq[2] << lpImeL->nSeqBits;
}
if (lpImcP->bSeq[4]) {
dwPatternA234 |= lpImcP->bSeq[3];
}
#endif
#if defined(PHON) || defined(CHAJEI) || defined(QUICK)
// PHONCODE.TBL ACODE.TBL
hTblCode = OpenFileMapping(FILE_MAP_READ, FALSE, lpImeL->szTblFile[2]);
if (!hTblCode) {
return;
}
lpTblCode = MapViewOfFile(hTblCode, FILE_MAP_READ, 0, 0, 0);
if (!lpTblCode) {
goto FndPatCloseTblCode;
}
lpStart = lpTblCode + sizeof(WORD) * iLo;
lpEnd = lpTblCode + sizeof(WORD) * iHi;
dwRecLen = sizeof(WORD);
#endif
#if defined(CHAJEI)
for (; lpStart < lpEnd; lpStart += dwRecLen, lpA234 += sizeof(WORD)) {
#else
for (; lpStart < lpEnd; lpStart += dwRecLen) {
#endif
UINT uCode;
#if defined(CHAJEI)
if (lpImcP->bSeq[1] == GHOSTCARD_SEQCODE) {
if (!lpImcP->bSeq[2]) {
// if the 3rd sequence code is 0, it is not a ghost card
continue;
}
} else if (dwPatternA234 != *(LPWORD)lpA234) {
continue;
} else {
}
#endif
#if defined(WINAR30) //1996/3/4
register DWORD dwSearchPattern;
dwSearchPattern = *(LPUNADWORD)lpStart & lpImeL->dwPatternMask;
if (lpImcP->dwPattern == dwSearchPattern) {
uCode = *(LPUNAWORD)(lpStart+lpImeL->nSeqBytes);
AddCodeIntoCand(lpCandList, uCode);
}
#else
uCode = *(LPUNAWORD)lpStart;
#if defined(PHON) || defined(DAYI)
#ifdef UNICODE
if (!IsValidCode(uCode)) {
uCode = InverseEncode(uCode);
}
#else
// resolve duplicate composition for one code
if (!(uCode & 0x8000)) {
uCode |= 0x8000;
}
#endif
#endif
#if defined(UNIIME)
AddCodeIntoCand(lpImeL,lpCandList, uCode);
#else
AddCodeIntoCand(lpCandList, uCode);
#endif
#endif
if (lpCandList->dwCount >= MAXCAND) {
// Grow memory here and do something,
// if you still want to process it.
break;
}
}
#if defined(PHON) || defined(CHAJEI) || defined(QUICK)
UnmapViewOfFile(lpTblCode);
FndPatCloseTblCode:
CloseHandle(hTblCode);
#endif
#if defined(CHAJEI)
UnmapViewOfFile(lpTblA234);
FndPatCloseTblA234:
CloseHandle(hTblA234);
#endif
return;
}
#endif // !defined(WINIME) && !defined(UNICDIME)
/**********************************************************************/
/* SearchTbl() */
/* Description: */
/* file format can be changed in different version for */
/* performance consideration, ISVs should not assume its format */
/**********************************************************************/
void PASCAL SearchTbl( // searching the standard table files
#if defined(UNIIME)
LPIMEL lpImeL,
#endif
UINT uTblIndex,
LPCANDIDATELIST lpCandList,
LPPRIVCONTEXT lpImcP)
{
#if defined(WINIME) || defined(UNICDIME)
if (!lpImcP->bSeq[0]) {
} else if (!lpImcP->bSeq[1]) {
} else if (!lpImcP->bSeq[3]) {
DWORD i;
UINT uCode;
uCode = (lpImcP->bSeq[0] - 1) << 12;
uCode |= (lpImcP->bSeq[1] - 1) << 8;
if (lpImcP->bSeq[2]) {
// we want it match with internal code here so | 0x0001
uCode |= (lpImcP->bSeq[2] - 1) << 4 | 0x0001;
} else {
uCode |= 0x0040;
}
for (i = 0; i < lpCandList->dwPageSize; i++, uCode++) {
#if defined(WINIME) && defined(UNICODE)
CHAR szCode[2];
WCHAR wCode[2];
szCode[0] = HIBYTE(uCode);
szCode[1] = LOBYTE(uCode);
wCode[0] = 0;
MultiByteToWideChar(sImeG.uAnsiCodePage, MB_PRECOMPOSED,
szCode, 2, wCode, sizeof(wCode) / sizeof(WCHAR));
uCode = wCode[0];
#endif
#if defined(UNIIME)
AddCodeIntoCand(lpImeL,lpCandList, uCode);
#else
AddCodeIntoCand(lpCandList, uCode);
#endif
}
} else if (!lpImcP->bSeq[2]) {
return;
} else {
UINT uCode;
#if defined(WINIME) && defined(UNICODE)
CHAR szCode[2];
WCHAR wCode[2];
#endif
uCode = (lpImcP->bSeq[0] - 1) << 12;
uCode |= (lpImcP->bSeq[1] - 1) << 8;
uCode |= (lpImcP->bSeq[2] - 1) << 4;
uCode |= (lpImcP->bSeq[3] - 1);
#if defined(WINIME) && defined(UNICODE)
szCode[0] = HIBYTE(uCode);
szCode[1] = LOBYTE(uCode);
wCode[0] = 0;
MultiByteToWideChar(sImeG.uAnsiCodePage, MB_PRECOMPOSED,
szCode, 2, wCode, sizeof(wCode) / sizeof(WCHAR));
uCode = wCode[0];
#endif
#if defined(UNIIME)
AddCodeIntoCand(lpImeL,lpCandList, uCode);
#else
AddCodeIntoCand(lpCandList, uCode);
#endif
}
return;
#else
HANDLE hTbl;
LPBYTE lpTbl;
if (!lpImcP->dwPattern) {
return;
}
#if defined(WINAR30) // 1996/2/5
if (lpImcP->dwCompChar==0x27)
goto SearchTblOvr;
#endif
hTbl = OpenFileMapping(FILE_MAP_READ, FALSE,
lpImeL->szTblFile[uTblIndex]);
if (!hTbl) {
return;
}
lpTbl = (LPBYTE)MapViewOfFile(hTbl, FILE_MAP_READ, 0, 0, 0);
if (!lpTbl) {
goto SearchTblOvr;
}
#if defined(WINAR30)
if (lpImcP->iGhostCard != lpImeL->nMaxKey) {
WildCardSearchPattern(lpTbl, lpTbl + lpImeL->uTblSize[uTblIndex],
lpImcP, lpCandList);
} else if (lpImcP->dwLastWildCard) {
WildCardSearchPattern(lpTbl, lpTbl + lpImeL->uTblSize[uTblIndex],
lpImcP, lpCandList);
} else {
#else
{
#endif // defined(WINAR30)
int iMid;
#if defined(CHAJEI) || defined(QUICK)
iMid = SearchPattern(lpTbl, lpImcP);
#else
iMid = SearchPattern(
#if defined(UNIIME)
lpImeL,
#endif
lpTbl, uTblIndex, lpImcP);
#endif
if (iMid > 0) {
FindPattern(
#if defined(UNIIME)
lpImeL,
#endif
lpTbl, iMid, lpCandList, lpImcP);
}
}
UnmapViewOfFile(lpTbl);
SearchTblOvr:
CloseHandle(hTbl);
#if defined(DAYI)
if (uTblIndex == 0) { // do not duplciate search the phrase table
SearchPhraseTbl(1, lpCandList, lpImcP->dwPattern);
}
#endif
#if defined(WINAR30) // 1996/2/5
if (uTblIndex == 0 && lpImcP->dwCompChar==0x27) { // do not duplciate search the phrase table
SearchPhraseTbl(4, lpCandList, lpImcP->dwPattern);
}
#endif
#if defined(UNIIME) // same as Dayi need to search phrase table
SearchPhraseTbl(lpImeL, 1, lpCandList, lpImcP->dwPattern);
#endif
return;
#endif // !defined(WINIME) && !defined(UNICDIME)
}
#if !defined(WINIME) && !defined(UNICDIME) && !defined(ROMANIME)
/**********************************************************************/
/* SearchUsrDic() */
/**********************************************************************/
void PASCAL SearchUsrDic( // searching the user dictionary
#if defined(UNIIME)
LPIMEL lpImeL,
#endif
LPCANDIDATELIST lpCandList,
LPPRIVCONTEXT lpImcP)
{
HANDLE hUsrDicMem;
LPBYTE lpUsrDicStart, lpCurr, lpUsrDicLimit;
hUsrDicMem = OpenFileMapping(FILE_MAP_READ, FALSE,
lpImeL->szUsrDicMap);
if (!hUsrDicMem) {
return;
}
lpUsrDicStart = (LPBYTE)MapViewOfFile(hUsrDicMem, FILE_MAP_READ,
0, 0, lpImeL->uUsrDicSize);
if (!lpUsrDicStart) {
goto SearchUsrDicOvr;
}
lpUsrDicLimit = lpUsrDicStart + lpImeL->uUsrDicSize;
for (lpCurr = lpUsrDicStart; lpCurr < lpUsrDicLimit;
lpCurr += lpImeL->nSeqBytes + sizeof(WORD)) {
DWORD dwSearchPattern;
UINT uCode;
// skip the first word (bank ID) of internal code
dwSearchPattern = *(LPUNADWORD)(lpCurr + sizeof(WORD)) &
lpImeL->dwPatternMask;
#if defined(CHAJEI) || defined(QUICK) || defined(WINAR30)
if (lpImcP->iGhostCard != lpImeL->nMaxKey) {
dwSearchPattern = MatchPattern(dwSearchPattern, lpImcP);
}
#endif
#if defined(WINAR30)
dwSearchPattern &= lpImcP->dwWildCardMask;
#endif
if (lpImcP->dwPattern != dwSearchPattern) {
continue;
}
#if defined(WINAR30)
if (!lpImcP->dwLastWildCard) {
} else if (dwSearchPattern & lpImcP->dwLastWildCard) {
// a ? wild card must have a stroke there
} else {
// a ? wild card do not have a stroke there - can not match
continue;
}
#endif
uCode = *(LPUNAWSTR)lpCurr;
#if defined(UNIIME)
AddCodeIntoCand(lpImeL,lpCandList, uCode);
#else
AddCodeIntoCand(lpCandList, uCode);
#endif
if (lpCandList->dwCount >= MAXCAND) {
// Grow memory here and do something,
// if you still want to process it.
break;
}
}
UnmapViewOfFile(lpUsrDicStart);
SearchUsrDicOvr:
CloseHandle(hUsrDicMem);
return;
}
#endif // !defined(WINIME) && !defined(UNICDIME) && !defined(ROMANIME)
#endif // !defined(ROMANIME)