authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2025-07-15 11:43:55-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2025-07-15 11:43:55-07:00
log6d39c295646ac779e2a2beff43a5dd8bf42eb1db
tree0f53289108ceb880b089636f3db94e4552881deb
parentc7f332a260c9d9bbed0a05a0760bb9d4c4e56c52

std.Io.Writer.Allocating: fix sendFile EndOfStream


1 files changed, 24 insertions(+), 5 deletions(-)

lib/std/Io/Writer.zig+24-5
...@@ -2491,18 +2491,17 @@ pub const Allocating = struct {...@@ -2491,18 +2491,17 @@ pub const Allocating = struct {
24912491
2492 fn sendFile(w: *Writer, file_reader: *File.Reader, limit: std.io.Limit) FileError!usize {2492 fn sendFile(w: *Writer, file_reader: *File.Reader, limit: std.io.Limit) FileError!usize {
2493 if (File.Handle == void) return error.Unimplemented;2493 if (File.Handle == void) return error.Unimplemented;
2494 if (limit == .nothing) return 0;
2494 const a: *Allocating = @fieldParentPtr("writer", w);2495 const a: *Allocating = @fieldParentPtr("writer", w);
2495 const gpa = a.allocator;2496 const gpa = a.allocator;
2496 var list = a.toArrayList();2497 var list = a.toArrayList();
2497 defer setArrayList(a, list);2498 defer setArrayList(a, list);
2498 const pos = file_reader.pos;2499 const pos = file_reader.pos;
2499 const additional = if (file_reader.getSize()) |size| size - pos else |_| std.atomic.cache_line;2500 const additional = if (file_reader.getSize()) |size| size - pos else |_| std.atomic.cache_line;
2501 if (additional == 0) return error.EndOfStream;
2500 list.ensureUnusedCapacity(gpa, limit.minInt64(additional)) catch return error.WriteFailed;2502 list.ensureUnusedCapacity(gpa, limit.minInt64(additional)) catch return error.WriteFailed;
2501 const dest = limit.slice(list.unusedCapacitySlice());2503 const dest = limit.slice(list.unusedCapacitySlice());
2502 const n = file_reader.read(dest) catch |err| switch (err) {2504 const n = try file_reader.read(dest);
2503 error.ReadFailed => return error.ReadFailed,
2504 error.EndOfStream => 0,
2505 };
2506 list.items.len += n;2505 list.items.len += n;
2507 return n;2506 return n;
2508 }2507 }
...@@ -2525,7 +2524,7 @@ pub const Allocating = struct {...@@ -2525,7 +2524,7 @@ pub const Allocating = struct {
2525 }2524 }
2526};2525};
25272526
2528test sendFile {2527test "discarding sendFile" {
2529 var tmp_dir = testing.tmpDir(.{});2528 var tmp_dir = testing.tmpDir(.{});
2530 defer tmp_dir.cleanup();2529 defer tmp_dir.cleanup();
25312530
...@@ -2544,3 +2543,23 @@ test sendFile {...@@ -2544,3 +2543,23 @@ test sendFile {
25442543
2545 _ = try file_reader.interface.streamRemaining(&discarding.writer);2544 _ = try file_reader.interface.streamRemaining(&discarding.writer);
2546}2545}
2546
2547test "allocating sendFile" {
2548 var tmp_dir = testing.tmpDir(.{});
2549 defer tmp_dir.cleanup();
2550
2551 const file = try tmp_dir.dir.createFile("input.txt", .{ .read = true });
2552 defer file.close();
2553 var r_buffer: [256]u8 = undefined;
2554 var file_writer: std.fs.File.Writer = .init(file, &r_buffer);
2555 try file_writer.interface.writeByte('h');
2556 try file_writer.interface.flush();
2557
2558 var file_reader = file_writer.moveToReader();
2559 try file_reader.seekTo(0);
2560
2561 var allocating: std.io.Writer.Allocating = .init(std.testing.allocator);
2562 defer allocating.deinit();
2563
2564 _ = try file_reader.interface.streamRemaining(&allocating.writer);
2565}