Changes
1 changed files (+29/-20)
-
-
@@ -21,13 +21,25 @@ const sood = @import("sood");/// Data required to connect to a Roon Server pub const Server = struct { /// Pointer for the buffer used in this struct's slice fields. message: []const u8, ip_addr: std.net.Address, unique_id: []const u8, name: []const u8, version: []const u8, pub fn clone(self: Server, allocator: std.mem.Allocator) std.mem.Allocator.Error!Server { return Server{ .ip_addr = self.ip_addr, .unique_id = try allocator.dupe(u8, self.unique_id), .name = try allocator.dupe(u8, self.name), .version = try allocator.dupe(u8, self.version), }; } pub fn deinit(self: Server, allocator: std.mem.Allocator) void { allocator.free(self.unique_id); allocator.free(self.name); allocator.free(self.version); } pub fn jsonStringify(self: *const Server, jws: anytype) !void { try jws.beginObject();
-
@@ -121,35 +133,32 @@ var src: std.net.Address = undefined;var src_len: std.posix.socklen_t = dst.getOsSockLen(); while (true) { if (std.posix.recvfrom(self.sockfd, &received, 0, &src.any, &src_len)) |received_size| { // `received` will be invalidated after a loop or function exits. // Cloning the buffer so strings (e.g. `name`) can continue working. const message = try self.allocator.dupe(u8, received[0..received_size]); errdefer self.allocator.free(message); const response = sood.discovery.Response.parse(message) catch { const response = sood.discovery.Response.parse(received[0..received_size]) catch { // Non-SOOD message. Unlikely but technically possible. self.allocator.free(message); continue; }; const stale_message: ?[]const u8 = if (self.servers.get(response.unique_id)) |existing| existing.message else null; defer if (stale_message) |msg| { self.allocator.free(msg); const stale = self.servers.get(response.unique_id); defer if (stale) |server| { server.deinit(self.allocator); }; var ip_addr = src; ip_addr.setPort(response.http_port); try self.servers.put(response.unique_id, Server{ .message = message, const new = Server{ .unique_id = response.unique_id, .version = response.display_version, .name = response.name, .ip_addr = ip_addr, }); }; // Server's fields point to `received` buffer, which invalidates every UDP receive. // We have to copy the slices. const entry = try new.clone(self.allocator); errdefer entry.deinit(self.allocator); try self.servers.put(response.unique_id, entry); } else |err| switch (err) { std.posix.RecvFromError.WouldBlock => return, std.posix.RecvFromError.MessageTooBig => continue,
-
@@ -161,7 +170,7 @@pub fn deinit(self: *ServerScanner) void { var iter = self.servers.iterator(); while (iter.next()) |server| { self.allocator.free(server.value_ptr.message); server.value_ptr.deinit(self.allocator); } self.servers.deinit();
-