diff options
Diffstat (limited to 'std')
| -rw-r--r-- | std/io.zig | 42 | ||||
| -rw-r--r-- | std/os/windows/index.zig | 7 |
2 files changed, 48 insertions, 1 deletions
diff --git a/std/io.zig b/std/io.zig index 605553b0ea..cfde7c6013 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) @@ -204,6 +205,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.unexpectedErrorWindows(err), + }; + } + }, else => @compileError("unsupported OS"), } } @@ -211,7 +221,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) { @@ -224,6 +235,16 @@ pub const File = struct { }; } }, + Os.windows => { + 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, + else => os.unexpectedErrorWindows(err), + }; + } + }, else => @compileError("unsupported OS: " ++ @tagName(builtin.os)), } } @@ -245,6 +266,25 @@ pub const File = struct { } return result; }, + Os.windows => { + 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, + else => os.unexpectedErrorWindows(err), + }; + } + + assert(pos >= 0); + if (@sizeOf(@typeOf(pos)) > @sizeOf(usize)) { + if (pos > @maxValue(usize)) { + return error.FilePosLargerThanPointerRange; + } + } + + return usize(pos); + }, else => @compileError("unsupported OS"), } } diff --git a/std/os/windows/index.zig b/std/os/windows/index.zig index d460e94f64..524760d9ed 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: ?&LARGE_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); @@ -289,3 +292,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 |
