Merge pull request #710 from Hejsil/seekto-getpos-windows

Implemented windows versions of seekTo and getPos
This commit is contained in:
Andrew Kelley 2018-01-19 16:17:04 -05:00 committed by GitHub
commit 2eede35577
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 48 additions and 1 deletions

View File

@ -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"),
}
}

View File

@ -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;