| ... | ... | @@ -76,7 +76,7 @@ pub fn flush(bw: *BufferedWriter) anyerror!void { |
| 76 | 76 | |
| 77 | 77 | /// The `data` parameter is mutable because this function needs to mutate the |
| 78 | 78 | /// fields in order to handle partial writes from `Writer.VTable.writev`. |
| 79 | | pub fn writevAll(bw: *BufferedWriter, data: []const []const u8) anyerror!void { |
| 79 | pub fn writevAll(bw: *BufferedWriter, data: [][]const u8) anyerror!void { |
| 80 | 80 | var i: usize = 0; |
| 81 | 81 | while (true) { |
| 82 | 82 | var n = try passthru_writeSplat(bw, data[i..], 1); |
| ... | ... | @@ -164,7 +164,7 @@ fn passthru_writeSplat(context: *anyopaque, data: []const []const u8, splat: usi |
| 164 | 164 | @branchHint(.likely); |
| 165 | 165 | @memset(buffer[end..new_end], pattern[0]); |
| 166 | 166 | bw.end = new_end; |
| 167 | | return end - start_end; |
| 167 | return new_end - start_end; |
| 168 | 168 | } |
| 169 | 169 | buffers[0] = buffer[0..end]; |
| 170 | 170 | buffers[1] = pattern; |
| ... | ... | @@ -186,8 +186,8 @@ fn passthru_writeSplat(context: *anyopaque, data: []const []const u8, splat: usi |
| 186 | 186 | while (end < new_end) : (end += pattern.len) { |
| 187 | 187 | @memcpy(buffer[end..][0..pattern.len], pattern); |
| 188 | 188 | } |
| 189 | | bw.end = end; |
| 190 | | return end - start_end; |
| 189 | bw.end = new_end; |
| 190 | return new_end - start_end; |
| 191 | 191 | } |
| 192 | 192 | buffers[0] = buffer[0..end]; |
| 193 | 193 | buffers[1] = pattern; |
| ... | ... | @@ -471,32 +471,55 @@ pub const WriteFileOptions = struct { |
| 471 | 471 | pub fn writeFileAll(bw: *BufferedWriter, file: std.fs.File, options: WriteFileOptions) anyerror!void { |
| 472 | 472 | const headers_and_trailers = options.headers_and_trailers; |
| 473 | 473 | const headers = headers_and_trailers[0..options.headers_len]; |
| 474 | | var len = options.len; |
| 475 | | var i: usize = 0; |
| 476 | | var offset = options.offset; |
| 477 | | if (len == .zero) return writevAll(bw, headers_and_trailers[i..]); |
| 478 | | while (i < headers_and_trailers.len) { |
| 479 | | var n = try writeFile(bw, file, offset, len, headers_and_trailers[i..], headers.len - i); |
| 480 | | while (i < headers.len and n >= headers[i].len) { |
| 481 | | n -= headers[i].len; |
| 482 | | i += 1; |
| 483 | | } |
| 484 | | if (i < headers.len) { |
| 485 | | headers[i] = headers[i][n..]; |
| 486 | | continue; |
| 474 | if (options.len == .zero) return writevAll(bw, headers_and_trailers); |
| 475 | if (options.len == .entire_file) { |
| 476 | // When reading the whole file, we cannot include the trailers in the |
| 477 | // call that reads from the file handle, because we have no way to |
| 478 | // determine whether a partial write is past the end of the file or |
| 479 | // not. |
| 480 | var i: usize = 0; |
| 481 | var offset = options.offset; |
| 482 | while (true) { |
| 483 | var n = try writeFile(bw, file, offset, .entire_file, headers[i..], headers.len - i); |
| 484 | while (i < headers.len and n >= headers[i].len) { |
| 485 | n -= headers[i].len; |
| 486 | i += 1; |
| 487 | } |
| 488 | if (i < headers.len) { |
| 489 | headers[i] = headers[i][n..]; |
| 490 | continue; |
| 491 | } |
| 492 | if (n == 0) break; |
| 493 | offset += n; |
| 487 | 494 | } |
| 488 | | if (n >= len.int()) { |
| 489 | | n -= len.int(); |
| 490 | | while (n >= headers_and_trailers[i].len) { |
| 491 | | n -= headers_and_trailers[i].len; |
| 495 | } else { |
| 496 | var len = options.len.int(); |
| 497 | var i: usize = 0; |
| 498 | var offset = options.offset; |
| 499 | while (true) { |
| 500 | var n = try writeFile(bw, file, offset, .init(len), headers_and_trailers[i..], headers.len - i); |
| 501 | while (i < headers.len and n >= headers[i].len) { |
| 502 | n -= headers[i].len; |
| 492 | 503 | i += 1; |
| 504 | } |
| 505 | if (i < headers.len) { |
| 506 | headers[i] = headers[i][n..]; |
| 507 | continue; |
| 508 | } |
| 509 | if (n >= len) { |
| 510 | n -= len; |
| 493 | 511 | if (i >= headers_and_trailers.len) return; |
| 512 | while (n >= headers_and_trailers[i].len) { |
| 513 | n -= headers_and_trailers[i].len; |
| 514 | i += 1; |
| 515 | if (i >= headers_and_trailers.len) return; |
| 516 | } |
| 517 | headers_and_trailers[i] = headers_and_trailers[i][n..]; |
| 518 | return writevAll(bw, headers_and_trailers[i..]); |
| 494 | 519 | } |
| 495 | | headers_and_trailers[i] = headers_and_trailers[i][n..]; |
| 496 | | return writevAll(bw, headers_and_trailers[i..]); |
| 520 | offset += n; |
| 521 | len -= n; |
| 497 | 522 | } |
| 498 | | offset += n; |
| 499 | | len = if (len == .entire_file) .entire_file else .init(len.int() - n); |
| 500 | 523 | } |
| 501 | 524 | } |
| 502 | 525 | |