From 8f0ab5ab3973265052dca442b582dfcb4965e993 Mon Sep 17 00:00:00 2001 From: Robby Zambito Date: Wed, 30 Apr 2025 10:51:09 -0400 Subject: Bad attempt at using @fieldParentPtr https://kagi.com/assistant/a8f0a9ac-a11a-472e-af38-98d7e877e293 --- src/message.zig | 36 +++++++++++++++++++++++++++++------- 1 file changed, 29 insertions(+), 7 deletions(-) diff --git a/src/message.zig b/src/message.zig index b276b3d..bcf9830 100644 --- a/src/message.zig +++ b/src/message.zig @@ -36,9 +36,30 @@ pub const ZeroCopyMessage = packed struct { dest: @Vector(4, u8), payload: void, - pub fn getPayload(self: *align(1) Relay) []u8 { - const len: *u16 = @ptrFromInt(@intFromPtr(self) - @sizeOf(u16)); - return @as([*]u8, @ptrCast(&self.payload))[0 .. len.* - @sizeOf(Relay)]; + pub fn getPayload(self: *align(@alignOf(ZeroCopyMessage)) Relay) []u8 { + // Cast the 'self' pointer (which points to the Relay header, + // located at the same memory as the parent's 'bytes' field) + // to a pointer to void, as required by @fieldParentPtr for a void field. + // Preserve the known alignment. + const self_as_void_ptr: *align(@alignOf(ZeroCopyMessage)) void = @ptrCast(self); + + // Cast the resulting *void pointer to the parent type *ZeroCopyMessage. + // This cast performs the necessary alignment check. + const parent: *ZeroCopyMessage = @alignCast(@fieldParentPtr("bytes", self_as_void_ptr)); + + // The 'length' field in the parent ZeroCopyMessage contains + // the size of the header (Relay) + payload length. + const total_len = parent.length; + + // Payload length = total_len - size of the Relay header + const payload_len = total_len - @sizeOf(Relay); + + // The payload starts immediately after the fixed fields of the Relay struct. + // The address of the 'payload' field represents this starting point. + const payload_start_ptr: [*]u8 = @ptrCast(&self.payload); + + // Return a slice from the payload start address with the calculated length. + return payload_start_ptr[0..payload_len]; } }; const Connection = packed struct { @@ -94,17 +115,17 @@ pub const ZeroCopyMessage = packed struct { allocator.free(self.asBytes()); } - fn getRelay(self: *Self) *align(1) Relay { + fn getRelay(self: *Self) *align(@alignOf(Self)) Relay { return std.mem.bytesAsValue(Relay, &self.bytes); } - fn getConnection(self: *Self) *align(1) Connection { + fn getConnection(self: *Self) *align(@alignOf(Self)) Connection { return std.mem.bytesAsValue(Connection, &self.bytes); } pub fn getSaprusTypePayload(self: *Self) Error!(union(PacketType) { - relay: *align(1) Relay, + relay: *align(@alignOf(Self)) Relay, file_transfer: void, - connection: *align(1) Connection, + connection: *align(@alignOf(Self)) Connection, }) { return switch (self.type) { .relay => .{ .relay = self.getRelay() }, @@ -172,6 +193,7 @@ test "testing variable length zero copy struct" { // Create a view of the byte slice as a ZeroCopyMessage const zcm: *ZeroCopyMessage = try .init(gpa, .relay, payload.len); defer zcm.deinit(gpa); + std.debug.print("outer: {*}\n", .{zcm}); { // Set the message values -- cgit