authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2025-07-30 00:28:11-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2025-07-31 22:10:11-07:00
log4c04835a08097d18a30ba74ef9a3aa59f3b90fd3
treec5127f5b4f02490fad9501dd0bd377b0429f80b3
parent84e4343b0c26a11cc667f8df3f9863b65bf1fa36

std.compress.zstd.Decompress: implement discard and readVec


2 files changed, 32 insertions(+), 22 deletions(-)

lib/std/Io/Reader.zig-17
...@@ -438,23 +438,6 @@ pub fn defaultReadVec(r: *Reader, data: []const []u8) Error!usize {...@@ -438,23 +438,6 @@ pub fn defaultReadVec(r: *Reader, data: []const []u8) Error!usize {
438 return 0;438 return 0;
439}439}
440440
441/// Always writes to `Reader.buffer` and returns 0.
442pub fn indirectReadVec(r: *Reader, data: []const []u8) Error!usize {
443 _ = data;
444 assert(r.seek == r.end);
445 var writer: Writer = .{
446 .buffer = r.buffer,
447 .end = r.end,
448 .vtable = &.{ .drain = Writer.fixedDrain },
449 };
450 const limit: Limit = .limited(writer.buffer.len - writer.end);
451 r.end += r.vtable.stream(r, &writer, limit) catch |err| switch (err) {
452 error.WriteFailed => unreachable,
453 else => |e| return e,
454 };
455 return 0;
456}
457
458pub fn buffered(r: *Reader) []u8 {441pub fn buffered(r: *Reader) []u8 {
459 return r.buffer[r.seek..r.end];442 return r.buffer[r.seek..r.end];
460}443}
lib/std/compress/zstd/Decompress.zig+32-5
...@@ -89,7 +89,7 @@ pub fn init(input: *Reader, buffer: []u8, options: Options) Decompress {...@@ -89,7 +89,7 @@ pub fn init(input: *Reader, buffer: []u8, options: Options) Decompress {
89 .stream = stream,89 .stream = stream,
90 .rebase = rebase,90 .rebase = rebase,
91 .discard = discard,91 .discard = discard,
92 .readVec = Reader.indirectReadVec,92 .readVec = readVec,
93 },93 },
94 .buffer = buffer,94 .buffer = buffer,
95 .seek = 0,95 .seek = 0,
...@@ -109,10 +109,20 @@ fn rebase(r: *Reader, capacity: usize) Reader.RebaseError!void {...@@ -109,10 +109,20 @@ fn rebase(r: *Reader, capacity: usize) Reader.RebaseError!void {
109 r.seek -= discard_n;109 r.seek -= discard_n;
110}110}
111111
112fn discard(r: *Reader, limit: Limit) Reader.Error!usize {112/// This could be improved so that when an amount is discarded that includes an
113 r.rebase(zstd.block_size_max) catch unreachable;113/// entire frame, skip decoding that frame.
114 var d: Writer.Discarding = .init(r.buffer);114fn discard(r: *Reader, limit: std.Io.Limit) Reader.Error!usize {
115 const n = r.stream(&d.writer, limit) catch |err| switch (err) {115 const d: *Decompress = @alignCast(@fieldParentPtr("reader", r));
116 r.rebase(d.window_len) catch unreachable;
117 var writer: Writer = .{
118 .vtable = &.{
119 .drain = std.Io.Writer.Discarding.drain,
120 .sendFile = std.Io.Writer.Discarding.sendFile,
121 },
122 .buffer = r.buffer,
123 .end = r.end,
124 };
125 const n = r.stream(&writer, limit) catch |err| switch (err) {
116 error.WriteFailed => unreachable,126 error.WriteFailed => unreachable,
117 error.ReadFailed => return error.ReadFailed,127 error.ReadFailed => return error.ReadFailed,
118 error.EndOfStream => return error.EndOfStream,128 error.EndOfStream => return error.EndOfStream,
...@@ -121,6 +131,23 @@ fn discard(r: *Reader, limit: Limit) Reader.Error!usize {...@@ -121,6 +131,23 @@ fn discard(r: *Reader, limit: Limit) Reader.Error!usize {
121 return n;131 return n;
122}132}
123133
134fn readVec(r: *Reader, data: []const []u8) Reader.Error!usize {
135 _ = data;
136 const d: *Decompress = @alignCast(@fieldParentPtr("reader", r));
137 assert(r.seek == r.end);
138 r.rebase(d.window_len) catch unreachable;
139 var writer: Writer = .{
140 .buffer = r.buffer,
141 .end = r.end,
142 .vtable = &.{ .drain = Writer.fixedDrain },
143 };
144 r.end += r.vtable.stream(r, &writer, .limited(writer.buffer.len - writer.end)) catch |err| switch (err) {
145 error.WriteFailed => unreachable,
146 else => |e| return e,
147 };
148 return 0;
149}
150
124fn stream(r: *Reader, w: *Writer, limit: Limit) Reader.StreamError!usize {151fn stream(r: *Reader, w: *Writer, limit: Limit) Reader.StreamError!usize {
125 const d: *Decompress = @alignCast(@fieldParentPtr("reader", r));152 const d: *Decompress = @alignCast(@fieldParentPtr("reader", r));
126 const in = d.input;153 const in = d.input;