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 }