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{
5353 EndOfStream,
5454};
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
5670pub 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
8190fn 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
86fn rebase(d: *Decompress, capacity: usize) void {
87 const r = &d.reader;
94fn 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.
100107fn 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 {
124131fn 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
130fn streamIndirect(d: *Decompress) Reader.Error!usize {
137fn 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
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 {
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
209222fn streamFallible(d: *Decompress, w: *Writer, limit: std.Io.Limit) Reader.StreamError!usize {