I’m trying to upgrade one of my hobby projects to 0.15.1. I was using File.readToEndAllocOptions to get a [:0]const u8 from the file.
The reason I need a null terminated string specifically is that std.zon.parse.fromSlice requires it and I’m parsing a config file in zon.
The Io.Reader interface has a readAlloc that will get the full contents of the file, but no way to null terminate it. It gives the contents without the null. Any ideas on how to work around this?
Previous code:
const config_data = try home.openFile(".config/mailbox/config.zon", .{ .mode = .read_only });
const config_bytes = try config_data.readToEndAllocOptions(alloc, 2048, 64, @alignOf([:0]u8), 0);
defer alloc.free(config_bytes);
var status: std.zon.parse.Status = .{}; // This is changed to Diagnostics in 0.15.1
const local_config = try std.zon.parse.fromSlice(Config, alloc, config_bytes, &status, .{
.ignore_unknown_fields = true,
});
I came up with a solution, but it’s a little janky. Basically allocating the buffer + 1 based on the length and then manually null terminating it. If anyone has a better solution, I would appreciate the suggestions. There’s a lot of len - 1 math here that would be easy to misplace.
That definitely looks like what I want, but that was added (the day) after 0.15.1 release. So that will be the answer going forward. Thanks for the link!
Here’s a version that read the whole file directly into the Reader’s buffer using fill(), rather than doing it with 256 chunks. Should have the least amount of buffer re-allocation and copying.
If you don’t actually need to keep the open File around after reading the data, you can just use std.fs.Dir.readFileAllocOptions (0.15.1 version) instead of handling the openFile → reader stuff yourself.