cs_string_rw/
read_7_bit_encoded_i32.rs

1use std::io;
2use std::slice;
3
4pub trait Read7BitEncodedI32Ext {
5	fn read_7_bit_encoded_i32(&mut self) -> io::Result<i32>;
6}
7
8impl<T: io::Read> Read7BitEncodedI32Ext for T {
9	fn read_7_bit_encoded_i32(&mut self) -> io::Result<i32> {
10		let mut buf = 0u8;
11		let mut result = 0u64;
12		for i in 0..5 {
13			self.read_exact(slice::from_mut(&mut buf))?;
14			result |= ((buf & 127) as u64) << (i * 7);
15
16			if buf & 128 == 0 {
17				break;
18			}
19		}
20
21		if result > u32::MAX as u64 {
22			return Err(io::Error::new(
23				io::ErrorKind::InvalidData,
24				"Input data can't fit into i32",
25			));
26		}
27
28		Ok(result as u32 as i32)
29	}
30}
31
32#[cfg(test)]
33mod tests {
34	use super::*;
35	use crate::read_byte_arr::ReadByteArr;
36	#[test]
37	fn reading_ints() {
38		let encoded_7_bit_ints: [u8; 40] = [
39			0xff, 0xff, 0xff, 0xff, 0x0f, 0x80, 0x80, 0x80, 0x80, 0x08, 0x01, 0xff, 0xff, 0xff,
40			0xff, 0x07, 0x00, 0x02, 0x05, 0x80, 0xa4, 0xe8, 0x03, 0x80, 0xd0, 0xa5, 0x4c, 0xb0,
41			0xea, 0x01, 0xe0, 0x99, 0xf2, 0xfe, 0x0f, 0xc0, 0xca, 0xfe, 0xff, 0x0f,
42		];
43
44		let mut reader = ReadByteArr::new(&encoded_7_bit_ints);
45		assert_eq!(reader.read_7_bit_encoded_i32().unwrap(), -1);
46		assert_eq!(reader.read_7_bit_encoded_i32().unwrap(), -2147483648);
47		assert_eq!(reader.read_7_bit_encoded_i32().unwrap(), 1);
48		assert_eq!(reader.read_7_bit_encoded_i32().unwrap(), 2147483647);
49		assert_eq!(reader.read_7_bit_encoded_i32().unwrap(), 0);
50		assert_eq!(reader.read_7_bit_encoded_i32().unwrap(), 2);
51		assert_eq!(reader.read_7_bit_encoded_i32().unwrap(), 5);
52		assert_eq!(reader.read_7_bit_encoded_i32().unwrap(), 8000000);
53		assert_eq!(reader.read_7_bit_encoded_i32().unwrap(), 160000000);
54		assert_eq!(reader.read_7_bit_encoded_i32().unwrap(), 30000);
55		assert_eq!(reader.read_7_bit_encoded_i32().unwrap(), -2323232);
56		assert_eq!(reader.read_7_bit_encoded_i32().unwrap(), -23232);
57	}
58
59	#[test]
60	fn too_short() {
61		let encoded_7_bit_int: [u8; 1] = [0xFF];
62		let mut reader = ReadByteArr::new(&encoded_7_bit_int);
63		assert_eq!(
64			reader.read_7_bit_encoded_i32().map_err(|e| e.kind()),
65			Err(io::ErrorKind::UnexpectedEof)
66		);
67	}
68
69	#[test]
70	fn invalid_data() {
71		let encoded_7_bit_int: [u8; 5] = [0xFF, 0xFF, 0xFF, 0xFF, 0xFF];
72		let mut reader = ReadByteArr::new(&encoded_7_bit_int);
73		assert_eq!(
74			reader.read_7_bit_encoded_i32().map_err(|e| e.kind()),
75			Err(io::ErrorKind::InvalidData)
76		);
77	}
78}