diff options
Diffstat (limited to 'src/Server/Payload.zig')
| -rw-r--r-- | src/Server/Payload.zig | 51 |
1 files changed, 51 insertions, 0 deletions
diff --git a/src/Server/Payload.zig b/src/Server/Payload.zig new file mode 100644 index 0000000..b512a81 --- /dev/null +++ b/src/Server/Payload.zig @@ -0,0 +1,51 @@ +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; +} |
