| ... | ... | @@ -15,6 +15,8 @@ const FEXTRA = 1 << 2; |
| 15 | 15 | const FNAME = 1 << 3; |
| 16 | 16 | const FCOMMENT = 1 << 4; |
| 17 | 17 | |
| 18 | const max_string_len = 1024; |
| 19 | |
| 18 | 20 | pub fn GzipStream(comptime ReaderType: type) type { |
| 19 | 21 | return struct { |
| 20 | 22 | const Self = @This(); |
| ... | ... | @@ -31,9 +33,11 @@ pub fn GzipStream(comptime ReaderType: type) type { |
| 31 | 33 | read_amt: usize, |
| 32 | 34 | |
| 33 | 35 | info: struct { |
| 36 | extra: ?[]const u8, |
| 34 | 37 | filename: ?[]const u8, |
| 35 | 38 | comment: ?[]const u8, |
| 36 | 39 | modification_time: u32, |
| 40 | operating_system: u8, |
| 37 | 41 | }, |
| 38 | 42 | |
| 39 | 43 | fn init(allocator: mem.Allocator, source: ReaderType) !Self { |
| ... | ... | @@ -57,33 +61,27 @@ pub fn GzipStream(comptime ReaderType: type) type { |
| 57 | 61 | // Operating system where the compression took place |
| 58 | 62 | const OS = header[9]; |
| 59 | 63 | _ = XFL; |
| 60 | | _ = OS; |
| 61 | 64 | |
| 62 | | if (FLG & FEXTRA != 0) { |
| 63 | | // Skip the extra data, we could read and expose it to the user |
| 64 | | // if somebody needs it. |
| 65 | const extra = if (FLG & FEXTRA != 0) blk: { |
| 65 | 66 | const len = try source.readIntLittle(u16); |
| 66 | | try source.skipBytes(len, .{}); |
| 67 | | } |
| 68 | | |
| 69 | | var filename: ?[]const u8 = null; |
| 70 | | if (FLG & FNAME != 0) { |
| 71 | | filename = try source.readUntilDelimiterAlloc( |
| 72 | | allocator, |
| 73 | | 0, |
| 74 | | std.math.maxInt(usize), |
| 75 | | ); |
| 76 | | } |
| 67 | const tmp_buf = try allocator.alloc(u8, len); |
| 68 | errdefer allocator.free(tmp_buf); |
| 69 | |
| 70 | try source.readNoEof(tmp_buf); |
| 71 | break :blk tmp_buf; |
| 72 | } else null; |
| 73 | errdefer if (extra) |p| allocator.free(p); |
| 74 | |
| 75 | const filename = if (FLG & FNAME != 0) |
| 76 | try source.readUntilDelimiterAlloc(allocator, 0, max_string_len) |
| 77 | else |
| 78 | null; |
| 77 | 79 | errdefer if (filename) |p| allocator.free(p); |
| 78 | 80 | |
| 79 | | var comment: ?[]const u8 = null; |
| 80 | | if (FLG & FCOMMENT != 0) { |
| 81 | | comment = try source.readUntilDelimiterAlloc( |
| 82 | | allocator, |
| 83 | | 0, |
| 84 | | std.math.maxInt(usize), |
| 85 | | ); |
| 86 | | } |
| 81 | const comment = if (FLG & FCOMMENT != 0) |
| 82 | try source.readUntilDelimiterAlloc(allocator, 0, max_string_len) |
| 83 | else |
| 84 | null; |
| 87 | 85 | errdefer if (comment) |p| allocator.free(p); |
| 88 | 86 | |
| 89 | 87 | if (FLG & FHCRC != 0) { |
| ... | ... | @@ -100,7 +98,9 @@ pub fn GzipStream(comptime ReaderType: type) type { |
| 100 | 98 | .info = .{ |
| 101 | 99 | .filename = filename, |
| 102 | 100 | .comment = comment, |
| 101 | .extra = extra, |
| 103 | 102 | .modification_time = MTIME, |
| 103 | .operating_system = OS, |
| 104 | 104 | }, |
| 105 | 105 | .read_amt = 0, |
| 106 | 106 | }; |
| ... | ... | @@ -108,6 +108,8 @@ pub fn GzipStream(comptime ReaderType: type) type { |
| 108 | 108 | |
| 109 | 109 | pub fn deinit(self: *Self) void { |
| 110 | 110 | self.inflater.deinit(); |
| 111 | if (self.info.extra) |extra| |
| 112 | self.allocator.free(extra); |
| 111 | 113 | if (self.info.filename) |filename| |
| 112 | 114 | self.allocator.free(filename); |
| 113 | 115 | if (self.info.comment) |comment| |