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
use std::io::Read; #[derive(Debug)] pub enum StreamDelimitError { NoLeadingVarintError(), } pub enum StreamDelimiter { Varint(usize), } pub trait Parse { fn parse(&mut self, buf: &mut Read, size: &mut usize) -> Result<(), StreamDelimitError>; } impl Parse for StreamDelimiter { fn parse(&mut self, read: &mut Read, size: &mut usize) -> Result<(), StreamDelimitError> { match *self { StreamDelimiter::Varint(max_attempts) => { let mut varint_buf: Vec<u8> = Vec::with_capacity(max_attempts); for i in 0..max_attempts { varint_buf.push(0u8); read.read_exact(&mut varint_buf[i..]).unwrap(); if (varint_buf[i] & 0b10000000) >> 7 != 0x1 { let mut concat: u64 = 0; for i in (0..varint_buf.len()).rev() { let i_ = i as u32; concat += ((varint_buf[i] & 0b01111111) as u64) << i_*(8u32.pow(i_) - 1); } *size = concat as usize; return Ok(()); } } return Err(StreamDelimitError::NoLeadingVarintError()) } } } } #[cfg(test)] mod tests { use super::{StreamDelimiter, Parse}; #[test] fn test_simple() { let mut buf: &[u8] = &[0x01]; let mut size: usize = 0; let mut delimiter = StreamDelimiter::Varint(10); delimiter.parse(&mut buf, &mut size).unwrap(); assert_eq!(1, size); } #[test] fn test_varint_delimiter_longer() { let mut buf: &[u8] = &[0xACu8, 0x02u8]; let mut size: usize = 0; let mut delimiter = StreamDelimiter::Varint(10); delimiter.parse(&mut buf, &mut size).unwrap(); assert_eq!(300, size); } }