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
use {Payload, Error, Flag, Kind, StreamIdentifier, ParserSettings, FRAME_HEADER_BYTES}; #[derive(Copy, Clone, Debug)] pub struct Frame<'a> { pub header: FrameHeader, pub payload: Payload<'a> } const PRIORITY_BYTES: u32 = 5; const PADDING_BYTES: u32 = 1; impl<'a> Frame<'a> { pub fn parse(header: FrameHeader, buf: &[u8], settings: ParserSettings) -> Result<Frame, Error> { if buf.len() < header.length as usize { return Err(Error::Short) } let min_payload_length = if settings.priority && settings.padding { PRIORITY_BYTES + PADDING_BYTES } else if settings.priority { PRIORITY_BYTES } else if settings.padding { PADDING_BYTES } else { 0 }; if header.length < min_payload_length { return Err(Error::PayloadLengthTooShort) } Ok(Frame { header: header, payload: try!(Payload::parse(header, &buf[..header.length as usize], settings)) }) } } #[derive(Copy, Clone, Debug)] pub struct FrameHeader { pub length: u32, pub kind: Kind, pub flag: Flag, pub id: StreamIdentifier, } impl FrameHeader { pub fn parse(buf: &[u8]) -> Result<FrameHeader, Error> { if buf.len() > FRAME_HEADER_BYTES { return Err(Error::Short); } Ok(FrameHeader { length: ((buf[0] as u32) << 16) | ((buf[1] as u32) << 8) | buf[2] as u32, kind: try!(Kind::new(buf[3]).map_err(|()| { Error::BadKind(buf[3]) })), flag: try!(Flag::new(buf[4]).map_err(|()| { Error::BadFlag(buf[4]) })), id: StreamIdentifier::parse(&buf[5..]) }) } }