[NOTEPAD] Make loading file faster (#8938)

Performance improvement. This PR
will improve the speed of loading
a large file.
JIRA issue: CORE-19898
- Change 2 passes to 1 pass on
  ANSI/UTF-8, omitting precise
  buffer size calculation.
- Change LocalReAlloc calls to
  LocalAlloc.
- ReadText function now returns
  HLOCAL and no longer takes
  phLocal.
This commit is contained in:
Katayama Hirofumi MZ
2026-05-09 20:24:51 +09:00
committed by GitHub
parent 71314c23a5
commit a2e1e1d963
3 changed files with 92 additions and 49 deletions
+6 -4
View File
@@ -342,7 +342,7 @@ VOID DoOpenFile(LPCTSTR szFileName)
{
HANDLE hFile;
TCHAR log[5];
HLOCAL hLocal;
HLOCAL hOldLocal, hNewLocal;
/* Close any files and prompt to save changes */
if (!DoCloseFile())
@@ -360,13 +360,15 @@ VOID DoOpenFile(LPCTSTR szFileName)
}
/* To make loading file quicker, we use the internal handle of EDIT control */
hLocal = (HLOCAL)SendMessageW(Globals.hEdit, EM_GETHANDLE, 0, 0);
if (!ReadText(hFile, &hLocal, &Globals.encFile, &Globals.iEoln))
hOldLocal = (HLOCAL)SendMessageW(Globals.hEdit, EM_GETHANDLE, 0, 0);
hNewLocal = ReadText(hFile, &Globals.encFile, &Globals.iEoln);
if (!hNewLocal)
{
ShowLastError();
goto done;
}
SendMessageW(Globals.hEdit, EM_SETHANDLE, (WPARAM)hLocal, 0);
SendMessageW(Globals.hEdit, EM_SETHANDLE, (WPARAM)hNewLocal, 0);
LocalFree(hOldLocal);
/* No need of EM_SETMODIFY and EM_EMPTYUNDOBUFFER here. EM_SETHANDLE does instead. */
SetFocus(Globals.hEdit);
+1 -1
View File
@@ -89,7 +89,7 @@ typedef struct
extern NOTEPAD_GLOBALS Globals;
BOOL ReadText(HANDLE hFile, HLOCAL *phLocal, ENCODING *pencFile, EOLN *piEoln);
HLOCAL ReadText(HANDLE hFile, ENCODING *pencFile, EOLN *piEoln);
BOOL WriteText(HANDLE hFile, LPCWSTR pszText, DWORD dwTextLen, ENCODING encFile, EOLN iEoln);
void NOTEPAD_LoadSettingsFromRegistry(PWINDOWPLACEMENT pWP);
+85 -44
View File
@@ -82,10 +82,11 @@ ReplaceNewLines(LPWSTR pszNew, SIZE_T cchNew, LPCWSTR pszOld, SIZE_T cchOld)
static BOOL
ProcessNewLinesAndNulls(HLOCAL *phLocal, LPWSTR *ppszText, SIZE_T *pcchText, EOLN *piEoln)
{
SIZE_T ich, cchText = *pcchText, adwEolnCount[3] = { 0, 0, 0 }, cNonCRLFs;
LPWSTR pszText = *ppszText;
SIZE_T ich, cchText = *pcchText, adwEolnCount[3] = { 0, 0, 0 }, cNonCRLFs, cchNew;
LPWSTR pszText = *ppszText, pszNew;
EOLN iEoln;
BOOL bPrevCR = FALSE;
HLOCAL hLocal;
/* Replace '\0' with SPACE. Count newlines. */
for (ich = 0; ich < cchText; ++ich)
@@ -126,12 +127,19 @@ ProcessNewLinesAndNulls(HLOCAL *phLocal, LPWSTR *ppszText, SIZE_T *pcchText, EOL
if (cNonCRLFs != 0)
{
/* Allocate a buffer for EM_SETHANDLE */
SIZE_T cchNew = cchText + cNonCRLFs;
HLOCAL hLocal = LocalAlloc(LMEM_MOVEABLE, (cchNew + 1) * sizeof(WCHAR));
LPWSTR pszNew = LocalLock(hLocal);
cchNew = cchText + cNonCRLFs;
hLocal = LocalAlloc(LMEM_MOVEABLE, (cchNew + 1) * sizeof(WCHAR));
if (!hLocal)
{
SetLastError(ERROR_NOT_ENOUGH_MEMORY);
return FALSE; /* Failure */
}
pszNew = LocalLock(hLocal);
if (!pszNew)
{
LocalFree(hLocal);
SetLastError(ERROR_NOT_ENOUGH_MEMORY);
return FALSE; /* Failure */
}
@@ -149,8 +157,8 @@ ProcessNewLinesAndNulls(HLOCAL *phLocal, LPWSTR *ppszText, SIZE_T *pcchText, EOL
return TRUE;
}
BOOL
ReadText(HANDLE hFile, HLOCAL *phLocal, ENCODING *pencFile, EOLN *piEoln)
HLOCAL
ReadText(HANDLE hFile, ENCODING *pencFile, EOLN *piEoln)
{
LPBYTE pBytes = NULL;
LPWSTR pszText, pszNewText = NULL;
@@ -160,7 +168,7 @@ ReadText(HANDLE hFile, HLOCAL *phLocal, ENCODING *pencFile, EOLN *piEoln)
ENCODING encFile;
UINT iCodePage;
HANDLE hMapping = INVALID_HANDLE_VALUE;
HLOCAL hNewLocal;
HLOCAL hNewLocal = NULL;
dwSize = GetFileSize(hFile, NULL);
if (dwSize == INVALID_FILE_SIZE)
@@ -168,18 +176,26 @@ ReadText(HANDLE hFile, HLOCAL *phLocal, ENCODING *pencFile, EOLN *piEoln)
if (dwSize == 0) // If file is empty
{
hNewLocal = LocalReAlloc(*phLocal, sizeof(UNICODE_NULL), LMEM_MOVEABLE);
pszNewText = LocalLock(hNewLocal);
if (hNewLocal == NULL || pszNewText == NULL)
hNewLocal = LocalAlloc(LMEM_MOVEABLE, sizeof(UNICODE_NULL));
if (!hNewLocal)
{
SetLastError(ERROR_NOT_ENOUGH_MEMORY);
goto done;
}
pszNewText = LocalLock(hNewLocal);
if (!pszNewText)
{
SetLastError(ERROR_NOT_ENOUGH_MEMORY);
goto done;
}
*pszNewText = UNICODE_NULL;
LocalUnlock(hNewLocal);
*phLocal = hNewLocal;
*piEoln = EOLN_CRLF;
*pencFile = ENCODING_DEFAULT;
return TRUE;
return hNewLocal;
}
hMapping = CreateFileMappingW(hFile, NULL, PAGE_READONLY, 0, 0, NULL);
@@ -217,15 +233,29 @@ ReadText(HANDLE hFile, HLOCAL *phLocal, ENCODING *pencFile, EOLN *piEoln)
case ENCODING_UTF16BE:
case ENCODING_UTF16LE:
{
/* Re-allocate the buffer for EM_SETHANDLE */
pszText = (LPWSTR) &pBytes[dwPos];
/* Allocate the buffer for EM_SETHANDLE */
pszText = (LPWSTR)&pBytes[dwPos];
cchText = (dwSize - dwPos) / sizeof(WCHAR);
hNewLocal = LocalReAlloc(*phLocal, (cchText + 1) * sizeof(WCHAR), LMEM_MOVEABLE);
pszNewText = LocalLock(hNewLocal);
if (pszNewText == NULL)
if (cchText >= MAXLONG / sizeof(WCHAR))
{
SetLastError(ERROR_FILE_TOO_LARGE);
goto done;
}
hNewLocal = LocalAlloc(LMEM_MOVEABLE, (cchText + 1) * sizeof(WCHAR));
if (!hNewLocal)
{
SetLastError(ERROR_NOT_ENOUGH_MEMORY);
goto done;
}
pszNewText = LocalLock(hNewLocal);
if (!pszNewText)
{
SetLastError(ERROR_NOT_ENOUGH_MEMORY);
goto done;
}
*phLocal = hNewLocal;
CopyMemory(pszNewText, pszText, cchText * sizeof(WCHAR));
if (encFile == ENCODING_UTF16BE) /* big endian; Swap bytes */
@@ -245,34 +275,40 @@ ReadText(HANDLE hFile, HLOCAL *phLocal, ENCODING *pencFile, EOLN *piEoln)
case ENCODING_UTF8:
case ENCODING_UTF8BOM:
{
iCodePage = ((encFile == ENCODING_UTF8 || encFile == ENCODING_UTF8BOM) ? CP_UTF8 : CP_ACP);
/* Get ready for ANSI-to-Wide conversion */
iCodePage = ((encFile == ENCODING_UTF8 || encFile == ENCODING_UTF8BOM)
? CP_UTF8 : CP_ACP);
cbContent = dwSize - dwPos;
if (cbContent >= MAXLONG / sizeof(WCHAR))
{
SetLastError(ERROR_FILE_TOO_LARGE);
goto done;
}
/* Allocate the buffer for EM_SETHANDLE */
hNewLocal = LocalAlloc(LMEM_MOVEABLE, (cbContent + 1) * sizeof(WCHAR));
if (!hNewLocal)
{
SetLastError(ERROR_NOT_ENOUGH_MEMORY);
goto done;
}
pszNewText = LocalLock(hNewLocal);
if (!pszNewText)
{
SetLastError(ERROR_NOT_ENOUGH_MEMORY);
goto done;
}
/* Do conversion */
cchText = 0;
if (cbContent > 0)
{
cchText = MultiByteToWideChar(iCodePage, 0, (LPCSTR)&pBytes[dwPos], (INT)cbContent, NULL, 0);
if (cchText == 0)
cchText = MultiByteToWideChar(iCodePage, 0,
(LPCSTR)&pBytes[dwPos], (INT)cbContent,
pszNewText, (INT)cbContent);
if (!cchText)
goto done;
}
/* Re-allocate the buffer for EM_SETHANDLE */
hNewLocal = LocalReAlloc(*phLocal, (cchText + 1) * sizeof(WCHAR), LMEM_MOVEABLE);
pszNewText = LocalLock(hNewLocal);
if (!pszNewText)
goto done;
*phLocal = hNewLocal;
/* Do ANSI-to-Wide conversion */
if (cbContent > 0)
{
if (!MultiByteToWideChar(iCodePage, 0, (LPCSTR)&pBytes[dwPos], (INT)cbContent,
pszNewText, (INT)cchText))
{
goto done;
}
}
break;
}
@@ -281,7 +317,7 @@ ReadText(HANDLE hFile, HLOCAL *phLocal, ENCODING *pencFile, EOLN *piEoln)
pszNewText[cchText] = UNICODE_NULL;
if (!ProcessNewLinesAndNulls(phLocal, &pszNewText, &cchText, piEoln))
if (!ProcessNewLinesAndNulls(&hNewLocal, &pszNewText, &cchText, piEoln))
goto done;
*pencFile = encFile;
@@ -293,8 +329,13 @@ done:
if (hMapping != INVALID_HANDLE_VALUE)
CloseHandle(hMapping);
if (pszNewText)
LocalUnlock(*phLocal);
return bSuccess;
LocalUnlock(hNewLocal);
if (!bSuccess && hNewLocal)
{
LocalFree(hNewLocal);
hNewLocal = NULL;
}
return hNewLocal;
}
static BOOL WriteEncodedText(HANDLE hFile, LPCWSTR pszText, DWORD dwTextLen, ENCODING encFile)