mirror of
https://github.com/ApfelTeeSaft/reactos.git
synced 2026-08-26 19:33:31 +00:00
[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:
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user