summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorRobby Zambito <contact@robbyzambito.me>2025-04-05 13:46:47 -0400
committerRobby Zambito <contact@robbyzambito.me>2025-04-06 13:08:09 -0400
commit3c935698aac68b081aaa62ef5473a194477e2578 (patch)
tree7d638d376422b1a0dcfe38cf124bfb2a0ada490c /src
parentbc75e869043e84f11a3aae6d3d228beff9a34be6 (diff)
Correctly handle the endiness and packedness of the the header reading and writing
Diffstat (limited to 'src')
-rw-r--r--src/saprus_message.zig36
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();