=?UTF-8?Q?Fr=C3=A9d=C3=A9ric=20Delanoy=20?=: cmd: Avoid reading char by char from files.
Alexandre Julliard
julliard at winehq.org
Thu Oct 6 17:24:31 CDT 2011
Module: wine
Branch: master
Commit: cd30c52b35e7e8884e9b66b6d5cd9822412f9a33
URL: http://source.winehq.org/git/wine.git/?a=commit;h=cd30c52b35e7e8884e9b66b6d5cd9822412f9a33
Author: Frédéric Delanoy <frederic.delanoy at gmail.com>
Date: Thu Oct 6 18:50:32 2011 +0200
cmd: Avoid reading char by char from files.
---
programs/cmd/batch.c | 54 ++++++++++++++++++++++++++-----------------------
1 files changed, 29 insertions(+), 25 deletions(-)
diff --git a/programs/cmd/batch.c b/programs/cmd/batch.c
index 79bb009..a276d3e 100644
--- a/programs/cmd/batch.c
+++ b/programs/cmd/batch.c
@@ -188,38 +188,42 @@ WCHAR *WCMD_parameter (WCHAR *s, int n, WCHAR **where, WCHAR **end) {
WCHAR *WCMD_fgets(WCHAR *buf, int noChars, HANDLE h)
{
- DWORD bytes, charsRead;
+ DWORD charsRead;
BOOL status;
- WCHAR *p;
+ LARGE_INTEGER filepos;
+ int i;
/* We can't use the native f* functions because of the filename syntax differences
between DOS and Unix. Also need to lose the LF (or CRLF) from the line. */
- p = buf;
- if (WCMD_is_console_handle(h)) {
- status = ReadConsoleW(h, buf, noChars, &charsRead, NULL);
- if (!status) return NULL;
- if (buf[charsRead-2] == '\r')
- buf[charsRead-2] = '\0'; /* Strip \r\n */
- else {
- /* Truncate */
- buf[noChars-1] = '\0';
- }
- return p;
+ if (!WCMD_is_console_handle(h)) {
+ /* Save current file position */
+ filepos.QuadPart = 0;
+ SetFilePointerEx(h, filepos, &filepos, FILE_CURRENT);
}
- /* TODO: More intelligent buffering for reading lines from files */
- do {
- status = WCMD_ReadFile(h, buf, 1, &bytes);
- if ((status == 0) || ((bytes == 0) && (buf == p))) return NULL;
- if (*buf == '\n') bytes = 0;
- else if (*buf != '\r') {
- buf++;
- noChars--;
- }
- *buf = '\0';
- } while ((bytes == 1) && (noChars > 1));
- return p;
+ status = WCMD_ReadFile(h, buf, noChars, &charsRead);
+ if (!status || charsRead == 0) return NULL;
+
+ /* Find first EOL */
+ for (i = 0; i < charsRead; i++) {
+ if (buf[i] == '\n' || buf[i] == '\r')
+ break;
+ }
+
+ if (!WCMD_is_console_handle(h) && i != charsRead) {
+ /* Sets file pointer to the start of the next line, if any */
+ filepos.QuadPart += i + 1 + (buf[i] == '\r' ? 1 : 0);
+ SetFilePointerEx(h, filepos, NULL, FILE_BEGIN);
+ }
+
+ /* Truncate at EOL (or end of buffer) */
+ if (i == noChars)
+ i--;
+
+ buf[i] = '\0';
+
+ return buf;
}
/* WCMD_splitpath - copied from winefile as no obvious way to use it otherwise */
More information about the wine-cvs
mailing list