Simplify init interface

This commit is contained in:
2025-04-29 08:46:18 -04:00
parent bcab1e4d00
commit f1dce257be

View File

@@ -76,8 +76,22 @@ pub const ZeroCopyMessage = packed struct {
length: u16,
bytes: void = {},
pub fn init(allocator: Allocator, payload_len: u16) !*Self {
const bytes = try allocator.alignedAlloc(u8, @alignOf(Self), @sizeOf(Self) + payload_len);
pub fn init(allocator: Allocator, comptime @"type": PacketType, payload_len: u16) !*Self {
const header_size = @sizeOf(switch (@"type") {
.relay => Relay,
.connection => Connection,
else => return error.Bad,
});
const size = payload_len + @sizeOf(Self) + header_size;
const bytes = try allocator.alignedAlloc(u8, @alignOf(Self), size);
const res: *Self = @ptrCast(bytes.ptr);
res.type = @"type";
res.length = payload_len + header_size;
return res;
}
pub fn deinit(self: *Self, allocator: Allocator) void {
allocator.free(self.toBytes());
}
fn getRelay(self: *Self) *align(1) Relay {
@@ -106,12 +120,13 @@ pub const ZeroCopyMessage = packed struct {
@intFromEnum(self.type),
));
self.length = bigToNative(@TypeOf(self.length), self.length);
try switch (try self.getSaprusTypePayload()) {
switch (try self.getSaprusTypePayload()) {
.relay => {},
.connection => |*con| con.*.nativeFromNetworkEndian(),
.file_transfer => Error.NotImplementedSaprusType,
else => Error.UnknownSaprusType,
};
.connection => |*con| try con.*.nativeFromNetworkEndian(),
// We know other values are unreachable,
// because they would have returned an error from the switch condition.
else => unreachable,
}
}
pub fn networkFromNativeEndian(self: *Self) Error!void {
@@ -136,33 +151,42 @@ pub const ZeroCopyMessage = packed struct {
const res: *Self = @ptrCast(@alignCast(bytes.ptr));
return if (bytes.len == res.length + @sizeOf(Self)) res else Error.InvalidMessage;
}
pub fn toBytes(self: *Self) []align(@alignOf(Self)) u8 {
return @as([*]align(@alignOf(Self)) u8, @ptrCast(self))[0 .. @sizeOf(Self) + self.length];
}
};
test "testing variable length zero copy struct" {
const gpa = std.testing.allocator;
const payload_len = 48;
defer gpa.free(bytes);
const payload = "Hello darkness my old friend";
// Create a view of the byte slice as a ZeroCopyMessage
const zcm: *ZeroCopyMessage = .fromBytesUnchecked(bytes);
const zcm: *ZeroCopyMessage = try .init(gpa, .relay, payload.len);
defer zcm.deinit(gpa);
{
// Set the message values
zcm.type = .relay;
{
// These are both set by the init call.
// zcm.type = .relay;
// zcm.length = payload_len;
}
const relay = (try zcm.getSaprusTypePayload()).relay;
relay.dest = .{ 1, 2, 3, 4 };
const payload = relay.getPayload();
const p = "Hello darkness my old friend";
@memcpy(payload[0..p.len], p);
@memcpy(relay.getPayload(), payload);
}
{
// Print the message as hex using the network
zcm.networkFromNativeEndian() catch unreachable;
const bytes = zcm.toBytes();
// Print the message as hex using the network byte order
try zcm.networkFromNativeEndian();
// We know the error from nativeFromNetworkEndian is unreachable because
// it would have returned an error from networkFromNativeEndian.
defer zcm.nativeFromNetworkEndian() catch unreachable;
std.debug.print("network bytes: {x}\n", .{bytes});
std.debug.print("network bytes: {s}\n", .{bytes});
std.debug.print("bytes len: {d}\n", .{bytes.len});
}
if (false) {