windows-nt/Source/XPSP1/NT/windows/feime/usa/convlist.c

229 lines
6.1 KiB
C
Raw Normal View History

2020-09-26 03:20:57 -05:00
/*************************************************
* convlist.c *
* *
* Copyright (C) 1999 Microsoft Inc. *
* *
*************************************************/
#include <windows.h>
#include <immdev.h>
#include "imeattr.h"
#include "imedefs.h"
/**********************************************************************/
/* Conversion() */
/**********************************************************************/
DWORD PASCAL Conversion(
LPCTSTR lpszReading,
LPCANDIDATELIST lpCandList,
DWORD dwBufLen)
{
UINT uMaxCand;
DWORD dwSize = // similar to ClearCand
// header length
sizeof(CANDIDATELIST) +
// candidate string pointers
sizeof(DWORD) * MAXCAND +
// string plus NULL terminator
(sizeof(WCHAR) + sizeof(TCHAR)) * MAXCAND;
PRIVCONTEXT ImcP;
if (!dwBufLen) {
return (dwSize);
}
uMaxCand = dwBufLen - sizeof(CANDIDATELIST);
uMaxCand /= sizeof(DWORD) + sizeof(WCHAR) + sizeof(TCHAR);
if (!uMaxCand) {
// can not even put one string
return (0);
}
lpCandList->dwSize = dwSize;
lpCandList->dwStyle = IME_CAND_READ; // candidate having same reading
lpCandList->dwCount = 0;
lpCandList->dwSelection = 0;
lpCandList->dwPageStart = 0;
lpCandList->dwPageSize = CANDPERPAGE;
lpCandList->dwOffset[0] = sizeof(CANDIDATELIST) + sizeof(DWORD) *
(uMaxCand - 1);
SearchTbl( 0, lpCandList, &ImcP);
return (dwSize);
}
/**********************************************************************/
/* SearchOffset() */
/* Return Value : */
/* the offset in table file which include this uOffset */
/**********************************************************************/
UINT PASCAL SearchOffset(
LPBYTE lpTbl,
UINT uTblSize,
UINT uOffset)
{
int iLo, iMid, iHi;
LPWORD lpwPtr;
iLo = 0;
iHi = uTblSize / sizeof(WORD);
iMid = (iLo + iHi) / 2;
// binary search
for (; iLo <= iHi; ) {
lpwPtr = (LPWORD)lpTbl + iMid;
if (uOffset > *lpwPtr) {
iLo = iMid + 1;
} else if (uOffset < *lpwPtr) {
iHi = iMid - 1;
} else {
break;
}
iMid = (iLo + iHi) / 2;
}
if (iMid > 0) {
iLo = iMid - 1;
} else {
iLo = 0;
}
iHi = uTblSize / sizeof(WORD);
lpwPtr = (LPWORD)lpTbl + iLo;
for (; iLo < iHi; iLo++, lpwPtr++) {
if (*lpwPtr > uOffset) {
return (iLo - 1);
}
}
return (0);
}
/**********************************************************************/
/* ReverseConversion() */
/**********************************************************************/
DWORD PASCAL ReverseConversion(
UINT uCode,
LPCANDIDATELIST lpCandList,
DWORD dwBufLen)
{
UINT uMaxCand;
DWORD dwSize = // similar to ClearCand
// header length
sizeof(CANDIDATELIST) +
// candidate string pointers
sizeof(DWORD) * MAX_COMP +
// string plus NULL terminator
(sizeof(WCHAR) * lpImeL->nMaxKey + sizeof(TCHAR));
UINT uTmpCode;
int i;
if (!dwBufLen) {
return (dwSize);
}
uMaxCand = dwBufLen - sizeof(CANDIDATELIST);
uMaxCand /= sizeof(DWORD) +
(sizeof(WCHAR) * lpImeL->nMaxKey + sizeof(TCHAR));
if (uMaxCand == 0) {
// can not put one string
return (0);
}
lpCandList->dwSize = sizeof(CANDIDATELIST) +
sizeof(DWORD) * uMaxCand +
(sizeof(WCHAR) * lpImeL->nMaxKey + sizeof(TCHAR));
lpCandList->dwStyle = IME_CAND_READ;
lpCandList->dwCount = 0;
lpCandList->dwSelection = 0;
lpCandList->dwPageSize = CANDPERPAGE;
lpCandList->dwOffset[0] = sizeof(CANDIDATELIST) + sizeof(DWORD) *
(uMaxCand - 1);
uTmpCode = uCode;
for (i = lpImeL->nMaxKey - 1; i >= 0; i--) {
UINT uCompChar;
uCompChar = lpImeL->wSeq2CompTbl[(uTmpCode & 0xF) + 1];
*(LPWSTR)((LPBYTE)lpCandList + lpCandList->dwOffset[
lpCandList->dwCount] + sizeof(WCHAR) * i) = (WCHAR)uCompChar;
uTmpCode >>= 4;
}
// null terminator
*(LPTSTR)((LPBYTE)lpCandList + lpCandList->dwOffset[
lpCandList->dwCount] + sizeof(WCHAR) * lpImeL->nMaxKey) = '\0';
// string count ++
lpCandList->dwCount++;
return (dwSize);
}
/**********************************************************************/
/* ImeConversionList() / UniImeConversionList() */
/**********************************************************************/
DWORD WINAPI ImeConversionList(
HIMC hIMC,
LPCTSTR lpszSrc,
LPCANDIDATELIST lpCandList,
DWORD dwBufLen,
UINT uFlag)
{
UINT uCode;
if (!dwBufLen) {
} else if (!lpszSrc) {
return (0);
} else if (!*lpszSrc) {
return (0);
} else if (!lpCandList) {
return (0);
} else if (dwBufLen <= sizeof(CANDIDATELIST)) {
// buffer size can not even put the header information
return (0);
} else {
}
switch (uFlag) {
case GCL_CONVERSION:
return Conversion(
lpszSrc, lpCandList, dwBufLen);
break;
case GCL_REVERSECONVERSION:
if (!dwBufLen) {
return ReverseConversion(
0, lpCandList, dwBufLen);
}
// only support one DBCS char reverse conversion
if (*(LPTSTR)((LPBYTE)lpszSrc + sizeof(WORD)) != '\0') {
return (0);
}
uCode = *(LPUNAWORD)lpszSrc;
return ReverseConversion(
uCode, lpCandList, dwBufLen);
break;
case GCL_REVERSE_LENGTH:
return sizeof(WCHAR);
break;
default:
return (0);
break;
}
}