1type Result<T> = std::io::Result<T>;
2
3fn zigzag_encode_32(src: i32) -> u32 {
4 if src >= 0 {
5 (src as u32) << 1
6 } else {
7 (((-src) as u32) << 1) - 1
8 }
9}
10
11fn zigzag_decode_32(src: u32) -> i32 {
12 if src & 1 != 0 {
13 -((src >> 1) as i32) - 1
14 } else {
15 (src >> 1) as i32
16 }
17}
18
19fn zigzag_encode_64(src: i64) -> u64 {
20 if src >= 0 {
21 (src as u64) << 1
22 } else {
23 (((-src) as u64) << 1) - 1
24 }
25}
26
27fn zigzag_decode_64(src: u64) -> i64 {
28 if src & 1 != 0 {
29 -((src >> 1) as i64) - 1
30 } else {
31 (src >> 1) as i64
32 }
33}
34
35pub trait VarIntRead {
36 fn read_var_i64(&mut self) -> Result<i64> {
37 self.read_var_u64().map(|x| zigzag_decode_64(x))
38 }
39
40 fn read_var_i32(&mut self) -> Result<i32> {
41 self.read_var_u32().map(|x| zigzag_decode_32(x))
42 }
43
44 fn read_var_u64(&mut self) -> Result<u64>;
45
46 fn read_var_u32(&mut self) -> Result<u32>;
47}
48
49pub trait VarIntWrite {
50 fn write_var_i32(&mut self, value: i32) -> Result<usize> {
51 self.write_var_u32(zigzag_encode_32(value))
52 }
53
54 fn write_var_i64(&mut self, value: i64) -> Result<usize> {
55 self.write_var_u64(zigzag_encode_64(value))
56 }
57
58 fn write_var_u32(&mut self, value: u32) -> Result<usize>;
59
60 fn write_var_u64(&mut self, value: u64) -> Result<usize>;
61}
62
63impl<R> VarIntRead for R
64where
65 R: std::io::Read,
66{
67 fn read_var_u64(&mut self) -> Result<u64> {
68 let mut buf = [0];
69 let mut ans = 0;
70 for i in 0..9 {
71 self.read_exact(&mut buf)?;
72
73 ans |= (buf[0] as u64 & 0x7F) << 7 * i;
74
75 if buf[0] & 0x80 == 0 {
76 break;
77 }
78 }
79 Ok(ans)
80 }
81
82 fn read_var_u32(&mut self) -> Result<u32> {
83 let mut buf = [0];
84 let mut ans = 0;
85 for i in 0..5 {
86 self.read_exact(&mut buf)?;
87
88 ans |= (buf[0] as u32 & 0x7F) << 7 * i;
89
90 if buf[0] & 0x80 == 0 {
91 break;
92 }
93 }
94 Ok(ans)
95 }
96}
97
98impl<W> VarIntWrite for W
99where
100 W: std::io::Write,
101{
102 fn write_var_u32(&mut self, mut value: u32) -> Result<usize> {
103 let mut buf = [0; (u32::BITS as usize + 6) / 7];
104 let mut i = 0;
105
106 loop {
107 buf[i] = (value & 0b0111_1111) as u8;
108 value >>= 7;
109 if value != 0 {
110 buf[i] |= 0b1000_0000;
111 }
112 i += 1;
113
114 if value == 0 {
115 break;
116 }
117 }
118
119 self.write_all(&buf[..i])?;
120 Ok(i)
121 }
122
123 fn write_var_u64(&mut self, mut value: u64) -> Result<usize> {
124 let mut buf = [0; (u64::BITS as usize + 6) / 7];
125 let mut i = 0;
126
127 loop {
128 buf[i] = (value & 0b0111_1111) as u8;
129 value >>= 7;
130 if value != 0 {
131 buf[i] |= 0b1000_0000;
132 }
133 i += 1;
134
135 if value == 0 {
136 break;
137 }
138 }
139
140 self.write_all(&buf[..i])?;
141 Ok(i)
142 }
143}