authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2025-07-31 18:05:22-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2025-07-31 22:10:11-07:00
loga7808892f71d0209a107e8d5e15405ce30f67a1e
treefedfcb359d96bd2c82a8aa5d5111b3ac1e3391c9
parent6eac56caf715bdc2dbd63b628ca48c0e32d5a70c

std.compress.flate.Decompress: be in indirect or direct mode

depending on whether buffered

1 files changed, 30 insertions(+), 17 deletions(-)

lib/std/compress/flate/Decompress.zig+30-17
...@@ -53,15 +53,24 @@ pub const Error = Container.Error || error{...@@ -53,15 +53,24 @@ pub const Error = Container.Error || error{
53 EndOfStream,53 EndOfStream,
54};54};
5555
56const direct_vtable: Reader.VTable = .{
57 .stream = streamDirect,
58 .rebase = rebaseFallible,
59 .discard = discard,
60 .readVec = readVec,
61};
62
63const indirect_vtable: Reader.VTable = .{
64 .stream = streamIndirect,
65 .rebase = rebaseFallible,
66 .discard = discard,
67 .readVec = readVec,
68};
69
56pub fn init(input: *Reader, container: Container, buffer: []u8) Decompress {70pub fn init(input: *Reader, container: Container, buffer: []u8) Decompress {
57 return .{71 return .{
58 .reader = .{72 .reader = .{
59 .vtable = &.{73 .vtable = if (buffer.len == 0) &direct_vtable else &indirect_vtable,
60 .stream = stream,
61 .rebase = rebaseFallible,
62 .discard = discard,
63 .readVec = readVec,
64 },
65 .buffer = buffer,74 .buffer = buffer,
66 .seek = 0,75 .seek = 0,
67 .end = 0,76 .end = 0,
...@@ -79,12 +88,10 @@ pub fn init(input: *Reader, container: Container, buffer: []u8) Decompress {...@@ -79,12 +88,10 @@ pub fn init(input: *Reader, container: Container, buffer: []u8) Decompress {
79}88}
8089
81fn rebaseFallible(r: *Reader, capacity: usize) Reader.RebaseError!void {90fn rebaseFallible(r: *Reader, capacity: usize) Reader.RebaseError!void {
82 const d: *Decompress = @alignCast(@fieldParentPtr("reader", r));91 rebase(r, capacity);
83 rebase(d, capacity);
84}92}
8593
86fn rebase(d: *Decompress, capacity: usize) void {94fn rebase(r: *Reader, capacity: usize) void {
87 const r = &d.reader;
88 assert(capacity <= r.buffer.len - flate.history_len);95 assert(capacity <= r.buffer.len - flate.history_len);
89 assert(r.end + capacity > r.buffer.len);96 assert(r.end + capacity > r.buffer.len);
90 const discard_n = r.end - flate.history_len;97 const discard_n = r.end - flate.history_len;
...@@ -98,7 +105,7 @@ fn rebase(d: *Decompress, capacity: usize) void {...@@ -98,7 +105,7 @@ fn rebase(d: *Decompress, capacity: usize) void {
98/// This could be improved so that when an amount is discarded that includes an105/// This could be improved so that when an amount is discarded that includes an
99/// entire frame, skip decoding that frame.106/// entire frame, skip decoding that frame.
100fn discard(r: *Reader, limit: std.Io.Limit) Reader.Error!usize {107fn 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);
102 var writer: Writer = .{109 var writer: Writer = .{
103 .vtable = &.{110 .vtable = &.{
104 .drain = std.Io.Writer.Discarding.drain,111 .drain = std.Io.Writer.Discarding.drain,
...@@ -124,12 +131,12 @@ fn discard(r: *Reader, limit: std.Io.Limit) Reader.Error!usize {...@@ -124,12 +131,12 @@ fn discard(r: *Reader, limit: std.Io.Limit) Reader.Error!usize {
124fn readVec(r: *Reader, data: [][]u8) Reader.Error!usize {131fn readVec(r: *Reader, data: [][]u8) Reader.Error!usize {
125 _ = data;132 _ = data;
126 const d: *Decompress = @alignCast(@fieldParentPtr("reader", r));133 const d: *Decompress = @alignCast(@fieldParentPtr("reader", r));
127 return streamIndirect(d);134 return streamIndirectInner(d);
128}135}
129136
130fn streamIndirect(d: *Decompress) Reader.Error!usize {137fn streamIndirectInner(d: *Decompress) Reader.Error!usize {
131 const r = &d.reader;138 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);
133 var writer: Writer = .{140 var writer: Writer = .{
134 .buffer = r.buffer,141 .buffer = r.buffer,
135 .end = r.end,142 .end = r.end,
...@@ -200,10 +207,16 @@ fn decodeSymbol(self: *Decompress, decoder: anytype) !Symbol {...@@ -200,10 +207,16 @@ fn decodeSymbol(self: *Decompress, decoder: anytype) !Symbol {
200 return sym;207 return sym;
201}208}
202209
203pub fn stream(r: *Reader, w: *Writer, limit: std.Io.Limit) Reader.StreamError!usize {210fn 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
215fn streamIndirect(r: *Reader, w: *Writer, limit: std.Io.Limit) Reader.StreamError!usize {
204 const d: *Decompress = @alignCast(@fieldParentPtr("reader", r));216 const d: *Decompress = @alignCast(@fieldParentPtr("reader", r));
205 if (w.end >= r.end) return streamFallible(d, w, limit);217 _ = limit;
206 return streamIndirect(d);218 _ = w;
219 return streamIndirectInner(d);
207}220}
208221
209fn streamFallible(d: *Decompress, w: *Writer, limit: std.Io.Limit) Reader.StreamError!usize {222fn streamFallible(d: *Decompress, w: *Writer, limit: std.Io.Limit) Reader.StreamError!usize {