From: Katayama Hirofumi MZ Date: Fri, 15 Oct 2021 13:46:58 +0000 (+0900) Subject: [IMM32] Refactor about reconversion (#4031) X-Git-Url: https://git.reactos.org/?p=reactos.git;a=commitdiff_plain;h=04cb13bc57f6fd81e881c6fbe9bb49fe636c76d1 [IMM32] Refactor about reconversion (#4031) - Delete Imm32ReconvertSize and Imm32ConvertReconvert helper functions. - Add Imm32ReconvertAnsiFromWide and Imm32ReconvertWideFromAnsi helper functions. CORE-11700 --- diff --git a/dll/win32/imm32/keymsg.c b/dll/win32/imm32/keymsg.c index 168382559e4..4273220d24b 100644 --- a/dll/win32/imm32/keymsg.c +++ b/dll/win32/imm32/keymsg.c @@ -355,106 +355,6 @@ VOID APIENTRY Imm32RequestError(DWORD dwError) SetLastError(dwError); } -DWORD APIENTRY Imm32ReconvertSize(DWORD dwSize, BOOL bAnsi, BOOL bConvert) -{ - DWORD dwOffset; - if (dwSize < sizeof(RECONVERTSTRING)) - return 0; - if (!bConvert) - return dwSize; - dwOffset = dwSize - sizeof(RECONVERTSTRING); - if (bAnsi) - dwOffset /= sizeof(WCHAR); - else - dwOffset *= sizeof(WCHAR); - return sizeof(RECONVERTSTRING) + dwOffset; -} - -DWORD APIENTRY -Imm32ConvertReconvert(LPRECONVERTSTRING pDest, const RECONVERTSTRING *pSrc, BOOL bAnsi, - UINT uCodePage) -{ - DWORD ret = sizeof(RECONVERTSTRING), cch0, cch1, cchDest; - - if ((pSrc->dwVersion != 0) || (pDest->dwVersion != 0)) - return 0; - - pDest->dwStrOffset = sizeof(RECONVERTSTRING); - - /* - * See RECONVERTSTRING structure: - * https://katahiromz.web.fc2.com/colony3rd/imehackerz/en/RECONVERTSTRING.html - * - * The dwCompStrOffset and dwTargetOffset members are the relative position of dwStrOffset. - * dwStrLen, dwCompStrLen, and dwTargetStrLen are the TCHAR count. dwStrOffset, - * dwCompStrOffset, and dwTargetStrOffset are the byte offset. - */ - if (bAnsi) /* Ansi <-- Wide */ - { - LPCWSTR pchSrc = (LPCWSTR)((LPCSTR)pSrc + pSrc->dwStrOffset); - LPSTR pchDest = (LPSTR)pDest + pDest->dwStrOffset; - - cchDest = WideCharToMultiByte(uCodePage, 0, pchSrc, pSrc->dwStrLen, - pchDest, pSrc->dwStrLen, NULL, NULL); - - /* dwCompStrOffset */ - cch1 = pSrc->dwCompStrOffset / sizeof(WCHAR); - cch0 = IchAnsiFromWide(cch1, pchSrc, uCodePage); - pDest->dwCompStrOffset = cch0 * sizeof(CHAR); - - /* dwCompStrLen */ - cch0 = IchAnsiFromWide(cch1 + pSrc->dwCompStrLen, pchSrc, uCodePage); - pDest->dwCompStrLen = cch0 * sizeof(CHAR) - pDest->dwCompStrOffset; - - /* dwTargetStrOffset */ - cch1 = pSrc->dwTargetStrOffset / sizeof(WCHAR); - cch0 = IchAnsiFromWide(cch1, pchSrc, uCodePage); - pDest->dwTargetStrOffset = cch0 * sizeof(CHAR); - - /* dwTargetStrLen */ - cch0 = IchAnsiFromWide(cch1 + pSrc->dwTargetStrLen, pchSrc, uCodePage); - pDest->dwTargetStrLen = cch0 * sizeof(CHAR) - pDest->dwTargetStrOffset; - - /* dwStrLen */ - pDest->dwStrLen = cchDest; - pchDest[cchDest] = 0; - - ret += (cchDest + 1) * sizeof(CHAR); - } - else /* Wide <-- Ansi */ - { - LPCSTR pchSrc = (LPCSTR)pSrc + pSrc->dwStrOffset; - LPWSTR pchDest = (LPWSTR)((LPBYTE)pDest + pDest->dwStrOffset); - - cchDest = MultiByteToWideChar(uCodePage, MB_PRECOMPOSED, pchSrc, pSrc->dwStrLen, - pchDest, pSrc->dwStrLen); - - /* dwCompStrOffset */ - cch0 = IchWideFromAnsi(pSrc->dwCompStrOffset, pchSrc, uCodePage); - pDest->dwCompStrOffset = cch0 * sizeof(WCHAR); - - /* dwCompStrLen */ - cch0 = IchWideFromAnsi(pSrc->dwCompStrOffset + pSrc->dwCompStrLen, pchSrc, uCodePage); - pDest->dwCompStrLen = (cch0 * sizeof(WCHAR) - pDest->dwCompStrOffset) / sizeof(WCHAR); - - /* dwTargetStrOffset */ - cch0 = IchWideFromAnsi(pSrc->dwTargetStrOffset, pchSrc, uCodePage); - pDest->dwTargetStrOffset = cch0 * sizeof(WCHAR); - - /* dwTargetStrLen */ - cch0 = IchWideFromAnsi(pSrc->dwTargetStrOffset + pSrc->dwTargetStrLen, pchSrc, uCodePage); - pDest->dwTargetStrLen = (cch0 * sizeof(WCHAR) - pSrc->dwTargetStrOffset) / sizeof(WCHAR); - - /* dwStrLen */ - pDest->dwStrLen = cchDest; - pchDest[cchDest] = 0; - - ret += (cchDest + 1) * sizeof(WCHAR); - } - - return ret; -} - LRESULT APIENTRY Imm32ProcessRequest(HIMC hIMC, PWND pWnd, DWORD dwCommand, LPVOID pData, BOOL bAnsiAPI) { @@ -539,8 +439,11 @@ Imm32ProcessRequest(HIMC hIMC, PWND pWnd, DWORD dwCommand, LPVOID pData, BOOL bA if (bAnsiAPI == bAnsiWnd || !pData) goto DoIt; - pRS = pData; - ret = Imm32ReconvertSize(pRS->dwSize, FALSE, bAnsiWnd); + if (bAnsiWnd) + ret = Imm32ReconvertAnsiFromWide(NULL, pData, uCodePage); + else + ret = Imm32ReconvertWideFromAnsi(NULL, pData, uCodePage); + pTempData = Imm32HeapAlloc(0, ret + sizeof(WCHAR)); if (!pTempData) return 0; @@ -550,7 +453,12 @@ Imm32ProcessRequest(HIMC hIMC, PWND pWnd, DWORD dwCommand, LPVOID pData, BOOL bA pRS->dwVersion = 0; if (dwCommand == IMR_CONFIRMRECONVERTSTRING) - Imm32ConvertReconvert(pData, pTempData, bAnsiWnd, uCodePage); + { + if (bAnsiWnd) + ret = Imm32ReconvertAnsiFromWide(pTempData, pData, uCodePage); + else + ret = Imm32ReconvertWideFromAnsi(pTempData, pData, uCodePage); + } break; case IMR_QUERYCHARPOSITION: @@ -617,13 +525,20 @@ DoIt: case IMR_RECONVERTSTRING: case IMR_DOCUMENTFEED: if (!ret) - goto Quit; + break; - ret = Imm32ReconvertSize(ret, TRUE, bAnsiWnd); - if (ret < sizeof(RECONVERTSTRING) || - (pTempData && !Imm32ConvertReconvert(pData, pTempData, bAnsiAPI, uCodePage))) + if (ret < sizeof(RECONVERTSTRING)) { ret = 0; + break; + } + + if (pTempData) + { + if (bAnsiWnd) + ret = Imm32ReconvertWideFromAnsi(pData, pTempData, uCodePage); + else + ret = Imm32ReconvertAnsiFromWide(pData, pTempData, uCodePage); } break; diff --git a/dll/win32/imm32/precomp.h b/dll/win32/imm32/precomp.h index 35d03332835..584defc5501 100644 --- a/dll/win32/imm32/precomp.h +++ b/dll/win32/imm32/precomp.h @@ -134,3 +134,8 @@ BOOL APIENTRY Imm32LoadImeStateSentence(LPINPUTCONTEXTDX pIC, PIME_STATE pState, HKL hKL); BOOL APIENTRY Imm32SaveImeStateSentence(LPINPUTCONTEXTDX pIC, PIME_STATE pState, HKL hKL); + +DWORD APIENTRY +Imm32ReconvertAnsiFromWide(LPRECONVERTSTRING pDest, const RECONVERTSTRING *pSrc, UINT uCodePage); +DWORD APIENTRY +Imm32ReconvertWideFromAnsi(LPRECONVERTSTRING pDest, const RECONVERTSTRING *pSrc, UINT uCodePage); diff --git a/dll/win32/imm32/utils.c b/dll/win32/imm32/utils.c index 6dddd9df22a..abbe5717bc9 100644 --- a/dll/win32/imm32/utils.c +++ b/dll/win32/imm32/utils.c @@ -361,6 +361,129 @@ Imm32SaveImeStateSentence(LPINPUTCONTEXTDX pIC, PIME_STATE pState, HKL hKL) return FALSE; } +/* + * See RECONVERTSTRING structure: + * https://katahiromz.web.fc2.com/colony3rd/imehackerz/en/RECONVERTSTRING.html + * + * The dwCompStrOffset and dwTargetOffset members are the relative position of dwStrOffset. + * dwStrLen, dwCompStrLen, and dwTargetStrLen are the TCHAR count. dwStrOffset, + * dwCompStrOffset, and dwTargetStrOffset are the byte offset. + */ + +DWORD APIENTRY +Imm32ReconvertWideFromAnsi(LPRECONVERTSTRING pDest, const RECONVERTSTRING *pSrc, UINT uCodePage) +{ + DWORD cch0, cchDest, cbDest; + LPCSTR pchSrc = (LPCSTR)pSrc + pSrc->dwStrOffset; + LPWSTR pchDest; + + if (pSrc->dwVersion != 0) + return 0; + + cchDest = MultiByteToWideChar(uCodePage, MB_PRECOMPOSED, pchSrc, pSrc->dwStrLen, + NULL, 0); + cbDest = sizeof(RECONVERTSTRING) + (cchDest + 1) * sizeof(WCHAR); + if (!pDest) + return cbDest; + + if (pDest->dwSize < cbDest) + return 0; + + /* dwSize */ + pDest->dwSize = cbDest; + + /* dwVersion */ + pDest->dwVersion = 0; + + /* dwStrOffset */ + pDest->dwStrOffset = sizeof(RECONVERTSTRING); + + /* dwCompStrOffset */ + cch0 = IchWideFromAnsi(pSrc->dwCompStrOffset, pchSrc, uCodePage); + pDest->dwCompStrOffset = cch0 * sizeof(WCHAR); + + /* dwCompStrLen */ + cch0 = IchWideFromAnsi(pSrc->dwCompStrOffset + pSrc->dwCompStrLen, pchSrc, uCodePage); + pDest->dwCompStrLen = (cch0 * sizeof(WCHAR) - pDest->dwCompStrOffset) / sizeof(WCHAR); + + /* dwTargetStrOffset */ + cch0 = IchWideFromAnsi(pSrc->dwTargetStrOffset, pchSrc, uCodePage); + pDest->dwTargetStrOffset = cch0 * sizeof(WCHAR); + + /* dwTargetStrLen */ + cch0 = IchWideFromAnsi(pSrc->dwTargetStrOffset + pSrc->dwTargetStrLen, pchSrc, uCodePage); + pDest->dwTargetStrLen = (cch0 * sizeof(WCHAR) - pSrc->dwTargetStrOffset) / sizeof(WCHAR); + + /* dwStrLen */ + pDest->dwStrLen = cchDest; + + /* the string */ + pchDest = (LPWSTR)((LPBYTE)pDest + pDest->dwStrOffset); + cchDest = MultiByteToWideChar(uCodePage, MB_PRECOMPOSED, pchSrc, pSrc->dwStrLen, + pchDest, cchDest); + pchDest[cchDest] = 0; + + return cbDest; +} + +DWORD APIENTRY +Imm32ReconvertAnsiFromWide(LPRECONVERTSTRING pDest, const RECONVERTSTRING *pSrc, UINT uCodePage) +{ + DWORD cch0, cch1, cchDest, cbDest; + LPCWSTR pchSrc = (LPCWSTR)((LPCSTR)pSrc + pSrc->dwStrOffset); + LPSTR pchDest; + + if (pSrc->dwVersion != 0) + return 0; + + cchDest = WideCharToMultiByte(uCodePage, 0, pchSrc, pSrc->dwStrLen, + NULL, 0, NULL, NULL); + cbDest = sizeof(RECONVERTSTRING) + (cchDest + 1) * sizeof(CHAR); + if (!pDest) + return cbDest; + + if (pDest->dwSize < cbDest) + return 0; + + /* dwSize */ + pDest->dwSize = cbDest; + + /* dwVersion */ + pDest->dwVersion = 0; + + /* dwStrOffset */ + pDest->dwStrOffset = sizeof(RECONVERTSTRING); + + /* dwCompStrOffset */ + cch1 = pSrc->dwCompStrOffset / sizeof(WCHAR); + cch0 = IchAnsiFromWide(cch1, pchSrc, uCodePage); + pDest->dwCompStrOffset = cch0 * sizeof(CHAR); + + /* dwCompStrLen */ + cch0 = IchAnsiFromWide(cch1 + pSrc->dwCompStrLen, pchSrc, uCodePage); + pDest->dwCompStrLen = cch0 * sizeof(CHAR) - pDest->dwCompStrOffset; + + /* dwTargetStrOffset */ + cch1 = pSrc->dwTargetStrOffset / sizeof(WCHAR); + cch0 = IchAnsiFromWide(cch1, pchSrc, uCodePage); + pDest->dwTargetStrOffset = cch0 * sizeof(CHAR); + + /* dwTargetStrLen */ + cch0 = IchAnsiFromWide(cch1 + pSrc->dwTargetStrLen, pchSrc, uCodePage); + pDest->dwTargetStrLen = cch0 * sizeof(CHAR) - pDest->dwTargetStrOffset; + + /* dwStrLen */ + pDest->dwStrLen = cchDest; + + /* the string */ + pchDest = (LPSTR)pDest + pDest->dwStrOffset; + cchDest = WideCharToMultiByte(uCodePage, 0, pchSrc, pSrc->dwStrLen, + pchDest, cchDest, NULL, NULL); + pchDest[cchDest] = 0; + + return cbDest; +} + /*********************************************************************** * CtfImmIsTextFrameServiceDisabled(IMM32.@) */