Fix build on latest rust.

This commit is contained in:
Paul Lietar 2015-09-01 13:20:37 +02:00
parent ab7b5ba69d
commit 267ccbe65e
14 changed files with 292 additions and 258 deletions

197
Cargo.lock generated
View file

@ -2,27 +2,51 @@
name = "librespot" name = "librespot"
version = "0.1.0" version = "0.1.0"
dependencies = [ dependencies = [
"byteorder 0.3.11 (registry+https://github.com/rust-lang/crates.io-index)", "bit-set 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
"getopts 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", "byteorder 0.3.13 (registry+https://github.com/rust-lang/crates.io-index)",
"lazy_static 0.1.11 (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", "librespot-protocol 0.1.0",
"mod_path 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", "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)", "portaudio 0.1.2 (git+https://github.com/mvdnes/portaudio-rs)",
"protobuf 1.0.1 (git+https://github.com/plietar/rust-protobuf.git)", "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)", "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)", "rand 0.3.11 (registry+https://github.com/rust-lang/crates.io-index)",
"readall 0.1.0 (git+https://github.com/plietar/rust-readall.git)",
"rpassword 0.0.5 (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-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)", "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)", "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)", "tempfile 1.1.1 (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)",
"vergen 0.0.13 (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.11 (git+https://github.com/plietar/vorbis-rs)", "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]] [[package]]
name = "bitflags" name = "bitflags"
version = "0.1.1" version = "0.1.1"
@ -35,39 +59,55 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]] [[package]]
name = "byteorder" name = "byteorder"
version = "0.3.11" version = "0.3.13"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]] [[package]]
name = "gcc" name = "clippy"
version = "0.3.8" version = "0.0.12"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "git+https://github.com/Manishearth/rust-clippy.git#d3da9f6c81dd3e026bd679c09cea1d6b337ccd25"
[[package]] [[package]]
name = "getopts" name = "eventual"
version = "0.2.11" version = "0.1.4"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [ 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]] [[package]]
name = "kernel32-sys" name = "gcc"
version = "0.1.2" version = "0.3.13"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [ dependencies = [
"winapi 0.1.23 (registry+https://github.com/rust-lang/crates.io-index)", "advapi32-sys 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi-build 0.1.0 (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]] [[package]]
name = "lazy_static" name = "lazy_static"
version = "0.1.11" version = "0.1.14"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]] [[package]]
name = "libc" name = "libc"
version = "0.1.8" version = "0.1.10"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]] [[package]]
@ -80,10 +120,10 @@ dependencies = [
[[package]] [[package]]
name = "log" name = "log"
version = "0.3.1" version = "0.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [ 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]] [[package]]
@ -93,11 +133,11 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]] [[package]]
name = "num" name = "num"
version = "0.1.25" version = "0.1.27"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [ dependencies = [
"rand 0.3.8 (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.15 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-serialize 0.3.16 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
[[package]] [[package]]
@ -105,8 +145,8 @@ name = "ogg-sys"
version = "0.0.9" version = "0.0.9"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [ 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)",
"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)", "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" source = "git+https://github.com/mvdnes/portaudio-rs#7c6d10f5edda0094cc33b682d88c3a6ea4919b9f"
dependencies = [ dependencies = [
"bitflags 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "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)", "portaudio_sys 0.1.0 (git+https://github.com/mvdnes/portaudio-rs)",
] ]
@ -130,7 +170,7 @@ name = "portaudio_sys"
version = "0.1.0" version = "0.1.0"
source = "git+https://github.com/mvdnes/portaudio-rs#7c6d10f5edda0094cc33b682d88c3a6ea4919b9f" source = "git+https://github.com/mvdnes/portaudio-rs#7c6d10f5edda0094cc33b682d88c3a6ea4919b9f"
dependencies = [ 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)", "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]] [[package]]
name = "protobuf_macros" name = "protobuf_macros"
version = "0.1.0" 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]] [[package]]
name = "rand" name = "rand"
version = "0.3.8" version = "0.3.11"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [ 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]] [[package]]
@ -162,10 +204,10 @@ name = "rpassword"
version = "0.0.5" version = "0.0.5"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [ dependencies = [
"kernel32-sys 0.1.2 (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.8 (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)", "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]] [[package]]
@ -173,24 +215,24 @@ name = "rust-crypto"
version = "0.2.31" version = "0.2.31"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [ 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)",
"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)",
"rand 0.3.8 (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.15 (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.30 (registry+https://github.com/rust-lang/crates.io-index)", "time 0.1.32 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
[[package]] [[package]]
name = "rust-gmp" name = "rust-gmp"
version = "0.2.0" 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 = [ 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]] [[package]]
name = "rustc-serialize" name = "rustc-serialize"
version = "0.3.15" version = "0.3.16"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]] [[package]]
@ -198,7 +240,7 @@ name = "shannon"
version = "0.1.0" version = "0.1.0"
source = "git+https://github.com/plietar/rust-shannon.git#c6be8a879a523a77d81c50df46faa891b76fea25" source = "git+https://github.com/plietar/rust-shannon.git#c6be8a879a523a77d81c50df46faa891b76fea25"
dependencies = [ 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)", "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)", "shannon-sys 0.1.0 (git+https://github.com/plietar/rust-shannon.git)",
] ]
@ -208,18 +250,27 @@ name = "shannon-sys"
version = "0.1.0" version = "0.1.0"
source = "git+https://github.com/plietar/rust-shannon.git#c6be8a879a523a77d81c50df46faa891b76fea25" source = "git+https://github.com/plietar/rust-shannon.git#c6be8a879a523a77d81c50df46faa891b76fea25"
dependencies = [ 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]] [[package]]
name = "tempfile" name = "tempfile"
version = "1.0.0" version = "1.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [ dependencies = [
"kernel32-sys 0.1.2 (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.8 (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.8 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.3.11 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi 0.1.23 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
[[package]] [[package]]
@ -227,34 +278,34 @@ name = "termios"
version = "0.0.5" version = "0.0.5"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [ 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]] [[package]]
name = "time" name = "time"
version = "0.1.30" version = "0.1.32"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [ dependencies = [
"kernel32-sys 0.1.2 (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.8 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi 0.1.23 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
[[package]] [[package]]
name = "vergen" name = "vergen"
version = "0.0.13" version = "0.0.16"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [ dependencies = [
"bitflags 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", "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]] [[package]]
name = "vorbis" name = "vorbis"
version = "0.0.11" version = "0.0.12"
source = "git+https://github.com/plietar/vorbis-rs#78058c3341832969030f49cbc4b8bc9deb376776" source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [ 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)", "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)", "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)", "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" version = "0.0.8"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [ 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)",
"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)", "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)", "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" version = "0.0.8"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [ 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)",
"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)", "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)", "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)", "vorbis-sys 0.0.8 (registry+https://github.com/rust-lang/crates.io-index)",
@ -285,19 +336,11 @@ dependencies = [
[[package]] [[package]]
name = "winapi" name = "winapi"
version = "0.1.23" version = "0.2.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)",
]
[[package]]
name = "winapi"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]] [[package]]
name = "winapi-build" name = "winapi-build"
version = "0.1.0" version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"

