lib/choir/src/backends/wasm/binary/sink.zig
daab053ee43316e1809a84551d573ddd1e5bf3d2
1 const std = @import("std");
2
3 pub const Count = struct {
4 len: usize = 0,
5
6 pub fn writeByte(self: *Count, _: u8) error{CapacityOverflow}!void {
7 self.len = std.math.add(usize, self.len, 1) catch return error.CapacityOverflow;
8 }
9
10 pub fn writeAll(self: *Count, bytes: []const u8) error{CapacityOverflow}!void {
11 self.len = std.math.add(usize, self.len, bytes.len) catch return error.CapacityOverflow;
12 }
13 };
14
15 pub const Fixed = struct {
16 bytes: []u8,
17 len: usize = 0,
18
19 pub fn init(bytes: []u8) Fixed {
20 return .{ .bytes = bytes };
21 }
22
23 pub fn writeByte(self: *Fixed, byte: u8) error{OutputOverflow}!void {
24 if (self.len == self.bytes.len) return error.OutputOverflow;
25 self.bytes[self.len] = byte;
26 self.len += 1;
27 }
28
29 pub fn writeAll(self: *Fixed, bytes: []const u8) error{OutputOverflow}!void {
30 const end = std.math.add(usize, self.len, bytes.len) catch return error.OutputOverflow;
31 if (end > self.bytes.len) return error.OutputOverflow;
32 @memcpy(self.bytes[self.len..end], bytes);
33 self.len = end;
34 }
35
36 pub fn finish(self: *const Fixed) error{OutputUnderflow}![]u8 {
37 if (self.len != self.bytes.len) return error.OutputUnderflow;
38 return self.bytes;
39 }
40 };
41
42 test "wasm binary fixed sink requires the exact output capacity" {
43 var bytes: [2]u8 = undefined;
44 var fixed = Fixed.init(&bytes);
45 try fixed.writeByte(1);
46 try std.testing.expectError(error.OutputUnderflow, fixed.finish());
47 try fixed.writeByte(2);
48 try std.testing.expectEqualSlices(u8, &.{ 1, 2 }, try fixed.finish());
49 try std.testing.expectError(error.OutputOverflow, fixed.writeByte(3));
50 }