diff options
Diffstat (limited to 'src/message.zig')
-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) { |