1pub(crate) const fn prefix(bfinal: bool) -> [u8; 9] {
2 [
3 0b00000100 | bfinal as u8,
4 0b11000000,
5 0b00010001,
6 0b00000001,
7 0b00000000,
8 0b00000000,
9 0b00000000,
10 0b00000000,
11 0b00100000,
12 ]
13}
14
15pub(crate) fn decode_from_end(bytes: &[u8]) -> Option<(usize, u64)> {
16 let prefix = prefix(true);
17 let mut start = bytes.len().checked_sub(13)?;
18 while !bytes[start..].starts_with(&prefix) {
19 start = start.checked_sub(1)?;
20 }
21 let payload = decode_rest(&bytes[start + prefix.len()..])?;
22 Some((start, payload))
23}
24
25pub(crate) fn decode_from_start(bytes: &[u8]) -> Option<u64> {
26 let prefix = prefix(false);
27 if bytes.starts_with(&prefix) {
28 decode_rest(&bytes[prefix.len()..])
29 } else {
30 None
31 }
32}
33
34fn decode_rest(bytes: &[u8]) -> Option<u64> {
35 let mut bitpos = 0;
36 let mut take = |n: usize| -> u8 {
37 let byte = (bytes.get(bitpos / 8).unwrap_or(&0) >> (bitpos % 8))
38 | bytes
39 .get(bitpos / 8 + 1)
40 .unwrap_or(&0)
41 .unbounded_shl((8 - bitpos % 8) as u32);
42 bitpos += n;
43 byte & 0b11111111u8.unbounded_shr((8 - n) as u32)
44 };
45
46 let mut payload = 0;
47 let mut zeros = 0;
48 for i in 0..22 {
49 if i > 0 && take(1) != 0 {
50 break;
51 }
52 let n = take(3);
53 payload |= u64::from(n) << (i * 3);
54 zeros += 3 + n as usize;
55 }
56
57 if (payload < 0x8000_0000_0000_0000 || take(1) == 1)
58 && take(1) == 1
59 && match zeros {
60 4..=97 => {
61 take(7) == 0b1111111
62 && take(2) == 0b11
63 && take(7) == (256 - (zeros + 138) - 11) as u8
64 }
65 98..=107 => {
66 take(7) == (256 - (zeros + 20) - 11) as u8
67 && take(1) == 0
68 && take(3) == 0b111
69 && take(1) == 0
70 && take(3) == 0b111
71 }
72 108..=117 => {
73 take(7) == (256 - (zeros + 10) - 11) as u8 && take(1) == 0 && take(3) == 0b111
74 }
75 118..=214 => take(7) == (256 - zeros - 11) as u8,
76 0..=3 | 215.. => false,
77 }
78 && take(2) == 1
79 && take(2) == 1
80 && take(1) == 0
81 {
82 Some(payload)
83 } else {
84 None
85 }
86}