Skip to content

Commit a780889

Browse files
committed
std.compress.flate.Decompress: be in indirect or direct mode
depending on whether buffered
1 parent 6eac56c commit a780889

File tree

1 file changed

+30
-17
lines changed

1 file changed

+30
-17
lines changed

lib/std/compress/flate/Decompress.zig

Lines changed: 30 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -53,15 +53,24 @@ pub const Error = Container.Error || error{
5353
EndOfStream,
5454
};
5555

56+
const direct_vtable: Reader.VTable = .{
57+
.stream = streamDirect,
58+
.rebase = rebaseFallible,
59+
.discard = discard,
60+
.readVec = readVec,
61+
};
62+
63+
const indirect_vtable: Reader.VTable = .{
64+
.stream = streamIndirect,
65+
.rebase = rebaseFallible,
66+
.discard = discard,
67+
.readVec = readVec,
68+
};
69+
5670
pub fn init(input: *Reader, container: Container, buffer: []u8) Decompress {
5771
return .{
5872
.reader = .{
59-
.vtable = &.{
60-
.stream = stream,
61-
.rebase = rebaseFallible,
62-
.discard = discard,
63-
.readVec = readVec,
64-
},
73+
.vtable = if (buffer.len == 0) &direct_vtable else &indirect_vtable,
6574
.buffer = buffer,
6675
.seek = 0,
6776
.end = 0,
@@ -79,12 +88,10 @@ pub fn init(input: *Reader, container: Container, buffer: []u8) Decompress {
7988
}
8089

8190
fn rebaseFallible(r: *Reader, capacity: usize) Reader.RebaseError!void {
82-
const d: *Decompress = @alignCast(@fieldParentPtr("reader", r));
83-
rebase(d, capacity);
91+
rebase(r, capacity);
8492
}
8593

86-
fn rebase(d: *Decompress, capacity: usize) void {
87-
const r = &d.reader;
94+
fn rebase(r: *Reader, capacity: usize) void {
8895
assert(capacity <= r.buffer.len - flate.history_len);
8996
assert(r.end + capacity > r.buffer.len);
9097
const discard_n = r.end - flate.history_len;
@@ -98,7 +105,7 @@ fn rebase(d: *Decompress, capacity: usize) void {
98105
/// This could be improved so that when an amount is discarded that includes an
99106
/// entire frame, skip decoding that frame.
100107
fn discard(r: *Reader, limit: std.Io.Limit) Reader.Error!usize {
101-
r.rebase(flate.history_len) catch unreachable;
108+
if (r.end + flate.history_len > r.buffer.len) rebase(r, flate.history_len);
102109
var writer: Writer = .{
103110
.vtable = &.{
104111
.drain = std.Io.Writer.Discarding.drain,
@@ -124,12 +131,12 @@ fn discard(r: *Reader, limit: std.Io.Limit) Reader.Error!usize {
124131
fn readVec(r: *Reader, data: [][]u8) Reader.Error!usize {
125132
_ = data;
126133
const d: *Decompress = @alignCast(@fieldParentPtr("reader", r));
127-
return streamIndirect(d);
134+
return streamIndirectInner(d);
128135
}
129136

130-
fn streamIndirect(d: *Decompress) Reader.Error!usize {
137+
fn streamIndirectInner(d: *Decompress) Reader.Error!usize {
131138
const r = &d.reader;
132-
if (r.end + flate.history_len > r.buffer.len) rebase(d, flate.history_len);
139+
if (r.end + flate.history_len > r.buffer.len) rebase(r, flate.history_len);
133140
var writer: Writer = .{
134141
.buffer = r.buffer,
135142
.end = r.end,
@@ -200,10 +207,16 @@ fn decodeSymbol(self: *Decompress, decoder: anytype) !Symbol {
200207
return sym;
201208
}
202209

203-
pub fn stream(r: *Reader, w: *Writer, limit: std.Io.Limit) Reader.StreamError!usize {
210+
fn streamDirect(r: *Reader, w: *Writer, limit: std.Io.Limit) Reader.StreamError!usize {
211+
const d: *Decompress = @alignCast(@fieldParentPtr("reader", r));
212+
return streamFallible(d, w, limit);
213+
}
214+
215+
fn streamIndirect(r: *Reader, w: *Writer, limit: std.Io.Limit) Reader.StreamError!usize {
204216
const d: *Decompress = @alignCast(@fieldParentPtr("reader", r));
205-
if (w.end >= r.end) return streamFallible(d, w, limit);
206-
return streamIndirect(d);
217+
_ = limit;
218+
_ = w;
219+
return streamIndirectInner(d);
207220
}
208221

209222
fn streamFallible(d: *Decompress, w: *Writer, limit: std.Io.Limit) Reader.StreamError!usize {

0 commit comments

Comments
 (0)