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