mumble_protocol/
varint.rs1use byteorder::ReadBytesExt;
4use byteorder::WriteBytesExt;
5use bytes::BufMut;
6use std::io;
7
8pub trait ReadExt: io::Read {
10 fn read_varint(&mut self) -> io::Result<u64>;
12}
13
14pub trait WriteExt: io::Write {
16 fn write_varint(&mut self, val: u64) -> io::Result<()>;
18}
19
20pub trait BufMutExt: BufMut {
22 fn put_varint(&mut self, val: u64);
24}
25
26impl<T: io::Read> ReadExt for T {
27 fn read_varint(&mut self) -> io::Result<u64> {
28 let b0 = self.read_u8()?;
29 if b0 & 0b1111_1100 == 0b1111_1000 {
30 return Ok(!self.read_varint()?);
31 }
32 if b0 & 0b1111_1100 == 0b1111_1100 {
33 return Ok(!u64::from(b0 & 0x03));
34 }
35 if (b0 & 0b1000_0000) == 0 {
36 return Ok(u64::from(b0 & 0b0111_1111));
37 }
38 let b1 = self.read_u8()?;
39 if (b0 & 0b0100_0000) == 0 {
40 return Ok(u64::from(b0 & 0b0011_1111) << 8 | u64::from(b1));
41 }
42 let b2 = self.read_u8()?;
43 if (b0 & 0b0010_0000) == 0 {
44 return Ok(u64::from(b0 & 0b0001_1111) << 16 | u64::from(b1) << 8 | u64::from(b2));
45 }
46 let b3 = self.read_u8()?;
47 if (b0 & 0b0001_0000) == 0 {
48 return Ok(u64::from(b0 & 0x0F) << 24
49 | u64::from(b1) << 16
50 | u64::from(b2) << 8
51 | u64::from(b3));
52 }
53 let b4 = self.read_u8()?;
54 if (b0 & 0b0000_0100) == 0 {
55 return Ok(u64::from(b1) << 24
56 | u64::from(b2) << 16
57 | u64::from(b3) << 8
58 | u64::from(b4));
59 }
60 let b5 = self.read_u8()?;
61 let b6 = self.read_u8()?;
62 let b7 = self.read_u8()?;
63 let b8 = self.read_u8()?;
64 Ok(u64::from(b1) << 56
65 | u64::from(b2) << 48
66 | u64::from(b3) << 40
67 | u64::from(b4) << 32
68 | u64::from(b5) << 24
69 | u64::from(b6) << 16
70 | u64::from(b7) << 8
71 | u64::from(b8))
72 }
73}
74
75impl<T: io::Write> WriteExt for T {
76 fn write_varint(&mut self, value: u64) -> io::Result<()> {
77 if value & 0xffff_ffff_ffff_fffc == 0xffff_ffff_ffff_fffc {
78 return self.write_u8(0b1111_1100 | (!value as u8));
79 }
80 if value & 0x8000_0000_0000_0000 == 0x8000_0000_0000_0000 {
81 self.write_u8(0b1111_1000)?;
82 return self.write_varint(!value);
83 }
84
85 if value > 0xffff_ffff {
86 self.write_u8(0b1111_0100)?;
87 self.write_u8((value >> 56) as u8)?;
88 self.write_u8((value >> 48) as u8)?;
89 self.write_u8((value >> 40) as u8)?;
90 self.write_u8((value >> 32) as u8)?;
91 self.write_u8((value >> 24) as u8)?;
92 self.write_u8((value >> 16) as u8)?;
93 self.write_u8((value >> 8) as u8)?;
94 return self.write_u8(value as u8);
95 }
96
97 if value > 0x0fff_ffff {
98 self.write_u8(0b1111_0000)?;
99 self.write_u8((value >> 24) as u8)?;
100 self.write_u8((value >> 16) as u8)?;
101 self.write_u8((value >> 8) as u8)?;
102 return self.write_u8(value as u8);
103 }
104
105 if value > 0x001f_ffff {
106 self.write_u8(0b1110_0000 | (value >> 24) as u8)?;
107 self.write_u8((value >> 16) as u8)?;
108 self.write_u8((value >> 8) as u8)?;
109 return self.write_u8(value as u8);
110 }
111
112 if value > 0x0000_3fff {
113 self.write_u8(0b1100_0000 | (value >> 16) as u8)?;
114 self.write_u8((value >> 8) as u8)?;
115 return self.write_u8(value as u8);
116 }
117
118 if value > 0x0000_007f {
119 self.write_u8(0b1000_0000 | (value >> 8) as u8)?;
120 return self.write_u8(value as u8);
121 }
122
123 self.write_u8(value as u8)
124 }
125}
126
127impl<T: BufMut> BufMutExt for T {
128 fn put_varint(&mut self, val: u64) {
129 self.writer()
130 .write_varint(val)
131 .expect("BufMut::writer never errors");
132 }
133}