View file

@ -16,17 +16,22 @@ path = "src/main.rs"
path = "protocol" path = "protocol"
[dependencies] [dependencies]
mod_path = "*" bit-set = "~0.2.0"
byteorder = "*" byteorder = "~0.3.13"
num = "*" eventual = "~0.1.4"
rand = "*" getopts = "~0.2.14"
lazy_static = "0.1.*" lazy_static = "~0.1.14"
rust-crypto = "*" mod_path = "~0.1.5"
time = "*" num = "~0.1.27"
tempfile = "*" rand = "~0.3.11"
rpassword = "*" rpassword = "~0.0.5"
getopts = "0.2.4" 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] [dependencies.protobuf]
git = "https://github.com/plietar/rust-protobuf.git" git = "https://github.com/plietar/rust-protobuf.git"
[dependencies.protobuf_macros] [dependencies.protobuf_macros]
@ -35,12 +40,9 @@ git = "https://github.com/plietar/rust-protobuf-macros.git"
git = "https://github.com/plietar/rust-gmp.git" git = "https://github.com/plietar/rust-gmp.git"
[dependencies.shannon] [dependencies.shannon]
git = "https://github.com/plietar/rust-shannon.git" git = "https://github.com/plietar/rust-shannon.git"
[dependencies.readall]
git = "https://github.com/plietar/rust-readall.git"
[dependencies.portaudio] [dependencies.portaudio]
git = "https://github.com/mvdnes/portaudio-rs" git = "https://github.com/mvdnes/portaudio-rs"
[dependencies.vorbis]
git = "https://github.com/plietar/vorbis-rs"
[build-dependencies] [build-dependencies]
vergen = "*" vergen = "~0.0.16"

View file

