1#![allow(non_snake_case)]
2
3use std::io::{Read, Write};
4use std::ops::{BitAnd, BitOrAssign, Shl};
5
6const MSB: u8 = 0x80;
7const REST: u8 = 0x7F;
8pub trait VarInt {
9 fn parse(value: u128) -> Self;
10 fn retrieve(value: Self) -> u128;
11}
12
13impl VarInt for u64 {
14 fn parse(data: u128) -> u64 {
15 return data as u64;
16 }
17 fn retrieve(value: u64) -> u128 {
18 return value as u128;
19 }
20}
21
22impl VarInt for u32 {
23 fn parse(data: u128) -> u32 {
24 return data as u32;
25 }
26 fn retrieve(value: u32) -> u128 {
27 return value as u128;
28 }
29}
30
31impl VarInt for u16 {
32 fn parse(data: u128) -> u16 {
33 return data as u16;
34 }
35 fn retrieve(value: u16) -> u128 {
36 return value as u128;
37 }
38}
39
40impl VarInt for u8 {
41 fn parse(data: u128) -> u8 {
42 return data as u8;
43 }
44 fn retrieve(value: u8) -> u128 {
45 return value as u128;
46 }
47}
48
49pub fn read<T: VarInt, R: Read>(mut reader: R) -> T
50where
51 T: From<u8> + BitAnd + BitOrAssign + Shl + VarInt,
52{
53 let mut temp: u128 = 0;
54 for shift in (0..).step_by(7) {
55 let mut piece = [0];
56 reader.read_exact(&mut piece[..]).expect("Failed to read");
57 temp |= ((piece[0] & REST) as u128) << shift;
58 if (piece[0] & MSB) == 0 {
59 if piece[0] == 0 && shift != 0 {
60 panic!("Read Varint, invalid value representation");
61 }
62 break;
63 }
64 }
65 return T::parse(temp);
66}
67
68pub fn write<T: VarInt, W: Write>(writer: &mut W, value: T)
69where
70 T: From<u8> + BitAnd + BitOrAssign + Shl + VarInt,
71{
72 let mut temp = T::retrieve(value);
73 while temp >= 0x80 {
74 let mut piece = [0];
75 piece[0] = temp as u8 | MSB;
76 writer.write(&piece).expect("Failed to write");
77 temp >>= 7;
78 }
79 let mut piece = [0];
80 piece[0] = temp as u8;
81 writer.write(&piece).expect("Failed to write");
82}
83
84#[cfg(test)]
85mod tests {
86 use super::{read, write};
87 use std::io::{Cursor, Seek, SeekFrom};
88
89 #[test]
90 fn it_should_read() {
91 let data0 = [0x01];
92 assert_eq!(read::<u8, _>(&data0[..]), 1);
93 let data = [0x01];
94 assert_eq!(read::<u16, _>(&data[..]), 1);
95 let data1 = [0xF, 0x00];
96 println!("{}", read::<u32, _>(&data1[..]));
97 assert_eq!(read::<u32, _>(&data1[..]), 15);
98 let data2 = [0x80, 0x1E];
99 assert_eq!(read::<u32, _>(&data2[..]), 0x0F00);
100
101 let data3 = [0x80, 0x1E, 0x11, 0x11, 0x11, 0x11];
102 println!("{}", read::<u64, _>(&data3[..]));
103 assert_eq!(read::<u64, _>(&data3[..]), 3840);
104 }
105
106 #[test]
107 fn it_should_write() {
108 let mut c = Cursor::new(Vec::new());
109 c.seek(SeekFrom::Start(0)).unwrap();
110 write::<u8, _>(&mut c, 1 as u8);
111 let mut c1 = Cursor::new(Vec::new());
112 c1.seek(SeekFrom::Start(0)).unwrap();
113 write::<u16, _>(&mut c1, 128 as u16);
114 let mut c2 = Cursor::new(Vec::new());
115 c2.seek(SeekFrom::Start(0)).unwrap();
116 write::<u32, _>(&mut c2, 129 as u32);
117 let mut c3 = Cursor::new(Vec::new());
118 c3.seek(SeekFrom::Start(0)).unwrap();
119 write::<u64, _>(&mut c3, 0xF1 as u64);
120 let mut c4 = Cursor::new(Vec::new());
121 c4.seek(SeekFrom::Start(0)).unwrap();
122 write::<u64, _>(&mut c4, 300 as u64);
123 let cArr = c.get_ref();
124 assert_eq!(cArr[0], 1);
125
126 let cArr1 = c1.get_ref();
127 assert_eq!(cArr1[0], 128);
128 assert_eq!(cArr1[1], 1);
129 let cArr2 = c2.get_ref();
130 assert_eq!(cArr2[0], 129);
131 assert_eq!(cArr2[1], 1);
132
133 let cArr3 = c3.get_ref();
134 assert_eq!(cArr3[0], 241);
135 assert_eq!(cArr3[1], 1);
136 let cArr4 = c4.get_ref();
137 assert_eq!(cArr4[0], 0xAC);
138 assert_eq!(cArr4[1], 0x02);
139 println!("c = {:?}\n", c.get_ref());
140 println!("c1 = {:?}\n", c1.get_ref());
141 println!("c2 = {:?}\n", c2.get_ref());
142 println!("c3 = {:?}\n", c3.get_ref());
143 println!("c4 = {:?}\n", c4.get_ref());
144 }
145 #[test]
146 #[should_panic]
147 fn it_should_panic_when_read() {
148 let data = [0xFF];
149 read::<u32, _>(&data[..]);
150 }
151}