use frame::{util, Frame, Head, Error, StreamId, Kind}; use bytes::{BufMut, Bytes, Buf}; #[derive(Debug)] pub struct Data { stream_id: StreamId, //data_len: FrameSize, data: T, flags: DataFlag, pad_len: Option, } #[derive(Debug, Copy, Clone, Eq, PartialEq)] pub struct DataFlag(u8); const END_STREAM: u8 = 0x1; const PADDED: u8 = 0x8; const ALL: u8 = END_STREAM | PADDED; impl Data { pub fn load(head: Head, mut payload: Bytes) -> Result { let flags = DataFlag::load(head.flag()); let pad_len = if flags.is_padded() { let len = try!(util::strip_padding(&mut payload)); Some(len) } else { None }; Ok(Data { stream_id: head.stream_id(), //data_len: payload.len() as FrameSize, data: payload, flags: flags, pad_len: pad_len, }) } } impl Data { pub fn stream_id(&self) -> StreamId { self.stream_id } pub fn is_end_stream(&self) -> bool { self.flags.is_end_stream() } pub fn set_end_stream(&mut self) { self.flags.set_end_stream() } pub fn head(&self) -> Head { Head::new(Kind::Data, self.flags.into(), self.stream_id) } pub fn payload(&self) -> &T { &self.data } pub fn into_payload(self) -> T { self.data } } impl Data { pub fn from_buf(stream_id: StreamId, data: T, eos: bool) -> Self { let mut flags = DataFlag::default(); if eos { flags.set_end_stream(); } Data { stream_id, //data_len: data.remaining() as FrameSize, data, flags, pad_len: None, } } pub fn encode_chunk(&mut self, dst: &mut U) { let len = self.data.remaining() as usize; if len > dst.remaining_mut() { unimplemented!(); } self.head().encode(len, dst); dst.put(&mut self.data); } } impl From> for Frame { fn from(src: Data) -> Self { Frame::Data(src) } } // ===== impl DataFlag ===== impl DataFlag { pub fn load(bits: u8) -> DataFlag { DataFlag(bits & ALL) } pub fn end_stream() -> DataFlag { DataFlag(END_STREAM) } pub fn padded() -> DataFlag { DataFlag(PADDED) } pub fn is_end_stream(&self) -> bool { self.0 & END_STREAM == END_STREAM } pub fn set_end_stream(&mut self) { self.0 |= END_STREAM } pub fn is_padded(&self) -> bool { self.0 & PADDED == PADDED } } impl Default for DataFlag { /// Returns a `HeadersFlag` value with `END_HEADERS` set. fn default() -> Self { DataFlag(0) } } impl From for u8 { fn from(src: DataFlag) -> u8 { src.0 } }