diff --git a/lib/std/Io/Reader.zig b/lib/std/Io/Reader.zig index 8dddc49ad2..1cd6a3ebe3 100644 --- a/lib/std/Io/Reader.zig +++ b/lib/std/Io/Reader.zig @@ -438,23 +438,6 @@ pub fn defaultReadVec(r: *Reader, data: []const []u8) Error!usize { return 0; } -/// Always writes to `Reader.buffer` and returns 0. -pub fn indirectReadVec(r: *Reader, data: []const []u8) Error!usize { - _ = data; - assert(r.seek == r.end); - var writer: Writer = .{ - .buffer = r.buffer, - .end = r.end, - .vtable = &.{ .drain = Writer.fixedDrain }, - }; - const limit: Limit = .limited(writer.buffer.len - writer.end); - r.end += r.vtable.stream(r, &writer, limit) catch |err| switch (err) { - error.WriteFailed => unreachable, - else => |e| return e, - }; - return 0; -} - pub fn buffered(r: *Reader) []u8 { return r.buffer[r.seek..r.end]; } diff --git a/lib/std/compress/zstd/Decompress.zig b/lib/std/compress/zstd/Decompress.zig index db85474e00..fefdf11931 100644 --- a/lib/std/compress/zstd/Decompress.zig +++ b/lib/std/compress/zstd/Decompress.zig @@ -89,7 +89,7 @@ pub fn init(input: *Reader, buffer: []u8, options: Options) Decompress { .stream = stream, .rebase = rebase, .discard = discard, - .readVec = Reader.indirectReadVec, + .readVec = readVec, }, .buffer = buffer, .seek = 0, @@ -109,10 +109,20 @@ fn rebase(r: *Reader, capacity: usize) Reader.RebaseError!void { r.seek -= discard_n; } -fn discard(r: *Reader, limit: Limit) Reader.Error!usize { - r.rebase(zstd.block_size_max) catch unreachable; - var d: Writer.Discarding = .init(r.buffer); - const n = r.stream(&d.writer, limit) catch |err| switch (err) { +/// This could be improved so that when an amount is discarded that includes an +/// entire frame, skip decoding that frame. +fn discard(r: *Reader, limit: std.Io.Limit) Reader.Error!usize { + const d: *Decompress = @alignCast(@fieldParentPtr("reader", r)); + r.rebase(d.window_len) catch unreachable; + var writer: Writer = .{ + .vtable = &.{ + .drain = std.Io.Writer.Discarding.drain, + .sendFile = std.Io.Writer.Discarding.sendFile, + }, + .buffer = r.buffer, + .end = r.end, + }; + const n = r.stream(&writer, limit) catch |err| switch (err) { error.WriteFailed => unreachable, error.ReadFailed => return error.ReadFailed, error.EndOfStream => return error.EndOfStream, @@ -121,6 +131,23 @@ fn discard(r: *Reader, limit: Limit) Reader.Error!usize { return n; } +fn readVec(r: *Reader, data: []const []u8) Reader.Error!usize { + _ = data; + const d: *Decompress = @alignCast(@fieldParentPtr("reader", r)); + assert(r.seek == r.end); + r.rebase(d.window_len) catch unreachable; + var writer: Writer = .{ + .buffer = r.buffer, + .end = r.end, + .vtable = &.{ .drain = Writer.fixedDrain }, + }; + r.end += r.vtable.stream(r, &writer, .limited(writer.buffer.len - writer.end)) catch |err| switch (err) { + error.WriteFailed => unreachable, + else => |e| return e, + }; + return 0; +} + fn stream(r: *Reader, w: *Writer, limit: Limit) Reader.StreamError!usize { const d: *Decompress = @alignCast(@fieldParentPtr("reader", r)); const in = d.input;