[3/4] cmd: Avoid reading char by char from files (try 5)
Frédéric Delanoy
frederic.delanoy at gmail.com
Wed Oct 5 07:02:45 CDT 2011
---
programs/cmd/batch.c | 42 ++++++++++++++++++++++++++----------------
1 files changed, 26 insertions(+), 16 deletions(-)
diff --git a/programs/cmd/batch.c b/programs/cmd/batch.c
index 77a49c9..3db94c7 100644
--- a/programs/cmd/batch.c
+++ b/programs/cmd/batch.c
@@ -188,14 +188,12 @@ WCHAR *WCMD_parameter (WCHAR *s, int n, WCHAR **where, WCHAR **end) {
WCHAR *WCMD_fgets(WCHAR *buf, int noChars, HANDLE h, const BOOL is_console_handle)
{
- DWORD bytes, charsRead;
+ DWORD charsRead;
BOOL status;
- WCHAR *p;
/* 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 (is_console_handle) {
status = ReadConsoleW(h, buf, noChars, &charsRead, NULL);
if (!status) return NULL;
@@ -205,21 +203,33 @@ WCHAR *WCMD_fgets(WCHAR *buf, int noChars, HANDLE h, const BOOL is_console_handl
/* Truncate */
buf[noChars-1] = '\0';
}
- return p;
- }
+ } else {
+ LARGE_INTEGER filepos;
+ int i;
+
+ /* Save current file position */
+ filepos.QuadPart = 0;
+ SetFilePointerEx(h, filepos, &filepos, FILE_CURRENT);
+
+ status = WCMD_ReadFile(h, buf, noChars, &charsRead);
+ if (!status || charsRead == 0) return NULL;
+ for (i = 0; i < charsRead; i++) {
+ if (buf[i] == '\n' || buf[i] == '\r')
+ break;
+ }
- /* 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--;
+ if (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);
+ } else {
+ /* File pointer positioned correctly already; truncate at the correct place */
+ i--;
}
- *buf = '\0';
- } while ((bytes == 1) && (noChars > 1));
- return p;
+ buf[i] = '\0';
+ }
+
+ return buf;
}
/* WCMD_splitpath - copied from winefile as no obvious way to use it otherwise */
--
1.7.7
More information about the wine-patches
mailing list