From ac5511e9bdda73f42e58189e7e143e8ba78ceb26 Mon Sep 17 00:00:00 2001 From: Robby Zambito Date: Sat, 5 Apr 2025 00:48:10 -0400 Subject: Not using writer Use direct mem copying into the buf instead of writing to it with the writer interface. Probably better to use the writer actually, since this suffers from the same issue with the extra two null bytes. --- src/saprus_message.zig | 37 ++++++++++++++++++++----------------- 1 file changed, 20 insertions(+), 17 deletions(-) (limited to 'src/saprus_message.zig') diff --git a/src/saprus_message.zig b/src/saprus_message.zig index b77f423..6c46a8f 100644 --- a/src/saprus_message.zig +++ b/src/saprus_message.zig @@ -44,7 +44,8 @@ pub const SaprusMessage = union(SaprusPacketType) { seq_num: u32 = 0, msg_id: u32 = 0, reserved: u8 = 0, - options: SaprusConnectionOptions = .{}, + // options: SaprusConnectionOptions = .{}, + options: u8 = 0, }; header: Header, payload: []const u8, @@ -62,11 +63,11 @@ pub const SaprusMessage = union(SaprusPacketType) { } } - inline fn toBytesAux( - Header: type, + fn toBytesAux( + comptime Header: type, header: Header, payload: []const u8, - w: std.ArrayList(u8).Writer, + buf: *std.ArrayList(u8), allocator: Allocator, ) !void { // Create a growable string to store the base64 bytes in. @@ -78,32 +79,31 @@ pub const SaprusMessage = union(SaprusPacketType) { // Write the payload bytes as base64 to the growable string. try base64Enc.encodeWriter(buf_w, payload); - // Write the packet body to the output writer. - try w.writeInt(u16, @intCast(payload_list.items.len), .big); - - // try w.writeStructEndian(header, .big); - - const header_bytes = std.mem.asBytes(&header); + // Write the packet body to the output writer + try buf.*.appendSlice(asBytes(&nativeToBig(u16, @intCast(payload_list.items.len)))); - try w.writeAll(header_bytes[0 .. header_bytes.len - 2]); + var h = header; + inline for (@typeInfo(Header).@"struct".fields) |f| { + @field(h, f.name) = nativeToBig(@TypeOf(@field(h, f.name)), @field(h, f.name)); + } - try w.writeAll(payload_list.items); + const h_bytes = asBytes(&h); + try buf.*.appendSlice(h_bytes[0 .. h_bytes.len - 2]); + try buf.*.appendSlice(payload_list.items); } /// Caller is responsible for freeing the returned bytes. pub fn toBytes(self: SaprusMessage, allocator: Allocator) ![]u8 { // Create a growable list of bytes to store the output in. var buf = std.ArrayList(u8).init(allocator); - // Create a writer for an easy interface to append arbitrary bytes. - const w = buf.writer(); // Start with writing the message type, which is the first 16 bits of every Saprus message. - try w.writeInt(u16, @intFromEnum(self), .big); + try buf.appendSlice(asBytes(&nativeToBig(u16, @intFromEnum(self)))); // Write the proper header and payload for the given packet type. switch (self) { - .relay => |r| try toBytesAux(Relay.Header, r.header, r.payload, w, allocator), - .connection => |c| try toBytesAux(Connection.Header, c.header, c.payload, w, allocator), + .relay => |r| try toBytesAux(Relay.Header, r.header, r.payload, &buf, allocator), + .connection => |c| try toBytesAux(Connection.Header, c.header, c.payload, &buf, allocator), .file_transfer => return SaprusError.NotImplementedSaprusType, } @@ -157,6 +157,9 @@ pub const SaprusMessage = union(SaprusPacketType) { const std = @import("std"); const Allocator = std.mem.Allocator; +const asBytes = std.mem.asBytes; +const nativeToBig = std.mem.nativeToBig; + test "Round trip Relay toBytes and fromBytes" { const gpa = std.testing.allocator; const msg = SaprusMessage{ -- cgit