| ... | ... | @@ -2194,8 +2194,10 @@ pub const Discarding = struct { |
| 2194 | 2194 | const d: *Discarding = @alignCast(@fieldParentPtr("writer", w)); |
| 2195 | 2195 | d.count += w.end; |
| 2196 | 2196 | w.end = 0; |
| 2197 | if (limit == .nothing) return 0; |
| 2197 | 2198 | if (file_reader.getSize()) |size| { |
| 2198 | 2199 | const n = limit.minInt64(size - file_reader.pos); |
| 2200 | if (n == 0) return error.EndOfStream; |
| 2199 | 2201 | file_reader.seekBy(@intCast(n)) catch return error.Unimplemented; |
| 2200 | 2202 | w.end = 0; |
| 2201 | 2203 | d.count += n; |
| ... | ... | @@ -2489,18 +2491,17 @@ pub const Allocating = struct { |
| 2489 | 2491 | |
| 2490 | 2492 | fn sendFile(w: *Writer, file_reader: *File.Reader, limit: std.io.Limit) FileError!usize { |
| 2491 | 2493 | if (File.Handle == void) return error.Unimplemented; |
| 2494 | if (limit == .nothing) return 0; |
| 2492 | 2495 | const a: *Allocating = @fieldParentPtr("writer", w); |
| 2493 | 2496 | const gpa = a.allocator; |
| 2494 | 2497 | var list = a.toArrayList(); |
| 2495 | 2498 | defer setArrayList(a, list); |
| 2496 | 2499 | const pos = file_reader.pos; |
| 2497 | 2500 | const additional = if (file_reader.getSize()) |size| size - pos else |_| std.atomic.cache_line; |
| 2501 | if (additional == 0) return error.EndOfStream; |
| 2498 | 2502 | list.ensureUnusedCapacity(gpa, limit.minInt64(additional)) catch return error.WriteFailed; |
| 2499 | 2503 | const dest = limit.slice(list.unusedCapacitySlice()); |
| 2500 | | const n = file_reader.read(dest) catch |err| switch (err) { |
| 2501 | | error.ReadFailed => return error.ReadFailed, |
| 2502 | | error.EndOfStream => 0, |
| 2503 | | }; |
| 2504 | const n = try file_reader.read(dest); |
| 2504 | 2505 | list.items.len += n; |
| 2505 | 2506 | return n; |
| 2506 | 2507 | } |
| ... | ... | @@ -2522,3 +2523,43 @@ pub const Allocating = struct { |
| 2522 | 2523 | try testing.expectEqualSlices(u8, "x: 42\ny: 1234\n", a.getWritten()); |
| 2523 | 2524 | } |
| 2524 | 2525 | }; |
| 2526 | |
| 2527 | test "discarding sendFile" { |
| 2528 | var tmp_dir = testing.tmpDir(.{}); |
| 2529 | defer tmp_dir.cleanup(); |
| 2530 | |
| 2531 | const file = try tmp_dir.dir.createFile("input.txt", .{ .read = true }); |
| 2532 | defer file.close(); |
| 2533 | var r_buffer: [256]u8 = undefined; |
| 2534 | var file_writer: std.fs.File.Writer = .init(file, &r_buffer); |
| 2535 | try file_writer.interface.writeByte('h'); |
| 2536 | try file_writer.interface.flush(); |
| 2537 | |
| 2538 | var file_reader = file_writer.moveToReader(); |
| 2539 | try file_reader.seekTo(0); |
| 2540 | |
| 2541 | var w_buffer: [256]u8 = undefined; |
| 2542 | var discarding: std.io.Writer.Discarding = .init(&w_buffer); |
| 2543 | |
| 2544 | _ = try file_reader.interface.streamRemaining(&discarding.writer); |
| 2545 | } |
| 2546 | |
| 2547 | test "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 | } |