mirror of
https://codeberg.org/ziglang/zig.git
synced 2025-12-06 05:44:20 +00:00
File.Writer.sendFile: properly update reader pos
seekBy affects the reader's physical position, not its logical position.
This commit is contained in:
parent
d94e061ade
commit
7687b916fd
2 changed files with 48 additions and 7 deletions
|
|
@ -1803,9 +1803,15 @@ pub const Writer = struct {
|
|||
file_reader.size = file_reader.pos;
|
||||
return error.EndOfStream;
|
||||
}
|
||||
const consumed = io_w.consume(@intCast(sbytes));
|
||||
file_reader.seekTo(file_reader.pos + consumed) catch return error.ReadFailed;
|
||||
return consumed;
|
||||
const n = io_w.consume(@intCast(sbytes));
|
||||
if (n <= file_reader.interface.bufferedLen()) {
|
||||
file_reader.interface.toss(n);
|
||||
} else {
|
||||
const direct_n = n - file_reader.interface.bufferedLen();
|
||||
file_reader.interface.tossBuffered();
|
||||
file_reader.seekBy(@intCast(direct_n)) catch return error.ReadFailed;
|
||||
}
|
||||
return n;
|
||||
}
|
||||
|
||||
if (native_os.isDarwin() and w.mode == .streaming) sf: {
|
||||
|
|
@ -1864,9 +1870,15 @@ pub const Writer = struct {
|
|||
file_reader.size = file_reader.pos;
|
||||
return error.EndOfStream;
|
||||
}
|
||||
const consumed = io_w.consume(@bitCast(len));
|
||||
file_reader.seekTo(file_reader.pos + consumed) catch return error.ReadFailed;
|
||||
return consumed;
|
||||
const n = io_w.consume(@bitCast(len));
|
||||
if (n <= file_reader.interface.bufferedLen()) {
|
||||
file_reader.interface.toss(n);
|
||||
} else {
|
||||
const direct_n = n - file_reader.interface.bufferedLen();
|
||||
file_reader.interface.tossBuffered();
|
||||
file_reader.seekBy(@intCast(direct_n)) catch return error.ReadFailed;
|
||||
}
|
||||
return n;
|
||||
}
|
||||
|
||||
if (native_os == .linux and w.mode == .streaming) sf: {
|
||||
|
|
@ -1998,7 +2010,7 @@ pub const Writer = struct {
|
|||
reader_buffered: []const u8,
|
||||
) std.Io.Writer.FileError!usize {
|
||||
const n = try drain(io_w, &.{reader_buffered}, 1);
|
||||
file_reader.seekTo(file_reader.pos + n) catch return error.ReadFailed;
|
||||
file_reader.interface.toss(n);
|
||||
return n;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -2180,3 +2180,32 @@ test "seekTo flushes buffered data" {
|
|||
try file_reader.interface.readSliceAll(&buf);
|
||||
try std.testing.expectEqualStrings(contents, &buf);
|
||||
}
|
||||
|
||||
test "File.Writer sendfile with buffered contents" {
|
||||
var tmp_dir = testing.tmpDir(.{});
|
||||
defer tmp_dir.cleanup();
|
||||
|
||||
try tmp_dir.dir.writeFile(.{ .sub_path = "a", .data = "bcd" });
|
||||
const in = try tmp_dir.dir.openFile("a", .{});
|
||||
defer in.close();
|
||||
const out = try tmp_dir.dir.createFile("b", .{});
|
||||
defer out.close();
|
||||
|
||||
var in_buf: [2]u8 = undefined;
|
||||
var in_r = in.reader(&in_buf);
|
||||
_ = try in_r.getSize(); // Catch seeks past end by populating size
|
||||
try in_r.interface.fill(2);
|
||||
|
||||
var out_buf: [1]u8 = undefined;
|
||||
var out_w = out.writerStreaming(&out_buf);
|
||||
try out_w.interface.writeByte('a');
|
||||
try testing.expectEqual(3, try out_w.interface.sendFileAll(&in_r, .unlimited));
|
||||
try out_w.interface.flush();
|
||||
|
||||
var check = try tmp_dir.dir.openFile("b", .{});
|
||||
defer check.close();
|
||||
var check_buf: [4]u8 = undefined;
|
||||
var check_r = check.reader(&check_buf);
|
||||
try testing.expectEqualStrings("abcd", try check_r.interface.take(4));
|
||||
try testing.expectError(error.EndOfStream, check_r.interface.takeByte());
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue