| ... | ... | @@ -1,11 +1,13 @@ |
| 1 | 1 | const std = @import("../../std.zig"); |
| 2 | const assert = std.debug.assert; |
| 2 | 3 | const flate = std.compress.flate; |
| 3 | | const Container = flate.Container; |
| 4 | | const Token = @import("Token.zig"); |
| 5 | 4 | const testing = std.testing; |
| 6 | | const Decompress = @This(); |
| 7 | 5 | const Writer = std.Io.Writer; |
| 8 | 6 | const Reader = std.Io.Reader; |
| 7 | const Container = flate.Container; |
| 8 | |
| 9 | const Decompress = @This(); |
| 10 | const Token = @import("Token.zig"); |
| 9 | 11 | |
| 10 | 12 | input: *Reader, |
| 11 | 13 | reader: Reader, |
| ... | ... | @@ -54,7 +56,10 @@ pub fn init(input: *Reader, container: Container, buffer: []u8) Decompress { |
| 54 | 56 | .reader = .{ |
| 55 | 57 | // TODO populate discard so that when an amount is discarded that |
| 56 | 58 | // includes an entire frame, skip decoding that frame. |
| 57 | | .vtable = &.{ .stream = stream }, |
| 59 | .vtable = &.{ |
| 60 | .stream = stream, |
| 61 | .rebase = rebase, |
| 62 | }, |
| 58 | 63 | .buffer = buffer, |
| 59 | 64 | .seek = 0, |
| 60 | 65 | .end = 0, |
| ... | ... | @@ -69,6 +74,17 @@ pub fn init(input: *Reader, container: Container, buffer: []u8) Decompress { |
| 69 | 74 | }; |
| 70 | 75 | } |
| 71 | 76 | |
| 77 | fn rebase(r: *Reader, capacity: usize) Reader.RebaseError!void { |
| 78 | assert(capacity <= r.buffer.len - flate.history_len); |
| 79 | assert(r.end + capacity > r.buffer.len); |
| 80 | const buffered = r.buffer[0..r.end]; |
| 81 | const discard = buffered.len - flate.history_len; |
| 82 | const keep = buffered[discard..]; |
| 83 | @memmove(r.buffer[0..keep.len], keep); |
| 84 | r.end = keep.len; |
| 85 | r.seek -= discard; |
| 86 | } |
| 87 | |
| 72 | 88 | fn decodeLength(self: *Decompress, code: u8) !u16 { |
| 73 | 89 | if (code > 28) return error.InvalidCode; |
| 74 | 90 | const ml = Token.matchLength(code); |