add comments!!!!!

This commit is contained in:
2025-04-03 17:09:40 -04:00
parent b1def25c69
commit e24220c98b

View File

@@ -2,6 +2,8 @@ const is_debug = builtin.mode == .Debug;
const base64Enc = std.base64.Base64Encoder.init(std.base64.standard_alphabet_chars, '='); const base64Enc = std.base64.Base64Encoder.init(std.base64.standard_alphabet_chars, '=');
const base64Dec = std.base64.Base64Decoder.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) { const SaprusPacketType = enum(u16) {
relay = 0x003C, relay = 0x003C,
file_transfer = 0x8888, file_transfer = 0x8888,
@@ -9,6 +11,8 @@ const SaprusPacketType = enum(u16) {
_, _,
}; };
/// Reserved option values.
/// Currently unused.
const SaprusConnectionOptions = packed struct(u8) { const SaprusConnectionOptions = packed struct(u8) {
opt1: bool = false, opt1: bool = false,
opt2: bool = false, opt2: bool = false,
@@ -25,6 +29,7 @@ const SaprusError = error{
UnknownSaprusType, UnknownSaprusType,
}; };
/// All Saprus messages
const SaprusMessage = union(SaprusPacketType) { const SaprusMessage = union(SaprusPacketType) {
const Relay = struct { const Relay = struct {
const Header = packed struct { const Header = packed struct {
@@ -49,6 +54,7 @@ const SaprusMessage = union(SaprusPacketType) {
file_transfer: void, // unimplemented file_transfer: void, // unimplemented
connection: Connection, 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 { fn deinit(self: SaprusMessage, allocator: Allocator) void {
switch (self) { switch (self) {
.relay => |r| allocator.free(r.payload), .relay => |r| allocator.free(r.payload),
@@ -64,27 +70,39 @@ const SaprusMessage = union(SaprusPacketType) {
w: std.ArrayList(u8).Writer, w: std.ArrayList(u8).Writer,
allocator: Allocator, allocator: Allocator,
) !void { ) !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); var payload_list = std.ArrayList(u8).init(allocator);
defer payload_list.deinit(); defer payload_list.deinit();
const buf_w = payload_list.writer(); const buf_w = payload_list.writer();
// Write the payload bytes as base64 to the growable string.
try base64Enc.encodeWriter(buf_w, payload); try base64Enc.encodeWriter(buf_w, payload);
// Write the packet body to the output writer.
try w.writeStructEndian(header, .big); try w.writeStructEndian(header, .big);
try w.writeInt(u16, @intCast(payload_list.items.len), .big); try w.writeInt(u16, @intCast(payload_list.items.len), .big);
try w.writeAll(payload_list.items); try w.writeAll(payload_list.items);
} }
/// Caller is responsible for freeing the returned bytes.
fn toBytes(self: SaprusMessage, allocator: Allocator) ![]u8 { 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); var buf = std.ArrayList(u8).init(allocator);
// Create a writer for an easy interface to append arbitrary bytes.
const w = buf.writer(); 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 w.writeInt(u16, @intFromEnum(self), .big);
// Write the proper header and payload for the given packet type.
switch (self) { switch (self) {
.relay => |r| try toBytesAux(Relay.Header, r.header, r.payload, w, allocator), .relay => |r| try toBytesAux(Relay.Header, r.header, r.payload, w, allocator),
.connection => |c| try toBytesAux(Connection.Header, c.header, c.payload, w, allocator), .connection => |c| try toBytesAux(Connection.Header, c.header, c.payload, w, allocator),
.file_transfer => return SaprusError.NotImplementedSaprusType, .file_transfer => return SaprusError.NotImplementedSaprusType,
} }
// Collect the growable list as a slice and return it.
return buf.toOwnedSlice(); return buf.toOwnedSlice();
} }
@@ -94,22 +112,28 @@ const SaprusMessage = union(SaprusPacketType) {
r: std.io.FixedBufferStream([]const u8).Reader, r: std.io.FixedBufferStream([]const u8).Reader,
allocator: Allocator, allocator: Allocator,
) !SaprusMessage { ) !SaprusMessage {
// Read the header for the current message type.
const header = try r.readStructEndian(Header, .big); const header = try r.readStructEndian(Header, .big);
// Read the length of the base64 encoded payload.
const len = try r.readInt(u16, .big); 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); var payload_buf = std.ArrayList(u8).init(allocator);
defer payload_buf.deinit(); defer payload_buf.deinit();
try r.readAllArrayList(&payload_buf, len); 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)); const payload = try allocator.alloc(u8, try base64Dec.calcSizeForSlice(payload_buf.items));
try base64Dec.decode(payload, 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), .{ return @unionInit(SaprusMessage, @tagName(packet), .{
.header = header, .header = header,
.payload = payload, .payload = payload,
}); });
} }
/// Caller is responsible for calling .deinit on the returned value.
fn fromBytes(bytes: []const u8, allocator: Allocator) !SaprusMessage { fn fromBytes(bytes: []const u8, allocator: Allocator) !SaprusMessage {
var s = std.io.fixedBufferStream(bytes); var s = std.io.fixedBufferStream(bytes);
const r = s.reader(); const r = s.reader();