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 {
438438 return 0;
439439}
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
458441pub fn buffered(r: *Reader) []u8 {
459442 return r.buffer[r.seek..r.end];
460443}
lib/std/compress/zstd/Decompress.zig+32-5
......@@ -89,7 +89,7 @@ pub fn init(input: *Reader, buffer: []u8, options: Options) Decompress {
8989 .stream = stream,
9090 .rebase = rebase,
9191 .discard = discard,
92 .readVec = Reader.indirectReadVec,
92 .readVec = readVec,
9393 },
9494 .buffer = buffer,
9595 .seek = 0,
......@@ -109,10 +109,20 @@ fn rebase(r: *Reader, capacity: usize) Reader.RebaseError!void {
109109 r.seek -= discard_n;
110110}
111111
112fn discard(r: *Reader, limit: Limit) Reader.Error!usize {
113 r.rebase(zstd.block_size_max) catch unreachable;
114 var d: Writer.Discarding = .init(r.buffer);
115 const n = r.stream(&d.writer, limit) catch |err| switch (err) {
112/// This could be improved so that when an amount is discarded that includes an
113/// entire frame, skip decoding that frame.
114fn discard(r: *Reader, limit: std.Io.Limit) Reader.Error!usize {
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) {
116126 error.WriteFailed => unreachable,
117127 error.ReadFailed => return error.ReadFailed,
118128 error.EndOfStream => return error.EndOfStream,
......@@ -121,6 +131,23 @@ fn discard(r: *Reader, limit: Limit) Reader.Error!usize {
121131 return n;
122132}
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
124151fn stream(r: *Reader, w: *Writer, limit: Limit) Reader.StreamError!usize {
125152 const d: *Decompress = @alignCast(@fieldParentPtr("reader", r));
126153 const in = d.input;