// // MPDClient+Songs.swift // Persephone // // Created by Daniel Barber on 2019/7/19. // Copyright © 2019 Dan Barber. All rights reserved. // import Foundation import mpdclient extension MPDClient { func fetchAlbumArt(song: MPDSong, callback: @escaping (Data?) -> Void) { enqueueCommand( command: .fetchAlbumArt, userData: ["song": song, "callback": callback] ) } func searchSongs(_ terms: [MPDClient.MPDTag: String]) -> [MPDSong] { var songs: [MPDSong] = [] mpd_search_db_songs(self.connection, true) for (tag, term) in terms { mpd_search_add_tag_constraint(self.connection, MPD_OPERATOR_DEFAULT, tag.mpdTag(), term) } mpd_search_commit(self.connection) while let song = mpd_recv_song(self.connection) { songs.append(MPDSong(song)) } return songs } func sendFetchAlbumArt(for song: MPDSong, callback: @escaping (Data?) -> Void) -> Void { var imageData: Data? var currentOffset: Int32 = 0 var size: Int? while size == nil || currentOffset < size! { mpd_send_albumart(self.connection, song.uri, String(currentOffset)) guard let sizePair = mpd_recv_pair(self.connection) else { mpd_connection_clear_error(self.connection) return } size = Int(MPDPair(sizePair).value) mpd_return_pair(self.connection, sizePair) if imageData == nil { imageData = Data(count: size!) } let binaryPair = MPDPair(mpd_recv_pair(self.connection)) let chunkSize = Int(binaryPair.value)! mpd_return_pair(self.connection, binaryPair.pair) _ = imageData![currentOffset...].withUnsafeMutableBytes { (pointer) in mpd_recv_binary(self.connection, pointer, chunkSize) } guard mpd_response_finish(self.connection) else { return } currentOffset += Int32(chunkSize) } DispatchQueue.main.async { callback(imageData) } } }