diff options
author | Robby Zambito <contact@robbyzambito.me> | 2025-04-05 13:46:47 -0400 |
---|---|---|
committer | Robby Zambito <contact@robbyzambito.me> | 2025-04-06 13:08:09 -0400 |
commit | 3c935698aac68b081aaa62ef5473a194477e2578 (patch) | |
tree | 7d638d376422b1a0dcfe38cf124bfb2a0ada490c /src | |
parent | bc75e869043e84f11a3aae6d3d228beff9a34be6 (diff) |
Correctly handle the endiness and packedness of the the header reading and writing
Diffstat (limited to 'src')
-rw-r--r-- | src/saprus_message.zig | 36 |
1 files changed, 20 insertions, 16 deletions
diff --git a/src/saprus_message.zig b/src/saprus_message.zig index 1f1d37e..495b741 100644 --- a/src/saprus_message.zig +++ b/src/saprus_message.zig @@ -64,7 +64,7 @@ pub const SaprusMessage = union(SaprusPacketType) { } fn toBytesAux( - comptime Header: type, + Header: type, header: Header, payload: []const u8, buf: *std.ArrayList(u8), @@ -81,19 +81,18 @@ pub const SaprusMessage = union(SaprusPacketType) { // At this point, payload_list contains the base64 encoded payload. - // Write the packet body to the output buf. - try buf.*.appendSlice(asBytes(&nativeToBig(u16, @intCast(payload_list.items.len)))); - - // Write the header bytes to the output buf. - const HeaderInt = @typeInfo(Header).@"struct".backing_integer.?; - std.mem.writePackedInt( - HeaderInt, - try buf.*.addManyAsSlice(@bitSizeOf(Header) / 8), - 0, - @bitCast(header), - .little, + // Add the payload length to the output buf. + try buf.*.appendSlice( + asBytes(&nativeToBig(u16, @intCast(payload_list.items.len + @bitSizeOf(Header) / 8))), ); + // Add the header bytes to the output buf. + var header_buf: [@sizeOf(Header)]u8 = undefined; + var header_buf_stream = std.io.fixedBufferStream(&header_buf); + try header_buf_stream.writer().writeStructEndian(header, .big); + // Add the exact number of bits in the header without padding. + try buf.*.appendSlice(header_buf[0 .. @bitSizeOf(Header) / 8]); + try buf.*.appendSlice(payload_list.items); } @@ -101,6 +100,7 @@ pub const SaprusMessage = union(SaprusPacketType) { 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); + errdefer buf.deinit(); // Start with writing the message type, which is the first 16 bits of every Saprus message. try buf.appendSlice(asBytes(&nativeToBig(u16, @intFromEnum(self)))); @@ -116,17 +116,21 @@ pub const SaprusMessage = union(SaprusPacketType) { return buf.toOwnedSlice(); } - inline fn fromBytesAux( - packet: SaprusPacketType, + fn fromBytesAux( + comptime packet: SaprusPacketType, Header: type, r: std.io.FixedBufferStream([]const u8).Reader, allocator: Allocator, ) !SaprusMessage { - // Read the header for the current message type. - const header = try r.readStructEndian(Header, .big); // Read the length of the base64 encoded payload. const len = try r.readInt(u16, .big); + // Read the header for the current message type. + var header_bytes: [@sizeOf(Header)]u8 = undefined; + _ = try r.read(header_bytes[0 .. @bitSizeOf(Header) / 8]); + var header_stream = std.io.fixedBufferStream(&header_bytes); + const header = try header_stream.reader().readStructEndian(Header, .big); + // Read the base64 bytes into a list to be able to call the decoder on it. var payload_buf = std.ArrayList(u8).init(allocator); defer payload_buf.deinit(); |