|
|
/****************************************************************************
HANJA.CPP
Owner: cslim Copyright (c) 1997-1999 Microsoft Corporation
Hanja conversion and dictionary lookup functions. Dictionary index is stored as globally shared memory. History: 26-APR-1999 cslim Modified for Multibox Applet Tooltip display 14-JUL-1999 cslim Copied from IME98 source tree *****************************************************************************/
#include <windows.h>
#include <windowsx.h>
#include <stdio.h>
#include <stdlib.h>
#include "hwxobj.h"
#include "lexheader.h"
#include "hanja.h"
#include "common.h"
#include "immsec.h"
#include "dbg.h"
// NT5 Globally shared memory.
const TCHAR IMEKR_LEX_SHAREDDATA_MUTEX_NAME[] = TEXT("ImeKrLex.Mutex"); const TCHAR IMEKR_LEX_SHAREDDATA_NAME[] = TEXT("ImeKrLexHanjaToHangul.SharedMemory");
UINT vuNumofK0=0, vuNumofK1=0; WCHAR vwcHangul=0;
// Private data
static BOOL vfLexOpen = FALSE; static HANDLE vhLex=0; static HANDLE vhLexIndexTbl=0; static UINT vuNumOfHanjaEntry=0; static DWORD viBufferStart=0; // seek point
// Private functions
static BOOL OpenLex(); //static VOID ClearHanjaSenseArray();
static INT SearchHanjaIndex(WCHAR wHChar, HanjaToHangulIndex *pLexIndexTbl);
BOOL EnsureHanjaLexLoaded() { _DictHeader *pLexHeader; HKEY hKey; DWORD dwReadBytes; CHAR szLexFileName[MAX_PATH], szLexPathExpanded[MAX_PATH]; DWORD dwCb, dwType; if (vfLexOpen) return TRUE;
// Get Lex file path
szLexFileName[0] = 0; szLexPathExpanded[0] = 0; if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, g_szIMERootKey, 0, KEY_READ, &hKey) == ERROR_SUCCESS) { dwCb = sizeof(szLexFileName); dwType = REG_SZ;
if (RegQueryValueEx(hKey, g_szDictionary, NULL, &dwType, (LPBYTE)szLexFileName, &dwCb) == ERROR_SUCCESS) ExpandEnvironmentStrings(szLexFileName, szLexPathExpanded, sizeof(szLexPathExpanded)); RegCloseKey(hKey); }
DBGAssert(szLexPathExpanded[0] != 0); if (szLexPathExpanded[0] == 0) return FALSE;
vhLex = CreateFile(szLexPathExpanded, GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING, FILE_FLAG_RANDOM_ACCESS, NULL); if (vhLex==INVALID_HANDLE_VALUE) { DBGAssert(0); return FALSE; }
pLexHeader = new _DictHeader; if (!pLexHeader) return FALSE;
if (ReadFile(vhLex, pLexHeader, sizeof(_DictHeader), &dwReadBytes, 0) == 0 || (dwReadBytes != sizeof(_DictHeader))) { DBGAssert(0); return FALSE; }
// Set member vars
vuNumOfHanjaEntry = pLexHeader->uiNumofHanja; viBufferStart = pLexHeader->iBufferStart;
if (pLexHeader->Version < LEX_VERSION || pLexHeader->Version > LEX_COMPATIBLE_VERSION_LIMIT ) { delete pLexHeader; DBGAssert(0); return FALSE; } if (lstrcmpA(pLexHeader->COPYRIGHT_HEADER, COPYRIGHT_STR)) { delete pLexHeader; DBGAssert(0); return FALSE; }
// Read Index table
SetFilePointer(vhLex, pLexHeader->iHanjaToHangulIndex, 0, FILE_BEGIN); delete pLexHeader;
return OpenLex(); }
__inline BOOL DoEnterCriticalSection(HANDLE hMutex) { if(WAIT_FAILED==WaitForSingleObject(hMutex, 3000)) // Wait 3 seconds
return(FALSE); return(TRUE); }
BOOL OpenLex() { BOOL fRet = FALSE; HanjaToHangulIndex* pHanjaToHangulIndex; HANDLE hMutex; DWORD dwReadBytes; ///////////////////////////////////////////////////////////////////////////
// Mapping Lex file
// The dictionary index is shared data between all IME instance
hMutex=CreateMutex(GetIMESecurityAttributes(), FALSE, IMEKR_LEX_SHAREDDATA_MUTEX_NAME);
if (hMutex != NULL) { if (DoEnterCriticalSection(hMutex) == FALSE) goto ExitOpenLexCritSection;
vhLexIndexTbl = OpenFileMapping(FILE_MAP_READ, TRUE, IMEKR_LEX_SHAREDDATA_NAME);
if(vhLexIndexTbl) { Dbg(("CHanja::OpenLex() - File mapping already exists")); fRet = TRUE; } else { // if no file mapping exist
vhLexIndexTbl = CreateFileMapping(INVALID_HANDLE_VALUE, GetIMESecurityAttributes(), PAGE_READWRITE, 0, sizeof(HanjaToHangulIndex)*(vuNumOfHanjaEntry), IMEKR_LEX_SHAREDDATA_NAME); if (vhLexIndexTbl) { Dbg(("CHanja::OpenLex() - File mapping Created")); pHanjaToHangulIndex = (HanjaToHangulIndex*)MapViewOfFile(vhLexIndexTbl, FILE_MAP_READ | FILE_MAP_WRITE, 0, 0, 0); if (!pHanjaToHangulIndex) goto ExitOpenLexCritSection;
if (ReadFile(vhLex, pHanjaToHangulIndex, sizeof(HanjaToHangulIndex)*(vuNumOfHanjaEntry), &dwReadBytes, 0) != 0 && dwReadBytes == sizeof(HanjaToHangulIndex)*(vuNumOfHanjaEntry)) { fRet = TRUE; } else { fRet = FALSE; } UnmapViewOfFile(pHanjaToHangulIndex); } #ifdef _DEBUG
else DBGAssert(0); #endif
} ExitOpenLexCritSection: ReleaseMutex(hMutex); CloseHandle(hMutex); } FreeIMESecurityAttributes();
vfLexOpen = fRet; return fRet; }
BOOL CloseLex() { //ClearHanjaSenseArray();
if (vhLexIndexTbl) { CloseHandle(vhLexIndexTbl); vhLexIndexTbl = 0; }
if (vhLex) { CloseHandle(vhLex); vhLex = 0; }
vfLexOpen = FALSE; return TRUE; }
BOOL GetMeaningAndProunc(WCHAR wch, LPWSTR lpwstrTip, INT cchMax) { HanjaToHangulIndex* pHanjaToHangulIndex; INT iMapHanjaInfo; WCHAR wcHanja; BYTE cchMeaning = 0; WCHAR wszMeaning[MAX_SENSE_LENGTH]; DWORD dwReadBytes; BOOL fRet = FALSE;
Dbg(("GetMeaningAndProunc"));
if (!EnsureHanjaLexLoaded()) return FALSE;
pHanjaToHangulIndex = (HanjaToHangulIndex*)MapViewOfFile(vhLexIndexTbl, FILE_MAP_READ, 0, 0, 0); if (!pHanjaToHangulIndex) { DBGAssert(0); return FALSE; }
// Search index
if ((iMapHanjaInfo = SearchHanjaIndex(wch, pHanjaToHangulIndex)) >= 0) { // Seek to mapping Hanja
SetFilePointer(vhLex, viBufferStart + pHanjaToHangulIndex[iMapHanjaInfo].iOffset, 0, FILE_BEGIN);
// Read Hanja Info
if (ReadFile(vhLex, &wcHanja, sizeof(WCHAR), &dwReadBytes, 0) == 0) { goto GetMeaningAndProuncExit; } DBGAssert(wch == wcHanja); if (ReadFile(vhLex, &cchMeaning, sizeof(BYTE), &dwReadBytes, 0) == 0) { goto GetMeaningAndProuncExit; } if (cchMeaning) { if (ReadFile(vhLex, wszMeaning, cchMeaning, &dwReadBytes, 0) == 0) { goto GetMeaningAndProuncExit; } } wszMeaning[cchMeaning>>1] = L'\0';
swprintf(lpwstrTip, L"%s %c\nU+%04X", wszMeaning, pHanjaToHangulIndex[iMapHanjaInfo].wchHangul, wch); fRet = TRUE; }
GetMeaningAndProuncExit: UnmapViewOfFile(pHanjaToHangulIndex); return fRet; }
INT SearchHanjaIndex(WCHAR wHChar, HanjaToHangulIndex *pLexIndexTbl) { int iHead = 0, iTail = vuNumOfHanjaEntry-1, iMid;
while (iHead <= iTail) { iMid = (iHead + iTail) >> 1;
Dbg(("SearchHanjaIndex iMid=%d, pLexIndexTbl[iMid].wchHanja = 0x%04X", iMid, pLexIndexTbl[iMid].wchHanja));
if (pLexIndexTbl[iMid].wchHanja > wHChar) iTail = iMid - 1; else if (pLexIndexTbl[iMid].wchHanja < wHChar) iHead = iMid + 1; else return (iMid); }
return (-1); }
|