std.fs.File.Reader: fix missed advance writer positions

This commit is contained in:
Andrew Kelley 2025-07-20 22:31:49 -07:00
parent f97c91ddb5
commit 9abc3232a8
3 changed files with 34 additions and 3 deletions

View File

@ -440,7 +440,8 @@ pub fn advance(w: *Writer, n: usize) void {
/// After calling `writableVector`, this function tracks how many bytes were /// After calling `writableVector`, this function tracks how many bytes were
/// written to it. /// written to it.
pub fn advanceVector(w: *Writer, n: usize) usize { pub fn advanceVector(w: *Writer, n: usize) usize {
return consume(w, n); if (w.vtable != VectorWrapper.vtable) advance(w, n);
return n;
} }
/// The `data` parameter is mutable because this function needs to mutate the /// The `data` parameter is mutable because this function needs to mutate the

View File

@ -1430,7 +1430,7 @@ pub const Reader = struct {
return error.EndOfStream; return error.EndOfStream;
} }
r.pos += n; r.pos += n;
return n; return w.advanceVector(n);
}, },
.streaming_reading => { .streaming_reading => {
if (is_windows) { if (is_windows) {
@ -1453,7 +1453,7 @@ pub const Reader = struct {
return error.EndOfStream; return error.EndOfStream;
} }
r.pos += n; r.pos += n;
return n; return w.advanceVector(n);
}, },
.failure => return error.ReadFailed, .failure => return error.ReadFailed,
} }

View File

@ -2071,3 +2071,33 @@ test "invalid UTF-8/WTF-8 paths" {
} }
}.impl); }.impl);
} }
test "read file non vectored" {
var tmp_dir = std.testing.tmpDir(.{});
defer tmp_dir.cleanup();
const contents = "hello, world!\n";
const file = try tmp_dir.dir.createFile("input.txt", .{ .read = true });
defer file.close();
{
var file_writer: std.fs.File.Writer = .init(file, &.{});
try file_writer.interface.writeAll(contents);
try file_writer.interface.flush();
}
var file_reader: std.fs.File.Reader = .init(file, &.{});
var write_buffer: [100]u8 = undefined;
var w: std.Io.Writer = .fixed(&write_buffer);
var i: usize = 0;
while (true) {
i += file_reader.interface.stream(&w, .limited(3)) catch |err| switch (err) {
error.EndOfStream => break,
else => |e| return e,
};
}
try std.testing.expectEqualStrings(contents, w.buffered());
try std.testing.expectEqual(contents.len, i);
}