@@ -56,11 +56,11 @@ pub const Error = Container.Error || error{
56
56
pub fn init (input : * Reader , container : Container , buffer : []u8 ) Decompress {
57
57
return .{
58
58
.reader = .{
59
- // TODO populate discard so that when an amount is discarded that
60
- // includes an entire frame, skip decoding that frame.
61
59
.vtable = &.{
62
60
.stream = stream ,
63
61
.rebase = rebase ,
62
+ .discard = discard ,
63
+ .readVec = Reader .indirectReadVec ,
64
64
},
65
65
.buffer = buffer ,
66
66
.seek = 0 ,
@@ -81,12 +81,32 @@ pub fn init(input: *Reader, container: Container, buffer: []u8) Decompress {
81
81
fn rebase (r : * Reader , capacity : usize ) Reader.RebaseError ! void {
82
82
assert (capacity <= r .buffer .len - flate .history_len );
83
83
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 ];
87
86
@memmove (r .buffer [0.. keep .len ], keep );
88
87
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 ;
90
110
}
91
111
92
112
fn decodeLength (self : * Decompress , code : u8 ) ! u16 {
@@ -268,8 +288,8 @@ fn readInner(d: *Decompress, w: *Writer, limit: std.Io.Limit) (Error || Reader.S
268
288
},
269
289
.stored_block = > | remaining_len | {
270
290
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 );
273
293
if (remaining_len - n == 0 ) {
274
294
d .state = if (d .final_block ) .protocol_footer else .block_header ;
275
295
} else {
0 commit comments