1use std::io::{Read, Write};
2use crate::CodecError;
3
4pub trait VarIntWrite: Write {
5 #[inline]
6 fn write_varint(&mut self, value: i32) -> Result<(), CodecError> {
7 let mut value = value as u32;
8 for i in 0..5 {
9 let byte = (value & 0x7F) as u8;
10 value >>= 7;
11 let has_next = value != 0 && i < 4;
12 let byte = if has_next { byte | 0x80 } else { byte };
13
14 self.write_all(&[byte])?;
15
16 if !has_next {
17 return Ok(());
18 }
19 }
20 Err(CodecError::VarIntOverflow)
21 }
22}
23
24pub trait VarIntRead: Read {
25 #[inline]
26 fn read_varint(&mut self) -> Result<i32, CodecError> {
27 let mut result = 0u32;
28 let mut shift = 0;
29
30 for _ in 0..5 {
31 let mut buf = [0u8; 1];
32 self.read_exact(&mut buf)?;
33 let byte = buf[0];
34
35 let value = (byte & 0x7F) as u32;
36 result |= value << shift;
37
38 if (byte & 0x80) == 0 {
39 return Ok(result as i32);
40 }
41
42 shift += 7;
43 }
44 Err(CodecError::VarIntOverflow)
45 }
46}
47
48impl<R: Read> VarIntRead for R {}
49impl<W: Write> VarIntWrite for W {}