audio_key.rs 2.7 KB

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