1use std::io;
2
3use byteorder::{ReadBytesExt, WriteBytesExt};
4
5use super::{
6 io::{MoshroomReadable, MoshroomWritable},
7 ProtocolVersion,
8};
9use crate::error::{MoshroomError, Result};
10
11#[derive(Copy, Clone, Debug, PartialEq, Eq)]
12pub struct VarInt(pub i32);
13
14impl MoshroomReadable for VarInt {
15 fn read(reader: &mut impl io::Read, _: ProtocolVersion) -> Result<Self> {
16 let mut num_read = 0;
17 let mut result = 0;
18
19 loop {
20 let read = reader.read_u8()?;
21 let value = i32::from(read & 0b0111_1111);
22 result |= value.overflowing_shl(7 * num_read).0;
23
24 num_read += 1;
25
26 if num_read > 5 {
27 return Err(MoshroomError::VarIntTooLong);
28 }
29 if read & 0b1000_0000 == 0 {
30 break;
31 }
32 }
33 Ok(Self(result))
34 }
35}
36
37impl MoshroomWritable for VarInt {
38 fn write(&self, writer: &mut impl io::Write, _: ProtocolVersion) -> Result<()> {
39 let mut x = self.0 as u32;
40 loop {
41 let mut temp = (x & 0b0111_1111) as u8;
42 x >>= 7;
43 if x != 0 {
44 temp |= 0b1000_0000;
45 }
46
47 writer.write_all(&[temp])?;
48
49 if x == 0 {
50 break;
51 }
52 }
53 Ok(())
54 }
55}
56
57#[derive(Copy, Clone, Debug, PartialEq, Eq)]
58pub struct VarLong(pub i64);
59
60impl MoshroomReadable for VarLong {
61 fn read(reader: &mut impl io::Read, _: ProtocolVersion) -> Result<Self> {
62 let mut num_read = 0;
63 let mut result = 0;
64
65 loop {
66 let read = reader.read_u8()?;
67 let value = i64::from(read & 0b0111_1111);
68 result |= value.overflowing_shl(7 * num_read).0;
69
70 num_read += 1;
71
72 if read & 0b1000_0000 == 0 {
73 break;
74 }
75
76 if num_read > 10 {
77 return Err(MoshroomError::VarIntTooLong);
78 }
79 }
80 Ok(Self(result))
81 }
82}
83
84impl MoshroomWritable for VarLong {
85 fn write(&self, writer: &mut impl io::Write, _: ProtocolVersion) -> Result<()> {
86 let mut x = self.0 as u64;
87 writer
88 .write_u8(((x & 0b0111_1111) | (0b1000_0000 * ((x >> 7 != 0) as u64))) as u8)
89 .map_err(MoshroomError::IoError)?;
90 x >>= 7;
91 loop {
92 if x == 0 {
93 break;
94 }
95 let mut temp = (x & 0b0111_1111) as u8;
96
97 x >>= 7;
98 if x != 0 {
99 temp |= 0b1000_0000;
100 }
101
102 writer.write_u8(temp).map_err(MoshroomError::IoError)?;
103 }
104
105 Ok(())
106 }
107}
108
109#[cfg(test)]
110mod tests {
111 use super::*;
112
113 #[test]
114 fn varint_read() {
115 assert_eq!(
116 VarInt::read(&mut [0x0].as_ref(), ProtocolVersion::V1_20).unwrap(),
117 VarInt(0)
118 );
119 assert_eq!(
120 VarInt::read(&mut [0x1].as_ref(), ProtocolVersion::V1_20).unwrap(),
121 VarInt(1)
122 );
123 assert_eq!(
124 VarInt::read(&mut [0x2].as_ref(), ProtocolVersion::V1_20).unwrap(),
125 VarInt(2)
126 );
127 assert_eq!(
128 VarInt::read(&mut [0x7f].as_ref(), ProtocolVersion::V1_20).unwrap(),
129 VarInt(127)
130 );
131 assert_eq!(
132 VarInt::read(&mut [0x80, 0x01].as_ref(), ProtocolVersion::V1_20).unwrap(),
133 VarInt(128)
134 );
135 assert_eq!(
136 VarInt::read(&mut [0xff, 0x01].as_ref(), ProtocolVersion::V1_20).unwrap(),
137 VarInt(255)
138 );
139 assert_eq!(
140 VarInt::read(&mut [0xdd, 0xc7, 0x01].as_ref(), ProtocolVersion::V1_20).unwrap(),
141 VarInt(25565)
142 );
143 assert_eq!(
144 VarInt::read(&mut [0xff, 0xff, 0x7f].as_ref(), ProtocolVersion::V1_20).unwrap(),
145 VarInt(2097151)
146 );
147 assert_eq!(
148 VarInt::read(
149 &mut [0xff, 0xff, 0xff, 0xff, 0x07].as_ref(),
150 ProtocolVersion::V1_20
151 )
152 .unwrap(),
153 VarInt(2147483647)
154 );
155 assert_eq!(
156 VarInt::read(
157 &mut [0xff, 0xff, 0xff, 0xff, 0x0f].as_ref(),
158 ProtocolVersion::V1_20
159 )
160 .unwrap(),
161 VarInt(-1)
162 );
163 assert_eq!(
164 VarInt::read(
165 &mut [0x80, 0x80, 0x80, 0x80, 0x08].as_ref(),
166 ProtocolVersion::V1_20
167 )
168 .unwrap(),
169 VarInt(-2147483648)
170 );
171 }
172
173 #[test]
174 fn varint_write() {
175 fn check_varint<const N: usize>(value: i32, expected: [u8; N]) {
176 let mut buffer = Vec::new();
177 VarInt(value)
178 .write(&mut buffer, ProtocolVersion::V1_20)
179 .unwrap();
180 let out: [u8; N] = buffer.try_into().unwrap();
181
182 assert_eq!(expected, out);
183 }
184
185 check_varint(0, [0x0]);
186 check_varint(1, [0x1]);
187 check_varint(2, [0x2]);
188 check_varint(127, [0x7f]);
189 check_varint(128, [0x80, 0x01]);
190 check_varint(255, [0xff, 0x01]);
191 check_varint(25565, [0xdd, 0xc7, 0x01]);
192 check_varint(2097151, [0xff, 0xff, 0x7f]);
193 check_varint(2147483647, [0xff, 0xff, 0xff, 0xff, 0x07]);
194 check_varint(-1, [0xff, 0xff, 0xff, 0xff, 0x0f]);
195 check_varint(-2147483648, [0x80, 0x80, 0x80, 0x80, 0x08]);
196 }
197
198 #[test]
199 fn varint_write_read() {
200 let tests = [
201 0,
202 1,
203 2,
204 127,
205 128,
206 255,
207 25565,
208 2097151,
209 2147483647,
210 -1,
211 -2147483648,
212 ];
213 let mut buffer = Vec::new();
214 for i in tests {
215 buffer.clear();
216 let vi = VarInt(i);
217 vi.write(&mut buffer, ProtocolVersion::V1_20).unwrap();
218
219 let vo = VarInt::read(&mut buffer.as_slice(), ProtocolVersion::V1_20).unwrap();
220 assert_eq!(vi, vo);
221 }
222 }
223
224 #[test]
225 fn varlong_read() {
226 assert_eq!(
227 VarLong::read(&mut [0x0].as_ref(), ProtocolVersion::V1_20).unwrap(),
228 VarLong(0)
229 );
230 assert_eq!(
231 VarLong::read(&mut [0x1].as_ref(), ProtocolVersion::V1_20).unwrap(),
232 VarLong(1)
233 );
234 assert_eq!(
235 VarLong::read(&mut [0x2].as_ref(), ProtocolVersion::V1_20).unwrap(),
236 VarLong(2)
237 );
238 assert_eq!(
239 VarLong::read(&mut [0x7f].as_ref(), ProtocolVersion::V1_20).unwrap(),
240 VarLong(127)
241 );
242 assert_eq!(
243 VarLong::read(&mut [0x80, 0x01].as_ref(), ProtocolVersion::V1_20).unwrap(),
244 VarLong(128)
245 );
246 assert_eq!(
247 VarLong::read(&mut [0xff, 0x01].as_ref(), ProtocolVersion::V1_20).unwrap(),
248 VarLong(255)
249 );
250 assert_eq!(
251 VarLong::read(&mut [0xdd, 0xc7, 0x01].as_ref(), ProtocolVersion::V1_20).unwrap(),
252 VarLong(25565)
253 );
254 assert_eq!(
255 VarLong::read(&mut [0xff, 0xff, 0x7f].as_ref(), ProtocolVersion::V1_20).unwrap(),
256 VarLong(2097151)
257 );
258 assert_eq!(
259 VarLong::read(
260 &mut [0xff, 0xff, 0xff, 0xff, 0x07].as_ref(),
261 ProtocolVersion::V1_20
262 )
263 .unwrap(),
264 VarLong(2147483647)
265 );
266 assert_eq!(
267 VarLong::read(
268 &mut [0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f].as_ref(),
269 ProtocolVersion::V1_20
270 )
271 .unwrap(),
272 VarLong(9223372036854775807)
273 );
274 assert_eq!(
275 VarLong::read(
276 &mut [0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x01].as_ref(),
277 ProtocolVersion::V1_20
278 )
279 .unwrap(),
280 VarLong(-1)
281 );
282 assert_eq!(
283 VarLong::read(
284 &mut [0x80, 0x80, 0x80, 0x80, 0xf8, 0xff, 0xff, 0xff, 0xff, 0x01].as_ref(),
285 ProtocolVersion::V1_20
286 )
287 .unwrap(),
288 VarLong(-2147483648)
289 );
290 assert_eq!(
291 VarLong::read(
292 &mut [0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x01].as_ref(),
293 ProtocolVersion::V1_20
294 )
295 .unwrap(),
296 VarLong(-9223372036854775808)
297 );
298 }
299
300 #[test]
301 fn varlong_write() {
302 fn check_varlong<const N: usize>(value: i64, expected: [u8; N]) {
303 let mut buffer = Vec::new();
304 VarLong(value)
305 .write(&mut buffer, ProtocolVersion::V1_20)
306 .unwrap();
307 assert_eq!(buffer.len(), N, "Value: {}", value);
308 let out: [u8; N] = buffer.try_into().unwrap();
309
310 assert_eq!(expected, out);
311 }
312
313 check_varlong(0, [0x0]);
314 check_varlong(1, [0x1]);
315 check_varlong(2, [0x2]);
316 check_varlong(127, [0x7f]);
317 check_varlong(128, [0x80, 0x01]);
318 check_varlong(255, [0xff, 0x01]);
319 check_varlong(25565, [0xdd, 0xc7, 0x01]);
320 check_varlong(2097151, [0xff, 0xff, 0x7f]);
321 check_varlong(2147483647, [0xff, 0xff, 0xff, 0xff, 0x07]);
322 check_varlong(
323 9223372036854775807,
324 [0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f],
325 );
326 check_varlong(
327 -1,
328 [0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x01],
329 );
330 check_varlong(
331 -2147483648,
332 [0x80, 0x80, 0x80, 0x80, 0xf8, 0xff, 0xff, 0xff, 0xff, 0x01],
333 );
334 check_varlong(
335 -9223372036854775808,
336 [0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x01],
337 );
338 }
339
340 #[test]
341 fn varlong_write_read() {
342 let tests = [
343 0,
344 1,
345 2,
346 127,
347 128,
348 255,
349 25565,
350 2097151,
351 2147483647,
352 9223372036854775807,
353 -1,
354 -2147483648,
355 -9223372036854775808,
356 ];
357 let mut buffer = Vec::new();
358 for i in tests {
359 buffer.clear();
360 let vi = VarLong(i);
361 vi.write(&mut buffer, ProtocolVersion::V1_20).unwrap();
362
363 let vo = VarLong::read(&mut buffer.as_slice(), ProtocolVersion::V1_20).unwrap();
364 assert_eq!(vi, vo);
365 }
366 }
367}