@@ -329,6 +329,11 @@ static int win32ReadConsole(FILE* file, char* buffer, size_t bufferSize)
329329 return -1;
330330 }
331331
332+ const size_t MAX_LINE_LENGTH = 32765;
333+ static WCHAR wideBuf[MAX_LINE_LENGTH +1];
334+
335+ WCHAR* pWide;
336+ DWORD charsRead = 0;
332337 size_t leftToRead = bufferSize;
333338
334339 while (leftToRead)
@@ -378,34 +383,42 @@ static int win32ReadConsole(FILE* file, char* buffer, size_t bufferSize)
378383 break;
379384 }
380385
381- WCHAR wideBuf[2];
382- DWORD charsRead;
386+ if (!charsRead)
387+ {
388+ if (!ReadConsoleW(handle, wideBuf, MAX_LINE_LENGTH, &charsRead, NULL))
389+ return -1;
383390
384- // Reading one code unit at a time is inefficient, but since this code
385- // is used only for the interactive console, that shouldn't matter.
386- if (!ReadConsoleW(handle, wideBuf, 1, &charsRead, 0))
387- return -1;
391+ if (!charsRead)
392+ break;
388393
389- if (!charsRead)
390- break;
394+ pWide = wideBuf;
395+ }
391396
392397 DWORD wideBufLen = 1;
398+ charsRead--;
393399
394- if (wideBuf[0] >= 0xD800 && wideBuf[0] <= 0xDBFF )
400+ if (IS_HIGH_SURROGATE(*pWide) )
395401 {
396402 // High surrogate, read one more code unit.
397- if (!ReadConsoleW(handle, wideBuf + 1, 1, &charsRead, 0))
398- return -1;
399-
400403 if (charsRead)
401- ++wideBufLen;
404+ charsRead--;
405+ else
406+ {
407+ DWORD read2;
408+ if (!ReadConsoleW(handle, pWide + 1, 1, &read2, NULL))
409+ return -1;
410+ }
411+
412+ ++wideBufLen;
402413 }
403414
404- convertedBufLen = WideCharToMultiByte(GetConsoleCP(), 0, wideBuf , wideBufLen,
415+ convertedBufLen = WideCharToMultiByte(GetConsoleCP(), 0, pWide , wideBufLen,
405416 convertedBuf, sizeof(convertedBuf), NULL, NULL);
406417
407418 if (!convertedBufLen)
408419 return -1;
420+
421+ pWide += wideBufLen;
409422 }
410423
411424 return bufferSize - leftToRead;
0 commit comments