From 90714a38311ec79500c0257670985bfe5d6c9a1b Mon Sep 17 00:00:00 2001 From: Jimmi Holst Christensen Date: Fri, 19 Jan 2018 21:30:57 +0100 Subject: [PATCH 1/6] Implemented windows versions of seekTo and getPos --- std/io.zig | 30 ++++++++++++++++++++++++++++++ std/os/windows/index.zig | 8 ++++++++ 2 files changed, 38 insertions(+) diff --git a/std/io.zig b/std/io.zig index 605553b0ea..5121fd0c21 100644 --- a/std/io.zig +++ b/std/io.zig @@ -204,6 +204,15 @@ pub const File = struct { }; } }, + Os.windows => { + if (system.SetFilePointerEx(self.handle, amount, null, system.FILE_CURRENT) == 0) { + const err = system.GetLastError(); + return switch (err) { + system.ERROR.INVALID_PARAMETER => error.BadFd, + else => os.unexpectedErrorPosix(err), + }; + } + }, else => @compileError("unsupported OS"), } } @@ -224,6 +233,15 @@ pub const File = struct { }; } }, + Os.windows => { + if (system.SetFilePointerEx(self.handle, @bitCast(isize, pos), null, system.FILE_BEGIN) == 0) { + const err = system.GetLastError(); + return switch (err) { + system.ERROR.INVALID_PARAMETER => error.BadFd, + else => os.unexpectedErrorWindows(err), + }; + } + }, else => @compileError("unsupported OS: " ++ @tagName(builtin.os)), } } @@ -245,6 +263,18 @@ pub const File = struct { } return result; }, + Os.windows => { + var pos : usize = undefined; + if (system.SetFilePointerEx(self.handle, 0, @ptrCast(system.PLARGE_INTEGER, &pos), system.FILE_CURRENT) == 0) { + const err = system.GetLastError(); + return switch (err) { + system.ERROR.INVALID_PARAMETER => error.BadFd, + else => os.unexpectedErrorWindows(err), + }; + } + + return pos; + }, else => @compileError("unsupported OS"), } } diff --git a/std/os/windows/index.zig b/std/os/windows/index.zig index d460e94f64..b10d373d78 100644 --- a/std/os/windows/index.zig +++ b/std/os/windows/index.zig @@ -74,6 +74,9 @@ pub extern "kernel32" stdcallcc fn ReadFile(in_hFile: HANDLE, out_lpBuffer: LPVO in_nNumberOfBytesToRead: DWORD, out_lpNumberOfBytesRead: &DWORD, in_out_lpOverlapped: ?&OVERLAPPED) -> BOOL; +pub extern "kernel32" stdcallcc fn SetFilePointerEx(in_fFile: HANDLE, in_liDistanceToMove: LARGE_INTEGER, + out_opt_ldNewFilePointer: ?PLARGE_INTEGER, in_dwMoveMethod: DWORD) -> BOOL; + pub extern "kernel32" stdcallcc fn SetHandleInformation(hObject: HANDLE, dwMask: DWORD, dwFlags: DWORD) -> BOOL; pub extern "kernel32" stdcallcc fn Sleep(dwMilliseconds: DWORD); @@ -126,6 +129,7 @@ pub const UNICODE = false; pub const WCHAR = u16; pub const WORD = u16; pub const LARGE_INTEGER = i64; +pub const PLARGE_INTEGER = &LARGE_INTEGER; pub const TRUE = 1; pub const FALSE = 0; @@ -289,3 +293,7 @@ pub const MOVEFILE_DELAY_UNTIL_REBOOT = 4; pub const MOVEFILE_FAIL_IF_NOT_TRACKABLE = 32; pub const MOVEFILE_REPLACE_EXISTING = 1; pub const MOVEFILE_WRITE_THROUGH = 8; + +pub const FILE_BEGIN = 0; +pub const FILE_CURRENT = 1; +pub const FILE_END = 2; \ No newline at end of file From a76023bcd860ac1b11a8dc87b3771365851584b2 Mon Sep 17 00:00:00 2001 From: Jimmi Holst Christensen Date: Fri, 19 Jan 2018 21:49:16 +0100 Subject: [PATCH 2/6] Removed PLARGE_INTEGER --- std/os/windows/index.zig | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/std/os/windows/index.zig b/std/os/windows/index.zig index b10d373d78..524760d9ed 100644 --- a/std/os/windows/index.zig +++ b/std/os/windows/index.zig @@ -75,7 +75,7 @@ pub extern "kernel32" stdcallcc fn ReadFile(in_hFile: HANDLE, out_lpBuffer: LPVO in_out_lpOverlapped: ?&OVERLAPPED) -> BOOL; pub extern "kernel32" stdcallcc fn SetFilePointerEx(in_fFile: HANDLE, in_liDistanceToMove: LARGE_INTEGER, - out_opt_ldNewFilePointer: ?PLARGE_INTEGER, in_dwMoveMethod: DWORD) -> BOOL; + out_opt_ldNewFilePointer: ?&LARGE_INTEGER, in_dwMoveMethod: DWORD) -> BOOL; pub extern "kernel32" stdcallcc fn SetHandleInformation(hObject: HANDLE, dwMask: DWORD, dwFlags: DWORD) -> BOOL; @@ -129,7 +129,6 @@ pub const UNICODE = false; pub const WCHAR = u16; pub const WORD = u16; pub const LARGE_INTEGER = i64; -pub const PLARGE_INTEGER = &LARGE_INTEGER; pub const TRUE = 1; pub const FALSE = 0; From 8be606ec80b347e2c7af157854cd6fcd5d512026 Mon Sep 17 00:00:00 2001 From: Jimmi Holst Christensen Date: Fri, 19 Jan 2018 21:51:10 +0100 Subject: [PATCH 3/6] Now using the right unexpectedError in seekForward --- std/io.zig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/std/io.zig b/std/io.zig index 5121fd0c21..d9b9368475 100644 --- a/std/io.zig +++ b/std/io.zig @@ -209,7 +209,7 @@ pub const File = struct { const err = system.GetLastError(); return switch (err) { system.ERROR.INVALID_PARAMETER => error.BadFd, - else => os.unexpectedErrorPosix(err), + else => os.unexpectedErrorWindows(err), }; } }, From 61497893d312e9e9bf5dd0c3d6fe232091ce8045 Mon Sep 17 00:00:00 2001 From: Jimmi Holst Christensen Date: Fri, 19 Jan 2018 21:57:13 +0100 Subject: [PATCH 4/6] Removed bitcast from usize to isize in seekTo --- std/io.zig | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/std/io.zig b/std/io.zig index d9b9368475..4367db78b1 100644 --- a/std/io.zig +++ b/std/io.zig @@ -220,7 +220,8 @@ pub const File = struct { pub fn seekTo(self: &File, pos: usize) -> %void { switch (builtin.os) { Os.linux, Os.macosx, Os.ios => { - const result = system.lseek(self.handle, @bitCast(isize, pos), system.SEEK_SET); + const ipos = try math.cast(isize, pos); + const result = system.lseek(self.handle, ipos, system.SEEK_SET); const err = system.getErrno(result); if (err > 0) { return switch (err) { @@ -234,7 +235,8 @@ pub const File = struct { } }, Os.windows => { - if (system.SetFilePointerEx(self.handle, @bitCast(isize, pos), null, system.FILE_BEGIN) == 0) { + const ipos = try math.cast(isize, pos); + if (system.SetFilePointerEx(self.handle, ipos, null, system.FILE_BEGIN) == 0) { const err = system.GetLastError(); return switch (err) { system.ERROR.INVALID_PARAMETER => error.BadFd, From a1a69f24c846fdd8a7682216c383df53963b5b3b Mon Sep 17 00:00:00 2001 From: Jimmi Holst Christensen Date: Fri, 19 Jan 2018 22:05:56 +0100 Subject: [PATCH 5/6] We now make a more correct conversion from windows LARGE_INTEGER type to usize --- std/io.zig | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/std/io.zig b/std/io.zig index 4367db78b1..2d20e17168 100644 --- a/std/io.zig +++ b/std/io.zig @@ -48,6 +48,7 @@ error PathNotFound; error OutOfMemory; error Unseekable; error EndOfFile; +error FilePosLargerThanPointerRange; pub fn getStdErr() -> %File { const handle = if (is_windows) @@ -266,8 +267,8 @@ pub const File = struct { return result; }, Os.windows => { - var pos : usize = undefined; - if (system.SetFilePointerEx(self.handle, 0, @ptrCast(system.PLARGE_INTEGER, &pos), system.FILE_CURRENT) == 0) { + var pos : system.LARGE_INTEGER = undefined; + if (system.SetFilePointerEx(self.handle, 0, &pos, system.FILE_CURRENT) == 0) { const err = system.GetLastError(); return switch (err) { system.ERROR.INVALID_PARAMETER => error.BadFd, @@ -275,7 +276,12 @@ pub const File = struct { }; } - return pos; + assert(pos >= 0); + if (pos > @maxValue(usize)) { + return error.FilePosLargerThanPointerRange; + } + + return usize(pos); }, else => @compileError("unsupported OS"), } From d8469e3c7ce9c0627aba65075ae85b98d2b60cbc Mon Sep 17 00:00:00 2001 From: Jimmi Holst Christensen Date: Fri, 19 Jan 2018 22:08:44 +0100 Subject: [PATCH 6/6] usize might be same size as LARGE_INTEGER. If that's the case, then we don't want to compare pos to @maxValue(usize). --- std/io.zig | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/std/io.zig b/std/io.zig index 2d20e17168..cfde7c6013 100644 --- a/std/io.zig +++ b/std/io.zig @@ -277,8 +277,10 @@ pub const File = struct { } assert(pos >= 0); - if (pos > @maxValue(usize)) { - return error.FilePosLargerThanPointerRange; + if (@sizeOf(@typeOf(pos)) > @sizeOf(usize)) { + if (pos > @maxValue(usize)) { + return error.FilePosLargerThanPointerRange; + } } return usize(pos);