1pub fn pack(data: &[u8]) -> Vec<u8> {
5 let mut out = Vec::with_capacity(data.len() * 8 / 7 + 1);
6 let (mut acc, mut nbits) = (0u32, 0u32);
7 for &b in data {
8 acc |= (b as u32) << nbits;
9 nbits += 8;
10 while nbits >= 7 {
11 out.push((acc & 0x7F) as u8);
12 acc >>= 7;
13 nbits -= 7;
14 }
15 }
16 if nbits > 0 {
17 out.push((acc & 0x7F) as u8);
18 }
19 out
20}
21
22pub fn unpack(midi: &[u8]) -> Vec<u8> {
24 let mut out = Vec::with_capacity(midi.len() * 7 / 8);
25 let (mut acc, mut nbits) = (0u32, 0u32);
26 for &b in midi {
27 acc |= ((b & 0x7F) as u32) << nbits;
28 nbits += 7;
29 if nbits >= 8 {
30 out.push((acc & 0xFF) as u8);
31 acc >>= 8;
32 nbits -= 8;
33 }
34 }
35 out
36}
37
38#[cfg(test)]
39mod tests {
40 use super::*;
41
42 #[test]
43 fn roundtrip() {
44 let data: Vec<u8> = (0..110u32).map(|i| (i * 37 + 11) as u8).collect();
45 let packed = pack(&data);
46 assert_eq!(packed.len(), 126);
47 assert!(packed.iter().all(|b| *b < 0x80));
48 assert_eq!(unpack(&packed), data);
49 }
50
51 #[test]
52 fn nam_slot_header() {
53 assert_eq!(&pack(&[0, 1, 4])[..3], &[0x00, 0x02, 0x10]);
55 }
56}