Skip to content

Commit a2e1e1d

Browse files
authored
[NOTEPAD] Make loading file faster (reactos#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.
1 parent 71314c2 commit a2e1e1d

3 files changed

Lines changed: 84 additions & 41 deletions

File tree

base/applications/notepad/dialog.c

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -342,7 +342,7 @@ VOID DoOpenFile(LPCTSTR szFileName)
342342
{
343343
HANDLE hFile;
344344
TCHAR log[5];
345-
HLOCAL hLocal;
345+
HLOCAL hOldLocal, hNewLocal;
346346

347347
/* Close any files and prompt to save changes */
348348
if (!DoCloseFile())
@@ -360,13 +360,15 @@ VOID DoOpenFile(LPCTSTR szFileName)
360360
}
361361

362362
/* To make loading file quicker, we use the internal handle of EDIT control */
363-
hLocal = (HLOCAL)SendMessageW(Globals.hEdit, EM_GETHANDLE, 0, 0);
364-
if (!ReadText(hFile, &hLocal, &Globals.encFile, &Globals.iEoln))
363+
hOldLocal = (HLOCAL)SendMessageW(Globals.hEdit, EM_GETHANDLE, 0, 0);
364+
hNewLocal = ReadText(hFile, &Globals.encFile, &Globals.iEoln);
365+
if (!hNewLocal)
365366
{
366367
ShowLastError();
367368
goto done;
368369
}
369-
SendMessageW(Globals.hEdit, EM_SETHANDLE, (WPARAM)hLocal, 0);
370+
SendMessageW(Globals.hEdit, EM_SETHANDLE, (WPARAM)hNewLocal, 0);
371+
LocalFree(hOldLocal);
370372
/* No need of EM_SETMODIFY and EM_EMPTYUNDOBUFFER here. EM_SETHANDLE does instead. */
371373

372374
SetFocus(Globals.hEdit);

base/applications/notepad/notepad.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@ typedef struct
8989

9090
extern NOTEPAD_GLOBALS Globals;
9191

92-
BOOL ReadText(HANDLE hFile, HLOCAL *phLocal, ENCODING *pencFile, EOLN *piEoln);
92+
HLOCAL ReadText(HANDLE hFile, ENCODING *pencFile, EOLN *piEoln);
9393
BOOL WriteText(HANDLE hFile, LPCWSTR pszText, DWORD dwTextLen, ENCODING encFile, EOLN iEoln);
9494

9595
void NOTEPAD_LoadSettingsFromRegistry(PWINDOWPLACEMENT pWP);

base/applications/notepad/text.c

Lines changed: 77 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -82,10 +82,11 @@ ReplaceNewLines(LPWSTR pszNew, SIZE_T cchNew, LPCWSTR pszOld, SIZE_T cchOld)
8282
static BOOL
8383
ProcessNewLinesAndNulls(HLOCAL *phLocal, LPWSTR *ppszText, SIZE_T *pcchText, EOLN *piEoln)
8484
{
85-
SIZE_T ich, cchText = *pcchText, adwEolnCount[3] = { 0, 0, 0 }, cNonCRLFs;
86-
LPWSTR pszText = *ppszText;
85+
SIZE_T ich, cchText = *pcchText, adwEolnCount[3] = { 0, 0, 0 }, cNonCRLFs, cchNew;
86+
LPWSTR pszText = *ppszText, pszNew;
8787
EOLN iEoln;
8888
BOOL bPrevCR = FALSE;
89+
HLOCAL hLocal;
8990

9091
/* Replace '\0' with SPACE. Count newlines. */
9192
for (ich = 0; ich < cchText; ++ich)
@@ -126,12 +127,19 @@ ProcessNewLinesAndNulls(HLOCAL *phLocal, LPWSTR *ppszText, SIZE_T *pcchText, EOL
126127
if (cNonCRLFs != 0)
127128
{
128129
/* Allocate a buffer for EM_SETHANDLE */
129-
SIZE_T cchNew = cchText + cNonCRLFs;
130-
HLOCAL hLocal = LocalAlloc(LMEM_MOVEABLE, (cchNew + 1) * sizeof(WCHAR));
131-
LPWSTR pszNew = LocalLock(hLocal);
130+
cchNew = cchText + cNonCRLFs;
131+
hLocal = LocalAlloc(LMEM_MOVEABLE, (cchNew + 1) * sizeof(WCHAR));
132+
if (!hLocal)
133+
{
134+
SetLastError(ERROR_NOT_ENOUGH_MEMORY);
135+
return FALSE; /* Failure */
136+
}
137+
138+
pszNew = LocalLock(hLocal);
132139
if (!pszNew)
133140
{
134141
LocalFree(hLocal);
142+
SetLastError(ERROR_NOT_ENOUGH_MEMORY);
135143
return FALSE; /* Failure */
136144
}
137145

@@ -149,8 +157,8 @@ ProcessNewLinesAndNulls(HLOCAL *phLocal, LPWSTR *ppszText, SIZE_T *pcchText, EOL
149157
return TRUE;
150158
}
151159

152-
BOOL
153-
ReadText(HANDLE hFile, HLOCAL *phLocal, ENCODING *pencFile, EOLN *piEoln)
160+
HLOCAL
161+
ReadText(HANDLE hFile, ENCODING *pencFile, EOLN *piEoln)
154162
{
155163
LPBYTE pBytes = NULL;
156164
LPWSTR pszText, pszNewText = NULL;
@@ -160,26 +168,34 @@ ReadText(HANDLE hFile, HLOCAL *phLocal, ENCODING *pencFile, EOLN *piEoln)
160168
ENCODING encFile;
161169
UINT iCodePage;
162170
HANDLE hMapping = INVALID_HANDLE_VALUE;
163-
HLOCAL hNewLocal;
171+
HLOCAL hNewLocal = NULL;
164172

165173
dwSize = GetFileSize(hFile, NULL);
166174
if (dwSize == INVALID_FILE_SIZE)
167175
goto done;
168176

169177
if (dwSize == 0) // If file is empty
170178
{
171-
hNewLocal = LocalReAlloc(*phLocal, sizeof(UNICODE_NULL), LMEM_MOVEABLE);
179+
hNewLocal = LocalAlloc(LMEM_MOVEABLE, sizeof(UNICODE_NULL));
180+
if (!hNewLocal)
181+
{
182+
SetLastError(ERROR_NOT_ENOUGH_MEMORY);
183+
goto done;
184+
}
185+
172186
pszNewText = LocalLock(hNewLocal);
173-
if (hNewLocal == NULL || pszNewText == NULL)
187+
if (!pszNewText)
188+
{
189+
SetLastError(ERROR_NOT_ENOUGH_MEMORY);
174190
goto done;
191+
}
175192

176193
*pszNewText = UNICODE_NULL;
177194
LocalUnlock(hNewLocal);
178195

179-
*phLocal = hNewLocal;
180196
*piEoln = EOLN_CRLF;
181197
*pencFile = ENCODING_DEFAULT;
182-
return TRUE;
198+
return hNewLocal;
183199
}
184200

185201
hMapping = CreateFileMappingW(hFile, NULL, PAGE_READONLY, 0, 0, NULL);
@@ -217,15 +233,29 @@ ReadText(HANDLE hFile, HLOCAL *phLocal, ENCODING *pencFile, EOLN *piEoln)
217233
case ENCODING_UTF16BE:
218234
case ENCODING_UTF16LE:
219235
{
220-
/* Re-allocate the buffer for EM_SETHANDLE */
221-
pszText = (LPWSTR) &pBytes[dwPos];
236+
/* Allocate the buffer for EM_SETHANDLE */
237+
pszText = (LPWSTR)&pBytes[dwPos];
222238
cchText = (dwSize - dwPos) / sizeof(WCHAR);
223-
hNewLocal = LocalReAlloc(*phLocal, (cchText + 1) * sizeof(WCHAR), LMEM_MOVEABLE);
239+
if (cchText >= MAXLONG / sizeof(WCHAR))
240+
{
241+
SetLastError(ERROR_FILE_TOO_LARGE);
242+
goto done;
243+
}
244+
245+
hNewLocal = LocalAlloc(LMEM_MOVEABLE, (cchText + 1) * sizeof(WCHAR));
246+
if (!hNewLocal)
247+
{
248+
SetLastError(ERROR_NOT_ENOUGH_MEMORY);
249+
goto done;
250+
}
251+
224252
pszNewText = LocalLock(hNewLocal);
225-
if (pszNewText == NULL)
253+
if (!pszNewText)
254+
{
255+
SetLastError(ERROR_NOT_ENOUGH_MEMORY);
226256
goto done;
257+
}
227258

228-
*phLocal = hNewLocal;
229259
CopyMemory(pszNewText, pszText, cchText * sizeof(WCHAR));
230260

231261
if (encFile == ENCODING_UTF16BE) /* big endian; Swap bytes */
@@ -245,33 +275,39 @@ ReadText(HANDLE hFile, HLOCAL *phLocal, ENCODING *pencFile, EOLN *piEoln)
245275
case ENCODING_UTF8:
246276
case ENCODING_UTF8BOM:
247277
{
248-
iCodePage = ((encFile == ENCODING_UTF8 || encFile == ENCODING_UTF8BOM) ? CP_UTF8 : CP_ACP);
249-
250-
/* Get ready for ANSI-to-Wide conversion */
278+
iCodePage = ((encFile == ENCODING_UTF8 || encFile == ENCODING_UTF8BOM)
279+
? CP_UTF8 : CP_ACP);
251280
cbContent = dwSize - dwPos;
252-
cchText = 0;
253-
if (cbContent > 0)
281+
if (cbContent >= MAXLONG / sizeof(WCHAR))
254282
{
255-
cchText = MultiByteToWideChar(iCodePage, 0, (LPCSTR)&pBytes[dwPos], (INT)cbContent, NULL, 0);
256-
if (cchText == 0)
257-
goto done;
283+
SetLastError(ERROR_FILE_TOO_LARGE);
284+
goto done;
285+
}
286+
287+
/* Allocate the buffer for EM_SETHANDLE */
288+
hNewLocal = LocalAlloc(LMEM_MOVEABLE, (cbContent + 1) * sizeof(WCHAR));
289+
if (!hNewLocal)
290+
{
291+
SetLastError(ERROR_NOT_ENOUGH_MEMORY);
292+
goto done;
258293
}
259294

260-
/* Re-allocate the buffer for EM_SETHANDLE */
261-
hNewLocal = LocalReAlloc(*phLocal, (cchText + 1) * sizeof(WCHAR), LMEM_MOVEABLE);
262295
pszNewText = LocalLock(hNewLocal);
263296
if (!pszNewText)
297+
{
298+
SetLastError(ERROR_NOT_ENOUGH_MEMORY);
264299
goto done;
265-
*phLocal = hNewLocal;
300+
}
266301

267-
/* Do ANSI-to-Wide conversion */
302+
/* Do conversion */
303+
cchText = 0;
268304
if (cbContent > 0)
269305
{
270-
if (!MultiByteToWideChar(iCodePage, 0, (LPCSTR)&pBytes[dwPos], (INT)cbContent,
271-
pszNewText, (INT)cchText))
272-
{
306+
cchText = MultiByteToWideChar(iCodePage, 0,
307+
(LPCSTR)&pBytes[dwPos], (INT)cbContent,
308+
pszNewText, (INT)cbContent);
309+
if (!cchText)
273310
goto done;
274-
}
275311
}
276312
break;
277313
}
@@ -281,7 +317,7 @@ ReadText(HANDLE hFile, HLOCAL *phLocal, ENCODING *pencFile, EOLN *piEoln)
281317

282318
pszNewText[cchText] = UNICODE_NULL;
283319

284-
if (!ProcessNewLinesAndNulls(phLocal, &pszNewText, &cchText, piEoln))
320+
if (!ProcessNewLinesAndNulls(&hNewLocal, &pszNewText, &cchText, piEoln))
285321
goto done;
286322

287323
*pencFile = encFile;
@@ -293,8 +329,13 @@ ReadText(HANDLE hFile, HLOCAL *phLocal, ENCODING *pencFile, EOLN *piEoln)
293329
if (hMapping != INVALID_HANDLE_VALUE)
294330
CloseHandle(hMapping);
295331
if (pszNewText)
296-
LocalUnlock(*phLocal);
297-
return bSuccess;
332+
LocalUnlock(hNewLocal);
333+
if (!bSuccess && hNewLocal)
334+
{
335+
LocalFree(hNewLocal);
336+
hNewLocal = NULL;
337+
}
338+
return hNewLocal;
298339
}
299340

300341
static BOOL WriteEncodedText(HANDLE hFile, LPCWSTR pszText, DWORD dwTextLen, ENCODING encFile)

0 commit comments

Comments
 (0)