diff options
author | Robby Zambito <contact@robbyzambito.me> | 2025-04-29 08:46:18 -0400 |
---|---|---|
committer | Robby Zambito <contact@robbyzambito.me> | 2025-04-30 13:46:55 -0400 |
commit | d0d0b83b57900fe2652fe1203d6e5407dca3ea9d (patch) | |
tree | 32c39b000ed62a62b70bfa8ac4ce27d46a2b4c3f | |
parent | bc3926bccadbb01747a1babb6f5a0ad93ce37ca4 (diff) |
Simplify init interface
-rw-r--r-- | src/message.zig | 60 |
1 files changed, 42 insertions, 18 deletions
diff --git a/src/message.zig b/src/message.zig index 80757fa..318d943 100644 --- a/src/message.zig +++ b/src/message.zig @@ -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; - // zcm.length = payload_len; + { + // 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) { |