use crate::frame::{self, Error, Head, Kind, StreamId}; use bytes::BufMut; const SIZE_INCREMENT_MASK: u32 = 1 << 31; #[derive(Debug, Copy, Clone, Eq, PartialEq)] pub struct WindowUpdate { stream_id: StreamId, size_increment: u32, } impl WindowUpdate { pub fn new(stream_id: StreamId, size_increment: u32) -> WindowUpdate { WindowUpdate { stream_id, size_increment, } } pub fn stream_id(&self) -> StreamId { self.stream_id } pub fn size_increment(&self) -> u32 { self.size_increment } /// Builds a `WindowUpdate` frame from a raw frame. pub fn load(head: Head, payload: &[u8]) -> Result { debug_assert_eq!(head.kind(), crate::frame::Kind::WindowUpdate); if payload.len() != 4 { return Err(Error::BadFrameSize); } // Clear the most significant bit, as that is reserved and MUST be ignored // when received. let size_increment = unpack_octets_4!(payload, 0, u32) & !SIZE_INCREMENT_MASK; if size_increment == 0 { return Err(Error::InvalidWindowUpdateValue); } Ok(WindowUpdate { stream_id: head.stream_id(), size_increment, }) } pub fn encode(&self, dst: &mut B) { tracing::trace!("encoding WINDOW_UPDATE; id={:?}", self.stream_id); let head = Head::new(Kind::WindowUpdate, 0, self.stream_id); head.encode(4, dst); dst.put_u32(self.size_increment); } } impl From for frame::Frame { fn from(src: WindowUpdate) -> Self { frame::Frame::WindowUpdate(src) } }