Skip to content

Commit

Permalink
gzip: implement compression
Browse files Browse the repository at this point in the history
  • Loading branch information
jacobly0 authored and andrewrk committed Jan 29, 2024
1 parent 27d2d8e commit 4dfca01
Show file tree
Hide file tree
Showing 8 changed files with 222 additions and 57 deletions.
32 changes: 31 additions & 1 deletion lib/std/compress.zig
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ pub fn HashedReader(

pub fn read(self: *@This(), buf: []u8) Error!usize {
const amt = try self.child_reader.read(buf);
self.hasher.update(buf);
self.hasher.update(buf[0..amt]);
return amt;
}

Expand All @@ -38,6 +38,36 @@ pub fn hashedReader(
return .{ .child_reader = reader, .hasher = hasher };
}

pub fn HashedWriter(
comptime WriterType: anytype,
comptime HasherType: anytype,
) type {
return struct {
child_writer: WriterType,
hasher: HasherType,

pub const Error = WriterType.Error;
pub const Writer = std.io.Writer(*@This(), Error, write);

pub fn write(self: *@This(), buf: []const u8) Error!usize {
const amt = try self.child_writer.write(buf);
self.hasher.update(buf[0..amt]);
return amt;
}

pub fn writer(self: *@This()) Writer {
return .{ .context = self };
}
};
}

pub fn hashedWriter(
writer: anytype,
hasher: anytype,
) HashedWriter(@TypeOf(writer), @TypeOf(hasher)) {
return .{ .child_writer = writer, .hasher = hasher };
}

test {
_ = deflate;
_ = gzip;
Expand Down
6 changes: 3 additions & 3 deletions lib/std/compress/deflate/compressor.zig
Original file line number Diff line number Diff line change
Expand Up @@ -733,7 +733,7 @@ pub fn Compressor(comptime WriterType: anytype) type {
}

/// Writes the compressed form of `input` to the underlying writer.
pub fn write(self: *Self, input: []const u8) !usize {
pub fn write(self: *Self, input: []const u8) Error!usize {
var buf = input;

// writes data to hm_bw, which will eventually write the
Expand All @@ -756,7 +756,7 @@ pub fn Compressor(comptime WriterType: anytype) type {
/// If the underlying writer returns an error, `flush()` returns that error.
///
/// In the terminology of the zlib library, Flush is equivalent to Z_SYNC_FLUSH.
pub fn flush(self: *Self) !void {
pub fn flush(self: *Self) Error!void {
self.sync = true;
try self.step();
try self.hm_bw.writeStoredHeader(0, false);
Expand Down Expand Up @@ -956,7 +956,7 @@ pub fn Compressor(comptime WriterType: anytype) type {
}

/// Writes any pending data to the underlying writer.
pub fn close(self: *Self) !void {
pub fn close(self: *Self) Error!void {
self.sync = true;
try self.step();
try self.hm_bw.writeStoredHeader(0, true);
Expand Down
8 changes: 4 additions & 4 deletions lib/std/compress/deflate/compressor_test.zig
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ fn testSync(level: deflate.Compression, input: []const u8) !void {
read = try decomp.reader().readAll(&final);
try testing.expectEqual(@as(usize, 0), read); // expect ended stream to return 0 bytes

_ = decomp.close();
try decomp.close();
}
}

Expand All @@ -102,7 +102,7 @@ fn testSync(level: deflate.Compression, input: []const u8) !void {
defer testing.allocator.free(decompressed);

_ = try decomp.reader().readAll(decompressed);
_ = decomp.close();
try decomp.close();

try testing.expectEqualSlices(u8, input, decompressed);
}
Expand Down Expand Up @@ -477,7 +477,7 @@ test "inflate reset" {
.readAllAlloc(testing.allocator, math.maxInt(usize));
defer testing.allocator.free(decompressed_1);

_ = decomp.close();
try decomp.close();

try testing.expectEqualSlices(u8, strings[0], decompressed_0);
try testing.expectEqualSlices(u8, strings[1], decompressed_1);
Expand Down Expand Up @@ -524,7 +524,7 @@ test "inflate reset dictionary" {
.readAllAlloc(testing.allocator, math.maxInt(usize));
defer testing.allocator.free(decompressed_1);

_ = decomp.close();
try decomp.close();

try testing.expectEqualSlices(u8, strings[0], decompressed_0);
try testing.expectEqualSlices(u8, strings[1], decompressed_1);
Expand Down
13 changes: 5 additions & 8 deletions lib/std/compress/deflate/decompressor.zig
Original file line number Diff line number Diff line change
Expand Up @@ -477,11 +477,10 @@ pub fn Decompressor(comptime ReaderType: type) type {
}
}

pub fn close(self: *Self) ?Error {
if (self.err == @as(?Error, error.EndOfStreamWithNoError)) {
return null;
pub fn close(self: *Self) Error!void {
if (self.err) |err| {
if (err != error.EndOfStreamWithNoError) return err;
}
return self.err;
}

// RFC 1951 section 3.2.7.
Expand Down Expand Up @@ -880,7 +879,7 @@ pub fn Decompressor(comptime ReaderType: type) type {

/// Replaces the inner reader and dictionary with new_reader and new_dict.
/// new_reader must be of the same type as the reader being replaced.
pub fn reset(s: *Self, new_reader: ReaderType, new_dict: ?[]const u8) !void {
pub fn reset(s: *Self, new_reader: ReaderType, new_dict: ?[]const u8) Error!void {
s.inner_reader = new_reader;
s.step = nextBlock;
s.err = null;
Expand Down Expand Up @@ -920,9 +919,7 @@ test "confirm decompressor resets" {
const buf = try decomp.reader().readAllAlloc(std.testing.allocator, 1024 * 100);
defer std.testing.allocator.free(buf);

if (decomp.close()) |err| {
return err;
}
try decomp.close();

try decomp.reset(stream.reader(), null);
}
Expand Down
4 changes: 2 additions & 2 deletions lib/std/compress/deflate/deflate_fast_test.zig
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ test "best speed" {
defer decomp.deinit();

const read = try decomp.reader().readAll(decompressed);
_ = decomp.close();
try decomp.close();

try testing.expectEqual(want.items.len, read);
try testing.expectEqualSlices(u8, want.items, decompressed);
Expand Down Expand Up @@ -150,7 +150,7 @@ test "best speed max match offset" {
var decomp = try inflate.decompressor(testing.allocator, fib.reader(), null);
defer decomp.deinit();
const read = try decomp.reader().readAll(decompressed);
_ = decomp.close();
try decomp.close();

try testing.expectEqual(src.len, read);
try testing.expectEqualSlices(u8, src, decompressed);
Expand Down
3 changes: 2 additions & 1 deletion lib/std/compress/deflate/huffman_bit_writer.zig
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,8 @@ pub fn HuffmanBitWriter(comptime WriterType: type) type {
if (self.err) {
return;
}
self.bytes_written += try self.inner_writer.write(b);
try self.inner_writer.writeAll(b);
self.bytes_written += b.len;
}

fn writeBits(self: *Self, b: u32, nb: u32) Error!void {
Expand Down
Loading

0 comments on commit 4dfca01

Please sign in to comment.