From c673401c2ad1c463153fe4dd7f2eb400459896b6 Mon Sep 17 00:00:00 2001 From: Robby Zambito Date: Tue, 9 Sep 2025 22:27:09 -0400 Subject: Use writer instead of RawSocket in Client --- src/RawSocketWriter.zig | 45 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) create mode 100644 src/RawSocketWriter.zig (limited to 'src/RawSocketWriter.zig') diff --git a/src/RawSocketWriter.zig b/src/RawSocketWriter.zig new file mode 100644 index 0000000..dfbb874 --- /dev/null +++ b/src/RawSocketWriter.zig @@ -0,0 +1,45 @@ +const std = @import("std"); +const gcat = @import("gatorcat"); +const Writer = @This(); +const assert = std.debug.assert; + +interface: std.Io.Writer, +socket: gcat.nic.RawSocket, +alloc: std.mem.Allocator, + +fn drain(io_w: *std.Io.Writer, data: []const []const u8, splat: usize) std.Io.Writer.Error!usize { + const w: *Writer = @alignCast(@fieldParentPtr("interface", io_w)); + const buffered = io_w.buffered(); + var res: usize = 0; + if (buffered.len > 0) { + w.socket.linkLayer().send(buffered) catch return error.WriteFailed; + _ = io_w.consumeAll(); + } + + for (data[0 .. data.len - 1]) |d| { + w.socket.linkLayer().send(d) catch return error.WriteFailed; + res += d.len; + } + + if (splat > 0 and data[data.len - 1].len > 0) { + var splatBuffer: std.ArrayList(u8) = .empty; + defer splatBuffer.deinit(w.alloc); + for (0..splat) |_| { + splatBuffer.appendSlice(w.alloc, data[data.len - 1]) catch return error.WriteFailed; + } + w.socket.linkLayer().send(splatBuffer.items) catch return error.WriteFailed; + } + + return res; +} + +pub fn init(interface_name: [:0]const u8, buffer: []u8, alloc: std.mem.Allocator) !Writer { + return .{ + .interface = .{ + .vtable = &.{ .drain = drain }, + .buffer = buffer, + }, + .socket = try .init(interface_name), + .alloc = alloc, + }; +} -- cgit