diff --git a/Cargo.lock b/Cargo.lock index 5f42547d..123eb889 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2,27 +2,51 @@ name = "librespot" version = "0.1.0" dependencies = [ - "byteorder 0.3.11 (registry+https://github.com/rust-lang/crates.io-index)", - "getopts 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", + "bit-set 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "byteorder 0.3.13 (registry+https://github.com/rust-lang/crates.io-index)", + "clippy 0.0.12 (git+https://github.com/Manishearth/rust-clippy.git)", + "eventual 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", + "getopts 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)", "librespot-protocol 0.1.0", "mod_path 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", - "num 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", + "num 0.1.27 (registry+https://github.com/rust-lang/crates.io-index)", "portaudio 0.1.2 (git+https://github.com/mvdnes/portaudio-rs)", "protobuf 1.0.1 (git+https://github.com/plietar/rust-protobuf.git)", "protobuf_macros 0.1.0 (git+https://github.com/plietar/rust-protobuf-macros.git)", - "rand 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", - "readall 0.1.0 (git+https://github.com/plietar/rust-readall.git)", + "rand 0.3.11 (registry+https://github.com/rust-lang/crates.io-index)", "rpassword 0.0.5 (registry+https://github.com/rust-lang/crates.io-index)", "rust-crypto 0.2.31 (registry+https://github.com/rust-lang/crates.io-index)", "rust-gmp 0.2.0 (git+https://github.com/plietar/rust-gmp.git)", "shannon 0.1.0 (git+https://github.com/plietar/rust-shannon.git)", - "tempfile 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "time 0.1.30 (registry+https://github.com/rust-lang/crates.io-index)", - "vergen 0.0.13 (registry+https://github.com/rust-lang/crates.io-index)", - "vorbis 0.0.11 (git+https://github.com/plietar/vorbis-rs)", + "tempfile 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "time 0.1.32 (registry+https://github.com/rust-lang/crates.io-index)", + "vergen 0.0.16 (registry+https://github.com/rust-lang/crates.io-index)", + "vorbis 0.0.12 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "advapi32-sys" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "winapi 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "bit-set" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "bit-vec 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "bit-vec" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "bitflags" version = "0.1.1" @@ -35,39 +59,55 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "byteorder" -version = "0.3.11" +version = "0.3.13" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] -name = "gcc" -version = "0.3.8" -source = "registry+https://github.com/rust-lang/crates.io-index" +name = "clippy" +version = "0.0.12" +source = "git+https://github.com/Manishearth/rust-clippy.git#d3da9f6c81dd3e026bd679c09cea1d6b337ccd25" [[package]] -name = "getopts" -version = "0.2.11" +name = "eventual" +version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "log 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", + "syncbox 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", + "time 0.1.32 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] -name = "kernel32-sys" -version = "0.1.2" +name = "gcc" +version = "0.3.13" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "winapi 0.1.23 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi-build 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "advapi32-sys 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "getopts" +version = "0.2.14" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "kernel32-sys" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "winapi 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "lazy_static" -version = "0.1.11" +version = "0.1.14" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "libc" -version = "0.1.8" +version = "0.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -80,10 +120,10 @@ dependencies = [ [[package]] name = "log" -version = "0.3.1" +version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -93,11 +133,11 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "num" -version = "0.1.25" +version = "0.1.27" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "rand 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc-serialize 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.3.11 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-serialize 0.3.16 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -105,8 +145,8 @@ name = "ogg-sys" version = "0.0.9" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "gcc 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", + "gcc 0.3.13 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", "pkg-config 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -121,7 +161,7 @@ version = "0.1.2" source = "git+https://github.com/mvdnes/portaudio-rs#7c6d10f5edda0094cc33b682d88c3a6ea4919b9f" dependencies = [ "bitflags 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", "portaudio_sys 0.1.0 (git+https://github.com/mvdnes/portaudio-rs)", ] @@ -130,7 +170,7 @@ name = "portaudio_sys" version = "0.1.0" source = "git+https://github.com/mvdnes/portaudio-rs#7c6d10f5edda0094cc33b682d88c3a6ea4919b9f" dependencies = [ - "libc 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", "pkg-config 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -142,14 +182,16 @@ source = "git+https://github.com/plietar/rust-protobuf.git#dae87e292a52a66da7f78 [[package]] name = "protobuf_macros" version = "0.1.0" -source = "git+https://github.com/plietar/rust-protobuf-macros.git#3b49de3937a34b7a21be1d13caea4348a93c6de4" +source = "git+https://github.com/plietar/rust-protobuf-macros.git#2b6a8129e015945300cb2bb7efae2ed78042ed48" [[package]] name = "rand" -version = "0.3.8" +version = "0.3.11" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", + "advapi32-sys 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -162,10 +204,10 @@ name = "rpassword" version = "0.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "kernel32-sys 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", + "kernel32-sys 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", "termios 0.0.5 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -173,24 +215,24 @@ name = "rust-crypto" version = "0.2.31" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "gcc 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc-serialize 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)", - "time 0.1.30 (registry+https://github.com/rust-lang/crates.io-index)", + "gcc 0.3.13 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.3.11 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-serialize 0.3.16 (registry+https://github.com/rust-lang/crates.io-index)", + "time 0.1.32 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "rust-gmp" version = "0.2.0" -source = "git+https://github.com/plietar/rust-gmp.git#cc003c224559f6035cd34a7ed5c6284a49785816" +source = "git+https://github.com/plietar/rust-gmp.git#d1bb4448fdbfa2505edadb83b6aac6257fe08ba2" dependencies = [ - "num 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", + "num 0.1.27 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "rustc-serialize" -version = "0.3.15" +version = "0.3.16" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -198,7 +240,7 @@ name = "shannon" version = "0.1.0" source = "git+https://github.com/plietar/rust-shannon.git#c6be8a879a523a77d81c50df46faa891b76fea25" dependencies = [ - "byteorder 0.3.11 (registry+https://github.com/rust-lang/crates.io-index)", + "byteorder 0.3.13 (registry+https://github.com/rust-lang/crates.io-index)", "readall 0.1.0 (git+https://github.com/plietar/rust-readall.git)", "shannon-sys 0.1.0 (git+https://github.com/plietar/rust-shannon.git)", ] @@ -208,18 +250,27 @@ name = "shannon-sys" version = "0.1.0" source = "git+https://github.com/plietar/rust-shannon.git#c6be8a879a523a77d81c50df46faa891b76fea25" dependencies = [ - "gcc 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", + "gcc 0.3.13 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "syncbox" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "log 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", + "time 0.1.32 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "tempfile" -version = "1.0.0" +version = "1.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "kernel32-sys 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.1.23 (registry+https://github.com/rust-lang/crates.io-index)", + "kernel32-sys 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.3.11 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -227,34 +278,34 @@ name = "termios" version = "0.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "time" -version = "0.1.30" +version = "0.1.32" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "kernel32-sys 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.1.23 (registry+https://github.com/rust-lang/crates.io-index)", + "kernel32-sys 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "vergen" -version = "0.0.13" +version = "0.0.16" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "bitflags 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", - "time 0.1.30 (registry+https://github.com/rust-lang/crates.io-index)", + "time 0.1.32 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "vorbis" -version = "0.0.11" -source = "git+https://github.com/plietar/vorbis-rs#78058c3341832969030f49cbc4b8bc9deb376776" +version = "0.0.12" +source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", "ogg-sys 0.0.9 (registry+https://github.com/rust-lang/crates.io-index)", "vorbis-sys 0.0.8 (registry+https://github.com/rust-lang/crates.io-index)", "vorbisfile-sys 0.0.8 (registry+https://github.com/rust-lang/crates.io-index)", @@ -265,8 +316,8 @@ name = "vorbis-sys" version = "0.0.8" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "gcc 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", + "gcc 0.3.13 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", "ogg-sys 0.0.9 (registry+https://github.com/rust-lang/crates.io-index)", "pkg-config 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -276,8 +327,8 @@ name = "vorbisfile-sys" version = "0.0.8" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "gcc 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", + "gcc 0.3.13 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", "ogg-sys 0.0.9 (registry+https://github.com/rust-lang/crates.io-index)", "pkg-config 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", "vorbis-sys 0.0.8 (registry+https://github.com/rust-lang/crates.io-index)", @@ -285,19 +336,11 @@ dependencies = [ [[package]] name = "winapi" -version = "0.1.23" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "libc 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "winapi" -version = "0.2.1" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "winapi-build" -version = "0.1.0" +version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" diff --git a/Cargo.toml b/Cargo.toml index 92aeb381..33db5954 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -16,17 +16,22 @@ path = "src/main.rs" path = "protocol" [dependencies] -mod_path = "*" -byteorder = "*" -num = "*" -rand = "*" -lazy_static = "0.1.*" -rust-crypto = "*" -time = "*" -tempfile = "*" -rpassword = "*" -getopts = "0.2.4" +bit-set = "~0.2.0" +byteorder = "~0.3.13" +eventual = "~0.1.4" +getopts = "~0.2.14" +lazy_static = "~0.1.14" +mod_path = "~0.1.5" +num = "~0.1.27" +rand = "~0.3.11" +rpassword = "~0.0.5" +rust-crypto = "~0.2.31" +time = "~0.1.32" +tempfile = "~1.1.1" +vorbis = "~0.0.12" +[dependencies.clippy] +git = "https://github.com/Manishearth/rust-clippy.git" [dependencies.protobuf] git = "https://github.com/plietar/rust-protobuf.git" [dependencies.protobuf_macros] @@ -35,12 +40,9 @@ git = "https://github.com/plietar/rust-protobuf-macros.git" git = "https://github.com/plietar/rust-gmp.git" [dependencies.shannon] git = "https://github.com/plietar/rust-shannon.git" -[dependencies.readall] -git = "https://github.com/plietar/rust-readall.git" [dependencies.portaudio] git = "https://github.com/mvdnes/portaudio-rs" -[dependencies.vorbis] -git = "https://github.com/plietar/vorbis-rs" [build-dependencies] -vergen = "*" +vergen = "~0.0.16" + diff --git a/src/audio_file.rs b/src/audio_file.rs index 2e1f0ee0..910e322a 100644 --- a/src/audio_file.rs +++ b/src/audio_file.rs @@ -1,6 +1,6 @@ +use bit_set::BitSet; use byteorder::{ByteOrder, BigEndian}; use std::cmp::min; -use std::collections::BitSet; use std::sync::{Arc, Condvar, Mutex}; use std::sync::mpsc::{self, TryRecvError}; use std::thread; @@ -9,27 +9,24 @@ use std::io::{self, Read, Write, Seek, SeekFrom}; use std::path::PathBuf; use tempfile::TempFile; -use stream::StreamEvent; use util::{FileId, IgnoreExt, ZeroFile, mkdir_existing}; use session::Session; +use stream::StreamEvent; const CHUNK_SIZE : usize = 0x20000; -pub enum AudioFile<'s> { +pub enum AudioFile { Direct(fs::File), - Loading(AudioFileLoading<'s>) + Loading(AudioFileLoading) } -pub struct AudioFileLoading<'s> { +pub struct AudioFileLoading { read_file: TempFile, position: u64, seek: mpsc::Sender, shared: Arc, - - #[allow(dead_code)] - thread: thread::JoinGuard<'s, ()>, } struct AudioFileShared { @@ -40,7 +37,7 @@ struct AudioFileShared { bitmap: Mutex, } -impl <'s> AudioFileLoading<'s> { +impl AudioFileLoading { fn new(session: &Session, file_id: FileId) -> AudioFileLoading { let mut files_iter = TempFile::shared(2).unwrap().into_iter(); let read_file = files_iter.next().unwrap(); @@ -70,17 +67,20 @@ impl <'s> AudioFileLoading<'s> { let (seek_tx, seek_rx) = mpsc::channel(); + let _shared = shared.clone(); + let _session = session.clone(); + + thread::spawn(move || { + AudioFileLoading::fetch(&_session, _shared, write_file, seek_rx) + }); + AudioFileLoading { read_file: read_file, position: 0, seek: seek_tx, - shared: shared.clone(), - - thread: thread::scoped(move || { - AudioFileLoading::fetch(session, shared, write_file, seek_rx) - }) + shared: shared } } @@ -155,7 +155,7 @@ impl <'s> AudioFileLoading<'s> { } } -impl <'s> Read for AudioFileLoading<'s> { +impl Read for AudioFileLoading { fn read(&mut self, output: &mut [u8]) -> io::Result { let index = self.position as usize / CHUNK_SIZE; let offset = self.position as usize % CHUNK_SIZE; @@ -167,15 +167,15 @@ impl <'s> Read for AudioFileLoading<'s> { } drop(bitmap); - let len = try!(self.read_file.read(&mut output[..len])); + let read_len = try!(self.read_file.read(&mut output[..len])); - self.position += len as u64; + self.position += read_len as u64; - Ok(len) + Ok(read_len) } } -impl <'s> Seek for AudioFileLoading<'s> { +impl Seek for AudioFileLoading { fn seek(&mut self, pos: SeekFrom) -> io::Result { self.position = try!(self.read_file.seek(pos)); @@ -189,7 +189,7 @@ impl <'s> Seek for AudioFileLoading<'s> { } } -impl <'s> Read for AudioFile<'s> { +impl Read for AudioFile { fn read(&mut self, output: &mut [u8]) -> io::Result { match *self { AudioFile::Direct(ref mut file) => file.read(output), @@ -198,7 +198,7 @@ impl <'s> Read for AudioFile<'s> { } } -impl <'s> Seek for AudioFile<'s> { +impl Seek for AudioFile { fn seek(&mut self, pos: io::SeekFrom) -> io::Result { match *self { AudioFile::Direct(ref mut file) => file.seek(pos), @@ -215,7 +215,7 @@ impl AudioFileManager { pub fn cache_dir(session: &Session, file_id: FileId) -> PathBuf { let name = file_id.to_base16(); - session.config.cache_location.join(&name[0..2]) + session.0.config.cache_location.join(&name[0..2]) } pub fn cache_path(session: &Session, file_id: FileId) -> PathBuf { @@ -223,7 +223,7 @@ impl AudioFileManager { AudioFileManager::cache_dir(session, file_id).join(&name[2..]) } - pub fn request<'a> (&mut self, session: &'a Session, file_id: FileId) -> AudioFile<'a> { + pub fn request (&mut self, session: &Session, file_id: FileId) -> AudioFile { match fs::File::open(AudioFileManager::cache_path(session, file_id)) { Ok(f) => AudioFile::Direct(f), Err(..) => AudioFile::Loading(AudioFileLoading::new(session, file_id)) diff --git a/src/audio_key.rs b/src/audio_key.rs index b1f1bb63..bdd5db1a 100644 --- a/src/audio_key.rs +++ b/src/audio_key.rs @@ -1,11 +1,10 @@ -use std::collections::{HashMap, LinkedList}; -use std::sync::{mpsc, Future}; -use std::io::{Cursor, Write}; use byteorder::{BigEndian, ByteOrder, ReadBytesExt, WriteBytesExt}; -use readall::ReadAllExt; +use eventual; +use std::collections::HashMap; +use std::io::{Cursor, Read, Write}; use std::mem; -use util::{SpotifyId, FileId, IgnoreExt}; +use util::{SpotifyId, FileId}; use session::Session; use connection::PacketHandler; @@ -15,7 +14,7 @@ pub type AudioKey = [u8; 16]; struct AudioKeyId(SpotifyId, FileId); enum AudioKeyStatus { - Loading(LinkedList>), + Loading(Vec>), Loaded(AudioKey) } @@ -35,17 +34,17 @@ impl AudioKeyManager { } pub fn request(&mut self, session: &Session, track: SpotifyId, file: FileId) - -> Future { + -> eventual::Future { let id = AudioKeyId(track, file); - self.cache.get_mut(&id).map(|status| match status { - &mut AudioKeyStatus::Loaded(key) => { - Future::from_value(key.clone()) + self.cache.get_mut(&id).map(|status| match *status { + AudioKeyStatus::Loaded(key) => { + eventual::Future::of(key.clone()) } - &mut AudioKeyStatus::Loading(ref mut req) => { - let (tx, rx) = mpsc::channel(); - req.push_front(tx); - Future::from_receiver(rx) + AudioKeyStatus::Loading(ref mut req) => { + let (tx, rx) = eventual::Future::pair(); + req.push(tx); + rx } }).unwrap_or_else(|| { let seq = self.next_seq; @@ -61,11 +60,9 @@ impl AudioKeyManager { self.pending.insert(seq, id.clone()); - let (tx, rx) = mpsc::channel(); - let mut req = LinkedList::new(); - req.push_front(tx); - self.cache.insert(id, AudioKeyStatus::Loading(req)); - Future::from_receiver(rx) + let (tx, rx) = eventual::Future::pair(); + self.cache.insert(id, AudioKeyStatus::Loading(vec!{ tx })); + rx }) } } @@ -77,14 +74,14 @@ impl PacketHandler for AudioKeyManager { let mut data = Cursor::new(data); let seq = data.read_u32::().unwrap(); let mut key = [0u8; 16]; - data.read_all(&mut key).unwrap(); + data.read_exact(&mut key).unwrap(); if let Some(status) = self.pending.remove(&seq).and_then(|id| { self.cache.get_mut(&id) }) { let status = mem::replace(status, AudioKeyStatus::Loaded(key)); if let AudioKeyStatus::Loading(cbs) = status { for cb in cbs { - cb.send(key).ignore(); + cb.complete(key); } } } diff --git a/src/connection.rs b/src/connection.rs index 704a6395..b299efdf 100644 --- a/src/connection.rs +++ b/src/connection.rs @@ -1,9 +1,8 @@ use byteorder::{self, BigEndian, ByteOrder, ReadBytesExt, WriteBytesExt}; -use readall::ReadAllExt; use shannon::ShannonStream; use std::convert; use std::io; -use std::io::Write; +use std::io::{Read, Write}; use std::net::TcpStream; use std::result; @@ -70,7 +69,7 @@ impl PlainConnection { let mut buffer = vec![0u8; size]; BigEndian::write_u32(&mut buffer, size as u32); - try!(self.stream.read_all(&mut buffer[4..])); + try!(self.stream.read_exact(&mut buffer[4..])); Ok(buffer) } @@ -98,7 +97,7 @@ impl CipherConnection { let size = try!(self.stream.read_u16::()) as usize; let mut data = vec![0; size]; - try!(self.stream.read_all(&mut data)); + try!(self.stream.read_exact(&mut data)); try!(self.stream.finish_recv()); diff --git a/src/lib.rs b/src/lib.rs index 0ef28231..bed46057 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,25 +1,25 @@ #![crate_name = "librespot"] -#![feature(plugin,scoped,zero_one,iter_arith,slice_position_elem,slice_bytes,bitset,arc_weak,append,future,mpsc_select)] -#![allow(deprecated)] -//#![allow(unused_imports,dead_code)] +#![feature(plugin,read_exact,zero_one,iter_arith,slice_bytes,arc_weak,append,mpsc_select)] +#![allow(needless_return)] +#![plugin(clippy)] #![plugin(protobuf_macros)] #[macro_use] extern crate lazy_static; - +extern crate bit_set; extern crate byteorder; extern crate crypto; +extern crate eventual; extern crate gmp; extern crate num; extern crate portaudio; extern crate protobuf; extern crate shannon; extern crate rand; -extern crate readall; -extern crate vorbis; extern crate time; extern crate tempfile; +extern crate vorbis; extern crate librespot_protocol; diff --git a/src/main.rs b/src/main.rs index 9284f4fd..87714529 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,4 +1,3 @@ -#![feature(scoped)] #![feature(result_expect)] #![allow(deprecated)] @@ -71,9 +70,10 @@ fn main() { session.login(username.clone(), password); session.poll(); - let poll_thread = thread::scoped(|| { + let _session = session.clone(); + thread::spawn(move || { loop { - session.poll(); + _session.poll(); } }); @@ -81,7 +81,5 @@ fn main() { let mut spirc_manager = SpircManager::new(&session, player, username, name); spirc_manager.run(); - - poll_thread.join(); } diff --git a/src/mercury.rs b/src/mercury.rs index b0d06c52..b905bfce 100644 --- a/src/mercury.rs +++ b/src/mercury.rs @@ -1,11 +1,10 @@ use byteorder::{BigEndian, ByteOrder, ReadBytesExt, WriteBytesExt}; +use eventual; use protobuf::{self, Message}; -use readall::ReadAllExt; -use std::collections::{HashMap, LinkedList}; +use std::collections::HashMap; use std::io::{Cursor, Read, Write}; -use std::fmt; use std::mem::replace; -use std::sync::{mpsc, Future}; +use std::sync::mpsc; use librespot_protocol as protocol; use session::Session; @@ -30,13 +29,13 @@ pub struct MercuryRequest { #[derive(Debug)] pub struct MercuryResponse { pub uri: String, - pub payload: LinkedList> + pub payload: Vec> } pub struct MercuryPending { - parts: LinkedList>, + parts: Vec>, partial: Option>, - callback: Option> + callback: Option> } pub struct MercuryManager { @@ -45,14 +44,14 @@ pub struct MercuryManager { subscriptions: HashMap>, } -impl fmt::Display for MercuryMethod { - fn fmt(&self, formatter: &mut fmt::Formatter) -> Result<(), fmt::Error> { - formatter.write_str(match *self { +impl ToString for MercuryMethod { + fn to_string(&self) -> String { + match *self { MercuryMethod::GET => "GET", MercuryMethod::SUB => "SUB", MercuryMethod::UNSUB => "UNSUB", MercuryMethod::SEND => "SEND" - }) + }.to_owned() } } @@ -66,7 +65,7 @@ impl MercuryManager { } pub fn request(&mut self, session: &Session, req: MercuryRequest) - -> Future { + -> eventual::Future { let mut seq = [0u8; 4]; BigEndian::write_u32(&mut seq, self.next_seq); @@ -81,14 +80,14 @@ impl MercuryManager { session.send_packet(cmd, &data).unwrap(); - let (tx, rx) = mpsc::channel(); + let (tx, rx) = eventual::Future::pair(); self.pending.insert(seq.to_vec(), MercuryPending{ - parts: LinkedList::new(), + parts: Vec::new(), partial: None, callback: Some(tx), }); - Future::from_receiver(rx) + rx } pub fn subscribe(&mut self, session: &Session, uri: String) @@ -109,33 +108,25 @@ impl MercuryManager { fn parse_part(mut s: &mut Read) -> Vec { let size = s.read_u16::().unwrap() as usize; let mut buffer = vec![0; size]; - s.read_all(&mut buffer).unwrap(); + s.read_exact(&mut buffer).unwrap(); buffer } fn complete_request(&mut self, cmd: u8, mut pending: MercuryPending) { - let header_data = match pending.parts.pop_front() { - Some(data) => data, - None => panic!("No header part !") - }; - + let header_data = pending.parts.remove(0); let header : protocol::mercury::Header = protobuf::parse_from_bytes(&header_data).unwrap(); - let callback = if cmd == 0xb5 { - self.subscriptions.get(header.get_uri()) - } else { - pending.callback.as_ref() + let response = MercuryResponse { + uri: header.get_uri().to_owned(), + payload: pending.parts }; - if let Some(ref ch) = callback { - // Ignore send error. - // It simply means the receiver was closed - ch.send(MercuryResponse{ - uri: header.get_uri().to_string(), - payload: pending.parts - }).ignore(); + if cmd == 0xb5 { + self.subscriptions.get(header.get_uri()).map(|ch| ch.send(response).ignore()); + } else { + pending.callback.map(|cb| cb.complete(response)); } } @@ -173,7 +164,7 @@ impl PacketHandler for MercuryManager { let seq = { let seq_length = packet.read_u16::().unwrap() as usize; let mut seq = vec![0; seq_length]; - packet.read_all(&mut seq).unwrap(); + packet.read_exact(&mut seq).unwrap(); seq }; let flags = packet.read_u8().unwrap(); @@ -183,7 +174,7 @@ impl PacketHandler for MercuryManager { pending } else if cmd == 0xb5 { MercuryPending { - parts: LinkedList::new(), + parts: Vec::new(), partial: None, callback: None, } @@ -202,7 +193,7 @@ impl PacketHandler for MercuryManager { if i == count - 1 && (flags == 2) { pending.partial = Some(part) } else { - pending.parts.push_back(part); + pending.parts.push(part); } } diff --git a/src/metadata.rs b/src/metadata.rs index 676aea7a..bb8e0d03 100644 --- a/src/metadata.rs +++ b/src/metadata.rs @@ -1,3 +1,4 @@ +use eventual::Async; use protobuf::{self, Message}; use std::any::{Any, TypeId}; use std::collections::HashMap; @@ -11,7 +12,7 @@ use mercury::{MercuryRequest, MercuryMethod}; use util::{SpotifyId, FileId}; use session::Session; -pub trait MetadataTrait : Send + Any + 'static { +pub trait MetadataTrait : Send + Sized + Any + 'static { type Message: protobuf::MessageStatic; fn from_msg(msg: &Self::Message) -> Self; fn base_url() -> &'static str; @@ -29,7 +30,7 @@ impl MetadataTrait for Track { type Message = protocol::metadata::Track; fn from_msg(msg: &Self::Message) -> Self { Track { - name: msg.get_name().to_string(), + name: msg.get_name().to_owned(), album: SpotifyId::from_raw(msg.get_album().get_gid()), files: msg.get_file().iter() .map(|file| { @@ -59,7 +60,7 @@ impl MetadataTrait for Album { type Message = protocol::metadata::Album; fn from_msg(msg: &Self::Message) -> Self { Album { - name: msg.get_name().to_string(), + name: msg.get_name().to_owned(), artists: msg.get_artist().iter() .map(|a| SpotifyId::from_raw(a.get_gid())) .collect(), @@ -89,7 +90,7 @@ impl MetadataTrait for Artist { type Message = protocol::metadata::Artist; fn from_msg(msg: &Self::Message) -> Self { Artist { - name: msg.get_name().to_string(), + name: msg.get_name().to_owned(), } } fn base_url() -> &'static str { @@ -164,7 +165,7 @@ impl MetadataState { } } - pub fn unwrap<'s>(&'s self) -> &'s T { + pub fn unwrap(&self) -> &T { match *self { MetadataState::Loaded(ref data) => data, _ => panic!("Not loaded") @@ -180,7 +181,7 @@ pub enum MetadataRequest { } pub struct MetadataManager { - cache: HashMap<(SpotifyId, TypeId), Box> + cache: HashMap<(SpotifyId, TypeId), Box> } impl MetadataManager { @@ -204,7 +205,7 @@ impl MetadataManager { cond: Condvar::new() }); - self.cache.insert(key, Box::new(x.downgrade())); + self.cache.insert(key, Box::new(Arc::downgrade(&x))); self.load(session, x.clone()); x }) @@ -219,10 +220,10 @@ impl MetadataManager { }); thread::spawn(move || { - let response = rx.into_inner(); + let response = rx.await().unwrap(); let msg : T::Message = protobuf::parse_from_bytes( - response.payload.front().unwrap()).unwrap(); + response.payload.first().unwrap()).unwrap(); object.set(MetadataState::Loaded(T::from_msg(&msg))); }); diff --git a/src/player.rs b/src/player.rs index b3766c5c..0addce23 100644 --- a/src/player.rs +++ b/src/player.rs @@ -1,7 +1,8 @@ +use eventual::Async; use portaudio; -use vorbis; use std::sync::{mpsc, Mutex, Arc, Condvar, MutexGuard}; use std::thread; +use vorbis; use metadata::TrackRef; use session::Session; @@ -9,13 +10,10 @@ use audio_decrypt::AudioDecrypt; use util::{self, SpotifyId, Subfile}; use spirc::{SpircState, SpircDelegate, PlayStatus}; -pub struct Player<'s> { +pub struct Player { state: Arc<(Mutex, Condvar)>, commands: mpsc::Sender, - - #[allow(dead_code)] - thread: thread::JoinGuard<'s, ()>, } pub struct PlayerState { @@ -27,10 +25,9 @@ pub struct PlayerState { end_of_track: bool } -struct PlayerInternal<'s> { +struct PlayerInternal { state: Arc<(Mutex, Condvar)>, - - session: &'s Session, + session: Session, commands: mpsc::Receiver, } @@ -42,7 +39,7 @@ enum PlayerCommand { Seek(u32) } -impl <'s> Player<'s> { +impl Player { pub fn new(session: &Session) -> Player { let (cmd_tx, cmd_rx) = mpsc::channel(); @@ -55,17 +52,18 @@ impl <'s> Player<'s> { }), Condvar::new())); let internal = PlayerInternal { - session: session, + session: session.clone(), commands: cmd_rx, state: state.clone() }; + thread::spawn(move || { + internal.run() + }); + Player { commands: cmd_tx, state: state, - thread: thread::scoped(move || { - internal.run() - }) } } @@ -74,7 +72,7 @@ impl <'s> Player<'s> { } } -impl <'s> PlayerInternal<'s> { +impl PlayerInternal { fn run(self) { portaudio::initialize().unwrap(); @@ -102,7 +100,8 @@ impl <'s> PlayerInternal<'s> { let track : TrackRef = self.session.metadata(id); let file_id = *track.wait().unwrap().files.first().unwrap(); - let key = self.session.audio_key(track.id(), file_id).into_inner(); + + let key = self.session.audio_key(track.id(), file_id).await().unwrap(); decoder = Some( vorbis::Decoder::new( Subfile::new( @@ -217,7 +216,7 @@ impl <'s> PlayerInternal<'s> { } } -impl <'s> SpircDelegate for Player<'s> { +impl SpircDelegate for Player { type State = PlayerState; fn load(&self, track: SpotifyId, diff --git a/src/session.rs b/src/session.rs index 46313fd8..613c4456 100644 --- a/src/session.rs +++ b/src/session.rs @@ -1,8 +1,9 @@ use crypto::digest::Digest; use crypto::sha1::Sha1; +use eventual::Future; use protobuf::{self, Message}; use rand::thread_rng; -use std::sync::{Mutex, Arc, Future, mpsc}; +use std::sync::{Mutex, Arc, mpsc}; use std::path::PathBuf; use connection::{self, PlainConnection, CipherConnection}; @@ -26,7 +27,7 @@ pub struct Config { pub cache_location: PathBuf, } -pub struct Session { +pub struct SessionData { pub config: Config, mercury: Mutex, @@ -38,7 +39,8 @@ pub struct Session { tx_connection: Mutex, } -type SessionRef = Arc; +#[derive(Clone)] +pub struct Session(pub Arc); impl Session { pub fn new(mut config: Config) -> Session { @@ -114,7 +116,7 @@ impl Session { let cipher_connection = connection.setup_cipher(shared_keys); - Session { + Session(Arc::new(SessionData { config: config, rx_connection: Mutex::new(cipher_connection.clone()), @@ -125,7 +127,7 @@ impl Session { stream: Mutex::new(StreamManager::new()), audio_key: Mutex::new(AudioKeyManager::new()), audio_file: Mutex::new(AudioFileManager::new()), - } + })) } pub fn login(&self, username: String, password: String) { @@ -138,15 +140,15 @@ impl Session { system_info => { cpu_family: protocol::authentication::CpuFamily::CPU_UNKNOWN, os: protocol::authentication::Os::OS_UNKNOWN, - system_information_string: "librespot".to_string(), - device_id: self.config.device_id.clone() + system_information_string: "librespot".to_owned(), + device_id: self.0.config.device_id.clone() }, version_string: util::version::version_string(), appkey => { - version: self.config.application_key[0] as u32, - devkey: self.config.application_key[0x1..0x81].to_vec(), - signature: self.config.application_key[0x81..0x141].to_vec(), - useragent: self.config.user_agent.clone(), + version: self.0.config.application_key[0] as u32, + devkey: self.0.config.application_key[0x1..0x81].to_vec(), + signature: self.0.config.application_key[0x81..0x141].to_vec(), + useragent: self.0.config.user_agent.clone(), callback_hash: vec![0; 20], } }); @@ -156,14 +158,14 @@ impl Session { pub fn poll(&self) { let (cmd, data) = - self.rx_connection.lock().unwrap().recv_packet().unwrap(); + self.0.rx_connection.lock().unwrap().recv_packet().unwrap(); match cmd { 0x4 => self.send_packet(0x49, &data).unwrap(), 0x4a => (), - 0x9 => self.stream.lock().unwrap().handle(cmd, data), - 0xd | 0xe => self.audio_key.lock().unwrap().handle(cmd, data), - 0xb2...0xb6 => self.mercury.lock().unwrap().handle(cmd, data), + 0x9 => self.0.stream.lock().unwrap().handle(cmd, data), + 0xd | 0xe => self.0.audio_key.lock().unwrap().handle(cmd, data), + 0xb2...0xb6 => self.0.mercury.lock().unwrap().handle(cmd, data), 0xac => eprintln!("Authentication succeedded"), 0xad => eprintln!("Authentication failed"), _ => () @@ -171,31 +173,31 @@ impl Session { } pub fn send_packet(&self, cmd: u8, data: &[u8]) -> connection::Result<()> { - self.tx_connection.lock().unwrap().send_packet(cmd, data) + self.0.tx_connection.lock().unwrap().send_packet(cmd, data) } - pub fn audio_key(&self, track: SpotifyId, file: FileId) -> Future { - self.audio_key.lock().unwrap().request(self, track, file) + pub fn audio_key(&self, track: SpotifyId, file: FileId) -> Future { + self.0.audio_key.lock().unwrap().request(self, track, file) } pub fn audio_file(&self, file: FileId) -> AudioFile { - self.audio_file.lock().unwrap().request(self, file) + self.0.audio_file.lock().unwrap().request(self, file) } pub fn stream(&self, file: FileId, offset: u32, size: u32) -> mpsc::Receiver { - self.stream.lock().unwrap().request(self, file, offset, size) + self.0.stream.lock().unwrap().request(self, file, offset, size) } pub fn metadata(&self, id: SpotifyId) -> MetadataRef { - self.metadata.lock().unwrap().get(self, id) + self.0.metadata.lock().unwrap().get(self, id) } - pub fn mercury(&self, req: MercuryRequest) -> Future { - self.mercury.lock().unwrap().request(self, req) + pub fn mercury(&self, req: MercuryRequest) -> Future { + self.0.mercury.lock().unwrap().request(self, req) } pub fn mercury_sub(&self, uri: String) -> mpsc::Receiver { - self.mercury.lock().unwrap().subscribe(self, uri) + self.0.mercury.lock().unwrap().subscribe(self, uri) } } diff --git a/src/spirc.rs b/src/spirc.rs index 6f6db7a0..91b0d06c 100644 --- a/src/spirc.rs +++ b/src/spirc.rs @@ -1,3 +1,4 @@ +use eventual::Async; use protobuf::{self, Message}; use std::sync::{mpsc, MutexGuard}; @@ -70,7 +71,7 @@ impl <'s, D: SpircDelegate> SpircManager<'s, D> { seq_nr: 0, name: name, - ident: session.config.device_id.clone(), + ident: session.0.config.device_id.clone(), device_type: 5, can_play: true, @@ -97,7 +98,8 @@ impl <'s, D: SpircDelegate> SpircManager<'s, D> { select! { pkt = rx.recv() => { let frame = protobuf::parse_from_bytes::( - pkt.unwrap().payload.front().unwrap()).unwrap(); + pkt.unwrap().payload.first().unwrap()).unwrap(); + println!("{:?} {} {} {} {}", frame.get_typ(), frame.get_device_state().get_name(), @@ -127,7 +129,7 @@ impl <'s, D: SpircDelegate> SpircManager<'s, D> { fn handle(&mut self, frame: protocol::spirc::Frame) { if frame.get_recipient().len() > 0 { - self.last_command_ident = frame.get_ident().to_string(); + self.last_command_ident = frame.get_ident().to_owned(); self.last_command_msgid = frame.get_seq_nr(); } match frame.get_typ() { @@ -174,12 +176,12 @@ impl <'s, D: SpircDelegate> SpircManager<'s, D> { let mut pkt = protobuf_init!(protocol::spirc::Frame::new(), { version: 1, ident: self.ident.clone(), - protocol_version: "2.0.0".to_string(), + protocol_version: "2.0.0".to_owned(), seq_nr: { self.seq_nr += 1; self.seq_nr }, typ: protocol::spirc::MessageType::kMessageTypeNotify, device_state: self.device_state(), recipient: protobuf::RepeatedField::from_vec( - recipient.map(|r| vec![r.to_string()] ).unwrap_or(vec![]) + recipient.map(|r| vec![r.to_owned()] ).unwrap_or(vec![]) ), state_update_id: self.state_update_id as i64 }); @@ -193,7 +195,7 @@ impl <'s, D: SpircDelegate> SpircManager<'s, D> { uri: format!("hm://remote/user/{}", self.username), content_type: None, payload: vec![ pkt.write_to_bytes().unwrap() ] - }); + }).await().unwrap(); } fn spirc_state(&self) -> protocol::spirc::State { @@ -259,23 +261,23 @@ impl <'s, D: SpircDelegate> SpircManager<'s, D> { @{ typ: protocol::spirc::CapabilityType::kSupportedContexts, stringValue => [ - "album".to_string(), - "playlist".to_string(), - "search".to_string(), - "inbox".to_string(), - "toplist".to_string(), - "starred".to_string(), - "publishedstarred".to_string(), - "track".to_string(), + "album".to_owned(), + "playlist".to_owned(), + "search".to_owned(), + "inbox".to_owned(), + "toplist".to_owned(), + "starred".to_owned(), + "publishedstarred".to_owned(), + "track".to_owned(), ] }, @{ typ: protocol::spirc::CapabilityType::kSupportedTypes, stringValue => [ - "audio/local".to_string(), - "audio/track".to_string(), - "local".to_string(), - "track".to_string(), + "audio/local".to_owned(), + "audio/track".to_owned(), + "local".to_owned(), + "track".to_owned(), ] } ], diff --git a/src/util/spotify_id.rs b/src/util/spotify_id.rs index aa823468..89372f05 100644 --- a/src/util/spotify_id.rs +++ b/src/util/spotify_id.rs @@ -19,7 +19,7 @@ impl SpotifyId { let mut n : u128 = std::num::Zero::zero(); for c in data { - let d = BASE16_DIGITS.position_elem(c).unwrap() as u8; + let d = BASE16_DIGITS.iter().position(|e| e == c).unwrap() as u8; n = n * u128::from(16); n = n + u128::from(d); } @@ -33,7 +33,7 @@ impl SpotifyId { let mut n : u128 = std::num::Zero::zero(); for c in data { - let d = BASE62_DIGITS.position_elem(c).unwrap() as u8; + let d = BASE62_DIGITS.iter().position(|e| e == c).unwrap() as u8; n = n * u128::from(62); n = n + u128::from(d); } @@ -62,7 +62,7 @@ impl SpotifyId { data[15-i] = BASE16_DIGITS[(high.wrapping_shr(4 * i as u32) & 0xF) as usize]; } - std::str::from_utf8(&data).unwrap().to_string() + std::str::from_utf8(&data).unwrap().to_owned() } pub fn to_raw(&self) -> [u8; 16] { diff --git a/src/util/zerofile.rs b/src/util/zerofile.rs index 7c8c66e2..5d98e2d6 100644 --- a/src/util/zerofile.rs +++ b/src/util/zerofile.rs @@ -33,8 +33,8 @@ impl io::Read for ZeroFile { // TODO optimize with memset or similar fn read(&mut self, output: &mut [u8]) -> io::Result { let len = min(output.len(), (self.size - self.position) as usize); - for i in 0..len { - output[i] = 0; + for b in output { + *b = 0; } self.position += len as u64;