@@ -67,12 +67,23 @@ export fn message_begin(len: usize) [*]u8 {
export fn message_end() void {
const msg_bytes = message_buffer.items;
const header: protocol.Header = @bitCast(msg_bytes[0..@sizeOf(protocol.Header)].*);
const files_start = @sizeOf(protocol.Header);
const Tag = protocol.ToClientTag;
switch (msg_bytes[0]) {
@intFromEnum(Tag.full_library) => return fullLibraryMessage(msg_bytes) catch @panic("OOM"),
@intFromEnum(Tag.play_queue) => return playQueueMessage(msg_bytes) catch @panic("OOM"),
else => unreachable,
}
}
fn fullLibraryMessage(msg_bytes: []u8) error{OutOfMemory}!void {
const Header = protocol.FullLibraryHeader;
const header: Header = @bitCast(msg_bytes[0..@sizeOf(Header)].*);
const files_start = @sizeOf(Header);
const files_end = files_start + header.files_len * @sizeOf(Db.File);
const directories_start = files_end;
const directories_end = directories_start + header.directories_len * @sizeOf(Db.Path);
const directories_end = directories_start + header.flags.directories_len * @sizeOf(Db.Path);
const albums_start = directories_end;
const albums_end = albums_start + header.albums_len * @sizeOf(Db.Album);
const string_bytes = msg_bytes[albums_end..][0..header.string_bytes_len];
@@ -80,7 +91,41 @@ export fn message_end() void {
const files: []const Db.File = @alignCast(std.mem.bytesAsSlice(Db.File, msg_bytes[files_start..files_end]));
const directories: []const Db.Path = @alignCast(std.mem.bytesAsSlice(Db.Path, msg_bytes[directories_start..directories_end]));
const albums: []const Db.Album = @alignCast(std.mem.bytesAsSlice(Db.Album, msg_bytes[albums_start..albums_end]));
updateDb(files, directories, albums, string_bytes) catch @panic("OOM");
try updateDb(files, directories, albums, string_bytes);
}
fn playQueueMessage(msg_bytes: []u8) error{OutOfMemory}!void {
const Header = protocol.PlayQueueHeader;
const header: Header = @bitCast(msg_bytes[0..@sizeOf(Header)].*);
const removed_start = @sizeOf(Header);
const removed_end = removed_start + header.removed_items_len * @sizeOf(Db.QueueItem.Id);
const added_start = removed_end;
const added_end = added_start + header.added_items_len * @sizeOf(Db.QueueItem);
const removed: []const Db.QueueItem.Id =
@alignCast(std.mem.bytesAsSlice(Db.QueueItem.Id, msg_bytes[removed_start..removed_end]));
const added: []const Db.QueueItem =
@alignCast(std.mem.bytesAsSlice(Db.QueueItem, msg_bytes[added_start..added_end]));
for (removed) |id| {
_ = db.queue_items.swapRemove(.{
.id = id,
.flags = undefined,
.file = undefined,
});
}
switch (added.len) {
0 => {},
1 => try db.queue_items.put(gpa, added[0], {}),
else => {
const old_len = db.queue_items.entries.len;
try db.queue_items.entries.resize(gpa, old_len + added.len);
@memcpy(db.queue_items.entries.items(.key)[old_len..], added);
try db.queue_items.reIndex(gpa);
},
}
}
fn updateDb(