std.compress.flate.Compress nontermination

Zig 0.15.2

The standard compression machinery seems to be broken, as in the following program does not terminate:

const std = @import("std");
const flate = std.compress.flate;

pub fn main() !void {
    const cwd = std.fs.cwd();
    var file = try cwd.createFile("my_file", .{});
    defer file.close();
    var write_buffer: [flate.max_window_len]u8 = undefined;
    var file_writer: std.fs.File.Writer = .init(file, &write_buffer);
    var flate_buffer: [flate.max_window_len]u8 = undefined;
    const options: flate.Compress.Options = .{ .level = .default, .container = .zlib };
    var compress: flate.Compress = .init(&file_writer.interface, &flate_buffer, options);
    try compress.writer.writeAll("my content\n");
    try compress.end();  // <-- the drain never terminates
    try file_writer.interface.flush();
}

The decompression works just fine.

What are my options for circumventing this?

1 Like

I have the same problem. Maybe someone has an example or can point to relevant code or documentation?

@jpsecher This backport solution works for me, so it might be worth trying as a workaround.

Another victim of the writergate scandal ;D Compression functionality was temporarily removed in 0.15. I’m not sure what flate.Compress is doing there at all actually…probably unfinished code. It will be fully functional in 0.16 because someone contributed it and got it merged. If you need this on 0.15 then I think the backport that @snubydev mentioned is your best bet.

I tried the solution merged in 0.16-dev.1859+212968c57 as well and it finally works too. I didn’t realize I needed to flush both the writer and the compression writer.

...

var compress = try flate.Compress.init(writer, &c_buffer, .zlib, .level_2);
var compress_writer = &compress.writer;
_ = try compress_writer.writeAll("my content\n");
_ = try compress_writer.flush();
_ = try writer.flush();

Thanks, so using Zig from master with

nix shell 'github:mitchellh/zig-overlay#master'

I can run this sucessfully:

const std = @import("std");
const flate = std.compress.flate;

pub fn main() !void {
    var threaded: std.Io.Threaded = .init_single_threaded;
    const io = threaded.io();
    const cwd = std.Io.Dir.cwd();
    var file = try cwd.createFile(io, "my_file", .{});
    defer file.close(io);
    var write_buffer: [flate.max_window_len]u8 = undefined;
    var file_writer: std.Io.File.Writer = .init(file, io, &write_buffer);
    var flate_buffer: [flate.max_window_len]u8 = undefined;
    var compress: flate.Compress = try .init(&file_writer.interface, &flate_buffer, .zlib, .level_2);
    try compress.writer.writeAll("my content\n");
    try compress.writer.flush();
    try file_writer.interface.flush();
}

Cheers,
/JP