Fished decompression (maybe)

Added the necessary skeleton functions to re-add test
This commit is contained in:
Caleb Gardner
2026-05-01 07:05:52 -05:00
parent 274d088490
commit ab606bdfa5
13 changed files with 547 additions and 80 deletions
+53 -35
View File
@@ -1,55 +1,73 @@
const std = @import("std");
const Reader = std.Io.Reader;
const flate = std.compress.flate;
const Node = std.SinglyLinkedList.Node;
const Decompressor = @import("../util/decompressor.zig");
const Error = Decompressor.Error;
pub fn Zlib(stateless: bool) type {
return if (stateless)
struct {
const Self = @This();
const Self = @This();
interface: Decompressor = .{ .decomp_fn = decomp },
const Buffer = struct {
node: Node,
buf: []u8,
};
const init: Self = .{};
interface: Decompressor = .{ .decomp_fn = decomp },
fn decomp(_: *?Decompressor, alloc: std.mem.Allocator, in: []u8, out: []u8) Error!usize {
const buf = try alloc.alloc(u8, in.len * 2);
defer alloc.free(buf);
return zlibDecomp(buf, in, out);
}
}
else
struct {
const Self = @This();
alloc: std.mem.Allocator,
interface: Decompressor = .{ .decomp_fn = decomp },
block_size: u32,
buffers: std.ArrayList(Buffer),
buffer_queue: std.SinglyLinkedList,
alloc: std.mem.Allocator,
pub fn init(alloc: std.mem.Allocator, block_size: u32) !Self {
return .{
.alloc = alloc,
block_size: u32,
buffers: std.ArrayList([]u8),
buffer_queue: std.SinglyLinkedList,
.block_size = block_size,
.buffers = try .initCapacity(alloc, 5),
};
}
pub fn deinit(self: Self) void {
for (self.buffers) |buf|
self.alloc.free(buf);
self.buffers.deinit(self.alloc);
}
pub fn init(alloc: std.mem.Allocator, block_size: u32) !Self {
return .{
.alloc = alloc,
.block_size = block_size,
.buffers = try .initCapacity(alloc, 20),
};
}
pub fn deinit(self: Self) void {
for (self.buffers) |buf|
self.alloc.free(buf);
}
};
fn decomp(d: ?*const Decompressor, alloc: std.mem.Allocator, in: []u8, out: []u8) Error!usize {
if (d == null) {
const buf = try alloc.alloc(u8, in.len * 2);
defer alloc.free(buf);
return zlibDecomp(buf, in, out);
}
var self: Self = @fieldParentPtr("interface", d.?);
const buf_node = self.buffer_queue.popFirst();
var buf: *Buffer = undefined;
if (buf_node == null) {
const new_buf = try self.buffers.addOne(self.alloc);
new_buf.* = .{ .{}, try self.alloc.alloc(u8, self.block_size) };
buf = new_buf;
} else {
buf = @fieldParentPtr("node", buf_node);
}
defer self.buffer_queue.prepend(&buf.node);
return zlibDecomp(buf.buf, in, out);
}
inline fn zlibDecomp(buffer: []u8, in: []u8, out: []u8) !usize {
var rdr: Reader = .fixed(in);
var decomp = flate.Decompress.init(&rdr, .zlib, buffer);
var d = flate.Decompress.init(&rdr, .zlib, buffer);
return decomp.reader.readSliceShort(out);
return d.reader.readSliceShort(out);
}
// Stateless
pub const stateless_decompressor: Decompressor = .{ .decomp_fn = statelessDecomp };
fn statelessDecomp(_: ?*const Decompressor, alloc: std.mem.Allocator, in: []u8, out: []u8) Error!usize {
const buf = try alloc.alloc(u8, in.len * 2);
defer alloc.free(buf);
return zlibDecomp(buf, in, out);
}