const std = @import("std"); const Reader = std.Io.Reader; const Writer = std.Io.Writer; const Allocator = std.mem.Allocator; const Payload = @This(); len: u32, short: [128]u8, long: ?[]u8, pub fn read(alloc: Allocator, in: *Reader, bytes: usize) !Payload { var res: Payload = .{ .len = @intCast(bytes), .short = undefined, .long = null, }; try in.readSliceAll(res.short[0..@min(bytes, res.short.len)]); if (bytes > res.short.len) { const long = try alloc.alloc(u8, bytes - res.short.len); errdefer alloc.free(long); try in.readSliceAll(long); res.long = long; } return res; } pub fn write(self: Payload, out: *Writer) !void { std.debug.assert(out.buffer.len >= self.short.len); std.debug.assert(self.len <= self.short.len or self.long != null); try out.writeAll(self.short[0..@min(self.len, self.short.len)]); if (self.long) |l| { try out.writeAll(l); } } pub fn deinit(self: Payload, alloc: Allocator) void { if (self.long) |l| { alloc.free(l); } } pub fn dupe(self: Payload, alloc: Allocator) !Payload { var res = self; if (self.long) |l| { res.long = try alloc.dupe(u8, l); } errdefer if (res.long) |l| alloc.free(l); return res; }