1use std::io::{Read, Write};
2use crate::CodecError;
3
4pub trait VarLongWrite: Write {
5 #[inline]
6 fn write_varlong(&mut self, value: i64) -> Result<(), CodecError> {
7 let mut value = value as u64;
8 for i in 0..10 {
9 let byte = (value & 0x7F) as u8;
10 value >>= 7;
11 let has_next = value != 0 && i < 9;
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::VarLongOverflow)
21 }
22}
23
24pub trait VarLongRead: Read {
25 #[inline]
26 fn read_varlong(&mut self) -> Result<i64, CodecError> {
27 let mut result = 0u64;
28 let mut shift = 0;
29
30 for _ in 0..10 {
31 let mut buf = [0u8; 1];
32 self.read_exact(&mut buf)?;
33 let byte = buf[0];
34
35 let value = (byte & 0x7F) as u64;
36 result |= value << shift;
37
38 if (byte & 0x80) == 0 {
39 return Ok(result as i64);
40 }
41
42 shift += 7;
43 }
44 Err(CodecError::VarLongOverflow)
45 }
46}
47
48impl<R: Read> VarLongRead for R {}
49impl<W: Write> VarLongWrite for W {}