@ -1,6 +1,6 @@
use bit_set::BitSet;
use byteorder::{ByteOrder, BigEndian}; use byteorder::{ByteOrder, BigEndian};
use std::cmp::min; use std::cmp::min;
use std::collections::BitSet;
use std::sync::{Arc, Condvar, Mutex}; use std::sync::{Arc, Condvar, Mutex};
use std::sync::mpsc::{self, TryRecvError}; use std::sync::mpsc::{self, TryRecvError};
use std::thread; use std::thread;
@ -9,27 +9,24 @@ use std::io::{self, Read, Write, Seek, SeekFrom};
use std::path::PathBuf; use std::path::PathBuf;
use tempfile::TempFile; use tempfile::TempFile;
use stream::StreamEvent;
use util::{FileId, IgnoreExt, ZeroFile, mkdir_existing}; use util::{FileId, IgnoreExt, ZeroFile, mkdir_existing};
use session::Session; use session::Session;
use stream::StreamEvent;
const CHUNK_SIZE : usize = 0x20000; const CHUNK_SIZE : usize = 0x20000;
pub enum AudioFile<'s> { pub enum AudioFile {
Direct(fs::File), Direct(fs::File),
Loading(AudioFileLoading<'s>) Loading(AudioFileLoading)
} }
pub struct AudioFileLoading<'s> { pub struct AudioFileLoading {
read_file: TempFile, read_file: TempFile,
position: u64, position: u64,
seek: mpsc::Sender<u64>, seek: mpsc::Sender<u64>,
shared: Arc<AudioFileShared>, shared: Arc<AudioFileShared>,
#[allow(dead_code)]
thread: thread::JoinGuard<'s, ()>,
} }
struct AudioFileShared { struct AudioFileShared {
@ -40,7 +37,7 @@ struct AudioFileShared {
bitmap: Mutex<BitSet>, bitmap: Mutex<BitSet>,
} }
impl <'s> AudioFileLoading<'s> { impl AudioFileLoading {
fn new(session: &Session, file_id: FileId) -> AudioFileLoading { fn new(session: &Session, file_id: FileId) -> AudioFileLoading {
let mut files_iter = TempFile::shared(2).unwrap().into_iter(); let mut files_iter = TempFile::shared(2).unwrap().into_iter();
let read_file = files_iter.next().unwrap(); let read_file = files_iter.next().unwrap();
@ -70,17 +67,20 @@ impl <'s> AudioFileLoading<'s> {
let (seek_tx, seek_rx) = mpsc::channel(); 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 { AudioFileLoading {
read_file: read_file, read_file: read_file,
position: 0, position: 0,
seek: seek_tx, seek: seek_tx,
shared: shared.clone(), shared: shared
thread: thread::scoped(move || {
AudioFileLoading::fetch(session, shared, write_file, seek_rx)
})
} }
} }
@ -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<usize> { fn read(&mut self, output: &mut [u8]) -> io::Result<usize> {
let index = self.position as usize / CHUNK_SIZE; let index = self.position as usize / CHUNK_SIZE;
let offset = 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); 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<u64> { fn seek(&mut self, pos: SeekFrom) -> io::Result<u64> {
self.position = try!(self.read_file.seek(pos)); 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<usize> { fn read(&mut self, output: &mut [u8]) -> io::Result<usize> {
match *self { match *self {
AudioFile::Direct(ref mut file) => file.read(output), 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<u64> { fn seek(&mut self, pos: io::SeekFrom) -> io::Result<u64> {
match *self { match *self {
AudioFile::Direct(ref mut file) => file.seek(pos), AudioFile::Direct(ref mut file) => file.seek(pos),
@ -215,7 +215,7 @@ impl AudioFileManager {
pub fn cache_dir(session: &Session, file_id: FileId) -> PathBuf { pub fn cache_dir(session: &Session, file_id: FileId) -> PathBuf {
let name = file_id.to_base16(); 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 { 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..]) 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)) { match fs::File::open(AudioFileManager::cache_path(session, file_id)) {
Ok(f) => AudioFile::Direct(f), Ok(f) => AudioFile::Direct(f),
Err(..) => AudioFile::Loading(AudioFileLoading::new(session, file_id)) Err(..) => AudioFile::Loading(AudioFileLoading::new(session, file_id))

View file

@ -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 byteorder::{BigEndian, ByteOrder, ReadBytesExt, WriteBytesExt};
use readall::ReadAllExt; use eventual;
use std::collections::HashMap;
use std::io::{Cursor, Read, Write};
use std::mem; use std::mem;
use util::{SpotifyId, FileId, IgnoreExt}; use util::{SpotifyId, FileId};
use session::Session; use session::Session;
use connection::PacketHandler; use connection::PacketHandler;
@ -15,7 +14,7 @@ pub type AudioKey = [u8; 16];
struct AudioKeyId(SpotifyId, FileId); struct AudioKeyId(SpotifyId, FileId);
enum AudioKeyStatus { enum AudioKeyStatus {
Loading(LinkedList<mpsc::Sender<AudioKey>>), Loading(Vec<eventual::Complete<AudioKey, ()>>),
Loaded(AudioKey) Loaded(AudioKey)
} }
@ -35,17 +34,17 @@ impl AudioKeyManager {
} }
pub fn request(&mut self, session: &Session, track: SpotifyId, file: FileId) pub fn request(&mut self, session: &Session, track: SpotifyId, file: FileId)
-> Future<AudioKey> { -> eventual::Future<AudioKey, ()> {
let id = AudioKeyId(track, file); let id = AudioKeyId(track, file);
self.cache.get_mut(&id).map(|status| match status { self.cache.get_mut(&id).map(|status| match *status {
&mut AudioKeyStatus::Loaded(key) => { AudioKeyStatus::Loaded(key) => {
Future::from_value(key.clone()) eventual::Future::of(key.clone())
} }
&mut AudioKeyStatus::Loading(ref mut req) => { AudioKeyStatus::Loading(ref mut req) => {
let (tx, rx) = mpsc::channel(); let (tx, rx) = eventual::Future::pair();
req.push_front(tx); req.push(tx);
Future::from_receiver(rx) rx
} }
}).unwrap_or_else(|| { }).unwrap_or_else(|| {
let seq = self.next_seq; let seq = self.next_seq;
@ -61,11 +60,9 @@ impl AudioKeyManager {
self.pending.insert(seq, id.clone()); self.pending.insert(seq, id.clone());
let (tx, rx) = mpsc::channel(); let (tx, rx) = eventual::Future::pair();
let mut req = LinkedList::new(); self.cache.insert(id, AudioKeyStatus::Loading(vec!{ tx }));
req.push_front(tx); rx
self.cache.insert(id, AudioKeyStatus::Loading(req));
Future::from_receiver(rx)
}) })
} }
} }
@ -77,14 +74,14 @@ impl PacketHandler for AudioKeyManager {
let mut data = Cursor::new(data); let mut data = Cursor::new(data);
let seq = data.read_u32::<BigEndian>().unwrap(); let seq = data.read_u32::<BigEndian>().unwrap();
let mut key = [0u8; 16]; 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) }) { if let Some(status) = self.pending.remove(&seq).and_then(|id| { self.cache.get_mut(&id) }) {
let status = mem::replace(status, AudioKeyStatus::Loaded(key)); let status = mem::replace(status, AudioKeyStatus::Loaded(key));
if let AudioKeyStatus::Loading(cbs) = status { if let AudioKeyStatus::Loading(cbs) = status {
for cb in cbs { for cb in cbs {
cb.send(key).ignore(); cb.complete(key);
} }
} }
} }

View file

@ -1,9 +1,8 @@
use byteorder::{self, BigEndian, ByteOrder, ReadBytesExt, WriteBytesExt}; use byteorder::{self, BigEndian, ByteOrder, ReadBytesExt, WriteBytesExt};
use readall::ReadAllExt;
use shannon::ShannonStream; use shannon::ShannonStream;
use std::convert; use std::convert;
use std::io; use std::io;
use std::io::Write; use std::io::{Read, Write};
use std::net::TcpStream; use std::net::TcpStream;
use std::result; use std::result;
@ -70,7 +69,7 @@ impl PlainConnection {
let mut buffer = vec![0u8; size]; let mut buffer = vec![0u8; size];
BigEndian::write_u32(&mut buffer, size as u32); 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) Ok(buffer)
} }
@ -98,7 +97,7 @@ impl CipherConnection {
let size = try!(self.stream.read_u16::<BigEndian>()) as usize; let size = try!(self.stream.read_u16::<BigEndian>()) as usize;
let mut data = vec![0; size]; 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()); try!(self.stream.finish_recv());

View file

@ -1,25 +1,25 @@
#![crate_name = "librespot"] #![crate_name = "librespot"]
#![feature(plugin,scoped,zero_one,iter_arith,slice_position_elem,slice_bytes,bitset,arc_weak,append,future,mpsc_select)] #![feature(plugin,read_exact,zero_one,iter_arith,slice_bytes,arc_weak,append,mpsc_select)]
#![allow(deprecated)] #![allow(needless_return)]
//#![allow(unused_imports,dead_code)]
#![plugin(clippy)]
#![plugin(protobuf_macros)] #![plugin(protobuf_macros)]
#[macro_use] extern crate lazy_static; #[macro_use] extern crate lazy_static;
extern crate bit_set;
extern crate byteorder; extern crate byteorder;
extern crate crypto; extern crate crypto;
extern crate eventual;
extern crate gmp; extern crate gmp;
extern crate num; extern crate num;
extern crate portaudio; extern crate portaudio;
extern crate protobuf; extern crate protobuf;
extern crate shannon; extern crate shannon;
extern crate rand; extern crate rand;
extern crate readall;
extern crate vorbis;
extern crate time; extern crate time;
extern crate tempfile; extern crate tempfile;
extern crate vorbis;
extern crate librespot_protocol; extern crate librespot_protocol;

View file

@ -1,4 +1,3 @@
#![feature(scoped)]
#![feature(result_expect)] #![feature(result_expect)]
#![allow(deprecated)] #![allow(deprecated)]
@ -71,9 +70,10 @@ fn main() {
session.login(username.clone(), password); session.login(username.clone(), password);
session.poll(); session.poll();
let poll_thread = thread::scoped(|| { let _session = session.clone();
thread::spawn(move || {
loop { loop {
session.poll(); _session.poll();
} }
}); });
@ -81,7 +81,5 @@ fn main() {
let mut spirc_manager = SpircManager::new(&session, player, username, name); let mut spirc_manager = SpircManager::new(&session, player, username, name);
spirc_manager.run(); spirc_manager.run();
poll_thread.join();
} }

View file

@ -1,11 +1,10 @@
use byteorder::{BigEndian, ByteOrder, ReadBytesExt, WriteBytesExt}; use byteorder::{BigEndian, ByteOrder, ReadBytesExt, WriteBytesExt};
use eventual;
use protobuf::{self, Message}; use protobuf::{self, Message};
use readall::ReadAllExt; use std::collections::HashMap;
use std::collections::{HashMap, LinkedList};
use std::io::{Cursor, Read, Write}; use std::io::{Cursor, Read, Write};
use std::fmt;
use std::mem::replace; use std::mem::replace;
use std::sync::{mpsc, Future}; use std::sync::mpsc;
use librespot_protocol as protocol; use librespot_protocol as protocol;
use session::Session; use session::Session;
@ -30,13 +29,13 @@ pub struct MercuryRequest {
#[derive(Debug)] #[derive(Debug)]
pub struct MercuryResponse { pub struct MercuryResponse {
pub uri: String, pub uri: String,
pub payload: LinkedList<Vec<u8>> pub payload: Vec<Vec<u8>>
} }
pub struct MercuryPending { pub struct MercuryPending {
parts: LinkedList<Vec<u8>>, parts: Vec<Vec<u8>>,
partial: Option<Vec<u8>>, partial: Option<Vec<u8>>,
callback: Option<mpsc::Sender<MercuryResponse>> callback: Option<eventual::Complete<MercuryResponse, ()>>
} }
pub struct MercuryManager { pub struct MercuryManager {
@ -45,14 +44,14 @@ pub struct MercuryManager {
subscriptions: HashMap<String, mpsc::Sender<MercuryResponse>>, subscriptions: HashMap<String, mpsc::Sender<MercuryResponse>>,
} }
impl fmt::Display for MercuryMethod { impl ToString for MercuryMethod {
fn fmt(&self, formatter: &mut fmt::Formatter) -> Result<(), fmt::Error> { fn to_string(&self) -> String {
formatter.write_str(match *self { match *self {
MercuryMethod::GET => "GET", MercuryMethod::GET => "GET",
MercuryMethod::SUB => "SUB", MercuryMethod::SUB => "SUB",
MercuryMethod::UNSUB => "UNSUB", MercuryMethod::UNSUB => "UNSUB",
MercuryMethod::SEND => "SEND" MercuryMethod::SEND => "SEND"
}) }.to_owned()
} }
} }
@ -66,7 +65,7 @@ impl MercuryManager {
} }
pub fn request(&mut self, session: &Session, req: MercuryRequest) pub fn request(&mut self, session: &Session, req: MercuryRequest)
-> Future<MercuryResponse> { -> eventual::Future<MercuryResponse, ()> {
let mut seq = [0u8; 4]; let mut seq = [0u8; 4];
BigEndian::write_u32(&mut seq, self.next_seq); BigEndian::write_u32(&mut seq, self.next_seq);
@ -81,14 +80,14 @@ impl MercuryManager {
session.send_packet(cmd, &data).unwrap(); session.send_packet(cmd, &data).unwrap();
let (tx, rx) = mpsc::channel(); let (tx, rx) = eventual::Future::pair();
self.pending.insert(seq.to_vec(), MercuryPending{ self.pending.insert(seq.to_vec(), MercuryPending{
parts: LinkedList::new(), parts: Vec::new(),
partial: None, partial: None,
callback: Some(tx), callback: Some(tx),
}); });
Future::from_receiver(rx) rx
} }
pub fn subscribe(&mut self, session: &Session, uri: String) pub fn subscribe(&mut self, session: &Session, uri: String)
@ -109,33 +108,25 @@ impl MercuryManager {
fn parse_part(mut s: &mut Read) -> Vec<u8> { fn parse_part(mut s: &mut Read) -> Vec<u8> {
let size = s.read_u16::<BigEndian>().unwrap() as usize; let size = s.read_u16::<BigEndian>().unwrap() as usize;
let mut buffer = vec![0; size]; let mut buffer = vec![0; size];
s.read_all(&mut buffer).unwrap(); s.read_exact(&mut buffer).unwrap();
buffer buffer
} }
fn complete_request(&mut self, cmd: u8, mut pending: MercuryPending) { fn complete_request(&mut self, cmd: u8, mut pending: MercuryPending) {
let header_data = match pending.parts.pop_front() { let header_data = pending.parts.remove(0);
Some(data) => data,
None => panic!("No header part !")
};
let header : protocol::mercury::Header = let header : protocol::mercury::Header =
protobuf::parse_from_bytes(&header_data).unwrap(); protobuf::parse_from_bytes(&header_data).unwrap();
let callback = if cmd == 0xb5 { let response = MercuryResponse {
self.subscriptions.get(header.get_uri()) uri: header.get_uri().to_owned(),
} else { payload: pending.parts
pending.callback.as_ref()
}; };
if let Some(ref ch) = callback { if cmd == 0xb5 {
// Ignore send error. self.subscriptions.get(header.get_uri()).map(|ch| ch.send(response).ignore());
// It simply means the receiver was closed } else {
ch.send(MercuryResponse{ pending.callback.map(|cb| cb.complete(response));
uri: header.get_uri().to_string(),
payload: pending.parts
}).ignore();
} }
} }
@ -173,7 +164,7 @@ impl PacketHandler for MercuryManager {
let seq = { let seq = {
let seq_length = packet.read_u16::<BigEndian>().unwrap() as usize; let seq_length = packet.read_u16::<BigEndian>().unwrap() as usize;
let mut seq = vec![0; seq_length]; let mut seq = vec![0; seq_length];
packet.read_all(&mut seq).unwrap(); packet.read_exact(&mut seq).unwrap();
seq seq
}; };
let flags = packet.read_u8().unwrap(); let flags = packet.read_u8().unwrap();
@ -183,7 +174,7 @@ impl PacketHandler for MercuryManager {
pending pending
} else if cmd == 0xb5 { } else if cmd == 0xb5 {
MercuryPending { MercuryPending {
parts: LinkedList::new(), parts: Vec::new(),
partial: None, partial: None,
callback: None, callback: None,
} }
@ -202,7 +193,7 @@ impl PacketHandler for MercuryManager {
if i == count - 1 && (flags == 2) { if i == count - 1 && (flags == 2) {
pending.partial = Some(part) pending.partial = Some(part)
} else { } else {
pending.parts.push_back(part); pending.parts.push(part);
} }
} }

View file

@ -1,3 +1,4 @@
use eventual::Async;
use protobuf::{self, Message}; use protobuf::{self, Message};
use std::any::{Any, TypeId}; use std::any::{Any, TypeId};
use std::collections::HashMap; use std::collections::HashMap;
@ -11,7 +12,7 @@ use mercury::{MercuryRequest, MercuryMethod};
use util::{SpotifyId, FileId}; use util::{SpotifyId, FileId};
use session::Session; use session::Session;
pub trait MetadataTrait : Send + Any + 'static { pub trait MetadataTrait : Send + Sized + Any + 'static {
type Message: protobuf::MessageStatic; type Message: protobuf::MessageStatic;
fn from_msg(msg: &Self::Message) -> Self; fn from_msg(msg: &Self::Message) -> Self;
fn base_url() -> &'static str; fn base_url() -> &'static str;
@ -29,7 +30,7 @@ impl MetadataTrait for Track {
type Message = protocol::metadata::Track; type Message = protocol::metadata::Track;
fn from_msg(msg: &Self::Message) -> Self { fn from_msg(msg: &Self::Message) -> Self {
Track { Track {
name: msg.get_name().to_string(), name: msg.get_name().to_owned(),
album: SpotifyId::from_raw(msg.get_album().get_gid()), album: SpotifyId::from_raw(msg.get_album().get_gid()),
files: msg.get_file().iter() files: msg.get_file().iter()
.map(|file| { .map(|file| {
@ -59,7 +60,7 @@ impl MetadataTrait for Album {
type Message = protocol::metadata::Album; type Message = protocol::metadata::Album;
fn from_msg(msg: &Self::Message) -> Self { fn from_msg(msg: &Self::Message) -> Self {
Album { Album {
name: msg.get_name().to_string(), name: msg.get_name().to_owned(),
artists: msg.get_artist().iter() artists: msg.get_artist().iter()
.map(|a| SpotifyId::from_raw(a.get_gid())) .map(|a| SpotifyId::from_raw(a.get_gid()))
.collect(), .collect(),
@ -89,7 +90,7 @@ impl MetadataTrait for Artist {
type Message = protocol::metadata::Artist; type Message = protocol::metadata::Artist;
fn from_msg(msg: &Self::Message) -> Self { fn from_msg(msg: &Self::Message) -> Self {
Artist { Artist {
name: msg.get_name().to_string(), name: msg.get_name().to_owned(),
} }
} }
fn base_url() -> &'static str { fn base_url() -> &'static str {
@ -164,7 +165,7 @@ impl <T: MetadataTrait> MetadataState<T> {
} }
} }
pub fn unwrap<'s>(&'s self) -> &'s T { pub fn unwrap(&self) -> &T {
match *self { match *self {
MetadataState::Loaded(ref data) => data, MetadataState::Loaded(ref data) => data,
_ => panic!("Not loaded") _ => panic!("Not loaded")
@ -180,7 +181,7 @@ pub enum MetadataRequest {
} }
pub struct MetadataManager { pub struct MetadataManager {
cache: HashMap<(SpotifyId, TypeId), Box<Any + Send>> cache: HashMap<(SpotifyId, TypeId), Box<Any + Send + 'static>>
} }
impl MetadataManager { impl MetadataManager {
@ -204,7 +205,7 @@ impl MetadataManager {
cond: Condvar::new() 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()); self.load(session, x.clone());
x x
}) })
@ -219,10 +220,10 @@ impl MetadataManager {
}); });
thread::spawn(move || { thread::spawn(move || {
let response = rx.into_inner(); let response = rx.await().unwrap();
let msg : T::Message = protobuf::parse_from_bytes( 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))); object.set(MetadataState::Loaded(T::from_msg(&msg)));
}); });

View file

@ -1,7 +1,8 @@
use eventual::Async;
use portaudio; use portaudio;
use vorbis;
use std::sync::{mpsc, Mutex, Arc, Condvar, MutexGuard}; use std::sync::{mpsc, Mutex, Arc, Condvar, MutexGuard};
use std::thread; use std::thread;
use vorbis;
use metadata::TrackRef; use metadata::TrackRef;
use session::Session; use session::Session;
@ -9,13 +10,10 @@ use audio_decrypt::AudioDecrypt;
use util::{self, SpotifyId, Subfile}; use util::{self, SpotifyId, Subfile};
use spirc::{SpircState, SpircDelegate, PlayStatus}; use spirc::{SpircState, SpircDelegate, PlayStatus};
pub struct Player<'s> { pub struct Player {
state: Arc<(Mutex<PlayerState>, Condvar)>, state: Arc<(Mutex<PlayerState>, Condvar)>,
commands: mpsc::Sender<PlayerCommand>, commands: mpsc::Sender<PlayerCommand>,
#[allow(dead_code)]
thread: thread::JoinGuard<'s, ()>,
} }
pub struct PlayerState { pub struct PlayerState {
@ -27,10 +25,9 @@ pub struct PlayerState {
end_of_track: bool end_of_track: bool
} }
struct PlayerInternal<'s> { struct PlayerInternal {
state: Arc<(Mutex<PlayerState>, Condvar)>, state: Arc<(Mutex<PlayerState>, Condvar)>,
session: Session,
session: &'s Session,
commands: mpsc::Receiver<PlayerCommand>, commands: mpsc::Receiver<PlayerCommand>,
} }
@ -42,7 +39,7 @@ enum PlayerCommand {
Seek(u32) Seek(u32)
} }
impl <'s> Player<'s> { impl Player {
pub fn new(session: &Session) -> Player { pub fn new(session: &Session) -> Player {
let (cmd_tx, cmd_rx) = mpsc::channel(); let (cmd_tx, cmd_rx) = mpsc::channel();
@ -55,17 +52,18 @@ impl <'s> Player<'s> {
}), Condvar::new())); }), Condvar::new()));
let internal = PlayerInternal { let internal = PlayerInternal {
session: session, session: session.clone(),
commands: cmd_rx, commands: cmd_rx,
state: state.clone() state: state.clone()
}; };
thread::spawn(move || {
internal.run()
});
Player { Player {
commands: cmd_tx, commands: cmd_tx,
state: state, 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) { fn run(self) {
portaudio::initialize().unwrap(); portaudio::initialize().unwrap();
@ -102,7 +100,8 @@ impl <'s> PlayerInternal<'s> {
let track : TrackRef = self.session.metadata(id); let track : TrackRef = self.session.metadata(id);
let file_id = *track.wait().unwrap().files.first().unwrap(); 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( decoder = Some(
vorbis::Decoder::new( vorbis::Decoder::new(
Subfile::new( Subfile::new(
@ -217,7 +216,7 @@ impl <'s> PlayerInternal<'s> {
} }
} }
impl <'s> SpircDelegate for Player<'s> { impl SpircDelegate for Player {
type State = PlayerState; type State = PlayerState;
fn load(&self, track: SpotifyId, fn load(&self, track: SpotifyId,

View file

@ -1,8 +1,9 @@
use crypto::digest::Digest; use crypto::digest::Digest;
use crypto::sha1::Sha1; use crypto::sha1::Sha1;
use eventual::Future;
use protobuf::{self, Message}; use protobuf::{self, Message};
use rand::thread_rng; use rand::thread_rng;
use std::sync::{Mutex, Arc, Future, mpsc}; use std::sync::{Mutex, Arc, mpsc};
use std::path::PathBuf; use std::path::PathBuf;
use connection::{self, PlainConnection, CipherConnection}; use connection::{self, PlainConnection, CipherConnection};
@ -26,7 +27,7 @@ pub struct Config {
pub cache_location: PathBuf, pub cache_location: PathBuf,
} }
pub struct Session { pub struct SessionData {
pub config: Config, pub config: Config,
mercury: Mutex<MercuryManager>, mercury: Mutex<MercuryManager>,
@ -38,7 +39,8 @@ pub struct Session {
tx_connection: Mutex<CipherConnection>, tx_connection: Mutex<CipherConnection>,
} }
type SessionRef = Arc<Session>; #[derive(Clone)]
pub struct Session(pub Arc<SessionData>);
impl Session { impl Session {
pub fn new(mut config: Config) -> Session { pub fn new(mut config: Config) -> Session {
@ -114,7 +116,7 @@ impl Session {
let cipher_connection = connection.setup_cipher(shared_keys); let cipher_connection = connection.setup_cipher(shared_keys);
Session { Session(Arc::new(SessionData {
config: config, config: config,
rx_connection: Mutex::new(cipher_connection.clone()), rx_connection: Mutex::new(cipher_connection.clone()),
@ -125,7 +127,7 @@ impl Session {
stream: Mutex::new(StreamManager::new()), stream: Mutex::new(StreamManager::new()),
audio_key: Mutex::new(AudioKeyManager::new()), audio_key: Mutex::new(AudioKeyManager::new()),
audio_file: Mutex::new(AudioFileManager::new()), audio_file: Mutex::new(AudioFileManager::new()),
} }))
} }
pub fn login(&self, username: String, password: String) { pub fn login(&self, username: String, password: String) {
@ -138,15 +140,15 @@ impl Session {
system_info => { system_info => {
cpu_family: protocol::authentication::CpuFamily::CPU_UNKNOWN, cpu_family: protocol::authentication::CpuFamily::CPU_UNKNOWN,
os: protocol::authentication::Os::OS_UNKNOWN, os: protocol::authentication::Os::OS_UNKNOWN,
system_information_string: "librespot".to_string(), system_information_string: "librespot".to_owned(),
device_id: self.config.device_id.clone() device_id: self.0.config.device_id.clone()
}, },
version_string: util::version::version_string(), version_string: util::version::version_string(),
appkey => { appkey => {
version: self.config.application_key[0] as u32, version: self.0.config.application_key[0] as u32,
devkey: self.config.application_key[0x1..0x81].to_vec(), devkey: self.0.config.application_key[0x1..0x81].to_vec(),
signature: self.config.application_key[0x81..0x141].to_vec(), signature: self.0.config.application_key[0x81..0x141].to_vec(),
useragent: self.config.user_agent.clone(), useragent: self.0.config.user_agent.clone(),
callback_hash: vec![0; 20], callback_hash: vec![0; 20],
} }
}); });
@ -156,14 +158,14 @@ impl Session {
pub fn poll(&self) { pub fn poll(&self) {
let (cmd, data) = let (cmd, data) =
self.rx_connection.lock().unwrap().recv_packet().unwrap(); self.0.rx_connection.lock().unwrap().recv_packet().unwrap();
match cmd { match cmd {
0x4 => self.send_packet(0x49, &data).unwrap(), 0x4 => self.send_packet(0x49, &data).unwrap(),
0x4a => (), 0x4a => (),
0x9 => self.stream.lock().unwrap().handle(cmd, data), 0x9 => self.0.stream.lock().unwrap().handle(cmd, data),
0xd | 0xe => self.audio_key.lock().unwrap().handle(cmd, data), 0xd | 0xe => self.0.audio_key.lock().unwrap().handle(cmd, data),
0xb2...0xb6 => self.mercury.lock().unwrap().handle(cmd, data), 0xb2...0xb6 => self.0.mercury.lock().unwrap().handle(cmd, data),
0xac => eprintln!("Authentication succeedded"), 0xac => eprintln!("Authentication succeedded"),
0xad => eprintln!("Authentication failed"), 0xad => eprintln!("Authentication failed"),
_ => () _ => ()
@ -171,31 +173,31 @@ impl Session {
} }
pub fn send_packet(&self, cmd: u8, data: &[u8]) -> connection::Result<()> { 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<AudioKey> { pub fn audio_key(&self, track: SpotifyId, file: FileId) -> Future<AudioKey, ()> {
self.audio_key.lock().unwrap().request(self, track, file) self.0.audio_key.lock().unwrap().request(self, track, file)
} }
pub fn audio_file(&self, file: FileId) -> AudioFile { 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<StreamEvent> { pub fn stream(&self, file: FileId, offset: u32, size: u32) -> mpsc::Receiver<StreamEvent> {
self.stream.lock().unwrap().request(self, file, offset, size) self.0.stream.lock().unwrap().request(self, file, offset, size)
} }
pub fn metadata<T: MetadataTrait>(&self, id: SpotifyId) -> MetadataRef<T> { pub fn metadata<T: MetadataTrait>(&self, id: SpotifyId) -> MetadataRef<T> {
self.metadata.lock().unwrap().get(self, id) self.0.metadata.lock().unwrap().get(self, id)
} }
pub fn mercury(&self, req: MercuryRequest) -> Future<MercuryResponse> { pub fn mercury(&self, req: MercuryRequest) -> Future<MercuryResponse, ()> {
self.mercury.lock().unwrap().request(self, req) self.0.mercury.lock().unwrap().request(self, req)
} }
pub fn mercury_sub(&self, uri: String) -> mpsc::Receiver<MercuryResponse> { pub fn mercury_sub(&self, uri: String) -> mpsc::Receiver<MercuryResponse> {
self.mercury.lock().unwrap().subscribe(self, uri) self.0.mercury.lock().unwrap().subscribe(self, uri)
} }
} }

View file

@ -1,3 +1,4 @@
use eventual::Async;
use protobuf::{self, Message}; use protobuf::{self, Message};
use std::sync::{mpsc, MutexGuard}; use std::sync::{mpsc, MutexGuard};
@ -70,7 +71,7 @@ impl <'s, D: SpircDelegate> SpircManager<'s, D> {
seq_nr: 0, seq_nr: 0,
name: name, name: name,
ident: session.config.device_id.clone(), ident: session.0.config.device_id.clone(),
device_type: 5, device_type: 5,
can_play: true, can_play: true,
@ -97,7 +98,8 @@ impl <'s, D: SpircDelegate> SpircManager<'s, D> {
select! { select! {
pkt = rx.recv() => { pkt = rx.recv() => {
let frame = protobuf::parse_from_bytes::<protocol::spirc::Frame>( let frame = protobuf::parse_from_bytes::<protocol::spirc::Frame>(
pkt.unwrap().payload.front().unwrap()).unwrap(); pkt.unwrap().payload.first().unwrap()).unwrap();
println!("{:?} {} {} {} {}", println!("{:?} {} {} {} {}",
frame.get_typ(), frame.get_typ(),
frame.get_device_state().get_name(), 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) { fn handle(&mut self, frame: protocol::spirc::Frame) {
if frame.get_recipient().len() > 0 { 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(); self.last_command_msgid = frame.get_seq_nr();
} }
match frame.get_typ() { match frame.get_typ() {
@ -174,12 +176,12 @@ impl <'s, D: SpircDelegate> SpircManager<'s, D> {
let mut pkt = protobuf_init!(protocol::spirc::Frame::new(), { let mut pkt = protobuf_init!(protocol::spirc::Frame::new(), {
version: 1, version: 1,
ident: self.ident.clone(), 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 }, seq_nr: { self.seq_nr += 1; self.seq_nr },
typ: protocol::spirc::MessageType::kMessageTypeNotify, typ: protocol::spirc::MessageType::kMessageTypeNotify,
device_state: self.device_state(), device_state: self.device_state(),
recipient: protobuf::RepeatedField::from_vec( 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 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), uri: format!("hm://remote/user/{}", self.username),
content_type: None, content_type: None,
payload: vec![ pkt.write_to_bytes().unwrap() ] payload: vec![ pkt.write_to_bytes().unwrap() ]
}); }).await().unwrap();
} }
fn spirc_state(&self) -> protocol::spirc::State { fn spirc_state(&self) -> protocol::spirc::State {
@ -259,23 +261,23 @@ impl <'s, D: SpircDelegate> SpircManager<'s, D> {
@{ @{
typ: protocol::spirc::CapabilityType::kSupportedContexts, typ: protocol::spirc::CapabilityType::kSupportedContexts,
stringValue => [ stringValue => [
"album".to_string(), "album".to_owned(),
"playlist".to_string(), "playlist".to_owned(),
"search".to_string(), "search".to_owned(),
"inbox".to_string(), "inbox".to_owned(),
"toplist".to_string(), "toplist".to_owned(),
"starred".to_string(), "starred".to_owned(),
"publishedstarred".to_string(), "publishedstarred".to_owned(),
"track".to_string(), "track".to_owned(),
] ]
}, },
@{ @{
typ: protocol::spirc::CapabilityType::kSupportedTypes, typ: protocol::spirc::CapabilityType::kSupportedTypes,
stringValue => [ stringValue => [
"audio/local".to_string(), "audio/local".to_owned(),
"audio/track".to_string(), "audio/track".to_owned(),
"local".to_string(), "local".to_owned(),
"track".to_string(), "track".to_owned(),
] ]
} }
], ],

View file

@ -19,7 +19,7 @@ impl SpotifyId {
let mut n : u128 = std::num::Zero::zero(); let mut n : u128 = std::num::Zero::zero();
for c in data { 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(16);
n = n + u128::from(d); n = n + u128::from(d);
} }
@ -33,7 +33,7 @@ impl SpotifyId {
let mut n : u128 = std::num::Zero::zero(); let mut n : u128 = std::num::Zero::zero();
for c in data { 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(62);
n = n + u128::from(d); 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]; 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] { pub fn to_raw(&self) -> [u8; 16] {

View file

@ -33,8 +33,8 @@ impl io::Read for ZeroFile {
// TODO optimize with memset or similar // TODO optimize with memset or similar
fn read(&mut self, output: &mut [u8]) -> io::Result<usize> { fn read(&mut self, output: &mut [u8]) -> io::Result<usize> {
let len = min(output.len(), (self.size - self.position) as usize); let len = min(output.len(), (self.size - self.position) as usize);
for i in 0..len { for b in output {
output[i] = 0; *b = 0;
} }
self.position += len as u64; self.position += len as u64;