mirror of
https://github.com/ziglang/zig.git
synced 2025-12-06 06:13:07 +00:00
Merge pull request #24464 from ziglang/fixes
std.Io fixes, docs, and tests
This commit is contained in:
commit
dbe0e0c1bc
@ -1303,6 +1303,13 @@ fn takeMultipleOf7Leb128(r: *Reader, comptime Result: type) TakeLeb128Error!Resu
|
||||
}
|
||||
|
||||
/// Left-aligns data such that `r.seek` becomes zero.
|
||||
///
|
||||
/// If `r.seek` is not already zero then `buffer` is mutated, making it illegal
|
||||
/// to call this function with a const-casted `buffer`, such as in the case of
|
||||
/// `fixed`. This issue can be avoided:
|
||||
/// * in implementations, by attempting a read before a rebase, in which
|
||||
/// case the read will return `error.EndOfStream`, preventing the rebase.
|
||||
/// * in usage, by copying into a mutable buffer before initializing `fixed`.
|
||||
pub fn rebase(r: *Reader) void {
|
||||
if (r.seek == 0) return;
|
||||
const data = r.buffer[r.seek..r.end];
|
||||
@ -1315,6 +1322,13 @@ pub fn rebase(r: *Reader) void {
|
||||
/// if necessary.
|
||||
///
|
||||
/// Asserts `capacity` is within the buffer capacity.
|
||||
///
|
||||
/// If the rebase occurs then `buffer` is mutated, making it illegal to call
|
||||
/// this function with a const-casted `buffer`, such as in the case of `fixed`.
|
||||
/// This issue can be avoided:
|
||||
/// * in implementations, by attempting a read before a rebase, in which
|
||||
/// case the read will return `error.EndOfStream`, preventing the rebase.
|
||||
/// * in usage, by copying into a mutable buffer before initializing `fixed`.
|
||||
pub fn rebaseCapacity(r: *Reader, capacity: usize) void {
|
||||
if (r.end > r.buffer.len - capacity) rebase(r);
|
||||
}
|
||||
|
||||
@ -2194,8 +2194,10 @@ pub const Discarding = struct {
|
||||
const d: *Discarding = @alignCast(@fieldParentPtr("writer", w));
|
||||
d.count += w.end;
|
||||
w.end = 0;
|
||||
if (limit == .nothing) return 0;
|
||||
if (file_reader.getSize()) |size| {
|
||||
const n = limit.minInt64(size - file_reader.pos);
|
||||
if (n == 0) return error.EndOfStream;
|
||||
file_reader.seekBy(@intCast(n)) catch return error.Unimplemented;
|
||||
w.end = 0;
|
||||
d.count += n;
|
||||
@ -2489,18 +2491,17 @@ pub const Allocating = struct {
|
||||
|
||||
fn sendFile(w: *Writer, file_reader: *File.Reader, limit: std.io.Limit) FileError!usize {
|
||||
if (File.Handle == void) return error.Unimplemented;
|
||||
if (limit == .nothing) return 0;
|
||||
const a: *Allocating = @fieldParentPtr("writer", w);
|
||||
const gpa = a.allocator;
|
||||
var list = a.toArrayList();
|
||||
defer setArrayList(a, list);
|
||||
const pos = file_reader.pos;
|
||||
const additional = if (file_reader.getSize()) |size| size - pos else |_| std.atomic.cache_line;
|
||||
if (additional == 0) return error.EndOfStream;
|
||||
list.ensureUnusedCapacity(gpa, limit.minInt64(additional)) catch return error.WriteFailed;
|
||||
const dest = limit.slice(list.unusedCapacitySlice());
|
||||
const n = file_reader.read(dest) catch |err| switch (err) {
|
||||
error.ReadFailed => return error.ReadFailed,
|
||||
error.EndOfStream => 0,
|
||||
};
|
||||
const n = try file_reader.read(dest);
|
||||
list.items.len += n;
|
||||
return n;
|
||||
}
|
||||
@ -2522,3 +2523,43 @@ pub const Allocating = struct {
|
||||
try testing.expectEqualSlices(u8, "x: 42\ny: 1234\n", a.getWritten());
|
||||
}
|
||||
};
|
||||
|
||||
test "discarding sendFile" {
|
||||
var tmp_dir = testing.tmpDir(.{});
|
||||
defer tmp_dir.cleanup();
|
||||
|
||||
const file = try tmp_dir.dir.createFile("input.txt", .{ .read = true });
|
||||
defer file.close();
|
||||
var r_buffer: [256]u8 = undefined;
|
||||
var file_writer: std.fs.File.Writer = .init(file, &r_buffer);
|
||||
try file_writer.interface.writeByte('h');
|
||||
try file_writer.interface.flush();
|
||||
|
||||
var file_reader = file_writer.moveToReader();
|
||||
try file_reader.seekTo(0);
|
||||
|
||||
var w_buffer: [256]u8 = undefined;
|
||||
var discarding: std.io.Writer.Discarding = .init(&w_buffer);
|
||||
|
||||
_ = try file_reader.interface.streamRemaining(&discarding.writer);
|
||||
}
|
||||
|
||||
test "allocating sendFile" {
|
||||
var tmp_dir = testing.tmpDir(.{});
|
||||
defer tmp_dir.cleanup();
|
||||
|
||||
const file = try tmp_dir.dir.createFile("input.txt", .{ .read = true });
|
||||
defer file.close();
|
||||
var r_buffer: [256]u8 = undefined;
|
||||
var file_writer: std.fs.File.Writer = .init(file, &r_buffer);
|
||||
try file_writer.interface.writeByte('h');
|
||||
try file_writer.interface.flush();
|
||||
|
||||
var file_reader = file_writer.moveToReader();
|
||||
try file_reader.seekTo(0);
|
||||
|
||||
var allocating: std.io.Writer.Allocating = .init(std.testing.allocator);
|
||||
defer allocating.deinit();
|
||||
|
||||
_ = try file_reader.interface.streamRemaining(&allocating.writer);
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user