cs_string_rw/
read_7_bit_encoded_i32.rs1use 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}