Skip to content

Commit afe9f3a

Browse files
committed
std.compress.flate.Decompress: implement readVec and discard
1 parent 81af4f3 commit afe9f3a

File tree

1 file changed

+28
-8
lines changed

1 file changed

+28
-8
lines changed

lib/std/compress/flate/Decompress.zig

Lines changed: 28 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -56,11 +56,11 @@ pub const Error = Container.Error || error{
5656
pub fn init(input: *Reader, container: Container, buffer: []u8) Decompress {
5757
return .{
5858
.reader = .{
59-
// TODO populate discard so that when an amount is discarded that
60-
// includes an entire frame, skip decoding that frame.
6159
.vtable = &.{
6260
.stream = stream,
6361
.rebase = rebase,
62+
.discard = discard,
63+
.readVec = Reader.indirectReadVec,
6464
},
6565
.buffer = buffer,
6666
.seek = 0,
@@ -81,12 +81,32 @@ pub fn init(input: *Reader, container: Container, buffer: []u8) Decompress {
8181
fn rebase(r: *Reader, capacity: usize) Reader.RebaseError!void {
8282
assert(capacity <= r.buffer.len - flate.history_len);
8383
assert(r.end + capacity > r.buffer.len);
84-
const buffered = r.buffer[0..r.end];
85-
const discard = buffered.len - flate.history_len;
86-
const keep = buffered[discard..];
84+
const discard_n = r.end - flate.history_len;
85+
const keep = r.buffer[discard_n..r.end];
8786
@memmove(r.buffer[0..keep.len], keep);
8887
r.end = keep.len;
89-
r.seek -= discard;
88+
r.seek -= discard_n;
89+
}
90+
91+
/// This could be improved so that when an amount is discarded that includes an
92+
/// entire frame, skip decoding that frame.
93+
fn discard(r: *Reader, limit: std.Io.Limit) Reader.Error!usize {
94+
r.rebase(flate.history_len) catch unreachable;
95+
var writer: Writer = .{
96+
.vtable = &.{
97+
.drain = std.Io.Writer.Discarding.drain,
98+
.sendFile = std.Io.Writer.Discarding.sendFile,
99+
},
100+
.buffer = r.buffer,
101+
.end = r.end,
102+
};
103+
const n = r.stream(&writer, limit) catch |err| switch (err) {
104+
error.WriteFailed => unreachable,
105+
error.ReadFailed => return error.ReadFailed,
106+
error.EndOfStream => return error.EndOfStream,
107+
};
108+
assert(n <= @intFromEnum(limit));
109+
return n;
90110
}
91111

92112
fn decodeLength(self: *Decompress, code: u8) !u16 {
@@ -268,8 +288,8 @@ fn readInner(d: *Decompress, w: *Writer, limit: std.Io.Limit) (Error || Reader.S
268288
},
269289
.stored_block => |remaining_len| {
270290
const out = try w.writableSliceGreedyPreserve(flate.history_len, 1);
271-
const limited_out = limit.min(.limited(remaining_len)).slice(out);
272-
const n = try d.input.readVec(&.{limited_out});
291+
var limited_out: [1][]u8 = .{limit.min(.limited(remaining_len)).slice(out)};
292+
const n = try d.input.readVec(&limited_out);
273293
if (remaining_len - n == 0) {
274294
d.state = if (d.final_block) .protocol_footer else .block_header;
275295
} else {

0 commit comments

Comments
 (0)