How can I use deflate with Writer.Allocating? (→ How do I make a buffered allocating writer?)

I want to use the new deflate compressor with an allocating writer because I don’t know the upper limit of the compressed size.
It is failing because it seems to want a buffered writer, with a buffer > 8.
Here is a full example:

const std = @import("std");

pub fn main() void {
	var result = std.Io.Writer.Allocating.init(std.heap.smp_allocator);
	var buffer: [65536]u8 = undefined;
	var compress = std.compress.flate.Compress.init(&result.writer, &buffer, .raw, .default) catch unreachable;
	_ = &compress;
}

Crashes because of an assertion failure:

/home/mint/Cubyz/compiler/zig/lib/std/compress/flate/Compress.zig:278:11: 0x113996d in init (std.zig)
    assert(output.buffer.len > 8);
          ^

I tried just overwriting the buffer like so

	var buffer: [16]u8 = undefined;
	writer.buffer = &buffer;

but that doesn’t seem to be allowed, since it then produces undefined data (of the right length though). So I guess that’s not allowed.

So how do I make a buffered allocating writer?

What if you use:

var result = std.Io.Writer.Allocating.init(std.heap.smp_allocator);
try result.ensureTotalCapacity(9);
var buffer: [65536]u8 = undefined;
var compress = std.compress.flate.Compress.init(&result.writer, &buffer, .raw, .default) catch unreachable;
_ = &compress;

To get past the assert?

3 Likes

How about preallocating buffer with initCapacity?

const std = @import("std");

pub fn main() !void {
    var result = try std.Io.Writer.Allocating.initCapacity(std.heap.smp_allocator, 8 + 1);
    var buffer: [65536]u8 = undefined;
    var compress = std.compress.flate.Compress.init(&result.writer, &buffer, .raw, .default) catch unreachable;
    _ = &compress;
}
5 Likes

Thank you, both solutions work. I personally prefer initCapacity, so I accepted that answer.

2 Likes