summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRobby Zambito <contact@robbyzambito.me>2025-04-03 17:09:40 -0400
committerRobby Zambito <contact@robbyzambito.me>2025-04-03 17:09:46 -0400
commite402970ab2f8887b6314469359508c5890d090d9 (patch)
treeb57f656d4d3fe55fbb936e1cc7cab58c9e064ea9
parent797624377a465766b396fb9a3d37d0a4e379e238 (diff)
add comments!!!!!
-rw-r--r--src/main.zig24
1 files changed, 24 insertions, 0 deletions
diff --git a/src/main.zig b/src/main.zig
index e0674d4..9a0b8a4 100644
--- a/src/main.zig
+++ b/src/main.zig
@@ -2,6 +2,8 @@ const is_debug = builtin.mode == .Debug;
const base64Enc = std.base64.Base64Encoder.init(std.base64.standard_alphabet_chars, '=');
const base64Dec = std.base64.Base64Decoder.init(std.base64.standard_alphabet_chars, '=');
+/// Type tag for SaprusMessage union.
+/// This is the first value in the actual packet sent over the network.
const SaprusPacketType = enum(u16) {
relay = 0x003C,
file_transfer = 0x8888,
@@ -9,6 +11,8 @@ const SaprusPacketType = enum(u16) {
_,
};
+/// Reserved option values.
+/// Currently unused.
const SaprusConnectionOptions = packed struct(u8) {
opt1: bool = false,
opt2: bool = false,
@@ -25,6 +29,7 @@ const SaprusError = error{
UnknownSaprusType,
};
+/// All Saprus messages
const SaprusMessage = union(SaprusPacketType) {
const Relay = struct {
const Header = packed struct {
@@ -49,6 +54,7 @@ const SaprusMessage = union(SaprusPacketType) {
file_transfer: void, // unimplemented
connection: Connection,
+ /// Should be called for any SaprusMessage that was declared using a function that you pass an allocator to.
fn deinit(self: SaprusMessage, allocator: Allocator) void {
switch (self) {
.relay => |r| allocator.free(r.payload),
@@ -64,27 +70,39 @@ const SaprusMessage = union(SaprusPacketType) {
w: std.ArrayList(u8).Writer,
allocator: Allocator,
) !void {
+ // Create a growable string to store the base64 bytes in.
+ // Doing this first so I can use the length of the encoded bytes for the length field.
var payload_list = std.ArrayList(u8).init(allocator);
defer payload_list.deinit();
const buf_w = payload_list.writer();
+
+ // 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.writeStructEndian(header, .big);
try w.writeInt(u16, @intCast(payload_list.items.len), .big);
try w.writeAll(payload_list.items);
}
+ /// Caller is responsible for freeing the returned bytes.
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);
+ // 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),
.file_transfer => return SaprusError.NotImplementedSaprusType,
}
+ // Collect the growable list as a slice and return it.
return buf.toOwnedSlice();
}
@@ -94,22 +112,28 @@ const SaprusMessage = union(SaprusPacketType) {
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 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();
try r.readAllArrayList(&payload_buf, len);
+ // Create a buffer to store the payload in, and decode the base64 bytes into the payload field.
const payload = try allocator.alloc(u8, try base64Dec.calcSizeForSlice(payload_buf.items));
try base64Dec.decode(payload, payload_buf.items);
+ // Return the type of SaprusMessage specified by the `packet` argument.
return @unionInit(SaprusMessage, @tagName(packet), .{
.header = header,
.payload = payload,
});
}
+ /// Caller is responsible for calling .deinit on the returned value.
fn fromBytes(bytes: []const u8, allocator: Allocator) !SaprusMessage {
var s = std.io.fixedBufferStream(bytes);
const r = s.reader();