/*++ Copyright (c) 1990-1999 Microsoft Corporation, All Rights Reserved Module Name: SEARCH.c ++*/ #include #include #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)