summaryrefslogtreecommitdiff
path: root/src/message.zig
diff options
context:
space:
mode:
Diffstat (limited to 'src/message.zig')
-rw-r--r--src/message.zig60
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) {