audio_key.rs 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990
  1. use byteorder::{BigEndian, ByteOrder, ReadBytesExt, WriteBytesExt};
  2. use eventual;
  3. use std::collections::HashMap;
  4. use std::io::{Cursor, Read, Write};
  5. use std::mem;
  6. use util::{SpotifyId, FileId};
  7. use session::Session;
  8. use connection::PacketHandler;
  9. pub type AudioKey = [u8; 16];
  10. #[derive(Debug,Hash,PartialEq,Eq,Clone)]
  11. struct AudioKeyId(SpotifyId, FileId);
  12. enum AudioKeyStatus {
  13. Loading(Vec<eventual::Complete<AudioKey, ()>>),
  14. Loaded(AudioKey)
  15. }
  16. pub struct AudioKeyManager {
  17. next_seq: u32,
  18. pending: HashMap<u32, AudioKeyId>,
  19. cache: HashMap<AudioKeyId, AudioKeyStatus>,
  20. }
  21. impl AudioKeyManager {
  22. pub fn new() -> AudioKeyManager {
  23. AudioKeyManager {
  24. next_seq: 1,
  25. pending: HashMap::new(),
  26. cache: HashMap::new()
  27. }
  28. }
  29. pub fn request(&mut self, session: &Session, track: SpotifyId, file: FileId)
  30. -> eventual::Future<AudioKey, ()> {
  31. let id = AudioKeyId(track, file);
  32. self.cache.get_mut(&id).map(|status| match *status {
  33. AudioKeyStatus::Loaded(key) => {
  34. eventual::Future::of(key.clone())
  35. }
  36. AudioKeyStatus::Loading(ref mut req) => {
  37. let (tx, rx) = eventual::Future::pair();
  38. req.push(tx);
  39. rx
  40. }
  41. }).unwrap_or_else(|| {
  42. let seq = self.next_seq;
  43. self.next_seq += 1;
  44. let mut data : Vec<u8> = Vec::new();
  45. data.write(&file.0).unwrap();
  46. data.write(&track.to_raw()).unwrap();
  47. data.write_u32::<BigEndian>(seq).unwrap();
  48. data.write_u16::<BigEndian>(0x0000).unwrap();
  49. session.send_packet(0xc, &data).unwrap();
  50. self.pending.insert(seq, id.clone());
  51. let (tx, rx) = eventual::Future::pair();
  52. self.cache.insert(id, AudioKeyStatus::Loading(vec!{ tx }));
  53. rx
  54. })
  55. }
  56. }
  57. impl PacketHandler for AudioKeyManager {
  58. fn handle(&mut self, cmd: u8, data: Vec<u8>) {
  59. assert_eq!(cmd, 0xd);
  60. let mut data = Cursor::new(data);
  61. let seq = data.read_u32::<BigEndian>().unwrap();
  62. let mut key = [0u8; 16];
  63. data.read_exact(&mut key).unwrap();
  64. if let Some(status) = self.pending.remove(&seq).and_then(|id| { self.cache.get_mut(&id) }) {
  65. let status = mem::replace(status, AudioKeyStatus::Loaded(key));
  66. if let AudioKeyStatus::Loading(cbs) = status {
  67. for cb in cbs {
  68. cb.complete(key);
  69. }
  70. }
  71. }
  72. }
  73. }