| ... | @@ -15,8 +15,7 @@ remaining_bits: std.math.Log2Int(usize), | ... | @@ -15,8 +15,7 @@ remaining_bits: std.math.Log2Int(usize), |
| 15 | | 15 | |
| 16 | reader: Reader, | 16 | reader: Reader, |
| 17 | | 17 | |
| 18 | /// Hashes, produces checksum, of uncompressed data for gzip/zlib footer. | 18 | container_metadata: Container.Metadata, |
| 19 | hasher: Container.Hasher, | | |
| 20 | | 19 | |
| 21 | lit_dec: LiteralDecoder, | 20 | lit_dec: LiteralDecoder, |
| 22 | dst_dec: DistanceDecoder, | 21 | dst_dec: DistanceDecoder, |
| ... | @@ -71,7 +70,7 @@ pub fn init(input: *Reader, container: Container, buffer: []u8) Decompress { | ... | @@ -71,7 +70,7 @@ pub fn init(input: *Reader, container: Container, buffer: []u8) Decompress { |
| 71 | .input = input, | 70 | .input = input, |
| 72 | .next_bits = 0, | 71 | .next_bits = 0, |
| 73 | .remaining_bits = 0, | 72 | .remaining_bits = 0, |
| 74 | .hasher = .init(container), | 73 | .container_metadata = .init(container), |
| 75 | .lit_dec = .{}, | 74 | .lit_dec = .{}, |
| 76 | .dst_dec = .{}, | 75 | .dst_dec = .{}, |
| 77 | .final_block = false, | 76 | .final_block = false, |
| ... | @@ -169,7 +168,7 @@ fn readInner(d: *Decompress, w: *Writer, limit: std.Io.Limit) (Error || Reader.S | ... | @@ -169,7 +168,7 @@ fn readInner(d: *Decompress, w: *Writer, limit: std.Io.Limit) (Error || Reader.S |
| 169 | var remaining = @intFromEnum(limit); | 168 | var remaining = @intFromEnum(limit); |
| 170 | const in = d.input; | 169 | const in = d.input; |
| 171 | sw: switch (d.state) { | 170 | sw: switch (d.state) { |
| 172 | .protocol_header => switch (d.hasher.container()) { | 171 | .protocol_header => switch (d.container_metadata.container()) { |
| 173 | .gzip => { | 172 | .gzip => { |
| 174 | const Header = extern struct { | 173 | const Header = extern struct { |
| 175 | magic: u16 align(1), | 174 | magic: u16 align(1), |
| ... | @@ -258,7 +257,7 @@ fn readInner(d: *Decompress, w: *Writer, limit: std.Io.Limit) (Error || Reader.S | ... | @@ -258,7 +257,7 @@ fn readInner(d: *Decompress, w: *Writer, limit: std.Io.Limit) (Error || Reader.S |
| 258 | try d.lit_dec.generate(dec_lens[0..hlit]); | 257 | try d.lit_dec.generate(dec_lens[0..hlit]); |
| 259 | | 258 | |
| 260 | // distance code lengths to distance decoder | 259 | // distance code lengths to distance decoder |
| 261 | try d.dst_dec.generate(dec_lens[hlit .. hlit + hdist]); | 260 | try d.dst_dec.generate(dec_lens[hlit..][0..hdist]); |
| 262 | | 261 | |
| 263 | continue :sw .dynamic_block; | 262 | continue :sw .dynamic_block; |
| 264 | }, | 263 | }, |
| ... | @@ -332,14 +331,17 @@ fn readInner(d: *Decompress, w: *Writer, limit: std.Io.Limit) (Error || Reader.S | ... | @@ -332,14 +331,17 @@ fn readInner(d: *Decompress, w: *Writer, limit: std.Io.Limit) (Error || Reader.S |
| 332 | }, | 331 | }, |
| 333 | .protocol_footer => { | 332 | .protocol_footer => { |
| 334 | d.alignBitsToByte(); | 333 | d.alignBitsToByte(); |
| 335 | switch (d.hasher) { | 334 | switch (d.container_metadata) { |
| 336 | .gzip => |*gzip| { | 335 | .gzip => |*gzip| { |
| 337 | if (try in.takeInt(u32, .little) != gzip.crc.final()) return error.WrongGzipChecksum; | 336 | gzip.* = .{ |
| 338 | if (try in.takeInt(u32, .little) != gzip.count) return error.WrongGzipSize; | 337 | .crc = try in.takeInt(u32, .little), |
| | 338 | .count = try in.takeInt(u32, .little), |
| | 339 | }; |
| 339 | }, | 340 | }, |
| 340 | .zlib => |*zlib| { | 341 | .zlib => |*zlib| { |
| 341 | const chksum: u32 = @byteSwap(zlib.adler); | 342 | zlib.* = .{ |
| 342 | if (try in.takeInt(u32, .big) != chksum) return error.WrongZlibChecksum; | 343 | .adler = try in.takeInt(u32, .little), |
| | 344 | }; |
| 343 | }, | 345 | }, |
| 344 | .raw => {}, | 346 | .raw => {}, |
| 345 | } | 347 | } |
| ... | @@ -868,8 +870,7 @@ fn testBasicCase(in: []const u8, out: []const u8) !void { | ... | @@ -868,8 +870,7 @@ fn testBasicCase(in: []const u8, out: []const u8) !void { |
| 868 | defer aw.deinit(); | 870 | defer aw.deinit(); |
| 869 | | 871 | |
| 870 | var decompress: Decompress = .init(&reader, .raw, &.{}); | 872 | var decompress: Decompress = .init(&reader, .raw, &.{}); |
| 871 | const r = &decompress.reader; | 873 | _ = try decompress.reader.streamRemaining(&aw.writer); |
| 872 | _ = try r.streamRemaining(&aw.writer); | | |
| 873 | try testing.expectEqualStrings(out, aw.getWritten()); | 874 | try testing.expectEqualStrings(out, aw.getWritten()); |
| 874 | } | 875 | } |
| 875 | | 876 | |
| ... | @@ -917,8 +918,7 @@ fn testGzipDecompress(in: []const u8, out: []const u8) !void { | ... | @@ -917,8 +918,7 @@ fn testGzipDecompress(in: []const u8, out: []const u8) !void { |
| 917 | defer aw.deinit(); | 918 | defer aw.deinit(); |
| 918 | | 919 | |
| 919 | var decompress: Decompress = .init(&reader, .gzip, &.{}); | 920 | var decompress: Decompress = .init(&reader, .gzip, &.{}); |
| 920 | const r = &decompress.reader; | 921 | _ = try decompress.reader.streamRemaining(&aw.writer); |
| 921 | _ = try r.streamRemaining(&aw.writer); | | |
| 922 | try testing.expectEqualStrings(out, aw.getWritten()); | 922 | try testing.expectEqualStrings(out, aw.getWritten()); |
| 923 | } | 923 | } |
| 924 | | 924 | |